From ff6d6c6e7a3b2c36618b5d1db662e10c929696e3 Mon Sep 17 00:00:00 2001 From: "James M. Greene" Date: Fri, 3 Mar 2017 20:30:35 -0600 Subject: [PATCH] Correctly format the Host header for IPv6 addresses Fixes #2292 --- request.js | 11 ++++------- tests/test-headers.js | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/request.js b/request.js index a683a590b..008df9810 100644 --- a/request.js +++ b/request.js @@ -289,13 +289,10 @@ Request.prototype.init = function (options) { self.setHost = false if (!self.hasHeader('host')) { var hostHeaderName = self.originalHostHeaderName || 'host' - self.setHeader(hostHeaderName, self.uri.hostname) - if (self.uri.port) { - if ( !(self.uri.port === 80 && self.uri.protocol === 'http:') && - !(self.uri.port === 443 && self.uri.protocol === 'https:') ) { - self.setHeader(hostHeaderName, self.getHeader('host') + (':' + self.uri.port) ) - } - } + // When used with an IPv6 address, `host` will provide + // the correct bracketed format, unlike using `hostname` and + // optionally adding the `port` when necessary. + self.setHeader(hostHeaderName, self.uri.host) self.setHost = true } diff --git a/tests/test-headers.js b/tests/test-headers.js index 53b7cb033..91abd25ef 100644 --- a/tests/test-headers.js +++ b/tests/test-headers.js @@ -4,6 +4,7 @@ var server = require('./server') , request = require('../index') , util = require('util') , tape = require('tape') + , url = require('url') var s = server.createServer() @@ -201,3 +202,42 @@ tape('catch invalid characters error - POST', function(t) { t.end() }) }) + +tape('IPv6 Host header', function(t) { + // Horrible hack to observe the raw data coming to the server + var rawData = '' + + s.on('connection', function(socket) { + if (socket.ondata) { + var ondata = socket.ondata + } + function handledata (d, start, end) { + if (ondata) { + rawData += d.slice(start, end).toString() + return ondata.apply(this, arguments) + } else { + rawData += d + } + } + socket.on('data', handledata) + socket.ondata = handledata + }) + + function checkHostHeader(host) { + t.ok( + new RegExp('^Host: ' + host + '$', 'im').test(rawData), + util.format( + 'Expected "Host: %s" in data "%s"', + host, rawData.trim().replace(/\r?\n/g, '\\n'))) + rawData = '' + } + + request({ + url : s.url.replace(url.parse(s.url).hostname, '[::1]') + '/headers.json' + }, function(err, res, body) { + t.equal(err, null) + t.equal(res.statusCode, 200) + checkHostHeader('\\[::1\\]:' + s.port) + t.end() + }) +})