httpx 1.7.5 → 1.7.7

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.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/doc/release_notes/1_7_4.md +1 -1
  3. data/doc/release_notes/1_7_6.md +24 -0
  4. data/doc/release_notes/1_7_7.md +17 -0
  5. data/lib/httpx/adapters/datadog.rb +14 -1
  6. data/lib/httpx/adapters/faraday.rb +0 -10
  7. data/lib/httpx/adapters/webmock.rb +1 -1
  8. data/lib/httpx/altsvc.rb +4 -2
  9. data/lib/httpx/connection/http1.rb +52 -43
  10. data/lib/httpx/connection/http2.rb +23 -16
  11. data/lib/httpx/connection.rb +80 -43
  12. data/lib/httpx/io/ssl.rb +24 -12
  13. data/lib/httpx/io/tcp.rb +18 -12
  14. data/lib/httpx/io/unix.rb +13 -9
  15. data/lib/httpx/loggable.rb +1 -1
  16. data/lib/httpx/options.rb +23 -7
  17. data/lib/httpx/parser/http1.rb +14 -5
  18. data/lib/httpx/plugins/auth/digest.rb +6 -0
  19. data/lib/httpx/plugins/auth.rb +23 -9
  20. data/lib/httpx/plugins/circuit_breaker/circuit.rb +1 -0
  21. data/lib/httpx/plugins/cookies/cookie.rb +0 -1
  22. data/lib/httpx/plugins/digest_auth.rb +3 -1
  23. data/lib/httpx/plugins/follow_redirects.rb +13 -1
  24. data/lib/httpx/plugins/h2c.rb +2 -12
  25. data/lib/httpx/plugins/proxy/http.rb +1 -1
  26. data/lib/httpx/plugins/proxy.rb +1 -1
  27. data/lib/httpx/plugins/response_cache.rb +11 -4
  28. data/lib/httpx/plugins/retries.rb +6 -6
  29. data/lib/httpx/plugins/ssrf_filter.rb +1 -1
  30. data/lib/httpx/plugins/tracing.rb +1 -6
  31. data/lib/httpx/plugins/upgrade/h2.rb +1 -11
  32. data/lib/httpx/plugins/upgrade.rb +17 -17
  33. data/lib/httpx/pool.rb +7 -9
  34. data/lib/httpx/request.rb +28 -3
  35. data/lib/httpx/resolver/native.rb +1 -1
  36. data/lib/httpx/response.rb +5 -1
  37. data/lib/httpx/selector.rb +18 -10
  38. data/lib/httpx/session.rb +32 -24
  39. data/lib/httpx/version.rb +1 -1
  40. data/sig/altsvc.rbs +2 -0
  41. data/sig/connection/http1.rbs +4 -2
  42. data/sig/connection/http2.rbs +1 -1
  43. data/sig/connection.rbs +9 -2
  44. data/sig/io/ssl.rbs +1 -0
  45. data/sig/io/tcp.rbs +2 -2
  46. data/sig/loggable.rbs +1 -1
  47. data/sig/options.rbs +8 -3
  48. data/sig/parser/http1.rbs +1 -1
  49. data/sig/plugins/auth/basic.rbs +1 -1
  50. data/sig/plugins/auth/digest.rbs +1 -1
  51. data/sig/plugins/auth/ntlm.rbs +2 -0
  52. data/sig/plugins/auth.rbs +5 -2
  53. data/sig/plugins/follow_redirects.rbs +1 -1
  54. data/sig/plugins/proxy.rbs +1 -0
  55. data/sig/plugins/response_cache.rbs +2 -0
  56. data/sig/plugins/retries.rbs +1 -1
  57. data/sig/plugins/tracing.rbs +1 -1
  58. data/sig/pool.rbs +1 -1
  59. data/sig/request.rbs +6 -0
  60. data/sig/session.rbs +0 -2
  61. metadata +5 -1
@@ -17,6 +17,7 @@ module HTTPX
17
17
  @break_in = break_in
18
18
  @circuit_breaker_half_open_drip_rate = circuit_breaker_half_open_drip_rate
19
19
  @attempts = 0
20
+ @opened_at = @attempted_at = @response = nil
20
21
 
