faraday 1.4.1 → 1.10.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/examples/client_spec.rb +34 -2
  3. data/examples/client_test.rb +41 -2
  4. data/lib/faraday/adapter/test.rb +59 -43
  5. data/lib/faraday/adapter.rb +1 -6
  6. data/lib/faraday/autoload.rb +1 -6
  7. data/lib/faraday/connection.rb +33 -6
  8. data/lib/faraday/dependency_loader.rb +3 -1
  9. data/lib/faraday/deprecate.rb +110 -0
  10. data/lib/faraday/error.rb +0 -6
  11. data/lib/faraday/options/proxy_options.rb +4 -0
  12. data/lib/faraday/request/authorization.rb +14 -7
  13. data/lib/faraday/request/json.rb +55 -0
  14. data/lib/faraday/request.rb +10 -12
  15. data/lib/faraday/response/json.rb +54 -0
  16. data/lib/faraday/response/logger.rb +2 -4
  17. data/lib/faraday/response.rb +3 -1
  18. data/lib/faraday/version.rb +1 -1
  19. data/lib/faraday.rb +19 -4
  20. data/spec/faraday/adapter/em_http_spec.rb +39 -37
  21. data/spec/faraday/adapter/em_synchrony_spec.rb +11 -9
  22. data/spec/faraday/adapter/test_spec.rb +117 -0
  23. data/spec/faraday/connection_spec.rb +15 -0
  24. data/spec/faraday/deprecate_spec.rb +147 -0
  25. data/spec/faraday/options/proxy_options_spec.rb +7 -0
  26. data/spec/faraday/request/authorization_spec.rb +8 -0
  27. data/spec/faraday/request/json_spec.rb +111 -0
  28. data/spec/faraday/request_spec.rb +1 -1
  29. data/spec/faraday/response/json_spec.rb +119 -0
  30. data/spec/spec_helper.rb +2 -0
  31. metadata +99 -28
  32. data/lib/faraday/adapter/em_http.rb +0 -289
  33. data/lib/faraday/adapter/em_http_ssl_patch.rb +0 -62
  34. data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +0 -69
  35. data/lib/faraday/adapter/em_synchrony.rb +0 -153
  36. data/lib/faraday/adapter/httpclient.rb +0 -152
  37. data/lib/faraday/adapter/patron.rb +0 -132
  38. data/lib/faraday/adapter/rack.rb +0 -75
  39. data/lib/faraday/file_part.rb +0 -128
  40. data/lib/faraday/param_part.rb +0 -53
  41. data/lib/faraday/request/multipart.rb +0 -106
  42. data/lib/faraday/request/retry.rb +0 -239
  43. data/spec/faraday/request/multipart_spec.rb +0 -302
  44. data/spec/faraday/request/retry_spec.rb +0 -242
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 78d94069f3e1d41648f0b2c82872d305bf2c829667526d2c95f39f3a2609792e
4
- data.tar.gz: 91e952182291cfc3311db77776811323980e00008966c8000259161c7a7e5294
3
+ metadata.gz: 5a35b8ef069416d74f46cbe1f9b14b9d28e8b141bed4143d2c97ac137b766f18
4
+ data.tar.gz: cdbb3768e4aa6d316e2216ec7fdf2a93b5141abe83dd82b3ffa522002b01523c
5
5
  SHA512:
6
- metadata.gz: cfa2dc1f4c6d8a869f381a59c80babeadeb83b5201078eac30560f7b7bc6940464625c264db0c7ea2486d461edb6b197b07d37bf7b7bf7e517ff546332f1106e
7
- data.tar.gz: bd4677f959813e83cb7f3f38369293ffd153b674c5dee1e45c8fe32e7796a84f047304e72c6b3b43fb90051ed91fd491bf5fb68344c729c07589eaf3b7513b2b
6
+ metadata.gz: 743727fca5013eb1bd1f005c334d171fc59a5cb56687395b3d14a48911ee4b7fef5da00e64ac6dbe15b75cc76edcb26d400b4d748e9676d9cdb12e8d2d8ee7b7
7
+ data.tar.gz: 203527c8adc2828334b74e97a33041ed9127548b91905d15331ff627c5f20d679c3d2ccd0b3102c0de35e011c5f15f2bac50b8aa4eccaeafaf1551611ca020e1
@@ -12,8 +12,8 @@ class Client
12
12
  @conn = conn
