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
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 {
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},
{"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) {