faraday 0.16.1 → 0.17.4
Sign up to get free protection for your applications and to get access to all the features.
- 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.rb +174 -93
- data/lib/faraday/adapter.rb +22 -36
- 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.rb +60 -104
- data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +15 -18
- 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/autoload.rb +36 -47
- data/lib/faraday/connection.rb +179 -321
- data/lib/faraday/deprecate.rb +109 -0
- data/lib/faraday/error.rb +72 -28
- 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.rb +36 -68
- 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/response.rb +13 -20
- data/lib/faraday/response/logger.rb +69 -22
- data/lib/faraday/response/raise_error.rb +18 -36
- data/lib/faraday/upload_io.rb +67 -0
- data/lib/faraday/utils.rb +245 -28
- 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 -26
- data/lib/faraday/adapter_registry.rb +0 -28
- data/lib/faraday/dependency_loader.rb +0 -37
- data/lib/faraday/deprecated_constant.rb +0 -53
- 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,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'faraday/
|
3
|
+
require 'faraday/deprecate'
|
4
4
|
|
5
5
|
# Faraday namespace.
|
6
6
|
module Faraday
|
@@ -9,18 +9,9 @@ module Faraday
|
|
9
9
|
attr_reader :response, :wrapped_exception
|
10
10
|
|
11
11
|
def initialize(exc, response = nil)
|
12
|
-
@wrapped_exception = nil
|
13
|
-
@response = response
|
14
|
-
|
15
|
-
if exc.respond_to?(:backtrace)
|
16
|
-
super(exc.message)
|
17
|
-
@wrapped_exception = exc
|
18
|
-
elsif exc.respond_to?(:each_key)
|
19
|
-
super("the server responded with status #{exc[:status]}")
|
20
|
-
@response = exc
|
21
|
-
else
|
22
|
-
super(exc.to_s)
|
23
|
-
end
|
12
|
+
@wrapped_exception = nil unless defined?(@wrapped_exception)
|
13
|
+
@response = nil unless defined?(@response)
|
14
|
+
super(exc_msg_and_response!(exc, response))
|
24
15
|
end
|
25
16
|
|
26
17
|
def backtrace
|
@@ -32,12 +23,44 @@ module Faraday
|
|
32
23
|
end
|
33
24
|
|
34
25
|
def inspect
|
35
|
-
inner =
|
36
|
-
inner
|
37
|
-
inner
|
38
|
-
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?
|
39
30
|
%(#<#{self.class}#{inner}>)
|
40
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
|
41
64
|
end
|
42
65
|
|
43
66
|
# Faraday client error class. Represents 4xx status responses.
|
@@ -77,38 +100,59 @@ module Faraday
|
|
77
100
|
end
|
78
101
|
|
79
102
|
# A unified client error for timeouts.
|
80
|
-
class TimeoutError <
|
103
|
+
class TimeoutError < ClientError
|
81
104
|
def initialize(exc = 'timeout', response = nil)
|
82
105
|
super(exc, response)
|
83
106
|
end
|
84
107
|
end
|
85
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
|
+
|
86
133
|
# A unified error for failed connections.
|
87
|
-
class ConnectionFailed <
|
134
|
+
class ConnectionFailed < ClientError
|
88
135
|
end
|
89
136
|
|
90
137
|
# A unified client error for SSL errors.
|
91
|
-
class SSLError <
|
138
|
+
class SSLError < ClientError
|
92
139
|
end
|
93
140
|
|
94
141
|
# Raised by FaradayMiddleware::ResponseMiddleware
|
95
|
-
class ParsingError <
|
142
|
+
class ParsingError < ClientError
|
96
143
|
end
|
97
144
|
|
98
145
|
# Exception used to control the Retry middleware.
|
99
146
|
#
|
100
147
|
# @see Faraday::Request::Retry
|
101
|
-
class RetriableResponse <
|
148
|
+
class RetriableResponse < ClientError
|
102
149
|
end
|
103
150
|
|
104
|
-
|
105
|
-
|
151
|
+
[:ClientError, :ConnectionFailed, :ResourceNotFound,
|
152
|
+
:ParsingError, :TimeoutError, :SSLError, :RetriableResponse].each do |const|
|
106
153
|
Error.const_set(
|
107
154
|
const,
|
108
|
-
Faraday
|
109
|
-
"Faraday::Error::#{const}",
|
110
|
-
Faraday.const_get(const)
|
111
|
-
)
|
155
|
+
DeprecatedClass.proxy_class(Faraday.const_get(const))
|
112
156
|
)
|
113
157
|
end
|
114
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
|