2021-02-06 00:36:43 +05:30
|
|
|
package offlinehttp
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"bufio"
|
2021-02-08 19:08:35 +05:30
|
|
|
"errors"
|
2021-02-06 00:36:43 +05:30
|
|
|
"net/http"
|
2021-10-02 14:30:40 +07:00
|
|
|
"regexp"
|
2021-02-06 00:36:43 +05:30
|
|
|
"strings"
|
|
|
|
|
)
|
|
|
|
|
|
2021-11-25 15:39:10 +02:00
|
|
|
var noMinor = regexp.MustCompile(`HTTP/([0-9]) `)
|
2021-10-09 18:53:17 +05:30
|
|
|
|
2021-02-06 00:36:43 +05:30
|
|
|
// readResponseFromString reads a raw http response from a string.
|
|
|
|
|
func readResponseFromString(data string) (*http.Response, error) {
|
2022-07-11 19:13:10 +02:00
|
|
|
// Check if "data" contains RFC compatible Request followed by a response
|
|
|
|
|
br := bufio.NewReader(strings.NewReader(data))
|
|
|
|
|
if req, err := http.ReadRequest(br); err == nil {
|
|
|
|
|
if resp, err := http.ReadResponse(br, req); err == nil {
|
|
|
|
|
return resp, nil
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-10-02 14:30:40 +07:00
|
|
|
|
2022-07-11 19:13:10 +02:00
|
|
|
// otherwise tries to patch known cases such as http minor version
|
|
|
|
|
var final string
|
2021-02-06 00:36:43 +05:30
|
|
|
if strings.HasPrefix(data, "HTTP/") {
|
2021-10-09 18:53:17 +05:30
|
|
|
final = addMinorVersionToHTTP(data)
|
2021-02-06 00:36:43 +05:30
|
|
|
} else {
|
2021-02-08 19:08:35 +05:30
|
|
|
lastIndex := strings.LastIndex(data, "HTTP/")
|
|
|
|
|
if lastIndex == -1 {
|
|
|
|
|
return nil, errors.New("malformed raw http response")
|
|
|
|
|
}
|
2021-02-27 12:31:17 +05:30
|
|
|
final = data[lastIndex:] // choose last http/ in case of it being later.
|
2021-10-02 14:30:40 +07:00
|
|
|
|
2021-10-09 18:53:17 +05:30
|
|
|
final = addMinorVersionToHTTP(final)
|
2021-02-06 00:36:43 +05:30
|
|
|
}
|
|
|
|
|
return http.ReadResponse(bufio.NewReader(strings.NewReader(final)), nil)
|
|
|
|
|
}
|
2021-10-09 18:53:17 +05:30
|
|
|
|
|
|
|
|
// addMinorVersionToHTTP tries to add a minor version to http status header
|
|
|
|
|
// fixing the compatibility issue with go standard library.
|
|
|
|
|
func addMinorVersionToHTTP(data string) string {
|
|
|
|
|
matches := noMinor.FindAllStringSubmatch(data, 1)
|
|
|
|
|
if len(matches) == 0 {
|
|
|
|
|
return data
|
|
|
|
|
}
|
|
|
|
|
if len(matches[0]) < 2 {
|
|
|
|
|
return data
|
|
|
|
|
}
|
|
|
|
|
replacedVersion := strings.Replace(matches[0][0], matches[0][1], matches[0][1]+".0", 1)
|
|
|
|
|
data = strings.Replace(data, matches[0][0], replacedVersion, 1)
|
|
|
|
|
return data
|
|
|
|
|
}
|