httpx 0.22.5 → 0.23.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 (83) hide show
  1. checksums.yaml +4 -4
  2. data/doc/release_notes/0_23_0.md +42 -0
  3. data/doc/release_notes/0_23_1.md +5 -0
  4. data/lib/httpx/adapters/datadog.rb +1 -1
  5. data/lib/httpx/adapters/faraday.rb +1 -1
  6. data/lib/httpx/adapters/sentry.rb +4 -4
  7. data/lib/httpx/adapters/webmock.rb +2 -2
  8. data/lib/httpx/buffer.rb +4 -0
  9. data/lib/httpx/chainable.rb +4 -4
  10. data/lib/httpx/connection/http1.rb +2 -2
  11. data/lib/httpx/connection/http2.rb +2 -3
  12. data/lib/httpx/connection.rb +29 -10
  13. data/lib/httpx/io/udp.rb +2 -0
  14. data/lib/httpx/io/unix.rb +1 -5
  15. data/lib/httpx/io.rb +0 -10
  16. data/lib/httpx/options.rb +16 -2
  17. data/lib/httpx/plugins/authentication/digest.rb +1 -1
  18. data/lib/httpx/plugins/aws_sdk_authentication.rb +1 -3
  19. data/lib/httpx/plugins/aws_sigv4.rb +1 -1
  20. data/lib/httpx/plugins/compression/brotli.rb +4 -4
  21. data/lib/httpx/plugins/compression/deflate.rb +12 -7
  22. data/lib/httpx/plugins/compression/gzip.rb +7 -5
  23. data/lib/httpx/plugins/compression.rb +9 -8
  24. data/lib/httpx/plugins/digest_authentication.rb +1 -4
  25. data/lib/httpx/plugins/follow_redirects.rb +1 -1
  26. data/lib/httpx/plugins/grpc/message.rb +3 -1
  27. data/lib/httpx/plugins/grpc.rb +3 -3
  28. data/lib/httpx/plugins/h2c.rb +5 -9
  29. data/lib/httpx/plugins/internal_telemetry.rb +16 -0
  30. data/lib/httpx/plugins/multipart.rb +14 -2
  31. data/lib/httpx/plugins/proxy/http.rb +4 -4
  32. data/lib/httpx/plugins/proxy.rb +65 -31
  33. data/lib/httpx/plugins/response_cache.rb +2 -2
  34. data/lib/httpx/plugins/retries.rb +49 -2
  35. data/lib/httpx/plugins/upgrade/h2.rb +3 -3
  36. data/lib/httpx/plugins/upgrade.rb +4 -7
  37. data/lib/httpx/plugins/webdav.rb +7 -7
  38. data/lib/httpx/pool.rb +1 -1
  39. data/lib/httpx/request.rb +23 -13
  40. data/lib/httpx/resolver/https.rb +37 -20
  41. data/lib/httpx/resolver/native.rb +131 -35
  42. data/lib/httpx/resolver.rb +26 -14
  43. data/lib/httpx/response.rb +14 -16
  44. data/lib/httpx/session.rb +1 -0
  45. data/lib/httpx/transcoder/body.rb +0 -1
  46. data/lib/httpx/transcoder/chunker.rb +0 -1
  47. data/lib/httpx/transcoder/form.rb +0 -1
  48. data/lib/httpx/transcoder/json.rb +0 -1
  49. data/lib/httpx/transcoder/xml.rb +0 -1
  50. data/lib/httpx/transcoder.rb +0 -2
  51. data/lib/httpx/version.rb +1 -1
  52. data/lib/httpx.rb +0 -1
  53. data/sig/buffer.rbs +1 -0
  54. data/sig/chainable.rbs +3 -3
  55. data/sig/connection.rbs +17 -6
  56. data/sig/errors.rbs +9 -0
  57. data/sig/httpx.rbs +3 -3
  58. data/sig/io/ssl.rbs +17 -0
  59. data/sig/io/tcp.rbs +57 -0
  60. data/sig/io/udp.rbs +20 -0
  61. data/sig/io/unix.rbs +10 -0
  62. data/sig/options.rbs +5 -1
  63. data/sig/plugins/compression.rbs +6 -2
  64. data/sig/plugins/cookies/jar.rbs +2 -2
  65. data/sig/plugins/grpc.rbs +3 -3
  66. data/sig/plugins/h2c.rbs +1 -1
  67. data/sig/plugins/proxy.rbs +1 -5
  68. data/sig/plugins/response_cache.rbs +1 -1
  69. data/sig/plugins/retries.rbs +28 -8
  70. data/sig/plugins/upgrade.rbs +5 -3
  71. data/sig/request.rbs +6 -2
  72. data/sig/resolver/https.rbs +3 -1
  73. data/sig/resolver/native.rbs +7 -2
  74. data/sig/resolver/resolver.rbs +0 -2
  75. data/sig/resolver/system.rbs +2 -0
  76. data/sig/resolver.rbs +8 -4
  77. data/sig/response.rbs +6 -2
  78. data/sig/session.rbs +10 -10
  79. data/sig/transcoder/xml.rbs +1 -1
  80. data/sig/transcoder.rbs +4 -5
  81. metadata +11 -5
  82. data/lib/httpx/registry.rb +0 -85
  83. data/sig/registry.rbs +0 -13
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1346874cf311c485468e6c99054806adfde48a145d9b012a9a2a2e56a9ae3a8b
4
- data.tar.gz: 4b345ffef12d65d66787e59bc3ed8c01619a343246ddd433a1a0e807029f14de
3
+ metadata.gz: 4b2b08112684f9bd8729c77dba080f3c6a6ae1f49f9edf64064e8f5511814ec9
4
+ data.tar.gz: 27c4c7e04269ef2c70c7a1b47d468344ffe40bd95ecaddea4fae383e23e7828b
5
5
  SHA512:
