Skip to content

net/http: Server removes all explicitly set Transfer-Encoding headers #16063

Closed
@seoester

Description

@seoester

The net/http server removes all explicitly set Transfer-Encoding headers (when operating in HTTP/1.1 mode).

This bug was introduced by the fix of #15960 (f9b4556), sorry for any ambiguous wording on my end.

Example:

package main

import (
    "compress/gzip"
    "net/http"
    "strings"
)

const Level int = -1

func myHandler(w http.ResponseWriter, r *http.Request) {
    if strings.Contains(r.Header.Get("TE"), "gzip") {
        writer, err := gzip.NewWriterLevel(w, Level)
        if err != nil {
            panic(err)
        }
        w.Header().Set("Transfer-Encoding", "gzip")
        writer.Write([]byte("Some content..."))
    } else {
        w.Write([]byte("Couldn't gzip (not accepted)"))
    }
}

func main() {
    http.ListenAndServe(":8080", http.HandlerFunc(myHandler))
}

For clients accepting a gzip transfer-coding, net/http removes the explicitly set gzip from the Transfer-Encoding header and only sends chunked.

To fix both issues there must be a check for the header field's value (== "chunked").
E.g. (the line introduced by #15960 also has to be removed):

        ...
        if hasTE && te == "identity" {
            cw.chunking = false
            w.closeAfterReply = true
        } else if hasTE && te == "chunked" {
            cw.chunking = true
            setHeader.transferEncoding = "chunked"
            delHeader("Transfer-Encoding")
        } else {
            // HTTP/1.1 or greater: use chunked transfer encoding
            ...

To reiterate:

  • An explicitly set transfer-coding of chunked should not result in a duplicate Transfer-Encoding: chunked header
  • Whenever another transfer-coding is set, chunked must be applied also, but the explicitly set transfer-encoding should be kept in the header

Details can be found in RFC 2616 Section 3.6.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions