diff options
| author | Christine Dodrill <me@christine.website> | 2017-01-10 12:38:33 -0800 |
|---|---|---|
| committer | Christine Dodrill <me@christine.website> | 2017-01-10 12:38:33 -0800 |
| commit | 6e292d4d1d65d83cc089e74063cb70ea63bbd795 (patch) | |
| tree | 2409c6b3f26a4e70499cbbc19f327e01b4a85ca1 /vendor/github.com/Xe | |
| parent | ee89843f5bf60a1e8a3a6bf604ac3f67d25ff72a (diff) | |
| download | xesite-6e292d4d1d65d83cc089e74063cb70ea63bbd795.tar.xz xesite-6e292d4d1d65d83cc089e74063cb70ea63bbd795.zip | |
move vendor to repo root
Diffstat (limited to 'vendor/github.com/Xe')
| -rw-r--r-- | vendor/github.com/Xe/asarfs/asarfs.go | 117 | ||||
| -rw-r--r-- | vendor/github.com/Xe/asarfs/bench_test.go | 156 | ||||
| -rw-r--r-- | vendor/github.com/Xe/asarfs/runtest.go | 24 |
3 files changed, 297 insertions, 0 deletions
diff --git a/vendor/github.com/Xe/asarfs/asarfs.go b/vendor/github.com/Xe/asarfs/asarfs.go new file mode 100644 index 0000000..7d18949 --- /dev/null +++ b/vendor/github.com/Xe/asarfs/asarfs.go @@ -0,0 +1,117 @@ +package asarfs + +import ( + "io" + "mime" + "net/http" + "os" + "path/filepath" + "strings" + + "layeh.com/asar" +) + +// ASARfs serves the contents of an asar archive as an HTTP handler. +type ASARfs struct { + fin *os.File + ar *asar.Entry + notFound http.Handler +} + +// Close closes the underlying file used for the asar archive. +func (a *ASARfs) Close() error { + return a.fin.Close() +} + +// Open satisfies the http.FileSystem interface for ASARfs. +func (a *ASARfs) Open(name string) (http.File, error) { + if name == "/" { + name = "/index.html" + } + + e := a.ar.Find(strings.Split(name, "/")[1:]...) + if e == nil { + return nil, os.ErrNotExist + } + + f := &file{ + Entry: e, + r: e.Open(), + } + + return f, nil +} + +// ServeHTTP satisfies the http.Handler interface for ASARfs. +func (a *ASARfs) ServeHTTP(w http.ResponseWriter, r *http.Request) { + if r.RequestURI == "/" { + r.RequestURI = "/index.html" + } + + f := a.ar.Find(strings.Split(r.RequestURI, "/")[1:]...) + if f == nil { + a.notFound.ServeHTTP(w, r) + return + } + + ext := filepath.Ext(f.Name) + mimeType := mime.TypeByExtension(ext) + + w.Header().Add("Content-Type", mimeType) + f.WriteTo(w) +} + +// New creates a new ASARfs pointer based on the filepath to the archive and +// a HTTP handler to hit when a file is not found. +func New(archivePath string, notFound http.Handler) (*ASARfs, error) { + fin, err := os.Open(archivePath) + if err != nil { + return nil, err + } + + root, err := asar.Decode(fin) + if err != nil { + return nil, err + } + + a := &ASARfs{ + fin: fin, + ar: root, + notFound: notFound, + } + + return a, nil +} + +// file is an internal shim that mimics http.File for an asar entry. +type file struct { + *asar.Entry + r io.ReadSeeker +} + +func (f *file) Close() error { + f.r = nil + return nil +} + +func (f *file) Read(buf []byte) (n int, err error) { + return f.r.Read(buf) +} + +func (f *file) Seek(offset int64, whence int) (int64, error) { + return f.r.Seek(offset, whence) +} + +func (f *file) Readdir(count int) ([]os.FileInfo, error) { + result := []os.FileInfo{} + + for _, e := range f.Entry.Children { + result = append(result, e.FileInfo()) + } + + return result, nil +} + +func (f *file) Stat() (os.FileInfo, error) { + return f.Entry.FileInfo(), nil +} diff --git a/vendor/github.com/Xe/asarfs/bench_test.go b/vendor/github.com/Xe/asarfs/bench_test.go new file mode 100644 index 0000000..fd332d5 --- /dev/null +++ b/vendor/github.com/Xe/asarfs/bench_test.go @@ -0,0 +1,156 @@ +// +build go1.8 + +package asarfs + +import ( + "fmt" + "io" + "io/ioutil" + "math/rand" + "net" + "net/http" + "os" + "testing" +) + +func BenchmarkHTTPFileSystem(b *testing.B) { + fs := http.FileServer(http.Dir(".")) + + l, s, err := setupHandler(fs) + if err != nil { + b.Fatal(err) + } + defer l.Close() + defer s.Close() + + url := fmt.Sprintf("http://%s", l.Addr()) + + for n := 0; n < b.N; n++ { + testHandler(url) + } +} + +func BenchmarkASARfs(b *testing.B) { + fs, err := New("./static.asar", http.HandlerFunc(do404)) + if err != nil { + b.Fatal(err) + } + + l, s, err := setupHandler(fs) + if err != nil { + b.Fatal(err) + } + defer l.Close() + defer s.Close() + + url := fmt.Sprintf("http://%s", l.Addr()) + + for n := 0; n < b.N; n++ { + testHandler(url) + } +} + +func BenchmarkPreloadedASARfs(b *testing.B) { + for n := 0; n < b.N; n++ { + testHandler(asarfsurl) + } +} + +func BenchmarkASARfsHTTPFilesystem(b *testing.B) { + fs, err := New("./static.asar", http.HandlerFunc(do404)) + if err != nil { + b.Fatal(err) + } + + l, s, err := setupHandler(http.FileServer(fs)) + if err != nil { + b.Fatal(err) + } + defer l.Close() + defer s.Close() + + url := fmt.Sprintf("http://%s", l.Addr()) + + for n := 0; n < b.N; n++ { + testHandler(url) + } +} + +func BenchmarkPreloadedASARfsHTTPFilesystem(b *testing.B) { + for n := 0; n < b.N; n++ { + testHandler(asarfshttpfsurl) + } +} + +func do404(w http.ResponseWriter, r *http.Request) { + http.Error(w, "Not found", http.StatusNotFound) +} + +func setupHandler(h http.Handler) (net.Listener, *http.Server, error) { + l, err := net.Listen("tcp", ":0") + if err != nil { + panic(err) + } + defer l.Close() + + s := &http.Server{ + Handler: h, + } + go s.ListenAndServe() + + return l, s, nil +} + +func testHandler(u string) error { + num := rand.Intn(9) + num++ + sub := rand.Intn(99) + + fname := fmt.Sprintf("/static/%d/%d%d.json", num, num, sub) + + resp, err := http.Get(u + fname) + if err != nil { + return err + } + defer resp.Body.Close() + + _, err = io.Copy(ioutil.Discard, resp.Body) + if err != nil { + panic(err) + } + + return nil +} + +var ( + asarfsurl string + asarfshttpfsurl string +) + +func TestMain(m *testing.M) { + go func() { + fs, err := New("./static.asar", http.HandlerFunc(do404)) + if err != nil { + } + + l, _, err := setupHandler(fs) + if err != nil { + } + + asarfsurl = fmt.Sprintf("http://%s", l.Addr().String()) + }() + + go func() { + fs, err := New("./static.asar", http.HandlerFunc(do404)) + if err != nil { + } + + l, _, err := setupHandler(http.FileServer(fs)) + if err != nil { + } + + asarfshttpfsurl = fmt.Sprintf("http://%s", l.Addr().String()) + }() + + os.Exit(m.Run()) +} diff --git a/vendor/github.com/Xe/asarfs/runtest.go b/vendor/github.com/Xe/asarfs/runtest.go new file mode 100644 index 0000000..4b839de --- /dev/null +++ b/vendor/github.com/Xe/asarfs/runtest.go @@ -0,0 +1,24 @@ +// +build ignore + +package main + +import ( + "log" + "net/http" + "os" + + "github.com/Xe/asarfs" +) + +func do404(w http.ResponseWriter, r *http.Request) { + http.Error(w, "Not found", http.StatusNotFound) +} + +func main() { + fs, err := asarfs.New("./static.asar", http.HandlerFunc(do404)) + if err != nil { + log.Fatal(err) + } + + http.ListenAndServe(":"+os.Getenv("PORT"), fs) +} |
