faraday 1.0.0 → 2.9.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 +299 -1
- data/LICENSE.md +1 -1
- data/README.md +35 -23
- data/Rakefile +3 -1
- data/examples/client_spec.rb +68 -14
- data/examples/client_test.rb +80 -15
- data/lib/faraday/adapter/test.rb +117 -52
- data/lib/faraday/adapter.rb +6 -20
- data/lib/faraday/adapter_registry.rb +3 -1
- data/lib/faraday/connection.rb +73 -132
- data/lib/faraday/encoders/flat_params_encoder.rb +9 -2
- data/lib/faraday/encoders/nested_params_encoder.rb +20 -8
- data/lib/faraday/error.rb +37 -8
- data/lib/faraday/logging/formatter.rb +28 -15
- data/lib/faraday/methods.rb +6 -0
- data/lib/faraday/middleware.rb +17 -5
- data/lib/faraday/middleware_registry.rb +17 -63
- data/lib/faraday/options/connection_options.rb +7 -6
- data/lib/faraday/options/env.rb +85 -62
- data/lib/faraday/options/proxy_options.rb +11 -3
- data/lib/faraday/options/request_options.rb +7 -6
- data/lib/faraday/options/ssl_options.rb +56 -45
- data/lib/faraday/options.rb +11 -14
- data/lib/faraday/rack_builder.rb +35 -32
- data/lib/faraday/request/authorization.rb +37 -36
- data/lib/faraday/request/instrumentation.rb +5 -1
- data/lib/faraday/request/json.rb +70 -0
- data/lib/faraday/request/url_encoded.rb +8 -2
- data/lib/faraday/request.rb +22 -29
- data/lib/faraday/response/json.rb +73 -0
- data/lib/faraday/response/logger.rb +8 -4
- data/lib/faraday/response/raise_error.rb +41 -3
- data/lib/faraday/response.rb +10 -23
- data/lib/faraday/utils/headers.rb +9 -4
- data/lib/faraday/utils.rb +22 -10
- data/lib/faraday/version.rb +5 -0
- data/lib/faraday.rb +49 -58
- data/spec/faraday/adapter/test_spec.rb +442 -0
- data/spec/faraday/connection_spec.rb +207 -90
- data/spec/faraday/error_spec.rb +45 -5
- data/spec/faraday/middleware_registry_spec.rb +31 -0
- data/spec/faraday/middleware_spec.rb +50 -6
- data/spec/faraday/options/env_spec.rb +8 -2
- data/spec/faraday/options/options_spec.rb +1 -1
- data/spec/faraday/options/proxy_options_spec.rb +15 -0
- data/spec/faraday/params_encoders/flat_spec.rb +8 -0
- data/spec/faraday/params_encoders/nested_spec.rb +16 -0
- data/spec/faraday/rack_builder_spec.rb +171 -50
- data/spec/faraday/request/authorization_spec.rb +54 -24
- data/spec/faraday/request/instrumentation_spec.rb +5 -7
- data/spec/faraday/request/json_spec.rb +199 -0
- data/spec/faraday/request/url_encoded_spec.rb +25 -2
- data/spec/faraday/request_spec.rb +11 -10
- data/spec/faraday/response/json_spec.rb +189 -0
- data/spec/faraday/response/logger_spec.rb +38 -0
- data/spec/faraday/response/raise_error_spec.rb +105 -0
- data/spec/faraday/response_spec.rb +3 -1
- data/spec/faraday/utils/headers_spec.rb +22 -4
- data/spec/faraday/utils_spec.rb +63 -1
- data/spec/faraday_spec.rb +8 -4
- data/spec/spec_helper.rb +6 -5
- data/spec/support/fake_safe_buffer.rb +1 -1
- data/spec/support/helper_methods.rb +0 -37
- data/spec/support/shared_examples/adapter.rb +4 -3
- data/spec/support/shared_examples/request_method.rb +60 -31
- metadata +19 -44
- 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/options.rb
CHANGED
@@ -30,7 +30,7 @@ module Faraday
|
|
30
30
|
new_value = value
|
31
31
|
end
|
32
32
|
|
33
|
-
send("#{key}=", new_value) unless new_value.nil?
|
33
|
+
send(:"#{key}=", new_value) unless new_value.nil?
|
34
34
|
end
|
35
35
|
self
|
36
36
|
end
|
@@ -38,7 +38,7 @@ module Faraday
|
|
38
38
|
# Public
|
39
39
|
def delete(key)
|
40
40
|
value = send(key)
|
41
|
-
send("#{key}=", nil)
|
41
|
+
send(:"#{key}=", nil)
|
42
42
|
value
|
43
43
|
end
|
44
44
|
|
@@ -57,7 +57,7 @@ module Faraday
|
|
57
57
|
else
|
58
58
|
other_value
|
59
59
|
end
|
60
|
-
send("#{key}=", new_value) unless new_value.nil?
|
60
|
+
send(:"#{key}=", new_value) unless new_value.nil?
|
61
61
|
end
|
62
62
|
self
|
63
63
|
end
|
@@ -103,12 +103,10 @@ module Faraday
|
|
103
103
|
end
|
104
104
|
|
105
105
|
# Public
|
106
|
-
def each_key
|
107
|
-
return to_enum(:each_key) unless
|
106
|
+
def each_key(&block)
|
107
|
+
return to_enum(:each_key) unless block
|
108
108
|
|
109
|
-
keys.each
|
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
|
123
|
-
return to_enum(:each_value) unless
|
120
|
+
def each_value(&block)
|
121
|
+
return to_enum(:each_value) unless block
|
124
122
|
|
125
|
-
values.each
|
126
|
-
yield(value)
|
127
|
-
end
|
123
|
+
values.each(&block)
|
128
124
|
end
|
129
125
|
|
130
126
|
# Public
|
@@ -172,12 +168,13 @@ module Faraday
|
|
172
168
|
end
|
173
169
|
|
174
170
|
def self.memoized(key, &block)
|
175
|
-
unless
|
171
|
+
unless block
|
176
172
|
raise ArgumentError, '#memoized must be called with a block'
|
177
173
|
end
|
178
174
|
|
179
175
|
memoized_attributes[key.to_sym] = block
|
180
176
|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
177
|
+
remove_method(key) if method_defined?(key, false)
|
181
178
|
def #{key}() self[:#{key}]; end
|
182
179
|
RUBY
|
183
180
|
end
|
data/lib/faraday/rack_builder.rb
CHANGED
@@ -7,7 +7,7 @@ module Faraday
|
|
7
7
|
# middleware stack (heavily inspired by Rack).
|
8
8
|
#
|
9
9
|
# @example
|
10
|
-
# Faraday::Connection.new(url: 'http://
|
10
|
+
# Faraday::Connection.new(url: 'http://httpbingo.org') do |builder|
|
11
11
|
# builder.request :url_encoded # Faraday::Request::UrlEncoded
|
12
12
|
# builder.adapter :net_http # Faraday::Adapter::NetHttp
|
13
13
|
# end
|
@@ -27,7 +27,7 @@ module Faraday
|
|
27
27
|
|
28
28
|
attr_reader :name
|
29
29
|
|
30
|
-
def initialize(klass, *args, &block)
|
30
|
+
ruby2_keywords def initialize(klass, *args, &block)
|
31
31
|
@name = klass.to_s
|
32
32
|
REGISTRY.set(klass) if klass.respond_to?(:name)
|
33
33
|
@args = args
|
@@ -57,23 +57,22 @@ module Faraday
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
-
def initialize(
|
61
|
-
@adapter =
|
62
|
-
@handlers =
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
60
|
+
def initialize(&block)
|
61
|
+
@adapter = nil
|
62
|
+
@handlers = []
|
63
|
+
build(&block)
|
64
|
+
end
|
65
|
+
|
66
|
+
def initialize_dup(original)
|
67
|
+
super
|
68
|
+
@adapter = original.adapter
|
69
|
+
@handlers = original.handlers.dup
|
70
70
|
end
|
71
71
|
|
72
|
-
def build
|
72
|
+
def build
|
73
73
|
raise_if_locked
|
74
|
-
|
75
|
-
|
76
|
-
adapter(Faraday.default_adapter) unless @adapter
|
74
|
+
block_given? ? yield(self) : request(:url_encoded)
|
75
|
+
adapter(Faraday.default_adapter, **Faraday.default_adapter_options) unless @adapter
|
77
76
|
end
|
78
77
|
|
79
78
|
def [](idx)
|
@@ -89,7 +88,7 @@ module Faraday
|
|
89
88
|
@handlers.frozen?
|
90
89
|
end
|
91
90
|
|
92
|
-
def use(klass, *args, &block)
|
91
|
+
ruby2_keywords def use(klass, *args, &block)
|
93
92
|
if klass.is_a? Symbol
|
94
93
|
use_symbol(Faraday::Middleware, klass, *args, &block)
|
95
94
|
else
|
@@ -99,16 +98,16 @@ module Faraday
|
|
99
98
|
end
|
100
99
|
end
|
101
100
|
|
102
|
-
def request(key, *args, &block)
|
101
|
+
ruby2_keywords def request(key, *args, &block)
|
103
102
|
use_symbol(Faraday::Request, key, *args, &block)
|
104
103
|
end
|
105
104
|
|
106
|
-
def response(key, *args, &block)
|
105
|
+
ruby2_keywords def response(key, *args, &block)
|
107
106
|
use_symbol(Faraday::Response, key, *args, &block)
|
108
107
|
end
|
109
108
|
|
110
|
-
def adapter(klass = NO_ARGUMENT, *args, &block)
|
111
|
-
return @adapter if klass == NO_ARGUMENT
|
109
|
+
ruby2_keywords def adapter(klass = NO_ARGUMENT, *args, &block)
|
110
|
+
return @adapter if klass == NO_ARGUMENT || klass.nil?
|
112
111
|
|
113
112
|
klass = Faraday::Adapter.lookup_middleware(klass) if klass.is_a?(Symbol)
|
114
113
|
@adapter = self.class::Handler.new(klass, *args, &block)
|
@@ -116,7 +115,7 @@ module Faraday
|
|
116
115
|
|
117
116
|
## methods to push onto the various positions in the stack:
|
118
117
|
|
119
|
-
def insert(index, *args, &block)
|
118
|
+
ruby2_keywords def insert(index, *args, &block)
|
120
119
|
raise_if_locked
|
121
120
|
index = assert_index(index)
|
122
121
|
handler = self.class::Handler.new(*args, &block)
|
@@ -125,12 +124,12 @@ module Faraday
|
|
125
124
|
|
126
125
|
alias insert_before insert
|
127
126
|
|
128
|
-
def insert_after(index, *args, &block)
|
127
|
+
ruby2_keywords def insert_after(index, *args, &block)
|
129
128
|
index = assert_index(index)
|
130
129
|
insert(index + 1, *args, &block)
|
131
130
|
end
|
132
131
|
|
133
|
-
def swap(index, *args, &block)
|
132
|
+
ruby2_keywords def swap(index, *args, &block)
|
134
133
|
raise_if_locked
|
135
134
|
index = assert_index(index)
|
136
135
|
@handlers.delete_at(index)
|
@@ -163,6 +162,7 @@ module Faraday
|
|
163
162
|
def app
|
164
163
|
@app ||= begin
|
165
164
|
lock!
|
165
|
+
ensure_adapter!
|
166
166
|
to_app
|
167
167
|
end
|
168
168
|
end
|
@@ -181,12 +181,8 @@ module Faraday
|
|
181
181
|
@adapter == other.adapter
|
182
182
|
end
|
183
183
|
|
184
|
-
def dup
|
185
|
-
self.class.new(@handlers.dup, @adapter.dup)
|
186
|
-
end
|
187
|
-
|
188
184
|
# ENV Keys
|
189
|
-
# :
|
185
|
+
# :http_method - a symbolized request HTTP method (:get, :post)
|
190
186
|
# :body - the request body that will eventually be converted to a string.
|
191
187
|
# :url - URI instance for the current request.
|
192
188
|
# :status - HTTP response status code
|
@@ -207,7 +203,7 @@ module Faraday
|
|
207
203
|
request.options.params_encoder
|
208
204
|
)
|
209
205
|
|
210
|
-
Env.new(request.
|
206
|
+
Env.new(request.http_method, request.body, exclusive_url,
|
211
207
|
request.options, request.headers, connection.ssl,
|
212
208
|
connection.parallel_manager)
|
213
209
|
end
|
@@ -215,6 +211,9 @@ module Faraday
|
|
215
211
|
private
|
216
212
|
|
217
213
|
LOCK_ERR = "can't modify middleware stack after making a request"
|
214
|
+
MISSING_ADAPTER_ERROR = "An attempt to run a request with a Faraday::Connection without adapter has been made.\n" \
|
215
|
+
"Please set Faraday.default_adapter or provide one when initializing the connection.\n" \
|
216
|
+
'For more info, check https://lostisland.github.io/faraday/usage/.'
|
218
217
|
|
219
218
|
def raise_if_locked
|
220
219
|
raise StackLocked, LOCK_ERR if locked?
|
@@ -226,15 +225,19 @@ module Faraday
|
|
226
225
|
raise 'Adapter should be set using the `adapter` method, not `use`'
|
227
226
|
end
|
228
227
|
|
228
|
+
def ensure_adapter!
|
229
|
+
raise MISSING_ADAPTER_ERROR unless @adapter
|
230
|
+
end
|
231
|
+
|
229
232
|
def adapter_set?
|
230
233
|
!@adapter.nil?
|
231
234
|
end
|
232
235
|
|
233
236
|
def is_adapter?(klass) # rubocop:disable Naming/PredicateName
|
234
|
-
klass
|
237
|
+
klass <= Faraday::Adapter
|
235
238
|
end
|
236
239
|
|
237
|
-
def use_symbol(mod, key, *args, &block)
|
240
|
+
ruby2_keywords def use_symbol(mod, key, *args, &block)
|
238
241
|
use(mod.lookup_middleware(key), *args, &block)
|
239
242
|
end
|
240
243
|
|
@@ -4,50 +4,51 @@ 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, env, *@params)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
# @param type [String, Symbol]
|
32
|
+
# @param env [Faraday::Env]
|
33
|
+
# @param params [Array]
|
34
|
+
# @return [String] a header value
|
35
|
+
def header_from(type, env, *params)
|
36
|
+
if type.to_s.casecmp('basic').zero? && params.size == 2
|
37
|
+
Utils.basic_header_from(*params)
|
38
|
+
elsif params.size != 1
|
39
|
+
raise ArgumentError, "Unexpected params received (got #{params.size} instead of 1)"
|
40
|
+
else
|
41
|
+
value = params.first
|
42
|
+
if (value.is_a?(Proc) && value.arity == 1) || (value.respond_to?(:call) && value.method(:call).arity == 1)
|
43
|
+
value = value.call(env)
|
44
|
+
elsif value.is_a?(Proc) || value.respond_to?(:call)
|
45
|
+
value = value.call
|
46
|
+
end
|
47
|
+
"#{type} #{value}"
|
48
|
+
end
|
50
49
|
end
|
51
50
|
end
|
52
51
|
end
|
53
52
|
end
|
53
|
+
|
54
|
+
Faraday::Request.register_middleware(authorization: Faraday::Request::Authorization)
|
@@ -5,12 +5,14 @@ module Faraday
|
|
5
5
|
# Middleware for instrumenting Requests.
|
6
6
|
class Instrumentation < Faraday::Middleware
|
7
7
|
# Options class used in Request::Instrumentation class.
|
8
|
-
|
8
|
+
Options = Faraday::Options.new(:name, :instrumenter) do
|
9
|
+
remove_method :name
|
9
10
|
# @return [String]
|
10
11
|
def name
|
11
12
|
self[:name] ||= 'request.faraday'
|
12
13
|
end
|
13
14
|
|
15
|
+
remove_method :instrumenter
|
14
16
|
# @return [Class]
|
15
17
|
def instrumenter
|
16
18
|
self[:instrumenter] ||= ActiveSupport::Notifications
|
@@ -52,3 +54,5 @@ module Faraday
|
|
52
54
|
end
|
53
55
|
end
|
54
56
|
end
|
57
|
+
|
58
|
+
Faraday::Request.register_middleware(instrumentation: Faraday::Request::Instrumentation)
|
@@ -0,0 +1,70 @@
|
|
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$}
|
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
|
+
if options[:encoder].is_a?(Array) && options[:encoder].size >= 2
|
28
|
+
options[:encoder][0].public_send(options[:encoder][1], data)
|
29
|
+
elsif options[:encoder].respond_to?(:dump)
|
30
|
+
options[:encoder].dump(data)
|
31
|
+
else
|
32
|
+
::JSON.generate(data)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def match_content_type(env)
|
37
|
+
return unless process_request?(env)
|
38
|
+
|
39
|
+
env[:request_headers][CONTENT_TYPE] ||= MIME_TYPE
|
40
|
+
yield env[:body] unless env[:body].respond_to?(:to_str)
|
41
|
+
end
|
42
|
+
|
43
|
+
def process_request?(env)
|
44
|
+
type = request_type(env)
|
45
|
+
body?(env) && (type.empty? || type.match?(MIME_TYPE_REGEX))
|
46
|
+
end
|
47
|
+
|
48
|
+
def body?(env)
|
49
|
+
body = env[:body]
|
50
|
+
case body
|
51
|
+
when true, false
|
52
|
+
true
|
53
|
+
when nil
|
54
|
+
# NOTE: nil can be converted to `"null"`, but this middleware doesn't process `nil` for the compatibility.
|
55
|
+
false
|
56
|
+
else
|
57
|
+
!(body.respond_to?(:to_str) && body.empty?)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def request_type(env)
|
62
|
+
type = env[:request_headers][CONTENT_TYPE].to_s
|
63
|
+
type = type.split(';', 2).first if type.index(';')
|
64
|
+
type
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
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
|
@@ -29,7 +31,9 @@ module Faraday
|
|
29
31
|
return unless process_request?(env)
|
30
32
|
|
31
33
|
env.request_headers[CONTENT_TYPE] ||= self.class.mime_type
|
32
|
-
|
34
|
+
return if env.body.respond_to?(:to_str) || env.body.respond_to?(:read)
|
35
|
+
|
36
|
+
yield(env.body)
|
33
37
|
end
|
34
38
|
|
35
39
|
# @param env [Faraday::Env]
|
@@ -52,3 +56,5 @@ module Faraday
|
|
52
56
|
end
|
53
57
|
end
|
54
58
|
end
|
59
|
+
|
60
|
+
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
|
@@ -21,30 +21,16 @@ module Faraday
|
|
21
21
|
# @!attribute headers
|
22
22
|
# @return [Faraday::Utils::Headers] headers
|
23
23
|
# @!attribute body
|
24
|
-
# @return [
|
24
|
+
# @return [String] body
|
25
25
|
# @!attribute options
|
26
26
|
# @return [RequestOptions] options
|
27
|
-
|
28
|
-
# rubocop:disable Style/StructInheritance
|
29
|
-
class Request < Struct.new(:method, :path, :params, :headers, :body, :options)
|
30
|
-
# rubocop:enable Style/StructInheritance
|
31
|
-
|
27
|
+
Request = Struct.new(:http_method, :path, :params, :headers, :body, :options) do
|
32
28
|
extend MiddlewareRegistry
|
33
29
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
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']
|
30
|
+
alias_method :member_get, :[]
|
31
|
+
private :member_get
|
32
|
+
alias_method :member_set, :[]=
|
33
|
+
private :member_set
|
48
34
|
|
49
35
|
# @param request_method [String]
|
50
36
|
# @yield [request] for block customization, if block given
|
@@ -56,6 +42,7 @@ module Faraday
|
|
56
42
|
end
|
57
43
|
end
|
58
44
|
|
45
|
+
remove_method :params=
|
59
46
|
# Replace params, preserving the existing hash type.
|
60
47
|
#
|
61
48
|
# @param hash [Hash] new params
|
@@ -63,10 +50,11 @@ module Faraday
|
|
63
50
|
if params
|
64
51
|
params.replace hash
|
65
52
|
else
|
66
|
-
|
53
|
+
member_set(:params, hash)
|
67
54
|
end
|
68
55
|
end
|
69
56
|
|
57
|
+
remove_method :headers=
|
70
58
|
# Replace request headers, preserving the existing hash type.
|
71
59
|
#
|
72
60
|
# @param hash [Hash] new headers
|
@@ -74,7 +62,7 @@ module Faraday
|
|
74
62
|
if headers
|
75
63
|
headers.replace hash
|
76
64
|
else
|
77
|
-
|
65
|
+
member_set(:headers, hash)
|
78
66
|
end
|
79
67
|
end
|
80
68
|
|
@@ -116,7 +104,7 @@ module Faraday
|
|
116
104
|
# @return [Hash] the hash ready to be serialized in Marshal.
|
117
105
|
def marshal_dump
|
118
106
|
{
|
119
|
-
|
107
|
+
http_method: http_method,
|
120
108
|
body: body,
|
121
109
|
headers: headers,
|
122
110
|
path: path,
|
@@ -129,18 +117,23 @@ module Faraday
|
|
129
117
|
# Restores the instance variables according to the +serialised+.
|
130
118
|
# @param serialised [Hash] the serialised object.
|
131
119
|
def marshal_load(serialised)
|
132
|
-
self.
|
133
|
-
self.body
|
120
|
+
self.http_method = serialised[:http_method]
|
121
|
+
self.body = serialised[:body]
|
134
122
|
self.headers = serialised[:headers]
|
135
|
-
self.path
|
136
|
-
self.params
|
123
|
+
self.path = serialised[:path]
|
124
|
+
self.params = serialised[:params]
|
137
125
|
self.options = serialised[:options]
|
138
126
|
end
|
139
127
|
|
140
128
|
# @return [Env] the Env for this Request
|
141
129
|
def to_env(connection)
|
142
|
-
Env.new(
|
130
|
+
Env.new(http_method, body, connection.build_exclusive_url(path, params),
|
143
131
|
options, headers, connection.ssl, connection.parallel_manager)
|
144
132
|
end
|
145
133
|
end
|
146
134
|
end
|
135
|
+
|
136
|
+
require 'faraday/request/authorization'
|
137
|
+
require 'faraday/request/instrumentation'
|
138
|
+
require 'faraday/request/json'
|
139
|
+
require 'faraday/request/url_encoded'
|
@@ -0,0 +1,73 @@
|
|
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
|
+
|
15
|
+
process_parser_options
|
16
|
+
end
|
17
|
+
|
18
|
+
def on_complete(env)
|
19
|
+
process_response(env) if parse_response?(env)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def process_response(env)
|
25
|
+
env[:raw_body] = env[:body] if @preserve_raw
|
26
|
+
env[:body] = parse(env[:body])
|
27
|
+
rescue StandardError, SyntaxError => e
|
28
|
+
raise Faraday::ParsingError.new(e, env[:response])
|
29
|
+
end
|
30
|
+
|
31
|
+
def parse(body)
|
32
|
+
return if body.strip.empty?
|
33
|
+
|
34
|
+
decoder, method_name = @decoder_options
|
35
|
+
|
36
|
+
decoder.public_send(method_name, body, @parser_options || {})
|
37
|
+
end
|
38
|
+
|
39
|
+
def parse_response?(env)
|
40
|
+
process_response_type?(env) &&
|
41
|
+
env[:body].respond_to?(:to_str)
|
42
|
+
end
|
43
|
+
|
44
|
+
def process_response_type?(env)
|
45
|
+
type = response_type(env)
|
46
|
+
@content_types.empty? || @content_types.any? do |pattern|
|
47
|
+
pattern.is_a?(Regexp) ? type.match?(pattern) : type == pattern
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def response_type(env)
|
52
|
+
type = env[:response_headers][CONTENT_TYPE].to_s
|
53
|
+
type = type.split(';', 2).first if type.index(';')
|
54
|
+
type
|
55
|
+
end
|
56
|
+
|
57
|
+
def process_parser_options
|
58
|
+
@decoder_options = @parser_options&.delete(:decoder)
|
59
|
+
|
60
|
+
@decoder_options =
|
61
|
+
if @decoder_options.is_a?(Array) && @decoder_options.size >= 2
|
62
|
+
@decoder_options.slice(0, 2)
|
63
|
+
elsif @decoder_options.respond_to?(:load)
|
64
|
+
[@decoder_options, :load]
|
65
|
+
else
|
66
|
+
[::JSON, :parse]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
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?
|
@@ -28,6 +26,12 @@ module Faraday
|
|
28
26
|
def on_complete(env)
|
29
27
|
@formatter.response(env)
|
30
28
|
end
|
29
|
+
|
30
|
+
def on_error(exc)
|
31
|
+
@formatter.exception(exc) if @formatter.respond_to?(:exception)
|
32
|
+
end
|
31
33
|
end
|
32
34
|
end
|
33
35
|
end
|
36
|
+
|
37
|
+
Faraday::Response.register_middleware(logger: Faraday::Response::Logger)
|