13
13
  end
14
14
 
15
- def sushi(jname)
16
- res = @conn.get("/#{jname}")
15
+ def sushi(jname, params: {})
16
+ res = @conn.get("/#{jname}", params)
17
17
  data = JSON.parse(res.body)
18
18
  data['name']
19
19
  end
@@ -62,4 +62,36 @@ RSpec.describe Client do
62
62
  expect { client.sushi('ebi') }.to raise_error(Faraday::ConnectionFailed)
63
63
  stubs.verify_stubbed_calls
64
64
  end
65
+
66
+ context 'When the test stub is run in strict_mode' do
67
+ let(:stubs) { Faraday::Adapter::Test::Stubs.new(strict_mode: true) }
68
+
69
+ it 'verifies the all parameter values are identical' do
70
+ stubs.get('/ebi?abc=123') do
71
+ [
72
+ 200,
73
+ { 'Content-Type': 'application/javascript' },
74
+ '{"name": "shrimp"}'
75
+ ]
76
+ end
77
+
78
+ # uncomment to raise Stubs::NotFound
79
+ # expect(client.sushi('ebi', params: { abc: 123, foo: 'Kappa' })).to eq('shrimp')
80
+ expect(client.sushi('ebi', params: { abc: 123 })).to eq('shrimp')
81
+ stubs.verify_stubbed_calls
82
+ end
83
+ end
84
+
85
+ context 'When the Faraday connection is configured with FlatParamsEncoder' do
86
+ let(:conn) { Faraday.new(request: { params_encoder: Faraday::FlatParamsEncoder }) { |b| b.adapter(:test, stubs) } }
87
+
88
+ it 'handles the same multiple URL parameters' do
89
+ stubs.get('/ebi?a=x&a=y&a=z') { [200, { 'Content-Type' => 'application/json' }, '{"name": "shrimp"}'] }
90
+
91
+ # uncomment to raise Stubs::NotFound
92
+ # expect(client.sushi('ebi', params: { a: %w[x y] })).to eq('shrimp')
93
+ expect(client.sushi('ebi', params: { a: %w[x y z] })).to eq('shrimp')
94
+ stubs.verify_stubbed_calls
95
+ end
96
+ end
65
97
  end
@@ -13,8 +13,8 @@ class Client
13
13
  @conn = conn
14
14
  end
15
15
 
16
- def sushi(jname)
17
- res = @conn.get("/#{jname}")
16
+ def sushi(jname, params: {})
17
+ res = @conn.get("/#{jname}", params)
18
18
  data = JSON.parse(res.body)
19
19
  data['name']
20
20
  end
@@ -70,6 +70,45 @@ class ClientTest < Test::Unit::TestCase
70
70
  stubs.verify_stubbed_calls
71
71
  end
72
72
 
73
+ def test_strict_mode
74
+ stubs = Faraday::Adapter::Test::Stubs.new(strict_mode: true)
75
+ stubs.get('/ebi?abc=123') do
76
+ [
77
+ 200,
78
+ { 'Content-Type': 'application/javascript' },
79
+ '{"name": "shrimp"}'
80
+ ]
81
+ end
82
+
83
+ cli = client(stubs)
84
+ assert_equal 'shrimp', cli.sushi('ebi', params: { abc: 123 })
85
+
86
+ # uncomment to raise Stubs::NotFound
87
+ # assert_equal 'shrimp', cli.sushi('ebi', params: { abc: 123, foo: 'Kappa' })
88
+ stubs.verify_stubbed_calls
89
+ end
90
+
91
+ def test_non_default_params_encoder
92
+ stubs = Faraday::Adapter::Test::Stubs.new(strict_mode: true)
93
+ stubs.get('/ebi?a=x&a=y&a=z') do
94
+ [
95
+ 200,
96
+ { 'Content-Type': 'application/javascript' },
97
+ '{"name": "shrimp"}'
98
+ ]
99
+ end
100
+ conn = Faraday.new(request: { params_encoder: Faraday::FlatParamsEncoder }) do |builder|
101
+ builder.adapter :test, stubs
102
+ end
103
+
104
+ cli = Client.new(conn)
105
+ assert_equal 'shrimp', cli.sushi('ebi', params: { a: %w[x y z] })
106
+
107
+ # uncomment to raise Stubs::NotFound
108
+ # assert_equal 'shrimp', cli.sushi('ebi', params: { a: %w[x y] })
109
+ stubs.verify_stubbed_calls
110
+ end
111
+
73
112
  def client(stubs)
