httpx 0.4.0 → 0.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 853641fa479bca4da2dca4d69bf8eddf6b323b12c40096cdb22faff1a8f80176
4
- data.tar.gz: 8f74a2b53e2037863b9b66e4184e568f7de33bab9f6a65f27b9b9d8f6f3b145b
3
+ metadata.gz: cdf61781fa437f8bf02932b38f029d56f25443690eee087fb09974c5d48595a3
4
+ data.tar.gz: 75ab23803f01f6c52bcc6f754a93c799efce99b5892c9a4f0815c6254a3e022c
5
5
  SHA512:
6
- metadata.gz: 736eb3d84089ac6d98576f6aeb1b20f3cb56cf32bc070c999fd41c0b1685612b89cf397884053e8d103c9464c1998f2651b9a219692b36dee9848a051f13d5d4
7
- data.tar.gz: 6c17fbd06732769f09689ccc2f10e0f5fcb8e897ac6c32aa6e96ef707b2bcc26577b4dae8a8b3486e35495e002e833e06593421f99baa26f3c2586e651aaf393
6
+ metadata.gz: 57ae0b1d04da8d0e19951a704a40d9c136785281fb5ec2677aaac6b54e98baab0542ad4c8d40553270af8b120d6cf856678bd62554fe1cab7192bfdc26ee08f2
7
+ data.tar.gz: 1e0f59ecd050838021578981d3ea1f3fa467671ef6c7efc740770cb33462ec81afa7e6a55bbfa2814cd19dacff0bf0e887c6b24ecea405c5440daf369074f766
@@ -18,6 +18,31 @@ module Faraday
18
18
  }
19
19
  [meth, env.url, request_options]
20
20
  end
21
+
22
+ def options_from_env(env)
23
+ timeout_options = {
24
+ connect_timeout: env.request.open_timeout,
25
+ operation_timeout: env.request.timeout,
26
+ }.reject { |_, v| v.nil? }
27
+
28
+ options = {
29
+ ssl: {},
30
+ timeout: timeout_options,
31
+ }
32
+
33
+ options[:ssl][:verify_mode] = OpenSSL::SSL::VERIFY_PEER if env.ssl.verify
34
+ options[:ssl][:ca_file] = env.ssl.ca_file if env.ssl.ca_file
35
+ options[:ssl][:ca_path] = env.ssl.ca_path if env.ssl.ca_path
36
+ options[:ssl][:cert_store] = env.ssl.cert_store if env.ssl.cert_store
37
+ options[:ssl][:cert] = env.ssl.client_cert if env.ssl.client_cert
38
+ options[:ssl][:key] = env.ssl.client_key if env.ssl.client_key
39
+ options[:ssl][:ssl_version] = env.ssl.version if env.ssl.version
40
+ options[:ssl][:verify_depth] = env.ssl.verify_depth if env.ssl.verify_depth
41
+ options[:ssl][:min_version] = env.ssl.min_version if env.ssl.min_version
42
+ options[:ssl][:max_version] = env.ssl.max_version if env.ssl.max_version
43
+
44
+ options
45
+ end
21
46
  end
22
47
 
23
48
  include RequestMixin
@@ -109,19 +134,9 @@ module Faraday
109
134
  requests = @handlers.map { |handler| build_request(handler.env) }
110
135
  env = @handlers.last.env
111
136
 
112
- timeout_options = {
113
- connect_timeout: env.request.open_timeout,
114
- operation_timeout: env.request.timeout,
115
- }.reject { |_, v| v.nil? }
116
-
117
- options = {
118
- ssl: env.ssl,
119
- timeout: timeout_options,
120
- }
121
-
122
137
  proxy_options = { uri: env.request.proxy }
123
138
 
124
- session = @session.with(options)
139
+ session = @session.with(options_from_env(env))
125
140
  session = session.plugin(:proxy).with_proxy(proxy_options) if env.request.proxy
126
141
 
127
142
  responses = session.request(requests)
@@ -159,19 +174,7 @@ module Faraday
159
174
 
160
175
  request_options = build_request(env)
161
176
 
