infra
/
goutils
Archived
1
0
Fork 0
This repository has been archived on 2022-04-06. You can view files and clone it, but cannot push or open issues or pull requests.
goutils/http/client/client.go

104 lines
2.4 KiB
Go

package client
import (
"net/http"
"net"
"time"
"errors"
"net/url"
"io"
)
var (
httpCannotRedirectError = errors.New("this client cannot redirect")
disableRedirect = func(_ *http.Request, _ []*http.Request) error {
return httpCannotRedirectError
}
limitedRedirect = func(_ *http.Request, via []*http.Request) error {
if len(via) >= 10 {
return errors.New("stopped after 10 redirects")
}
return nil
}
)
type GracefulClient interface {
http.RoundTripper
client() *http.Client
roundTripper() http.RoundTripper
Do(req *http.Request) (*http.Response, error)
Get(url string) (resp *http.Response, err error)
Head(url string) (resp *http.Response, err error)
Post(url string, contentType string, body io.Reader) (resp *http.Response, err error)
PostForm(url string, data url.Values) (resp *http.Response, err error)
}
type wrappedClient struct {
http.Client
}
func (cli *wrappedClient) client() (*http.Client) {
return &cli.Client
}
func (cli *wrappedClient) roundTripper() http.RoundTripper {
return cli.Transport
}
func (cli *wrappedClient) RoundTrip(req *http.Request) (*http.Response, error) {
return cli.Client.Transport.RoundTrip(req)
}
func NewClient(
keepaliveDuration time.Duration,
connectTimeout time.Duration,
responseHeaderTimeout time.Duration,
idleConnectionTimeout time.Duration,
maxIdleConnections int,
redirectSupport bool,
serverName string,
) GracefulClient {
srvName := []string{serverName}
var redirectChecker func(*http.Request, []*http.Request) error
if redirectSupport {
redirectChecker = limitedRedirect
} else {
redirectChecker = disableRedirect
}
keepaliveDisabled := keepaliveDuration == 0
dialer := &net.Dialer{
Timeout: connectTimeout,
KeepAlive: keepaliveDuration,
DualStack: false,
}
transport := &predefinedHeaderTransport{
useragentName: srvName,
Transport: http.Transport{
Proxy: nil,
DialTLS: nil,
TLSClientConfig: nil,
DisableKeepAlives: keepaliveDisabled,
DisableCompression: true,
MaxIdleConnsPerHost: maxIdleConnections,
DialContext: dialer.DialContext,
MaxIdleConns: maxIdleConnections,
IdleConnTimeout: idleConnectionTimeout,
ResponseHeaderTimeout: responseHeaderTimeout,
TLSNextProto: nil,
ExpectContinueTimeout: 0,
},
}
return &wrappedClient{
Client: http.Client{
Transport: transport,
CheckRedirect: redirectChecker,
Jar: nil,
},
}
}