Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
projectdiscovery
GitHub Repository: projectdiscovery/nuclei
Path: blob/dev/pkg/protocols/http/httpclientpool/options.go
2072 views
1
package httpclientpool
2
3
import (
4
"io"
5
"net/http"
6
"strings"
7
"time"
8
9
"github.com/projectdiscovery/rawhttp"
10
stringsutil "github.com/projectdiscovery/utils/strings"
11
urlutil "github.com/projectdiscovery/utils/url"
12
)
13
14
// WithCustomTimeout is a configuration for custom timeout
15
type WithCustomTimeout struct {
16
Timeout time.Duration
17
}
18
19
// RawHttpRequestOpts is a configuration for raw http request
20
type RawHttpRequestOpts struct {
21
// Method is the http method to use
22
Method string
23
// URL is the url to request
24
URL string
25
// Path is request path to use
26
Path string
27
// Headers is the headers to use
28
Headers map[string][]string
29
// Body is the body to use
30
Body io.Reader
31
// Options is more client related options
32
Options *rawhttp.Options
33
}
34
35
// SendRawRequest sends a raw http request with the provided options and returns http response
36
func SendRawRequest(client *rawhttp.Client, opts *RawHttpRequestOpts) (*http.Response, error) {
37
resp, err := client.DoRawWithOptions(opts.Method, opts.URL, opts.Path, opts.Headers, opts.Body, opts.Options)
38
if err != nil {
39
cause := err.Error()
40
if stringsutil.ContainsAll(cause, "ReadStatusLine: ", "read: connection reset by peer") {
41
// this error is caused when rawhttp client sends a corrupted or malformed request packet to server
42
// some servers may attempt gracefully shutdown but most will just abruptly close the connection which results
43
// in a connection reset by peer error and this can be safely assumed as 400 Bad Request in terms of normal http flow
44
req, reqErr := http.NewRequest(opts.Method, opts.URL, opts.Body)
45
if reqErr != nil {
46
// failed to build new request mostly because of invalid url or body
47
// try again or else return urlErr
48
parsed, urlErr := urlutil.ParseAbsoluteURL(opts.URL, true)
49
if urlErr != nil {
50
return nil, err
51
}
52
req, reqErr = http.NewRequest(opts.Method, parsed.Host, opts.Body)
53
if reqErr != nil {
54
return nil, err
55
}
56
req.URL = parsed.URL
57
req.Header = opts.Headers
58
}
59
60
// if req is still nil, return error
61
if req == nil {
62
return nil, err
63
}
64
65
req.Header = opts.Headers
66
resp = &http.Response{
67
Request: req,
68
StatusCode: http.StatusBadRequest,
69
Status: http.StatusText(http.StatusBadRequest),
70
Body: io.NopCloser(strings.NewReader("")),
71
}
72
return resp, nil
73
}
74
}
75
return resp, err
76
}
77
78