httpx 0.24.1 → 0.24.2

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 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