74
113
  conn = Faraday.new do |builder|
75
114
  builder.adapter :test, stubs
@@ -25,6 +25,9 @@ module Faraday
25
25
  # "showing item: #{meta[:match_data][1]}"
26
26
  # ]
27
27
  # end
28
+ #
29
+ # # You can set strict_mode to exactly match the stubbed requests.
30
+ # stub.strict_mode = true
28
31
  # end
29
32
  # end
30
33
  #
@@ -47,10 +50,11 @@ module Faraday
47
50
  class NotFound < StandardError
48
51
  end
49
52
 
50
- def initialize
53
+ def initialize(strict_mode: false)
51
54
  # { get: [Stub, Stub] }
52
55
  @stack = {}
53
56
  @consumed = {}
57
+ @strict_mode = strict_mode
54
58
  yield(self) if block_given?
55
59
  end
56
60
 
@@ -58,18 +62,20 @@ module Faraday
58
62
  @stack.empty?
59
63
  end
60
64
 
61
- def match(request_method, host, path, headers, body)
65
+ # @param env [Faraday::Env]
66
+ def match(env)
67
+ request_method = env[:method]
62
68
  return false unless @stack.key?(request_method)
63
69
 
64
70
  stack = @stack[request_method]
65
71
  consumed = (@consumed[request_method] ||= [])
66
72
 
67
- stub, meta = matches?(stack, host, path, headers, body)
73
+ stub, meta = matches?(stack, env)
68
74
  if stub
69
75
  consumed << stack.delete(stub)
70
76
  return stub, meta
71
77
  end
72
- matches?(consumed, host, path, headers, body)
78
+ matches?(consumed, env)
73
79
  end
74
80
 
75
81
  def get(path, headers = {}, &block)
@@ -115,6 +121,17 @@ module Faraday
115
121
  raise failed_stubs.join(' ') unless failed_stubs.empty?
116
122
  end
117
123
 
124
+ # Set strict_mode. If the value is true, this adapter tries to find matched requests strictly,
125
+ # which means that all of a path, parameters, and headers must be the same as an actual request.
126
+ def strict_mode=(value)
127
+ @strict_mode = value
128
+ @stack.each do |_method, stubs|
129
+ stubs.each do |stub|
130
+ stub.strict_mode = value
131
+ end
132
+ end
133
+ end
134
+
118
135
  protected
119
136
 
120
137
  def new_stub(request_method, path, headers = {}, body = nil, &block)
@@ -127,14 +144,18 @@ module Faraday
127
144
  Faraday::Utils.URI(path).host
128
145
  ]
129
146
  end
147
+ path, query = normalized_path.respond_to?(:split) ? normalized_path.split('?') : normalized_path
148
+ headers = Utils::Headers.new(headers)
130
149
 
131
- stub = Stub.new(host, normalized_path, headers, body, block)
150
+ stub = Stub.new(host, path, query, headers, body, @strict_mode, block)
132
151
  (@stack[request_method] ||= []) << stub
133
152
  end
134
153
 
135
- def matches?(stack, host, path, headers, body)
154
+ # @param stack [Hash]
155
+ # @param env [Faraday::Env]
156
+ def matches?(stack, env)
136
157
  stack.each do |stub|
137
- match_result, meta = stub.matches?(host, path, headers, body)
158
+ match_result, meta = stub.matches?(env)
138
159
  return stub, meta if match_result
139
160
  end
140
161
  nil
@@ -142,35 +163,20 @@ module Faraday
142
163
  end
143
164
 
144
165
  # Stub request
145
- # rubocop:disable Style/StructInheritance
146
- class Stub < Struct.new(:host, :path, :params, :headers, :body, :block)
147
- # rubocop:enable Style/StructInheritance
148
- 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
-
157
- super(host, path, params, headers, body, block)
158
- end
166
+ class Stub < Struct.new(:host, :path, :query, :headers, :body, :strict_mode, :block) # rubocop:disable Style/StructInheritance
167
+ # @param env [Faraday::Env]
168
+ def matches?(env)
169
+ request_host = env[:url].host
170
+ request_path = Faraday::Utils.normalize_path(env[:url].path)
171
+ request_headers = env.request_headers
172
+ request_body = env[:body]
159
173
 
