httpx 0.22.4 → 0.23.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 (85) hide show
  1. checksums.yaml +4 -4
  2. data/doc/release_notes/0_22_5.md +6 -0
  3. data/doc/release_notes/0_23_0.md +42 -0
  4. data/lib/httpx/adapters/datadog.rb +12 -2
  5. data/lib/httpx/adapters/faraday.rb +1 -1
  6. data/lib/httpx/adapters/sentry.rb +15 -5
  7. data/lib/httpx/adapters/webmock.rb +2 -2
  8. data/lib/httpx/buffer.rb +4 -0
  9. data/lib/httpx/callbacks.rb +3 -3
  10. data/lib/httpx/chainable.rb +4 -4
  11. data/lib/httpx/connection/http1.rb +2 -2
  12. data/lib/httpx/connection/http2.rb +2 -3
  13. data/lib/httpx/connection.rb +31 -11
  14. data/lib/httpx/io/udp.rb +2 -0
  15. data/lib/httpx/io/unix.rb +1 -5
  16. data/lib/httpx/io.rb +0 -10
  17. data/lib/httpx/options.rb +16 -2
  18. data/lib/httpx/plugins/authentication/digest.rb +1 -1
  19. data/lib/httpx/plugins/aws_sdk_authentication.rb +1 -3
  20. data/lib/httpx/plugins/aws_sigv4.rb +1 -1
  21. data/lib/httpx/plugins/compression/brotli.rb +4 -4
  22. data/lib/httpx/plugins/compression/deflate.rb +12 -7
  23. data/lib/httpx/plugins/compression/gzip.rb +7 -5
  24. data/lib/httpx/plugins/compression.rb +9 -8
  25. data/lib/httpx/plugins/digest_authentication.rb +1 -4
  26. data/lib/httpx/plugins/follow_redirects.rb +1 -1
  27. data/lib/httpx/plugins/grpc/message.rb +3 -1
  28. data/lib/httpx/plugins/grpc.rb +3 -3
  29. data/lib/httpx/plugins/h2c.rb +5 -9
  30. data/lib/httpx/plugins/internal_telemetry.rb +16 -0
  31. data/lib/httpx/plugins/multipart.rb +14 -2
  32. data/lib/httpx/plugins/proxy/http.rb +4 -4
  33. data/lib/httpx/plugins/proxy.rb +65 -31
  34. data/lib/httpx/plugins/response_cache.rb +2 -2
  35. data/lib/httpx/plugins/retries.rb +49 -2
  36. data/lib/httpx/plugins/upgrade/h2.rb +3 -3
  37. data/lib/httpx/plugins/upgrade.rb +4 -7
  38. data/lib/httpx/plugins/webdav.rb +7 -7
  39. data/lib/httpx/pool.rb +7 -3
  40. data/lib/httpx/request.rb +23 -13
  41. data/lib/httpx/resolver/https.rb +37 -20
  42. data/lib/httpx/resolver/multi.rb +1 -6
  43. data/lib/httpx/resolver/native.rb +128 -36
  44. data/lib/httpx/resolver.rb +26 -14
  45. data/lib/httpx/response.rb +14 -16
  46. data/lib/httpx/session.rb +1 -0
  47. data/lib/httpx/transcoder/body.rb +0 -1
  48. data/lib/httpx/transcoder/chunker.rb +0 -1
  49. data/lib/httpx/transcoder/form.rb +0 -1
  50. data/lib/httpx/transcoder/json.rb +0 -1
  51. data/lib/httpx/transcoder/xml.rb +0 -1
  52. data/lib/httpx/transcoder.rb +0 -2
  53. data/lib/httpx/version.rb +1 -1
  54. data/lib/httpx.rb +0 -1
  55. data/sig/buffer.rbs +1 -0
  56. data/sig/chainable.rbs +3 -3
  57. data/sig/connection.rbs +17 -6
  58. data/sig/errors.rbs +9 -0
  59. data/sig/httpx.rbs +3 -3
  60. data/sig/io/ssl.rbs +17 -0
  61. data/sig/io/tcp.rbs +57 -0
  62. data/sig/io/udp.rbs +20 -0
  63. data/sig/io/unix.rbs +10 -0
  64. data/sig/options.rbs +5 -1
  65. data/sig/plugins/compression.rbs +6 -2
  66. data/sig/plugins/cookies/jar.rbs +2 -2
  67. data/sig/plugins/grpc.rbs +3 -3
  68. data/sig/plugins/h2c.rbs +1 -1
  69. data/sig/plugins/proxy.rbs +1 -5
  70. data/sig/plugins/response_cache.rbs +1 -1
  71. data/sig/plugins/retries.rbs +28 -8
  72. data/sig/plugins/upgrade.rbs +5 -3
  73. data/sig/request.rbs +6 -2
  74. data/sig/resolver/https.rbs +3 -1
  75. data/sig/resolver/native.rbs +7 -2
  76. data/sig/resolver/resolver.rbs +0 -2
  77. data/sig/resolver/system.rbs +2 -0
  78. data/sig/resolver.rbs +8 -4
  79. data/sig/response.rbs +6 -2
  80. data/sig/session.rbs +10 -10
  81. data/sig/transcoder/xml.rbs +1 -1
  82. data/sig/transcoder.rbs +4 -5
  83. metadata +11 -5
  84. data/lib/httpx/registry.rb +0 -85
  85. data/sig/registry.rbs +0 -13
