faraday 0.9.1 → 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (146) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +360 -0
  3. data/LICENSE.md +1 -1
  4. data/README.md +28 -195
  5. data/Rakefile +4 -68
  6. data/examples/client_spec.rb +97 -0
  7. data/examples/client_test.rb +118 -0
  8. data/lib/faraday/adapter/test.rb +158 -58
  9. data/lib/faraday/adapter/typhoeus.rb +7 -115
  10. data/lib/faraday/adapter.rb +79 -20
  11. data/lib/faraday/adapter_registry.rb +30 -0
  12. data/lib/faraday/autoload.rb +39 -36
  13. data/lib/faraday/connection.rb +378 -168
  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 +128 -29
  18. data/lib/faraday/file_part.rb +128 -0
  19. data/lib/faraday/logging/formatter.rb +105 -0
  20. data/lib/faraday/methods.rb +6 -0
  21. data/lib/faraday/middleware.rb +19 -25
  22. data/lib/faraday/middleware_registry.rb +129 -0
  23. data/lib/faraday/options/connection_options.rb +22 -0
  24. data/lib/faraday/options/env.rb +181 -0
  25. data/lib/faraday/options/proxy_options.rb +32 -0
  26. data/lib/faraday/options/request_options.rb +22 -0
  27. data/lib/faraday/options/ssl_options.rb +59 -0
  28. data/lib/faraday/options.rb +61 -193
  29. data/lib/faraday/param_part.rb +53 -0
  30. data/lib/faraday/parameters.rb +4 -180
  31. data/lib/faraday/rack_builder.rb +84 -47
  32. data/lib/faraday/request/authorization.rb +51 -31
  33. data/lib/faraday/request/basic_authentication.rb +14 -7
  34. data/lib/faraday/request/instrumentation.rb +45 -27
  35. data/lib/faraday/request/multipart.rb +88 -45
  36. data/lib/faraday/request/retry.rb +212 -121
  37. data/lib/faraday/request/token_authentication.rb +15 -10
  38. data/lib/faraday/request/url_encoded.rb +43 -23
  39. data/lib/faraday/request.rb +96 -32
  40. data/lib/faraday/response/logger.rb +22 -48
  41. data/lib/faraday/response/raise_error.rb +49 -14
  42. data/lib/faraday/response.rb +33 -25
  43. data/lib/faraday/utils/headers.rb +139 -0
  44. data/lib/faraday/utils/params_hash.rb +61 -0
  45. data/lib/faraday/utils.rb +38 -218
  46. data/lib/faraday/version.rb +5 -0
  47. data/lib/faraday.rb +130 -213
  48. data/spec/external_adapters/faraday_specs_setup.rb +14 -0
  49. data/spec/faraday/adapter/em_http_spec.rb +49 -0
  50. data/spec/faraday/adapter/em_synchrony_spec.rb +18 -0
  51. data/spec/faraday/adapter/excon_spec.rb +49 -0
  52. data/spec/faraday/adapter/httpclient_spec.rb +73 -0
  53. data/spec/faraday/adapter/net_http_spec.rb +64 -0
  54. data/spec/faraday/adapter/patron_spec.rb +18 -0
  55. data/spec/faraday/adapter/rack_spec.rb +8 -0
  56. data/spec/faraday/adapter/test_spec.rb +377 -0
  57. data/spec/faraday/adapter/typhoeus_spec.rb +7 -0
  58. data/spec/faraday/adapter_registry_spec.rb +28 -0
  59. data/spec/faraday/adapter_spec.rb +55 -0
  60. data/spec/faraday/composite_read_io_spec.rb +80 -0
  61. data/spec/faraday/connection_spec.rb +736 -0
  62. data/spec/faraday/error_spec.rb +60 -0
  63. data/spec/faraday/middleware_spec.rb +52 -0
  64. data/spec/faraday/options/env_spec.rb +70 -0
  65. data/spec/faraday/options/options_spec.rb +297 -0
  66. data/spec/faraday/options/proxy_options_spec.rb +44 -0
  67. data/spec/faraday/options/request_options_spec.rb +19 -0
  68. data/spec/faraday/params_encoders/flat_spec.rb +42 -0
  69. data/spec/faraday/params_encoders/nested_spec.rb +142 -0
  70. data/spec/faraday/rack_builder_spec.rb +345 -0
  71. data/spec/faraday/request/authorization_spec.rb +96 -0
  72. data/spec/faraday/request/instrumentation_spec.rb +76 -0
  73. data/spec/faraday/request/multipart_spec.rb +302 -0
  74. data/spec/faraday/request/retry_spec.rb +242 -0
  75. data/spec/faraday/request/url_encoded_spec.rb +83 -0
  76. data/spec/faraday/request_spec.rb +120 -0
  77. data/spec/faraday/response/logger_spec.rb +220 -0
  78. data/spec/faraday/response/middleware_spec.rb +68 -0
  79. data/spec/faraday/response/raise_error_spec.rb +169 -0
  80. data/spec/faraday/response_spec.rb +75 -0
  81. data/spec/faraday/utils/headers_spec.rb +82 -0
  82. data/spec/faraday/utils_spec.rb +56 -0
  83. data/spec/faraday_spec.rb +37 -0
  84. data/spec/spec_helper.rb +132 -0
  85. data/spec/support/disabling_stub.rb +14 -0
  86. data/spec/support/fake_safe_buffer.rb +15 -0
  87. data/spec/support/helper_methods.rb +133 -0
  88. data/spec/support/shared_examples/adapter.rb +105 -0
  89. data/spec/support/shared_examples/params_encoder.rb +18 -0
  90. data/spec/support/shared_examples/request_method.rb +262 -0
  91. data/spec/support/streaming_response_checker.rb +35 -0
  92. data/spec/support/webmock_rack_app.rb +68 -0
  93. metadata +199 -98
  94. data/.document +0 -6
  95. data/CONTRIBUTING.md +0 -36
  96. data/Gemfile +0 -25
  97. data/faraday.gemspec +0 -34
  98. data/lib/faraday/adapter/em_http.rb +0 -237
  99. data/lib/faraday/adapter/em_http_ssl_patch.rb +0 -56
  100. data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +0 -66
  101. data/lib/faraday/adapter/em_synchrony.rb +0 -92
  102. data/lib/faraday/adapter/excon.rb +0 -80
  103. data/lib/faraday/adapter/httpclient.rb +0 -106
  104. data/lib/faraday/adapter/net_http.rb +0 -130
  105. data/lib/faraday/adapter/net_http_persistent.rb +0 -48
  106. data/lib/faraday/adapter/patron.rb +0 -72
  107. data/lib/faraday/adapter/rack.rb +0 -58
  108. data/lib/faraday/upload_io.rb +0 -67
  109. data/script/cached-bundle +0 -46
  110. data/script/console +0 -7
  111. data/script/generate_certs +0 -42
  112. data/script/package +0 -7
  113. data/script/proxy-server +0 -42
  114. data/script/release +0 -17
  115. data/script/s3-put +0 -71
  116. data/script/server +0 -36
  117. data/script/test +0 -172
  118. data/test/adapters/default_test.rb +0 -14
  119. data/test/adapters/em_http_test.rb +0 -20
  120. data/test/adapters/em_synchrony_test.rb +0 -20
  121. data/test/adapters/excon_test.rb +0 -20
  122. data/test/adapters/httpclient_test.rb +0 -21
  123. data/test/adapters/integration.rb +0 -254
  124. data/test/adapters/logger_test.rb +0 -82
  125. data/test/adapters/net_http_persistent_test.rb +0 -20
  126. data/test/adapters/net_http_test.rb +0 -14
  127. data/test/adapters/patron_test.rb +0 -20
  128. data/test/adapters/rack_test.rb +0 -31
  129. data/test/adapters/test_middleware_test.rb +0 -114
  130. data/test/adapters/typhoeus_test.rb +0 -28
  131. data/test/authentication_middleware_test.rb +0 -65
  132. data/test/composite_read_io_test.rb +0 -111
  133. data/test/connection_test.rb +0 -522
  134. data/test/env_test.rb +0 -218
  135. data/test/helper.rb +0 -81
  136. data/test/live_server.rb +0 -67
  137. data/test/middleware/instrumentation_test.rb +0 -88
  138. data/test/middleware/retry_test.rb +0 -177
  139. data/test/middleware_stack_test.rb +0 -173
  140. data/test/multibyte.txt +0 -1
  141. data/test/options_test.rb +0 -252
  142. data/test/parameters_test.rb +0 -64
  143. data/test/request_middleware_test.rb +0 -142
  144. data/test/response_middleware_test.rb +0 -72
  145. data/test/strawberry.rb +0 -2
  146. 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,58 @@ 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: Initializes a new Faraday::Connection.
42
+ # @return [Hash] proxy options.
43
+ attr_reader :proxy
44
+
45
+ # Initializes a new Faraday::Connection.
43
46
  #
44
- # 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
45
48
  # 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)
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
57
63
  def initialize(url = nil, options = nil)
58
- if url.is_a?(Hash)
59
- options = ConnectionOptions.from(url)
64
+ options = ConnectionOptions.from(options)
65
+
66
+ if url.is_a?(Hash) || url.is_a?(ConnectionOptions)
67
+ options = options.merge(url)
60
68
  url = options.url
61
- else
62
- options = ConnectionOptions.from(options)
63
69
  end
64
70
 
65
71
  @parallel_manager = nil
@@ -68,10 +74,11 @@ module Faraday
68
74
  @options = options.request
69
75
  @ssl = options.ssl
70
76
  @default_parallel_manager = options.parallel_manager
77
+ @manual_proxy = nil
71
78
 
72
79
  @builder = options.builder || begin
73
80
  # pass an empty block to Builder so it doesn't assume default middleware
74
- options.new_builder(block_given? ? Proc.new { |b| } : nil)
81
+ options.new_builder(block_given? ? proc { |b| } : nil)
75
82
  end
76
83
 
77
84
  self.url_prefix = url || 'http:/'
@@ -79,26 +86,31 @@ module Faraday
79
86
  @params.update(options.params) if options.params
