From 77882e60869c57c4541557b263f09c3673b01e2a Mon Sep 17 00:00:00 2001 From: Sergey Mishin Date: Sat, 4 Apr 2015 20:06:20 +0300 Subject: [PATCH] Enable gzip encoding static files for webgui --- cmd/genassets/main.go | 31 ++-- cmd/syncthing/gui.go | 14 +- internal/auto/auto_test.go | 7 + internal/auto/gui.files.go | 309 ++++++++----------------------------- test/http_test.go | 24 ++- 5 files changed, 122 insertions(+), 263 deletions(-) diff --git a/cmd/genassets/main.go b/cmd/genassets/main.go index 44adfe6e4..5ac2e21bb 100644 --- a/cmd/genassets/main.go +++ b/cmd/genassets/main.go @@ -15,33 +15,32 @@ import ( "flag" "go/format" "io" + "net/http" "os" "path/filepath" "strings" "text/template" + "time" ) var tpl = template.Must(template.New("assets").Parse(`package auto import ( - "bytes" - "compress/gzip" "encoding/base64" - "io/ioutil" +) + +const ( + AssetsBuildDate = "{{.BuildDate}}" ) func Assets() map[string][]byte { - var assets = make(map[string][]byte, {{.assets | len}}) - var bs []byte - var gr *gzip.Reader -{{range $asset := .assets}} - bs, _ = base64.StdEncoding.DecodeString("{{$asset.Data}}") - gr, _ = gzip.NewReader(bytes.NewReader(bs)) - bs, _ = ioutil.ReadAll(gr) - assets["{{$asset.Name}}"] = bs + var assets = make(map[string][]byte, {{.Assets | len}}) +{{range $asset := .Assets}} + assets["{{$asset.Name}}"], _ = base64.StdEncoding.DecodeString("{{$asset.Data}}") {{end}} return assets } + `)) type asset struct { @@ -86,12 +85,20 @@ func walkerFor(basePath string) filepath.WalkFunc { } } +type templateVars struct { + Assets []asset + BuildDate string +} + func main() { flag.Parse() filepath.Walk(flag.Arg(0), walkerFor(flag.Arg(0))) var buf bytes.Buffer - tpl.Execute(&buf, map[string][]asset{"assets": assets}) + tpl.Execute(&buf, templateVars{ + Assets: assets, + BuildDate: time.Now().UTC().Format(http.TimeFormat), + }) bs, err := format.Source(buf.Bytes()) if err != nil { panic(err) diff --git a/cmd/syncthing/gui.go b/cmd/syncthing/gui.go index de1111532..74817270c 100644 --- a/cmd/syncthing/gui.go +++ b/cmd/syncthing/gui.go @@ -7,6 +7,8 @@ package main import ( + "bytes" + "compress/gzip" "crypto/tls" "encoding/json" "fmt" @@ -45,7 +47,6 @@ var ( configInSync = true guiErrors = []guiError{} guiErrorsMut sync.Mutex - modt = time.Now().UTC().Format(http.TimeFormat) eventSub *events.BufferedSubscription ) @@ -832,8 +833,17 @@ func embeddedStatic(assetDir string) http.Handler { if len(mtype) != 0 { w.Header().Set("Content-Type", mtype) } + if strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") { + w.Header().Set("Content-Encoding", "gzip") + } else { + // ungzip if browser not send gzip accepted header + var gr *gzip.Reader + gr, _ = gzip.NewReader(bytes.NewReader(bs)) + bs, _ = ioutil.ReadAll(gr) + gr.Close() + } w.Header().Set("Content-Length", fmt.Sprintf("%d", len(bs))) - w.Header().Set("Last-Modified", modt) + w.Header().Set("Last-Modified", auto.AssetsBuildDate) w.Write(bs) }) diff --git a/internal/auto/auto_test.go b/internal/auto/auto_test.go index 0f6d120c4..9bd750b26 100644 --- a/internal/auto/auto_test.go +++ b/internal/auto/auto_test.go @@ -8,6 +8,8 @@ package auto_test import ( "bytes" + "compress/gzip" + "io/ioutil" "testing" "github.com/syncthing/syncthing/internal/auto" @@ -19,6 +21,11 @@ func TestAssets(t *testing.T) { if !ok { t.Fatal("No index.html in compiled in assets") } + + var gr *gzip.Reader + gr, _ = gzip.NewReader(bytes.NewReader(idx)) + idx, _ = ioutil.ReadAll(gr) + if !bytes.Contains(idx, []byte("")) { + t.Error("Incorrect response") } if res.Header.Get("Set-Cookie") == "" { t.Error("No set-cookie header") @@ -64,8 +73,15 @@ func TestGetIndex(t *testing.T) { if res.StatusCode != 200 { t.Errorf("Status %d != 200", res.StatusCode) } - if res.ContentLength < 1024 { - t.Errorf("Length %d < 1024", res.ContentLength) + bs, err = ioutil.ReadAll(res.Body) + if err != nil { + t.Fatal(err) + } + if len(bs) < 1024 { + t.Errorf("Length %d < 1024", len(bs)) + } + if !bytes.Contains(bs, []byte("")) { + t.Error("Incorrect response") } if res.Header.Get("Set-Cookie") == "" { t.Error("No set-cookie header")