httpx 1.2.6 → 1.4.4

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 (130) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -2
  3. data/doc/release_notes/1_3_0.md +18 -0
  4. data/doc/release_notes/1_3_1.md +17 -0
  5. data/doc/release_notes/1_3_2.md +6 -0
  6. data/doc/release_notes/1_3_3.md +5 -0
  7. data/doc/release_notes/1_3_4.md +6 -0
  8. data/doc/release_notes/1_4_0.md +43 -0
  9. data/doc/release_notes/1_4_1.md +19 -0
  10. data/doc/release_notes/1_4_2.md +20 -0
  11. data/doc/release_notes/1_4_3.md +11 -0
  12. data/doc/release_notes/1_4_4.md +14 -0
  13. data/lib/httpx/adapters/datadog.rb +56 -80
  14. data/lib/httpx/adapters/faraday.rb +5 -2
  15. data/lib/httpx/adapters/webmock.rb +24 -8
  16. data/lib/httpx/callbacks.rb +2 -7
  17. data/lib/httpx/chainable.rb +3 -1
  18. data/lib/httpx/connection/http1.rb +11 -7
  19. data/lib/httpx/connection/http2.rb +57 -34
  20. data/lib/httpx/connection.rb +270 -71
  21. data/lib/httpx/errors.rb +15 -4
  22. data/lib/httpx/io/ssl.rb +6 -3
  23. data/lib/httpx/io/tcp.rb +1 -1
  24. data/lib/httpx/io/unix.rb +1 -1
  25. data/lib/httpx/loggable.rb +17 -10
  26. data/lib/httpx/options.rb +30 -23
  27. data/lib/httpx/plugins/aws_sdk_authentication.rb +3 -0
  28. data/lib/httpx/plugins/aws_sigv4.rb +36 -17
  29. data/lib/httpx/plugins/callbacks.rb +13 -2
  30. data/lib/httpx/plugins/circuit_breaker.rb +11 -5
  31. data/lib/httpx/plugins/content_digest.rb +202 -0
  32. data/lib/httpx/plugins/cookies.rb +9 -6
  33. data/lib/httpx/plugins/digest_auth.rb +3 -0
  34. data/lib/httpx/plugins/expect.rb +10 -4
  35. data/lib/httpx/plugins/follow_redirects.rb +68 -33
  36. data/lib/httpx/plugins/grpc/grpc_encoding.rb +2 -0
  37. data/lib/httpx/plugins/grpc.rb +2 -2
  38. data/lib/httpx/plugins/h2c.rb +23 -20
  39. data/lib/httpx/plugins/internal_telemetry.rb +48 -1
  40. data/lib/httpx/plugins/oauth.rb +1 -1
  41. data/lib/httpx/plugins/persistent.rb +16 -0
  42. data/lib/httpx/plugins/proxy/http.rb +19 -16
  43. data/lib/httpx/plugins/proxy/socks4.rb +1 -1
  44. data/lib/httpx/plugins/proxy/socks5.rb +1 -1
  45. data/lib/httpx/plugins/proxy.rb +96 -85
  46. data/lib/httpx/plugins/retries.rb +28 -10
  47. data/lib/httpx/plugins/ssrf_filter.rb +4 -1
  48. data/lib/httpx/plugins/stream.rb +42 -18
  49. data/lib/httpx/plugins/upgrade.rb +5 -10
  50. data/lib/httpx/plugins/webdav.rb +6 -0
  51. data/lib/httpx/plugins/xml.rb +76 -0
  52. data/lib/httpx/pool.rb +73 -244
  53. data/lib/httpx/request/body.rb +50 -55
  54. data/lib/httpx/request.rb +77 -14
  55. data/lib/httpx/resolver/https.rb +17 -20
  56. data/lib/httpx/resolver/multi.rb +34 -16
  57. data/lib/httpx/resolver/native.rb +140 -61
  58. data/lib/httpx/resolver/resolver.rb +64 -19
  59. data/lib/httpx/resolver/system.rb +32 -16
  60. data/lib/httpx/resolver.rb +21 -14
  61. data/lib/httpx/response/body.rb +12 -1
  62. data/lib/httpx/response.rb +16 -9
  63. data/lib/httpx/selector.rb +170 -91
  64. data/lib/httpx/session.rb +282 -139
  65. data/lib/httpx/timers.rb +17 -2
  66. data/lib/httpx/transcoder/body.rb +15 -29
  67. data/lib/httpx/transcoder/form.rb +2 -0
  68. data/lib/httpx/transcoder/gzip.rb +0 -3
  69. data/lib/httpx/transcoder/json.rb +16 -2
  70. data/lib/httpx/transcoder/multipart/encoder.rb +11 -2
  71. data/lib/httpx/transcoder/multipart/part.rb +1 -1
  72. data/lib/httpx/transcoder/utils/deflater.rb +7 -4
  73. data/lib/httpx/transcoder.rb +0 -1
  74. data/lib/httpx/version.rb +1 -1
  75. data/lib/httpx.rb +20 -21
  76. data/sig/callbacks.rbs +2 -3
  77. data/sig/chainable.rbs +6 -2
  78. data/sig/connection/http1.rbs +2 -2
  79. data/sig/connection/http2.rbs +22 -18
  80. data/sig/connection.rbs +40 -9
  81. data/sig/errors.rbs +9 -3
  82. data/sig/httpx.rbs +3 -3
  83. data/sig/io/tcp.rbs +1 -1
  84. data/sig/io/unix.rbs +1 -1
  85. data/sig/loggable.rbs +4 -2
  86. data/sig/options.rbs +8 -13
  87. data/sig/plugins/aws_sigv4.rbs +8 -2
  88. data/sig/plugins/content_digest.rbs +51 -0
  89. data/sig/plugins/cookies/cookie.rbs +9 -0
  90. data/sig/plugins/follow_redirects.rbs +1 -1
  91. data/sig/plugins/grpc/call.rbs +4 -0
  92. data/sig/plugins/persistent.rbs +4 -1
  93. data/sig/plugins/proxy/http.rbs +3 -0
  94. data/sig/plugins/proxy/socks5.rbs +11 -3
  95. data/sig/plugins/proxy.rbs +18 -9
  96. data/sig/plugins/push_promise.rbs +6 -3
  97. data/sig/plugins/rate_limiter.rbs +2 -0
  98. data/sig/plugins/retries.rbs +1 -1
  99. data/sig/plugins/ssrf_filter.rbs +26 -0
  100. data/sig/plugins/stream.rbs +3 -0
  101. data/sig/plugins/webdav.rbs +23 -0
  102. data/sig/plugins/xml.rbs +37 -0
  103. data/sig/pool.rbs +27 -33
  104. data/sig/request/body.rbs +4 -10
  105. data/sig/request.rbs +14 -1
  106. data/sig/resolver/multi.rbs +26 -1
  107. data/sig/resolver/native.rbs +6 -3
  108. data/sig/resolver/resolver.rbs +22 -3
  109. data/sig/resolver.rbs +5 -1
  110. data/sig/response/body.rbs +2 -2
  111. data/sig/response/buffer.rbs +2 -2
  112. data/sig/response.rbs +9 -4
  113. data/sig/selector.rbs +31 -4
  114. data/sig/session.rbs +54 -20
  115. data/sig/timers.rbs +15 -4
  116. data/sig/transcoder/body.rbs +2 -4
  117. data/sig/transcoder/chunker.rbs +1 -1
  118. data/sig/transcoder/deflate.rbs +1 -0
  119. data/sig/transcoder/form.rbs +8 -0
  120. data/sig/transcoder/gzip.rbs +4 -1
  121. data/sig/transcoder/json.rbs +1 -1
  122. data/sig/transcoder/multipart.rbs +6 -4
  123. data/sig/transcoder/utils/body_reader.rbs +3 -3
  124. data/sig/transcoder/utils/deflater.rbs +2 -3
  125. metadata +32 -14
  126. data/lib/httpx/session2.rb +0 -23
  127. data/lib/httpx/transcoder/utils/inflater.rb +0 -19
  128. data/lib/httpx/transcoder/xml.rb +0 -52
  129. data/sig/transcoder/utils/inflater.rbs +0 -12
  130. data/sig/transcoder/xml.rbs +0 -22
