faraday 1.0.1 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +104 -0
  3. data/LICENSE.md +1 -1
  4. data/README.md +3 -5
  5. data/examples/client_spec.rb +1 -1
  6. data/lib/faraday.rb +60 -41
  7. data/lib/faraday/adapter.rb +2 -12
  8. data/lib/faraday/autoload.rb +2 -10
  9. data/lib/faraday/connection.rb +14 -7
  10. data/lib/faraday/encoders/flat_params_encoder.rb +9 -2
  11. data/lib/faraday/encoders/nested_params_encoder.rb +7 -2
  12. data/lib/faraday/error.rb +20 -0
  13. data/lib/faraday/methods.rb +6 -0
  14. data/lib/faraday/middleware.rb +14 -4
  15. data/lib/faraday/options.rb +4 -8
  16. data/lib/faraday/options/proxy_options.rb +4 -0
  17. data/lib/faraday/rack_builder.rb +13 -12
  18. data/lib/faraday/request.rb +20 -10
  19. data/lib/faraday/request/multipart.rb +9 -2
  20. data/lib/faraday/request/retry.rb +2 -2
  21. data/lib/faraday/response.rb +0 -6
  22. data/lib/faraday/response/raise_error.rb +12 -1
  23. data/lib/faraday/utils.rb +2 -2
  24. data/lib/faraday/utils/headers.rb +2 -2
  25. data/lib/faraday/version.rb +5 -0
  26. data/spec/faraday/adapter/em_http_spec.rb +39 -37
  27. data/spec/faraday/adapter/em_synchrony_spec.rb +11 -9
  28. data/spec/faraday/adapter/test_spec.rb +260 -0
  29. data/spec/faraday/connection_spec.rb +45 -0
  30. data/spec/faraday/error_spec.rb +15 -0
  31. data/spec/faraday/middleware_spec.rb +32 -6
  32. data/spec/faraday/options/proxy_options_spec.rb +7 -0
  33. data/spec/faraday/params_encoders/flat_spec.rb +8 -0
  34. data/spec/faraday/params_encoders/nested_spec.rb +8 -0
  35. data/spec/faraday/rack_builder_spec.rb +149 -0
  36. data/spec/faraday/request/authorization_spec.rb +2 -2
  37. data/spec/faraday/request/multipart_spec.rb +41 -13
  38. data/spec/faraday/request/retry_spec.rb +1 -1
  39. data/spec/faraday/request_spec.rb +16 -5
  40. data/spec/faraday/response/raise_error_spec.rb +63 -0
  41. data/spec/support/shared_examples/adapter.rb +2 -1
  42. data/spec/support/shared_examples/request_method.rb +39 -11
  43. metadata +134 -16
  44. data/lib/faraday/adapter/em_http.rb +0 -286
  45. data/lib/faraday/adapter/em_http_ssl_patch.rb +0 -62
  46. data/lib/faraday/adapter/em_synchrony.rb +0 -150
  47. data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +0 -69
  48. data/lib/faraday/adapter/excon.rb +0 -124
  49. data/lib/faraday/adapter/httpclient.rb +0 -152
  50. data/lib/faraday/adapter/net_http.rb +0 -219
  51. data/lib/faraday/adapter/net_http_persistent.rb +0 -91
  52. data/lib/faraday/adapter/patron.rb +0 -132
  53. data/lib/faraday/adapter/rack.rb +0 -75
  54. data/spec/faraday/adapter/net_http_persistent_spec.rb +0 -57
@@ -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.1
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - "@technoweenie"
@@ -10,8 +10,120 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2020-03-29 00:00:00.000000000 Z
13
+ date: 2021-08-01 00:00:00.000000000 Z
14
14
  dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: faraday-em_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'
29
+ - !ruby/object:Gem::Dependency
30
+ name: faraday-em_synchrony
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - "~>"
34
+ - !ruby/object:Gem::Version
35
+ version: '1.0'
36
+ type: :runtime
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - "~>"
41
+ - !ruby/object:Gem::Version
42
+ version: '1.0'
43
+ - !ruby/object:Gem::Dependency
44
+ name: faraday-excon
45
+ requirement: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '1.1'
50
+ type: :runtime
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - "~>"
55
+ - !ruby/object:Gem::Version
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
71
+ - !ruby/object:Gem::Dependency
72
+ name: faraday-net_http
73
+ requirement: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - "~>"
76
+ - !ruby/object:Gem::Version
77
+ version: '1.0'
78
+ type: :runtime
79
+ prerelease: false
80
+ version_requirements: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - "~>"
83
+ - !ruby/object:Gem::Version
84
+ version: '1.0'
85
+ - !ruby/object:Gem::Dependency
86
+ name: faraday-net_http_persistent
87
+ requirement: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - "~>"
90
+ - !ruby/object:Gem::Version
91
+ version: '1.1'
92
+ type: :runtime
93
+ prerelease: false
94
+ version_requirements: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - "~>"
97
+ - !ruby/object:Gem::Version
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'
15
127
  - !ruby/object:Gem::Dependency