@@ -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)
@@ -32,6 +32,15 @@ module HTTPX
32
32
  end
33
33
  end
34
34
 
35
+ module NativeResolverMethods
36
+ def transition(nextstate)
37
+ state = @state
38
+ val = super
39
+ meter_elapsed_time("Resolver::Native: #{state} -> #{nextstate}")
40
+ val
41
+ end
42
+ end
43
+
35
44
  module InstanceMethods
36
45
  def self.included(klass)
37
46
  klass.prepend TrackTimeMethods
@@ -42,6 +51,13 @@ module HTTPX
42
51
  meter_elapsed_time("Session: initializing...")
43
52
  super
44
53
  meter_elapsed_time("Session: initialized!!!")
54
+ resolver_type = @options.resolver_class
55
+ resolver_type = Resolver.resolver_for(resolver_type)
56
+ return unless resolver_type <= Resolver::Native
57
+
58
+ resolver_type.prepend TrackTimeMethods
59
+ resolver_type.prepend NativeResolverMethods
60
+ @options = @options.merge(resolver_class: resolver_type)
45
61
  end
46
62
 
47
63
  def close(*)
@@ -40,9 +40,21 @@ module HTTPX
40
40
  require "httpx/plugins/multipart/part"
41
41
  require "httpx/plugins/multipart/mime_type_detector"
42
42
  end
43
+ end
44
+
45
+ module RequestBodyMethods
46
+ private
47
+
48
+ def initialize_body(options)
49
+ return FormTranscoder.encode(options.form) if options.form
50
+
51
+ super
52
+ end
53
+ end
43
54
 
44
- def configure(*)
45
- Transcoder.register("form", FormTranscoder)
55
+ module ResponseMethods
56
+ def form
57
+ decode(FormTranscoder)
46
58
  end
47
59
  end
48
60
 
@@ -61,7 +61,7 @@ module HTTPX
61
61
  return unless @io.connected?
62
62
 
63
63
  @parser || begin
64
- @parser = registry(@io.protocol).new(@write_buffer, @options.merge(max_concurrent_requests: 1))
64
+ @parser = self.class.parser_type(@io.protocol).new(@write_buffer, @options.merge(max_concurrent_requests: 1))
65
65
  parser = @parser
66
66
  parser.extend(ProxyParser)
67
67
  parser.on(:response, &method(:__http_on_connect))
