faraday 1.0.0 → 1.3.1
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/CHANGELOG.md +104 -0
- data/LICENSE.md +1 -1
- data/README.md +4 -5
- data/examples/client_spec.rb +1 -1
- data/lib/faraday.rb +51 -41
- data/lib/faraday/adapter.rb +1 -1
- data/lib/faraday/adapter/em_http.rb +18 -14
- data/lib/faraday/adapter/em_synchrony.rb +16 -13
- data/lib/faraday/adapter/excon.rb +2 -2
- data/lib/faraday/adapter/httpclient.rb +2 -1
- data/lib/faraday/adapter/net_http_persistent.rb +1 -1
- data/lib/faraday/adapter/typhoeus.rb +1 -1
- data/lib/faraday/adapter_registry.rb +3 -1
- data/lib/faraday/autoload.rb +1 -2
- data/lib/faraday/connection.rb +5 -4
- data/lib/faraday/encoders/flat_params_encoder.rb +9 -2
- data/lib/faraday/encoders/nested_params_encoder.rb +7 -2
- data/lib/faraday/error.rb +20 -0
- data/lib/faraday/methods.rb +6 -0
- data/lib/faraday/middleware.rb +14 -4
- data/lib/faraday/options.rb +4 -8
- data/lib/faraday/rack_builder.rb +13 -12
- data/lib/faraday/request.rb +20 -10
- data/lib/faraday/request/authorization.rb +3 -1
- data/lib/faraday/request/multipart.rb +10 -3
- data/lib/faraday/request/retry.rb +2 -2
- data/lib/faraday/request/url_encoded.rb +3 -1
- data/lib/faraday/response.rb +4 -7
- data/lib/faraday/response/raise_error.rb +12 -1
- data/lib/faraday/utils.rb +11 -3
- data/lib/faraday/utils/headers.rb +2 -2
- data/lib/faraday/version.rb +5 -0
- data/spec/faraday/adapter/em_http_spec.rb +1 -1
- data/spec/faraday/adapter/em_synchrony_spec.rb +1 -1
- data/spec/faraday/adapter/patron_spec.rb +1 -1
- data/spec/faraday/adapter/test_spec.rb +260 -0
- data/spec/faraday/connection_spec.rb +30 -0
- data/spec/faraday/error_spec.rb +15 -0
- data/spec/faraday/middleware_spec.rb +32 -6
- data/spec/faraday/params_encoders/flat_spec.rb +8 -0
- data/spec/faraday/params_encoders/nested_spec.rb +8 -0
- data/spec/faraday/rack_builder_spec.rb +150 -1
- data/spec/faraday/request/authorization_spec.rb +2 -2
- data/spec/faraday/request/multipart_spec.rb +41 -13
- data/spec/faraday/request/retry_spec.rb +1 -1
- data/spec/faraday/request/url_encoded_spec.rb +13 -0
- data/spec/faraday/request_spec.rb +16 -5
- data/spec/faraday/response/middleware_spec.rb +16 -0
- data/spec/faraday/response/raise_error_spec.rb +63 -0
- data/spec/support/shared_examples/adapter.rb +2 -1
- data/spec/support/shared_examples/request_method.rb +39 -11
- metadata +37 -7
- data/UPGRADING.md +0 -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,
|
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' => '
|
17
|
-
expect(response.headers['set-cookie']).to eq('
|
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
|
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
|
-
|
222
|
-
|
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
|
-
|
225
|
-
expect(res.status).to eq(200)
|
240
|
+
include_examples 'proxy examples'
|
226
241
|
end
|
227
242
|
|
228
|
-
|
229
|
-
|
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
|
-
|
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.
|
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:
|
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.
|
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.
|
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
|
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
|