@@ -1,14 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "securerandom"
4
- require "http/2/next"
4
+ require "http/2"
5
5
 
6
6
  module HTTPX
7
7
  class Connection::HTTP2
8
8
  include Callbacks
9
9
  include Loggable
10
10
 
11
- MAX_CONCURRENT_REQUESTS = HTTP2Next::DEFAULT_MAX_CONCURRENT_STREAMS
11
+ MAX_CONCURRENT_REQUESTS = ::HTTP2::DEFAULT_MAX_CONCURRENT_STREAMS
12
12
 
13
13
  class Error < Error
14
14
  def initialize(id, code)
@@ -16,6 +16,12 @@ module HTTPX
16
16
  end
17
17
  end
18
18
 
19
+ class PingError < Error
20
+ def initialize
21
+ super(0, :ping_error)
22
+ end
23
+ end
24
+
19
25
  class GoawayError < Error
20
26
  def initialize
21
27
  super(0, :no_error)
@@ -25,7 +31,7 @@ module HTTPX
25
31
  attr_reader :streams, :pending
26
32
 
27
33
  def initialize(buffer, options)
28
- @options = Options.new(options)
34
+ @options = options
29
35
  @settings = @options.http2_settings
30
36
  @pending = []
31
37
  @streams = {}
@@ -98,10 +104,10 @@ module HTTPX
98
104
  @streams.size < @max_requests
99
105
  end
100
106
 
101
- def send(request)
107
+ def send(request, head = false)
102
108
  unless can_buffer_more_requests?
103
- @pending << request
104
- return
109
+ head ? @pending.unshift(request) : @pending << request
110
+ return false
105
111
  end
106
112
  unless (stream = @streams[request])
107
113
  stream = @connection.new_stream
@@ -111,8 +117,9 @@ module HTTPX
111
117
  end
112
118
  handle(request, stream)
