github.com/influxdata/influxdb/v2@v2.7.6/http/client.go (about) 1 package http 2 3 import ( 4 "crypto/tls" 5 "net" 6 "net/http" 7 "net/url" 8 "time" 9 10 "github.com/influxdata/influxdb/v2/dbrp" 11 "github.com/influxdata/influxdb/v2/kit/tracing" 12 "github.com/influxdata/influxdb/v2/pkg/httpc" 13 ) 14 15 // NewHTTPClient creates a new httpc.Client type. This call sets all 16 // the options that are important to the http pkg on the httpc client. 17 // The default status fn and so forth will all be set for the caller. 18 // In addition, some options can be specified. Those will be added to the defaults. 19 func NewHTTPClient(addr, token string, insecureSkipVerify bool, opts ...httpc.ClientOptFn) (*httpc.Client, error) { 20 u, err := url.Parse(addr) 21 if err != nil { 22 return nil, err 23 } 24 25 defaultOpts := []httpc.ClientOptFn{ 26 httpc.WithAddr(addr), 27 httpc.WithContentType("application/json"), 28 httpc.WithHTTPClient(NewClient(u.Scheme, insecureSkipVerify)), 29 httpc.WithInsecureSkipVerify(insecureSkipVerify), 30 httpc.WithStatusFn(CheckError), 31 } 32 if token != "" { 33 defaultOpts = append(defaultOpts, httpc.WithAuthToken(token)) 34 } 35 opts = append(defaultOpts, opts...) 36 return httpc.New(opts...) 37 } 38 39 // Service connects to an InfluxDB via HTTP. 40 type Service struct { 41 Addr string 42 Token string 43 InsecureSkipVerify bool 44 45 *TaskService 46 *NotificationRuleService 47 *VariableService 48 *WriteService 49 *CheckService 50 *NotificationEndpointService 51 *TelegrafService 52 *LabelService 53 DBRPMappingService *dbrp.Client 54 } 55 56 // NewService returns a service that is an HTTP client to a remote. 57 // Address and token are needed for those services that do not use httpc.Client, 58 // but use those for configuring. 59 // Usually one would do: 60 // 61 // ``` 62 // c := NewHTTPClient(addr, token, insecureSkipVerify) 63 // s := NewService(c, addr token) 64 // ``` 65 // 66 // So one should provide the same `addr` and `token` to both calls to ensure consistency 67 // in the behavior of the returned service. 68 func NewService(httpClient *httpc.Client, addr, token string) (*Service, error) { 69 return &Service{ 70 Addr: addr, 71 Token: token, 72 TaskService: &TaskService{Client: httpClient}, 73 NotificationRuleService: &NotificationRuleService{Client: httpClient}, 74 VariableService: &VariableService{Client: httpClient}, 75 WriteService: &WriteService{ 76 Addr: addr, 77 Token: token, 78 }, 79 CheckService: &CheckService{Client: httpClient}, 80 NotificationEndpointService: &NotificationEndpointService{Client: httpClient}, 81 TelegrafService: NewTelegrafService(httpClient), 82 LabelService: &LabelService{Client: httpClient}, 83 DBRPMappingService: dbrp.NewClient(httpClient), 84 }, nil 85 } 86 87 // NewURL concats addr and path. 88 func NewURL(addr, path string) (*url.URL, error) { 89 u, err := url.Parse(addr) 90 if err != nil { 91 return nil, err 92 } 93 u.Path = path 94 return u, nil 95 } 96 97 // NewClient returns an http.Client that pools connections and injects a span. 98 func NewClient(scheme string, insecure bool) *http.Client { 99 return httpClient(scheme, insecure) 100 } 101 102 // SpanTransport injects the http.RoundTripper.RoundTrip() request 103 // with a span. 104 type SpanTransport struct { 105 base http.RoundTripper 106 } 107 108 // RoundTrip implements the http.RoundTripper, intercepting the base 109 // round trippers call and injecting a span. 110 func (s *SpanTransport) RoundTrip(r *http.Request) (*http.Response, error) { 111 span, _ := tracing.StartSpanFromContext(r.Context()) 112 defer span.Finish() 113 tracing.InjectToHTTPRequest(span, r) 114 return s.base.RoundTrip(r) 115 } 116 117 // DefaultTransport wraps http.DefaultTransport in SpanTransport to inject 118 // tracing headers into all outgoing requests. 119 var DefaultTransport http.RoundTripper = &SpanTransport{base: http.DefaultTransport} 120 121 // DefaultTransportInsecure is identical to DefaultTransport, with 122 // the exception that tls.Config is configured with InsecureSkipVerify 123 // set to true. 124 var DefaultTransportInsecure http.RoundTripper = &SpanTransport{ 125 base: &http.Transport{ 126 Proxy: http.ProxyFromEnvironment, 127 DialContext: (&net.Dialer{ 128 Timeout: 30 * time.Second, 129 KeepAlive: 30 * time.Second, 130 DualStack: true, 131 }).DialContext, 132 ForceAttemptHTTP2: true, 133 MaxIdleConns: 100, 134 IdleConnTimeout: 90 * time.Second, 135 TLSHandshakeTimeout: 10 * time.Second, 136 ExpectContinueTimeout: 1 * time.Second, 137 TLSClientConfig: &tls.Config{ 138 InsecureSkipVerify: true, 139 }, 140 }, 141 } 142 143 func httpClient(scheme string, insecure bool) *http.Client { 144 if scheme == "https" && insecure { 145 return &http.Client{Transport: DefaultTransportInsecure} 146 } 147 return &http.Client{Transport: DefaultTransport} 148 }