16
128
  name: multipart-post
17
129
  requirement: !ruby/object:Gem::Requirement
@@ -32,6 +144,20 @@ dependencies:
32
144
  - - "<"
33
145
  - !ruby/object:Gem::Version
34
146
  version: '3'
147
+ - !ruby/object:Gem::Dependency
148
+ name: ruby2_keywords
149
+ requirement: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - ">="
152
+ - !ruby/object:Gem::Version
153
+ version: 0.0.4
154
+ type: :runtime
155
+ prerelease: false
156
+ version_requirements: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - ">="
159
+ - !ruby/object:Gem::Version
160
+ version: 0.0.4
35
161
  description:
36
162
  email: technoweenie@gmail.com
37
163
  executables: []
@@ -46,16 +172,6 @@ files:
46
172
  - examples/client_test.rb
47
173
  - lib/faraday.rb
48
174
  - lib/faraday/adapter.rb
49
- - lib/faraday/adapter/em_http.rb
50
- - lib/faraday/adapter/em_http_ssl_patch.rb
51
- - lib/faraday/adapter/em_synchrony.rb
52
- - lib/faraday/adapter/em_synchrony/parallel_manager.rb
53
- - lib/faraday/adapter/excon.rb
54
- - lib/faraday/adapter/httpclient.rb
55
- - lib/faraday/adapter/net_http.rb
56
- - lib/faraday/adapter/net_http_persistent.rb
57
- - lib/faraday/adapter/patron.rb
58
- - lib/faraday/adapter/rack.rb
59
175
  - lib/faraday/adapter/test.rb
60
176
  - lib/faraday/adapter/typhoeus.rb
61
177
  - lib/faraday/adapter_registry.rb
@@ -67,6 +183,7 @@ files:
67
183
  - lib/faraday/error.rb
68
184
  - lib/faraday/file_part.rb
69
185
  - lib/faraday/logging/formatter.rb
186
+ - lib/faraday/methods.rb
70
187
  - lib/faraday/middleware.rb
71
188
  - lib/faraday/middleware_registry.rb
72
189
  - lib/faraday/options.rb
@@ -92,15 +209,16 @@ files:
92
209
  - lib/faraday/utils.rb
93
210
  - lib/faraday/utils/headers.rb
94
211
  - lib/faraday/utils/params_hash.rb
212
+ - lib/faraday/version.rb
95
213
  - spec/external_adapters/faraday_specs_setup.rb
96
214
  - spec/faraday/adapter/em_http_spec.rb
97
215
  - spec/faraday/adapter/em_synchrony_spec.rb
98
216
  - spec/faraday/adapter/excon_spec.rb
99
217
  - spec/faraday/adapter/httpclient_spec.rb
100
- - spec/faraday/adapter/net_http_persistent_spec.rb
101
218
  - spec/faraday/adapter/net_http_spec.rb
102
219
  - spec/faraday/adapter/patron_spec.rb
103
220
  - spec/faraday/adapter/rack_spec.rb
221
+ - spec/faraday/adapter/test_spec.rb
104
222
  - spec/faraday/adapter/typhoeus_spec.rb
105
223
  - spec/faraday/adapter_registry_spec.rb
106
224
  - spec/faraday/adapter_spec.rb
@@ -142,7 +260,7 @@ licenses:
142
260
  - MIT
143
261
  metadata:
144
262
  homepage_uri: https://lostisland.github.io/faraday
145
- changelog_uri: https://github.com/lostisland/faraday/releases/tag/v1.0.1
263
+ changelog_uri: https://github.com/lostisland/faraday/releases/tag/v1.6.0
146
264
  source_code_uri: https://github.com/lostisland/faraday
147
265
  bug_tracker_uri: https://github.com/lostisland/faraday/issues
148
266
  post_install_message:
@@ -154,14 +272,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
154
272
  requirements:
