[MM-63578] Fix support packet caching issue (#31133)
Fix support packet caching issue by adding no-cache headers Added Cache-Control headers to prevent browser caching when downloading support packets. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
2fd319b0ac
Коммит
0cf6361139
@@ -133,10 +133,13 @@ func generateSupportPacket(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
fileBytesReader := bytes.NewReader(fileBytes)
|
||||
|
||||
// Send the zip file back to client
|
||||
// We are able to pass 0 for content size due to the fact that Golang's serveContent (https://golang.org/src/net/http/fs.go)
|
||||
// already sets that for us
|
||||
web.WriteFileResponse(outputZipFilename, FileMime, 0, now, *c.App.Config().ServiceSettings.WebserverMode, fileBytesReader, true, w, r)
|
||||
// Prevent caching so support packets are always fresh
|
||||
w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
|
||||
|
||||
err = web.WriteStreamResponse(w, fileBytesReader, outputZipFilename, FileMime, true)
|
||||
if err != nil {
|
||||
c.Logger.Warn("Error while writing response", mlog.Err(err))
|
||||
}
|
||||
}
|
||||
|
||||
// supportPacketFileName returns the ZIP file name in the format mm_support_packet_$CUSTOMER_NAME_YYYY-MM-DDTHH-MM.zip.
|
||||
|
||||
@@ -236,7 +236,7 @@ func TestGenerateSupportPacket(t *testing.T) {
|
||||
th.App.Srv().SetLicense(l)
|
||||
|
||||
th.TestForSystemAdminAndLocal(t, func(t *testing.T, c *model.Client4) {
|
||||
file, filename, _, err := th.SystemAdminClient.GenerateSupportPacket(context.Background())
|
||||
file, filename, resp, err := th.SystemAdminClient.GenerateSupportPacket(context.Background())
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Contains(t, filename, "mm_support_packet_My_awesome_Company_")
|
||||
@@ -244,6 +244,9 @@ func TestGenerateSupportPacket(t *testing.T) {
|
||||
d, err := io.ReadAll(file)
|
||||
require.NoError(t, err)
|
||||
assert.NotZero(t, len(d))
|
||||
|
||||
// Verify that the Cache-Control header is set to prevent caching
|
||||
assert.Equal(t, "no-cache, no-store, must-revalidate", resp.Header.Get("Cache-Control"))
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -54,20 +54,23 @@ func WriteFileResponse(filename string, contentType string, contentSize int64, l
|
||||
http.ServeContent(w, r, filename, lastModification, fileReader)
|
||||
}
|
||||
|
||||
// WriteStreamResponse copies the ReadCloser `r` to the ResponseWriter `w`. Use this when you need to stream a response
|
||||
// WriteStreamResponse copies the Reader `r` to the ResponseWriter `w`. Use this when you need to stream a response
|
||||
// to the client that will appear as a file `filename` of type `contentType`.
|
||||
func WriteStreamResponse(w http.ResponseWriter, r io.ReadCloser, filename string, contentType string, forceDownload bool) error {
|
||||
func WriteStreamResponse(w http.ResponseWriter, r io.Reader, filename string, contentType string, forceDownload bool) error {
|
||||
setHeaders(w, contentType, forceDownload, filename)
|
||||
|
||||
if _, err := io.Copy(w, r); err != nil {
|
||||
return errors.Wrap(err, "error streaming ReadCloser")
|
||||
return errors.Wrap(err, "error streaming Reader")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func setHeaders(w http.ResponseWriter, contentType string, forceDownload bool, filename string) {
|
||||
w.Header().Set("Cache-Control", "private, max-age=86400")
|
||||
// Only set Cache-Control if it hasn't been set already
|
||||
if w.Header().Get("Cache-Control") == "" {
|
||||
w.Header().Set("Cache-Control", "private, max-age=86400")
|
||||
}
|
||||
w.Header().Set("X-Content-Type-Options", "nosniff")
|
||||
|
||||
if contentType == "" {
|
||||
|
||||
Ссылка в новой задаче
Block a user