faraday 1.0.1 → 1.10.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +104 -0
  3. data/LICENSE.md +1 -1
  4. data/README.md +3 -5
  5. data/examples/client_spec.rb +35 -3
  6. data/examples/client_test.rb +41 -2
  7. data/lib/faraday/adapter/test.rb +59 -43
  8. data/lib/faraday/adapter.rb +2 -12
  9. data/lib/faraday/autoload.rb +2 -10
  10. data/lib/faraday/connection.rb +37 -9
  11. data/lib/faraday/dependency_loader.rb +3 -1
  12. data/lib/faraday/deprecate.rb +110 -0
  13. data/lib/faraday/encoders/flat_params_encoder.rb +9 -2
  14. data/lib/faraday/encoders/nested_params_encoder.rb +7 -2
  15. data/lib/faraday/error.rb +20 -6
  16. data/lib/faraday/methods.rb +6 -0
  17. data/lib/faraday/middleware.rb +14 -4
  18. data/lib/faraday/options/proxy_options.rb +4 -0
  19. data/lib/faraday/options.rb +4 -8
  20. data/lib/faraday/rack_builder.rb +13 -12
  21. data/lib/faraday/request/authorization.rb +14 -7
  22. data/lib/faraday/request/json.rb +55 -0
  23. data/lib/faraday/request.rb +19 -11
  24. data/lib/faraday/response/json.rb +54 -0
  25. data/lib/faraday/response/logger.rb +2 -4
  26. data/lib/faraday/response/raise_error.rb +12 -1
  27. data/lib/faraday/response.rb +3 -7
  28. data/lib/faraday/utils/headers.rb +2 -2
  29. data/lib/faraday/utils.rb +2 -2
  30. data/lib/faraday/version.rb +5 -0
  31. data/lib/faraday.rb +67 -40
  32. data/spec/faraday/adapter/em_http_spec.rb +39 -37
  33. data/spec/faraday/adapter/em_synchrony_spec.rb +11 -9
  34. data/spec/faraday/adapter/test_spec.rb +377 -0
  35. data/spec/faraday/connection_spec.rb +45 -0
  36. data/spec/faraday/deprecate_spec.rb +147 -0
  37. data/spec/faraday/error_spec.rb +15 -0
  38. data/spec/faraday/middleware_spec.rb +32 -6
  39. data/spec/faraday/options/proxy_options_spec.rb +7 -0
  40. data/spec/faraday/params_encoders/flat_spec.rb +8 -0
  41. data/spec/faraday/params_encoders/nested_spec.rb +8 -0
  42. data/spec/faraday/rack_builder_spec.rb +149 -0
  43. data/spec/faraday/request/authorization_spec.rb +10 -2
  44. data/spec/faraday/request/json_spec.rb +111 -0
  45. data/spec/faraday/request_spec.rb +16 -5
  46. data/spec/faraday/response/json_spec.rb +119 -0
  47. data/spec/faraday/response/raise_error_spec.rb +63 -0
  48. data/spec/spec_helper.rb +2 -0
  49. data/spec/support/shared_examples/adapter.rb +2 -1
  50. data/spec/support/shared_examples/request_method.rb +39 -11
  51. metadata +156 -30
  52. data/lib/faraday/adapter/em_http.rb +0 -286
  53. data/lib/faraday/adapter/em_http_ssl_patch.rb +0 -62
  54. data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +0 -69
  55. data/lib/faraday/adapter/em_synchrony.rb +0 -150
  56. data/lib/faraday/adapter/excon.rb +0 -124
  57. data/lib/faraday/adapter/httpclient.rb +0 -152
  58. data/lib/faraday/adapter/net_http.rb +0 -219
  59. data/lib/faraday/adapter/net_http_persistent.rb +0 -91
  60. data/lib/faraday/adapter/patron.rb +0 -132
  61. data/lib/faraday/adapter/rack.rb +0 -75
  62. data/lib/faraday/file_part.rb +0 -128
  63. data/lib/faraday/param_part.rb +0 -53
  64. data/lib/faraday/request/multipart.rb +0 -99
  65. data/lib/faraday/request/retry.rb +0 -239
  66. data/spec/faraday/adapter/net_http_persistent_spec.rb +0 -57
  67. data/spec/faraday/request/multipart_spec.rb +0 -274
  68. data/spec/faraday/request/retry_spec.rb +0 -242