6
- metadata.gz: 6dfa20f805f0421917c6aee58ff2bedb31173d4b227fa76c6b23d1af9ee903242f26ab12474907400d5e6dae7b0fe4084c771689e4e6391ff6227277a7beef9b
7
- data.tar.gz: 7d8a89d569f0b8abc775eae0563450e1e9470c7a74cd7aa249abc49570901f6ceb0548ba5236b1575ba17e9f8a17c433cea12a1708a9df3b520c599304bcd458
6
+ metadata.gz: a5e434e9ff70a0c1c70fc35d5c5a9a854c4ac4d205a1116a92594c59dd7a70abe9985623c7d7c96348a15b73a51cf08244f6e8ae0ffb9a61760249b5213e6d8f
7
+ data.tar.gz: 3eb75f06e34ff49cf998eeccb70a316acfa4962e6663fd6c59e03cbfdb1200ce5f6580fed0baac2e034b2106cba163bb0fd6454cf008a58bac5bcc6babb744af
@@ -0,0 +1,42 @@
1
+ # 0.23.0
2
+
3
+ ## Features
4
+
5
+ ### `:retries` plugin: resumable requests
6
+
7
+ The `:retries` plugin will now support scenarios where, if the request being retried supports the `range` header, and a partial response has been already buffered, the retry will resume from there and only download the missing data.
8
+
9
+ #### HTTPX::ErrorResponse#response
10
+
11
+ As a result, ´HTTPX::ErrorResponse#response` has also been introduced; error responses may have an actual response. This happens in cases where the request failed **after** a partial response was initiated.
12
+
13
+ #### `:buffer_size` option
14
+
15
+ A nnew option, `:buffer_size`, can be used to tweak the buffers used by the read/write socket routines (16k by default, you can lower it in memory-constrained environments).
16
+
17
+ ## Improvements
18
+
19
+ ### `:native` resolver falls back to TCP for truncated messages
20
+
21
+ The `:native` resolver will repeat DNS queries to a nameserver via TCP when the first attempt is marked as truncated. This behaviour is both aligned with `getaddrinfo` and the `resolv` standard library.
22
+
23
+ This introduces a new `resolver_options` option, `:socket_type`, which can now be `:tcp` if it is to remain the default.
24
+
25
+ ## Chore
26
+
27
+ ### HTTPX.build_request should receive upcased string (i.e. "GET")
28
+
29
+ Functions which receive an HTTP verb should be given he verb in "upcased string" format now. The usage of symbols is still possible, but a deprecation warning will be emitted, and support will be removed in v1.0.0 .
30
+
31
+ ### Remove HTTPX::Registry
32
+
33
+ These internal registries were a bit magical to use, difficult to debug, not thread-safe, and overall a nuisance when it came to type checking. While there is the possibility that someone was relying on it existing, nothing had ever been publicly documented.
34
+
35
+ ## Bugfixes
36
+
37
+ * fixed proxy discovery using proxy env vars (`HTTPS_PROXY`, `NO_PROXY`...) being enabled/disabled based on first host uused in the session;
38
+ * fixed `:no_proxy` option usage inn the `:proxy` plugin.
39
+ * fixed `webmock` adapter to correctly disable it when `Webmock.disable!` is called.
40
+ * fixed bug in `:digest_authentication` plugin when enabled and no credentials were passed.
41
+ * fixed several bugs in the `sentry` adapter around breadcrumb handling.
42
+ * fixed `:native` resolver candidate calculation by putting absolute domain at the bottom of the list.
@@ -0,0 +1,5 @@
1
+ # 0.23.1
2
+
3
+ ## Bugfixes
4
+
5
+ * fixed regression causing dns candidate names not being tried after first one fails.
@@ -68,7 +68,7 @@ module TRACING_MODULE # rubocop:disable Naming/ClassAndModuleCamelCase
68
68
 
