faraday 0.17.3 → 2.7.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (124) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +350 -8
  3. data/LICENSE.md +1 -1
  4. data/README.md +27 -367
  5. data/Rakefile +1 -7
  6. data/examples/client_spec.rb +119 -0
  7. data/examples/client_test.rb +144 -0
  8. data/lib/faraday/adapter/test.rb +170 -72
  9. data/lib/faraday/adapter.rb +69 -23
  10. data/lib/faraday/adapter_registry.rb +30 -0
  11. data/lib/faraday/connection.rb +309 -233
  12. data/lib/faraday/encoders/flat_params_encoder.rb +105 -0
  13. data/lib/faraday/encoders/nested_params_encoder.rb +183 -0
  14. data/lib/faraday/error.rb +31 -42
  15. data/lib/faraday/logging/formatter.rb +122 -0
  16. data/lib/faraday/methods.rb +6 -0
  17. data/lib/faraday/middleware.rb +21 -25
  18. data/lib/faraday/middleware_registry.rb +83 -0
  19. data/lib/faraday/options/connection_options.rb +22 -0
  20. data/lib/faraday/options/env.rb +205 -0
  21. data/lib/faraday/options/proxy_options.rb +32 -0
  22. data/lib/faraday/options/request_options.rb +22 -0
  23. data/lib/faraday/options/ssl_options.rb +69 -0
  24. data/lib/faraday/options.rb +38 -193
  25. data/lib/faraday/parameters.rb +4 -197
  26. data/lib/faraday/rack_builder.rb +91 -76
  27. data/lib/faraday/request/authorization.rb +42 -29
  28. data/lib/faraday/request/instrumentation.rb +47 -27
  29. data/lib/faraday/request/json.rb +55 -0
  30. data/lib/faraday/request/url_encoded.rb +48 -24
  31. data/lib/faraday/request.rb +64 -42
  32. data/lib/faraday/response/json.rb +54 -0
  33. data/lib/faraday/response/logger.rb +24 -67
  34. data/lib/faraday/response/raise_error.rb +57 -18
  35. data/lib/faraday/response.rb +26 -32
  36. data/lib/faraday/utils/headers.rb +144 -0
  37. data/lib/faraday/utils/params_hash.rb +61 -0
  38. data/lib/faraday/utils.rb +47 -251
  39. data/lib/faraday/version.rb +5 -0
  40. data/lib/faraday.rb +108 -198
  41. data/spec/external_adapters/faraday_specs_setup.rb +14 -0
  42. data/spec/faraday/adapter/test_spec.rb +442 -0
  43. data/spec/faraday/adapter_registry_spec.rb +28 -0
  44. data/spec/faraday/adapter_spec.rb +55 -0
  45. data/spec/faraday/connection_spec.rb +808 -0
  46. data/spec/faraday/error_spec.rb +12 -54
  47. data/spec/faraday/middleware_registry_spec.rb +31 -0
  48. data/spec/faraday/middleware_spec.rb +70 -0
  49. data/spec/faraday/options/env_spec.rb +76 -0
  50. data/spec/faraday/options/options_spec.rb +297 -0
  51. data/spec/faraday/options/proxy_options_spec.rb +44 -0
  52. data/spec/faraday/options/request_options_spec.rb +19 -0
  53. data/spec/faraday/params_encoders/flat_spec.rb +42 -0
  54. data/spec/faraday/params_encoders/nested_spec.rb +150 -0
  55. data/spec/faraday/rack_builder_spec.rb +317 -0
  56. data/spec/faraday/request/authorization_spec.rb +118 -0
  57. data/spec/faraday/request/instrumentation_spec.rb +74 -0
  58. data/spec/faraday/request/json_spec.rb +111 -0
  59. data/spec/faraday/request/url_encoded_spec.rb +93 -0
  60. data/spec/faraday/request_spec.rb +110 -0
  61. data/spec/faraday/response/json_spec.rb +117 -0
  62. data/spec/faraday/response/logger_spec.rb +248 -0
  63. data/spec/faraday/response/raise_error_spec.rb +81 -15
  64. data/spec/faraday/response_spec.rb +77 -0
  65. data/spec/faraday/utils/headers_spec.rb +100 -0
  66. data/spec/faraday/utils_spec.rb +118 -0
  67. data/spec/faraday_spec.rb +37 -0
  68. data/spec/spec_helper.rb +63 -36
  69. data/spec/support/disabling_stub.rb +14 -0
  70. data/spec/support/fake_safe_buffer.rb +15 -0
  71. data/spec/support/helper_methods.rb +96 -0
  72. data/spec/support/shared_examples/adapter.rb +105 -0
  73. data/spec/support/shared_examples/params_encoder.rb +18 -0
  74. data/spec/support/shared_examples/request_method.rb +263 -0
  75. data/spec/support/streaming_response_checker.rb +35 -0
  76. metadata +76 -59
  77. data/lib/faraday/adapter/em_http.rb +0 -243
  78. data/lib/faraday/adapter/em_http_ssl_patch.rb +0 -56
  79. data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +0 -66
  80. data/lib/faraday/adapter/em_synchrony.rb +0 -106
  81. data/lib/faraday/adapter/excon.rb +0 -82
  82. data/lib/faraday/adapter/httpclient.rb +0 -128
  83. data/lib/faraday/adapter/net_http.rb +0 -152
  84. data/lib/faraday/adapter/net_http_persistent.rb +0 -68
  85. data/lib/faraday/adapter/patron.rb +0 -95
  86. data/lib/faraday/adapter/rack.rb +0 -58
  87. data/lib/faraday/adapter/typhoeus.rb +0 -12
  88. data/lib/faraday/autoload.rb +0 -84
  89. data/lib/faraday/deprecate.rb +0 -107
  90. data/lib/faraday/request/basic_authentication.rb +0 -13
  91. data/lib/faraday/request/multipart.rb +0 -68
  92. data/lib/faraday/request/retry.rb +0 -213
  93. data/lib/faraday/request/token_authentication.rb +0 -15
  94. data/lib/faraday/upload_io.rb +0 -67
  95. data/spec/faraday/deprecate_spec.rb +0 -69
  96. data/test/adapters/default_test.rb +0 -14
  97. data/test/adapters/em_http_test.rb +0 -30
  98. data/test/adapters/em_synchrony_test.rb +0 -32
  99. data/test/adapters/excon_test.rb +0 -30
  100. data/test/adapters/httpclient_test.rb +0 -34
  101. data/test/adapters/integration.rb +0 -263
  102. data/test/adapters/logger_test.rb +0 -136
  103. data/test/adapters/net_http_persistent_test.rb +0 -114
  104. data/test/adapters/net_http_test.rb +0 -79
  105. data/test/adapters/patron_test.rb +0 -40
  106. data/test/adapters/rack_test.rb +0 -38
  107. data/test/adapters/test_middleware_test.rb +0 -157
  108. data/test/adapters/typhoeus_test.rb +0 -38
  109. data/test/authentication_middleware_test.rb +0 -65
  110. data/test/composite_read_io_test.rb +0 -109
  111. data/test/connection_test.rb +0 -738
  112. data/test/env_test.rb +0 -268
  113. data/test/helper.rb +0 -75
  114. data/test/live_server.rb +0 -67
  115. data/test/middleware/instrumentation_test.rb +0 -88
  116. data/test/middleware/retry_test.rb +0 -282
  117. data/test/middleware_stack_test.rb +0 -260
  118. data/test/multibyte.txt +0 -1
  119. data/test/options_test.rb +0 -333
  120. data/test/parameters_test.rb +0 -157
  121. data/test/request_middleware_test.rb +0 -126
  122. data/test/response_middleware_test.rb +0 -72
  123. data/test/strawberry.rb +0 -2
  124. data/test/utils_test.rb +0 -98
