faraday 0.16.0 → 0.17.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 (54) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.md +1 -1
  3. data/README.md +347 -18
  4. data/lib/faraday/adapter/em_http.rb +99 -142
  5. data/lib/faraday/adapter/em_http_ssl_patch.rb +17 -23
  6. data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +15 -18
  7. data/lib/faraday/adapter/em_synchrony.rb +60 -104
  8. data/lib/faraday/adapter/excon.rb +55 -100
  9. data/lib/faraday/adapter/httpclient.rb +39 -61
  10. data/lib/faraday/adapter/net_http.rb +51 -104
  11. data/lib/faraday/adapter/net_http_persistent.rb +27 -48
  12. data/lib/faraday/adapter/patron.rb +35 -54
  13. data/lib/faraday/adapter/rack.rb +12 -28
  14. data/lib/faraday/adapter/test.rb +53 -86
  15. data/lib/faraday/adapter/typhoeus.rb +1 -4
  16. data/lib/faraday/adapter.rb +22 -36
  17. data/lib/faraday/autoload.rb +36 -47
  18. data/lib/faraday/connection.rb +179 -321
  19. data/lib/faraday/error.rb +33 -67
  20. data/lib/faraday/middleware.rb +28 -4
  21. data/lib/faraday/options.rb +186 -35
  22. data/lib/faraday/parameters.rb +197 -4
  23. data/lib/faraday/rack_builder.rb +56 -67
  24. data/lib/faraday/request/authorization.rb +30 -42
  25. data/lib/faraday/request/basic_authentication.rb +7 -14
  26. data/lib/faraday/request/instrumentation.rb +27 -45
  27. data/lib/faraday/request/multipart.rb +48 -79
  28. data/lib/faraday/request/retry.rb +170 -197
  29. data/lib/faraday/request/token_authentication.rb +10 -15
  30. data/lib/faraday/request/url_encoded.rb +23 -41
  31. data/lib/faraday/request.rb +36 -68
  32. data/lib/faraday/response/logger.rb +69 -22
  33. data/lib/faraday/response/raise_error.rb +14 -36
  34. data/lib/faraday/response.rb +16 -23
  35. data/lib/faraday/upload_io.rb +67 -0
  36. data/lib/faraday/utils.rb +245 -28
  37. data/lib/faraday.rb +175 -93
  38. metadata +5 -22
  39. data/lib/faraday/adapter_registry.rb +0 -28
  40. data/lib/faraday/dependency_loader.rb +0 -37
  41. data/lib/faraday/encoders/flat_params_encoder.rb +0 -94
  42. data/lib/faraday/encoders/nested_params_encoder.rb +0 -171
  43. data/lib/faraday/file_part.rb +0 -128
  44. data/lib/faraday/logging/formatter.rb +0 -92
  45. data/lib/faraday/middleware_registry.rb +0 -129
  46. data/lib/faraday/options/connection_options.rb +0 -22
  47. data/lib/faraday/options/env.rb +0 -181
  48. data/lib/faraday/options/proxy_options.rb +0 -28
  49. data/lib/faraday/options/request_options.rb +0 -21
  50. data/lib/faraday/options/ssl_options.rb +0 -59
  51. data/lib/faraday/param_part.rb +0 -53
  52. data/lib/faraday/utils/headers.rb +0 -139
  53. data/lib/faraday/utils/params_hash.rb +0 -61
  54. data/spec/external_adapters/faraday_specs_setup.rb +0 -14
@@ -1,15 +1,10 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Faraday
4
2
  class Adapter
5
- # EventMachine adapter. This adapter is useful for either asynchronous
6
- # requests when in an EM reactor loop, or for making parallel requests in
3
+ # EventMachine adapter is useful for either asynchronous requests
4
+ # when in EM reactor loop or for making parallel requests in
7
5
  # synchronous code.
8
6
  class EMHttp < Faraday::Adapter
9
- # Options is a module containing helpers to convert the Faraday env object
10
- # into options hashes for EMHTTP method calls.
11
7
  module Options
12
- # @return [Hash]
13
8
  def connection_config(env)
14
9
  options = {}
15
10
  configure_proxy(options, env)
