httpx 0.24.1 → 0.24.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 588deec0af9ead32480f7cca9ce8c278b344ccdd2e608cc2a6a8db8c6135647f
4
- data.tar.gz: 3b69af49050cd6ba7b0317ddcd2286cbe6a2261add9fd0b9839bb89290e3962a
3
+ metadata.gz: 63f31bb23a4d1676f6d537df456a52e4ee5c4f24e39239072d698abf37cf48fd
4
+ data.tar.gz: b21ec1aeac1a3fdb52be5cccc3e9781bbc8f5e63f81c04a08eb60b89dba00c1b
5
5
  SHA512:
6
- metadata.gz: e630447fb6bc2aabb6efd842fdd322734e78e7859ea03126ab3d45cf4580d91ede945aa4e77700ae6cbe92179cc0a7e96fdc294ccaf729b287c4b4269b9b40b8
7
- data.tar.gz: 138310fead4041c202f32b3e53564023472383f5cc251c59cc88b115c8f2947801da8269518d3dce48ff8b53abe3b1350d92b553a9264be8ab052064a135b605
6
+ metadata.gz: f0554a088f8ee971e2ccb6534f4d6ef2e43c95c04e6b3930dbeded34485664f340e8c1109a10608c4706098ad43726f2547905eea641b5a45d148ae1f7829e55
7
+ data.tar.gz: 92800524ec31ec676ba7e90a0f51a7d0ea8f6e752253c2b31c0805b807fc2f5fcdbb491f74ceb674e72dd691980cca968a945ec81bd2f9f7ff6eb25b5f9e0a2a
@@ -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.
@@ -35,8 +35,46 @@ 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 = @connection.with(options_from_env(env))
44
+
45
+ if (proxy = env.request.proxy)
46
+ proxy_options = { uri: proxy.uri }
47
+ proxy_options[:username] = proxy.user if proxy.user
48
+ proxy_options[:password] = proxy.password if proxy.password
49
+
50
+ @connection = @connection.plugin(:proxy).with(proxy: proxy_options)
51
+ end
52
+ @connection = @connection.plugin(OnDataPlugin) if env.request.stream_response?
53
+
54
+ @connection
55
+ end
56
+
57
+ def close
58
+ @session.close
59
+ end
60
+
38
61
  private
39
62
 
63
+ def connect(env, &blk)
64
+ connection(env, &blk)
65
+ rescue ::HTTPX::TLSError => e
66
+ raise SSL_ERROR, e
67
+ rescue Errno::ECONNABORTED,
68
+ Errno::ECONNREFUSED,
69
+ Errno::ECONNRESET,
70
+ Errno::EHOSTUNREACH,
71
+ Errno::EINVAL,
72
+ Errno::ENETUNREACH,
73
+ Errno::EPIPE,
74
+ ::HTTPX::ConnectionError => e
75
+ raise CONNECTION_FAILED_ERROR, e
76
+ end
77
+
40
78
  def build_request(env)
41
79
  meth = env[:method]
42
80
 
@@ -48,28 +86,36 @@ module Faraday
48
86
  end
49
87
 
50
88
  def options_from_env(env)
51
- timeout_options = {
52
- connect_timeout: env.request.open_timeout,
53
- operation_timeout: env.request.timeout,
54
- }.compact
89
+ timeout_options = {}
90
+ if (sec = request_timeout(:read, env))
91
+ timeout_options[:operation_timeout] = sec
92
+ end
55
93
 
