faraday 1.8.0 → 1.10.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f6441da03048f7371bd0cb898dd3e27c7be6382c67fc4901883e9dbe9841b56f
4
- data.tar.gz: 0beb3f2da75282655fc46cd5540de96d5fef259dd35193ec9eb0d3163cc959d2
3
+ metadata.gz: 5a35b8ef069416d74f46cbe1f9b14b9d28e8b141bed4143d2c97ac137b766f18
4
+ data.tar.gz: cdbb3768e4aa6d316e2216ec7fdf2a93b5141abe83dd82b3ffa522002b01523c
5
5
  SHA512:
6
- metadata.gz: 1ab1aa0e0c68c9348d9e180a903f01f2517bd38672fe1bdf056ceab4729e841944173e47dc26aa1b4fe16b2779f1a8102914ed594ea92d08feff6dc944412f0b
7
- data.tar.gz: bc43fbac427062861e79d5328b60886a5b9c8783f707faa1fcfad064b9c6945f6a4e2a97dbad9ecadc1c1620b5327d651a764962764b7fc86e6d2fbd84ad0b4b
6
+ metadata.gz: 743727fca5013eb1bd1f005c334d171fc59a5cb56687395b3d14a48911ee4b7fef5da00e64ac6dbe15b75cc76edcb26d400b4d748e9676d9cdb12e8d2d8ee7b7
7
+ data.tar.gz: 203527c8adc2828334b74e97a33041ed9127548b91905d15331ff627c5f20d679c3d2ccd0b3102c0de35e011c5f15f2bac50b8aa4eccaeafaf1551611ca020e1
@@ -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.
@@ -297,14 +299,12 @@ module Faraday
297
299
  #
298
300
  # @return [void]
299
301
  def basic_auth(login, pass)
300
- warn <<~TEXT
301
- WARNING: `Faraday::Connection#basic_auth` is deprecated; it will be removed in version 2.0.
302
- While initializing your connection, use `#request(:basic_auth, ...)` instead.
303
- See https://lostisland.github.io/faraday/middleware/authentication for more usage info.
304
- TEXT
305
302
  set_authorization_header(:basic_auth, login, pass)
306
303
  end
307
304
 
305
+ extend Faraday::Deprecate
306
+ deprecate :basic_auth, '#request(:basic_auth, ...)', '2.0'
307
+
308
308
  # Sets up the Authorization header with the given token.
309
309
  #
310
310
  # @param token [String]
@@ -319,14 +319,14 @@ module Faraday
319
319
  #
320
320
  # @return [void]
321
321
  def token_auth(token, options = nil)
322
- warn <<~TEXT
323
- WARNING: `Faraday::Connection#token_auth` is deprecated; it will be removed in version 2.0.
324
- While initializing your connection, use `#request(:token_auth, ...)` instead.
325
- See https://lostisland.github.io/faraday/middleware/authentication for more usage info.
326
- TEXT
327
322
  set_authorization_header(:token_auth, token, options)
328
323
  end
329
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
+
330
330
  # Sets up a custom Authorization header.
331
331
  #
332
332
  # @param type [String] authorization type
@@ -346,14 +346,14 @@ module Faraday
346
346
  #
347
347
  # @return [void]
348
348
  def authorization(type, token)
349
- warn <<~TEXT
350
- WARNING: `Faraday::Connection#authorization` is deprecated; it will be removed in version 2.0.
351
- While initializing your connection, use `#request(:authorization, ...)` instead.
352
- See https://lostisland.github.io/faraday/middleware/authentication for more usage info.
353
- TEXT
354
349
  set_authorization_header(:authorization, type, token)
355
350
  end
356
351
 
352
+ deprecate :authorization,
353
+ '#request(:authorization, ...)',
354
+ '2.0',
355
+ 'See https://lostisland.github.io/faraday/middleware/authentication for more usage info.'
356
+
357
357
  # Check if the adapter is parallel-capable.
358
358
  #
359
359
  # @yield if the adapter isn't parallel-capable, or if no adapter is set yet.
