httpx 1.2.5 → 1.3.0

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 (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