@@ -21,10 +16,10 @@ module Faraday
21
16
 
22
17
  def request_config(env)
23
18
  options = {
24
- body: read_body(env),
25
- head: env[:request_headers]
26
- # keepalive: true,
27
- # file: 'path/to/file', # stream data off disk
19
+ :body => read_body(env),
20
+ :head => env[:request_headers],
21
+ # :keepalive => true,
22
+ # :file => 'path/to/file', # stream data off disk
28
23
  }
29
24
  configure_compression(options, env)
30
25
  options
@@ -35,53 +30,44 @@ module Faraday
35
30
  body.respond_to?(:read) ? body.read : body
36
31
  end
37
32
 
38
- # Reads out proxy settings from env into options
39
33
  def configure_proxy(options, env)
40
- proxy = request_options(env)[:proxy]
41
- return unless proxy
42
-
43
- options[:proxy] = {
44
- host: proxy[:uri].host,
45
- port: proxy[:uri].port,
46
- authorization: [proxy[:user], proxy[:password]]
47
- }
34
+ if proxy = request_options(env)[:proxy]
35
+ options[:proxy] = {
36
+ :host => proxy[:uri].host,
37
+ :port => proxy[:uri].port,
38
+ :authorization => [proxy[:user], proxy[:password]]
39
+ }
40
+ end
48
41
  end
49
42
 
50
- # Reads out host and port settings from env into options
51
43
  def configure_socket(options, env)
52
- bind = request_options(env)[:bind]
53
- return unless bind
54
-
55
- options[:bind] = {
56
- host: bind[:host],
57
- port: bind[:port]
58
- }
44
+ if bind = request_options(env)[:bind]
45
+ options[:bind] = {
46
+ :host => bind[:host],
47
+ :port => bind[:port]
48
+ }
49
+ end
59
50
  end
60
51
 
61
- # Reads out SSL certificate settings from env into options
62
52
  def configure_ssl(options, env)
63
- return unless env[:url].scheme == 'https' && env[:ssl]
64
-
65
- options[:ssl] = {
66
- cert_chain_file: env[:ssl][:ca_file],
67
- verify_peer: env[:ssl].fetch(:verify, true)
68
- }
53
+ if env[:url].scheme == 'https' && env[:ssl]
54
+ options[:ssl] = {
55
+ :cert_chain_file => env[:ssl][:ca_file],
56
+ :verify_peer => env[:ssl].fetch(:verify, true)
57
+ }
58
+ end
69
59
  end
70
60
 
71
- # Reads out timeout settings from env into options
72
61
  def configure_timeout(options, env)
73
- timeout, open_timeout = request_options(env)
74
- .values_at(:timeout, :open_timeout)
62
+ timeout, open_timeout = request_options(env).values_at(:timeout, :open_timeout)
75
63
  options[:connect_timeout] = options[:inactivity_timeout] = timeout
76
64
  options[:connect_timeout] = open_timeout if open_timeout
77
65
  end
78
66
 
79
- # Reads out compression header settings from env into options
80
67
  def configure_compression(options, env)
81
- return unless (env[:method] == :get) &&
82
- !options[:head].key?('accept-encoding')
83
-
84
- options[:head]['accept-encoding'] = 'gzip, compressed'
68
+ if env[:method] == :get and not options[:head].key? 'accept-encoding'
69
+ options[:head]['accept-encoding'] = 'gzip, compressed'
70
+ end
85
71
  end
86
72
 
87
73
  def request_options(env)
@@ -95,8 +81,7 @@ module Faraday
95
81
 
96
82
  self.supports_parallel = true
97
83
 
98
- # @return [Manager]
99
- def self.setup_parallel_manager(_options = nil)
84
+ def self.setup_parallel_manager(options = nil)
100
85
  Manager.new
101
86
  end
102
87
 
@@ -109,113 +94,95 @@ module Faraday
109
94
  def perform_request(env)
110
95
  if parallel?(env)
111
96
  manager = env[:parallel_manager]
