faraday 1.0.0 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +104 -0
  3. data/LICENSE.md +1 -1
  4. data/README.md +4 -5
  5. data/examples/client_spec.rb +1 -1
  6. data/lib/faraday.rb +51 -41
  7. data/lib/faraday/adapter.rb +1 -1
  8. data/lib/faraday/adapter/em_http.rb +18 -14
  9. data/lib/faraday/adapter/em_synchrony.rb +16 -13
  10. data/lib/faraday/adapter/excon.rb +2 -2
  11. data/lib/faraday/adapter/httpclient.rb +2 -1
  12. data/lib/faraday/adapter/net_http_persistent.rb +1 -1
  13. data/lib/faraday/adapter/typhoeus.rb +1 -1
  14. data/lib/faraday/adapter_registry.rb +3 -1
  15. data/lib/faraday/autoload.rb +1 -2
  16. data/lib/faraday/connection.rb +5 -4
  17. data/lib/faraday/encoders/flat_params_encoder.rb +9 -2
  18. data/lib/faraday/encoders/nested_params_encoder.rb +7 -2
  19. data/lib/faraday/error.rb +20 -0
  20. data/lib/faraday/methods.rb +6 -0
  21. data/lib/faraday/middleware.rb +14 -4
  22. data/lib/faraday/options.rb +4 -8
  23. data/lib/faraday/rack_builder.rb +13 -12
  24. data/lib/faraday/request.rb +20 -10
  25. data/lib/faraday/request/authorization.rb +3 -1
  26. data/lib/faraday/request/multipart.rb +10 -3
  27. data/lib/faraday/request/retry.rb +2 -2
  28. data/lib/faraday/request/url_encoded.rb +3 -1
  29. data/lib/faraday/response.rb +4 -7
  30. data/lib/faraday/response/raise_error.rb +12 -1
  31. data/lib/faraday/utils.rb +11 -3
  32. data/lib/faraday/utils/headers.rb +2 -2
  33. data/lib/faraday/version.rb +5 -0
  34. data/spec/faraday/adapter/em_http_spec.rb +1 -1
  35. data/spec/faraday/adapter/em_synchrony_spec.rb +1 -1
  36. data/spec/faraday/adapter/patron_spec.rb +1 -1
  37. data/spec/faraday/adapter/test_spec.rb +260 -0
  38. data/spec/faraday/connection_spec.rb +30 -0
  39. data/spec/faraday/error_spec.rb +15 -0
  40. data/spec/faraday/middleware_spec.rb +32 -6
  41. data/spec/faraday/params_encoders/flat_spec.rb +8 -0
  42. data/spec/faraday/params_encoders/nested_spec.rb +8 -0
  43. data/spec/faraday/rack_builder_spec.rb +150 -1
  44. data/spec/faraday/request/authorization_spec.rb +2 -2
  45. data/spec/faraday/request/multipart_spec.rb +41 -13
  46. data/spec/faraday/request/retry_spec.rb +1 -1
  47. data/spec/faraday/request/url_encoded_spec.rb +13 -0
  48. data/spec/faraday/request_spec.rb +16 -5
  49. data/spec/faraday/response/middleware_spec.rb +16 -0
  50. data/spec/faraday/response/raise_error_spec.rb +63 -0
  51. data/spec/support/shared_examples/adapter.rb +2 -1
  52. data/spec/support/shared_examples/request_method.rb +39 -11
  53. metadata +37 -7
  54. data/UPGRADING.md +0 -55
  55. data/lib/faraday/adapter/net_http.rb +0 -209
@@ -29,6 +29,9 @@ RSpec.describe Faraday::Response::RaiseError do
29
29
  expect(ex.message).to eq('the server responded with status 400')
30
30
  expect(ex.response[:headers]['X-Reason']).to eq('because')
31
31
  expect(ex.response[:status]).to eq(400)
32
+ expect(ex.response_status).to eq(400)
33
+ expect(ex.response_body).to eq('keep looking')
34
+ expect(ex.response_headers['X-Reason']).to eq('because')
32
35
  end
33
36
  end
34
37
 
@@ -37,6 +40,9 @@ RSpec.describe Faraday::Response::RaiseError do
37
40
  expect(ex.message).to eq('the server responded with status 401')
