Path: blob/dev/pkg/protocols/http/httpclientpool/options.go
2072 views
package httpclientpool12import (3"io"4"net/http"5"strings"6"time"78"github.com/projectdiscovery/rawhttp"9stringsutil "github.com/projectdiscovery/utils/strings"10urlutil "github.com/projectdiscovery/utils/url"11)1213// WithCustomTimeout is a configuration for custom timeout14type WithCustomTimeout struct {15Timeout time.Duration16}1718// RawHttpRequestOpts is a configuration for raw http request19type RawHttpRequestOpts struct {20// Method is the http method to use21Method string22// URL is the url to request23URL string24// Path is request path to use25Path string26// Headers is the headers to use27Headers map[string][]string28// Body is the body to use29Body io.Reader30// Options is more client related options31Options *rawhttp.Options32}3334// SendRawRequest sends a raw http request with the provided options and returns http response35func SendRawRequest(client *rawhttp.Client, opts *RawHttpRequestOpts) (*http.Response, error) {36resp, err := client.DoRawWithOptions(opts.Method, opts.URL, opts.Path, opts.Headers, opts.Body, opts.Options)37if err != nil {38cause := err.Error()39if stringsutil.ContainsAll(cause, "ReadStatusLine: ", "read: connection reset by peer") {40// this error is caused when rawhttp client sends a corrupted or malformed request packet to server41// some servers may attempt gracefully shutdown but most will just abruptly close the connection which results42// in a connection reset by peer error and this can be safely assumed as 400 Bad Request in terms of normal http flow43req, reqErr := http.NewRequest(opts.Method, opts.URL, opts.Body)44if reqErr != nil {45// failed to build new request mostly because of invalid url or body46// try again or else return urlErr47parsed, urlErr := urlutil.ParseAbsoluteURL(opts.URL, true)48if urlErr != nil {49return nil, err50}51req, reqErr = http.NewRequest(opts.Method, parsed.Host, opts.Body)52if reqErr != nil {53return nil, err54}55req.URL = parsed.URL56req.Header = opts.Headers57}5859// if req is still nil, return error60if req == nil {61return nil, err62}6364req.Header = opts.Headers65resp = &http.Response{66Request: req,67StatusCode: http.StatusBadRequest,68Status: http.StatusText(http.StatusBadRequest),69Body: io.NopCloser(strings.NewReader("")),70}71return resp, nil72}73}74return resp, err75}767778