123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- package request
- import (
- "crypto/tls"
- "io"
- "net"
- "net/http"
- "net/http/cookiejar"
- "strings"
- "time"
- )
- type (
- BeforeRequest func(req *http.Request) (err error)
- AfterRequest func(req *http.Request, res *http.Response) (err error)
- Client struct {
- baseUrl string
- Authorization Authorization
- client *http.Client
- cookieJar *cookiejar.Jar
- interceptorRequest []BeforeRequest
- interceptorResponse []AfterRequest
- }
- )
- var (
- DefaultClient = &http.Client{
- Transport: &http.Transport{
- Proxy: http.ProxyFromEnvironment,
- ForceAttemptHTTP2: true,
- MaxIdleConns: 64,
- MaxIdleConnsPerHost: 8,
- IdleConnTimeout: 90 * time.Second,
- TLSHandshakeTimeout: 10 * time.Second,
- ExpectContinueTimeout: 1 * time.Second,
- TLSClientConfig: &tls.Config{
- InsecureSkipVerify: true,
- },
- },
- Timeout: time.Second * 30,
- }
- UnsafeClient = &http.Client{
- Transport: &http.Transport{
- Proxy: http.ProxyFromEnvironment,
- ForceAttemptHTTP2: true,
- DialContext: (&net.Dialer{
- Timeout: 30 * time.Second,
- KeepAlive: 30 * time.Second,
- }).DialContext,
- MaxIdleConns: 64,
- MaxIdleConnsPerHost: 8,
- IdleConnTimeout: 90 * time.Second,
- TLSHandshakeTimeout: 10 * time.Second,
- ExpectContinueTimeout: 1 * time.Second,
- TLSClientConfig: &tls.Config{
- InsecureSkipVerify: true,
- },
- },
- Timeout: time.Second * 30,
- }
- )
- func (client *Client) stashUri(urlPath string) string {
- var (
- pos int
- )
- if len(urlPath) == 0 {
- return client.baseUrl
- }
- if pos = strings.Index(urlPath, "//"); pos == -1 {
- if client.baseUrl != "" {
- if urlPath[0] != '/' {
- urlPath = "/" + urlPath
- }
- return client.baseUrl + urlPath
- }
- }
- return urlPath
- }
- func (client *Client) BeforeRequest(cb BeforeRequest) *Client {
- client.interceptorRequest = append(client.interceptorRequest, cb)
- return client
- }
- func (client *Client) AfterRequest(cb AfterRequest) *Client {
- client.interceptorResponse = append(client.interceptorResponse, cb)
- return client
- }
- func (client *Client) SetBaseUrl(s string) *Client {
- client.baseUrl = strings.TrimSuffix(s, "/")
- return client
- }
- func (client *Client) SetCookieJar(cookieJar *cookiejar.Jar) *Client {
- client.client.Jar = cookieJar
- return client
- }
- func (client *Client) SetClient(httpClient *http.Client) *Client {
- client.client = httpClient
- if client.cookieJar != nil {
- client.client.Jar = client.cookieJar
- }
- return client
- }
- func (client *Client) SetTransport(transport http.RoundTripper) *Client {
- client.client.Transport = transport
- return client
- }
- func (client *Client) Get(urlPath string) *Request {
- return newRequest(http.MethodGet, client.stashUri(urlPath), client)
- }
- func (client *Client) Put(urlPath string) *Request {
- return newRequest(http.MethodPut, client.stashUri(urlPath), client)
- }
- func (client *Client) Post(urlPath string) *Request {
- return newRequest(http.MethodPost, client.stashUri(urlPath), client)
- }
- func (client *Client) Delete(urlPath string) *Request {
- return newRequest(http.MethodDelete, client.stashUri(urlPath), client)
- }
- func (client *Client) execute(r *Request) (res *http.Response, err error) {
- var (
- n int
- reader io.Reader
- )
- if r.contentType == "" && r.body != nil {
- r.contentType = r.detectContentType(r.body)
- }
- if r.body != nil {
- if reader, err = r.readRequestBody(r.contentType, r.body); err != nil {
- return
- }
- }
- if r.rawRequest, err = http.NewRequest(r.method, r.uri, reader); err != nil {
- return
- }
- for k, vs := range r.header {
- for _, v := range vs {
- r.rawRequest.Header.Add(k, v)
- }
- }
- if r.contentType != "" {
- r.rawRequest.Header.Set("Content-Type", r.contentType)
- }
- if client.Authorization != nil {
- r.rawRequest.Header.Set("Authorization", client.Authorization.Token())
- }
- if r.context != nil {
- r.rawRequest = r.rawRequest.WithContext(r.context)
- }
- n = len(client.interceptorRequest)
- for i := n - 1; i >= 0; i-- {
- if err = client.interceptorRequest[i](r.rawRequest); err != nil {
- return
- }
- }
- if r.rawResponse, err = client.client.Do(r.rawRequest); err != nil {
- return nil, err
- }
- n = len(client.interceptorResponse)
- for i := n - 1; i >= 0; i-- {
- if err = client.interceptorResponse[i](r.rawRequest, r.rawResponse); err != nil {
- _ = r.rawResponse.Body.Close()
- return
- }
- }
- return r.rawResponse, err
- }
- func New() *Client {
- client := &Client{
- client: DefaultClient,
- interceptorRequest: make([]BeforeRequest, 0, 10),
- interceptorResponse: make([]AfterRequest, 0, 10),
- }
- client.cookieJar, _ = cookiejar.New(nil)
- client.client.Jar = client.cookieJar
- return client
- }
|