@@ -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
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ module Faraday
6
+ class Request
7
+ # Request middleware that encodes the body as JSON.
8
+ #
9
+ # Processes only requests with matching Content-type or those without a type.
10
+ # If a request doesn't have a type but has a body, it sets the Content-type
11
+ # to JSON MIME-type.
12
+ #
13
+ # Doesn't try to encode bodies that already are in string form.
14
+ class Json < Middleware
15
+ MIME_TYPE = 'application/json'
16
+ MIME_TYPE_REGEX = %r{^application/(vnd\..+\+)?json$}.freeze
17
+
18
+ def on_request(env)
19
+ match_content_type(env) do |data|
20
+ env[:body] = encode(data)
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def encode(data)
27
+ ::JSON.generate(data)
28
+ end
29
+
30
+ def match_content_type(env)
31
+ return unless process_request?(env)
32
+
33
+ env[:request_headers][CONTENT_TYPE] ||= MIME_TYPE
34
+ yield env[:body] unless env[:body].respond_to?(:to_str)
35
+ end
36
+
37
+ def process_request?(env)
38
+ type = request_type(env)
39
+ body?(env) && (type.empty? || type.match?(MIME_TYPE_REGEX))
40
+ end
41
+
42
+ def body?(env)
43
+ (body = env[:body]) && !(body.respond_to?(:to_str) && body.empty?)
44
+ end
45
+
46
+ def request_type(env)
47
+ type = env[:request_headers][CONTENT_TYPE].to_s
48
+ type = type.split(';', 2).first if type.index(';')
49
+ type
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ Faraday::Request.register_middleware(json: Faraday::Request::Json)
@@ -35,8 +35,6 @@ module Faraday
35
35
 
36
36
  register_middleware File.expand_path('request', __dir__),
37
37
  url_encoded: [:UrlEncoded, 'url_encoded'],
38
- multipart: [:Multipart, 'multipart'],
39
- retry: [:Retry, 'retry'],
40
38
  authorization: [:Authorization, 'authorization'],
41
39
  basic_auth: [
42
40
  :BasicAuthentication,
@@ -46,7 +44,8 @@ module Faraday
46
44
  :TokenAuthentication,
47
45
  'token_authentication'
48
46
  ],
49
- instrumentation: [:Instrumentation, 'instrumentation']
47
+ instrumentation: [:Instrumentation, 'instrumentation'],
48
+ json: [:Json, 'json']
50
49
 
51
50
  # @param request_method [String]
52
51
  # @yield [request] for block customization, if block given
@@ -59,13 +58,12 @@ module Faraday
59
58
  end
60
59
 
61
60
  def method
62
- warn <<~TEXT
63
- WARNING: `Faraday::Request##{__method__}` is deprecated; use `#http_method` instead. It will be removed in or after version 2.0.
64
- `Faraday::Request##{__method__}` called from #{caller_locations(1..1).first}
65
- TEXT
66
61
  http_method
67
62
  end
68
63
 
64
+ extend Faraday::Deprecate
65
+ deprecate :method, :http_method, '2.0'
66
+
69
67
  # Replace params, preserving the existing hash type.
70
68
  #
71
69
  # @param hash [Hash] new params
@@ -140,11 +138,11 @@ module Faraday
140
138
  # @param serialised [Hash] the serialised object.
141
139
  def marshal_load(serialised)
142
140
  self.http_method = serialised[:http_method]
143
- self.body = serialised[:body]
144
- self.headers = serialised[:headers]
145
- self.path = serialised[:path]
146
- self.params = serialised[:params]
147
- self.options = serialised[:options]
141
+ self.body = serialised[:body]
142
+ self.headers = serialised[:headers]
143
+ self.path = serialised[:path]
144
+ self.params = serialised[:params]
145
+ self.options = serialised[:options]
148
146
  end
149
147
 
150
148
  # @return [Env] the Env for this Request
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ module Faraday
6
+ class Response
7
+ # Parse response bodies as JSON.
8
+ class Json < Middleware
9
+ def initialize(app = nil, options = {})
10
+ super(app)
11
+ @parser_options = options[:parser_options]
12
+ @content_types = Array(options[:content_type] || /\bjson$/)
13
+ @preserve_raw = options[:preserve_raw]
14
+ end
15
+
16
+ def on_complete(env)
17
+ process_response(env) if parse_response?(env)
18
+ end
19
+
20
+ private
21
+
22
+ def process_response(env)
23
+ env[:raw_body] = env[:body] if @preserve_raw
24
+ env[:body] = parse(env[:body])
25
+ rescue StandardError, SyntaxError => e
26
+ raise Faraday::ParsingError.new(e, env[:response])
27
+ end
28
+
29
+ def parse(body)
30
+ ::JSON.parse(body, @parser_options || {}) unless body.strip.empty?
31
+ end
32
+
33
+ def parse_response?(env)
34
+ process_response_type?(env) &&
35
+ env[:body].respond_to?(:to_str)
36
+ end
37
+
38
+ def process_response_type?(env)
39
+ type = response_type(env)
40
+ @content_types.empty? || @content_types.any? do |pattern|
41
+ pattern.is_a?(Regexp) ? type.match?(pattern) : type == pattern
42
+ end
43
+ end
44
+
45
+ def response_type(env)
46
+ type = env[:response_headers][CONTENT_TYPE].to_s
47
+ type = type.split(';', 2).first if type.index(';')
48
+ type
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ Faraday::Response.register_middleware(json: Faraday::Response::Json)
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'forwardable'
4
+ require 'logger'
4
5
  require 'faraday/logging/formatter'