112
- manager.add do
113
- perform_single_request(env)
114
- .callback { env[:response].finish(env) }
115
- end
116
- elsif EventMachine.reactor_running?
117
- # EM is running: instruct upstream that this is an async request
118
- env[:parallel_manager] = true
119
- perform_single_request(env)
120
- .callback { env[:response].finish(env) }
121
- .errback do
122
- # TODO: no way to communicate the error in async mode
123
- raise NotImplementedError
124
- end
97
+ manager.add {
98
+ perform_single_request(env).
99
+ callback { env[:response].finish(env) }
100
+ }
125
101
  else
126
- error = nil
127
- # start EM, block until request is completed
128
- EventMachine.run do
129
- perform_single_request(env)
130
- .callback { EventMachine.stop }
131
- .errback do |client|
132
- error = error_message(client)
133
- EventMachine.stop
134
- end
102
+ unless EventMachine.reactor_running?
103
+ error = nil
104
+ # start EM, block until request is completed
105
+ EventMachine.run do
106
+ perform_single_request(env).
107
+ callback { EventMachine.stop }.
108
+ errback { |client|
109
+ error = error_message(client)
110
+ EventMachine.stop
111
+ }
112
+ end
113
+ raise_error(error) if error
114
+ else
115
+ # EM is running: instruct upstream that this is an async request
116
+ env[:parallel_manager] = true
117
+ perform_single_request(env).
118
+ callback { env[:response].finish(env) }.
119
+ errback {
120
+ # TODO: no way to communicate the error in async mode
121
+ raise NotImplementedError
122
+ }
135
123
  end
136
- raise_error(error) if error
137
124
  end
138
- rescue EventMachine::Connectify::CONNECTError => e
139
- if e.message.include?('Proxy Authentication Required')
140
- raise Faraday::ConnectionFailed,
141
- %(407 "Proxy Authentication Required ")
125
+ rescue EventMachine::Connectify::CONNECTError => err
126
+ if err.message.include?("Proxy Authentication Required")
127
+ raise Error::ConnectionFailed, %{407 "Proxy Authentication Required "}
128
+ else
129
+ raise Error::ConnectionFailed, err
142
130
  end
143
-
144
- raise Faraday::ConnectionFailed, e
145
- rescue StandardError => e
146
- if defined?(OpenSSL) && e.is_a?(OpenSSL::SSL::SSLError)
147
- raise Faraday::SSLError, e
131
+ rescue => err
132
+ if defined?(OpenSSL) && OpenSSL::SSL::SSLError === err
133
+ raise Faraday::SSLError, err
134
+ else
135
+ raise
148
136
  end
149
-
150
- raise
151
137
  end
152
138
 
153
139
  # TODO: reuse the connection to support pipelining
154
140
  def perform_single_request(env)
155
141
  req = create_request(env)
156
- req = req.setup_request(env[:method], request_config(env))
157
- req.callback do |client|
158
- if env[:request].stream_response?
159
- warn "Streaming downloads for #{self.class.name} " \
160
- 'are not yet implemented.'
161
- env[:request].on_data.call(
162
- client.response,
163
- client.response.bytesize
164
- )
165
- end
142
+ req.setup_request(env[:method], request_config(env)).callback { |client|
166
143
  status = client.response_header.status
167
144
  reason = client.response_header.http_reason
168
- save_response(env, status, client.response, nil, reason) do |headers|
145
+ save_response(env, status, client.response, nil, reason) do |resp_headers|
169
146
  client.response_header.each do |name, value|
170
- headers[name.to_sym] = value
147
+ resp_headers[name.to_sym] = value
171
148
  end
172
149
  end
173
- end
150
+ }
174
151
  end
175
152
 
176
153
  def create_request(env)
177
- EventMachine::HttpRequest.new(
178
- env[:url], connection_config(env).merge(@connection_options)
179
- )
154
+ EventMachine::HttpRequest.new(env[:url], connection_config(env).merge(@connection_options))
180
155
  end
181
156
 
182
157
  def error_message(client)
183
- client.error || 'request failed'
158
+ client.error or "request failed"
184
159
  end
185
160
 
186
161
  def raise_error(msg)
