faraday 0.9.1 → 1.8.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 (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