faraday 0.16.0 → 0.17.4
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 +232 -0
- data/LICENSE.md +1 -1
- data/README.md +358 -18
- data/Rakefile +13 -0
- data/lib/faraday/adapter/em_http.rb +97 -140
- data/lib/faraday/adapter/em_http_ssl_patch.rb +17 -23
- data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +15 -18
- data/lib/faraday/adapter/em_synchrony.rb +60 -104
- data/lib/faraday/adapter/excon.rb +55 -100
- data/lib/faraday/adapter/httpclient.rb +39 -61
- data/lib/faraday/adapter/net_http.rb +51 -103
- data/lib/faraday/adapter/net_http_persistent.rb +28 -49
- data/lib/faraday/adapter/patron.rb +35 -54
- data/lib/faraday/adapter/rack.rb +12 -28
- data/lib/faraday/adapter/test.rb +53 -86
- data/lib/faraday/adapter/typhoeus.rb +1 -4
- data/lib/faraday/adapter.rb +22 -36
- data/lib/faraday/autoload.rb +36 -47
- data/lib/faraday/connection.rb +179 -321
- data/lib/faraday/deprecate.rb +109 -0
- data/lib/faraday/error.rb +79 -21
- data/lib/faraday/middleware.rb +28 -4
- data/lib/faraday/options.rb +183 -32
- data/lib/faraday/parameters.rb +197 -4
- data/lib/faraday/rack_builder.rb +55 -66
- data/lib/faraday/request/authorization.rb +30 -42
- data/lib/faraday/request/basic_authentication.rb +7 -14
- data/lib/faraday/request/instrumentation.rb +27 -45
- data/lib/faraday/request/multipart.rb +48 -79
- data/lib/faraday/request/retry.rb +171 -197
- data/lib/faraday/request/token_authentication.rb +10 -15
- data/lib/faraday/request/url_encoded.rb +23 -41
- data/lib/faraday/request.rb +36 -68
- data/lib/faraday/response/logger.rb +69 -22
- data/lib/faraday/response/raise_error.rb +18 -36
- data/lib/faraday/response.rb +13 -20
- data/lib/faraday/upload_io.rb +67 -0
- data/lib/faraday/utils.rb +245 -28
- data/lib/faraday.rb +174 -93
- data/spec/faraday/deprecate_spec.rb +147 -0
- data/spec/faraday/error_spec.rb +102 -0
- data/spec/faraday/response/raise_error_spec.rb +106 -0
- data/spec/spec_helper.rb +105 -0
- data/test/adapters/default_test.rb +14 -0
- data/test/adapters/em_http_test.rb +30 -0
- data/test/adapters/em_synchrony_test.rb +32 -0
- data/test/adapters/excon_test.rb +30 -0
- data/test/adapters/httpclient_test.rb +34 -0
- data/test/adapters/integration.rb +263 -0
- data/test/adapters/logger_test.rb +136 -0
- data/test/adapters/net_http_persistent_test.rb +114 -0
- data/test/adapters/net_http_test.rb +79 -0
- data/test/adapters/patron_test.rb +40 -0
- data/test/adapters/rack_test.rb +38 -0
- data/test/adapters/test_middleware_test.rb +157 -0
- data/test/adapters/typhoeus_test.rb +38 -0
- data/test/authentication_middleware_test.rb +65 -0
- data/test/composite_read_io_test.rb +109 -0
- data/test/connection_test.rb +738 -0
- data/test/env_test.rb +268 -0
- data/test/helper.rb +75 -0
- data/test/live_server.rb +67 -0
- data/test/middleware/instrumentation_test.rb +88 -0
- data/test/middleware/retry_test.rb +282 -0
- data/test/middleware_stack_test.rb +260 -0
- data/test/multibyte.txt +1 -0
- data/test/options_test.rb +333 -0
- data/test/parameters_test.rb +157 -0
- data/test/request_middleware_test.rb +126 -0
- data/test/response_middleware_test.rb +72 -0
- data/test/strawberry.rb +2 -0
- data/test/utils_test.rb +98 -0
- metadata +50 -25
- data/lib/faraday/adapter_registry.rb +0 -28
- data/lib/faraday/dependency_loader.rb +0 -37
- data/lib/faraday/encoders/flat_params_encoder.rb +0 -94
- data/lib/faraday/encoders/nested_params_encoder.rb +0 -171
- data/lib/faraday/file_part.rb +0 -128
- data/lib/faraday/logging/formatter.rb +0 -92
- data/lib/faraday/middleware_registry.rb +0 -129
- data/lib/faraday/options/connection_options.rb +0 -22
- data/lib/faraday/options/env.rb +0 -181
- data/lib/faraday/options/proxy_options.rb +0 -28
- data/lib/faraday/options/request_options.rb +0 -21
- data/lib/faraday/options/ssl_options.rb +0 -59
- data/lib/faraday/param_part.rb +0 -53
- data/lib/faraday/utils/headers.rb +0 -139
- data/lib/faraday/utils/params_hash.rb +0 -61
- data/spec/external_adapters/faraday_specs_setup.rb +0 -14
@@ -0,0 +1,109 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Faraday
|
4
|
+
# @param new_klass [Class] new Klass to use
|
5
|
+
#
|
6
|
+
# @return [Class] A modified version of new_klass that warns on
|
7
|
+
# usage about deprecation.
|
8
|
+
# @see Faraday::Deprecate
|
9
|
+
module DeprecatedClass
|
10
|
+
def self.proxy_class(origclass, ver = '1.0')
|
11
|
+
proxy = Class.new(origclass) do
|
12
|
+
const_set("ORIG_CLASS", origclass)
|
13
|
+
|
14
|
+
class << self
|
15
|
+
extend Faraday::Deprecate
|
16
|
+
|
17
|
+
def ===(other)
|
18
|
+
(superclass == const_get("ORIG_CLASS") && other.is_a?(superclass)) || super
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
proxy.singleton_class.send(:deprecate, :new, "#{origclass}.new", ver)
|
23
|
+
proxy.singleton_class.send(:deprecate, :inherited, origclass.name, ver)
|
24
|
+
proxy
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Deprecation using semver instead of date, based on Gem::Deprecate
|
29
|
+
# Provides a single method +deprecate+ to be used to declare when
|
30
|
+
# something is going away.
|
31
|
+
#
|
32
|
+
# class Legacy
|
33
|
+
# def self.klass_method
|
34
|
+
# # ...
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# def instance_method
|
38
|
+
# # ...
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# extend Faraday::Deprecate
|
42
|
+
# deprecate :instance_method, "X.z", '1.0'
|
43
|
+
#
|
44
|
+
# class << self
|
45
|
+
# extend Faraday::Deprecate
|
46
|
+
# deprecate :klass_method, :none, '1.0'
|
47
|
+
# end
|
48
|
+
# end
|
49
|
+
module Deprecate
|
50
|
+
def self.skip # :nodoc:
|
51
|
+
@skip ||= begin
|
52
|
+
case ENV['FARADAY_DEPRECATE'].to_s.downcase
|
53
|
+
when '1', 'warn' then :warn
|
54
|
+
else :skip
|
55
|
+
end
|
56
|
+
end
|
57
|
+
@skip == :skip
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.skip=(value) # :nodoc:
|
61
|
+
@skip = value ? :skip : :warn
|
62
|
+
end
|
63
|
+
|
64
|
+
# Temporarily turn off warnings. Intended for tests only.
|
65
|
+
def skip_during
|
66
|
+
original = Faraday::Deprecate.skip
|
67
|
+
Faraday::Deprecate.skip, = true
|
68
|
+
yield
|
69
|
+
ensure
|
70
|
+
Faraday::Deprecate.skip = original
|
71
|
+
end
|
72
|
+
|
73
|
+
# Simple deprecation method that deprecates +name+ by wrapping it up
|
74
|
+
# in a dummy method. It warns on each call to the dummy method
|
75
|
+
# telling the user of +repl+ (unless +repl+ is :none) and the
|
76
|
+
# semver that it is planned to go away.
|
77
|
+
# @param name [Symbol] the method symbol to deprecate
|
78
|
+
# @param repl [#to_s, :none] the replacement to use, when `:none` it will
|
79
|
+
# alert the user that no replacemtent is present.
|
80
|
+
# @param ver [String] the semver the method will be removed.
|
81
|
+
def deprecate(name, repl, ver)
|
82
|
+
class_eval do
|
83
|
+
gem_ver = Gem::Version.new(ver)
|
84
|
+
old = "_deprecated_#{name}"
|
85
|
+
alias_method old, name
|
86
|
+
define_method name do |*args, &block|
|
87
|
+
mod = is_a? Module
|
88
|
+
target = mod ? "#{self}." : "#{self.class}#"
|
89
|
+
target_message = if name == :inherited
|
90
|
+
"Inheriting #{self}"
|
91
|
+
else
|
92
|
+
"#{target}#{name}"
|
93
|
+
end
|
94
|
+
|
95
|
+
msg = [
|
96
|
+
"NOTE: #{target_message} is deprecated",
|
97
|
+
repl == :none ? ' with no replacement' : "; use #{repl} instead. ",
|
98
|
+
"It will be removed in or after version #{gem_ver}",
|
99
|
+
"\n#{target}#{name} called from #{Gem.location_of_caller.join(':')}"
|
100
|
+
]
|
101
|
+
warn "#{msg.join}." unless Faraday::Deprecate.skip
|
102
|
+
send old, *args, &block
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
module_function :deprecate, :skip_during
|
108
|
+
end
|
109
|
+
end
|
data/lib/faraday/error.rb
CHANGED
@@ -1,23 +1,17 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'faraday/deprecate'
|
4
|
+
|
5
|
+
# Faraday namespace.
|
3
6
|
module Faraday
|
4
7
|
# Faraday error base class.
|
5
8
|
class Error < StandardError
|
6
9
|
attr_reader :response, :wrapped_exception
|
7
10
|
|
8
11
|
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
|
12
|
+
@wrapped_exception = nil unless defined?(@wrapped_exception)
|
13
|
+
@response = nil unless defined?(@response)
|
14
|
+
super(exc_msg_and_response!(exc, response))
|
21
15
|
end
|
22
16
|
|
23
17
|
def backtrace
|
@@ -29,12 +23,44 @@ module Faraday
|
|
29
23
|
end
|
30
24
|
|
31
25
|
def inspect
|
32
|
-
inner =
|
33
|
-
inner
|
34
|
-
inner
|
35
|
-
inner
|
26
|
+
inner = ''
|
27
|
+
inner += " wrapped=#{@wrapped_exception.inspect}" if @wrapped_exception
|
28
|
+
inner += " response=#{@response.inspect}" if @response
|
29
|
+
inner += " #{super}" if inner.empty?
|
36
30
|
%(#<#{self.class}#{inner}>)
|
37
31
|
end
|
32
|
+
|
33
|
+
protected
|
34
|
+
|
35
|
+
# Pulls out potential parent exception and response hash, storing them in
|
36
|
+
# instance variables.
|
37
|
+
# exc - Either an Exception, a string message, or a response hash.
|
38
|
+
# response - Hash
|
39
|
+
# :status - Optional integer HTTP response status
|
40
|
+
# :headers - String key/value hash of HTTP response header
|
41
|
+
# values.
|
42
|
+
# :body - Optional string HTTP response body.
|
43
|
+
#
|
44
|
+
# If a subclass has to call this, then it should pass a string message
|
45
|
+
# to `super`. See NilStatusError.
|
46
|
+
def exc_msg_and_response!(exc, response = nil)
|
47
|
+
if @response.nil? && @wrapped_exception.nil?
|
48
|
+
@wrapped_exception, msg, @response = exc_msg_and_response(exc, response)
|
49
|
+
return msg
|
50
|
+
end
|
51
|
+
|
52
|
+
exc.to_s
|
53
|
+
end
|
54
|
+
|
55
|
+
# Pulls out potential parent exception and response hash.
|
56
|
+
def exc_msg_and_response(exc, response = nil)
|
57
|
+
return [exc, exc.message, response] if exc.respond_to?(:backtrace)
|
58
|
+
|
59
|
+
return [nil, "the server responded with status #{exc[:status]}", exc] \
|
60
|
+
if exc.respond_to?(:each_key)
|
61
|
+
|
62
|
+
[nil, exc.to_s, response]
|
63
|
+
end
|
38
64
|
end
|
39
65
|
|
40
66
|
# Faraday client error class. Represents 4xx status responses.
|
@@ -74,27 +100,59 @@ module Faraday
|
|
74
100
|
end
|
75
101
|
|
76
102
|
# A unified client error for timeouts.
|
77
|
-
class TimeoutError <
|
103
|
+
class TimeoutError < ClientError
|
78
104
|
def initialize(exc = 'timeout', response = nil)
|
79
105
|
super(exc, response)
|
80
106
|
end
|
81
107
|
end
|
82
108
|
|
109
|
+
# Raised by Faraday::Response::RaiseError in case of a nil status in response.
|
110
|
+
class NilStatusError < ServerError
|
111
|
+
def initialize(exc, response = nil)
|
112
|
+
exc_msg_and_response!(exc, response)
|
113
|
+
@response = unwrap_resp!(@response)
|
114
|
+
super('http status could not be derived from the server response')
|
115
|
+
end
|
116
|
+
|
117
|
+
private
|
118
|
+
|
119
|
+
extend Faraday::Deprecate
|
120
|
+
|
121
|
+
def unwrap_resp(resp)
|
122
|
+
if inner = (resp.keys.size == 1 && resp[:response])
|
123
|
+
return unwrap_resp(inner)
|
124
|
+
end
|
125
|
+
|
126
|
+
resp
|
127
|
+
end
|
128
|
+
|
129
|
+
alias_method :unwrap_resp!, :unwrap_resp
|
130
|
+
deprecate('unwrap_resp', nil, '1.0')
|
131
|
+
end
|
132
|
+
|
83
133
|
# A unified error for failed connections.
|
84
|
-
class ConnectionFailed <
|
134
|
+
class ConnectionFailed < ClientError
|
85
135
|
end
|
86
136
|
|
87
137
|
# A unified client error for SSL errors.
|
88
|
-
class SSLError <
|
138
|
+
class SSLError < ClientError
|
89
139
|
end
|
90
140
|
|
91
141
|
# Raised by FaradayMiddleware::ResponseMiddleware
|
92
|
-
class ParsingError <
|
142
|
+
class ParsingError < ClientError
|
93
143
|
end
|
94
144
|
|
95
145
|
# Exception used to control the Retry middleware.
|
96
146
|
#
|
97
147
|
# @see Faraday::Request::Retry
|
98
|
-
class RetriableResponse <
|
148
|
+
class RetriableResponse < ClientError
|
149
|
+
end
|
150
|
+
|
151
|
+
[:ClientError, :ConnectionFailed, :ResourceNotFound,
|
152
|
+
:ParsingError, :TimeoutError, :SSLError, :RetriableResponse].each do |const|
|
153
|
+
Error.const_set(
|
154
|
+
const,
|
155
|
+
DeprecatedClass.proxy_class(Faraday.const_get(const))
|
156
|
+
)
|
99
157
|
end
|
100
158
|
end
|
data/lib/faraday/middleware.rb
CHANGED
@@ -1,10 +1,34 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
module Faraday
|
4
|
-
# Middleware is the basic base class of any Faraday middleware.
|
5
2
|
class Middleware
|
6
3
|
extend MiddlewareRegistry
|
7
|
-
|
4
|
+
|
5
|
+
class << self
|
6
|
+
attr_accessor :load_error
|
7
|
+
private :load_error=
|
8
|
+
end
|
9
|
+
|
10
|
+
self.load_error = nil
|
11
|
+
|
12
|
+
# Executes a block which should try to require and reference dependent libraries
|
13
|
+
def self.dependency(lib = nil)
|
14
|
+
lib ? require(lib) : yield
|
15
|
+
rescue LoadError, NameError => error
|
16
|
+
self.load_error = error
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.new(*)
|
20
|
+
raise "missing dependency for #{self}: #{load_error.message}" unless loaded?
|
21
|
+
super
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.loaded?
|
25
|
+
load_error.nil?
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.inherited(subclass)
|
29
|
+
super
|
30
|
+
subclass.send(:load_error=, self.load_error)
|
31
|
+
end
|
8
32
|
|
9
33
|
def initialize(app = nil)
|
10
34
|
@app = app
|
data/lib/faraday/options.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
module Faraday
|
4
2
|
# Subclasses Struct with some special helpers for converting from a Hash to
|
5
3
|
# a Struct.
|
@@ -12,7 +10,6 @@ module Faraday
|
|
12
10
|
# Public
|
13
11
|
def each
|
14
12
|
return to_enum(:each) unless block_given?
|
15
|
-
|
16
13
|
members.each do |key|
|
17
14
|
yield(key.to_sym, send(key))
|
18
15
|
end
|
@@ -30,7 +27,7 @@ module Faraday
|
|
30
27
|
new_value = value
|
31
28
|
end
|
32
29
|
|
33
|
-
send("#{key}=", new_value) unless new_value.nil?
|
30
|
+
self.send("#{key}=", new_value) unless new_value.nil?
|
34
31
|
end
|
35
32
|
self
|
36
33
|
end
|
@@ -50,14 +47,10 @@ module Faraday
|
|
50
47
|
# Public
|
51
48
|
def merge!(other)
|
52
49
|
other.each do |key, other_value|
|
53
|
-
self_value = send(key)
|
50
|
+
self_value = self.send(key)
|
54
51
|
sub_options = self.class.options_for(key)
|
55
|
-
new_value =
|
56
|
-
|
57
|
-
else
|
58
|
-
other_value
|
59
|
-
end
|
60
|
-
send("#{key}=", new_value) unless new_value.nil?
|
52
|
+
new_value = (self_value && sub_options && other_value) ? self_value.merge(other_value) : other_value
|
53
|
+
self.send("#{key}=", new_value) unless new_value.nil?
|
61
54
|
end
|
62
55
|
self
|
63
56
|
end
|
@@ -76,7 +69,7 @@ module Faraday
|
|
76
69
|
def fetch(key, *args)
|
77
70
|
unless symbolized_key_set.include?(key.to_sym)
|
78
71
|
key_setter = "#{key}="
|
79
|
-
if
|
72
|
+
if args.size > 0
|
80
73
|
send(key_setter, args.first)
|
81
74
|
elsif block_given?
|
82
75
|
send(key_setter, yield(key))
|
@@ -105,7 +98,6 @@ module Faraday
|
|
105
98
|
# Public
|
106
99
|
def each_key
|
107
100
|
return to_enum(:each_key) unless block_given?
|
108
|
-
|
109
101
|
keys.each do |key|
|
110
102
|
yield(key)
|
111
103
|
end
|
@@ -121,7 +113,6 @@ module Faraday
|
|
121
113
|
# Public
|
122
114
|
def each_value
|
123
115
|
return to_enum(:each_value) unless block_given?
|
124
|
-
|
125
116
|
values.each do |value|
|
126
117
|
yield(value)
|
127
118
|
end
|
@@ -151,9 +142,9 @@ module Faraday
|
|
151
142
|
value = send(member)
|
152
143
|
values << "#{member}=#{value.inspect}" if value
|
153
144
|
end
|
154
|
-
values = values.empty? ? '(empty)' : values.join(
|
145
|
+
values = values.empty? ? ' (empty)' : (' ' << values.join(", "))
|
155
146
|
|
156
|
-
%(#<#{self.class}
|
147
|
+
%(#<#{self.class}#{values}>)
|
157
148
|
end
|
158
149
|
|
159
150
|
# Internal
|
@@ -172,10 +163,6 @@ module Faraday
|
|
172
163
|
end
|
173
164
|
|
174
165
|
def self.memoized(key, &block)
|
175
|
-
unless block_given?
|
176
|
-
raise ArgumentError, '#memoized must be called with a block'
|
177
|
-
end
|
178
|
-
|
179
166
|
memoized_attributes[key.to_sym] = block
|
180
167
|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
181
168
|
def #{key}() self[:#{key}]; end
|
@@ -188,7 +175,7 @@ module Faraday
|
|
188
175
|
|
189
176
|
def [](key)
|
190
177
|
key = key.to_sym
|
191
|
-
if
|
178
|
+
if method = self.class.memoized_attributes[key]
|
192
179
|
super(key) || (self[key] = instance_eval(&method))
|
193
180
|
else
|
194
181
|
super
|
@@ -196,7 +183,7 @@ module Faraday
|
|
196
183
|
end
|
197
184
|
|
198
185
|
def symbolized_key_set
|
199
|
-
@symbolized_key_set ||= Set.new(keys.map
|
186
|
+
@symbolized_key_set ||= Set.new(keys.map { |k| k.to_sym })
|
200
187
|
end
|
201
188
|
|
202
189
|
def self.inherited(subclass)
|
@@ -207,16 +194,180 @@ module Faraday
|
|
207
194
|
|
208
195
|
def self.fetch_error_class
|
209
196
|
@fetch_error_class ||= if Object.const_defined?(:KeyError)
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
197
|
+
::KeyError
|
198
|
+
else
|
199
|
+
::IndexError
|
200
|
+
end
|
214
201
|
end
|
215
202
|
end
|
216
|
-
end
|
217
203
|
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
204
|
+
class RequestOptions < Options.new(:params_encoder, :proxy, :bind,
|
205
|
+
:timeout, :open_timeout, :write_timeout, :boundary, :oauth, :context)
|
206
|
+
|
207
|
+
def []=(key, value)
|
208
|
+
if key && key.to_sym == :proxy
|
209
|
+
super(key, value ? ProxyOptions.from(value) : nil)
|
210
|
+
else
|
211
|
+
super(key, value)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
class SSLOptions < Options.new(:verify, :ca_file, :ca_path, :verify_mode,
|
217
|
+
:cert_store, :client_cert, :client_key, :certificate, :private_key, :verify_depth,
|
218
|
+
:version, :min_version, :max_version)
|
219
|
+
|
220
|
+
def verify?
|
221
|
+
verify != false
|
222
|
+
end
|
223
|
+
|
224
|
+
def disable?
|
225
|
+
!verify?
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
class ProxyOptions < Options.new(:uri, :user, :password)
|
230
|
+
extend Forwardable
|
231
|
+
def_delegators :uri, :scheme, :scheme=, :host, :host=, :port, :port=, :path, :path=
|
232
|
+
|
233
|
+
def self.from(value)
|
234
|
+
case value
|
235
|
+
when String
|
236
|
+
value = {:uri => Utils.URI(value)}
|
237
|
+
when URI
|
238
|
+
value = {:uri => value}
|
239
|
+
when Hash, Options
|
240
|
+
if uri = value.delete(:uri)
|
241
|
+
value[:uri] = Utils.URI(uri)
|
242
|
+
end
|
243
|
+
end
|
244
|
+
super(value)
|
245
|
+
end
|
246
|
+
|
247
|
+
memoized(:user) { uri && uri.user && Utils.unescape(uri.user) }
|
248
|
+
memoized(:password) { uri && uri.password && Utils.unescape(uri.password) }
|
249
|
+
end
|
250
|
+
|
251
|
+
class ConnectionOptions < Options.new(:request, :proxy, :ssl, :builder, :url,
|
252
|
+
:parallel_manager, :params, :headers, :builder_class)
|
253
|
+
|
254
|
+
options :request => RequestOptions, :ssl => SSLOptions
|
255
|
+
|
256
|
+
memoized(:request) { self.class.options_for(:request).new }
|
257
|
+
|
258
|
+
memoized(:ssl) { self.class.options_for(:ssl).new }
|
259
|
+
|
260
|
+
memoized(:builder_class) { RackBuilder }
|
261
|
+
|
262
|
+
def new_builder(block)
|
263
|
+
builder_class.new(&block)
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
class Env < Options.new(:method, :body, :url, :request, :request_headers,
|
268
|
+
:ssl, :parallel_manager, :params, :response, :response_headers, :status,
|
269
|
+
:reason_phrase)
|
270
|
+
|
271
|
+
ContentLength = 'Content-Length'.freeze
|
272
|
+
StatusesWithoutBody = Set.new [204, 304]
|
273
|
+
SuccessfulStatuses = 200..299
|
274
|
+
|
275
|
+
# A Set of HTTP verbs that typically send a body. If no body is set for
|
276
|
+
# these requests, the Content-Length header is set to 0.
|
277
|
+
MethodsWithBodies = Set.new [:post, :put, :patch, :options]
|
278
|
+
|
279
|
+
options :request => RequestOptions,
|
280
|
+
:request_headers => Utils::Headers, :response_headers => Utils::Headers
|
281
|
+
|
282
|
+
extend Forwardable
|
283
|
+
|
284
|
+
def_delegators :request, :params_encoder
|
285
|
+
|
286
|
+
# Public
|
287
|
+
def self.from(value)
|
288
|
+
env = super(value)
|
289
|
+
if value.respond_to?(:custom_members)
|
290
|
+
env.custom_members.update(value.custom_members)
|
291
|
+
end
|
292
|
+
env
|
293
|
+
end
|
294
|
+
|
295
|
+
# Public
|
296
|
+
def [](key)
|
297
|
+
if in_member_set?(key)
|
298
|
+
super(key)
|
299
|
+
else
|
300
|
+
custom_members[key]
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
# Public
|
305
|
+
def []=(key, value)
|
306
|
+
if in_member_set?(key)
|
307
|
+
super(key, value)
|
308
|
+
else
|
309
|
+
custom_members[key] = value
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
# Public
|
314
|
+
def success?
|
315
|
+
SuccessfulStatuses.include?(status)
|
316
|
+
end
|
317
|
+
|
318
|
+
# Public
|
319
|
+
def needs_body?
|
320
|
+
!body && MethodsWithBodies.include?(method)
|
321
|
+
end
|
322
|
+
|
323
|
+
# Public
|
324
|
+
def clear_body
|
325
|
+
request_headers[ContentLength] = '0'
|
326
|
+
self.body = ''
|
327
|
+
end
|
328
|
+
|
329
|
+
# Public
|
330
|
+
def parse_body?
|
331
|
+
!StatusesWithoutBody.include?(status)
|
332
|
+
end
|
333
|
+
|
334
|
+
# Public
|
335
|
+
def parallel?
|
336
|
+
!!parallel_manager
|
337
|
+
end
|
338
|
+
|
339
|
+
def inspect
|
340
|
+
attrs = [nil]
|
341
|
+
members.each do |mem|
|
342
|
+
if value = send(mem)
|
343
|
+
attrs << "@#{mem}=#{value.inspect}"
|
344
|
+
end
|
345
|
+
end
|
346
|
+
if !custom_members.empty?
|
347
|
+
attrs << "@custom=#{custom_members.inspect}"
|
348
|
+
end
|
349
|
+
%(#<#{self.class}#{attrs.join(" ")}>)
|
350
|
+
end
|
351
|
+
|
352
|
+
# Internal
|
353
|
+
def custom_members
|
354
|
+
@custom_members ||= {}
|
355
|
+
end
|
356
|
+
|
357
|
+
# Internal
|
358
|
+
if members.first.is_a?(Symbol)
|
359
|
+
def in_member_set?(key)
|
360
|
+
self.class.member_set.include?(key.to_sym)
|
361
|
+
end
|
362
|
+
else
|
363
|
+
def in_member_set?(key)
|
364
|
+
self.class.member_set.include?(key.to_s)
|
365
|
+
end
|
366
|
+
end
|
367
|
+
|
368
|
+
# Internal
|
369
|
+
def self.member_set
|
370
|
+
@member_set ||= Set.new(members)
|
371
|
+
end
|
372
|
+
end
|
373
|
+
end
|