diff options
author | Damien Neil <dneil@google.com> | 2020-10-13 13:02:45 -0700 |
---|---|---|
committer | Damien Neil <dneil@google.com> | 2020-10-14 18:05:16 +0000 |
commit | 9c56300e62d126875dcd6508c0ca7dce3985ad50 (patch) | |
tree | 6ce4e02ec69f50ee0f60c2ccaf69d9f46d951291 | |
parent | b95f0b123160a67c9e0b1d8c03993fe1e8208800 (diff) | |
download | go-git-9c56300e62d126875dcd6508c0ca7dce3985ad50.tar.gz |
net/http: return 505 status for rejected protocol version
When rejecting a request with an unsupported HTTP protocol version,
return a 505 error ("HTTP Version Not Supported") instead of 400.
Fixes #40454.
Change-Id: I0269f0f5755d90d1b772ba0094a6bb24b5eb4701
Reviewed-on: https://go-review.googlesource.com/c/go/+/261977
Trust: Damien Neil <dneil@google.com>
Run-TryBot: Damien Neil <dneil@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Urban Ishimwe <urbainishimwe@gmail.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
-rw-r--r-- | src/net/http/serve_test.go | 8 | ||||
-rw-r--r-- | src/net/http/server.go | 21 |
2 files changed, 18 insertions, 11 deletions
diff --git a/src/net/http/serve_test.go b/src/net/http/serve_test.go index 6d3317fb0c..cbd3101f27 100644 --- a/src/net/http/serve_test.go +++ b/src/net/http/serve_test.go @@ -4622,7 +4622,7 @@ func TestServerValidatesHostHeader(t *testing.T) { host string want int }{ - {"HTTP/0.9", "", 400}, + {"HTTP/0.9", "", 505}, {"HTTP/1.1", "", 400}, {"HTTP/1.1", "Host: \r\n", 200}, @@ -4654,9 +4654,9 @@ func TestServerValidatesHostHeader(t *testing.T) { {"CONNECT golang.org:443 HTTP/1.1", "", 200}, // But not other HTTP/2 stuff: - {"PRI / HTTP/2.0", "", 400}, - {"GET / HTTP/2.0", "", 400}, - {"GET / HTTP/3.0", "", 400}, + {"PRI / HTTP/2.0", "", 505}, + {"GET / HTTP/2.0", "", 505}, + {"GET / HTTP/3.0", "", 505}, } for _, tt := range tests { conn := &testConn{closec: make(chan bool, 1)} diff --git a/src/net/http/server.go b/src/net/http/server.go index 25fab288f2..db3a09b993 100644 --- a/src/net/http/server.go +++ b/src/net/http/server.go @@ -992,7 +992,7 @@ func (c *conn) readRequest(ctx context.Context) (w *response, err error) { } if !http1ServerSupportsRequest(req) { - return nil, badRequestError("unsupported protocol version") + return nil, statusError{StatusHTTPVersionNotSupported, "unsupported protocol version"} } c.lastMethod = req.Method @@ -1773,9 +1773,16 @@ func (c *conn) getState() (state ConnState, unixSec int64) { // badRequestError is a literal string (used by in the server in HTML, // unescaped) to tell the user why their request was bad. It should // be plain text without user info or other embedded errors. -type badRequestError string +func badRequestError(e string) error { return statusError{StatusBadRequest, e} } -func (e badRequestError) Error() string { return "Bad Request: " + string(e) } +// statusError is an error used to respond to a request with an HTTP status. +// The text should be plain text without user info or other embedded errors. +type statusError struct { + code int + text string +} + +func (e statusError) Error() string { return StatusText(e.code) + ": " + e.text } // ErrAbortHandler is a sentinel panic value to abort a handler. // While any panic from ServeHTTP aborts the response to the client, @@ -1898,11 +1905,11 @@ func (c *conn) serve(ctx context.Context) { return // don't reply default: - publicErr := "400 Bad Request" - if v, ok := err.(badRequestError); ok { - publicErr = publicErr + ": " + string(v) + if v, ok := err.(statusError); ok { + fmt.Fprintf(c.rwc, "HTTP/1.1 %d %s: %s%s%d %s: %s", v.code, StatusText(v.code), v.text, errorHeaders, v.code, StatusText(v.code), v.text) + return } - + publicErr := "400 Bad Request" fmt.Fprintf(c.rwc, "HTTP/1.1 "+publicErr+errorHeaders+publicErr) return } |