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