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.
@@ -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') == 0 && body.nil?
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(String.new("0#{CR_NL}#{CR_NL}"))
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') == 0 } || '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') == 0 })
303
- if datum[:response][:headers][key].casecmp('close') == 0
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.merge!(:persistent => @data[:persistent])
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') == 0 })
343
- if responses.last[:headers][key].casecmp('close') == 0
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 =~ /certificate verify failed/
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))
@@ -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__), "..", "..", "data", "cacert.pem"))
5
+ DEFAULT_CA_FILE = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'data', 'cacert.pem'))
7
6
 
8
- DEFAULT_CHUNK_SIZE = 1048576 # 1 megabyte
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::Timeout,
17
+ Excon::Error::RequestTimeout,
18
+ Excon::Error::Server,
21
19
  Excon::Error::Socket,
22
- Excon::Error::HTTPStatus
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{connect delete get head options patch post put trace}
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
- VALID_REQUEST_KEYS = [
44
- :allow_unstubbed_requests,
45
- :body,
46
- :chunk_size,
47
- :debug_request,
48
- :debug_response,
49
- :dns_timeouts,
50
- :headers,
51
- :instrumentor, # Used for setting logging within Connection
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
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
- VALID_CONNECTION_KEYS = VALID_REQUEST_KEYS + [
72
- :ciphers,
73
- :client_key,
74
- :client_key_data,
75
- :client_key_pass,
76
- :client_cert,
77
- :client_cert_data,
78
- :client_chain,
79
- :client_chain_data,
80
- :certificate,
81
- :certificate_path,
82
- :disable_proxy,
83
- :private_key,
84
- :private_key_path,
85
- :connect_timeout,
86
- :family,
87
- :keepalive,
88
- :host,
89
- :hostname,
90
- :omit_default_port,
91
- :nonblock,
92
- :reuseaddr,
93
- :port,
94
- :proxy,
95
- :scheme,
96
- :socket,
97
- :ssl_ca_file,
98
- :ssl_ca_path,
99
- :ssl_cert_store,
100
- :ssl_verify_callback,
101
- :ssl_verify_peer,
102
- :ssl_verify_peer_host,
103
- :ssl_verify_hostname,
104
- :ssl_version,
105
- :ssl_min_version,
106
- :ssl_max_version,
107
- :ssl_security_level,
108
- :ssl_proxy_headers,
109
- :ssl_uri_schemes,
110
- :tcp_nodelay,
111
- :thread_safe_sockets,
112
- :uri_parser,
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
- :captures => 'Mock',
117
- :expects => 'Expects',
118
- :idempotent => 'Idempotent',
119
- :instrumentor_name => 'Instrumentor',
120
- :mock => 'Mock',
121
- :retries_remaining => 'Idempotent', # referenced in Instrumentor, but only relevant with Idempotent
122
- :retry_errors => 'Idempotent',
123
- :retry_interval => 'Idempotent',
124
- :retry_limit => 'Idempotent' # referenced in Instrumentor, but only relevant with Idempotent
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
- DEFAULTS = {
140
- :chunk_size => CHUNK_SIZE || DEFAULT_CHUNK_SIZE,
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
- :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',
144
- :connect_timeout => 60,
145
- :debug_request => false,
146
- :debug_response => false,
147
- :dns_timeouts => nil,
148
- # nil allows Resolv::DNS to set its default timeouts value (see https://ruby-doc.org/3.2.2/stdlibs/resolv/Resolv/DNS.html#method-i-timeouts-3D)
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
- :idempotent => false,
154
- :instrumentor_name => 'excon',
155
- :middlewares => [
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
- :mock => false,
163
- :nonblock => true,
164
- :omit_default_port => false,
165
- :persistent => false,
166
- :read_timeout => 60,
167
- :resolv_resolver => nil,
168
- :retry_errors => DEFAULT_RETRY_ERRORS,
169
- :retry_limit => DEFAULT_RETRY_LIMIT,
170
- :ssl_verify_peer => true,
171
- :ssl_uri_schemes => [HTTPS],
172
- :stubs => :global,
173
- :tcp_nodelay => false,
174
- :thread_safe_sockets => true,
175
- :timeout => nil,
176
- :uri_parser => URI,
177
- :versions => VERSIONS,
178
- :write_timeout => 60
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 =~ /Error\Z/
220
- class_name = klass.to_s + 'Error' if class_name =~ legacy_re
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
@@ -9,7 +9,7 @@ module Excon
9
9
 
10
10
  def get_header(datum, header)
11
11
  _, header_value = datum[:response][:headers].detect do |key, _|
12
- key.casecmp(header) == 0
12
+ key.casecmp?(header)
13
13
  end
14
14
  header_value
15
15
  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.has_key?(:response_block)
11
- key = datum[:headers].keys.detect {|k| k.to_s.casecmp('Accept-Encoding') == 0 } || '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
- unless datum.has_key?(:response_block) || body.nil? || body.empty?
22
- if (key = datum[:response][:headers].keys.detect {|k| k.casecmp('Content-Encoding') == 0 })
23
- encodings = Utils.split_header_value(datum[:response][:headers][key])
24
- if (encoding = encodings.last)
25
- if encoding.casecmp('deflate') == 0
26
- datum[:response][:body] = begin
27
- Zlib::Inflate.new(INFLATE_ZLIB_OR_GZIP).inflate(body)
28
- rescue Zlib::DataError # fallback to raw on error
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) == 0
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.merge!(:user => Utils.unescape_uri(uri.user)) if uri.user
71
- params.merge!(:password => Utils.unescape_uri(uri.password)) if uri.password
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!({
@@ -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') == 0 })
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') == 0
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') == 0 })
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') == 0
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::DefaultResolver
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.close rescue nil if socket
184
+ socket&.close rescue nil
185
185
  end
186
186
  end
187
187
 
@@ -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 =~ /^jar: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.merge(:omit_default_port => false))}#{Excon::HTTP_1_1}" +
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 =~ /Use Ctrl-C to stop/
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 =~ /worker\=0 ready/
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 =~ /HTTPServer#start/
13
+ until line.include?('HTTPServer#start')
14
14
  line = error.gets
15
15
  raise process_stderr if line.nil?
16
16
  process_stderr << line