httpx 0.24.0 → 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: 159ab63d2464f90d5b73651241f85443c6b79d5d4e0e542cbb93a8e876fd9c97
4
- data.tar.gz: 43c759345b7c52114bea8066ce7e27dd1b026a85bbdf624d1d81f12ce3314248
3
+ metadata.gz: 63f31bb23a4d1676f6d537df456a52e4ee5c4f24e39239072d698abf37cf48fd
4
+ data.tar.gz: b21ec1aeac1a3fdb52be5cccc3e9781bbc8f5e63f81c04a08eb60b89dba00c1b
5
5
  SHA512:
6
- metadata.gz: 4139bbc4d97e28c7c12dcaa9c3a1b71490c9b870cb60d432fb07c946af6b9346f71c8b7554abd30f584fe67b790c8095fa658571769c6a1f527b451604327354
7
- data.tar.gz: 07b636c4eaf69fe3e60c10f4f86a0f8a58e9b1b431d27a9bf7a8b431fba2bdec8f1d4175b5b25de4487d02e90c38b00eaa5b789aacd17b5d3ced34790da55948
6
+ metadata.gz: f0554a088f8ee971e2ccb6534f4d6ef2e43c95c04e6b3930dbeded34485664f340e8c1109a10608c4706098ad43726f2547905eea641b5a45d148ae1f7829e55
7
+ data.tar.gz: 92800524ec31ec676ba7e90a0f51a7d0ea8f6e752253c2b31c0805b807fc2f5fcdbb491f74ceb674e72dd691980cca968a945ec81bd2f9f7ff6eb25b5f9e0a2a
@@ -0,0 +1,12 @@
1
+ # 0.24.1
2
+
3
+ ## Improvements
4
+
5
+ * datadog adapter: support `:service_name` configuration option.
6
+ * datadog adapter: set `:distributed_tracing` to `true` by default.
7
+ * `:proxy` plugin: when the proxy uri uses an unsupported scheme (i.e.: "scp://125.24.2.1"), a more user friendly error is raised (instead of the previous broken stacktrace).
8
+
9
+ ## Bugfixes
10
+
11
+ * datadog adapter: fix tracing enable call, which was wrongly calling `super`.
12
+ + `:proxy` plugin: fix for bug which was turning off plugins overriding `HTTPX::Connection#send` (such as the datadog adapter).
@@ -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.
@@ -160,7 +160,7 @@ module TRACING_MODULE # rubocop:disable Naming/ClassAndModuleCamelCase
160
160
 
161
161
  module RequestMethods
162
162
  def __datadog_enable_trace!
163
- return super if @__datadog_enable_trace
163
+ return if @__datadog_enable_trace
164
164
 
165
165
  RequestTracer.new(self).call
166
166
  @__datadog_enable_trace = true
@@ -203,6 +203,27 @@ module TRACING_MODULE # rubocop:disable Naming/ClassAndModuleCamelCase
203
203
  o.lazy
204
204
  end
205
205
 
206
+ if defined?(TRACING_MODULE::Contrib::SpanAttributeSchema)
207
+ option :service_name do |o|
208
+ o.default do
209
+ TRACING_MODULE::Contrib::SpanAttributeSchema.fetch_service_name(
210
+ "DD_TRACE_HTTPX_SERVICE_NAME",
211
+ "httpx"
212
+ )
213
+ end
214
+ o.lazy
215
+ end
216
+ else
217
+ option :service_name do |o|
218
+ o.default do
219
+ ENV.fetch("DD_TRACE_HTTPX_SERVICE_NAME", "httpx")
220
+ end
221
+ o.lazy
222
+ end
223
+ end
224
+
225
+ option :distributed_tracing, default: true
226
+
206
227
  option :error_handler, default: DEFAULT_ERROR_HANDLER
207
228
  end
208
229
  end
@@ -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
@@ -63,7 +63,7 @@ module HTTPX
63
63
  # Normalizes a _domain_ using the Punycode algorithm as necessary.
64
64
  # The result will be a downcased, ASCII-only string.
65
65
  def normalize(domain)
66
- domain = domain.ascii_only? ? domain : domain.chomp(DOT).unicode_normalize(:nfc)
66
+ domain = domain.chomp(DOT).unicode_normalize(:nfc) unless domain.ascii_only?
67
67
  Punycode.encode_hostname(domain).downcase
68
68
  end
69
69
  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
@@ -6,6 +6,12 @@ module HTTPX
6
6
  module Plugins
7
7
  module Proxy
8
8
  module HTTP
9
+ class << self
10
+ def extra_options(options)
11
+ options.merge(supported_proxy_protocols: options.supported_proxy_protocols + %w[http])
12
+ end
13
+ end
14
+
9
15
  module InstanceMethods
10
16
  def with_proxy_basic_auth(opts)
11
17
  with(proxy: opts.merge(scheme: "basic"))
@@ -16,6 +16,12 @@ module HTTPX
16
16
 
17
17
  Error = Socks4Error
18
18
 
19
+ class << self
20
+ def extra_options(options)
21
+ options.merge(supported_proxy_protocols: options.supported_proxy_protocols + PROTOCOLS)
22
+ end
23
+ end
24
+
19
25
  module ConnectionMethods
20
26
  def interests
21
27
  if @state == :connecting
@@ -18,8 +18,14 @@ module HTTPX
18
18
 
19
19
  Error = Socks5Error
20
20
 
