excon 0.71.1 → 0.89.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -12,6 +12,11 @@ module Excon
12
12
  # create ssl context
13
13
  ssl_context = OpenSSL::SSL::SSLContext.new
14
14
 
15
+ # set the security level before setting other parameters affected by it
16
+ if @data[:ssl_security_level]
17
+ ssl_context.security_level = @data[:ssl_security_level]
18
+ end
19
+
15
20
  # disable less secure options, when supported
16
21
  ssl_context_options = OpenSSL::SSL::SSLContext::DEFAULT_PARAMS[:options]
17
22
  if defined?(OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS)
@@ -39,13 +44,13 @@ module Excon
39
44
  # turn verification on
40
45
  ssl_context.verify_mode = OpenSSL::SSL::VERIFY_PEER
41
46
 
42
- if ca_file = @data[:ssl_ca_file] || ENV['SSL_CERT_FILE']
47
+ if (ca_file = @data[:ssl_ca_file] || ENV['SSL_CERT_FILE'])
43
48
  ssl_context.ca_file = ca_file
44
49
  end
45
- if ca_path = @data[:ssl_ca_path] || ENV['SSL_CERT_DIR']
50
+ if (ca_path = @data[:ssl_ca_path] || ENV['SSL_CERT_DIR'])
46
51
  ssl_context.ca_path = ca_path
47
52
  end
48
- if cert_store = @data[:ssl_cert_store]
53
+ if (cert_store = @data[:ssl_cert_store])
49
54
  ssl_context.cert_store = cert_store
50
55
  end
51
56
 
@@ -65,7 +70,7 @@ module Excon
65
70
  end
66
71
  end
67
72
 
68
- if verify_callback = @data[:ssl_verify_callback]
73
+ if (verify_callback = @data[:ssl_verify_callback])
69
74
  ssl_context.verify_callback = verify_callback
70
75
  end
71
76
  else
@@ -73,6 +78,9 @@ module Excon
73
78
  ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE
74
79
  end
75
80
 
81
+ # Verify certificate hostname if supported (ruby >= 2.4.0)
82
+ ssl_context.verify_hostname = @data[:ssl_verify_hostname] if ssl_context.respond_to?(:verify_hostname=)
83
+
76
84
  if client_cert_data && client_key_data
77
85
  ssl_context.cert = OpenSSL::X509::Certificate.new client_cert_data
78
86
  if OpenSSL::PKey.respond_to? :read
@@ -101,6 +109,10 @@ module Excon
101
109
 
102
110
  request += "Proxy-Connection: Keep-Alive#{Excon::CR_NL}"
103
111
 
112
+ if @data[:ssl_proxy_headers]
113
+ request << Utils.headers_hash_to_s(@data[:ssl_proxy_headers])
114
+ end
115
+
104
116
  request += Excon::CR_NL
105
117
 
106
118
  # write out the proxy setup request
@@ -109,7 +121,7 @@ module Excon
109
121
  # eat the proxy's connection response
110
122
  response = Excon::Response.parse(self, :expects => 200, :method => 'CONNECT')
111
123
  if response[:response][:status] != 200
112
- raise(Excon::Errors::ProxyConnectionError.new("proxy connection is not exstablished"))
124
+ raise(Excon::Errors::ProxyConnectionError.new("proxy connection could not be established", request, response))
113
125
  end
114
126
  end
115
127
 
@@ -142,18 +154,16 @@ module Excon
142
154
  if @data[:ssl_verify_peer]
143
155
  @socket.post_connection_check(@data[:ssl_verify_peer_host] || @data[:host])
144
156
  end
145
-
146
- @socket
147
157
  end
148
158
 
149
159
  private
150
160
 
151
161
  def client_cert_data
152
- @client_cert_data ||= if ccd = @data[:client_cert_data]
162
+ @client_cert_data ||= if (ccd = @data[:client_cert_data])
153
163
  ccd
154
- elsif path = @data[:client_cert]
164
+ elsif (path = @data[:client_cert])
155
165
  File.read path
156
- elsif path = @data[:certificate_path]
166
+ elsif (path = @data[:certificate_path])
157
167
  warn ":certificate_path is no longer supported and will be deprecated. Please use :client_cert or :client_cert_data"
158
168
  File.read path
159
169
  end
@@ -166,11 +176,11 @@ module Excon
166
176
  end
167
177
 
168
178
  def client_key_data
169
- @client_key_data ||= if ckd = @data[:client_key_data]
179
+ @client_key_data ||= if (ckd = @data[:client_key_data])
170
180
  ckd
171
- elsif path = @data[:client_key]
181
+ elsif (path = @data[:client_key])
172
182
  File.read path
173
- elsif path = @data[:private_key_path]
183
+ elsif (path = @data[:private_key_path])
174
184
  warn ":private_key_path is no longer supported and will be deprecated. Please use :client_key or :client_key_data"
175
185
  File.read path
176
186
  end
@@ -4,13 +4,16 @@ module Excon
4
4
  module Server
