104 lines
2.4 KiB
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,
|
|
},
|
|
}
|
|
}
|