From 414f93ecb38a28aa02f2a4053c747071e633773c Mon Sep 17 00:00:00 2001 From: Brian White Date: Fri, 19 May 2017 17:14:53 -0400 Subject: [PATCH] http: fix IPv6 Host header check PR-URL: https://github.com/nodejs/node/pull/13122 Reviewed-By: James M Snell Reviewed-By: Refael Ackermann --- lib/_http_client.js | 8 ++-- .../test-http-host-header-ipv6-fail.js | 43 ++++++++++--------- 2 files changed, 27 insertions(+), 24 deletions(-) diff --git a/lib/_http_client.js b/lib/_http_client.js index 3e1ed888279df3..7707fa74cf784a 100644 --- a/lib/_http_client.js +++ b/lib/_http_client.js @@ -173,14 +173,14 @@ function ClientRequest(options, cb) { } if (host && !this.getHeader('host') && setHost) { var hostHeader = host; - var posColon = -1; // For the Host header, ensure that IPv6 addresses are enclosed // in square brackets, as defined by URI formatting // https://tools.ietf.org/html/rfc3986#section-3.2.2 - if (-1 !== (posColon = hostHeader.indexOf(':')) && - -1 !== (posColon = hostHeader.indexOf(':', posColon)) && - '[' !== hostHeader[0]) { + var posColon = hostHeader.indexOf(':'); + if (posColon !== -1 && + hostHeader.indexOf(':', posColon + 1) !== -1 && + hostHeader.charCodeAt(0) !== 91/*'['*/) { hostHeader = `[${hostHeader}]`; } diff --git a/test/parallel/test-http-host-header-ipv6-fail.js b/test/parallel/test-http-host-header-ipv6-fail.js index 94351bc5c167e4..0c56afad7f28e5 100644 --- a/test/parallel/test-http-host-header-ipv6-fail.js +++ b/test/parallel/test-http-host-header-ipv6-fail.js @@ -12,28 +12,31 @@ const common = require('../common'); const assert = require('assert'); const http = require('http'); +const net = require('net'); -const hostname = '::1'; +const requests = [ + { host: 'foo:1234', headers: { expectedhost: 'foo:1234:80' } }, + { host: '::1', headers: { expectedhost: '[::1]:80' } } +]; -function httpreq() { - const req = http.request({ - host: hostname, - port: server.address().port, - path: '/', - method: 'GET' - }); - req.end(); +function createLocalConnection(options) { + options.host = undefined; + options.port = this.port; + options.path = undefined; + return net.createConnection(options); } -if (!common.hasIPv6) { - console.error('Skipping test, no IPv6 support'); - return; -} - -const server = http.createServer(common.mustCall(function(req, res) { - assert.ok(req.headers.host, `[${hostname}]`); +http.createServer(common.mustCall(function(req, res) { + this.requests = this.requests || 0; + assert.strictEqual(req.headers.host, req.headers.expectedhost); res.end(); - server.close(true); -})); - -server.listen(0, hostname, () => httpreq()); + if (++this.requests === requests.length) + this.close(); +}, requests.length)).listen(0, function() { + const address = this.address(); + for (let i = 0; i < requests.length; ++i) { + requests[i].createConnection = + common.mustCall(createLocalConnection.bind(address)); + http.get(requests[i]); + } +});