faraday 0.17.6 → 1.0.0.pre.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.md +1 -1
  3. data/README.md +18 -358
  4. data/lib/faraday/adapter/em_http.rb +142 -99
  5. data/lib/faraday/adapter/em_http_ssl_patch.rb +23 -17
  6. data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +18 -15
  7. data/lib/faraday/adapter/em_synchrony.rb +104 -60
  8. data/lib/faraday/adapter/excon.rb +97 -57
  9. data/lib/faraday/adapter/httpclient.rb +61 -39
  10. data/lib/faraday/adapter/net_http.rb +103 -51
  11. data/lib/faraday/adapter/net_http_persistent.rb +49 -28
  12. data/lib/faraday/adapter/patron.rb +54 -35
  13. data/lib/faraday/adapter/rack.rb +28 -12
  14. data/lib/faraday/adapter/test.rb +86 -53
  15. data/lib/faraday/adapter/typhoeus.rb +4 -1
  16. data/lib/faraday/adapter.rb +36 -22
  17. data/lib/faraday/adapter_registry.rb +28 -0
  18. data/lib/faraday/autoload.rb +47 -36
  19. data/lib/faraday/connection.rb +321 -179
  20. data/lib/faraday/dependency_loader.rb +37 -0
  21. data/lib/faraday/encoders/flat_params_encoder.rb +94 -0
  22. data/lib/faraday/encoders/nested_params_encoder.rb +171 -0
  23. data/lib/faraday/error.rb +21 -79
  24. data/lib/faraday/logging/formatter.rb +92 -0
  25. data/lib/faraday/middleware.rb +4 -28
  26. data/lib/faraday/middleware_registry.rb +129 -0
  27. data/lib/faraday/options/connection_options.rb +22 -0
  28. data/lib/faraday/options/env.rb +181 -0
  29. data/lib/faraday/options/proxy_options.rb +28 -0
  30. data/lib/faraday/options/request_options.rb +21 -0
  31. data/lib/faraday/options/ssl_options.rb +59 -0
  32. data/lib/faraday/options.rb +33 -184
  33. data/lib/faraday/parameters.rb +4 -197
  34. data/lib/faraday/rack_builder.rb +66 -55
  35. data/lib/faraday/request/authorization.rb +42 -30
  36. data/lib/faraday/request/basic_authentication.rb +14 -7
  37. data/lib/faraday/request/instrumentation.rb +45 -27
  38. data/lib/faraday/request/multipart.rb +72 -49
  39. data/lib/faraday/request/retry.rb +197 -171
  40. data/lib/faraday/request/token_authentication.rb +15 -10
  41. data/lib/faraday/request/url_encoded.rb +41 -23
  42. data/lib/faraday/request.rb +68 -38
  43. data/lib/faraday/response/logger.rb +22 -69
  44. data/lib/faraday/response/raise_error.rb +36 -18
  45. data/lib/faraday/response.rb +22 -15
  46. data/lib/faraday/upload_io.rb +31 -30
  47. data/lib/faraday/utils/headers.rb +139 -0
  48. data/lib/faraday/utils/params_hash.rb +61 -0
  49. data/lib/faraday/utils.rb +28 -245
  50. data/lib/faraday.rb +93 -174
  51. data/spec/external_adapters/faraday_specs_setup.rb +14 -0
  52. metadata +25 -51
  53. data/CHANGELOG.md +0 -232
  54. data/Rakefile +0 -13
  55. data/lib/faraday/deprecate.rb +0 -109
  56. data/spec/faraday/deprecate_spec.rb +0 -147
  57. data/spec/faraday/error_spec.rb +0 -102
  58. data/spec/faraday/response/raise_error_spec.rb +0 -106
  59. data/spec/spec_helper.rb +0 -105
  60. data/test/adapters/default_test.rb +0 -14
  61. data/test/adapters/em_http_test.rb +0 -30
  62. data/test/adapters/em_synchrony_test.rb +0 -32
  63. data/test/adapters/excon_test.rb +0 -30
  64. data/test/adapters/httpclient_test.rb +0 -34
  65. data/test/adapters/integration.rb +0 -263
  66. data/test/adapters/logger_test.rb +0 -136
  67. data/test/adapters/net_http_persistent_test.rb +0 -114
  68. data/test/adapters/net_http_test.rb +0 -79
  69. data/test/adapters/patron_test.rb +0 -40
  70. data/test/adapters/rack_test.rb +0 -38
  71. data/test/adapters/test_middleware_test.rb +0 -157
  72. data/test/adapters/typhoeus_test.rb +0 -38
  73. data/test/authentication_middleware_test.rb +0 -65
  74. data/test/composite_read_io_test.rb +0 -109
  75. data/test/connection_test.rb +0 -738
  76. data/test/env_test.rb +0 -268
  77. data/test/helper.rb +0 -75
  78. data/test/live_server.rb +0 -67
  79. data/test/middleware/instrumentation_test.rb +0 -88
  80. data/test/middleware/retry_test.rb +0 -282
  81. data/test/middleware_stack_test.rb +0 -260
  82. data/test/multibyte.txt +0 -1
  83. data/test/options_test.rb +0 -333
  84. data/test/parameters_test.rb +0 -157
  85. data/test/request_middleware_test.rb +0 -126
  86. data/test/response_middleware_test.rb +0 -72
  87. data/test/strawberry.rb +0 -2
  88. data/test/utils_test.rb +0 -98