@@ -141,9 +141,9 @@ module HTTPX
141
141
 
142
142
  module ProxyParser
143
143
  def join_headline(request)
144
- return super if request.verb == :connect
144
+ return super if request.verb == "CONNECT"
145
145
 
146
- "#{request.verb.to_s.upcase} #{request.uri} HTTP/#{@version.join(".")}"
146
+ "#{request.verb} #{request.uri} HTTP/#{@version.join(".")}"
147
147
  end
148
148
 
149
149
  def set_protocol_headers(request)
@@ -161,7 +161,7 @@ module HTTPX
161
161
 
162
162
  class ConnectRequest < Request
163
163
  def initialize(uri, _options)
164
- super(:connect, uri, {})
164
+ super("CONNECT", uri, {})
165
165
  @headers.delete("accept")
166
166
  end
167
167
 
@@ -18,6 +18,43 @@ module HTTPX
18
18
  Error = HTTPProxyError
19
19
  PROXY_ERRORS = [TimeoutError, IOError, SystemCallError, Error].freeze
20
20
 
21
+ class << self
22
+ def configure(klass)
23
+ klass.plugin(:"proxy/http")
24
+ klass.plugin(:"proxy/socks4")
25
+ klass.plugin(:"proxy/socks5")
26
+ end
27
+
28
+ if URI::Generic.methods.include?(:use_proxy?)
29
+ def use_proxy?(*args)
30
+ URI::Generic.use_proxy?(*args)
31
+ end
32
+ else
33
+ # https://github.com/ruby/uri/blob/ae07f956a4bea00b4f54a75bd40b8fa918103eed/lib/uri/generic.rb
34
+ def use_proxy?(hostname, addr, port, no_proxy)
35
+ hostname = hostname.downcase
36
+ dothostname = ".#{hostname}"
37
+ no_proxy.scan(/([^:,\s]+)(?::(\d+))?/) do |p_host, p_port|
38
+ if !p_port || port == p_port.to_i
39
+ if p_host.start_with?(".")
40
+ return false if hostname.end_with?(p_host.downcase)
41
+ else
42
+ return false if dothostname.end_with?(".#{p_host.downcase}")
43
+ end
44
+ if addr
45
+ begin
46
+ return false if IPAddr.new(p_host).include?(addr)
47
+ rescue IPAddr::InvalidAddressError
48
+ next
49
+ end
50
+ end
51
+ end
52
+ end
53
+ true
54
+ end
55
+ end
56
+ end
57
+
21
58
  class Parameters
22
59
  attr_reader :uri, :username, :password, :scheme
23
60
 
@@ -77,14 +114,6 @@ module HTTPX
77
114
  end
78
115
  end
79
116
 
80
- class << self
81
- def configure(klass)
82
- klass.plugin(:"proxy/http")
83
- klass.plugin(:"proxy/socks4")
84
- klass.plugin(:"proxy/socks5")
85
- end
86
- end
87
-
88
117
  module OptionsMethods
89
118
  def option_proxy(value)
90
119
  value.is_a?(Parameters) ? value : Hash[value]
@@ -94,34 +123,39 @@ module HTTPX
94
123
  module InstanceMethods
95
124
  private
96
125
 
97
- def proxy_uris(uri, options)
98
- @_proxy_uris ||= begin
99
- uris = options.proxy ? Array(options.proxy[:uri]) : []
100
- if uris.empty?
101
- uri = URI(uri).find_proxy
102
- uris << uri if uri
103
- end
104
- uris
105
- end
106
- return if @_proxy_uris.empty?
126
+ def find_connection(request, connections, options)
127
+ return super unless options.respond_to?(:proxy)
107
128
 
108
- proxy = options.proxy
129
+ uri = URI(request.uri)
109
130
 
