faraday 1.4.1 → 2.14.2
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 +4 -4
- data/CHANGELOG.md +198 -4
- data/LICENSE.md +1 -1
- data/README.md +34 -20
- data/Rakefile +6 -1
- data/examples/client_spec.rb +67 -13
- data/examples/client_test.rb +81 -16
- data/lib/faraday/adapter/test.rb +117 -52
- data/lib/faraday/adapter.rb +12 -20
- data/lib/faraday/connection.rb +86 -134
- data/lib/faraday/encoders/flat_params_encoder.rb +3 -2
- data/lib/faraday/encoders/nested_params_encoder.rb +15 -7
- data/lib/faraday/error.rb +65 -15
- data/lib/faraday/logging/formatter.rb +30 -17
- data/lib/faraday/middleware.rb +44 -3
- data/lib/faraday/middleware_registry.rb +17 -63
- data/lib/faraday/options/connection_options.rb +7 -6
- data/lib/faraday/options/env.rb +88 -65
- data/lib/faraday/options/proxy_options.rb +17 -6
- data/lib/faraday/options/request_options.rb +8 -7
- data/lib/faraday/options/ssl_options.rb +62 -45
- data/lib/faraday/options.rb +8 -7
- data/lib/faraday/rack_builder.rb +46 -47
- data/lib/faraday/request/authorization.rb +37 -38
- data/lib/faraday/request/instrumentation.rb +5 -1
- data/lib/faraday/request/json.rb +70 -0
- data/lib/faraday/request/url_encoded.rb +5 -1
- data/lib/faraday/request.rb +20 -37
- data/lib/faraday/response/json.rb +74 -0
- data/lib/faraday/response/logger.rb +13 -7
- data/lib/faraday/response/raise_error.rb +45 -18
- data/lib/faraday/response.rb +15 -21
- data/lib/faraday/utils/headers.rb +18 -7
- data/lib/faraday/utils.rb +11 -7
- data/lib/faraday/version.rb +1 -1
- data/lib/faraday.rb +12 -32
- data/spec/faraday/adapter/test_spec.rb +182 -0
- data/spec/faraday/connection_spec.rb +219 -92
- data/spec/faraday/error_spec.rb +122 -7
- data/spec/faraday/middleware_registry_spec.rb +31 -0
- data/spec/faraday/middleware_spec.rb +163 -2
- data/spec/faraday/options/env_spec.rb +8 -2
- data/spec/faraday/options/options_spec.rb +1 -1
- data/spec/faraday/options/proxy_options_spec.rb +42 -0
- data/spec/faraday/params_encoders/nested_spec.rb +10 -1
- data/spec/faraday/rack_builder_spec.rb +26 -54
- data/spec/faraday/request/authorization_spec.rb +54 -24
- data/spec/faraday/request/instrumentation_spec.rb +5 -7
- data/spec/faraday/request/json_spec.rb +199 -0
- data/spec/faraday/request/url_encoded_spec.rb +12 -2
- data/spec/faraday/request_spec.rb +14 -15
- data/spec/faraday/response/json_spec.rb +206 -0
- data/spec/faraday/response/logger_spec.rb +84 -5
- data/spec/faraday/response/raise_error_spec.rb +133 -16
- data/spec/faraday/response_spec.rb +10 -1
- data/spec/faraday/utils/headers_spec.rb +31 -4
- data/spec/faraday/utils_spec.rb +66 -2
- data/spec/faraday_spec.rb +10 -4
- data/spec/spec_helper.rb +6 -5
- data/spec/support/fake_safe_buffer.rb +1 -1
- data/spec/support/faraday_middleware_subclasses.rb +18 -0
- data/spec/support/helper_methods.rb +0 -37
- data/spec/support/shared_examples/adapter.rb +2 -2
- data/spec/support/shared_examples/request_method.rb +22 -21
- metadata +27 -81
- data/lib/faraday/adapter/em_http.rb +0 -289
- data/lib/faraday/adapter/em_http_ssl_patch.rb +0 -62
- data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +0 -69
- data/lib/faraday/adapter/em_synchrony.rb +0 -153
- data/lib/faraday/adapter/httpclient.rb +0 -152
- data/lib/faraday/adapter/patron.rb +0 -132
- data/lib/faraday/adapter/rack.rb +0 -75
- data/lib/faraday/adapter/typhoeus.rb +0 -15
- data/lib/faraday/autoload.rb +0 -92
- data/lib/faraday/dependency_loader.rb +0 -37
- data/lib/faraday/file_part.rb +0 -128
- data/lib/faraday/param_part.rb +0 -53
- data/lib/faraday/request/basic_authentication.rb +0 -20
- data/lib/faraday/request/multipart.rb +0 -106
- data/lib/faraday/request/retry.rb +0 -239
- data/lib/faraday/request/token_authentication.rb +0 -20
- data/spec/faraday/adapter/em_http_spec.rb +0 -47
- data/spec/faraday/adapter/em_synchrony_spec.rb +0 -16
- data/spec/faraday/adapter/excon_spec.rb +0 -49
- data/spec/faraday/adapter/httpclient_spec.rb +0 -73
- data/spec/faraday/adapter/net_http_spec.rb +0 -64
- data/spec/faraday/adapter/patron_spec.rb +0 -18
- data/spec/faraday/adapter/rack_spec.rb +0 -8
- data/spec/faraday/adapter/typhoeus_spec.rb +0 -7
- data/spec/faraday/composite_read_io_spec.rb +0 -80
- data/spec/faraday/request/multipart_spec.rb +0 -302
- data/spec/faraday/request/retry_spec.rb +0 -242
- data/spec/faraday/response/middleware_spec.rb +0 -68
- data/spec/support/webmock_rack_app.rb +0 -68
data/lib/faraday/connection.rb
CHANGED
|
@@ -6,15 +6,16 @@ module Faraday
|
|
|
6
6
|
#
|
|
7
7
|
# @example
|
|
8
8
|
#
|
|
9
|
-
# conn = Faraday::Connection.new 'http://
|
|
9
|
+
# conn = Faraday::Connection.new 'http://httpbingo.org'
|
|
10
10
|
#
|
|
11
|
-
# # GET http://
|
|
11
|
+
# # GET http://httpbingo.org/nigiri
|
|
12
12
|
# conn.get 'nigiri'
|
|
13
13
|
# # => #<Faraday::Response>
|
|
14
14
|
#
|
|
15
15
|
class Connection
|
|
16
16
|
# A Set of allowed HTTP verbs.
|
|
17
17
|
METHODS = Set.new %i[get post put delete head patch options trace]
|
|
18
|
+
USER_AGENT = "Faraday v#{VERSION}".freeze
|
|
18
19
|
|
|
19
20
|
# @return [Hash] URI query unencoded key/value pairs.
|
|
20
21
|
attr_reader :params
|
|
@@ -26,7 +27,7 @@ module Faraday
|
|
|
26
27
|
# Connection. This includes a default host name, scheme, port, and path.
|
|
27
28
|
attr_reader :url_prefix
|
|
28
29
|
|
|
29
|
-
# @return [Faraday::
|
|
30
|
+
# @return [Faraday::RackBuilder] Builder for this Connection.
|
|
30
31
|
attr_reader :builder
|
|
31
32
|
|
|
32
33
|
# @return [Hash] SSL options.
|
|
@@ -63,7 +64,7 @@ module Faraday
|
|
|
63
64
|
options = ConnectionOptions.from(options)
|
|
64
65
|
|
|
65
66
|
if url.is_a?(Hash) || url.is_a?(ConnectionOptions)
|
|
66
|
-
options =
|
|
67
|
+
options = Utils.deep_merge(options, url)
|
|
67
68
|
url = options.url
|
|
68
69
|
end
|
|
69
70
|
|
|
@@ -73,6 +74,7 @@ module Faraday
|
|
|
73
74
|
@options = options.request
|
|
74
75
|
@ssl = options.ssl
|
|
75
76
|
@default_parallel_manager = options.parallel_manager
|
|
77
|
+
@manual_proxy = nil
|
|
76
78
|
|
|
77
79
|
@builder = options.builder || begin
|
|
78
80
|
# pass an empty block to Builder so it doesn't assume default middleware
|
|
@@ -88,7 +90,7 @@ module Faraday
|
|
|
88
90
|
|
|
89
91
|
yield(self) if block_given?
|
|
90
92
|
|
|
91
|
-
@headers[:user_agent] ||=
|
|
93
|
+
@headers[:user_agent] ||= USER_AGENT
|
|
92
94
|
end
|
|
93
95
|
|
|
94
96
|
def initialize_proxy(url, options)
|
|
@@ -115,7 +117,7 @@ module Faraday
|
|
|
115
117
|
|
|
116
118
|
extend Forwardable
|
|
117
119
|
|
|
118
|
-
def_delegators :builder, :
|
|
120
|
+
def_delegators :builder, :use, :request, :response, :adapter, :app
|
|
119
121
|
|
|
120
122
|
# Closes the underlying resources and/or connections. In the case of
|
|
121
123
|
# persistent connections, this closes all currently open connections
|
|
@@ -128,10 +130,10 @@ module Faraday
|
|
|
128
130
|
# Makes a GET HTTP request without a body.
|
|
129
131
|
# @!scope class
|
|
130
132
|
#
|
|
131
|
-
# @param url [String] The optional String base URL to use as a prefix for
|
|
133
|
+
# @param url [String, URI, nil] The optional String base URL to use as a prefix for
|
|
132
134
|
# all requests. Can also be the options Hash.
|
|
133
|
-
# @param params [Hash] Hash of URI query unencoded key/value pairs.
|
|
134
|
-
# @param headers [Hash] unencoded HTTP header key/value pairs.
|
|
135
|
+
# @param params [Hash, nil] Hash of URI query unencoded key/value pairs.
|
|
136
|
+
# @param headers [Hash, nil] unencoded HTTP header key/value pairs.
|
|
135
137
|
#
|
|
136
138
|
# @example
|
|
137
139
|
# conn.get '/items', { page: 1 }, :accept => 'application/json'
|
|
@@ -150,10 +152,10 @@ module Faraday
|
|
|
150
152
|
# Makes a HEAD HTTP request without a body.
|
|
151
153
|
# @!scope class
|
|
152
154
|
#
|
|
153
|
-
# @param url [String] The optional String base URL to use as a prefix for
|
|
155
|
+
# @param url [String, URI, nil] The optional String base URL to use as a prefix for
|
|
154
156
|
# all requests. Can also be the options Hash.
|
|
155
|
-
# @param params [Hash] Hash of URI query unencoded key/value pairs.
|
|
156
|
-
# @param headers [Hash] unencoded HTTP header key/value pairs.
|
|
157
|
+
# @param params [Hash, nil] Hash of URI query unencoded key/value pairs.
|
|
158
|
+
# @param headers [Hash, nil] unencoded HTTP header key/value pairs.
|
|
157
159
|
#
|
|
158
160
|
# @example
|
|
159
161
|
# conn.head '/items/1'
|
|
@@ -165,10 +167,10 @@ module Faraday
|
|
|
165
167
|
# Makes a DELETE HTTP request without a body.
|
|
166
168
|
# @!scope class
|
|
167
169
|
#
|
|
168
|
-
# @param url [String] The optional String base URL to use as a prefix for
|
|
170
|
+
# @param url [String, URI, nil] The optional String base URL to use as a prefix for
|
|
169
171
|
# all requests. Can also be the options Hash.
|
|
170
|
-
# @param params [Hash] Hash of URI query unencoded key/value pairs.
|
|
171
|
-
# @param headers [Hash] unencoded HTTP header key/value pairs.
|
|
172
|
+
# @param params [Hash, nil] Hash of URI query unencoded key/value pairs.
|
|
173
|
+
# @param headers [Hash, nil] unencoded HTTP header key/value pairs.
|
|
172
174
|
#
|
|
173
175
|
# @example
|
|
174
176
|
# conn.delete '/items/1'
|
|
@@ -180,10 +182,10 @@ module Faraday
|
|
|
180
182
|
# Makes a TRACE HTTP request without a body.
|
|
181
183
|
# @!scope class
|
|
182
184
|
#
|
|
183
|
-
# @param url [String] The optional String base URL to use as a prefix for
|
|
185
|
+
# @param url [String, URI, nil] The optional String base URL to use as a prefix for
|
|
184
186
|
# all requests. Can also be the options Hash.
|
|
185
|
-
# @param params [Hash] Hash of URI query unencoded key/value pairs.
|
|
186
|
-
# @param headers [Hash] unencoded HTTP header key/value pairs.
|
|
187
|
+
# @param params [Hash, nil] Hash of URI query unencoded key/value pairs.
|
|
188
|
+
# @param headers [Hash, nil] unencoded HTTP header key/value pairs.
|
|
187
189
|
#
|
|
188
190
|
# @example
|
|
189
191
|
# conn.connect '/items/1'
|
|
@@ -208,9 +210,9 @@ module Faraday
|
|
|
208
210
|
#
|
|
209
211
|
# @overload options(url, params = nil, headers = nil)
|
|
210
212
|
# Makes an OPTIONS HTTP request to the given URL.
|
|
211
|
-
# @param url [String] String base URL to sue as a prefix for all requests.
|
|
212
|
-
# @param params [Hash] Hash of URI query unencoded key/value pairs.
|
|
213
|
-
# @param headers [Hash] unencoded HTTP header key/value pairs.
|
|
213
|
+
# @param url [String, URI, nil] String base URL to sue as a prefix for all requests.
|
|
214
|
+
# @param params [Hash, nil] Hash of URI query unencoded key/value pairs.
|
|
215
|
+
# @param headers [Hash, nil] unencoded HTTP header key/value pairs.
|
|
214
216
|
#
|
|
215
217
|
# @example
|
|
216
218
|
# conn.options '/items/1'
|
|
@@ -218,7 +220,7 @@ module Faraday
|
|
|
218
220
|
# @yield [Faraday::Request] for further request customizations
|
|
219
221
|
# @return [Faraday::Response]
|
|
220
222
|
def options(*args)
|
|
221
|
-
return @options if args.
|
|
223
|
+
return @options if args.empty?
|
|
222
224
|
|
|
223
225
|
url, params, headers = *args
|
|
224
226
|
run_request(:options, url, nil, headers) do |request|
|
|
@@ -231,10 +233,10 @@ module Faraday
|
|
|
231
233
|
# Makes a POST HTTP request with a body.
|
|
232
234
|
# @!scope class
|
|
233
235
|
#
|
|
234
|
-
# @param url [String] The optional String base URL to use as a prefix for
|
|
236
|
+
# @param url [String, URI, nil] The optional String base URL to use as a prefix for
|
|
235
237
|
# all requests. Can also be the options Hash.
|
|
236
|
-
# @param body [String] body for the request.
|
|
237
|
-
# @param headers [Hash] unencoded HTTP header key/value pairs.
|
|
238
|
+
# @param body [String, nil] body for the request.
|
|
239
|
+
# @param headers [Hash, nil] unencoded HTTP header key/value pairs.
|
|
238
240
|
#
|
|
239
241
|
# @example
|
|
240
242
|
# conn.post '/items', data, content_type: 'application/json'
|
|
@@ -253,20 +255,19 @@ module Faraday
|
|
|
253
255
|
# Makes a PUT HTTP request with a body.
|
|
254
256
|
# @!scope class
|
|
255
257
|
#
|
|
256
|
-
# @param url [String] The optional String base URL to use as a prefix for
|
|
258
|
+
# @param url [String, URI, nil] The optional String base URL to use as a prefix for
|
|
257
259
|
# all requests. Can also be the options Hash.
|
|
258
|
-
# @param body [String] body for the request.
|
|
259
|
-
# @param headers [Hash] unencoded HTTP header key/value pairs.
|
|
260
|
+
# @param body [String, nil] body for the request.
|
|
261
|
+
# @param headers [Hash, nil] unencoded HTTP header key/value pairs.
|
|
260
262
|
#
|
|
261
263
|
# @example
|
|
262
|
-
#
|
|
263
|
-
# conn.post '/items', data, content_type: 'application/json'
|
|
264
|
+
# conn.put '/products/123', data, content_type: 'application/json'
|
|
264
265
|
#
|
|
265
|
-
# #
|
|
266
|
-
# conn.
|
|
267
|
-
# req.headers[
|
|
268
|
-
# req.
|
|
269
|
-
# req.
|
|
266
|
+
# # Star a gist.
|
|
267
|
+
# conn.put 'https://api.github.com/gists/GIST_ID/star' do |req|
|
|
268
|
+
# req.headers['Accept'] = 'application/vnd.github+json'
|
|
269
|
+
# req.headers['Authorization'] = 'Bearer <YOUR-TOKEN>'
|
|
270
|
+
# req.headers['X-GitHub-Api-Version'] = '2022-11-28'
|
|
270
271
|
# end
|
|
271
272
|
#
|
|
272
273
|
# @yield [Faraday::Request] for further request customizations
|
|
@@ -281,62 +282,6 @@ module Faraday
|
|
|
281
282
|
RUBY
|
|
282
283
|
end
|
|
283
284
|
|
|
284
|
-
# Sets up the Authorization header with these credentials, encoded
|
|
285
|
-
# with base64.
|
|
286
|
-
#
|
|
287
|
-
# @param login [String] The authentication login.
|
|
288
|
-
# @param pass [String] The authentication password.
|
|
289
|
-
#
|
|
290
|
-
# @example
|
|
291
|
-
#
|
|
292
|
-
# conn.basic_auth 'Aladdin', 'open sesame'
|
|
293
|
-
# conn.headers['Authorization']
|
|
294
|
-
# # => "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="
|
|
295
|
-
#
|
|
296
|
-
# @return [void]
|
|
297
|
-
def basic_auth(login, pass)
|
|
298
|
-
set_authorization_header(:basic_auth, login, pass)
|
|
299
|
-
end
|
|
300
|
-
|
|
301
|
-
# Sets up the Authorization header with the given token.
|
|
302
|
-
#
|
|
303
|
-
# @param token [String]
|
|
304
|
-
# @param options [Hash] extra token options.
|
|
305
|
-
#
|
|
306
|
-
# @example
|
|
307
|
-
#
|
|
308
|
-
# conn.token_auth 'abcdef', foo: 'bar'
|
|
309
|
-
# conn.headers['Authorization']
|
|
310
|
-
# # => "Token token=\"abcdef\",
|
|
311
|
-
# foo=\"bar\""
|
|
312
|
-
#
|
|
313
|
-
# @return [void]
|
|
314
|
-
def token_auth(token, options = nil)
|
|
315
|
-
set_authorization_header(:token_auth, token, options)
|
|
316
|
-
end
|
|
317
|
-
|
|
318
|
-
# Sets up a custom Authorization header.
|
|
319
|
-
#
|
|
320
|
-
# @param type [String] authorization type
|
|
321
|
-
# @param token [String, Hash] token. A String value is taken literally, and
|
|
322
|
-
# a Hash is encoded into comma-separated key/value pairs.
|
|
323
|
-
#
|
|
324
|
-
# @example
|
|
325
|
-
#
|
|
326
|
-
# conn.authorization :Bearer, 'mF_9.B5f-4.1JqM'
|
|
327
|
-
# conn.headers['Authorization']
|
|
328
|
-
# # => "Bearer mF_9.B5f-4.1JqM"
|
|
329
|
-
#
|
|
330
|
-
# conn.authorization :Token, token: 'abcdef', foo: 'bar'
|
|
331
|
-
# conn.headers['Authorization']
|
|
332
|
-
# # => "Token token=\"abcdef\",
|
|
333
|
-
# foo=\"bar\""
|
|
334
|
-
#
|
|
335
|
-
# @return [void]
|
|
336
|
-
def authorization(type, token)
|
|
337
|
-
set_authorization_header(:authorization, type, token)
|
|
338
|
-
end
|
|
339
|
-
|
|
340
285
|
# Check if the adapter is parallel-capable.
|
|
341
286
|
#
|
|
342
287
|
# @yield if the adapter isn't parallel-capable, or if no adapter is set yet.
|
|
@@ -369,15 +314,23 @@ module Faraday
|
|
|
369
314
|
#
|
|
370
315
|
# @yield a block to execute multiple requests.
|
|
371
316
|
# @return [void]
|
|
372
|
-
def in_parallel(manager = nil)
|
|
317
|
+
def in_parallel(manager = nil, &block)
|
|
373
318
|
@parallel_manager = manager || default_parallel_manager do
|
|
374
319
|
warn 'Warning: `in_parallel` called but no parallel-capable adapter ' \
|
|
375
320
|
'on Faraday stack'
|
|
376
321
|
warn caller[2, 10].join("\n")
|
|
377
322
|
nil
|
|
378
323
|
end
|
|
379
|
-
yield
|
|
380
|
-
|
|
324
|
+
return yield unless @parallel_manager
|
|
325
|
+
|
|
326
|
+
if @parallel_manager.respond_to?(:execute)
|
|
327
|
+
# Execute is the new method that is responsible for executing the block.
|
|
328
|
+
@parallel_manager.execute(&block)
|
|
329
|
+
else
|
|
330
|
+
# TODO: Old behaviour, deprecate and remove in 3.0
|
|
331
|
+
yield
|
|
332
|
+
@parallel_manager.run
|
|
333
|
+
end
|
|
381
334
|
ensure
|
|
382
335
|
@parallel_manager = nil
|
|
383
336
|
end
|
|
@@ -403,11 +356,11 @@ module Faraday
|
|
|
403
356
|
# @example
|
|
404
357
|
#
|
|
405
358
|
# conn = Faraday::Connection.new { ... }
|
|
406
|
-
# conn.url_prefix = "https://
|
|
359
|
+
# conn.url_prefix = "https://httpbingo.org/api"
|
|
407
360
|
# conn.scheme # => https
|
|
408
361
|
# conn.path_prefix # => "/api"
|
|
409
362
|
#
|
|
410
|
-
# conn.get("nigiri?page=2") # accesses https://
|
|
363
|
+
# conn.get("nigiri?page=2") # accesses https://httpbingo.org/api/nigiri
|
|
411
364
|
def url_prefix=(url, encoder = nil)
|
|
412
365
|
uri = @url_prefix = Utils.URI(url)
|
|
413
366
|
self.path_prefix = uri.path
|
|
@@ -416,9 +369,16 @@ module Faraday
|
|
|
416
369
|
uri.query = nil
|
|
417
370
|
|
|
418
371
|
with_uri_credentials(uri) do |user, password|
|
|
419
|
-
|
|
372
|
+
set_basic_auth(user, password)
|
|
420
373
|
uri.user = uri.password = nil
|
|
421
374
|
end
|
|
375
|
+
|
|
376
|
+
@proxy = proxy_from_env(url) unless @manual_proxy
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
def set_basic_auth(user, password)
|
|
380
|
+
header = Faraday::Utils.basic_header_from(user, password)
|
|
381
|
+
headers[Faraday::Request::Authorization::KEY] = header
|
|
422
382
|
end
|
|
423
383
|
|
|
424
384
|
# Sets the path prefix and ensures that it always has a leading
|
|
@@ -437,20 +397,20 @@ module Faraday
|
|
|
437
397
|
# Takes a relative url for a request and combines it with the defaults
|
|
438
398
|
# set on the connection instance.
|
|
439
399
|
#
|
|
440
|
-
# @param url [String]
|
|
400
|
+
# @param url [String, URI, nil]
|
|
441
401
|
# @param extra_params [Hash]
|
|
442
402
|
#
|
|
443
403
|
# @example
|
|
444
404
|
# conn = Faraday::Connection.new { ... }
|
|
445
|
-
# conn.url_prefix = "https://
|
|
405
|
+
# conn.url_prefix = "https://httpbingo.org/api?token=abc"
|
|
446
406
|
# conn.scheme # => https
|
|
447
407
|
# conn.path_prefix # => "/api"
|
|
448
408
|
#
|
|
449
409
|
# conn.build_url("nigiri?page=2")
|
|
450
|
-
# # => https://
|
|
410
|
+
# # => https://httpbingo.org/api/nigiri?token=abc&page=2
|
|
451
411
|
#
|
|
452
412
|
# conn.build_url("nigiri", page: 2)
|
|
453
|
-
# # => https://
|
|
413
|
+
# # => https://httpbingo.org/api/nigiri?token=abc&page=2
|
|
454
414
|
#
|
|
455
415
|
def build_url(url = nil, extra_params = nil)
|
|
456
416
|
uri = build_exclusive_url(url)
|
|
@@ -470,10 +430,10 @@ module Faraday
|
|
|
470
430
|
# Builds and runs the Faraday::Request.
|
|
471
431
|
#
|
|
472
432
|
# @param method [Symbol] HTTP method.
|
|
473
|
-
# @param url [String, URI] String or URI to access.
|
|
474
|
-
# @param body [
|
|
475
|
-
# a string.
|
|
476
|
-
# @param headers [Hash] unencoded HTTP header key/value pairs.
|
|
433
|
+
# @param url [String, URI, nil] String or URI to access.
|
|
434
|
+
# @param body [String, Hash, Array, nil] The request body that will eventually be converted to
|
|
435
|
+
# a string; middlewares can be used to support more complex types.
|
|
436
|
+
# @param headers [Hash, nil] unencoded HTTP header key/value pairs.
|
|
477
437
|
#
|
|
478
438
|
# @return [Faraday::Response]
|
|
479
439
|
def run_request(method, url, body, headers)
|
|
@@ -509,7 +469,7 @@ module Faraday
|
|
|
509
469
|
|
|
510
470
|
# Build an absolute URL based on url_prefix.
|
|
511
471
|
#
|
|
512
|
-
# @param url [String, URI]
|
|
472
|
+
# @param url [String, URI, nil]
|
|
513
473
|
# @param params [Faraday::Utils::ParamsHash] A Faraday::Utils::ParamsHash to
|
|
514
474
|
# replace the query values
|
|
515
475
|
# of the resulting url (default: nil).
|
|
@@ -517,19 +477,20 @@ module Faraday
|
|
|
517
477
|
# @return [URI]
|
|
518
478
|
def build_exclusive_url(url = nil, params = nil, params_encoder = nil)
|
|
519
479
|
url = nil if url.respond_to?(:empty?) && url.empty?
|
|
520
|
-
base = url_prefix
|
|
521
|
-
if url && base.path
|
|
522
|
-
base = base.dup
|
|
480
|
+
base = url_prefix.dup
|
|
481
|
+
if url && !base.path.end_with?('/')
|
|
523
482
|
base.path = "#{base.path}/" # ensure trailing slash
|
|
524
483
|
end
|
|
525
|
-
url = url
|
|
484
|
+
url = url.to_s if url.respond_to?(:host)
|
|
485
|
+
# Ensure relative url will be parsed correctly (such as `service:search` or `//evil.com`)
|
|
486
|
+
url = "./#{url}" if url.respond_to?(:start_with?) &&
|
|
487
|
+
(url.start_with?('//') ||
|
|
488
|
+
!url.start_with?('http://', 'https://', '/', './', '../'))
|
|
526
489
|
uri = url ? base + url : base
|
|
527
490
|
if params
|
|
528
491
|
uri.query = params.to_query(params_encoder || options.params_encoder)
|
|
529
492
|
end
|
|
530
|
-
# rubocop:disable Style/SafeNavigation
|
|
531
493
|
uri.query = nil if uri.query && uri.query.empty?
|
|
532
|
-
# rubocop:enable Style/SafeNavigation
|
|
533
494
|
uri
|
|
534
495
|
end
|
|
535
496
|
|
|
@@ -561,37 +522,28 @@ module Faraday
|
|
|
561
522
|
yield(Utils.unescape(uri.user), Utils.unescape(uri.password))
|
|
562
523
|
end
|
|
563
524
|
|
|
564
|
-
def set_authorization_header(header_type, *args)
|
|
565
|
-
header = Faraday::Request
|
|
566
|
-
.lookup_middleware(header_type)
|
|
567
|
-
.header(*args)
|
|
568
|
-
|
|
569
|
-
headers[Faraday::Request::Authorization::KEY] = header
|
|
570
|
-
end
|
|
571
|
-
|
|
572
525
|
def proxy_from_env(url)
|
|
573
526
|
return if Faraday.ignore_env_proxy
|
|
574
527
|
|
|
575
528
|
uri = nil
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
warn 'no_proxy is unsupported' if ENV['no_proxy'] || ENV['NO_PROXY']
|
|
529
|
+
case url
|
|
530
|
+
when String
|
|
531
|
+
uri = Utils.URI(url)
|
|
532
|
+
uri = if uri.host.nil?
|
|
533
|
+
find_default_proxy
|
|
534
|
+
else
|
|
535
|
+
URI.parse("#{uri.scheme}://#{uri.host}").find_proxy
|
|
536
|
+
end
|
|
537
|
+
when URI
|
|
538
|
+
uri = url.find_proxy
|
|
539
|
+
when nil
|
|
588
540
|
uri = find_default_proxy
|
|
589
541
|
end
|
|
590
542
|
ProxyOptions.from(uri) if uri
|
|
591
543
|
end
|
|
592
544
|
|
|
593
545
|
def find_default_proxy
|
|
594
|
-
uri = ENV
|
|
546
|
+
uri = ENV.fetch('http_proxy', nil)
|
|
595
547
|
return unless uri && !uri.empty?
|
|
596
548
|
|
|
597
549
|
uri = "http://#{uri}" unless uri.match?(/^http/i)
|
|
@@ -609,7 +561,7 @@ module Faraday
|
|
|
609
561
|
end
|
|
610
562
|
|
|
611
563
|
def support_parallel?(adapter)
|
|
612
|
-
adapter
|
|
564
|
+
adapter.respond_to?(:supports_parallel?) && adapter&.supports_parallel?
|
|
613
565
|
end
|
|
614
566
|
end
|
|
615
567
|
end
|
|
@@ -6,6 +6,7 @@ module Faraday
|
|
|
6
6
|
module FlatParamsEncoder
|
|
7
7
|
class << self
|
|
8
8
|
extend Forwardable
|
|
9
|
+
|
|
9
10
|
def_delegators :'Faraday::Utils', :escape, :unescape
|
|
10
11
|
end
|
|
11
12
|
|
|
@@ -76,9 +77,9 @@ module Faraday
|
|
|
76
77
|
|
|
77
78
|
empty_accumulator = {}
|
|
78
79
|
|
|
79
|
-
split_query =
|
|
80
|
+
split_query = query.split('&').filter_map do |pair|
|
|
80
81
|
pair.split('=', 2) if pair && !pair.empty?
|
|
81
|
-
end
|
|
82
|
+
end
|
|
82
83
|
split_query.each_with_object(empty_accumulator.dup) do |pair, accu|
|
|
83
84
|
pair[0] = unescape(pair[0])
|
|
84
85
|
pair[1] = true if pair[1].nil?
|
|
@@ -62,11 +62,17 @@ module Faraday
|
|
|
62
62
|
end
|
|
63
63
|
|
|
64
64
|
def encode_array(parent, value)
|
|
65
|
-
|
|
66
|
-
return new_parent if value.empty?
|
|
65
|
+
return "#{parent}%5B%5D" if value.empty?
|
|
67
66
|
|
|
68
67
|
buffer = +''
|
|
69
|
-
value.
|
|
68
|
+
value.each_with_index do |val, index|
|
|
69
|
+
new_parent = if @array_indices
|
|
70
|
+
"#{parent}%5B#{index}%5D"
|
|
71
|
+
else
|
|
72
|
+
"#{parent}%5B%5D"
|
|
73
|
+
end
|
|
74
|
+
buffer << "#{encode_pair(new_parent, val)}&"
|
|
75
|
+
end
|
|
70
76
|
buffer.chop
|
|
71
77
|
end
|
|
72
78
|
end
|
|
@@ -96,13 +102,13 @@ module Faraday
|
|
|
96
102
|
|
|
97
103
|
protected
|
|
98
104
|
|
|
99
|
-
SUBKEYS_REGEX = /[^\[\]]+(?:\]?\[\])
|
|
105
|
+
SUBKEYS_REGEX = /[^\[\]]+(?:\]?\[\])?/
|
|
100
106
|
|
|
101
107
|
def decode_pair(key, value, context)
|
|
102
108
|
subkeys = key.scan(SUBKEYS_REGEX)
|
|
103
109
|
subkeys.each_with_index do |subkey, i|
|
|
104
110
|
is_array = subkey =~ /[\[\]]+\Z/
|
|
105
|
-
subkey =
|
|
111
|
+
subkey = Regexp.last_match.pre_match if is_array
|
|
106
112
|
last_subkey = i == subkeys.length - 1
|
|
107
113
|
|
|
108
114
|
context = prepare_context(context, subkey, is_array, last_subkey)
|
|
@@ -124,7 +130,7 @@ module Faraday
|
|
|
124
130
|
value_type = is_array ? Array : Hash
|
|
125
131
|
if context[subkey] && !context[subkey].is_a?(value_type)
|
|
126
132
|
raise TypeError, "expected #{value_type.name} " \
|
|
127
|
-
|
|
133
|
+
"(got #{context[subkey].class.name}) for param `#{subkey}'"
|
|
128
134
|
end
|
|
129
135
|
|
|
130
136
|
context[subkey] ||= value_type.new
|
|
@@ -161,14 +167,16 @@ module Faraday
|
|
|
161
167
|
# for your requests.
|
|
162
168
|
module NestedParamsEncoder
|
|
163
169
|
class << self
|
|
164
|
-
attr_accessor :sort_params
|
|
170
|
+
attr_accessor :sort_params, :array_indices
|
|
165
171
|
|
|
166
172
|
extend Forwardable
|
|
173
|
+
|
|
167
174
|
def_delegators :'Faraday::Utils', :escape, :unescape
|
|
168
175
|
end
|
|
169
176
|
|
|
170
177
|
# Useful default for OAuth and caching.
|
|
171
178
|
@sort_params = true
|
|
179
|
+
@array_indices = false
|
|
172
180
|
|
|
173
181
|
extend EncodeMethods
|
|
174
182
|
extend DecodeMethods
|
data/lib/faraday/error.rb
CHANGED
|
@@ -6,7 +6,7 @@ module Faraday
|
|
|
6
6
|
class Error < StandardError
|
|
7
7
|
attr_reader :response, :wrapped_exception
|
|
8
8
|
|
|
9
|
-
def initialize(exc, response = nil)
|
|
9
|
+
def initialize(exc = nil, response = nil)
|
|
10
10
|
@wrapped_exception = nil unless defined?(@wrapped_exception)
|
|
11
11
|
@response = nil unless defined?(@response)
|
|
12
12
|
super(exc_msg_and_response!(exc, response))
|
|
@@ -29,15 +29,21 @@ module Faraday
|
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
def response_status
|
|
32
|
-
|
|
32
|
+
return unless @response
|
|
33
|
+
|
|
34
|
+
@response.is_a?(Faraday::Response) ? @response.status : @response[:status]
|
|
33
35
|
end
|
|
34
36
|
|
|
35
37
|
def response_headers
|
|
36
|
-
|
|
38
|
+
return unless @response
|
|
39
|
+
|
|
40
|
+
@response.is_a?(Faraday::Response) ? @response.headers : @response[:headers]
|
|
37
41
|
end
|
|
38
42
|
|
|
39
43
|
def response_body
|
|
40
|
-
|
|
44
|
+
return unless @response
|
|
45
|
+
|
|
46
|
+
@response.is_a?(Faraday::Response) ? @response.body : @response[:body]
|
|
41
47
|
end
|
|
42
48
|
|
|
43
49
|
protected
|
|
@@ -52,6 +58,7 @@ module Faraday
|
|
|
52
58
|
# :body - Optional string HTTP response body.
|
|
53
59
|
# :request - Hash
|
|
54
60
|
# :method - Symbol with the request HTTP method.
|
|
61
|
+
# :url - URI object with the url requested.
|
|
55
62
|
# :url_path - String with the url path requested.
|
|
56
63
|
# :params - String key/value hash of query params
|
|
57
64
|
# present in the request.
|
|
@@ -72,12 +79,46 @@ module Faraday
|
|
|
72
79
|
|
|
73
80
|
# Pulls out potential parent exception and response hash.
|
|
74
81
|
def exc_msg_and_response(exc, response = nil)
|
|
75
|
-
|
|
82
|
+
case exc
|
|
83
|
+
when Exception
|
|
84
|
+
[exc, exc.message, response]
|
|
85
|
+
when Hash
|
|
86
|
+
[nil, build_error_message_from_hash(exc), exc]
|
|
87
|
+
when Faraday::Env
|
|
88
|
+
[nil, build_error_message_from_env(exc), exc]
|
|
89
|
+
else
|
|
90
|
+
[nil, exc.to_s, response]
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
private
|
|
95
|
+
|
|
96
|
+
def build_error_message_from_hash(hash)
|
|
97
|
+
# Be defensive with external Hash objects - they might be missing keys
|
|
98
|
+
status = hash.fetch(:status, nil)
|
|
99
|
+
request = hash.fetch(:request, nil)
|
|
100
|
+
|
|
101
|
+
return fallback_error_message(status) if request.nil?
|
|
76
102
|
|
|
77
|
-
|
|
78
|
-
|
|
103
|
+
method = request.fetch(:method, nil)
|
|
104
|
+
url = request.fetch(:url, nil)
|
|
105
|
+
build_status_error_message(status, method, url)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def build_error_message_from_env(env)
|
|
109
|
+
# Faraday::Env is internal - we can make reasonable assumptions about its structure
|
|
110
|
+
build_status_error_message(env.status, env.method, env.url)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def build_status_error_message(status, method, url)
|
|
114
|
+
method_str = method ? method.to_s.upcase : ''
|
|
115
|
+
url_str = url ? url.to_s : ''
|
|
116
|
+
"the server responded with status #{status} for #{method_str} #{url_str}"
|
|
117
|
+
end
|
|
79
118
|
|
|
80
|
-
|
|
119
|
+
def fallback_error_message(status)
|
|
120
|
+
"the server responded with status #{status} - method and url are not available " \
|
|
121
|
+
'due to include_request: false on Faraday::Response::RaiseError middleware'
|
|
81
122
|
end
|
|
82
123
|
end
|
|
83
124
|
|
|
@@ -105,12 +146,23 @@ module Faraday
|
|
|
105
146
|
class ProxyAuthError < ClientError
|
|
106
147
|
end
|
|
107
148
|
|
|
149
|
+
# Raised by Faraday::Response::RaiseError in case of a 408 response.
|
|
150
|
+
class RequestTimeoutError < ClientError
|
|
151
|
+
end
|
|
152
|
+
|
|
108
153
|
# Raised by Faraday::Response::RaiseError in case of a 409 response.
|
|
109
154
|
class ConflictError < ClientError
|
|
110
155
|
end
|
|
111
156
|
|
|
112
157
|
# Raised by Faraday::Response::RaiseError in case of a 422 response.
|
|
113
|
-
class
|
|
158
|
+
class UnprocessableContentError < ClientError
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# Used to provide compatibility with legacy error name.
|
|
162
|
+
UnprocessableEntityError = UnprocessableContentError
|
|
163
|
+
|
|
164
|
+
# Raised by Faraday::Response::RaiseError in case of a 429 response.
|
|
165
|
+
class TooManyRequestsError < ClientError
|
|
114
166
|
end
|
|
115
167
|
|
|
116
168
|
# Faraday server error class. Represents 5xx status responses.
|
|
@@ -120,7 +172,7 @@ module Faraday
|
|
|
120
172
|
# A unified client error for timeouts.
|
|
121
173
|
class TimeoutError < ServerError
|
|
122
174
|
def initialize(exc = 'timeout', response = nil)
|
|
123
|
-
super
|
|
175
|
+
super
|
|
124
176
|
end
|
|
125
177
|
end
|
|
126
178
|
|
|
@@ -140,13 +192,11 @@ module Faraday
|
|
|
140
192
|
class SSLError < Error
|
|
141
193
|
end
|
|
142
194
|
|
|
143
|
-
# Raised by
|
|
195
|
+
# Raised by middlewares that parse the response, like the JSON response middleware.
|
|
144
196
|
class ParsingError < Error
|
|
145
197
|
end
|
|
146
198
|
|
|
147
|
-
#
|
|
148
|
-
|
|
149
|
-
# @see Faraday::Request::Retry
|
|
150
|
-
class RetriableResponse < Error
|
|
199
|
+
# Raised by Faraday::Middleware and subclasses when invalid default_options are used
|
|
200
|
+
class InitializationError < Error
|
|
151
201
|
end
|
|
152
202
|
end
|