From 6d50db5f6c08d89dc1cbba8a93e281cb81a5c43b Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 29 Jan 2019 13:59:57 +0100 Subject: [PATCH] fix: ipv6 hostname normalization The old check looked at both `host` and `hostname`, which was prone to errors for multiple reasons: - `host` could include `:` but be ipv4 - ipv6 could already have square brackets, which produced invalid URIs like `http://[[::1]]:80` This changes ipv6 normalization to only run if `hostname` parameter is provided and does not start with `[`. Also, added missing tests for ipv6. License: MIT Signed-off-by: Marcin Rataj --- index.js | 7 +++--- test/node/http-browserify.js | 43 +++++++++++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/index.js b/index.js index 84bfe51..b441c69 100644 --- a/index.js +++ b/index.js @@ -23,8 +23,9 @@ http.request = function (opts, cb) { var path = opts.path || '/' // Necessary for IPv6 addresses - if (host && host.indexOf(':') !== -1) - host = '[' + host + ']' + if (host && host === opts.hostname && host.indexOf(':') !== -1 && host.indexOf('[') !== 0) { + host = '[' + host + ']' + } // This may be a relative url. The browser should always be able to interpret it correctly. opts.url = (host ? (protocol + '//' + host) : '') + (port ? ':' + port : '') + path @@ -82,4 +83,4 @@ http.METHODS = [ 'TRACE', 'UNLOCK', 'UNSUBSCRIBE' -] \ No newline at end of file +] diff --git a/test/node/http-browserify.js b/test/node/http-browserify.js index 42a718f..f2483be 100644 --- a/test/node/http-browserify.js +++ b/test/node/http-browserify.js @@ -121,7 +121,7 @@ test('Test withCredentials param', function(t) { t.end() }) -test('Test ipv6 address', function(t) { +test('Test ipv6 address as string', function(t) { var testUrl = 'http://[::1]:80/foo' var request = http.get(testUrl, noop) @@ -130,6 +130,47 @@ test('Test ipv6 address', function(t) { t.end() }) +test('Test ipv6 address as opts with hostname [brackets] and port', function(t) { + var opts = { + protocol: "http:", + hostname: "[::1]", + port: "80", + path: "/foo" + } + var request = http.get(opts, noop) + + var resolved = url.resolve(location, request._opts.url) + t.equal(resolved, 'http://[::1]:80/foo', 'Url should be correct') + t.end() +}) + +test('Test ipv6 address as opts with hostname [no brackets] and port', function(t) { + var opts = { + protocol: "http:", + hostname: "::1", + port: "80", + path: "/foo" + } + var request = http.get(opts, noop) + + var resolved = url.resolve(location, request._opts.url) + t.equal(resolved, 'http://[::1]:80/foo', 'Url should be correct') + t.end() +}) + +test('Test ipv6 address as opts with host', function(t) { + var opts = { + protocol: "http:", + host: "[::1]:80", + path: "/foo" + } + var request = http.get(opts, noop) + + var resolved = url.resolve(location, request._opts.url) + t.equal(resolved, 'http://[::1]:80/foo', 'Url should be correct') + t.end() +}) + test('Test relative path in url', function(t) { var params = { path: './bar' } var request = http.get(params, noop)