From 512799ed9ed19c2cd79f695ff4db81ee9033420d Mon Sep 17 00:00:00 2001 From: chemicstry Date: Mon, 6 Jun 2016 02:17:36 +0300 Subject: [PATCH] Initial IPv6 support --- tools/cli/commands.js | 27 +++++++++------ tools/cordova/builder.js | 2 +- tools/runners/run-all.js | 9 +++-- tools/tests/cordova-run.js | 10 +++--- tools/tests/test-modes.js | 5 +++ tools/tests/utils-tests.js | 71 ++++++++++++++++++++++++++------------ tools/utils/utils.js | 32 ++++++++--------- 7 files changed, 96 insertions(+), 60 deletions(-) diff --git a/tools/cli/commands.js b/tools/cli/commands.js index 1f91e94c74..259a62d88c 100644 --- a/tools/cli/commands.js +++ b/tools/cli/commands.js @@ -108,9 +108,9 @@ function parseMobileServerOption(mobileServerOption, optionName = 'mobile-server') { let parsedMobileServerUrl = utils.parseUrl( mobileServerOption, - { protocol: 'http://' }); + { protocol: 'http' }); - if (!parsedMobileServerUrl.host) { + if (!parsedMobileServerUrl.hostname) { Console.error(`--${optionName} must include a hostname.`); throw new main.ExitWithCode(1); } @@ -123,8 +123,8 @@ function detectMobileServerUrl(parsedServerUrl, isRunOnDeviceRequested) { try { const myIp = utils.ipAddress(); return { - protocol: 'http://', - host: myIp, + protocol: 'http', + hostname: myIp, port: parsedServerUrl.port }; } catch (error) { @@ -138,8 +138,8 @@ to with --mobile-server.`); throw new main.ExitWithCode(1); } else { return { - protocol: 'http://', - host: 'localhost', + protocol: 'http', + hostname: 'localhost', port: parsedServerUrl.port }; } @@ -336,8 +336,13 @@ function doRunCommand(options) { // NOTE: this calls process.exit() when testing is done. if (options['test']){ options.once = true; - const serverUrlForVelocity = - `http://${(parsedServerUrl.host || "localhost")}:${parsedServerUrl.port}`; + const serverUrlForVelocity = utils.formatUrl({ + protocol: 'http', + hostname: parsedServerUrl.hostname || "localhost", + port: parsedServerUrl.port, + pathname: '' + }); + const velocity = require('../runners/run-velocity.js'); velocity.runVelocity(serverUrlForVelocity); } @@ -361,7 +366,7 @@ function doRunCommand(options) { return runAll.run({ projectContext: projectContext, proxyPort: parsedServerUrl.port, - proxyHost: parsedServerUrl.host, + proxyHost: parsedServerUrl.hostname, appPort: appPort, appHost: appHost, debugPort: options['debug-port'], @@ -1666,7 +1671,7 @@ function doTestCommand(options) { if (options.velocity) { const serverUrlForVelocity = - `http://${(parsedServerUrl.host || "localhost")}:${parsedServerUrl.port}`; + `http://${(parsedServerUrl.hostname || "localhost")}:${parsedServerUrl.port}`; const velocity = require('../runners/run-velocity.js'); velocity.runVelocity(serverUrlForVelocity); } @@ -1676,7 +1681,7 @@ function doTestCommand(options) { { mobileServerUrl: utils.formatUrl(parsedMobileServerUrl), proxyPort: parsedServerUrl.port, - proxyHost: parsedServerUrl.host, + proxyHost: parsedServerUrl.hostname, } )); } diff --git a/tools/cordova/builder.js b/tools/cordova/builder.js index 4981732930..3eff75e8fd 100644 --- a/tools/cordova/builder.js +++ b/tools/cordova/builder.js @@ -138,7 +138,7 @@ export class CordovaBuilder { const mobileServerUrl = this.options.mobileServerUrl; const serverDomain = mobileServerUrl ? - utils.parseUrl(mobileServerUrl).host : null; + utils.parseUrl(mobileServerUrl).hostname : null; // If the remote server domain is known, allow access to it for XHR and DDP // connections. diff --git a/tools/runners/run-all.js b/tools/runners/run-all.js index ff531298c8..a49500a7f8 100644 --- a/tools/runners/run-all.js +++ b/tools/runners/run-all.js @@ -2,6 +2,7 @@ const _ = require('underscore'); const files = require('../fs/files.js'); const buildmessage = require('../utils/buildmessage.js'); +const utils = require('../utils/utils.js'); const runLog = require('./run-log.js'); const release = require('../packaging/release.js'); @@ -52,10 +53,12 @@ class Runner { if (rootUrl) { self.rootUrl = rootUrl; - } else if (proxyHost) { - self.rootUrl = 'http://' + proxyHost + ':' + listenPort + '/'; } else { - self.rootUrl = 'http://localhost:' + listenPort + '/'; + self.rootUrl = utils.formatUrl({ + protocol: 'http', + hostname: proxyHost || "localhost", + port: listenPort, + }); } self.proxy = new Proxy({ diff --git a/tools/tests/cordova-run.js b/tools/tests/cordova-run.js index 5fb7a19817..e0bc2b353d 100644 --- a/tools/tests/cordova-run.js +++ b/tools/tests/cordova-run.js @@ -7,13 +7,13 @@ selftest.define('get mobile server argument for meteor run', ['cordova'], functi // => mobile server should be :3000 selftest.expectEqual(parseServerOptionsForRunCommand({ port: "3000" - }).parsedMobileServerUrl, { host: utils.ipAddress(), port: "3000", protocol: "http://" }); + }).parsedMobileServerUrl, { hostname: utils.ipAddress(), port: "3000", protocol: "http" }); // meteor run -p example.com:3000 // => mobile server should be :3000 selftest.expectEqual(parseServerOptionsForRunCommand({ port: "example.com:3000" - }).parsedMobileServerUrl, { host: utils.ipAddress(), port: "3000", protocol: "http://" }); + }).parsedMobileServerUrl, { hostname: utils.ipAddress(), port: "3000", protocol: "http" }); // meteor run -p example.com:3000 --mobile-server 4000 => error, mobile // server must include a hostname @@ -29,19 +29,19 @@ selftest.define('get mobile server argument for meteor run', ['cordova'], functi selftest.expectEqual(parseServerOptionsForRunCommand({ port: "example.com:3000", "mobile-server": "example.com" - }).parsedMobileServerUrl, { protocol: "http://", host: "example.com", port: undefined }); + }).parsedMobileServerUrl, { protocol: "http", hostname: "example.com", port: undefined }); // meteor run -p example.com:3000 --mobile-server https://example.com => // mobile server should be https://example.com selftest.expectEqual(parseServerOptionsForRunCommand({ port: "example.com:3000", "mobile-server": "https://example.com" - }).parsedMobileServerUrl, { host: "example.com", protocol: "https://", port: undefined }); + }).parsedMobileServerUrl, { hostname: "example.com", protocol: "https", port: undefined }); // meteor run -p example.com:3000 --mobile-server http://example.com:4000 => // mobile server should be http://example.com:4000 selftest.expectEqual(parseServerOptionsForRunCommand({ port: "example.com:3000", "mobile-server": "http://example.com:4000" - }).parsedMobileServerUrl, { host: "example.com", port: "4000", protocol: "http://" }); + }).parsedMobileServerUrl, { hostname: "example.com", port: "4000", protocol: "http" }); }); diff --git a/tools/tests/test-modes.js b/tools/tests/test-modes.js index f6a413dee0..6e4565ec73 100644 --- a/tools/tests/test-modes.js +++ b/tools/tests/test-modes.js @@ -22,4 +22,9 @@ selftest.define("'meteor test --port' accepts/rejects proper values", function ( run.waitSecs(60); run.match('App running at: http://127.0.0.1:3700/'); run.stop(); + + run = s.run("test", "--port", "[::]:3700", "--driver-package", "practicalmeteor:mocha"); + run.waitSecs(60); + run.match('App running at: http://[::]:3700/'); + run.stop(); }); diff --git a/tools/tests/utils-tests.js b/tools/tests/utils-tests.js index 9477e15af2..729bca6116 100644 --- a/tools/tests/utils-tests.js +++ b/tools/tests/utils-tests.js @@ -59,71 +59,96 @@ selftest.define("url has scheme", function () { selftest.define("parse url", function () { selftest.expectEqual(utils.parseUrl("http://localhost:3000"), { - host: "localhost", + hostname: "localhost", port: "3000", - protocol: "http://" + protocol: "http" }); selftest.expectEqual(utils.parseUrl("https://localhost:3000"), { - host: "localhost", + hostname: "localhost", port: "3000", - protocol: "https://" + protocol: "https" }); selftest.expectEqual(utils.parseUrl("localhost:3000"), { - host: "localhost", + hostname: "localhost", port: "3000", protocol: undefined }); selftest.expectEqual(utils.parseUrl("3000"), { - host: undefined, + hostname: undefined, port: "3000", protocol: undefined }); selftest.expectEqual(utils.parseUrl("3000example.com:3000"), { - host: "3000example.com", + hostname: "3000example.com", port: "3000", protocol: undefined }); selftest.expectEqual(utils.parseUrl("http://example.com:3000"), { - host: "example.com", + hostname: "example.com", port: "3000", - protocol: "http://" + protocol: "http" }); selftest.expectEqual(utils.parseUrl("https://example.com:3000"), { - host: "example.com", + hostname: "example.com", port: "3000", - protocol: "https://" + protocol: "https" }); selftest.expectEqual(utils.parseUrl("example.com:3000"), { - host: "example.com", + hostname: "example.com", + port: "3000", + protocol: undefined + }); + selftest.expectEqual(utils.parseUrl("127.0.0.1:3000"), { + hostname: "127.0.0.1", + port: "3000", + protocol: undefined + }); + selftest.expectEqual(utils.parseUrl("[::]:3000"), { + hostname: "::", + port: "3000", + protocol: undefined + }); + selftest.expectEqual(utils.parseUrl("http://[::]:3000"), { + hostname: "::", + port: "3000", + protocol: "http" + }); + selftest.expectEqual(utils.parseUrl("https://[::]:3000"), { + hostname: "::", + port: "3000", + protocol: "https" + }); + selftest.expectEqual(utils.parseUrl("[0000:0000:0000:0000:0000:0000:0000:0001]:3000"), { + hostname: "0000:0000:0000:0000:0000:0000:0000:0001", port: "3000", protocol: undefined }); // tests for defaults selftest.expectEqual(utils.parseUrl("http://example.com:3000", { - host: "foo.com", + hostname: "foo.com", port: "4000", - protocol: "https://" + protocol: "https" }), { - host: "example.com", + hostname: "example.com", port: "3000", - protocol: "http://" + protocol: "http" }); selftest.expectEqual(utils.parseUrl("example.com:3000", { port: "4000", - protocol: "https://" + protocol: "https" }), { - host: "example.com", + hostname: "example.com", port: "3000", - protocol: "https://" + protocol: "https" }); selftest.expectEqual(utils.parseUrl("3000", { port: "4000", - protocol: "https://", - host: "example.com" + protocol: "https", + hostname: "example.com" }), { - host: "example.com", + hostname: "example.com", port: "3000", - protocol: "https://" + protocol: "https" }); }); diff --git a/tools/utils/utils.js b/tools/utils/utils.js index 39f4fcbe9b..e3b209997a 100644 --- a/tools/utils/utils.js +++ b/tools/utils/utils.js @@ -18,19 +18,19 @@ var utils = exports; // 'url.parse' would give us {protocol:' 3000', host: undefined, port: // undefined} or something like that. // -// 'defaults' is an optional object with 'host', 'port', and 'protocol' keys. +// 'defaults' is an optional object with 'hostname', 'port', and 'protocol' keys. exports.parseUrl = function (str, defaults) { // XXX factor this out into a {type: host/port}? defaults = defaults || {}; - var defaultHost = defaults.host || undefined; + var defaultHostname = defaults.hostname || undefined; var defaultPort = defaults.port || undefined; var defaultProtocol = defaults.protocol || undefined; if (str.match(/^[0-9]+$/)) { // just a port return { port: str, - host: defaultHost, + hostname: defaultHostname, protocol: defaultProtocol }; } @@ -40,29 +40,27 @@ exports.parseUrl = function (str, defaults) { } var parsed = url.parse(str); - if (! parsed.protocol.match(/\/\/$/)) { - // For easy concatenation, add double slashes to protocols. - parsed.protocol = parsed.protocol + "//"; - } + + // for consistency remove colon at the end of protocol + parsed.protocol = parsed.protocol.replace(/\:$/, ''); + return { protocol: hasScheme ? parsed.protocol : defaultProtocol, - host: parsed.hostname || defaultHost, + hostname: parsed.hostname || defaultHostname, port: parsed.port || defaultPort }; }; -// 'url' is an object with 'host', 'port', and 'protocol' keys, such as +// 'options' is an object with 'hostname', 'port', and 'protocol' keys, such as // the return value of parseUrl. -exports.formatUrl = function (url) { - let string = url.protocol + url.host; - if (url.port) { - string += `:${url.port}`; - } +exports.formatUrl = function (options) { // For consistency with `Meteor.absoluteUrl`, add a trailing slash to make // this a valid URL - string += "/"; - return string; -} + if (!options.pathname) + options.pathname = "/"; + + return url.format(options); +}; exports.ipAddress = function () { let defaultRoute;