@@ -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
@@ -33,9 +33,9 @@ module Faraday
33
33
  key = key.to_s if key.is_a?(Symbol)
34
34
  [key, value]
35
35
  end
36
- # Useful default for OAuth and caching.
36
+
37
37
  # Only to be used for non-Array inputs. Arrays should preserve order.
38
- params.sort!
38
+ params.sort! if @sort_params
39
39
  end
40
40
 
41
41
  # The params have form [['key1', 'value1'], ['key2', 'value2']].
@@ -94,5 +94,12 @@ module Faraday
94
94
  end
95
95
  end
96
96
  end
97
+
98
+ class << self
99
+ attr_accessor :sort_params
100
+ end
101
+
102
+ # Useful default for OAuth and caching.
103
+ @sort_params = true
97
104
  end
98
105
  end
@@ -21,9 +21,9 @@ module Faraday
21
21
  key = key.to_s if key.is_a?(Symbol)
22
22
  [key, value]
23
23
  end
24
- # Useful default for OAuth and caching.
24
+
25
25
  # Only to be used for non-Array inputs. Arrays should preserve order.
26
- params.sort!
26
+ params.sort! if @sort_params
27
27
  end
28
28
 
29
29
  # The params have form [['key1', 'value1'], ['key2', 'value2']].
@@ -161,10 +161,15 @@ module Faraday
161
161
  # for your requests.
162
162
  module NestedParamsEncoder
163
163
  class << self
164
+ attr_accessor :sort_params
165
+
164
166
  extend Forwardable
165
167
  def_delegators :'Faraday::Utils', :escape, :unescape
166
168
  end
167
169
 
170
+ # Useful default for OAuth and caching.
171
+ @sort_params = true
172
+
168
173
  extend EncodeMethods
169
174
  extend DecodeMethods
170
175
  end
data/lib/faraday/error.rb CHANGED
@@ -28,6 +28,18 @@ module Faraday
28
28
  %(#<#{self.class}#{inner}>)
29
29
  end
30
30
 
31
+ def response_status
32
+ @response[:status] if @response
33
+ end
34
+
35
+ def response_headers
36
+ @response[:headers] if @response
37
+ end
38
+
39
+ def response_body
40
+ @response[:body] if @response
41
+ end
42
+
31
43
  protected
32
44
 
33
45
  # Pulls out potential parent exception and response hash, storing them in
@@ -38,6 +50,14 @@ module Faraday
38
50
  # :headers - String key/value hash of HTTP response header
39
51
  # values.
40
52
  # :body - Optional string HTTP response body.
53
+ # :request - Hash
54
+ # :method - Symbol with the request HTTP method.
55
+ # :url_path - String with the url path requested.
56
+ # :params - String key/value hash of query params
57
+ # present in the request.
58
+ # :headers - String key/value hash of HTTP request
59
+ # header values.
60
+ # :body - String HTTP request body.
41
61
  #
42
62
  # If a subclass has to call this, then it should pass a string message
43
63
  # to `super`. See NilStatusError.
@@ -123,10 +143,4 @@ module Faraday
123
143
  # Raised by FaradayMiddleware::ResponseMiddleware
124
144
  class ParsingError < Error
125
145
  end
126
-
127
- # Exception used to control the Retry middleware.
128
- #
129
- # @see Faraday::Request::Retry
130
- class RetriableResponse < Error
131
- end
132
146
  end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Faraday
4
+ METHODS_WITH_QUERY = %w[get head delete trace].freeze
5
+ METHODS_WITH_BODY = %w[post put patch].freeze
6
+ end
@@ -6,15 +6,25 @@ module Faraday
6
6
  extend MiddlewareRegistry
7
7
  extend DependencyLoader
8
8
 
9
- def initialize(app = nil)
9
+ attr_reader :app, :options
10
+
11
+ def initialize(app = nil, options = {})
10
12
  @app = app
13
+ @options = options
14
+ end
15
+
16
+ def call(env)
17
+ on_request(env) if respond_to?(:on_request)
18
+ app.call(env).on_complete do |environment|
19
+ on_complete(environment) if respond_to?(:on_complete)
20
+ end
11
21
  end
12
22
 
13
23
  def close
14
- if @app.respond_to?(:close)
15
- @app.close
24
+ if app.respond_to?(:close)
25
+ app.close
16
26
  else
17
- warn "#{@app} does not implement \#close!"
27
+ warn "#{app} does not implement \#close!"
18
28
  end
19
29
  end
20
30
  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
 
@@ -103,12 +103,10 @@ module Faraday
103
103
  end
104
104
 
105
105
  # Public
106
- def each_key
106
+ def each_key(&block)
107
107
  return to_enum(:each_key) unless block_given?
108
108
 
109
- keys.each do |key|
110
- yield(key)
111
- end
109
+ keys.each(&block)
112
110
  end
113
111
 
114
112
  # Public
@@ -119,12 +117,10 @@ module Faraday
119
117
  alias has_key? key?
120
118
 
121
119
  # Public
122
- def each_value
120
+ def each_value(&block)
123
121
  return to_enum(:each_value) unless block_given?
124
122
 
125
- values.each do |value|
126
- yield(value)
127
- end
123
+ values.each(&block)
128
124
  end
129
125
 
130
126
  # Public
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'ruby2_keywords'
3
4
  require 'faraday/adapter_registry'
4
5
 
5
6
  module Faraday
@@ -27,7 +28,7 @@ module Faraday
27
28
 
28
29
  attr_reader :name
29
30
 
30
- def initialize(klass, *args, &block)
31
+ ruby2_keywords def initialize(klass, *args, &block)
31
32
  @name = klass.to_s
32
33
  REGISTRY.set(klass) if klass.respond_to?(:name)
33
34
  @args = args
@@ -89,7 +90,7 @@ module Faraday
89
90
  @handlers.frozen?
90
91
  end
91
92
 
92
- def use(klass, *args, &block)
93
+ ruby2_keywords def use(klass, *args, &block)
93
94
  if klass.is_a? Symbol
94
95
  use_symbol(Faraday::Middleware, klass, *args, &block)
95
96
  else
@@ -99,15 +100,15 @@ module Faraday
99
100
  end
100
101
  end
101
102
 
102
- def request(key, *args, &block)
103
+ ruby2_keywords def request(key, *args, &block)
103
104
  use_symbol(Faraday::Request, key, *args, &block)
104
105
  end
105
106
 
106
- def response(key, *args, &block)
107
+ ruby2_keywords def response(key, *args, &block)
107
108
  use_symbol(Faraday::Response, key, *args, &block)
108
109
  end
109
110
 
110
- def adapter(klass = NO_ARGUMENT, *args, &block)
111
+ ruby2_keywords def adapter(klass = NO_ARGUMENT, *args, &block)
111
112
  return @adapter if klass == NO_ARGUMENT
112
113
 
113
114
  klass = Faraday::Adapter.lookup_middleware(klass) if klass.is_a?(Symbol)
@@ -116,7 +117,7 @@ module Faraday
116
117
 
117
118
  ## methods to push onto the various positions in the stack:
118
119
 
119
- def insert(index, *args, &block)
120
+ ruby2_keywords def insert(index, *args, &block)
120
121
  raise_if_locked
121
122
  index = assert_index(index)
122
123
  handler = self.class::Handler.new(*args, &block)
@@ -125,12 +126,12 @@ module Faraday
125
126
 
126
127
  alias insert_before insert
127
128
 
128
- def insert_after(index, *args, &block)
129
+ ruby2_keywords def insert_after(index, *args, &block)
129
130
  index = assert_index(index)
130
131
  insert(index + 1, *args, &block)
131
132
  end
132
133
 
133
- def swap(index, *args, &block)
134
+ ruby2_keywords def swap(index, *args, &block)
134
135
  raise_if_locked
135
136
  index = assert_index(index)
136
137
  @handlers.delete_at(index)
@@ -186,7 +187,7 @@ module Faraday
186
187
  end
187
188
 
188
189
  # ENV Keys
189
- # :method - a symbolized request method (:get, :post)
190
+ # :http_method - a symbolized request HTTP method (:get, :post)
190
191
  # :body - the request body that will eventually be converted to a string.
191
192
  # :url - URI instance for the current request.
192
193
  # :status - HTTP response status code
@@ -207,7 +208,7 @@ module Faraday
207
208
  request.options.params_encoder
208
209
  )
209
210
 
