faraday 0.9.1 → 2.5.2

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