faraday 0.17.3 → 2.7.4

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