From e2febf246ea42c8f4639151e34ebdbceacf7aa59 Mon Sep 17 00:00:00 2001 From: greatroar <61184462+greatroar@users.noreply.github.com> Date: Thu, 7 May 2020 11:47:23 +0200 Subject: [PATCH] all: Store assets as strings (#6611) Storing assets as []byte requires every compiled-in asset to be copied into writable memory at program startup. That currently takes up 1.6MB per syncthing process. Strings stay in the RODATA section and should be shared between processes running the same binary. --- cmd/strelaypoolsrv/main.go | 12 ++++-------- lib/api/api_statics.go | 15 +++++++-------- lib/api/api_test.go | 6 +++--- lib/auto/auto_test.go | 7 ++++--- script/genassets.go | 6 +++--- 5 files changed, 21 insertions(+), 25 deletions(-) diff --git a/cmd/strelaypoolsrv/main.go b/cmd/strelaypoolsrv/main.go index 0c5bd4f00..c5dbb158f 100644 --- a/cmd/strelaypoolsrv/main.go +++ b/cmd/strelaypoolsrv/main.go @@ -1,11 +1,8 @@ // Copyright (C) 2015 Audrius Butkevicius and Contributors (see the CONTRIBUTORS file). -//go:generate go run ../../script/genassets.go gui >auto/gui.go - package main import ( - "bytes" "compress/gzip" "context" "crypto/tls" @@ -302,16 +299,15 @@ func handleAssets(w http.ResponseWriter, r *http.Request) { } if strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") { w.Header().Set("Content-Encoding", "gzip") + w.Header().Set("Content-Length", strconv.Itoa(len(bs))) + io.WriteString(w, bs) } else { // ungzip if browser not send gzip accepted header var gr *gzip.Reader - gr, _ = gzip.NewReader(bytes.NewReader(bs)) - bs, _ = ioutil.ReadAll(gr) + gr, _ = gzip.NewReader(strings.NewReader(bs)) + io.Copy(w, gr) gr.Close() } - w.Header().Set("Content-Length", fmt.Sprintf("%d", len(bs))) - - w.Write(bs) } func mimeTypeForFile(file string) string { diff --git a/lib/api/api_statics.go b/lib/api/api_statics.go index 719f211c4..18a51c062 100644 --- a/lib/api/api_statics.go +++ b/lib/api/api_statics.go @@ -7,14 +7,14 @@ package api import ( - "bytes" "compress/gzip" "fmt" - "io/ioutil" + "io" "mime" "net/http" "os" "path/filepath" + "strconv" "strings" "time" @@ -27,7 +27,7 @@ const themePrefix = "theme-assets/" type staticsServer struct { assetDir string - assets map[string][]byte + assets map[string]string availableThemes []string mut sync.RWMutex @@ -168,16 +168,15 @@ func (s *staticsServer) serveAsset(w http.ResponseWriter, r *http.Request) { } if strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") { w.Header().Set("Content-Encoding", "gzip") + w.Header().Set("Content-Length", strconv.Itoa(len(bs))) + io.WriteString(w, bs) } else { // ungzip if browser not send gzip accepted header var gr *gzip.Reader - gr, _ = gzip.NewReader(bytes.NewReader(bs)) - bs, _ = ioutil.ReadAll(gr) + gr, _ = gzip.NewReader(strings.NewReader(bs)) + io.Copy(w, gr) gr.Close() } - w.Header().Set("Content-Length", fmt.Sprintf("%d", len(bs))) - - w.Write(bs) } func (s *staticsServer) serveThemes(w http.ResponseWriter, r *http.Request) { diff --git a/lib/api/api_test.go b/lib/api/api_test.go index c315c28df..4cc981bc3 100644 --- a/lib/api/api_test.go +++ b/lib/api/api_test.go @@ -152,19 +152,19 @@ func TestAssetsDir(t *testing.T) { gw := gzip.NewWriter(buf) gw.Write([]byte("default")) gw.Close() - def := buf.Bytes() + def := buf.String() buf = new(bytes.Buffer) gw = gzip.NewWriter(buf) gw.Write([]byte("foo")) gw.Close() - foo := buf.Bytes() + foo := buf.String() e := &staticsServer{ theme: "foo", mut: sync.NewRWMutex(), assetDir: "testdata", - assets: map[string][]byte{ + assets: map[string]string{ "foo/a": foo, // overridden in foo/a "foo/b": foo, "default/a": def, // overridden in default/a (but foo/a takes precedence) diff --git a/lib/auto/auto_test.go b/lib/auto/auto_test.go index 4e065cdff..a33e3c7d3 100644 --- a/lib/auto/auto_test.go +++ b/lib/auto/auto_test.go @@ -10,6 +10,7 @@ import ( "bytes" "compress/gzip" "io/ioutil" + "strings" "testing" "github.com/syncthing/syncthing/lib/auto" @@ -23,10 +24,10 @@ func TestAssets(t *testing.T) { } var gr *gzip.Reader - gr, _ = gzip.NewReader(bytes.NewReader(idx)) - idx, _ = ioutil.ReadAll(gr) + gr, _ = gzip.NewReader(strings.NewReader(idx)) + html, _ := ioutil.ReadAll(gr) - if !bytes.Contains(idx, []byte("