@@ -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)
@@ -1,36 +1,60 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Faraday
2
- class Request::UrlEncoded < Faraday::Middleware
3
- CONTENT_TYPE = 'Content-Type'.freeze unless defined? CONTENT_TYPE
4
+ class Request
5
+ # Middleware for supporting urlencoded requests.
6
+ class UrlEncoded < Faraday::Middleware
7
+ unless defined?(::Faraday::Request::UrlEncoded::CONTENT_TYPE)
8
+ CONTENT_TYPE = 'Content-Type'
9
+ end
4
10
 
5
- class << self
6
- attr_accessor :mime_type
7
- end
8
- self.mime_type = 'application/x-www-form-urlencoded'.freeze
11
+ class << self
12
+ attr_accessor :mime_type
13
+ end
14
+ self.mime_type = 'application/x-www-form-urlencoded'
9
15
 
10
- def call(env)
11
- match_content_type(env) do |data|
12
- params = Faraday::Utils::ParamsHash[data]
13
- env.body = params.to_query(env.params_encoder)
16
+ # Encodes as "application/x-www-form-urlencoded" if not already encoded or
17
+ # of another type.
18
+ #
19
+ # @param env [Faraday::Env]
20
+ def call(env)
21
+ match_content_type(env) do |data|
22
+ params = Faraday::Utils::ParamsHash[data]
23
+ env.body = params.to_query(env.params_encoder)
24
+ end
25
+ @app.call env
14
26
  end