21
- def self.load_dependencies(*)
22
- require_relative "../authentication/socks5"
21
+ class << self
22
+ def load_dependencies(*)
23
+ require_relative "../authentication/socks5"
24
+ end
25
+
26
+ def extra_options(options)
27
+ options.merge(supported_proxy_protocols: options.supported_proxy_protocols + %w[socks5])
28
+ end
23
29
  end
24
30
 
25
31
  module ConnectionMethods
@@ -25,6 +25,10 @@ module HTTPX
25
25
  klass.plugin(:"proxy/socks5")
26
26
  end
27
27
 
28
+ def extra_options(options)
29
+ options.merge(supported_proxy_protocols: [])
30
+ end
31
+
28
32
  if URI::Generic.methods.include?(:use_proxy?)
29
33
  def use_proxy?(*args)
30
34
  URI::Generic.use_proxy?(*args)
@@ -118,6 +122,12 @@ module HTTPX
118
122
  def option_proxy(value)
119
123
  value.is_a?(Parameters) ? value : Hash[value]
120
124
  end
125
+
126
+ def option_supported_proxy_protocols(value)
127
+ raise TypeError, ":supported_proxy_protocols must be an Array" unless value.is_a?(Array)
128
+
129
+ value.map(&:to_s)
130
+ end
121
131
  end
122
132
 
123
133
  module InstanceMethods
@@ -142,8 +152,12 @@ module HTTPX
142
152
  next_proxy = @_proxy_uris.first
143
153
  raise Error, "Failed to connect to proxy" unless next_proxy
144
154
 
155
+ next_proxy = URI(next_proxy)
156
+
157
+ raise Error,
158
+ "#{next_proxy.scheme}: unsupported proxy protocol" unless options.supported_proxy_protocols.include?(next_proxy.scheme)
159
+
145
160
  if proxy.key?(:no_proxy)
146
- next_proxy = URI(next_proxy)
147
161
 
148
162
  no_proxy = proxy[:no_proxy]
149
163
  no_proxy = no_proxy.join(",") if no_proxy.is_a?(Array)
@@ -253,10 +267,11 @@ module HTTPX
253
267
  end
254
268
 
255
269
  def send(request)
256
- return super unless @options.proxy
257
- return super unless connecting?
270
+ return super unless (
271
+ @options.proxy && @state != :idle && connecting?
272
+ )
258
273
 
259
- @pending << request
274
+ (@proxy_pending ||= []) << request
260
275
  end
261
276
 
262
277
  def connecting?
@@ -294,6 +309,12 @@ module HTTPX
294
309
  when :idle
295
310
  transition(:connecting)
296
311
  when :connected
312
+ if @proxy_pending
313
+ while (req = @proxy_pendind.shift)
314
+ send(req)
315
+ end
316
+ end
317
+
297
318
  transition(:open)
298
319
  end
299
320
  end
@@ -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
@@ -9,10 +9,13 @@ module HTTPX
9
9
  # redefine the default options static var, which needs to
10
10
  # refresh options_class
11
11
  options = proxy_session.class.default_options.to_hash
12
- options.freeze
13
12
  original_verbosity = $VERBOSE
14
13
  $VERBOSE = nil
14
+ const_set(:Options, proxy_session.class.default_options.options_class)
15
+ options[:options_class] = Class.new(options[:options_class])
16
+ options.freeze
15
17
  Options.send(:const_set, :DEFAULT_OPTIONS, options)
18
+ Session.instance_variable_set(:@default_options, Options.new(options))
16
19
  $VERBOSE = original_verbosity
17
20
  end
18
21
 
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.0"
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.0
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-15 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
@@ -100,6 +100,8 @@ extra_rdoc_files:
100
100
  - doc/release_notes/0_23_3.md
101
101
  - doc/release_notes/0_23_4.md
102
102
  - doc/release_notes/0_24_0.md
103
+ - doc/release_notes/0_24_1.md
104
+ - doc/release_notes/0_24_2.md
103
105
  - doc/release_notes/0_2_0.md
104
106
  - doc/release_notes/0_2_1.md
105
107
  - doc/release_notes/0_3_0.md
@@ -192,6 +194,8 @@ files:
192
194
  - doc/release_notes/0_23_3.md
193
195
  - doc/release_notes/0_23_4.md
194
196
  - doc/release_notes/0_24_0.md
197
+ - doc/release_notes/0_24_1.md
198
+ - doc/release_notes/0_24_2.md
195
199
  - doc/release_notes/0_2_0.md
196
200
  - doc/release_notes/0_2_1.md
197
201
  - doc/release_notes/0_3_0.md
@@ -392,7 +396,7 @@ metadata:
392
396
  changelog_uri: https://os85.gitlab.io/httpx/#release-notes
393
397
  documentation_uri: https://os85.gitlab.io/httpx/rdoc/
394
398
  source_code_uri: https://gitlab.com/os85/httpx
395
- homepage_uri: https://os85.gitlab.io/httpx/
399
+ homepage_uri: https://honeyryderchuck.gitlab.io/httpx/
396
400
  rubygems_mfa_required: 'true'
397
401
  post_install_message:
398
402
  rdoc_options: []
@@ -409,7 +413,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
409
413
  - !ruby/object:Gem::Version
410
414
  version: '0'
411
415
  requirements: []
412
- rubygems_version: 3.4.6
416
+ rubygems_version: 3.4.10
413
417
  signing_key:
414
418
  specification_version: 4
415
419
  summary: HTTPX, to the future, and beyond