@@ -1,10 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Faraday
2
4
  class Adapter
3
- # EventMachine adapter is useful for either asynchronous requests
4
- # when in EM reactor loop or for making parallel requests in
5
+ # EventMachine adapter. This adapter is useful for either asynchronous
6
+ # requests when in an EM reactor loop, or for making parallel requests in
5
7
  # synchronous code.
6
8
  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.
7
11
  module Options
12
+ # @return [Hash]
8
13
  def connection_config(env)
9
14
  options = {}
10
15
  configure_proxy(options, env)
@@ -16,10 +21,10 @@ module Faraday
16
21
 
17
22
  def request_config(env)
18
23
  options = {
19
- :body => read_body(env),
20
- :head => env[:request_headers],
21
- # :keepalive => true,
22
- # :file => 'path/to/file', # stream data off disk
24
+ body: read_body(env),
25
+ head: env[:request_headers]
26
+ # keepalive: true,
27
+ # file: 'path/to/file', # stream data off disk
23
28
  }
24
29
  configure_compression(options, env)
25
30
  options
@@ -30,44 +35,53 @@ module Faraday
30
35
  body.respond_to?(:read) ? body.read : body
31
36
  end
32
37
 
38
+ # Reads out proxy settings from env into options
33
39
  def configure_proxy(options, env)
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
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
+ }
41
48
  end
42
49
 
50
+ # Reads out host and port settings from env into options
43
51
  def configure_socket(options, env)
44
- if bind = request_options(env)[:bind]
45
- options[:bind] = {
46
- :host => bind[:host],
47
- :port => bind[:port]
48
- }
49
- end
52
+ bind = request_options(env)[:bind]
53
+ return unless bind
54
+
55
+ options[:bind] = {
56
+ host: bind[:host],
57
+ port: bind[:port]
58
+ }
50
59
  end
51
60
 
61
+ # Reads out SSL certificate settings from env into options
52
62
  def configure_ssl(options, env)
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
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
+ }
59
69
  end
60
70
 
71
+ # Reads out timeout settings from env into options
61
72
  def configure_timeout(options, env)
62
- timeout, open_timeout = request_options(env).values_at(:timeout, :open_timeout)
73
+ timeout, open_timeout = request_options(env)
74
+ .values_at(:timeout, :open_timeout)
63
75
  options[:connect_timeout] = options[:inactivity_timeout] = timeout
64
76
  options[:connect_timeout] = open_timeout if open_timeout
65
77
  end
66
78
 
79
+ # Reads out compression header settings from env into options
67
80
  def configure_compression(options, env)
68
- if env[:method] == :get and not options[:head].key? 'accept-encoding'
69
- options[:head]['accept-encoding'] = 'gzip, compressed'
70
- end
81
+ return unless (env[:method] == :get) &&
82
+ !options[:head].key?('accept-encoding')
83
+
84
+ options[:head]['accept-encoding'] = 'gzip, compressed'
71
85
  end
72
86
 
73
87
  def request_options(env)
@@ -81,7 +95,8 @@ module Faraday
81
95
 
82
96
  self.supports_parallel = true
83
97
 
84
- def self.setup_parallel_manager(options = nil)
98
+ # @return [Manager]
99
+ def self.setup_parallel_manager(_options = nil)
85
100
  Manager.new