160
- def matches?(request_host, request_uri, request_headers, request_body)
161
- 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
174
  # meta is a hash used as carrier
169
175
  # that will be yielded to consumer block
170
176
  meta = {}
171
177
  [(host.nil? || host == request_host) &&
172
178
  path_match?(request_path, meta) &&
173
- params_match?(request_params) &&
179
+ params_match?(env) &&
174
180
  (body.to_s.size.zero? || request_body == body) &&
175
181
  headers_match?(request_headers), meta]
176
182
  end
@@ -183,13 +189,30 @@ module Faraday
183
189
  end
184
190
  end
185
191
 
186
- def params_match?(request_params)
192
+ # @param env [Faraday::Env]
193
+ def params_match?(env)
194
+ request_params = env[:params]
195
+ params = env.params_encoder.decode(query) || {}
196
+
197
+ if strict_mode
198
+ return Set.new(params) == Set.new(request_params)
199
+ end
200
+
187
201
  params.keys.all? do |key|
188
202
  request_params[key] == params[key]
189
203
  end
190
204
  end
191
205
 
192
206
  def headers_match?(request_headers)
207
+ if strict_mode
208
+ headers_with_user_agent = headers.dup.tap do |hs|
209
+ # NOTE: Set User-Agent in case it's not set when creating Stubs.
210
+ # Users would not want to set Faraday's User-Agent explicitly.
211
+ hs[:user_agent] ||= Connection::USER_AGENT
212
+ end
213
+ return Set.new(headers_with_user_agent) == Set.new(request_headers)
214
+ end
215
+
193
216
  headers.keys.all? do |key|
194
217
  request_headers[key] == headers[key]
195
218
  end
@@ -210,26 +233,19 @@ module Faraday
210
233
  yield(stubs)
211
234
  end
212
235
 
236
+ # @param env [Faraday::Env]
213
237
  def call(env)
214
238
  super
215
- host = env[:url].host
216
- normalized_path = Faraday::Utils.normalize_path(env[:url])
217
- params_encoder = env.request.params_encoder ||
218
- Faraday::Utils.default_params_encoder
219
239
 
220
- stub, meta = stubs.match(env[:method], host, normalized_path,
221
- env.request_headers, env[:body])
240
+ env.request.params_encoder ||= Faraday::Utils.default_params_encoder
241
+ env[:params] = env.params_encoder.decode(env[:url].query) || {}
242
+ stub, meta = stubs.match(env)
222
243
 
223
244
  unless stub
224
245
  raise Stubs::NotFound, "no stubbed request for #{env[:method]} "\
225
- "#{normalized_path} #{env[:body]}"
246
+ "#{env[:url]} #{env[:body]}"
226
247
  end
227
248
 
228
- env[:params] = if (query = env[:url].query)
229
- params_encoder.decode(query)
230
- else
231
- {}
232
- end
233
249
  block_arity = stub.block.arity
234
250
  status, headers, body =
235
251
  if block_arity >= 0
@@ -11,12 +11,7 @@ module Faraday
11
11
 
12
12
  register_middleware File.expand_path('adapter', __dir__),
13
13
  test: [:Test, 'test'],
14
- typhoeus: [:Typhoeus, 'typhoeus'],
15
- patron: [:Patron, 'patron'],
16
- em_synchrony: [:EMSynchrony, 'em_synchrony'],
17
- em_http: [:EMHttp, 'em_http'],
18
- rack: [:Rack, 'rack'],
19
- httpclient: [:HTTPClient, 'httpclient']
14
+ typhoeus: [:Typhoeus, 'typhoeus']
20
15
 
21
16
  # This module marks an Adapter as supporting parallel requests.
22
17
  module Parallelism
@@ -58,13 +58,8 @@ module Faraday
58
58
  class Adapter
59
59
  extend AutoloadHelper
60
60
  autoload_all 'faraday/adapter',