5
5
  module Exec
6
6
  def start(app_str = app)
7
+ open_process(app_str)
8
+ process_stderr = ""
7
9
  line = ''
8
- open_process(app)
9
10
  until line =~ /\Aready\Z/
10
11
  line = error.gets
12
+ raise process_stderr if line.nil?
13
+ process_stderr << line
11
14
  fatal_time = elapsed_time > timeout
12
15
  if fatal_time
13
- msg = "executable #{app} has taken too long to start"
16
+ msg = "executable #{app_str} has taken too long to start"
14
17
  raise msg
15
18
  end
16
19
  end
@@ -4,10 +4,13 @@ module Excon
4
4
  module Server
5
5
  module Puma
6
6
  def start(app_str = app, bind_uri = bind)
7
- open_process('puma', '-b', bind_uri.to_s, app_str)
7
+ open_process(RbConfig.ruby, '-S', 'puma', '-b', bind_uri.to_s, app_str)
8
+ process_stderr = ""
8
9
  line = ''
9
10
  until line =~ /Use Ctrl-C to stop/
10
11
  line = read.gets
12
+ raise process_stderr if line.nil?
13
+ process_stderr << line
11
14
  fatal_time = elapsed_time > timeout
12
15
  raise 'puma server has taken too long to start' if fatal_time
13
16
  end
@@ -13,6 +13,8 @@ module Excon
13
13
  bind_str = "#{host}:#{bind_uri.port}"
14
14
  end
15
15
  args = [
16
+ RbConfig.ruby,
17
+ '-S',
16
18
  'unicorn',
17
19
  '--no-default-middleware',
18
20
  '-l',
@@ -20,9 +22,12 @@ module Excon
20
22
  app_str
21
23
  ]
22
24
  open_process(*args)
25
+ process_stderr = ''
23
26
  line = ''
24
27
  until line =~ /worker\=0 ready/
25
28
  line = error.gets
29
+ raise process_stderr if line.nil?
30
+ process_stderr << line
26
31
  fatal_time = elapsed_time > timeout
27
32
  raise 'unicorn server has taken too long to start' if fatal_time
28
33
  end
@@ -7,10 +7,13 @@ module Excon
7
7
  bind_uri = URI.parse(bind_uri) unless bind_uri.is_a? URI::Generic
8
8
  host = bind_uri.host.gsub(/[\[\]]/, '')
9
9
  port = bind_uri.port.to_s
10
- open_process('rackup', '-s', 'webrick', '--host', host, '--port', port, app_str)
10
+ open_process(RbConfig.ruby, '-S', 'rackup', '-s', 'webrick', '--host', host, '--port', port, app_str)
11
+ process_stderr = ""
11
12
  line = ''
12
13
  until line =~ /HTTPServer#start/
13
14
  line = error.gets
15
+ raise process_stderr if line.nil?
16
+ process_stderr << line
14
17
  fatal_time = elapsed_time > timeout
15
18
  raise 'webrick server has taken too long to start' if fatal_time
16
19
  end
@@ -72,7 +72,7 @@ module Excon
72
72
  end
73
73
  def dump_errors
74
74
  lines = error.read.split($/)
75
- while line = lines.shift
75
+ while (line = lines.shift)
76
76
  case line
77
77
  when /(ERROR|Error)/
78
78
  unless line =~ /(null cert chain|did not return a certificate|SSL_read:: internal error)/
@@ -20,6 +20,7 @@ module Excon
20
20
  begin
21
21
  @socket.connect_nonblock(sockaddr)
22
22
  rescue Errno::EISCONN
23
+ 0 # same return as connect_nonblock success
23
24
  end
24
25
  end
25
26
  else
data/lib/excon/utils.rb CHANGED
@@ -50,7 +50,7 @@ module Excon
50
50
  if datum.has_key?(:password)
51
51
  datum[:password] = REDACTED
52
52
  end
53
- if datum.has_key?(:proxy) && datum[:proxy].has_key?(:password)
53
+ if datum.has_key?(:proxy) && datum[:proxy] && datum[:proxy].has_key?(:password)
54
54
  datum[:proxy] = datum[:proxy].dup
55
55
  datum[:proxy][:password] = REDACTED
56
56
  end
@@ -96,7 +96,7 @@ module Excon
96
96
  return [] if str.nil?
97
97
  str = str.dup.strip
98
98
  str = binary_encode(str)
