httpx 0.24.1 → 0.24.3
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/doc/release_notes/0_24_2.md +12 -0
- data/doc/release_notes/0_24_3.md +12 -0
- data/lib/httpx/adapters/faraday.rb +129 -67
- data/lib/httpx/plugins/authentication.rb +4 -0
- data/lib/httpx/plugins/response_cache/file_store.rb +1 -0
- data/lib/httpx/resolver/native.rb +7 -5
- data/lib/httpx/version.rb +1 -1
- data/sig/plugins/authentication.rbs +2 -0
- data/sig/resolver/native.rbs +1 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 145a6e293b5ae6bfc1008765a755ab823d490edf7c50bdbf1de01194e3e1537b
|
4
|
+
data.tar.gz: 42d235a66fdb050a993b305d3aefed91893d26253cc62864ff2d0d088167ef0a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7b10d4d91debc907d3445526ab864357a1e39cddfbe8b628f104241ed9015ae340e122dd49535be21bda7b20b95ebc047db4c476b7ff412e310d685f835e62c3
|
7
|
+
data.tar.gz: 3d82a8bc8bc3d5e6f94c2dde6f330ab52a3a42e0cd95e4b62328e4b6b005aac9946d1903d384f0944112e997ca26801dc342d77b44290dddb8e88ec0523e1338
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# 0.24.2
|
2
|
+
|
3
|
+
## Improvements
|
4
|
+
|
5
|
+
* besides an array, `:resolver_options` can now receive a hash for `:nameserver`, which **must** be indexed by IP family (`Socket::AF_INET6` or `Socket::AF_INET`); each group of nameservers will be used for emitting DNS queries of that iP family.
|
6
|
+
* `:authentication` plugin: Added `#bearer_auth` helper, which receives a token, and sets it as `"Bearer $TOKEN` in the `"authorization"` header.
|
7
|
+
* `faraday` adapter: now implements `#build_connection` and `#close`, will now interact with `faraday` native timeouts (`:read`, `:write` and `:connect`).
|
8
|
+
|
9
|
+
|
10
|
+
## Bugfixes
|
11
|
+
|
12
|
+
* fixed native resolver bug when queries involving intermediate alias would be kept after the original query and mess with re-queries.
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# 0.24.3
|
2
|
+
|
3
|
+
## Improvements
|
4
|
+
|
5
|
+
* faraday adapter: reraise httpx timeout errors as faraday errors.
|
6
|
+
* faraday adapter: support `:bind` option, which expects a host and port to connect to.
|
7
|
+
|
8
|
+
## Bugfixes
|
9
|
+
|
10
|
+
* faraday adapter: fix `#close` implementation using the wrong ivar.
|
11
|
+
* faraday adapter: fix usage of `requestt_timeout` translation of faraday timeouts into httpx timeouts.
|
12
|
+
* faraday adapter: `ssl: { verify: false }` was being ignored, and certification verification was still proceeding.
|
@@ -35,8 +35,55 @@ module Faraday
|
|
35
35
|
module RequestMixin
|
36
36
|
using ::HTTPX::HashExtensions
|
37
37
|
|
38
|
+
def build_connection(env)
|
39
|
+
return @connection if defined?(@connection)
|
40
|
+
|
41
|
+
@connection = ::HTTPX.plugin(:compression).plugin(:persistent).plugin(ReasonPlugin)
|
42
|
+
@connection = @connection.with(@connection_options) unless @connection_options.empty?
|
43
|
+
connection_opts = options_from_env(env)
|
44
|
+
|
45
|
+
if (bind = env.request.bind)
|
46
|
+
@bind = TCPSocket.new(bind[:host], bind[:port])
|
47
|
+
connection_opts[:io] = @bind
|
48
|
+
end
|
49
|
+
@connection = @connection.with(connection_opts)
|
50
|
+
|
51
|
+
if (proxy = env.request.proxy)
|
52
|
+
proxy_options = { uri: proxy.uri }
|
53
|
+
proxy_options[:username] = proxy.user if proxy.user
|
54
|
+
proxy_options[:password] = proxy.password if proxy.password
|
55
|
+
|
56
|
+
@connection = @connection.plugin(:proxy).with(proxy: proxy_options)
|
57
|
+
end
|
58
|
+
@connection = @connection.plugin(OnDataPlugin) if env.request.stream_response?
|
59
|
+
|
60
|
+
@connection
|
61
|
+
end
|
62
|
+
|
63
|
+
def close
|
64
|
+
@connection.close if @connection
|
65
|
+
@bind.close if @bind
|
66
|
+
end
|
67
|
+
|
38
68
|
private
|
39
69
|
|
70
|
+
def connect(env, &blk)
|
71
|
+
connection(env, &blk)
|
72
|
+
rescue ::HTTPX::TLSError => e
|
73
|
+
raise SSL_ERROR, e
|
74
|
+
rescue Errno::ECONNABORTED,
|
75
|
+
Errno::ECONNREFUSED,
|
76
|
+
Errno::ECONNRESET,
|
77
|
+
Errno::EHOSTUNREACH,
|
78
|
+
Errno::EINVAL,
|
79
|
+
Errno::ENETUNREACH,
|
80
|
+
Errno::EPIPE,
|
81
|
+
::HTTPX::ConnectionError => e
|
82
|
+
raise CONNECTION_FAILED_ERROR, e
|
83
|
+
rescue ::HTTPX::TimeoutError => e
|
84
|
+
raise Faraday::TimeoutError, e
|
85
|
+
end
|
86
|
+
|
40
87
|
def build_request(env)
|
41
88
|
meth = env[:method]
|
42
89
|
|
@@ -48,28 +95,40 @@ module Faraday
|
|
48
95
|
end
|
49
96
|
|
50
97
|
def options_from_env(env)
|
51
|
-
timeout_options = {
|
52
|
-
|
53
|
-
|
54
|
-
|
98
|
+
timeout_options = {}
|
99
|
+
req_opts = env.request
|
100
|
+
if (sec = request_timeout(:read, req_opts))
|
101
|
+
timeout_options[:operation_timeout] = sec
|
102
|
+
end
|
103
|
+
|
104
|
+
if (sec = request_timeout(:write, req_opts))
|
105
|
+
timeout_options[:operation_timeout] = sec
|
106
|
+
end
|
107
|
+
|
108
|
+
if (sec = request_timeout(:open, req_opts))
|
109
|
+
timeout_options[:connect_timeout] = sec
|
110
|
+
end
|
111
|
+
|
112
|
+
ssl_options = {}
|
113
|
+
|
114
|
+
unless env.ssl.verify.nil?
|
115
|
+
ssl_options[:verify_mode] = env.ssl.verify ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
|
116
|
+
end
|
55
117
|
|
56
|
-
|
57
|
-
|
118
|
+
ssl_options[:ca_file] = env.ssl.ca_file if env.ssl.ca_file
|
119
|
+
ssl_options[:ca_path] = env.ssl.ca_path if env.ssl.ca_path
|
120
|
+
ssl_options[:cert_store] = env.ssl.cert_store if env.ssl.cert_store
|
121
|
+
ssl_options[:cert] = env.ssl.client_cert if env.ssl.client_cert
|
122
|
+
ssl_options[:key] = env.ssl.client_key if env.ssl.client_key
|
123
|
+
ssl_options[:ssl_version] = env.ssl.version if env.ssl.version
|
124
|
+
ssl_options[:verify_depth] = env.ssl.verify_depth if env.ssl.verify_depth
|
125
|
+
ssl_options[:min_version] = env.ssl.min_version if env.ssl.min_version
|
126
|
+
ssl_options[:max_version] = env.ssl.max_version if env.ssl.max_version
|
127
|
+
|
128
|
+
{
|
129
|
+
ssl: ssl_options,
|
58
130
|
timeout: timeout_options,
|
59
131
|
}
|
60
|
-
|
61
|
-
options[:ssl][:verify_mode] = OpenSSL::SSL::VERIFY_PEER if env.ssl.verify
|
62
|
-
options[:ssl][:ca_file] = env.ssl.ca_file if env.ssl.ca_file
|
63
|
-
options[:ssl][:ca_path] = env.ssl.ca_path if env.ssl.ca_path
|
64
|
-
options[:ssl][:cert_store] = env.ssl.cert_store if env.ssl.cert_store
|
65
|
-
options[:ssl][:cert] = env.ssl.client_cert if env.ssl.client_cert
|
66
|
-
options[:ssl][:key] = env.ssl.client_key if env.ssl.client_key
|
67
|
-
options[:ssl][:ssl_version] = env.ssl.version if env.ssl.version
|
68
|
-
options[:ssl][:verify_depth] = env.ssl.verify_depth if env.ssl.verify_depth
|
69
|
-
options[:ssl][:min_version] = env.ssl.min_version if env.ssl.min_version
|
70
|
-
options[:ssl][:max_version] = env.ssl.max_version if env.ssl.max_version
|
71
|
-
|
72
|
-
options
|
73
132
|
end
|
74
133
|
end
|
75
134
|
|
@@ -122,10 +181,6 @@ module Faraday
|
|
122
181
|
end
|
123
182
|
end
|
124
183
|
|
125
|
-
def self.session
|
126
|
-
@session ||= ::HTTPX.plugin(:compression).plugin(:persistent).plugin(ReasonPlugin)
|
127
|
-
end
|
128
|
-
|
129
184
|
class ParallelManager
|
130
185
|
class ResponseHandler < SimpleDelegator
|
131
186
|
attr_reader :env
|
@@ -158,8 +213,9 @@ module Faraday
|
|
158
213
|
|
159
214
|
include RequestMixin
|
160
215
|
|
161
|
-
def initialize
|
216
|
+
def initialize(options)
|
162
217
|
@handlers = []
|
218
|
+
@connection_options = options
|
163
219
|
end
|
164
220
|
|
165
221
|
def enqueue(request)
|
@@ -173,40 +229,54 @@ module Faraday
|
|
173
229
|
|
174
230
|
env = @handlers.last.env
|
175
231
|
|
176
|
-
|
177
|
-
|
178
|
-
session = session.plugin(OnDataPlugin) if env.request.stream_response?
|
232
|
+
connect(env) do |session|
|
233
|
+
requests = @handlers.map { |handler| session.build_request(*build_request(handler.env)) }
|
179
234
|
|
180
|
-
|
235
|
+
if env.request.stream_response?
|
236
|
+
requests.each do |request|
|
237
|
+
request.response_on_data = env.request.on_data
|
238
|
+
end
|
239
|
+
end
|
181
240
|
|
182
|
-
|
183
|
-
|
184
|
-
|
241
|
+
responses = session.request(*requests)
|
242
|
+
Array(responses).each_with_index do |response, index|
|
243
|
+
handler = @handlers[index]
|
244
|
+
handler.on_response.call(response)
|
245
|
+
handler.on_complete.call(handler.env)
|
185
246
|
end
|
186
247
|
end
|
248
|
+
rescue ::HTTPX::TimeoutError => e
|
249
|
+
raise Faraday::TimeoutError, e
|
250
|
+
end
|
251
|
+
|
252
|
+
# from Faraday::Adapter#connection
|
253
|
+
def connection(env)
|
254
|
+
conn = build_connection(env)
|
255
|
+
return conn unless block_given?
|
256
|
+
|
257
|
+
yield conn
|
258
|
+
end
|
259
|
+
|
260
|
+
private
|
187
261
|
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
262
|
+
# from Faraday::Adapter#request_timeout
|
263
|
+
def request_timeout(type, options)
|
264
|
+
key = Faraday::Adapter::TIMEOUT_KEYS.fetch(type) do
|
265
|
+
msg = "Expected :read, :write, :open. Got #{type.inspect} :("
|
266
|
+
raise ArgumentError, msg
|
193
267
|
end
|
268
|
+
options[key] || options[:timeout]
|
194
269
|
end
|
195
270
|
end
|
196
271
|
|
197
272
|
self.supports_parallel = true
|
198
273
|
|
199
274
|
class << self
|
200
|
-
def setup_parallel_manager
|
201
|
-
ParallelManager.new
|
275
|
+
def setup_parallel_manager(options = {})
|
276
|
+
ParallelManager.new(options)
|
202
277
|
end
|
203
278
|
end
|
204
279
|
|
205
|
-
def initialize(app, options = {})
|
206
|
-
super(app)
|
207
|
-
@session_options = options
|
208
|
-
end
|
209
|
-
|
210
280
|
def call(env)
|
211
281
|
super
|
212
282
|
if parallel?(env)
|
@@ -224,38 +294,30 @@ module Faraday
|
|
224
294
|
return handler
|
225
295
|
end
|
226
296
|
|
227
|
-
|
228
|
-
session = session.with(@session_options) unless @session_options.empty?
|
229
|
-
session = session.with(options_from_env(env))
|
230
|
-
session = session.plugin(:proxy).with(proxy: { uri: env.request.proxy }) if env.request.proxy
|
231
|
-
session = session.plugin(OnDataPlugin) if env.request.stream_response?
|
232
|
-
|
233
|
-
request = session.build_request(*build_request(env))
|
234
|
-
|
235
|
-
request.response_on_data = env.request.on_data if env.request.stream_response?
|
236
|
-
|
237
|
-
response = session.request(request)
|
238
|
-
# do not call #raise_for_status for HTTP 4xx or 5xx, as faraday has a middleware for that.
|
239
|
-
response.raise_for_status unless response.is_a?(::HTTPX::Response)
|
297
|
+
response = connect_and_request(env)
|
240
298
|
save_response(env, response.status, response.body.to_s, response.headers, response.reason) do |response_headers|
|
241
299
|
response_headers.merge!(response.headers)
|
242
300
|
end
|
243
301
|
@app.call(env)
|
244
|
-
rescue ::HTTPX::TLSError => e
|
245
|
-
raise SSL_ERROR, e
|
246
|
-
rescue Errno::ECONNABORTED,
|
247
|
-
Errno::ECONNREFUSED,
|
248
|
-
Errno::ECONNRESET,
|
249
|
-
Errno::EHOSTUNREACH,
|
250
|
-
Errno::EINVAL,
|
251
|
-
Errno::ENETUNREACH,
|
252
|
-
Errno::EPIPE,
|
253
|
-
::HTTPX::ConnectionError => e
|
254
|
-
raise CONNECTION_FAILED_ERROR, e
|
255
302
|
end
|
256
303
|
|
257
304
|
private
|
258
305
|
|
306
|
+
def connect_and_request(env)
|
307
|
+
connect(env) do |session|
|
308
|
+
request = session.build_request(*build_request(env))
|
309
|
+
|
310
|
+
request.response_on_data = env.request.on_data if env.request.stream_response?
|
311
|
+
|
312
|
+
response = session.request(request)
|
313
|
+
# do not call #raise_for_status for HTTP 4xx or 5xx, as faraday has a middleware for that.
|
314
|
+
response.raise_for_status unless response.is_a?(::HTTPX::Response)
|
315
|
+
response
|
316
|
+
end
|
317
|
+
rescue ::HTTPX::TimeoutError => e
|
318
|
+
raise Faraday::TimeoutError, e
|
319
|
+
end
|
320
|
+
|
259
321
|
def parallel?(env)
|
260
322
|
env[:parallel_manager]
|
261
323
|
end
|
@@ -29,12 +29,15 @@ module HTTPX
|
|
29
29
|
|
30
30
|
attr_reader :state
|
31
31
|
|
32
|
-
def initialize(
|
32
|
+
def initialize(family, options)
|
33
33
|
super
|
34
34
|
@ns_index = 0
|
35
35
|
@resolver_options = DEFAULTS.merge(@options.resolver_options)
|
36
36
|
@socket_type = @resolver_options.fetch(:socket_type, :udp)
|
37
|
-
@nameserver =
|
37
|
+
@nameserver = if (nameserver = @resolver_options[:nameserver])
|
38
|
+
nameserver = nameserver[family] if nameserver.is_a?(Hash)
|
39
|
+
Array(nameserver)
|
40
|
+
end
|
38
41
|
@ndots = @resolver_options[:ndots]
|
39
42
|
@search = Array(@resolver_options[:search]).map { |srch| srch.scan(/[^.]+/) }
|
40
43
|
@_timeouts = Array(@resolver_options[:timeouts])
|
@@ -318,7 +321,7 @@ module HTTPX
|
|
318
321
|
return
|
319
322
|
end
|
320
323
|
else
|
321
|
-
|
324
|
+
reset_hostname(name, connection: connection)
|
322
325
|
@timeouts.delete(connection.origin.host)
|
323
326
|
@connections.delete(connection)
|
324
327
|
Resolver.cached_lookup_set(connection.origin.host, @family, addresses) if @resolver_options[:cache]
|
@@ -429,9 +432,8 @@ module HTTPX
|
|
429
432
|
end
|
430
433
|
end
|
431
434
|
|
432
|
-
def reset_hostname(hostname, reset_candidates: true)
|
435
|
+
def reset_hostname(hostname, connection: @queries.delete(hostname), reset_candidates: true)
|
433
436
|
@timeouts.delete(hostname)
|
434
|
-
connection = @queries.delete(hostname)
|
435
437
|
@timeouts.delete(hostname)
|
436
438
|
|
437
439
|
return unless connection && reset_candidates
|
data/lib/httpx/version.rb
CHANGED
data/sig/resolver/native.rbs
CHANGED
@@ -63,7 +63,7 @@ module HTTPX
|
|
63
63
|
|
64
64
|
def handle_error: (NativeResolveError | StandardError) -> void
|
65
65
|
|
66
|
-
def reset_hostname: (String hostname, ?reset_candidates: bool) -> void
|
66
|
+
def reset_hostname: (String hostname, ?connection: Connection, ?reset_candidates: bool) -> void
|
67
67
|
end
|
68
68
|
end
|
69
69
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: httpx
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.24.
|
4
|
+
version: 0.24.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tiago Cardoso
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-07-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: http-2-next
|
@@ -101,6 +101,8 @@ extra_rdoc_files:
|
|
101
101
|
- doc/release_notes/0_23_4.md
|
102
102
|
- doc/release_notes/0_24_0.md
|
103
103
|
- doc/release_notes/0_24_1.md
|
104
|
+
- doc/release_notes/0_24_2.md
|
105
|
+
- doc/release_notes/0_24_3.md
|
104
106
|
- doc/release_notes/0_2_0.md
|
105
107
|
- doc/release_notes/0_2_1.md
|
106
108
|
- doc/release_notes/0_3_0.md
|
@@ -194,6 +196,8 @@ files:
|
|
194
196
|
- doc/release_notes/0_23_4.md
|
195
197
|
- doc/release_notes/0_24_0.md
|
196
198
|
- doc/release_notes/0_24_1.md
|
199
|
+
- doc/release_notes/0_24_2.md
|
200
|
+
- doc/release_notes/0_24_3.md
|
197
201
|
- doc/release_notes/0_2_0.md
|
198
202
|
- doc/release_notes/0_2_1.md
|
199
203
|
- doc/release_notes/0_3_0.md
|