69
69
  @request.on(:response, &method(:finish))
70
70
 
71
- verb = @request.verb.to_s.upcase
71
+ verb = @request.verb
72
72
  uri = @request.uri
73
73
 
74
74
  @span = build_span
@@ -44,7 +44,7 @@ module Faraday
44
44
  headers: env.request_headers,
45
45
  body: env.body,
46
46
  }
47
- [meth, env.url, request_options]
47
+ [meth.to_s.upcase, env.url, request_options]
48
48
  end
49
49
 
50
50
  def options_from_env(env)
@@ -43,8 +43,8 @@ module HTTPX::Plugins
43
43
 
44
44
  request_info = extract_request_info(req)
45
45
 
46
- data = if response.is_a?(HTTPX::ErrorResponse)
47
- { error: res.message, **request_info }
46
+ data = if res.is_a?(HTTPX::ErrorResponse)
47
+ { error: res.error.message, **request_info }
48
48
  else
49
49
  { status: res.status, **request_info }
50
50
  end
@@ -64,7 +64,7 @@ module HTTPX::Plugins
64
64
  request_info = extract_request_info(req)
65
65
  sentry_span.set_description("#{request_info[:method]} #{request_info[:url]}")
66
66
  if res.is_a?(HTTPX::ErrorResponse)
67
- sentry_span.set_data(:error, res.message)
67
+ sentry_span.set_data(:error, res.error.message)
68
68
  else
69
69
  sentry_span.set_data(:status, res.status)
70
70
  end
@@ -75,7 +75,7 @@ module HTTPX::Plugins
75
75
  uri = req.uri
76
76
 
77
77
  result = {
78
- method: req.verb.to_s.upcase,
78
+ method: req.verb,
79
79
  }
80
80
 
81
81
  if ::Sentry.configuration.send_default_pii
@@ -23,7 +23,7 @@ module WebMock
23
23
  uri.path = uri.normalized_path.gsub("[^:]//", "/")
24
24
 
