excon 0.62.0 → 0.85.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 +5 -5
- data/LICENSE.md +1 -1
- data/README.md +6 -5
- data/data/cacert.pem +939 -1720
- data/excon.gemspec +17 -2
- data/lib/excon.rb +25 -17
- data/lib/excon/connection.rb +206 -139
- data/lib/excon/constants.rb +38 -13
- data/lib/excon/error.rb +15 -0
- data/lib/excon/headers.rb +4 -3
- data/lib/excon/instrumentors/logging_instrumentor.rb +4 -15
- data/lib/excon/instrumentors/standard_instrumentor.rb +2 -9
- data/lib/excon/middlewares/base.rb +6 -0
- data/lib/excon/middlewares/capture_cookies.rb +1 -1
- data/lib/excon/middlewares/decompress.rb +2 -2
- data/lib/excon/middlewares/expects.rb +7 -1
- data/lib/excon/middlewares/idempotent.rb +20 -3
- data/lib/excon/middlewares/instrumentor.rb +8 -0
- data/lib/excon/middlewares/mock.rb +12 -3
- data/lib/excon/middlewares/redirect_follower.rb +25 -3
- data/lib/excon/middlewares/response_parser.rb +3 -0
- data/lib/excon/pretty_printer.rb +1 -8
- data/lib/excon/response.rb +12 -9
- data/lib/excon/socket.rb +51 -33
- data/lib/excon/ssl_socket.rb +33 -13
- data/lib/excon/test/plugin/server/exec.rb +2 -2
- data/lib/excon/test/server.rb +1 -1
- data/lib/excon/unix_socket.rb +1 -0
- data/lib/excon/utils.rb +58 -5
- data/lib/excon/version.rb +1 -1
- metadata +27 -98
- data/.document +0 -5
- data/.gitignore +0 -13
- data/.rspec +0 -3
- data/.travis.yml +0 -29
- data/Gemfile +0 -19
- data/Rakefile +0 -41
- data/benchmarks/class_vs_lambda.rb +0 -50
- data/benchmarks/concat_vs_insert.rb +0 -21
- data/benchmarks/concat_vs_interpolate.rb +0 -22
- data/benchmarks/cr_lf.rb +0 -21
- data/benchmarks/downcase-eq-eq_vs_casecmp.rb +0 -169
- data/benchmarks/excon.rb +0 -69
- data/benchmarks/excon_vs.rb +0 -165
- data/benchmarks/for_vs_array_each.rb +0 -27
- data/benchmarks/for_vs_hash_each.rb +0 -27
- data/benchmarks/has_key-vs-lookup.rb +0 -177
- data/benchmarks/headers_case_sensitivity.rb +0 -83
- data/benchmarks/headers_split_vs_match.rb +0 -34
- data/benchmarks/implicit_block-vs-explicit_block.rb +0 -98
- data/benchmarks/merging.rb +0 -21
- data/benchmarks/single_vs_double_quotes.rb +0 -21
- data/benchmarks/string_ranged_index.rb +0 -87
- data/benchmarks/strip_newline.rb +0 -115
- data/benchmarks/vs_stdlib.rb +0 -82
- data/changelog.txt +0 -1083
- data/spec/excon/error_spec.rb +0 -139
- data/spec/excon/test/server_spec.rb +0 -28
- data/spec/excon_spec.rb +0 -7
- data/spec/helpers/file_path_helpers.rb +0 -22
- data/spec/requests/basic_spec.rb +0 -40
- data/spec/requests/eof_requests_spec.rb +0 -36
- data/spec/requests/unix_socket_spec.rb +0 -46
- data/spec/spec_helper.rb +0 -24
- data/spec/support/shared_contexts/test_server_context.rb +0 -83
- data/spec/support/shared_examples/shared_example_for_clients.rb +0 -218
- data/spec/support/shared_examples/shared_example_for_streaming_clients.rb +0 -20
- data/spec/support/shared_examples/shared_example_for_test_servers.rb +0 -16
- data/tests/authorization_header_tests.rb +0 -29
- data/tests/bad_tests.rb +0 -47
- data/tests/basic_tests.rb +0 -351
- data/tests/batch_requests.rb +0 -133
- data/tests/complete_responses.rb +0 -31
- data/tests/data/127.0.0.1.cert.crt +0 -20
- data/tests/data/127.0.0.1.cert.key +0 -27
- data/tests/data/excon.cert.crt +0 -20
- data/tests/data/excon.cert.key +0 -27
- data/tests/data/xs +0 -1
- data/tests/error_tests.rb +0 -145
- data/tests/header_tests.rb +0 -119
- data/tests/middlewares/canned_response_tests.rb +0 -34
- data/tests/middlewares/capture_cookies_tests.rb +0 -34
- data/tests/middlewares/decompress_tests.rb +0 -157
- data/tests/middlewares/escape_path_tests.rb +0 -36
- data/tests/middlewares/idempotent_tests.rb +0 -206
- data/tests/middlewares/instrumentation_tests.rb +0 -315
- data/tests/middlewares/mock_tests.rb +0 -304
- data/tests/middlewares/redirect_follower_tests.rb +0 -112
- data/tests/pipeline_tests.rb +0 -40
- data/tests/proxy_tests.rb +0 -306
- data/tests/query_string_tests.rb +0 -87
- data/tests/rackups/basic.rb +0 -41
- data/tests/rackups/basic.ru +0 -3
- data/tests/rackups/basic_auth.ru +0 -14
- data/tests/rackups/deflater.ru +0 -4
- data/tests/rackups/proxy.ru +0 -18
- data/tests/rackups/query_string.ru +0 -13
- data/tests/rackups/redirecting.ru +0 -23
- data/tests/rackups/redirecting_with_cookie.ru +0 -40
- data/tests/rackups/request_headers.ru +0 -15
- data/tests/rackups/request_methods.ru +0 -21
- data/tests/rackups/response_header.ru +0 -18
- data/tests/rackups/ssl.ru +0 -16
- data/tests/rackups/ssl_mismatched_cn.ru +0 -15
- data/tests/rackups/ssl_verify_peer.ru +0 -16
- data/tests/rackups/streaming.ru +0 -30
- data/tests/rackups/thread_safety.ru +0 -17
- data/tests/rackups/timeout.ru +0 -14
- data/tests/rackups/webrick_patch.rb +0 -34
- data/tests/request_headers_tests.rb +0 -21
- data/tests/request_method_tests.rb +0 -47
- data/tests/request_tests.rb +0 -59
- data/tests/response_tests.rb +0 -197
- data/tests/servers/bad.rb +0 -20
- data/tests/servers/eof.rb +0 -17
- data/tests/servers/error.rb +0 -20
- data/tests/servers/good.rb +0 -350
- data/tests/test_helper.rb +0 -306
- data/tests/thread_safety_tests.rb +0 -39
- data/tests/timeout_tests.rb +0 -12
- data/tests/utils_tests.rb +0 -81
data/lib/excon/constants.rb
CHANGED
|
@@ -12,8 +12,16 @@ module Excon
|
|
|
12
12
|
CHUNK_SIZE = DEFAULT_CHUNK_SIZE
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
+
DEFAULT_REDIRECT_LIMIT = 10
|
|
16
|
+
|
|
15
17
|
DEFAULT_RETRY_LIMIT = 4
|
|
16
18
|
|
|
19
|
+
DEFAULT_RETRY_ERRORS = [
|
|
20
|
+
Excon::Error::Timeout,
|
|
21
|
+
Excon::Error::Socket,
|
|
22
|
+
Excon::Error::HTTPStatus
|
|
23
|
+
]
|
|
24
|
+
|
|
17
25
|
FORCE_ENC = CR_NL.respond_to?(:force_encoding)
|
|
18
26
|
|
|
19
27
|
HTTP_1_1 = " HTTP/1.1\r\n"
|
|
@@ -33,19 +41,17 @@ module Excon
|
|
|
33
41
|
VERSIONS = "#{USER_AGENT} (#{RUBY_PLATFORM}) ruby/#{RUBY_VERSION}"
|
|
34
42
|
|
|
35
43
|
VALID_REQUEST_KEYS = [
|
|
44
|
+
:allow_unstubbed_requests,
|
|
36
45
|
:body,
|
|
37
|
-
:captures,
|
|
38
46
|
:chunk_size,
|
|
39
47
|
:debug_request,
|
|
40
48
|
:debug_response,
|
|
41
|
-
:expects,
|
|
42
49
|
:headers,
|
|
43
|
-
:
|
|
44
|
-
:
|
|
45
|
-
:instrumentor_name,
|
|
50
|
+
:instrumentor, # Used for setting logging within Connection
|
|
51
|
+
:logger,
|
|
46
52
|
:method,
|
|
47
53
|
:middlewares,
|
|
48
|
-
:
|
|
54
|
+
:password,
|
|
49
55
|
:path,
|
|
50
56
|
:persistent,
|
|
51
57
|
:pipeline,
|
|
@@ -53,9 +59,8 @@ module Excon
|
|
|
53
59
|
:read_timeout,
|
|
54
60
|
:request_block,
|
|
55
61
|
:response_block,
|
|
56
|
-
:
|
|
57
|
-
:
|
|
58
|
-
:retry_interval,
|
|
62
|
+
:stubs,
|
|
63
|
+
:user,
|
|
59
64
|
:versions,
|
|
60
65
|
:write_timeout
|
|
61
66
|
]
|
|
@@ -74,12 +79,12 @@ module Excon
|
|
|
74
79
|
:private_key_path,
|
|
75
80
|
:connect_timeout,
|
|
76
81
|
:family,
|
|
82
|
+
:keepalive,
|
|
77
83
|
:host,
|
|
78
84
|
:hostname,
|
|
79
85
|
:omit_default_port,
|
|
80
86
|
:nonblock,
|
|
81
87
|
:reuseaddr,
|
|
82
|
-
:password,
|
|
83
88
|
:port,
|
|
84
89
|
:proxy,
|
|
85
90
|
:scheme,
|
|
@@ -90,13 +95,30 @@ module Excon
|
|
|
90
95
|
:ssl_verify_callback,
|
|
91
96
|
:ssl_verify_peer,
|
|
92
97
|
:ssl_verify_peer_host,
|
|
98
|
+
:ssl_verify_hostname,
|
|
93
99
|
:ssl_version,
|
|
100
|
+
:ssl_min_version,
|
|
101
|
+
:ssl_max_version,
|
|
102
|
+
:ssl_security_level,
|
|
103
|
+
:ssl_proxy_headers,
|
|
104
|
+
:ssl_uri_schemes,
|
|
94
105
|
:tcp_nodelay,
|
|
95
106
|
:thread_safe_sockets,
|
|
96
107
|
:uri_parser,
|
|
97
|
-
:user
|
|
98
108
|
]
|
|
99
109
|
|
|
110
|
+
DEPRECATED_VALID_REQUEST_KEYS = {
|
|
111
|
+
:captures => 'Mock',
|
|
112
|
+
:expects => 'Expects',
|
|
113
|
+
:idempotent => 'Idempotent',
|
|
114
|
+
:instrumentor_name => 'Instrumentor',
|
|
115
|
+
:mock => 'Mock',
|
|
116
|
+
:retries_remaining => 'Idempotent', # referenced in Instrumentor, but only relevant with Idempotent
|
|
117
|
+
:retry_errors => 'Idempotent',
|
|
118
|
+
:retry_interval => 'Idempotent',
|
|
119
|
+
:retry_limit => 'Idempotent' # referenced in Instrumentor, but only relevant with Idempotent
|
|
120
|
+
}
|
|
121
|
+
|
|
100
122
|
unless ::IO.const_defined?(:WaitReadable)
|
|
101
123
|
class ::IO
|
|
102
124
|
module WaitReadable; end
|
|
@@ -112,12 +134,14 @@ module Excon
|
|
|
112
134
|
DEFAULTS = {
|
|
113
135
|
:chunk_size => CHUNK_SIZE || DEFAULT_CHUNK_SIZE,
|
|
114
136
|
# see https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28default.29
|
|
115
|
-
|
|
137
|
+
# list provided then had DES related things sorted to the end
|
|
138
|
+
:ciphers => 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:DES-CBC3-SHA:!DSS',
|
|
116
139
|
:connect_timeout => 60,
|
|
117
140
|
:debug_request => false,
|
|
118
141
|
:debug_response => false,
|
|
119
142
|
:headers => {
|
|
120
|
-
'User-Agent' => USER_AGENT
|
|
143
|
+
'User-Agent' => USER_AGENT,
|
|
144
|
+
'Accept' => '*/*'
|
|
121
145
|
},
|
|
122
146
|
:idempotent => false,
|
|
123
147
|
:instrumentor_name => 'excon',
|
|
@@ -133,6 +157,7 @@ module Excon
|
|
|
133
157
|
:omit_default_port => false,
|
|
134
158
|
:persistent => false,
|
|
135
159
|
:read_timeout => 60,
|
|
160
|
+
:retry_errors => DEFAULT_RETRY_ERRORS,
|
|
136
161
|
:retry_limit => DEFAULT_RETRY_LIMIT,
|
|
137
162
|
:ssl_verify_peer => true,
|
|
138
163
|
:ssl_uri_schemes => [HTTPS],
|
data/lib/excon/error.rb
CHANGED
|
@@ -6,6 +6,7 @@ module Excon
|
|
|
6
6
|
|
|
7
7
|
class StubNotFound < Error; end
|
|
8
8
|
class InvalidStub < Error; end
|
|
9
|
+
class Warning < Error; end
|
|
9
10
|
|
|
10
11
|
# Socket related errors
|
|
11
12
|
class Socket < Error
|
|
@@ -45,9 +46,23 @@ or:
|
|
|
45
46
|
end
|
|
46
47
|
end
|
|
47
48
|
|
|
49
|
+
class InvalidHeaderKey < Error; end
|
|
50
|
+
class InvalidHeaderValue < Error; end
|
|
48
51
|
class Timeout < Error; end
|
|
49
52
|
class ResponseParse < Error; end
|
|
53
|
+
|
|
54
|
+
class ProxyConnectionError < Error
|
|
55
|
+
attr_reader :request, :response
|
|
56
|
+
|
|
57
|
+
def initialize(msg, request = nil, response = nil)
|
|
58
|
+
super(msg)
|
|
59
|
+
@request = request
|
|
60
|
+
@response = response
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
50
64
|
class ProxyParse < Error; end
|
|
65
|
+
class TooManyRedirects < Error; end
|
|
51
66
|
|
|
52
67
|
# Base class for HTTP Error classes
|
|
53
68
|
class HTTPStatus < Error
|
data/lib/excon/headers.rb
CHANGED
|
@@ -22,6 +22,7 @@ module Excon
|
|
|
22
22
|
alias_method :raw_values_at, :values_at
|
|
23
23
|
|
|
24
24
|
def initialize
|
|
25
|
+
super
|
|
25
26
|
@downcased = {}
|
|
26
27
|
end
|
|
27
28
|
|
|
@@ -29,11 +30,11 @@ module Excon
|
|
|
29
30
|
@downcased[key.to_s.downcase]
|
|
30
31
|
end
|
|
31
32
|
|
|
32
|
-
alias_method :[]=, :store
|
|
33
33
|
def []=(key, value)
|
|
34
34
|
raw_writer(key, value)
|
|
35
35
|
@downcased[key.to_s.downcase] = value
|
|
36
36
|
end
|
|
37
|
+
alias_method :store, :[]=
|
|
37
38
|
|
|
38
39
|
if SENTINEL.respond_to? :assoc
|
|
39
40
|
def assoc(obj)
|
|
@@ -54,11 +55,11 @@ module Excon
|
|
|
54
55
|
end
|
|
55
56
|
end
|
|
56
57
|
|
|
57
|
-
alias_method :has_key?, :key?
|
|
58
|
-
alias_method :has_key?, :member?
|
|
59
58
|
def has_key?(key)
|
|
60
59
|
raw_key?(key) || @downcased.has_key?(key.to_s.downcase)
|
|
61
60
|
end
|
|
61
|
+
alias_method :key?, :has_key?
|
|
62
|
+
alias_method :member?, :has_key?
|
|
62
63
|
|
|
63
64
|
def merge(other_hash)
|
|
64
65
|
self.dup.merge!(other_hash)
|
|
@@ -2,23 +2,12 @@ require 'logger'
|
|
|
2
2
|
|
|
3
3
|
module Excon
|
|
4
4
|
class LoggingInstrumentor
|
|
5
|
-
# Returns the Logger object for the LoggingInstrumentor. If one doesn't
|
|
6
|
-
# already exist, then one will be created using $stderr as the output
|
|
7
|
-
# stream.
|
|
8
|
-
#
|
|
9
|
-
def self.logger
|
|
10
|
-
@logger ||= Logger.new($stderr)
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
# Sets the logger object for the LoggingInstrumentor.
|
|
14
|
-
#
|
|
15
|
-
def self.logger=(logger)
|
|
16
|
-
@logger = logger
|
|
17
|
-
end
|
|
18
5
|
|
|
19
|
-
def self.instrument(name, params = {}
|
|
6
|
+
def self.instrument(name, params = {})
|
|
20
7
|
params = params.dup
|
|
21
8
|
|
|
9
|
+
logger = params[:logger] || Logger.new($stderr)
|
|
10
|
+
|
|
22
11
|
# reduce duplication/noise of output
|
|
23
12
|
params.delete(:connection)
|
|
24
13
|
params.delete(:stack)
|
|
@@ -51,7 +40,7 @@ module Excon
|
|
|
51
40
|
end
|
|
52
41
|
end
|
|
53
42
|
|
|
54
|
-
|
|
43
|
+
logger.info(info) if info
|
|
55
44
|
|
|
56
45
|
yield if block_given?
|
|
57
46
|
end
|
|
@@ -1,21 +1,14 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
module Excon
|
|
3
3
|
class StandardInstrumentor
|
|
4
|
-
def self.instrument(name, params = {}
|
|
4
|
+
def self.instrument(name, params = {})
|
|
5
5
|
params = params.dup
|
|
6
6
|
|
|
7
7
|
# reduce duplication/noise of output
|
|
8
8
|
params.delete(:connection)
|
|
9
9
|
params.delete(:stack)
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
params[:headers] = params[:headers].dup
|
|
13
|
-
params[:headers]['Authorization'] = REDACTED
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
if params.has_key?(:password)
|
|
17
|
-
params[:password] = REDACTED
|
|
18
|
-
end
|
|
11
|
+
params = Utils.redact(params)
|
|
19
12
|
|
|
20
13
|
$stderr.puts(name)
|
|
21
14
|
Excon::PrettyPrinter.pp($stderr, params)
|
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
module Excon
|
|
3
3
|
module Middleware
|
|
4
4
|
class Base
|
|
5
|
+
# Returns the list of parameters that this middleware uses that are valid
|
|
6
|
+
# as arguments to `Connection#request` or `Connection#new`.
|
|
7
|
+
def self.valid_parameter_keys
|
|
8
|
+
[]
|
|
9
|
+
end
|
|
10
|
+
|
|
5
11
|
def initialize(stack)
|
|
6
12
|
@stack = stack
|
|
7
13
|
end
|
|
@@ -15,9 +15,9 @@ module Excon
|
|
|
15
15
|
def response_call(datum)
|
|
16
16
|
body = datum[:response][:body]
|
|
17
17
|
unless datum.has_key?(:response_block) || body.nil? || body.empty?
|
|
18
|
-
if key = datum[:response][:headers].keys.detect {|k| k.casecmp('Content-Encoding') == 0 }
|
|
18
|
+
if (key = datum[:response][:headers].keys.detect {|k| k.casecmp('Content-Encoding') == 0 })
|
|
19
19
|
encodings = Utils.split_header_value(datum[:response][:headers][key])
|
|
20
|
-
if encoding = encodings.last
|
|
20
|
+
if (encoding = encodings.last)
|
|
21
21
|
if encoding.casecmp('deflate') == 0
|
|
22
22
|
# assume inflate omits header
|
|
23
23
|
datum[:response][:body] = Zlib::Inflate.new(-Zlib::MAX_WBITS).inflate(body)
|
|
@@ -2,11 +2,17 @@
|
|
|
2
2
|
module Excon
|
|
3
3
|
module Middleware
|
|
4
4
|
class Expects < Excon::Middleware::Base
|
|
5
|
+
def self.valid_parameter_keys
|
|
6
|
+
[
|
|
7
|
+
:expects
|
|
8
|
+
]
|
|
9
|
+
end
|
|
10
|
+
|
|
5
11
|
def response_call(datum)
|
|
6
12
|
if datum.has_key?(:expects) && ![*datum[:expects]].include?(datum[:response][:status])
|
|
7
13
|
raise(
|
|
8
14
|
Excon::Errors.status_error(
|
|
9
|
-
datum.reject {|key,
|
|
15
|
+
datum.reject {|key,_| key == :response},
|
|
10
16
|
Excon::Response.new(datum[:response])
|
|
11
17
|
)
|
|
12
18
|
)
|
|
@@ -1,7 +1,24 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
require 'set'
|
|
3
|
+
|
|
2
4
|
module Excon
|
|
3
5
|
module Middleware
|
|
4
6
|
class Idempotent < Excon::Middleware::Base
|
|
7
|
+
def self.valid_parameter_keys
|
|
8
|
+
[
|
|
9
|
+
:idempotent,
|
|
10
|
+
:retries_remaining,
|
|
11
|
+
:retry_errors,
|
|
12
|
+
:retry_interval,
|
|
13
|
+
:retry_limit
|
|
14
|
+
]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def request_call(datum)
|
|
18
|
+
datum[:retries_remaining] ||= datum[:retry_limit]
|
|
19
|
+
@stack.request_call(datum)
|
|
20
|
+
end
|
|
21
|
+
|
|
5
22
|
def error_call(datum)
|
|
6
23
|
if datum[:idempotent]
|
|
7
24
|
if datum.has_key?(:request_block)
|
|
@@ -21,15 +38,15 @@ module Excon
|
|
|
21
38
|
end
|
|
22
39
|
end
|
|
23
40
|
|
|
24
|
-
if datum[:idempotent] && [
|
|
25
|
-
Excon::Errors::HTTPStatusError].any? {|ex| datum[:error].kind_of?(ex) } && datum[:retries_remaining] > 1
|
|
41
|
+
if datum[:idempotent] && datum[:retry_errors].any? {|ex| datum[:error].kind_of?(ex) } && datum[:retries_remaining] > 1
|
|
26
42
|
|
|
27
43
|
sleep(datum[:retry_interval]) if datum[:retry_interval]
|
|
28
44
|
|
|
29
45
|
# reduces remaining retries, reset connection, and restart request_call
|
|
30
46
|
datum[:retries_remaining] -= 1
|
|
31
47
|
connection = datum.delete(:connection)
|
|
32
|
-
|
|
48
|
+
valid_keys = Set.new(connection.valid_request_keys(datum[:middlewares]))
|
|
49
|
+
datum.select! {|key, _| valid_keys.include?(key) }
|
|
33
50
|
connection.request(datum)
|
|
34
51
|
else
|
|
35
52
|
@stack.error_call(datum)
|
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
module Excon
|
|
3
3
|
module Middleware
|
|
4
4
|
class Instrumentor < Excon::Middleware::Base
|
|
5
|
+
def self.valid_parameter_keys
|
|
6
|
+
[
|
|
7
|
+
:logger,
|
|
8
|
+
:instrumentor,
|
|
9
|
+
:instrumentor_name
|
|
10
|
+
]
|
|
11
|
+
end
|
|
12
|
+
|
|
5
13
|
def error_call(datum)
|
|
6
14
|
if datum.has_key?(:instrumentor)
|
|
7
15
|
datum[:instrumentor].instrument("#{datum[:instrumentor_name]}.error", :error => datum[:error]) do
|
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
module Excon
|
|
3
3
|
module Middleware
|
|
4
4
|
class Mock < Excon::Middleware::Base
|
|
5
|
+
def self.valid_parameter_keys
|
|
6
|
+
[
|
|
7
|
+
:allow_unstubbed_requests,
|
|
8
|
+
:captures,
|
|
9
|
+
:mock
|
|
10
|
+
]
|
|
11
|
+
end
|
|
12
|
+
|
|
5
13
|
def request_call(datum)
|
|
6
14
|
if datum[:mock]
|
|
7
15
|
# convert File/Tempfile body to string before matching:
|
|
@@ -17,12 +25,13 @@ module Excon
|
|
|
17
25
|
raise Excon::Errors::InvalidStub.new("Request body should be a string or an IO object. #{datum[:body].class} provided")
|
|
18
26
|
end
|
|
19
27
|
|
|
20
|
-
if stub = Excon.stub_for(datum)
|
|
28
|
+
if (stub = Excon.stub_for(datum))
|
|
29
|
+
datum[:remote_ip] ||= '127.0.0.1'
|
|
21
30
|
datum[:response] = {
|
|
22
31
|
:body => '',
|
|
23
32
|
:headers => {},
|
|
24
33
|
:status => 200,
|
|
25
|
-
:remote_ip =>
|
|
34
|
+
:remote_ip => datum[:remote_ip]
|
|
26
35
|
}
|
|
27
36
|
|
|
28
37
|
stub_datum = case stub.last
|
|
@@ -32,7 +41,7 @@ module Excon
|
|
|
32
41
|
stub.last
|
|
33
42
|
end
|
|
34
43
|
|
|
35
|
-
datum[:response].merge!(stub_datum.reject {|key,
|
|
44
|
+
datum[:response].merge!(stub_datum.reject {|key,_| key == :headers})
|
|
36
45
|
if stub_datum.has_key?(:headers)
|
|
37
46
|
datum[:response][:headers].merge!(stub_datum[:headers])
|
|
38
47
|
end
|
|
@@ -2,9 +2,21 @@
|
|
|
2
2
|
module Excon
|
|
3
3
|
module Middleware
|
|
4
4
|
class RedirectFollower < Excon::Middleware::Base
|
|
5
|
+
def self.valid_parameter_keys
|
|
6
|
+
[
|
|
7
|
+
:redirects_remaining,
|
|
8
|
+
:redirect_limit
|
|
9
|
+
]
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def request_call(datum)
|
|
13
|
+
datum[:redirects_remaining] ||= datum[:redirect_limit] ||
|
|
14
|
+
Excon::DEFAULT_REDIRECT_LIMIT
|
|
15
|
+
@stack.request_call(datum)
|
|
16
|
+
end
|
|
5
17
|
|
|
6
18
|
def get_header(datum, header)
|
|
7
|
-
_, header_value = datum[:response][:headers].detect do |key,
|
|
19
|
+
_, header_value = datum[:response][:headers].detect do |key, _|
|
|
8
20
|
key.casecmp(header) == 0
|
|
9
21
|
end
|
|
10
22
|
header_value
|
|
@@ -14,14 +26,21 @@ module Excon
|
|
|
14
26
|
if datum.has_key?(:response)
|
|
15
27
|
case datum[:response][:status]
|
|
16
28
|
when 301, 302, 303, 307, 308
|
|
29
|
+
if datum[:redirects_remaining] <= 0
|
|
30
|
+
raise Excon::Errors::TooManyRedirects
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
datum[:redirects_remaining] -= 1
|
|
34
|
+
|
|
17
35
|
uri_parser = datum[:uri_parser] || Excon.defaults[:uri_parser]
|
|
18
36
|
|
|
19
37
|
location = get_header(datum, 'Location')
|
|
20
38
|
base_uri = Excon::Utils.request_uri(datum)
|
|
21
39
|
uri = uri_parser.join(base_uri, location)
|
|
22
40
|
|
|
23
|
-
# delete old/redirect response
|
|
41
|
+
# delete old/redirect response and remote_ip
|
|
24
42
|
response = datum.delete(:response)
|
|
43
|
+
datum.delete(:remote_ip)
|
|
25
44
|
|
|
26
45
|
params = datum.dup
|
|
27
46
|
params.delete(:connection)
|
|
@@ -52,7 +71,10 @@ module Excon
|
|
|
52
71
|
params.merge!(:password => Utils.unescape_uri(uri.password)) if uri.password
|
|
53
72
|
|
|
54
73
|
response = Excon::Connection.new(params).request
|
|
55
|
-
datum.merge!({
|
|
74
|
+
datum.merge!({
|
|
75
|
+
:remote_ip => response.remote_ip,
|
|
76
|
+
:response => response.data
|
|
77
|
+
})
|
|
56
78
|
else
|
|
57
79
|
@stack.response_call(datum)
|
|
58
80
|
end
|