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