25
25
  WebMock::RequestSignature.new(
26
- request.verb,
26
+ request.verb.downcase.to_sym,
27
27
  uri.to_s,
28
28
  body: request.body.each.to_a.join,
29
29
  headers: request.headers.to_h
@@ -122,7 +122,7 @@ module WebMock
122
122
 
123
123
  class << self
124
124
  def enable!
125
- @original_session = HTTPX::Session
125
+ @original_session ||= HTTPX::Session
126
126
 
127
127
  webmock_session = HTTPX.plugin(Plugin)
128
128
 
data/lib/httpx/buffer.rb CHANGED
@@ -31,6 +31,10 @@ module HTTPX
31
31
  @buffer.bytesize >= @limit
32
32
  end
33
33
 
34
+ def capacity
35
+ @limit - @buffer.bytesize
36
+ end
37
+
34
38
  def shift!(fin)
35
39
  @buffer = @buffer.byteslice(fin..-1) || "".b
36
40
  end
@@ -2,11 +2,11 @@
2
2
 
3
3
  module HTTPX
4
4
  module Chainable
5
- %i[head get post put delete trace options connect patch].each do |meth|
5
+ %w[head get post put delete trace options connect patch].each do |meth|
6
6
  class_eval(<<-MOD, __FILE__, __LINE__ + 1)
7
- def #{meth}(*uri, **options) # def get(*uri, **options)
8
- request(:#{meth}, uri, **options) # request(:get, uri, **options)
9
- end # end
7
+ def #{meth}(*uri, **options) # def get(*uri, **options)
8
+ request("#{meth.upcase}", uri, **options) # request("GET", uri, **options)
9
+ end # end
10
10
  MOD
11
11
  end
12
12
 
@@ -106,6 +106,7 @@ module HTTPX
106
106
 
107
107
  def on_headers(h)
108
108
  @request = @requests.first
109
+
109
110
  return if @request.response
110
111
 
111
112
  log(level: 2) { "headers received" }
@@ -312,7 +313,7 @@ module HTTPX
312
313
  end
313
314
 
314
315
  def join_headline(request)
315
- "#{request.verb.to_s.upcase} #{request.path} HTTP/#{@version.join(".")}"
316
+ "#{request.verb} #{request.path} HTTP/#{@version.join(".")}"
316
317
  end
317
318
 
318
319
  def join_headers(request)
@@ -367,5 +368,4 @@ module HTTPX
367
368
  UPCASED[field] || field.split("-").map(&:capitalize).join("-")
368
369
  end
369
370
  end
370
- Connection.register "http/1.1", Connection::HTTP1
371
371
  end
@@ -208,7 +208,7 @@ module HTTPX
208
208
  def set_protocol_headers(request)
209
209
  {
210
210
  ":scheme" => request.scheme,
211
- ":method" => request.verb.to_s.upcase,
211
+ ":method" => request.verb,
212
212
  ":path" => request.path,
213
213
  ":authority" => request.authority,
214
214
  }
@@ -317,7 +317,7 @@ module HTTPX
317
317
  emit(:response, request, response)
318
318
  else
319
319
  response = request.response
320
- if response && response.status == 421
320
+ if response && response.is_a?(Response) && response.status == 421
321
321
  ex = MisdirectedRequestError.new(response)
322
322
  ex.set_backtrace(caller)
323
323
  emit(:error, request, ex)
@@ -412,5 +412,4 @@ module HTTPX
412
412
  end
413
413
  end
414
414
  end
415
- Connection.register "h2", Connection::HTTP2
416
415
  end
@@ -29,7 +29,6 @@ module HTTPX
29
29
  #
30
30
  class Connection
31
31
  extend Forwardable
32
- include Registry
33
32
  include Loggable
34
33
  include Callbacks
35
34
 
@@ -39,8 +38,6 @@ module HTTPX
39
38
  require "httpx/connection/http2"
40
39
  require "httpx/connection/http1"
41
40
 
42
- BUFFER_SIZE = 1 << 14
43
-
44
41
  def_delegator :@io, :closed?
45
42
 
46
43
  def_delegator :@write_buffer, :empty?
@@ -57,15 +54,15 @@ module HTTPX
57
54
  @origin = Utils.to_uri(uri.origin)
58
55
  @options = Options.new(options)
59
56
  @window_size = @options.window_size
60
- @read_buffer = Buffer.new(BUFFER_SIZE)
61
- @write_buffer = Buffer.new(BUFFER_SIZE)
57
+ @read_buffer = Buffer.new(@options.buffer_size)
58
+ @write_buffer = Buffer.new(@options.buffer_size)
62
59
  @pending = []
63
60
  on(:error, &method(:on_error))
64
61
  if @options.io
65
62
  # if there's an already open IO, get its
66
63
  # peer address, and force-initiate the parser
67
64
  transition(:already_open)
68
- @io = IO.registry(@type).new(@origin, nil, @options)
65
+ @io = build_socket
69
66
  parser
70
67
  else
71
68
  transition(:idle)
@@ -84,7 +81,7 @@ module HTTPX
84
81
  if @io
85
82
  @io.add_addresses(addrs)
86
83
  else
87
- @io = IO.registry(@type).new(@origin, addrs, @options)
84
+ @io = build_socket(addrs)
88
85
  end
89
86
  end
90
87
 
@@ -104,7 +101,7 @@ module HTTPX
104
101
  # was the result of coalescing. To prevent blind trust in the case where the
105
102
  # origin came from an ORIGIN frame, we're going to verify the hostname with the
106
103
  # SSL certificate
107
- (@origins.size == 1 || @origin == uri.origin || (@io && @io.verify_hostname(uri.host)))
104
+ (@origins.size == 1 || @origin == uri.origin || (@io.is_a?(SSL) && @io.verify_hostname(uri.host)))
108
105
  ) && @options == options
109
106
  ) || (match_altsvcs?(uri) && match_altsvc_options?(uri, options))
