Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
projectdiscovery
GitHub Repository: projectdiscovery/nuclei
Path: blob/dev/pkg/protocols/offlinehttp/read_response.go
2070 views
1
package offlinehttp
2
3
import (
4
"bufio"
5
"errors"
6
"net/http"
7
"regexp"
8
"strings"
9
)
10
11
var noMinor = regexp.MustCompile(`HTTP/([0-9]) `)
12
13
// readResponseFromString reads a raw http response from a string.
14
func readResponseFromString(data string) (*http.Response, error) {
15
// Check if "data" contains RFC compatible Request followed by a response
16
br := bufio.NewReader(strings.NewReader(data))
17
if req, err := http.ReadRequest(br); err == nil {
18
if resp, err := http.ReadResponse(br, req); err == nil {
19
return resp, nil
20
}
21
}
22
23
// otherwise tries to patch known cases such as http minor version
24
var final string
25
if strings.HasPrefix(data, "HTTP/") {
26
final = addMinorVersionToHTTP(data)
27
} else {
28
lastIndex := strings.LastIndex(data, "HTTP/")
29
if lastIndex == -1 {
30
return nil, errors.New("malformed raw http response")
31
}
32
final = data[lastIndex:] // choose last http/ in case of it being later.
33
34
final = addMinorVersionToHTTP(final)
35
}
36
return http.ReadResponse(bufio.NewReader(strings.NewReader(final)), nil)
37
}
38
39
// addMinorVersionToHTTP tries to add a minor version to http status header
40
// fixing the compatibility issue with go standard library.
41
func addMinorVersionToHTTP(data string) string {
42
matches := noMinor.FindAllStringSubmatch(data, 1)
43
if len(matches) == 0 {
44
return data
45
}
46
if len(matches[0]) < 2 {
47
return data
48
}
49
replacedVersion := strings.Replace(matches[0][0], matches[0][1], matches[0][1]+".0", 1)
50
data = strings.Replace(data, matches[0][0], replacedVersion, 1)
51
return data
52
}
53
54