210
- Env.new(request.method, request.body, exclusive_url,
211
+ Env.new(request.http_method, request.body, exclusive_url,
211
212
  request.options, request.headers, connection.ssl,
212
213
  connection.parallel_manager)
213
214
  end
@@ -231,10 +232,10 @@ module Faraday
231
232
  end
232
233
 
233
234
  def is_adapter?(klass) # rubocop:disable Naming/PredicateName
234
- klass.ancestors.include?(Faraday::Adapter)
235
+ klass <= Faraday::Adapter
235
236
  end
236
237
 
237
- def use_symbol(mod, key, *args, &block)
238
+ ruby2_keywords def use_symbol(mod, key, *args, &block)
238
239
  use(mod.lookup_middleware(key), *args, &block)
239
240
  end
240
241
 
@@ -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
@@ -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)
@@ -12,7 +12,7 @@ module Faraday
12
12
  # req.body = 'abc'
13
13
  # end
14
14
  #
15
- # @!attribute method
15
+ # @!attribute http_method
16
16
  # @return [Symbol] the HTTP method of the Request
17
17
  # @!attribute path
18
18
  # @return [URI, String] the path
@@ -26,15 +26,15 @@ module Faraday
26
26
  # @return [RequestOptions] options
27
27
  #
28
28
  # rubocop:disable Style/StructInheritance
29
- class Request < Struct.new(:method, :path, :params, :headers, :body, :options)
29
+ class Request < Struct.new(
30
+ :http_method, :path, :params, :headers, :body, :options
31
+ )
30
32
  # rubocop:enable Style/StructInheritance
31
33
 
32
34
  extend MiddlewareRegistry
33
35
 
34
36
  register_middleware File.expand_path('request', __dir__),
35
37
  url_encoded: [:UrlEncoded, 'url_encoded'],
36
- multipart: [:Multipart, 'multipart'],
37
- retry: [:Retry, 'retry'],
38
38
  authorization: [:Authorization, 'authorization'],
39
39
  basic_auth: [
40
40
  :BasicAuthentication,
@@ -44,7 +44,8 @@ module Faraday
44
44
  :TokenAuthentication,
45
45
  'token_authentication'
46
46
  ],
47
- instrumentation: [:Instrumentation, 'instrumentation']
47
+ instrumentation: [:Instrumentation, 'instrumentation'],
48
+ json: [:Json, 'json']
48
49
 
49
50
  # @param request_method [String]
50
51
  # @yield [request] for block customization, if block given
@@ -56,6 +57,13 @@ module Faraday
56
57
  end
57
58
  end
58
59
 
60
+ def method
61
+ http_method
62
+ end
63
+
64
+ extend Faraday::Deprecate
65
+ deprecate :method, :http_method, '2.0'
66
+
59
67
  # Replace params, preserving the existing hash type.
60
68
  #
61
69
  # @param hash [Hash] new params
@@ -116,7 +124,7 @@ module Faraday
116
124
  # @return [Hash] the hash ready to be serialized in Marshal.
117
125
  def marshal_dump
118
126
  {
119
- method: method,
127
+ http_method: http_method,
120
128
  body: body,
121
129
  headers: headers,
122
130
  path: path,
@@ -129,17 +137,17 @@ module Faraday
129
137
  # Restores the instance variables according to the +serialised+.
130
138
  # @param serialised [Hash] the serialised object.
131
139
  def marshal_load(serialised)
132
- self.method = serialised[:method]
133
- self.body = serialised[:body]
140
+ self.http_method = serialised[:http_method]
141
+ self.body = serialised[:body]
134
142
  self.headers = serialised[:headers]
135
- self.path = serialised[:path]
136
- self.params = serialised[:params]
143
+ self.path = serialised[:path]
144
+ self.params = serialised[:params]
137
145
  self.options = serialised[:options]
138
146
  end
139
147
 
140
148
  # @return [Env] the Env for this Request
141
149
  def to_env(connection)
142
- Env.new(method, body, connection.build_exclusive_url(path, params),
150
+ Env.new(http_method, body, connection.build_exclusive_url(path, params),
143
151
  options, headers, connection.ssl, connection.parallel_manager)
144
152
  end
145
153
  end
@@ -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?
@@ -38,7 +38,18 @@ module Faraday
38
38
  end
39
39
 
40
40
  def response_values(env)
41
- { status: env.status, headers: env.response_headers, body: env.body }
41
+ {
42
+ status: env.status,
43
+ headers: env.response_headers,
44
+ body: env.body,
45
+ request: {
46
+ method: env.method,
47
+ url_path: env.url.path,
48
+ params: env.params,
49
+ headers: env.request_headers,
50
+ body: env.request_body
51
+ }
52
+ }
42
53
  end
43
54
  end
44
55
  end