21
22
  total_real_attempts = @max_attempts * @circuit_breaker_half_open_drip_rate
22
23
  @drip_factor = (@max_attempts / total_real_attempts).round
@@ -155,7 +155,6 @@ module HTTPX
155
155
  # Tests if it is OK to send this cookie to a given `uri`. A
156
156
  # RuntimeError is raised if the cookie's domain is unknown.
157
157
  def valid_for_uri?(uri)
158
- uri = URI(uri)
159
158
  # RFC 6265 5.4
160
159
 
161
160
  return false if @secure && uri.scheme != "https"
@@ -51,7 +51,9 @@ module HTTPX
51
51
 
52
52
  if probe_response.status == 401 && digest.can_authenticate?(probe_response.headers["www-authenticate"])
53
53
  request.transition(:idle)
54
- request.authorize(digest.authenticate(request, probe_response.headers["www-authenticate"]))
54
+ if (auth_header = digest.authenticate(request, probe_response.headers["www-authenticate"]))
55
+ request.authorize(auth_header)
56
+ end
55
57
  super(request)
56
58
  else
57
59
  probe_response
@@ -157,7 +157,7 @@ module HTTPX
157
157
  response.finish!
158
158
  retry_request.response = response
159
159
  # request has terminated abruptly meanwhile
160
- retry_request.emit(:response, response)
160
+ retry_request.emit_response(response)
161
161
  else
162
162
  log { "redirecting (elapsed time: #{Utils.elapsed_time(retry_start)})!!" }
163
163
  send_request(retry_request, selector, options)
@@ -201,6 +201,17 @@ module HTTPX
201
201
  # returns the top-most original HTTPX::Request from the redirect chain
202
202
  attr_accessor :root_request
203
203
 
204
+ def initialize(*)
205
+ super
206
+ @redirect_request = nil
207
+ end
208
+
209
+ def on_response_arrived=(cb)
210
+ @redirect_request.on_response_arrived = cb if @redirect_request
211
+
212
+ super
213
+ end
214
+
204
215
  # returns the follow-up redirect request, or itself
205
216
  def redirect_request
206
217
  @redirect_request || self
@@ -210,6 +221,7 @@ module HTTPX
210
221
  def redirect_request=(req)
211
222
  @redirect_request = req
212
223
  req.root_request = @root_request || self
224
+ req.on_response_arrived = @on_response_arrived
213
225
  @response = nil
214
226
  end
215
227
 
@@ -68,23 +68,13 @@ module HTTPX
68
68
  end
69
69
 
70
70
  def upgrade_to_h2c(request, response)
71
- prev_parser = @parser
72
-
73
- if prev_parser
74
- prev_parser.reset
75
- @inflight -= prev_parser.requests.size
76
- end
71
+ enqueue_pending_requests_from_parser(@parser)
77
72
 
78
73
  @parser = request.options.h2c_class.new(@write_buffer, @options)
79
74
  set_parser_callbacks(@parser)
80
- @inflight += 1
75
+ @inflight += 1 # request is being completed below
81
76
  @parser.upgrade(request, response)
82
77
  @upgrade_protocol = "h2c"
83
-
84
- prev_parser.pending.each do |req|
85
- req.transition(:idle)
86
- send(req)
87
- end
88
78
  end
89
79
 
90
80
  private
@@ -171,7 +171,7 @@ module HTTPX
171
171
  while (req = pending.shift)
172
172
  response.finish!
173
173
  req.response = response
174
- req.emit(:response, response)
174
+ req.emit_response(response)
175
175
  end
176
176
  reset
177
177
  end
@@ -88,7 +88,7 @@ module HTTPX
88
88
  end
89
89
 
90
90
  def can_authenticate?(*args)
91
- return false unless @authenticator
91
+ return false unless @authenticator && @authenticator.respond_to?(:can_authenticate?)
92
92
 
93
93
  @authenticator.can_authenticate?(*args)
94
94
  end
@@ -140,7 +140,7 @@ module HTTPX
140
140
  cached_response = cached_response.dup
141
141
  cached_response.mark_as_cached!
142
142
  request.response = cached_response
143
- request.emit(:response, cached_response)
143
+ request.emit_response(cached_response)
144
144
  return
