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,8 +1,5 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Faraday
4
2
  class Adapter
5
- # Patron adapter.
6
3
  class Patron < Faraday::Adapter
7
4
  dependency 'patron'
8
5
 
@@ -12,60 +9,46 @@ module Faraday
12
9
  env[:body] = env[:body].read if env[:body].respond_to? :read
13
10
 
14
11
  session = ::Patron::Session.new
15
- @config_block&.call(session)
16
- if (env[:url].scheme == 'https') && env[:ssl]
17
- configure_ssl(session, env[:ssl])
18
- end
12
+ @config_block.call(session) if @config_block
13
+ configure_ssl(session, env[:ssl]) if env[:url].scheme == 'https' and env[:ssl]
19
14
 
20
- if (req = env[:request])
21
- if req[:timeout]
22
- session.timeout = session.connect_timeout = req[:timeout]
23
- end
24
- session.connect_timeout = req[:open_timeout] if req[:open_timeout]
15
+ if req = env[:request]
16
+ session.timeout = session.connect_timeout = req[:timeout] if req[:timeout]
17
+ session.connect_timeout = req[:open_timeout] if req[:open_timeout]
25
18
 
26
- if (proxy = req[:proxy])
19
+ if proxy = req[:proxy]
27
20
  proxy_uri = proxy[:uri].dup
28
- proxy_uri.user = proxy[:user] &&
29
- Utils.escape(proxy[:user]).gsub('+', '%20')
30
- proxy_uri.password = proxy[:password] &&
31
- Utils.escape(proxy[:password]).gsub('+', '%20')
21
+ proxy_uri.user = proxy[:user] && Utils.escape(proxy[:user]).gsub('+', '%20')
22
+ proxy_uri.password = proxy[:password] && Utils.escape(proxy[:password]).gsub('+', '%20')
32
23
  session.proxy = proxy_uri.to_s
33
24
  end
34
25
  end
35
26
 
36
27
  response = begin
37
28
  data = env[:body] ? env[:body].to_s : nil
38
- session.request(env[:method], env[:url].to_s,
39
- env[:request_headers], data: data)
40
- rescue Errno::ECONNREFUSED, ::Patron::ConnectionFailed
41
- raise Faraday::ConnectionFailed, $ERROR_INFO
29
+ session.request(env[:method], env[:url].to_s, env[:request_headers], :data => data)
30
+ rescue Errno::ECONNREFUSED, ::Patron::ConnectionFailed
31
+ raise Error::ConnectionFailed, $!
42
32
  end
43
33
 
44
- if (req = env[:request]).stream_response?
45
- warn "Streaming downloads for #{self.class.name} " \
46
- 'are not yet implemented.'
47
- req.on_data.call(response.body, response.body.bytesize)
48
- end
49
34
  # Remove the "HTTP/1.1 200", leaving just the reason phrase
50
35
  reason_phrase = response.status_line.gsub(/^.* \d{3} /, '')
51
36
 
52
- save_response(env, response.status, response.body,
53
- response.headers, reason_phrase)
37
+ save_response(env, response.status, response.body, response.headers, reason_phrase)
54
38
 
55
39
  @app.call env
56
- rescue ::Patron::TimeoutError => e
57
- if connection_timed_out_message?(e.message)
58
- raise Faraday::ConnectionFailed, e
40
+ rescue ::Patron::TimeoutError => err
41
+ if connection_timed_out_message?(err.message)
42
+ raise Faraday::Error::ConnectionFailed, err
43
+ else
44
+ raise Faraday::Error::TimeoutError, err
59
45
  end
60
-
61
- raise Faraday::TimeoutError, e
62
- rescue ::Patron::Error => e
63
- if e.message.include?('code 407')
64
- raise Faraday::ConnectionFailed,
65
- %(407 "Proxy Authentication Required ")
46
+ rescue ::Patron::Error => err
47
+ if err.message.include?("code 407")
48
+ raise Error::ConnectionFailed, %{407 "Proxy Authentication Required "}
49
+ else
50
+ raise Error::ConnectionFailed, err
66
51
  end
67
-
68
- raise Faraday::ConnectionFailed, e
69
52
  end
70
53
 
71
54
  if loaded? && defined?(::Patron::Request::VALID_ACTIONS)
@@ -77,8 +60,8 @@ module Faraday
77
60
  actions << :options unless actions.include? :options
78
61
  else
79
62
  # Patron 0.4.20 and up