110
107
  end
@@ -118,7 +115,7 @@ module HTTPX
118
115
 
119
116
  (
120
117
  (open? && @origin == connection.origin) ||
121
- !(@io.addresses & connection.addresses).empty?
118
+ !(@io.addresses & (connection.addresses || [])).empty?
122
119
  ) && @options == connection.options
123
120
  end
124
121
 
@@ -453,7 +450,7 @@ module HTTPX
453
450
  end
454
451
 
455
452
  def build_parser(protocol = @io.protocol)
456
- parser = registry(protocol).new(@write_buffer, @options)
453
+ parser = self.class.parser_type(protocol).new(@write_buffer, @options)
457
454
  set_parser_callbacks(parser)
458
455
  parser
459
456
  end
@@ -596,6 +593,17 @@ module HTTPX
596
593
  remove_instance_variable(:@timeout) if defined?(@timeout)
597
594
  end
598
595
 
596
+ def build_socket(addrs = nil)
597
+ transport_type = case @type
598
+ when "tcp" then TCP
599
+ when "ssl" then SSL
600
+ when "unix" then UNIX
601
+ else
602
+ raise Error, "unsupported transport (#{@type})"
603
+ end
604
+ transport_type.new(@origin, addrs, @options)
605
+ end
606
+
599
607
  def on_error(error)
600
608
  if error.instance_of?(TimeoutError)
601
609
 
@@ -664,5 +672,16 @@ module HTTPX
664
672
  error = error_type.new(request, request.response, read_timeout)
665
673
  on_error(error)
666
674
  end
675
+
676
+ class << self
677
+ def parser_type(protocol)
678
+ case protocol
679
+ when "h2" then HTTP2
680
+ when "http/1.1" then HTTP1
681
+ else
682
+ raise Error, "unsupported protocol (##{protocol})"
683
+ end
684
+ end
685
+ end
667
686
  end
668
687
  end
data/lib/httpx/io/udp.rb CHANGED
@@ -78,6 +78,8 @@ module HTTPX
78
78
  return 0 if ret == :wait_readable
79
79
  return if ret.nil?
80
80
 
81
+ log { "READ: #{buffer.bytesize} bytes..." }
82
+
81
83
  buffer.bytesize
82
84
  rescue IOError
83
85
  end
data/lib/httpx/io/unix.rb CHANGED
@@ -1,11 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "forwardable"
4
-
5
3
  module HTTPX
6
4
  class UNIX < TCP
7
- extend Forwardable
8
-
9
5
  using URIExtensions
10
6
 
11
7
  attr_reader :path
