httpx 1.2.5 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/doc/release_notes/1_2_6.md +13 -0
  3. data/doc/release_notes/1_3_0.md +18 -0
  4. data/lib/httpx/adapters/datadog.rb +1 -1
  5. data/lib/httpx/adapters/faraday.rb +1 -0
  6. data/lib/httpx/adapters/webmock.rb +1 -1
  7. data/lib/httpx/connection/http1.rb +3 -2
  8. data/lib/httpx/connection/http2.rb +6 -6
  9. data/lib/httpx/connection.rb +11 -5
  10. data/lib/httpx/io/tcp.rb +1 -1
  11. data/lib/httpx/io/unix.rb +5 -3
  12. data/lib/httpx/options.rb +3 -7
  13. data/lib/httpx/parser/http1.rb +4 -0
  14. data/lib/httpx/plugins/aws_sigv4.rb +1 -1
  15. data/lib/httpx/plugins/cookies.rb +6 -6
  16. data/lib/httpx/plugins/follow_redirects.rb +44 -24
  17. data/lib/httpx/plugins/grpc.rb +3 -2
  18. data/lib/httpx/plugins/h2c.rb +1 -1
  19. data/lib/httpx/plugins/oauth.rb +1 -1
  20. data/lib/httpx/plugins/proxy/http.rb +2 -2
  21. data/lib/httpx/plugins/proxy/socks4.rb +1 -1
  22. data/lib/httpx/plugins/proxy/socks5.rb +1 -1
  23. data/lib/httpx/plugins/rate_limiter.rb +2 -0
  24. data/lib/httpx/plugins/ssrf_filter.rb +1 -1
  25. data/lib/httpx/request/body.rb +37 -41
  26. data/lib/httpx/request.rb +36 -10
  27. data/lib/httpx/resolver/https.rb +1 -1
  28. data/lib/httpx/resolver/native.rb +26 -8
  29. data/lib/httpx/resolver/resolver.rb +1 -1
  30. data/lib/httpx/response.rb +2 -2
  31. data/lib/httpx/session.rb +20 -17
  32. data/lib/httpx/timers.rb +1 -1
  33. data/lib/httpx/transcoder/multipart/encoder.rb +1 -1
  34. data/lib/httpx/version.rb +1 -1
  35. data/sig/chainable.rbs +2 -2
  36. data/sig/connection/http1.rbs +2 -2
  37. data/sig/connection/http2.rbs +17 -17
  38. data/sig/connection.rbs +7 -6
  39. data/sig/httpx.rbs +3 -3
  40. data/sig/io/ssl.rbs +1 -0
  41. data/sig/io/tcp.rbs +1 -1
  42. data/sig/io/unix.rbs +18 -1
  43. data/sig/options.rbs +5 -14
  44. data/sig/parser/http1.rbs +1 -1
  45. data/sig/plugins/callbacks.rbs +1 -1
  46. data/sig/plugins/follow_redirects.rbs +10 -5
  47. data/sig/plugins/grpc.rbs +5 -0
  48. data/sig/plugins/proxy/http.rbs +3 -0
  49. data/sig/plugins/proxy/socks4.rbs +5 -2
  50. data/sig/plugins/proxy/socks5.rbs +5 -2
  51. data/sig/plugins/push_promise.rbs +3 -3
  52. data/sig/plugins/rate_limiter.rbs +1 -1
  53. data/sig/plugins/retries.rbs +2 -0
  54. data/sig/request/body.rbs +1 -3
  55. data/sig/request.rbs +2 -1
  56. data/sig/resolver/https.rbs +1 -1
  57. data/sig/resolver/native.rbs +2 -0
  58. data/sig/resolver/resolver.rbs +1 -1
  59. data/sig/response.rbs +1 -1
  60. data/sig/session.rbs +10 -7
  61. data/sig/transcoder/multipart.rbs +11 -6
  62. data/sig/transcoder/xml.rbs +1 -0
  63. data/sig/utils.rbs +4 -0
  64. metadata +10 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e80b08847467e6ba67e57afef2787c2c617167624ae510e255dd23998b25210e
