golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
124.16k stars 17.69k forks source link

net/http: CanonicalHeaderKey capitalization is non-conformant with RFC 6455 #18495

Closed shosti closed 7 years ago

shosti commented 7 years ago

What version of Go are you using (go version)?

go version go1.7.4 linux/amd64

What operating system and processor architecture are you using (go env)?

GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/shosti/go"
GORACE=""
GOROOT="/usr/lib/go"
GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build649225145=/tmp/go-build -gno-record-gcc-switches"
CXX="g++"
CGO_ENABLED="1"

What did you do?

Minimal reproduction: https://play.golang.org/p/jMuUMK5TDL

What did you expect to see?

According to RFC 6455, headers for WebSocket upgrades are capitalized as Sec-WebSocket-* (e.g. Sec-WebSocket-Key). CanonicalHeaderKey should canonicalize those headers to be compliant with the spec.

What did you see instead?

CanonicalizeHeaderKey returns header keys capitalized as Sec-Websocket-* (without the uppercase S in Socket).

While this may not seem like a big deal, I've encountered real-world servers that rely on the correct capitalization (obviously not a good idea). It's especially problematic because all HTTP request parsing canonicalizes the header keys. This has led to some pretty severe issues with a proxy server I had running in production that had to forward WebSocket requests to arbitrary servers.

bradfitz commented 7 years ago

Dup of #18476 #18196 #5022 etc

I don't think we're going to do anything here. RFC 6455 can't mandate the case of headers, since HTTP/1 says that they're case insensitive. And in HTTP/2 there is no case on the wire.

Sorry. I don't want to complicate Go and encourage buggy libraries from assuming case.