Description
When setting the Transfer-Encoding
header to chunked
explicitly within a handler for a net/http Server (to trigger chunked encoding), the header field is sent to the client twice.
While this does not break most clients (e.g. Chrome, wget) it is confusing and in discord with RFC 2616:
The "chunked" transfer-coding MUST NOT be applied more than once to a message-body.
The transfer-coding is of course only applied once, just the header is sent twice.
server.go:1148 sets the chunked
flag when a Transfer-Encoding
is manually set and != "identity"
.
But Transfer-Encoding
is not removed from the header map.
As I understand, this is the generally sought after behaviour, (developers should be able to use custom transfer-codings without interference), with the exception of when Transfer-Encoding
is set to chunked
.
Later on the Transfer-Encoding
header is sent when writing the header map and then again by server.go:1176.
If Transfer-Encoding
is simply not meant to be set to chunked
to signal the server to chunk the response this should perhaps be pointed out in the documentation.
It does however provide a nice way to enable sending chunked content without use of the Flusher interface (and is very readable), even though so far it is essentially a side effect. Just dropping the explicit header in this case should be fine as HTTP does not allow multiple chunked
codings.
- What version of Go are you using (
go version
)?
go version go1.6.2 linux/amd64 - What operating system and processor architecture are you using (
go env
)?
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH=""
GORACE=""
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GO15VENDOREXPERIMENT="1"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0"
CXX="g++"
CGO_ENABLED="1" - What did you do?
package main
import (
"net/http"
)
func myHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Transfer-Encoding", "chunked")
w.Write([]byte("Some content..."))
}
func main() {
http.ListenAndServe(":8080", http.HandlerFunc(myHandler))
}