15
- @app.call env
16
- end
17
27
 
18
- def match_content_type(env)
19
- if process_request?(env)
28
+ # @param env [Faraday::Env]
29
+ # @yield [request_body] Body of the request
30
+ def match_content_type(env)
31
+ return unless process_request?(env)
32
+
20
33
  env.request_headers[CONTENT_TYPE] ||= self.class.mime_type
21
- yield(env.body) unless env.body.respond_to?(:to_str)
34
+ return if env.body.respond_to?(:to_str) || env.body.respond_to?(:read)
35
+
36
+ yield(env.body)
22
37
  end
23
- end
24
38
 
25
- def process_request?(env)
26
- type = request_type(env)
27
- env.body and (type.empty? or type == self.class.mime_type)
28
- end
39
+ # @param env [Faraday::Env]
40
+ #
41
+ # @return [Boolean] True if the request has a body and its Content-Type is
42
+ # urlencoded.
43
+ def process_request?(env)
44
+ type = request_type(env)
45
+ env.body && (type.empty? || (type == self.class.mime_type))
46
+ end
29
47
 
30
- def request_type(env)
31
- type = env.request_headers[CONTENT_TYPE].to_s
32
- type = type.split(';', 2).first if type.index(';')
33
- type
48
+ # @param env [Faraday::Env]
49
+ #
50
+ # @return [String]
51
+ def request_type(env)
52
+ type = env.request_headers[CONTENT_TYPE].to_s
53
+ type = type.split(';', 2).first if type.index(';')
54
+ type
55
+ end
34
56
  end
35
57
  end
36
58
  end
59
+
60
+ Faraday::Request.register_middleware(url_encoded: Faraday::Request::UrlEncoded)
@@ -1,6 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Faraday
2
- # Used to setup urls, params, headers, and the request body in a sane manner.
4
+ # Used to setup URLs, params, headers, and the request body in a sane manner.
3
5
  #
6
+ # @example
4
7
  # @connection.post do |req|
5
8
  # req.url 'http://localhost', 'a' => '1' # 'http://localhost?a=1'
6
9
  # req.headers['b'] = '2' # Header
@@ -9,25 +12,38 @@ module Faraday
9
12
  # req.body = 'abc'
10
13
  # end
11
14
  #
