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