@@ -13,7 +9,7 @@ module HTTPX
13
9
  alias_method :host, :path
14
10
 
15
11
  def initialize(origin, addresses, options)
16
- @addresses = addresses
12
+ @addresses = []
17
13
  @hostname = origin.host
18
14
  @state = :idle
19
15
  @options = Options.new(options)
data/lib/httpx/io.rb CHANGED
@@ -5,13 +5,3 @@ require "httpx/io/udp"
5
5
  require "httpx/io/tcp"
6
6
  require "httpx/io/unix"
7
7
  require "httpx/io/ssl"
8
-
9
- module HTTPX
10
- module IO
11
- extend Registry
12
- register "udp", UDP
13
- register "unix", HTTPX::UNIX
14
- register "tcp", TCP
15
- register "ssl", SSL
16
- end
17
- end
data/lib/httpx/options.rb CHANGED
@@ -4,6 +4,7 @@ require "socket"
4
4
 
5
5
  module HTTPX
6
6
  class Options
7
+ BUFFER_SIZE = 1 << 14
7
8
  WINDOW_SIZE = 1 << 14 # 16K
8
9
  MAX_BODY_THRESHOLD_SIZE = (1 << 10) * 112 # 112K
9
10
  CONNECT_TIMEOUT = 60
@@ -41,6 +42,7 @@ module HTTPX
41
42
  },
42
43
  :headers => {},
43
44
  :window_size => WINDOW_SIZE,
45
+ :buffer_size => BUFFER_SIZE,
44
46
  :body_threshold_size => MAX_BODY_THRESHOLD_SIZE,
45
47
  :request_class => Class.new(Request),
46
48
  :response_class => Class.new(Response),
@@ -178,7 +180,19 @@ module HTTPX
178
180
  end
179
181
 
180
182
  def option_window_size(value)
181
- Integer(value)
183
+ value = Integer(value)
184
+
185
+ raise TypeError, ":window_size must be positive" unless value.positive?
186
+
187
+ value
188
+ end
189
+
190
+ def option_buffer_size(value)
191
+ value = Integer(value)
192
+
193
+ raise TypeError, ":buffer_size must be positive" unless value.positive?
194
+
195
+ value
182
196
  end
183
197
 
184
198
  def option_body_threshold_size(value)
@@ -187,7 +201,7 @@ module HTTPX
187
201
 
188
202
  def option_transport(value)
189
203
  transport = value.to_s
190
- raise TypeError, "\#{transport} is an unsupported transport type" unless IO.registry.key?(transport)
204
+ raise TypeError, "#{transport} is an unsupported transport type" unless %w[unix].include?(transport)
191
205
 
192
206
  transport
193
207
  end
@@ -21,7 +21,7 @@ module HTTPX
21
21
  end
22
22
 
23
23
  def authenticate(request, authenticate)
24
- "Digest #{generate_header(request.verb.to_s.upcase, request.path, authenticate)}"
24
+ "Digest #{generate_header(request.verb, request.path, authenticate)}"
25
25
  end
26
26
 
27
27
  private
@@ -20,9 +20,7 @@ module HTTPX
20
20
  true
21
21
  end
22
22
 
23
- def method_missing(*)
24
- nil
25
- end
23
+ def method_missing(*); end
26
24
  end
27
25
 
28
26
  #
@@ -71,7 +71,7 @@ module HTTPX
71
71
  end.join
72
72
 
73
73
  # canonical request
74
- creq = "#{request.verb.to_s.upcase}" \
74
+ creq = "#{request.verb}" \
75
75
  "\n#{request.canonical_path}" \
76
76
  "\n#{request.canonical_query}" \
77
77
  "\n#{canonical_headers}" \
@@ -5,13 +5,13 @@ module HTTPX
5
5
  module Compression
6
6
  module Brotli
7
7
  class << self
8
- def load_dependencies(_klass)
8
+ def load_dependencies(klass)
9
9
  require "brotli"
10
+ klass.plugin(:compression)
10
11
  end
11
12
 
