faraday 1.0.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +221 -1
- data/LICENSE.md +1 -1
- data/README.md +19 -14
- data/examples/client_spec.rb +36 -4
- data/examples/client_test.rb +43 -4
- data/lib/faraday/adapter/test.rb +61 -43
- data/lib/faraday/adapter.rb +3 -16
- data/lib/faraday/adapter_registry.rb +3 -1
- data/lib/faraday/connection.rb +25 -78
- data/lib/faraday/encoders/flat_params_encoder.rb +9 -2
- data/lib/faraday/encoders/nested_params_encoder.rb +9 -4
- data/lib/faraday/error.rb +23 -8
- data/lib/faraday/logging/formatter.rb +1 -0
- data/lib/faraday/methods.rb +6 -0
- data/lib/faraday/middleware.rb +14 -5
- data/lib/faraday/middleware_registry.rb +15 -79
- data/lib/faraday/options/proxy_options.rb +4 -0
- data/lib/faraday/options.rb +7 -11
- data/lib/faraday/rack_builder.rb +34 -30
- data/lib/faraday/request/authorization.rb +32 -36
- data/lib/faraday/request/instrumentation.rb +2 -0
- data/lib/faraday/request/json.rb +55 -0
- data/lib/faraday/request/url_encoded.rb +5 -1
- data/lib/faraday/request.rb +13 -23
- data/lib/faraday/response/json.rb +54 -0
- data/lib/faraday/response/logger.rb +4 -4
- data/lib/faraday/response/raise_error.rb +20 -1
- data/lib/faraday/response.rb +8 -22
- data/lib/faraday/utils/headers.rb +3 -3
- data/lib/faraday/utils.rb +21 -8
- data/lib/faraday/version.rb +5 -0
- data/lib/faraday.rb +44 -59
- data/spec/faraday/adapter/test_spec.rb +377 -0
- data/spec/faraday/connection_spec.rb +147 -51
- data/spec/faraday/error_spec.rb +15 -0
- data/spec/faraday/middleware_spec.rb +32 -6
- data/spec/faraday/options/env_spec.rb +2 -2
- data/spec/faraday/options/proxy_options_spec.rb +7 -0
- data/spec/faraday/params_encoders/flat_spec.rb +8 -0
- data/spec/faraday/params_encoders/nested_spec.rb +8 -0
- data/spec/faraday/rack_builder_spec.rb +144 -38
- data/spec/faraday/request/authorization_spec.rb +19 -24
- data/spec/faraday/request/instrumentation_spec.rb +5 -7
- data/spec/faraday/request/json_spec.rb +111 -0
- data/spec/faraday/request/url_encoded_spec.rb +13 -1
- data/spec/faraday/request_spec.rb +6 -6
- data/spec/faraday/response/json_spec.rb +117 -0
- data/spec/faraday/response/raise_error_spec.rb +66 -0
- data/spec/faraday/utils_spec.rb +62 -1
- data/spec/support/fake_safe_buffer.rb +1 -1
- data/spec/support/helper_methods.rb +0 -37
- data/spec/support/shared_examples/adapter.rb +2 -2
- data/spec/support/shared_examples/request_method.rb +43 -28
- metadata +16 -48
- data/UPGRADING.md +0 -55
- data/lib/faraday/adapter/em_http.rb +0 -285
- data/lib/faraday/adapter/em_http_ssl_patch.rb +0 -62
- data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +0 -69
- data/lib/faraday/adapter/em_synchrony.rb +0 -150
- data/lib/faraday/adapter/excon.rb +0 -124
- data/lib/faraday/adapter/httpclient.rb +0 -151
- data/lib/faraday/adapter/net_http.rb +0 -209
- data/lib/faraday/adapter/net_http_persistent.rb +0 -91
- data/lib/faraday/adapter/patron.rb +0 -132
- data/lib/faraday/adapter/rack.rb +0 -75
- data/lib/faraday/adapter/typhoeus.rb +0 -15
- data/lib/faraday/autoload.rb +0 -95
- data/lib/faraday/dependency_loader.rb +0 -37
- data/lib/faraday/file_part.rb +0 -128
- data/lib/faraday/param_part.rb +0 -53
- data/lib/faraday/request/basic_authentication.rb +0 -20
- data/lib/faraday/request/multipart.rb +0 -99
- data/lib/faraday/request/retry.rb +0 -239
- data/lib/faraday/request/token_authentication.rb +0 -20
- data/spec/faraday/adapter/em_http_spec.rb +0 -47
- data/spec/faraday/adapter/em_synchrony_spec.rb +0 -16
- data/spec/faraday/adapter/excon_spec.rb +0 -49
- data/spec/faraday/adapter/httpclient_spec.rb +0 -73
- data/spec/faraday/adapter/net_http_persistent_spec.rb +0 -57
- data/spec/faraday/adapter/net_http_spec.rb +0 -64
- data/spec/faraday/adapter/patron_spec.rb +0 -18
- data/spec/faraday/adapter/rack_spec.rb +0 -8
- data/spec/faraday/adapter/typhoeus_spec.rb +0 -7
- data/spec/faraday/composite_read_io_spec.rb +0 -80
- data/spec/faraday/request/multipart_spec.rb +0 -274
- data/spec/faraday/request/retry_spec.rb +0 -242
- data/spec/faraday/response/middleware_spec.rb +0 -52
- data/spec/support/webmock_rack_app.rb +0 -68
data/lib/faraday/rack_builder.rb
CHANGED
@@ -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
|
@@ -57,22 +58,21 @@ module Faraday
|
|
57
58
|
end
|
58
59
|
end
|
59
60
|
|
60
|
-
def initialize(
|
61
|
-
@adapter =
|
62
|
-
@handlers =
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
61
|
+
def initialize(&block)
|
62
|
+
@adapter = nil
|
63
|
+
@handlers = []
|
64
|
+
build(&block)
|
65
|
+
end
|
66
|
+
|
67
|
+
def initialize_dup(original)
|
68
|
+
super
|
69
|
+
@adapter = original.adapter
|
70
|
+
@handlers = original.handlers.dup
|
70
71
|
end
|
71
72
|
|
72
|
-
def build
|
73
|
+
def build
|
73
74
|
raise_if_locked
|
74
|
-
|
75
|
-
yield(self) if block_given?
|
75
|
+
block_given? ? yield(self) : request(:url_encoded)
|
76
76
|
adapter(Faraday.default_adapter) unless @adapter
|
77
77
|
end
|
78
78
|
|
@@ -89,7 +89,7 @@ module Faraday
|
|
89
89
|
@handlers.frozen?
|
90
90
|
end
|
91
91
|
|
92
|
-
def use(klass, *args, &block)
|
92
|
+
ruby2_keywords def use(klass, *args, &block)
|
93
93
|
if klass.is_a? Symbol
|
94
94
|
use_symbol(Faraday::Middleware, klass, *args, &block)
|
95
95
|
else
|
@@ -99,16 +99,16 @@ module Faraday
|
|
99
99
|
end
|
100
100
|
end
|
101
101
|
|
102
|
-
def request(key, *args, &block)
|
102
|
+
ruby2_keywords def request(key, *args, &block)
|
103
103
|
use_symbol(Faraday::Request, key, *args, &block)
|
104
104
|
end
|
105
105
|
|
106
|
-
def response(key, *args, &block)
|
106
|
+
ruby2_keywords def response(key, *args, &block)
|
107
107
|
use_symbol(Faraday::Response, key, *args, &block)
|
108
108
|
end
|
109
109
|
|
110
|
-
def adapter(klass = NO_ARGUMENT, *args, &block)
|
111
|
-
return @adapter if klass == NO_ARGUMENT
|
110
|
+
ruby2_keywords def adapter(klass = NO_ARGUMENT, *args, &block)
|
111
|
+
return @adapter if klass == NO_ARGUMENT || klass.nil?
|
112
112
|
|
113
113
|
klass = Faraday::Adapter.lookup_middleware(klass) if klass.is_a?(Symbol)
|
114
114
|
@adapter = self.class::Handler.new(klass, *args, &block)
|
@@ -116,7 +116,7 @@ module Faraday
|
|
116
116
|
|
117
117
|
## methods to push onto the various positions in the stack:
|
118
118
|
|
119
|
-
def insert(index, *args, &block)
|
119
|
+
ruby2_keywords def insert(index, *args, &block)
|
120
120
|
raise_if_locked
|
121
121
|
index = assert_index(index)
|
122
122
|
handler = self.class::Handler.new(*args, &block)
|
@@ -125,12 +125,12 @@ module Faraday
|
|
125
125
|
|
126
126
|
alias insert_before insert
|
127
127
|
|
128
|
-
def insert_after(index, *args, &block)
|
128
|
+
ruby2_keywords def insert_after(index, *args, &block)
|
129
129
|
index = assert_index(index)
|
130
130
|
insert(index + 1, *args, &block)
|
131
131
|
end
|
132
132
|
|
133
|
-
def swap(index, *args, &block)
|
133
|
+
ruby2_keywords def swap(index, *args, &block)
|
134
134
|
raise_if_locked
|
135
135
|
index = assert_index(index)
|
136
136
|
@handlers.delete_at(index)
|
@@ -163,6 +163,7 @@ module Faraday
|
|
163
163
|
def app
|
164
164
|
@app ||= begin
|
165
165
|
lock!
|
166
|
+
ensure_adapter!
|
166
167
|
to_app
|
167
168
|
end
|
168
169
|
end
|
@@ -181,12 +182,8 @@ module Faraday
|
|
181
182
|
@adapter == other.adapter
|
182
183
|
end
|
183
184
|
|
184
|
-
def dup
|
185
|
-
self.class.new(@handlers.dup, @adapter.dup)
|
186
|
-
end
|
187
|
-
|
188
185
|
# ENV Keys
|
189
|
-
# :
|
186
|
+
# :http_method - a symbolized request HTTP method (:get, :post)
|
190
187
|
# :body - the request body that will eventually be converted to a string.
|
191
188
|
# :url - URI instance for the current request.
|
192
189
|
# :status - HTTP response status code
|
@@ -207,7 +204,7 @@ module Faraday
|
|
207
204
|
request.options.params_encoder
|
208
205
|
)
|
209
206
|
|
210
|
-
Env.new(request.
|
207
|
+
Env.new(request.http_method, request.body, exclusive_url,
|
211
208
|
request.options, request.headers, connection.ssl,
|
212
209
|
connection.parallel_manager)
|
213
210
|
end
|
@@ -215,6 +212,9 @@ module Faraday
|
|
215
212
|
private
|
216
213
|
|
217
214
|
LOCK_ERR = "can't modify middleware stack after making a request"
|
215
|
+
MISSING_ADAPTER_ERROR = "An attempt to run a request with a Faraday::Connection without adapter has been made.\n" \
|
216
|
+
"Please set Faraday.default_adapter or provide one when initializing the connection.\n" \
|
217
|
+
'For more info, check https://lostisland.github.io/faraday/usage/.'
|
218
218
|
|
219
219
|
def raise_if_locked
|
220
220
|
raise StackLocked, LOCK_ERR if locked?
|
@@ -226,15 +226,19 @@ module Faraday
|
|
226
226
|
raise 'Adapter should be set using the `adapter` method, not `use`'
|
227
227
|
end
|
228
228
|
|
229
|
+
def ensure_adapter!
|
230
|
+
raise MISSING_ADAPTER_ERROR unless @adapter
|
231
|
+
end
|
232
|
+
|
229
233
|
def adapter_set?
|
230
234
|
!@adapter.nil?
|
231
235
|
end
|
232
236
|
|
233
237
|
def is_adapter?(klass) # rubocop:disable Naming/PredicateName
|
234
|
-
klass
|
238
|
+
klass <= Faraday::Adapter
|
235
239
|
end
|
236
240
|
|
237
|
-
def use_symbol(mod, key, *args, &block)
|
241
|
+
ruby2_keywords def use_symbol(mod, key, *args, &block)
|
238
242
|
use(mod.lookup_middleware(key), *args, &block)
|
239
243
|
end
|
240
244
|
|
@@ -4,50 +4,46 @@ module Faraday
|
|
4
4
|
class Request
|
5
5
|
# Request middleware for the Authorization HTTP header
|
6
6
|
class Authorization < Faraday::Middleware
|
7
|
-
KEY = 'Authorization'
|
8
|
-
|
9
|
-
# @param type [String, Symbol]
|
10
|
-
# @param token [String, Symbol, Hash]
|
11
|
-
# @return [String] a header value
|
12
|
-
def self.header(type, token)
|
13
|
-
case token
|
14
|
-
when String, Symbol
|
15
|
-
"#{type} #{token}"
|
16
|
-
when Hash
|
17
|
-
build_hash(type.to_s, token)
|
18
|
-
else
|
19
|
-
raise ArgumentError,
|
20
|
-
"Can't build an Authorization #{type}" \
|
21
|
-
"header from #{token.inspect}"
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
# @param type [String]
|
26
|
-
# @param hash [Hash]
|
27
|
-
# @return [String] type followed by comma-separated key=value pairs
|
28
|
-
# @api private
|
29
|
-
def self.build_hash(type, hash)
|
30
|
-
comma = ', '
|
31
|
-
values = []
|
32
|
-
hash.each do |key, value|
|
33
|
-
values << "#{key}=#{value.to_s.inspect}"
|
34
|
-
end
|
35
|
-
"#{type} #{values * comma}"
|
36
|
-
end
|
7
|
+
KEY = 'Authorization'
|
37
8
|
|
38
9
|
# @param app [#call]
|
39
10
|
# @param type [String, Symbol] Type of Authorization
|
40
|
-
# @param
|
41
|
-
|
42
|
-
|
11
|
+
# @param params [Array<String, Proc, #call>] parameters to build the Authorization header.
|
12
|
+
# If the type is `:basic`, then these can be a login and password pair.
|
13
|
+
# Otherwise, a single value is expected that will be appended after the type.
|
14
|
+
# This value can be a proc or an object responding to `.call`, in which case
|
15
|
+
# it will be invoked on each request.
|
16
|
+
def initialize(app, type, *params)
|
17
|
+
@type = type
|
18
|
+
@params = params
|
43
19
|
super(app)
|
44
20
|
end
|
45
21
|
|
46
22
|
# @param env [Faraday::Env]
|
47
|
-
def
|
48
|
-
|
49
|
-
|
23
|
+
def on_request(env)
|
24
|
+
return if env.request_headers[KEY]
|
25
|
+
|
26
|
+
env.request_headers[KEY] = header_from(@type, *@params)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
# @param type [String, Symbol]
|
32
|
+
# @param params [Array]
|
33
|
+
# @return [String] a header value
|
34
|
+
def header_from(type, *params)
|
35
|
+
if type.to_s.casecmp('basic').zero? && params.size == 2
|
36
|
+
Utils.basic_header_from(*params)
|
37
|
+
elsif params.size != 1
|
38
|
+
raise ArgumentError, "Unexpected params received (got #{params.size} instead of 1)"
|
39
|
+
else
|
40
|
+
value = params.first
|
41
|
+
value = value.call if value.is_a?(Proc) || value.respond_to?(:call)
|
42
|
+
"#{type} #{value}"
|
43
|
+
end
|
50
44
|
end
|
51
45
|
end
|
52
46
|
end
|
53
47
|
end
|
48
|
+
|
49
|
+
Faraday::Request.register_middleware(authorization: Faraday::Request::Authorization)
|
@@ -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)
|
@@ -4,7 +4,9 @@ module Faraday
|
|
4
4
|
class Request
|
5
5
|
# Middleware for supporting urlencoded requests.
|
6
6
|
class UrlEncoded < Faraday::Middleware
|
7
|
-
|
7
|
+
unless defined?(::Faraday::Request::UrlEncoded::CONTENT_TYPE)
|
8
|
+
CONTENT_TYPE = 'Content-Type'
|
9
|
+
end
|
8
10
|
|
9
11
|
class << self
|
10
12
|
attr_accessor :mime_type
|
@@ -52,3 +54,5 @@ module Faraday
|
|
52
54
|
end
|
53
55
|
end
|
54
56
|
end
|
57
|
+
|
58
|
+
Faraday::Request.register_middleware(url_encoded: Faraday::Request::UrlEncoded)
|
data/lib/faraday/request.rb
CHANGED
@@ -12,7 +12,7 @@ module Faraday
|
|
12
12
|
# req.body = 'abc'
|
13
13
|
# end
|
14
14
|
#
|
15
|
-
# @!attribute
|
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,26 +26,11 @@ module Faraday
|
|
26
26
|
# @return [RequestOptions] options
|
27
27
|
#
|
28
28
|
# rubocop:disable Style/StructInheritance
|
29
|
-
class Request < Struct.new(:
|
29
|
+
class Request < Struct.new(:http_method, :path, :params, :headers, :body, :options)
|
30
30
|
# rubocop:enable Style/StructInheritance
|
31
31
|
|
32
32
|
extend MiddlewareRegistry
|
33
33
|
|
34
|
-
register_middleware File.expand_path('request', __dir__),
|
35
|
-
url_encoded: [:UrlEncoded, 'url_encoded'],
|
36
|
-
multipart: [:Multipart, 'multipart'],
|
37
|
-
retry: [:Retry, 'retry'],
|
38
|
-
authorization: [:Authorization, 'authorization'],
|
39
|
-
basic_auth: [
|
40
|
-
:BasicAuthentication,
|
41
|
-
'basic_authentication'
|
42
|
-
],
|
43
|
-
token_auth: [
|
44
|
-
:TokenAuthentication,
|
45
|
-
'token_authentication'
|
46
|
-
],
|
47
|
-
instrumentation: [:Instrumentation, 'instrumentation']
|
48
|
-
|
49
34
|
# @param request_method [String]
|
50
35
|
# @yield [request] for block customization, if block given
|
51
36
|
# @yieldparam request [Request]
|
@@ -116,7 +101,7 @@ module Faraday
|
|
116
101
|
# @return [Hash] the hash ready to be serialized in Marshal.
|
117
102
|
def marshal_dump
|
118
103
|
{
|
119
|
-
|
104
|
+
http_method: http_method,
|
120
105
|
body: body,
|
121
106
|
headers: headers,
|
122
107
|
path: path,
|
@@ -129,18 +114,23 @@ module Faraday
|
|
129
114
|
# Restores the instance variables according to the +serialised+.
|
130
115
|
# @param serialised [Hash] the serialised object.
|
131
116
|
def marshal_load(serialised)
|
132
|
-
self.
|
133
|
-
self.body
|
117
|
+
self.http_method = serialised[:http_method]
|
118
|
+
self.body = serialised[:body]
|
134
119
|
self.headers = serialised[:headers]
|
135
|
-
self.path
|
136
|
-
self.params
|
120
|
+
self.path = serialised[:path]
|
121
|
+
self.params = serialised[:params]
|
137
122
|
self.options = serialised[:options]
|
138
123
|
end
|
139
124
|
|
140
125
|
# @return [Env] the Env for this Request
|
141
126
|
def to_env(connection)
|
142
|
-
Env.new(
|
127
|
+
Env.new(http_method, body, connection.build_exclusive_url(path, params),
|
143
128
|
options, headers, connection.ssl, connection.parallel_manager)
|
144
129
|
end
|
145
130
|
end
|
146
131
|
end
|
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,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 ||=
|
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?
|
@@ -31,3 +29,5 @@ module Faraday
|
|
31
29
|
end
|
32
30
|
end
|
33
31
|
end
|
32
|
+
|
33
|
+
Faraday::Response.register_middleware(logger: Faraday::Response::Logger)
|
@@ -38,8 +38,27 @@ module Faraday
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def response_values(env)
|
41
|
-
{
|
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
|
+
}
|
54
|
+
end
|
55
|
+
|
56
|
+
def query_params(env)
|
57
|
+
env.request.params_encoder ||= Faraday::Utils.default_params_encoder
|
58
|
+
env.params_encoder.decode(env.url.query)
|
42
59
|
end
|
43
60
|
end
|
44
61
|
end
|
45
62
|
end
|
63
|
+
|
64
|
+
Faraday::Response.register_middleware(raise_error: Faraday::Response::RaiseError)
|
data/lib/faraday/response.rb
CHANGED
@@ -5,28 +5,9 @@ require 'forwardable'
|
|
5
5
|
module Faraday
|
6
6
|
# Response represents an HTTP response from making an HTTP request.
|
7
7
|
class Response
|
8
|
-
# Used for simple response middleware.
|
9
|
-
class Middleware < Faraday::Middleware
|
10
|
-
def call(env)
|
11
|
-
@app.call(env).on_complete do |environment|
|
12
|
-
on_complete(environment)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
# Override this to modify the environment after the response has finished.
|
17
|
-
# Calls the `parse` method if defined
|
18
|
-
def on_complete(env)
|
19
|
-
env.body = parse(env.body) if respond_to?(:parse) && env.parse_body?
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
8
|
extend Forwardable
|
24
9
|
extend MiddlewareRegistry
|
25
10
|
|
26
|
-
register_middleware File.expand_path('response', __dir__),
|
27
|
-
raise_error: [:RaiseError, 'raise_error'],
|
28
|
-
logger: [:Logger, 'logger']
|
29
|
-
|
30
11
|
def initialize(env = nil)
|
31
12
|
@env = Env.from(env) if env
|
32
13
|
@on_complete_callbacks = []
|
@@ -45,6 +26,7 @@ module Faraday
|
|
45
26
|
def headers
|
46
27
|
finished? ? env.response_headers : {}
|
47
28
|
end
|
29
|
+
|
48
30
|
def_delegator :headers, :[]
|
49
31
|
|
50
32
|
def body
|
@@ -56,10 +38,10 @@ module Faraday
|
|
56
38
|
end
|
57
39
|
|
58
40
|
def on_complete(&block)
|
59
|
-
if
|
60
|
-
@on_complete_callbacks << block
|
61
|
-
else
|
41
|
+
if finished?
|
62
42
|
yield(env)
|
43
|
+
else
|
44
|
+
@on_complete_callbacks << block
|
63
45
|
end
|
64
46
|
self
|
65
47
|
end
|
@@ -102,3 +84,7 @@ module Faraday
|
|
102
84
|
end
|
103
85
|
end
|
104
86
|
end
|
87
|
+
|
88
|
+
require 'faraday/response/json'
|
89
|
+
require 'faraday/response/logger'
|
90
|
+
require 'faraday/response/raise_error'
|
@@ -105,16 +105,16 @@ module Faraday
|
|
105
105
|
end
|
106
106
|
|
107
107
|
def to_hash
|
108
|
-
|
108
|
+
{}.update(self)
|
109
109
|
end
|
110
110
|
|
111
111
|
def parse(header_string)
|
112
112
|
return unless header_string && !header_string.empty?
|
113
113
|
|
114
|
-
headers = header_string.split(
|
114
|
+
headers = header_string.split("\r\n")
|
115
115
|
|
116
116
|
# Find the last set of response headers.
|
117
|
-
start_index = headers.rindex { |x| x.
|
117
|
+
start_index = headers.rindex { |x| x.start_with?('HTTP/') } || 0
|
118
118
|
last_response = headers.slice(start_index, headers.size)
|
119
119
|
|
120
120
|
last_response
|
data/lib/faraday/utils.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'base64'
|
4
|
+
require 'uri'
|
3
5
|
require 'faraday/utils/headers'
|
4
6
|
require 'faraday/utils/params_hash'
|
5
7
|
|
@@ -16,12 +18,20 @@ module Faraday
|
|
16
18
|
NestedParamsEncoder.encode(params)
|
17
19
|
end
|
18
20
|
|
21
|
+
def default_space_encoding
|
22
|
+
@default_space_encoding ||= '+'
|
23
|
+
end
|
24
|
+
|
25
|
+
class << self
|
26
|
+
attr_writer :default_space_encoding
|
27
|
+
end
|
28
|
+
|
19
29
|
ESCAPE_RE = /[^a-zA-Z0-9 .~_-]/.freeze
|
20
30
|
|
21
31
|
def escape(str)
|
22
32
|
str.to_s.gsub(ESCAPE_RE) do |match|
|
23
|
-
|
24
|
-
end.
|
33
|
+
"%#{match.unpack('H2' * match.bytesize).join('%').upcase}"
|
34
|
+
end.gsub(' ', default_space_encoding)
|
25
35
|
end
|
26
36
|
|
27
37
|
def unescape(str)
|
@@ -43,6 +53,12 @@ module Faraday
|
|
43
53
|
@default_params_encoder ||= NestedParamsEncoder
|
44
54
|
end
|
45
55
|
|
56
|
+
def basic_header_from(login, pass)
|
57
|
+
value = Base64.encode64("#{login}:#{pass}")
|
58
|
+
value.delete!("\n")
|
59
|
+
"Basic #{value}"
|
60
|
+
end
|
61
|
+
|
46
62
|
class << self
|
47
63
|
attr_writer :default_params_encoder
|
48
64
|
end
|
@@ -63,10 +79,7 @@ module Faraday
|
|
63
79
|
end
|
64
80
|
|
65
81
|
def default_uri_parser
|
66
|
-
@default_uri_parser ||=
|
67
|
-
require 'uri'
|
68
|
-
Kernel.method(:URI)
|
69
|
-
end
|
82
|
+
@default_uri_parser ||= Kernel.method(:URI)
|
70
83
|
end
|
71
84
|
|
72
85
|
def default_uri_parser=(parser)
|
@@ -81,14 +94,14 @@ module Faraday
|
|
81
94
|
# the path with the query string sorted.
|
82
95
|
def normalize_path(url)
|
83
96
|
url = URI(url)
|
84
|
-
(url.path.start_with?('/') ? url.path :
|
97
|
+
(url.path.start_with?('/') ? url.path : "/#{url.path}") +
|
85
98
|
(url.query ? "?#{sort_query_params(url.query)}" : '')
|
86
99
|
end
|
87
100
|
|
88
101
|
# Recursive hash update
|
89
102
|
def deep_merge!(target, hash)
|
90
103
|
hash.each do |key, value|
|
91
|
-
target[key] = if value.is_a?(Hash) && target[key].is_a?(Hash)
|
104
|
+
target[key] = if value.is_a?(Hash) && (target[key].is_a?(Hash) || target[key].is_a?(Options))
|
92
105
|
deep_merge(target[key], value)
|
93
106
|
else
|
94
107
|
value
|