12
- class Request < Struct.new(:method, :path, :params, :headers, :body, :options)
13
- extend MiddlewareRegistry
15
+ # @!attribute http_method
16
+ # @return [Symbol] the HTTP method of the Request
17
+ # @!attribute path
18
+ # @return [URI, String] the path
19
+ # @!attribute params
20
+ # @return [Hash] query parameters
21
+ # @!attribute headers
22
+ # @return [Faraday::Utils::Headers] headers
23
+ # @!attribute body
24
+ # @return [String] body
25
+ # @!attribute options
26
+ # @return [RequestOptions] options
27
+ #
28
+ # rubocop:disable Style/StructInheritance
29
+ class Request < Struct.new(:http_method, :path, :params, :headers, :body, :options)
30
+ # rubocop:enable Style/StructInheritance
14
31
 
15
- register_middleware File.expand_path('../request', __FILE__),
16
- :url_encoded => [:UrlEncoded, 'url_encoded'],
17
- :multipart => [:Multipart, 'multipart'],
18
- :retry => [:Retry, 'retry'],
19
- :authorization => [:Authorization, 'authorization'],
20
- :basic_auth => [:BasicAuthentication, 'basic_authentication'],
21
- :token_auth => [:TokenAuthentication, 'token_authentication'],
22
- :instrumentation => [:Instrumentation, 'instrumentation']
32
+ extend MiddlewareRegistry
23
33
 
34
+ # @param request_method [String]
35
+ # @yield [request] for block customization, if block given
36
+ # @yieldparam request [Request]
37
+ # @return [Request]
24
38
  def self.create(request_method)
25
39
  new(request_method).tap do |request|
26
40
  yield(request) if block_given?
27
41
  end
28
42
  end
29
43
 
30
- # Public: Replace params, preserving the existing hash type
44
+ # Replace params, preserving the existing hash type.
45
+ #
46
+ # @param hash [Hash] new params
31
47
  def params=(hash)
32
48
  if params
33
49
  params.replace hash
@@ -36,7 +52,9 @@ module Faraday
36
52
  end
37
53
  end
38
54
 
39
- # Public: Replace request headers, preserving the existing hash type
55
+ # Replace request headers, preserving the existing hash type.
56
+ #
57
+ # @param hash [Hash] new headers
40
58
  def headers=(hash)
41
59
  if headers
42
60
  headers.replace hash
@@ -45,9 +63,14 @@ module Faraday
45
63
  end
46
64
  end
47
65
 
66
+ # Update path and params.
67
+ #
68
+ # @param path [URI, String]
69
+ # @param params [Hash, nil]
70
+ # @return [void]
48
71
  def url(path, params = nil)
49
72
  if path.respond_to? :query
50
- if query = path.query
73
+ if (query = path.query)
51
74
  path = path.dup
52
75
  path.query = nil
53
76
  end
@@ -61,54 +84,53 @@ module Faraday
61
84
  self.params.update(params) if params
62
85
  end
63
86
 
87
+ # @param key [Object] key to look up in headers
88
+ # @return [Object] value of the given header name
64
89
  def [](key)
65
90
  headers[key]
66
91
  end
67
92
 
93
+ # @param key [Object] key of header to write
94
+ # @param value [Object] value of header
68
95
  def []=(key, value)
69
96
  headers[key] = value
70
97
  end
71
98
 
99
+ # Marshal serialization support.
100
+ #
101
+ # @return [Hash] the hash ready to be serialized in Marshal.
72
102
  def marshal_dump
73
103
  {
74
- :method => method,
75
- :body => body,
76
- :headers => headers,
77
- :path => path,
78
- :params => params,
79
- :options => options
104
+ http_method: http_method,
105
+ body: body,
106
+ headers: headers,
107
+ path: path,
108
+ params: params,
109
+ options: options
80
110
  }
81
111
  end
82
112
 
113
+ # Marshal serialization support.
114
+ # Restores the instance variables according to the +serialised+.
115
+ # @param serialised [Hash] the serialised object.
83
116
  def marshal_load(serialised)
84
- self.method = serialised[:method]
85
- self.body = serialised[:body]
117
+ self.http_method = serialised[:http_method]
118
+ self.body = serialised[:body]
86
119
  self.headers = serialised[:headers]
87
- self.path = serialised[:path]
88
- self.params = serialised[:params]
120
+ self.path = serialised[:path]
121
+ self.params = serialised[:params]
89
122
  self.options = serialised[:options]
