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

Code before:
			rw.ResponseWriter.WriteHeader(rw.statusCode)
		}
		rw.wroteHeader = true
	}

	var err error
	if rw.w != nil {
		err = rw.w.Close()
		rw.w.Reset(nil)
		rw.config.writerPools[rw.encodingName].Put(rw.w)
		rw.w = nil
	}
	return err
}

// Unwrap returns the underlying ResponseWriter.
func (rw *responseWriter) Unwrap() http.ResponseWriter {
	return rw.ResponseWriter
}

// init should be called before we write a response, if rw.buf has contents.
func (rw *responseWriter) init() {
	hdr := rw.Header()

	// Don't initialize encoder for error responses
	// This prevents response corruption when handle_errors is used
	if rw.disabled {
		return
	}

	if hdr.Get("Content-Encoding") == "" && isEncodeAllowed(hdr) &&
		rw.config.Match(rw) {
		rw.w = rw.config.writerPools[rw.encodingName].Get().(Encoder)
		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)

Review comment (suggestion):
I think this should be moved above `hdr :=`, I don't see a reason it needs to be after it.

Code after:
		}
		rw.wroteHeader = true
	}

	var err error
	if rw.w != nil {
		err = rw.w.Close()
		rw.w.Reset(nil)
		rw.config.writerPools[rw.encodingName].Put(rw.w)
		rw.w = nil
	}
	return err
}

// Unwrap returns the underlying ResponseWriter.
func (rw *responseWriter) Unwrap() http.ResponseWriter {
	return rw.ResponseWriter
}

// init should be called before we write a response, if rw.buf has contents.
func (rw *responseWriter) init() {
	// Don't initialize encoder for error responses
	// This prevents response corruption when handle_errors is used
	if rw.disabled {
		return
	}

	hdr := rw.Header()

	if hdr.Get("Content-Encoding") == "" && isEncodeAllowed(hdr) &&
		rw.config.Match(rw) {
		rw.w = rw.config.writerPools[rw.encodingName].Get().(Encoder)
		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)
		}