38
41
  expect(ex.response[:headers]['X-Reason']).to eq('because')
39
42
  expect(ex.response[:status]).to eq(401)
43
+ expect(ex.response_status).to eq(401)
44
+ expect(ex.response_body).to eq('keep looking')
45
+ expect(ex.response_headers['X-Reason']).to eq('because')
40
46
  end
41
47
  end
42
48
 
@@ -45,6 +51,9 @@ RSpec.describe Faraday::Response::RaiseError do
45
51
  expect(ex.message).to eq('the server responded with status 403')
46
52
  expect(ex.response[:headers]['X-Reason']).to eq('because')
47
53
  expect(ex.response[:status]).to eq(403)
54
+ expect(ex.response_status).to eq(403)
55
+ expect(ex.response_body).to eq('keep looking')
56
+ expect(ex.response_headers['X-Reason']).to eq('because')
48
57
  end
49
58
  end
50
59
 
@@ -53,6 +62,9 @@ RSpec.describe Faraday::Response::RaiseError do
53
62
  expect(ex.message).to eq('the server responded with status 404')
54
63
  expect(ex.response[:headers]['X-Reason']).to eq('because')
55
64
  expect(ex.response[:status]).to eq(404)
65
+ expect(ex.response_status).to eq(404)
66
+ expect(ex.response_body).to eq('keep looking')
67
+ expect(ex.response_headers['X-Reason']).to eq('because')
56
68
  end
57
69
  end
58
70
 
@@ -61,6 +73,9 @@ RSpec.describe Faraday::Response::RaiseError do
61
73
  expect(ex.message).to eq('407 "Proxy Authentication Required"')
62
74
  expect(ex.response[:headers]['X-Reason']).to eq('because')
63
75
  expect(ex.response[:status]).to eq(407)
76
+ expect(ex.response_status).to eq(407)
77
+ expect(ex.response_body).to eq('keep looking')
78
+ expect(ex.response_headers['X-Reason']).to eq('because')
64
79
  end
65
80
  end
66
81
 
@@ -69,6 +84,9 @@ RSpec.describe Faraday::Response::RaiseError do
69
84
  expect(ex.message).to eq('the server responded with status 409')
70
85
  expect(ex.response[:headers]['X-Reason']).to eq('because')
71
86
  expect(ex.response[:status]).to eq(409)
87
+ expect(ex.response_status).to eq(409)
88
+ expect(ex.response_body).to eq('keep looking')
89
+ expect(ex.response_headers['X-Reason']).to eq('because')
72
90
  end
73
91
  end
74
92
 
@@ -77,6 +95,9 @@ RSpec.describe Faraday::Response::RaiseError do
77
95
  expect(ex.message).to eq('the server responded with status 422')
78
96
  expect(ex.response[:headers]['X-Reason']).to eq('because')
79
97
  expect(ex.response[:status]).to eq(422)
98
+ expect(ex.response_status).to eq(422)
99
+ expect(ex.response_body).to eq('keep looking')
100
+ expect(ex.response_headers['X-Reason']).to eq('because')
80
101
  end
81
102
  end
82
103
 
@@ -85,6 +106,9 @@ RSpec.describe Faraday::Response::RaiseError do
85
106
  expect(ex.message).to eq('http status could not be derived from the server response')
86
107
  expect(ex.response[:headers]['X-Reason']).to eq('nil')
87
108
  expect(ex.response[:status]).to be_nil
109
+ expect(ex.response_status).to be_nil
110
+ expect(ex.response_body).to eq('fail')
111
+ expect(ex.response_headers['X-Reason']).to eq('nil')
88
112
  end
89
113
  end
90
114
 
@@ -93,6 +117,9 @@ RSpec.describe Faraday::Response::RaiseError do
93
117
  expect(ex.message).to eq('the server responded with status 499')
94
118
  expect(ex.response[:headers]['X-Reason']).to eq('because')
95
119
  expect(ex.response[:status]).to eq(499)
120
+ expect(ex.response_status).to eq(499)
121
+ expect(ex.response_body).to eq('keep looking')
122
+ expect(ex.response_headers['X-Reason']).to eq('because')
96
123
  end