12
- def configure(klass)
13
- klass.plugin(:compression)
14
- klass.default_options.encodings.register "br", self
13
+ def extra_options(options)
14
+ options.merge(encodings: options.encodings.merge("br" => self))
15
15
  end
16
16
  end
17
17
 
@@ -4,14 +4,19 @@ module HTTPX
4
4
  module Plugins
5
5
  module Compression
6
6
  module Deflate
7
- def self.load_dependencies(_klass)
8
- require "stringio"
9
- require "zlib"
10
- end
7
+ class << self
8
+ def load_dependencies(_klass)
9
+ require "stringio"
10
+ require "zlib"
11
+ end
11
12
 
12
- def self.configure(klass)
13
- klass.plugin(:"compression/gzip")
14
- klass.default_options.encodings.register "deflate", self
13
+ def configure(klass)
14
+ klass.plugin(:"compression/gzip")
15
+ end
16
+
17
+ def extra_options(options)
18
+ options.merge(encodings: options.encodings.merge("deflate" => self))
19
+ end
15
20
  end
16
21
 
17
22
  module Deflater
@@ -6,12 +6,14 @@ module HTTPX
6
6
  module Plugins
7
7
  module Compression
8
8
  module GZIP
9
- def self.load_dependencies(*)
10
- require "zlib"
11
- end
9
+ class << self
10
+ def load_dependencies(*)
11
+ require "zlib"
12
+ end
12
13
 
13
- def self.configure(klass)
14
- klass.default_options.encodings.register "gzip", self
14
+ def extra_options(options)
15
+ options.merge(encodings: options.encodings.merge("gzip" => self))
16
+ end
15
17
  end
16
18
 
17
19
  class Deflater
@@ -20,10 +20,7 @@ module HTTPX
20
20
  end
21
21
 
22
22
  def extra_options(options)
23
- encodings = Module.new do
24
- extend Registry
25
- end
26
- options.merge(encodings: encodings)
23
+ options.merge(encodings: {})
27
24
  end
28
25
  end
29
26
 
@@ -36,7 +33,7 @@ module HTTPX
36
33
  end
37
34
 
38
35
  def option_encodings(value)
39
- raise TypeError, ":encodings must be a registry" unless value.respond_to?(:registry)
36
+ raise TypeError, ":encodings must be an Hash" unless value.is_a?(Hash)
40
37
 
41
38
  value
42
39
  end
@@ -49,7 +46,7 @@ module HTTPX
49
46
  if @headers.key?("range")
50
47
  @headers.delete("accept-encoding")
51
48
  else
52
- @headers["accept-encoding"] ||= @options.encodings.registry.keys
49
+ @headers["accept-encoding"] ||= @options.encodings.keys
53
50
  end
54
51
  end
55
52
  end
@@ -65,7 +62,9 @@ module HTTPX
65
62
  @headers.get("content-encoding").each do |encoding|
66
63
  next if encoding == "identity"
67
64
 
68
- @body = Encoder.new(@body, options.encodings.registry(encoding).deflater)
65
+ next unless options.encodings.key?(encoding)
66
+
67
+ @body = Encoder.new(@body, options.encodings[encoding].deflater)
69
68
  end
70
69
  @headers["content-length"] = @body.bytesize unless unbounded_body?
71
70
  end
@@ -95,7 +94,9 @@ module HTTPX
95
94
  @_inflaters = @headers.get("content-encoding").filter_map do |encoding|
96
95
  next if encoding == "identity"
97
96
 
98
- inflater = @options.encodings.registry(encoding).inflater(compressed_length)
97
+ next unless @options.encodings.key?(encoding)
98
+
99
+ inflater = @options.encodings[encoding].inflater(compressed_length)
99
100
  # do not uncompress if there is no decoder available. In fact, we can't reliably
100
101
  # continue decompressing beyond that, so ignore.
101
102
  break unless inflater
@@ -39,10 +39,7 @@ module HTTPX
39
39
  requests.flat_map do |request|
40
40
  digest = request.options.digest
41
41
 
42
- unless digest
43
- super(request)
44
- next
45
- end
42
+ next super(request) unless digest
46
43
 