162
- timeout_options = {
163
- connect_timeout: env.request.open_timeout,
164
- operation_timeout: env.request.timeout,
165
- }.reject { |_, v| v.nil? }
166
-
167
- options = {
168
- ssl: env.ssl,
169
- timeout: timeout_options,
170
- }
171
-
172
- proxy_options = { uri: env.request.proxy }
173
-
174
- session = @session.with(options)
177
+ session = @session.with(options_from_env(env))
175
178
  session = session.plugin(:proxy).with_proxy(proxy_options) if env.request.proxy
176
179
  response = session.__send__(*request_options)
177
180
  response.raise_for_status unless response.is_a?(::HTTPX::Response)
@@ -177,8 +177,8 @@ module HTTPX
177
177
  end
178
178
 
179
179
  def send(request)
180
- if @error_response
181
- emit(:response, request, @error_response)
180
+ if @error
181
+ emit(:response, request, ErrorResponse.new(request, @error, @options))
182
182
  elsif @parser && !@write_buffer.full?
183
183
  request.headers["alt-used"] = @origin.authority if match_altsvcs?(request.uri)
184
184
  parser.send(request)
@@ -297,7 +297,7 @@ module HTTPX
297
297
  when MisdirectedRequestError
298
298
  emit(:uncoalesce, request.uri)
299
299
  else
300
- response = ErrorResponse.new(ex, @options)
300
+ response = ErrorResponse.new(request, ex, @options)
301
301
  request.emit(:response, response)
302
302
  end
303
303
  end
@@ -306,7 +306,7 @@ module HTTPX
306
306
  def transition(nextstate)
307
307
  case nextstate
308
308
  when :idle
309
- @error_response = nil
309
+ @error = nil
310
310
  @timeout_threshold = @options.timeout.connect_timeout
311
311
  @timeout = @timeout_threshold
312
312
  when :open
@@ -363,9 +363,9 @@ module HTTPX
363
363
  end
364
364
 
365
365
  parser.handle_error(e) if @parser && parser.respond_to?(:handle_error)
366
- @error_response = ErrorResponse.new(e, @options)
366
+ @error = e
367
367
  @pending.each do |request, _|
368
- request.emit(:response, @error_response)
368
+ request.emit(:response, ErrorResponse.new(request, @error, @options))
369
369
  end
370
370
  end
371
371
  end
@@ -26,6 +26,15 @@ module HTTPX
26
26
 
27
27
  ResolveError = Class.new(Error)
28
28
 
29
+ NativeResolveError = Class.new(ResolveError) do
30
+ attr_reader :connection, :host
31
+ def initialize(connection, host, message = "Can't resolve #{host}")
32
+ @connection = connection
33
+ @host = host
34
+ super(message)
35
+ end
36
+ end
37
+
29
38
  HTTPError = Class.new(Error) do
30
39
  attr_reader :response
31
40
 
@@ -3,9 +3,11 @@
3
3
  module HTTPX
4
4
  module Plugins
5
5
  #
6
- # This plugin adds a shim #authentication method to the session, which will fill
6
+ # This plugin adds a shim +authentication+ method to the session, which will fill
7
7
  # the HTTP Authorization header.
8
8
  #
9
+ # https://gitlab.com/honeyryderchuck/httpx/wikis/Authentication#authentication
10
+ #
9
11
  module Authentication
10
12
  module InstanceMethods
11
13
  def authentication(token)
@@ -3,11 +3,12 @@
3
3
  module HTTPX
4
4
  module Plugins
5
5
  #
6
- # This plugin adds helper methods to implement HTTP Basic Auth
7
- # https://tools.ietf.org/html/rfc7617
6
+ # This plugin adds helper methods to implement HTTP Basic Auth (https://tools.ietf.org/html/rfc7617)
7
+ #
8
+ # https://gitlab.com/honeyryderchuck/httpx/wikis/Authentication#basic-authentication
8
9
  #
9
10
  module BasicAuthentication
10
- def self.load_dependencies(klass, *)
11
+ def self.load_dependencies(klass)
11
12
  require "base64"
12
13
  klass.plugin(:authentication)
13
14
  end
@@ -10,9 +10,11 @@ module HTTPX
10
10
  #
