lib/httpx/io/ssl.rb in httpx-0.19.8 vs lib/httpx/io/ssl.rb in httpx-0.20.0
- old
+ new
@@ -2,12 +2,15 @@
require "openssl"
module HTTPX
TLSError = OpenSSL::SSL::SSLError
+ IPRegex = Regexp.union(Resolv::IPv4::Regex, Resolv::IPv6::Regex)
class SSL < TCP
+ using RegexpExtensions unless Regexp.method_defined?(:match?)
+
TLS_OPTIONS = if OpenSSL::SSL::SSLContext.instance_methods.include?(:alpn_protocols)
{ alpn_protocols: %w[h2 http/1.1].freeze }.freeze
else
{}.freeze
end
@@ -17,10 +20,12 @@
@ctx = OpenSSL::SSL::SSLContext.new
ctx_options = TLS_OPTIONS.merge(options.ssl)
@sni_hostname = ctx_options.delete(:hostname) || @hostname
@ctx.set_params(ctx_options) unless ctx_options.empty?
@state = :negotiated if @keep_open
+
+ @hostname_is_ip = IPRegex.match?(@sni_hostname)
end
def protocol
@io.alpn_protocol || super
rescue StandardError
@@ -54,21 +59,21 @@
return if @state == :negotiated ||
@state != :connected
unless @io.is_a?(OpenSSL::SSL::SSLSocket)
@io = OpenSSL::SSL::SSLSocket.new(@io, @ctx)
- @io.hostname = @sni_hostname
+ @io.hostname = @sni_hostname unless @hostname_is_ip
@io.sync_close = true
end
try_ssl_connect
end
if RUBY_VERSION < "2.3"
# :nocov:
def try_ssl_connect
@io.connect_nonblock
- @io.post_connection_check(@sni_hostname) if @ctx.verify_mode != OpenSSL::SSL::VERIFY_NONE
+ @io.post_connection_check(@sni_hostname) if @ctx.verify_mode != OpenSSL::SSL::VERIFY_NONE && !@hostname_is_ip
transition(:negotiated)
@interests = :w
rescue ::IO::WaitReadable
@interests = :r
rescue ::IO::WaitWritable
@@ -96,10 +101,10 @@
return
when :wait_writable
@interests = :w
return
end
- @io.post_connection_check(@sni_hostname) if @ctx.verify_mode != OpenSSL::SSL::VERIFY_NONE
+ @io.post_connection_check(@sni_hostname) if @ctx.verify_mode != OpenSSL::SSL::VERIFY_NONE && !@hostname_is_ip
transition(:negotiated)
@interests = :w
end
# :nocov: