faraday 0.13.0 → 2.0.0

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