4
- data.tar.gz: b11ea8d914872689bc1710680c9962b0362c3bf28b62f6e7209f7e2a54a34674
3
+ metadata.gz: 99138c8286fb426f6bd70a62357cbaf1b54f3ceb030f1ff3c78c9e2bffd8e75a
4
+ data.tar.gz: 59a28cbadff4830ed047eba007b5f71455b5a8d6aa3e111cfb5897b82b1350fa
5
5
  SHA512:
6
- metadata.gz: 3fc7994fd3b460e267bce129fdcf6536d844fd5dd9695833c4075028cf128fe954c599ee96eacdf722756c6615c703c96f2df44628e34cd1964fee9f3f92e5e9
7
- data.tar.gz: 04c4ad1bcf05a3ee96de206a05c294f29f90fa0698fb094b982027cb09db8969a99bd7a324af23dcec18d227fe9708947211fc31ae9e4cddfb4b4360df94aa99
6
+ metadata.gz: 78b08826c993b9a2c5d1164a2bf6c7bb4123cb9599a1ddc44bd38b827c91da73abf4fee18ae39d67f9370834b3a8d04eb32999cf2c68f9fe654a0605e6d7ca5b
7
+ data.tar.gz: 6b22a1e473abc7967314785f6fb517bf5d663d87951a7a2cba5855913a348b95dc50e2fddaa801fbcf25aef96b4d7d9b4e4d0dda8388696c0b628ba0c5dd7c1b
@@ -0,0 +1,13 @@
1
+ # 1.2.6
2
+
3
+ ## Improvements
4
+
5
+ * `native` resolver: when timing out on DNS query for an alias, retry the DNS query for the alias (instead of the original hostname).
6
+
7
+ ## Bugfixes
8
+
9
+ * `faraday` adapter: set `env` options on the request object, so they are available in the request object when yielded.
10
+ * `follow_redirects` plugin: remove body-related headers (`content-length`, `content-type`) on POST-to-GET redirects.
11
+ * `follow_redirects` plugin: maintain verb (and body) of original request when the response status code is 307.
12
+ * `native` resolver: when timing out on TCP-based name resolution, downgrade to UDP before retrying.
13
+ * `rate_limiter` plugin: do not try fetching the retry-after of error responses.
@@ -0,0 +1,18 @@
1
+ # 1.3.0
2
+
3
+ ## Dependencies
4
+
5
+ `http-2` v1.0.0 is replacing `http-2-next` as the HTTP/2 parser.
6
+
7
+ `http-2-next` was forked from `http-2` 5 years ago; its improvements have been merged back to `http-2` recently though, so `http-2-next` willl therefore no longer be maintained.
8
+
9
+ ## Improvements
10
+
11
+ Request-specific options (`:params`, `:form`, `:json` and `:xml`) are now separately kept by the request, which allows them to share `HTTPX::Options`, and reduce the number of copying / allocations.
12
+
13
+ This means that `HTTPX::Options` will throw an error if you initialize an object which such keys; this should not happen, as this class is considered internal and you should not be using it directly.
14
+
15
+ ## Fixes
16
+
17
+ * support for the `datadog` gem v2.0.0 in its adapter has been unblocked, now that the gem has been released.
18
+ * loading the `:cookies` plugin was making the `Session#build_request` private.
@@ -142,7 +142,7 @@ module Datadog::Tracing
142
142
  @configuration ||= Datadog.configuration.tracing[:httpx, @request.uri.host]
143
143
  end
144
144
 
145
- if Gem::Version.new(DATADOG_VERSION::STRING) >= Gem::Version.new("2.0.0.beta1")
145
+ if Gem::Version.new(DATADOG_VERSION::STRING) >= Gem::Version.new("2.0.0")
146
146
  def propagate_trace_http(digest, headers)
147
147
  Datadog::Tracing::Contrib::HTTP.inject(digest, headers)
148
148
  end
@@ -61,6 +61,7 @@ module Faraday
61
61
  request_options = {
62
62
  headers: env.request_headers,
63
63
  body: env.body,
64
+ **options_from_env(env),
64
65
  }
65
66
  [meth.to_s.upcase, env.url, request_options]
66
67
  end
@@ -47,7 +47,7 @@ module WebMock
47
47
  end
48
48
 
49
49
  def build_error_response(request, exception)
