149 lines
4.2 KiB
Go
149 lines
4.2 KiB
Go
package http
|
|
|
|
import (
|
|
"context"
|
|
"crypto/tls"
|
|
"net"
|
|
"net/http"
|
|
"time"
|
|
|
|
"go.unistack.org/micro/v4/client"
|
|
)
|
|
|
|
// --------------------------------------------- HTTPClient option -----------------------------------------------------
|
|
type httpClientKey struct{}
|
|
|
|
func HTTPClient(c *http.Client) client.Option {
|
|
return client.SetOption(httpClientKey{}, c)
|
|
}
|
|
|
|
func httpClientFromOpts(opts client.Options) (*http.Client, bool) {
|
|
httpClient, ok := opts.Context.Value(httpClientKey{}).(*http.Client)
|
|
return httpClient, ok
|
|
}
|
|
|
|
func defaultHTTPClient(
|
|
dialer func(ctx context.Context, addr string) (net.Conn, error),
|
|
tlsConfig *tls.Config,
|
|
) *http.Client {
|
|
tr := &http.Transport{
|
|
Proxy: http.ProxyFromEnvironment,
|
|
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
|
|
return dialer(ctx, addr)
|
|
},
|
|
ForceAttemptHTTP2: true,
|
|
MaxConnsPerHost: 100,
|
|
MaxIdleConns: 20,
|
|
IdleConnTimeout: 60 * time.Second,
|
|
TLSHandshakeTimeout: 10 * time.Second,
|
|
ExpectContinueTimeout: 1 * time.Second,
|
|
TLSClientConfig: tlsConfig,
|
|
}
|
|
return &http.Client{Transport: tr}
|
|
}
|
|
|
|
// --------------------------------------------- HTTPDialer option -----------------------------------------------------
|
|
type httpDialerKey struct{}
|
|
|
|
func HTTPDialer(d *net.Dialer) client.Option {
|
|
return client.SetOption(httpDialerKey{}, d)
|
|
}
|
|
|
|
func httpDialerFromOpts(opts client.Options) (dialerFunc func(context.Context, string) (net.Conn, error), ok bool) {
|
|
var d *net.Dialer
|
|
|
|
if d, ok = opts.Context.Value(httpDialerKey{}).(*net.Dialer); ok {
|
|
dialerFunc = func(ctx context.Context, addr string) (net.Conn, error) {
|
|
return d.DialContext(ctx, "tcp", addr)
|
|
}
|
|
}
|
|
|
|
if opts.ContextDialer != nil {
|
|
dialerFunc, ok = opts.ContextDialer, true
|
|
}
|
|
|
|
return dialerFunc, ok
|
|
}
|
|
|
|
func defaultHTTPDialer() func(ctx context.Context, addr string) (net.Conn, error) {
|
|
return func(ctx context.Context, addr string) (net.Conn, error) {
|
|
d := &net.Dialer{
|
|
Timeout: 30 * time.Second,
|
|
KeepAlive: 30 * time.Second,
|
|
}
|
|
return d.DialContext(ctx, "tcp", addr)
|
|
}
|
|
}
|
|
|
|
// ----------------------------------------------- Method option -------------------------------------------------------
|
|
type methodKey struct{}
|
|
|
|
func Method(m string) client.CallOption {
|
|
return client.SetCallOption(methodKey{}, m)
|
|
}
|
|
|
|
func methodFromOpts(opts client.CallOptions) (string, bool) {
|
|
m, ok := opts.Context.Value(methodKey{}).(string)
|
|
return m, ok
|
|
}
|
|
|
|
// ------------------------------------------------ Path option --------------------------------------------------------
|
|
type pathKey struct{}
|
|
|
|
func Path(p string) client.CallOption {
|
|
return client.SetCallOption(pathKey{}, p)
|
|
}
|
|
|
|
func pathFromOpts(opts client.CallOptions) (string, bool) {
|
|
p, ok := opts.Context.Value(pathKey{}).(string)
|
|
return p, ok
|
|
}
|
|
|
|
// ------------------------------------------------ Body option --------------------------------------------------------
|
|
type bodyKey struct{}
|
|
|
|
func Body(b string) client.CallOption {
|
|
return client.SetCallOption(bodyKey{}, b)
|
|
}
|
|
|
|
func bodyFromOpts(opts client.CallOptions) (string, bool) {
|
|
b, ok := opts.Context.Value(bodyKey{}).(string)
|
|
return b, ok
|
|
}
|
|
|
|
// ---------------------------------------------- ErrorMap option ------------------------------------------------------
|
|
type errorMapKey struct{}
|
|
|
|
func ErrorMap(m map[string]any) client.CallOption {
|
|
return client.SetCallOption(errorMapKey{}, m)
|
|
}
|
|
|
|
func errorMapFromOpts(opts client.CallOptions) (map[string]any, bool) {
|
|
errMap, ok := opts.Context.Value(errorMapKey{}).(map[string]any)
|
|
return errMap, ok
|
|
}
|
|
|
|
// ------------------------------------------------ Cookie option ------------------------------------------------------
|
|
type cookieKey struct{}
|
|
|
|
func Cookie(cookies ...string) client.CallOption {
|
|
return client.SetCallOption(cookieKey{}, cookies)
|
|
}
|
|
|
|
func cookieFromOpts(opts client.CallOptions) ([]string, bool) {
|
|
c, ok := opts.Context.Value(cookieKey{}).([]string)
|
|
return c, ok
|
|
}
|
|
|
|
// ------------------------------------------------ Header option ------------------------------------------------------
|
|
type headerKey struct{}
|
|
|
|
func Header(headers ...string) client.CallOption {
|
|
return client.SetCallOption(headerKey{}, headers)
|
|
}
|
|
|
|
func headerFromOpts(opts client.CallOptions) ([]string, bool) {
|
|
h, ok := opts.Context.Value(headerKey{}).([]string)
|
|
return h, ok
|
|
}
|