80
87
  @headers.update(options.headers) if options.headers
81
88
 
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
- })
89
+ initialize_proxy(url, options)
90
90
 
91
91
  yield(self) if block_given?
92
92
 
93
- @headers[:user_agent] ||= "Faraday v#{VERSION}"
93
+ @headers[:user_agent] ||= USER_AGENT
94
94
  end
95
95
 
96
- # 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]
97
108
  def params=(hash)
98
109
  @params.replace hash
99
110
  end
100
111
 
101
- # 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]
102
114
  def headers=(hash)
103
115
  @headers.replace hash
104
116
  end
@@ -107,71 +119,163 @@ module Faraday
107
119
 
108
120
  def_delegators :builder, :build, :use, :request, :response, :adapter, :app
109
121
 
110
- # Public: Makes an HTTP request without a body.
111
- #
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.
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
116
132
  #
117
- # 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.
118
137
  #
119
- # conn.get '/items', {:page => 1}, :accept => 'application/json'
120
- # conn.head '/items/1'
138
+ # @example
139
+ # conn.get '/items', { page: 1 }, :accept => 'application/json'
121
140
  #
122
141
  # # ElasticSearch example sending a body with GET.
123
142
  # conn.get '/twitter/tweet/_search' do |req|
124
143
  # req.headers[:content_type] = 'application/json'
125
144
  # req.params[:routing] = 'kimchy'
126
- # req.body = JSON.generate(:query => {...})
145
+ # req.body = JSON.generate(query: {...})
127
146
  # end
128
147
  #
129
- # Yields a Faraday::Response for further request customizations.
130
- # 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
131
169
  #
132
- # 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.
133
174
  #
134
- # <verb>(url = nil, params = nil, headers = nil)
175
+ # @example
176
+ # conn.delete '/items/1'
135
177
  #
136
- # verb - An HTTP verb: get, head, or delete.
137
- %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|
138
198
  class_eval <<-RUBY, __FILE__, __LINE__ + 1
139
199
  def #{method}(url = nil, params = nil, headers = nil)
140
- run_request(:#{method}, url, nil, headers) { |request|
200
+ run_request(:#{method}, url, nil, headers) do |request|
141
201
  request.params.update(params) if params
142
- yield(request) if block_given?
143
- }
202
+ yield request if block_given?
203
+ end
144
204
  end
145
205
  RUBY
146
206
  end
147
207
 
148
- # Public: Makes an HTTP request with a body.
208
+ # @overload options()
209
+ # Returns current Connection options.
149
210
  #
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.
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.
216
+ #
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
154
235
  #
155
- # 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.
156
240
  #
157
- # conn.post '/items', data, :content_type => 'application/json'
241
+ # @example
242
+ # conn.post '/items', data, content_type: 'application/json'
158
243
  #
159
244
  # # Simple ElasticSearch indexing sample.
160
245
  # conn.post '/twitter/tweet' do |req|
161
246
  # req.headers[:content_type] = 'application/json'
162
247
  # req.params[:routing] = 'kimchy'
163
- # req.body = JSON.generate(:user => 'kimchy', ...)
248
+ # req.body = JSON.generate(user: 'kimchy', ...)
164
249
  # end
165
250
  #
166
- # Yields a Faraday::Response for further request customizations.
167
- # 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
168
257
  #
169
- # Signature
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.
170
262
  #
171
- # <verb>(url = nil, body = nil, headers = nil)
263
+ # @example
264
+ # # TODO: Make it a PUT example
265
+ # conn.post '/items', data, content_type: 'application/json'
266
+ #
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
172
273
  #
173
- # verb - An HTTP verb: post, put, or patch.
174
- %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|
175
279
  class_eval <<-RUBY, __FILE__, __LINE__ + 1
176
280
  def #{method}(url = nil, body = nil, headers = nil, &block)
177
281
  run_request(:#{method}, url, body, headers, &block)
@@ -179,123 +283,141 @@ module Faraday
179
283
  RUBY
180
284
  end
181
285
 
182
- # Public: Sets up the Authorization header with these credentials, encoded
286
+ # Sets up the Authorization header with these credentials, encoded
183
287
  # with base64.
184
288
  #
185
- # login - The authentication login.
186
- # pass - The authentication password.
289
+ # @param login [String] The authentication login.
290
+ # @param pass [String] The authentication password.
187
291
  #
188
- # Examples
292
+ # @example
189
293
  #
190
294
  # conn.basic_auth 'Aladdin', 'open sesame'
191
295
  # conn.headers['Authorization']
192
296
  # # => "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="
193
297
  #
194
- # Returns nothing.
298
+ # @return [void]
195
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
196
305
  set_authorization_header(:basic_auth, login, pass)
197
306
  end
198
307
 
199
- # Public: Sets up the Authorization header with the given token.
308
+ # Sets up the Authorization header with the given token.
200
309
  #
201
- # token - The String token.
202
- # options - Optional Hash of extra token options.
310
+ # @param token [String]
311
+ # @param options [Hash] extra token options.
203
312
  #
204
- # Examples
313
+ # @example
205
314
  #
206
- # conn.token_auth 'abcdef', :foo => 'bar'
315
+ # conn.token_auth 'abcdef', foo: 'bar'
207
316
  # conn.headers['Authorization']
208
317
  # # => "Token token=\"abcdef\",
209
318
  # foo=\"bar\""
210
319
  #
211
- # Returns nothing.
320
+ # @return [void]
212
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
213
327
  set_authorization_header(:token_auth, token, options)
214
328
  end
215
329
 
216
- # Public: Sets up a custom Authorization header.
330
+ # Sets up a custom Authorization header.
217
331
  #
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.
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.
221
335
  #
222
- # Examples
336
+ # @example
223
337
  #
224
338
  # conn.authorization :Bearer, 'mF_9.B5f-4.1JqM'
225
339
  # conn.headers['Authorization']
226
340
  # # => "Bearer mF_9.B5f-4.1JqM"
227
341
  #
228
- # conn.authorization :Token, :token => 'abcdef', :foo => 'bar'
342
+ # conn.authorization :Token, token: 'abcdef', foo: 'bar'
229
343
  # conn.headers['Authorization']
230
344
  # # => "Token token=\"abcdef\",
231
345
  # foo=\"bar\""
232
346
  #
233
- # Returns nothing.
347
+ # @return [void]
234
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
235
354
  set_authorization_header(:authorization, type, token)
236
355
  end
237
356
 
238
- # Internal: Traverse the middleware stack in search of a
239
- # parallel-capable adapter.
357
+ # Check if the adapter is parallel-capable.
240
358
  #
241
- # Yields in case of not found.
359
+ # @yield if the adapter isn't parallel-capable, or if no adapter is set yet.
242
360
  #
243
- # Returns a parallel manager or nil if not found.
361
+ # @return [Object, nil] a parallel manager or nil if yielded
362
+ # @api private
244
363
  def default_parallel_manager
245
364
  @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
365
+ adapter = @builder.adapter.klass if @builder.adapter
249
366
 
250
- if handler
251
- handler.klass.setup_parallel_manager
367
+ if support_parallel?(adapter)
368
+ adapter.setup_parallel_manager
252
369
  elsif block_given?
253
370
  yield
254
371
  end
255
372
  end
256
373
  end
257
374
 
258
- # Public: Determine if this Faraday::Connection can make parallel requests.
375
+ # Determine if this Faraday::Connection can make parallel requests.
259
376
  #
260
- # Returns true or false.
377
+ # @return [Boolean]
261
378
  def in_parallel?
262
379
  !!@parallel_manager
263
380
  end
264
381
 
265
- # Public: Sets up the parallel manager to make a set of requests.
382
+ # Sets up the parallel manager to make a set of requests.
266
383
  #
267
- # manager - The parallel manager that this Connection's Adapter uses.
384
+ # @param manager [Object] The parallel manager that this Connection's
385
+ # Adapter uses.
268
386
  #
269
- # Yields a block to execute multiple requests.
270
- # Returns nothing.
387
+ # @yield a block to execute multiple requests.
388
+ # @return [void]
271
389
  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")
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")
275
394
  nil
276
- }
395
+ end
277
396
  yield
278
- @parallel_manager && @parallel_manager.run
397
+ @parallel_manager&.run
279
398
  ensure
280
399
  @parallel_manager = nil
281
400
  end
282
401
 
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)
402
+ # Sets the Hash proxy options.
403
+ #
404
+ # @param new_value [Object]
405
+ def proxy=(new_value)
406
+ @manual_proxy = true
407
+ @proxy = new_value ? ProxyOptions.from(new_value) : nil
287
408
  end
