faraday 0.16.2 → 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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.md +1 -1
  3. data/README.md +347 -18
  4. data/lib/faraday.rb +175 -93
  5. data/lib/faraday/adapter.rb +22 -36
  6. data/lib/faraday/adapter/em_http.rb +99 -142
  7. data/lib/faraday/adapter/em_http_ssl_patch.rb +17 -23
  8. data/lib/faraday/adapter/em_synchrony.rb +60 -104
  9. data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +15 -18
  10. data/lib/faraday/adapter/excon.rb +55 -100
  11. data/lib/faraday/adapter/httpclient.rb +39 -61
  12. data/lib/faraday/adapter/net_http.rb +51 -104
  13. data/lib/faraday/adapter/net_http_persistent.rb +27 -48
  14. data/lib/faraday/adapter/patron.rb +35 -54
  15. data/lib/faraday/adapter/rack.rb +12 -28
  16. data/lib/faraday/adapter/test.rb +53 -86
  17. data/lib/faraday/adapter/typhoeus.rb +1 -4
  18. data/lib/faraday/autoload.rb +36 -47
  19. data/lib/faraday/connection.rb +179 -321
  20. data/lib/faraday/error.rb +32 -80
  21. data/lib/faraday/middleware.rb +28 -4
  22. data/lib/faraday/options.rb +186 -35
  23. data/lib/faraday/parameters.rb +197 -4
  24. data/lib/faraday/rack_builder.rb +56 -67
  25. data/lib/faraday/request.rb +36 -68
  26. data/lib/faraday/request/authorization.rb +30 -42
  27. data/lib/faraday/request/basic_authentication.rb +7 -14
  28. data/lib/faraday/request/instrumentation.rb +27 -45
  29. data/lib/faraday/request/multipart.rb +48 -79
  30. data/lib/faraday/request/retry.rb +170 -197
  31. data/lib/faraday/request/token_authentication.rb +10 -15
  32. data/lib/faraday/request/url_encoded.rb +23 -41
  33. data/lib/faraday/response.rb +16 -23
  34. data/lib/faraday/response/logger.rb +69 -22
  35. data/lib/faraday/response/raise_error.rb +14 -36
  36. data/lib/faraday/upload_io.rb +67 -0
  37. data/lib/faraday/utils.rb +245 -28
  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/deprecated_class.rb +0 -28
  42. data/lib/faraday/encoders/flat_params_encoder.rb +0 -94
  43. data/lib/faraday/encoders/nested_params_encoder.rb +0 -171
  44. data/lib/faraday/file_part.rb +0 -128
  45. data/lib/faraday/logging/formatter.rb +0 -92
  46. data/lib/faraday/middleware_registry.rb +0 -129
  47. data/lib/faraday/options/connection_options.rb +0 -22
  48. data/lib/faraday/options/env.rb +0 -181
  49. data/lib/faraday/options/proxy_options.rb +0 -28
  50. data/lib/faraday/options/request_options.rb +0 -21
  51. data/lib/faraday/options/ssl_options.rb +0 -59
  52. data/lib/faraday/param_part.rb +0 -53
  53. data/lib/faraday/utils/headers.rb +0 -139
  54. data/lib/faraday/utils/params_hash.rb +0 -61
  55. data/spec/external_adapters/faraday_specs_setup.rb +0 -14
@@ -1,54 +1,43 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Faraday
4
- # Base class for all Faraday adapters. Adapters are
2
+ # Public: This is a base class for all Faraday adapters. Adapters are
5
3
  # responsible for fulfilling a Faraday request.
6
- class Adapter
7
- extend MiddlewareRegistry
8
- extend DependencyLoader
9
-
10
- CONTENT_LENGTH = 'Content-Length'
11
-
12
- register_middleware File.expand_path('adapter', __dir__),
13
- test: [:Test, 'test'],
14
- net_http: [:NetHttp, 'net_http'],
15
- net_http_persistent: [
16
- :NetHttpPersistent,
17
- 'net_http_persistent'
18
- ],
19
- typhoeus: [:Typhoeus, 'typhoeus'],
20
- patron: [:Patron, 'patron'],
21
- em_synchrony: [:EMSynchrony, 'em_synchrony'],
22
- em_http: [:EMHttp, 'em_http'],
23
- excon: [:Excon, 'excon'],
24
- rack: [:Rack, 'rack'],
25
- httpclient: [:HTTPClient, 'httpclient']
26
-
27
- # This module marks an Adapter as supporting parallel requests.
4
+ class Adapter < Middleware
5
+ CONTENT_LENGTH = 'Content-Length'.freeze
6
+
7
+ register_middleware File.expand_path('../adapter', __FILE__),
8
+ :test => [:Test, 'test'],
9
+ :net_http => [:NetHttp, 'net_http'],
10
+ :net_http_persistent => [:NetHttpPersistent, 'net_http_persistent'],
11
+ :typhoeus => [:Typhoeus, 'typhoeus'],
12
+ :patron => [:Patron, 'patron'],
13
+ :em_synchrony => [:EMSynchrony, 'em_synchrony'],
14
+ :em_http => [:EMHttp, 'em_http'],
15
+ :excon => [:Excon, 'excon'],
16
+ :rack => [:Rack, 'rack'],
17
+ :httpclient => [:HTTPClient, 'httpclient']
18
+
19
+ # Public: This module marks an Adapter as supporting parallel requests.
28
20
  module Parallelism
29
21
  attr_writer :supports_parallel
30
- def supports_parallel?
31
- @supports_parallel
32
- end
22
+ def supports_parallel?() @supports_parallel end
33
23
 
34
24
  def inherited(subclass)
35
25
  super
36
- subclass.supports_parallel = supports_parallel?
26
+ subclass.supports_parallel = self.supports_parallel?
37
27
  end
38
28
  end
39
29
 
40
30
  extend Parallelism
41
31
  self.supports_parallel = false
42
32
 
43
- def initialize(_app = nil, opts = {}, &block)
44
- @app = ->(env) { env.response }
33
+ def initialize(app = nil, opts = {}, &block)
34
+ super(app)
45
35
  @connection_options = opts
46
36
  @config_block = block
47
37
  end
48
38
 
49
39
  def call(env)
50
40
  env.clear_body if env.needs_body?
51
- env.response = Response.new
52
41
  end
53
42
 
54
43
  private
@@ -56,14 +45,11 @@ module Faraday
56
45
  def save_response(env, status, body, headers = nil, reason_phrase = nil)
57
46
  env.status = status
58
47
  env.body = body
59
- env.reason_phrase = reason_phrase&.to_s&.strip
48
+ env.reason_phrase = reason_phrase && reason_phrase.to_s.strip
60
49
  env.response_headers = Utils::Headers.new.tap do |response_headers|
61
50
  response_headers.update headers unless headers.nil?
62
51
  yield(response_headers) if block_given?
63
52
  end
64
-
65
- env.response.finish(env) unless env.parallel?
66
- env.response
67
53
  end
68
54
  end
69
55
  end
@@ -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?