90
123
  end
91
124
 
92
- # ENV Keys
93
- # :method - a symbolized request method (:get, :post)
94
- # :body - the request body that will eventually be converted to a string.
95
- # :url - URI instance for the current request.
96
- # :status - HTTP response status code
97
- # :request_headers - hash of HTTP Headers to be sent to the server
98
- # :response_headers - Hash of HTTP headers from the server
99
- # :parallel_manager - sent if the connection is in parallel mode
100
- # :request - Hash of options for configuring the request.
101
- # :timeout - open/read timeout Integer in seconds
102
- # :open_timeout - read timeout Integer in seconds
103
- # :proxy - Hash of proxy options
104
- # :uri - Proxy Server URI
105
- # :user - Proxy server username
106
- # :password - Proxy server password
107
- # :ssl - Hash of options for configuring SSL requests.
125
+ # @return [Env] the Env for this Request
108
126
  def to_env(connection)
109
- Env.new(method, body, connection.build_exclusive_url(path, params),
110
- options, headers, connection.ssl, connection.parallel_manager)
127
+ Env.new(http_method, body, connection.build_exclusive_url(path, params),
128
+ options, headers, connection.ssl, connection.parallel_manager)
111
129
  end
112
130
  end
113
131
  end
114
132
 
133
+ require 'faraday/request/authorization'
134
+ require 'faraday/request/instrumentation'
135
+ require 'faraday/request/json'
136
+ require 'faraday/request/url_encoded'
@@ -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, parser_options: nil, content_type: /\bjson$/, preserve_raw: false)
10
+ super(app)
11
+ @parser_options = parser_options
12
+ @content_types = Array(content_type)
13
+ @preserve_raw = 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,80 +1,37 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'forwardable'
4
+ require 'logger'
5
+ require 'faraday/logging/formatter'
2
6
 
3
7
  module Faraday
4
- class Response::Logger < Response::Middleware
5
- extend Forwardable
6
-
7
- DEFAULT_OPTIONS = { :headers => true, :bodies => false }
8
-
9
- def initialize(app, logger = nil, options = {})
10
- super(app)
11
- @logger = logger || begin
12
- require 'logger'
13
- ::Logger.new($stdout)
8
+ class Response
9
+ # Logger is a middleware that logs internal events in the HTTP request
10
+ # lifecycle to a given Logger object. By default, this logs to STDOUT. See
11
+ # Faraday::Logging::Formatter to see specifically what is logged.
12
+ class Logger < Middleware
13
+ def initialize(app, logger = nil, options = {})
14
+ super(app)
15
+ logger ||= ::Logger.new($stdout)
16
+ formatter_class = options.delete(:formatter) || Logging::Formatter
17
+ @formatter = formatter_class.new(logger: logger, options: options)
18
+ yield @formatter if block_given?
14
19
  end
15
- @filter = []
16
- @options = DEFAULT_OPTIONS.merge(options)
17
- yield self if block_given?
18
- end
19
-
20
- def_delegators :@logger, :debug, :info, :warn, :error, :fatal
21
-
22
- def call(env)
23
- info('request') { "#{env.method.upcase} #{apply_filters(env.url.to_s)}" }
24
- debug('request') { apply_filters( dump_headers env.request_headers ) } if log_headers?(:request)
25
- debug('request') { apply_filters( dump_body(env[:body]) ) } if env[:body] && log_body?(:request)
26
- super
27
- end
28
-
29
- def on_complete(env)
30
- info('response') { "Status #{env.status.to_s}" }
31
- debug('response') { apply_filters( dump_headers env.response_headers ) } if log_headers?(:response)
32
- debug('response') { apply_filters( dump_body env[:body] ) } if env[:body] && log_body?(:response)
33
- end
34
-
35
- def filter(filter_word, filter_replacement)
36
- @filter.push([ filter_word, filter_replacement ])
37
- end
38
-
39
- private
40
20
 
