faraday 1.0.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|