httpx 0.21.0 → 1.2.1

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 (229) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +0 -48
  3. data/README.md +54 -45
  4. data/doc/release_notes/0_10_0.md +2 -2
  5. data/doc/release_notes/0_11_0.md +3 -5
  6. data/doc/release_notes/0_12_0.md +5 -5
  7. data/doc/release_notes/0_13_0.md +4 -4
  8. data/doc/release_notes/0_14_0.md +2 -2
  9. data/doc/release_notes/0_16_0.md +3 -3
  10. data/doc/release_notes/0_17_0.md +1 -1
  11. data/doc/release_notes/0_18_0.md +4 -4
  12. data/doc/release_notes/0_18_2.md +1 -1
  13. data/doc/release_notes/0_19_0.md +1 -1
  14. data/doc/release_notes/0_20_0.md +1 -1
  15. data/doc/release_notes/0_21_0.md +7 -5
  16. data/doc/release_notes/0_21_1.md +12 -0
  17. data/doc/release_notes/0_22_0.md +13 -0
  18. data/doc/release_notes/0_22_1.md +11 -0
  19. data/doc/release_notes/0_22_2.md +5 -0
  20. data/doc/release_notes/0_22_3.md +55 -0
  21. data/doc/release_notes/0_22_4.md +6 -0
  22. data/doc/release_notes/0_22_5.md +6 -0
  23. data/doc/release_notes/0_23_0.md +42 -0
  24. data/doc/release_notes/0_23_1.md +5 -0
  25. data/doc/release_notes/0_23_2.md +5 -0
  26. data/doc/release_notes/0_23_3.md +6 -0
  27. data/doc/release_notes/0_23_4.md +5 -0
  28. data/doc/release_notes/0_24_0.md +48 -0
  29. data/doc/release_notes/0_24_1.md +12 -0
  30. data/doc/release_notes/0_24_2.md +12 -0
  31. data/doc/release_notes/0_24_3.md +12 -0
  32. data/doc/release_notes/0_24_4.md +18 -0
  33. data/doc/release_notes/0_24_5.md +6 -0
  34. data/doc/release_notes/0_24_6.md +5 -0
  35. data/doc/release_notes/0_24_7.md +10 -0
  36. data/doc/release_notes/1_0_0.md +60 -0
  37. data/doc/release_notes/1_0_1.md +5 -0
  38. data/doc/release_notes/1_0_2.md +7 -0
  39. data/doc/release_notes/1_1_0.md +32 -0
  40. data/doc/release_notes/1_1_1.md +17 -0
  41. data/doc/release_notes/1_1_2.md +12 -0
  42. data/doc/release_notes/1_1_3.md +18 -0
  43. data/doc/release_notes/1_1_4.md +6 -0
  44. data/doc/release_notes/1_1_5.md +12 -0
  45. data/doc/release_notes/1_2_0.md +49 -0
  46. data/doc/release_notes/1_2_1.md +6 -0
  47. data/lib/httpx/adapters/datadog.rb +100 -106
  48. data/lib/httpx/adapters/faraday.rb +143 -107
  49. data/lib/httpx/adapters/sentry.rb +26 -7
  50. data/lib/httpx/adapters/webmock.rb +33 -17
  51. data/lib/httpx/altsvc.rb +61 -24
  52. data/lib/httpx/base64.rb +27 -0
  53. data/lib/httpx/buffer.rb +12 -0
  54. data/lib/httpx/callbacks.rb +5 -3
  55. data/lib/httpx/chainable.rb +54 -39
  56. data/lib/httpx/connection/http1.rb +62 -37
  57. data/lib/httpx/connection/http2.rb +16 -27
  58. data/lib/httpx/connection.rb +213 -120
  59. data/lib/httpx/domain_name.rb +10 -13
  60. data/lib/httpx/errors.rb +34 -2
  61. data/lib/httpx/extensions.rb +4 -134
  62. data/lib/httpx/io/ssl.rb +77 -71
  63. data/lib/httpx/io/tcp.rb +46 -70
  64. data/lib/httpx/io/udp.rb +18 -52
  65. data/lib/httpx/io/unix.rb +6 -13
  66. data/lib/httpx/io.rb +3 -9
  67. data/lib/httpx/loggable.rb +4 -19
  68. data/lib/httpx/options.rb +168 -110
  69. data/lib/httpx/plugins/{authentication → auth}/basic.rb +1 -5
  70. data/lib/httpx/plugins/{authentication → auth}/digest.rb +13 -14
  71. data/lib/httpx/plugins/{authentication → auth}/ntlm.rb +1 -3
  72. data/lib/httpx/plugins/{authentication → auth}/socks5.rb +0 -2
  73. data/lib/httpx/plugins/auth.rb +25 -0
  74. data/lib/httpx/plugins/aws_sdk_authentication.rb +1 -3
  75. data/lib/httpx/plugins/aws_sigv4.rb +5 -6
  76. data/lib/httpx/plugins/basic_auth.rb +29 -0
  77. data/lib/httpx/plugins/brotli.rb +50 -0
  78. data/lib/httpx/plugins/callbacks.rb +91 -0
  79. data/lib/httpx/plugins/circuit_breaker/circuit.rb +40 -16
  80. data/lib/httpx/plugins/circuit_breaker/circuit_store.rb +14 -5
  81. data/lib/httpx/plugins/circuit_breaker.rb +30 -7
  82. data/lib/httpx/plugins/cookies/set_cookie_parser.rb +0 -2
  83. data/lib/httpx/plugins/cookies.rb +20 -10
  84. data/lib/httpx/plugins/{digest_authentication.rb → digest_auth.rb} +11 -12
  85. data/lib/httpx/plugins/expect.rb +15 -13
  86. data/lib/httpx/plugins/follow_redirects.rb +71 -29
  87. data/lib/httpx/plugins/grpc/call.rb +2 -3
  88. data/lib/httpx/plugins/grpc/grpc_encoding.rb +88 -0
  89. data/lib/httpx/plugins/grpc/message.rb +7 -37
  90. data/lib/httpx/plugins/grpc.rb +35 -29
  91. data/lib/httpx/plugins/h2c.rb +25 -18
  92. data/lib/httpx/plugins/internal_telemetry.rb +16 -0
  93. data/lib/httpx/plugins/{ntlm_authentication.rb → ntlm_auth.rb} +7 -5
  94. data/lib/httpx/plugins/oauth.rb +170 -0
  95. data/lib/httpx/plugins/persistent.rb +1 -1
  96. data/lib/httpx/plugins/proxy/http.rb +15 -10
  97. data/lib/httpx/plugins/proxy/socks4.rb +8 -6
  98. data/lib/httpx/plugins/proxy/socks5.rb +10 -8
  99. data/lib/httpx/plugins/proxy.rb +69 -67
  100. data/lib/httpx/plugins/push_promise.rb +1 -1
  101. data/lib/httpx/plugins/rate_limiter.rb +3 -1
  102. data/lib/httpx/plugins/response_cache/file_store.rb +40 -0
  103. data/lib/httpx/plugins/response_cache/store.rb +34 -17
  104. data/lib/httpx/plugins/response_cache.rb +6 -6
  105. data/lib/httpx/plugins/retries.rb +61 -12
  106. data/lib/httpx/plugins/ssrf_filter.rb +142 -0
  107. data/lib/httpx/plugins/stream.rb +27 -32
  108. data/lib/httpx/plugins/upgrade/h2.rb +4 -4
  109. data/lib/httpx/plugins/upgrade.rb +8 -10
  110. data/lib/httpx/plugins/webdav.rb +10 -8
  111. data/lib/httpx/pool.rb +85 -23
  112. data/lib/httpx/punycode.rb +9 -291
  113. data/lib/httpx/request/body.rb +158 -0
  114. data/lib/httpx/request.rb +86 -121
  115. data/lib/httpx/resolver/https.rb +54 -17
  116. data/lib/httpx/resolver/multi.rb +8 -12
  117. data/lib/httpx/resolver/native.rb +163 -70
  118. data/lib/httpx/resolver/resolver.rb +28 -13
  119. data/lib/httpx/resolver/system.rb +15 -10
  120. data/lib/httpx/resolver.rb +38 -16
  121. data/lib/httpx/response/body.rb +242 -0
  122. data/lib/httpx/response/buffer.rb +96 -0
  123. data/lib/httpx/response.rb +113 -211
  124. data/lib/httpx/selector.rb +2 -4
  125. data/lib/httpx/session.rb +91 -64
  126. data/lib/httpx/session_extensions.rb +4 -1
  127. data/lib/httpx/timers.rb +28 -8
  128. data/lib/httpx/transcoder/body.rb +0 -2
  129. data/lib/httpx/transcoder/chunker.rb +0 -1
  130. data/lib/httpx/transcoder/deflate.rb +37 -0
  131. data/lib/httpx/transcoder/form.rb +52 -33
  132. data/lib/httpx/transcoder/gzip.rb +74 -0
  133. data/lib/httpx/transcoder/json.rb +2 -5
  134. data/lib/httpx/transcoder/multipart/decoder.rb +139 -0
  135. data/lib/httpx/{plugins → transcoder}/multipart/encoder.rb +3 -3
  136. data/lib/httpx/{plugins → transcoder}/multipart/mime_type_detector.rb +1 -1
  137. data/lib/httpx/{plugins → transcoder}/multipart/part.rb +3 -2
  138. data/lib/httpx/transcoder/multipart.rb +17 -0
  139. data/lib/httpx/transcoder/utils/body_reader.rb +46 -0
  140. data/lib/httpx/transcoder/utils/deflater.rb +72 -0
  141. data/lib/httpx/transcoder/utils/inflater.rb +19 -0
  142. data/lib/httpx/transcoder/xml.rb +0 -5
  143. data/lib/httpx/transcoder.rb +4 -6
  144. data/lib/httpx/utils.rb +36 -16
  145. data/lib/httpx/version.rb +1 -1
  146. data/lib/httpx.rb +12 -14
  147. data/sig/altsvc.rbs +33 -0
  148. data/sig/buffer.rbs +1 -0
  149. data/sig/callbacks.rbs +3 -3
  150. data/sig/chainable.rbs +10 -9
  151. data/sig/connection/http1.rbs +5 -4
  152. data/sig/connection/http2.rbs +1 -1
  153. data/sig/connection.rbs +46 -24
  154. data/sig/errors.rbs +9 -3
  155. data/sig/httpx.rbs +5 -4
  156. data/sig/io/ssl.rbs +26 -0
  157. data/sig/io/tcp.rbs +60 -0
  158. data/sig/io/udp.rbs +20 -0
  159. data/sig/io/unix.rbs +10 -0
  160. data/sig/options.rbs +28 -12
  161. data/sig/plugins/{authentication → auth}/basic.rbs +0 -2
  162. data/sig/plugins/{authentication → auth}/digest.rbs +2 -1
  163. data/sig/plugins/auth.rbs +13 -0
  164. data/sig/plugins/{basic_authentication.rbs → basic_auth.rbs} +2 -2
  165. data/sig/plugins/brotli.rbs +22 -0
  166. data/sig/plugins/callbacks.rbs +38 -0
  167. data/sig/plugins/circuit_breaker.rbs +13 -3
  168. data/sig/plugins/compression.rbs +6 -4
  169. data/sig/plugins/cookies/jar.rbs +2 -2
  170. data/sig/plugins/cookies.rbs +2 -0
  171. data/sig/plugins/{digest_authentication.rbs → digest_auth.rbs} +2 -2
  172. data/sig/plugins/follow_redirects.rbs +11 -2
  173. data/sig/plugins/grpc/call.rbs +19 -0
  174. data/sig/plugins/grpc/grpc_encoding.rbs +37 -0
  175. data/sig/plugins/grpc/message.rbs +17 -0
  176. data/sig/plugins/grpc.rbs +2 -32
  177. data/sig/plugins/h2c.rbs +1 -1
  178. data/sig/plugins/{ntlm_authentication.rbs → ntlm_auth.rbs} +2 -2
  179. data/sig/plugins/oauth.rbs +54 -0
  180. data/sig/plugins/proxy/socks4.rbs +4 -4
  181. data/sig/plugins/proxy/socks5.rbs +2 -2
  182. data/sig/plugins/proxy/ssh.rbs +1 -1
  183. data/sig/plugins/proxy.rbs +10 -4
  184. data/sig/plugins/response_cache.rbs +12 -3
  185. data/sig/plugins/retries.rbs +28 -8
  186. data/sig/plugins/stream.rbs +24 -17
  187. data/sig/plugins/upgrade.rbs +5 -3
  188. data/sig/pool.rbs +5 -4
  189. data/sig/request/body.rbs +40 -0
  190. data/sig/request.rbs +12 -28
  191. data/sig/resolver/https.rbs +7 -2
  192. data/sig/resolver/native.rbs +10 -4
  193. data/sig/resolver/resolver.rbs +6 -4
  194. data/sig/resolver/system.rbs +2 -0
  195. data/sig/resolver.rbs +9 -5
  196. data/sig/response/body.rbs +53 -0
  197. data/sig/response/buffer.rbs +24 -0
  198. data/sig/response.rbs +17 -38
  199. data/sig/session.rbs +24 -18
  200. data/sig/timers.rbs +17 -7
  201. data/sig/transcoder/body.rbs +4 -3
  202. data/sig/transcoder/deflate.rbs +11 -0
  203. data/sig/transcoder/form.rbs +5 -3
  204. data/sig/transcoder/gzip.rbs +24 -0
  205. data/sig/transcoder/json.rbs +4 -2
  206. data/sig/{plugins → transcoder}/multipart.rbs +3 -12
  207. data/sig/transcoder/utils/body_reader.rbs +15 -0
  208. data/sig/transcoder/utils/deflater.rbs +29 -0
  209. data/sig/transcoder/utils/inflater.rbs +12 -0
  210. data/sig/transcoder/xml.rbs +1 -1
  211. data/sig/transcoder.rbs +22 -7
  212. data/sig/utils.rbs +2 -0
  213. metadata +127 -40
  214. data/lib/httpx/plugins/authentication.rb +0 -20
  215. data/lib/httpx/plugins/basic_authentication.rb +0 -30
  216. data/lib/httpx/plugins/compression/brotli.rb +0 -54
  217. data/lib/httpx/plugins/compression/deflate.rb +0 -49
  218. data/lib/httpx/plugins/compression/gzip.rb +0 -88
  219. data/lib/httpx/plugins/compression.rb +0 -164
  220. data/lib/httpx/plugins/multipart/decoder.rb +0 -187
  221. data/lib/httpx/plugins/multipart.rb +0 -84
  222. data/lib/httpx/registry.rb +0 -85
  223. data/sig/plugins/authentication.rbs +0 -11
  224. data/sig/plugins/compression/brotli.rbs +0 -21
  225. data/sig/plugins/compression/deflate.rbs +0 -17
  226. data/sig/plugins/compression/gzip.rbs +0 -29
  227. data/sig/registry.rbs +0 -13
  228. /data/sig/plugins/{authentication → auth}/ntlm.rbs +0 -0
  229. /data/sig/plugins/{authentication → auth}/socks5.rbs +0 -0
