Skip to content

Commit

Permalink
feat: add spa package (#49)
Browse files Browse the repository at this point in the history
* feat: add spa package

* chore:fix typo

* fix: remove spa type

* fix: remove panic

* fix: merge handlers
  • Loading branch information
ravisuhag authored Sep 13, 2022
1 parent d28f61d commit 55cf8bb
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 0 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ require (
github.com/AlecAivazis/survey/v2 v2.3.5
github.com/DATA-DOG/go-sqlmock v1.5.0
github.com/MakeNowJust/heredoc v1.0.0
github.com/NYTimes/gziphandler v1.1.1
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
github.com/briandowns/spinner v1.18.0
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
Expand Down
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ github.com/Microsoft/hcsshim v0.9.2/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfy
github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU=
github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s=
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w=
Expand Down
32 changes: 32 additions & 0 deletions spa/router.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package spa

import (
"errors"
"io/fs"
"net/http"
)

// router is the http filesystem which only serves files
// and prevent the directory traversal.
type router struct {
index string
fs http.FileSystem
}

// Open inspects the URL path to locate a file within the static dir.
// If a file is found, it will be served. If not, the file located at
// the index path on the SPA handler will be served.
func (r *router) Open(name string) (http.File, error) {
file, err := r.fs.Open(name)

if err == nil {
return file, nil
}
// Serve index if file does not exist.
if errors.Is(err, fs.ErrNotExist) {
file, err := r.fs.Open(r.index)
return file, err
}

return nil, err
}
40 changes: 40 additions & 0 deletions spa/spa.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package spa

import (
"embed"
"errors"
"fmt"
"io/fs"
"net/http"

"github.com/NYTimes/gziphandler"
)

// Handler return a file server http handler for single page
// application. This handler can be mounted on your mux server.
//
// If gzip is set true, handler gzip the response body, for clients
// which support it. Usually it also can be left to proxies like Nginx,
// this method is useful when that's undesirable.
func Handler(build embed.FS, dir string, index string, gzip bool) (http.Handler, error) {
fsys, err := fs.Sub(build, dir)
if err != nil {
return nil, fmt.Errorf("couldn't create sub filesystem: %w", err)
}

if _, err = fsys.Open(index); err != nil {
if errors.Is(err, fs.ErrNotExist) {
return nil, fmt.Errorf("ui is enabled but no index.html found: %w", err)
} else {
return nil, fmt.Errorf("ui assets error: %w", err)
}
}
router := &router{index: index, fs: http.FS(fsys)}

hlr := http.FileServer(router)

if !gzip {
return hlr, nil
}
return gziphandler.GzipHandler(hlr), nil
}

0 comments on commit 55cf8bb

Please sign in to comment.