61
- EMSynchrony: 'em_synchrony',
62
- EMHttp: 'em_http',
63
61
  Typhoeus: 'typhoeus',
64
- Patron: 'patron',
65
- Test: 'test',
66
- Rack: 'rack',
67
- HTTPClient: 'httpclient'
62
+ Test: 'test'
68
63
  end
69
64
 
70
65
  # Request represents a single HTTP request for a Faraday adapter to make.
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'faraday/deprecate'
4
+
3
5
  module Faraday
4
6
  # Connection objects manage the default properties and the middleware
5
7
  # stack for fulfilling an HTTP request.
@@ -15,6 +17,7 @@ module Faraday
15
17
  class Connection
16
18
  # A Set of allowed HTTP verbs.
17
19
  METHODS = Set.new %i[get post put delete head patch options trace]
20
+ USER_AGENT = "Faraday v#{VERSION}"
18
21
 
19
22
  # @return [Hash] URI query unencoded key/value pairs.
20
23
  attr_reader :params
@@ -26,7 +29,7 @@ module Faraday
26
29
  # Connection. This includes a default host name, scheme, port, and path.
27
30
  attr_reader :url_prefix
28
31
 
29
- # @return [Faraday::Builder] Builder for this Connection.
32
+ # @return [Faraday::RackBuilder] Builder for this Connection.
30
33
  attr_reader :builder
31
34
 
32
35
  # @return [Hash] SSL options.
@@ -73,6 +76,7 @@ module Faraday
73
76
  @options = options.request
74
77
  @ssl = options.ssl
75
78
  @default_parallel_manager = options.parallel_manager
79
+ @manual_proxy = nil
76
80
 
77
81
  @builder = options.builder || begin
78
82
  # pass an empty block to Builder so it doesn't assume default middleware
@@ -88,7 +92,7 @@ module Faraday
88
92
 
89
93
  yield(self) if block_given?
90
94
 
91
- @headers[:user_agent] ||= "Faraday v#{VERSION}"
95
+ @headers[:user_agent] ||= USER_AGENT
92
96
  end
93
97
 
94
98
  def initialize_proxy(url, options)
@@ -298,6 +302,9 @@ module Faraday
298
302
  set_authorization_header(:basic_auth, login, pass)
299
303
  end
300
304
 
305
+ extend Faraday::Deprecate
306
+ deprecate :basic_auth, '#request(:basic_auth, ...)', '2.0'
307
+
301
308
  # Sets up the Authorization header with the given token.
302
309
  #
303
310
  # @param token [String]
@@ -315,6 +322,11 @@ module Faraday
315
322
  set_authorization_header(:token_auth, token, options)
316
323
  end
317
324
 
325
+ deprecate :token_auth,
326
+ '#request(:token_auth, ...)',
327
+ '2.0',
328
+ 'See https://lostisland.github.io/faraday/middleware/authentication for more usage info.'
329
+
318
330
  # Sets up a custom Authorization header.
319
331
  #
320
332
  # @param type [String] authorization type
@@ -337,6 +349,11 @@ module Faraday
337
349
  set_authorization_header(:authorization, type, token)
338
350
  end
339
351
 
352
+ deprecate :authorization,
353
+ '#request(:authorization, ...)',
354
+ '2.0',
355
+ 'See https://lostisland.github.io/faraday/middleware/authentication for more usage info.'
356
+
340
357
  # Check if the adapter is parallel-capable.
341
358
  #
342
359
  # @yield if the adapter isn't parallel-capable, or if no adapter is set yet.
@@ -416,9 +433,16 @@ module Faraday
416
433
  uri.query = nil
417
434
 
418
435
  with_uri_credentials(uri) do |user, password|
419
- basic_auth user, password
436
+ set_basic_auth(user, password)
420
437
  uri.user = uri.password = nil
421
438
  end
439
+
440
+ @proxy = proxy_from_env(url) unless @manual_proxy
441
+ end
442
+
443
+ def set_basic_auth(user, password)
444
+ header = Faraday::Request::BasicAuthentication.header(user, password)
445
+ headers[Faraday::Request::Authorization::KEY] = header
422
446
  end
423
447
 
424
448
  # Sets the path prefix and ensures that it always has a leading
@@ -517,9 +541,8 @@ module Faraday
517
541
  # @return [URI]
