fix #875
This commit is contained in:
Urban Ishimwe
2021-01-15 21:37:22 +03:00
committed by GitHub
parent 790545042b
commit 51db961942
2 changed files with 54 additions and 13 deletions
+14 -11
View File
@@ -195,7 +195,7 @@ func Body(payload []byte) []byte {
// Path takes payload and retuns request path: Split(firstLine, ' ')[1]
func Path(payload []byte) []byte {
if !HasTitle(payload) {
if !HasRequestTitle(payload) {
return nil
}
start := bytes.IndexByte(payload, ' ') + 1
@@ -309,7 +309,12 @@ func Method(payload []byte) []byte {
// Status returns response status.
// It happens to be in same position as request payload path
func Status(payload []byte) []byte {
return Path(payload)
if !HasResponseTitle(payload) {
return nil
}
start := bytes.IndexByte(payload, ' ') + 1
// status code are in range 100-600
return payload[start : start+3]
}
// Methods holds the http methods ordered in ascending order
@@ -322,8 +327,8 @@ var Methods = [...]string{
const (
//MinRequestCount GET / HTTP/1.1\r\n
MinRequestCount = 16
// MinResponseCount HTTP/1.1 200 OK\r\n
MinResponseCount = 17
// MinResponseCount HTTP/1.1 200\r\n
MinResponseCount = 14
// VersionLen HTTP/1.1
VersionLen = 8
)
@@ -346,17 +351,15 @@ func HasResponseTitle(payload []byte) bool {
return false
}
status, ok := atoI(payload[VersionLen+1:VersionLen+4], 10)
if !ok || s[VersionLen+4] != ' ' {
if !ok {
return false
}
statusText := http.StatusText(status)
if statusText == "" {
// only validate status codes mentioned in rfc2616.
if len(http.StatusText(status)) == 0 {
return false
}
if titleLen+len(CRLF) > len(s) {
return false
}
return s[VersionLen+5:titleLen] == statusText
// handle cases from #875
return payload[VersionLen+4] == ' ' || payload[VersionLen+4] == '\r'
}
// HasRequestTitle reports whether this payload has an HTTP/1 request title
+40 -2
View File
@@ -136,6 +136,24 @@ func TestParseHeaders(t *testing.T) {
if !reflect.DeepEqual(headers, expected) {
t.Error("Headers do not properly parsed", headers)
}
// Response with Reason phrase
payload = [][]byte{[]byte("HTTP/1.1 200 OK\r\nContent-Length: 7\r\nHost: www.w3.org\r\nUser-Agent:Chrome\r\n\r\nbody")}
headers = ParseHeaders(bytes.Join(payload, nil))
if !reflect.DeepEqual(headers, expected) {
t.Error("Headers do not properly parsed", headers)
}
// Response without Reason phrase
payload = [][]byte{[]byte("HTTP/1.1 200\r\nContent-Length: 7\r\nHost: www.w3.org\r\nUser-Agent:Chrome\r\n\r\nbody")}
headers = ParseHeaders(bytes.Join(payload, nil))
if !reflect.DeepEqual(headers, expected) {
t.Error("Headers do not properly parsed", headers)
}
}
// See https://github.com/dvyukov/go-fuzz and fuzz.go
@@ -219,6 +237,25 @@ func TestPath(t *testing.T) {
}
}
func TestStatus(t *testing.T) {
var status, payload []byte
payload = []byte("HTTP/1.1 200 OK\r\n")
if status = Status(payload); !bytes.Equal(status, []byte("200")) {
t.Error("Should find status 200 but:", string(status))
}
payload = []byte("HTTP/1.1 200\r\n")
if status = Status(payload); !bytes.Equal(status, []byte("200")) {
t.Error("1Should find status 200 but:", string(status))
}
payload = []byte("HTTP/1.1 404 Not Found\r\n")
if status = Status(payload); !bytes.Equal(status, []byte("404")) {
t.Error("2Should find status 404 but:", string(status))
}
}
func TestSetPath(t *testing.T) {
var payload, payloadAfter []byte
@@ -318,9 +355,10 @@ func TestHasResponseTitle(t *testing.T) {
"HTTP/1.1 100 Continue\r\n": true,
"HTTP/1.1 \r\n": false,
"HTTP/4.0 100Continue\r\n": false,
"HTTP/1.0 100Continue\r\n": false,
"HTTP/1.0 10r Continue\r\n": false,
"HTTP/1.1 200\r\n": false,
"HTTP/1.1 200\r\nServer: Tengine\r\nContent-Length: 0\r\nConnection: close\r\n\r\n": false,
"HTTP/1.1 200\r\n": true,
"HTTP/1.1 200\r\nServer: Tengine\r\nContent-Length: 0\r\nConnection: close\r\n\r\n": true,
}
for k, v := range m {
if HasResponseTitle([]byte(k)) != v {