@@ -7,15 +7,17 @@ module HTTPX
7
7
  include Callbacks
8
8
  include Loggable
9
9
 
10
- MAX_REQUESTS = 100
10
+ MAX_REQUESTS = 200
11
11
  CRLF = "\r\n"
12
12
 
13
13
  attr_reader :pending, :requests
14
14
 
15
+ attr_accessor :max_concurrent_requests
16
+
15
17
  def initialize(buffer, options)
16
18
  @options = Options.new(options)
17
19
  @max_concurrent_requests = @options.max_concurrent_requests || MAX_REQUESTS
18
- @max_requests = @options.max_requests || MAX_REQUESTS
20
+ @max_requests = @options.max_requests
19
21
  @parser = Parser::HTTP1.new(self)
20
22
  @buffer = buffer
21
23
  @version = [1, 1]
@@ -47,6 +49,7 @@ module HTTPX
47
49
  @max_requests = @options.max_requests || MAX_REQUESTS
48
50
  @parser.reset!
49
51
  @handshake_completed = false
52
+ @pending.concat(@requests) unless @requests.empty?
50
53
  end
51
54
 
52
55
  def close
@@ -106,6 +109,7 @@ module HTTPX
106
109
 
107
110
  def on_headers(h)
108
111
  @request = @requests.first