50
- HTTPX::ErrorResponse.new(request, exception, request.options)
50
+ HTTPX::ErrorResponse.new(request, exception)
51
51
  end
52
52
  end
53
53
 
@@ -15,7 +15,7 @@ module HTTPX
15
15
  attr_accessor :max_concurrent_requests
16
16
 
17
17
  def initialize(buffer, options)
18
- @options = Options.new(options)
18
+ @options = options
19
19
  @max_concurrent_requests = @options.max_concurrent_requests || MAX_REQUESTS
20
20
  @max_requests = @options.max_requests
21
21
  @parser = Parser::HTTP1.new(self)
@@ -146,7 +146,7 @@ module HTTPX
146
146
 
147
147
  response << chunk
148
148
  rescue StandardError => e
149
- error_response = ErrorResponse.new(request, e, request.options)
149
+ error_response = ErrorResponse.new(request, e)
150
150
  request.response = error_response
151
151
  dispatch
152
152
  end
@@ -387,6 +387,7 @@ module HTTPX
387
387
  UPCASED = {
388
388
  "www-authenticate" => "WWW-Authenticate",
389
389
  "http2-settings" => "HTTP2-Settings",
390
+ "content-md5" => "Content-MD5",
390
391
  }.freeze
391
392
 
392
393
  def capitalized(field)
@@ -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)
@@ -25,7 +25,7 @@ module HTTPX
25
25
  attr_reader :streams, :pending
26
26
 
27
27
  def initialize(buffer, options)
28
- @options = Options.new(options)
28
+ @options = options
29
29
  @settings = @options.http2_settings
30
30
  @pending = []
31
31
  @streams = {}
@@ -111,7 +111,7 @@ module HTTPX
111
111
  end
112
112
  handle(request, stream)
113
113
  true
114
- rescue HTTP2Next::Error::StreamLimitExceeded
114
+ rescue ::HTTP2::Error::StreamLimitExceeded
115
115
  @pending.unshift(request)
116
116
  end
117
117
 
@@ -168,7 +168,7 @@ module HTTPX
168
168
  end
169
169
 
170
170
  def init_connection
171
- @connection = HTTP2Next::Client.new(@settings)
171
+ @connection = ::HTTP2::Client.new(@settings)
172
172
  @connection.on(:frame, &method(:on_frame))
173
173
  @connection.on(:frame_sent, &method(:on_frame_sent))
174
174
  @connection.on(:frame_received, &method(:on_frame_received))
@@ -309,7 +309,7 @@ module HTTPX
309
309
  if error
310
310
  ex = Error.new(stream.id, error)
311
311
  ex.set_backtrace(caller)
312
- response = ErrorResponse.new(request, ex, request.options)
312
+ response = ErrorResponse.new(request, ex)
313
313
  request.response = response
314
314
  emit(:response, request, response)
315
315
  else
@@ -48,6 +48,8 @@ module HTTPX
48
48
  attr_accessor :family
49
49
 
50
50
  def initialize(uri, options)
51
+ @origins = [uri.origin]
52
+ @origin = Utils.to_uri(uri.origin)
51
53
  @options = Options.new(options)
52
54
  @type = initialize_type(uri, @options)
53
55
  @origins = [uri.origin]
@@ -337,7 +339,7 @@ module HTTPX
337
339
  #
338
340
  loop do
339
341
  siz = @io.read(@window_size, @read_buffer)
340
- log(level: 3, color: :cyan) { "IO READ: #{siz} bytes..." }
342
+ log(level: 3, color: :cyan) { "IO READ: #{siz} bytes... (wsize: #{@window_size}, rbuffer: #{@read_buffer.bytesize})" }
341
343
  unless siz
342
344
  ex = EOFError.new("descriptor closed")
343
345
  ex.set_backtrace(caller)
@@ -504,7 +506,7 @@ module HTTPX
504
506
  when MisdirectedRequestError
505
507
  emit(:misdirected, request)
506
508
  else
507
- response = ErrorResponse.new(request, ex, @options)
509
+ response = ErrorResponse.new(request, ex)
508
510
  request.response = response
509
511
  request.emit(:response, response)
510
512
  end