80
- actions << 'PATCH' unless actions.include? 'PATCH'
81
- actions << 'OPTIONS' unless actions.include? 'OPTIONS'
63
+ actions << "PATCH" unless actions.include? "PATCH"
64
+ actions << "OPTIONS" unless actions.include? "OPTIONS"
82
65
  end
83
66
  end
84
67
  end
@@ -93,22 +76,20 @@ module Faraday
93
76
 
94
77
  private
95
78
 
96
- CURL_TIMEOUT_MESSAGES = [
97
- 'Connection time-out',
98
- 'Connection timed out',
99
- 'Timed out before name resolve',
100
- 'server connect has timed out',
101
- 'Resolving timed out',
102
- 'name lookup timed out',
103
- 'timed out before SSL',
104
- 'connect() timed out'
105
- ].freeze
79
+ CURL_TIMEOUT_MESSAGES = [ "Connection time-out",
80
+ "Connection timed out",
81
+ "Timed out before name resolve",
82
+ "server connect has timed out",
83
+ "Resolving timed out",
84
+ "name lookup timed out",
85
+ "timed out before SSL",
86
+ "connect() timed out"
87
+ ].freeze
106
88
 
107
89
  def connection_timed_out_message?(message)
108
- CURL_TIMEOUT_MESSAGES.any? do |curl_message|
109
- message.include?(curl_message)
110
- end
90
+ CURL_TIMEOUT_MESSAGES.any? { |curl_message| message.include?(curl_message) }
111
91
  end
92
+
112
93
  end
113
94
  end
114
95
  end
@@ -1,10 +1,8 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Faraday
4
2
  class Adapter
5
3
  # Sends requests to a Rack app.
6
4
  #
7
- # @example
5
+ # Examples
8
6
  #
9
7
  # class MyRackApp
10
8
  # def call(env)
@@ -19,7 +17,7 @@ module Faraday
19
17
  dependency 'rack/test'
20
18
 
21
19
  # not prefixed with "HTTP_"
22
- SPECIAL_HEADERS = %w[CONTENT_LENGTH CONTENT_TYPE].freeze
20
+ SPECIAL_HEADERS = %w[ CONTENT_LENGTH CONTENT_TYPE ]
23
21
 
24
22
  def initialize(faraday_app, rack_app)
25
23
  super(faraday_app)
@@ -29,46 +27,32 @@ module Faraday
29
27
 
30
28
  def call(env)
31
29
  super
32
- rack_env = build_rack_env(env)
30
+ rack_env = {
31
+ :method => env[:method],
32
+ :input => env[:body].respond_to?(:read) ? env[:body].read : env[:body],
33
+ 'rack.url_scheme' => env[:url].scheme
34
+ }
33
35
 
34
- env[:request_headers]&.each do |name, value|
36
+ env[:request_headers].each do |name, value|
35
37
  name = name.upcase.tr('-', '_')
36
38
  name = "HTTP_#{name}" unless SPECIAL_HEADERS.include? name
37
39
  rack_env[name] = value
38
- end
40
+ end if env[:request_headers]
39
41
 
40
42
  timeout = env[:request][:timeout] || env[:request][:open_timeout]
41
43
  response = if timeout
42
- Timer.timeout(timeout, Faraday::TimeoutError) do
43
- execute_request(env, rack_env)
44
- end
45
- else
46
- execute_request(env, rack_env)
47
- end
48
-
49
- if (req = env[:request]).stream_response?
50
- warn "Streaming downloads for #{self.class.name} " \
51
- 'are not yet implemented.'
52
- req.on_data.call(response.body, response.body.bytesize)
44
+ Timer.timeout(timeout, Faraday::Error::TimeoutError) { execute_request(env, rack_env) }
45
+ else
46
+ execute_request(env, rack_env)
53
47
  end
54
48
 
55
49
  save_response(env, response.status, response.body, response.headers)
56
50
  @app.call env
57
51
  end
58
52
 
59
- private
60
-
61
53
  def execute_request(env, rack_env)
62
54
  @session.request(env[:url].to_s, rack_env)
63
55
  end
64
-
65
- def build_rack_env(env)
66
- {
67
- method: env[:method],
68
- input: env[:body].respond_to?(:read) ? env[:body].read : env[:body],
69
- 'rack.url_scheme' => env[:url].scheme
70
- }
71
- end
72
56
  end
73
57
  end
74
58
  end
@@ -1,56 +1,51 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Faraday
4
2
  class Adapter
5
- # @example
3
+ # Examples
4
+ #
6
5
  # test = Faraday::Connection.new do
7
6
  # use Faraday::Adapter::Test do |stub|