288
409
 
289
410
  def_delegators :url_prefix, :scheme, :scheme=, :host, :host=, :port, :port=
290
411
  def_delegator :url_prefix, :path, :path_prefix
291
412
 
292
- # Public: Parses the giving url with URI and stores the individual
293
- # 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
294
415
  # requests made by this connection.
295
416
  #
296
- # url - A String or URI.
417
+ # @param url [String, URI]
418
+ # @param encoder [Object]
297
419
  #
298
- # Examples
420
+ # @example
299
421
  #
300
422
  # conn = Faraday::Connection.new { ... }
301
423
  # conn.url_prefix = "https://sushi.com/api"
@@ -303,8 +425,6 @@ module Faraday
303
425
  # conn.path_prefix # => "/api"
304
426
  #
305
427
  # conn.get("nigiri?page=2") # accesses https://sushi.com/api/nigiri
306
- #
307
- # Returns the parsed URI from teh given input..
308
428
  def url_prefix=(url, encoder = nil)
309
429
  uri = @url_prefix = Utils.URI(url)
310
430
  self.path_prefix = uri.path
@@ -313,61 +433,80 @@ module Faraday
313
433
  uri.query = nil
314
434
 
315
435
  with_uri_credentials(uri) do |user, password|
316
- basic_auth user, password
436
+ set_basic_auth(user, password)
317
437
  uri.user = uri.password = nil
318
438
  end
319
439
 
320
- 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
321
446
  end
322
447
 
323
- # 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
324
449
  # slash.
325
450
  #
326
- # value - A String.
451
+ # @param value [String]
327
452
  #
328
- # Returns the new String path prefix.
453
+ # @return [String] the new path prefix
329
454
  def path_prefix=(value)
330
455
  url_prefix.path = if value
331
- value = '/' + value unless value[0,1] == '/'
332
- value
333
- end
456
+ value = "/#{value}" unless value[0, 1] == '/'
457
+ value
458
+ end
334
459
  end
335
460
 
336
- # 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
337
462
  # set on the connection instance.
338
463
  #
464
+ # @param url [String]
465
+ # @param extra_params [Hash]
466
+ #
467
+ # @example
339
468
  # conn = Faraday::Connection.new { ... }
340
469
  # conn.url_prefix = "https://sushi.com/api?token=abc"
341
470
  # conn.scheme # => https
342
471
  # conn.path_prefix # => "/api"
343
472
  #
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
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
346
478
  #
347
479
  def build_url(url = nil, extra_params = nil)
348
480
  uri = build_exclusive_url(url)
349
481
 
350
482
  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)
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
353
490
 
354
491
  uri
355
492
  end
356
493
 
357
494
  # Builds and runs the Faraday::Request.
358
495
  #
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.
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.
363
501
  #
364
- # Returns a Faraday::Response.
502
+ # @return [Faraday::Response]
365
503
  def run_request(method, url, body, headers)
