require File.expand_path('helper', File.dirname(__FILE__))
require 'webrick/https'
class TestSSL < Test::Unit::TestCase
include Helper
DIR = File.dirname(File.expand_path(__FILE__))
def setup
super
@serverpid = @client = nil
@verify_callback_called = false
setup_server
setup_client
@url = "https://localhost:#{serverport}/hello"
end
def teardown
super
end
def path(filename)
File.expand_path(filename, DIR)
end
def test_proxy_ssl
setup_proxyserver
escape_noproxy do
@client.proxy = proxyurl
@client.ssl_config.set_client_cert_file(path('client.cert'), path('client.key'))
@client.ssl_config.add_trust_ca(path('ca.cert'))
@client.ssl_config.add_trust_ca(path('subca.cert'))
@client.debug_dev = str = ""
assert_equal(200, @client.get(@url).status)
assert(/accept/ =~ @proxyio.string, 'proxy is not used')
assert(/Host: localhost:#{serverport}/ =~ str)
end
end
def test_options
cfg = @client.ssl_config
assert_nil(cfg.client_cert)
assert_nil(cfg.client_key)
assert_nil(cfg.client_ca)
assert_equal(OpenSSL::SSL::VERIFY_PEER | OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT, cfg.verify_mode)
assert_nil(cfg.verify_callback)
assert_nil(cfg.timeout)
expected_options = OpenSSL::SSL::OP_ALL | OpenSSL::SSL::OP_NO_SSLv2 | OpenSSL::SSL::OP_NO_SSLv3
expected_options &= ~OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS if defined?(OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS)
expected_options |= OpenSSL::SSL::OP_NO_COMPRESSION if defined?(OpenSSL::SSL::OP_NO_COMPRESSION)
assert_equal(expected_options, cfg.options)
assert_equal("ALL:!aNULL:!eNULL:!SSLv2", cfg.ciphers)
assert_instance_of(OpenSSL::X509::Store, cfg.cert_store)
end
unless defined?(HTTPClient::JRubySSLSocket)
# JRubySSLSocket does not support sync mode.
def test_sync
cfg = @client.ssl_config
cfg.set_client_cert_file(path('client.cert'), path('client.key'))
cfg.add_trust_ca(path('ca.cert'))
cfg.add_trust_ca(path('subca.cert'))
assert_equal("hello", @client.get_content(@url))
@client.socket_sync = false
@client.reset_all
assert_equal("hello", @client.get_content(@url))
end
end
def test_debug_dev
str = @client.debug_dev = ''
cfg = @client.ssl_config
cfg.client_cert = path("client.cert")
cfg.client_key = path("client.key")
cfg.add_trust_ca(path('ca.cert'))
cfg.add_trust_ca(path('subca.cert'))
assert_equal("hello", @client.get_content(@url))
assert(str.scan(/^hello$/)[0])
end
def test_verification_without_httpclient
raw_cert = "-----BEGIN CERTIFICATE-----\nMIIDOTCCAiGgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBCMRMwEQYKCZImiZPyLGQB\nGRYDb3JnMRkwFwYKCZImiZPyLGQBGRYJcnVieS1sYW5nMRAwDgYDVQQDDAdSdWJ5\nIENBMB4XDTE2MDgxMDE3MjEzNFoXDTE3MDgxMDE3MjEzNFowSzETMBEGCgmSJomT\n8ixkARkWA29yZzEZMBcGCgmSJomT8ixkARkWCXJ1YnktbGFuZzEZMBcGA1UEAwwQ\nUnVieSBjZXJ0aWZpY2F0ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB\nAJCfsSXpSMpmZCVa+ZCM+QDgomnhDlvnrGDq6pasTaIspGTXgws+7r8Dt/cNe6EH\nHJpRH2cGRiO4yPcfcT9eS4X7k8OC4f33wHfACOmLu6LeoNE8ujmSk6L6WzLUI+sE\nnLZbFrXxoAo4XHsm8vEG9C+jEoXZ1p+47wrAGaDwDQTnzlMy4dT9pRQEJP2G/Rry\nUkuZn8SUWmh3/YS78iaSzsNF1cgE1ealHOrPPFDjiCGDaH/LHyUPYlbFSLZ/B7Qx\nLxi5sePLcywWq/EJrmWpgeVTDjtNijsdKv/A3qkY+fm/oD0pzt7XsfJaP9YKNyJO\nQFdxWZeiPcDF+Hwf+IwSr+kCAwEAAaMxMC8wDgYDVR0PAQH/BAQDAgeAMB0GA1Ud\nDgQWBBQNvzYzJyXemGhxbA8NMXLolDnPyjANBgkqhkiG9w0BAQsFAAOCAQEARIJV\noKejGlOTn71QutnNnu07UtTu0IHs6YqjYzzND+m4JXLN+wvYm72AFUG0b1L7dRg0\niK8XjQrlNQNVqP1Mc6tffchy20neOPOHeiO6qTdRU8P2S8D3Uwe+1qhgxjfE+cWc\nwZmWxYK4HA8c58PxWMqrkr2QqXDplG9KWLvOgrtPGiLLZcQSKhvvB63QzItHBDU6\nRayiJY3oPkK/HrIvFlySqFqzWmuyknkciOFywEHQMz/tcSFJ2QFpPj/tBz9VXohH\nZ8KscmfhZrTPBjo+ky1lz/WraWoz4LMiLnkC2ABczWLRSawu+v3Irx1NFJngt05e\npqwtqIUeg7j+JLiTaA==\n-----END CERTIFICATE-----"
raw_ca_cert = "-----BEGIN CERTIFICATE-----\nMIIDYjCCAkqgAwIBAgIBATANBgkqhkiG9w0BAQsFADBCMRMwEQYKCZImiZPyLGQB\nGRYDb3JnMRkwFwYKCZImiZPyLGQBGRYJcnVieS1sYW5nMRAwDgYDVQQDDAdSdWJ5\nIENBMB4XDTE2MDgxMDE3MjA1NFoXDTE4MDgxMDE3MjA1NFowQjETMBEGCgmSJomT\n8ixkARkWA29yZzEZMBcGCgmSJomT8ixkARkWCXJ1YnktbGFuZzEQMA4GA1UEAwwH\nUnVieSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALKGwyM3Ejtl\npo7CqaDlS71gDZn3gm6IwWpmRMLJofSI9LCwAbjijSC2HvO0xUWoYW40FbzjnnEi\ngszsWyPwuQIx9t0bhuAyllNIfImmkaQkrikXKBKzia4jPnbc4iXPnfjuThjESFWl\ntfbN6y1B5TjKhD1KelfakUO+iMu8WlIA9NKQZYfJ/F3QSpP5Iqb3KN/jVifFbDV8\nbAl3Ln4rT2kTCKrZZcl1jmWsJv8jBw6+P7hk0/Mu0JeHAITsjbNbpHd8UXpCfbVs\nsNGZrBU4uJdZ2YTG+Y27/t25jFNQwb+TWbvig7rfdX2sjssuxa00BBxarC08tIVj\nZprM37KcNn8CAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\nAQYwHQYDVR0OBBYEFA2/NjMnJd6YaHFsDw0xcuiUOc/KMB8GA1UdIwQYMBYEFA2/\nNjMnJd6YaHFsDw0xcuiUOc/KMA0GCSqGSIb3DQEBCwUAA4IBAQAJSOw49XqvUll0\n3vU9EAO6yUdeZSsQENIfYbRMQgapbnN1vTyrUjPZkGC5hIE1pVdoHtEoUEICxIwy\nr6BKxiSLBDLp+rvIuDdzMkXIWdUVvTZguVRyKtM2gfnpsPLpVnv+stBmAW2SMyxm\nkymhOpkjdv3He+45uorB3tdfBS9VVomDEUJdg38UE1b5eXRQ3D6gG0iCPFzKszXg\nLoAYhGxtjCJaKlbzduMK0YO6aelgW1+XnVIKcA7DJ9egk5d/dFZBPFfwumwr9hTH\nh7/fp3Fr87weI+CkfmFyJZrsEBlXJBVuvPesMVHTh3Whm5kmCdWcBJU0QmSq42ZL\n72U0PXLR\n-----END CERTIFICATE-----"
ca_cert = ::OpenSSL::X509::Certificate.new(raw_ca_cert)
cert = ::OpenSSL::X509::Certificate.new(raw_cert)
store = ::OpenSSL::X509::Store.new
store.add_cert(ca_cert)
assert(store.verify(cert))
end
def test_verification
cfg = @client.ssl_config
cfg.verify_callback = method(:verify_callback).to_proc
begin
@verify_callback_called = false
@client.get(@url)
assert(false)
rescue OpenSSL::SSL::SSLError => ssle
assert_match(/(certificate verify failed|unable to find valid certification path to requested target)/, ssle.message)
assert(@verify_callback_called)
end
#
cfg.client_cert = path("client.cert")
cfg.client_key = path("client.key")
@verify_callback_called = false
begin
@client.get(@url)
assert(false)
rescue OpenSSL::SSL::SSLError => ssle
assert_match(/(certificate verify failed|unable to find valid certification path to requested target)/, ssle.message)
assert(@verify_callback_called)
end
#
cfg.add_trust_ca(path('ca.cert'))
@verify_callback_called = false
begin
@client.get(@url)
assert(false)
rescue OpenSSL::SSL::SSLError => ssle
assert_match(/(certificate verify failed|unable to find valid certification path to requested target)/, ssle.message)
assert(@verify_callback_called)
end
#
cfg.add_trust_ca(path('subca.cert'))
@verify_callback_called = false
assert_equal("hello", @client.get_content(@url))
assert(@verify_callback_called)
#
if false
# JRubySSLSocket does not support depth.
# Also on travis environment, verify_depth seems to not work properly.
cfg.verify_depth = 1 # 2 required: root-sub
@verify_callback_called = false
begin
@client.get(@url)
assert(false, "verify_depth is not supported? #{OpenSSL::OPENSSL_VERSION}")
rescue OpenSSL::SSL::SSLError => ssle
assert_match(/(certificate verify failed|unable to find valid certification path to requested target)/, ssle.message)
assert(@verify_callback_called)
end
#
cfg.verify_depth = 2 # 2 required: root-sub
@verify_callback_called = false
@client.get(@url)
assert(@verify_callback_called)
#
end
cfg.verify_depth = nil
cfg.cert_store = OpenSSL::X509::Store.new
cfg.verify_mode = OpenSSL::SSL::VERIFY_PEER
begin
@client.get_content(@url)
assert(false)
rescue OpenSSL::SSL::SSLError => ssle
assert_match(/(certificate verify failed|unable to find valid certification path to requested target)/, ssle.message)
end
#
cfg.verify_mode = nil
assert_equal("hello", @client.get_content(@url))
cfg.verify_mode = OpenSSL::SSL::VERIFY_NONE
assert_equal("hello", @client.get_content(@url))
end
def test_cert_store
cfg = @client.ssl_config
cfg.cert_store.add_cert(cert('ca.cert'))
begin
@client.get(@url)
assert(false)
rescue OpenSSL::SSL::SSLError => ssle
assert_match(/(certificate verify failed|unable to find valid certification path to requested target)/, ssle.message)
end
#
cfg.cert_store.add_cert(cert('subca.cert'))
assert_equal("hello", @client.get_content(@url))
cfg.clear_cert_store
begin
@client.get(@url)
assert(false)
rescue OpenSSL::SSL::SSLError => ssle
assert_match(/(certificate verify failed|unable to find valid certification path to requested target)/, ssle.message)
end
end
if defined?(HTTPClient::JRubySSLSocket)
def test_ciphers
cfg = @client.ssl_config
cfg.set_client_cert_file(path('client.cert'), path('client-pass.key'), 'pass4key')
cfg.add_trust_ca(path('ca.cert'))
cfg.add_trust_ca(path('subca.cert'))
cfg.timeout = 123
assert_equal("hello", @client.get_content(@url))
#
cfg.ciphers = []
begin
@client.get(@url)
assert(false)
rescue OpenSSL::SSL::SSLError => ssle
assert_match(/No appropriate protocol/, ssle.message)
end
#
cfg.ciphers = %w(TLS_RSA_WITH_AES_128_CBC_SHA)
assert_equal("hello", @client.get_content(@url))
#
cfg.ciphers = HTTPClient::SSLConfig::CIPHERS_DEFAULT
assert_equal("hello", @client.get_content(@url))
end
else
def test_ciphers
cfg = @client.ssl_config
cfg.set_client_cert_file(path('client.cert'), path('client-pass.key'), 'pass4key')
cfg.add_trust_ca(path('ca.cert'))
cfg.add_trust_ca(path('subca.cert'))
cfg.timeout = 123
assert_equal("hello", @client.get_content(@url))
#
cfg.ciphers = "!ALL"
begin
@client.get(@url)
assert(false)
rescue OpenSSL::SSL::SSLError => ssle
assert_match(/no cipher match/, ssle.message)
end
#
cfg.ciphers = "ALL"
assert_equal("hello", @client.get_content(@url))
#
cfg.ciphers = "DEFAULT"
assert_equal("hello", @client.get_content(@url))
end
end
def test_set_default_paths
assert_raise(OpenSSL::SSL::SSLError) do
@client.get(@url)
end
escape_env do
ENV['SSL_CERT_FILE'] = File.join(DIR, 'ca-chain.pem')
@client.ssl_config.set_default_paths
@client.get(@url)
end
end
def test_no_sslv3
teardown_server
setup_server_with_ssl_version(:SSLv3)
assert_raise(OpenSSL::SSL::SSLError) do
@client.ssl_config.verify_mode = nil
@client.get("https://localhost:#{serverport}/hello")
end
end
def test_allow_tlsv1
teardown_server
setup_server_with_ssl_version(:TLSv1)
assert_nothing_raised do
@client.ssl_config.verify_mode = nil
@client.get("https://localhost:#{serverport}/hello")
end
end
def test_use_higher_TLS
omit('TODO: it does not pass with Java 7 or old openssl ')
teardown_server
setup_server_with_ssl_version('TLSv1_2')
assert_nothing_raised do
@client.ssl_config.verify_mode = nil
@client.get("https://localhost:#{serverport}/hello")
# TODO: should check JRubySSLSocket.ssl_socket.getSession.getProtocol
# but it's not thread safe. How can I return protocol version to the caller?
end
end
VERIFY_TEST_CERT_LOCALHOST = OpenSSL::X509::Certificate.new(<<-EOS)
-----BEGIN CERTIFICATE-----
MIIB9jCCAV+gAwIBAgIJAIH8Gsm4PcNKMA0GCSqGSIb3DQEBCwUAMBQxEjAQBgNV
BAMMCWxvY2FsaG9zdDAeFw0xNjA4MTgxMDI2MDVaFw00NDAxMDMxMDI2MDVaMBQx
EjAQBgNVBAMMCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
p7D8q0lcx5EZEV5+zPnQsxrbft5xyhH/MCStbH46DRATGPNSOaLRCG5r8gTKQzpD
4swGrQFYe2ienQ+7o4aEHErsXp4O/EmDKeiXWWrMqPr23r3HOBDebuynC/sCwy7N
epnX9u1VLB03eo+suj4d86OoOF+o11t9ZP+GA29Rsf8CAwEAAaNQME4wHQYDVR0O
BBYEFIxsJuPVvd5KKFcAvHGSeKSsWiUJMB8GA1UdIwQYMBaAFIxsJuPVvd5KKFcA
vHGSeKSsWiUJMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADgYEAMJaVCrrM
SM2I06Vr4BL+jtDFhZh3HmJFEDpwEFQ5Y9hduwdUGRBGCpkuea3fE2FKwWW9gLM1
w7rFMzYFtCEqm78dJWIU79MRy0wjO4LgtYfoikgBh6JKWuV5ed/+L3sLyLG0ZTtv
lrD7lzDtXgwvj007PxDoYRp3JwYzKRmTbH8=
-----END CERTIFICATE-----
EOS
VERIFY_TEST_CERT_FOO_DOMAIN = OpenSSL::X509::Certificate.new(<<-EOS)
-----BEGIN CERTIFICATE-----
MIIB8jCCAVugAwIBAgIJAL/od7Whx7VTMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNV
BAMMB2Zvby5jb20wHhcNMTYwODE4MTAyMzUyWhcNNDQwMTAzMTAyMzUyWjASMRAw
DgYDVQQDDAdmb28uY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnsPyr
SVzHkRkRXn7M+dCzGtt+3nHKEf8wJK1sfjoNEBMY81I5otEIbmvyBMpDOkPizAat
AVh7aJ6dD7ujhoQcSuxeng78SYMp6JdZasyo+vbevcc4EN5u7KcL+wLDLs16mdf2
7VUsHTd6j6y6Ph3zo6g4X6jXW31k/4YDb1Gx/wIDAQABo1AwTjAdBgNVHQ4EFgQU
jGwm49W93kooVwC8cZJ4pKxaJQkwHwYDVR0jBBgwFoAUjGwm49W93kooVwC8cZJ4
pKxaJQkwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOBgQCVKTvfxx+yezuR
5WpVKw1E9qabKOYFB5TqdHMHreRubMJTaoZC+YzhcCwtyLlAA9+axKINAiMM8T+z
jjfOHQSa2GS2TaaVDJWmXIgsAlEbjd2BEiQF0LZYGJRG9pyq0WbTV+CyFdrghjcO
xX/t7OG7NfOG9dhv3J+5SX10S5V5Dg==
-----END CERTIFICATE-----
EOS
VERIFY_TEST_CERT_ALT_NAME = OpenSSL::X509::Certificate.new(<<-EOS)
-----BEGIN CERTIFICATE-----
MIICDDCCAXWgAwIBAgIJAOxXY4nOwxhGMA0GCSqGSIb3DQEBCwUAMBQxEjAQBgNV
BAMMCWxvY2FsaG9zdDAeFw0xNjA4MTgxMDM0NTJaFw00NDAxMDMxMDM0NTJaMBQx
EjAQBgNVBAMMCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
p7D8q0lcx5EZEV5+zPnQsxrbft5xyhH/MCStbH46DRATGPNSOaLRCG5r8gTKQzpD
4swGrQFYe2ienQ+7o4aEHErsXp4O/EmDKeiXWWrMqPr23r3HOBDebuynC/sCwy7N
epnX9u1VLB03eo+suj4d86OoOF+o11t9ZP+GA29Rsf8CAwEAAaNmMGQwFAYDVR0R
BA0wC4IJKi5mb28uY29tMB0GA1UdDgQWBBSMbCbj1b3eSihXALxxknikrFolCTAf
BgNVHSMEGDAWgBSMbCbj1b3eSihXALxxknikrFolCTAMBgNVHRMEBTADAQH/MA0G
CSqGSIb3DQEBCwUAA4GBADJlKNFuOnsDIhHGW72HuQw4naN6lM3eZE9JJ+UF/XIF
ghGtgqw+00Yy5wMFc1K2Wm4p5NymmDfC/P1FOe34bpxt9/IWm6mEoIWoodC3N4Cm
PtnSS1/CRWzVIPGMglTGGDcUc70tfeAWgyTxgcNQd4vTFtnN0f0RDdaXa8kfKMTw
-----END CERTIFICATE-----
EOS
VERIFY_TEST_PKEY = OpenSSL::PKey::RSA.new(<<-EOS)
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQCnsPyrSVzHkRkRXn7M+dCzGtt+3nHKEf8wJK1sfjoNEBMY81I5
otEIbmvyBMpDOkPizAatAVh7aJ6dD7ujhoQcSuxeng78SYMp6JdZasyo+vbevcc4
EN5u7KcL+wLDLs16mdf27VUsHTd6j6y6Ph3zo6g4X6jXW31k/4YDb1Gx/wIDAQAB
AoGAe0RHx+WKtQx8/96VmTl951qzxMPho2etTYd4kAsNwzJwx2N9qu57eBYrdWF+
CQMYievucFhP4Y+bINtC1Eb6btz9TCUwjCfeIxfGRoFf3cxVmxlsRJJmN1kSZlu1
yYlcMVuP4noeFIMQBRrt5pyLCx2Z9A01NCQT4Y6VoREBIeECQQDWeNhsL6xkrmdB
M9+zl+SqHdNKhgKwMdp74+UNnAV9I8GB7bGlOWhc83aqMLgS+JBDFXcmNF/KawTR
zcnkod5xAkEAyClFgr3lZQSnwUwoA/AOcyW0+H63taaaXS/g8n3H8ENK6kL4ldUx
IgCk2ekbQ5Y3S2WScIGXNxMOza9MlsOvbwJAPUtoPvMZB+U4KVBT/JXKijvf6QqH
tidpU8L78XnHr84KPcHa5WeUxgvmvBkUYoebYzC9TrPlNIqFZBi2PJtuYQJBAMda
E5j7eJT75fhm2RPS6xFT5MH5sw6AOA3HucrJ63AoFVzsBpl0E9NBwO4ndLgDzF6T
cx4Kc4iuunewuB8QFpECQQCfvsHCjIJ/X4kiqeBzxDq2GR/oDgQkOzY+4H9U7Lwl
e61RBaxk5OHOA0bLtvJblV6NL72ZEZhX60wAWbrOPhpT
-----END RSA PRIVATE KEY-----
EOS
def test_post_connection_check
teardown_server
setup_server_with_server_cert(nil, VERIFY_TEST_CERT_LOCALHOST, VERIFY_TEST_PKEY)
file = Tempfile.new('cert')
File.write(file.path, VERIFY_TEST_CERT_LOCALHOST.to_pem)
@client.ssl_config.add_trust_ca(file.path)
assert_nothing_raised do
@client.get("https://localhost:#{serverport}/hello")
end
@client.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE
assert_nothing_raised do
@client.get("https://localhost:#{serverport}/hello")
end
@client.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_PEER
teardown_server
setup_server_with_server_cert(nil, VERIFY_TEST_CERT_FOO_DOMAIN, VERIFY_TEST_PKEY)
File.write(file.path, VERIFY_TEST_CERT_FOO_DOMAIN.to_pem)
@client.ssl_config.add_trust_ca(file.path)
assert_raises(OpenSSL::SSL::SSLError) do
@client.get("https://localhost:#{serverport}/hello")
end
@client.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE
assert_nothing_raised do
@client.get("https://localhost:#{serverport}/hello")
end
@client.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_PEER
teardown_server
setup_server_with_server_cert(nil, VERIFY_TEST_CERT_ALT_NAME, VERIFY_TEST_PKEY)
File.write(file.path, VERIFY_TEST_CERT_ALT_NAME.to_pem)
@client.ssl_config.add_trust_ca(file.path)
assert_raises(OpenSSL::SSL::SSLError) do
@client.get("https://localhost:#{serverport}/hello")
end
@client.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE
assert_nothing_raised do
@client.get("https://localhost:#{serverport}/hello")
end
@client.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_PEER
end
def test_x509_store_add_cert_prepend
store = OpenSSL::X509::Store.new
assert_equal(store, store.add_cert(OpenSSL::X509::Certificate.new(VERIFY_TEST_CERT_LOCALHOST)))
end
def test_tcp_keepalive
@client.tcp_keepalive = true
@client.ssl_config.add_trust_ca(path('ca-chain.pem'))
@client.get_content(@url)
# expecting HTTP keepalive caches the socket
session = @client.instance_variable_get(:@session_manager).send(:get_cached_session, HTTPClient::Site.new(URI.parse(@url)))
socket = session.instance_variable_get(:@socket).instance_variable_get(:@socket)
assert_true(session.tcp_keepalive)
if RUBY_ENGINE == 'jruby'
assert_true(socket.getKeepAlive())
else
assert_equal(Socket::SO_KEEPALIVE, socket.getsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE).optname)
end
end
def test_timeout
url = "https://localhost:#{serverport}/"
@client.ssl_config.add_trust_ca(path('ca-chain.pem'))
assert_equal('sleep', @client.get_content(url + 'sleep?sec=2'))
@client.receive_timeout = 1
@client.reset_all
assert_equal('sleep', @client.get_content(url + 'sleep?sec=0'))
start = Time.now
assert_raise(HTTPClient::ReceiveTimeoutError) do
@client.get_content(url + 'sleep?sec=5')
end
if Time.now - start > 3
# before #342 it detected timeout when IO was freed
fail 'timeout does not work'
end
@client.receive_timeout = 3
@client.reset_all
assert_equal('sleep', @client.get_content(url + 'sleep?sec=2'))
end
private
def cert(filename)
OpenSSL::X509::Certificate.new(File.read(File.join(DIR, filename)))
end
def key(filename)
OpenSSL::PKey::RSA.new(File.read(File.join(DIR, filename)))
end
def q(str)
%Q["#{str}"]
end
def setup_server
logger = Logger.new(STDERR)
logger.level = Logger::Severity::FATAL # avoid logging SSLError (ERROR level)
@server = WEBrick::HTTPServer.new(
:BindAddress => "localhost",
:Logger => logger,
:Port => 0,
:AccessLog => [],
:DocumentRoot => DIR,
:SSLEnable => true,
:SSLCACertificateFile => File.join(DIR, 'ca.cert'),
:SSLCertificate => cert('server.cert'),
:SSLPrivateKey => key('server.key'),
:SSLVerifyClient => nil, #OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT|OpenSSL::SSL::VERIFY_PEER,
:SSLClientCA => cert('ca.cert'),
:SSLCertName => nil
)
@serverport = @server.config[:Port]
[:hello, :sleep].each do |sym|
@server.mount(
"/#{sym}",
WEBrick::HTTPServlet::ProcHandler.new(method("do_#{sym}").to_proc)
)
end
@server_thread = start_server_thread(@server)
end
def setup_server_with_ssl_version(ssl_version)
# JRubyOpenSSL does not support "TLSv1_2" as an known version, and some JCE provides TLS v1.2 as "TLSv1.2" not "TLSv1_2"
if RUBY_ENGINE == 'jruby' && ['TLSv1_1', 'TLSv1_2'].include?(ssl_version)
ssl_version = ssl_version.tr('_', '.')
end
logger = Logger.new(STDERR)
logger.level = Logger::Severity::FATAL # avoid logging SSLError (ERROR level)
@server = WEBrick::HTTPServer.new(
:BindAddress => "localhost",
:Logger => logger,
:Port => 0,
:AccessLog => [],
:DocumentRoot => DIR,
:SSLEnable => true,
:SSLCACertificateFile => File.join(DIR, 'ca.cert'),
:SSLCertificate => cert('server.cert'),
:SSLPrivateKey => key('server.key')
)
@server.ssl_context.ssl_version = ssl_version
@serverport = @server.config[:Port]
[:hello].each do |sym|
@server.mount(
"/#{sym}",
WEBrick::HTTPServlet::ProcHandler.new(method("do_#{sym}").to_proc)
)
end
@server_thread = start_server_thread(@server)
end
def setup_server_with_server_cert(ca_cert, server_cert, server_key)
logger = Logger.new(STDERR)
logger.level = Logger::Severity::FATAL # avoid logging SSLError (ERROR level)
@server = WEBrick::HTTPServer.new(
:BindAddress => "localhost",
:Logger => logger,
:Port => 0,
:AccessLog => [],
:DocumentRoot => DIR,
:SSLEnable => true,
:SSLCACertificateFile => ca_cert,
:SSLCertificate => server_cert,
:SSLPrivateKey => server_key,
:SSLVerifyClient => nil,
:SSLClientCA => nil,
:SSLCertName => nil
)
@serverport = @server.config[:Port]
[:hello].each do |sym|
@server.mount(
"/#{sym}",
WEBrick::HTTPServlet::ProcHandler.new(method("do_#{sym}").to_proc)
)
end
@server_thread = start_server_thread(@server)
end
def do_hello(req, res)
res['content-type'] = 'text/html'
res.body = "hello"
end
def do_sleep(req, res)
sec = req.query['sec'].to_i
sleep sec
res['content-type'] = 'text/html'
res.body = "sleep"
end
def start_server_thread(server)
t = Thread.new {
Thread.current.abort_on_exception = true
server.start
}
while server.status != :Running
sleep 0.1
unless t.alive?
t.join
raise
end
end
t
end
def verify_callback(ok, cert)
@verify_callback_called = true
p ["client", ok, cert] if $DEBUG
ok
end
end
Copyright 2K16 - 2K18 Indonesian Hacker Rulez