110
- return { uri: uri.host } if proxy && proxy.key?(:no_proxy) && !Array(proxy[:no_proxy]).grep(uri.host).empty?
131
+ proxy_opts = if (next_proxy = uri.find_proxy)
132
+ { uri: next_proxy }
133
+ else
134
+ proxy = options.proxy
111
135
 
112
- proxy_opts = { uri: @_proxy_uris.first }
113
- proxy_opts = options.proxy.merge(proxy_opts) if options.proxy
114
- proxy_opts
115
- end
136
+ return super unless proxy
116
137
 
117
- def find_connection(request, connections, options)
118
- return super unless options.respond_to?(:proxy)
138
+ return super(request, connections, options.merge(proxy: nil)) unless proxy.key?(:uri)
119
139
 
120
- uri = URI(request.uri)
121
- next_proxy = proxy_uris(uri, options)
122
- raise Error, "Failed to connect to proxy" unless next_proxy
140
+ @_proxy_uris ||= Array(proxy[:uri])
141
+
142
+ next_proxy = @_proxy_uris.first
143
+ raise Error, "Failed to connect to proxy" unless next_proxy
144
+
145
+ if proxy.key?(:no_proxy)
146
+ next_proxy = URI(next_proxy)
147
+
148
+ no_proxy = proxy[:no_proxy]
149
+ no_proxy = no_proxy.join(",") if no_proxy.is_a?(Array)
150
+
151
+ return super(request, connections, options.merge(proxy: nil)) unless Proxy.use_proxy?(uri.host, next_proxy.host,
152
+ next_proxy.port, no_proxy)
153
+ end
154
+
155
+ proxy.merge(uri: next_proxy)
156
+ end
123
157
 
124
- proxy = Parameters.new(**next_proxy) unless next_proxy[:uri] == uri.host
158
+ proxy = Parameters.new(**proxy_opts)
125
159
 
126
160
  proxy_options = options.merge(proxy: proxy)
127
161
  connection = pool.find_connection(uri, proxy_options) || build_connection(uri, proxy_options)
@@ -284,7 +318,7 @@ module HTTPX
284
318
  register_plugin :proxy, Proxy
285
319
  end
286
320
 
287
- class ProxySSL < IO.registry["ssl"]
321
+ class ProxySSL < SSL
288
322
  def initialize(tcp, request_uri, options)
289
323
  @io = tcp.to_io
290
324
  super(request_uri, tcp.addresses, options)
@@ -8,7 +8,7 @@ module HTTPX
8
8
  # https://gitlab.com/os85/httpx/wikis/Response-Cache
9
9
  #
10
10
  module ResponseCache
11
- CACHEABLE_VERBS = %i[get head].freeze
11
+ CACHEABLE_VERBS = %w[GET HEAD].freeze
12
12
  CACHEABLE_STATUS_CODES = [200, 203, 206, 300, 301, 410].freeze
13
13
  private_constant :CACHEABLE_VERBS
14
14
  private_constant :CACHEABLE_STATUS_CODES
@@ -96,7 +96,7 @@ module HTTPX
96
96
 
97
97
  module RequestMethods
98
98
  def response_cache_key
99
- @response_cache_key ||= Digest::SHA1.hexdigest("httpx-response-cache-#{@verb}#{@uri}")
99
+ @response_cache_key ||= Digest::SHA1.hexdigest("httpx-response-cache-#{@verb}-#{@uri}")
100
100
  end
101
101
  end
102
102
 
@@ -11,7 +11,7 @@ module HTTPX
11
11
  MAX_RETRIES = 3
12
12
  # TODO: pass max_retries in a configure/load block
13
13
 
14
- IDEMPOTENT_METHODS = %i[get options head put delete].freeze
14
+ IDEMPOTENT_METHODS = %w[GET OPTIONS HEAD PUT DELETE].freeze
15
15
  RETRYABLE_ERRORS = [
16
16
  IOError,
17
17
  EOFError,
@@ -96,7 +96,7 @@ module HTTPX
96
96
  )
