excon 0.110.0 → 1.2.7
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/README.md +4 -0
- data/data/cacert.pem +180 -281
- data/excon.gemspec +24 -18
- data/lib/excon/connection.rb +16 -11
- data/lib/excon/constants.rb +136 -126
- data/lib/excon/error.rb +2 -2
- data/lib/excon/middlewares/capture_cookies.rb +1 -1
- data/lib/excon/middlewares/decompress.rb +17 -22
- data/lib/excon/middlewares/redirect_follower.rb +3 -3
- data/lib/excon/response.rb +4 -4
- data/lib/excon/socket.rb +8 -8
- data/lib/excon/ssl_socket.rb +3 -2
- data/lib/excon/test/plugin/server/puma.rb +1 -1
- data/lib/excon/test/plugin/server/unicorn.rb +5 -5
- data/lib/excon/test/plugin/server/webrick.rb +1 -1
- data/lib/excon/test/server.rb +2 -7
- data/lib/excon/unix_socket.rb +1 -1
- data/lib/excon/utils.rb +39 -36
- data/lib/excon/version.rb +1 -1
- data/lib/excon.rb +40 -49
- metadata +46 -17
data/lib/excon/connection.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
require 'ipaddr'
|
3
2
|
|
4
3
|
module Excon
|
5
4
|
class Connection
|
@@ -139,7 +138,7 @@ module Excon
|
|
139
138
|
|
140
139
|
# The HTTP spec isn't clear on it, but specifically, GET requests don't usually send bodies;
|
141
140
|
# if they don't, sending Content-Length:0 can cause issues.
|
142
|
-
unless datum[:method].to_s.casecmp('GET')
|
141
|
+
unless datum[:method].to_s.casecmp?('GET') && body.nil?
|
143
142
|
unless datum[:headers].has_key?('Content-Length')
|
144
143
|
datum[:headers]['Content-Length'] = detect_content_length(body)
|
145
144
|
end
|
@@ -160,7 +159,7 @@ module Excon
|
|
160
159
|
if chunk.length > 0
|
161
160
|
socket(datum).write(chunk.length.to_s(16) << CR_NL << chunk << CR_NL)
|
162
161
|
else
|
163
|
-
socket(datum).write(
|
162
|
+
socket(datum).write("0#{CR_NL}#{CR_NL}")
|
164
163
|
break
|
165
164
|
end
|
166
165
|
end
|
@@ -195,7 +194,7 @@ module Excon
|
|
195
194
|
raise(error)
|
196
195
|
when Errno::EPIPE
|
197
196
|
# Read whatever remains in the pipe to aid in debugging
|
198
|
-
response = socket.read
|
197
|
+
response = socket.read rescue ""
|
199
198
|
error = Excon::Error.new(response + error.message)
|
200
199
|
raise_socket_error(error)
|
201
200
|
else
|
@@ -251,7 +250,7 @@ module Excon
|
|
251
250
|
datum[:headers]['Authorization'] ||= 'Basic ' + ["#{user}:#{pass}"].pack('m').delete(Excon::CR_NL)
|
252
251
|
end
|
253
252
|
|
254
|
-
host_key = datum[:headers].keys.detect {|k| k.casecmp('Host')
|
253
|
+
host_key = datum[:headers].keys.detect {|k| k.casecmp?('Host') } || 'Host'
|
255
254
|
if datum[:scheme] == UNIX
|
256
255
|
datum[:headers][host_key] ||= ''
|
257
256
|
else
|
@@ -299,8 +298,8 @@ module Excon
|
|
299
298
|
@persistent_socket_reusable = true
|
300
299
|
|
301
300
|
if datum[:persistent]
|
302
|
-
if (key = datum[:response][:headers].keys.detect {|k| k.casecmp('Connection')
|
303
|
-
if datum[:response][:headers][key].casecmp('close')
|
301
|
+
if (key = datum[:response][:headers].keys.detect {|k| k.casecmp?('Connection') })
|
302
|
+
if datum[:response][:headers][key].casecmp?('close')
|
304
303
|
reset
|
305
304
|
end
|
306
305
|
end
|
@@ -330,7 +329,7 @@ module Excon
|
|
330
329
|
# @param pipeline_params [Array<Hash>] An array of one or more optional params, override defaults set in Connection.new, see #request for details
|
331
330
|
def requests(pipeline_params)
|
332
331
|
pipeline_params.each {|params| params.merge!(:pipeline => true, :persistent => true) }
|
333
|
-
pipeline_params.last
|
332
|
+
pipeline_params.last[:persistent] = @data[:persistent]
|
334
333
|
|
335
334
|
responses = pipeline_params.map do |params|
|
336
335
|
request(params)
|
@@ -339,8 +338,8 @@ module Excon
|
|
339
338
|
end
|
340
339
|
|
341
340
|
if @data[:persistent]
|
342
|
-
if (key = responses.last[:headers].keys.detect {|k| k.casecmp('Connection')
|
343
|
-
if responses.last[:headers][key].casecmp('close')
|
341
|
+
if (key = responses.last[:headers].keys.detect {|k| k.casecmp?('Connection') })
|
342
|
+
if responses.last[:headers][key].casecmp?('close')
|
344
343
|
reset
|
345
344
|
end
|
346
345
|
end
|
@@ -447,6 +446,12 @@ module Excon
|
|
447
446
|
raise ArgumentError.new("Invalid validation type '#{validation}'")
|
448
447
|
end
|
449
448
|
|
449
|
+
if validation == :connection && params[:omit_default_port] != true
|
450
|
+
Excon.display_warning(
|
451
|
+
'The `omit_default_port` connection option is deprecated, please use `include_default_port` instead.'
|
452
|
+
)
|
453
|
+
end
|
454
|
+
|
450
455
|
invalid_keys = params.keys - valid_keys
|
451
456
|
unless invalid_keys.empty?
|
452
457
|
Excon.display_warning("Invalid Excon #{validation} keys: #{invalid_keys.map(&:inspect).join(', ')}")
|
@@ -506,7 +511,7 @@ module Excon
|
|
506
511
|
end
|
507
512
|
|
508
513
|
def raise_socket_error(error)
|
509
|
-
if error.message
|
514
|
+
if error.message.include?('certificate verify failed')
|
510
515
|
raise(Excon::Errors::CertificateError.new(error))
|
511
516
|
else
|
512
517
|
raise(Excon::Errors::SocketError.new(error))
|
data/lib/excon/constants.rb
CHANGED
@@ -1,32 +1,31 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
module Excon
|
3
|
-
|
4
3
|
CR_NL = "\r\n"
|
5
4
|
|
6
|
-
DEFAULT_CA_FILE = File.expand_path(File.join(File.dirname(__FILE__),
|
5
|
+
DEFAULT_CA_FILE = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'data', 'cacert.pem'))
|
7
6
|
|
8
|
-
DEFAULT_CHUNK_SIZE =
|
7
|
+
DEFAULT_CHUNK_SIZE = 1_048_576 # 1 megabyte
|
9
8
|
|
10
9
|
# avoid overwrite if somebody has redefined
|
11
|
-
unless const_defined?(:CHUNK_SIZE)
|
12
|
-
CHUNK_SIZE = DEFAULT_CHUNK_SIZE
|
13
|
-
end
|
10
|
+
CHUNK_SIZE = DEFAULT_CHUNK_SIZE unless const_defined?(:CHUNK_SIZE)
|
14
11
|
|
15
12
|
DEFAULT_REDIRECT_LIMIT = 10
|
16
13
|
|
17
14
|
DEFAULT_RETRY_LIMIT = 4
|
18
15
|
|
19
16
|
DEFAULT_RETRY_ERRORS = [
|
20
|
-
Excon::Error::
|
17
|
+
Excon::Error::RequestTimeout,
|
18
|
+
Excon::Error::Server,
|
21
19
|
Excon::Error::Socket,
|
22
|
-
Excon::Error::
|
23
|
-
|
20
|
+
Excon::Error::Timeout,
|
21
|
+
Excon::Error::TooManyRequests
|
22
|
+
].freeze
|
24
23
|
|
25
24
|
FORCE_ENC = CR_NL.respond_to?(:force_encoding)
|
26
25
|
|
27
26
|
HTTP_1_1 = " HTTP/1.1\r\n"
|
28
27
|
|
29
|
-
HTTP_VERBS = %w
|
28
|
+
HTTP_VERBS = %w[connect delete get head options patch post put trace].freeze
|
30
29
|
|
31
30
|
HTTPS = 'https'
|
32
31
|
|
@@ -36,93 +35,97 @@ module Excon
|
|
36
35
|
|
37
36
|
UNIX = 'unix'
|
38
37
|
|
39
|
-
USER_AGENT = "excon/#{VERSION}"
|
40
|
-
|
41
|
-
VERSIONS = "#{USER_AGENT} (#{RUBY_PLATFORM}) ruby/#{RUBY_VERSION}"
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
38
|
+
USER_AGENT = "excon/#{VERSION}".freeze
|
39
|
+
|
40
|
+
VERSIONS = "#{USER_AGENT} (#{RUBY_PLATFORM}) ruby/#{RUBY_VERSION}".freeze
|
41
|
+
|
42
|
+
# FIXME: should be frozen, but with a way to change them, similar to defaults
|
43
|
+
VALID_REQUEST_KEYS = %i[
|
44
|
+
allow_unstubbed_requests
|
45
|
+
body
|
46
|
+
chunk_size
|
47
|
+
debug_request
|
48
|
+
debug_response
|
49
|
+
dns_timeouts
|
50
|
+
headers
|
51
|
+
instrumentor
|
52
|
+
logger
|
53
|
+
method
|
54
|
+
middlewares
|
55
|
+
password
|
56
|
+
path
|
57
|
+
persistent
|
58
|
+
pipeline
|
59
|
+
query
|
60
|
+
read_timeout
|
61
|
+
request_block
|
62
|
+
resolv_resolver
|
63
|
+
response_block
|
64
|
+
stubs
|
65
|
+
timeout
|
66
|
+
user
|
67
|
+
versions
|
68
|
+
write_timeout
|
69
69
|
]
|
70
70
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
71
|
+
# FIXME: should be frozen, but with a way to change them, similar to defaults
|
72
|
+
VALID_CONNECTION_KEYS = (VALID_REQUEST_KEYS + %i[
|
73
|
+
ciphers
|
74
|
+
client_key
|
75
|
+
client_key_data
|
76
|
+
client_key_pass
|
77
|
+
client_cert
|
78
|
+
client_cert_data
|
79
|
+
client_chain
|
80
|
+
client_chain_data
|
81
|
+
certificate
|
82
|
+
certificate_path
|
83
|
+
disable_proxy
|
84
|
+
private_key
|
85
|
+
private_key_path
|
86
|
+
connect_timeout
|
87
|
+
family
|
88
|
+
keepalive
|
89
|
+
host
|
90
|
+
hostname
|
91
|
+
ignore_unexpected_eof
|
92
|
+
include_default_port
|
93
|
+
omit_default_port
|
94
|
+
nonblock
|
95
|
+
reuseaddr
|
96
|
+
port
|
97
|
+
proxy
|
98
|
+
scheme
|
99
|
+
socket
|
100
|
+
ssl_ca_file
|
101
|
+
ssl_ca_path
|
102
|
+
ssl_cert_store
|
103
|
+
ssl_verify_callback
|
104
|
+
ssl_verify_peer
|
105
|
+
ssl_verify_peer_host
|
106
|
+
ssl_verify_hostname
|
107
|
+
ssl_version
|
108
|
+
ssl_min_version
|
109
|
+
ssl_max_version
|
110
|
+
ssl_security_level
|
111
|
+
ssl_proxy_headers
|
112
|
+
ssl_uri_schemes
|
113
|
+
tcp_nodelay
|
114
|
+
thread_safe_sockets
|
115
|
+
uri_parser
|
116
|
+
])
|
114
117
|
|
115
118
|
DEPRECATED_VALID_REQUEST_KEYS = {
|
116
|
-
:
|
117
|
-
:
|
118
|
-
:
|
119
|
-
:
|
120
|
-
:
|
121
|
-
:
|
122
|
-
:
|
123
|
-
:
|
124
|
-
:
|
125
|
-
}
|
119
|
+
captures: 'Mock',
|
120
|
+
expects: 'Expects',
|
121
|
+
idempotent: 'Idempotent',
|
122
|
+
instrumentor_name: 'Instrumentor',
|
123
|
+
mock: 'Mock',
|
124
|
+
retries_remaining: 'Idempotent', # referenced in Instrumentor, but only relevant with Idempotent
|
125
|
+
retry_errors: 'Idempotent',
|
126
|
+
retry_interval: 'Idempotent',
|
127
|
+
retry_limit: 'Idempotent' # referenced in Instrumentor, but only relevant with Idempotent
|
128
|
+
}.freeze
|
126
129
|
|
127
130
|
unless ::IO.const_defined?(:WaitReadable)
|
128
131
|
class ::IO
|
@@ -135,47 +138,54 @@ module Excon
|
|
135
138
|
module WaitWritable; end
|
136
139
|
end
|
137
140
|
end
|
141
|
+
|
138
142
|
# these come last as they rely on the above
|
139
|
-
|
140
|
-
:
|
143
|
+
base_defaults = {
|
144
|
+
chunk_size: CHUNK_SIZE || DEFAULT_CHUNK_SIZE,
|
141
145
|
# see https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28default.29
|
142
146
|
# list provided then had DES related things sorted to the end
|
143
|
-
:
|
144
|
-
:
|
145
|
-
:
|
146
|
-
:
|
147
|
-
:
|
148
|
-
|
149
|
-
:headers => {
|
147
|
+
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',
|
148
|
+
connect_timeout: 60,
|
149
|
+
debug_request: false,
|
150
|
+
debug_response: false,
|
151
|
+
dns_timeouts: nil, # nil allows Resolv::DNS default timeout value (see https://ruby-doc.org/3.2.2/stdlibs/resolv/Resolv/DNS.html#method-i-timeouts-3D)
|
152
|
+
headers: {
|
150
153
|
'User-Agent' => USER_AGENT,
|
151
|
-
'Accept'
|
152
|
-
},
|
153
|
-
:
|
154
|
-
:
|
155
|
-
:
|
154
|
+
'Accept' => '*/*'
|
155
|
+
}.freeze,
|
156
|
+
idempotent: false,
|
157
|
+
instrumentor_name: 'excon',
|
158
|
+
middlewares: [
|
156
159
|
Excon::Middleware::ResponseParser,
|
160
|
+
Excon::Middleware::Decompress,
|
157
161
|
Excon::Middleware::Expects,
|
158
162
|
Excon::Middleware::Idempotent,
|
159
163
|
Excon::Middleware::Instrumentor,
|
160
164
|
Excon::Middleware::Mock
|
161
165
|
],
|
162
|
-
:
|
163
|
-
:
|
164
|
-
:
|
165
|
-
:
|
166
|
-
:
|
167
|
-
:
|
168
|
-
:
|
169
|
-
:
|
170
|
-
:
|
171
|
-
:
|
172
|
-
:
|
173
|
-
:
|
174
|
-
:
|
175
|
-
:
|
176
|
-
:
|
177
|
-
:
|
178
|
-
:
|
179
|
-
|
180
|
-
|
166
|
+
mock: false,
|
167
|
+
include_default_port: false,
|
168
|
+
nonblock: true,
|
169
|
+
omit_default_port: true,
|
170
|
+
persistent: false,
|
171
|
+
read_timeout: 60,
|
172
|
+
resolv_resolver: nil,
|
173
|
+
retry_errors: DEFAULT_RETRY_ERRORS,
|
174
|
+
retry_limit: DEFAULT_RETRY_LIMIT,
|
175
|
+
ssl_verify_peer: true,
|
176
|
+
ssl_uri_schemes: [HTTPS].freeze,
|
177
|
+
stubs: :global,
|
178
|
+
tcp_nodelay: false,
|
179
|
+
thread_safe_sockets: true,
|
180
|
+
timeout: nil,
|
181
|
+
uri_parser: URI,
|
182
|
+
versions: VERSIONS,
|
183
|
+
write_timeout: 60
|
184
|
+
}.freeze
|
185
|
+
|
186
|
+
DEFAULTS = if defined? TEST_SUITE_DEFAULTS
|
187
|
+
base_defaults.merge(TEST_SUITE_DEFAULTS).freeze
|
188
|
+
else
|
189
|
+
base_defaults.freeze
|
190
|
+
end
|
181
191
|
end
|
data/lib/excon/error.rb
CHANGED
@@ -216,8 +216,8 @@ or:
|
|
216
216
|
|
217
217
|
klasses.each do |klass|
|
218
218
|
class_name = klass.to_s
|
219
|
-
unless class_name
|
220
|
-
class_name = klass.to_s + 'Error' if class_name
|
219
|
+
unless class_name.match?(/Error\Z/)
|
220
|
+
class_name = klass.to_s + 'Error' if class_name.match?(legacy_re)
|
221
221
|
end
|
222
222
|
Excon::Errors.const_set(class_name, Excon::Error.const_get(klass))
|
223
223
|
end
|
@@ -1,41 +1,36 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Excon
|
3
4
|
module Middleware
|
4
5
|
class Decompress < Excon::Middleware::Base
|
5
|
-
|
6
6
|
INFLATE_ZLIB_OR_GZIP = 47 # Zlib::MAX_WBITS + 32
|
7
7
|
INFLATE_RAW = -15 # Zlib::MAX_WBITS * -1
|
8
8
|
|
9
9
|
def request_call(datum)
|
10
|
-
unless datum.
|
11
|
-
key = datum[:headers].keys.detect {|k| k.to_s.casecmp('Accept-Encoding')
|
12
|
-
if datum[:headers][key].to_s.empty?
|
13
|
-
datum[:headers][key] = 'deflate, gzip'
|
14
|
-
end
|
10
|
+
unless datum.key?(:response_block)
|
11
|
+
key = datum[:headers].keys.detect { |k| k.to_s.casecmp?('Accept-Encoding') } || 'Accept-Encoding'
|
12
|
+
datum[:headers][key] = 'deflate, gzip' if datum[:headers][key].to_s.empty?
|
15
13
|
end
|
16
14
|
@stack.request_call(datum)
|
17
15
|
end
|
18
16
|
|
19
17
|
def response_call(datum)
|
20
18
|
body = datum[:response][:body]
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
Zlib::Inflate.new(INFLATE_RAW).inflate(body)
|
30
|
-
end
|
31
|
-
encodings.pop
|
32
|
-
elsif encoding.casecmp('gzip') == 0 || encoding.casecmp('x-gzip') == 0
|
33
|
-
datum[:response][:body] = Zlib::GzipReader.new(StringIO.new(body)).read
|
34
|
-
encodings.pop
|
35
|
-
end
|
36
|
-
datum[:response][:headers][key] = encodings.join(', ')
|
19
|
+
if !(datum.key?(:response_block) || body.nil? || body.empty?) &&
|
20
|
+
(key = datum[:response][:headers].keys.detect { |k| k.casecmp?('Content-Encoding') })
|
21
|
+
encodings = Utils.split_header_value(datum[:response][:headers][key])
|
22
|
+
if encodings&.last&.casecmp?('deflate')
|
23
|
+
datum[:response][:body] = begin
|
24
|
+
Zlib::Inflate.new(INFLATE_ZLIB_OR_GZIP).inflate(body)
|
25
|
+
rescue Zlib::DataError # fallback to raw on error
|
26
|
+
Zlib::Inflate.new(INFLATE_RAW).inflate(body)
|
37
27
|
end
|
28
|
+
encodings.pop
|
29
|
+
elsif encodings&.last&.casecmp?('gzip') || encodings&.last&.casecmp?('x-gzip')
|
30
|
+
datum[:response][:body] = Zlib::GzipReader.new(StringIO.new(body)).read
|
31
|
+
encodings.pop
|
38
32
|
end
|
33
|
+
datum[:response][:headers][key] = encodings.join(', ')
|
39
34
|
end
|
40
35
|
@stack.response_call(datum)
|
41
36
|
end
|
@@ -17,7 +17,7 @@ module Excon
|
|
17
17
|
|
18
18
|
def get_header(datum, header)
|
19
19
|
_, header_value = datum[:response][:headers].detect do |key, _|
|
20
|
-
key.casecmp(header)
|
20
|
+
key.casecmp?(header)
|
21
21
|
end
|
22
22
|
header_value
|
23
23
|
end
|
@@ -67,8 +67,8 @@ module Excon
|
|
67
67
|
:query => uri.query
|
68
68
|
)
|
69
69
|
|
70
|
-
params
|
71
|
-
params
|
70
|
+
params[:user] = Utils.unescape_uri(uri.user) if uri.user
|
71
|
+
params[:password] = Utils.unescape_uri(uri.password) if uri.password
|
72
72
|
|
73
73
|
response = Excon::Connection.new(params).request
|
74
74
|
datum.merge!({
|
data/lib/excon/response.rb
CHANGED
@@ -106,9 +106,9 @@ module Excon
|
|
106
106
|
|
107
107
|
unless (['HEAD', 'CONNECT'].include?(datum[:method].to_s.upcase)) || NO_ENTITY.include?(datum[:response][:status])
|
108
108
|
|
109
|
-
if (key = datum[:response][:headers].keys.detect {|k| k.casecmp('Transfer-Encoding')
|
109
|
+
if (key = datum[:response][:headers].keys.detect {|k| k.casecmp?('Transfer-Encoding') })
|
110
110
|
encodings = Utils.split_header_value(datum[:response][:headers][key])
|
111
|
-
if (encoding = encodings.last) && encoding.casecmp('chunked')
|
111
|
+
if (encoding = encodings.last) && encoding.casecmp?('chunked')
|
112
112
|
transfer_encoding_chunked = true
|
113
113
|
if encodings.length == 1
|
114
114
|
datum[:response][:headers].delete(key)
|
@@ -156,7 +156,7 @@ module Excon
|
|
156
156
|
end
|
157
157
|
parse_headers(socket, datum) # merge trailers into headers
|
158
158
|
else
|
159
|
-
if (key = datum[:response][:headers].keys.detect {|k| k.casecmp('Content-Length')
|
159
|
+
if (key = datum[:response][:headers].keys.detect {|k| k.casecmp?('Content-Length') })
|
160
160
|
content_length = datum[:response][:headers][key].to_i
|
161
161
|
end
|
162
162
|
|
@@ -202,7 +202,7 @@ module Excon
|
|
202
202
|
raise Excon::Error::ResponseParse, 'malformed header' unless value
|
203
203
|
# add key/value or append value to existing values
|
204
204
|
datum[:response][:headers][key] = ([datum[:response][:headers][key]] << value.strip).compact.join(', ')
|
205
|
-
if key.casecmp('Set-Cookie')
|
205
|
+
if key.casecmp?('Set-Cookie')
|
206
206
|
datum[:response][:cookies] << value.strip
|
207
207
|
end
|
208
208
|
last_key = key
|
data/lib/excon/socket.rb
CHANGED
@@ -11,19 +11,19 @@ module Excon
|
|
11
11
|
|
12
12
|
# read/write drawn from https://github.com/ruby-amqp/bunny/commit/75d9dd79551b31a5dd3d1254c537bad471f108cf
|
13
13
|
CONNECT_RETRY_EXCEPTION_CLASSES = if defined?(IO::EINPROGRESSWaitWritable) # Ruby >= 2.1
|
14
|
-
[Errno::EINPROGRESS, IO::EINPROGRESSWaitWritable]
|
14
|
+
[Errno::EINPROGRESS, IO::EINPROGRESSWaitWritable].freeze
|
15
15
|
else # Ruby <= 2.0
|
16
|
-
[Errno::EINPROGRESS]
|
16
|
+
[Errno::EINPROGRESS].freeze
|
17
17
|
end
|
18
18
|
READ_RETRY_EXCEPTION_CLASSES = if defined?(IO::EAGAINWaitReadable) # Ruby >= 2.1
|
19
|
-
[Errno::EAGAIN, Errno::EWOULDBLOCK, IO::WaitReadable, IO::EAGAINWaitReadable, IO::EWOULDBLOCKWaitReadable]
|
19
|
+
[Errno::EAGAIN, Errno::EWOULDBLOCK, IO::WaitReadable, IO::EAGAINWaitReadable, IO::EWOULDBLOCKWaitReadable].freeze
|
20
20
|
else # Ruby <= 2.0
|
21
|
-
[Errno::EAGAIN, Errno::EWOULDBLOCK, IO::WaitReadable]
|
21
|
+
[Errno::EAGAIN, Errno::EWOULDBLOCK, IO::WaitReadable].freeze
|
22
22
|
end
|
23
23
|
WRITE_RETRY_EXCEPTION_CLASSES = if defined?(IO::EAGAINWaitWritable) # Ruby >= 2.1
|
24
|
-
[Errno::EAGAIN, Errno::EWOULDBLOCK, IO::WaitWritable, IO::EAGAINWaitWritable, IO::EWOULDBLOCKWaitWritable]
|
24
|
+
[Errno::EAGAIN, Errno::EWOULDBLOCK, IO::WaitWritable, IO::EAGAINWaitWritable, IO::EWOULDBLOCKWaitWritable].freeze
|
25
25
|
else # Ruby <= 2.0
|
26
|
-
[Errno::EAGAIN, Errno::EWOULDBLOCK, IO::WaitWritable]
|
26
|
+
[Errno::EAGAIN, Errno::EWOULDBLOCK, IO::WaitWritable].freeze
|
27
27
|
end
|
28
28
|
# Maps a socket operation to a timeout property.
|
29
29
|
OPERATION_TO_TIMEOUT = {
|
@@ -132,7 +132,7 @@ module Excon
|
|
132
132
|
family = @data[:proxy][:family]
|
133
133
|
end
|
134
134
|
|
135
|
-
resolver = @data[:resolv_resolver] || Resolv
|
135
|
+
resolver = @data[:resolv_resolver] || Resolv.new
|
136
136
|
|
137
137
|
# Deprecated
|
138
138
|
if @data[:dns_timeouts]
|
@@ -181,7 +181,7 @@ module Excon
|
|
181
181
|
socket.close rescue nil
|
182
182
|
end
|
183
183
|
rescue SystemCallError => exception
|
184
|
-
socket
|
184
|
+
socket&.close rescue nil
|
185
185
|
end
|
186
186
|
end
|
187
187
|
|
data/lib/excon/ssl_socket.rb
CHANGED
@@ -26,6 +26,7 @@ module Excon
|
|
26
26
|
if defined?(OpenSSL::SSL::OP_NO_COMPRESSION)
|
27
27
|
ssl_context_options |= OpenSSL::SSL::OP_NO_COMPRESSION
|
28
28
|
end
|
29
|
+
ssl_context_options |= OpenSSL::SSL::OP_IGNORE_UNEXPECTED_EOF if @data[:ignore_unexpected_eof]
|
29
30
|
ssl_context.options = ssl_context_options
|
30
31
|
|
31
32
|
ssl_context.ciphers = @data[:ciphers]
|
@@ -63,7 +64,7 @@ module Excon
|
|
63
64
|
unless ca_file || ca_path || cert_store
|
64
65
|
# workaround issue #257 (JRUBY-6970)
|
65
66
|
ca_file = DEFAULT_CA_FILE
|
66
|
-
ca_file = ca_file.gsub(/^jar:/, '') if ca_file
|
67
|
+
ca_file = ca_file.gsub(/^jar:/, '') if ca_file.match?(/^jar:file:\//)
|
67
68
|
|
68
69
|
begin
|
69
70
|
ssl_context.cert_store.add_file(ca_file)
|
@@ -108,7 +109,7 @@ module Excon
|
|
108
109
|
end
|
109
110
|
|
110
111
|
if @data[:proxy]
|
111
|
-
request = "CONNECT #{@data[:host]}#{port_string(@data
|
112
|
+
request = "CONNECT #{@data[:host]}#{port_string(@data)}#{Excon::HTTP_1_1}" \
|
112
113
|
"Host: #{@data[:host]}#{port_string(@data)}#{Excon::CR_NL}"
|
113
114
|
|
114
115
|
if @data[:proxy].has_key?(:user) || @data[:proxy].has_key?(:password)
|
@@ -7,7 +7,7 @@ module Excon
|
|
7
7
|
open_process(RbConfig.ruby, '-S', 'puma', '-b', bind_uri.to_s, app_str)
|
8
8
|
process_stderr = ""
|
9
9
|
line = ''
|
10
|
-
until line
|
10
|
+
until line.include?('Use Ctrl-C to stop')
|
11
11
|
line = read.gets
|
12
12
|
raise process_stderr if line.nil?
|
13
13
|
process_stderr << line
|
@@ -12,19 +12,19 @@ module Excon
|
|
12
12
|
host = bind_uri.host.gsub(/[\[\]]/, '')
|
13
13
|
bind_str = "#{host}:#{bind_uri.port}"
|
14
14
|
end
|
15
|
-
args = [
|
15
|
+
args = [
|
16
16
|
RbConfig.ruby,
|
17
17
|
'-S',
|
18
|
-
'unicorn',
|
19
|
-
'--no-default-middleware',
|
18
|
+
'unicorn',
|
19
|
+
'--no-default-middleware',
|
20
20
|
'-l',
|
21
|
-
bind_str,
|
21
|
+
bind_str,
|
22
22
|
app_str
|
23
23
|
]
|
24
24
|
open_process(*args)
|
25
25
|
process_stderr = ''
|
26
26
|
line = ''
|
27
|
-
until line
|
27
|
+
until line.include?('worker=0 ready')
|
28
28
|
line = error.gets
|
29
29
|
raise process_stderr if line.nil?
|
30
30
|
process_stderr << line
|
@@ -10,7 +10,7 @@ module Excon
|
|
10
10
|
open_process(RbConfig.ruby, '-S', 'rackup', '-s', 'webrick', '--host', host, '--port', port, app_str)
|
11
11
|
process_stderr = ""
|
12
12
|
line = ''
|
13
|
-
until line
|
13
|
+
until line.include?('HTTPServer#start')
|
14
14
|
line = error.gets
|
15
15
|
raise process_stderr if line.nil?
|
16
16
|
process_stderr << line
|