145
145
  end
146
146
 
@@ -220,11 +220,12 @@ module HTTPX
220
220
  end
221
221
 
222
222
  module ResponseMethods
223
- attr_writer :original_request
223
+ attr_writer :original_request, :revalidated_at
224
224
 
225
225
  def initialize(*)
226
226
  super
227
227
  @cached = false
228
+ @revalidated_at = nil
228
229
  end
229
230
 
230
231
  # a copy of the request this response was originally cached from
@@ -254,6 +255,8 @@ module HTTPX
254
255
  @body = cached_response.body.dup
255
256
 
256
257
  @body.rewind
258
+
259
+ cached_response.revalidated_at = date
257
260
  end
258
261
 
259
262
  # A response is fresh if its age has not yet exceeded its freshness lifetime.
@@ -314,9 +317,13 @@ module HTTPX
314
317
  # returns the value of the "age" header as an Integer (time since epoch).
315
318
  # if no "age" of header exists, it returns the number of seconds since {#date}.
316
319
  def age
317
- return @headers["age"].to_i if @headers.key?("age")
320
+ if (revalidated_at = @revalidated_at)
321
+ (Time.now - revalidated_at).to_i
322
+ else
323
+ return @headers["age"].to_i if @headers.key?("age")
318
324
 
319
- (Time.now - date).to_i
325
+ (Time.now - date).to_i
326
+ end
320
327
  end
321
328
 
322
329
  # returns the value of the "date" header as a Time object
@@ -148,11 +148,7 @@ module HTTPX
148
148
  log { "failed to get response, #{request.retries} tries to go..." }
149
149
  prepare_to_retry(request, response)
150
150
 
151
- if (retry_after = when_to_retry(request, response, options))
152
- # apply jitter
153
- if (jitter = request.options.retry_jitter)
154
- retry_after = jitter.call(retry_after)
155
- end
151
+ if (retry_after = when_to_retry(request, response, options)) && retry_after.positive?
156
152
 
157
153
  retry_start = Utils.now
158
154
  log { "retrying after #{retry_after} secs..." }
@@ -160,7 +156,7 @@ module HTTPX
160
156
  if (response = request.response)
161
157
  response.finish!
162
158
  # request has terminated abruptly meanwhile
163
- request.emit(:response, response)
159
+ request.emit_response(response)
164
160
  else
165
161
  log { "retrying (elapsed time: #{Utils.elapsed_time(retry_start)})!!" }
166
162
  send_request(request, selector, options)
@@ -205,6 +201,10 @@ module HTTPX
205
201
  def when_to_retry(request, response, options)
206
202
  retry_after = options.retry_after
207
203
  retry_after = retry_after.call(request, response) if retry_after.respond_to?(:call)
204
+ # apply jitter
205
+ if (jitter = request.options.retry_jitter)
206
+ retry_after = jitter.call(retry_after)
207
+ end
208
208
  retry_after
209
209
  end
210
210
 
@@ -107,7 +107,7 @@ module HTTPX
107
107
  error.set_backtrace(caller)
108
108
  response = ErrorResponse.new(request, error)
109
109
  request.response = response
110
- request.emit(:response, response)
110
+ request.emit_response(response)
111
111
  response
112
112
  end
113
113
  allowed_requests = requests.select { |req| responses[requests.index(req)].nil? }
@@ -25,12 +25,7 @@ module HTTPX::Plugins
25
25
  end
26
26
 
27
27
  def merge(tracer)
28
- case tracer
29
- when Wrapper
30
- Wrapper.new(*@tracers, *tracer.tracers)
31
- else
32
- Wrapper.new(*@tracers, tracer)
33
- end
28
+ Wrapper.new(*@tracers, *tracer.tracers)
34
29
  end
35
30
 
36
31
  def freeze
@@ -33,12 +33,7 @@ module HTTPX
33
33
  end
34
34
 
35
35
  def upgrade_to_h2
36
- prev_parser = @parser
37
-
38
- if prev_parser
39
- prev_parser.reset
40
- @inflight -= prev_parser.requests.size
41
- end
36
+ enqueue_pending_requests_from_parser(@parser)
42
37
 