97
97
  # rubocop:enable Style/MultilineTernaryOperator
98
98
  )
99
- response.close if response.respond_to?(:close)
99
+ __try_partial_retry(request, response)
100
100
  log { "failed to get response, #{request.retries} tries to go..." }
101
101
  request.retries -= 1
102
102
  request.transition(:idle)
@@ -134,15 +134,62 @@ module HTTPX
134
134
  def __retryable_error?(ex)
135
135
  RETRYABLE_ERRORS.any? { |klass| ex.is_a?(klass) }
136
136
  end
137
+
138
+ #
139
+ # Atttempt to set the request to perform a partial range request.
140
+ # This happens if the peer server accepts byte-range requests, and
141
+ # the last response contains some body payload.
142
+ #
143
+ def __try_partial_retry(request, response)
144
+ response = response.response if response.is_a?(ErrorResponse)
145
+
146
+ return unless response
147
+
148
+ unless response.headers.key?("accept-ranges") &&
149
+ response.headers["accept-ranges"] == "bytes" && # there's nothing else supported though...
150
+ (original_body = response.body)
151
+ response.close if response.respond_to?(:close)
152
+ return
153
+ end
154
+
155
+ request.partial_response = response
156
+
157
+ size = original_body.bytesize
158
+
159
+ request.headers["range"] = "bytes=#{size}-"
160
+ end
137
161
  end
138
162
 
139
163
  module RequestMethods
140
164
  attr_accessor :retries
141
165
 
166
+ attr_writer :partial_response
167
+
142
168
  def initialize(*args)
143
169
  super
144
170
  @retries = @options.max_retries
145
171
  end
172
+
173
+ def response=(response)
174
+ if @partial_response
175
+ if response.is_a?(Response) && response.status == 206
176
+ response.from_partial_response(@partial_response)
177
+ else
178
+ @partial_response.close
179
+ end
180
+ @partial_response = nil
181
+ end
182
+
183
+ super
184
+ end
185
+ end
186
+
187
+ module ResponseMethods
188
+ def from_partial_response(response)
189
+ @status = response.status
190
+ @headers = response.headers
191
+ @body = response.body
192
+ end
146
193
  end
147
194
  end
148
195
  register_plugin :retries, Retries
@@ -10,8 +10,8 @@ module HTTPX
10
10
  #
11
11
  module H2
12
12
  class << self
13
- def configure(klass)
14
- klass.default_options.upgrade_handlers.register "h2", self
13
+ def extra_options(options)
14
+ options.merge(upgrade_handlers: options.upgrade_handlers.merge("h2" => self))
15
15
  end
16
16
 
17
17
  def call(connection, _request, _response)
@@ -32,7 +32,7 @@ module HTTPX
32
32
 
33
33
  @parser = Connection::HTTP2.new(@write_buffer, @options)
34
34
  set_parser_callbacks(@parser)
35
- @upgrade_protocol = :h2
35
+ @upgrade_protocol = "h2"
36
36
 
37
37
  # what's happening here:
38
38
  # a deviation from the state machine is done to perform the actions when a
@@ -15,16 +15,13 @@ module HTTPX
15
15
  end
16
16
 
17
17
  def extra_options(options)
18
- upgrade_handlers = Module.new do
19
- extend Registry
20
- end
21
- options.merge(upgrade_handlers: upgrade_handlers)
18
+ options.merge(upgrade_handlers: {})
22
19
  end
23
20
  end
24
21
 
25
22
  module OptionsMethods
26
23
  def option_upgrade_handlers(value)
27
- raise TypeError, ":upgrade_handlers must be a registry" unless value.respond_to?(:registry)
24
+ raise TypeError, ":upgrade_handlers must be a Hash" unless value.is_a?(Hash)
28
25
 
29
26
  value
30
27
  end
@@ -41,9 +38,9 @@ module HTTPX
41
38
 