155
273
  - - ">="
156
274
  - !ruby/object:Gem::Version
157
- version: '2.3'
275
+ version: '2.4'
158
276
  required_rubygems_version: !ruby/object:Gem::Requirement
159
277
  requirements:
160
278
  - - ">="
161
279
  - !ruby/object:Gem::Version
162
280
  version: '0'
163
281
  requirements: []
164
- rubygems_version: 3.0.3
282
+ rubygems_version: 3.0.3.1
165
283
  signing_key:
166
284
  specification_version: 4
167
285
  summary: HTTP/REST API client library.
@@ -1,286 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Faraday
4
- class Adapter
5
- # EventMachine adapter. This adapter is useful for either asynchronous
6
- # requests when in an EM reactor loop, or for making parallel requests in
7
- # synchronous code.
8
- class EMHttp < Faraday::Adapter
9
- # Options is a module containing helpers to convert the Faraday env object
10
- # into options hashes for EMHTTP method calls.
11
- module Options
12
- # @return [Hash]
13
- def connection_config(env)
14
- options = {}
15
- configure_proxy(options, env)
16
- configure_timeout(options, env)
17
- configure_socket(options, env)
18
- configure_ssl(options, env)
19
- options
20
- end
21
-
22
- def request_config(env)
23
- options = {
24
- body: read_body(env),
25
- head: env[:request_headers]
26
- # keepalive: true,
27
- # file: 'path/to/file', # stream data off disk
28
- }
29
- configure_compression(options, env)
30
- options
31
- end
32
-
33
- def read_body(env)
34
- body = env[:body]
35
- body.respond_to?(:read) ? body.read : body
36
- end
37
-
38
- # Reads out proxy settings from env into options
39
- def configure_proxy(options, env)
40
- proxy = request_options(env)[:proxy]
41
- return unless proxy
42
-
43
- options[:proxy] = {
44
- host: proxy[:uri].host,
45
- port: proxy[:uri].port,
46
- authorization: [proxy[:user], proxy[:password]]
47
- }
48
- end
49
-
50
- # Reads out host and port settings from env into options
51
- def configure_socket(options, env)
52
- bind = request_options(env)[:bind]
53
- return unless bind
54
-
55
- options[:bind] = {
56
- host: bind[:host],
57
- port: bind[:port]
58
- }
59
- end
60
-
61
- # Reads out SSL certificate settings from env into options
62
- def configure_ssl(options, env)
63
- return unless env[:url].scheme == 'https' && env[:ssl]
64
-
65
- options[:ssl] = {
66
- cert_chain_file: env[:ssl][:ca_file],
67
- verify_peer: env[:ssl].fetch(:verify, true)
68
- }
69
- end
70
-
71
- # Reads out timeout settings from env into options
72
- def configure_timeout(options, env)
73
- req = request_options(env)
74
- options[:inactivity_timeout] = request_timeout(:read, req)
75
- options[:connect_timeout] = request_timeout(:open, req)
76
- end
77
-
78
- # Reads out compression header settings from env into options
79
- def configure_compression(options, env)
80
- return unless (env[:method] == :get) &&
81
- !options[:head].key?('accept-encoding')
82
-
83
- options[:head]['accept-encoding'] = 'gzip, compressed'
84
- end
85
-
86
- def request_options(env)
87
- env[:request]
88
- end
89
- end
90
-
91
- include Options
92
-
93
- dependency 'em-http'
94
-
95
- self.supports_parallel = true
96
-
97
- # @return [Manager]
98
- def self.setup_parallel_manager(_options = nil)
99
- Manager.new
100
- end
101
-
102
- def call(env)
103
- super
104
- perform_request env
105
- @app.call env
106
- end
107
-
108
- def perform_request(env)
109
- if parallel?(env)
110
- manager = env[:parallel_manager]
111
- manager.add do
112
- perform_single_request(env)
113
- .callback { env[:response].finish(env) }
114
- end
115
- elsif EventMachine.reactor_running?
116
- # EM is running: instruct upstream that this is an async request
117
- env[:parallel_manager] = true
118
- perform_single_request(env)
119
- .callback { env[:response].finish(env) }
120
- .errback do
121
- # TODO: no way to communicate the error in async mode
122
- raise NotImplementedError
123
- end
124
- else
125
- error = nil
126
- # start EM, block until request is completed
127
- EventMachine.run do
128
- perform_single_request(env)
129
- .callback { EventMachine.stop }
130
- .errback do |client|
131
- error = error_message(client)
132
- EventMachine.stop
133
- end
134
- end
135
- raise_error(error) if error
136
- end
137
- rescue EventMachine::Connectify::CONNECTError => e
138
- if e.message.include?('Proxy Authentication Required')
139
- raise Faraday::ConnectionFailed,
140
- %(407 "Proxy Authentication Required ")
141
- end
142
-
143
- raise Faraday::ConnectionFailed, e
144
- rescue StandardError => e
145
- if defined?(::OpenSSL::SSL::SSLError) && \
146
- e.is_a?(::OpenSSL::SSL::SSLError)
147
- raise Faraday::SSLError, e
148
- end
149
-
150
- raise
151
- end
152
-
153
- # TODO: reuse the connection to support pipelining
154
- def perform_single_request(env)
155
- req = create_request(env)
156
- req = req.setup_request(env[:method], request_config(env))
157
- req.callback do |client|
158
- if env[:request].stream_response?
159
- warn "Streaming downloads for #{self.class.name} " \
160
- 'are not yet implemented.'
161
- env[:request].on_data.call(
162
- client.response,
163
- client.response.bytesize
164
- )
165
- end
166
- status = client.response_header.status
167
- reason = client.response_header.http_reason
168
- save_response(env, status, client.response, nil, reason) do |headers|
169
- client.response_header.each do |name, value|
170
- headers[name.to_sym] = value
171
- end
172
- end
173
- end
174
- end
175
-
176
- def create_request(env)
177
- EventMachine::HttpRequest.new(
178
- env[:url], connection_config(env).merge(@connection_options)
179
- )
180
- end
181
-
182
- def error_message(client)
183
- client.error || 'request failed'
184
- end
185
-
186
- def raise_error(msg)
187
- error_class = Faraday::ClientError
188
- if timeout_message?(msg)
189
- error_class = Faraday::TimeoutError
190
- msg = 'request timed out'
191
- elsif msg == Errno::ECONNREFUSED
192
- error_class = Faraday::ConnectionFailed
193
- msg = 'connection refused'
194
- elsif msg == 'connection closed by server'
195
- error_class = Faraday::ConnectionFailed
196
- end
197
- raise error_class, msg
198
- end
199
-
200
- def timeout_message?(msg)
201
- msg == Errno::ETIMEDOUT ||
202
- (msg.is_a?(String) && msg.include?('timeout error'))
203
- end
204
-
205
- # @return [Boolean]
206
- def parallel?(env)
207
- !!env[:parallel_manager]
208
- end
209
-
210
- # This parallel manager is designed to start an EventMachine loop
211
- # and block until all registered requests have been completed.
212
- class Manager
213
- # @see reset
214
- def initialize
215
- reset
216
- end
217
-
218
- # Re-initializes instance variables
219
- def reset
220
- @registered_procs = []
221
- @num_registered = 0
222
- @num_succeeded = 0
223
- @errors = []
224
- @running = false
225
- end
226
-
227
- # @return [Boolean]
228
- def running?
229
- @running
230
- end
231
-
232
- def add(&block)
233
- if running?
234
- perform_request { yield }
235
- else
236
- @registered_procs << block
237
- end
238
- @num_registered += 1
239
- end
240
-
241
- def run
242
- if @num_registered.positive?
243
- @running = true
244
- EventMachine.run do
245
- @registered_procs.each do |proc|
246
- perform_request(&proc)
247
- end
248
- end
249
- unless @errors.empty?
250
- raise Faraday::ClientError, @errors.first || 'connection failed'
251
- end
252
- end
253
- ensure
254
- reset
255
- end
256
-
257
- def perform_request
258
- client = yield
259
- client.callback do
260
- @num_succeeded += 1
261
- check_finished
262
- end
263
- client.errback do
264
- @errors << client.error
265
- check_finished
266
- end
267
- end
268
-
269
- def check_finished
270
- EventMachine.stop if @num_succeeded + @errors.size == @num_registered
271
- end
272
- end
273
- end
274
- end
275
- end
276
-
277
- if Faraday::Adapter::EMHttp.loaded?
278
- begin
279
- require 'openssl'
280
- rescue LoadError
281
- warn 'Warning: no such file to load -- openssl. ' \
282
- 'Make sure it is installed if you want HTTPS support'
283
- else
284
- require 'faraday/adapter/em_http_ssl_patch'
285
- end
286
- end