112
+
109
113
  return if @request.response
110
114
 
111
115
  log(level: 2) { "headers received" }
@@ -132,33 +136,42 @@ module HTTPX
132
136
  end
133
137
 
134
138
  def on_data(chunk)
135
- return unless @request
139
+ request = @request
140
+
141
+ return unless request
136
142
 
137
143
  log(color: :green) { "-> DATA: #{chunk.bytesize} bytes..." }
138
144
  log(level: 2, color: :green) { "-> #{chunk.inspect}" }
139
- response = @request.response
145
+ response = request.response
140
146
 
141
147
  response << chunk
148
+ rescue StandardError => e
149
+ error_response = ErrorResponse.new(request, e, request.options)
150
+ request.response = error_response
151
+ dispatch
142
152
  end
143
153
 
144
154
  def on_complete
145
- return unless @request
155
+ request = @request
156
+
157
+ return unless request
146
158
 
147
159
  log(level: 2) { "parsing complete" }
148
160
  dispatch
149
161
  end
150
162
 
151
163
  def dispatch
152
- if @request.expects?
164
+ request = @request
165
+
166
+ if request.expects?
153
167
  @parser.reset!
154
- return handle(@request)
168
+ return handle(request)
155
169
  end
156
170
 
157
- request = @request
158
171
  @request = nil