41
- def dump_headers(headers)
42
- headers.map { |k, v| "#{k}: #{v.inspect}" }.join("\n")
43
- end
44
-
45
- def dump_body(body)
46
- if body.respond_to?(:to_str)
47
- body.to_str
48
- else
49
- pretty_inspect(body)
21
+ def call(env)
22
+ @formatter.request(env)
23
+ super
50
24
  end
51
- end
52
25
 
53
- def pretty_inspect(body)
54
- require 'pp' unless body.respond_to?(:pretty_inspect)
55
- body.pretty_inspect
56
- end
57
-
58
- def log_headers?(type)
59
- case @options[:headers]
60
- when Hash then @options[:headers][type]
61
- else @options[:headers]
26
+ def on_complete(env)
27
+ @formatter.response(env)
62
28
  end
63
- end
64
29
 
65
- def log_body?(type)
66
- case @options[:bodies]
67
- when Hash then @options[:bodies][type]
68
- else @options[:bodies]
30
+ def on_error(exc)
31
+ @formatter.exception(exc) if @formatter.respond_to?(:exception)
69
32
  end
70
33
  end
71
-
72
- def apply_filters(output)
73
- @filter.each do |pattern, replacement|
74
- output = output.to_s.gsub(pattern, replacement)
75
- end
76
- output
77
- end
78
-
79
34
  end
80
35
  end
36
+
37
+ Faraday::Response.register_middleware(logger: Faraday::Response::Logger)
@@ -1,25 +1,64 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Faraday
2
- class Response::RaiseError < Response::Middleware
3
- ClientErrorStatuses = 400...600
4
+ class Response
5
+ # RaiseError is a Faraday middleware that raises exceptions on common HTTP
6
+ # client or server error responses.
7
+ class RaiseError < Middleware
8
+ # rubocop:disable Naming/ConstantName
9
+ ClientErrorStatuses = (400...500).freeze
10
+ ServerErrorStatuses = (500...600).freeze
11
+ # rubocop:enable Naming/ConstantName
4
12
 
5
- def on_complete(env)
6
- case env[:status]
7
- when 404
8
- raise Faraday::ResourceNotFound, response_values(env)
9
- when 407
10
- # mimic the behavior that we get with proxy requests with HTTPS
11
- raise Faraday::ConnectionFailed.new(
12
- %{407 "Proxy Authentication Required "},
13
- response_values(env))
14
- when ClientErrorStatuses
15
- raise Faraday::ClientError, response_values(env)
16
- when nil
17
- raise Faraday::NilStatusError, response_values(env)
13
+ def on_complete(env)
14
+ case env[:status]
15
+ when 400
16
+ raise Faraday::BadRequestError, response_values(env)
17
+ when 401
18
+ raise Faraday::UnauthorizedError, response_values(env)
19
+ when 403
20
+ raise Faraday::ForbiddenError, response_values(env)
21
+ when 404
22
+ raise Faraday::ResourceNotFound, response_values(env)
23
+ when 407
24
+ # mimic the behavior that we get with proxy requests with HTTPS
25
+ msg = %(407 "Proxy Authentication Required")
26
+ raise Faraday::ProxyAuthError.new(msg, response_values(env))
27
+ when 409
28
+ raise Faraday::ConflictError, response_values(env)
29
+ when 422
30
+ raise Faraday::UnprocessableEntityError, response_values(env)
31
+ when ClientErrorStatuses
32
+ raise Faraday::ClientError, response_values(env)
33
+ when ServerErrorStatuses
34
+ raise Faraday::ServerError, response_values(env)
35
+ when nil
36
+ raise Faraday::NilStatusError, response_values(env)
37
+ end
38
+ end
39
+
40
+ def response_values(env)
41
+ {
42
+ status: env.status,
43
+ headers: env.response_headers,
44
+ body: env.body,
45
+ request: {
46
+ method: env.method,
47
+ url: env.url,
48
+ url_path: env.url.path,
49
+ params: query_params(env),
50
+ headers: env.request_headers,
51
+ body: env.request_body
52
+ }
53
+ }
18
54
  end