11
11
  # It supports both *gzip* and *deflate*.
12
12
  #
13
+ # https://gitlab.com/honeyryderchuck/httpx/wikis/Compression
14
+ #
13
15
  module Compression
14
16
  extend Registry
15
- def self.load_dependencies(klass, *)
17
+ def self.load_dependencies(klass)
16
18
  klass.plugin(:"compression/gzip")
17
19
  klass.plugin(:"compression/deflate")
18
20
  end
@@ -4,7 +4,7 @@ module HTTPX
4
4
  module Plugins
5
5
  module Compression
6
6
  module Brotli
7
- def self.load_dependencies(klass, *)
7
+ def self.load_dependencies(klass)
8
8
  klass.plugin(:compression)
9
9
  require "brotli"
10
10
  end
@@ -9,6 +9,8 @@ module HTTPX
9
9
  #
10
10
  # It also adds a *#cookies* helper, so that you can pre-fill the cookies of a session.
11
11
  #
12
+ # https://gitlab.com/honeyryderchuck/httpx/wikis/Cookies
13
+ #
12
14
  module Cookies
13
15
  using URIExtensions
14
16
 
@@ -3,8 +3,9 @@
3
3
  module HTTPX
4
4
  module Plugins
5
5
  #
6
- # This plugin adds helper methods to implement HTTP Digest Auth
7
- # https://tools.ietf.org/html/rfc7616
6
+ # This plugin adds helper methods to implement HTTP Digest Auth (https://tools.ietf.org/html/rfc7616)
7
+ #
8
+ # https://gitlab.com/honeyryderchuck/httpx/wikis/Authentication#authentication
8
9
  #
9
10
  module DigestAuthentication
10
11
  DigestError = Class.new(Error)
@@ -11,6 +11,8 @@ module HTTPX
11
11
  #
12
12
  # It also doesn't follow insecure redirects (https -> http) by default (see *follow_insecure_redirects*).
13
13
  #
14
+ # https://gitlab.com/honeyryderchuck/httpx/wikis/Follow-Redirects
15
+ #
14
16
  module FollowRedirects
15
17
  MAX_REDIRECTS = 3
16
18
  REDIRECT_STATUS = (300..399).freeze
@@ -54,7 +56,7 @@ module HTTPX
54
56
  retry_request.uri.scheme == "http"
55
57
  error = InsecureRedirectError.new(retry_request.uri.to_s)
56
58
  error.set_backtrace(caller)
57
- return ErrorResponse.new(error, options)
59
+ return ErrorResponse.new(request, error, options)
58
60
  end
59
61
 
60
62
  connection = find_connection(retry_request, connections, options)
@@ -3,9 +3,10 @@
3
3
  module HTTPX
4
4
  module Plugins
5
5
  #
6
- # This plugin adds support for upgrading a plaintext HTTP/1.1 connection to HTTP/2.
6
+ # This plugin adds support for upgrading a plaintext HTTP/1.1 connection to HTTP/2
7
+ # (https://tools.ietf.org/html/rfc7540#section-3.2)
7
8
  #
8
- # https://tools.ietf.org/html/rfc7540#section-3.2
9
+ # https://gitlab.com/honeyryderchuck/httpx/wikis/Follow-Redirects
9
10
  #
10
11
  module H2C
11
12
  def self.load_dependencies(*)
@@ -7,6 +7,8 @@ module HTTPX
7
7
  #
8
8
  # HTTPX.post(URL, form: form: { image: HTTP::FormData::File.new("path/to/file")})
9
9
  #
10
+ # https://gitlab.com/honeyryderchuck/httpx/wikis/Multipart-Uploads
11
+ #
10
12
  module Multipart
11
13
  module FormTranscoder
12
14
  module_function
@@ -15,9 +15,11 @@ module HTTPX
15
15
  # This plugin is also not recommendable when connecting to >9000 (like, a lot) different origins.
16
16
  # So when you use this, make sure that you don't fall into this trap.
17
17
  #
18
+ # https://gitlab.com/honeyryderchuck/httpx/wikis/Persistent
19
+ #
18
20
  module Persistent
