Don't set Expires HTTP header

This commit is contained in:
DarthSim
2023-12-04 20:18:01 +03:00
parent 79e6b32c9c
commit 04d65a220b
4 changed files with 42 additions and 32 deletions

View File

@@ -5,6 +5,7 @@
- Allow relative values for `gravity` and `watermark` offsets. - Allow relative values for `gravity` and `watermark` offsets.
- Revised downloading errors reporting. - Revised downloading errors reporting.
- Allow `IMGPROXY_TTL` to be zero. - Allow `IMGPROXY_TTL` to be zero.
- Don't set `Expires` HTTP header as it is ignored if the `Cache-Control` header is set.
## [3.21.0] - 2023-11-23 ## [3.21.0] - 2023-11-23
### Add ### Add

View File

@@ -57,8 +57,6 @@ func initProcessingHandler() {
} }
func setCacheControl(rw http.ResponseWriter, force *time.Time, originHeaders map[string]string) { func setCacheControl(rw http.ResponseWriter, force *time.Time, originHeaders map[string]string) {
var cacheControl, expires string
ttl := -1 ttl := -1
if _, ok := originHeaders["Fallback-Image"]; ok && config.FallbackImageTTL > 0 { if _, ok := originHeaders["Fallback-Image"]; ok && config.FallbackImageTTL > 0 {
@@ -71,30 +69,25 @@ func setCacheControl(rw http.ResponseWriter, force *time.Time, originHeaders map
if config.CacheControlPassthrough && ttl < 0 && originHeaders != nil { if config.CacheControlPassthrough && ttl < 0 && originHeaders != nil {
if val, ok := originHeaders["Cache-Control"]; ok && len(val) > 0 { if val, ok := originHeaders["Cache-Control"]; ok && len(val) > 0 {
cacheControl = val rw.Header().Set("Cache-Control", val)
return
} }
if val, ok := originHeaders["Expires"]; ok && len(val) > 0 { if val, ok := originHeaders["Expires"]; ok && len(val) > 0 {
expires = val if t, err := time.Parse(http.TimeFormat, val); err == nil {
ttl = imath.Max(0, int(time.Until(t).Seconds()))
}
} }
} }
if len(cacheControl) == 0 && len(expires) == 0 { if ttl < 0 {
if ttl < 0 { ttl = config.TTL
ttl = config.TTL
}
if ttl > 0 {
cacheControl = fmt.Sprintf("max-age=%d, public", ttl)
} else {
cacheControl = "no-cache"
}
expires = time.Now().Add(time.Second * time.Duration(ttl)).Format(http.TimeFormat)
} }
if len(cacheControl) > 0 { if ttl > 0 {
rw.Header().Set("Cache-Control", cacheControl) rw.Header().Set("Cache-Control", fmt.Sprintf("max-age=%d, public", ttl))
} } else {
if len(expires) > 0 { rw.Header().Set("Cache-Control", "no-cache")
rw.Header().Set("Expires", expires)
} }
} }

View File

@@ -343,12 +343,12 @@ func (s *ProcessingHandlerTestSuite) TestErrorSavingToSVG() {
require.Equal(s.T(), 422, res.StatusCode) require.Equal(s.T(), 422, res.StatusCode)
} }
func (s *ProcessingHandlerTestSuite) TestCacheControlPassthrough() { func (s *ProcessingHandlerTestSuite) TestCacheControlPassthroughCacheControl() {
config.CacheControlPassthrough = true config.CacheControlPassthrough = true
ts := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { ts := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
rw.Header().Set("Cache-Control", "fake-cache-control") rw.Header().Set("Cache-Control", "max-age=1234, public")
rw.Header().Set("Expires", "fake-expires") rw.Header().Set("Expires", time.Now().Add(time.Hour).UTC().Format(http.TimeFormat))
rw.WriteHeader(200) rw.WriteHeader(200)
rw.Write(s.readTestFile("test1.png")) rw.Write(s.readTestFile("test1.png"))
})) }))
@@ -357,16 +357,34 @@ func (s *ProcessingHandlerTestSuite) TestCacheControlPassthrough() {
rw := s.send("/unsafe/rs:fill:4:4/plain/" + ts.URL) rw := s.send("/unsafe/rs:fill:4:4/plain/" + ts.URL)
res := rw.Result() res := rw.Result()
require.Equal(s.T(), "fake-cache-control", res.Header.Get("Cache-Control")) require.Equal(s.T(), "max-age=1234, public", res.Header.Get("Cache-Control"))
require.Equal(s.T(), "fake-expires", res.Header.Get("Expires")) require.Empty(s.T(), res.Header.Get("Expires"))
}
func (s *ProcessingHandlerTestSuite) TestCacheControlPassthroughExpires() {
config.CacheControlPassthrough = true
ts := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
rw.Header().Set("Expires", time.Now().Add(1239*time.Second).UTC().Format(http.TimeFormat))
rw.WriteHeader(200)
rw.Write(s.readTestFile("test1.png"))
}))
defer ts.Close()
rw := s.send("/unsafe/rs:fill:4:4/plain/" + ts.URL)
res := rw.Result()
// Use regex to allow some delay
require.Regexp(s.T(), regexp.MustCompile("max-age=123[0-9], public"), res.Header.Get("Cache-Control"))
require.Empty(s.T(), res.Header.Get("Expires"))
} }
func (s *ProcessingHandlerTestSuite) TestCacheControlPassthroughDisabled() { func (s *ProcessingHandlerTestSuite) TestCacheControlPassthroughDisabled() {
config.CacheControlPassthrough = false config.CacheControlPassthrough = false
ts := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { ts := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
rw.Header().Set("Cache-Control", "fake-cache-control") rw.Header().Set("Cache-Control", "max-age=1234, public")
rw.Header().Set("Expires", "fake-expires") rw.Header().Set("Expires", time.Now().Add(time.Hour).UTC().Format(http.TimeFormat))
rw.WriteHeader(200) rw.WriteHeader(200)
rw.Write(s.readTestFile("test1.png")) rw.Write(s.readTestFile("test1.png"))
})) }))
@@ -375,8 +393,8 @@ func (s *ProcessingHandlerTestSuite) TestCacheControlPassthroughDisabled() {
rw := s.send("/unsafe/rs:fill:4:4/plain/" + ts.URL) rw := s.send("/unsafe/rs:fill:4:4/plain/" + ts.URL)
res := rw.Result() res := rw.Result()
require.NotEqual(s.T(), "fake-cache-control", res.Header.Get("Cache-Control")) require.NotEqual(s.T(), "max-age=1234, public", res.Header.Get("Cache-Control"))
require.NotEqual(s.T(), "fake-expires", res.Header.Get("Expires")) require.Empty(s.T(), res.Header.Get("Expires"))
} }
func (s *ProcessingHandlerTestSuite) TestETagDisabled() { func (s *ProcessingHandlerTestSuite) TestETagDisabled() {

View File

@@ -30,8 +30,6 @@ var (
} }
streamRespHeaders = []string{ streamRespHeaders = []string{
"Cache-Control",
"Expires",
"ETag", "ETag",
"Content-Type", "Content-Type",
"Content-Encoding", "Content-Encoding",
@@ -117,8 +115,8 @@ func streamOriginImage(ctx context.Context, reqID string, r *http.Request, rw ht
} }
setCacheControl(rw, po.Expires, map[string]string{ setCacheControl(rw, po.Expires, map[string]string{
"Cache-Control": rw.Header().Get("Cache-Control"), "Cache-Control": res.Header.Get("Cache-Control"),
"Expires": rw.Header().Get("Expires"), "Expires": res.Header.Get("Expires"),
}) })
setCanonical(rw, imageURL) setCanonical(rw, imageURL)
rw.Header().Set("Content-Security-Policy", "script-src 'none'") rw.Header().Set("Content-Security-Policy", "script-src 'none'")