518
542
  def build_exclusive_url(url = nil, params = nil, params_encoder = nil)
519
543
  url = nil if url.respond_to?(:empty?) && url.empty?
520
- base = url_prefix
544
+ base = url_prefix.dup
521
545
  if url && base.path && base.path !~ %r{/$}
522
- base = base.dup
523
546
  base.path = "#{base.path}/" # ensure trailing slash
524
547
  end
525
548
  url = url && URI.parse(url.to_s).opaque ? url.to_s.gsub(':', '%3A') : url
@@ -577,7 +600,11 @@ module Faraday
577
600
  case url
578
601
  when String
579
602
  uri = Utils.URI(url)
580
- uri = URI.parse("#{uri.scheme}://#{uri.host}").find_proxy
603
+ uri = if uri.host.nil?
604
+ find_default_proxy
605
+ else
606
+ URI.parse("#{uri.scheme}://#{uri.host}").find_proxy
607
+ end
581
608
  when URI
582
609
  uri = url.find_proxy
583
610
  when nil
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'ruby2_keywords'
4
+
3
5
  module Faraday
4
6
  # DependencyLoader helps Faraday adapters and middleware load dependencies.
5
7
  module DependencyLoader
@@ -13,7 +15,7 @@ module Faraday
13
15
  self.load_error = e
14
16
  end
15
17
 
16
- def new(*)
18
+ ruby2_keywords def new(*)
17
19
  unless loaded?
18
20
  raise "missing dependency for #{self}: #{load_error.message}"
19
21
  end
@@ -0,0 +1,110 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Faraday
4
+ # @param new_klass [Class] new Klass to use
5
+ #
6
+ # @return [Class] A modified version of new_klass that warns on
7
+ # usage about deprecation.
8
+ # @see Faraday::Deprecate
9
+ module DeprecatedClass
10
+ def self.proxy_class(origclass, ver = '1.0')
11
+ proxy = Class.new(origclass) do
12
+ const_set('ORIG_CLASS', origclass)
13
+
14
+ class << self
15
+ extend Faraday::Deprecate
16
+
17
+ def ===(other)
18
+ (superclass == const_get('ORIG_CLASS') && other.is_a?(superclass)) || super
19
+ end
20
+ end
21
+ end
22
+ proxy.singleton_class.send(:deprecate, :new, "#{origclass}.new", ver)
23
+ proxy.singleton_class.send(:deprecate, :inherited, origclass.name, ver)
24
+ proxy
25
+ end
26
+ end
27
+
28
+ # Deprecation using semver instead of date, based on Gem::Deprecate
29
+ # Provides a single method +deprecate+ to be used to declare when
30
+ # something is going away.
31
+ #
32
+ # class Legacy
33
+ # def self.klass_method
34
+ # # ...
35
+ # end
36
+ #
37
+ # def instance_method
38
+ # # ...
39
+ # end
40
+ #
41
+ # extend Faraday::Deprecate
42
+ # deprecate :instance_method, "X.z", '1.0'
43
+ #
44
+ # class << self
45
+ # extend Faraday::Deprecate
46
+ # deprecate :klass_method, :none, '1.0'
47
+ # end
48
+ # end
49
+ module Deprecate
50
+ def self.skip # :nodoc:
51
+ @skip ||= begin
52
+ case ENV['FARADAY_DEPRECATE'].to_s.downcase
53
+ when '1', 'warn' then :warn
54
+ else :skip
55
+ end
56
+ end
57
+ @skip == :skip
58
+ end
59
+
60
+ def self.skip=(value) # :nodoc:
61
+ @skip = value ? :skip : :warn
62
+ end
63
+
64
+ # Temporarily turn off warnings. Intended for tests only.
65
+ def skip_during
66
+ original = Faraday::Deprecate.skip
67
+ Faraday::Deprecate.skip = true
68
+ yield
69
+ ensure
70
+ Faraday::Deprecate.skip = original
71
+ end
72
+
73
+ # Simple deprecation method that deprecates +name+ by wrapping it up
74
+ # in a dummy method. It warns on each call to the dummy method
75
+ # telling the user of +repl+ (unless +repl+ is :none) and the
76
+ # semver that it is planned to go away.
77
+ # @param name [Symbol] the method symbol to deprecate
78
+ # @param repl [#to_s, :none] the replacement to use, when `:none` it will
79
+ # alert the user that no replacement is present.
80
+ # @param ver [String] the semver the method will be removed.
81
+ def deprecate(name, repl, ver, custom_message = nil)
82
+ class_eval do
83
+ gem_ver = Gem::Version.new(ver)
84
+ old = "_deprecated_#{name}"
85
+ alias_method old, name
86
+ define_method name do |*args, &block|
87
+ mod = is_a? Module
88
+ target = mod ? "#{self}." : "#{self.class}#"
89
+ target_message = if name == :inherited
90
+ "Inheriting #{self}"
91
+ else
92
+ "#{target}#{name}"
93
+ end
94
+
95
+ msg = [
96
+ "NOTE: #{target_message} is deprecated",
97
+ repl == :none ? ' with no replacement' : "; use #{repl} instead. ",
98
+ "It will be removed in or after version #{gem_ver} ",
99
+ custom_message,
100
+ "\n#{target}#{name} called from #{Gem.location_of_caller.join(':')}"
101
+ ]
102
+ warn "#{msg.join}." unless Faraday::Deprecate.skip
103
+ send old, *args, &block
104
+ end
105
+ end
106
+ end
107
+
108
+ module_function :deprecate, :skip_during
109
+ end
110
+ end
data/lib/faraday/error.rb CHANGED
@@ -143,10 +143,4 @@ module Faraday
143
143
  # Raised by FaradayMiddleware::ResponseMiddleware