19
- def self.load_dependencies(klass, *)
20
- klass.plugin(:retries) # TODO: pass default max_retries -> 1 as soon as this is a parameter
21
+ def self.load_dependencies(klass)
22
+ klass.plugin(:retries, max_retries: 1, retry_change_requests: true)
21
23
  end
22
24
 
23
25
  def self.extra_options(options)
@@ -14,6 +14,8 @@ module HTTPX
14
14
  # * Socks4/4a proxies
15
15
  # * Socks5 proxies
16
16
  #
17
+ # https://gitlab.com/honeyryderchuck/httpx/wikis/Proxy
18
+ #
17
19
  module Proxy
18
20
  Error = Class.new(Error)
19
21
  PROXY_ERRORS = [TimeoutError, IOError, SystemCallError, Error].freeze
@@ -47,7 +49,7 @@ module HTTPX
47
49
  end
48
50
 
49
51
  class << self
50
- def configure(klass, *)
52
+ def configure(klass)
51
53
  klass.plugin(:"proxy/http")
52
54
  klass.plugin(:"proxy/socks4")
53
55
  klass.plugin(:"proxy/socks5")
@@ -6,8 +6,7 @@ module HTTPX
6
6
  module Plugins
7
7
  module Proxy
8
8
  module SSH
9
- def self.load_dependencies(_klass, *)
10
- # klass.plugin(:proxy)
9
+ def self.load_dependencies(*)
11
10
  require "net/ssh/gateway"
12
11
  end
13
12
 
@@ -74,6 +73,21 @@ module HTTPX
74
73
  end
75
74
  end
76
75
  end
76
+
77
+ module ConnectionMethods
78
+ def match?(uri, options)
79
+ return super unless @options.proxy
80
+
81
+ super && @options.proxy == options.proxy
82
+ end
83
+
84
+ # should not coalesce connections here, as the IP is the IP of the proxy
85
+ def coalescable?(*)
86
+ return super unless @options.proxy
87
+
88
+ false
89
+ end
90
+ end
77
91
  end
78
92
  end
79
93
  register_plugin :"proxy/ssh", Proxy::SSH
@@ -8,6 +8,8 @@ module HTTPX
8
8
  # In order to benefit from this, requests are sent one at a time, so that
9
9
  # no push responses are received after corresponding request has been sent.
10
10
  #
11
+ # https://gitlab.com/honeyryderchuck/httpx/wikis/Server-Push
12
+ #
11
13
  module PushPromise
12
14
  def self.extra_options(options)
