Sfoglia il codice sorgente

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.
greatroar 5 anni fa
parent
commit
e2febf246e

+ 4 - 8
cmd/strelaypoolsrv/main.go

@@ -1,11 +1,8 @@
 // Copyright (C) 2015 Audrius Butkevicius and Contributors (see the CONTRIBUTORS file).
 // Copyright (C) 2015 Audrius Butkevicius and Contributors (see the CONTRIBUTORS file).
 
 
-//go:generate go run ../../script/genassets.go gui >auto/gui.go
-
 package main
 package main
 
 
 import (
 import (
-	"bytes"
 	"compress/gzip"
 	"compress/gzip"
 	"context"
 	"context"
 	"crypto/tls"
 	"crypto/tls"
@@ -302,16 +299,15 @@ func handleAssets(w http.ResponseWriter, r *http.Request) {
 	}
 	}
 	if strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
 	if strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
 		w.Header().Set("Content-Encoding", "gzip")
 		w.Header().Set("Content-Encoding", "gzip")
+		w.Header().Set("Content-Length", strconv.Itoa(len(bs)))
+		io.WriteString(w, bs)
 	} else {
 	} else {
 		// ungzip if browser not send gzip accepted header
 		// ungzip if browser not send gzip accepted header
 		var gr *gzip.Reader
 		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()
 		gr.Close()
 	}
 	}
-	w.Header().Set("Content-Length", fmt.Sprintf("%d", len(bs)))
-
-	w.Write(bs)
 }
 }
 
 
 func mimeTypeForFile(file string) string {
 func mimeTypeForFile(file string) string {

+ 7 - 8
lib/api/api_statics.go

@@ -7,14 +7,14 @@
 package api
 package api
 
 
 import (
 import (
-	"bytes"
 	"compress/gzip"
 	"compress/gzip"
 	"fmt"
 	"fmt"
-	"io/ioutil"
+	"io"
 	"mime"
 	"mime"
 	"net/http"
 	"net/http"
 	"os"
 	"os"
 	"path/filepath"
 	"path/filepath"
+	"strconv"
 	"strings"
 	"strings"
 	"time"
 	"time"
 
 
@@ -27,7 +27,7 @@ const themePrefix = "theme-assets/"
 
 
 type staticsServer struct {
 type staticsServer struct {
 	assetDir        string
 	assetDir        string
-	assets          map[string][]byte
+	assets          map[string]string
 	availableThemes []string
 	availableThemes []string
 
 
 	mut             sync.RWMutex
 	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") {
 	if strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
 		w.Header().Set("Content-Encoding", "gzip")
 		w.Header().Set("Content-Encoding", "gzip")
+		w.Header().Set("Content-Length", strconv.Itoa(len(bs)))
+		io.WriteString(w, bs)
 	} else {
 	} else {
 		// ungzip if browser not send gzip accepted header
 		// ungzip if browser not send gzip accepted header
 		var gr *gzip.Reader
 		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()
 		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) {
 func (s *staticsServer) serveThemes(w http.ResponseWriter, r *http.Request) {

+ 3 - 3
lib/api/api_test.go

@@ -152,19 +152,19 @@ func TestAssetsDir(t *testing.T) {
 	gw := gzip.NewWriter(buf)
 	gw := gzip.NewWriter(buf)
 	gw.Write([]byte("default"))
 	gw.Write([]byte("default"))
 	gw.Close()
 	gw.Close()
-	def := buf.Bytes()
+	def := buf.String()
 
 
 	buf = new(bytes.Buffer)
 	buf = new(bytes.Buffer)
 	gw = gzip.NewWriter(buf)
 	gw = gzip.NewWriter(buf)
 	gw.Write([]byte("foo"))
 	gw.Write([]byte("foo"))
 	gw.Close()
 	gw.Close()
-	foo := buf.Bytes()
+	foo := buf.String()
 
 
 	e := &staticsServer{
 	e := &staticsServer{
 		theme:    "foo",
 		theme:    "foo",
 		mut:      sync.NewRWMutex(),
 		mut:      sync.NewRWMutex(),
 		assetDir: "testdata",
 		assetDir: "testdata",
-		assets: map[string][]byte{
+		assets: map[string]string{
 			"foo/a":     foo, // overridden in foo/a
 			"foo/a":     foo, // overridden in foo/a
 			"foo/b":     foo,
 			"foo/b":     foo,
 			"default/a": def, // overridden in default/a (but foo/a takes precedence)
 			"default/a": def, // overridden in default/a (but foo/a takes precedence)

+ 4 - 3
lib/auto/auto_test.go

@@ -10,6 +10,7 @@ import (
 	"bytes"
 	"bytes"
 	"compress/gzip"
 	"compress/gzip"
 	"io/ioutil"
 	"io/ioutil"
+	"strings"
 	"testing"
 	"testing"
 
 
 	"github.com/syncthing/syncthing/lib/auto"
 	"github.com/syncthing/syncthing/lib/auto"
@@ -23,10 +24,10 @@ func TestAssets(t *testing.T) {
 	}
 	}
 
 
 	var gr *gzip.Reader
 	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("<html")) {
+	if !bytes.Contains(html, []byte("<html")) {
 		t.Fatal("No html in index.html")
 		t.Fatal("No html in index.html")
 	}
 	}
 }
 }

+ 3 - 3
script/genassets.go

@@ -29,8 +29,8 @@ package auto
 
 
 const Generated int64 = {{.Generated}}
 const Generated int64 = {{.Generated}}
 
 
-func Assets() map[string][]byte {
-	var assets = make(map[string][]byte, {{.Assets | len}})
+func Assets() map[string]string {
+	var assets = make(map[string]string, {{.Assets | len}})
 {{range $asset := .Assets}}
 {{range $asset := .Assets}}
 	assets["{{$asset.Name}}"] = {{$asset.Data}}{{end}}
 	assets["{{$asset.Name}}"] = {{$asset.Data}}{{end}}
 	return assets
 	return assets
@@ -72,7 +72,7 @@ func walkerFor(basePath string) filepath.WalkFunc {
 			name, _ = filepath.Rel(basePath, name)
 			name, _ = filepath.Rel(basePath, name)
 			assets = append(assets, asset{
 			assets = append(assets, asset{
 				Name: filepath.ToSlash(name),
 				Name: filepath.ToSlash(name),
-				Data: fmt.Sprintf("[]byte(%q)", buf.String()),
+				Data: fmt.Sprintf("%q", buf.String()),
 			})
 			})
 		}
 		}