faraday 0.15.0 → 2.2.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 +570 -0
- data/LICENSE.md +1 -1
- data/README.md +25 -351
- data/Rakefile +7 -0
- data/examples/client_spec.rb +97 -0
- data/examples/client_test.rb +118 -0
- data/lib/faraday/adapter/test.rb +127 -72
- data/lib/faraday/adapter.rb +69 -22
- data/lib/faraday/adapter_registry.rb +30 -0
- data/lib/faraday/connection.rb +309 -232
- data/lib/faraday/encoders/flat_params_encoder.rb +105 -0
- data/lib/faraday/encoders/nested_params_encoder.rb +176 -0
- data/lib/faraday/error.rb +119 -38
- data/lib/faraday/logging/formatter.rb +106 -0
- data/lib/faraday/methods.rb +6 -0
- data/lib/faraday/middleware.rb +18 -25
- data/lib/faraday/middleware_registry.rb +83 -0
- data/lib/faraday/options/connection_options.rb +22 -0
- data/lib/faraday/options/env.rb +181 -0
- data/lib/faraday/options/proxy_options.rb +32 -0
- data/lib/faraday/options/request_options.rb +22 -0
- data/lib/faraday/options/ssl_options.rb +59 -0
- data/lib/faraday/options.rb +41 -195
- data/lib/faraday/parameters.rb +4 -196
- data/lib/faraday/rack_builder.rb +91 -76
- data/lib/faraday/request/authorization.rb +37 -29
- data/lib/faraday/request/instrumentation.rb +47 -27
- data/lib/faraday/request/json.rb +55 -0
- data/lib/faraday/request/url_encoded.rb +45 -23
- data/lib/faraday/request.rb +74 -32
- data/lib/faraday/response/json.rb +54 -0
- data/lib/faraday/response/logger.rb +22 -69
- data/lib/faraday/response/raise_error.rb +57 -14
- data/lib/faraday/response.rb +26 -33
- data/lib/faraday/utils/headers.rb +139 -0
- data/lib/faraday/utils/params_hash.rb +61 -0
- data/lib/faraday/utils.rb +47 -251
- data/lib/faraday/version.rb +5 -0
- data/lib/faraday.rb +108 -199
- data/spec/external_adapters/faraday_specs_setup.rb +14 -0
- data/spec/faraday/adapter/test_spec.rb +377 -0
- data/spec/faraday/adapter_registry_spec.rb +28 -0
- data/spec/faraday/adapter_spec.rb +55 -0
- data/spec/faraday/connection_spec.rb +787 -0
- data/spec/faraday/error_spec.rb +60 -0
- data/spec/faraday/middleware_registry_spec.rb +31 -0
- data/spec/faraday/middleware_spec.rb +52 -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 +44 -0
- data/spec/faraday/options/request_options_spec.rb +19 -0
- data/spec/faraday/params_encoders/flat_spec.rb +42 -0
- data/spec/faraday/params_encoders/nested_spec.rb +142 -0
- data/spec/faraday/rack_builder_spec.rb +317 -0
- data/spec/faraday/request/authorization_spec.rb +83 -0
- data/spec/faraday/request/instrumentation_spec.rb +74 -0
- data/spec/faraday/request/json_spec.rb +111 -0
- data/spec/faraday/request/url_encoded_spec.rb +82 -0
- data/spec/faraday/request_spec.rb +109 -0
- data/spec/faraday/response/json_spec.rb +117 -0
- data/spec/faraday/response/logger_spec.rb +220 -0
- data/spec/faraday/response/raise_error_spec.rb +172 -0
- data/spec/faraday/response_spec.rb +75 -0
- data/spec/faraday/utils/headers_spec.rb +82 -0
- data/spec/faraday/utils_spec.rb +117 -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 +96 -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 +249 -0
- data/spec/support/streaming_response_checker.rb +35 -0
- metadata +86 -34
- data/lib/faraday/adapter/em_http.rb +0 -243
- data/lib/faraday/adapter/em_http_ssl_patch.rb +0 -56
- data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +0 -66
- data/lib/faraday/adapter/em_synchrony.rb +0 -106
- data/lib/faraday/adapter/excon.rb +0 -79
- data/lib/faraday/adapter/httpclient.rb +0 -128
- data/lib/faraday/adapter/net_http.rb +0 -137
- data/lib/faraday/adapter/net_http_persistent.rb +0 -63
- data/lib/faraday/adapter/patron.rb +0 -100
- data/lib/faraday/adapter/rack.rb +0 -58
- data/lib/faraday/adapter/typhoeus.rb +0 -12
- data/lib/faraday/autoload.rb +0 -84
- data/lib/faraday/request/basic_authentication.rb +0 -13
- data/lib/faraday/request/multipart.rb +0 -68
- data/lib/faraday/request/retry.rb +0 -211
- data/lib/faraday/request/token_authentication.rb +0 -15
- data/lib/faraday/upload_io.rb +0 -67
@@ -0,0 +1,83 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'monitor'
|
4
|
+
|
5
|
+
module Faraday
|
6
|
+
# Adds the ability for other modules to register and lookup
|
7
|
+
# middleware classes.
|
8
|
+
module MiddlewareRegistry
|
9
|
+
def registered_middleware
|
10
|
+
@registered_middleware ||= {}
|
11
|
+
end
|
12
|
+
|
13
|
+
# Register middleware class(es) on the current module.
|
14
|
+
#
|
15
|
+
# @param mappings [Hash] Middleware mappings from a lookup symbol to a middleware class.
|
16
|
+
# @return [void]
|
17
|
+
#
|
18
|
+
# @example Lookup by a constant
|
19
|
+
#
|
20
|
+
# module Faraday
|
21
|
+
# class Whatever < Middleware
|
22
|
+
# # Middleware looked up by :foo returns Faraday::Whatever::Foo.
|
23
|
+
# register_middleware(foo: Whatever)
|
24
|
+
# end
|
25
|
+
# end
|
26
|
+
def register_middleware(**mappings)
|
27
|
+
middleware_mutex do
|
28
|
+
registered_middleware.update(mappings)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Unregister a previously registered middleware class.
|
33
|
+
#
|
34
|
+
# @param key [Symbol] key for the registered middleware.
|
35
|
+
def unregister_middleware(key)
|
36
|
+
registered_middleware.delete(key)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Lookup middleware class with a registered Symbol shortcut.
|
40
|
+
#
|
41
|
+
# @param key [Symbol] key for the registered middleware.
|
42
|
+
# @return [Class] a middleware Class.
|
43
|
+
# @raise [Faraday::Error] if given key is not registered
|
44
|
+
#
|
45
|
+
# @example
|
46
|
+
#
|
47
|
+
# module Faraday
|
48
|
+
# class Whatever < Middleware
|
49
|
+
# register_middleware(foo: Whatever)
|
50
|
+
# end
|
51
|
+
# end
|
52
|
+
#
|
53
|
+
# Faraday::Middleware.lookup_middleware(:foo)
|
54
|
+
# # => Faraday::Whatever
|
55
|
+
def lookup_middleware(key)
|
56
|
+
load_middleware(key) ||
|
57
|
+
raise(Faraday::Error, "#{key.inspect} is not registered on #{self}")
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def middleware_mutex(&block)
|
63
|
+
@middleware_mutex ||= Monitor.new
|
64
|
+
@middleware_mutex.synchronize(&block)
|
65
|
+
end
|
66
|
+
|
67
|
+
def load_middleware(key)
|
68
|
+
value = registered_middleware[key]
|
69
|
+
case value
|
70
|
+
when Module
|
71
|
+
value
|
72
|
+
when Symbol, String
|
73
|
+
middleware_mutex do
|
74
|
+
@registered_middleware[key] = const_get(value)
|
75
|
+
end
|
76
|
+
when Proc
|
77
|
+
middleware_mutex do
|
78
|
+
@registered_middleware[key] = value.call
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Faraday
|
4
|
+
# ConnectionOptions contains the configurable properties for a Faraday
|
5
|
+
# connection object.
|
6
|
+
class ConnectionOptions < Options.new(:request, :proxy, :ssl, :builder, :url,
|
7
|
+
:parallel_manager, :params, :headers,
|
8
|
+
:builder_class)
|
9
|
+
|
10
|
+
options request: RequestOptions, ssl: SSLOptions
|
11
|
+
|
12
|
+
memoized(:request) { self.class.options_for(:request).new }
|
13
|
+
|
14
|
+
memoized(:ssl) { self.class.options_for(:ssl).new }
|
15
|
+
|
16
|
+
memoized(:builder_class) { RackBuilder }
|
17
|
+
|
18
|
+
def new_builder(block)
|
19
|
+
builder_class.new(&block)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,181 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Faraday
|
4
|
+
# @!attribute method
|
5
|
+
# @return [Symbol] HTTP method (`:get`, `:post`)
|
6
|
+
#
|
7
|
+
# @!attribute body
|
8
|
+
# @return [String] The request body that will eventually be converted to a
|
9
|
+
# string.
|
10
|
+
#
|
11
|
+
# @!attribute url
|
12
|
+
# @return [URI] URI instance for the current request.
|
13
|
+
#
|
14
|
+
# @!attribute request
|
15
|
+
# @return [Hash] options for configuring the request.
|
16
|
+
# Options for configuring the request.
|
17
|
+
#
|
18
|
+
# - `:timeout` open/read timeout Integer in seconds
|
19
|
+
# - `:open_timeout` - read timeout Integer in seconds
|
20
|
+
# - `:on_data` - Proc for streaming
|
21
|
+
# - `:proxy` - Hash of proxy options
|
22
|
+
# - `:uri` - Proxy Server URI
|
23
|
+
# - `:user` - Proxy server username
|
24
|
+
# - `:password` - Proxy server password
|
25
|
+
#
|
26
|
+
# @!attribute request_headers
|
27
|
+
# @return [Hash] HTTP Headers to be sent to the server.
|
28
|
+
#
|
29
|
+
# @!attribute ssl
|
30
|
+
# @return [Hash] options for configuring SSL requests
|
31
|
+
#
|
32
|
+
# @!attribute parallel_manager
|
33
|
+
# @return [Object] sent if the connection is in parallel mode
|
34
|
+
#
|
35
|
+
# @!attribute params
|
36
|
+
# @return [Hash]
|
37
|
+
#
|
38
|
+
# @!attribute response
|
39
|
+
# @return [Response]
|
40
|
+
#
|
41
|
+
# @!attribute response_headers
|
42
|
+
# @return [Hash] HTTP headers from the server
|
43
|
+
#
|
44
|
+
# @!attribute status
|
45
|
+
# @return [Integer] HTTP response status code
|
46
|
+
#
|
47
|
+
# @!attribute reason_phrase
|
48
|
+
# @return [String]
|
49
|
+
class Env < Options.new(:method, :request_body, :url, :request,
|
50
|
+
:request_headers, :ssl, :parallel_manager, :params,
|
51
|
+
:response, :response_headers, :status,
|
52
|
+
:reason_phrase, :response_body)
|
53
|
+
|
54
|
+
# rubocop:disable Naming/ConstantName
|
55
|
+
ContentLength = 'Content-Length'
|
56
|
+
StatusesWithoutBody = Set.new [204, 304]
|
57
|
+
SuccessfulStatuses = (200..299).freeze
|
58
|
+
# rubocop:enable Naming/ConstantName
|
59
|
+
|
60
|
+
# A Set of HTTP verbs that typically send a body. If no body is set for
|
61
|
+
# these requests, the Content-Length header is set to 0.
|
62
|
+
MethodsWithBodies = Set.new(Faraday::METHODS_WITH_BODY.map(&:to_sym))
|
63
|
+
|
64
|
+
options request: RequestOptions,
|
65
|
+
request_headers: Utils::Headers, response_headers: Utils::Headers
|
66
|
+
|
67
|
+
extend Forwardable
|
68
|
+
|
69
|
+
def_delegators :request, :params_encoder
|
70
|
+
|
71
|
+
# Build a new Env from given value. Respects and updates `custom_members`.
|
72
|
+
#
|
73
|
+
# @param value [Object] a value fitting Option.from(v).
|
74
|
+
# @return [Env] from given value
|
75
|
+
def self.from(value)
|
76
|
+
env = super(value)
|
77
|
+
if value.respond_to?(:custom_members)
|
78
|
+
env.custom_members.update(value.custom_members)
|
79
|
+
end
|
80
|
+
env
|
81
|
+
end
|
82
|
+
|
83
|
+
# @param key [Object]
|
84
|
+
def [](key)
|
85
|
+
return self[current_body] if key == :body
|
86
|
+
|
87
|
+
if in_member_set?(key)
|
88
|
+
super(key)
|
89
|
+
else
|
90
|
+
custom_members[key]
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# @param key [Object]
|
95
|
+
# @param value [Object]
|
96
|
+
def []=(key, value)
|
97
|
+
if key == :body
|
98
|
+
super(current_body, value)
|
99
|
+
return
|
100
|
+
end
|
101
|
+
|
102
|
+
if in_member_set?(key)
|
103
|
+
super(key, value)
|
104
|
+
else
|
105
|
+
custom_members[key] = value
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def current_body
|
110
|
+
!!status ? :response_body : :request_body
|
111
|
+
end
|
112
|
+
|
113
|
+
def body
|
114
|
+
self[:body]
|
115
|
+
end
|
116
|
+
|
117
|
+
def body=(value)
|
118
|
+
self[:body] = value
|
119
|
+
end
|
120
|
+
|
121
|
+
# @return [Boolean] true if status is in the set of {SuccessfulStatuses}.
|
122
|
+
def success?
|
123
|
+
SuccessfulStatuses.include?(status)
|
124
|
+
end
|
125
|
+
|
126
|
+
# @return [Boolean] true if there's no body yet, and the method is in the
|
127
|
+
# set of {MethodsWithBodies}.
|
128
|
+
def needs_body?
|
129
|
+
!body && MethodsWithBodies.include?(method)
|
130
|
+
end
|
131
|
+
|
132
|
+
# Sets content length to zero and the body to the empty string.
|
133
|
+
def clear_body
|
134
|
+
request_headers[ContentLength] = '0'
|
135
|
+
self.body = +''
|
136
|
+
end
|
137
|
+
|
138
|
+
# @return [Boolean] true if the status isn't in the set of
|
139
|
+
# {StatusesWithoutBody}.
|
140
|
+
def parse_body?
|
141
|
+
!StatusesWithoutBody.include?(status)
|
142
|
+
end
|
143
|
+
|
144
|
+
# @return [Boolean] true if there is a parallel_manager
|
145
|
+
def parallel?
|
146
|
+
!!parallel_manager
|
147
|
+
end
|
148
|
+
|
149
|
+
def inspect
|
150
|
+
attrs = [nil]
|
151
|
+
members.each do |mem|
|
152
|
+
if (value = send(mem))
|
153
|
+
attrs << "@#{mem}=#{value.inspect}"
|
154
|
+
end
|
155
|
+
end
|
156
|
+
attrs << "@custom=#{custom_members.inspect}" unless custom_members.empty?
|
157
|
+
%(#<#{self.class}#{attrs.join(' ')}>)
|
158
|
+
end
|
159
|
+
|
160
|
+
# @private
|
161
|
+
def custom_members
|
162
|
+
@custom_members ||= {}
|
163
|
+
end
|
164
|
+
|
165
|
+
# @private
|
166
|
+
if members.first.is_a?(Symbol)
|
167
|
+
def in_member_set?(key)
|
168
|
+
self.class.member_set.include?(key.to_sym)
|
169
|
+
end
|
170
|
+
else
|
171
|
+
def in_member_set?(key)
|
172
|
+
self.class.member_set.include?(key.to_s)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
# @private
|
177
|
+
def self.member_set
|
178
|
+
@member_set ||= Set.new(members)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Faraday
|
4
|
+
# ProxyOptions contains the configurable properties for the proxy
|
5
|
+
# configuration used when making an HTTP request.
|
6
|
+
class ProxyOptions < Options.new(:uri, :user, :password)
|
7
|
+
extend Forwardable
|
8
|
+
def_delegators :uri, :scheme, :scheme=, :host, :host=, :port, :port=,
|
9
|
+
:path, :path=
|
10
|
+
|
11
|
+
def self.from(value)
|
12
|
+
case value
|
13
|
+
when String
|
14
|
+
# URIs without a scheme should default to http (like 'example:123').
|
15
|
+
# This fixes #1282 and prevents a silent failure in some adapters.
|
16
|
+
value = "http://#{value}" unless value.include?('://')
|
17
|
+
value = { uri: Utils.URI(value) }
|
18
|
+
when URI
|
19
|
+
value = { uri: value }
|
20
|
+
when Hash, Options
|
21
|
+
if (uri = value.delete(:uri))
|
22
|
+
value[:uri] = Utils.URI(uri)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
super(value)
|
27
|
+
end
|
28
|
+
|
29
|
+
memoized(:user) { uri&.user && Utils.unescape(uri.user) }
|
30
|
+
memoized(:password) { uri&.password && Utils.unescape(uri.password) }
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Faraday
|
4
|
+
# RequestOptions contains the configurable properties for a Faraday request.
|
5
|
+
class RequestOptions < Options.new(:params_encoder, :proxy, :bind,
|
6
|
+
:timeout, :open_timeout, :read_timeout,
|
7
|
+
:write_timeout, :boundary, :oauth,
|
8
|
+
:context, :on_data)
|
9
|
+
|
10
|
+
def []=(key, value)
|
11
|
+
if key && key.to_sym == :proxy
|
12
|
+
super(key, value ? ProxyOptions.from(value) : nil)
|
13
|
+
else
|
14
|
+
super(key, value)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def stream_response?
|
19
|
+
on_data.is_a?(Proc)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Faraday
|
4
|
+
# SSL-related options.
|
5
|
+
#
|
6
|
+
# @!attribute verify
|
7
|
+
# @return [Boolean] whether to verify SSL certificates or not
|
8
|
+
#
|
9
|
+
# @!attribute ca_file
|
10
|
+
# @return [String] CA file
|
11
|
+
#
|
12
|
+
# @!attribute ca_path
|
13
|
+
# @return [String] CA path
|
14
|
+
#
|
15
|
+
# @!attribute verify_mode
|
16
|
+
# @return [Integer] Any `OpenSSL::SSL::` constant (see https://ruby-doc.org/stdlib-2.5.1/libdoc/openssl/rdoc/OpenSSL/SSL.html)
|
17
|
+
#
|
18
|
+
# @!attribute cert_store
|
19
|
+
# @return [OpenSSL::X509::Store] certificate store
|
20
|
+
#
|
21
|
+
# @!attribute client_cert
|
22
|
+
# @return [String, OpenSSL::X509::Certificate] client certificate
|
23
|
+
#
|
24
|
+
# @!attribute client_key
|
25
|
+
# @return [String, OpenSSL::PKey::RSA, OpenSSL::PKey::DSA] client key
|
26
|
+
#
|
27
|
+
# @!attribute certificate
|
28
|
+
# @return [OpenSSL::X509::Certificate] certificate (Excon only)
|
29
|
+
#
|
30
|
+
# @!attribute private_key
|
31
|
+
# @return [OpenSSL::PKey::RSA, OpenSSL::PKey::DSA] private key (Excon only)
|
32
|
+
#
|
33
|
+
# @!attribute verify_depth
|
34
|
+
# @return [Integer] maximum depth for the certificate chain verification
|
35
|
+
#
|
36
|
+
# @!attribute version
|
37
|
+
# @return [String, Symbol] SSL version (see https://ruby-doc.org/stdlib-2.5.1/libdoc/openssl/rdoc/OpenSSL/SSL/SSLContext.html#method-i-ssl_version-3D)
|
38
|
+
#
|
39
|
+
# @!attribute min_version
|
40
|
+
# @return [String, Symbol] minimum SSL version (see https://ruby-doc.org/stdlib-2.5.1/libdoc/openssl/rdoc/OpenSSL/SSL/SSLContext.html#method-i-min_version-3D)
|
41
|
+
#
|
42
|
+
# @!attribute max_version
|
43
|
+
# @return [String, Symbol] maximum SSL version (see https://ruby-doc.org/stdlib-2.5.1/libdoc/openssl/rdoc/OpenSSL/SSL/SSLContext.html#method-i-max_version-3D)
|
44
|
+
class SSLOptions < Options.new(:verify, :ca_file, :ca_path, :verify_mode,
|
45
|
+
:cert_store, :client_cert, :client_key,
|
46
|
+
:certificate, :private_key, :verify_depth,
|
47
|
+
:version, :min_version, :max_version)
|
48
|
+
|
49
|
+
# @return [Boolean] true if should verify
|
50
|
+
def verify?
|
51
|
+
verify != false
|
52
|
+
end
|
53
|
+
|
54
|
+
# @return [Boolean] true if should not verify
|
55
|
+
def disable?
|
56
|
+
!verify?
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|