aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/Xe
diff options
context:
space:
mode:
authorChristine Dodrill <me@christine.website>2017-01-10 12:38:33 -0800
committerChristine Dodrill <me@christine.website>2017-01-10 12:38:33 -0800
commit6e292d4d1d65d83cc089e74063cb70ea63bbd795 (patch)
tree2409c6b3f26a4e70499cbbc19f327e01b4a85ca1 /vendor/github.com/Xe
parentee89843f5bf60a1e8a3a6bf604ac3f67d25ff72a (diff)
downloadxesite-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.go117
-rw-r--r--vendor/github.com/Xe/asarfs/bench_test.go156
-rw-r--r--vendor/github.com/Xe/asarfs/runtest.go24
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)
+}