43
38
  @parser = @options.http2_class.new(@write_buffer, @options)
44
39
  set_parser_callbacks(@parser)
@@ -51,11 +46,6 @@ module HTTPX
51
46
  # while the parser is already here.
52
47
  purge_after_closed
53
48
  transition(:idle)
54
-
55
- prev_parser.requests.each do |req|
56
- req.transition(:idle)
57
- send(req)
58
- end
59
49
  end
60
50
  end
61
51
  end
@@ -33,32 +33,32 @@ module HTTPX
33
33
  def fetch_response(request, selector, options)
34
34
  response = super
35
35
 
36
- if response
37
- return response unless response.is_a?(Response)
36
+ return unless response
38
37
 
39
- return response unless response.headers.key?("upgrade")
38
+ return response unless response.is_a?(Response)
40
39
 
41
- upgrade_protocol = response.headers["upgrade"].split(/ *, */).first
40
+ return response unless response.headers.key?("upgrade")
42
41
 
43
- return response unless upgrade_protocol && options.upgrade_handlers.key?(upgrade_protocol)
42
+ upgrade_protocol = response.headers["upgrade"].split(/ *, */).first
44
43
 
45
- protocol_handler = options.upgrade_handlers[upgrade_protocol]
44
+ return response unless upgrade_protocol && options.upgrade_handlers.key?(upgrade_protocol)
46
45
 
47
- return response unless protocol_handler
46
+ protocol_handler = options.upgrade_handlers[upgrade_protocol]
48
47
 
49
- log { "upgrading to #{upgrade_protocol}..." }
50
- connection = find_connection(request.uri, selector, options)
48
+ return response unless protocol_handler
51
49
 
52
- # do not upgrade already upgraded connections
53
- return if connection.upgrade_protocol == upgrade_protocol
50
+ log { "upgrading to #{upgrade_protocol}..." }
51
+ connection = find_connection(request.uri, selector, options)
54
52
 
55
- protocol_handler.call(connection, request, response)
53
+ # do not upgrade already upgraded connections
54
+ return if connection.upgrade_protocol == upgrade_protocol
56
55
 
57
- # keep in the loop if the server is switching, unless
58
- # the connection has been hijacked, in which case you want
59
- # to terminante immediately
60
- return if response.status == 101 && !connection.hijacked
61
- end
56
+ protocol_handler.call(connection, request, response)
57
+
58
+ # keep in the loop if the server is switching, unless
59
+ # the connection has been hijacked, in which case you want
60
+ # to terminante immediately
61
+ return fetch_response(request, selector, options) if response.status == 101 && !connection.hijacked
62
62
 
63
63
  response
64
64
  end
data/lib/httpx/pool.rb CHANGED
@@ -122,12 +122,6 @@ module HTTPX
122
122
 
123
123
  @max_connections_cond.signal
124
124
  @origin_conds[connection.origin.to_s].signal
125
-
126
- # Observed situations where a session handling multiple requests in a loop
127
- # across multiple threads checks the same connection in and out, while another
128
- # thread which is waiting on the same connection never gets the chance to pick
129
- # it up, because ruby's thread scheduler never switched on to it in the process.
130
- Thread.pass
131
125
  end
132
126
  end
133
127
 
@@ -153,16 +147,20 @@ module HTTPX
153
147
  resolvers = @resolvers[resolver_type]
154
148
 
155
149
  idx = resolvers.find_index do |res|
156
- res.options == options
150
+ res.options.resolver_options_match?(options)
157
151
  end
158
152
  resolvers.delete_at(idx) if idx
159
153
  end || checkout_new_resolver(resolver_type, options)
160
154
  end
161
155
 
162
156
  def checkin_resolver(resolver)
163
- resolver_class = resolver.class
157
+ if resolver.is_a?(Resolver::Multi)
158
+ resolver_class = resolver.resolvers.first.class
159
+ else
160
+ resolver_class = resolver.class
164
161
 
165
- resolver = resolver.multi
162
+ resolver = resolver.multi
163
+ end
166
164
 
167
165
  # a multi requires all sub-resolvers being closed in order to be
168
166
  # correctly checked back in.
