我正在为一个项目编写集成测试代码,它在服务器上设置了一个新的安全虚拟主机。服务器支持 SNI。但是,由于测试代码是在开发环境中运行的,因此主机名的 DNS 记录没有正确设置。因此,为了检查是否返回了正确的证书,使用 curl 我必须这样做
curl -i --cacert sample_ca.crt --resolve example.com:443:1.2.3.4 https://example.com/
或通过 openssl 实用程序
openssl s_client -connect 1.2.3.4:443 -servername example.com
我设法找到了在 ruby 中重现用例的参考,如下所示
context = OpenSSL::SSL::SSLContext.new
context.ca_file = 'sample_ca.crt'
context.verify_mode = OpenSSL::SSL::VERIFY_PEER
tcp_client = TCPSocket.new('1.2.3.4', 443)
ssl_client = OpenSSL::SSL::SSLSocket.new(tcp_client, context)
ssl_client.hostname = 'example.com'
ssl_client.connect
cert = OpenSSL::X509::Certificate.new(ssl_client.peer_cert)
pkey = OpenSSL::PKey.read(File.read(''sample_pkey.key))
if cert.check_private_key(pkey) then
ssl_client.print "GET #{uri} HTTP/1.1\r\n"
ssl_client.print "Host: example.com\r\n\r\n"
header, body = ssl_client.read.split("\r\n\r\n")
else
header, body = ['', '']
end
ssl_client.sysclose
tcp_client.close
我最初想用纯 net/http 来实现它,但是除非我为 example.com 正确设置了 DNS(我无权访问 DNS 设置,所以我通过编辑我的主机文件来作弊),它不会无论我如何尝试都可以工作。考虑到我对 ruby 比较陌生,我想知道是否有办法只使用 net/http?