faraday 1.0.0.pre.rc1 → 1.0.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 +4 -4
- data/CHANGELOG.md +276 -0
- data/README.md +4 -4
- data/Rakefile +7 -0
- data/UPGRADING.md +55 -0
- data/examples/client_spec.rb +65 -0
- data/examples/client_test.rb +79 -0
- data/lib/faraday.rb +4 -4
- data/lib/faraday/adapter.rb +46 -0
- data/lib/faraday/adapter/em_http.rb +5 -6
- data/lib/faraday/adapter/em_http_ssl_patch.rb +1 -1
- data/lib/faraday/adapter/excon.rb +24 -22
- data/lib/faraday/adapter/httpclient.rb +40 -39
- data/lib/faraday/adapter/net_http.rb +42 -38
- data/lib/faraday/adapter/net_http_persistent.rb +3 -1
- data/lib/faraday/adapter/patron.rb +42 -24
- data/lib/faraday/adapter/rack.rb +2 -1
- data/lib/faraday/connection.rb +10 -22
- data/lib/faraday/encoders/flat_params_encoder.rb +7 -3
- data/lib/faraday/error.rb +44 -12
- data/lib/faraday/{upload_io.rb → file_part.rb} +53 -3
- data/lib/faraday/logging/formatter.rb +28 -15
- data/lib/faraday/middleware.rb +8 -0
- data/lib/faraday/options.rb +1 -1
- data/lib/faraday/options/env.rb +1 -1
- data/lib/faraday/options/request_options.rb +3 -2
- data/lib/faraday/param_part.rb +53 -0
- data/lib/faraday/request/multipart.rb +9 -1
- data/lib/faraday/response.rb +2 -2
- data/lib/faraday/response/raise_error.rb +2 -0
- data/spec/faraday/adapter/em_http_spec.rb +47 -0
- data/spec/faraday/adapter/em_synchrony_spec.rb +16 -0
- data/spec/faraday/adapter/excon_spec.rb +49 -0
- data/spec/faraday/adapter/httpclient_spec.rb +73 -0
- data/spec/faraday/adapter/net_http_persistent_spec.rb +57 -0
- data/spec/faraday/adapter/net_http_spec.rb +64 -0
- data/spec/faraday/adapter/patron_spec.rb +18 -0
- data/spec/faraday/adapter/rack_spec.rb +8 -0
- data/spec/faraday/adapter/typhoeus_spec.rb +7 -0
- data/spec/faraday/adapter_registry_spec.rb +28 -0
- data/spec/faraday/adapter_spec.rb +55 -0
- data/spec/faraday/composite_read_io_spec.rb +80 -0
- data/spec/faraday/connection_spec.rb +691 -0
- data/spec/faraday/error_spec.rb +45 -0
- data/spec/faraday/middleware_spec.rb +26 -0
- data/spec/faraday/options/env_spec.rb +70 -0
- data/spec/faraday/options/options_spec.rb +297 -0
- data/spec/faraday/options/proxy_options_spec.rb +37 -0
- data/spec/faraday/options/request_options_spec.rb +19 -0
- data/spec/faraday/params_encoders/flat_spec.rb +34 -0
- data/spec/faraday/params_encoders/nested_spec.rb +134 -0
- data/spec/faraday/rack_builder_spec.rb +196 -0
- data/spec/faraday/request/authorization_spec.rb +88 -0
- data/spec/faraday/request/instrumentation_spec.rb +76 -0
- data/spec/faraday/request/multipart_spec.rb +274 -0
- data/spec/faraday/request/retry_spec.rb +242 -0
- data/spec/faraday/request/url_encoded_spec.rb +70 -0
- data/spec/faraday/request_spec.rb +109 -0
- data/spec/faraday/response/logger_spec.rb +220 -0
- data/spec/faraday/response/middleware_spec.rb +52 -0
- data/spec/faraday/response/raise_error_spec.rb +106 -0
- data/spec/faraday/response_spec.rb +75 -0
- data/spec/faraday/utils/headers_spec.rb +82 -0
- data/spec/faraday/utils_spec.rb +56 -0
- data/spec/faraday_spec.rb +37 -0
- data/spec/spec_helper.rb +132 -0
- data/spec/support/disabling_stub.rb +14 -0
- data/spec/support/fake_safe_buffer.rb +15 -0
- data/spec/support/helper_methods.rb +133 -0
- data/spec/support/shared_examples/adapter.rb +104 -0
- data/spec/support/shared_examples/params_encoder.rb +18 -0
- data/spec/support/shared_examples/request_method.rb +234 -0
- data/spec/support/streaming_response_checker.rb +35 -0
- data/spec/support/webmock_rack_app.rb +68 -0
- metadata +65 -11
@@ -16,7 +16,7 @@ module Faraday
|
|
16
16
|
if @connection_options.key?(:pool_size)
|
17
17
|
options[:pool_size] = @connection_options[:pool_size]
|
18
18
|
end
|
19
|
-
Net::HTTP::Persistent.new(options)
|
19
|
+
Net::HTTP::Persistent.new(**options)
|
20
20
|
else
|
21
21
|
Net::HTTP::Persistent.new('Faraday')
|
22
22
|
end
|
@@ -73,6 +73,8 @@ module Faraday
|
|
73
73
|
}.freeze
|
74
74
|
|
75
75
|
def configure_ssl(http, ssl)
|
76
|
+
return unless ssl
|
77
|
+
|
76
78
|
http_set(http, :verify_mode, ssl_verify_mode(ssl))
|
77
79
|
http_set(http, :cert_store, ssl_cert_store(ssl))
|
78
80
|
|
@@ -6,11 +6,7 @@ module Faraday
|
|
6
6
|
class Patron < Faraday::Adapter
|
7
7
|
dependency 'patron'
|
8
8
|
|
9
|
-
def
|
10
|
-
super
|
11
|
-
# TODO: support streaming requests
|
12
|
-
env[:body] = env[:body].read if env[:body].respond_to? :read
|
13
|
-
|
9
|
+
def build_connection(env)
|
14
10
|
session = ::Patron::Session.new
|
15
11
|
@config_block&.call(session)
|
16
12
|
if (env[:url].scheme == 'https') && env[:ssl]
|
@@ -18,27 +14,26 @@ module Faraday
|
|
18
14
|
end
|
19
15
|
|
20
16
|
if (req = env[:request])
|
21
|
-
|
22
|
-
|
23
|
-
end
|
24
|
-
session.connect_timeout = req[:open_timeout] if req[:open_timeout]
|
25
|
-
|
26
|
-
if (proxy = req[:proxy])
|
27
|
-
proxy_uri = proxy[:uri].dup
|
28
|
-
proxy_uri.user = proxy[:user] &&
|
29
|
-
Utils.escape(proxy[:user]).gsub('+', '%20')
|
30
|
-
proxy_uri.password = proxy[:password] &&
|
31
|
-
Utils.escape(proxy[:password]).gsub('+', '%20')
|
32
|
-
session.proxy = proxy_uri.to_s
|
33
|
-
end
|
17
|
+
configure_timeouts(session, req)
|
18
|
+
configure_proxy(session, req[:proxy])
|
34
19
|
end
|
35
20
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
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
|
42
37
|
end
|
43
38
|
|
44
39
|
if (req = env[:request]).stream_response?
|
@@ -91,6 +86,29 @@ module Faraday
|
|
91
86
|
end
|
92
87
|
end
|
93
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
|
+
|
94
112
|
private
|
95
113
|
|
96
114
|
CURL_TIMEOUT_MESSAGES = [
|
data/lib/faraday/adapter/rack.rb
CHANGED
@@ -37,7 +37,8 @@ module Faraday
|
|
37
37
|
rack_env[name] = value
|
38
38
|
end
|
39
39
|
|
40
|
-
timeout
|
40
|
+
timeout = request_timeout(:open, env[:request])
|
41
|
+
timeout ||= request_timeout(:read, env[:request])
|
41
42
|
response = if timeout
|
42
43
|
Timer.timeout(timeout, Faraday::TimeoutError) do
|
43
44
|
execute_request(env, rack_env)
|
data/lib/faraday/connection.rb
CHANGED
@@ -14,7 +14,7 @@ module Faraday
|
|
14
14
|
#
|
15
15
|
class Connection
|
16
16
|
# A Set of allowed HTTP verbs.
|
17
|
-
METHODS = Set.new %i[get post put delete head patch options trace
|
17
|
+
METHODS = Set.new %i[get post put delete head patch options trace]
|
18
18
|
|
19
19
|
# @return [Hash] URI query unencoded key/value pairs.
|
20
20
|
attr_reader :params
|
@@ -99,7 +99,6 @@ module Faraday
|
|
99
99
|
else
|
100
100
|
proxy_from_env(url)
|
101
101
|
end
|
102
|
-
@temp_proxy = @proxy
|
103
102
|
end
|
104
103
|
|
105
104
|
# Sets the Hash of URI query unencoded key/value pairs.
|
@@ -118,6 +117,13 @@ module Faraday
|
|
118
117
|
|
119
118
|
def_delegators :builder, :build, :use, :request, :response, :adapter, :app
|
120
119
|
|
120
|
+
# Closes the underlying resources and/or connections. In the case of
|
121
|
+
# persistent connections, this closes all currently open connections
|
122
|
+
# but does not prevent new connections from being made.
|
123
|
+
def close
|
124
|
+
app.close
|
125
|
+
end
|
126
|
+
|
121
127
|
# @!method get(url = nil, params = nil, headers = nil)
|
122
128
|
# Makes a GET HTTP request without a body.
|
123
129
|
# @!scope class
|
@@ -170,21 +176,6 @@ module Faraday
|
|
170
176
|
# @yield [Faraday::Request] for further request customizations
|
171
177
|
# @return [Faraday::Response]
|
172
178
|
|
173
|
-
# @!method connect(url = nil, params = nil, headers = nil)
|
174
|
-
# Makes a CONNECT HTTP request without a body.
|
175
|
-
# @!scope class
|
176
|
-
#
|
177
|
-
# @param url [String] The optional String base URL to use as a prefix for
|
178
|
-
# all requests. Can also be the options Hash.
|
179
|
-
# @param params [Hash] Hash of URI query unencoded key/value pairs.
|
180
|
-
# @param headers [Hash] unencoded HTTP header key/value pairs.
|
181
|
-
#
|
182
|
-
# @example
|
183
|
-
# conn.connect '/items/1'
|
184
|
-
#
|
185
|
-
# @yield [Faraday::Request] for further request customizations
|
186
|
-
# @return [Faraday::Response]
|
187
|
-
|
188
179
|
# @!method trace(url = nil, params = nil, headers = nil)
|
189
180
|
# Makes a TRACE HTTP request without a body.
|
190
181
|
# @!scope class
|
@@ -490,11 +481,8 @@ module Faraday
|
|
490
481
|
raise ArgumentError, "unknown http method: #{method}"
|
491
482
|
end
|
492
483
|
|
493
|
-
# Resets temp_proxy
|
494
|
-
@temp_proxy = proxy_for_request(url)
|
495
|
-
|
496
484
|
request = build_request(method) do |req|
|
497
|
-
req.options =
|
485
|
+
req.options.proxy = proxy_for_request(url)
|
498
486
|
req.url(url) if url
|
499
487
|
req.headers.update(headers) if headers
|
500
488
|
req.body = body if body
|
@@ -514,7 +502,7 @@ module Faraday
|
|
514
502
|
Request.create(method) do |req|
|
515
503
|
req.params = params.dup
|
516
504
|
req.headers = headers.dup
|
517
|
-
req.options = options
|
505
|
+
req.options = options.dup
|
518
506
|
yield(req) if block_given?
|
519
507
|
end
|
520
508
|
end
|
@@ -45,9 +45,13 @@ module Faraday
|
|
45
45
|
if value.nil?
|
46
46
|
buffer << "#{encoded_key}&"
|
47
47
|
elsif value.is_a?(Array)
|
48
|
-
value.
|
49
|
-
|
50
|
-
|
48
|
+
if value.empty?
|
49
|
+
buffer << "#{encoded_key}=&"
|
50
|
+
else
|
51
|
+
value.each do |sub_value|
|
52
|
+
encoded_value = escape(sub_value)
|
53
|
+
buffer << "#{encoded_key}=#{encoded_value}&"
|
54
|
+
end
|
51
55
|
end
|
52
56
|
else
|
53
57
|
encoded_value = escape(value)
|
data/lib/faraday/error.rb
CHANGED
@@ -1,23 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# Faraday namespace.
|
3
4
|
module Faraday
|
4
5
|
# Faraday error base class.
|
5
6
|
class Error < StandardError
|
6
7
|
attr_reader :response, :wrapped_exception
|
7
8
|
|
8
9
|
def initialize(exc, response = nil)
|
9
|
-
@wrapped_exception = nil
|
10
|
-
@response = response
|
11
|
-
|
12
|
-
if exc.respond_to?(:backtrace)
|
13
|
-
super(exc.message)
|
14
|
-
@wrapped_exception = exc
|
15
|
-
elsif exc.respond_to?(:each_key)
|
16
|
-
super("the server responded with status #{exc[:status]}")
|
17
|
-
@response = exc
|
18
|
-
else
|
19
|
-
super(exc.to_s)
|
20
|
-
end
|
10
|
+
@wrapped_exception = nil unless defined?(@wrapped_exception)
|
11
|
+
@response = nil unless defined?(@response)
|
12
|
+
super(exc_msg_and_response!(exc, response))
|
21
13
|
end
|
22
14
|
|
23
15
|
def backtrace
|
@@ -35,6 +27,38 @@ module Faraday
|
|
35
27
|
inner << " #{super}" if inner.empty?
|
36
28
|
%(#<#{self.class}#{inner}>)
|
37
29
|
end
|
30
|
+
|
31
|
+
protected
|
32
|
+
|
33
|
+
# Pulls out potential parent exception and response hash, storing them in
|
34
|
+
# instance variables.
|
35
|
+
# exc - Either an Exception, a string message, or a response hash.
|
36
|
+
# response - Hash
|
37
|
+
# :status - Optional integer HTTP response status
|
38
|
+
# :headers - String key/value hash of HTTP response header
|
39
|
+
# values.
|
40
|
+
# :body - Optional string HTTP response body.
|
41
|
+
#
|
42
|
+
# If a subclass has to call this, then it should pass a string message
|
43
|
+
# to `super`. See NilStatusError.
|
44
|
+
def exc_msg_and_response!(exc, response = nil)
|
45
|
+
if @response.nil? && @wrapped_exception.nil?
|
46
|
+
@wrapped_exception, msg, @response = exc_msg_and_response(exc, response)
|
47
|
+
return msg
|
48
|
+
end
|
49
|
+
|
50
|
+
exc.to_s
|
51
|
+
end
|
52
|
+
|
53
|
+
# Pulls out potential parent exception and response hash.
|
54
|
+
def exc_msg_and_response(exc, response = nil)
|
55
|
+
return [exc, exc.message, response] if exc.respond_to?(:backtrace)
|
56
|
+
|
57
|
+
return [nil, "the server responded with status #{exc[:status]}", exc] \
|
58
|
+
if exc.respond_to?(:each_key)
|
59
|
+
|
60
|
+
[nil, exc.to_s, response]
|
61
|
+
end
|
38
62
|
end
|
39
63
|
|
40
64
|
# Faraday client error class. Represents 4xx status responses.
|
@@ -80,6 +104,14 @@ module Faraday
|
|
80
104
|
end
|
81
105
|
end
|
82
106
|
|
107
|
+
# Raised by Faraday::Response::RaiseError in case of a nil status in response.
|
108
|
+
class NilStatusError < ServerError
|
109
|
+
def initialize(exc, response = nil)
|
110
|
+
exc_msg_and_response!(exc, response)
|
111
|
+
super('http status could not be derived from the server response')
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
83
115
|
# A unified error for failed connections.
|
84
116
|
class ConnectionFailed < Error
|
85
117
|
end
|
@@ -7,6 +7,59 @@ require 'composite_io'
|
|
7
7
|
require 'parts'
|
8
8
|
|
9
9
|
module Faraday
|
10
|
+
# Multipart value used to POST a binary data from a file or
|
11
|
+
#
|
12
|
+
# @example
|
13
|
+
# payload = { file: Faraday::FilePart.new("file_name.ext", "content/type") }
|
14
|
+
# http.post("/upload", payload)
|
15
|
+
#
|
16
|
+
|
17
|
+
# @!method initialize(filename_or_io, content_type, filename = nil, opts = {})
|
18
|
+
#
|
19
|
+
# @param filename_or_io [String, IO] Either a String filename to a local
|
20
|
+
# file or an open IO object.
|
21
|
+
# @param content_type [String] String content type of the file data.
|
22
|
+
# @param filename [String] Optional String filename, usually to add context
|
23
|
+
# to a given IO object.
|
24
|
+
# @param opts [Hash] Optional Hash of String key/value pairs to describethis
|
25
|
+
# this uploaded file. Expected Header keys include:
|
26
|
+
# * Content-Transfer-Encoding - Defaults to "binary"
|
27
|
+
# * Content-Disposition - Defaults to "form-data"
|
28
|
+
# * Content-Type - Defaults to the content_type argument.
|
29
|
+
# * Content-ID - Optional.
|
30
|
+
#
|
31
|
+
# @return [Faraday::FilePart]
|
32
|
+
#
|
33
|
+
# @!attribute [r] content_type
|
34
|
+
# The uploaded binary data's content type.
|
35
|
+
#
|
36
|
+
# @return [String]
|
37
|
+
#
|
38
|
+
# @!attribute [r] original_filename
|
39
|
+
# The base filename, taken either from the filename_or_io or filename
|
40
|
+
# arguments in #initialize.
|
41
|
+
#
|
42
|
+
# @return [String]
|
43
|
+
#
|
44
|
+
# @!attribute [r] opts
|
45
|
+
# Extra String key/value pairs to make up the header for this uploaded file.
|
46
|
+
#
|
47
|
+
# @return [Hash]
|
48
|
+
#
|
49
|
+
# @!attribute [r] io
|
50
|
+
# The open IO object for the uploaded file.
|
51
|
+
#
|
52
|
+
# @return [IO]
|
53
|
+
FilePart = ::UploadIO
|
54
|
+
|
55
|
+
# Multipart value used to POST a file.
|
56
|
+
#
|
57
|
+
# @deprecated Use FilePart instead of this class. It behaves identically, with
|
58
|
+
# a matching name to ParamPart.
|
59
|
+
UploadIO = ::UploadIO
|
60
|
+
|
61
|
+
Parts = ::Parts
|
62
|
+
|
10
63
|
# Similar to, but not compatible with CompositeReadIO provided by the
|
11
64
|
# multipart-post gem.
|
12
65
|
# https://github.com/nicksieger/multipart-post/blob/master/lib/composite_io.rb
|
@@ -72,7 +125,4 @@ module Faraday
|
|
72
125
|
@index += 1
|
73
126
|
end
|
74
127
|
end
|
75
|
-
|
76
|
-
UploadIO = ::UploadIO
|
77
|
-
Parts = ::Parts
|
78
128
|
end
|
@@ -7,7 +7,8 @@ module Faraday
|
|
7
7
|
class Formatter
|
8
8
|
extend Forwardable
|
9
9
|
|
10
|
-
DEFAULT_OPTIONS = { headers: true, bodies: false
|
10
|
+
DEFAULT_OPTIONS = { headers: true, bodies: false,
|
11
|
+
log_level: :info }.freeze
|
11
12
|
|
12
13
|
def initialize(logger:, options:)
|
13
14
|
@logger = logger
|
@@ -18,27 +19,21 @@ module Faraday
|
|
18
19
|
def_delegators :@logger, :debug, :info, :warn, :error, :fatal
|
19
20
|
|
20
21
|
def request(env)
|
21
|
-
|
22
|
+
request_log = proc do
|
22
23
|
"#{env.method.upcase} #{apply_filters(env.url.to_s)}"
|
23
24
|
end
|
24
|
-
|
25
|
-
debug('request') { apply_filters(dump_headers(env.request_headers)) }
|
26
|
-
end
|
27
|
-
return unless env[:body] && log_body?(:request)
|
25
|
+
public_send(log_level, 'request', &request_log)
|
28
26
|
|
29
|
-
|
27
|
+
log_headers('request', env.request_headers) if log_headers?(:request)
|
28
|
+
log_body('request', env[:body]) if env[:body] && log_body?(:request)
|
30
29
|
end
|
31
30
|
|
32
31
|
def response(env)
|
33
|
-
|
34
|
-
|
35
|
-
debug('response') do
|
36
|
-
apply_filters(dump_headers(env.response_headers))
|
37
|
-
end
|
38
|
-
end
|
39
|
-
return unless env[:body] && log_body?(:response)
|
32
|
+
status = proc { "Status #{env.status}" }
|
33
|
+
public_send(log_level, 'response', &status)
|
40
34
|
|
41
|
-
|
35
|
+
log_headers('response', env.response_headers) if log_headers?(:response)
|
36
|
+
log_body('response', env[:body]) if env[:body] && log_body?(:response)
|
42
37
|
end
|
43
38
|
|
44
39
|
def filter(filter_word, filter_replacement)
|
@@ -87,6 +82,24 @@ module Faraday
|
|
87
82
|
end
|
88
83
|
output
|
89
84
|
end
|
85
|
+
|
86
|
+
def log_level
|
87
|
+
unless %i[debug info warn error fatal].include?(@options[:log_level])
|
88
|
+
return :info
|
89
|
+
end
|
90
|
+
|
91
|
+
@options[:log_level]
|
92
|
+
end
|
93
|
+
|
94
|
+
def log_headers(type, headers)
|
95
|
+
headers_log = proc { apply_filters(dump_headers(headers)) }
|
96
|
+
public_send(log_level, type, &headers_log)
|
97
|
+
end
|
98
|
+
|
99
|
+
def log_body(type, body)
|
100
|
+
body_log = proc { apply_filters(dump_body(body)) }
|
101
|
+
public_send(log_level, type, &body_log)
|
102
|
+
end
|
90
103
|
end
|
91
104
|
end
|
92
105
|
end
|
data/lib/faraday/middleware.rb
CHANGED
data/lib/faraday/options.rb
CHANGED