13
15
  options.merge(http2_settings: { settings_enable_push: 1 },
@@ -5,6 +5,8 @@ module HTTPX
5
5
  #
6
6
  # This plugin adds support for retrying requests when certain errors happen.
7
7
  #
8
+ # https://gitlab.com/honeyryderchuck/httpx/wikis/Retries
9
+ #
8
10
  module Retries
9
11
  MAX_RETRIES = 3
10
12
  # TODO: pass max_retries in a configure/load block
@@ -31,7 +33,7 @@ module HTTPX
31
33
  end
32
34
 
33
35
  def_option(:retry_change_requests)
34
- end.new(options)
36
+ end.new(options).merge(max_retries: MAX_RETRIES)
35
37
  end
36
38
 
37
39
  module InstanceMethods
@@ -71,7 +73,7 @@ module HTTPX
71
73
 
72
74
  def initialize(*args)
73
75
  super
74
- @retries = @options.max_retries || MAX_RETRIES
76
+ @retries = @options.max_retries
75
77
  end
76
78
  end
77
79
  end
@@ -76,13 +76,22 @@ module HTTPX
76
76
  consume
77
77
  end
78
78
  nil
79
- rescue Errno::EHOSTUNREACH => e
79
+ rescue Errno::EHOSTUNREACH,
80
+ NativeResolveError => e
80
81
  @ns_index += 1
81
82
  if @ns_index < @nameserver.size
83
+ log(label: "resolver: ") do
84
+ "failed resolving on nameserver #{@nameserver[@ns_index - 1]} (#{e.message})"
85
+ end
82
86
  transition(:idle)
83
87
  else
84
- @queries.each do |host, connection|
88
+ if e.respond_to?(:connection) &&
89
+ e.respond_to?(:host)
85
90
  emit_resolve_error(connection, host, e)
91
+ else
92
+ @queries.each do |host, connection|
93
+ emit_resolve_error(connection, host, e)
94
+ end
86
95
  end
87
96
  end
88
97
  end
@@ -141,8 +150,7 @@ module HTTPX
141
150
  @timeouts[host].shift
142
151
  if @timeouts[host].empty?
143
152
  @timeouts.delete(host)
144
- emit_resolve_error(connection, host)
145
- return
153
+ raise NativeResolveError.new(connection, host)
146
154
  else
147
155
  connections << connection
148
156
  log(label: "resolver: ") do
@@ -188,8 +196,9 @@ module HTTPX
188
196
  rescue Resolv::DNS::DecodeError => e
189
197
  hostname, connection = @queries.first
190
198
  if @_record_types[hostname].empty?
191
- emit_resolve_error(connection, hostname, e)
192
- return
199
+ ex = NativeResolveError.new(connection, hostname, e.message)
200
+ ex.set_backtrace(e.backtrace)
201
+ raise ex
193
202
  end
194
203
  end
195
204
 
@@ -198,8 +207,7 @@ module HTTPX
198
207
  @_record_types[hostname].shift
199
208
  if @_record_types[hostname].empty?
200
209
  @_record_types.delete(hostname)
201
- emit_resolve_error(connection, hostname)
202
- return
210
+ raise NativeResolveError.new(connection, hostname)
203
211
  end
204
212
  else
205
213
  address = addresses.first
@@ -238,9 +238,10 @@ module HTTPX
238
238
  class ErrorResponse
239
239
  include Loggable
240
240
 
241
- attr_reader :error
241
+ attr_reader :request, :error
242
242
 
243
- def initialize(error, options)
243
+ def initialize(request, error, options)
244
+ @request = request
244
245
  @error = error
245
246
  @options = Options.new(options)
246
247
  log_exception(@error)
@@ -203,14 +203,15 @@ module HTTPX
203
203
  klass.instance_variable_set(:@plugins, @plugins.dup)
204
204
  end
205
205
 
206
- def plugin(pl, *args, &block)
206
+ def plugin(pl, options = nil, &block)
207
207
  # raise Error, "Cannot add a plugin to a frozen config" if frozen?
208
208
  pl = Plugins.load_plugin(pl) if pl.is_a?(Symbol)
209
209
  unless @plugins.include?(pl)
210
210
  @plugins << pl
211
- pl.load_dependencies(self, *args, &block) if pl.respond_to?(:load_dependencies)
211
+ pl.load_dependencies(self, &block) if pl.respond_to?(:load_dependencies)
212
212
  @default_options = @default_options.dup
213
- @default_options = pl.extra_options(@default_options) if pl.respond_to?(:extra_options)
213
+ @default_options = pl.extra_options(@default_options, &block) if pl.respond_to?(:extra_options)
214
+ @default_options = @default_options.merge(options) if options
214
215
 
215
216
  include(pl::InstanceMethods) if defined?(pl::InstanceMethods)
216
217
  extend(pl::ClassMethods) if defined?(pl::ClassMethods)
@@ -227,7 +228,7 @@ module HTTPX
227
228
  opts.response_body_class.__send__(:include, pl::ResponseBodyMethods) if defined?(pl::ResponseBodyMethods)
228
229
  opts.response_body_class.extend(pl::ResponseBodyClassMethods) if defined?(pl::ResponseBodyClassMethods)
229
230
  opts.connection_class.__send__(:include, pl::ConnectionMethods) if defined?(pl::ConnectionMethods)
230
- pl.configure(self, *args, &block) if pl.respond_to?(:configure)
231
+ pl.configure(self, &block) if pl.respond_to?(:configure)
231
232
 
232
233
  @default_options.freeze
233
234
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module HTTPX
4
- VERSION = "0.4.0"
4
+ VERSION = "0.4.1"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: httpx
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tiago Cardoso
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-20 00:00:00.000000000 Z
11
+ date: 2019-06-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: http-2