159
172
  @requests.shift
160
173
  response = request.response
161
- response.finish!
174
+ response.finish! unless response.is_a?(ErrorResponse)
162
175
  emit(:response, request, response)
163
176
 
164
177
  if @parser.upgrade?
@@ -168,9 +181,20 @@ module HTTPX
168
181
 
169
182
  @parser.reset!
170
183
  @max_requests -= 1
171
- manage_connection(response)
184
+ if response.is_a?(ErrorResponse)
185
+ disable
186
+ else
187
+ manage_connection(request, response)
188
+ end
172
189
 
173
- send(@pending.shift) unless @pending.empty?
190
+ if exhausted?
191
+ @pending.concat(@requests)
192
+ @requests.clear
193
+
194
+ emit(:exhausted)
195
+ else
196
+ send(@pending.shift) unless @pending.empty?
197
+ end
174
198
  end
175
199
 
176
200
  def handle_error(ex)
@@ -197,13 +221,14 @@ module HTTPX
197
221
  end
198
222
 
199
223
  def ping
224
+ reset
200
225
  emit(:reset)
201
226
  emit(:exhausted)
202
227
  end
203
228
 
204
229
  private
205
230
 
206
- def manage_connection(response)
231
+ def manage_connection(request, response)
207
232
  connection = response.headers["connection"]