86
101
  end
87
102
 
@@ -94,95 +109,113 @@ module Faraday
94
109
  def perform_request(env)
95
110
  if parallel?(env)
96
111
  manager = env[:parallel_manager]
97
- manager.add {
98
- perform_single_request(env).
99
- callback { env[:response].finish(env) }
100
- }
101
- else
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
+ 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
112
124
  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
- }
125
+ 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
123
135
  end
136
+ raise_error(error) if error
124
137
  end
125
- rescue EventMachine::Connectify::CONNECTError => err
126
- if err.message.include?("Proxy Authentication Required")
127
- raise Faraday::ConnectionFailed, %{407 "Proxy Authentication Required "}
128
- else
129
- raise Faraday::ConnectionFailed, err
138
+ rescue EventMachine::Connectify::CONNECTError => e
139
+ if e.message.include?('Proxy Authentication Required')
140
+ raise Faraday::ConnectionFailed,
141
+ %(407 "Proxy Authentication Required ")
130
142
  end
131
- rescue => err
132
- if defined?(OpenSSL) && OpenSSL::SSL::SSLError === err
133
- raise Faraday::SSLError, err
134
- else
135
- raise
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
136
148
  end
149
+
150
+ raise
137
151
  end
138
152
 
139
153
  # TODO: reuse the connection to support pipelining
140
154
  def perform_single_request(env)
141
155
  req = create_request(env)
142
- req.setup_request(env[:method], request_config(env)).callback { |client|
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
143
166
  status = client.response_header.status
144
167
  reason = client.response_header.http_reason
145
- save_response(env, status, client.response, nil, reason) do |resp_headers|
168
+ save_response(env, status, client.response, nil, reason) do |headers|
146
169
  client.response_header.each do |name, value|
147
- resp_headers[name.to_sym] = value
170
+ headers[name.to_sym] = value
148
171
  end
149
172
  end
150
- }
173
+ end
151
174
  end
152
175
 
153
176
  def create_request(env)
154
- EventMachine::HttpRequest.new(env[:url], connection_config(env).merge(@connection_options))
177
+ EventMachine::HttpRequest.new(
178
+ env[:url], connection_config(env).merge(@connection_options)
179
+ )
155
180
  end
156
181
 
157
182
  def error_message(client)
158
- client.error or "request failed"
183
+ client.error || 'request failed'
159
184
  end
160
185
 
161
186
  def raise_error(msg)
162
- errklass = Faraday::ClientError
163
- if msg == Errno::ETIMEDOUT
164
- errklass = Faraday::TimeoutError
165
- msg = "request timed out"
187
+ error_class = Faraday::ClientError
188
+ if timeout_message?(msg)
189
+ error_class = Faraday::TimeoutError
190
+ msg = 'request timed out'
166
191
  elsif msg == Errno::ECONNREFUSED
167
- errklass = Faraday::ConnectionFailed
168
- msg = "connection refused"
169
- elsif msg == "connection closed by server"
170
- errklass = Faraday::ConnectionFailed
192
+ error_class = Faraday::ConnectionFailed
193
+ msg = 'connection refused'
194
+ elsif msg == 'connection closed by server'
195
+ error_class = Faraday::ConnectionFailed
171
196
  end
172
- raise errklass, msg
197
+ raise error_class, msg
173
198
  end
174
199
 
200
+ def timeout_message?(msg)
201
+ msg == Errno::ETIMEDOUT ||
202
+ (msg.is_a?(String) && msg.include?('timeout error'))
203
+ end
204
+
205
+ # @return [Boolean]
175
206
  def parallel?(env)
176
207
  !!env[:parallel_manager]
177
208
  end
178
209
 
179
- # The parallel manager is designed to start an EventMachine loop
210
+ # This parallel manager is designed to start an EventMachine loop
180
211
  # and block until all registered requests have been completed.
181
212
  class Manager
213
+ # @see reset
182
214
  def initialize
183
215
  reset
184
216
  end
185
217
 
218
+ # Re-initializes instance variables
186
219
  def reset
187
220
  @registered_procs = []
188
221
  @num_registered = 0
@@ -191,27 +224,30 @@ module Faraday
191
224
  @running = false
192
225
  end
193
226
 