97
124
  end
98
125
 
@@ -101,6 +128,42 @@ RSpec.describe Faraday::Response::RaiseError do
101
128
  expect(ex.message).to eq('the server responded with status 500')
102
129
  expect(ex.response[:headers]['X-Error']).to eq('bailout')
103
130
  expect(ex.response[:status]).to eq(500)
131
+ expect(ex.response_status).to eq(500)
132
+ expect(ex.response_body).to eq('fail')
133
+ expect(ex.response_headers['X-Error']).to eq('bailout')
134
+ end
135
+ end
136
+
137
+ describe 'request info' do
138
+ let(:conn) do
139
+ Faraday.new do |b|
140
+ b.response :raise_error
141
+ b.adapter :test do |stub|
142
+ stub.post('request?full=true', request_body, request_headers) do
143
+ [400, { 'X-Reason' => 'because' }, 'keep looking']
144
+ end
145
+ end
146
+ end
147
+ end
148
+ let(:request_body) { JSON.generate({ 'item' => 'sth' }) }
149
+ let(:request_headers) { { 'Authorization' => 'Basic 123' } }
150
+
151
+ subject(:perform_request) do
152
+ conn.post 'request' do |req|
153
+ req.headers['Authorization'] = 'Basic 123'
154
+ req.params[:full] = true
155
+ req.body = request_body
156
+ end
157
+ end
158
+
159
+ it 'returns the request info in the exception' do
160
+ expect { perform_request }.to raise_error(Faraday::BadRequestError) do |ex|
161
+ expect(ex.response[:request][:method]).to eq(:post)
162
+ expect(ex.response[:request][:url_path]).to eq('/request')
163
+ expect(ex.response[:request][:params]).to eq({ 'full' => 'true' })
164
+ expect(ex.response[:request][:headers]).to match(a_hash_including(request_headers))
165
+ expect(ex.response[:request][:body]).to eq(request_body)
166
+ end
104
167
  end
105
168
  end
106
169
  end
@@ -33,6 +33,7 @@ shared_examples 'adapter examples' do |**options|
33
33
 
34
34
  let(:protocol) { ssl_mode? ? 'https' : 'http' }
35
35
  let(:remote) { "#{protocol}://example.com" }
36
+ let(:stub_remote) { remote }
36
37
 
37
38
  let(:conn) do
38
39
  conn_options[:ssl] ||= {}
@@ -46,7 +47,7 @@ shared_examples 'adapter examples' do |**options|
46
47
  end
47
48
  end
48
49
 
49
- let!(:request_stub) { stub_request(http_method, remote) }
50
+ let!(:request_stub) { stub_request(http_method, stub_remote) }
50
51
 
51
52
  after do
52
53
  expect(request_stub).to have_been_requested unless request_stub.disabled?
@@ -1,5 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ shared_examples 'proxy examples' do
4
+ it 'handles requests with proxy' do
5
+ res = conn.public_send(http_method, '/')
6
+
7
+ expect(res.status).to eq(200)
8
+ end
9
+
10
+ it 'handles proxy failures' do
11
+ request_stub.to_return(status: 407)
12
+
13
+ expect { conn.public_send(http_method, '/') }.to raise_error(Faraday::ProxyAuthError)
14
+ end
15
+ end
16
+
3
17
  shared_examples 'a request method' do |http_method|
4
18
  let(:query_or_body) { method_with_body?(http_method) ? :body : :query }
5
19
  let(:response) { conn.public_send(http_method, '/') }
@@ -13,8 +27,8 @@ shared_examples 'a request method' do |http_method|
13
27
  end
14
28
 
15
29
  it 'handles headers with multiple values' do
16
- request_stub.to_return(headers: { 'Set-Cookie' => 'one, two' })
17
- expect(response.headers['set-cookie']).to eq('one, two')
30
+ request_stub.to_return(headers: { 'Set-Cookie' => 'name=value' })
31
+ expect(response.headers['set-cookie']).to eq('name=value')
18
32
  end
19
33
 
20
34
  it 'retrieves the response headers' do