47
44
  probe_response = wrap { super(request).first }
48
45
 
@@ -103,7 +103,7 @@ module HTTPX
103
103
  max_redirects: max_redirects - 1)
104
104
  end
105
105
 
106
- build_request(:get, redirect_uri, retry_options)
106
+ build_request("GET", redirect_uri, retry_options)
107
107
  end
108
108
 
109
109
  def __get_location_from_response(response)
@@ -47,7 +47,9 @@ module HTTPX
47
47
  data = message.byteslice(5..size + 5 - 1)
48
48
  if compressed == 1
49
49
  encodings.reverse_each do |algo|
50
- inflater = encoders.registry(algo).inflater(size)
50
+ next unless encoders.key?(algo)
51
+
52
+ inflater = encoders[algo].inflater(size)
51
53
  data = inflater.inflate(data)
52
54
  size = data.bytesize
53
55
  end
@@ -233,7 +233,7 @@ module HTTPX
233
233
  uri.path = rpc_method
234
234
 
235
235
  headers = HEADERS.merge(
236
- "grpc-accept-encoding" => ["identity", *@options.encodings.registry.keys]
236
+ "grpc-accept-encoding" => ["identity", *@options.encodings.keys]
237
237
  )
238
238
  unless deadline == Float::INFINITY
239
239
  # convert to milliseconds
@@ -249,7 +249,7 @@ module HTTPX
249
249
 
250
250
  if compression
251
251
  headers["grpc-encoding"] = compression
252
- deflater = @options.encodings.registry(compression).deflater
252
+ deflater = @options.encodings[compression].deflater if @options.encodings.key?(compression)
253
253
  end
254
254
 
255
255
  headers.merge!(@options.call_credentials.call) if @options.call_credentials
@@ -264,7 +264,7 @@ module HTTPX
264
264
  Message.encode(input, deflater: deflater)
265
265
  end
266
266
 
267
- build_request(:post, uri, headers: headers, body: body)
267
+ build_request("POST", uri, headers: headers, body: body)
268
268
  end
269
269
  end
270
270
  end
@@ -9,16 +9,12 @@ module HTTPX
9
9
  # https://gitlab.com/os85/httpx/wikis/Upgrade#h2c
10
10
  #
11
11
  module H2C
12
- VALID_H2C_VERBS = %i[get options head].freeze
12
+ VALID_H2C_VERBS = %w[GET OPTIONS HEAD].freeze
13
13
 
14
14
  class << self
15
- def load_dependencies(*)
15
+ def load_dependencies(klass)
16
16
  require "base64"
17
- end
18
-
19
- def configure(klass)
20
17
  klass.plugin(:upgrade)
21
- klass.default_options.upgrade_handlers.register "h2c", self
22
18
  end
23
19
 
24
20
  def call(connection, request, response)
@@ -26,7 +22,7 @@ module HTTPX
26
22
  end
27
23
 
28
24
  def extra_options(options)
29
- options.merge(max_concurrent_requests: 1)
25
+ options.merge(max_concurrent_requests: 1, upgrade_handlers: options.upgrade_handlers.merge("h2c" => self))
30
26
  end
31
27
  end
32
28
 
@@ -38,7 +34,7 @@ module HTTPX
38
34
 
39
35
  connection = pool.find_connection(upgrade_request.uri, upgrade_request.options)
40
36
 
41
- return super if connection && connection.upgrade_protocol == :h2c
37
+ return super if connection && connection.upgrade_protocol == "h2c"
42
38
 
43
39
  # build upgrade request
44
40
  upgrade_request.headers.add("connection", "upgrade")
@@ -83,7 +79,7 @@ module HTTPX
83
79
  set_parser_callbacks(@parser)
84
80
  @inflight += 1
85
81
  @parser.upgrade(request, response)
86
- @upgrade_protocol = :h2c
82
+ @upgrade_protocol = "h2c"
87
83
 
88
84
  if request.options.max_concurrent_requests != @options.max_concurrent_requests
89
85
  @options = @options.merge(max_concurrent_requests: nil)