httpx 0.21.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|