summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Neil <dneil@google.com>2020-10-13 13:02:45 -0700
committerDamien Neil <dneil@google.com>2020-10-14 18:05:16 +0000
commit9c56300e62d126875dcd6508c0ca7dce3985ad50 (patch)
tree6ce4e02ec69f50ee0f60c2ccaf69d9f46d951291
parentb95f0b123160a67c9e0b1d8c03993fe1e8208800 (diff)
downloadgo-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.go8
-rw-r--r--src/net/http/server.go21
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
}