amuz.es/src/infra/goutils@v0.1.3/http/client/client.go (about)

     1  package client
     2  
     3  import (
     4  	"net/http"
     5  	"net"
     6  	"time"
     7  	"errors"
     8  	"net/url"
     9  	"io"
    10  )
    11  
    12  var (
    13  	httpCannotRedirectError = errors.New("this client cannot redirect")
    14  
    15  	disableRedirect = func(_ *http.Request, _ []*http.Request) error {
    16  		return httpCannotRedirectError
    17  	}
    18  	limitedRedirect = func(_ *http.Request, via []*http.Request) error {
    19  		if len(via) >= 10 {
    20  			return errors.New("stopped after 10 redirects")
    21  		}
    22  		return nil
    23  	}
    24  )
    25  
    26  type GracefulClient interface {
    27  	http.RoundTripper
    28  	client() *http.Client
    29  	roundTripper() http.RoundTripper
    30  	Do(req *http.Request) (*http.Response, error)
    31  	Get(url string) (resp *http.Response, err error)
    32  	Head(url string) (resp *http.Response, err error)
    33  	Post(url string, contentType string, body io.Reader) (resp *http.Response, err error)
    34  	PostForm(url string, data url.Values) (resp *http.Response, err error)
    35  }
    36  
    37  
    38  type wrappedClient struct {
    39  	http.Client
    40  }
    41  
    42  func (cli *wrappedClient) client() (*http.Client) {
    43  	return &cli.Client
    44  }
    45  func (cli *wrappedClient) roundTripper() http.RoundTripper {
    46  	return cli.Transport
    47  }
    48  
    49  func (cli *wrappedClient) RoundTrip(req *http.Request) (*http.Response, error) {
    50  	return cli.Client.Transport.RoundTrip(req)
    51  }
    52  
    53  func NewClient(
    54  	keepaliveDuration time.Duration,
    55  	connectTimeout time.Duration,
    56  	responseHeaderTimeout time.Duration,
    57  	idleConnectionTimeout time.Duration,
    58  	maxIdleConnections int,
    59  	redirectSupport bool,
    60  	serverName string,
    61  ) GracefulClient {
    62  
    63  	srvName := []string{serverName}
    64  	var redirectChecker func(*http.Request, []*http.Request) error
    65  	if redirectSupport {
    66  		redirectChecker = limitedRedirect
    67  	} else {
    68  		redirectChecker = disableRedirect
    69  	}
    70  
    71  	keepaliveDisabled := keepaliveDuration == 0
    72  	dialer := &net.Dialer{
    73  		Timeout:   connectTimeout,
    74  		KeepAlive: keepaliveDuration,
    75  		DualStack: false,
    76  	}
    77  
    78  	transport := &predefinedHeaderTransport{
    79  		useragentName: srvName,
    80  		Transport: http.Transport{
    81  			Proxy:                 nil,
    82  			DialTLS:               nil,
    83  			TLSClientConfig:       nil,
    84  			DisableKeepAlives:     keepaliveDisabled,
    85  			DisableCompression:    true,
    86  			MaxIdleConnsPerHost:   maxIdleConnections,
    87  			DialContext:           dialer.DialContext,
    88  			MaxIdleConns:          maxIdleConnections,
    89  			IdleConnTimeout:       idleConnectionTimeout,
    90  			ResponseHeaderTimeout: responseHeaderTimeout,
    91  			TLSNextProto:          nil,
    92  			ExpectContinueTimeout: 0,
    93  		},
    94  	}
    95  
    96  	return &wrappedClient{
    97  		Client: http.Client{
    98  			Transport:     transport,
    99  			CheckRedirect: redirectChecker,
   100  			Jar:           nil,
   101  		},
   102  	}
   103  }