5
6
 
6
7
  module Faraday
@@ -11,10 +12,7 @@ module Faraday
11
12
  class Logger < Middleware
12
13
  def initialize(app, logger = nil, options = {})
13
14
  super(app)
14
- logger ||= begin
15
- require 'logger'
16
- ::Logger.new($stdout)
17
- end
15
+ logger ||= ::Logger.new($stdout)
18
16
  formatter_class = options.delete(:formatter) || Logging::Formatter
19
17
  @formatter = formatter_class.new(logger: logger, options: options)
20
18
  yield @formatter if block_given?
@@ -22,7 +22,8 @@ module Faraday
22
22
 
23
23
  register_middleware File.expand_path('response', __dir__),
24
24
  raise_error: [:RaiseError, 'raise_error'],
25
- logger: [:Logger, 'logger']
25
+ logger: [:Logger, 'logger'],
26
+ json: [:Json, 'json']
26
27
 
27
28
  def initialize(env = nil)
28
29
  @env = Env.from(env) if env
@@ -42,6 +43,7 @@ module Faraday
42
43
  def headers
43
44
  finished? ? env.response_headers : {}
44
45
  end
46
+
45
47
  def_delegator :headers, :[]
46
48
 
47
49
  def body
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Faraday
4
- VERSION = '1.8.0'
4
+ VERSION = '1.10.3'
5
5
  end
data/lib/faraday.rb CHANGED
@@ -24,9 +24,15 @@ require 'faraday/adapter'
24
24
  require 'faraday/request'
25
25
  require 'faraday/response'
26
26
  require 'faraday/error'
27
- require 'faraday/file_part'
28
- require 'faraday/param_part'
27
+ require 'faraday/request/url_encoded' # needed by multipart
29
28
 
29
+ # External Middleware gems and their aliases
30
+ require 'faraday/multipart'
31
+ require 'faraday/retry'
32
+ Faraday::Request::Multipart = Faraday::Multipart::Middleware
33
+ Faraday::Request::Retry = Faraday::Retry::Middleware
34
+
35
+ # External Adapters gems
30
36
  unless defined?(JRUBY_VERSION)
31
37
  require 'faraday/em_http'
32
38
  require 'faraday/em_synchrony'
@@ -51,6 +57,8 @@ require 'faraday/rack'
51
57
  # conn.get '/'
52
58
  #
53
59
  module Faraday
60
+ CONTENT_TYPE = 'Content-Type'
61
+
54
62
  class << self
55
63
  # The root path that Faraday is being loaded from.
56
64
  #
