diff --git a/lib/net/http/persistent.rb b/lib/net/http/persistent.rb index 46eefb1..5f1e6c5 100644 --- a/lib/net/http/persistent.rb +++ b/lib/net/http/persistent.rb @@ -73,6 +73,8 @@ # #verify_callback :: For server certificate verification # #verify_depth :: Depth of certificate verification # #verify_mode :: How connections should be verified +# #verify_hostname :: Use hostname verification for server certificate +# during the handshake # # == Proxies # @@ -454,6 +456,21 @@ def self.detect_idle_timeout uri, max = 10 attr_reader :verify_mode + ## + # HTTPS verify_hostname. + # + # If a client sets this to true and enables SNI with SSLSocket#hostname=, + # the hostname verification on the server certificate is performed + # automatically during the handshake using + # OpenSSL::SSL.verify_certificate_identity(). + # + # You can set +verify_hostname+ as true to use hostname verification + # during the handshake. + # + # NOTE: This works with Ruby > 3.0. + + attr_reader :verify_hostname + ## # Creates a new Net::HTTP::Persistent. # @@ -513,6 +530,7 @@ def initialize name: nil, proxy: nil, pool_size: DEFAULT_POOL_SIZE @verify_callback = nil @verify_depth = nil @verify_mode = nil + @verify_hostname = nil @cert_store = nil @generation = 0 # incremented when proxy URI changes @@ -980,8 +998,10 @@ def ssl connection connection.min_version = @min_version if @min_version connection.max_version = @max_version if @max_version - connection.verify_depth = @verify_depth - connection.verify_mode = @verify_mode + connection.verify_depth = @verify_depth + connection.verify_mode = @verify_mode + connection.verify_hostname = @verify_hostname if + @verify_hostname && connection.respond_to?(:verify_hostname=) if OpenSSL::SSL::VERIFY_PEER == OpenSSL::SSL::VERIFY_NONE and not Object.const_defined?(:I_KNOW_THAT_OPENSSL_VERIFY_PEER_EQUALS_VERIFY_NONE_IS_WRONG) then @@ -1090,6 +1110,15 @@ def verify_mode= verify_mode reconnect_ssl end + ## + # Sets the HTTPS verify_hostname. Defaults to false. + + def verify_hostname= verify_hostname + @verify_hostname = verify_hostname + + reconnect_ssl + end + ## # SSL verification callback. diff --git a/test/test_net_http_persistent.rb b/test/test_net_http_persistent.rb index fc90e90..9147bfa 100644 --- a/test/test_net_http_persistent.rb +++ b/test/test_net_http_persistent.rb @@ -1259,6 +1259,7 @@ def test_ssl assert_equal OpenSSL::SSL::VERIFY_PEER, c.verify_mode assert_kind_of OpenSSL::X509::Store, c.cert_store assert_nil c.verify_callback + assert_nil c.verify_hostname if c.respond_to?(:verify_hostname) end def test_ssl_ca_file @@ -1342,6 +1343,21 @@ def test_ssl_verify_mode assert_equal OpenSSL::SSL::VERIFY_NONE, c.verify_mode end + def test_ssl_verify_hostname + skip 'OpenSSL is missing' unless HAVE_OPENSSL + + @http.verify_hostname = true + c = Net::HTTP.new 'localhost', 80 + + skip 'net/http doesn\'t provide verify_hostname= method' unless + c.respond_to?(:verify_hostname=) + + @http.ssl c + + assert c.use_ssl? + assert c.verify_hostname + end + def test_ssl_warning skip 'OpenSSL is missing' unless HAVE_OPENSSL