113
119
  true
114
- rescue HTTP2Next::Error::StreamLimitExceeded
120
+ rescue ::HTTP2::Error::StreamLimitExceeded
115
121
  @pending.unshift(request)
122
+ false
116
123
  end
117
124
 
118
125
  def consume
@@ -123,19 +130,23 @@ module HTTPX
123
130
  end
124
131
  end
125
132
 
126
- def handle_error(ex)
127
- if ex.instance_of?(TimeoutError) && !@handshake_completed && @connection.state != :closed
133
+ def handle_error(ex, request = nil)
134
+ if ex.is_a?(OperationTimeoutError) && !@handshake_completed && @connection.state != :closed
128
135
  @connection.goaway(:settings_timeout, "closing due to settings timeout")
129
136
  emit(:close_handshake)
130
137
  settings_ex = SettingsTimeoutError.new(ex.timeout, ex.message)
131
138
  settings_ex.set_backtrace(ex.backtrace)
132
139
  ex = settings_ex
133
140
  end
134
- @streams.each_key do |request|
135
- emit(:error, request, ex)
141
+ @streams.each_key do |req|
142
+ next if request && request == req
143
+
144
+ emit(:error, req, ex)
136
145
  end
137
- @pending.each do |request|
138
- emit(:error, request, ex)
146
+ while (req = @pending.shift)
147
+ next if request && request == req
148
+
149
+ emit(:error, req, ex)
139
150
  end
140
151
  end
141
152
 
@@ -150,8 +161,7 @@ module HTTPX
150
161
 
151
162
  def send_pending
152
163
  while (request = @pending.shift)
153
- # TODO: this request should go back to top of stack
154
- break unless send(request)
164
+ break unless send(request, true)
155
165
  end
156
166
  end
157
167
 
@@ -168,7 +178,7 @@ module HTTPX
168
178
  end
169
179
 
170
180
  def init_connection
171
- @connection = HTTP2Next::Client.new(@settings)
181
+ @connection = ::HTTP2::Client.new(@settings)
172
182
  @connection.on(:frame, &method(:on_frame))
173
183
  @connection.on(:frame_sent, &method(:on_frame_sent))
174
184
  @connection.on(:frame_received, &method(:on_frame_received))
@@ -307,26 +317,33 @@ module HTTPX
307
317
  @streams.delete(request)
308
318
 
309
319
  if error
310
- ex = Error.new(stream.id, error)
311
- ex.set_backtrace(caller)
312
- response = ErrorResponse.new(request, ex, request.options)
313
- request.response = response
314
- emit(:response, request, response)
320
+ case error
321
+ when :http_1_1_required
322
+ emit(:error, request, error)
323
+ else
324
+ ex = Error.new(stream.id, error)
325
+ ex.set_backtrace(caller)
326
+ response = ErrorResponse.new(request, ex)
327
+ request.response = response
328
+ emit(:response, request, response)
329
+ end
315
330
  else
316
331
  response = request.response
317
332
  if response && response.is_a?(Response) && response.status == 421
318
- ex = MisdirectedRequestError.new(response)
319
- ex.set_backtrace(caller)
320
- emit(:error, request, ex)
333
+ emit(:error, request, :http_1_1_required)
321
334
  else
322
335
  emit(:response, request, response)
323
336
  end
324
337
  end
325
338
  send(@pending.shift) unless @pending.empty?
339
+
326
340
  return unless @streams.empty? && exhausted?
327
341
 
328
- close
329
- emit(:exhausted) unless @pending.empty?
342
+ if @pending.empty?
343
+ close
344
+ else
345
+ emit(:exhausted)
346
+ end
330
347
  end
331
348
 
332
349
  def on_frame(bytes)
@@ -344,7 +361,12 @@ module HTTPX
344
361
  is_connection_closed = @connection.state == :closed
345
362
  if error
346
363
  @buffer.clear if is_connection_closed
347
- if error == :no_error
364
+ case error
365
+ when :http_1_1_required
366
+ while (request = @pending.shift)
367
+ emit(:error, request, error)
368
+ end
369
+ when :no_error
348
370
  ex = GoawayError.new
349
371
  @pending.unshift(*@streams.keys)
350
372
  @drains.clear
@@ -352,8 +374,11 @@ module HTTPX
352
374
  else
353
375
  ex = Error.new(0, error)
354
376
  end
355
- ex.set_backtrace(caller)
356
- handle_error(ex)
377
+
378
+ if ex
379
+ ex.set_backtrace(caller)
380
+ handle_error(ex)
381
+ end
357
382
  end
358
383
  return unless is_connection_closed && @streams.empty?
359
384
 
@@ -395,11 +420,9 @@ module HTTPX
395
420
  end
396
421
 
397
422
  def on_pong(ping)
398
- if @pings.delete(ping.to_s)
399
- emit(:pong)
400
- else
401
- close(:protocol_error, "ping payload did not match")
402
- end
423
+ raise PingError unless @pings.delete(ping.to_s)
424
+
425
+ emit(:pong)
403
426
  end
404
427
  end
405
428
  end