]> Cypherpunks repositories - gostls13.git/commitdiff
net/http: return 505 status for rejected protocol version
authorDamien Neil <dneil@google.com>
Tue, 13 Oct 2020 20:02:45 +0000 (13:02 -0700)
committerDamien Neil <dneil@google.com>
Wed, 14 Oct 2020 18:05:16 +0000 (18:05 +0000)
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>
src/net/http/serve_test.go
src/net/http/server.go

index 6d3317fb0c6f3c2b6e49ca2b52b7183f913e91b8..cbd3101f273494b1d84ef7a3cdf5d271223b9a51 100644 (file)
@@ -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)}
index 25fab288f2c9570ec864e8595ebcf1191496ca63..db3a09b9937d5dd4613a5f54d582970614e64298 100644 (file)
@@ -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
                        }