187
- error_class = Faraday::ClientError
188
- if timeout_message?(msg)
189
- error_class = Faraday::TimeoutError
190
- msg = 'request timed out'
162
+ errklass = Faraday::Error::ClientError
163
+ if msg == Errno::ETIMEDOUT
164
+ errklass = Faraday::Error::TimeoutError
165
+ msg = "request timed out"
191
166
  elsif msg == Errno::ECONNREFUSED
192
- error_class = Faraday::ConnectionFailed
193
- msg = 'connection refused'
194
- elsif msg == 'connection closed by server'
195
- error_class = Faraday::ConnectionFailed
167
+ errklass = Faraday::Error::ConnectionFailed
168
+ msg = "connection refused"
169
+ elsif msg == "connection closed by server"
170
+ errklass = Faraday::Error::ConnectionFailed
196
171
  end
197
- raise error_class, msg
172
+ raise errklass, msg
198
173
  end
199
174
 
200
- def timeout_message?(msg)
201
- msg == Errno::ETIMEDOUT ||
202
- (msg.is_a?(String) && msg.include?('timeout error'))
203
- end
204
-
205
- # @return [Boolean]
206
175
  def parallel?(env)
207
176
  !!env[:parallel_manager]
208
177
  end
209
178
 
210
- # This parallel manager is designed to start an EventMachine loop
179
+ # The parallel manager is designed to start an EventMachine loop
211
180
  # and block until all registered requests have been completed.
212
181
  class Manager
213
- # @see reset
214
182
  def initialize
215
183
  reset
216
184
  end
217
185
 
218
- # Re-initializes instance variables
219
186
  def reset
220
187
  @registered_procs = []
221
188
  @num_registered = 0
@@ -224,30 +191,27 @@ module Faraday
224
191
  @running = false
225
192
  end
226
193
 
227
- # @return [Boolean]
228
- def running?
229
- @running
230
- end
194
+ def running?() @running end
231
195
 
232
- def add(&block)
196
+ def add
233
197
  if running?
234
198
  perform_request { yield }
235
199
  else
236
- @registered_procs << block
200
+ @registered_procs << Proc.new
237
201
  end
238
202
  @num_registered += 1
239
203
  end
240
204
 
241
205
  def run
242
- if @num_registered.positive?
206
+ if @num_registered > 0
243
207
  @running = true
244
208
  EventMachine.run do
245
209
  @registered_procs.each do |proc|
246
210
  perform_request(&proc)
247
211
  end
248
212
  end
249
- unless @errors.empty?
250
- raise Faraday::ClientError, @errors.first || 'connection failed'
213
+ if @errors.size > 0
214
+ raise Faraday::Error::ClientError, @errors.first || "connection failed"
251
215
  end
252
216
  end
253
217
  ensure
@@ -256,31 +220,24 @@ module Faraday
256
220
 
257
221
  def perform_request
258
222
  client = yield
259
- client.callback do
260
- @num_succeeded += 1
261
- check_finished
262
- end
263
- client.errback do
264
- @errors << client.error
265
- check_finished
266
- end
223
+ client.callback { @num_succeeded += 1; check_finished }
224
+ client.errback { @errors << client.error; check_finished }
267
225
  end
268
226
 
269
227
  def check_finished
270
- EventMachine.stop if @num_succeeded + @errors.size == @num_registered
228
+ if @num_succeeded + @errors.size == @num_registered
229
+ EventMachine.stop
230
+ end
271
231
  end
272
232
  end
273
233
  end
274
234
  end
275
235
  end
276
236
 
277
- if Faraday::Adapter::EMHttp.loaded?
278
- begin
279
- require 'openssl'
280
- rescue LoadError
281
- warn 'Warning: no such file to load -- openssl. ' \
282
- 'Make sure it is installed if you want HTTPS support'
283
- else
284
- require 'faraday/adapter/em_http_ssl_patch'
285
- end
286
- end
237
+ begin
238
+ require 'openssl'
239
+ rescue LoadError
240
+ warn "Warning: no such file to load -- openssl. Make sure it is installed if you want HTTPS support"
241
+ else
242
+ require 'faraday/adapter/em_http_ssl_patch'
243
+ end if Faraday::Adapter::EMHttp.loaded?
@@ -1,49 +1,43 @@
1
- # frozen_string_literal: true
2
-
3
1
  require 'openssl'