144
144
  class ParsingError < Error
145
145
  end
146
-
147
- # Exception used to control the Retry middleware.
148
- #
149
- # @see Faraday::Request::Retry
150
- class RetriableResponse < Error
151
- end
152
146
  end
@@ -11,6 +11,9 @@ module Faraday
11
11
  def self.from(value)
12
12
  case value
13
13
  when String
14
+ # URIs without a scheme should default to http (like 'example:123').
15
+ # This fixes #1282 and prevents a silent failure in some adapters.
16
+ value = "http://#{value}" unless value.include?('://')
14
17
  value = { uri: Utils.URI(value) }
15
18
  when URI
16
19
  value = { uri: value }
@@ -19,6 +22,7 @@ module Faraday
19
22
  value[:uri] = Utils.URI(uri)
20
23
  end
21
24
  end
25
+
22
26
  super(value)
23
27
  end
24
28
 
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'base64'
4
+
3
5
  module Faraday
4
6
  class Request
5
7
  # Request middleware for the Authorization HTTP header
@@ -13,7 +15,8 @@ module Faraday
13
15
  # @return [String] a header value
14
16
  def self.header(type, token)
15
17
  case token
16
- when String, Symbol
18
+ when String, Symbol, Proc
19
+ token = token.call if token.is_a?(Proc)
17
20
  "#{type} #{token}"
18
21
  when Hash
19
22
  build_hash(type.to_s, token)
@@ -32,6 +35,7 @@ module Faraday
32
35
  comma = ', '
33
36
  values = []
34
37
  hash.each do |key, value|
38
+ value = value.call if value.is_a?(Proc)
35
39
  values << "#{key}=#{value.to_s.inspect}"
36
40
  end
37
41
  "#{type} #{values * comma}"
@@ -39,16 +43,19 @@ module Faraday
39
43
 
40
44
  # @param app [#call]
41
45
  # @param type [String, Symbol] Type of Authorization
42
- # @param token [String, Symbol, Hash] Token value for the Authorization
43
- def initialize(app, type, token)
44
- @header_value = self.class.header(type, token)
46
+ # @param param [String, Symbol, Hash, Proc] parameter to build the Authorization header.
47
+ # This value can be a proc, in which case it will be invoked on each request.
48
+ def initialize(app, type, param)
49
+ @type = type
50
+ @param = param
45
51
  super(app)
46
52
  end
47
53
 
48
54
  # @param env [Faraday::Env]
49
- def call(env)
50
- env.request_headers[KEY] = @header_value unless env.request_headers[KEY]
51
- @app.call(env)
55
+ def on_request(env)
56
+ return if env.request_headers[KEY]
57
+
58
+ env.request_headers[KEY] = self.class.header(@type, @param)
52
59
  end
53
60
  end
54
61
  end