faraday 1.8.0 → 2.7.11
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 +197 -3
- data/LICENSE.md +1 -1
- data/README.md +34 -20
- data/Rakefile +3 -1
- data/examples/client_spec.rb +41 -19
- data/examples/client_test.rb +48 -22
- data/lib/faraday/adapter/test.rb +61 -12
- data/lib/faraday/adapter.rb +5 -9
- data/lib/faraday/connection.rb +58 -145
- data/lib/faraday/encoders/nested_params_encoder.rb +13 -6
- data/lib/faraday/error.rb +16 -11
- data/lib/faraday/logging/formatter.rb +27 -14
- data/lib/faraday/middleware.rb +3 -1
- data/lib/faraday/middleware_registry.rb +17 -63
- data/lib/faraday/options/connection_options.rb +7 -6
- data/lib/faraday/options/env.rb +85 -62
- data/lib/faraday/options/proxy_options.rb +7 -3
- data/lib/faraday/options/request_options.rb +7 -6
- data/lib/faraday/options/ssl_options.rb +56 -45
- data/lib/faraday/options.rb +4 -3
- data/lib/faraday/rack_builder.rb +23 -20
- data/lib/faraday/request/authorization.rb +33 -41
- data/lib/faraday/request/instrumentation.rb +5 -1
- data/lib/faraday/request/json.rb +64 -0
- data/lib/faraday/request/url_encoded.rb +5 -1
- data/lib/faraday/request.rb +20 -37
- data/lib/faraday/response/json.rb +54 -0
- data/lib/faraday/response/logger.rb +8 -4
- data/lib/faraday/response/raise_error.rb +29 -4
- data/lib/faraday/response.rb +10 -20
- data/lib/faraday/utils/headers.rb +7 -2
- data/lib/faraday/utils.rb +10 -5
- data/lib/faraday/version.rb +1 -1
- data/lib/faraday.rb +10 -38
- data/spec/faraday/adapter/test_spec.rb +65 -0
- data/spec/faraday/connection_spec.rb +163 -91
- data/spec/faraday/error_spec.rb +31 -6
- data/spec/faraday/middleware_registry_spec.rb +31 -0
- data/spec/faraday/middleware_spec.rb +18 -0
- data/spec/faraday/options/env_spec.rb +8 -2
- data/spec/faraday/options/options_spec.rb +1 -1
- data/spec/faraday/options/proxy_options_spec.rb +8 -0
- data/spec/faraday/params_encoders/nested_spec.rb +8 -0
- data/spec/faraday/rack_builder_spec.rb +26 -54
- data/spec/faraday/request/authorization_spec.rb +50 -28
- data/spec/faraday/request/instrumentation_spec.rb +5 -7
- data/spec/faraday/request/json_spec.rb +135 -0
- data/spec/faraday/request/url_encoded_spec.rb +12 -2
- data/spec/faraday/request_spec.rb +5 -15
- data/spec/faraday/response/json_spec.rb +117 -0
- data/spec/faraday/response/logger_spec.rb +38 -0
- data/spec/faraday/response/raise_error_spec.rb +35 -5
- data/spec/faraday/response_spec.rb +3 -1
- data/spec/faraday/utils/headers_spec.rb +22 -4
- data/spec/faraday/utils_spec.rb +63 -1
- data/spec/faraday_spec.rb +8 -4
- data/spec/support/fake_safe_buffer.rb +1 -1
- data/spec/support/helper_methods.rb +0 -37
- data/spec/support/shared_examples/adapter.rb +2 -2
- data/spec/support/shared_examples/request_method.rb +22 -21
- metadata +19 -134
- data/lib/faraday/adapter/typhoeus.rb +0 -15
- data/lib/faraday/autoload.rb +0 -87
- data/lib/faraday/dependency_loader.rb +0 -37
- data/lib/faraday/file_part.rb +0 -128
- data/lib/faraday/param_part.rb +0 -53
- data/lib/faraday/request/basic_authentication.rb +0 -20
- data/lib/faraday/request/multipart.rb +0 -106
- data/lib/faraday/request/retry.rb +0 -239
- data/lib/faraday/request/token_authentication.rb +0 -20
- data/spec/faraday/adapter/em_http_spec.rb +0 -49
- data/spec/faraday/adapter/em_synchrony_spec.rb +0 -18
- data/spec/faraday/adapter/excon_spec.rb +0 -49
- data/spec/faraday/adapter/httpclient_spec.rb +0 -73
- data/spec/faraday/adapter/net_http_spec.rb +0 -64
- data/spec/faraday/adapter/patron_spec.rb +0 -18
- data/spec/faraday/adapter/rack_spec.rb +0 -8
- data/spec/faraday/adapter/typhoeus_spec.rb +0 -7
- data/spec/faraday/composite_read_io_spec.rb +0 -80
- data/spec/faraday/request/multipart_spec.rb +0 -302
- data/spec/faraday/request/retry_spec.rb +0 -242
- data/spec/faraday/response/middleware_spec.rb +0 -68
- data/spec/support/webmock_rack_app.rb +0 -68
@@ -24,6 +24,8 @@ module Faraday
|
|
24
24
|
# mimic the behavior that we get with proxy requests with HTTPS
|
25
25
|
msg = %(407 "Proxy Authentication Required")
|
26
26
|
raise Faraday::ProxyAuthError.new(msg, response_values(env))
|
27
|
+
when 408
|
28
|
+
raise Faraday::RequestTimeoutError, response_values(env)
|
27
29
|
when 409
|
28
30
|
raise Faraday::ConflictError, response_values(env)
|
29
31
|
when 422
|
@@ -37,20 +39,43 @@ module Faraday
|
|
37
39
|
end
|
38
40
|
end
|
39
41
|
|
42
|
+
# Returns a hash of response data with the following keys:
|
43
|
+
# - status
|
44
|
+
# - headers
|
45
|
+
# - body
|
46
|
+
# - request
|
47
|
+
#
|
48
|
+
# The `request` key is omitted when the middleware is explicitly
|
49
|
+
# configured with the option `include_request: false`.
|
40
50
|
def response_values(env)
|
41
|
-
{
|
51
|
+
response = {
|
42
52
|
status: env.status,
|
43
53
|
headers: env.response_headers,
|
44
|
-
body: env.body
|
54
|
+
body: env.body
|
55
|
+
}
|
56
|
+
|
57
|
+
# Include the request data by default. If the middleware was explicitly
|
58
|
+
# configured to _not_ include request data, then omit it.
|
59
|
+
return response unless options.fetch(:include_request, true)
|
60
|
+
|
61
|
+
response.merge(
|
45
62
|
request: {
|
46
63
|
method: env.method,
|
64
|
+
url: env.url,
|
47
65
|
url_path: env.url.path,
|
48
|
-
params: env
|
66
|
+
params: query_params(env),
|
49
67
|
headers: env.request_headers,
|
50
68
|
body: env.request_body
|
51
69
|
}
|
52
|
-
|
70
|
+
)
|
71
|
+
end
|
72
|
+
|
73
|
+
def query_params(env)
|
74
|
+
env.request.params_encoder ||= Faraday::Utils.default_params_encoder
|
75
|
+
env.params_encoder.decode(env.url.query)
|
53
76
|
end
|
54
77
|
end
|
55
78
|
end
|
56
79
|
end
|
80
|
+
|
81
|
+
Faraday::Response.register_middleware(raise_error: Faraday::Response::RaiseError)
|
data/lib/faraday/response.rb
CHANGED
@@ -5,25 +5,9 @@ require 'forwardable'
|
|
5
5
|
module Faraday
|
6
6
|
# Response represents an HTTP response from making an HTTP request.
|
7
7
|
class Response
|
8
|
-
# Used for simple response middleware.
|
9
|
-
class Middleware < Faraday::Middleware
|
10
|
-
# Override this to modify the environment after the response has finished.
|
11
|
-
# Calls the `parse` method if defined
|
12
|
-
# `parse` method can be defined as private, public and protected
|
13
|
-
def on_complete(env)
|
14
|
-
return unless respond_to?(:parse, true) && env.parse_body?
|
15
|
-
|
16
|
-
env.body = parse(env.body)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
8
|
extend Forwardable
|
21
9
|
extend MiddlewareRegistry
|
22
10
|
|
23
|
-
register_middleware File.expand_path('response', __dir__),
|
24
|
-
raise_error: [:RaiseError, 'raise_error'],
|
25
|
-
logger: [:Logger, 'logger']
|
26
|
-
|
27
11
|
def initialize(env = nil)
|
28
12
|
@env = Env.from(env) if env
|
29
13
|
@on_complete_callbacks = []
|
@@ -42,6 +26,7 @@ module Faraday
|
|
42
26
|
def headers
|
43
27
|
finished? ? env.response_headers : {}
|
44
28
|
end
|
29
|
+
|
45
30
|
def_delegator :headers, :[]
|
46
31
|
|
47
32
|
def body
|
@@ -53,10 +38,10 @@ module Faraday
|
|
53
38
|
end
|
54
39
|
|
55
40
|
def on_complete(&block)
|
56
|
-
if
|
57
|
-
@on_complete_callbacks << block
|
58
|
-
else
|
41
|
+
if finished?
|
59
42
|
yield(env)
|
43
|
+
else
|
44
|
+
@on_complete_callbacks << block
|
60
45
|
end
|
61
46
|
self
|
62
47
|
end
|
@@ -76,7 +61,8 @@ module Faraday
|
|
76
61
|
def to_hash
|
77
62
|
{
|
78
63
|
status: env.status, body: env.body,
|
79
|
-
response_headers: env.response_headers
|
64
|
+
response_headers: env.response_headers,
|
65
|
+
url: env.url
|
80
66
|
}
|
81
67
|
end
|
82
68
|
|
@@ -99,3 +85,7 @@ module Faraday
|
|
99
85
|
end
|
100
86
|
end
|
101
87
|
end
|
88
|
+
|
89
|
+
require 'faraday/response/json'
|
90
|
+
require 'faraday/response/logger'
|
91
|
+
require 'faraday/response/raise_error'
|
@@ -111,7 +111,7 @@ module Faraday
|
|
111
111
|
def parse(header_string)
|
112
112
|
return unless header_string && !header_string.empty?
|
113
113
|
|
114
|
-
headers = header_string.split(
|
114
|
+
headers = header_string.split("\r\n")
|
115
115
|
|
116
116
|
# Find the last set of response headers.
|
117
117
|
start_index = headers.rindex { |x| x.start_with?('HTTP/') } || 0
|
@@ -132,7 +132,12 @@ module Faraday
|
|
132
132
|
|
133
133
|
# Join multiple values with a comma.
|
134
134
|
def add_parsed(key, value)
|
135
|
-
|
135
|
+
if key?(key)
|
136
|
+
self[key] = self[key].to_s
|
137
|
+
self[key] << ', ' << value
|
138
|
+
else
|
139
|
+
self[key] = value
|
140
|
+
end
|
136
141
|
end
|
137
142
|
end
|
138
143
|
end
|
data/lib/faraday/utils.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'base64'
|
4
|
+
require 'uri'
|
3
5
|
require 'faraday/utils/headers'
|
4
6
|
require 'faraday/utils/params_hash'
|
5
7
|
|
@@ -51,6 +53,12 @@ module Faraday
|
|
51
53
|
@default_params_encoder ||= NestedParamsEncoder
|
52
54
|
end
|
53
55
|
|
56
|
+
def basic_header_from(login, pass)
|
57
|
+
value = Base64.encode64("#{login}:#{pass}")
|
58
|
+
value.delete!("\n")
|
59
|
+
"Basic #{value}"
|
60
|
+
end
|
61
|
+
|
54
62
|
class << self
|
55
63
|
attr_writer :default_params_encoder
|
56
64
|
end
|
@@ -71,10 +79,7 @@ module Faraday
|
|
71
79
|
end
|
72
80
|
|
73
81
|
def default_uri_parser
|
74
|
-
@default_uri_parser ||=
|
75
|
-
require 'uri'
|
76
|
-
Kernel.method(:URI)
|
77
|
-
end
|
82
|
+
@default_uri_parser ||= Kernel.method(:URI)
|
78
83
|
end
|
79
84
|
|
80
85
|
def default_uri_parser=(parser)
|
@@ -96,7 +101,7 @@ module Faraday
|
|
96
101
|
# Recursive hash update
|
97
102
|
def deep_merge!(target, hash)
|
98
103
|
hash.each do |key, value|
|
99
|
-
target[key] = if value.is_a?(Hash) && target[key].is_a?(Hash)
|
104
|
+
target[key] = if value.is_a?(Hash) && (target[key].is_a?(Hash) || target[key].is_a?(Options))
|
100
105
|
deep_merge(target[key], value)
|
101
106
|
else
|
102
107
|
value
|
data/lib/faraday/version.rb
CHANGED
data/lib/faraday.rb
CHANGED
@@ -4,16 +4,10 @@ require 'cgi'
|
|
4
4
|
require 'date'
|
5
5
|
require 'set'
|
6
6
|
require 'forwardable'
|
7
|
-
require 'faraday/middleware_registry'
|
8
|
-
require 'faraday/dependency_loader'
|
9
|
-
|
10
|
-
unless defined?(::Faraday::Timer)
|
11
|
-
require 'timeout'
|
12
|
-
::Faraday::Timer = Timeout
|
13
|
-
end
|
14
|
-
|
15
7
|
require 'faraday/version'
|
16
8
|
require 'faraday/methods'
|
9
|
+
require 'faraday/error'
|
10
|
+
require 'faraday/middleware_registry'
|
17
11
|
require 'faraday/utils'
|
18
12
|
require 'faraday/options'
|
19
13
|
require 'faraday/connection'
|
@@ -23,21 +17,7 @@ require 'faraday/middleware'
|
|
23
17
|
require 'faraday/adapter'
|
24
18
|
require 'faraday/request'
|
25
19
|
require 'faraday/response'
|
26
|
-
require 'faraday/error'
|
27
|
-
require 'faraday/file_part'
|
28
|
-
require 'faraday/param_part'
|
29
|
-
|
30
|
-
unless defined?(JRUBY_VERSION)
|
31
|
-
require 'faraday/em_http'
|
32
|
-
require 'faraday/em_synchrony'
|
33
|
-
end
|
34
|
-
require 'faraday/excon'
|
35
|
-
require 'faraday/httpclient'
|
36
20
|
require 'faraday/net_http'
|
37
|
-
require 'faraday/net_http_persistent'
|
38
|
-
require 'faraday/patron'
|
39
|
-
require 'faraday/rack'
|
40
|
-
|
41
21
|
# This is the main namespace for Faraday.
|
42
22
|
#
|
43
23
|
# It provides methods to create {Connection} objects, and HTTP-related
|
@@ -51,6 +31,8 @@ require 'faraday/rack'
|
|
51
31
|
# conn.get '/'
|
52
32
|
#
|
53
33
|
module Faraday
|
34
|
+
CONTENT_TYPE = 'Content-Type'
|
35
|
+
|
54
36
|
class << self
|
55
37
|
# The root path that Faraday is being loaded from.
|
56
38
|
#
|
@@ -72,6 +54,10 @@ module Faraday
|
|
72
54
|
# @return [Symbol] the new default_adapter.
|
73
55
|
attr_reader :default_adapter
|
74
56
|
|
57
|
+
# Option for the default_adapter
|
58
|
+
# @return [Hash] default_adapter options
|
59
|
+
attr_accessor :default_adapter_options
|
60
|
+
|
75
61
|
# Documented below, see default_connection
|
76
62
|
attr_writer :default_connection
|
77
63
|
|
@@ -108,23 +94,10 @@ module Faraday
|
|
108
94
|
# params: { page: 1 }
|
109
95
|
# # => Faraday::Connection to http://faraday.com?page=1
|
110
96
|
def new(url = nil, options = {}, &block)
|
111
|
-
options =
|
97
|
+
options = Utils.deep_merge(default_connection_options, options)
|
112
98
|
Faraday::Connection.new(url, options, &block)
|
113
99
|
end
|
114
100
|
|
115
|
-
# @private
|
116
|
-
# Internal: Requires internal Faraday libraries.
|
117
|
-
#
|
118
|
-
# @param libs [Array] one or more relative String names to Faraday classes.
|
119
|
-
# @return [void]
|
120
|
-
def require_libs(*libs)
|
121
|
-
libs.each do |lib|
|
122
|
-
require "#{lib_path}/#{lib}"
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
alias require_lib require_libs
|
127
|
-
|
128
101
|
# Documented elsewhere, see default_adapter reader
|
129
102
|
def default_adapter=(adapter)
|
130
103
|
@default_connection = nil
|
@@ -180,6 +153,5 @@ module Faraday
|
|
180
153
|
self.root_path = File.expand_path __dir__
|
181
154
|
self.lib_path = File.expand_path 'faraday', __dir__
|
182
155
|
self.default_adapter = :net_http
|
183
|
-
|
184
|
-
require_lib 'autoload' unless ENV['FARADAY_NO_AUTOLOAD']
|
156
|
+
self.default_adapter_options = {}
|
185
157
|
end
|
@@ -373,5 +373,70 @@ RSpec.describe Faraday::Adapter::Test do
|
|
373
373
|
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' }
|
374
374
|
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' }
|
375
375
|
end
|
376
|
+
|
377
|
+
describe 'body_match?' do
|
378
|
+
let(:stubs) do
|
379
|
+
described_class::Stubs.new do |stubs|
|
380
|
+
stubs.post('/no_check') { [200, {}, 'ok'] }
|
381
|
+
stubs.post('/with_string', 'abc') { [200, {}, 'ok'] }
|
382
|
+
stubs.post(
|
383
|
+
'/with_proc',
|
384
|
+
->(request_body) { JSON.parse(request_body, symbolize_names: true) == { x: '!', a: [{ m: [{ a: true }], n: 123 }] } },
|
385
|
+
{ content_type: 'application/json' }
|
386
|
+
) do
|
387
|
+
[200, {}, 'ok']
|
388
|
+
end
|
389
|
+
end
|
390
|
+
end
|
391
|
+
|
392
|
+
context 'when trying without any args for body' do
|
393
|
+
subject(:without_body) { connection.post('/no_check') }
|
394
|
+
|
395
|
+
it { expect(without_body.status).to eq 200 }
|
396
|
+
end
|
397
|
+
|
398
|
+
context 'when trying with string body stubs' do
|
399
|
+
subject(:with_string) { connection.post('/with_string', 'abc') }
|
400
|
+
|
401
|
+
it { expect(with_string.status).to eq 200 }
|
402
|
+
end
|
403
|
+
|
404
|
+
context 'when trying with proc body stubs' do
|
405
|
+
subject(:with_proc) do
|
406
|
+
connection.post('/with_proc', JSON.dump(a: [{ n: 123, m: [{ a: true }] }], x: '!'), { 'Content-Type' => 'application/json' })
|
407
|
+
end
|
408
|
+
|
409
|
+
it { expect(with_proc.status).to eq 200 }
|
410
|
+
end
|
411
|
+
end
|
412
|
+
end
|
413
|
+
|
414
|
+
describe 'request timeout' do
|
415
|
+
subject(:request) do
|
416
|
+
connection.get('/sleep') do |req|
|
417
|
+
req.options.timeout = timeout
|
418
|
+
end
|
419
|
+
end
|
420
|
+
|
421
|
+
before do
|
422
|
+
stubs.get('/sleep') do
|
423
|
+
sleep(0.01)
|
424
|
+
[200, {}, '']
|
425
|
+
end
|
426
|
+
end
|
427
|
+
|
428
|
+
context 'when request is within timeout' do
|
429
|
+
let(:timeout) { 1 }
|
430
|
+
|
431
|
+
it { expect(request.status).to eq 200 }
|
432
|
+
end
|
433
|
+
|
434
|
+
context 'when request is too slow' do
|
435
|
+
let(:timeout) { 0.001 }
|
436
|
+
|
437
|
+
it 'raises an exception' do
|
438
|
+
expect { request }.to raise_error(Faraday::TimeoutError)
|
439
|
+
end
|
440
|
+
end
|
376
441
|
end
|
377
442
|
end
|