@@ -119,7 +133,7 @@ shared_examples 'a request method' do |http_method|
119
133
  request_stub.with(headers: { 'Content-Type' => %r{\Amultipart/form-data} }) do |request|
120
134
  # WebMock does not support matching body for multipart/form-data requests yet :(
121
135
  # https://github.com/bblimke/webmock/issues/623
122
- request.body =~ /RubyMultipartPost/
136
+ request.body.include?('RubyMultipartPost')
123
137
  end
124
138
  conn.public_send(http_method, '/', payload)
125
139
  end
@@ -218,17 +232,31 @@ shared_examples 'a request method' do |http_method|
218
232
  end
219
233
  end
220
234
 
221
- it 'handles requests with proxy' do
222
- conn_options[:proxy] = 'http://google.co.uk'
235
+ context 'when a proxy is provided as option' do
236
+ before do
237
+ conn_options[:proxy] = 'http://env-proxy.com:80'
238
+ end
223
239
 
224
- res = conn.public_send(http_method, '/')
225
- expect(res.status).to eq(200)
240
+ include_examples 'proxy examples'
226
241
  end
227
242
 
228
- it 'handles proxy failures' do
229
- conn_options[:proxy] = 'http://google.co.uk'
230
- request_stub.to_return(status: 407)
243
+ context 'when http_proxy env variable is set' do
244
+ let(:proxy_url) { 'http://env-proxy.com:80' }
231
245
 
232
- expect { conn.public_send(http_method, '/') }.to raise_error(Faraday::ProxyAuthError)
246
+ around do |example|
247
+ with_env 'http_proxy' => proxy_url do
248
+ example.run
249
+ end
250
+ end
251
+
252
+ include_examples 'proxy examples'
253
+
254
+ context 'when the env proxy is ignored' do
255
+ around do |example|
256
+ with_env_proxy_disabled(&example)
257
+ end
258
+
259
+ include_examples 'proxy examples'
260
+ end
233
261
  end
234
262
  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.0.0
4
+ version: 1.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - "@technoweenie"
@@ -10,8 +10,22 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2020-01-01 00:00:00.000000000 Z
13
+ date: 2021-04-16 00:00:00.000000000 Z
14
14
  dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: faraday-net_http
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - "~>"
20
+ - !ruby/object:Gem::Version
21
+ version: '1.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - "~>"
27
+ - !ruby/object:Gem::Version
28
+ version: '1.0'
15
29
  - !ruby/object:Gem::Dependency
16
30
  name: multipart-post
17
31
  requirement: !ruby/object:Gem::Requirement
@@ -32,6 +46,20 @@ dependencies:
32
46
  - - "<"
33
47
  - !ruby/object:Gem::Version
34
48
  version: '3'
49
+ - !ruby/object:Gem::Dependency
50
+ name: ruby2_keywords
51
+ requirement: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: 0.0.4
56
+ type: :runtime
57
+ prerelease: false
58
+ version_requirements: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 0.0.4
35
63
  description:
36
64
  email: technoweenie@gmail.com
37
65
  executables: []
@@ -42,7 +70,6 @@ files:
42
70
  - LICENSE.md
43
71
  - README.md
44
72
  - Rakefile
45
- - UPGRADING.md
46
73
  - examples/client_spec.rb
47
74
  - examples/client_test.rb
48
75
  - lib/faraday.rb
@@ -53,7 +80,6 @@ files:
53
80
  - lib/faraday/adapter/em_synchrony/parallel_manager.rb
54
81
  - lib/faraday/adapter/excon.rb
55
82
  - lib/faraday/adapter/httpclient.rb
56
- - lib/faraday/adapter/net_http.rb
57
83
  - lib/faraday/adapter/net_http_persistent.rb
58
84
  - lib/faraday/adapter/patron.rb
59
85
  - lib/faraday/adapter/rack.rb
@@ -68,6 +94,7 @@ files:
68
94
  - lib/faraday/error.rb
69
95
  - lib/faraday/file_part.rb
70
96
  - lib/faraday/logging/formatter.rb
97
+ - lib/faraday/methods.rb
71
98
  - lib/faraday/middleware.rb
72
99
  - lib/faraday/middleware_registry.rb