99
- str.scan(%r'\G((?:"(?:\\.|[^"])+?"|[^",]+)+)
99
+ str.scan(%r'\G((?:"(?:\\.|[^"])+?"|[^",])+)
100
100
  (?:,\s*|\Z)'xn).flatten
101
101
  end
102
102
 
@@ -121,5 +121,23 @@ module Excon
121
121
  str.gsub!(/\+/, ' ')
122
122
  str.gsub(ESCAPED) { $1.hex.chr }
123
123
  end
124
+
125
+ # Performs validation on the passed header hash and returns a string representation of the headers
126
+ def headers_hash_to_s(headers)
127
+ headers_str = String.new
128
+ headers.each do |key, values|
129
+ if key.to_s.match(/[\r\n]/)
130
+ raise Excon::Errors::InvalidHeaderKey.new(key.to_s.inspect + ' contains forbidden "\r" or "\n"')
131
+ end
132
+ [values].flatten.each do |value|
133
+ if value.to_s.match(/[\r\n]/)
134
+ # Don't include the potentially sensitive header value (i.e. authorization token) in the message
135
+ raise Excon::Errors::InvalidHeaderValue.new(key.to_s + ' header value contains forbidden "\r" or "\n"')
136
+ end
137
+ headers_str << key.to_s << ': ' << value.to_s << CR_NL
138
+ end
139
+ end
140
+ headers_str
141
+ end
124
142
  end
125
143
  end
data/lib/excon/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Excon
3
- VERSION = '0.71.1'
3
+ VERSION = '0.89.0'
4
4
  end
data/lib/excon.rb CHANGED
@@ -146,10 +146,10 @@ module Excon
146
146
  # @param request_params [Hash<Symbol, >] request params to match against, omitted params match all
147
147
  # @param response_params [Hash<Symbol, >] response params to return from matched request or block to call with params
148
148
  def stub(request_params = {}, response_params = nil, &block)
149
- if method = request_params.delete(:method)
149
+ if (method = request_params.delete(:method))
150
150
  request_params[:method] = method.to_s.downcase.to_sym
151
151
  end
152
- if url = request_params.delete(:url)
152
+ if (url = request_params.delete(:url))
153
153
  uri = URI.parse(url)
154
154
  request_params = {
155
155
  :host => uri.host,
@@ -190,7 +190,7 @@ module Excon
190
190
  # @param request_params [Hash<Symbol, >] request params to match against, omitted params match all
191
191
  # @return [Hash<Symbol, >] response params to return from matched request or block to call with params
192
192
  def stub_for(request_params={})
193
- if method = request_params.delete(:method)
193
+ if (method = request_params.delete(:method))
194
194
  request_params[:method] = method.to_s.downcase.to_sym
195
195
  end
196
196
  Excon.stubs.each do |stub, response_params|
@@ -198,7 +198,7 @@ module Excon
198
198
  headers_match = !stub.has_key?(:headers) || stub[:headers].keys.all? do |key|
199
199
  case value = stub[:headers][key]
200
200
  when Regexp
201
- if match = value.match(request_params[:headers][key])
201
+ if (match = value.match(request_params[:headers][key]))
202
202
  captures[:headers][key] = match.captures
203
203
  end
204
204
  match
@@ -209,7 +209,7 @@ module Excon
209
209
  non_headers_match = (stub.keys - [:headers]).all? do |key|
210
210
  case value = stub[key]
211
211
  when Regexp
212
- if match = value.match(request_params[key])
212
+ if (match = value.match(request_params[key]))
213
213
  captures[key] = match.captures
214
214
  end
215
215
  match
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: excon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.71.1
4
+ version: 0.89.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - dpiddy (Dan Peterson)
8
8
  - geemus (Wesley Beary)
9
9
  - nextmat (Matt Sanders)
10
- autorequire:
10
+ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2019-12-18 00:00:00.000000000 Z
13
+ date: 2021-12-07 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rspec
@@ -180,6 +180,20 @@ dependencies:
180
180
  - - ">="
181
181
  - !ruby/object:Gem::Version
182
182
  version: '0'
183
+ - !ruby/object:Gem::Dependency
184
+ name: webrick
185
+ requirement: !ruby/object:Gem::Requirement
186
+ requirements:
187
+ - - ">="
188
+ - !ruby/object:Gem::Version
189
+ version: '0'
190
+ type: :development
191
+ prerelease: false
192
+ version_requirements: !ruby/object:Gem::Requirement
193
+ requirements:
194
+ - - ">="
195
+ - !ruby/object:Gem::Version
196
+ version: '0'
183
197
  description: EXtended http(s) CONnections
184
198
  email: geemus@gmail.com
185
199
  executables: []
@@ -235,7 +249,7 @@ metadata:
235
249
  documentation_uri: https://github.com/excon/excon/blob/master/README.md
236
250
  source_code_uri: https://github.com/excon/excon
237
251
  wiki_uri: https://github.com/excon/excon/wiki
238
- post_install_message:
252
+ post_install_message:
239
253
  rdoc_options:
240
254
  - "--charset=UTF-8"
241
255
  require_paths:
@@ -251,8 +265,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
251
265
  - !ruby/object:Gem::Version
252
266
  version: '0'
253
267
  requirements: []
254
- rubygems_version: 3.0.3
255
- signing_key:
268
+ rubygems_version: 3.2.15
269
+ signing_key:
256
270
  specification_version: 4
257
271
  summary: speed, persistence, http(s)
258
272
  test_files: []