mirror of
https://github.com/octoleo/syncthing.git
synced 2025-01-02 22:50:18 +00:00
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.
This commit is contained in:
parent
2cdeb1bf70
commit
e2febf246e
@ -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))
|
gr, _ = gzip.NewReader(strings.NewReader(bs))
|
||||||
bs, _ = ioutil.ReadAll(gr)
|
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,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))
|
gr, _ = gzip.NewReader(strings.NewReader(bs))
|
||||||
bs, _ = ioutil.ReadAll(gr)
|
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) {
|
||||||
|
@ -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)
|
||||||
|
@ -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))
|
gr, _ = gzip.NewReader(strings.NewReader(idx))
|
||||||
idx, _ = ioutil.ReadAll(gr)
|
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")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,8 +29,8 @@ package auto
|
|||||||
|
|
||||||
const Generated int64 = {{.Generated}}
|
const Generated int64 = {{.Generated}}
|
||||||
|
|
||||||
func Assets() map[string][]byte {
|
func Assets() map[string]string {
|
||||||
var assets = make(map[string][]byte, {{.Assets | len}})
|
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()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user