faraday 0.9.2 → 1.0.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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +276 -0
- data/LICENSE.md +1 -1
- data/README.md +27 -217
- data/Rakefile +7 -0
- data/UPGRADING.md +55 -0
- data/examples/client_spec.rb +65 -0
- data/examples/client_test.rb +79 -0
- data/lib/faraday/adapter/em_http.rb +149 -101
- data/lib/faraday/adapter/em_http_ssl_patch.rb +25 -19
- data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +18 -15
- data/lib/faraday/adapter/em_synchrony.rb +106 -56
- data/lib/faraday/adapter/excon.rb +98 -55
- data/lib/faraday/adapter/httpclient.rb +89 -55
- data/lib/faraday/adapter/net_http.rb +132 -53
- data/lib/faraday/adapter/net_http_persistent.rb +70 -28
- data/lib/faraday/adapter/patron.rb +92 -38
- data/lib/faraday/adapter/rack.rb +30 -13
- data/lib/faraday/adapter/test.rb +136 -52
- data/lib/faraday/adapter/typhoeus.rb +7 -115
- data/lib/faraday/adapter.rb +89 -20
- data/lib/faraday/adapter_registry.rb +28 -0
- data/lib/faraday/autoload.rb +47 -36
- data/lib/faraday/connection.rb +345 -168
- data/lib/faraday/dependency_loader.rb +37 -0
- data/lib/faraday/encoders/flat_params_encoder.rb +98 -0
- data/lib/faraday/encoders/nested_params_encoder.rb +171 -0
- data/lib/faraday/error.rb +108 -29
- data/lib/faraday/file_part.rb +128 -0
- data/lib/faraday/logging/formatter.rb +105 -0
- data/lib/faraday/middleware.rb +12 -28
- data/lib/faraday/middleware_registry.rb +129 -0
- data/lib/faraday/options/connection_options.rb +22 -0
- data/lib/faraday/options/env.rb +181 -0
- data/lib/faraday/options/proxy_options.rb +28 -0
- data/lib/faraday/options/request_options.rb +22 -0
- data/lib/faraday/options/ssl_options.rb +59 -0
- data/lib/faraday/options.rb +57 -194
- data/lib/faraday/param_part.rb +53 -0
- data/lib/faraday/parameters.rb +4 -196
- data/lib/faraday/rack_builder.rb +74 -39
- data/lib/faraday/request/authorization.rb +42 -31
- data/lib/faraday/request/basic_authentication.rb +14 -7
- data/lib/faraday/request/instrumentation.rb +45 -27
- data/lib/faraday/request/multipart.rb +81 -45
- data/lib/faraday/request/retry.rb +211 -126
- data/lib/faraday/request/token_authentication.rb +15 -10
- data/lib/faraday/request/url_encoded.rb +41 -23
- data/lib/faraday/request.rb +84 -30
- data/lib/faraday/response/logger.rb +22 -48
- data/lib/faraday/response/raise_error.rb +38 -14
- data/lib/faraday/response.rb +27 -16
- data/lib/faraday/utils/headers.rb +139 -0
- data/lib/faraday/utils/params_hash.rb +61 -0
- data/lib/faraday/utils.rb +28 -228
- data/lib/faraday.rb +102 -204
- data/spec/external_adapters/faraday_specs_setup.rb +14 -0
- data/spec/faraday/adapter/em_http_spec.rb +47 -0
- data/spec/faraday/adapter/em_synchrony_spec.rb +16 -0
- data/spec/faraday/adapter/excon_spec.rb +49 -0
- data/spec/faraday/adapter/httpclient_spec.rb +73 -0
- data/spec/faraday/adapter/net_http_persistent_spec.rb +57 -0
- data/spec/faraday/adapter/net_http_spec.rb +64 -0
- data/spec/faraday/adapter/patron_spec.rb +18 -0
- data/spec/faraday/adapter/rack_spec.rb +8 -0
- data/spec/faraday/adapter/typhoeus_spec.rb +7 -0
- data/spec/faraday/adapter_registry_spec.rb +28 -0
- data/spec/faraday/adapter_spec.rb +55 -0
- data/spec/faraday/composite_read_io_spec.rb +80 -0
- data/spec/faraday/connection_spec.rb +691 -0
- data/spec/faraday/error_spec.rb +45 -0
- data/spec/faraday/middleware_spec.rb +26 -0
- data/spec/faraday/options/env_spec.rb +70 -0
- data/spec/faraday/options/options_spec.rb +297 -0
- data/spec/faraday/options/proxy_options_spec.rb +37 -0
- data/spec/faraday/options/request_options_spec.rb +19 -0
- data/spec/faraday/params_encoders/flat_spec.rb +34 -0
- data/spec/faraday/params_encoders/nested_spec.rb +134 -0
- data/spec/faraday/rack_builder_spec.rb +196 -0
- data/spec/faraday/request/authorization_spec.rb +88 -0
- data/spec/faraday/request/instrumentation_spec.rb +76 -0
- data/spec/faraday/request/multipart_spec.rb +274 -0
- data/spec/faraday/request/retry_spec.rb +242 -0
- data/spec/faraday/request/url_encoded_spec.rb +70 -0
- data/spec/faraday/request_spec.rb +109 -0
- data/spec/faraday/response/logger_spec.rb +220 -0
- data/spec/faraday/response/middleware_spec.rb +52 -0
- data/spec/faraday/response/raise_error_spec.rb +106 -0
- data/spec/faraday/response_spec.rb +75 -0
- data/spec/faraday/utils/headers_spec.rb +82 -0
- data/spec/faraday/utils_spec.rb +56 -0
- data/spec/faraday_spec.rb +37 -0
- data/spec/spec_helper.rb +132 -0
- data/spec/support/disabling_stub.rb +14 -0
- data/spec/support/fake_safe_buffer.rb +15 -0
- data/spec/support/helper_methods.rb +133 -0
- data/spec/support/shared_examples/adapter.rb +104 -0
- data/spec/support/shared_examples/params_encoder.rb +18 -0
- data/spec/support/shared_examples/request_method.rb +234 -0
- data/spec/support/streaming_response_checker.rb +35 -0
- data/spec/support/webmock_rack_app.rb +68 -0
- metadata +110 -64
- data/lib/faraday/upload_io.rb +0 -67
data/lib/faraday/connection.rb
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Faraday
|
|
2
|
-
#
|
|
4
|
+
# Connection objects manage the default properties and the middleware
|
|
3
5
|
# stack for fulfilling an HTTP request.
|
|
4
6
|
#
|
|
5
|
-
#
|
|
7
|
+
# @example
|
|
6
8
|
#
|
|
7
9
|
# conn = Faraday::Connection.new 'http://sushi.com'
|
|
8
10
|
#
|
|
@@ -12,54 +14,57 @@ module Faraday
|
|
|
12
14
|
#
|
|
13
15
|
class Connection
|
|
14
16
|
# A Set of allowed HTTP verbs.
|
|
15
|
-
METHODS = Set.new [
|
|
17
|
+
METHODS = Set.new %i[get post put delete head patch options trace]
|
|
16
18
|
|
|
17
|
-
#
|
|
19
|
+
# @return [Hash] URI query unencoded key/value pairs.
|
|
18
20
|
attr_reader :params
|
|
19
21
|
|
|
20
|
-
#
|
|
22
|
+
# @return [Hash] unencoded HTTP header key/value pairs.
|
|
21
23
|
attr_reader :headers
|
|
22
24
|
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
+
# @return [String] a URI with the prefix used for all requests from this
|
|
26
|
+
# Connection. This includes a default host name, scheme, port, and path.
|
|
25
27
|
attr_reader :url_prefix
|
|
26
28
|
|
|
27
|
-
#
|
|
29
|
+
# @return [Faraday::Builder] Builder for this Connection.
|
|
28
30
|
attr_reader :builder
|
|
29
31
|
|
|
30
|
-
#
|
|
31
|
-
attr_reader :options
|
|
32
|
-
|
|
33
|
-
# Public: Returns a Hash of the SSL options.
|
|
32
|
+
# @return [Hash] SSL options.
|
|
34
33
|
attr_reader :ssl
|
|
35
34
|
|
|
36
|
-
#
|
|
35
|
+
# @return [Object] the parallel manager for this Connection.
|
|
37
36
|
attr_reader :parallel_manager
|
|
38
37
|
|
|
39
|
-
#
|
|
38
|
+
# Sets the default parallel manager for this connection.
|
|
40
39
|
attr_writer :default_parallel_manager
|
|
41
40
|
|
|
42
|
-
#
|
|
41
|
+
# @return [Hash] proxy options.
|
|
42
|
+
attr_reader :proxy
|
|
43
|
+
|
|
44
|
+
# Initializes a new Faraday::Connection.
|
|
43
45
|
#
|
|
44
|
-
# url
|
|
46
|
+
# @param url [URI, String] URI or String base URL to use as a prefix for all
|
|
45
47
|
# requests (optional).
|
|
46
|
-
# options
|
|
47
|
-
#
|
|
48
|
-
#
|
|
49
|
-
#
|
|
50
|
-
#
|
|
51
|
-
#
|
|
52
|
-
#
|
|
53
|
-
#
|
|
54
|
-
#
|
|
55
|
-
#
|
|
56
|
-
#
|
|
48
|
+
# @param options [Hash, Faraday::ConnectionOptions]
|
|
49
|
+
# @option options [URI, String] :url ('http:/') URI or String base URL
|
|
50
|
+
# @option options [Hash<String => String>] :params URI query unencoded
|
|
51
|
+
# key/value pairs.
|
|
52
|
+
# @option options [Hash<String => String>] :headers Hash of unencoded HTTP
|
|
53
|
+
# header key/value pairs.
|
|
54
|
+
# @option options [Hash] :request Hash of request options.
|
|
55
|
+
# @option options [Hash] :ssl Hash of SSL options.
|
|
56
|
+
# @option options [Hash, URI, String] :proxy proxy options, either as a URL
|
|
57
|
+
# or as a Hash
|
|
58
|
+
# @option options [URI, String] :proxy[:uri]
|
|
59
|
+
# @option options [String] :proxy[:user]
|
|
60
|
+
# @option options [String] :proxy[:password]
|
|
61
|
+
# @yield [self] after all setup has been done
|
|
57
62
|
def initialize(url = nil, options = nil)
|
|
58
|
-
|
|
59
|
-
|
|
63
|
+
options = ConnectionOptions.from(options)
|
|
64
|
+
|
|
65
|
+
if url.is_a?(Hash) || url.is_a?(ConnectionOptions)
|
|
66
|
+
options = options.merge(url)
|
|
60
67
|
url = options.url
|
|
61
|
-
else
|
|
62
|
-
options = ConnectionOptions.from(options)
|
|
63
68
|
end
|
|
64
69
|
|
|
65
70
|
@parallel_manager = nil
|
|
@@ -71,7 +76,7 @@ module Faraday
|
|
|
71
76
|
|
|
72
77
|
@builder = options.builder || begin
|
|
73
78
|
# pass an empty block to Builder so it doesn't assume default middleware
|
|
74
|
-
options.new_builder(block_given? ?
|
|
79
|
+
options.new_builder(block_given? ? proc { |b| } : nil)
|
|
75
80
|
end
|
|
76
81
|
|
|
77
82
|
self.url_prefix = url || 'http:/'
|
|
@@ -79,26 +84,31 @@ module Faraday
|
|
|
79
84
|
@params.update(options.params) if options.params
|
|
80
85
|
@headers.update(options.headers) if options.headers
|
|
81
86
|
|
|
82
|
-
|
|
83
|
-
proxy(options.fetch(:proxy) {
|
|
84
|
-
uri = ENV['http_proxy']
|
|
85
|
-
if uri && !uri.empty?
|
|
86
|
-
uri = 'http://' + uri if uri !~ /^http/i
|
|
87
|
-
uri
|
|
88
|
-
end
|
|
89
|
-
})
|
|
87
|
+
initialize_proxy(url, options)
|
|
90
88
|
|
|
91
89
|
yield(self) if block_given?
|
|
92
90
|
|
|
93
91
|
@headers[:user_agent] ||= "Faraday v#{VERSION}"
|
|
94
92
|
end
|
|
95
93
|
|
|
96
|
-
|
|
94
|
+
def initialize_proxy(url, options)
|
|
95
|
+
@manual_proxy = !!options.proxy
|
|
96
|
+
@proxy =
|
|
97
|
+
if options.proxy
|
|
98
|
+
ProxyOptions.from(options.proxy)
|
|
99
|
+
else
|
|
100
|
+
proxy_from_env(url)
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Sets the Hash of URI query unencoded key/value pairs.
|
|
105
|
+
# @param hash [Hash]
|
|
97
106
|
def params=(hash)
|
|
98
107
|
@params.replace hash
|
|
99
108
|
end
|
|
100
109
|
|
|
101
|
-
#
|
|
110
|
+
# Sets the Hash of unencoded HTTP header key/value pairs.
|
|
111
|
+
# @param hash [Hash]
|
|
102
112
|
def headers=(hash)
|
|
103
113
|
@headers.replace hash
|
|
104
114
|
end
|
|
@@ -107,71 +117,163 @@ module Faraday
|
|
|
107
117
|
|
|
108
118
|
def_delegators :builder, :build, :use, :request, :response, :adapter, :app
|
|
109
119
|
|
|
110
|
-
#
|
|
120
|
+
# Closes the underlying resources and/or connections. In the case of
|
|
121
|
+
# persistent connections, this closes all currently open connections
|
|
122
|
+
# but does not prevent new connections from being made.
|
|
123
|
+
def close
|
|
124
|
+
app.close
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# @!method get(url = nil, params = nil, headers = nil)
|
|
128
|
+
# Makes a GET HTTP request without a body.
|
|
129
|
+
# @!scope class
|
|
111
130
|
#
|
|
112
|
-
# url
|
|
113
|
-
#
|
|
114
|
-
# params
|
|
115
|
-
# headers
|
|
131
|
+
# @param url [String] The optional String base URL to use as a prefix for
|
|
132
|
+
# 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.
|
|
116
135
|
#
|
|
117
|
-
#
|
|
118
|
-
#
|
|
119
|
-
# conn.get '/items', {:page => 1}, :accept => 'application/json'
|
|
120
|
-
# conn.head '/items/1'
|
|
136
|
+
# @example
|
|
137
|
+
# conn.get '/items', { page: 1 }, :accept => 'application/json'
|
|
121
138
|
#
|
|
122
139
|
# # ElasticSearch example sending a body with GET.
|
|
123
140
|
# conn.get '/twitter/tweet/_search' do |req|
|
|
124
141
|
# req.headers[:content_type] = 'application/json'
|
|
125
142
|
# req.params[:routing] = 'kimchy'
|
|
126
|
-
# req.body = JSON.generate(:
|
|
143
|
+
# req.body = JSON.generate(query: {...})
|
|
127
144
|
# end
|
|
128
145
|
#
|
|
129
|
-
#
|
|
130
|
-
#
|
|
146
|
+
# @yield [Faraday::Request] for further request customizations
|
|
147
|
+
# @return [Faraday::Response]
|
|
148
|
+
|
|
149
|
+
# @!method head(url = nil, params = nil, headers = nil)
|
|
150
|
+
# Makes a HEAD HTTP request without a body.
|
|
151
|
+
# @!scope class
|
|
152
|
+
#
|
|
153
|
+
# @param url [String] The optional String base URL to use as a prefix for
|
|
154
|
+
# 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
|
+
#
|
|
158
|
+
# @example
|
|
159
|
+
# conn.head '/items/1'
|
|
160
|
+
#
|
|
161
|
+
# @yield [Faraday::Request] for further request customizations
|
|
162
|
+
# @return [Faraday::Response]
|
|
163
|
+
|
|
164
|
+
# @!method delete(url = nil, params = nil, headers = nil)
|
|
165
|
+
# Makes a DELETE HTTP request without a body.
|
|
166
|
+
# @!scope class
|
|
167
|
+
#
|
|
168
|
+
# @param url [String] The optional String base URL to use as a prefix for
|
|
169
|
+
# 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
|
+
#
|
|
173
|
+
# @example
|
|
174
|
+
# conn.delete '/items/1'
|
|
175
|
+
#
|
|
176
|
+
# @yield [Faraday::Request] for further request customizations
|
|
177
|
+
# @return [Faraday::Response]
|
|
178
|
+
|
|
179
|
+
# @!method trace(url = nil, params = nil, headers = nil)
|
|
180
|
+
# Makes a TRACE HTTP request without a body.
|
|
181
|
+
# @!scope class
|
|
131
182
|
#
|
|
132
|
-
#
|
|
183
|
+
# @param url [String] The optional String base URL to use as a prefix for
|
|
184
|
+
# 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.
|
|
133
187
|
#
|
|
134
|
-
#
|
|
188
|
+
# @example
|
|
189
|
+
# conn.connect '/items/1'
|
|
135
190
|
#
|
|
136
|
-
#
|
|
137
|
-
|
|
191
|
+
# @yield [Faraday::Request] for further request customizations
|
|
192
|
+
# @return [Faraday::Response]
|
|
193
|
+
|
|
194
|
+
# @!visibility private
|
|
195
|
+
METHODS_WITH_QUERY.each do |method|
|
|
138
196
|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
|
139
197
|
def #{method}(url = nil, params = nil, headers = nil)
|
|
140
|
-
run_request(:#{method}, url, nil, headers)
|
|
198
|
+
run_request(:#{method}, url, nil, headers) do |request|
|
|
141
199
|
request.params.update(params) if params
|
|
142
|
-
yield
|
|
143
|
-
|
|
200
|
+
yield request if block_given?
|
|
201
|
+
end
|
|
144
202
|
end
|
|
145
203
|
RUBY
|
|
146
204
|
end
|
|
147
205
|
|
|
148
|
-
#
|
|
206
|
+
# @overload options()
|
|
207
|
+
# Returns current Connection options.
|
|
208
|
+
#
|
|
209
|
+
# @overload options(url, params = nil, headers = nil)
|
|
210
|
+
# 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.
|
|
149
214
|
#
|
|
150
|
-
#
|
|
151
|
-
#
|
|
152
|
-
#
|
|
153
|
-
#
|
|
215
|
+
# @example
|
|
216
|
+
# conn.options '/items/1'
|
|
217
|
+
#
|
|
218
|
+
# @yield [Faraday::Request] for further request customizations
|
|
219
|
+
# @return [Faraday::Response]
|
|
220
|
+
def options(*args)
|
|
221
|
+
return @options if args.size.zero?
|
|
222
|
+
|
|
223
|
+
url, params, headers = *args
|
|
224
|
+
run_request(:options, url, nil, headers) do |request|
|
|
225
|
+
request.params.update(params) if params
|
|
226
|
+
yield request if block_given?
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
# @!method post(url = nil, body = nil, headers = nil)
|
|
231
|
+
# Makes a POST HTTP request with a body.
|
|
232
|
+
# @!scope class
|
|
154
233
|
#
|
|
155
|
-
#
|
|
234
|
+
# @param url [String] The optional String base URL to use as a prefix for
|
|
235
|
+
# 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.
|
|
156
238
|
#
|
|
157
|
-
#
|
|
239
|
+
# @example
|
|
240
|
+
# conn.post '/items', data, content_type: 'application/json'
|
|
158
241
|
#
|
|
159
242
|
# # Simple ElasticSearch indexing sample.
|
|
160
243
|
# conn.post '/twitter/tweet' do |req|
|
|
161
244
|
# req.headers[:content_type] = 'application/json'
|
|
162
245
|
# req.params[:routing] = 'kimchy'
|
|
163
|
-
# req.body = JSON.generate(:
|
|
246
|
+
# req.body = JSON.generate(user: 'kimchy', ...)
|
|
164
247
|
# end
|
|
165
248
|
#
|
|
166
|
-
#
|
|
167
|
-
#
|
|
249
|
+
# @yield [Faraday::Request] for further request customizations
|
|
250
|
+
# @return [Faraday::Response]
|
|
251
|
+
|
|
252
|
+
# @!method put(url = nil, body = nil, headers = nil)
|
|
253
|
+
# Makes a PUT HTTP request with a body.
|
|
254
|
+
# @!scope class
|
|
168
255
|
#
|
|
169
|
-
#
|
|
256
|
+
# @param url [String] The optional String base URL to use as a prefix for
|
|
257
|
+
# 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.
|
|
170
260
|
#
|
|
171
|
-
#
|
|
261
|
+
# @example
|
|
262
|
+
# # TODO: Make it a PUT example
|
|
263
|
+
# conn.post '/items', data, content_type: 'application/json'
|
|
172
264
|
#
|
|
173
|
-
#
|
|
174
|
-
|
|
265
|
+
# # Simple ElasticSearch indexing sample.
|
|
266
|
+
# conn.post '/twitter/tweet' do |req|
|
|
267
|
+
# req.headers[:content_type] = 'application/json'
|
|
268
|
+
# req.params[:routing] = 'kimchy'
|
|
269
|
+
# req.body = JSON.generate(user: 'kimchy', ...)
|
|
270
|
+
# end
|
|
271
|
+
#
|
|
272
|
+
# @yield [Faraday::Request] for further request customizations
|
|
273
|
+
# @return [Faraday::Response]
|
|
274
|
+
|
|
275
|
+
# @!visibility private
|
|
276
|
+
METHODS_WITH_BODY.each do |method|
|
|
175
277
|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
|
176
278
|
def #{method}(url = nil, body = nil, headers = nil, &block)
|
|
177
279
|
run_request(:#{method}, url, body, headers, &block)
|
|
@@ -179,123 +281,126 @@ module Faraday
|
|
|
179
281
|
RUBY
|
|
180
282
|
end
|
|
181
283
|
|
|
182
|
-
#
|
|
284
|
+
# Sets up the Authorization header with these credentials, encoded
|
|
183
285
|
# with base64.
|
|
184
286
|
#
|
|
185
|
-
# login
|
|
186
|
-
# pass
|
|
287
|
+
# @param login [String] The authentication login.
|
|
288
|
+
# @param pass [String] The authentication password.
|
|
187
289
|
#
|
|
188
|
-
#
|
|
290
|
+
# @example
|
|
189
291
|
#
|
|
190
292
|
# conn.basic_auth 'Aladdin', 'open sesame'
|
|
191
293
|
# conn.headers['Authorization']
|
|
192
294
|
# # => "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="
|
|
193
295
|
#
|
|
194
|
-
#
|
|
296
|
+
# @return [void]
|
|
195
297
|
def basic_auth(login, pass)
|
|
196
298
|
set_authorization_header(:basic_auth, login, pass)
|
|
197
299
|
end
|
|
198
300
|
|
|
199
|
-
#
|
|
301
|
+
# Sets up the Authorization header with the given token.
|
|
200
302
|
#
|
|
201
|
-
# token
|
|
202
|
-
# options
|
|
303
|
+
# @param token [String]
|
|
304
|
+
# @param options [Hash] extra token options.
|
|
203
305
|
#
|
|
204
|
-
#
|
|
306
|
+
# @example
|
|
205
307
|
#
|
|
206
|
-
# conn.token_auth 'abcdef', :
|
|
308
|
+
# conn.token_auth 'abcdef', foo: 'bar'
|
|
207
309
|
# conn.headers['Authorization']
|
|
208
310
|
# # => "Token token=\"abcdef\",
|
|
209
311
|
# foo=\"bar\""
|
|
210
312
|
#
|
|
211
|
-
#
|
|
313
|
+
# @return [void]
|
|
212
314
|
def token_auth(token, options = nil)
|
|
213
315
|
set_authorization_header(:token_auth, token, options)
|
|
214
316
|
end
|
|
215
317
|
|
|
216
|
-
#
|
|
318
|
+
# Sets up a custom Authorization header.
|
|
217
319
|
#
|
|
218
|
-
# type
|
|
219
|
-
# token
|
|
220
|
-
# a Hash is encoded into comma
|
|
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.
|
|
221
323
|
#
|
|
222
|
-
#
|
|
324
|
+
# @example
|
|
223
325
|
#
|
|
224
326
|
# conn.authorization :Bearer, 'mF_9.B5f-4.1JqM'
|
|
225
327
|
# conn.headers['Authorization']
|
|
226
328
|
# # => "Bearer mF_9.B5f-4.1JqM"
|
|
227
329
|
#
|
|
228
|
-
# conn.authorization :Token, :
|
|
330
|
+
# conn.authorization :Token, token: 'abcdef', foo: 'bar'
|
|
229
331
|
# conn.headers['Authorization']
|
|
230
332
|
# # => "Token token=\"abcdef\",
|
|
231
333
|
# foo=\"bar\""
|
|
232
334
|
#
|
|
233
|
-
#
|
|
335
|
+
# @return [void]
|
|
234
336
|
def authorization(type, token)
|
|
235
337
|
set_authorization_header(:authorization, type, token)
|
|
236
338
|
end
|
|
237
339
|
|
|
238
|
-
#
|
|
239
|
-
# parallel-capable adapter.
|
|
340
|
+
# Check if the adapter is parallel-capable.
|
|
240
341
|
#
|
|
241
|
-
#
|
|
342
|
+
# @yield if the adapter isn't parallel-capable, or if no adapter is set yet.
|
|
242
343
|
#
|
|
243
|
-
#
|
|
344
|
+
# @return [Object, nil] a parallel manager or nil if yielded
|
|
345
|
+
# @api private
|
|
244
346
|
def default_parallel_manager
|
|
245
347
|
@default_parallel_manager ||= begin
|
|
246
|
-
|
|
247
|
-
h.klass.respond_to?(:supports_parallel?) and h.klass.supports_parallel?
|
|
248
|
-
end
|
|
348
|
+
adapter = @builder.adapter.klass if @builder.adapter
|
|
249
349
|
|
|
250
|
-
if
|
|
251
|
-
|
|
350
|
+
if support_parallel?(adapter)
|
|
351
|
+
adapter.setup_parallel_manager
|
|
252
352
|
elsif block_given?
|
|
253
353
|
yield
|
|
254
354
|
end
|
|
255
355
|
end
|
|
256
356
|
end
|
|
257
357
|
|
|
258
|
-
#
|
|
358
|
+
# Determine if this Faraday::Connection can make parallel requests.
|
|
259
359
|
#
|
|
260
|
-
#
|
|
360
|
+
# @return [Boolean]
|
|
261
361
|
def in_parallel?
|
|
262
362
|
!!@parallel_manager
|
|
263
363
|
end
|
|
264
364
|
|
|
265
|
-
#
|
|
365
|
+
# Sets up the parallel manager to make a set of requests.
|
|
266
366
|
#
|
|
267
|
-
# manager
|
|
367
|
+
# @param manager [Object] The parallel manager that this Connection's
|
|
368
|
+
# Adapter uses.
|
|
268
369
|
#
|
|
269
|
-
#
|
|
270
|
-
#
|
|
370
|
+
# @yield a block to execute multiple requests.
|
|
371
|
+
# @return [void]
|
|
271
372
|
def in_parallel(manager = nil)
|
|
272
|
-
@parallel_manager = manager || default_parallel_manager
|
|
273
|
-
warn
|
|
274
|
-
|
|
373
|
+
@parallel_manager = manager || default_parallel_manager do
|
|
374
|
+
warn 'Warning: `in_parallel` called but no parallel-capable adapter ' \
|
|
375
|
+
'on Faraday stack'
|
|
376
|
+
warn caller[2, 10].join("\n")
|
|
275
377
|
nil
|
|
276
|
-
|
|
378
|
+
end
|
|
277
379
|
yield
|
|
278
|
-
@parallel_manager
|
|
380
|
+
@parallel_manager&.run
|
|
279
381
|
ensure
|
|
280
382
|
@parallel_manager = nil
|
|
281
383
|
end
|
|
282
384
|
|
|
283
|
-
#
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
385
|
+
# Sets the Hash proxy options.
|
|
386
|
+
#
|
|
387
|
+
# @param new_value [Object]
|
|
388
|
+
def proxy=(new_value)
|
|
389
|
+
@manual_proxy = true
|
|
390
|
+
@proxy = new_value ? ProxyOptions.from(new_value) : nil
|
|
287
391
|
end
|
|
288
392
|
|
|
289
393
|
def_delegators :url_prefix, :scheme, :scheme=, :host, :host=, :port, :port=
|
|
290
394
|
def_delegator :url_prefix, :path, :path_prefix
|
|
291
395
|
|
|
292
|
-
#
|
|
293
|
-
# components in this connection.
|
|
396
|
+
# Parses the given URL with URI and stores the individual
|
|
397
|
+
# components in this connection. These components serve as defaults for
|
|
294
398
|
# requests made by this connection.
|
|
295
399
|
#
|
|
296
|
-
# url
|
|
400
|
+
# @param url [String, URI]
|
|
401
|
+
# @param encoder [Object]
|
|
297
402
|
#
|
|
298
|
-
#
|
|
403
|
+
# @example
|
|
299
404
|
#
|
|
300
405
|
# conn = Faraday::Connection.new { ... }
|
|
301
406
|
# conn.url_prefix = "https://sushi.com/api"
|
|
@@ -303,8 +408,6 @@ module Faraday
|
|
|
303
408
|
# conn.path_prefix # => "/api"
|
|
304
409
|
#
|
|
305
410
|
# conn.get("nigiri?page=2") # accesses https://sushi.com/api/nigiri
|
|
306
|
-
#
|
|
307
|
-
# Returns the parsed URI from teh given input..
|
|
308
411
|
def url_prefix=(url, encoder = nil)
|
|
309
412
|
uri = @url_prefix = Utils.URI(url)
|
|
310
413
|
self.path_prefix = uri.path
|
|
@@ -316,58 +419,70 @@ module Faraday
|
|
|
316
419
|
basic_auth user, password
|
|
317
420
|
uri.user = uri.password = nil
|
|
318
421
|
end
|
|
319
|
-
|
|
320
|
-
uri
|
|
321
422
|
end
|
|
322
423
|
|
|
323
|
-
#
|
|
424
|
+
# Sets the path prefix and ensures that it always has a leading
|
|
324
425
|
# slash.
|
|
325
426
|
#
|
|
326
|
-
# value
|
|
427
|
+
# @param value [String]
|
|
327
428
|
#
|
|
328
|
-
#
|
|
429
|
+
# @return [String] the new path prefix
|
|
329
430
|
def path_prefix=(value)
|
|
330
431
|
url_prefix.path = if value
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
432
|
+
value = '/' + value unless value[0, 1] == '/'
|
|
433
|
+
value
|
|
434
|
+
end
|
|
334
435
|
end
|
|
335
436
|
|
|
336
|
-
#
|
|
437
|
+
# Takes a relative url for a request and combines it with the defaults
|
|
337
438
|
# set on the connection instance.
|
|
338
439
|
#
|
|
440
|
+
# @param url [String]
|
|
441
|
+
# @param extra_params [Hash]
|
|
442
|
+
#
|
|
443
|
+
# @example
|
|
339
444
|
# conn = Faraday::Connection.new { ... }
|
|
340
445
|
# conn.url_prefix = "https://sushi.com/api?token=abc"
|
|
341
446
|
# conn.scheme # => https
|
|
342
447
|
# conn.path_prefix # => "/api"
|
|
343
448
|
#
|
|
344
|
-
# conn.build_url("nigiri?page=2")
|
|
345
|
-
#
|
|
449
|
+
# conn.build_url("nigiri?page=2")
|
|
450
|
+
# # => https://sushi.com/api/nigiri?token=abc&page=2
|
|
451
|
+
#
|
|
452
|
+
# conn.build_url("nigiri", page: 2)
|
|
453
|
+
# # => https://sushi.com/api/nigiri?token=abc&page=2
|
|
346
454
|
#
|
|
347
455
|
def build_url(url = nil, extra_params = nil)
|
|
348
456
|
uri = build_exclusive_url(url)
|
|
349
457
|
|
|
350
458
|
query_values = params.dup.merge_query(uri.query, options.params_encoder)
|
|
351
|
-
query_values.update
|
|
352
|
-
uri.query =
|
|
459
|
+
query_values.update(extra_params) if extra_params
|
|
460
|
+
uri.query =
|
|
461
|
+
if query_values.empty?
|
|
462
|
+
nil
|
|
463
|
+
else
|
|
464
|
+
query_values.to_query(options.params_encoder)
|
|
465
|
+
end
|
|
353
466
|
|
|
354
467
|
uri
|
|
355
468
|
end
|
|
356
469
|
|
|
357
470
|
# Builds and runs the Faraday::Request.
|
|
358
471
|
#
|
|
359
|
-
# method
|
|
360
|
-
# url
|
|
361
|
-
# body
|
|
362
|
-
#
|
|
472
|
+
# @param method [Symbol] HTTP method.
|
|
473
|
+
# @param url [String, URI] String or URI to access.
|
|
474
|
+
# @param body [Object] The request body that will eventually be converted to
|
|
475
|
+
# a string.
|
|
476
|
+
# @param headers [Hash] unencoded HTTP header key/value pairs.
|
|
363
477
|
#
|
|
364
|
-
#
|
|
478
|
+
# @return [Faraday::Response]
|
|
365
479
|
def run_request(method, url, body, headers)
|
|
366
|
-
|
|
480
|
+
unless METHODS.include?(method)
|
|
367
481
|
raise ArgumentError, "unknown http method: #{method}"
|
|
368
482
|
end
|
|
369
483
|
|
|
370
484
|
request = build_request(method) do |req|
|
|
485
|
+
req.options.proxy = proxy_for_request(url)
|
|
371
486
|
req.url(url) if url
|
|
372
487
|
req.headers.update(headers) if headers
|
|
373
488
|
req.body = body if body
|
|
@@ -379,59 +494,121 @@ module Faraday
|
|
|
379
494
|
|
|
380
495
|
# Creates and configures the request object.
|
|
381
496
|
#
|
|
382
|
-
#
|
|
497
|
+
# @param method [Symbol]
|
|
498
|
+
#
|
|
499
|
+
# @yield [Faraday::Request] if block given
|
|
500
|
+
# @return [Faraday::Request]
|
|
383
501
|
def build_request(method)
|
|
384
502
|
Request.create(method) do |req|
|
|
385
|
-
req.params =
|
|
386
|
-
req.headers =
|
|
387
|
-
req.options =
|
|
503
|
+
req.params = params.dup
|
|
504
|
+
req.headers = headers.dup
|
|
505
|
+
req.options = options.dup
|
|
388
506
|
yield(req) if block_given?
|
|
389
507
|
end
|
|
390
508
|
end
|
|
391
509
|
|
|
392
|
-
#
|
|
510
|
+
# Build an absolute URL based on url_prefix.
|
|
393
511
|
#
|
|
394
|
-
# url
|
|
395
|
-
# params
|
|
512
|
+
# @param url [String, URI]
|
|
513
|
+
# @param params [Faraday::Utils::ParamsHash] A Faraday::Utils::ParamsHash to
|
|
514
|
+
# replace the query values
|
|
396
515
|
# of the resulting url (default: nil).
|
|
397
516
|
#
|
|
398
|
-
#
|
|
517
|
+
# @return [URI]
|
|
399
518
|
def build_exclusive_url(url = nil, params = nil, params_encoder = nil)
|
|
400
|
-
url = nil if url.respond_to?(:empty?)
|
|
519
|
+
url = nil if url.respond_to?(:empty?) && url.empty?
|
|
401
520
|
base = url_prefix
|
|
402
|
-
if url
|
|
521
|
+
if url && base.path && base.path !~ %r{/$}
|
|
403
522
|
base = base.dup
|
|
404
|
-
base.path = base.path + '/'
|
|
523
|
+
base.path = base.path + '/' # ensure trailing slash
|
|
405
524
|
end
|
|
406
525
|
uri = url ? base + url : base
|
|
407
|
-
|
|
408
|
-
|
|
526
|
+
if params
|
|
527
|
+
uri.query = params.to_query(params_encoder || options.params_encoder)
|
|
528
|
+
end
|
|
529
|
+
# rubocop:disable Style/SafeNavigation
|
|
530
|
+
uri.query = nil if uri.query && uri.query.empty?
|
|
531
|
+
# rubocop:enable Style/SafeNavigation
|
|
409
532
|
uri
|
|
410
533
|
end
|
|
411
534
|
|
|
412
|
-
#
|
|
535
|
+
# Creates a duplicate of this Faraday::Connection.
|
|
413
536
|
#
|
|
414
|
-
#
|
|
537
|
+
# @api private
|
|
538
|
+
#
|
|
539
|
+
# @return [Faraday::Connection]
|
|
415
540
|
def dup
|
|
416
541
|
self.class.new(build_exclusive_url,
|
|
417
|
-
:
|
|
418
|
-
:
|
|
419
|
-
:
|
|
420
|
-
:
|
|
421
|
-
:
|
|
542
|
+
headers: headers.dup,
|
|
543
|
+
params: params.dup,
|
|
544
|
+
builder: builder.dup,
|
|
545
|
+
ssl: ssl.dup,
|
|
546
|
+
request: options.dup)
|
|
422
547
|
end
|
|
423
548
|
|
|
424
|
-
#
|
|
549
|
+
# Yields username and password extracted from a URI if they both exist.
|
|
550
|
+
#
|
|
551
|
+
# @param uri [URI]
|
|
552
|
+
# @yield [username, password] any username and password
|
|
553
|
+
# @yieldparam username [String] any username from URI
|
|
554
|
+
# @yieldparam password [String] any password from URI
|
|
555
|
+
# @return [void]
|
|
556
|
+
# @api private
|
|
425
557
|
def with_uri_credentials(uri)
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
558
|
+
return unless uri.user && uri.password
|
|
559
|
+
|
|
560
|
+
yield(Utils.unescape(uri.user), Utils.unescape(uri.password))
|
|
429
561
|
end
|
|
430
562
|
|
|
431
563
|
def set_authorization_header(header_type, *args)
|
|
432
|
-
header = Faraday::Request
|
|
433
|
-
|
|
564
|
+
header = Faraday::Request
|
|
565
|
+
.lookup_middleware(header_type)
|
|
566
|
+
.header(*args)
|
|
567
|
+
|
|
434
568
|
headers[Faraday::Request::Authorization::KEY] = header
|
|
435
569
|
end
|
|
570
|
+
|
|
571
|
+
def proxy_from_env(url)
|
|
572
|
+
return if Faraday.ignore_env_proxy
|
|
573
|
+
|
|
574
|
+
uri = nil
|
|
575
|
+
if URI.parse('').respond_to?(:find_proxy)
|
|
576
|
+
case url
|
|
577
|
+
when String
|
|
578
|
+
uri = Utils.URI(url)
|
|
579
|
+
uri = URI.parse("#{uri.scheme}://#{uri.hostname}").find_proxy
|
|
580
|
+
when URI
|
|
581
|
+
uri = url.find_proxy
|
|
582
|
+
when nil
|
|
583
|
+
uri = find_default_proxy
|
|
584
|
+
end
|
|
585
|
+
else
|
|
586
|
+
warn 'no_proxy is unsupported' if ENV['no_proxy'] || ENV['NO_PROXY']
|
|
587
|
+
uri = find_default_proxy
|
|
588
|
+
end
|
|
589
|
+
ProxyOptions.from(uri) if uri
|
|
590
|
+
end
|
|
591
|
+
|
|
592
|
+
def find_default_proxy
|
|
593
|
+
uri = ENV['http_proxy']
|
|
594
|
+
return unless uri && !uri.empty?
|
|
595
|
+
|
|
596
|
+
uri = 'http://' + uri if uri !~ /^http/i
|
|
597
|
+
uri
|
|
598
|
+
end
|
|
599
|
+
|
|
600
|
+
def proxy_for_request(url)
|
|
601
|
+
return proxy if @manual_proxy
|
|
602
|
+
|
|
603
|
+
if url && Utils.URI(url).absolute?
|
|
604
|
+
proxy_from_env(url)
|
|
605
|
+
else
|
|
606
|
+
proxy
|
|
607
|
+
end
|
|
608
|
+
end
|
|
609
|
+
|
|
610
|
+
def support_parallel?(adapter)
|
|
611
|
+
adapter&.respond_to?(:supports_parallel?) && adapter&.supports_parallel?
|
|
612
|
+
end
|
|
436
613
|
end
|
|
437
614
|
end
|