httpx 0.21.0 → 1.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE.txt +0 -48
- data/README.md +54 -45
- data/doc/release_notes/0_10_0.md +2 -2
- data/doc/release_notes/0_11_0.md +3 -5
- data/doc/release_notes/0_12_0.md +5 -5
- data/doc/release_notes/0_13_0.md +4 -4
- data/doc/release_notes/0_14_0.md +2 -2
- data/doc/release_notes/0_16_0.md +3 -3
- data/doc/release_notes/0_17_0.md +1 -1
- data/doc/release_notes/0_18_0.md +4 -4
- data/doc/release_notes/0_18_2.md +1 -1
- data/doc/release_notes/0_19_0.md +1 -1
- data/doc/release_notes/0_20_0.md +1 -1
- data/doc/release_notes/0_21_0.md +7 -5
- data/doc/release_notes/0_21_1.md +12 -0
- data/doc/release_notes/0_22_0.md +13 -0
- data/doc/release_notes/0_22_1.md +11 -0
- data/doc/release_notes/0_22_2.md +5 -0
- data/doc/release_notes/0_22_3.md +55 -0
- data/doc/release_notes/0_22_4.md +6 -0
- data/doc/release_notes/0_22_5.md +6 -0
- data/doc/release_notes/0_23_0.md +42 -0
- data/doc/release_notes/0_23_1.md +5 -0
- data/doc/release_notes/0_23_2.md +5 -0
- data/doc/release_notes/0_23_3.md +6 -0
- data/doc/release_notes/0_23_4.md +5 -0
- data/doc/release_notes/0_24_0.md +48 -0
- data/doc/release_notes/0_24_1.md +12 -0
- data/doc/release_notes/0_24_2.md +12 -0
- data/doc/release_notes/0_24_3.md +12 -0
- data/doc/release_notes/0_24_4.md +18 -0
- data/doc/release_notes/0_24_5.md +6 -0
- data/doc/release_notes/0_24_6.md +5 -0
- data/doc/release_notes/0_24_7.md +10 -0
- data/doc/release_notes/1_0_0.md +60 -0
- data/doc/release_notes/1_0_1.md +5 -0
- data/doc/release_notes/1_0_2.md +7 -0
- data/doc/release_notes/1_1_0.md +32 -0
- data/doc/release_notes/1_1_1.md +17 -0
- data/doc/release_notes/1_1_2.md +12 -0
- data/doc/release_notes/1_1_3.md +18 -0
- data/doc/release_notes/1_1_4.md +6 -0
- data/doc/release_notes/1_1_5.md +12 -0
- data/doc/release_notes/1_2_0.md +49 -0
- data/doc/release_notes/1_2_1.md +6 -0
- data/lib/httpx/adapters/datadog.rb +100 -106
- data/lib/httpx/adapters/faraday.rb +143 -107
- data/lib/httpx/adapters/sentry.rb +26 -7
- data/lib/httpx/adapters/webmock.rb +33 -17
- data/lib/httpx/altsvc.rb +61 -24
- data/lib/httpx/base64.rb +27 -0
- data/lib/httpx/buffer.rb +12 -0
- data/lib/httpx/callbacks.rb +5 -3
- data/lib/httpx/chainable.rb +54 -39
- data/lib/httpx/connection/http1.rb +62 -37
- data/lib/httpx/connection/http2.rb +16 -27
- data/lib/httpx/connection.rb +213 -120
- data/lib/httpx/domain_name.rb +10 -13
- data/lib/httpx/errors.rb +34 -2
- data/lib/httpx/extensions.rb +4 -134
- data/lib/httpx/io/ssl.rb +77 -71
- data/lib/httpx/io/tcp.rb +46 -70
- data/lib/httpx/io/udp.rb +18 -52
- data/lib/httpx/io/unix.rb +6 -13
- data/lib/httpx/io.rb +3 -9
- data/lib/httpx/loggable.rb +4 -19
- data/lib/httpx/options.rb +168 -110
- data/lib/httpx/plugins/{authentication → auth}/basic.rb +1 -5
- data/lib/httpx/plugins/{authentication → auth}/digest.rb +13 -14
- data/lib/httpx/plugins/{authentication → auth}/ntlm.rb +1 -3
- data/lib/httpx/plugins/{authentication → auth}/socks5.rb +0 -2
- data/lib/httpx/plugins/auth.rb +25 -0
- data/lib/httpx/plugins/aws_sdk_authentication.rb +1 -3
- data/lib/httpx/plugins/aws_sigv4.rb +5 -6
- data/lib/httpx/plugins/basic_auth.rb +29 -0
- data/lib/httpx/plugins/brotli.rb +50 -0
- data/lib/httpx/plugins/callbacks.rb +91 -0
- data/lib/httpx/plugins/circuit_breaker/circuit.rb +40 -16
- data/lib/httpx/plugins/circuit_breaker/circuit_store.rb +14 -5
- data/lib/httpx/plugins/circuit_breaker.rb +30 -7
- data/lib/httpx/plugins/cookies/set_cookie_parser.rb +0 -2
- data/lib/httpx/plugins/cookies.rb +20 -10
- data/lib/httpx/plugins/{digest_authentication.rb → digest_auth.rb} +11 -12
- data/lib/httpx/plugins/expect.rb +15 -13
- data/lib/httpx/plugins/follow_redirects.rb +71 -29
- data/lib/httpx/plugins/grpc/call.rb +2 -3
- data/lib/httpx/plugins/grpc/grpc_encoding.rb +88 -0
- data/lib/httpx/plugins/grpc/message.rb +7 -37
- data/lib/httpx/plugins/grpc.rb +35 -29
- data/lib/httpx/plugins/h2c.rb +25 -18
- data/lib/httpx/plugins/internal_telemetry.rb +16 -0
- data/lib/httpx/plugins/{ntlm_authentication.rb → ntlm_auth.rb} +7 -5
- data/lib/httpx/plugins/oauth.rb +170 -0
- data/lib/httpx/plugins/persistent.rb +1 -1
- data/lib/httpx/plugins/proxy/http.rb +15 -10
- data/lib/httpx/plugins/proxy/socks4.rb +8 -6
- data/lib/httpx/plugins/proxy/socks5.rb +10 -8
- data/lib/httpx/plugins/proxy.rb +69 -67
- data/lib/httpx/plugins/push_promise.rb +1 -1
- data/lib/httpx/plugins/rate_limiter.rb +3 -1
- data/lib/httpx/plugins/response_cache/file_store.rb +40 -0
- data/lib/httpx/plugins/response_cache/store.rb +34 -17
- data/lib/httpx/plugins/response_cache.rb +6 -6
- data/lib/httpx/plugins/retries.rb +61 -12
- data/lib/httpx/plugins/ssrf_filter.rb +142 -0
- data/lib/httpx/plugins/stream.rb +27 -32
- data/lib/httpx/plugins/upgrade/h2.rb +4 -4
- data/lib/httpx/plugins/upgrade.rb +8 -10
- data/lib/httpx/plugins/webdav.rb +10 -8
- data/lib/httpx/pool.rb +85 -23
- data/lib/httpx/punycode.rb +9 -291
- data/lib/httpx/request/body.rb +158 -0
- data/lib/httpx/request.rb +86 -121
- data/lib/httpx/resolver/https.rb +54 -17
- data/lib/httpx/resolver/multi.rb +8 -12
- data/lib/httpx/resolver/native.rb +163 -70
- data/lib/httpx/resolver/resolver.rb +28 -13
- data/lib/httpx/resolver/system.rb +15 -10
- data/lib/httpx/resolver.rb +38 -16
- data/lib/httpx/response/body.rb +242 -0
- data/lib/httpx/response/buffer.rb +96 -0
- data/lib/httpx/response.rb +113 -211
- data/lib/httpx/selector.rb +2 -4
- data/lib/httpx/session.rb +91 -64
- data/lib/httpx/session_extensions.rb +4 -1
- data/lib/httpx/timers.rb +28 -8
- data/lib/httpx/transcoder/body.rb +0 -2
- data/lib/httpx/transcoder/chunker.rb +0 -1
- data/lib/httpx/transcoder/deflate.rb +37 -0
- data/lib/httpx/transcoder/form.rb +52 -33
- data/lib/httpx/transcoder/gzip.rb +74 -0
- data/lib/httpx/transcoder/json.rb +2 -5
- data/lib/httpx/transcoder/multipart/decoder.rb +139 -0
- data/lib/httpx/{plugins → transcoder}/multipart/encoder.rb +3 -3
- data/lib/httpx/{plugins → transcoder}/multipart/mime_type_detector.rb +1 -1
- data/lib/httpx/{plugins → transcoder}/multipart/part.rb +3 -2
- data/lib/httpx/transcoder/multipart.rb +17 -0
- data/lib/httpx/transcoder/utils/body_reader.rb +46 -0
- data/lib/httpx/transcoder/utils/deflater.rb +72 -0
- data/lib/httpx/transcoder/utils/inflater.rb +19 -0
- data/lib/httpx/transcoder/xml.rb +0 -5
- data/lib/httpx/transcoder.rb +4 -6
- data/lib/httpx/utils.rb +36 -16
- data/lib/httpx/version.rb +1 -1
- data/lib/httpx.rb +12 -14
- data/sig/altsvc.rbs +33 -0
- data/sig/buffer.rbs +1 -0
- data/sig/callbacks.rbs +3 -3
- data/sig/chainable.rbs +10 -9
- data/sig/connection/http1.rbs +5 -4
- data/sig/connection/http2.rbs +1 -1
- data/sig/connection.rbs +46 -24
- data/sig/errors.rbs +9 -3
- data/sig/httpx.rbs +5 -4
- data/sig/io/ssl.rbs +26 -0
- data/sig/io/tcp.rbs +60 -0
- data/sig/io/udp.rbs +20 -0
- data/sig/io/unix.rbs +10 -0
- data/sig/options.rbs +28 -12
- data/sig/plugins/{authentication → auth}/basic.rbs +0 -2
- data/sig/plugins/{authentication → auth}/digest.rbs +2 -1
- data/sig/plugins/auth.rbs +13 -0
- data/sig/plugins/{basic_authentication.rbs → basic_auth.rbs} +2 -2
- data/sig/plugins/brotli.rbs +22 -0
- data/sig/plugins/callbacks.rbs +38 -0
- data/sig/plugins/circuit_breaker.rbs +13 -3
- data/sig/plugins/compression.rbs +6 -4
- data/sig/plugins/cookies/jar.rbs +2 -2
- data/sig/plugins/cookies.rbs +2 -0
- data/sig/plugins/{digest_authentication.rbs → digest_auth.rbs} +2 -2
- data/sig/plugins/follow_redirects.rbs +11 -2
- data/sig/plugins/grpc/call.rbs +19 -0
- data/sig/plugins/grpc/grpc_encoding.rbs +37 -0
- data/sig/plugins/grpc/message.rbs +17 -0
- data/sig/plugins/grpc.rbs +2 -32
- data/sig/plugins/h2c.rbs +1 -1
- data/sig/plugins/{ntlm_authentication.rbs → ntlm_auth.rbs} +2 -2
- data/sig/plugins/oauth.rbs +54 -0
- data/sig/plugins/proxy/socks4.rbs +4 -4
- data/sig/plugins/proxy/socks5.rbs +2 -2
- data/sig/plugins/proxy/ssh.rbs +1 -1
- data/sig/plugins/proxy.rbs +10 -4
- data/sig/plugins/response_cache.rbs +12 -3
- data/sig/plugins/retries.rbs +28 -8
- data/sig/plugins/stream.rbs +24 -17
- data/sig/plugins/upgrade.rbs +5 -3
- data/sig/pool.rbs +5 -4
- data/sig/request/body.rbs +40 -0
- data/sig/request.rbs +12 -28
- data/sig/resolver/https.rbs +7 -2
- data/sig/resolver/native.rbs +10 -4
- data/sig/resolver/resolver.rbs +6 -4
- data/sig/resolver/system.rbs +2 -0
- data/sig/resolver.rbs +9 -5
- data/sig/response/body.rbs +53 -0
- data/sig/response/buffer.rbs +24 -0
- data/sig/response.rbs +17 -38
- data/sig/session.rbs +24 -18
- data/sig/timers.rbs +17 -7
- data/sig/transcoder/body.rbs +4 -3
- data/sig/transcoder/deflate.rbs +11 -0
- data/sig/transcoder/form.rbs +5 -3
- data/sig/transcoder/gzip.rbs +24 -0
- data/sig/transcoder/json.rbs +4 -2
- data/sig/{plugins → transcoder}/multipart.rbs +3 -12
- data/sig/transcoder/utils/body_reader.rbs +15 -0
- data/sig/transcoder/utils/deflater.rbs +29 -0
- data/sig/transcoder/utils/inflater.rbs +12 -0
- data/sig/transcoder/xml.rbs +1 -1
- data/sig/transcoder.rbs +22 -7
- data/sig/utils.rbs +2 -0
- metadata +127 -40
- data/lib/httpx/plugins/authentication.rb +0 -20
- data/lib/httpx/plugins/basic_authentication.rb +0 -30
- data/lib/httpx/plugins/compression/brotli.rb +0 -54
- data/lib/httpx/plugins/compression/deflate.rb +0 -49
- data/lib/httpx/plugins/compression/gzip.rb +0 -88
- data/lib/httpx/plugins/compression.rb +0 -164
- data/lib/httpx/plugins/multipart/decoder.rb +0 -187
- data/lib/httpx/plugins/multipart.rb +0 -84
- data/lib/httpx/registry.rb +0 -85
- data/sig/plugins/authentication.rbs +0 -11
- data/sig/plugins/compression/brotli.rbs +0 -21
- data/sig/plugins/compression/deflate.rbs +0 -17
- data/sig/plugins/compression/gzip.rbs +0 -29
- data/sig/registry.rbs +0 -13
- /data/sig/plugins/{authentication → auth}/ntlm.rbs +0 -0
- /data/sig/plugins/{authentication → auth}/socks5.rbs +0 -0
@@ -1,51 +1,24 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
require "datadog/tracing/contrib/patcher"
|
3
|
+
require "datadog/tracing/contrib/integration"
|
4
|
+
require "datadog/tracing/contrib/configuration/settings"
|
5
|
+
require "datadog/tracing/contrib/patcher"
|
7
6
|
|
8
|
-
|
9
|
-
else
|
10
|
-
|
11
|
-
require "ddtrace/contrib/integration"
|
12
|
-
require "ddtrace/contrib/configuration/settings"
|
13
|
-
require "ddtrace/contrib/patcher"
|
14
|
-
|
15
|
-
TRACING_MODULE = Datadog
|
16
|
-
end
|
17
|
-
|
18
|
-
module TRACING_MODULE # rubocop:disable Naming/ClassAndModuleCamelCase
|
7
|
+
module Datadog::Tracing
|
19
8
|
module Contrib
|
20
9
|
module HTTPX
|
21
|
-
|
22
|
-
METADATA_MODULE = TRACING_MODULE::Metadata
|
23
|
-
|
24
|
-
TYPE_OUTBOUND = TRACING_MODULE::Metadata::Ext::HTTP::TYPE_OUTBOUND
|
25
|
-
|
26
|
-
TAG_PEER_SERVICE = TRACING_MODULE::Metadata::Ext::TAG_PEER_SERVICE
|
10
|
+
METADATA_MODULE = Datadog::Tracing::Metadata
|
27
11
|
|
28
|
-
|
29
|
-
TAG_METHOD = TRACING_MODULE::Metadata::Ext::HTTP::TAG_METHOD
|
30
|
-
TAG_TARGET_HOST = TRACING_MODULE::Metadata::Ext::NET::TAG_TARGET_HOST
|
31
|
-
TAG_TARGET_PORT = TRACING_MODULE::Metadata::Ext::NET::TAG_TARGET_PORT
|
12
|
+
TYPE_OUTBOUND = Datadog::Tracing::Metadata::Ext::HTTP::TYPE_OUTBOUND
|
32
13
|
|
33
|
-
|
14
|
+
TAG_PEER_SERVICE = Datadog::Tracing::Metadata::Ext::TAG_PEER_SERVICE
|
34
15
|
|
35
|
-
|
16
|
+
TAG_URL = Datadog::Tracing::Metadata::Ext::HTTP::TAG_URL
|
17
|
+
TAG_METHOD = Datadog::Tracing::Metadata::Ext::HTTP::TAG_METHOD
|
18
|
+
TAG_TARGET_HOST = Datadog::Tracing::Metadata::Ext::NET::TAG_TARGET_HOST
|
19
|
+
TAG_TARGET_PORT = Datadog::Tracing::Metadata::Ext::NET::TAG_TARGET_PORT
|
36
20
|
|
37
|
-
|
38
|
-
|
39
|
-
TYPE_OUTBOUND = TRACING_MODULE::Ext::HTTP::TYPE_OUTBOUND
|
40
|
-
TAG_PEER_SERVICE = TRACING_MODULE::Ext::Integration::TAG_PEER_SERVICE
|
41
|
-
TAG_URL = TRACING_MODULE::Ext::HTTP::URL
|
42
|
-
TAG_METHOD = TRACING_MODULE::Ext::HTTP::METHOD
|
43
|
-
TAG_TARGET_HOST = TRACING_MODULE::Ext::NET::TARGET_HOST
|
44
|
-
TAG_TARGET_PORT = TRACING_MODULE::Ext::NET::TARGET_PORT
|
45
|
-
TAG_STATUS_CODE = Datadog::Ext::HTTP::STATUS_CODE
|
46
|
-
PROPAGATOR = TRACING_MODULE::HTTPPropagator
|
47
|
-
|
48
|
-
end
|
21
|
+
TAG_STATUS_CODE = Datadog::Tracing::Metadata::Ext::HTTP::TAG_STATUS_CODE
|
49
22
|
|
50
23
|
# HTTPX Datadog Plugin
|
51
24
|
#
|
@@ -64,14 +37,18 @@ module TRACING_MODULE # rubocop:disable Naming/ClassAndModuleCamelCase
|
|
64
37
|
end
|
65
38
|
|
66
39
|
def call
|
67
|
-
return unless
|
40
|
+
return unless Datadog::Tracing.enabled?
|
68
41
|
|
69
42
|
@request.on(:response, &method(:finish))
|
70
43
|
|
71
|
-
verb = @request.verb
|
44
|
+
verb = @request.verb
|
72
45
|
uri = @request.uri
|
73
46
|
|
74
|
-
@span =
|
47
|
+
@span = Datadog::Tracing.trace(
|
48
|
+
SPAN_REQUEST,
|
49
|
+
service: service_name(@request.uri.host, configuration, Datadog.configuration_for(self)),
|
50
|
+
span_type: TYPE_OUTBOUND
|
51
|
+
)
|
75
52
|
|
76
53
|
@span.resource = verb
|
77
54
|
|
@@ -86,7 +63,8 @@ module TRACING_MODULE # rubocop:disable Naming/ClassAndModuleCamelCase
|
|
86
63
|
# Tag as an external peer service
|
87
64
|
@span.set_tag(TAG_PEER_SERVICE, @span.service)
|
88
65
|
|
89
|
-
|
66
|
+
Datadog::Tracing::Propagation::HTTP.inject!(Datadog::Tracing.active_trace,
|
67
|
+
@request.headers) if @configuration[:distributed_tracing]
|
90
68
|
|
91
69
|
# Set analytics sample rate
|
92
70
|
if Contrib::Analytics.enabled?(@configuration[:analytics_enabled])
|
@@ -113,54 +91,24 @@ module TRACING_MODULE # rubocop:disable Naming/ClassAndModuleCamelCase
|
|
113
91
|
|
114
92
|
private
|
115
93
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
SPAN_REQUEST,
|
121
|
-
service: service_name(@request.uri.host, configuration, Datadog.configuration_for(self)),
|
122
|
-
span_type: TYPE_OUTBOUND
|
123
|
-
)
|
124
|
-
end
|
125
|
-
|
126
|
-
def propagate_headers
|
127
|
-
TRACING_MODULE::Propagation::HTTP.inject!(TRACING_MODULE.active_trace, @request.headers)
|
128
|
-
end
|
129
|
-
|
130
|
-
def configuration
|
131
|
-
@configuration ||= Datadog.configuration.tracing[:httpx, @request.uri.host]
|
132
|
-
end
|
133
|
-
|
134
|
-
def tracing_enabled?
|
135
|
-
TRACING_MODULE.enabled?
|
136
|
-
end
|
137
|
-
else
|
138
|
-
def build_span
|
139
|
-
service_name = configuration[:split_by_domain] ? @request.uri.host : configuration[:service_name]
|
140
|
-
configuration[:tracer].trace(
|
141
|
-
SPAN_REQUEST,
|
142
|
-
service: service_name,
|
143
|
-
span_type: TYPE_OUTBOUND
|
144
|
-
)
|
145
|
-
end
|
146
|
-
|
147
|
-
def propagate_headers
|
148
|
-
Datadog::HTTPPropagator.inject!(@span.context, @request.headers)
|
149
|
-
end
|
94
|
+
def configuration
|
95
|
+
@configuration ||= Datadog.configuration.tracing[:httpx, @request.uri.host]
|
96
|
+
end
|
97
|
+
end
|
150
98
|
|
151
|
-
|
152
|
-
|
153
|
-
|
99
|
+
module RequestMethods
|
100
|
+
def __datadog_enable_trace!
|
101
|
+
return if @__datadog_enable_trace
|
154
102
|
|
155
|
-
|
156
|
-
|
157
|
-
end
|
103
|
+
RequestTracer.new(self).call
|
104
|
+
@__datadog_enable_trace = true
|
158
105
|
end
|
159
106
|
end
|
160
107
|
|
161
108
|
module ConnectionMethods
|
162
109
|
def send(request)
|
163
|
-
|
110
|
+
request.__datadog_enable_trace!
|
111
|
+
|
164
112
|
super
|
165
113
|
end
|
166
114
|
end
|
@@ -169,7 +117,7 @@ module TRACING_MODULE # rubocop:disable Naming/ClassAndModuleCamelCase
|
|
169
117
|
module Configuration
|
170
118
|
# Default settings for httpx
|
171
119
|
#
|
172
|
-
class Settings <
|
120
|
+
class Settings < Datadog::Tracing::Contrib::Configuration::Settings
|
173
121
|
DEFAULT_ERROR_HANDLER = lambda do |response|
|
174
122
|
Datadog::Ext::HTTP::ERROR_RANGE.cover?(response.status)
|
175
123
|
end
|
@@ -178,29 +126,82 @@ module TRACING_MODULE # rubocop:disable Naming/ClassAndModuleCamelCase
|
|
178
126
|
option :distributed_tracing, default: true
|
179
127
|
option :split_by_domain, default: false
|
180
128
|
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
129
|
+
if Gem::Version.new(DDTrace::VERSION::STRING) >= Gem::Version.new("1.13.0")
|
130
|
+
option :enabled do |o|
|
131
|
+
o.type :bool
|
132
|
+
o.env "DD_TRACE_HTTPX_ENABLED"
|
133
|
+
o.default true
|
134
|
+
end
|
135
|
+
|
136
|
+
option :analytics_enabled do |o|
|
137
|
+
o.type :bool
|
138
|
+
o.env "DD_TRACE_HTTPX_ANALYTICS_ENABLED"
|
139
|
+
o.default false
|
140
|
+
end
|
141
|
+
|
142
|
+
option :analytics_sample_rate do |o|
|
143
|
+
o.type :float
|
144
|
+
o.env "DD_TRACE_HTTPX_ANALYTICS_SAMPLE_RATE"
|
145
|
+
o.default 1.0
|
146
|
+
end
|
147
|
+
else
|
148
|
+
option :enabled do |o|
|
149
|
+
o.default { env_to_bool("DD_TRACE_HTTPX_ENABLED", true) }
|
150
|
+
o.lazy
|
151
|
+
end
|
152
|
+
|
153
|
+
option :analytics_enabled do |o|
|
154
|
+
o.default { env_to_bool(%w[DD_TRACE_HTTPX_ANALYTICS_ENABLED DD_HTTPX_ANALYTICS_ENABLED], false) }
|
155
|
+
o.lazy
|
156
|
+
end
|
185
157
|
|
186
|
-
|
187
|
-
|
188
|
-
|
158
|
+
option :analytics_sample_rate do |o|
|
159
|
+
o.default { env_to_float(%w[DD_TRACE_HTTPX_ANALYTICS_SAMPLE_RATE DD_HTTPX_ANALYTICS_SAMPLE_RATE], 1.0) }
|
160
|
+
o.lazy
|
161
|
+
end
|
189
162
|
end
|
190
163
|
|
191
|
-
|
192
|
-
|
193
|
-
|
164
|
+
if defined?(Datadog::Tracing::Contrib::SpanAttributeSchema)
|
165
|
+
option :service_name do |o|
|
166
|
+
o.default do
|
167
|
+
Datadog::Tracing::Contrib::SpanAttributeSchema.fetch_service_name(
|
168
|
+
"DD_TRACE_HTTPX_SERVICE_NAME",
|
169
|
+
"httpx"
|
170
|
+
)
|
171
|
+
end
|
172
|
+
o.lazy
|
173
|
+
end
|
174
|
+
else
|
175
|
+
option :service_name do |o|
|
176
|
+
o.default do
|
177
|
+
ENV.fetch("DD_TRACE_HTTPX_SERVICE_NAME", "httpx")
|
178
|
+
end
|
179
|
+
o.lazy
|
180
|
+
end
|
194
181
|
end
|
195
182
|
|
196
|
-
option :
|
183
|
+
option :distributed_tracing, default: true
|
184
|
+
|
185
|
+
if Gem::Version.new(DDTrace::VERSION::STRING) >= Gem::Version.new("1.15.0")
|
186
|
+
option :error_handler do |o|
|
187
|
+
o.type :proc
|
188
|
+
o.default_proc(&DEFAULT_ERROR_HANDLER)
|
189
|
+
end
|
190
|
+
elsif Gem::Version.new(DDTrace::VERSION::STRING) >= Gem::Version.new("1.13.0")
|
191
|
+
option :error_handler do |o|
|
192
|
+
o.type :proc
|
193
|
+
o.experimental_default_proc(&DEFAULT_ERROR_HANDLER)
|
194
|
+
end
|
195
|
+
else
|
196
|
+
option :error_handler, default: DEFAULT_ERROR_HANDLER
|
197
|
+
end
|
197
198
|
end
|
198
199
|
end
|
199
200
|
|
200
201
|
# Patcher enables patching of 'httpx' with datadog components.
|
201
202
|
#
|
202
203
|
module Patcher
|
203
|
-
include
|
204
|
+
include Datadog::Tracing::Contrib::Patcher
|
204
205
|
|
205
206
|
module_function
|
206
207
|
|
@@ -223,7 +224,6 @@ module TRACING_MODULE # rubocop:disable Naming/ClassAndModuleCamelCase
|
|
223
224
|
class Integration
|
224
225
|
include Contrib::Integration
|
225
226
|
|
226
|
-
# MINIMUM_VERSION = Gem::Version.new('0.11.0')
|
227
227
|
MINIMUM_VERSION = Gem::Version.new("0.10.2")
|
228
228
|
|
229
229
|
register_as :httpx
|
@@ -240,14 +240,8 @@ module TRACING_MODULE # rubocop:disable Naming/ClassAndModuleCamelCase
|
|
240
240
|
super && version >= MINIMUM_VERSION
|
241
241
|
end
|
242
242
|
|
243
|
-
|
244
|
-
|
245
|
-
Configuration::Settings.new
|
246
|
-
end
|
247
|
-
else
|
248
|
-
def default_configuration
|
249
|
-
Configuration::Settings.new
|
250
|
-
end
|
243
|
+
def new_configuration
|
244
|
+
Configuration::Settings.new
|
251
245
|
end
|
252
246
|
|
253
247
|
def patcher
|
@@ -7,36 +7,54 @@ require "faraday"
|
|
7
7
|
module Faraday
|
8
8
|
class Adapter
|
9
9
|
class HTTPX < Faraday::Adapter
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
else
|
14
|
-
Faraday::Error::SSLError
|
15
|
-
end
|
10
|
+
module RequestMixin
|
11
|
+
def build_connection(env)
|
12
|
+
return @connection if defined?(@connection)
|
16
13
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
Faraday::Error::ConnectionFailed
|
21
|
-
end
|
22
|
-
# :nocov:
|
14
|
+
@connection = ::HTTPX.plugin(:persistent).plugin(ReasonPlugin)
|
15
|
+
@connection = @connection.with(@connection_options) unless @connection_options.empty?
|
16
|
+
connection_opts = options_from_env(env)
|
23
17
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
18
|
+
if (bind = env.request.bind)
|
19
|
+
@bind = TCPSocket.new(bind[:host], bind[:port])
|
20
|
+
connection_opts[:io] = @bind
|
21
|
+
end
|
22
|
+
@connection = @connection.with(connection_opts)
|
23
|
+
|
24
|
+
if (proxy = env.request.proxy)
|
25
|
+
proxy_options = { uri: proxy.uri }
|
26
|
+
proxy_options[:username] = proxy.user if proxy.user
|
27
|
+
proxy_options[:password] = proxy.password if proxy.password
|
28
|
+
|
29
|
+
@connection = @connection.plugin(:proxy).with(proxy: proxy_options)
|
30
30
|
end
|
31
|
+
@connection = @connection.plugin(OnDataPlugin) if env.request.stream_response?
|
32
|
+
|
33
|
+
@connection
|
31
34
|
end
|
32
|
-
using RequestOptionsExtensions
|
33
|
-
end
|
34
35
|
|
35
|
-
|
36
|
-
|
36
|
+
def close
|
37
|
+
@connection.close if @connection
|
38
|
+
@bind.close if @bind
|
39
|
+
end
|
37
40
|
|
38
41
|
private
|
39
42
|
|
43
|
+
def connect(env, &blk)
|
44
|
+
connection(env, &blk)
|
45
|
+
rescue ::HTTPX::TLSError => e
|
46
|
+
raise Faraday::SSLError, e
|
47
|
+
rescue Errno::ECONNABORTED,
|
48
|
+
Errno::ECONNREFUSED,
|
49
|
+
Errno::ECONNRESET,
|
50
|
+
Errno::EHOSTUNREACH,
|
51
|
+
Errno::EINVAL,
|
52
|
+
Errno::ENETUNREACH,
|
53
|
+
Errno::EPIPE,
|
54
|
+
::HTTPX::ConnectionError => e
|
55
|
+
raise Faraday::ConnectionFailed, e
|
56
|
+
end
|
57
|
+
|
40
58
|
def build_request(env)
|
41
59
|
meth = env[:method]
|
42
60
|
|
@@ -44,32 +62,53 @@ module Faraday
|
|
44
62
|
headers: env.request_headers,
|
45
63
|
body: env.body,
|
46
64
|
}
|
47
|
-
[meth, env.url, request_options]
|
65
|
+
[meth.to_s.upcase, env.url, request_options]
|
48
66
|
end
|
49
67
|
|
50
68
|
def options_from_env(env)
|
51
|
-
timeout_options = {
|
52
|
-
|
53
|
-
|
54
|
-
|
69
|
+
timeout_options = {}
|
70
|
+
req_opts = env.request
|
71
|
+
if (sec = request_timeout(:read, req_opts))
|
72
|
+
timeout_options[:read_timeout] = sec
|
73
|
+
end
|
55
74
|
|
56
|
-
|
57
|
-
|
75
|
+
if (sec = request_timeout(:write, req_opts))
|
76
|
+
timeout_options[:write_timeout] = sec
|
77
|
+
end
|
78
|
+
|
79
|
+
if (sec = request_timeout(:open, req_opts))
|
80
|
+
timeout_options[:connect_timeout] = sec
|
81
|
+
end
|
82
|
+
|
83
|
+
{
|
84
|
+
ssl: ssl_options_from_env(env),
|
58
85
|
timeout: timeout_options,
|
59
86
|
}
|
87
|
+
end
|
88
|
+
|
89
|
+
if defined?(::OpenSSL)
|
90
|
+
def ssl_options_from_env(env)
|
91
|
+
ssl_options = {}
|
92
|
+
|
93
|
+
unless env.ssl.verify.nil?
|
94
|
+
ssl_options[:verify_mode] = env.ssl.verify ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
|
95
|
+
end
|
60
96
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
97
|
+
ssl_options[:ca_file] = env.ssl.ca_file if env.ssl.ca_file
|
98
|
+
ssl_options[:ca_path] = env.ssl.ca_path if env.ssl.ca_path
|
99
|
+
ssl_options[:cert_store] = env.ssl.cert_store if env.ssl.cert_store
|
100
|
+
ssl_options[:cert] = env.ssl.client_cert if env.ssl.client_cert
|
101
|
+
ssl_options[:key] = env.ssl.client_key if env.ssl.client_key
|
102
|
+
ssl_options[:ssl_version] = env.ssl.version if env.ssl.version
|
103
|
+
ssl_options[:verify_depth] = env.ssl.verify_depth if env.ssl.verify_depth
|
104
|
+
ssl_options[:min_version] = env.ssl.min_version if env.ssl.min_version
|
105
|
+
ssl_options[:max_version] = env.ssl.max_version if env.ssl.max_version
|
106
|
+
ssl_options
|
107
|
+
end
|
108
|
+
else
|
109
|
+
def ssl_options_from_env(*)
|
110
|
+
{}
|
111
|
+
end
|
73
112
|
end
|
74
113
|
end
|
75
114
|
|
@@ -100,32 +139,17 @@ module Faraday
|
|
100
139
|
end
|
101
140
|
|
102
141
|
module ReasonPlugin
|
103
|
-
|
104
|
-
|
105
|
-
require "webrick"
|
106
|
-
end
|
107
|
-
else
|
108
|
-
def self.load_dependencies(*)
|
109
|
-
require "net/http/status"
|
110
|
-
end
|
142
|
+
def self.load_dependencies(*)
|
143
|
+
require "net/http/status"
|
111
144
|
end
|
145
|
+
|
112
146
|
module ResponseMethods
|
113
|
-
|
114
|
-
|
115
|
-
WEBrick::HTTPStatus::StatusMessage.fetch(@status)
|
116
|
-
end
|
117
|
-
else
|
118
|
-
def reason
|
119
|
-
Net::HTTP::STATUS_CODES.fetch(@status)
|
120
|
-
end
|
147
|
+
def reason
|
148
|
+
Net::HTTP::STATUS_CODES.fetch(@status)
|
121
149
|
end
|
122
150
|
end
|
123
151
|
end
|
124
152
|
|
125
|
-
def self.session
|
126
|
-
@session ||= ::HTTPX.plugin(:compression).plugin(:persistent).plugin(ReasonPlugin)
|
127
|
-
end
|
128
|
-
|
129
153
|
class ParallelManager
|
130
154
|
class ResponseHandler < SimpleDelegator
|
131
155
|
attr_reader :env
|
@@ -158,8 +182,9 @@ module Faraday
|
|
158
182
|
|
159
183
|
include RequestMixin
|
160
184
|
|
161
|
-
def initialize
|
185
|
+
def initialize(options)
|
162
186
|
@handlers = []
|
187
|
+
@connection_options = options
|
163
188
|
end
|
164
189
|
|
165
190
|
def enqueue(request)
|
@@ -169,85 +194,96 @@ module Faraday
|
|
169
194
|
end
|
170
195
|
|
171
196
|
def run
|
197
|
+
return unless @handlers.last
|
198
|
+
|
172
199
|
env = @handlers.last.env
|
173
200
|
|
174
|
-
|
175
|
-
|
176
|
-
session = session.plugin(OnDataPlugin) if env.request.stream_response?
|
201
|
+
connect(env) do |session|
|
202
|
+
requests = @handlers.map { |handler| session.build_request(*build_request(handler.env)) }
|
177
203
|
|
178
|
-
|
204
|
+
if env.request.stream_response?
|
205
|
+
requests.each do |request|
|
206
|
+
request.response_on_data = env.request.on_data
|
207
|
+
end
|
208
|
+
end
|
179
209
|
|
180
|
-
|
181
|
-
|
182
|
-
|
210
|
+
responses = session.request(*requests)
|
211
|
+
Array(responses).each_with_index do |response, index|
|
212
|
+
handler = @handlers[index]
|
213
|
+
handler.on_response.call(response)
|
214
|
+
handler.on_complete.call(handler.env)
|
183
215
|
end
|
184
216
|
end
|
217
|
+
rescue ::HTTPX::TimeoutError => e
|
218
|
+
raise Faraday::TimeoutError, e
|
219
|
+
end
|
185
220
|
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
221
|
+
# from Faraday::Adapter#connection
|
222
|
+
def connection(env)
|
223
|
+
conn = build_connection(env)
|
224
|
+
return conn unless block_given?
|
225
|
+
|
226
|
+
yield conn
|
227
|
+
end
|
228
|
+
|
229
|
+
private
|
230
|
+
|
231
|
+
# from Faraday::Adapter#request_timeout
|
232
|
+
def request_timeout(type, options)
|
233
|
+
key = Faraday::Adapter::TIMEOUT_KEYS[type]
|
234
|
+
options[key] || options[:timeout]
|
192
235
|
end
|
193
236
|
end
|
194
237
|
|
195
238
|
self.supports_parallel = true
|
196
239
|
|
197
240
|
class << self
|
198
|
-
def setup_parallel_manager
|
199
|
-
ParallelManager.new
|
241
|
+
def setup_parallel_manager(options = {})
|
242
|
+
ParallelManager.new(options)
|
200
243
|
end
|
201
244
|
end
|
202
245
|
|
203
|
-
def initialize(app, options = {})
|
204
|
-
super(app)
|
205
|
-
@session_options = options
|
206
|
-
end
|
207
|
-
|
208
246
|
def call(env)
|
209
247
|
super
|
210
248
|
if parallel?(env)
|
211
249
|
handler = env[:parallel_manager].enqueue(env)
|
212
250
|
handler.on_response do |response|
|
213
|
-
response.
|
214
|
-
|
215
|
-
|
251
|
+
if response.is_a?(::HTTPX::Response)
|
252
|
+
save_response(env, response.status, response.body.to_s, response.headers, response.reason) do |response_headers|
|
253
|
+
response_headers.merge!(response.headers)
|
254
|
+
end
|
255
|
+
else
|
256
|
+
env[:error] = response.error
|
257
|
+
save_response(env, 0, "", {}, nil)
|
216
258
|
end
|
217
259
|
end
|
218
260
|
return handler
|
219
261
|
end
|
220
262
|
|
221
|
-
|
222
|
-
session = session.with(@session_options) unless @session_options.empty?
|
223
|
-
session = session.with(options_from_env(env))
|
224
|
-
session = session.plugin(:proxy).with(proxy: { uri: env.request.proxy }) if env.request.proxy
|
225
|
-
session = session.plugin(OnDataPlugin) if env.request.stream_response?
|
226
|
-
|
227
|
-
request = session.build_request(*build_request(env))
|
228
|
-
|
229
|
-
request.response_on_data = env.request.on_data if env.request.stream_response?
|
230
|
-
|
231
|
-
response = session.request(request)
|
232
|
-
response.raise_for_status unless response.is_a?(::HTTPX::Response)
|
263
|
+
response = connect_and_request(env)
|
233
264
|
save_response(env, response.status, response.body.to_s, response.headers, response.reason) do |response_headers|
|
234
265
|
response_headers.merge!(response.headers)
|
235
266
|
end
|
236
267
|
@app.call(env)
|
237
|
-
rescue ::HTTPX::TLSError => e
|
238
|
-
raise SSL_ERROR, e
|
239
|
-
rescue Errno::ECONNABORTED,
|
240
|
-
Errno::ECONNREFUSED,
|
241
|
-
Errno::ECONNRESET,
|
242
|
-
Errno::EHOSTUNREACH,
|
243
|
-
Errno::EINVAL,
|
244
|
-
Errno::ENETUNREACH,
|
245
|
-
Errno::EPIPE => e
|
246
|
-
raise CONNECTION_FAILED_ERROR, e
|
247
268
|
end
|
248
269
|
|
249
270
|
private
|
250
271
|
|
272
|
+
def connect_and_request(env)
|
273
|
+
connect(env) do |session|
|
274
|
+
request = session.build_request(*build_request(env))
|
275
|
+
|
276
|
+
request.response_on_data = env.request.on_data if env.request.stream_response?
|
277
|
+
|
278
|
+
response = session.request(request)
|
279
|
+
# do not call #raise_for_status for HTTP 4xx or 5xx, as faraday has a middleware for that.
|
280
|
+
response.raise_for_status unless response.is_a?(::HTTPX::Response)
|
281
|
+
response
|
282
|
+
end
|
283
|
+
rescue ::HTTPX::TimeoutError => e
|
284
|
+
raise Faraday::TimeoutError, e
|
285
|
+
end
|
286
|
+
|
251
287
|
def parallel?(env)
|
252
288
|
env[:parallel_manager]
|
253
289
|
end
|