@@ -239,7 +239,7 @@ func (rw *responseWriter) WriteHeader(status int) {
239
239
// Not Modified must have certain headers set as if it was a 200 response, and according to the issue
240
240
// we would miss the Vary header in this case when compression was also enabled; note that we set this
241
241
// header in the responseWriter.init() method but that is only called if we are writing a response body
242
- if status == http .StatusNotModified {
242
+ if status == http .StatusNotModified && ! hasVaryValue ( rw . Header (), "Accept-Encoding" ) {
243
243
rw .Header ().Add ("Vary" , "Accept-Encoding" )
244
244
}
245
245
@@ -349,14 +349,17 @@ func (rw *responseWriter) Unwrap() http.ResponseWriter {
349
349
350
350
// init should be called before we write a response, if rw.buf has contents.
351
351
func (rw * responseWriter ) init () {
352
- if rw .Header ().Get ("Content-Encoding" ) == "" && isEncodeAllowed (rw .Header ()) &&
352
+ hdr := rw .Header ()
353
+ if hdr .Get ("Content-Encoding" ) == "" && isEncodeAllowed (hdr ) &&
353
354
rw .config .Match (rw ) {
354
355
rw .w = rw .config .writerPools [rw .encodingName ].Get ().(Encoder )
355
356
rw .w .Reset (rw .ResponseWriter )
356
- rw .Header ().Del ("Content-Length" ) // https://github.com/golang/go/issues/14975
357
- rw .Header ().Set ("Content-Encoding" , rw .encodingName )
358
- rw .Header ().Add ("Vary" , "Accept-Encoding" )
359
- rw .Header ().Del ("Accept-Ranges" ) // we don't know ranges for dynamically-encoded content
357
+ hdr .Del ("Content-Length" ) // https://github.com/golang/go/issues/14975
358
+ hdr .Set ("Content-Encoding" , rw .encodingName )
359
+ if ! hasVaryValue (hdr , "Accept-Encoding" ) {
360
+ hdr .Add ("Vary" , "Accept-Encoding" )
361
+ }
362
+ hdr .Del ("Accept-Ranges" ) // we don't know ranges for dynamically-encoded content
360
363
361
364
// strong ETags need to be distinct depending on the encoding ("selected representation")
362
365
// see RFC 9110 section 8.8.3.3:
@@ -365,11 +368,23 @@ func (rw *responseWriter) init() {
365
368
// (We have to strip the value we append from If-None-Match headers before
366
369
// sending subsequent requests back upstream, however, since upstream handlers
367
370
// don't know about our appending to their Etag since they've already done their work)
368
- if etag := rw . Header () .Get ("Etag" ); etag != "" && ! strings .HasPrefix (etag , "W/" ) {
371
+ if etag := hdr .Get ("Etag" ); etag != "" && ! strings .HasPrefix (etag , "W/" ) {
369
372
etag = fmt .Sprintf (`%s-%s"` , strings .TrimSuffix (etag , `"` ), rw .encodingName )
370
- rw .Header ().Set ("Etag" , etag )
373
+ hdr .Set ("Etag" , etag )
374
+ }
375
+ }
376
+ }
377
+
378
+ func hasVaryValue (hdr http.Header , target string ) bool {
379
+ for _ , vary := range hdr .Values ("Vary" ) {
380
+ vals := strings .Split (vary , "," )
381
+ for _ , val := range vals {
382
+ if strings .EqualFold (strings .TrimSpace (val ), target ) {
383
+ return true
384
+ }
371
385
}
372
386
}
387
+ return false
373
388
}
374
389
375
390
// AcceptedEncodings returns the list of encodings that the
0 commit comments