8
- # # Define matcher to match the request
7
+ # # simply define matcher to match the request
9
8
  # stub.get '/resource.json' do
10
9
  # # return static content
11
10
  # [200, {'Content-Type' => 'application/json'}, 'hi world']
12
11
  # end
13
- #
12
+ #
14
13
  # # response with content generated based on request
15
14
  # stub.get '/showget' do |env|
16
15
  # [200, {'Content-Type' => 'text/plain'}, env[:method].to_s]
17
16
  # end
18
- #
19
- # # A regular expression can be used as matching filter
17
+ #
18
+ # # regular expression can be used as matching filter
20
19
  # stub.get /\A\/items\/(\d+)\z/ do |env, meta|
21
- # # in case regular expression is used, an instance of MatchData
22
- # # can be received
23
- # [200,
24
- # {'Content-Type' => 'text/plain'},
25
- # "showing item: #{meta[:match_data][1]}"
26
- # ]
20
+ # # in case regular expression is used an instance of MatchData can be received
21
+ # [200, {'Content-Type' => 'text/plain'}, "showing item: #{meta[:match_data][1]}"]
27
22
  # end
28
23
  # end
29
24
  # end
30
- #
25
+ #
31
26
  # resp = test.get '/resource.json'
32
27
  # resp.body # => 'hi world'
33
- #
28
+ #
34
29
  # resp = test.get '/showget'
35
30
  # resp.body # => 'get'
36
- #
31
+ #
37
32
  # resp = test.get '/items/1'
38
33
  # resp.body # => 'showing item: 1'
39
- #
34
+ #
40
35
  # resp = test.get '/items/2'
41
36
  # resp.body # => 'showing item: 2'
37
+ #
38
+
42
39
  class Test < Faraday::Adapter
43
40
  attr_accessor :stubs
44
41
 
45
- # A stack of Stubs
46
42
  class Stubs
47
43
  class NotFound < StandardError
48
44
  end
49
45
 
50
46
  def initialize
51
- # { get: [Stub, Stub] }
52
- @stack = {}
53
- @consumed = {}
47
+ # {:get => [Stub, Stub]}
48
+ @stack, @consumed = {}, {}
54
49
  yield(self) if block_given?
55
50
  end
56
51
 
@@ -59,8 +54,7 @@ module Faraday
59
54
  end
60
55
 
61
56
  def match(request_method, host, path, headers, body)
62
- return false unless @stack.key?(request_method)
63
-
57
+ return false if !@stack.key?(request_method)
64
58
  stack = @stack[request_method]
65
59
  consumed = (@consumed[request_method] ||= [])
66
60
 
@@ -80,15 +74,15 @@ module Faraday
80
74
  new_stub(:head, path, headers, &block)
81
75
  end
82
76
 
83
- def post(path, body = nil, headers = {}, &block)
77
+ def post(path, body=nil, headers = {}, &block)
84
78
  new_stub(:post, path, headers, body, &block)
85
79
  end
86
80
 
87
- def put(path, body = nil, headers = {}, &block)
81
+ def put(path, body=nil, headers = {}, &block)
88
82
  new_stub(:put, path, headers, body, &block)
89
83
  end
90
84
 
91
- def patch(path, body = nil, headers = {}, &block)
85
+ def patch(path, body=nil, headers = {}, &block)
92
86
  new_stub(:patch, path, headers, body, &block)
93
87
  end
94
88
 
@@ -104,32 +98,26 @@ module Faraday
104
98
  def verify_stubbed_calls
105
99
  failed_stubs = []
106
100
  @stack.each do |method, stubs|
107
- next if stubs.empty?
108
-
109
- failed_stubs.concat(
110
- stubs.map do |stub|
101
+ unless stubs.size == 0
102
+ failed_stubs.concat(stubs.map {|stub|
111
103
  "Expected #{method} #{stub}."
112
- end
113
- )
104
+ })
105
+ end
114
106
  end
115
- raise failed_stubs.join(' ') unless failed_stubs.empty?
107
+ raise failed_stubs.join(" ") unless failed_stubs.size == 0
116
108
  end
117
109
 
118
110
  protected
119
111
 
120
- def new_stub(request_method, path, headers = {}, body = nil, &block)
112
+ def new_stub(request_method, path, headers = {}, body=nil, &block)
121
113
  normalized_path, host =
122
114
  if path.is_a?(Regexp)
123
115
  path
124
116
  else
125
- [
126
- Faraday::Utils.normalize_path(path),
127
- Faraday::Utils.URI(path).host
128
- ]
117
+ [Faraday::Utils.normalize_path(path), Faraday::Utils.URI(path).host]
129
118
  end
