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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bc82ee913ef4ffa6468eea5e656c49d4eab0f769321eb63a85fdb4caa9a90143
4
- data.tar.gz: cccf1ae40f10f353ca2cc5e4e92bb01e4b1d65a9ac3ed50b7e5c5951680ba019
3
+ metadata.gz: e0b66c2e6b13140f2093c73a7b8dab39dd25690b15b1e5eadaba90a787d2fdf5
4
+ data.tar.gz: af34783d38f124632f2e4edcfd7f6bf2d763bd5d6f36ad8b6de6cac675c9858d
5
5
  SHA512:
6
- metadata.gz: 5360375fef63ad3e1068792458dd8ccc956b603be65e5571b9b6ce73938fc7ba2d220aeb99d4f3b022fa9945a07c8264c6452916e58963883fdd6843ded2d58e
7
- data.tar.gz: fac76254509856e7e827fecda3c76a070c53cdb1771782ff5d668f14a4b8a4b126be9761d0856fe28eccda4607daf031cb7c8ea4559e245b100db08e95f01a0a
6
+ metadata.gz: dd547129c965998e13208a5a0accab40ddee955f7a001365f2a951c6a0e7d7fefc9e61c5d708188deff9e8e239c991627485e3f07e9686a87a3cd30938a8f05b
7
+ data.tar.gz: 81fdc31d08d17db983ea4a4c68951942c3673d5447096e1f51cd0f4eebac1289348b860a56e064131b65ef59e3ed6f63ce1fc004db435f7fb051460b98190b31
@@ -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
- require 'faraday/em_http'
31
- require 'faraday/em_synchrony'
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
  #
@@ -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
@@ -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
- stub = Stub.new(host, normalized_path, headers, body, block)
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
@@ -59,10 +59,7 @@ module Faraday
59
59
  extend AutoloadHelper
60
60
  autoload_all 'faraday/adapter',
61
61
  Typhoeus: 'typhoeus',
62
- Patron: 'patron',
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.
@@ -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::Builder] Builder for this Connection.
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] ||= "Faraday v#{VERSION}"
93
+ @headers[:user_agent] ||= USER_AGENT
93
94
  end
94
95
 
95
96
  def initialize_proxy(url, options)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Faraday
4
- VERSION = '1.4.3'
4
+ VERSION = '1.7.0'
5
5
  end
@@ -1,47 +1,49 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- RSpec.describe Faraday::Adapter::EMHttp, unless: defined?(JRUBY_VERSION) do
4
- features :request_body_on_query_methods, :reason_phrase_parse, :trace_method,
5
- :skip_response_body_on_head, :parallel, :local_socket_binding
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
- it_behaves_like 'an adapter'
8
+ it_behaves_like 'an adapter'
8
9
 
9
- it 'allows to provide adapter specific configs' do
10
- url = URI('https://example.com:1234')
11
- adapter = described_class.new nil, inactivity_timeout: 20
12
- req = adapter.create_request(url: url, request: {})
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
- expect(req.connopts.inactivity_timeout).to eq(20)
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
- it 'configures all timeout settings' do
39
- request.timeout = 5
40
- request.read_timeout = 3
41
- request.open_timeout = 1
42
- adapter.configure_timeout(options, env)
43
- expect(options[:inactivity_timeout]).to eq(3)
44
- expect(options[:connect_timeout]).to eq(1)
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
- RSpec.describe Faraday::Adapter::EMSynchrony, unless: defined?(JRUBY_VERSION) do
4
- features :request_body_on_query_methods, :reason_phrase_parse,
5
- :skip_response_body_on_head, :parallel, :local_socket_binding
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
- it_behaves_like 'an adapter'
8
+ it_behaves_like 'an adapter'
8
9
 
9
- it 'allows to provide adapter specific configs' do
10
- url = URI('https://example.com:1234')
11
- adapter = described_class.new nil, inactivity_timeout: 20
12
- req = adapter.create_request(url: url, request: {})
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
- expect(req.connopts.inactivity_timeout).to eq(20)
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.3
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-06-24 00:00:00.000000000 Z
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.4.3
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
@@ -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