keel/net/http/client.go
Kevin Franklin Kim 0d147cbe2a
style: reformat
2024-09-23 08:43:11 +02:00

262 lines
6.1 KiB
Go

package http
import (
"context"
"crypto/tls"
"net"
"net/http"
"net/url"
"time"
"github.com/foomo/keel/net/http/roundtripware"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
"go.uber.org/zap"
)
type HTTPClientOption func(*http.Client)
func HTTPClientWithTimeout(o time.Duration) HTTPClientOption {
return func(v *http.Client) {
v.Timeout = o
}
}
func HTTPClientWithJar(o http.CookieJar) HTTPClientOption {
return func(v *http.Client) {
v.Jar = o
}
}
func HTTPClientWithTransport(o http.RoundTripper) HTTPClientOption {
return func(v *http.Client) {
// TODO warn in case of overriding other options
v.Transport = o
}
}
func HTTPClientWithCheckRedirect(o func(req *http.Request, via []*http.Request) error) HTTPClientOption {
return func(v *http.Client) {
v.CheckRedirect = o
}
}
func HTTPClientWithProxy(o func(request *http.Request) (*url.URL, error)) HTTPClientOption {
return func(v *http.Client) {
if t, ok := v.Transport.(*http.Transport); ok {
t.Proxy = o
v.Transport = t
}
}
}
func HTTPClientWithDialContext(o func(ctx context.Context, network, addr string) (net.Conn, error)) HTTPClientOption {
return func(v *http.Client) {
if t, ok := v.Transport.(*http.Transport); ok {
t.DialContext = o
v.Transport = t
}
}
}
func HTTPClientWithDialTLSContext(o func(ctx context.Context, network, addr string) (net.Conn, error)) HTTPClientOption {
return func(v *http.Client) {
if t, ok := v.Transport.(*http.Transport); ok {
t.DialTLSContext = o
v.Transport = t
}
}
}
func HTTPClientWithTLSClientConfig(o *tls.Config) HTTPClientOption {
return func(v *http.Client) {
if t, ok := v.Transport.(*http.Transport); ok {
t.TLSClientConfig = o
v.Transport = t
}
}
}
func HTTPClientWithTLSHandshakeTimeout(o time.Duration) HTTPClientOption {
return func(v *http.Client) {
if t, ok := v.Transport.(*http.Transport); ok {
t.TLSHandshakeTimeout = o
v.Transport = t
}
}
}
func HTTPClientWithDisableKeepAlives(o bool) HTTPClientOption {
return func(v *http.Client) {
if t, ok := v.Transport.(*http.Transport); ok {
t.DisableKeepAlives = o
v.Transport = t
}
}
}
func HTTPClientWithDisableCompression(o bool) HTTPClientOption {
return func(v *http.Client) {
if t, ok := v.Transport.(*http.Transport); ok {
t.DisableCompression = o
v.Transport = t
}
}
}
func HTTPClientWithMaxIdleConns(o int) HTTPClientOption {
return func(v *http.Client) {
if t, ok := v.Transport.(*http.Transport); ok {
t.MaxIdleConns = o
v.Transport = t
}
}
}
func HTTPClientWithMaxIdleConnsPerHost(o int) HTTPClientOption {
return func(v *http.Client) {
if t, ok := v.Transport.(*http.Transport); ok {
t.MaxIdleConnsPerHost = o
v.Transport = t
}
}
}
func HTTPClientWithMaxConnsPerHost(o int) HTTPClientOption {
return func(v *http.Client) {
if t, ok := v.Transport.(*http.Transport); ok {
t.MaxConnsPerHost = o
v.Transport = t
}
}
}
func HTTPClientWithIdleConnTimeout(o time.Duration) HTTPClientOption {
return func(v *http.Client) {
if t, ok := v.Transport.(*http.Transport); ok {
t.IdleConnTimeout = o
v.Transport = t
}
}
}
func HTTPClientWithResponseHeaderTimeout(o time.Duration) HTTPClientOption {
return func(v *http.Client) {
if t, ok := v.Transport.(*http.Transport); ok {
t.ResponseHeaderTimeout = o
v.Transport = t
}
}
}
func HTTPClientWithExpectContinueTimeout(o time.Duration) HTTPClientOption {
return func(v *http.Client) {
if t, ok := v.Transport.(*http.Transport); ok {
t.ExpectContinueTimeout = o
v.Transport = t
}
}
}
func HTTPClientWithTLSNextProto(o map[string]func(authority string, c *tls.Conn) http.RoundTripper) HTTPClientOption {
return func(v *http.Client) {
if t, ok := v.Transport.(*http.Transport); ok {
t.TLSNextProto = o
v.Transport = t
}
}
}
func HTTPClientWithProxyConnectHeader(o http.Header) HTTPClientOption {
return func(v *http.Client) {
if t, ok := v.Transport.(*http.Transport); ok {
t.ProxyConnectHeader = o
v.Transport = t
}
}
}
func HTTPClientWithGetProxyConnectHeader(o func(ctx context.Context, proxyURL *url.URL, target string) (http.Header, error)) HTTPClientOption {
return func(v *http.Client) {
if t, ok := v.Transport.(*http.Transport); ok {
t.GetProxyConnectHeader = o
v.Transport = t
}
}
}
func HTTPClientWithMaxResponseHeaderBytes(o int64) HTTPClientOption {
return func(v *http.Client) {
if t, ok := v.Transport.(*http.Transport); ok {
t.MaxResponseHeaderBytes = o
v.Transport = t
}
}
}
func HTTPClientWithWriteBufferSize(o int) HTTPClientOption {
return func(v *http.Client) {
if t, ok := v.Transport.(*http.Transport); ok {
t.WriteBufferSize = o
v.Transport = t
}
}
}
func HTTPClientWithReadBufferSize(o int) HTTPClientOption {
return func(v *http.Client) {
if t, ok := v.Transport.(*http.Transport); ok {
t.ReadBufferSize = o
v.Transport = t
}
}
}
func HTTPClientWithForceAttemptHTTP2(o bool) HTTPClientOption {
return func(v *http.Client) {
if t, ok := v.Transport.(*http.Transport); ok {
t.ForceAttemptHTTP2 = o
v.Transport = t
}
}
}
func HTTPClientWithRoundTripware(l *zap.Logger, roundTripware ...roundtripware.RoundTripware) HTTPClientOption {
return func(v *http.Client) {
v.Transport = roundtripware.NewRoundTripper(l, v.Transport, roundTripware...)
}
}
func HTTPClientWithTelemetry(opts ...otelhttp.Option) HTTPClientOption {
return func(v *http.Client) {
v.Transport = otelhttp.NewTransport(v.Transport, opts...)
}
}
func DefaultHTTPTransportDialer() *net.Dialer {
return &net.Dialer{
Timeout: 45 * time.Second,
KeepAlive: 45 * time.Second,
}
}
func DefaultHTTPTransport() *http.Transport {
return &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: DefaultHTTPTransportDialer().DialContext,
DisableKeepAlives: true,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 5 * time.Second,
}
}
func NewHTTPClient(opts ...HTTPClientOption) *http.Client {
inst := &http.Client{
Transport: DefaultHTTPTransport(),
Timeout: 2 * time.Minute,
}
for _, opt := range opts {
opt(inst)
}
return inst
}