package httpclient import ( "bytes" "context" "encoding/json" "encoding/xml" "fmt" "git.nspix.com/golang/micro/helper/random" "io" "net" "net/http" "strings" "time" ) var ( httpClient = http.Client{ Timeout: time.Second * 15, Transport: &http.Transport{ Proxy: http.ProxyFromEnvironment, DialContext: (&net.Dialer{ Timeout: 30 * time.Second, KeepAlive: 30 * time.Second, }).DialContext, ForceAttemptHTTP2: false, MaxIdleConns: 10, IdleConnTimeout: 30 * time.Second, TLSHandshakeTimeout: 10 * time.Second, ExpectContinueTimeout: 1 * time.Second, }, } ) func Get(ctx context.Context, url string, header map[string]string) (res *http.Response, err error) { var ( req *http.Request ) if req, err = http.NewRequest("GET", url, nil); err != nil { return } if header != nil { for k, v := range header { req.Header.Set(k, v) } } return MockDo(ctx, req) } func Post(ctx context.Context, url string, header map[string]string, data interface{}) (res *http.Response, err error) { var ( req *http.Request contentType string reader io.Reader ) switch v := data.(type) { case string: reader = strings.NewReader(v) contentType = "x-www-form-urlencoded" case []byte: reader = bytes.NewReader(v) contentType = "" default: var b []byte if b, err = json.Marshal(v); err == nil { reader = bytes.NewReader(b) contentType = "application/json" } else { return } } if req, err = http.NewRequest("POST", url, reader); err != nil { return } if contentType != "" { req.Header.Set("Content-Type", contentType) } if header != nil { for k, v := range header { req.Header.Set(k, v) } } return MockDo(ctx, req) } func MockDo(ctx context.Context, req *http.Request) (res *http.Response, err error) { randomIp := random.IP() req.Header.Set("X-Forwarded-For", randomIp) req.Header.Set("X-Real-IP", randomIp) req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36") if ctx != nil { req = req.WithContext(ctx) } return Do(ctx, req) } func Fetch(ctx context.Context, req *http.Request, outer interface{}) (err error) { var ( res *http.Response contentType string ) randomIp := random.IP() req.Header.Set("X-Forwarded-For", randomIp) req.Header.Set("X-Real-IP", randomIp) req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.81 Safari/537.36 Edg/104.0.1293.54") if req.Header.Get("Referer") == "" { req.Header.Set("Referer", req.URL.String()) } if ctx != nil { req = req.WithContext(ctx) } if res, err = Do(ctx, req); err != nil { return } defer func() { _ = res.Body.Close() }() if res.StatusCode != http.StatusOK { err = fmt.Errorf("got http response (%d)%s", res.StatusCode, res.Status) return } contentType = res.Header.Get("Content-Type") if strings.HasPrefix(contentType, "application/json") { err = json.NewDecoder(res.Body).Decode(outer) } else if strings.HasPrefix(contentType, "application/xml") { err = xml.NewDecoder(res.Body).Decode(outer) } return } func Do(ctx context.Context, req *http.Request) (res *http.Response, err error) { if ctx != nil { req = req.WithContext(ctx) } return httpClient.Do(req) }