Skip to content

Commit f81e97c

Browse files
committed
reduce copy paste
1 parent 21e0aa8 commit f81e97c

File tree

16 files changed

+794
-1332
lines changed

16 files changed

+794
-1332
lines changed

libbeat/common/transport/httpcommon/httpcommon.go

Lines changed: 0 additions & 329 deletions
Original file line numberDiff line numberDiff line change
@@ -21,215 +21,11 @@ package httpcommon
2121

2222
import (
2323
"net/http"
24-
"time"
2524

26-
"go.elastic.co/apm/module/apmhttp"
27-
"golang.org/x/net/http2"
28-
29-
"github.com/elastic/beats/v7/libbeat/common"
3025
"github.com/elastic/beats/v7/libbeat/common/transport"
3126
"github.com/elastic/beats/v7/libbeat/common/transport/tlscommon"
32-
"github.com/elastic/beats/v7/libbeat/logp"
33-
)
34-
35-
// HTTPTransportSettings provides common HTTP settings for HTTP clients.
36-
type HTTPTransportSettings struct {
37-
// TLS provides ssl/tls setup settings
38-
TLS *tlscommon.Config `config:"ssl" yaml:"ssl,omitempty" json:"ssl,omitempty"`
39-
40-
// Timeout configures the `(http.Transport).Timeout`.
41-
Timeout time.Duration `config:"timeout" yaml:"timeout,omitempty" json:"timeout,omitempty"`
42-
43-
Proxy HTTPClientProxySettings `config:",inline" yaml:",inline"`
44-
45-
// TODO: Add more settings:
46-
// - DisableKeepAlive
47-
// - MaxIdleConns
48-
// - IdleConnTimeout
49-
// - ResponseHeaderTimeout
50-
// - ConnectionTimeout (currently 'Timeout' is used for both)
51-
}
52-
53-
// WithKeepaliveSettings options can be used to modify the Keepalive
54-
type WithKeepaliveSettings struct {
55-
Disable bool
56-
MaxIdleConns int
57-
MaxIdleConnsPerHost int
58-
IdleConnTimeout time.Duration
59-
}
60-
61-
var _ httpTransportOption = WithKeepaliveSettings{}
62-
63-
const defaultHTTPTimeout = 90 * time.Second
64-
65-
type (
66-
// TransportOption are applied to the http.RoundTripper to be build
67-
// from HTTPTransportSettings.
68-
TransportOption interface{ sealTransportOption() }
69-
70-
extraSettings struct {
71-
logger *logp.Logger
72-
http2 bool
73-
}
74-
75-
dialerOption interface {
76-
TransportOption
77-
baseDialer() transport.Dialer
78-
}
79-
dialerModOption interface {
80-
TransportOption
81-
applyDialer(*HTTPTransportSettings, transport.Dialer) transport.Dialer
82-
}
83-
httpTransportOption interface {
84-
TransportOption
85-
applyTransport(*HTTPTransportSettings, *http.Transport)
86-
}
87-
roundTripperOption interface {
88-
TransportOption
89-
applyRoundTripper(*HTTPTransportSettings, http.RoundTripper) http.RoundTripper
90-
}
91-
extraOption interface {
92-
TransportOption
93-
applyExtra(*extraSettings)
94-
}
9527
)
9628

