Repository: caddyserver/caddy
File: modules/caddyhttp/encode/encode.go (Go)

Code before:
		rw.w.Reset(rw.ResponseWriter)
		hdr.Del("Content-Length") // https://github.com/golang/go/issues/14975
		hdr.Set("Content-Encoding", rw.encodingName)
		if !hasVaryValue(hdr, "Accept-Encoding") {
			hdr.Add("Vary", "Accept-Encoding")
		}
		hdr.Del("Accept-Ranges") // we don't know ranges for dynamically-encoded content

		// strong ETags need to be distinct depending on the encoding ("selected representation")
		// see RFC 9110 section 8.8.3.3:
		// https://www.rfc-editor.org/rfc/rfc9110.html#name-example-entity-tags-varying
		// I don't know a great way to do this... how about appending? That's a neat trick!
		// (We have to strip the value we append from If-None-Match headers before
		// sending subsequent requests back upstream, however, since upstream handlers
		// don't know about our appending to their Etag since they've already done their work)
		if etag := hdr.Get("Etag"); etag != "" && !strings.HasPrefix(etag, "W/") {
			etag = fmt.Sprintf(`%s-%s"`, strings.TrimSuffix(etag, `"`), rw.encodingName)
			hdr.Set("Etag", etag)
		}
	}
}

func hasVaryValue(hdr http.Header, target string) bool {
	for _, vary := range hdr.Values("Vary") {
		vals := strings.SplitSeq(vary, ",")
		for val := range vals {
			if strings.EqualFold(strings.TrimSpace(val), target) {
				return true
			}
		}
	}
	return false
}

// AcceptedEncodings returns the list of encodings that the
// client supports, in descending order of preference.
// The client preference via q-factor and the server
// preference via Prefer setting are taken into account. If
// the Sec-WebSocket-Key header is present then non-identity
// encodings are not considered. See
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html.
func AcceptedEncodings(r *http.Request, preferredOrder []string) []string {
	acceptEncHeader := r.Header.Get("Accept-Encoding")
	websocketKey := r.Header.Get("Sec-WebSocket-Key")
	if acceptEncHeader == "" {
		return []string{}
	}

	prefs := []encodingPreference{}

	for accepted := range strings.SplitSeq(acceptEncHeader, ",") {

Review comment (suggestion):
```suggestion
		for val := range strings.SplitSeq(vary, ",") {
```

Code after:
		rw.w.Reset(rw.ResponseWriter)
		hdr.Del("Content-Length") // https://github.com/golang/go/issues/14975
		hdr.Set("Content-Encoding", rw.encodingName)
		if !hasVaryValue(hdr, "Accept-Encoding") {
			hdr.Add("Vary", "Accept-Encoding")
		}
		hdr.Del("Accept-Ranges") // we don't know ranges for dynamically-encoded content

		// strong ETags need to be distinct depending on the encoding ("selected representation")
		// see RFC 9110 section 8.8.3.3:
		// https://www.rfc-editor.org/rfc/rfc9110.html#name-example-entity-tags-varying
		// I don't know a great way to do this... how about appending? That's a neat trick!
		// (We have to strip the value we append from If-None-Match headers before
		// sending subsequent requests back upstream, however, since upstream handlers
		// don't know about our appending to their Etag since they've already done their work)
		if etag := hdr.Get("Etag"); etag != "" && !strings.HasPrefix(etag, "W/") {
			etag = fmt.Sprintf(`%s-%s"`, strings.TrimSuffix(etag, `"`), rw.encodingName)
			hdr.Set("Etag", etag)
		}
	}
}

func hasVaryValue(hdr http.Header, target string) bool {
	for _, vary := range hdr.Values("Vary") {
		for val := range strings.SplitSeq(vary, ",") {
			if strings.EqualFold(strings.TrimSpace(val), target) {
				return true
			}
		}
	}
	return false
}

// AcceptedEncodings returns the list of encodings that the
// client supports, in descending order of preference.
// The client preference via q-factor and the server
// preference via Prefer setting are taken into account. If
// the Sec-WebSocket-Key header is present then non-identity
// encodings are not considered. See
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html.
func AcceptedEncodings(r *http.Request, preferredOrder []string) []string {
	acceptEncHeader := r.Header.Get("Accept-Encoding")
	websocketKey := r.Header.Get("Sec-WebSocket-Key")
	if acceptEncHeader == "" {
		return []string{}
	}

	prefs := []encodingPreference{}

	for accepted := range strings.SplitSeq(acceptEncHeader, ",") {
		parts := strings.Split(accepted, ";")