42
39
  upgrade_protocol = response.headers["upgrade"].split(/ *, */).first
43
40
 
44
- return response unless upgrade_protocol && options.upgrade_handlers.registry.key?(upgrade_protocol)
41
+ return response unless upgrade_protocol && options.upgrade_handlers.key?(upgrade_protocol)
45
42
 
46
- protocol_handler = options.upgrade_handlers.registry(upgrade_protocol)
43
+ protocol_handler = options.upgrade_handlers[upgrade_protocol]
47
44
 
48
45
  return response unless protocol_handler
49
46
 
@@ -10,11 +10,11 @@ module HTTPX
10
10
  module WebDav
11
11
  module InstanceMethods
12
12
  def copy(src, dest)
13
- request(:copy, src, headers: { "destination" => @options.origin.merge(dest) })
13
+ request("COPY", src, headers: { "destination" => @options.origin.merge(dest) })
14
14
  end
15
15
 
16
16
  def move(src, dest)
17
- request(:move, src, headers: { "destination" => @options.origin.merge(dest) })
17
+ request("MOVE", src, headers: { "destination" => @options.origin.merge(dest) })
18
18
  end
19
19
 
20
20
  def lock(path, timeout: nil, &blk)
@@ -30,7 +30,7 @@ module HTTPX
30
30
  "<D:locktype><D:write/></D:locktype>" \
31
31
  "<D:owner>null</D:owner>" \
32
32
  "</D:lockinfo>"
33
- response = request(:lock, path, headers: headers, xml: xml)
33
+ response = request("LOCK", path, headers: headers, xml: xml)
34
34
 
35
35
  return response unless response.is_a?(Response)
36
36
 
@@ -46,11 +46,11 @@ module HTTPX
46
46
  end
47
47
 
48
48
  def unlock(path, lock_token)
49
- request(:unlock, path, headers: { "lock-token" => lock_token })
49
+ request("UNLOCK", path, headers: { "lock-token" => lock_token })
50
50
  end
51
51
 
52
52
  def mkcol(dir)
53
- request(:mkcol, dir)
53
+ request("MKCOL", dir)
54
54
  end
55
55
 
56
56
  def propfind(path, xml = nil)
@@ -64,13 +64,13 @@ module HTTPX
64
64
  xml
65
65
  end
66
66
 
67
- request(:propfind, path, headers: { "depth" => "1" }, xml: body)
67
+ request("PROPFIND", path, headers: { "depth" => "1" }, xml: body)
68
68
  end
69
69
 
70
70
  def proppatch(path, xml)
71
71
  body = "<?xml version=\"1.0\"?>" \
72
72
  "<D:propertyupdate xmlns:D=\"DAV:\" xmlns:Z=\"http://ns.example.com/standards/z39.50/\">#{xml}</D:propertyupdate>"
73
- request(:proppatch, path, xml: body)
73
+ request("PROPPATCH", path, xml: body)
74
74
  end
75
75
  # %i[ orderpatch acl report search]
76
76
  end
data/lib/httpx/pool.rb CHANGED
@@ -141,8 +141,9 @@ module HTTPX
141
141
  connection.once(:connect_error) do |err|
142
142
  if new_connection.connecting?
143
143
  new_connection.merge(connection)
144
+ connection.force_reset
144
145
  else
145
- connection.handle_error(err)
146
+ connection.__send__(:handle_error, err)
146
147
  end
147
148
  end
148
149
 
@@ -156,8 +157,9 @@ module HTTPX
156
157
  if connection.connecting?
157
158
  # main connection has the requests
158
159
  connection.merge(new_connection)
160
+ new_connection.force_reset
159
161
  else
160
- new_connection.handle_error(err)
162
+ new_connection.__send__(:handle_error, err)
161
163
  end
162
164
  end
163
165
 
@@ -183,6 +185,8 @@ module HTTPX
183
185
  end
184
186
 
185
187
  def on_resolver_error(connection, error)
