1
0
Эх сурвалжийг харах

gui: Enable proper asset caching (#4931)

Audrius Butkevicius 7 жил өмнө
parent
commit
e125f8b05b

+ 19 - 0
cmd/strelaypoolsrv/main.go

@@ -251,6 +251,8 @@ func handleMetrics(w http.ResponseWriter, r *http.Request) {
 }
 
 func handleAssets(w http.ResponseWriter, r *http.Request) {
+	w.Header().Set("Cache-Control", "no-cache, must-revalidate")
+
 	assets := auto.Assets()
 	path := r.URL.Path[1:]
 	if path == "" {
@@ -263,11 +265,28 @@ func handleAssets(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
+	etag := fmt.Sprintf("%d", auto.Generated)
+	modified := time.Unix(auto.Generated, 0).UTC()
+
+	w.Header().Set("Last-Modified", modified.Format(http.TimeFormat))
+	w.Header().Set("Etag", etag)
+
 	mtype := mimeTypeForFile(path)
 	if len(mtype) != 0 {
 		w.Header().Set("Content-Type", mtype)
 	}
 
+	if t, err := time.Parse(http.TimeFormat, r.Header.Get("If-Modified-Since")); err == nil && modified.Add(time.Second).After(t) {
+		w.WriteHeader(http.StatusNotModified)
+		return
+	}
+
+	if match := r.Header.Get("If-None-Match"); match != "" {
+		if strings.Contains(match, etag) {
+			w.WriteHeader(http.StatusNotModified)
+			return
+		}
+	}
 	if strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
 		w.Header().Set("Content-Encoding", "gzip")
 	} else {

+ 21 - 0
cmd/syncthing/gui_statics.go

@@ -16,6 +16,7 @@ import (
 	"os"
 	"path/filepath"
 	"strings"
+	"time"
 
 	"github.com/syncthing/syncthing/lib/auto"
 	"github.com/syncthing/syncthing/lib/config"
@@ -71,6 +72,8 @@ func (s *staticsServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 }
 
 func (s *staticsServer) serveAsset(w http.ResponseWriter, r *http.Request) {
+	w.Header().Set("Cache-Control", "no-cache, must-revalidate")
+
 	file := r.URL.Path
 
 	if file[0] == '/' {
@@ -122,6 +125,24 @@ func (s *staticsServer) serveAsset(w http.ResponseWriter, r *http.Request) {
 		}
 	}
 
+	etag := fmt.Sprintf("%d", auto.Generated)
+	modified := time.Unix(auto.Generated, 0).UTC()
+
+	w.Header().Set("Last-Modified", modified.Format(http.TimeFormat))
+	w.Header().Set("Etag", etag)
+
+	if t, err := time.Parse(http.TimeFormat, r.Header.Get("If-Modified-Since")); err == nil && modified.Add(time.Second).After(t) {
+		w.WriteHeader(http.StatusNotModified)
+		return
+	}
+
+	if match := r.Header.Get("If-None-Match"); match != "" {
+		if strings.Contains(match, etag) {
+			w.WriteHeader(http.StatusNotModified)
+			return
+		}
+	}
+
 	mtype := s.mimeTypeForFile(file)
 	if len(mtype) != 0 {
 		w.Header().Set("Content-Type", mtype)

+ 7 - 2
script/genassets.go

@@ -19,10 +19,13 @@ import (
 	"path/filepath"
 	"strings"
 	"text/template"
+	"time"
 )
 
 var tpl = template.Must(template.New("assets").Parse(`package auto
 
+const Generated int64 = {{.Generated}}
+
 func Assets() map[string][]byte {
 	var assets = make(map[string][]byte, {{.Assets | len}})
 {{range $asset := .Assets}}
@@ -75,7 +78,8 @@ func walkerFor(basePath string) filepath.WalkFunc {
 }
 
 type templateVars struct {
-	Assets []asset
+	Assets    []asset
+	Generated int64
 }
 
 func main() {
@@ -84,7 +88,8 @@ func main() {
 	filepath.Walk(flag.Arg(0), walkerFor(flag.Arg(0)))
 	var buf bytes.Buffer
 	tpl.Execute(&buf, templateVars{
-		Assets: assets,
+		Assets:    assets,
+		Generated: time.Now().Unix(),
 	})
 	bs, err := format.Source(buf.Bytes())
 	if err != nil {