56
- options = {
57
- ssl: {},
94
+ if (sec = request_timeout(:write, env))
95
+ timeout_options[:operation_timeout] = sec
96
+ end
97
+
98
+ if (sec = request_timeout(:open, env))
99
+ timeout_options[:connect_timeout] = sec
100
+ end
101
+
102
+ ssl_options = {}
103
+
104
+ ssl_options[:verify_mode] = OpenSSL::SSL::VERIFY_PEER if env.ssl.verify
105
+ ssl_options[:ca_file] = env.ssl.ca_file if env.ssl.ca_file
106
+ ssl_options[:ca_path] = env.ssl.ca_path if env.ssl.ca_path
107
+ ssl_options[:cert_store] = env.ssl.cert_store if env.ssl.cert_store
108
+ ssl_options[:cert] = env.ssl.client_cert if env.ssl.client_cert
109
+ ssl_options[:key] = env.ssl.client_key if env.ssl.client_key
110
+ ssl_options[:ssl_version] = env.ssl.version if env.ssl.version
111
+ ssl_options[:verify_depth] = env.ssl.verify_depth if env.ssl.verify_depth
112
+ ssl_options[:min_version] = env.ssl.min_version if env.ssl.min_version
113
+ ssl_options[:max_version] = env.ssl.max_version if env.ssl.max_version
114
+
115
+ {
116
+ ssl: ssl_options,
58
117
  timeout: timeout_options,
59
118
  }
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
119
  end
74
120
  end
75
121
 
@@ -122,10 +168,6 @@ module Faraday
122
168
  end
123
169
  end
124
170
 
125
- def self.session
126
- @session ||= ::HTTPX.plugin(:compression).plugin(:persistent).plugin(ReasonPlugin)
127
- end
128
-
129
171
  class ParallelManager
130
172
  class ResponseHandler < SimpleDelegator
131
173
  attr_reader :env
@@ -158,8 +200,9 @@ module Faraday
158
200
 
159
201
  include RequestMixin
160
202
 
161
- def initialize
203
+ def initialize(options)
162
204
  @handlers = []
205
+ @connection_options = options
163
206
  end
164
207
 
165
208
  def enqueue(request)
@@ -173,40 +216,52 @@ module Faraday
173
216
 
174
217
  env = @handlers.last.env
175
218
 
176
- session = HTTPX.session.with(options_from_env(env))
177
- session = session.plugin(:proxy).with(proxy: { uri: env.request.proxy }) if env.request.proxy
178
- session = session.plugin(OnDataPlugin) if env.request.stream_response?
219
+ connect(env) do |session|
220
+ requests = @handlers.map { |handler| session.build_request(*build_request(handler.env)) }
179
221
 
180
- requests = @handlers.map { |handler| session.build_request(*build_request(handler.env)) }
222
+ if env.request.stream_response?
223
+ requests.each do |request|
224
+ request.response_on_data = env.request.on_data
225
+ end
226
+ end
181
227
 
182
- if env.request.stream_response?
183
- requests.each do |request|
184
- request.response_on_data = env.request.on_data
228
+ responses = session.request(*requests)
229
+ Array(responses).each_with_index do |response, index|
230
+ handler = @handlers[index]
231
+ handler.on_response.call(response)
232
+ handler.on_complete.call(handler.env)
185
233
  end
186
234
  end
235
+ end
187
236
 
188
- responses = session.request(*requests)
189
- Array(responses).each_with_index do |response, index|
190
- handler = @handlers[index]
191
- handler.on_response.call(response)
192
- handler.on_complete.call(handler.env)
237
+ # from Faraday::Adapter#connection
238
+ def connection(env)
239
+ conn = build_connection(env)
240
+ return conn unless block_given?
241
+
242
+ yield conn
243
+ end
244
+
245
+ private
246
+
247
+ # from Faraday::Adapter#request_timeout
248
+ def request_timeout(type, options)
249
+ key = Faraday::Adapter::TIMEOUT_KEYS.fetch(type) do
250
+ msg = "Expected :read, :write, :open. Got #{type.inspect} :("
251
+ raise ArgumentError, msg
193
252
  end
253
+ options[key] || options[:timeout]
194
254
  end
195
255
  end
196
256
 
197
257
  self.supports_parallel = true
198
258
 
199
259
  class << self
200
- def setup_parallel_manager
201
- ParallelManager.new
260
+ def setup_parallel_manager(options = {})
261
+ ParallelManager.new(options)
202
262
  end
203
263
  end
204
264
 
205
- def initialize(app, options = {})
206
- super(app)
207
- @session_options = options
208
- end
209
-
210
265
  def call(env)
211
266
  super
212
267
  if parallel?(env)
@@ -224,38 +279,28 @@ module Faraday
224
279
  return handler
225
280
  end
226
281
 
227
- session = HTTPX.session
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)
282
+ response = connect_and_request(env)
240
283
  save_response(env, response.status, response.body.to_s, response.headers, response.reason) do |response_headers|
241
284
  response_headers.merge!(response.headers)
242
285
  end
243
286
  @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
287
  end
256
288
 
257
289
  private
258
290
 
291
+ def connect_and_request(env)
292
+ connect(env) do |session|
293
+ request = session.build_request(*build_request(env))
294
+
295
+ request.response_on_data = env.request.on_data if env.request.stream_response?
296
+
297
+ response = session.request(request)
298
+ # do not call #raise_for_status for HTTP 4xx or 5xx, as faraday has a middleware for that.
299
+ response.raise_for_status unless response.is_a?(::HTTPX::Response)
300
+ response
301
+ end
302
+ end
303
+
259
304
  def parallel?(env)
260
305
  env[:parallel_manager]
261
306
  end
@@ -13,6 +13,10 @@ module HTTPX
13
13
  def authentication(token)
14
14
  with(headers: { "authorization" => token })
15
15
  end
16
+
17
+ def bearer_auth(token)
18
+ authentication("Bearer #{token}")
19
+ end
16
20
  end
17
21
  end
18
22
  register_plugin :authentication, Authentication
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "pathname"
4
+ require_relative "store"
4
5
 
5
6
  module HTTPX::Plugins
6
7
  module ResponseCache
@@ -29,12 +29,15 @@ module HTTPX
29
29
 
30
30
  attr_reader :state
31
31
 
32
- def initialize(_, options)
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 = Array(@resolver_options[:nameserver]) if @resolver_options[: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
- @timeouts.delete(name)
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module HTTPX
4
- VERSION = "0.24.1"
4
+ VERSION = "0.24.2"
5
5
  end
@@ -3,6 +3,8 @@ module HTTPX
3
3
  module Authentication
4
4
  module InstanceMethods
5
5
  def authentication: (string token) -> instance
6
+
7
+ def bearer_auth: (string token) -> instance
6
8
  end
7
9
  end
8
10
 
@@ -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.1
4
+ version: 0.24.2
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-06-27 00:00:00.000000000 Z
11
+ date: 2023-07-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: http-2-next
@@ -101,6 +101,7 @@ 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
104
105
  - doc/release_notes/0_2_0.md
105
106
  - doc/release_notes/0_2_1.md
106
107
  - doc/release_notes/0_3_0.md
@@ -194,6 +195,7 @@ files:
194
195
  - doc/release_notes/0_23_4.md
195
196
  - doc/release_notes/0_24_0.md
196
197
  - doc/release_notes/0_24_1.md
198
+ - doc/release_notes/0_24_2.md
197
199
  - doc/release_notes/0_2_0.md
198
200
  - doc/release_notes/0_2_1.md
199
201
  - doc/release_notes/0_3_0.md