208
233
  case connection
209
234
  when /keep-alive/i
@@ -233,7 +258,7 @@ module HTTPX
233
258
  disable
234
259
  when nil
235
260
  # In HTTP/1.1, it's keep alive by default
236
- return if response.version == "1.1"
261
+ return if response.version == "1.1" && request.headers["connection"] != "close"
237
262
 
238
263
  disable
239
264
  end
@@ -241,6 +266,7 @@ module HTTPX
241
266
 
242
267
  def disable
243
268
  disable_pipelining
269
+ reset
244
270
  emit(:reset)
245
271
  throw(:called)
246
272
  end
@@ -271,29 +297,31 @@ module HTTPX
271
297
  request.body.chunk!
272
298
  end
273
299
 
274
- connection = request.headers["connection"]
300
+ extra_headers = {}
275
301
 
276
- connection ||= if request.options.persistent
277
- # when in a persistent connection, the request can't be at
278
- # the edge of a renegotiation
279
- if @requests.index(request) + 1 < @max_requests
280
- "keep-alive"
281
- else
282
- "close"
283
- end
284
- else
285
- # when it's not a persistent connection, it sets "Connection: close" always
286
- # on the last request of the possible batch (either allowed max requests,
287
- # or if smaller, the size of the batch itself)
288
- requests_limit = [@max_requests, @requests.size].min
289
- if request == @requests[requests_limit - 1]
290
- "close"
302
+ unless request.headers.key?("connection")
303
+ connection_value = if request.persistent?
304
+ # when in a persistent connection, the request can't be at
305
+ # the edge of a renegotiation
306
+ if @requests.index(request) + 1 < @max_requests
307
+ "keep-alive"
308
+ else
309
+ "close"
310
+ end
291
311
  else
