faraday 0.15.4 → 1.6.0

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