130
119
 
131
- stub = Stub.new(host, normalized_path, headers, body, block)
132
- (@stack[request_method] ||= []) << stub
120
+ (@stack[request_method] ||= []) << Stub.new(host, normalized_path, headers, body, block)
133
121
  end
134
122
 
135
123
  def matches?(stack, host, path, headers, body)
@@ -141,42 +129,32 @@ module Faraday
141
129
  end
142
130
  end
143
131
 
144
- # Stub request
145
- # rubocop:disable Style/StructInheritance
146
132
  class Stub < Struct.new(:host, :path, :params, :headers, :body, :block)
147
- # rubocop:enable Style/StructInheritance
148
133
  def initialize(host, full, headers, body, block)
149
- path, query = full.respond_to?(:split) ? full.split('?') : full
150
- params =
151
- if query
152
- Faraday::Utils.parse_nested_query(query)
153
- else
154
- {}
155
- end
156
-
134
+ path, query = full.respond_to?(:split) ? full.split("?") : full
135
+ params = query ?
136
+ Faraday::Utils.parse_nested_query(query) :
137
+ {}
157
138
  super(host, path, params, headers, body, block)
158
139
  end
159
140
 
160
141
  def matches?(request_host, request_uri, request_headers, request_body)
161
142
  request_path, request_query = request_uri.split('?')
162
- request_params =
163
- if request_query
164
- Faraday::Utils.parse_nested_query(request_query)
165
- else
166
- {}
167
- end
168
- # meta is a hash used as carrier
143
+ request_params = request_query ?
144
+ Faraday::Utils.parse_nested_query(request_query) :
145
+ {}
146
+ # meta is a hash use as carrier
169
147
  # that will be yielded to consumer block
170
148
  meta = {}
171
- [(host.nil? || host == request_host) &&
149
+ return (host.nil? || host == request_host) &&
172
150
  path_match?(request_path, meta) &&
173
151
  params_match?(request_params) &&
174
152
  (body.to_s.size.zero? || request_body == body) &&
175
- headers_match?(request_headers), meta]
153
+ headers_match?(request_headers), meta
176
154
  end
177
155
 
178
156
  def path_match?(request_path, meta)
179
- if path.is_a?(Regexp)
157
+ if path.is_a? Regexp
180
158
  !!(meta[:match_data] = path.match(request_path))
181
159
  else
182
160
  path == request_path
@@ -200,7 +178,7 @@ module Faraday
200
178
  end
201
179
  end
202
180
 
203
- def initialize(app, stubs = nil, &block)
181
+ def initialize(app, stubs=nil, &block)
204
182
  super(app)
205
183
  @stubs = stubs || Stubs.new
206
184
  configure(&block) if block
@@ -214,31 +192,20 @@ module Faraday
214
192
  super
215
193
  host = env[:url].host
216
194
  normalized_path = Faraday::Utils.normalize_path(env[:url])
217
- params_encoder = env.request.params_encoder ||
218
- Faraday::Utils.default_params_encoder
219
-
220
- stub, meta = stubs.match(env[:method], host, normalized_path,
221
- env.request_headers, env[:body])
222
-
223
- unless stub
224
- raise Stubs::NotFound, "no stubbed request for #{env[:method]} "\
225
- "#{normalized_path} #{env[:body]}"
226
- end
227
-
228
- env[:params] = if (query = env[:url].query)
229
- params_encoder.decode(query)
230
- else
231
- {}
232
- end
233
- block_arity = stub.block.arity
234
- status, headers, body =
235
- if block_arity >= 0
236
- stub.block.call(*[env, meta].take(block_arity))
237
- else
195
+ params_encoder = env.request.params_encoder || Faraday::Utils.default_params_encoder
196
+
197
+ stub, meta = stubs.match(env[:method], host, normalized_path, env.request_headers, env[:body])
198
+ if stub
199
+ env[:params] = (query = env[:url].query) ?
200
+ params_encoder.decode(query) : {}
201
+ block_arity = stub.block.arity
202
+ status, headers, body = (block_arity >= 0) ?
203
+ stub.block.call(*[env, meta].take(block_arity)) :
238
204
  stub.block.call(env, meta)
239
- end
240
- save_response(env, status, body, headers)
241
-
205
+ save_response(env, status, body, headers)
206
+ else
207
+ raise Stubs::NotFound, "no stubbed request for #{env[:method]} #{normalized_path} #{env[:body]}"
208
+ end
242
209
  @app.call(env)
243
210
  end
244
211
  end