@marcel91200 / caddy Mirror · read-only / commits / dac7cacd
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 13, 08:00 UTC

encode: Respect Cache-Control no-transform (#5257)

* encode: respect Cache-Control HTTP header no-transform * encode: switch to strings.Contains

darkweak committed Dec 20, 2022 at 21:26 UTC dac7cacd4df35e96a4d8c7d09b925bb432509884
2 files changed +60 -7
modules/caddyhttp/encode/encode.go
+13 -7
@@ -117,14 +117,20 @@ func (enc *Encode) Validate() error {
117 return nil
118 }
119
120 +func isEncodeAllowed(h http.Header) bool {
121 + return !strings.Contains(h.Get("Cache-Control"), "no-transform")
122 +}
123 +
124 func (enc *Encode) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error {
121 - for _, encName := range AcceptedEncodings(r, enc.Prefer) {
122 - if _, ok := enc.writerPools[encName]; !ok {
123 - continue // encoding not offered
125 + if isEncodeAllowed(r.Header) {
126 + for _, encName := range AcceptedEncodings(r, enc.Prefer) {
127 + if _, ok := enc.writerPools[encName]; !ok {
128 + continue // encoding not offered
129 + }
130 + w = enc.openResponseWriter(encName, w)
131 + defer w.(*responseWriter).Close()
132 + break
133 }
125 - w = enc.openResponseWriter(encName, w)
126 - defer w.(*responseWriter).Close()
127 - break
134 }
135 return next.ServeHTTP(w, r)
136 }
@@ -281,7 +287,7 @@ func (rw *responseWriter) Close() error {
287
288 // init should be called before we write a response, if rw.buf has contents.
289 func (rw *responseWriter) init() {
284 - if rw.Header().Get("Content-Encoding") == "" &&
290 + if rw.Header().Get("Content-Encoding") == "" && isEncodeAllowed(rw.Header()) &&
291 rw.config.Match(rw) {
292
293 rw.w = rw.config.writerPools[rw.encodingName].Get().(Encoder)
modules/caddyhttp/encode/encode_test.go
+47
@@ -261,3 +261,50 @@ func TestValidate(t *testing.T) {
261
262 }
263 }
264 +
265 +func TestIsEncodeAllowed(t *testing.T) {
266 + testCases := []struct {
267 + name string
268 + headers http.Header
269 + expected bool
270 + }{
271 + {
272 + name: "Without any headers",
273 + headers: http.Header{},
274 + expected: true,
275 + },
276 + {
277 + name: "Without Cache-Control HTTP header",
278 + headers: http.Header{
279 + "Accept-Encoding": {"gzip"},
280 + },
281 + expected: true,
282 + },
283 + {
284 + name: "Cache-Control HTTP header ending with no-transform directive",
285 + headers: http.Header{
286 + "Accept-Encoding": {"gzip"},
287 + "Cache-Control": {"no-cache; no-transform"},
288 + },
289 + expected: false,
290 + },
291 + {
292 + name: "With Cache-Control HTTP header no-transform as Cache-Extension value",
293 + headers: http.Header{
294 + "Accept-Encoding": {"gzip"},
295 + "Cache-Control": {`no-store; no-cache; community="no-transform"`},
296 + },
297 + expected: false,
298 + },
299 + }
300 +
301 + for _, test := range testCases {
302 + t.Run(test.name, func(t *testing.T) {
303 + if result := isEncodeAllowed(test.headers); result != test.expected {
304 + t.Errorf("The headers given to the isEncodeAllowed should return %t, %t given.",
305 + result,
306 + test.expected)
307 + }
308 + })
309 + }
310 +}