|
@@ -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)
|