@@ -530,7 +532,7 @@ module HTTPX
530
532
  connecting? && callbacks_for?(:connect_error) ? emit(:connect_error, error) : handle_error(error)
531
533
  @state = :closed
532
534
  emit(:close)
533
- rescue TLSError, HTTP2Next::Error::ProtocolError, HTTP2Next::Error::HandshakeError => e
535
+ rescue TLSError, ::HTTP2::Error::ProtocolError, ::HTTP2::Error::HandshakeError => e
534
536
  # connect errors, exit gracefully
535
537
  handle_error(e)
536
538
  connecting? && callbacks_for?(:connect_error) ? emit(:connect_error, e) : handle_error(e)
@@ -626,7 +628,11 @@ module HTTPX
626
628
  end
627
629
  end
628
630
  when "unix"
629
- UNIX.new(@origin, addrs, @options)
631
+ path = Array(addrs).first
632
+
633
+ path = String(path) if path
634
+
635
+ UNIX.new(@origin, path, @options)
630
636
  else
631
637
  raise Error, "unsupported transport (#{@type})"
632
638
  end
@@ -653,7 +659,7 @@ module HTTPX
653
659
  def handle_error(error)
654
660
  parser.handle_error(error) if @parser && parser.respond_to?(:handle_error)
655
661
  while (request = @pending.shift)
656
- response = ErrorResponse.new(request, error, request.options)
662
+ response = ErrorResponse.new(request, error)
657
663
  request.response = response
658
664
  request.emit(:response, response)
659
665
  end
data/lib/httpx/io/tcp.rb CHANGED
@@ -17,7 +17,7 @@ module HTTPX
17
17
  @state = :idle
18
18
  @addresses = []
19
19
  @hostname = origin.host
20
- @options = Options.new(options)
20
+ @options = options
21
21
  @fallback_protocol = @options.fallback_protocol
22
22
  @port = origin.port
23
23
  @interests = :w
data/lib/httpx/io/unix.rb CHANGED
@@ -8,11 +8,11 @@ module HTTPX
8
8
 
9
9
  alias_method :host, :path
10
10
 
11
- def initialize(origin, addresses, options)
11
+ def initialize(origin, path, options)
12
12
  @addresses = []
13
13
  @hostname = origin.host
14
14
  @state = :idle
15
- @options = Options.new(options)
15
+ @options = options
16
16
  @fallback_protocol = @options.fallback_protocol
17
17
  if @options.io
18
18
  @io = case @options.io
@@ -26,8 +26,10 @@ module HTTPX
26
26
  @path = @io.path
27
27
  @keep_open = true
28
28
  @state = :connected
29
+ elsif path
30
+ @path = path
29
31
  else
30
- @path = addresses.first
32
+ raise Error, "No path given where to store the socket"
31
33
  end
32
34
  @io ||= build_socket
33
35
  end
data/lib/httpx/options.rb CHANGED
@@ -91,7 +91,7 @@ module HTTPX
91
91
  # :debug :: an object which log messages are written to (must respond to <tt><<</tt>)
92
92
  # :debug_level :: the log level of messages (can be 1, 2, or 3).
93
93
  # :ssl :: a hash of options which can be set as params of OpenSSL::SSL::SSLContext (see HTTPX::IO::SSL)
94
- # :http2_settings :: a hash of options to be passed to a HTTP2Next::Connection (ex: <tt>{ max_concurrent_streams: 2 }</tt>)
94
+ # :http2_settings :: a hash of options to be passed to a HTTP2::Connection (ex: <tt>{ max_concurrent_streams: 2 }</tt>)
95
95
  # :fallback_protocol :: version of HTTP protocol to use by default in the absence of protocol negotiation
96
96
  # like ALPN (defaults to <tt>"http/1.1"</tt>)
97
97
  # :supported_compression_formats :: list of compressions supported by the transcoder layer (defaults to <tt>%w[gzip deflate]</tt>).
@@ -124,10 +124,6 @@ module HTTPX
124
124
  # :base_path :: path to prefix given relative paths with (ex: "/v2")
125
125
  # :max_concurrent_requests :: max number of requests which can be set concurrently
126
126
  # :max_requests :: max number of requests which can be made on socket before it reconnects.