19
- end
20
55
 
21
- def response_values(env)
22
- {:status => env.status, :headers => env.response_headers, :body => env.body}
56
+ def query_params(env)
57
+ env.request.params_encoder ||= Faraday::Utils.default_params_encoder
58
+ env.params_encoder.decode(env.url.query)
59
+ end
23
60
  end
24
61
  end
25
62
  end
63
+
64
+ Faraday::Response.register_middleware(raise_error: Faraday::Response::RaiseError)
@@ -1,29 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'forwardable'
2
4
 
3
5
  module Faraday
6
+ # Response represents an HTTP response from making an HTTP request.
4
7
  class Response
5
- # Used for simple response middleware.
6
- class Middleware < Faraday::Middleware
7
- def call(env)
8
- @app.call(env).on_complete do |environment|
9
- on_complete(environment)
10
- end
11
- end
12
-
13
- # Override this to modify the environment after the response has finished.
14
- # Calls the `parse` method if defined
15
- def on_complete(env)
16
- env.body = parse(env.body) if respond_to?(:parse) && env.parse_body?
17
- end
18
- end
19
-
20
8
  extend Forwardable
21
9
  extend MiddlewareRegistry
22
10
 
23
- register_middleware File.expand_path('../response', __FILE__),
24
- :raise_error => [:RaiseError, 'raise_error'],
25
- :logger => [:Logger, 'logger']
26
-
27
11
  def initialize(env = nil)
28
12
  @env = Env.from(env) if env
29
13
  @on_complete_callbacks = []
@@ -31,8 +15,6 @@ module Faraday
31
15
 
32
16
  attr_reader :env
33
17
 
34
- def_delegators :env, :to_hash
35
-
36
18
  def status
37
19
  finished? ? env.status : nil
38
20
  end
@@ -44,6 +26,7 @@ module Faraday
44
26
  def headers
45
27
  finished? ? env.response_headers : {}
46
28
  end
29
+
47
30
  def_delegator :headers, :[]
48
31
 
49
32
  def body
@@ -55,31 +38,37 @@ module Faraday
55
38
  end
56
39
 
57
40
  def on_complete(&block)
58
- if !finished?
59
- @on_complete_callbacks << block
60
- else
41
+ if finished?
61
42
  yield(env)
43
+ else
44
+ @on_complete_callbacks << block
62
45
  end
63
- return self
46
+ self
64
47
  end
65
48
 
66
49
  def finish(env)
67
- raise "response already finished" if finished?
50
+ raise 'response already finished' if finished?
51
+
68
52
  @env = env.is_a?(Env) ? env : Env.from(env)
69
53
  @on_complete_callbacks.each { |callback| callback.call(@env) }
70
- return self
54
+ self
71
55
  end
72
56
 
73
57
  def success?
74
58
  finished? && env.success?
75
59
  end
76
60
 
61
+ def to_hash
62
+ {
63
+ status: env.status, body: env.body,
64
+ response_headers: env.response_headers,
65
+ url: env.url
66
+ }
67
+ end
68
+
77
69
  # because @on_complete_callbacks cannot be marshalled
78
70
  def marshal_dump
79
- !finished? ? nil : {
80
- :status => @env.status, :body => @env.body,
81
- :response_headers => @env.response_headers
82
- }
71
+ finished? ? to_hash : nil
83
72
  end
84
73
 
85
74
  def marshal_load(env)
@@ -90,8 +79,13 @@ module Faraday
90
79
  # Useful for applying request params after restoring a marshalled Response.
91
80
  def apply_request(request_env)
92
81
  raise "response didn't finish yet" unless finished?
82
+
93
83
  @env = Env.from(request_env).update(@env)
94
- return self
84
+ self
95
85
  end
96
86
  end
97
87
  end
88
+
89
+ require 'faraday/response/json'
90
+ require 'faraday/response/logger'
91
+ require 'faraday/response/raise_error'