diff options
author | Damien Neil <dneil@google.com> | 2021-06-07 16:16:45 -0700 |
---|---|---|
committer | Brad Fitzpatrick <bradfitz@golang.org> | 2021-10-06 00:43:45 +0000 |
commit | 72c52bfbe2f72fbcacc865e18f132366bdd2effa (patch) | |
tree | 1b25d5ad4c5919b8e8bbb30f298fc50004b418c4 | |
parent | ac60900759c29d9c06d9fe131825c4677e47d6a1 (diff) | |
download | go-72c52bfbe2f72fbcacc865e18f132366bdd2effa.tar.gz go-72c52bfbe2f72fbcacc865e18f132366bdd2effa.zip |
net/http: parse HTTP version strings according to RFC 7230
RFC 2616 permits multiple digits in the major and minor numbers of an
HTTP version:
https://datatracker.ietf.org/doc/html/rfc2616#section-3.1
RFC 7230 obsoletes 2616 and tightens the specification to permit only a
single digit in the major and minor number:
https://datatracker.ietf.org/doc/html/rfc7230#section-2.6
Use the stricter definition.
Also fix a bug which caused version numbers with a leading "+" to
be accepted (e.g., "HTTP/1.+1".)
Fixes #46587.
Change-Id: Ic5923bb858e5ac402cfde486fba2c075e221553d
Reviewed-on: https://go-review.googlesource.com/c/go/+/325874
Trust: Damien Neil <dneil@google.com>
Trust: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Damien Neil <dneil@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
-rw-r--r-- | src/net/http/request.go | 19 | ||||
-rw-r--r-- | src/net/http/request_test.go | 8 |
2 files changed, 17 insertions, 10 deletions
diff --git a/src/net/http/request.go b/src/net/http/request.go index 09cb0c7f56..0eb7042d7b 100644 --- a/src/net/http/request.go +++ b/src/net/http/request.go @@ -779,11 +779,10 @@ func removeZone(host string) string { return host[:j] + host[i:] } -// ParseHTTPVersion parses an HTTP version string. +// ParseHTTPVersion parses an HTTP version string according to RFC 7230, section 2.6. // "HTTP/1.0" returns (1, 0, true). Note that strings without // a minor version, such as "HTTP/2", are not valid. func ParseHTTPVersion(vers string) (major, minor int, ok bool) { - const Big = 1000000 // arbitrary upper bound switch vers { case "HTTP/1.1": return 1, 1, true @@ -793,19 +792,21 @@ func ParseHTTPVersion(vers string) (major, minor int, ok bool) { if !strings.HasPrefix(vers, "HTTP/") { return 0, 0, false } - dot := strings.Index(vers, ".") - if dot < 0 { + if len(vers) != len("HTTP/X.Y") { return 0, 0, false } - major, err := strconv.Atoi(vers[5:dot]) - if err != nil || major < 0 || major > Big { + if vers[6] != '.' { return 0, 0, false } - minor, err = strconv.Atoi(vers[dot+1:]) - if err != nil || minor < 0 || minor > Big { + maj, err := strconv.ParseUint(vers[5:6], 10, 0) + if err != nil { + return 0, 0, false + } + min, err := strconv.ParseUint(vers[7:8], 10, 0) + if err != nil { return 0, 0, false } - return major, minor, true + return int(maj), int(min), true } func validMethod(method string) bool { diff --git a/src/net/http/request_test.go b/src/net/http/request_test.go index 4e0c4ba207..4363e11033 100644 --- a/src/net/http/request_test.go +++ b/src/net/http/request_test.go @@ -639,10 +639,10 @@ var parseHTTPVersionTests = []struct { major, minor int ok bool }{ + {"HTTP/0.0", 0, 0, true}, {"HTTP/0.9", 0, 9, true}, {"HTTP/1.0", 1, 0, true}, {"HTTP/1.1", 1, 1, true}, - {"HTTP/3.14", 3, 14, true}, {"HTTP", 0, 0, false}, {"HTTP/one.one", 0, 0, false}, @@ -651,6 +651,12 @@ var parseHTTPVersionTests = []struct { {"HTTP/0,-1", 0, 0, false}, {"HTTP/", 0, 0, false}, {"HTTP/1,1", 0, 0, false}, + {"HTTP/+1.1", 0, 0, false}, + {"HTTP/1.+1", 0, 0, false}, + {"HTTP/0000000001.1", 0, 0, false}, + {"HTTP/1.0000000001", 0, 0, false}, + {"HTTP/3.14", 0, 0, false}, + {"HTTP/12.3", 0, 0, false}, } func TestParseHTTPVersion(t *testing.T) { |