diff --git a/web/static.go b/web/static.go index d354962215..a694f747db 100644 --- a/web/static.go +++ b/web/static.go @@ -81,7 +81,11 @@ func staticFilesHandler(handler http.Handler) http.Handler { //wrap our ResponseWriter with our no-cache 404-handler w = ¬FoundNoCacheResponseWriter{ResponseWriter: w} - w.Header().Set("Cache-Control", "max-age=31556926, public") + if path.Base(r.URL.Path) == "remote_entry.js" { + w.Header().Set("Cache-Control", "no-cache, max-age=31556926, public") + } else { + w.Header().Set("Cache-Control", "max-age=31556926, public") + } if strings.HasSuffix(r.URL.Path, "/") { http.NotFound(w, r) diff --git a/web/web_test.go b/web/web_test.go index ae8e322f91..4214649031 100644 --- a/web/web_test.go +++ b/web/web_test.go @@ -8,6 +8,8 @@ import ( "net/http" "net/http/httptest" "os" + "os/exec" + "path" "path/filepath" "testing" "time" @@ -359,6 +361,65 @@ func TestStatic(t *testing.T) { } */ +func TestStaticFilesCaching(t *testing.T) { + th := Setup(t).InitPlugins() + defer th.TearDown() + + wd, _ := os.Getwd() + cmd := exec.Command("ls", path.Join(wd, "client", "plugins")) + cmd.Stdout = os.Stdout + cmd.Run() + + fakeMainBundleName := "main.1234ab.js" + fakeRootHTML := ` + + Mattermost + +` + fakeMainBundle := `module.exports = 'main';` + fakeRemoteEntry := `module.exports = 'remote';` + + err := os.WriteFile("./client/root.html", []byte(fakeRootHTML), 0600) + require.NoError(t, err) + err = os.WriteFile("./client/"+fakeMainBundleName, []byte(fakeMainBundle), 0600) + require.NoError(t, err) + err = os.WriteFile("./client/remote_entry.js", []byte(fakeRemoteEntry), 0600) + require.NoError(t, err) + + err = os.MkdirAll("./client/products/boards", 0777) + require.NoError(t, err) + err = os.WriteFile("./client/products/boards/remote_entry.js", []byte(fakeRemoteEntry), 0600) + require.NoError(t, err) + + req, _ := http.NewRequest("GET", "/", nil) + res := httptest.NewRecorder() + th.Web.MainRouter.ServeHTTP(res, req) + require.Equal(t, http.StatusOK, res.Code) + require.Equal(t, fakeRootHTML, res.Body.String()) + require.Equal(t, []string{"no-cache, max-age=31556926, public"}, res.Result().Header[http.CanonicalHeaderKey("Cache-Control")]) + + req, _ = http.NewRequest("GET", "/static/"+fakeMainBundleName, nil) + res = httptest.NewRecorder() + th.Web.MainRouter.ServeHTTP(res, req) + require.Equal(t, http.StatusOK, res.Code) + require.Equal(t, fakeMainBundle, res.Body.String()) + require.Equal(t, []string{"max-age=31556926, public"}, res.Result().Header[http.CanonicalHeaderKey("Cache-Control")]) + + req, _ = http.NewRequest("GET", "/static/remote_entry.js", nil) + res = httptest.NewRecorder() + th.Web.MainRouter.ServeHTTP(res, req) + require.Equal(t, http.StatusOK, res.Code) + require.Equal(t, fakeRemoteEntry, res.Body.String()) + require.Equal(t, []string{"no-cache, max-age=31556926, public"}, res.Result().Header[http.CanonicalHeaderKey("Cache-Control")]) + + req, _ = http.NewRequest("GET", "/static/products/boards/remote_entry.js", nil) + res = httptest.NewRecorder() + th.Web.MainRouter.ServeHTTP(res, req) + require.Equal(t, http.StatusOK, res.Code) + require.Equal(t, fakeRemoteEntry, res.Body.String()) + require.Equal(t, []string{"no-cache, max-age=31556926, public"}, res.Result().Header[http.CanonicalHeaderKey("Cache-Control")]) +} + func TestCheckClientCompatability(t *testing.T) { //Browser Name, UA String, expected result (if the browser should fail the test false and if it should pass the true) type uaTest struct {