292
- "keep-alive"
312
+ # when it's not a persistent connection, it sets "Connection: close" always
313
+ # on the last request of the possible batch (either allowed max requests,
314
+ # or if smaller, the size of the batch itself)
315
+ requests_limit = [@max_requests, @requests.size].min
316
+ if request == @requests[requests_limit - 1]
317
+ "close"
318
+ else
319
+ "keep-alive"
320
+ end
293
321
  end
294
- end
295
322
 
296
- extra_headers = { "connection" => connection }
323
+ extra_headers["connection"] = connection_value
324
+ end
297
325
  extra_headers["host"] = request.authority unless request.headers.key?("host")
298
326
  extra_headers
299
327
  end
@@ -312,7 +340,7 @@ module HTTPX
312
340
  end
313
341
 
314
342
  def join_headline(request)
315
- "#{request.verb.to_s.upcase} #{request.path} HTTP/#{@version.join(".")}"
343
+ "#{request.verb} #{request.path} HTTP/#{@version.join(".")}"
316
344
  end
317
345
 
318
346
  def join_headers(request)
@@ -349,12 +377,10 @@ module HTTPX
349
377
  end
350
378
 
351
379
  def join_headers2(headers)
352
- buffer = "".b
353
380
  headers.each do |field, value|
354
- buffer << "#{capitalized(field)}: #{value}" << CRLF
381
+ buffer = "#{capitalized(field)}: #{value}#{CRLF}"
355
382
  log(color: :yellow) { "<- HEADER: #{buffer.chomp}" }
356
383
  @buffer << buffer
357
- buffer.clear
358
384
  end
359
385
  end
360
386
 
@@ -367,5 +393,4 @@ module HTTPX
367
393
  UPCASED[field] || field.split("-").map(&:capitalize).join("-")
368
394
  end
369
395
  end
370
- Connection.register "http/1.1", Connection::HTTP1
371
396
  end
@@ -35,7 +35,7 @@ module HTTPX
35
35
  @handshake_completed = false
36
36
  @wait_for_handshake = @settings.key?(:wait_for_handshake) ? @settings.delete(:wait_for_handshake) : true
37
37
  @max_concurrent_requests = @options.max_concurrent_requests || MAX_CONCURRENT_REQUESTS
38
- @max_requests = @options.max_requests || 0
38
+ @max_requests = @options.max_requests
39
39
  init_connection
40
40
  end
41
41
 
@@ -55,7 +55,7 @@ module HTTPX
55
55
  return :w
56
56
  end
57
57
 
58
- unless (@connection.state == :connected && @handshake_completed)
58
+ unless @connection.state == :connected && @handshake_completed
59
59
  return @buffer.empty? ? :r : :rw
60
60
  end
61
61
 
@@ -73,8 +73,11 @@ module HTTPX
73
73
  end
74
74
 
75
75
  def close
76
- @connection.goaway unless @connection.state == :closed
77
- emit(:close)
76
+ unless @connection.state == :closed
77
+ @connection.goaway
78
+ emit(:timeout, @options.timeout[:close_handshake_timeout])
79
+ end
80
+ emit(:close, true)
78
81
  end
79
82
 
80
83
  def empty?
@@ -82,9 +85,7 @@ module HTTPX
82
85
  end
83
86
 