366
- if !METHODS.include?(method)
504
+ unless METHODS.include?(method)
367
505
  raise ArgumentError, "unknown http method: #{method}"
368
506
  end
369
507
 
370
508
  request = build_request(method) do |req|
509
+ req.options.proxy = proxy_for_request(url)
371
510
  req.url(url) if url
372
511
  req.headers.update(headers) if headers
373
512
  req.body = body if body
@@ -379,54 +518,125 @@ module Faraday
379
518
 
380
519
  # Creates and configures the request object.
381
520
  #
382
- # Returns the new Request.
521
+ # @param method [Symbol]
522
+ #
523
+ # @yield [Faraday::Request] if block given
524
+ # @return [Faraday::Request]
383
525
  def build_request(method)
384
526
  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)
527
+ req.params = params.dup
528
+ req.headers = headers.dup
529
+ req.options = options.dup
388
530
  yield(req) if block_given?
389
531
  end
390
532
  end
391
533
 
392
- # Internal: Build an absolute URL based on url_prefix.
534
+ # Build an absolute URL based on url_prefix.
393
535
  #
394
- # url - A String or URI-like object
395
- # 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
396
539
  # of the resulting url (default: nil).
397
540
  #
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?
401
- base = url_prefix
402
- if url and base.path and base.path !~ /\/$/
403
- base = base.dup
404
- base.path = base.path + '/' # ensure trailing slash
541
+ # @return [URI]
542
+ def build_exclusive_url(url = nil, params = nil, params_encoder = nil)
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
405
547
  end
548
+ url = url && URI.parse(url.to_s).opaque ? url.to_s.gsub(':', '%3A') : url
406
549
  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?
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
409
556
  uri
410
557
  end
411
558
 
412
- # Internal: Creates a duplicate of this Faraday::Connection.
559
+ # Creates a duplicate of this Faraday::Connection.
560
+ #
561
+ # @api private
413
562
  #
414
- # Returns a Faraday::Connection.
563
+ # @return [Faraday::Connection]
415
564
  def dup
416
- self.class.new(build_exclusive_url, :headers => headers.dup, :params => params.dup, :builder => builder.dup, :ssl => ssl.dup)
565
+ self.class.new(build_exclusive_url,
566
+ headers: headers.dup,
567
+ params: params.dup,
568
+ builder: builder.dup,
569
+ ssl: ssl.dup,
570
+ request: options.dup)
417
571
  end
418
572
 
419
- # 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
420
581
  def with_uri_credentials(uri)
421
- if uri.user and uri.password
422
- yield(Utils.unescape(uri.user), Utils.unescape(uri.password))
423
- end
582
+ return unless uri.user && uri.password
583
+
584
+ yield(Utils.unescape(uri.user), Utils.unescape(uri.password))
424
585
  end
425
586
 
426
587
  def set_authorization_header(header_type, *args)
427
- header = Faraday::Request.lookup_middleware(header_type).
428
- header(*args)
588
+ header = Faraday::Request
589
+ .lookup_middleware(header_type)
590
+ .header(*args)
591
+
429
592
  headers[Faraday::Request::Authorization::KEY] = header
430
593
  end
594
+
595
+ def proxy_from_env(url)
596
+ return if Faraday.ignore_env_proxy
597
+
598
+ uri = nil
599
+ if URI.parse('').respond_to?(:find_proxy)
600
+ case url
601
+ when String
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
612
+ end
613
+ else
614
+ warn 'no_proxy is unsupported' if ENV['no_proxy'] || ENV['NO_PROXY']
615
+ uri = find_default_proxy
616
+ end
617
+ ProxyOptions.from(uri) if uri
618
+ end
619
+
620
+ def find_default_proxy
621
+ uri = ENV['http_proxy']
622
+ return unless uri && !uri.empty?
623
+
624
+ uri = "http://#{uri}" unless uri.match?(/^http/i)
625
+ uri
626
+ end
627
+
628
+ def proxy_for_request(url)
629
+ return proxy if @manual_proxy
630
+
631
+ if url && Utils.URI(url).absolute?
632
+ proxy_from_env(url)
633
+ else
634
+ proxy
635
+ end
636
+ end
637
+
638
+ def support_parallel?(adapter)
639
+ adapter&.respond_to?(:supports_parallel?) && adapter&.supports_parallel?
640
+ end
431
641
  end
432
642
  end