faraday 0.16.2 → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
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