From 4d3a3b1f7b16595febbbd39eeed72b2663549014 Mon Sep 17 00:00:00 2001 From: Mattias Holmlund Date: Thu, 8 Mar 2018 15:06:09 +0100 Subject: [PATCH] fix: Handle ipv6 addresses in host-header correctly with TLS (#53) When a url uses an ipv6-addresses as the host part, the host-header of the request will be [::1]:3000 (for ipv6 address ::1). To verify the IP address against a TLS certificate, we need to extract the IP-address correctly. Requires node with https://github.com/nodejs/node/issues/14736 resolved to work. * Add ca certificate and check that certs are valid * Add tests for certificates with ipv6 addresses * Fix check for supported node version * Skip test if ipv6 is not available --- lib/_http_agent.js | 41 ++++++++++----- test/fixtures/agenttest-cert.pem | 29 +++++----- test/fixtures/agenttest-key.pem | 26 ++++----- test/fixtures/ca.cnf | 28 ++++++++++ test/fixtures/ca.key | 28 ++++++++++ test/fixtures/ca.pem | 20 +++++++ test/fixtures/genkey.sh | 23 ++++++-- test/fixtures/server.cnf | 35 +++++++++++++ test/https_agent.test.js | 4 +- test/test-https-ipv6.test.js | 90 ++++++++++++++++++++++++++++++++ 10 files changed, 279 insertions(+), 45 deletions(-) create mode 100644 test/fixtures/ca.cnf create mode 100644 test/fixtures/ca.key create mode 100644 test/fixtures/ca.pem mode change 100644 => 100755 test/fixtures/genkey.sh create mode 100644 test/fixtures/server.cnf create mode 100644 test/test-https-ipv6.test.js diff --git a/lib/_http_agent.js b/lib/_http_agent.js index 604a884..83f1d11 100644 --- a/lib/_http_agent.js +++ b/lib/_http_agent.js @@ -196,13 +196,8 @@ Agent.prototype.addRequest = function addRequest(req, options, port/*legacy*/, options = util._extend({}, options); options = util._extend(options, this.options); - if (!options.servername) { - options.servername = options.host; - const hostHeader = req.getHeader('host'); - if (hostHeader) { - options.servername = hostHeader.replace(/:.*$/, ''); - } - } + if (!options.servername) + options.servername = calculateServerName(options, req); var name = this.getName(options); if (!this.sockets[name]) { @@ -258,13 +253,8 @@ Agent.prototype.createSocket = function createSocket(req, options, cb) { options = util._extend({}, options); options = util._extend(options, self.options); - if (!options.servername) { - options.servername = options.host; - const hostHeader = req.getHeader('host'); - if (hostHeader) { - options.servername = hostHeader.replace(/:.*$/, ''); - } - } + if (!options.servername) + options.servername = calculateServerName(options, req); var name = self.getName(options); options._agentKey = name; @@ -342,6 +332,29 @@ Agent.prototype.createSocket = function createSocket(req, options, cb) { } }; +function calculateServerName(options, req) { + let servername = options.host; + const hostHeader = req.getHeader('host'); + if (hostHeader) { + // abc => abc + // abc:123 => abc + // [::1] => ::1 + // [::1]:123 => ::1 + if (hostHeader.startsWith('[')) { + const index = hostHeader.indexOf(']'); + if (index === -1) { + // Leading '[', but no ']'. Need to do something... + servername = hostHeader; + } else { + servername = hostHeader.substr(1, index - 1); + } + } else { + servername = hostHeader.split(':', 1)[0]; + } + } + return servername; +} + Agent.prototype.removeSocket = function removeSocket(s, options) { var name = this.getName(options); debug('removeSocket', name, 'writable:', s.writable); diff --git a/test/fixtures/agenttest-cert.pem b/test/fixtures/agenttest-cert.pem index bce2f21..acc0412 100644 --- a/test/fixtures/agenttest-cert.pem +++ b/test/fixtures/agenttest-cert.pem @@ -1,15 +1,18 @@ -----BEGIN CERTIFICATE----- -MIICaTCCAdICCQDsGV9pOh7bwjANBgkqhkiG9w0BAQUFADB5MQswCQYDVQQGEwJB -VTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0 -cyBQdHkgTHRkMRAwDgYDVQQDEwdmZW5nbWsyMSAwHgYJKoZIhvcNAQkBFhFmZW5n -bWsyQGdtYWlsLmNvbTAeFw0xMzAzMjIwNzQ2MjBaFw0xMzA0MjEwNzQ2MjBaMHkx -CzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRl -cm5ldCBXaWRnaXRzIFB0eSBMdGQxEDAOBgNVBAMTB2ZlbmdtazIxIDAeBgkqhkiG -9w0BCQEWEWZlbmdtazJAZ21haWwuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB -iQKBgQCjZLaMW373Af9BkrGQ1il8Focy/DZUz4YXXMAiBWFE8dudrdVPQaDPoYv2 -p7ZJr8K0UxGf4svdhsqWkoQ+LcYaHn1Ffez5SR/6Vbic4k8w30RR+a5Iyf2K9ag9 -0jCqbBlU8roSQ2fx52oMlbhTQsodcLikoCs9DqYSptmlAmnOCwIDAQABMA0GCSqG -SIb3DQEBBQUAA4GBAJodC7/MlaUYlrG+7PqI3B7226sk2TrdllJOkDVz+bCjQ9HD -/ngeHMKbAh5t4+A5zXtTpPM0XTE6vMmkMsXGNUj1P8BHWPBfGM9+80NphhHX8CzE -qXUvbxHo0TM3qx434OjkDH1ksIBBGUoJDr7YVzhw4guYFvHBnGOzDHdh7QiM +MIIC+jCCAeKgAwIBAgIJAMuPffHFVqVzMA0GCSqGSIb3DQEBCwUAMGExCzAJBgNV +BAYTAlNFMRIwEAYDVQQIDAlTdG9ja2hvbG0xEjAQBgNVBAcMCVN0b2NraG9sbTEL +MAkGA1UEAwwCY2ExHTAbBgkqhkiG9w0BCQEWDmNhQGV4YW1wbGUuY29tMB4XDTE3 +MTAyMDExMzQwOFoXDTIwMDcxNTExMzQwOFowUjELMAkGA1UEBhMCU0UxEjAQBgNV +BAgMCVN0b2NraG9sbTESMBAGA1UEBwwJU3RvY2tob2xtMRswGQYDVQQDDBJhZ2Vu +dGtlZXBhbGl2ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOWRbiod +/IXLR3z3bDfN4DMqzXn8A5+V7Qz3Z/FpgMoQxV/fUgvJIh4l6CwCN+aBa9pBvRUf +U77CnGuSn1uQAKIRWvlJ5KqrzHqCyU03bFRcAPDwFDFrD5+49Ici5M5tTSuIsj7P +jZuVIOL4oXZ4Biq8P8KGFl9g9Bs8Ttj4trmPAgMBAAGjSDBGMCwGA1UdEQQlMCOH +BH8AAAGHEAAAAAAAAAAAAAAAAAAAAAGCCWxvY2FsaG9zdDAJBgNVHRMEAjAAMAsG +A1UdDwQEAwIF4DANBgkqhkiG9w0BAQsFAAOCAQEAsD/3f+HO1FJo9kOSitaJV4z7 ++5NLX3CRpn9vYJU1D6KFLyHJ2Nzuv8lJm0lnMhkO85xfDNCOotokK236vFTFQZpT +VQMZraHzU7aJ0xHC01vXMMXrtY1IoBWZQoyONoU4texmoHcYte408innxHcfTzuf +xFE6id1R9KdrHe/tIt2b0E+7aBCh3RUSP9uEx1/HgNkAEGULo9JAh3JaRJT5ft3M +xCqMGf9RsqUhENOJ/UonEHoaR8gT5QqOrbwq9HezRDSK2LyppCEZ9NE7Yezm3HIP +BhtYMKeNMlwZigyJ0k/ygWXRADSzwcSbrhuB/QZoDdxqhinJCTS4OestY1nQoA== -----END CERTIFICATE----- diff --git a/test/fixtures/agenttest-key.pem b/test/fixtures/agenttest-key.pem index 747102b..77abd3f 100644 --- a/test/fixtures/agenttest-key.pem +++ b/test/fixtures/agenttest-key.pem @@ -1,15 +1,15 @@ -----BEGIN RSA PRIVATE KEY----- -MIICXAIBAAKBgQCjZLaMW373Af9BkrGQ1il8Focy/DZUz4YXXMAiBWFE8dudrdVP -QaDPoYv2p7ZJr8K0UxGf4svdhsqWkoQ+LcYaHn1Ffez5SR/6Vbic4k8w30RR+a5I -yf2K9ag90jCqbBlU8roSQ2fx52oMlbhTQsodcLikoCs9DqYSptmlAmnOCwIDAQAB -AoGAKBW3KyvvNA4LXzzrzwqbVtP4CywQ8DGRRf39LNuBB3cGV+KjqDQDjaymN7bh -Y6Z47+BJPJ5ZQVmmLdZ4FwEHzlA1PhoeIhJ5jXB1orqiadkEn+4lRXR3twexpvzo -GU/2VgN80hVwQQhEKH5ZFXFpIwle+c9TD34L1s8XhqHrEtECQQDSMHfVEsmjyjBY -Ff5b0Q42bN5EsgiMTmV0T1/13aGnAvvILrW1WQ74h43Mb3hQV6KXEvUzui/HWHg+ -+fPJHAqfAkEAxwFDPZhsdatjnBPfQu6KKf8VZwKgUhwglCgR0ofceQwwsb5yhg9K -/lej2HMNil6Jtq50oiZc55akMvltXxuxFQJBAKCfTVPU0aaLAjquQ/yiW3wX4hsY -+hNObZVeevSGc9wPGZ22pEF7V0dxP1k07fpnneZZJGxtIcnyv6FQnY3YEf0CQBJd -a3cjud6iEm805kWm/dkiUTdQZrstHVSO3hYvs4j4NwYwLSFyB9mw/M3c0EMUtmDF -eL3+DFTS8hRCMHW2eIECQEuKwy8HOJIoM/BbIlkXupeMypD0Y/aIQ+YLinunHK7v -Cq5mFf6oALSTpDQm2yjmBS3d7+geZ4YTH/iUq1q8nvQ= +MIICXgIBAAKBgQDlkW4qHfyFy0d892w3zeAzKs15/AOfle0M92fxaYDKEMVf31IL +ySIeJegsAjfmgWvaQb0VH1O+wpxrkp9bkACiEVr5SeSqq8x6gslNN2xUXADw8BQx +aw+fuPSHIuTObU0riLI+z42blSDi+KF2eAYqvD/ChhZfYPQbPE7Y+La5jwIDAQAB +AoGAf4Icb1ZCeUnkRhvjRseZ/LGMeXGpzYznoqkUWblg6FsSVeLjXlp0Ecy6PR9q +TySZdBvJWx8QU8ciPHmu+5trTYwHyTcoj4vZ7yIi5bgJLzIcbKv7zeeiKF+u9+iX +VkLHVdGXWkpw+AsgKZWHfAp9hKcUnSMGW72bU7buUXe0dLkCQQD0xoJKkc4WeLxb +cEqrmks9cIAVxn9QQpqsP5E174Pe6Nq+YPpCiz3vURPb/uTM487NhOX4qwIbmn/F +8lW+4e6rAkEA8Bhl33lMPy3mSD8t+Vl8Nzd96OSl4O9MI1X//hwAK3Unpir0POzb +LprTftVK2w015vFZlWe3Smf3R8pFMllQrQJBAKeX4027Vyf7srvIvteP5URD6u79 +4d3KPK0DOSF8xQWy2VLQg4lcXSOml7phY7cFo2sEO5FvRRoxRpr5ucvgVdECQQDf +6tEvvw+WKLeJD6tPzt4jHRTHXF87zdFjbzRlCDY8UXHd7leEbp3n9CtlMYUzkDmC +HfsfdPAja5zajlFEqLmtAkEAsxUKoiBkrJ1TQUmepETKtPNk6eNU8O3Gf484E2Aa +ooNrBva7VvyuOw+OgQKnXZ4sH37uNkS1KQHDp/x5kZX+DQ== -----END RSA PRIVATE KEY----- diff --git a/test/fixtures/ca.cnf b/test/fixtures/ca.cnf new file mode 100644 index 0000000..a203619 --- /dev/null +++ b/test/fixtures/ca.cnf @@ -0,0 +1,28 @@ +[ ca ] +default_ca = CA_default + +[ CA_default ] +serial = ca-serial +crl = ca-crl.pem +database = ca-database.txt +name_opt = CA_default +cert_opt = CA_default +default_crl_days = 9999 +default_md = md5 + +[ req ] +default_bits = 2048 +days = 9999 +distinguished_name = req_distinguished_name +attributes = req_attributes +prompt = no + +[ req_distinguished_name ] +C = SE +ST = Stockholm +L = Stockholm +CN = ca +emailAddress = ca@example.com + +[ req_attributes ] +challengePassword = test \ No newline at end of file diff --git a/test/fixtures/ca.key b/test/fixtures/ca.key new file mode 100644 index 0000000..894487d --- /dev/null +++ b/test/fixtures/ca.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDirhR/SK8uxDp3 +pZANtV3IeTKFwLdA2G6xNgo7isgCG+OnzEN8zKePSL6vSoUJnYH5KYmNOlO2zc0b +qrvUQWd375WB/zl3MEjJS1+taLxyO+lFlq7fPoB/V4XO+s0l2cA4PyGAkCcisJ5s +LCI2oaxrbjkOPzHC4W05Cj8Svn440kf/2faeHYIdhHGVs36t6nb5d2WnivPvmucp +FOShhK+LFBxL7AQIdoeDdpkjdukT9CnnRT5S1LUq6ReXzjhYqhGU+nmn6GqznpPn +cnZFIRdBQvM3b5BL2NLb5VzglUa2fNYqYGKNGgzj9G/depW8QHOxk3VUJS7vaY0z +PlkTgPO3AgMBAAECggEBAMk4Pnm+y8N37W7ISVfh555N98tDh2jIt3oXvn2cdG9q +0mvhpwbhpNxMdvij7fTbHMVRWglD/YwIpEorBREl/fM5ej4rkZd8BSCrCAOnNaEy +DaD4YcNKeEaSKvXRLMqswTUs1VCKpjLlFbxwcO6OFcBH194Nut6DvbEkp1i8QM+u +LwF4Sqm6r/CbJMMG6RSamb+nwSu2s8HH+B/n+ba8rNQNqJIwxueGuZGSzQ82SoYp +Mtq8v/Lb0Ea+OeN6cG1zhHe5vwT8o/vfPzkH50tI6kq4lltai3MaqxcaV3XRc8R0 +lndGL4Rf/Q+AiF2nYgZZYpVdkbW06e7GSFfE7OmLPgECgYEA9HKuOHklNwzsOyDo +KMQ6iSGCPwUQSBgyNOF/uu+wwPnOxGU3GaSsC8QFNsgKlDfXjTFefJwdzhvGB5ES +JQxIYwa1TwCODavrNow7LUIExC8P6NI7DyWOeZZenVIHhBEejrbzMaiAS0/hklL8 +EZpeNniQHED/S37kWZdEp3SE+1MCgYEA7WRxiHxARu54A1lIv2b+3NSSS7lTqweW +ELswyl6CGm2HQlt4iWccSqM5xMb9idJPDehijj92rXR1k64SurEL2OQstKg3ivfq +TcKKyVmj1WDm2v56LXIpjAb7Iy6ewbRmC9WWs4Wfqf6KK7Nm3FzDpKf5Uarqm3eh +Z0vvQMPpfY0CgYEAogkKt2CGbLFiPeeYPL2mV5QgtAl1O3TegvMfKhkMPz7X8pNt +LNBdQwdStXdwm8NQXMVm7o7FqwP6BrYBIxG7QfkGYjHp9+IH7oaSC3QBmNHhZ+FD +SM0KXkpwuTPQy5hVeyCGoFojgMiYq9faQwjifpT4YeIr2C1qzIBa/+1a4QUCgYEA +5+PgC2TkHOXBEfRbXaysdOao6ZNlKYJFkp5oMKZVDJ/FKorTmdTBDB+ZxKBk9gYb +9wfzjeRsd091swatgPSFEB8DlI1lhDhcBg1tKPaJVVxM5csDafVEpGYFV/6oUat4 +q0K+7SowJwxfyAR9C/EJo4P5xU7h0W/wmEjSsz8si9kCgYBDA5wGbBcr55zkEO5L +7bnTq8jCtUmFcZaosWlRmsSB7gHQva+bmnmtJbSpzKbGgGHp6c21BowRXO0E7lZv +aIZz2SzIR9+JQw9GtVy2e797oZzhG2+u/BIkxGwowlPRVsiM468fID/j7VMRWXsM +FZBgmTZ8TpJPtO+1VTB1j5QdPg== +-----END PRIVATE KEY----- diff --git a/test/fixtures/ca.pem b/test/fixtures/ca.pem new file mode 100644 index 0000000..1ca481b --- /dev/null +++ b/test/fixtures/ca.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDPjCCAiYCCQDsuRUq6wfGEDANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQGEwJT +RTESMBAGA1UECAwJU3RvY2tob2xtMRIwEAYDVQQHDAlTdG9ja2hvbG0xCzAJBgNV +BAMMAmNhMR0wGwYJKoZIhvcNAQkBFg5jYUBleGFtcGxlLmNvbTAeFw0xNzEwMjAx +MTM0MDhaFw00NTAzMDYxMTM0MDhaMGExCzAJBgNVBAYTAlNFMRIwEAYDVQQIDAlT +dG9ja2hvbG0xEjAQBgNVBAcMCVN0b2NraG9sbTELMAkGA1UEAwwCY2ExHTAbBgkq +hkiG9w0BCQEWDmNhQGV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEA4q4Uf0ivLsQ6d6WQDbVdyHkyhcC3QNhusTYKO4rIAhvjp8xDfMyn +j0i+r0qFCZ2B+SmJjTpTts3NG6q71EFnd++Vgf85dzBIyUtfrWi8cjvpRZau3z6A +f1eFzvrNJdnAOD8hgJAnIrCebCwiNqGsa245Dj8xwuFtOQo/Er5+ONJH/9n2nh2C +HYRxlbN+rep2+Xdlp4rz75rnKRTkoYSvixQcS+wECHaHg3aZI3bpE/Qp50U+UtS1 +KukXl844WKoRlPp5p+hqs56T53J2RSEXQULzN2+QS9jS2+Vc4JVGtnzWKmBijRoM +4/Rv3XqVvEBzsZN1VCUu72mNMz5ZE4DztwIDAQABMA0GCSqGSIb3DQEBCwUAA4IB +AQAgR8F1/E3slNqbHEk5pLqPw4V0Trk3jB8yNwpkhdpYJKSeAxuX4FdS+vCd1wG6 +V3GG7VR/iQABlH/YQjhqAMGjMhmGbZgvEENr9hRYf6Rp7eEC4gddwn4zq/xv90n6 +/St4V5Ek4/jnTXdwaZFWR1UHiwhYJ4qUYsKR1TiA3nGckKtd52+Veu+xu9DCEOlI +R2PAKca7bwH+M9GosIV6SJdh+YT3+7hp0d2xUjPvDDXVcb2ezGyxsfDJmXsa0YEt +V5NvocKipnU2ZYHUvORLix/7OyaHkrsfdwvaFlvRNBKge3F/l+bcs50WhD5daB+g +bdLER/TWIIcc6x4karOucHS8 +-----END CERTIFICATE----- diff --git a/test/fixtures/genkey.sh b/test/fixtures/genkey.sh old mode 100644 new mode 100755 index 66fd94c..2a86e69 --- a/test/fixtures/genkey.sh +++ b/test/fixtures/genkey.sh @@ -1,5 +1,22 @@ +#!/bin/bash +# DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +# Generate ca key and pem +openssl req -new -x509 -nodes -days 9999 -config ca.cnf -keyout ca.key -out ca.pem + +# Generate server key +# openssl genrsa -out server.key 2048 openssl genrsa -out agenttest-key.pem 1024 -openssl req -new -key agenttest-key.pem -out certrequest.csr -openssl x509 -req -in certrequest.csr -signkey agenttest-key.pem -out agenttest-cert.pem -rm certrequest.csr + +# Generate a certificate signing request for server.key +# openssl req -new -key server.key -out server.csr +openssl req -new -key agenttest-key.pem -out agenttest.csr -config server.cnf + +# Sign the csr with the ca certificate, generating server.pem +openssl x509 -req -extfile server.cnf -days 999 -passin "pass:password" -extensions v3_req -in agenttest.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out agenttest-cert.pem + +# openssl req -new -key agenttest-key.pem -out certrequest.csr +rm agenttest.csr ca.srl # http://www.hacksparrow.com/node-js-https-ssl-certificate.html + + diff --git a/test/fixtures/server.cnf b/test/fixtures/server.cnf new file mode 100644 index 0000000..4d80389 --- /dev/null +++ b/test/fixtures/server.cnf @@ -0,0 +1,35 @@ +[ req ] +default_bits = 2048 +days = 9999 +distinguished_name = req_distinguished_name +attributes = req_attributes +prompt = no +x509_extensions = v3_ca +req_extensions = v3_req + +[ req_distinguished_name ] +C = SE +ST = Stockholm +L = Stockholm +CN = agentkeepalive.com + +[ req_attributes ] +challengePassword = password + +[ v3_ca ] +authorityInfoAccess = @issuer_info + +[ v3_req ] +subjectAltName = @alt_names +# Extensions to add to a certificate request +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +[ issuer_info ] +OCSP;URI.0 = http://ocsp.example.com/ +caIssuers;URI.0 = http://example.com/ca.cert + +[ alt_names ] +IP.1 = 127.0.0.1 +IP.2 = ::1 +DNS.1 = localhost diff --git a/test/https_agent.test.js b/test/https_agent.test.js index 9ba4b21..25a80c5 100644 --- a/test/https_agent.test.js +++ b/test/https_agent.test.js @@ -56,7 +56,7 @@ describe('test/https_agent.test.js', () => { agent: agentkeepalive, port, path: '/', - rejectUnauthorized: false, + ca: fs.readFileSync(__dirname + '/fixtures/ca.pem'), }, res => { assert(res.statusCode === 200); res.resume(); @@ -76,7 +76,7 @@ describe('test/https_agent.test.js', () => { agent: agentkeepalive, port, path: '/', - rejectUnauthorized: false, + ca: fs.readFileSync(__dirname + '/fixtures/ca.pem'), }, res => { assert(res.statusCode === 200); res.resume(); diff --git a/test/test-https-ipv6.test.js b/test/test-https-ipv6.test.js new file mode 100644 index 0000000..2106186 --- /dev/null +++ b/test/test-https-ipv6.test.js @@ -0,0 +1,90 @@ +'use strict'; + +const https = require('https'); +const assert = require('assert'); +const fs = require('fs'); +const constants = require('constants'); +const HttpsAgent = require('..').HttpsAgent; +const os = require('os'); + +function isIPv6Available() { + const networkInterfaces = os.networkInterfaces(); + return !!Object.keys(networkInterfaces).find(ifName => { + const addresses = networkInterfaces[ifName]; + return !!addresses.find(addr => addr.family === 'IPv6'); + }); +} + +describe('test/test-ipv6.test.js', () => { + let port; + let server; + const httpsAgent = new HttpsAgent({ + keepAlive: true, + }); + const options = { + key: fs.readFileSync(__dirname + '/fixtures/agenttest-key.pem'), + cert: fs.readFileSync(__dirname + '/fixtures/agenttest-cert.pem'), + secureOptions: constants.SSL_OP_NO_TICKET, + }; + + before(function(done) { + if (!isIPv6Available()) { + this.skip(); + } + + // Create TLS1.2 server + server = https.createServer(options, (req, res) => { + res.end('ohai'); + }); + server.listen(0, () => { + port = server.address().port; + done(); + }); + }); + + it('should GET / success with 200 status from ::1', function(done) { + const m = process.version.match(/^v(\d+)\.(\d+)/); + const major = parseInt(m[1]); + const minor = parseInt(m[2]); + if (major < 8 || (major === 8 && minor < 10) || (major === 9 && minor < 1)) { + // This only works in node-versions with the fix for + // https://github.com/nodejs/node/issues/14736 included. + this.skip(); + } + + https.get({ + agent: httpsAgent, + hostname: '::1', + port, + path: '/', + ca: fs.readFileSync(__dirname + '/fixtures/ca.pem'), + }, res => { + assert(res.statusCode === 200); + res.resume(); + res.on('end', () => { + process.nextTick(() => { + assert(Object.keys(httpsAgent.sockets).length === 0); + assert(Object.keys(httpsAgent.freeSockets).length === 1); + done(); + }); + }); + }); + assert(Object.keys(httpsAgent.sockets).length === 1); + }); + + it('should not crash with invalid host-header', done => { + https.get({ + agent: httpsAgent, + hostname: '::1', + port, + path: '/', + headers: { + host: '[::1:80', + }, + rejectUnauthorized: false, + }, () => { + done(); + }); + }); + +});