@@ -0,0 +1,147 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Faraday::DeprecatedClass do
4
+ class SampleClass < StandardError
5
+ attr_accessor :foo
6
+
7
+ def initialize(foo = nil)
8
+ @foo = foo || :foo
9
+ end
10
+ end
11
+
12
+ SampleDeprecatedClass = Faraday::DeprecatedClass.proxy_class(SampleClass)
13
+
14
+ it 'does not raise error for deprecated classes but prints an error message' do
15
+ error_message, foobar = with_warn_squelching { SampleDeprecatedClass.new(:foo_bar) }
16
+ expect(foobar).to be_a(SampleClass)
17
+ expect(foobar.foo).to eq(:foo_bar)
18
+ expect(error_message).to match(
19
+ Regexp.new(
20
+ 'NOTE: SampleDeprecatedClass.new is deprecated; '\
21
+ 'use SampleClass.new instead. It will be removed in or after version 1.0'
22
+ )
23
+ )
24
+ end
25
+
26
+ it 'does not raise an error for inherited error-namespaced classes but prints an error message' do
27
+ error_message, = with_warn_squelching { Class.new(SampleDeprecatedClass) }
28
+
29
+ expect(error_message).to match(
30
+ Regexp.new(
31
+ 'NOTE: Inheriting SampleDeprecatedClass is deprecated; '\
32
+ 'use SampleClass instead. It will be removed in or after version 1.0'
33
+ )
34
+ )
35
+ end
36
+
37
+ it 'allows backward-compatible class to be subclassed' do
38
+ expect do
39
+ with_warn_squelching { Class.new(SampleDeprecatedClass) }
40
+ end.not_to raise_error
41
+ end
42
+
43
+ it 'allows rescuing of a current error with a deprecated error' do
44
+ expect { raise SampleClass, nil }.to raise_error(SampleDeprecatedClass)
45
+ end
46
+
47
+ it 'allows rescuing of a current error with a current error' do
48
+ expect { raise SampleClass, nil }.to raise_error(SampleClass)
49
+ end
50
+
51
+ it 'allows rescuing of a deprecated error with a deprecated error' do
52
+ expect { raise SampleDeprecatedClass, nil }.to raise_error(SampleDeprecatedClass)
53
+ end
54
+
55
+ it 'allows rescuing of a deprecated error with a current error' do
56
+ expect { raise SampleDeprecatedClass, nil }.to raise_error(SampleClass)
57
+ end
58
+
59
+ describe 'match behavior' do
60
+ class SampleDeprecatedClassA < SampleDeprecatedClass; end
61
+ class SampleDeprecatedClassB < SampleDeprecatedClass; end
62
+
63
+ class SampleDeprecatedClassAX < SampleDeprecatedClassA; end
64
+
65
+ class SampleClassA < SampleClass; end
66
+
67
+ describe 'undeprecated class' do
68
+ it 'is === to instance of deprecated class' do
69
+ expect(SampleDeprecatedClass.new.is_a?(SampleClass)).to be true
70
+ end
71
+
72
+ it 'is === to instance of subclass of deprecated class' do
73
+ expect(SampleDeprecatedClassA.new.is_a?(SampleClass)).to be true
74
+ end
75
+
76
+ it 'is === to instance of subclass of subclass of deprecated class' do
77
+ expect(SampleDeprecatedClassAX.new.is_a?(SampleClass)).to be true
78
+ end
79
+ end
80
+
81
+ describe 'subclass of undeprecated class' do
82
+ it 'is not === to instance of undeprecated class' do
83
+ expect(SampleClass.new.is_a?(SampleClassA)).to be false
84
+ end
85
+
86
+ it 'is not === to instance of deprecated class' do
87
+ expect(SampleDeprecatedClass.new.is_a?(SampleClassA)).to be false
88
+ end
89
+ end
90
+
91
+ describe 'deprecated class' do
92
+ it 'is === to instance of undeprecated class' do
93
+ expect(SampleDeprecatedClass.new.is_a?(SampleClass)).to be true
94
+ end
95
+
96
+ it 'is === to instance of subclass of undeprecated class' do
97
+ expect(SampleClassA.superclass == SampleDeprecatedClass.superclass).to be true
98
+ end
99
+
100
+ it 'is === to instance of subclass of deprecated class' do
101
+ expect(SampleDeprecatedClassA.new.is_a?(SampleDeprecatedClass)).to be true
102
+ end
103
+
104
+ it 'is === to instance of subclass of subclass of deprecated class' do
105
+ expect(SampleDeprecatedClassAX.new.is_a?(SampleDeprecatedClass)).to be true
106
+ end
107
+ end
108
+
109
+ describe 'subclass of deprecated class' do
110
+ it 'is not === to instance of subclass of undeprecated class' do
111
+ expect(SampleClass.new.is_a?(SampleDeprecatedClassA)).to be false
112
+ end
113
+
114
+ it 'is not === to instance of another subclass of deprecated class' do
115
+ expect(SampleDeprecatedClassB.new.is_a?(SampleDeprecatedClassA)).to be false
116
+ end
117
+
118
+ it 'is === to instance of its subclass' do
119
+ expect(SampleDeprecatedClassAX.new.is_a?(SampleDeprecatedClassA)).to be true
120
+ end
121
+
122
+ it 'is === to instance of deprecated class' do
123
+ expect(SampleDeprecatedClassB.new.is_a?(SampleDeprecatedClass)).to be true
124
+ end
125
+ end
126
+
127
+ describe 'subclass of subclass of deprecated class' do
128
+ it 'is not === to instance of subclass of another subclass of deprecated class' do
129
+ expect(SampleDeprecatedClassB.new.is_a?(SampleDeprecatedClassAX)).to be false
130
+ end
131
+
132
+ it 'is not === to instance of its superclass' do
133
+ expect(SampleDeprecatedClass.new.is_a?(SampleDeprecatedClassA)).to be false
134
+ end
135
+ end
136
+ end
137
+
138
+ def with_warn_squelching
139
+ stderr_catcher = StringIO.new
140
+ original_stderr = $stderr
141
+ $stderr = stderr_catcher
142
+ result = yield if block_given?
143
+ [stderr_catcher.tap(&:rewind).string, result]
144
+ ensure
145
+ $stderr = original_stderr
146
+ end
147
+ end