faraday 0.9.1 → 2.5.2
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 +5 -5
- data/CHANGELOG.md +554 -0
- data/LICENSE.md +1 -1
- data/README.md +32 -197
- data/Rakefile +4 -68
- data/examples/client_spec.rb +119 -0
- data/examples/client_test.rb +144 -0
- data/lib/faraday/adapter/test.rb +194 -58
- data/lib/faraday/adapter.rb +76 -20
- data/lib/faraday/adapter_registry.rb +30 -0
- data/lib/faraday/connection.rb +341 -212
- data/lib/faraday/encoders/flat_params_encoder.rb +105 -0
- data/lib/faraday/encoders/nested_params_encoder.rb +183 -0
- data/lib/faraday/error.rb +123 -29
- data/lib/faraday/logging/formatter.rb +106 -0
- data/lib/faraday/methods.rb +6 -0
- data/lib/faraday/middleware.rb +18 -25
- data/lib/faraday/middleware_registry.rb +83 -0
- data/lib/faraday/options/connection_options.rb +22 -0
- data/lib/faraday/options/env.rb +199 -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 +69 -0
- data/lib/faraday/options.rb +63 -195
- data/lib/faraday/parameters.rb +4 -180
- data/lib/faraday/rack_builder.rb +99 -59
- data/lib/faraday/request/authorization.rb +37 -30
- data/lib/faraday/request/instrumentation.rb +47 -27
- data/lib/faraday/request/json.rb +55 -0
- data/lib/faraday/request/url_encoded.rb +48 -24
- data/lib/faraday/request.rb +76 -32
- data/lib/faraday/response/json.rb +54 -0
- data/lib/faraday/response/logger.rb +22 -48
- data/lib/faraday/response/raise_error.rb +57 -14
- data/lib/faraday/response.rb +32 -35
- data/lib/faraday/utils/headers.rb +139 -0
- data/lib/faraday/utils/params_hash.rb +61 -0
- data/lib/faraday/utils.rb +47 -222
- data/lib/faraday/version.rb +5 -0
- data/lib/faraday.rb +111 -222
- data/spec/external_adapters/faraday_specs_setup.rb +14 -0
- data/spec/faraday/adapter/test_spec.rb +413 -0
- data/spec/faraday/adapter_registry_spec.rb +28 -0
- data/spec/faraday/adapter_spec.rb +55 -0
- data/spec/faraday/connection_spec.rb +793 -0
- data/spec/faraday/error_spec.rb +60 -0
- data/spec/faraday/middleware_registry_spec.rb +31 -0
- data/spec/faraday/middleware_spec.rb +52 -0
- data/spec/faraday/options/env_spec.rb +76 -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 +150 -0
- data/spec/faraday/rack_builder_spec.rb +317 -0
- data/spec/faraday/request/authorization_spec.rb +83 -0
- data/spec/faraday/request/instrumentation_spec.rb +74 -0
- data/spec/faraday/request/json_spec.rb +111 -0
- data/spec/faraday/request/url_encoded_spec.rb +93 -0
- data/spec/faraday/request_spec.rb +110 -0
- data/spec/faraday/response/json_spec.rb +117 -0
- data/spec/faraday/response/logger_spec.rb +220 -0
- data/spec/faraday/response/raise_error_spec.rb +172 -0
- data/spec/faraday/response_spec.rb +75 -0
- data/spec/faraday/utils/headers_spec.rb +82 -0
- data/spec/faraday/utils_spec.rb +118 -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 +96 -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 +263 -0
- data/spec/support/streaming_response_checker.rb +35 -0
- metadata +81 -109
- data/.document +0 -6
- data/CONTRIBUTING.md +0 -36
- data/Gemfile +0 -25
- data/faraday.gemspec +0 -34
- data/lib/faraday/adapter/em_http.rb +0 -237
- 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 -92
- data/lib/faraday/adapter/excon.rb +0 -80
- data/lib/faraday/adapter/httpclient.rb +0 -106
- data/lib/faraday/adapter/net_http.rb +0 -130
- data/lib/faraday/adapter/net_http_persistent.rb +0 -48
- data/lib/faraday/adapter/patron.rb +0 -72
- data/lib/faraday/adapter/rack.rb +0 -58
- data/lib/faraday/adapter/typhoeus.rb +0 -123
- data/lib/faraday/autoload.rb +0 -84
- data/lib/faraday/request/basic_authentication.rb +0 -13
- data/lib/faraday/request/multipart.rb +0 -63
- data/lib/faraday/request/retry.rb +0 -148
- data/lib/faraday/request/token_authentication.rb +0 -15
- data/lib/faraday/upload_io.rb +0 -67
- data/script/cached-bundle +0 -46
- data/script/console +0 -7
- data/script/generate_certs +0 -42
- data/script/package +0 -7
- data/script/proxy-server +0 -42
- data/script/release +0 -17
- data/script/s3-put +0 -71
- data/script/server +0 -36
- data/script/test +0 -172
- data/test/adapters/default_test.rb +0 -14
- data/test/adapters/em_http_test.rb +0 -20
- data/test/adapters/em_synchrony_test.rb +0 -20
- data/test/adapters/excon_test.rb +0 -20
- data/test/adapters/httpclient_test.rb +0 -21
- data/test/adapters/integration.rb +0 -254
- data/test/adapters/logger_test.rb +0 -82
- data/test/adapters/net_http_persistent_test.rb +0 -20
- data/test/adapters/net_http_test.rb +0 -14
- data/test/adapters/patron_test.rb +0 -20
- data/test/adapters/rack_test.rb +0 -31
- data/test/adapters/test_middleware_test.rb +0 -114
- data/test/adapters/typhoeus_test.rb +0 -28
- data/test/authentication_middleware_test.rb +0 -65
- data/test/composite_read_io_test.rb +0 -111
- data/test/connection_test.rb +0 -522
- data/test/env_test.rb +0 -218
- data/test/helper.rb +0 -81
- data/test/live_server.rb +0 -67
- data/test/middleware/instrumentation_test.rb +0 -88
- data/test/middleware/retry_test.rb +0 -177
- data/test/middleware_stack_test.rb +0 -173
- data/test/multibyte.txt +0 -1
- data/test/options_test.rb +0 -252
- data/test/parameters_test.rb +0 -64
- data/test/request_middleware_test.rb +0 -142
- data/test/response_middleware_test.rb +0 -72
- data/test/strawberry.rb +0 -2
- data/test/utils_test.rb +0 -58
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://httpbingo.org') 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,33 +53,34 @@ 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(
|
|
53
|
-
@
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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
|
|
61
71
|
end
|
|
62
72
|
|
|
63
|
-
def build
|
|
73
|
+
def build
|
|
64
74
|
raise_if_locked
|
|
65
|
-
|
|
66
|
-
|
|
75
|
+
block_given? ? yield(self) : request(:url_encoded)
|
|
76
|
+
adapter(Faraday.default_adapter, **Faraday.default_adapter_options) unless @adapter
|
|
67
77
|
end
|
|
68
78
|
|
|
69
79
|
def [](idx)
|
|
70
80
|
@handlers[idx]
|
|
71
81
|
end
|
|
72
82
|
|
|
73
|
-
# Locks the middleware stack to ensure no further modifications are
|
|
83
|
+
# Locks the middleware stack to ensure no further modifications are made.
|
|
74
84
|
def lock!
|
|
75
85
|
@handlers.freeze
|
|
76
86
|
end
|
|
@@ -79,44 +89,48 @@ module Faraday
|
|
|
79
89
|
@handlers.frozen?
|
|
80
90
|
end
|
|
81
91
|
|
|
82
|
-
def use(klass, *args, &block)
|
|
92
|
+
ruby2_keywords def use(klass, *args, &block)
|
|
83
93
|
if klass.is_a? Symbol
|
|
84
94
|
use_symbol(Faraday::Middleware, klass, *args, &block)
|
|
85
95
|
else
|
|
86
96
|
raise_if_locked
|
|
97
|
+
raise_if_adapter(klass)
|
|
87
98
|
@handlers << self.class::Handler.new(klass, *args, &block)
|
|
88
99
|
end
|
|
89
100
|
end
|
|
90
101
|
|
|
91
|
-
def request(key, *args, &block)
|
|
102
|
+
ruby2_keywords def request(key, *args, &block)
|
|
92
103
|
use_symbol(Faraday::Request, key, *args, &block)
|
|
93
104
|
end
|
|
94
105
|
|
|
95
|
-
def response(key, *args, &block)
|
|
106
|
+
ruby2_keywords def response(key, *args, &block)
|
|
96
107
|
use_symbol(Faraday::Response, key, *args, &block)
|
|
97
108
|
end
|
|
98
109
|
|
|
99
|
-
def adapter(
|
|
100
|
-
|
|
110
|
+
ruby2_keywords def adapter(klass = NO_ARGUMENT, *args, &block)
|
|
111
|
+
return @adapter if klass == NO_ARGUMENT || klass.nil?
|
|
112
|
+
|
|
113
|
+
klass = Faraday::Adapter.lookup_middleware(klass) if klass.is_a?(Symbol)
|
|
114
|
+
@adapter = self.class::Handler.new(klass, *args, &block)
|
|
101
115
|
end
|
|
102
116
|
|
|
103
117
|
## methods to push onto the various positions in the stack:
|
|
104
118
|
|
|
105
|
-
def insert(index, *args, &block)
|
|
119
|
+
ruby2_keywords def insert(index, *args, &block)
|
|
106
120
|
raise_if_locked
|
|
107
121
|
index = assert_index(index)
|
|
108
122
|
handler = self.class::Handler.new(*args, &block)
|
|
109
123
|
@handlers.insert(index, handler)
|
|
110
124
|
end
|
|
111
125
|
|
|
112
|
-
|
|
126
|
+
alias insert_before insert
|
|
113
127
|
|
|
114
|
-
def insert_after(index, *args, &block)
|
|
128
|
+
ruby2_keywords def insert_after(index, *args, &block)
|
|
115
129
|
index = assert_index(index)
|
|
116
130
|
insert(index + 1, *args, &block)
|
|
117
131
|
end
|
|
118
132
|
|
|
119
|
-
def swap(index, *args, &block)
|
|
133
|
+
ruby2_keywords def swap(index, *args, &block)
|
|
120
134
|
raise_if_locked
|
|
121
135
|
index = assert_index(index)
|
|
122
136
|
@handlers.delete_at(index)
|
|
@@ -131,10 +145,10 @@ module Faraday
|
|
|
131
145
|
# Processes a Request into a Response by passing it through this Builder's
|
|
132
146
|
# middleware stack.
|
|
133
147
|
#
|
|
134
|
-
# connection
|
|
135
|
-
# request
|
|
148
|
+
# @param connection [Faraday::Connection]
|
|
149
|
+
# @param request [Faraday::Request]
|
|
136
150
|
#
|
|
137
|
-
#
|
|
151
|
+
# @return [Faraday::Response]
|
|
138
152
|
def build_response(connection, request)
|
|
139
153
|
app.call(build_env(connection, request))
|
|
140
154
|
end
|
|
@@ -149,29 +163,27 @@ module Faraday
|
|
|
149
163
|
def app
|
|
150
164
|
@app ||= begin
|
|
151
165
|
lock!
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
response.finish(env) unless env.parallel?
|
|
155
|
-
env.response = response
|
|
156
|
-
})
|
|
166
|
+
ensure_adapter!
|
|
167
|
+
to_app
|
|
157
168
|
end
|
|
158
169
|
end
|
|
159
170
|
|
|
160
|
-
def to_app
|
|
171
|
+
def to_app
|
|
161
172
|
# last added handler is the deepest and thus closest to the inner app
|
|
162
|
-
|
|
173
|
+
# adapter is always the last one
|
|
174
|
+
@handlers.reverse.inject(@adapter.build) do |app, handler|
|
|
175
|
+
handler.build(app)
|
|
176
|
+
end
|
|
163
177
|
end
|
|
164
178
|
|
|
165
179
|
def ==(other)
|
|
166
|
-
other.is_a?(self.class) &&
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
def dup
|
|
170
|
-
self.class.new(@handlers.dup)
|
|
180
|
+
other.is_a?(self.class) &&
|
|
181
|
+
@handlers == other.handlers &&
|
|
182
|
+
@adapter == other.adapter
|
|
171
183
|
end
|
|
172
184
|
|
|
173
185
|
# ENV Keys
|
|
174
|
-
# :
|
|
186
|
+
# :http_method - a symbolized request HTTP method (:get, :post)
|
|
175
187
|
# :body - the request body that will eventually be converted to a string.
|
|
176
188
|
# :url - URI instance for the current request.
|
|
177
189
|
# :status - HTTP response status code
|
|
@@ -187,25 +199,53 @@ module Faraday
|
|
|
187
199
|
# :password - Proxy server password
|
|
188
200
|
# :ssl - Hash of options for configuring SSL requests.
|
|
189
201
|
def build_env(connection, request)
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
request.options
|
|
193
|
-
|
|
202
|
+
exclusive_url = connection.build_exclusive_url(
|
|
203
|
+
request.path, request.params,
|
|
204
|
+
request.options.params_encoder
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
Env.new(request.http_method, request.body, exclusive_url,
|
|
208
|
+
request.options, request.headers, connection.ssl,
|
|
209
|
+
connection.parallel_manager)
|
|
194
210
|
end
|
|
195
211
|
|
|
196
212
|
private
|
|
197
213
|
|
|
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
|
+
|
|
198
219
|
def raise_if_locked
|
|
199
|
-
raise StackLocked,
|
|
220
|
+
raise StackLocked, LOCK_ERR if locked?
|
|
200
221
|
end
|
|
201
222
|
|
|
202
|
-
def
|
|
223
|
+
def raise_if_adapter(klass)
|
|
224
|
+
return unless is_adapter?(klass)
|
|
225
|
+
|
|
226
|
+
raise 'Adapter should be set using the `adapter` method, not `use`'
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
def ensure_adapter!
|
|
230
|
+
raise MISSING_ADAPTER_ERROR unless @adapter
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
def adapter_set?
|
|
234
|
+
!@adapter.nil?
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
def is_adapter?(klass) # rubocop:disable Naming/PredicateName
|
|
238
|
+
klass <= Faraday::Adapter
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
ruby2_keywords def use_symbol(mod, key, *args, &block)
|
|
203
242
|
use(mod.lookup_middleware(key), *args, &block)
|
|
204
243
|
end
|
|
205
244
|
|
|
206
245
|
def assert_index(index)
|
|
207
246
|
idx = index.is_a?(Integer) ? index : @handlers.index(index)
|
|
208
247
|
raise "No such handler: #{index.inspect}" unless idx
|
|
248
|
+
|
|
209
249
|
idx
|
|
210
250
|
end
|
|
211
251
|
end
|
|
@@ -1,42 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Faraday
|
|
2
|
-
class Request
|
|
3
|
-
|
|
4
|
+
class Request
|
|
5
|
+
# Request middleware for the Authorization HTTP header
|
|
6
|
+
class Authorization < Faraday::Middleware
|
|
7
|
+
KEY = 'Authorization'
|
|
4
8
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
# @param app [#call]
|
|
10
|
+
# @param type [String, Symbol] Type of Authorization
|
|
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
|
|
19
|
+
super(app)
|
|
14
20
|
end
|
|
15
|
-
end
|
|
16
21
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
hash.each do |key, value|
|
|
23
|
-
values << "#{key}=#{value.to_s.inspect}"
|
|
22
|
+
# @param env [Faraday::Env]
|
|
23
|
+
def on_request(env)
|
|
24
|
+
return if env.request_headers[KEY]
|
|
25
|
+
|
|
26
|
+
env.request_headers[KEY] = header_from(@type, *@params)
|
|
24
27
|
end
|
|
25
|
-
"#{type} #{values * comma}"
|
|
26
|
-
end
|
|
27
28
|
|
|
28
|
-
|
|
29
|
-
@header_value = self.class.header(type, token)
|
|
30
|
-
super(app)
|
|
31
|
-
end
|
|
29
|
+
private
|
|
32
30
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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
|
|
37
44
|
end
|
|
38
|
-
@app.call(env)
|
|
39
45
|
end
|
|
40
46
|
end
|
|
41
47
|
end
|
|
42
48
|
|
|
49
|
+
Faraday::Request.register_middleware(authorization: Faraday::Request::Authorization)
|
|
@@ -1,36 +1,56 @@
|
|
|
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
|
|
36
54
|
end
|
|
55
|
+
|
|
56
|
+
Faraday::Request.register_middleware(instrumentation: Faraday::Request::Instrumentation)
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'json'
|
|
4
|
+
|
|
5
|
+
module Faraday
|
|
6
|
+
class Request
|
|
7
|
+
# Request middleware that encodes the body as JSON.
|
|
8
|
+
#
|
|
9
|
+
# Processes only requests with matching Content-type or those without a type.
|
|
10
|
+
# If a request doesn't have a type but has a body, it sets the Content-type
|
|
11
|
+
# to JSON MIME-type.
|
|
12
|
+
#
|
|
13
|
+
# Doesn't try to encode bodies that already are in string form.
|
|
14
|
+
class Json < Middleware
|
|
15
|
+
MIME_TYPE = 'application/json'
|
|
16
|
+
MIME_TYPE_REGEX = %r{^application/(vnd\..+\+)?json$}.freeze
|
|
17
|
+
|
|
18
|
+
def on_request(env)
|
|
19
|
+
match_content_type(env) do |data|
|
|
20
|
+
env[:body] = encode(data)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
def encode(data)
|
|
27
|
+
::JSON.generate(data)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def match_content_type(env)
|
|
31
|
+
return unless process_request?(env)
|
|
32
|
+
|
|
33
|
+
env[:request_headers][CONTENT_TYPE] ||= MIME_TYPE
|
|
34
|
+
yield env[:body] unless env[:body].respond_to?(:to_str)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def process_request?(env)
|
|
38
|
+
type = request_type(env)
|
|
39
|
+
body?(env) && (type.empty? || type.match?(MIME_TYPE_REGEX))
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def body?(env)
|
|
43
|
+
(body = env[:body]) && !(body.respond_to?(:to_str) && body.empty?)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def request_type(env)
|
|
47
|
+
type = env[:request_headers][CONTENT_TYPE].to_s
|
|
48
|
+
type = type.split(';', 2).first if type.index(';')
|
|
49
|
+
type
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
Faraday::Request.register_middleware(json: Faraday::Request::Json)
|
|
@@ -1,36 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Faraday
|
|
2
|
-
class Request
|
|
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
|
+
return if env.body.respond_to?(:to_str) || env.body.respond_to?(:read)
|
|
35
|
+
|
|
36
|
+
yield(env.body)
|
|
22
37
|
end
|
|
23
|
-
end
|
|
24
38
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
39
|
+
# @param env [Faraday::Env]
|
|
40
|
+
#
|
|
41
|
+
# @return [Boolean] True if the request has a body and its Content-Type is
|
|
42
|
+
# urlencoded.
|
|
43
|
+
def process_request?(env)
|
|
44
|
+
type = request_type(env)
|
|
45
|
+
env.body && (type.empty? || (type == self.class.mime_type))
|
|
46
|
+
end
|
|
29
47
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
48
|
+
# @param env [Faraday::Env]
|
|
49
|
+
#
|
|
50
|
+
# @return [String]
|
|
51
|
+
def request_type(env)
|
|
52
|
+
type = env.request_headers[CONTENT_TYPE].to_s
|
|
53
|
+
type = type.split(';', 2).first if type.index(';')
|
|
54
|
+
type
|
|
55
|
+
end
|
|
34
56
|
end
|
|
35
57
|
end
|
|
36
58
|
end
|
|
59
|
+
|
|
60
|
+
Faraday::Request.register_middleware(url_encoded: Faraday::Request::UrlEncoded)
|