73
100
  - lib/faraday/options.rb
@@ -93,6 +120,7 @@ files:
93
120
  - lib/faraday/utils.rb
94
121
  - lib/faraday/utils/headers.rb
95
122
  - lib/faraday/utils/params_hash.rb
123
+ - lib/faraday/version.rb
96
124
  - spec/external_adapters/faraday_specs_setup.rb
97
125
  - spec/faraday/adapter/em_http_spec.rb
98
126
  - spec/faraday/adapter/em_synchrony_spec.rb
@@ -102,6 +130,7 @@ files:
102
130
  - spec/faraday/adapter/net_http_spec.rb
103
131
  - spec/faraday/adapter/patron_spec.rb
104
132
  - spec/faraday/adapter/rack_spec.rb
133
+ - spec/faraday/adapter/test_spec.rb
105
134
  - spec/faraday/adapter/typhoeus_spec.rb
106
135
  - spec/faraday/adapter_registry_spec.rb
107
136
  - spec/faraday/adapter_spec.rb
@@ -143,25 +172,26 @@ licenses:
143
172
  - MIT
144
173
  metadata:
145
174
  homepage_uri: https://lostisland.github.io/faraday
146
- changelog_uri: https://github.com/lostisland/faraday/releases/tag/v1.0.0
175
+ changelog_uri: https://github.com/lostisland/faraday/releases/tag/v1.3.1
147
176
  source_code_uri: https://github.com/lostisland/faraday
148
177
  bug_tracker_uri: https://github.com/lostisland/faraday/issues
149
178
  post_install_message:
150
179
  rdoc_options: []
151
180
  require_paths:
152
181
  - lib
182
+ - spec/external_adapters
153
183
  required_ruby_version: !ruby/object:Gem::Requirement
154
184
  requirements:
155
185
  - - ">="
156
186
  - !ruby/object:Gem::Version
157
- version: '2.3'
187
+ version: '2.4'
158
188
  required_rubygems_version: !ruby/object:Gem::Requirement
159
189
  requirements:
160
190
  - - ">="
161
191
  - !ruby/object:Gem::Version
162
192
  version: '0'
163
193
  requirements: []
164
- rubygems_version: 3.1.2
194
+ rubygems_version: 3.0.3.1
165
195
  signing_key:
166
196
  specification_version: 4
167
197
  summary: HTTP/REST API client library.