data/lib/httpx/request.rb CHANGED
@@ -42,6 +42,12 @@ module HTTPX
42
42
  # The IP address from the peer server.
43
43
  attr_accessor :peer_address
44
44
 
45
+ # the connection the request is currently being sent to (none if before or after transaction)
46
+ attr_writer :connection
47
+
48
+ # callback triggered when a response (which may not be the final response) was assigned to the request.
49
+ attr_writer :on_response_arrived
50
+
45
51
  attr_writer :persistent
46
52
 
47
53
  attr_reader :active_timeouts
@@ -91,7 +97,9 @@ module HTTPX
91
97
  raise UnsupportedSchemeError, "#{@uri}: #{@uri.scheme}: unsupported URI scheme" unless ALLOWED_URI_SCHEMES.include?(@uri.scheme)
92
98
 
93
99
  @state = :idle
94
- @response = @drainer = @peer_address = @informational_status = nil
100
+ @connection = @response =
101
+ @drainer = @peer_address =
102
+ @informational_status = @on_response_arrived = nil
95
103
  @ping = false
96
104
  @persistent = @options.persistent
97
105
  @active_timeouts = []
@@ -274,8 +282,7 @@ module HTTPX
274
282
  when :idle
275
283
  @body.rewind
276
284
  @ping = false
277
- @response = nil
278
- @drainer = nil
285
+ @response = @drainer = nil
279
286
  @active_timeouts.clear
280
287
  when :headers
281
288
  return unless @state == :idle
@@ -321,6 +328,24 @@ module HTTPX
321
328
  callbacks(event).delete(clb)
322
329
  end
323
330
  end
331
+
332
+ def handle_error(error)
333
+ if (connection = @connection)
334
+ connection.on_error(error, self)
335
+ else
336
+ response = ErrorResponse.new(self, error)
337
+ self.response = response
338
+ emit_response(response)
339
+ end
340
+ end
341
+
342
+ def emit_response(response)
343
+ emit(:response, response)
344
+
345
+ return unless @on_response_arrived
346
+
347
+ @on_response_arrived.call
348
+ end
324
349
  end
325
350
  end
326
351
 
@@ -66,7 +66,7 @@ module HTTPX
66
66
  end
67
67
 
68
68
  def closed?
69
- @state == :closed
69
+ @state == :idle || @state == :closed
70
70
  end
71
71
 
72
72
  def to_io
@@ -112,6 +112,7 @@ module HTTPX
112
112
  def finish!
113
113
  @finished = true
114
114
  @headers.freeze
115
+ @request.connection = nil
115
116
  end
116
117
 
117
118
  # returns whether the response contains body payload.
@@ -282,6 +283,7 @@ module HTTPX
282
283
  @error = error
283
284
  @options = request.options
284
285
  log_exception(@error)
286
+ finish!
285
287
  end
286
288
 
287
289
  # returns the exception full message.
@@ -299,7 +301,9 @@ module HTTPX
299
301
  true
300
302
  end
301
303
 
302
- def finish!; end
304
+ def finish!
305
+ @request.connection = nil
306
+ end
303
307
 
304
308
  # raises the wrapped exception.
305
309
  def raise_for_status
@@ -81,7 +81,8 @@ module HTTPX
81
81
 
82
82
  def find_resolver(options)
83
83
  res = @selectables.find do |c|
84
- c.is_a?(Resolver::Resolver) && options == c.options
84
+ c.is_a?(Resolver::Resolver) &&
85
+ options.resolver_options_match?(c.options)
85
86
  end
86
87
 
87
88
  res.multi if res
@@ -146,18 +147,25 @@ module HTTPX
146
147
 
147
148
  is_closed = io.state == :closed
148
149
 
149
- next(is_closed) if is_closed
150
-
151
- io.log(level: 2) do
152
- "[#{io.state}] registering in selector##{object_id} for select (#{interests})#{" for #{interval} seconds" unless interval.nil?}"
150
+ if is_closed
151
+ # the process by which io was closed may have already triggered the on_close callback,
152
+ # which already deregistered the io. this check prevents it from deleting the wrong io,
153
+ # because of https://bugs.ruby-lang.org/issues/22021 .
154
+ next(@selectables.include?(io))
153
155
  end
154
156
 
