faraday 1.10.4 → 2.13.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 +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 +41 -19
- data/examples/client_test.rb +48 -22
- data/lib/faraday/adapter/test.rb +62 -13
- data/lib/faraday/adapter.rb +6 -10
- data/lib/faraday/connection.rb +72 -150
- data/lib/faraday/encoders/nested_params_encoder.rb +14 -7
- data/lib/faraday/error.rb +24 -5
- data/lib/faraday/logging/formatter.rb +29 -16
- data/lib/faraday/middleware.rb +43 -2
- data/lib/faraday/middleware_registry.rb +17 -63
- data/lib/faraday/options/connection_options.rb +7 -6
- data/lib/faraday/options/env.rb +85 -62
- data/lib/faraday/options/proxy_options.rb +11 -5
- data/lib/faraday/options/request_options.rb +7 -6
- data/lib/faraday/options/ssl_options.rb +62 -45
- data/lib/faraday/options.rb +7 -6
- data/lib/faraday/rack_builder.rb +43 -40
- data/lib/faraday/request/authorization.rb +33 -41
- data/lib/faraday/request/instrumentation.rb +5 -1
- data/lib/faraday/request/json.rb +18 -3
- data/lib/faraday/request/url_encoded.rb +5 -1
- data/lib/faraday/request.rb +15 -30
- data/lib/faraday/response/json.rb +25 -5
- data/lib/faraday/response/logger.rb +11 -3
- data/lib/faraday/response/raise_error.rb +45 -18
- data/lib/faraday/response.rb +9 -21
- data/lib/faraday/utils/headers.rb +15 -4
- data/lib/faraday/utils.rb +11 -7
- data/lib/faraday/version.rb +1 -1
- data/lib/faraday.rb +8 -44
- data/spec/faraday/adapter/test_spec.rb +65 -0
- data/spec/faraday/connection_spec.rb +165 -93
- data/spec/faraday/error_spec.rb +39 -6
- data/spec/faraday/middleware_registry_spec.rb +31 -0
- data/spec/faraday/middleware_spec.rb +161 -0
- 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 +35 -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 +50 -28
- data/spec/faraday/request/instrumentation_spec.rb +5 -7
- data/spec/faraday/request/json_spec.rb +88 -0
- data/spec/faraday/request/url_encoded_spec.rb +12 -2
- data/spec/faraday/request_spec.rb +5 -15
- data/spec/faraday/response/json_spec.rb +93 -6
- data/spec/faraday/response/logger_spec.rb +77 -4
- data/spec/faraday/response/raise_error_spec.rb +111 -5
- data/spec/faraday/response_spec.rb +3 -1
- data/spec/faraday/utils/headers_spec.rb +31 -4
- data/spec/faraday/utils_spec.rb +65 -1
- data/spec/faraday_spec.rb +10 -4
- data/spec/spec_helper.rb +5 -6
- 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 +24 -149
- data/lib/faraday/adapter/typhoeus.rb +0 -15
- data/lib/faraday/autoload.rb +0 -89
- data/lib/faraday/dependency_loader.rb +0 -39
- data/lib/faraday/deprecate.rb +0 -110
- data/lib/faraday/request/basic_authentication.rb +0 -20
- data/lib/faraday/request/token_authentication.rb +0 -20
- data/spec/faraday/adapter/em_http_spec.rb +0 -49
- data/spec/faraday/adapter/em_synchrony_spec.rb +0 -18
- 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/deprecate_spec.rb +0 -147
- data/spec/faraday/response/middleware_spec.rb +0 -68
- data/spec/support/webmock_rack_app.rb +0 -68
data/lib/faraday/adapter/test.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'timeout'
|
4
|
+
|
3
5
|
module Faraday
|
4
6
|
class Adapter
|
5
7
|
# @example
|
@@ -26,6 +28,15 @@ module Faraday
|
|
26
28
|
# ]
|
27
29
|
# end
|
28
30
|
#
|
31
|
+
# # Test the request body is the same as the stubbed body
|
32
|
+
# stub.post('/bar', 'name=YK&word=call') { [200, {}, ''] }
|
33
|
+
#
|
34
|
+
# # You can pass a proc as a stubbed body and check the request body in your way.
|
35
|
+
# # In this case, the proc should return true or false.
|
36
|
+
# stub.post('/foo', ->(request_body) do
|
37
|
+
# JSON.parse(request_body).slice('name') == { 'name' => 'YK' } }) { [200, {}, '']
|
38
|
+
# end
|
39
|
+
#
|
29
40
|
# # You can set strict_mode to exactly match the stubbed requests.
|
30
41
|
# stub.strict_mode = true
|
31
42
|
# end
|
@@ -42,6 +53,12 @@ module Faraday
|
|
42
53
|
#
|
43
54
|
# resp = test.get '/items/2'
|
44
55
|
# resp.body # => 'showing item: 2'
|
56
|
+
#
|
57
|
+
# resp = test.post '/bar', 'name=YK&word=call'
|
58
|
+
# resp.status # => 200
|
59
|
+
#
|
60
|
+
# resp = test.post '/foo', JSON.dump(name: 'YK', created_at: Time.now)
|
61
|
+
# resp.status # => 200
|
45
62
|
class Test < Faraday::Adapter
|
46
63
|
attr_accessor :stubs
|
47
64
|
|
@@ -55,6 +72,7 @@ module Faraday
|
|
55
72
|
@stack = {}
|
56
73
|
@consumed = {}
|
57
74
|
@strict_mode = strict_mode
|
75
|
+
@stubs_mutex = Monitor.new
|
58
76
|
yield(self) if block_given?
|
59
77
|
end
|
60
78
|
|
@@ -70,10 +88,13 @@ module Faraday
|
|
70
88
|
stack = @stack[request_method]
|
71
89
|
consumed = (@consumed[request_method] ||= [])
|
72
90
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
91
|
+
@stubs_mutex.synchronize do
|
92
|
+
stub, meta = matches?(stack, env)
|
93
|
+
if stub
|
94
|
+
removed = stack.delete(stub)
|
95
|
+
consumed << removed unless removed.nil?
|
96
|
+
return stub, meta
|
97
|
+
end
|
77
98
|
end
|
78
99
|
matches?(consumed, env)
|
79
100
|
end
|
@@ -125,7 +146,7 @@ module Faraday
|
|
125
146
|
# which means that all of a path, parameters, and headers must be the same as an actual request.
|
126
147
|
def strict_mode=(value)
|
127
148
|
@strict_mode = value
|
128
|
-
@stack.
|
149
|
+
@stack.each_value do |stubs|
|
129
150
|
stubs.each do |stub|
|
130
151
|
stub.strict_mode = value
|
131
152
|
end
|
@@ -163,7 +184,7 @@ module Faraday
|
|
163
184
|
end
|
164
185
|
|
165
186
|
# Stub request
|
166
|
-
|
187
|
+
Stub = Struct.new(:host, :path, :query, :headers, :body, :strict_mode, :block) do
|
167
188
|
# @param env [Faraday::Env]
|
168
189
|
def matches?(env)
|
169
190
|
request_host = env[:url].host
|
@@ -177,7 +198,7 @@ module Faraday
|
|
177
198
|
[(host.nil? || host == request_host) &&
|
178
199
|
path_match?(request_path, meta) &&
|
179
200
|
params_match?(env) &&
|
180
|
-
(
|
201
|
+
body_match?(request_body) &&
|
181
202
|
headers_match?(request_headers), meta]
|
182
203
|
end
|
183
204
|
|
@@ -218,6 +239,17 @@ module Faraday
|
|
218
239
|
end
|
219
240
|
end
|
220
241
|
|
242
|
+
def body_match?(request_body)
|
243
|
+
return true if body.to_s.empty?
|
244
|
+
|
245
|
+
case body
|
246
|
+
when Proc
|
247
|
+
body.call(request_body)
|
248
|
+
else
|
249
|
+
request_body == body
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
221
253
|
def to_s
|
222
254
|
"#{path} #{body}"
|
223
255
|
end
|
@@ -242,21 +274,38 @@ module Faraday
|
|
242
274
|
stub, meta = stubs.match(env)
|
243
275
|
|
244
276
|
unless stub
|
245
|
-
raise Stubs::NotFound, "no stubbed request for #{env[:method]} "\
|
246
|
-
"#{env[:url]} #{env[:body]}"
|
277
|
+
raise Stubs::NotFound, "no stubbed request for #{env[:method]} " \
|
278
|
+
"#{env[:url]} #{env[:body]} #{env[:headers]}"
|
247
279
|
end
|
248
280
|
|
249
281
|
block_arity = stub.block.arity
|
282
|
+
params = if block_arity >= 0
|
283
|
+
[env, meta].take(block_arity)
|
284
|
+
else
|
285
|
+
[env, meta]
|
286
|
+
end
|
287
|
+
|
288
|
+
timeout = request_timeout(:open, env[:request])
|
289
|
+
timeout ||= request_timeout(:read, env[:request])
|
290
|
+
|
250
291
|
status, headers, body =
|
251
|
-
if
|
252
|
-
|
292
|
+
if timeout
|
293
|
+
::Timeout.timeout(timeout, Faraday::TimeoutError) do
|
294
|
+
stub.block.call(*params)
|
295
|
+
end
|
253
296
|
else
|
254
|
-
stub.block.call(
|
297
|
+
stub.block.call(*params)
|
255
298
|
end
|
256
|
-
|
299
|
+
|
300
|
+
# We need to explicitly pass `reason_phrase = nil` here to avoid keyword args conflicts.
|
301
|
+
# See https://github.com/lostisland/faraday/issues/1444
|
302
|
+
# TODO: remove `nil` explicit reason_phrase once Ruby 3.0 becomes minimum req. version
|
303
|
+
save_response(env, status, body, headers, nil)
|
257
304
|
|
258
305
|
@app.call(env)
|
259
306
|
end
|
260
307
|
end
|
261
308
|
end
|
262
309
|
end
|
310
|
+
|
311
|
+
Faraday::Adapter.register_middleware(test: Faraday::Adapter::Test)
|
data/lib/faraday/adapter.rb
CHANGED
@@ -5,14 +5,9 @@ module Faraday
|
|
5
5
|
# responsible for fulfilling a Faraday request.
|
6
6
|
class Adapter
|
7
7
|
extend MiddlewareRegistry
|
8
|
-
extend DependencyLoader
|
9
8
|
|
10
9
|
CONTENT_LENGTH = 'Content-Length'
|
11
10
|
|
12
|
-
register_middleware File.expand_path('adapter', __dir__),
|
13
|
-
test: [:Test, 'test'],
|
14
|
-
typhoeus: [:Typhoeus, 'typhoeus']
|
15
|
-
|
16
11
|
# This module marks an Adapter as supporting parallel requests.
|
17
12
|
module Parallelism
|
18
13
|
attr_writer :supports_parallel
|
@@ -31,7 +26,7 @@ module Faraday
|
|
31
26
|
self.supports_parallel = false
|
32
27
|
|
33
28
|
def initialize(_app = nil, opts = {}, &block)
|
34
|
-
@app =
|
29
|
+
@app = lambda(&:response)
|
35
30
|
@connection_options = opts
|
36
31
|
@config_block = block
|
37
32
|
end
|
@@ -64,7 +59,7 @@ module Faraday
|
|
64
59
|
|
65
60
|
private
|
66
61
|
|
67
|
-
def save_response(env, status, body, headers = nil, reason_phrase = nil)
|
62
|
+
def save_response(env, status, body, headers = nil, reason_phrase = nil, finished: true)
|
68
63
|
env.status = status
|
69
64
|
env.body = body
|
70
65
|
env.reason_phrase = reason_phrase&.to_s&.strip
|
@@ -73,7 +68,7 @@ module Faraday
|
|
73
68
|
yield(response_headers) if block_given?
|
74
69
|
end
|
75
70
|
|
76
|
-
env.response.finish(env) unless env.parallel?
|
71
|
+
env.response.finish(env) unless env.parallel? || !finished
|
77
72
|
env.response
|
78
73
|
end
|
79
74
|
|
@@ -83,8 +78,7 @@ module Faraday
|
|
83
78
|
# @param type [Symbol] Describes which timeout setting to get: :read,
|
84
79
|
# :write, or :open.
|
85
80
|
# @param options [Hash] Hash containing Symbol keys like :timeout,
|
86
|
-
# :read_timeout, :write_timeout, :open_timeout
|
87
|
-
# :timeout
|
81
|
+
# :read_timeout, :write_timeout, or :open_timeout
|
88
82
|
#
|
89
83
|
# @return [Integer, nil] Timeout duration in seconds, or nil if no timeout
|
90
84
|
# has been set.
|
@@ -103,3 +97,5 @@ module Faraday
|
|
103
97
|
}.freeze
|
104
98
|
end
|
105
99
|
end
|
100
|
+
|
101
|
+
require 'faraday/adapter/test'
|
data/lib/faraday/connection.rb
CHANGED
@@ -1,23 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'faraday/deprecate'
|
4
|
-
|
5
3
|
module Faraday
|
6
4
|
# Connection objects manage the default properties and the middleware
|
7
5
|
# stack for fulfilling an HTTP request.
|
8
6
|
#
|
9
7
|
# @example
|
10
8
|
#
|
11
|
-
# conn = Faraday::Connection.new 'http://
|
9
|
+
# conn = Faraday::Connection.new 'http://httpbingo.org'
|
12
10
|
#
|
13
|
-
# # GET http://
|
11
|
+
# # GET http://httpbingo.org/nigiri
|
14
12
|
# conn.get 'nigiri'
|
15
13
|
# # => #<Faraday::Response>
|
16
14
|
#
|
17
15
|
class Connection
|
18
16
|
# A Set of allowed HTTP verbs.
|
19
17
|
METHODS = Set.new %i[get post put delete head patch options trace]
|
20
|
-
USER_AGENT = "Faraday v#{VERSION}"
|
18
|
+
USER_AGENT = "Faraday v#{VERSION}".freeze
|
21
19
|
|
22
20
|
# @return [Hash] URI query unencoded key/value pairs.
|
23
21
|
attr_reader :params
|
@@ -66,7 +64,7 @@ module Faraday
|
|
66
64
|
options = ConnectionOptions.from(options)
|
67
65
|
|
68
66
|
if url.is_a?(Hash) || url.is_a?(ConnectionOptions)
|
69
|
-
options =
|
67
|
+
options = Utils.deep_merge(options, url)
|
70
68
|
url = options.url
|
71
69
|
end
|
72
70
|
|
@@ -119,7 +117,7 @@ module Faraday
|
|
119
117
|
|
120
118
|
extend Forwardable
|
121
119
|
|
122
|
-
def_delegators :builder, :
|
120
|
+
def_delegators :builder, :use, :request, :response, :adapter, :app
|
123
121
|
|
124
122
|
# Closes the underlying resources and/or connections. In the case of
|
125
123
|
# persistent connections, this closes all currently open connections
|
@@ -132,10 +130,10 @@ module Faraday
|
|
132
130
|
# Makes a GET HTTP request without a body.
|
133
131
|
# @!scope class
|
134
132
|
#
|
135
|
-
# @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
|
136
134
|
# all requests. Can also be the options Hash.
|
137
|
-
# @param params [Hash] Hash of URI query unencoded key/value pairs.
|
138
|
-
# @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.
|
139
137
|
#
|
140
138
|
# @example
|
141
139
|
# conn.get '/items', { page: 1 }, :accept => 'application/json'
|
@@ -154,10 +152,10 @@ module Faraday
|
|
154
152
|
# Makes a HEAD HTTP request without a body.
|
155
153
|
# @!scope class
|
156
154
|
#
|
157
|
-
# @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
|
158
156
|
# all requests. Can also be the options Hash.
|
159
|
-
# @param params [Hash] Hash of URI query unencoded key/value pairs.
|
160
|
-
# @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.
|
161
159
|
#
|
162
160
|
# @example
|
163
161
|
# conn.head '/items/1'
|
@@ -169,10 +167,10 @@ module Faraday
|
|
169
167
|
# Makes a DELETE HTTP request without a body.
|
170
168
|
# @!scope class
|
171
169
|
#
|
172
|
-
# @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
|
173
171
|
# all requests. Can also be the options Hash.
|
174
|
-
# @param params [Hash] Hash of URI query unencoded key/value pairs.
|
175
|
-
# @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.
|
176
174
|
#
|
177
175
|
# @example
|
178
176
|
# conn.delete '/items/1'
|
@@ -184,10 +182,10 @@ module Faraday
|
|
184
182
|
# Makes a TRACE HTTP request without a body.
|
185
183
|
# @!scope class
|
186
184
|
#
|
187
|
-
# @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
|
188
186
|
# all requests. Can also be the options Hash.
|
189
|
-
# @param params [Hash] Hash of URI query unencoded key/value pairs.
|
190
|
-
# @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.
|
191
189
|
#
|
192
190
|
# @example
|
193
191
|
# conn.connect '/items/1'
|
@@ -212,9 +210,9 @@ module Faraday
|
|
212
210
|
#
|
213
211
|
# @overload options(url, params = nil, headers = nil)
|
214
212
|
# Makes an OPTIONS HTTP request to the given URL.
|
215
|
-
# @param url [String] String base URL to sue as a prefix for all requests.
|
216
|
-
# @param params [Hash] Hash of URI query unencoded key/value pairs.
|
217
|
-
# @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.
|
218
216
|
#
|
219
217
|
# @example
|
220
218
|
# conn.options '/items/1'
|
@@ -222,7 +220,7 @@ module Faraday
|
|
222
220
|
# @yield [Faraday::Request] for further request customizations
|
223
221
|
# @return [Faraday::Response]
|
224
222
|
def options(*args)
|
225
|
-
return @options if args.
|
223
|
+
return @options if args.empty?
|
226
224
|
|
227
225
|
url, params, headers = *args
|
228
226
|
run_request(:options, url, nil, headers) do |request|
|
@@ -235,10 +233,10 @@ module Faraday
|
|
235
233
|
# Makes a POST HTTP request with a body.
|
236
234
|
# @!scope class
|
237
235
|
#
|
238
|
-
# @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
|
239
237
|
# all requests. Can also be the options Hash.
|
240
|
-
# @param body [String] body for the request.
|
241
|
-
# @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.
|
242
240
|
#
|
243
241
|
# @example
|
244
242
|
# conn.post '/items', data, content_type: 'application/json'
|
@@ -257,20 +255,19 @@ module Faraday
|
|
257
255
|
# Makes a PUT HTTP request with a body.
|
258
256
|
# @!scope class
|
259
257
|
#
|
260
|
-
# @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
|
261
259
|
# all requests. Can also be the options Hash.
|
262
|
-
# @param body [String] body for the request.
|
263
|
-
# @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.
|
264
262
|
#
|
265
263
|
# @example
|
266
|
-
#
|
267
|
-
# conn.post '/items', data, content_type: 'application/json'
|
264
|
+
# conn.put '/products/123', data, content_type: 'application/json'
|
268
265
|
#
|
269
|
-
# #
|
270
|
-
# conn.
|
271
|
-
# req.headers[
|
272
|
-
# req.
|
273
|
-
# 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'
|
274
271
|
# end
|
275
272
|
#
|
276
273
|
# @yield [Faraday::Request] for further request customizations
|
@@ -285,75 +282,6 @@ module Faraday
|
|
285
282
|
RUBY
|
286
283
|
end
|
287
284
|
|
288
|
-
# Sets up the Authorization header with these credentials, encoded
|
289
|
-
# with base64.
|
290
|
-
#
|
291
|
-
# @param login [String] The authentication login.
|
292
|
-
# @param pass [String] The authentication password.
|
293
|
-
#
|
294
|
-
# @example
|
295
|
-
#
|
296
|
-
# conn.basic_auth 'Aladdin', 'open sesame'
|
297
|
-
# conn.headers['Authorization']
|
298
|
-
# # => "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="
|
299
|
-
#
|
300
|
-
# @return [void]
|
301
|
-
def basic_auth(login, pass)
|
302
|
-
set_authorization_header(:basic_auth, login, pass)
|
303
|
-
end
|
304
|
-
|
305
|
-
extend Faraday::Deprecate
|
306
|
-
deprecate :basic_auth, '#request(:basic_auth, ...)', '2.0'
|
307
|
-
|
308
|
-
# Sets up the Authorization header with the given token.
|
309
|
-
#
|
310
|
-
# @param token [String]
|
311
|
-
# @param options [Hash] extra token options.
|
312
|
-
#
|
313
|
-
# @example
|
314
|
-
#
|
315
|
-
# conn.token_auth 'abcdef', foo: 'bar'
|
316
|
-
# conn.headers['Authorization']
|
317
|
-
# # => "Token token=\"abcdef\",
|
318
|
-
# foo=\"bar\""
|
319
|
-
#
|
320
|
-
# @return [void]
|
321
|
-
def token_auth(token, options = nil)
|
322
|
-
set_authorization_header(:token_auth, token, options)
|
323
|
-
end
|
324
|
-
|
325
|
-
deprecate :token_auth,
|
326
|
-
'#request(:token_auth, ...)',
|
327
|
-
'2.0',
|
328
|
-
'See https://lostisland.github.io/faraday/middleware/authentication for more usage info.'
|
329
|
-
|
330
|
-
# Sets up a custom Authorization header.
|
331
|
-
#
|
332
|
-
# @param type [String] authorization type
|
333
|
-
# @param token [String, Hash] token. A String value is taken literally, and
|
334
|
-
# a Hash is encoded into comma-separated key/value pairs.
|
335
|
-
#
|
336
|
-
# @example
|
337
|
-
#
|
338
|
-
# conn.authorization :Bearer, 'mF_9.B5f-4.1JqM'
|
339
|
-
# conn.headers['Authorization']
|
340
|
-
# # => "Bearer mF_9.B5f-4.1JqM"
|
341
|
-
#
|
342
|
-
# conn.authorization :Token, token: 'abcdef', foo: 'bar'
|
343
|
-
# conn.headers['Authorization']
|
344
|
-
# # => "Token token=\"abcdef\",
|
345
|
-
# foo=\"bar\""
|
346
|
-
#
|
347
|
-
# @return [void]
|
348
|
-
def authorization(type, token)
|
349
|
-
set_authorization_header(:authorization, type, token)
|
350
|
-
end
|
351
|
-
|
352
|
-
deprecate :authorization,
|
353
|
-
'#request(:authorization, ...)',
|
354
|
-
'2.0',
|
355
|
-
'See https://lostisland.github.io/faraday/middleware/authentication for more usage info.'
|
356
|
-
|
357
285
|
# Check if the adapter is parallel-capable.
|
358
286
|
#
|
359
287
|
# @yield if the adapter isn't parallel-capable, or if no adapter is set yet.
|
@@ -386,15 +314,23 @@ module Faraday
|
|
386
314
|
#
|
387
315
|
# @yield a block to execute multiple requests.
|
388
316
|
# @return [void]
|
389
|
-
def in_parallel(manager = nil)
|
317
|
+
def in_parallel(manager = nil, &block)
|
390
318
|
@parallel_manager = manager || default_parallel_manager do
|
391
319
|
warn 'Warning: `in_parallel` called but no parallel-capable adapter ' \
|
392
320
|
'on Faraday stack'
|
393
321
|
warn caller[2, 10].join("\n")
|
394
322
|
nil
|
395
323
|
end
|
396
|
-
yield
|
397
|
-
|
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
|
398
334
|
ensure
|
399
335
|
@parallel_manager = nil
|
400
336
|
end
|
@@ -420,11 +356,11 @@ module Faraday
|
|
420
356
|
# @example
|
421
357
|
#
|
422
358
|
# conn = Faraday::Connection.new { ... }
|
423
|
-
# conn.url_prefix = "https://
|
359
|
+
# conn.url_prefix = "https://httpbingo.org/api"
|
424
360
|
# conn.scheme # => https
|
425
361
|
# conn.path_prefix # => "/api"
|
426
362
|
#
|
427
|
-
# conn.get("nigiri?page=2") # accesses https://
|
363
|
+
# conn.get("nigiri?page=2") # accesses https://httpbingo.org/api/nigiri
|
428
364
|
def url_prefix=(url, encoder = nil)
|
429
365
|
uri = @url_prefix = Utils.URI(url)
|
430
366
|
self.path_prefix = uri.path
|
@@ -441,7 +377,7 @@ module Faraday
|
|
441
377
|
end
|
442
378
|
|
443
379
|
def set_basic_auth(user, password)
|
444
|
-
header = Faraday::
|
380
|
+
header = Faraday::Utils.basic_header_from(user, password)
|
445
381
|
headers[Faraday::Request::Authorization::KEY] = header
|
446
382
|
end
|
447
383
|
|
@@ -461,20 +397,20 @@ module Faraday
|
|
461
397
|
# Takes a relative url for a request and combines it with the defaults
|
462
398
|
# set on the connection instance.
|
463
399
|
#
|
464
|
-
# @param url [String]
|
400
|
+
# @param url [String, URI, nil]
|
465
401
|
# @param extra_params [Hash]
|
466
402
|
#
|
467
403
|
# @example
|
468
404
|
# conn = Faraday::Connection.new { ... }
|
469
|
-
# conn.url_prefix = "https://
|
405
|
+
# conn.url_prefix = "https://httpbingo.org/api?token=abc"
|
470
406
|
# conn.scheme # => https
|
471
407
|
# conn.path_prefix # => "/api"
|
472
408
|
#
|
473
409
|
# conn.build_url("nigiri?page=2")
|
474
|
-
# # => https://
|
410
|
+
# # => https://httpbingo.org/api/nigiri?token=abc&page=2
|
475
411
|
#
|
476
412
|
# conn.build_url("nigiri", page: 2)
|
477
|
-
# # => https://
|
413
|
+
# # => https://httpbingo.org/api/nigiri?token=abc&page=2
|
478
414
|
#
|
479
415
|
def build_url(url = nil, extra_params = nil)
|
480
416
|
uri = build_exclusive_url(url)
|
@@ -494,10 +430,10 @@ module Faraday
|
|
494
430
|
# Builds and runs the Faraday::Request.
|
495
431
|
#
|
496
432
|
# @param method [Symbol] HTTP method.
|
497
|
-
# @param url [String, URI] String or URI to access.
|
498
|
-
# @param body [
|
499
|
-
# a string.
|
500
|
-
# @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.
|
501
437
|
#
|
502
438
|
# @return [Faraday::Response]
|
503
439
|
def run_request(method, url, body, headers)
|
@@ -533,7 +469,7 @@ module Faraday
|
|
533
469
|
|
534
470
|
# Build an absolute URL based on url_prefix.
|
535
471
|
#
|
536
|
-
# @param url [String, URI]
|
472
|
+
# @param url [String, URI, nil]
|
537
473
|
# @param params [Faraday::Utils::ParamsHash] A Faraday::Utils::ParamsHash to
|
538
474
|
# replace the query values
|
539
475
|
# of the resulting url (default: nil).
|
@@ -542,17 +478,16 @@ module Faraday
|
|
542
478
|
def build_exclusive_url(url = nil, params = nil, params_encoder = nil)
|
543
479
|
url = nil if url.respond_to?(:empty?) && url.empty?
|
544
480
|
base = url_prefix.dup
|
545
|
-
if url && base.path
|
481
|
+
if url && !base.path.end_with?('/')
|
546
482
|
base.path = "#{base.path}/" # ensure trailing slash
|
547
483
|
end
|
548
|
-
|
484
|
+
# Ensure relative url will be parsed correctly (such as `service:search` )
|
485
|
+
url = "./#{url}" if url.respond_to?(:start_with?) && !url.start_with?('http://', 'https://', '/', './', '../')
|
549
486
|
uri = url ? base + url : base
|
550
487
|
if params
|
551
488
|
uri.query = params.to_query(params_encoder || options.params_encoder)
|
552
489
|
end
|
553
|
-
# rubocop:disable Style/SafeNavigation
|
554
490
|
uri.query = nil if uri.query && uri.query.empty?
|
555
|
-
# rubocop:enable Style/SafeNavigation
|
556
491
|
uri
|
557
492
|
end
|
558
493
|
|
@@ -584,41 +519,28 @@ module Faraday
|
|
584
519
|
yield(Utils.unescape(uri.user), Utils.unescape(uri.password))
|
585
520
|
end
|
586
521
|
|
587
|
-
def set_authorization_header(header_type, *args)
|
588
|
-
header = Faraday::Request
|
589
|
-
.lookup_middleware(header_type)
|
590
|
-
.header(*args)
|
591
|
-
|
592
|
-
headers[Faraday::Request::Authorization::KEY] = header
|
593
|
-
end
|
594
|
-
|
595
522
|
def proxy_from_env(url)
|
596
523
|
return if Faraday.ignore_env_proxy
|
597
524
|
|
598
525
|
uri = nil
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
when nil
|
611
|
-
uri = find_default_proxy
|
612
|
-
end
|
613
|
-
else
|
614
|
-
warn 'no_proxy is unsupported' if ENV['no_proxy'] || ENV['NO_PROXY']
|
526
|
+
case url
|
527
|
+
when String
|
528
|
+
uri = Utils.URI(url)
|
529
|
+
uri = if uri.host.nil?
|
530
|
+
find_default_proxy
|
531
|
+
else
|
532
|
+
URI.parse("#{uri.scheme}://#{uri.host}").find_proxy
|
533
|
+
end
|
534
|
+
when URI
|
535
|
+
uri = url.find_proxy
|
536
|
+
when nil
|
615
537
|
uri = find_default_proxy
|
616
538
|
end
|
617
539
|
ProxyOptions.from(uri) if uri
|
618
540
|
end
|
619
541
|
|
620
542
|
def find_default_proxy
|
621
|
-
uri = ENV
|
543
|
+
uri = ENV.fetch('http_proxy', nil)
|
622
544
|
return unless uri && !uri.empty?
|
623
545
|
|
624
546
|
uri = "http://#{uri}" unless uri.match?(/^http/i)
|
@@ -636,7 +558,7 @@ module Faraday
|
|
636
558
|
end
|
637
559
|
|
638
560
|
def support_parallel?(adapter)
|
639
|
-
adapter
|
561
|
+
adapter.respond_to?(:supports_parallel?) && adapter&.supports_parallel?
|
640
562
|
end
|
641
563
|
end
|
642
564
|
end
|
@@ -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,7 +167,7 @@ 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
|
167
173
|
def_delegators :'Faraday::Utils', :escape, :unescape
|
@@ -169,6 +175,7 @@ module Faraday
|
|
169
175
|
|
170
176
|
# Useful default for OAuth and caching.
|
171
177
|
@sort_params = true
|
178
|
+
@array_indices = false
|
172
179
|
|
173
180
|
extend EncodeMethods
|
174
181
|
extend DecodeMethods
|