diff options
| author | Brad Fitzpatrick <bradfitz@golang.org> | 2017-11-27 22:48:11 +0000 |
|---|---|---|
| committer | Brad Fitzpatrick <bradfitz@golang.org> | 2017-11-27 23:35:10 +0000 |
| commit | 18ae4c834bdb33903dbf6774f57536c73de923bb (patch) | |
| tree | c65f66db2ffd31827cea70b7929c4901c9bfb273 /src/net/http/server.go | |
| parent | 1c69384da4fb4a1323e011941c101189247fea67 (diff) | |
| download | go-18ae4c834bdb33903dbf6774f57536c73de923bb.tar.xz | |
net/http: panic on invalid WriteHeader status code
Panic if an http Handler does:
rw.WriteHeader(0)
... or other invalid values. (for a forgiving range of valid)
I previously made it kinda work in https://golang.org/cl/19130 but
there's no good way to fake it in HTTP/2, and we want HTTP/1 and
HTTP/2 behavior to be the same, regardless of what programs do.
Currently HTTP/2 omitted the :status header altogether, which was a
protocol violation. In fixing that, I found CL 19130 added a test
about bogus WriteHeader values with the comment:
// This might change at some point, but not yet in Go 1.6.
This now changes. Time to be strict.
Updates golang/go#228800
Change-Id: I20eb6c0e514a31f4bba305ac4c24266f39b95fd5
Reviewed-on: https://go-review.googlesource.com/80077
Reviewed-by: Tom Bergan <tombergan@google.com>
Diffstat (limited to 'src/net/http/server.go')
| -rw-r--r-- | src/net/http/server.go | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/src/net/http/server.go b/src/net/http/server.go index 7a4ff88baf..45877096e2 100644 --- a/src/net/http/server.go +++ b/src/net/http/server.go @@ -1046,7 +1046,25 @@ func (w *response) Header() Header { // well read them) const maxPostHandlerReadBytes = 256 << 10 +func checkWriteHeaderCode(code int) { + // Issue 22880: require valid WriteHeader status codes. + // For now we only enforce that it's three digits. + // In the future we might block things over 599 (600 and above aren't defined + // at http://httpwg.org/specs/rfc7231.html#status.codes) + // and we might block under 200 (once we have more mature 1xx support). + // But for now any three digits. + // + // We used to send "HTTP/1.1 000 0" on the wire in responses but there's + // no equivalent bogus thing we can realistically send in HTTP/2, + // so we'll consistently panic instead and help people find their bugs + // early. (We can't return an error from WriteHeader even if we wanted to.) + if code < 100 || code > 999 { + panic(fmt.Sprintf("invalid WriteHeader code %v", code)) + } +} + func (w *response) WriteHeader(code int) { + checkWriteHeaderCode(code) if w.conn.hijacked() { w.conn.server.logf("http: response.WriteHeader on hijacked connection") return @@ -3140,6 +3158,7 @@ func (tw *timeoutWriter) Write(p []byte) (int, error) { } func (tw *timeoutWriter) WriteHeader(code int) { + checkWriteHeaderCode(code) tw.mu.Lock() defer tw.mu.Unlock() if tw.timedOut || tw.wroteHeader { |