194
- def running?() @running end
227
+ # @return [Boolean]
228
+ def running?
229
+ @running
230
+ end
195
231
 
196
- def add(&block)
232
+ def add
197
233
  if running?
198
234
  perform_request { yield }
199
235
  else
200
- @registered_procs << block
236
+ @registered_procs << Proc.new
201
237
  end
202
238
  @num_registered += 1
203
239
  end
204
240
 
205
241
  def run
206
- if @num_registered > 0
242
+ if @num_registered.positive?
207
243
  @running = true
208
244
  EventMachine.run do
209
245
  @registered_procs.each do |proc|
210
246
  perform_request(&proc)
211
247
  end
212
248
  end
213
- if @errors.size > 0
214
- raise Faraday::ClientError, @errors.first || "connection failed"
249
+ unless @errors.empty?
250
+ raise Faraday::ClientError, @errors.first || 'connection failed'
215
251
  end
216
252
  end
217
253
  ensure
@@ -220,24 +256,31 @@ module Faraday
220
256
 
221
257
  def perform_request
222
258
  client = yield
223
- client.callback { @num_succeeded += 1; check_finished }
224
- client.errback { @errors << client.error; check_finished }
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
225
267
  end
226
268
 
227
269
  def check_finished
228
- if @num_succeeded + @errors.size == @num_registered
229
- EventMachine.stop
230
- end
270
+ EventMachine.stop if @num_succeeded + @errors.size == @num_registered
231
271
  end
232
272
  end
233
273
  end
234
274
  end
235
275
  end
236
276
 
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?
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
@@ -1,43 +1,49 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'openssl'
2
4
  require 'em-http'
3
5
 
6
+ # EventMachine patch to make SSL work.
4
7
  module EmHttpSslPatch
5
8
  def ssl_verify_peer(cert_string)
6
- cert = nil
7
9
  begin
8
- cert = OpenSSL::X509::Certificate.new(cert_string)
10
+ @last_seen_cert = OpenSSL::X509::Certificate.new(cert_string)
9
11
  rescue OpenSSL::X509::CertificateError
10
12
  return false
11
13
  end
12
14
 
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}"))
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'
24
24
  end
25
+ true
25
26
  end
26
27
 
27
28
  def ssl_handshake_completed
28
29
  return true unless verify_peer?
29
30
 
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
31
+ unless verified_cert_identity?
32
+ raise OpenSSL::SSL::SSLError,
33
+ %(host "#{host}" does not match the server certificate)
34
34
  end
35
+
36
+ true
35
37
  end
36
38
 
37
39
  def verify_peer?
38
40
  parent.connopts.tls[:verify_peer]
39
41
  end
40
42
 
43
+ def verified_cert_identity?
44
+ OpenSSL::SSL.verify_certificate_identity(@last_seen_cert, host)
45
+ end
46
+
41
47
  def host
42
48
  parent.uri.host
43
49
  end
@@ -1,16 +1,21 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Faraday
2
4
  class Adapter
3
5
  class EMSynchrony < Faraday::Adapter
6
+ # A parallel manager for EMSynchrony.
4
7
  class ParallelManager
5
-
6
- # Add requests to queue. The `request` argument should be a
7
- # `EM::HttpRequest` object.
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
8
13
  def add(request, method, *args, &block)
9
14
  queue << {
10
- :request => request,
11
- :method => method,
12
- :args => args,
13
- :block => block
15
+ request: request,
16
+ method: method,
17
+ args: args,
18
+ block: block
14
19
  }
15
20
  end
16
21
 
@@ -19,19 +24,18 @@ module Faraday
19
24
  def run
20
25
  result = nil
21
26
  if !EM.reactor_running?
22
- EM.run {
27
+ EM.run do
23
28
  Fiber.new do
24
29
  result = perform
25
30
  EM.stop
26
31
  end.resume
27
- }
32
+ end
28
33
  else
29
34
  result = perform
30
35
  end
31
36
  result
32
37
  end
33
38
 
34
-
35
39
  private
36
40
 
37
41
  # The request queue.
@@ -59,8 +63,7 @@ module Faraday
59
63
  # Block fiber until all requests have returned.
60
64
  multi.perform
61
65
  end
62
-
63
- end # ParallelManager
64
- end # EMSynchrony
65
- end # Adapter
66
- end # Faraday
66
+ end
67
+ end
68
+ end
69
+ end