97-
type baseDialerFunc func() transport.Dialer
98-
99-
var _ dialerOption = baseDialerFunc(nil)
100-
101-
func (baseDialerFunc) sealTransportOption() {}
102-
func (fn baseDialerFunc) baseDialer() transport.Dialer {
103-
return fn()
104-
}
105-
106-
type dialerOptFunc func(transport.Dialer) transport.Dialer
107-
108-
var _ dialerModOption = dialerOptFunc(nil)
109-
110-
func (dialerOptFunc) sealTransportOption() {}
111-
func (fn dialerOptFunc) applyDialer(_ *HTTPTransportSettings, d transport.Dialer) transport.Dialer {
112-
return fn(d)
113-
114-
}
115-
116-
type transportOptFunc func(*HTTPTransportSettings, *http.Transport)
117-
118-
var _ httpTransportOption = transportOptFunc(nil)
119-
120-
func (transportOptFunc) sealTransportOption() {}
121-
func (fn transportOptFunc) applyTransport(s *HTTPTransportSettings, t *http.Transport) {
122-
fn(s, t)
123-
}
124-
125-
type rtOptFunc func(http.RoundTripper) http.RoundTripper
126-
127-
var _ roundTripperOption = rtOptFunc(nil)
128-
129-
func (rtOptFunc) sealTransportOption() {}
130-
func (fn rtOptFunc) applyRoundTripper(_ *HTTPTransportSettings, rt http.RoundTripper) http.RoundTripper {
131-
return fn(rt)
132-
}
133-
134-
type extraOptionFunc func(*extraSettings)
135-
136-
func (extraOptionFunc) sealTransportOption() {}
137-
func (fn extraOptionFunc) applyExtra(s *extraSettings) { fn(s) }
138-
139-
// DefaultHTTPTransportSettings returns the default HTTP transport setting.
140-
func DefaultHTTPTransportSettings() HTTPTransportSettings {
141-
return HTTPTransportSettings{
142-
Proxy: DefaultHTTPClientProxySettings(),
143-
Timeout: defaultHTTPTimeout,
144-
}
145-
}
146-
147-
// Unpack reads a config object into the settings.
148-
func (settings *HTTPTransportSettings) Unpack(cfg *common.Config) error {
149-
tmp := struct {
150-
TLS *tlscommon.Config `config:"ssl"`
151-
Timeout time.Duration `config:"timeout"`
152-
}{Timeout: settings.Timeout}
153-
154-
if err := cfg.Unpack(&tmp); err != nil {
155-
return err
156-
}
157-
158-
var proxy HTTPClientProxySettings
159-
if err := cfg.Unpack(&proxy); err != nil {
160-
return err
161-
}
162-
163-
_, err := tlscommon.LoadTLSConfig(tmp.TLS)
164-
if err != nil {
165-
return err
166-
}
167-
168-
*settings = HTTPTransportSettings{
169-
TLS: tmp.TLS,
170-
Timeout: tmp.Timeout,
171-
Proxy: proxy,
172-
}
173-
return nil
174-
}
175-
176-
// RoundTripper creates a http.RoundTripper for use with http.Client.
177-
//
178-
// The dialers will registers with stats if given. Stats is used to collect metrics for io errors,
179-
// bytes in, and bytes out.
180-
func (settings *HTTPTransportSettings) RoundTripper(opts ...TransportOption) (http.RoundTripper, error) {
181-
var dialer transport.Dialer
182-
183-
var extra extraSettings
184-
for _, opt := range opts {
185-
if opt, ok := opt.(extraOption); ok {
186-
opt.applyExtra(&extra)
187-
}
188-
}
189-
190-
for _, opt := range opts {
191-
if dialOpt, ok := opt.(dialerOption); ok {
192-
dialer = dialOpt.baseDialer()
193-
}
194-
}
195-
196-
if dialer == nil {
197-
dialer = transport.NetDialer(settings.Timeout)
198-
}
199-
200-
tls, err := tlscommon.LoadTLSConfig(settings.TLS)
201-
if err != nil {
202-
return nil, err
203-
}
204-
205-
tlsDialer := transport.TLSDialer(dialer, tls, settings.Timeout)
206-
for _, opt := range opts {
207-
if dialOpt, ok := opt.(dialerModOption); ok {
208-
dialer = dialOpt.applyDialer(settings, dialer)
209-
tlsDialer = dialOpt.applyDialer(settings, tlsDialer)
210-
}
211-
}
212-
213-
if logger := extra.logger; logger != nil {
214-
dialer = transport.LoggingDialer(dialer, logger)
215-
tlsDialer = transport.LoggingDialer(tlsDialer, logger)
216-
}
217-
218-
var rt http.RoundTripper
219-
if extra.http2 {
220-
rt, err = settings.http2RoundTripper(tls, dialer, tlsDialer, opts...)
221-
} else {
222-
rt, err = settings.httpRoundTripper(tls, dialer, tlsDialer, opts...)
223-
}
224-
225-
for _, opt := range opts {
226-
if rtOpt, ok := opt.(roundTripperOption); ok {
227-
rt = rtOpt.applyRoundTripper(settings, rt)
228-
}
229-
}
230-
return rt, nil
231-
}
232-
23329
func (settings *HTTPTransportSettings) httpRoundTripper(
23430
tls *tlscommon.TLSConfig,
23531
dialer, tlsDialer transport.Dialer,
@@ -257,128 +53,3 @@ func (settings *HTTPTransportSettings) httpRoundTripper(
25753

25854
return t, nil
25955
}
260-
261-
func (settings *HTTPTransportSettings) http2RoundTripper(
262-
tls *tlscommon.TLSConfig,
263-
dialer, tlsDialer transport.Dialer,
264-
opts ...TransportOption,
265-
) (*http2.Transport, error) {
266-
t1, err := settings.httpRoundTripper(tls, dialer, tlsDialer, opts...)
267-
if err != nil {
268-
return nil, err
269-
}
270-
271-
t2, err := http2.ConfigureTransports(t1)
272-
if err != nil {
273-
return nil, err
274-
}
275-
276-
t2.AllowHTTP = true
277-
return t2, nil
278-
}
279-
280-
// Client creates a new http.Client with configured Transport. The transport is
281-
// instrumented using apmhttp.WrapRoundTripper.
282-
func (settings HTTPTransportSettings) Client(opts ...TransportOption) (*http.Client, error) {
283-
rt, err := settings.RoundTripper(opts...)
284-
if err != nil {
285-
return nil, err
286-
}
287-
288-
return &http.Client{Transport: rt, Timeout: settings.Timeout}, nil
289-
}
290-
291-
func (opts WithKeepaliveSettings) sealTransportOption() {}
292-
func (opts WithKeepaliveSettings) applyTransport(_ *HTTPTransportSettings, t *http.Transport) {
293-
t.DisableKeepAlives = opts.Disable
294-
if opts.IdleConnTimeout != 0 {
295-
t.IdleConnTimeout = opts.IdleConnTimeout
296-
}
297-
if opts.MaxIdleConns != 0 {
298-
t.MaxIdleConns = opts.MaxIdleConns
299-
}
300-
if opts.MaxIdleConnsPerHost != 0 {
301-
t.MaxIdleConnsPerHost = opts.MaxIdleConnsPerHost
302-
}
303-
}
304-
305-
// WithBaseDialer configures the dialer used for TCP and TLS connections.
306-
func WithBaseDialer(d transport.Dialer) TransportOption {
307-
return baseDialerFunc(func() transport.Dialer {
308-
return d
309-
})
310-
}
311-
312-
// WithIOStats instruments the RoundTripper dialers with the given statser, such
313-
// that bytes in, bytes out, and errors can be monitored.
314-
func WithIOStats(stats transport.IOStatser) TransportOption {
315-
return dialerOptFunc(func(d transport.Dialer) transport.Dialer {
316-
if stats == nil {
317-
return d
318-
}
319-
return transport.StatsDialer(d, stats)
320-
})
321-
}
322-
323-
// WithTransportFunc register a custom function that is used to apply
324-
// custom changes to the net.Transport, when the Client is build.
325-
func WithTransportFunc(fn func(*http.Transport)) TransportOption {
326-
return transportOptFunc(func(_ *HTTPTransportSettings, t *http.Transport) {
327-
fn(t)
328-
})
329-
}
330-
331-
// WithHTTP2Only will ensure that a HTTP 2 only roundtripper is created.
332-
func WithHTTP2Only(b bool) TransportOption {
333-
return extraOptionFunc(func(settings *extraSettings) {
334-
settings.http2 = b
335-
})
336-
}
337-
338-
// WithForceAttemptHTTP2 sets the `http.Tansport.ForceAttemptHTTP2` field.
339-
func WithForceAttemptHTTP2(b bool) TransportOption {
340-
return transportOptFunc(func(settings *HTTPTransportSettings, t *http.Transport) {
341-
t.ForceAttemptHTTP2 = b
342-
})
343-
}
344-
345-
// WithNOProxy disables the configured proxy. Proxy environment variables
346-
// like HTTP_PROXY and HTTPS_PROXY will have no affect.
347-
func WithNOProxy() TransportOption {
348-
return transportOptFunc(func(s *HTTPTransportSettings, t *http.Transport) {
349-
t.Proxy = nil
350-
})
351-
}
352-
353-
// WithoutProxyEnvironmentVariables disables support for the HTTP_PROXY, HTTPS_PROXY and
354-
// NO_PROXY envionrment variables. Explicitely configured proxy URLs will still applied.
355-
func WithoutProxyEnvironmentVariables() TransportOption {
356-
return transportOptFunc(func(settings *HTTPTransportSettings, t *http.Transport) {
357-
if settings.Proxy.Disable || settings.Proxy.URL == nil {
358-
t.Proxy = nil
359-
}
360-
})
361-
}
362-
363-
// WithModRoundtripper allows customization of the roundtipper.
364-
func WithModRoundtripper(w func(http.RoundTripper) http.RoundTripper) TransportOption {
365-
return rtOptFunc(w)
366-
}
367-
368-
var withAPMHTTPRountTripper = WithModRoundtripper(func(rt http.RoundTripper) http.RoundTripper {
369-
return apmhttp.WrapRoundTripper(rt)
370-
})
371-
372-
// WithAPMHTTPInstrumentation insruments the HTTP client via apmhttp.WrapRoundTripper.
373-
// Custom APM round tripper wrappers can be configured via WithModRoundtripper.
374-
func WithAPMHTTPInstrumentation() TransportOption {
375-
return withAPMHTTPRountTripper
376-
}
377-
378-
// WithLogger sets the internal logger that will be used to log dial or TCP level errors.
379-
// Logging at the connection level will only happen if the logger has been set.
380-
func WithLogger(logger *logp.Logger) TransportOption {
381-
return extraOptionFunc(func(s *extraSettings) {
382-
s.logger = logger
383-
})
384-
}

0 commit comments

Comments
 (0)