188
+ return connection.emit(:connect_error, error) if connection.connecting? && connection.callbacks_for?(:connect_error)
189
+
186
190
  connection.emit(:error, error)
187
191
  end
188
192
 
@@ -240,7 +244,7 @@ module HTTPX
240
244
  def find_resolver_for(connection)
241
245
  connection_options = connection.options
242
246
  resolver_type = connection_options.resolver_class
243
- resolver_type = Resolver.registry(resolver_type) if resolver_type.is_a?(Symbol)
247
+ resolver_type = Resolver.resolver_for(resolver_type)
244
248
 
245
249
  @resolvers[resolver_type] ||= begin
246
250
  resolver_manager = if resolver_type.multi?
data/lib/httpx/request.rb CHANGED
@@ -19,7 +19,11 @@ module HTTPX
19
19
  def_delegator :@body, :empty?
20
20
 
21
21
  def initialize(verb, uri, options = {})
22
- @verb = verb.to_s.downcase.to_sym
22
+ if verb.is_a?(Symbol)
23
+ warn "DEPRECATION WARNING: Using symbols for `verb` is deprecated, and will not be supported in httpx 1.0. " \
24
+ "Use \"#{verb.to_s.upcase}\" instead."
25
+ end
26
+ @verb = verb.to_s.upcase
23
27
  @options = Options.new(options)
24
28
  @uri = Utils.to_uri(uri)
25
29
  if @uri.relative?
@@ -116,7 +120,7 @@ module HTTPX
116
120
 
117
121
  query = []
118
122
  if (q = @options.params)
119
- query << Transcoder.registry("form").encode(q)
123
+ query << Transcoder::Form.encode(q)
120
124
  end
121
125
  query << @uri.query if @uri.query
122
126
  @query = query.join("&")
@@ -138,7 +142,7 @@ module HTTPX
138
142
  # :nocov:
139
143
  def inspect
140
144
  "#<HTTPX::Request:#{object_id} " \
141
- "#{@verb.to_s.upcase} " \
145
+ "#{@verb} " \
142
146
  "#{uri} " \
143
147
  "@headers=#{@headers} " \
144
148
  "@body=#{@body}>"
@@ -156,15 +160,7 @@ module HTTPX
156
160
 
157
161
  def initialize(headers, options)
158
162
  @headers = headers
159
- @body = if options.body
160
- Transcoder.registry("body").encode(options.body)
161
- elsif options.form
162
- Transcoder.registry("form").encode(options.form)
163
- elsif options.json
164
- Transcoder.registry("json").encode(options.json)
165
- elsif options.xml
166
- Transcoder.registry("xml").encode(options.xml)
167
- end
163
+ @body = initialize_body(options)
168
164
  return if @body.nil?
169
165
 
170
166
  @headers["content-type"] ||= @body.content_type
@@ -207,7 +203,7 @@ module HTTPX
207
203
 
208
204
  def stream(body)
209
205
  encoded = body
210
- encoded = Transcoder.registry("chunker").encode(body.enum_for(:each)) if chunked?
206
+ encoded = Transcoder::Chunker.encode(body.enum_for(:each)) if chunked?
211
207
  encoded
212
208
  end
213
209
 
@@ -231,6 +227,20 @@ module HTTPX
231
227
  "#{unbounded_body? ? "stream" : "@bytesize=#{bytesize}"}>"
232
228
  end
233
229
  # :nocov:
230
+
231
+ private
232
+
233
+ def initialize_body(options)
234
+ if options.body
235
+ Transcoder::Body.encode(options.body)
236
+ elsif options.form
237
+ Transcoder::Form.encode(options.form)
238
+ elsif options.json
239
+ Transcoder::JSON.encode(options.json)
240
+ elsif options.xml
241
+ Transcoder::Xml.encode(options.xml)
242
+ end
243
+ end
234
244
  end
235
245
 
236
246
  def transition(nextstate)