155
- if READABLE.include?(interests)
156
- r = r.nil? ? io : (Array(r) << io)
157
- end
157
+ if interests
158
+ io.log(level: 2) do
159
+ "[#{io.state}] registering in selector##{object_id} for select (#{interests})#{" for #{interval} seconds" unless interval.nil?}"
160
+ end
158
161
 
159
- if WRITABLE.include?(interests)
160
- w = w.nil? ? io : (Array(w) << io)
162
+ if READABLE.include?(interests)
163
+ r = r.nil? ? io : (Array(r) << io)
164
+ end
165
+
166
+ if WRITABLE.include?(interests)
167
+ w = w.nil? ? io : (Array(w) << io)
168
+ end
161
169
  end
162
170
 
163
171
  is_closed
data/lib/httpx/session.rb CHANGED
@@ -192,11 +192,8 @@ module HTTPX
192
192
  when :idle
193
193
  do_init_connection(connection, selector)
194
194
  when :open
195
- if options.io
196
- select_connection(connection, selector)
197
- else
198
- pin(connection, selector)
199
- end
195
+ # external io
196
+ select_connection(connection, selector)
200
197
  when :closing, :closed
201
198
  connection.idling
202
199
  if connection.addresses?
@@ -262,7 +259,7 @@ module HTTPX
262
259
 
263
260
  response = ErrorResponse.new(request, error)
264
261
  request.response = response
265
- request.emit(:response, response)
262
+ request.emit_response(response)
266
263
  end
267
264
 
268
265
  # returns a set of HTTPX::Request objects built from the given +args+ and +options+.
@@ -303,7 +300,6 @@ module HTTPX
303
300
  def send_requests(*requests)
304
301
  selector = get_current_selector { Selector.new }
305
302
  begin
306
- _send_requests(requests, selector)
307
303
  receive_requests(requests, selector)
308
304
  ensure
309
305
  unless @wrapped
@@ -316,42 +312,50 @@ module HTTPX
316
312
  end
317
313
  end
318
314
 
319
- # sends an array of HTTPX::Request objects
320
- def _send_requests(requests, selector)
321
- requests.each do |request|
322
- send_request(request, selector)
323
- end
324
- end
325
-
326
315
  # returns the array of HTTPX::Response objects corresponding to the array of HTTPX::Request +requests+.
327
316
  def receive_requests(requests, selector)
328
- waiting = 0
329
- responses = requests.map do |request|
317
+ pending_idxs = [] #: Array[Integer]
318
+ pending = 0
319
+
320
+ waiting = false
321
+
322
+ responses = requests.each_with_index.map do |request, idx|
323
+ send_request(request, selector)
324
+
330
325
  fetch_response(request, selector, request.options).tap do |response|
331
- waiting += 1 if response.nil?
326
+ if response.nil?
327
+ pending += 1
328
+ request.on_response_arrived = lambda do
329
+ pending_idxs << idx if waiting
330
+ end
331
+ end
332
332
  end
333
333
  end
334
334
 
335
- until waiting.zero? || selector.empty?
335
+ until pending.zero? || selector.empty?
336
336
  # loop on selector until at least one response has been received.
337
+ waiting = true
337
338
  catch(:coalesced) { selector.next_tick }
339
+ waiting = false
338
340
 
339
- responses.each_with_index do |response, idx|
340
- next unless response.nil?
341
-
341
+ while (idx = pending_idxs.shift)
342
342
  request = requests[idx]
343
343
 
344
344
  response = fetch_response(request, selector, request.options)
345
345
 
346
+ # stop on first pending response. this avoids traversing pending idxs all the way
347
+ # (which is more expensive in the beginning, when the array is larger and N) while
348
+ # making the next loop cheaper (because we're dropping).
346
349
  next unless response
347
350
 
348
351
  request.complete!(response)
349
352
  responses[idx] = response
350
- waiting -= 1
353
+ request.on_response_arrived = nil
354
+ pending -= 1
351
355
  end
352
356
  end
353
357
 
354
- raise Error, "something went wrong, responses not found and requests not resent" unless waiting.zero?
358
+ raise Error, "something went wrong, responses not found and requests not resent" unless pending.zero?
355
359
 