4
2
  require 'em-http'
5
3
 
6
- # EventMachine patch to make SSL work.
7
4
  module EmHttpSslPatch
8
5
  def ssl_verify_peer(cert_string)
6
+ cert = nil
9
7
  begin
10
- @last_seen_cert = OpenSSL::X509::Certificate.new(cert_string)
8
+ cert = OpenSSL::X509::Certificate.new(cert_string)
11
9
  rescue OpenSSL::X509::CertificateError
12
10
  return false
13
11
  end
14
12
 
15
- unless certificate_store.verify(@last_seen_cert)
16
- raise OpenSSL::SSL::SSLError,
17
- %(unable to verify the server certificate for "#{host}")
18
- end
19
-
20
- begin
21
- certificate_store.add_cert(@last_seen_cert)
22
- rescue OpenSSL::X509::StoreError => e
23
- raise e unless e.message == 'cert already in hash table'
13
+ @last_seen_cert = cert
14
+
15
+ if certificate_store.verify(@last_seen_cert)
16
+ begin
17
+ certificate_store.add_cert(@last_seen_cert)
18
+ rescue OpenSSL::X509::StoreError => e
19
+ raise e unless e.message == 'cert already in hash table'
20
+ end
21
+ true
22
+ else
23
+ raise OpenSSL::SSL::SSLError.new(%(unable to verify the server certificate for "#{host}"))
24
24
  end
25
- true
26
25
  end
27
26
 
28
27
  def ssl_handshake_completed
29
28
  return true unless verify_peer?
30
29
 
31
- unless verified_cert_identity?
32
- raise OpenSSL::SSL::SSLError,
33
- %(host "#{host}" does not match the server certificate)
30
+ unless OpenSSL::SSL.verify_certificate_identity(@last_seen_cert, host)
31
+ raise OpenSSL::SSL::SSLError.new(%(host "#{host}" does not match the server certificate))
32
+ else
33
+ true
34
34
  end
35
-
36
- true
37
35
  end
38
36
 
39
37
  def verify_peer?
40
38
  parent.connopts.tls[:verify_peer]
41
39
  end
42
40
 
43
- def verified_cert_identity?
44
- OpenSSL::SSL.verify_certificate_identity(@last_seen_cert, host)
45
- end
46
-
47
41
  def host
48
42
  parent.uri.host
49
43
  end
@@ -1,21 +1,16 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Faraday
4
2
  class Adapter
5
3
  class EMSynchrony < Faraday::Adapter
6
- # A parallel manager for EMSynchrony.
7
4
  class ParallelManager
8
- # Add requests to queue.
9
- #
10
- # @param request [EM::HttpRequest]
11
- # @param method [Symbol, String] HTTP method
12
- # @param args [Array] the rest of the positional arguments
5
+
6
+ # Add requests to queue. The `request` argument should be a
7
+ # `EM::HttpRequest` object.
13
8
  def add(request, method, *args, &block)
14
9
  queue << {
15
- request: request,
16
- method: method,
17
- args: args,
18
- block: block
10
+ :request => request,
11
+ :method => method,
12
+ :args => args,
13
+ :block => block
19
14
  }
20
15
  end
21
16
 
@@ -24,18 +19,19 @@ module Faraday
24
19
  def run
25
20
  result = nil
26
21
  if !EM.reactor_running?
27
- EM.run do
22
+ EM.run {
28
23
  Fiber.new do
29
24
  result = perform
30
25
  EM.stop
31
26
  end.resume
32
- end
27
+ }
33
28
  else
34
29
  result = perform
35
30
  end
36
31
  result
37
32
  end
38
33
 
34
+
39
35
  private
40
36
 
41
37
  # The request queue.
@@ -63,7 +59,8 @@ module Faraday
63
59
  # Block fiber until all requests have returned.
64
60
  multi.perform
65
61
  end
66
- end
67
- end
68
- end
69
- end
62
+
63
+ end # ParallelManager
64
+ end # EMSynchrony
65
+ end # Adapter
66
+ end # Faraday