faraday 1.4.3 → 1.7.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/examples/client_spec.rb +21 -2
- data/lib/faraday.rb +7 -2
- data/lib/faraday/adapter.rb +1 -4
- data/lib/faraday/adapter/test.rb +34 -5
- data/lib/faraday/autoload.rb +1 -4
- data/lib/faraday/connection.rb +3 -2
- data/lib/faraday/version.rb +1 -1
- data/spec/faraday/adapter/em_http_spec.rb +39 -37
- data/spec/faraday/adapter/em_synchrony_spec.rb +11 -9
- data/spec/faraday/adapter/test_spec.rb +85 -0
- metadata +45 -6
- data/lib/faraday/adapter/httpclient.rb +0 -152
- data/lib/faraday/adapter/patron.rb +0 -132
- data/lib/faraday/adapter/rack.rb +0 -75
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e0b66c2e6b13140f2093c73a7b8dab39dd25690b15b1e5eadaba90a787d2fdf5
|
4
|
+
data.tar.gz: af34783d38f124632f2e4edcfd7f6bf2d763bd5d6f36ad8b6de6cac675c9858d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dd547129c965998e13208a5a0accab40ddee955f7a001365f2a951c6a0e7d7fefc9e61c5d708188deff9e8e239c991627485e3f07e9686a87a3cd30938a8f05b
|
7
|
+
data.tar.gz: 81fdc31d08d17db983ea4a4c68951942c3673d5447096e1f51cd0f4eebac1289348b860a56e064131b65ef59e3ed6f63ce1fc004db435f7fb051460b98190b31
|
data/examples/client_spec.rb
CHANGED
@@ -12,8 +12,8 @@ class Client
|
|
12
12
|
@conn = conn
|
13
13
|
end
|
14
14
|
|
15
|
-
def sushi(jname)
|
16
|
-
res = @conn.get("/#{jname}")
|
15
|
+
def sushi(jname, params: {})
|
16
|
+
res = @conn.get("/#{jname}", params)
|
17
17
|
data = JSON.parse(res.body)
|
18
18
|
data['name']
|
19
19
|
end
|
@@ -62,4 +62,23 @@ RSpec.describe Client do
|
|
62
62
|
expect { client.sushi('ebi') }.to raise_error(Faraday::ConnectionFailed)
|
63
63
|
stubs.verify_stubbed_calls
|
64
64
|
end
|
65
|
+
|
66
|
+
context 'When the test stub is run in strict_mode' do
|
67
|
+
let(:stubs) { Faraday::Adapter::Test::Stubs.new(strict_mode: true) }
|
68
|
+
|
69
|
+
it 'verifies the all parameter values are identical' do
|
70
|
+
stubs.get('/ebi?abc=123') do
|
71
|
+
[
|
72
|
+
200,
|
73
|
+
{ 'Content-Type': 'application/javascript' },
|
74
|
+
'{"name": "shrimp"}'
|
75
|
+
]
|
76
|
+
end
|
77
|
+
|
78
|
+
# uncomment to raise Stubs::NotFound
|
79
|
+
# expect(client.sushi('ebi', params: { abc: 123, foo: 'Kappa' })).to eq('shrimp')
|
80
|
+
expect(client.sushi('ebi', params: { abc: 123 })).to eq('shrimp')
|
81
|
+
stubs.verify_stubbed_calls
|
82
|
+
end
|
83
|
+
end
|
65
84
|
end
|
data/lib/faraday.rb
CHANGED
@@ -27,11 +27,16 @@ require 'faraday/error'
|
|
27
27
|
require 'faraday/file_part'
|
28
28
|
require 'faraday/param_part'
|
29
29
|
|
30
|
-
|
31
|
-
require 'faraday/
|
30
|
+
unless defined?(JRUBY_VERSION)
|
31
|
+
require 'faraday/em_http'
|
32
|
+
require 'faraday/em_synchrony'
|
33
|
+
end
|
32
34
|
require 'faraday/excon'
|
35
|
+
require 'faraday/httpclient'
|
33
36
|
require 'faraday/net_http'
|
34
37
|
require 'faraday/net_http_persistent'
|
38
|
+
require 'faraday/patron'
|
39
|
+
require 'faraday/rack'
|
35
40
|
|
36
41
|
# This is the main namespace for Faraday.
|
37
42
|
#
|
data/lib/faraday/adapter.rb
CHANGED
@@ -11,10 +11,7 @@ module Faraday
|
|
11
11
|
|
12
12
|
register_middleware File.expand_path('adapter', __dir__),
|
13
13
|
test: [:Test, 'test'],
|
14
|
-
typhoeus: [:Typhoeus, 'typhoeus']
|
15
|
-
patron: [:Patron, 'patron'],
|
16
|
-
rack: [:Rack, 'rack'],
|
17
|
-
httpclient: [:HTTPClient, 'httpclient']
|
14
|
+
typhoeus: [:Typhoeus, 'typhoeus']
|
18
15
|
|
19
16
|
# This module marks an Adapter as supporting parallel requests.
|
20
17
|
module Parallelism
|
data/lib/faraday/adapter/test.rb
CHANGED
@@ -25,6 +25,9 @@ module Faraday
|
|
25
25
|
# "showing item: #{meta[:match_data][1]}"
|
26
26
|
# ]
|
27
27
|
# end
|
28
|
+
#
|
29
|
+
# # You can set strict_mode to exactly match the stubbed requests.
|
30
|
+
# stub.strict_mode = true
|
28
31
|
# end
|
29
32
|
# end
|
30
33
|
#
|
@@ -47,10 +50,11 @@ module Faraday
|
|
47
50
|
class NotFound < StandardError
|
48
51
|
end
|
49
52
|
|
50
|
-
def initialize
|
53
|
+
def initialize(strict_mode: false)
|
51
54
|
# { get: [Stub, Stub] }
|
52
55
|
@stack = {}
|
53
56
|
@consumed = {}
|
57
|
+
@strict_mode = strict_mode
|
54
58
|
yield(self) if block_given?
|
55
59
|
end
|
56
60
|
|
@@ -115,6 +119,17 @@ module Faraday
|
|
115
119
|
raise failed_stubs.join(' ') unless failed_stubs.empty?
|
116
120
|
end
|
117
121
|
|
122
|
+
# Set strict_mode. If the value is true, this adapter tries to find matched requests strictly,
|
123
|
+
# which means that all of a path, parameters, and headers must be the same as an actual request.
|
124
|
+
def strict_mode=(value)
|
125
|
+
@strict_mode = value
|
126
|
+
@stack.each do |_method, stubs|
|
127
|
+
stubs.each do |stub|
|
128
|
+
stub.strict_mode = value
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
118
133
|
protected
|
119
134
|
|
120
135
|
def new_stub(request_method, path, headers = {}, body = nil, &block)
|
@@ -128,7 +143,8 @@ module Faraday
|
|
128
143
|
]
|
129
144
|
end
|
130
145
|
|
131
|
-
|
146
|
+
headers = Utils::Headers.new(headers)
|
147
|
+
stub = Stub.new(host, normalized_path, headers, body, @strict_mode, block)
|
132
148
|
(@stack[request_method] ||= []) << stub
|
133
149
|
end
|
134
150
|
|
@@ -143,9 +159,9 @@ module Faraday
|
|
143
159
|
|
144
160
|
# Stub request
|
145
161
|
# rubocop:disable Style/StructInheritance
|
146
|
-
class Stub < Struct.new(:host, :path, :params, :headers, :body, :block)
|
162
|
+
class Stub < Struct.new(:host, :path, :params, :headers, :body, :strict_mode, :block)
|
147
163
|
# rubocop:enable Style/StructInheritance
|
148
|
-
def initialize(host, full, headers, body, block)
|
164
|
+
def initialize(host, full, headers, body, strict_mode, block) # rubocop:disable Metrics/ParameterLists
|
149
165
|
path, query = full.respond_to?(:split) ? full.split('?') : full
|
150
166
|
params =
|
151
167
|
if query
|
@@ -154,7 +170,7 @@ module Faraday
|
|
154
170
|
{}
|
155
171
|
end
|
156
172
|
|
157
|
-
super(host, path, params, headers, body, block)
|
173
|
+
super(host, path, params, headers, body, strict_mode, block)
|
158
174
|
end
|
159
175
|
|
160
176
|
def matches?(request_host, request_uri, request_headers, request_body)
|
@@ -184,12 +200,25 @@ module Faraday
|
|
184
200
|
end
|
185
201
|
|
186
202
|
def params_match?(request_params)
|
203
|
+
if strict_mode
|
204
|
+
return Set.new(params) == Set.new(request_params)
|
205
|
+
end
|
206
|
+
|
187
207
|
params.keys.all? do |key|
|
188
208
|
request_params[key] == params[key]
|
189
209
|
end
|
190
210
|
end
|
191
211
|
|
192
212
|
def headers_match?(request_headers)
|
213
|
+
if strict_mode
|
214
|
+
headers_with_user_agent = headers.dup.tap do |hs|
|
215
|
+
# NOTE: Set User-Agent in case it's not set when creating Stubs.
|
216
|
+
# Users would not want to set Faraday's User-Agent explicitly.
|
217
|
+
hs[:user_agent] ||= Connection::USER_AGENT
|
218
|
+
end
|
219
|
+
return Set.new(headers_with_user_agent) == Set.new(request_headers)
|
220
|
+
end
|
221
|
+
|
193
222
|
headers.keys.all? do |key|
|
194
223
|
request_headers[key] == headers[key]
|
195
224
|
end
|
data/lib/faraday/autoload.rb
CHANGED
@@ -59,10 +59,7 @@ module Faraday
|
|
59
59
|
extend AutoloadHelper
|
60
60
|
autoload_all 'faraday/adapter',
|
61
61
|
Typhoeus: 'typhoeus',
|
62
|
-
|
63
|
-
Test: 'test',
|
64
|
-
Rack: 'rack',
|
65
|
-
HTTPClient: 'httpclient'
|
62
|
+
Test: 'test'
|
66
63
|
end
|
67
64
|
|
68
65
|
# Request represents a single HTTP request for a Faraday adapter to make.
|
data/lib/faraday/connection.rb
CHANGED
@@ -15,6 +15,7 @@ module Faraday
|
|
15
15
|
class Connection
|
16
16
|
# A Set of allowed HTTP verbs.
|
17
17
|
METHODS = Set.new %i[get post put delete head patch options trace]
|
18
|
+
USER_AGENT = "Faraday v#{VERSION}"
|
18
19
|
|
19
20
|
# @return [Hash] URI query unencoded key/value pairs.
|
20
21
|
attr_reader :params
|
@@ -26,7 +27,7 @@ module Faraday
|
|
26
27
|
# Connection. This includes a default host name, scheme, port, and path.
|
27
28
|
attr_reader :url_prefix
|
28
29
|
|
29
|
-
# @return [Faraday::
|
30
|
+
# @return [Faraday::RackBuilder] Builder for this Connection.
|
30
31
|
attr_reader :builder
|
31
32
|
|
32
33
|
# @return [Hash] SSL options.
|
@@ -89,7 +90,7 @@ module Faraday
|
|
89
90
|
|
90
91
|
yield(self) if block_given?
|
91
92
|
|
92
|
-
@headers[:user_agent] ||=
|
93
|
+
@headers[:user_agent] ||= USER_AGENT
|
93
94
|
end
|
94
95
|
|
95
96
|
def initialize_proxy(url, options)
|
data/lib/faraday/version.rb
CHANGED
@@ -1,47 +1,49 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
unless defined?(JRUBY_VERSION)
|
4
|
+
RSpec.describe Faraday::Adapter::EMHttp do
|
5
|
+
features :request_body_on_query_methods, :reason_phrase_parse, :trace_method,
|
6
|
+
:skip_response_body_on_head, :parallel, :local_socket_binding
|
6
7
|
|
7
|
-
|
8
|
+
it_behaves_like 'an adapter'
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
it 'allows to provide adapter specific configs' do
|
11
|
+
url = URI('https://example.com:1234')
|
12
|
+
adapter = described_class.new nil, inactivity_timeout: 20
|
13
|
+
req = adapter.create_request(url: url, request: {})
|
13
14
|
|
14
|
-
|
15
|
-
end
|
16
|
-
|
17
|
-
context 'Options' do
|
18
|
-
let(:request) { Faraday::RequestOptions.new }
|
19
|
-
let(:env) { { request: request } }
|
20
|
-
let(:options) { {} }
|
21
|
-
let(:adapter) { Faraday::Adapter::EMHttp.new }
|
22
|
-
|
23
|
-
it 'configures timeout' do
|
24
|
-
request.timeout = 5
|
25
|
-
adapter.configure_timeout(options, env)
|
26
|
-
expect(options[:inactivity_timeout]).to eq(5)
|
27
|
-
expect(options[:connect_timeout]).to eq(5)
|
28
|
-
end
|
29
|
-
|
30
|
-
it 'configures timeout and open_timeout' do
|
31
|
-
request.timeout = 5
|
32
|
-
request.open_timeout = 1
|
33
|
-
adapter.configure_timeout(options, env)
|
34
|
-
expect(options[:inactivity_timeout]).to eq(5)
|
35
|
-
expect(options[:connect_timeout]).to eq(1)
|
15
|
+
expect(req.connopts.inactivity_timeout).to eq(20)
|
36
16
|
end
|
37
17
|
|
38
|
-
|
39
|
-
request.
|
40
|
-
request
|
41
|
-
|
42
|
-
adapter.
|
43
|
-
|
44
|
-
|
18
|
+
context 'Options' do
|
19
|
+
let(:request) { Faraday::RequestOptions.new }
|
20
|
+
let(:env) { { request: request } }
|
21
|
+
let(:options) { {} }
|
22
|
+
let(:adapter) { Faraday::Adapter::EMHttp.new }
|
23
|
+
|
24
|
+
it 'configures timeout' do
|
25
|
+
request.timeout = 5
|
26
|
+
adapter.configure_timeout(options, env)
|
27
|
+
expect(options[:inactivity_timeout]).to eq(5)
|
28
|
+
expect(options[:connect_timeout]).to eq(5)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'configures timeout and open_timeout' do
|
32
|
+
request.timeout = 5
|
33
|
+
request.open_timeout = 1
|
34
|
+
adapter.configure_timeout(options, env)
|
35
|
+
expect(options[:inactivity_timeout]).to eq(5)
|
36
|
+
expect(options[:connect_timeout]).to eq(1)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'configures all timeout settings' do
|
40
|
+
request.timeout = 5
|
41
|
+
request.read_timeout = 3
|
42
|
+
request.open_timeout = 1
|
43
|
+
adapter.configure_timeout(options, env)
|
44
|
+
expect(options[:inactivity_timeout]).to eq(3)
|
45
|
+
expect(options[:connect_timeout]).to eq(1)
|
46
|
+
end
|
45
47
|
end
|
46
48
|
end
|
47
49
|
end
|
@@ -1,16 +1,18 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
unless defined?(JRUBY_VERSION)
|
4
|
+
RSpec.describe Faraday::Adapter::EMSynchrony do
|
5
|
+
features :request_body_on_query_methods, :reason_phrase_parse,
|
6
|
+
:skip_response_body_on_head, :parallel, :local_socket_binding
|
6
7
|
|
7
|
-
|
8
|
+
it_behaves_like 'an adapter'
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
it 'allows to provide adapter specific configs' do
|
11
|
+
url = URI('https://example.com:1234')
|
12
|
+
adapter = described_class.new nil, inactivity_timeout: 20
|
13
|
+
req = adapter.create_request(url: url, request: {})
|
13
14
|
|
14
|
-
|
15
|
+
expect(req.connopts.inactivity_timeout).to eq(20)
|
16
|
+
end
|
15
17
|
end
|
16
18
|
end
|
@@ -257,4 +257,89 @@ RSpec.describe Faraday::Adapter::Test do
|
|
257
257
|
it { expect { request }.to raise_error described_class::Stubs::NotFound }
|
258
258
|
end
|
259
259
|
end
|
260
|
+
|
261
|
+
describe 'strict_mode' do
|
262
|
+
let(:stubs) do
|
263
|
+
described_class::Stubs.new(strict_mode: true) do |stubs|
|
264
|
+
stubs.get('/strict?a=12&b=xy', 'Authorization' => 'Bearer m_ck', 'X-C' => 'hello') { [200, {}, 'a'] }
|
265
|
+
stubs.get('/with_user_agent?a=12&b=xy', authorization: 'Bearer m_ck', 'User-Agent' => 'My Agent') { [200, {}, 'a'] }
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
context 'when params and headers are exactly set' do
|
270
|
+
subject(:request) { connection.get('/strict', { a: '12', b: 'xy' }, { authorization: 'Bearer m_ck', x_c: 'hello' }) }
|
271
|
+
|
272
|
+
it { expect(request.status).to eq 200 }
|
273
|
+
end
|
274
|
+
|
275
|
+
context 'when params and headers are exactly set with a custom user agent' do
|
276
|
+
subject(:request) { connection.get('/with_user_agent', { a: '12', b: 'xy' }, { authorization: 'Bearer m_ck', 'User-Agent' => 'My Agent' }) }
|
277
|
+
|
278
|
+
it { expect(request.status).to eq 200 }
|
279
|
+
end
|
280
|
+
|
281
|
+
shared_examples 'raise NotFound when params do not satisfy the strict check' do |params|
|
282
|
+
subject(:request) { connection.get('/strict', params, { 'Authorization' => 'Bearer m_ck', 'X-C' => 'hello' }) }
|
283
|
+
|
284
|
+
context "with #{params.inspect}" do
|
285
|
+
it { expect { request }.to raise_error described_class::Stubs::NotFound }
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
it_behaves_like 'raise NotFound when params do not satisfy the strict check', { a: '12' }
|
290
|
+
it_behaves_like 'raise NotFound when params do not satisfy the strict check', { b: 'xy' }
|
291
|
+
it_behaves_like 'raise NotFound when params do not satisfy the strict check', { a: '123', b: 'xy' }
|
292
|
+
it_behaves_like 'raise NotFound when params do not satisfy the strict check', { a: '12', b: 'xyz' }
|
293
|
+
it_behaves_like 'raise NotFound when params do not satisfy the strict check', { a: '12', b: 'xy', c: 'hello' }
|
294
|
+
it_behaves_like 'raise NotFound when params do not satisfy the strict check', { additional: 'special', a: '12', b: 'xy', c: 'hello' }
|
295
|
+
|
296
|
+
shared_examples 'raise NotFound when headers do not satisfy the strict check' do |path, headers|
|
297
|
+
subject(:request) { connection.get(path, { a: 12, b: 'xy' }, headers) }
|
298
|
+
|
299
|
+
context "with #{headers.inspect}" do
|
300
|
+
it { expect { request }.to raise_error described_class::Stubs::NotFound }
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
it_behaves_like 'raise NotFound when headers do not satisfy the strict check', '/strict', { authorization: 'Bearer m_ck' }
|
305
|
+
it_behaves_like 'raise NotFound when headers do not satisfy the strict check', '/strict', { 'X-C' => 'hello' }
|
306
|
+
it_behaves_like 'raise NotFound when headers do not satisfy the strict check', '/strict', { authorization: 'Bearer m_ck', 'x-c': 'Hi' }
|
307
|
+
it_behaves_like 'raise NotFound when headers do not satisfy the strict check', '/strict', { authorization: 'Basic m_ck', 'x-c': 'hello' }
|
308
|
+
it_behaves_like 'raise NotFound when headers do not satisfy the strict check', '/strict', { authorization: 'Bearer m_ck', 'x-c': 'hello', x_special: 'special' }
|
309
|
+
it_behaves_like 'raise NotFound when headers do not satisfy the strict check', '/with_user_agent', { authorization: 'Bearer m_ck' }
|
310
|
+
it_behaves_like 'raise NotFound when headers do not satisfy the strict check', '/with_user_agent', { authorization: 'Bearer m_ck', user_agent: 'Unknown' }
|
311
|
+
it_behaves_like 'raise NotFound when headers do not satisfy the strict check', '/with_user_agent', { authorization: 'Bearer m_ck', user_agent: 'My Agent', x_special: 'special' }
|
312
|
+
|
313
|
+
context 'when strict_mode is disabled' do
|
314
|
+
before do
|
315
|
+
stubs.strict_mode = false
|
316
|
+
end
|
317
|
+
|
318
|
+
shared_examples 'does not raise NotFound even when params do not satisfy the strict check' do |params|
|
319
|
+
subject(:request) { connection.get('/strict', params, { 'Authorization' => 'Bearer m_ck', 'X-C' => 'hello' }) }
|
320
|
+
|
321
|
+
context "with #{params.inspect}" do
|
322
|
+
it { expect(request.status).to eq 200 }
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
it_behaves_like 'does not raise NotFound even when params do not satisfy the strict check', { a: '12', b: 'xy' }
|
327
|
+
it_behaves_like 'does not raise NotFound even when params do not satisfy the strict check', { a: '12', b: 'xy', c: 'hello' }
|
328
|
+
it_behaves_like 'does not raise NotFound even when params do not satisfy the strict check', { additional: 'special', a: '12', b: 'xy', c: 'hello' }
|
329
|
+
|
330
|
+
shared_examples 'does not raise NotFound even when headers do not satisfy the strict check' do |path, headers|
|
331
|
+
subject(:request) { connection.get(path, { a: 12, b: 'xy' }, headers) }
|
332
|
+
|
333
|
+
context "with #{headers.inspect}" do
|
334
|
+
it { expect(request.status).to eq 200 }
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
it_behaves_like 'does not raise NotFound even when headers do not satisfy the strict check', '/strict', { authorization: 'Bearer m_ck', 'x-c': 'hello' }
|
339
|
+
it_behaves_like 'does not raise NotFound even when headers do not satisfy the strict check', '/strict', { authorization: 'Bearer m_ck', 'x-c': 'hello', x_special: 'special' }
|
340
|
+
it_behaves_like 'does not raise NotFound even when headers do not satisfy the strict check', '/strict', { authorization: 'Bearer m_ck', 'x-c': 'hello', user_agent: 'Special Agent' }
|
341
|
+
it_behaves_like 'does not raise NotFound even when headers do not satisfy the strict check', '/with_user_agent', { authorization: 'Bearer m_ck', user_agent: 'My Agent' }
|
342
|
+
it_behaves_like 'does not raise NotFound even when headers do not satisfy the strict check', '/with_user_agent', { authorization: 'Bearer m_ck', user_agent: 'My Agent', x_special: 'special' }
|
343
|
+
end
|
344
|
+
end
|
260
345
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: faraday
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- "@technoweenie"
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2021-
|
13
|
+
date: 2021-08-09 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: faraday-em_http
|
@@ -54,6 +54,20 @@ dependencies:
|
|
54
54
|
- - "~>"
|
55
55
|
- !ruby/object:Gem::Version
|
56
56
|
version: '1.1'
|
57
|
+
- !ruby/object:Gem::Dependency
|
58
|
+
name: faraday-httpclient
|
59
|
+
requirement: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - "~>"
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: 1.0.1
|
64
|
+
type: :runtime
|
65
|
+
prerelease: false
|
66
|
+
version_requirements: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - "~>"
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: 1.0.1
|
57
71
|
- !ruby/object:Gem::Dependency
|
58
72
|
name: faraday-net_http
|
59
73
|
requirement: !ruby/object:Gem::Requirement
|
@@ -82,6 +96,34 @@ dependencies:
|
|
82
96
|
- - "~>"
|
83
97
|
- !ruby/object:Gem::Version
|
84
98
|
version: '1.1'
|
99
|
+
- !ruby/object:Gem::Dependency
|
100
|
+
name: faraday-patron
|
101
|
+
requirement: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - "~>"
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '1.0'
|
106
|
+
type: :runtime
|
107
|
+
prerelease: false
|
108
|
+
version_requirements: !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - "~>"
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '1.0'
|
113
|
+
- !ruby/object:Gem::Dependency
|
114
|
+
name: faraday-rack
|
115
|
+
requirement: !ruby/object:Gem::Requirement
|
116
|
+
requirements:
|
117
|
+
- - "~>"
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: '1.0'
|
120
|
+
type: :runtime
|
121
|
+
prerelease: false
|
122
|
+
version_requirements: !ruby/object:Gem::Requirement
|
123
|
+
requirements:
|
124
|
+
- - "~>"
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: '1.0'
|
85
127
|
- !ruby/object:Gem::Dependency
|
86
128
|
name: multipart-post
|
87
129
|
requirement: !ruby/object:Gem::Requirement
|
@@ -130,9 +172,6 @@ files:
|
|
130
172
|
- examples/client_test.rb
|
131
173
|
- lib/faraday.rb
|
132
174
|
- lib/faraday/adapter.rb
|
133
|
-
- lib/faraday/adapter/httpclient.rb
|
134
|
-
- lib/faraday/adapter/patron.rb
|
135
|
-
- lib/faraday/adapter/rack.rb
|
136
175
|
- lib/faraday/adapter/test.rb
|
137
176
|
- lib/faraday/adapter/typhoeus.rb
|
138
177
|
- lib/faraday/adapter_registry.rb
|
@@ -221,7 +260,7 @@ licenses:
|
|
221
260
|
- MIT
|
222
261
|
metadata:
|
223
262
|
homepage_uri: https://lostisland.github.io/faraday
|
224
|
-
changelog_uri: https://github.com/lostisland/faraday/releases/tag/v1.
|
263
|
+
changelog_uri: https://github.com/lostisland/faraday/releases/tag/v1.7.0
|
225
264
|
source_code_uri: https://github.com/lostisland/faraday
|
226
265
|
bug_tracker_uri: https://github.com/lostisland/faraday/issues
|
227
266
|
post_install_message:
|
@@ -1,152 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Faraday
|
4
|
-
class Adapter
|
5
|
-
# HTTPClient adapter.
|
6
|
-
class HTTPClient < Faraday::Adapter
|
7
|
-
dependency 'httpclient'
|
8
|
-
|
9
|
-
def build_connection(env)
|
10
|
-
@client ||= ::HTTPClient.new.tap do |cli|
|
11
|
-
# enable compression
|
12
|
-
cli.transparent_gzip_decompression = true
|
13
|
-
end
|
14
|
-
|
15
|
-
if (req = env[:request])
|
16
|
-
if (proxy = req[:proxy])
|
17
|
-
configure_proxy @client, proxy
|
18
|
-
end
|
19
|
-
|
20
|
-
if (bind = req[:bind])
|
21
|
-
configure_socket @client, bind
|
22
|
-
end
|
23
|
-
|
24
|
-
configure_timeouts @client, req
|
25
|
-
end
|
26
|
-
|
27
|
-
if env[:url].scheme == 'https' && (ssl = env[:ssl])
|
28
|
-
configure_ssl @client, ssl
|
29
|
-
end
|
30
|
-
|
31
|
-
configure_client @client
|
32
|
-
|
33
|
-
@client
|
34
|
-
end
|
35
|
-
|
36
|
-
def call(env)
|
37
|
-
super
|
38
|
-
|
39
|
-
# TODO: Don't stream yet.
|
40
|
-
# https://github.com/nahi/httpclient/pull/90
|
41
|
-
env[:body] = env[:body].read if env[:body].respond_to? :read
|
42
|
-
|
43
|
-
connection(env) do |http|
|
44
|
-
resp = http.request env[:method], env[:url],
|
45
|
-
body: env[:body],
|
46
|
-
header: env[:request_headers]
|
47
|
-
|
48
|
-
if (req = env[:request]).stream_response?
|
49
|
-
warn "Streaming downloads for #{self.class.name} " \
|
50
|
-
'are not yet implemented.'
|
51
|
-
req.on_data.call(resp.body, resp.body.bytesize)
|
52
|
-
end
|
53
|
-
save_response env, resp.status, resp.body, resp.headers, resp.reason
|
54
|
-
|
55
|
-
@app.call env
|
56
|
-
end
|
57
|
-
rescue ::HTTPClient::TimeoutError, Errno::ETIMEDOUT
|
58
|
-
raise Faraday::TimeoutError, $ERROR_INFO
|
59
|
-
rescue ::HTTPClient::BadResponseError => e
|
60
|
-
if e.message.include?('status 407')
|
61
|
-
raise Faraday::ConnectionFailed,
|
62
|
-
%(407 "Proxy Authentication Required ")
|
63
|
-
end
|
64
|
-
|
65
|
-
raise Faraday::ClientError, $ERROR_INFO
|
66
|
-
rescue Errno::EADDRNOTAVAIL, Errno::ECONNREFUSED, IOError, SocketError
|
67
|
-
raise Faraday::ConnectionFailed, $ERROR_INFO
|
68
|
-
rescue StandardError => e
|
69
|
-
if defined?(::OpenSSL::SSL::SSLError) && \
|
70
|
-
e.is_a?(::OpenSSL::SSL::SSLError)
|
71
|
-
raise Faraday::SSLError, e
|
72
|
-
end
|
73
|
-
|
74
|
-
raise
|
75
|
-
end
|
76
|
-
|
77
|
-
# @param bind [Hash]
|
78
|
-
def configure_socket(client, bind)
|
79
|
-
client.socket_local.host = bind[:host]
|
80
|
-
client.socket_local.port = bind[:port]
|
81
|
-
end
|
82
|
-
|
83
|
-
# Configure proxy URI and any user credentials.
|
84
|
-
#
|
85
|
-
# @param proxy [Hash]
|
86
|
-
def configure_proxy(client, proxy)
|
87
|
-
client.proxy = proxy[:uri]
|
88
|
-
return unless proxy[:user] && proxy[:password]
|
89
|
-
|
90
|
-
client.set_proxy_auth(proxy[:user], proxy[:password])
|
91
|
-
end
|
92
|
-
|
93
|
-
# @param ssl [Hash]
|
94
|
-
def configure_ssl(client, ssl)
|
95
|
-
ssl_config = client.ssl_config
|
96
|
-
ssl_config.verify_mode = ssl_verify_mode(ssl)
|
97
|
-
ssl_config.cert_store = ssl_cert_store(ssl)
|
98
|
-
|
99
|
-
ssl_config.add_trust_ca ssl[:ca_file] if ssl[:ca_file]
|
100
|
-
ssl_config.add_trust_ca ssl[:ca_path] if ssl[:ca_path]
|
101
|
-
ssl_config.client_cert = ssl[:client_cert] if ssl[:client_cert]
|
102
|
-
ssl_config.client_key = ssl[:client_key] if ssl[:client_key]
|
103
|
-
ssl_config.verify_depth = ssl[:verify_depth] if ssl[:verify_depth]
|
104
|
-
end
|
105
|
-
|
106
|
-
# @param req [Hash]
|
107
|
-
def configure_timeouts(client, req)
|
108
|
-
if (sec = request_timeout(:open, req))
|
109
|
-
client.connect_timeout = sec
|
110
|
-
end
|
111
|
-
|
112
|
-
if (sec = request_timeout(:write, req))
|
113
|
-
client.send_timeout = sec
|
114
|
-
end
|
115
|
-
|
116
|
-
return unless (sec = request_timeout(:read, req))
|
117
|
-
|
118
|
-
client.receive_timeout = sec
|
119
|
-
end
|
120
|
-
|
121
|
-
def configure_client(client)
|
122
|
-
@config_block&.call(client)
|
123
|
-
end
|
124
|
-
|
125
|
-
# @param ssl [Hash]
|
126
|
-
# @return [OpenSSL::X509::Store]
|
127
|
-
def ssl_cert_store(ssl)
|
128
|
-
return ssl[:cert_store] if ssl[:cert_store]
|
129
|
-
|
130
|
-
# Memoize the cert store so that the same one is passed to
|
131
|
-
# HTTPClient each time, to avoid resyncing SSL sessions when
|
132
|
-
# it's changed
|
133
|
-
@ssl_cert_store ||= begin
|
134
|
-
# Use the default cert store by default, i.e. system ca certs
|
135
|
-
OpenSSL::X509::Store.new.tap(&:set_default_paths)
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
# @param ssl [Hash]
|
140
|
-
def ssl_verify_mode(ssl)
|
141
|
-
ssl[:verify_mode] || begin
|
142
|
-
if ssl.fetch(:verify, true)
|
143
|
-
OpenSSL::SSL::VERIFY_PEER |
|
144
|
-
OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
|
145
|
-
else
|
146
|
-
OpenSSL::SSL::VERIFY_NONE
|
147
|
-
end
|
148
|
-
end
|
149
|
-
end
|
150
|
-
end
|
151
|
-
end
|
152
|
-
end
|
@@ -1,132 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Faraday
|
4
|
-
class Adapter
|
5
|
-
# Patron adapter.
|
6
|
-
class Patron < Faraday::Adapter
|
7
|
-
dependency 'patron'
|
8
|
-
|
9
|
-
def build_connection(env)
|
10
|
-
session = ::Patron::Session.new
|
11
|
-
@config_block&.call(session)
|
12
|
-
if (env[:url].scheme == 'https') && env[:ssl]
|
13
|
-
configure_ssl(session, env[:ssl])
|
14
|
-
end
|
15
|
-
|
16
|
-
if (req = env[:request])
|
17
|
-
configure_timeouts(session, req)
|
18
|
-
configure_proxy(session, req[:proxy])
|
19
|
-
end
|
20
|
-
|
21
|
-
session
|
22
|
-
end
|
23
|
-
|
24
|
-
def call(env)
|
25
|
-
super
|
26
|
-
# TODO: support streaming requests
|
27
|
-
env[:body] = env[:body].read if env[:body].respond_to? :read
|
28
|
-
|
29
|
-
response = connection(env) do |session|
|
30
|
-
begin
|
31
|
-
data = env[:body] ? env[:body].to_s : nil
|
32
|
-
session.request(env[:method], env[:url].to_s,
|
33
|
-
env[:request_headers], data: data)
|
34
|
-
rescue Errno::ECONNREFUSED, ::Patron::ConnectionFailed
|
35
|
-
raise Faraday::ConnectionFailed, $ERROR_INFO
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
if (req = env[:request]).stream_response?
|
40
|
-
warn "Streaming downloads for #{self.class.name} " \
|
41
|
-
'are not yet implemented.'
|
42
|
-
req.on_data.call(response.body, response.body.bytesize)
|
43
|
-
end
|
44
|
-
# Remove the "HTTP/1.1 200", leaving just the reason phrase
|
45
|
-
reason_phrase = response.status_line.gsub(/^.* \d{3} /, '')
|
46
|
-
|
47
|
-
save_response(env, response.status, response.body,
|
48
|
-
response.headers, reason_phrase)
|
49
|
-
|
50
|
-
@app.call env
|
51
|
-
rescue ::Patron::TimeoutError => e
|
52
|
-
if connection_timed_out_message?(e.message)
|
53
|
-
raise Faraday::ConnectionFailed, e
|
54
|
-
end
|
55
|
-
|
56
|
-
raise Faraday::TimeoutError, e
|
57
|
-
rescue ::Patron::Error => e
|
58
|
-
if e.message.include?('code 407')
|
59
|
-
raise Faraday::ConnectionFailed,
|
60
|
-
%(407 "Proxy Authentication Required ")
|
61
|
-
end
|
62
|
-
|
63
|
-
raise Faraday::ConnectionFailed, e
|
64
|
-
end
|
65
|
-
|
66
|
-
if loaded? && defined?(::Patron::Request::VALID_ACTIONS)
|
67
|
-
# HAX: helps but doesn't work completely
|
68
|
-
# https://github.com/toland/patron/issues/34
|
69
|
-
::Patron::Request::VALID_ACTIONS.tap do |actions|
|
70
|
-
if actions[0].is_a?(Symbol)
|
71
|
-
actions << :patch unless actions.include? :patch
|
72
|
-
actions << :options unless actions.include? :options
|
73
|
-
else
|
74
|
-
# Patron 0.4.20 and up
|
75
|
-
actions << 'PATCH' unless actions.include? 'PATCH'
|
76
|
-
actions << 'OPTIONS' unless actions.include? 'OPTIONS'
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
def configure_ssl(session, ssl)
|
82
|
-
if ssl.fetch(:verify, true)
|
83
|
-
session.cacert = ssl[:ca_file]
|
84
|
-
else
|
85
|
-
session.insecure = true
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
def configure_timeouts(session, req)
|
90
|
-
return unless req
|
91
|
-
|
92
|
-
if (sec = request_timeout(:read, req))
|
93
|
-
session.timeout = sec
|
94
|
-
end
|
95
|
-
|
96
|
-
return unless (sec = request_timeout(:open, req))
|
97
|
-
|
98
|
-
session.connect_timeout = sec
|
99
|
-
end
|
100
|
-
|
101
|
-
def configure_proxy(session, proxy)
|
102
|
-
return unless proxy
|
103
|
-
|
104
|
-
proxy_uri = proxy[:uri].dup
|
105
|
-
proxy_uri.user = proxy[:user] &&
|
106
|
-
Utils.escape(proxy[:user]).gsub('+', '%20')
|
107
|
-
proxy_uri.password = proxy[:password] &&
|
108
|
-
Utils.escape(proxy[:password]).gsub('+', '%20')
|
109
|
-
session.proxy = proxy_uri.to_s
|
110
|
-
end
|
111
|
-
|
112
|
-
private
|
113
|
-
|
114
|
-
CURL_TIMEOUT_MESSAGES = [
|
115
|
-
'Connection time-out',
|
116
|
-
'Connection timed out',
|
117
|
-
'Timed out before name resolve',
|
118
|
-
'server connect has timed out',
|
119
|
-
'Resolving timed out',
|
120
|
-
'name lookup timed out',
|
121
|
-
'timed out before SSL',
|
122
|
-
'connect() timed out'
|
123
|
-
].freeze
|
124
|
-
|
125
|
-
def connection_timed_out_message?(message)
|
126
|
-
CURL_TIMEOUT_MESSAGES.any? do |curl_message|
|
127
|
-
message.include?(curl_message)
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
132
|
-
end
|
data/lib/faraday/adapter/rack.rb
DELETED
@@ -1,75 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Faraday
|
4
|
-
class Adapter
|
5
|
-
# Sends requests to a Rack app.
|
6
|
-
#
|
7
|
-
# @example
|
8
|
-
#
|
9
|
-
# class MyRackApp
|
10
|
-
# def call(env)
|
11
|
-
# [200, {'Content-Type' => 'text/html'}, ["hello world"]]
|
12
|
-
# end
|
13
|
-
# end
|
14
|
-
#
|
15
|
-
# Faraday.new do |conn|
|
16
|
-
# conn.adapter :rack, MyRackApp.new
|
17
|
-
# end
|
18
|
-
class Rack < Faraday::Adapter
|
19
|
-
dependency 'rack/test'
|
20
|
-
|
21
|
-
# not prefixed with "HTTP_"
|
22
|
-
SPECIAL_HEADERS = %w[CONTENT_LENGTH CONTENT_TYPE].freeze
|
23
|
-
|
24
|
-
def initialize(faraday_app, rack_app)
|
25
|
-
super(faraday_app)
|
26
|
-
mock_session = ::Rack::MockSession.new(rack_app)
|
27
|
-
@session = ::Rack::Test::Session.new(mock_session)
|
28
|
-
end
|
29
|
-
|
30
|
-
def call(env)
|
31
|
-
super
|
32
|
-
rack_env = build_rack_env(env)
|
33
|
-
|
34
|
-
env[:request_headers]&.each do |name, value|
|
35
|
-
name = name.upcase.tr('-', '_')
|
36
|
-
name = "HTTP_#{name}" unless SPECIAL_HEADERS.include? name
|
37
|
-
rack_env[name] = value
|
38
|
-
end
|
39
|
-
|
40
|
-
timeout = request_timeout(:open, env[:request])
|
41
|
-
timeout ||= request_timeout(:read, env[:request])
|
42
|
-
response = if timeout
|
43
|
-
Timer.timeout(timeout, Faraday::TimeoutError) do
|
44
|
-
execute_request(env, rack_env)
|
45
|
-
end
|
46
|
-
else
|
47
|
-
execute_request(env, rack_env)
|
48
|
-
end
|
49
|
-
|
50
|
-
if (req = env[:request]).stream_response?
|
51
|
-
warn "Streaming downloads for #{self.class.name} " \
|
52
|
-
'are not yet implemented.'
|
53
|
-
req.on_data.call(response.body, response.body.bytesize)
|
54
|
-
end
|
55
|
-
|
56
|
-
save_response(env, response.status, response.body, response.headers)
|
57
|
-
@app.call env
|
58
|
-
end
|
59
|
-
|
60
|
-
private
|
61
|
-
|
62
|
-
def execute_request(env, rack_env)
|
63
|
-
@session.request(env[:url].to_s, rack_env)
|
64
|
-
end
|
65
|
-
|
66
|
-
def build_rack_env(env)
|
67
|
-
{
|
68
|
-
method: env[:method],
|
69
|
-
input: env[:body].respond_to?(:read) ? env[:body].read : env[:body],
|
70
|
-
'rack.url_scheme' => env[:url].scheme
|
71
|
-
}
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|