data/UPGRADING.md DELETED
@@ -1,55 +0,0 @@
1
- ## Faraday 1.0
2
-
3
- ### Errors
4
- * Removes sub-class constants definition from `Faraday::Error`. A sub-class (e.g. `ClientError`) was previously accessible
5
- either through the `Faraday` module (e.g. `Faraday::ClientError`) or through the `Faraday::Error` class (e.g. `Faraday::Error::ClientError`).
6
- The latter is no longer available and the former should be used instead, so check your `rescue`s.
7
- * Introduces a new `Faraday::ServerError` (5xx status codes) alongside the existing `Faraday::ClientError` (4xx status codes).
8
- Please note `Faraday::ClientError` was previously used for both.
9
- * Introduces new Errors that describe the most common REST status codes:
10
- * Faraday::BadRequestError (400)
11
- * Faraday::UnauthorizedError (401)
12
- * Faraday::ForbiddenError (403)
13
- * Faraday::ProxyAuthError (407). Please note this raised a `Faraday::ConnectionFailed` before.
14
- * Faraday::ConflictError (409)
15
- * Faraday::UnprocessableEntityError (422)
16
- * The following error classes have changed the hierarchy to better mirror their real-world usage and semantic meaning:
17
- * TimeoutError < ServerError (was < ClientError)
18
- * ConnectionFailed < Error (was < ClientError)
19
- * SSLError < Error (was < ClientError)
20
- * ParsingError < Error (was < ClientError)
21
- * RetriableResponse < Error (was < ClientError)
22
-
23
- ### Custom adapters
24
- If you have written a custom adapter, please be aware that `env.body` is now an alias to the two new properties `request_body` and `response_body`.
25
- This should work without you noticing if your adapter inherits from `Faraday::Adapter` and calls `save_response`, but if it doesn't, then please ensure you set the `status` BEFORE the `body` while processing the response.
26
-
27
- ### Others
28
- * Dropped support for jruby and Rubinius.
29
- * Officially supports Ruby 2.4+
30
- * In order to specify the adapter you now MUST use the `#adapter` method on the connection builder. If you don't do so and your adapter inherits from `Faraday::Adapter` then Faraday will raise an exception. Otherwise, Faraday will automatically push the default adapter at the end of the stack causing your request to be executed twice.
31
- ```ruby
32
- class OfficialAdapter < Faraday::Adapter
33
- ...
34
- end
35
-
36
- class MyAdapter
37
- ...
38
- end
39
-
40
- # This will raise an exception
41
- conn = Faraday.new(...) do |f|
42
- f.use OfficialAdapter
43
- end
44
-
45
- # This will cause Faraday inserting the default adapter at the end of the stack
46
- conn = Faraday.new(...) do |f|
47
- f.use MyAdapter
48
- end
49
-
50
- # You MUST use `adapter` method
51
- conn = Faraday.new(...) do |f|
52
- f.adapter AnyAdapter
53
- end
54
- ```
55
-
@@ -1,209 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- begin
4
- require 'net/https'
5
- rescue LoadError
6
- warn 'Warning: no such file to load -- net/https. ' \
7
- 'Make sure openssl is installed if you want ssl support'
8
- require 'net/http'
9
- end
10
- require 'zlib'
11
-
12
- module Faraday
13
- class Adapter
14
- # Net::HTTP adapter.
15
- class NetHttp < Faraday::Adapter
16
- exceptions = [
17
- IOError,
18
- Errno::EADDRNOTAVAIL,
19
- Errno::ECONNABORTED,
20
- Errno::ECONNREFUSED,
21
- Errno::ECONNRESET,
22
- Errno::EHOSTUNREACH,
23
- Errno::EINVAL,
24
- Errno::ENETUNREACH,
25
- Errno::EPIPE,
26
- Net::HTTPBadResponse,
27
- Net::HTTPHeaderSyntaxError,
28
- Net::ProtocolError,
29
- SocketError,
30
- Zlib::GzipFile::Error
31
- ]
32
-
33
- exceptions << OpenSSL::SSL::SSLError if defined?(OpenSSL)
34
- exceptions << Net::OpenTimeout if defined?(Net::OpenTimeout)
35
-
36
- NET_HTTP_EXCEPTIONS = exceptions.freeze
37
-
38
- def initialize(app = nil, opts = {}, &block)
39
- @ssl_cert_store = nil
40
- super(app, opts, &block)
41
- end
42
-
43
- def build_connection(env)
44
- net_http_connection(env).tap do |http|
45
- if http.respond_to?(:use_ssl=)
46
- http.use_ssl = env[:url].scheme == 'https'
47
- end
48
- configure_ssl(http, env[:ssl])
49
- configure_request(http, env[:request])
50
- end
51
- end
52
-
53
- def net_http_connection(env)
54
- klass = if (proxy = env[:request][:proxy])
55
- Net::HTTP::Proxy(proxy[:uri].hostname, proxy[:uri].port,
56
- proxy[:user], proxy[:password])
57
- else
58
- Net::HTTP
59
- end
60
- port = env[:url].port || (env[:url].scheme == 'https' ? 443 : 80)
61
- klass.new(env[:url].hostname, port)
62
- end
63
-
64
- def call(env)
65
- super
66
- http_response = connection(env) do |http|
67
- begin
68
- perform_request(http, env)
69
- rescue *NET_HTTP_EXCEPTIONS => e
70
- if defined?(OpenSSL) && e.is_a?(OpenSSL::SSL::SSLError)
71
- raise Faraday::SSLError, e
72
- end
73
-
74
- raise Faraday::ConnectionFailed, e
75
- end
76
- end
77
-
78
- save_response(env, http_response.code.to_i,
79
- http_response.body || +'', nil,
80
- http_response.message) do |response_headers|
81
- http_response.each_header do |key, value|
82
- response_headers[key] = value
83
- end
84
- end
85
-
86
- @app.call env
87
- rescue Timeout::Error, Errno::ETIMEDOUT => e
88
- raise Faraday::TimeoutError, e
89
- end
90
-
91
- private
92
-
93
- def create_request(env)
94
- request = Net::HTTPGenericRequest.new \
95
- env[:method].to_s.upcase, # request method
96
- !!env[:body], # is there request body
97
- env[:method] != :head, # is there response body
98
- env[:url].request_uri, # request uri path
99
- env[:request_headers] # request headers
100
-
101
- if env[:body].respond_to?(:read)
102
- request.body_stream = env[:body]
103
- else
104
- request.body = env[:body]
105
- end
106
- request
107
- end
108
-
109
- def perform_request(http, env)
110
- if env[:request].stream_response?
111
- size = 0
112
- yielded = false
113
- http_response = request_with_wrapped_block(http, env) do |chunk|
114
- if chunk.bytesize.positive? || size.positive?
115
- yielded = true
116
- size += chunk.bytesize
117
- env[:request].on_data.call(chunk, size)
118
- end
119
- end
120
- env[:request].on_data.call(+'', 0) unless yielded
121
- # Net::HTTP returns something,
122
- # but it's not meaningful according to the docs.
123
- http_response.body = nil
124
- http_response
125
- else
126
- request_with_wrapped_block(http, env)
127
- end
128
- end
129
-
130
- def request_with_wrapped_block(http, env, &block)
131
- if (env[:method] == :get) && !env[:body]
132
- # prefer `get` to `request` because the former handles gzip (ruby 1.9)
133
- request_via_get_method(http, env, &block)
134
- else
135
- request_via_request_method(http, env, &block)
136
- end
137
- end
138
-
139
- def request_via_get_method(http, env, &block)
140
- http.get env[:url].request_uri, env[:request_headers], &block
141
- end
142
-
143
- def request_via_request_method(http, env, &block)
144
- if block_given?
145
- http.request create_request(env) do |response|
146
- response.read_body(&block)
147
- end
148
- else
149
- http.request create_request(env)
150
- end
151
- end
152
-
153
- def configure_ssl(http, ssl)
154
- return unless ssl
155
-
156
- http.verify_mode = ssl_verify_mode(ssl)
157
- http.cert_store = ssl_cert_store(ssl)
158
-
159
- http.cert = ssl[:client_cert] if ssl[:client_cert]
160
- http.key = ssl[:client_key] if ssl[:client_key]
161
- http.ca_file = ssl[:ca_file] if ssl[:ca_file]
162
- http.ca_path = ssl[:ca_path] if ssl[:ca_path]
163
- http.verify_depth = ssl[:verify_depth] if ssl[:verify_depth]
164
- http.ssl_version = ssl[:version] if ssl[:version]
165
- http.min_version = ssl[:min_version] if ssl[:min_version]
166
- http.max_version = ssl[:max_version] if ssl[:max_version]
167
- end
168
-
169
- def configure_request(http, req)
170
- if (sec = request_timeout(:read, req))
171
- http.read_timeout = sec
172
- end
173
-
174
- if (sec = http.respond_to?(:write_timeout=) &&
175
- request_timeout(:write, req))
176
- http.write_timeout = sec
177
- end
178
-
179
- if (sec = request_timeout(:open, req))
180
- http.open_timeout = sec
181
- end
182
-
183
- # Only set if Net::Http supports it, since Ruby 2.5.
184
- http.max_retries = 0 if http.respond_to?(:max_retries=)
185
-
186
- @config_block&.call(http)
187
- end
188
-
189
- def ssl_cert_store(ssl)
190
- return ssl[:cert_store] if ssl[:cert_store]
191
-
192
- @ssl_cert_store ||= begin
193
- # Use the default cert store by default, i.e. system ca certs
194
- OpenSSL::X509::Store.new.tap(&:set_default_paths)
195
- end
196
- end
197
-
198
- def ssl_verify_mode(ssl)
199
- ssl[:verify_mode] || begin
200
- if ssl.fetch(:verify, true)
201
- OpenSSL::SSL::VERIFY_PEER
202
- else
203
- OpenSSL::SSL::VERIFY_NONE
204
- end
205
- end
206
- end
207
- end
208
- end
209
- end