356
360
  responses
357
361
  end
@@ -373,7 +377,11 @@ module HTTPX
373
377
  resolver = find_resolver_for(connection, selector)
374
378
 
375
379
  pin(connection, selector)
376
- early_resolve(resolver, connection) || resolver.lazy_resolve(connection)
380
+ if early_resolve(resolver, connection)
381
+ @pool.checkin_resolver(resolver)
382
+ else
383
+ resolver.lazy_resolve(connection)
384
+ end
377
385
  end
378
386
 
379
387
  def early_resolve(resolver, connection)
data/lib/httpx/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module HTTPX
4
- VERSION = "1.7.5"
4
+ VERSION = "1.7.7"
5
5
  end
data/sig/altsvc.rbs CHANGED
@@ -3,6 +3,8 @@ module HTTPX
3
3
  module ConnectionMixin
4
4
  H2_ALTSVC_SCHEMES: Array[String]
5
5
 
6
+ ALTSVC_IGNORE_IVARS: Array[Symbol]
7
+
6
8
  def send: (Request request) -> void
7
9
 
8
10
  def match?: (http_uri uri, Options options) -> bool
@@ -52,7 +52,7 @@ module HTTPX
52
52
 
53
53
  def on_complete: () -> void
54
54
 
55
- def dispatch: () -> void
55
+ def dispatch: (Request request) -> void
56
56
 
57
57
  def ping: () -> void
58
58
 
@@ -74,11 +74,13 @@ module HTTPX
74
74
 
75
75
  def handle: (Request request) -> void
76
76
 
77
+ def join_headline: (Request request) -> String
78
+
77
79
  def join_headers: (Request request) -> void
78
80
 
79
81
  def join_trailers: (Request request) -> void
80
82
 
81
- def join_headers2: (_Each[[String, String]] headers) -> void
83
+ def join_headers2: (Request request, _Each[[String, String]] headers) -> void
82
84
 
83
85
  def join_body: (Request request) -> void
84
86
 
@@ -76,7 +76,7 @@ module HTTPX
76
76
 
77
77
  def on_stream_headers: (::HTTP2::Stream stream, Request request, Array[[String, String]] headers) -> void
78
78
 
79
- def on_stream_trailers: (::HTTP2::Stream stream, Response response, Array[[String, String]] headers) -> void
79
+ def on_stream_trailers: (::HTTP2::Stream stream, Request request, Response response, Array[[String, String]] headers) -> void
80
80
 
81
81
  def on_stream_data: (::HTTP2::Stream stream, Request request, String data) -> void
82
82
 
data/sig/connection.rbs CHANGED
@@ -50,6 +50,7 @@ module HTTPX
50
50
  @altsvc_connection: instance?
51
51
  @sibling: instance?
52
52
  @main_sibling: bool
53
+ @no_more_requests_counter: Integer
53
54
 
54
55
 
55
56
  def addresses: () -> Array[Resolver::Entry]?
@@ -156,6 +157,12 @@ module HTTPX
156
157
 
157
158
  def build_socket: (?Array[Resolver::Entry]? addrs) -> (TCP | SSL | UNIX)
158
159
 
160
+ def ping: () -> void
161
+
162
+ def pong: () -> void
163
+
164
+ def no_more_requests_loop_check: () -> void
165
+
159
166
  def handle_error: (StandardError error, ?Request? request) -> void
160
167
 
161
168
  def force_purge: () -> void
@@ -172,9 +179,9 @@ module HTTPX
172
179
 
173
180
  def set_request_request_timeout: (Request request) -> void
174
181
 
175
- def write_timeout_callback: (Request request, Numeric write_timeout) -> void
182
+ def write_timeout_callback: (Request request, Numeric timeout) -> void
176
183
 
177
- def read_timeout_callback: (Request request, Numeric read_timeout, ?singleton(RequestTimeoutError) error_type) -> void
184
+ def read_timeout_callback: (Request request, Numeric timeout, ?singleton(RequestTimeoutError) error_type) -> void
178
185
 
179
186
  def set_request_timeout: (Symbol label, Request request, Numeric timeout, Symbol start_event, Symbol | Array[Symbol] finish_events) { () -> void } -> void
180
187