faraday 0.15.0 → 1.10.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 +380 -0
- data/LICENSE.md +1 -1
- data/README.md +17 -345
- data/Rakefile +7 -0
- data/examples/client_spec.rb +97 -0
- data/examples/client_test.rb +118 -0
- data/lib/faraday/adapter/test.rb +118 -69
- data/lib/faraday/adapter/typhoeus.rb +4 -1
- data/lib/faraday/adapter.rb +72 -22
- data/lib/faraday/adapter_registry.rb +30 -0
- data/lib/faraday/autoload.rb +39 -36
- data/lib/faraday/connection.rb +343 -185
- data/lib/faraday/dependency_loader.rb +37 -0
- data/lib/faraday/encoders/flat_params_encoder.rb +105 -0
- data/lib/faraday/encoders/nested_params_encoder.rb +176 -0
- data/lib/faraday/error.rb +118 -38
- data/lib/faraday/logging/formatter.rb +105 -0
- data/lib/faraday/methods.rb +6 -0
- data/lib/faraday/middleware.rb +19 -25
- data/lib/faraday/middleware_registry.rb +129 -0
- data/lib/faraday/options/connection_options.rb +22 -0
- data/lib/faraday/options/env.rb +181 -0
- data/lib/faraday/options/proxy_options.rb +32 -0
- data/lib/faraday/options/request_options.rb +22 -0
- data/lib/faraday/options/ssl_options.rb +59 -0
- data/lib/faraday/options.rb +39 -193
- data/lib/faraday/parameters.rb +4 -196
- data/lib/faraday/rack_builder.rb +77 -65
- data/lib/faraday/request/authorization.rb +51 -30
- data/lib/faraday/request/basic_authentication.rb +14 -7
- data/lib/faraday/request/instrumentation.rb +45 -27
- data/lib/faraday/request/json.rb +55 -0
- data/lib/faraday/request/token_authentication.rb +15 -10
- data/lib/faraday/request/url_encoded.rb +43 -23
- data/lib/faraday/request.rb +93 -32
- data/lib/faraday/response/json.rb +54 -0
- data/lib/faraday/response/logger.rb +20 -69
- data/lib/faraday/response/raise_error.rb +49 -14
- data/lib/faraday/response.rb +29 -23
- data/lib/faraday/utils/headers.rb +139 -0
- data/lib/faraday/utils/params_hash.rb +61 -0
- data/lib/faraday/utils.rb +38 -247
- data/lib/faraday/version.rb +5 -0
- data/lib/faraday.rb +134 -189
- data/spec/external_adapters/faraday_specs_setup.rb +14 -0
- data/spec/faraday/adapter/em_http_spec.rb +49 -0
- data/spec/faraday/adapter/em_synchrony_spec.rb +18 -0
- data/spec/faraday/adapter/excon_spec.rb +49 -0
- data/spec/faraday/adapter/httpclient_spec.rb +73 -0
- data/spec/faraday/adapter/net_http_spec.rb +64 -0
- data/spec/faraday/adapter/patron_spec.rb +18 -0
- data/spec/faraday/adapter/rack_spec.rb +8 -0
- data/spec/faraday/adapter/test_spec.rb +377 -0
- data/spec/faraday/adapter/typhoeus_spec.rb +7 -0
- data/spec/faraday/adapter_registry_spec.rb +28 -0
- data/spec/faraday/adapter_spec.rb +55 -0
- data/spec/faraday/composite_read_io_spec.rb +80 -0
- data/spec/faraday/connection_spec.rb +736 -0
- data/spec/faraday/error_spec.rb +60 -0
- data/spec/faraday/middleware_spec.rb +52 -0
- data/spec/faraday/options/env_spec.rb +70 -0
- data/spec/faraday/options/options_spec.rb +297 -0
- data/spec/faraday/options/proxy_options_spec.rb +44 -0
- data/spec/faraday/options/request_options_spec.rb +19 -0
- data/spec/faraday/params_encoders/flat_spec.rb +42 -0
- data/spec/faraday/params_encoders/nested_spec.rb +142 -0
- data/spec/faraday/rack_builder_spec.rb +345 -0
- data/spec/faraday/request/authorization_spec.rb +96 -0
- data/spec/faraday/request/instrumentation_spec.rb +76 -0
- data/spec/faraday/request/json_spec.rb +111 -0
- data/spec/faraday/request/url_encoded_spec.rb +83 -0
- data/spec/faraday/request_spec.rb +120 -0
- data/spec/faraday/response/json_spec.rb +119 -0
- data/spec/faraday/response/logger_spec.rb +220 -0
- data/spec/faraday/response/middleware_spec.rb +68 -0
- data/spec/faraday/response/raise_error_spec.rb +169 -0
- data/spec/faraday/response_spec.rb +75 -0
- data/spec/faraday/utils/headers_spec.rb +82 -0
- data/spec/faraday/utils_spec.rb +56 -0
- data/spec/faraday_spec.rb +37 -0
- data/spec/spec_helper.rb +132 -0
- data/spec/support/disabling_stub.rb +14 -0
- data/spec/support/fake_safe_buffer.rb +15 -0
- data/spec/support/helper_methods.rb +133 -0
- data/spec/support/shared_examples/adapter.rb +105 -0
- data/spec/support/shared_examples/params_encoder.rb +18 -0
- data/spec/support/shared_examples/request_method.rb +262 -0
- data/spec/support/streaming_response_checker.rb +35 -0
- data/spec/support/webmock_rack_app.rb +68 -0
- metadata +222 -29
- data/lib/faraday/adapter/em_http.rb +0 -243
- data/lib/faraday/adapter/em_http_ssl_patch.rb +0 -56
- data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +0 -66
- data/lib/faraday/adapter/em_synchrony.rb +0 -106
- data/lib/faraday/adapter/excon.rb +0 -79
- data/lib/faraday/adapter/httpclient.rb +0 -128
- data/lib/faraday/adapter/net_http.rb +0 -137
- data/lib/faraday/adapter/net_http_persistent.rb +0 -63
- data/lib/faraday/adapter/patron.rb +0 -100
- data/lib/faraday/adapter/rack.rb +0 -58
- data/lib/faraday/request/multipart.rb +0 -68
- data/lib/faraday/request/retry.rb +0 -211
- data/lib/faraday/upload_io.rb +0 -67
data/lib/faraday/rack_builder.rb
CHANGED
@@ -1,12 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ruby2_keywords'
|
4
|
+
require 'faraday/adapter_registry'
|
5
|
+
|
1
6
|
module Faraday
|
2
7
|
# A Builder that processes requests into responses by passing through an inner
|
3
8
|
# middleware stack (heavily inspired by Rack).
|
4
9
|
#
|
5
|
-
#
|
10
|
+
# @example
|
11
|
+
# Faraday::Connection.new(url: 'http://sushi.com') do |builder|
|
6
12
|
# builder.request :url_encoded # Faraday::Request::UrlEncoded
|
7
13
|
# builder.adapter :net_http # Faraday::Adapter::NetHttp
|
8
14
|
# end
|
9
15
|
class RackBuilder
|
16
|
+
# Used to detect missing arguments
|
17
|
+
NO_ARGUMENT = Object.new
|
18
|
+
|
10
19
|
attr_accessor :handlers
|
11
20
|
|
12
21
|
# Error raised when trying to modify the stack after calling `lock!`
|
@@ -15,28 +24,28 @@ module Faraday
|
|
15
24
|
# borrowed from ActiveSupport::Dependencies::Reference &
|
16
25
|
# ActionDispatch::MiddlewareStack::Middleware
|
17
26
|
class Handler
|
18
|
-
|
19
|
-
@@constants = Hash.new { |h, k|
|
20
|
-
value = k.respond_to?(:constantize) ? k.constantize : Object.const_get(k)
|
21
|
-
@@constants_mutex.synchronize { h[k] = value }
|
22
|
-
}
|
27
|
+
REGISTRY = Faraday::AdapterRegistry.new
|
23
28
|
|
24
29
|
attr_reader :name
|
25
30
|
|
26
|
-
def initialize(klass, *args, &block)
|
31
|
+
ruby2_keywords def initialize(klass, *args, &block)
|
27
32
|
@name = klass.to_s
|
28
|
-
if klass.respond_to?(:name)
|
29
|
-
|
30
|
-
|
31
|
-
@args, @block = args, block
|
33
|
+
REGISTRY.set(klass) if klass.respond_to?(:name)
|
34
|
+
@args = args
|
35
|
+
@block = block
|
32
36
|
end
|
33
37
|
|
34
|
-
def klass
|
35
|
-
|
38
|
+
def klass
|
39
|
+
REGISTRY.get(@name)
|
40
|
+
end
|
41
|
+
|
42
|
+
def inspect
|
43
|
+
@name
|
44
|
+
end
|
36
45
|
|
37
46
|
def ==(other)
|
38
47
|
if other.is_a? Handler
|
39
|
-
|
48
|
+
name == other.name
|
40
49
|
elsif other.respond_to? :name
|
41
50
|
klass == other
|
42
51
|
else
|
@@ -44,18 +53,19 @@ module Faraday
|
|
44
53
|
end
|
45
54
|
end
|
46
55
|
|
47
|
-
def build(app)
|
56
|
+
def build(app = nil)
|
48
57
|
klass.new(app, *@args, &@block)
|
49
58
|
end
|
50
59
|
end
|
51
60
|
|
52
|
-
def initialize(handlers = [])
|
61
|
+
def initialize(handlers = [], adapter = nil, &block)
|
62
|
+
@adapter = adapter
|
53
63
|
@handlers = handlers
|
54
64
|
if block_given?
|
55
|
-
build(&
|
65
|
+
build(&block)
|
56
66
|
elsif @handlers.empty?
|
57
67
|
# default stack, if nothing else is configured
|
58
|
-
|
68
|
+
request :url_encoded
|
59
69
|
self.adapter Faraday.default_adapter
|
60
70
|
end
|
61
71
|
end
|
@@ -64,13 +74,14 @@ module Faraday
|
|
64
74
|
raise_if_locked
|
65
75
|
@handlers.clear unless options[:keep]
|
66
76
|
yield(self) if block_given?
|
77
|
+
adapter(Faraday.default_adapter) unless @adapter
|
67
78
|
end
|
68
79
|
|
69
80
|
def [](idx)
|
70
81
|
@handlers[idx]
|
71
82
|
end
|
72
83
|
|
73
|
-
# Locks the middleware stack to ensure no further modifications are
|
84
|
+
# Locks the middleware stack to ensure no further modifications are made.
|
74
85
|
def lock!
|
75
86
|
@handlers.freeze
|
76
87
|
end
|
@@ -79,46 +90,48 @@ module Faraday
|
|
79
90
|
@handlers.frozen?
|
80
91
|
end
|
81
92
|
|
82
|
-
def use(klass, *args, &block)
|
93
|
+
ruby2_keywords def use(klass, *args, &block)
|
83
94
|
if klass.is_a? Symbol
|
84
95
|
use_symbol(Faraday::Middleware, klass, *args, &block)
|
85
96
|
else
|
86
97
|
raise_if_locked
|
87
|
-
|
98
|
+
raise_if_adapter(klass)
|
88
99
|
@handlers << self.class::Handler.new(klass, *args, &block)
|
89
100
|
end
|
90
101
|
end
|
91
102
|
|
92
|
-
def request(key, *args, &block)
|
103
|
+
ruby2_keywords def request(key, *args, &block)
|
93
104
|
use_symbol(Faraday::Request, key, *args, &block)
|
94
105
|
end
|
95
106
|
|
96
|
-
def response(key, *args, &block)
|
107
|
+
ruby2_keywords def response(key, *args, &block)
|
97
108
|
use_symbol(Faraday::Response, key, *args, &block)
|
98
109
|
end
|
99
110
|
|
100
|
-
def adapter(
|
101
|
-
|
111
|
+
ruby2_keywords def adapter(klass = NO_ARGUMENT, *args, &block)
|
112
|
+
return @adapter if klass == NO_ARGUMENT
|
113
|
+
|
114
|
+
klass = Faraday::Adapter.lookup_middleware(klass) if klass.is_a?(Symbol)
|
115
|
+
@adapter = self.class::Handler.new(klass, *args, &block)
|
102
116
|
end
|
103
117
|
|
104
118
|
## methods to push onto the various positions in the stack:
|
105
119
|
|
106
|
-
def insert(index, *args, &block)
|
120
|
+
ruby2_keywords def insert(index, *args, &block)
|
107
121
|
raise_if_locked
|
108
122
|
index = assert_index(index)
|
109
|
-
warn_middleware_after_adapter if inserting_after_adapter?(index)
|
110
123
|
handler = self.class::Handler.new(*args, &block)
|
111
124
|
@handlers.insert(index, handler)
|
112
125
|
end
|
113
126
|
|
114
|
-
|
127
|
+
alias insert_before insert
|
115
128
|
|
116
|
-
def insert_after(index, *args, &block)
|
129
|
+
ruby2_keywords def insert_after(index, *args, &block)
|
117
130
|
index = assert_index(index)
|
118
131
|
insert(index + 1, *args, &block)
|
119
132
|
end
|
120
133
|
|
121
|
-
def swap(index, *args, &block)
|
134
|
+
ruby2_keywords def swap(index, *args, &block)
|
122
135
|
raise_if_locked
|
123
136
|
index = assert_index(index)
|
124
137
|
@handlers.delete_at(index)
|
@@ -133,13 +146,11 @@ module Faraday
|
|
133
146
|
# Processes a Request into a Response by passing it through this Builder's
|
134
147
|
# middleware stack.
|
135
148
|
#
|
136
|
-
# connection
|
137
|
-
# request
|
149
|
+
# @param connection [Faraday::Connection]
|
150
|
+
# @param request [Faraday::Request]
|
138
151
|
#
|
139
|
-
#
|
152
|
+
# @return [Faraday::Response]
|
140
153
|
def build_response(connection, request)
|
141
|
-
warn 'WARNING: No adapter was configured for this request' unless adapter_set?
|
142
|
-
|
143
154
|
app.call(build_env(connection, request))
|
144
155
|
end
|
145
156
|
|
@@ -153,30 +164,30 @@ module Faraday
|
|
153
164
|
def app
|
154
165
|
@app ||= begin
|
155
166
|
lock!
|
156
|
-
to_app
|
157
|
-
response = Response.new
|
158
|
-
env.response = response
|
159
|
-
response.finish(env) unless env.parallel?
|
160
|
-
response
|
161
|
-
})
|
167
|
+
to_app
|
162
168
|
end
|
163
169
|
end
|
164
170
|
|
165
|
-
def to_app
|
171
|
+
def to_app
|
166
172
|
# last added handler is the deepest and thus closest to the inner app
|
167
|
-
|
173
|
+
# adapter is always the last one
|
174
|
+
@handlers.reverse.inject(@adapter.build) do |app, handler|
|
175
|
+
handler.build(app)
|
176
|
+
end
|
168
177
|
end
|
169
178
|
|
170
179
|
def ==(other)
|
171
|
-
other.is_a?(self.class) &&
|
180
|
+
other.is_a?(self.class) &&
|
181
|
+
@handlers == other.handlers &&
|
182
|
+
@adapter == other.adapter
|
172
183
|
end
|
173
184
|
|
174
185
|
def dup
|
175
|
-
self.class.new(@handlers.dup)
|
186
|
+
self.class.new(@handlers.dup, @adapter.dup)
|
176
187
|
end
|
177
188
|
|
178
189
|
# ENV Keys
|
179
|
-
# :
|
190
|
+
# :http_method - a symbolized request HTTP method (:get, :post)
|
180
191
|
# :body - the request body that will eventually be converted to a string.
|
181
192
|
# :url - URI instance for the current request.
|
182
193
|
# :status - HTTP response status code
|
@@ -192,45 +203,46 @@ module Faraday
|
|
192
203
|
# :password - Proxy server password
|
193
204
|
# :ssl - Hash of options for configuring SSL requests.
|
194
205
|
def build_env(connection, request)
|
195
|
-
|
196
|
-
|
197
|
-
request.options
|
198
|
-
|
206
|
+
exclusive_url = connection.build_exclusive_url(
|
207
|
+
request.path, request.params,
|
208
|
+
request.options.params_encoder
|
209
|
+
)
|
210
|
+
|
211
|
+
Env.new(request.http_method, request.body, exclusive_url,
|
212
|
+
request.options, request.headers, connection.ssl,
|
213
|
+
connection.parallel_manager)
|
199
214
|
end
|
200
215
|
|
201
216
|
private
|
202
217
|
|
218
|
+
LOCK_ERR = "can't modify middleware stack after making a request"
|
219
|
+
|
203
220
|
def raise_if_locked
|
204
|
-
raise StackLocked,
|
221
|
+
raise StackLocked, LOCK_ERR if locked?
|
205
222
|
end
|
206
223
|
|
207
|
-
def
|
208
|
-
|
209
|
-
"This won't be supported from Faraday 1.0."
|
210
|
-
end
|
224
|
+
def raise_if_adapter(klass)
|
225
|
+
return unless is_adapter?(klass)
|
211
226
|
|
212
|
-
|
213
|
-
@handlers.any? { |handler| is_adapter?(handler) }
|
227
|
+
raise 'Adapter should be set using the `adapter` method, not `use`'
|
214
228
|
end
|
215
229
|
|
216
|
-
def
|
217
|
-
|
218
|
-
return false if adapter_index.nil?
|
219
|
-
|
220
|
-
index > adapter_index
|
230
|
+
def adapter_set?
|
231
|
+
!@adapter.nil?
|
221
232
|
end
|
222
233
|
|
223
|
-
def is_adapter?(
|
224
|
-
|
234
|
+
def is_adapter?(klass) # rubocop:disable Naming/PredicateName
|
235
|
+
klass <= Faraday::Adapter
|
225
236
|
end
|
226
237
|
|
227
|
-
def use_symbol(mod, key, *args, &block)
|
238
|
+
ruby2_keywords def use_symbol(mod, key, *args, &block)
|
228
239
|
use(mod.lookup_middleware(key), *args, &block)
|
229
240
|
end
|
230
241
|
|
231
242
|
def assert_index(index)
|
232
243
|
idx = index.is_a?(Integer) ? index : @handlers.index(index)
|
233
244
|
raise "No such handler: #{index.inspect}" unless idx
|
245
|
+
|
234
246
|
idx
|
235
247
|
end
|
236
248
|
end
|
@@ -1,41 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'base64'
|
4
|
+
|
1
5
|
module Faraday
|
2
|
-
class Request
|
3
|
-
|
6
|
+
class Request
|
7
|
+
# Request middleware for the Authorization HTTP header
|
8
|
+
class Authorization < Faraday::Middleware
|
9
|
+
unless defined?(::Faraday::Request::Authorization::KEY)
|
10
|
+
KEY = 'Authorization'
|
11
|
+
end
|
4
12
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
13
|
+
# @param type [String, Symbol]
|
14
|
+
# @param token [String, Symbol, Hash]
|
15
|
+
# @return [String] a header value
|
16
|
+
def self.header(type, token)
|
17
|
+
case token
|
18
|
+
when String, Symbol, Proc
|
19
|
+
token = token.call if token.is_a?(Proc)
|
20
|
+
"#{type} #{token}"
|
21
|
+
when Hash
|
22
|
+
build_hash(type.to_s, token)
|
23
|
+
else
|
24
|
+
raise ArgumentError,
|
25
|
+
"Can't build an Authorization #{type}" \
|
26
|
+
"header from #{token.inspect}"
|
27
|
+
end
|
14
28
|
end
|
15
|
-
end
|
16
29
|
|
17
|
-
|
18
|
-
|
19
|
-
comma =
|
20
|
-
|
21
|
-
|
22
|
-
|
30
|
+
# @param type [String]
|
31
|
+
# @param hash [Hash]
|
32
|
+
# @return [String] type followed by comma-separated key=value pairs
|
33
|
+
# @api private
|
34
|
+
def self.build_hash(type, hash)
|
35
|
+
comma = ', '
|
36
|
+
values = []
|
37
|
+
hash.each do |key, value|
|
38
|
+
value = value.call if value.is_a?(Proc)
|
39
|
+
values << "#{key}=#{value.to_s.inspect}"
|
40
|
+
end
|
41
|
+
"#{type} #{values * comma}"
|
23
42
|
end
|
24
|
-
"#{type} #{values * comma}"
|
25
|
-
end
|
26
43
|
|
27
|
-
|
28
|
-
@
|
29
|
-
|
30
|
-
|
44
|
+
# @param app [#call]
|
45
|
+
# @param type [String, Symbol] Type of Authorization
|
46
|
+
# @param param [String, Symbol, Hash, Proc] parameter to build the Authorization header.
|
47
|
+
# This value can be a proc, in which case it will be invoked on each request.
|
48
|
+
def initialize(app, type, param)
|
49
|
+
@type = type
|
50
|
+
@param = param
|
51
|
+
super(app)
|
52
|
+
end
|
31
53
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
54
|
+
# @param env [Faraday::Env]
|
55
|
+
def on_request(env)
|
56
|
+
return if env.request_headers[KEY]
|
57
|
+
|
58
|
+
env.request_headers[KEY] = self.class.header(@type, @param)
|
36
59
|
end
|
37
|
-
@app.call(env)
|
38
60
|
end
|
39
61
|
end
|
40
62
|
end
|
41
|
-
|
@@ -1,13 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'base64'
|
2
4
|
|
3
5
|
module Faraday
|
4
|
-
class Request
|
5
|
-
#
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
class Request
|
7
|
+
# Authorization middleware for Basic Authentication.
|
8
|
+
class BasicAuthentication < load_middleware(:authorization)
|
9
|
+
# @param login [String]
|
10
|
+
# @param pass [String]
|
11
|
+
#
|
12
|
+
# @return [String] a Basic Authentication header line
|
13
|
+
def self.header(login, pass)
|
14
|
+
value = Base64.encode64([login, pass].join(':'))
|
15
|
+
value.delete!("\n")
|
16
|
+
super(:Basic, value)
|
17
|
+
end
|
10
18
|
end
|
11
19
|
end
|
12
20
|
end
|
13
|
-
|
@@ -1,35 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Faraday
|
2
|
-
class Request
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
class Request
|
5
|
+
# Middleware for instrumenting Requests.
|
6
|
+
class Instrumentation < Faraday::Middleware
|
7
|
+
# Options class used in Request::Instrumentation class.
|
8
|
+
class Options < Faraday::Options.new(:name, :instrumenter)
|
9
|
+
# @return [String]
|
10
|
+
def name
|
11
|
+
self[:name] ||= 'request.faraday'
|
12
|
+
end
|
7
13
|
|
8
|
-
|
9
|
-
|
14
|
+
# @return [Class]
|
15
|
+
def instrumenter
|
16
|
+
self[:instrumenter] ||= ActiveSupport::Notifications
|
17
|
+
end
|
10
18
|
end
|
11
|
-
end
|
12
19
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
20
|
+
# Instruments requests using Active Support.
|
21
|
+
#
|
22
|
+
# Measures time spent only for synchronous requests.
|
23
|
+
#
|
24
|
+
# @example Using ActiveSupport::Notifications to measure time spent
|
25
|
+
# for Faraday requests.
|
26
|
+
# ActiveSupport::Notifications
|
27
|
+
# .subscribe('request.faraday') do |name, starts, ends, _, env|
|
28
|
+
# url = env[:url]
|
29
|
+
# http_method = env[:method].to_s.upcase
|
30
|
+
# duration = ends - starts
|
31
|
+
# $stderr.puts '[%s] %s %s (%.3f s)' %
|
32
|
+
# [url.host, http_method, url.request_uri, duration]
|
33
|
+
# end
|
34
|
+
# @param app [#call]
|
35
|
+
# @param options [nil, Hash] Options hash
|
36
|
+
# @option options [String] :name ('request.faraday')
|
37
|
+
# Name of the instrumenter
|
38
|
+
# @option options [Class] :instrumenter (ActiveSupport::Notifications)
|
39
|
+
# Active Support instrumenter class.
|
40
|
+
def initialize(app, options = nil)
|
41
|
+
super(app)
|
42
|
+
@name, @instrumenter = Options.from(options)
|
43
|
+
.values_at(:name, :instrumenter)
|
44
|
+
end
|
29
45
|
|
30
|
-
|
31
|
-
|
32
|
-
@
|
46
|
+
# @param env [Faraday::Env]
|
47
|
+
def call(env)
|
48
|
+
@instrumenter.instrument(@name, env) do
|
49
|
+
@app.call(env)
|
50
|
+
end
|
33
51
|
end
|
34
52
|
end
|
35
53
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module Faraday
|
6
|
+
class Request
|
7
|
+
# Request middleware that encodes the body as JSON.
|
8
|
+
#
|
9
|
+
# Processes only requests with matching Content-type or those without a type.
|
10
|
+
# If a request doesn't have a type but has a body, it sets the Content-type
|
11
|
+
# to JSON MIME-type.
|
12
|
+
#
|
13
|
+
# Doesn't try to encode bodies that already are in string form.
|
14
|
+
class Json < Middleware
|
15
|
+
MIME_TYPE = 'application/json'
|
16
|
+
MIME_TYPE_REGEX = %r{^application/(vnd\..+\+)?json$}.freeze
|
17
|
+
|
18
|
+
def on_request(env)
|
19
|
+
match_content_type(env) do |data|
|
20
|
+
env[:body] = encode(data)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def encode(data)
|
27
|
+
::JSON.generate(data)
|
28
|
+
end
|
29
|
+
|
30
|
+
def match_content_type(env)
|
31
|
+
return unless process_request?(env)
|
32
|
+
|
33
|
+
env[:request_headers][CONTENT_TYPE] ||= MIME_TYPE
|
34
|
+
yield env[:body] unless env[:body].respond_to?(:to_str)
|
35
|
+
end
|
36
|
+
|
37
|
+
def process_request?(env)
|
38
|
+
type = request_type(env)
|
39
|
+
body?(env) && (type.empty? || type.match?(MIME_TYPE_REGEX))
|
40
|
+
end
|
41
|
+
|
42
|
+
def body?(env)
|
43
|
+
(body = env[:body]) && !(body.respond_to?(:to_str) && body.empty?)
|
44
|
+
end
|
45
|
+
|
46
|
+
def request_type(env)
|
47
|
+
type = env[:request_headers][CONTENT_TYPE].to_s
|
48
|
+
type = type.split(';', 2).first if type.index(';')
|
49
|
+
type
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
Faraday::Request.register_middleware(json: Faraday::Request::Json)
|
@@ -1,15 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Faraday
|
2
|
-
class Request
|
3
|
-
#
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
class Request
|
5
|
+
# TokenAuthentication is a middleware that adds a 'Token' header to a
|
6
|
+
# Faraday request.
|
7
|
+
class TokenAuthentication < load_middleware(:authorization)
|
8
|
+
# Public
|
9
|
+
def self.header(token, options = nil)
|
10
|
+
options ||= {}
|
11
|
+
options[:token] = token
|
12
|
+
super(:Token, options)
|
13
|
+
end
|
9
14
|
|
10
|
-
|
11
|
-
|
15
|
+
def initialize(app, token, options = nil)
|
16
|
+
super(app, token, options)
|
17
|
+
end
|
12
18
|
end
|
13
19
|
end
|
14
20
|
end
|
15
|
-
|
@@ -1,36 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Faraday
|
2
|
-
class Request
|
3
|
-
|
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
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
11
|
+
class << self
|
12
|
+
attr_accessor :mime_type
|
13
|
+
end
|
14
|
+
self.mime_type = 'application/x-www-form-urlencoded'
|
9
15
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
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
|
-
|
19
|
-
|
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
34
|
yield(env.body) unless env.body.respond_to?(:to_str)
|
22
35
|
end
|
23
|
-
end
|
24
36
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
37
|
+
# @param env [Faraday::Env]
|
38
|
+
#
|
39
|
+
# @return [Boolean] True if the request has a body and its Content-Type is
|
40
|
+
# urlencoded.
|
41
|
+
def process_request?(env)
|
42
|
+
type = request_type(env)
|
43
|
+
env.body && (type.empty? || (type == self.class.mime_type))
|
44
|
+
end
|
29
45
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
46
|
+
# @param env [Faraday::Env]
|
47
|
+
#
|
48
|
+
# @return [String]
|
49
|
+
def request_type(env)
|
50
|
+
type = env.request_headers[CONTENT_TYPE].to_s
|
51
|
+
type = type.split(';', 2).first if type.index(';')
|
52
|
+
type
|
53
|
+
end
|
34
54
|
end
|
35
55
|
end
|
36
56
|
end
|