127
- # :params :: hash or array of key-values which will be encoded and set in the query string of request uris.
128
- # :form :: hash of array of key-values which will be form-or-multipart-encoded in requests body payload.
129
- # :json :: hash of array of key-values which will be JSON-encoded in requests body payload.
130
- # :xml :: Nokogiri XML nodes which will be encoded in requests body payload.
131
127
  #
132
128
  # This list of options are enhanced with each loaded plugin, see the plugin docs for details.
133
129
  def initialize(options = {})
@@ -216,7 +212,7 @@ module HTTPX
216
212
  end
217
213
 
218
214
  %i[
219
- params form json xml body ssl http2_settings
215
+ ssl http2_settings
220
216
  request_class response_class headers_class request_body_class
221
217
  response_body_class connection_class options_class
222
218
  io fallback_protocol debug debug_level resolver_class resolver_options
@@ -228,7 +224,7 @@ module HTTPX
228
224
  OUT
229
225
  end
230
226
 
231
- REQUEST_BODY_IVARS = %i[@headers @params @form @xml @json @body].freeze
227
+ REQUEST_BODY_IVARS = %i[@headers].freeze
232
228
 
233
229
  def ==(other)
234
230
  super || options_equals?(other)
@@ -75,6 +75,7 @@ module HTTPX
75
75
  buffer = @buffer
76
76
 
77
77
  while (idx = buffer.index("\n"))
78
+ # @type var line: String
78
79
  line = buffer.byteslice(0..idx)
79
80
  raise Error, "wrong header format" if line.start_with?("\s", "\t")
80
81
 
@@ -101,9 +102,11 @@ module HTTPX
101
102
  separator_index = line.index(":")
102
103
  raise Error, "wrong header format" unless separator_index
103
104
 
105
+ # @type var key: String
104
106
  key = line.byteslice(0..(separator_index - 1))
105
107
 
106
108
  key.rstrip! # was lstripped previously!
109
+ # @type var value: String
107
110
  value = line.byteslice((separator_index + 1)..-1)
108
111
  value.strip!
109
112
  raise Error, "wrong header format" if value.nil?
@@ -118,6 +121,7 @@ module HTTPX
118
121
  @observer.on_data(chunk)
119
122
  end
120
123
  elsif @content_length
124
+ # @type var data: String
121
125
  data = @buffer.byteslice(0, @content_length)
122
126
  @buffer = @buffer.byteslice(@content_length..-1) || "".b
123
127
  @content_length -= data.bytesize
@@ -160,7 +160,7 @@ module HTTPX
160
160
  with(sigv4_signer: Signer.new(**options))
161
161
  end
162
162
 
163
- def build_request(*, _)
163
+ def build_request(*)
164
164
  request = super
165
165
 
166
166
  return request if request.headers.key?("authorization")
@@ -40,6 +40,12 @@ module HTTPX
40
40
  end
41
41
  end
42
42
 
43
+ def build_request(*)
44
+ request = super
45
+ request.headers.set_cookie(request.options.cookies[request.uri])
46
+ request
47
+ end
48
+
43
49
  private
44
50
 
45
51
  def on_response(_request, response)
@@ -52,12 +58,6 @@ module HTTPX
52
58
 
53
59
  super
54
60
  end
55
-
56
- def build_request(*, _)
57
- request = super
58
- request.headers.set_cookie(request.options.cookies[request.uri])
59
- request
60
- end
61
61
  end
62
62
 
63
63
  module HeadersMethods
@@ -16,6 +16,7 @@ module HTTPX
16
16
  module FollowRedirects
17
17
  MAX_REDIRECTS = 3
18
18
  REDIRECT_STATUS = (300..399).freeze
19
+ REQUEST_BODY_HEADERS = %w[transfer-encoding content-encoding content-type content-length content-language content-md5 trailer].freeze
19
20
 
20
21
  using URIExtensions
21
22
 
@@ -60,7 +61,6 @@ module HTTPX
60
61
  return response unless REDIRECT_STATUS.include?(response.status) && response.headers.key?("location")
61
62
  return response unless max_redirects.positive?
62
63
 
63
- # build redirect request
64
64
  redirect_uri = __get_location_from_response(response)
65
65
 
66
66
  if options.redirect_on
@@ -68,25 +68,43 @@ module HTTPX
68
68
  return response unless redirect_allowed
69
69
  end
70
70
 
71
+ # build redirect request
72
+ request_body = redirect_request.body
73
+ redirect_method = "GET"
74
+ redirect_params = {}
75
+
71
76
  if response.status == 305 && options.respond_to?(:proxy)
77
+ request_body.rewind
72
78
  # The requested resource MUST be accessed through the proxy given by
73
79
  # the Location field. The Location field gives the URI of the proxy.
74
- retry_options = options.merge(headers: redirect_request.headers,
75
- proxy: { uri: redirect_uri },
76
- body: redirect_request.body,
77
- max_redirects: max_redirects - 1)
80
+ redirect_options = options.merge(headers: redirect_request.headers,
81
+ proxy: { uri: redirect_uri },
82
+ max_redirects: max_redirects - 1)
83
+
84
+ redirect_params[:body] = request_body
78
85
  redirect_uri = redirect_request.uri
79
- options = retry_options
86
+ options = redirect_options
80
87
  else
81
88
  redirect_headers = redirect_request_headers(redirect_request.uri, redirect_uri, request.headers, options)
89
+ redirect_opts = Hash[options]
90
+ redirect_params[:max_redirects] = max_redirects - 1
91
+
92
+ unless request_body.empty?
93
+ if response.status == 307
94
+ # The method and the body of the original request are reused to perform the redirected request.
95
+ redirect_method = redirect_request.verb
96
+ request_body.rewind
97
+ redirect_params[:body] = request_body
98
+ else
99
+ # redirects are **ALWAYS** GET, so remove body-related headers
100
+ REQUEST_BODY_HEADERS.each do |h|
101
+ redirect_headers.delete(h)
102
+ end
103
+ redirect_params[:body] = nil
104
+ end
105
+ end
82
106
 
83
- # redirects are **ALWAYS** GET
84
- retry_opts = Hash[options].merge(
85
- headers: redirect_headers.to_h,
86
- body: redirect_request.body,
87
- max_redirects: max_redirects - 1
88
- )
89
- retry_options = options.class.new(retry_opts)
107
+ options = options.class.new(redirect_opts.merge(headers: redirect_headers.to_h))
90
108
  end
91
109
 
92
110
  redirect_uri = Utils.to_uri(redirect_uri)
@@ -96,26 +114,26 @@ module HTTPX
96
114
  redirect_uri.scheme == "http"
97
115
  error = InsecureRedirectError.new(redirect_uri.to_s)
98
116
  error.set_backtrace(caller)
99
- return ErrorResponse.new(request, error, options)
117
+ return ErrorResponse.new(request, error)
100
118
  end
101
119
 
102
- retry_request = build_request("GET", redirect_uri, retry_options)
120
+ retry_request = build_request(redirect_method, redirect_uri, redirect_params, options)
103
121
 
104
122
  request.redirect_request = retry_request
105
123
 
106
- retry_after = response.headers["retry-after"]
124
+ redirect_after = response.headers["retry-after"]
107
125
 
108
- if retry_after
126
+ if redirect_after
109
127
  # Servers send the "Retry-After" header field to indicate how long the
110
128
  # user agent ought to wait before making a follow-up request.
111
129
  # When sent with any 3xx (Redirection) response, Retry-After indicates
112
130
  # the minimum time that the user agent is asked to wait before issuing
113
131
  # the redirected request.
114
132
  #
115
- retry_after = Utils.parse_retry_after(retry_after)
133
+ redirect_after = Utils.parse_retry_after(redirect_after)
116
134
 
117
- log { "redirecting after #{retry_after} secs..." }
118
- pool.after(retry_after) do
135
+ log { "redirecting after #{redirect_after} secs..." }
136
+ pool.after(redirect_after) do
119
137
  send_request(retry_request, connections, options)
120
138
  end
121
139
  else
@@ -125,19 +143,21 @@ module HTTPX
125
143
  end
126
144
 
127
145
  def redirect_request_headers(original_uri, redirect_uri, headers, options)
146
+ headers = headers.dup
147
+
128
148
  return headers if options.allow_auth_to_other_origins
129
149
 
130
150
  return headers unless headers.key?("authorization")
131
151
 
132
- unless original_uri.origin == redirect_uri.origin
133
- headers = headers.dup
134
- headers.delete("authorization")
135
- end
152
+ return headers if original_uri.origin == redirect_uri.origin
153
+
154
+ headers.delete("authorization")
136
155
 
137
156
  headers
138
157
  end
139
158
 
140
159
  def __get_location_from_response(response)
160
+ # @type var location_uri: http_uri
141
161
  location_uri = URI(response.headers["location"])
142
162
  location_uri = response.uri.merge(location_uri) if location_uri.relative?
143
163
  location_uri
@@ -110,10 +110,10 @@ module HTTPX
110
110
  end
111
111
 
112
112
  module RequestBodyMethods
113
- def initialize(headers, _)
113
+ def initialize(*, **)
114
114
  super
115
115
 
116
- if (compression = headers["grpc-encoding"])
116
+ if (compression = @headers["grpc-encoding"])
117
117
  deflater_body = self.class.initialize_deflater_body(@body, compression)
118
118
  @body = Transcoder::GRPCEncoding.encode(deflater_body || @body, compressed: !deflater_body.nil?)
119
119
  else
@@ -124,6 +124,7 @@ module HTTPX
124
124
 
125
125
  module InstanceMethods
126
126
  def with_channel_credentials(ca_path, key = nil, cert = nil, **ssl_opts)
127
+ # @type var ssl_params: ::Hash[::Symbol, untyped]
127
128
  ssl_params = {
128
129
  **ssl_opts,
129
130
  ca_file: ca_path,
@@ -39,7 +39,7 @@ module HTTPX
39
39
  upgrade_request.headers.add("connection", "upgrade")
40
40
  upgrade_request.headers.add("connection", "http2-settings")
41
41
  upgrade_request.headers["upgrade"] = "h2c"
42
- upgrade_request.headers["http2-settings"] = HTTP2Next::Client.settings_header(upgrade_request.options.http2_settings)
42
+ upgrade_request.headers["http2-settings"] = ::HTTP2::Client.settings_header(upgrade_request.options.http2_settings)
43
43
 
44
44
  super(upgrade_request, *remainder)
45
45
  end
@@ -155,7 +155,7 @@ module HTTPX
155
155
  with(oauth_session: oauth_session.merge(access_token: access_token, refresh_token: refresh_token))
156
156
  end
157
157
 
158
- def build_request(*, _)
158
+ def build_request(*)
159
159
  request = super
160
160
 
161
161
  return request if request.headers.key?("authorization")
@@ -163,8 +163,8 @@ module HTTPX
163
163
  end
164
164
 
165
165
  class ConnectRequest < Request
166
- def initialize(uri, _options)
167
- super("CONNECT", uri, {})
166
+ def initialize(uri, options)
167
+ super("CONNECT", uri, options)
168
168
  @headers.delete("accept")
169
169
  end
170
170
 
@@ -89,7 +89,7 @@ module HTTPX
89
89
 
90
90
  def initialize(buffer, options)
91
91
  @buffer = buffer
92
- @options = Options.new(options)
92
+ @options = options
93
93
  end
94
94
 
95
95
  def close; end
@@ -141,7 +141,7 @@ module HTTPX
141
141
 
142
142
  def initialize(buffer, options)
143
143
  @buffer = buffer
144
- @options = Options.new(options)
144
+ @options = options
145
145
  end
146
146
 
147
147
  def close; end
@@ -39,6 +39,8 @@ module HTTPX
39
39
  # the redirected request.
40
40
  #
41
41
  def retry_after_rate_limit(_, response)
42
+ return unless response.is_a?(Response)
43
+
42
44
  retry_after = response.headers["retry-after"]
43
45
 
44
46
  return unless retry_after
@@ -100,7 +100,7 @@ module HTTPX
100
100
 
101
101
  error = ServerSideRequestForgeryError.new("#{request.uri} URI scheme not allowed")
102
102
  error.set_backtrace(caller)
103
- response = ErrorResponse.new(request, error, request.options)
103
+ response = ErrorResponse.new(request, error)
104
104
  request.emit(:response, response)
105
105
  response
106
106
  end