84
87
  def exhausted?
85
- return false if @max_requests.zero? && @connection.active_stream_count.zero?
86
-
87
- @connection.active_stream_count >= @max_requests
88
+ !@max_requests.positive?
88
89
  end
89
90
 
90
91
  def <<(data)
@@ -92,13 +93,9 @@ module HTTPX
92
93
  end
93
94
 
94
95
  def can_buffer_more_requests?
95
- if @handshake_completed
96
+ (@handshake_completed || !@wait_for_handshake) &&
96
97
  @streams.size < @max_concurrent_requests &&
97
- @streams.size < @max_requests
98
- else
99
- !@wait_for_handshake &&
100
- @streams.size < @max_concurrent_requests
101
- end
98
+ @streams.size < @max_requests
102
99
  end
103
100
 
104
101
  def send(request)
@@ -116,7 +113,6 @@ module HTTPX
116
113
  true
117
114
  rescue HTTP2Next::Error::StreamLimitExceeded
118
115
  @pending.unshift(request)
119
- emit(:exhausted)
120
116
  end
121
117
 
122
118
  def consume
@@ -154,6 +150,7 @@ module HTTPX
154
150
 
155
151
  def send_pending
156
152
  while (request = @pending.shift)
153
+ # TODO: this request should go back to top of stack
157
154
  break unless send(request)
158
155
  end
159
156
  end
@@ -172,7 +169,6 @@ module HTTPX
172
169
 
173
170
  def init_connection
174
171
  @connection = HTTP2Next::Client.new(@settings)
175
- @connection.max_streams = @max_requests if @connection.respond_to?(:max_streams=) && @max_requests.positive?
176
172
  @connection.on(:frame, &method(:on_frame))
177
173
  @connection.on(:frame_sent, &method(:on_frame_sent))
178
174
  @connection.on(:frame_received, &method(:on_frame_received))
@@ -208,7 +204,7 @@ module HTTPX
208
204
  def set_protocol_headers(request)
209
205
  {
210
206
  ":scheme" => request.scheme,
211
- ":method" => request.verb.to_s.upcase,
207
+ ":method" => request.verb,
212
208
  ":path" => request.path,
213
209
  ":authority" => request.authority,
214
210
  }
@@ -314,10 +310,11 @@ module HTTPX
314
310
  ex = Error.new(stream.id, error)
315
311
  ex.set_backtrace(caller)
316
312
  response = ErrorResponse.new(request, ex, request.options)
313
+ request.response = response
317
314
  emit(:response, request, response)
318
315
  else
319
316
  response = request.response
320
- if response && response.status == 421
317
+ if response && response.is_a?(Response) && response.status == 421
321
318
  ex = MisdirectedRequestError.new(response)
322
319
  ex.set_backtrace(caller)
323
320
  emit(:error, request, ex)
@@ -339,14 +336,7 @@ module HTTPX
339
336
  def on_settings(*)
340
337
  @handshake_completed = true
341
338
  emit(:current_timeout)
342
-
343
- if @max_requests.zero?
344
- @max_requests = @connection.remote_settings[:settings_max_concurrent_streams]
345
-
346
- @connection.max_streams = @max_requests if @connection.respond_to?(:max_streams=) && @max_requests.positive?
347
- end
348
-
349
- @max_concurrent_requests = [@max_concurrent_requests, @max_requests].min
339
+ @max_concurrent_requests = [@max_concurrent_requests, @connection.remote_settings[:settings_max_concurrent_streams]].min
350
340
  send_pending
351
341
  end
352
342
 
@@ -365,7 +355,7 @@ module HTTPX
365
355
  ex.set_backtrace(caller)
366
356
  handle_error(ex)
367
357
  end
368
- return unless is_connection_closed && @streams.size.zero?
358
+ return unless is_connection_closed && @streams.empty?
369
359
 
370
360
  emit(:close, is_connection_closed)
371
361
  end
@@ -412,5 +402,4 @@ module HTTPX
412
402
  end
413
403
  end
414
404
  end
415
- Connection.register "h2", Connection::HTTP2
416
405
  end