diff --git a/lib/utils/ip.js b/lib/utils/ip.js index f92fadd7..6b977db4 100644 --- a/lib/utils/ip.js +++ b/lib/utils/ip.js @@ -30,38 +30,61 @@ var ipv6Regex = */ IP.parseHost = function parseHost(addr, fallback) { - var port = fallback || 0; - var parts, host, version; + var parts, host, port, version; assert(typeof addr === 'string'); - assert(typeof port === 'number'); assert(addr.length > 0, 'Bad address.'); - // [ipv6]:port if (addr[0] === '[') { - addr = addr.substring(1); - parts = addr.split(/\]:?/); - assert(parts.length === 2, 'Bad IPv6 address.'); + if (addr[addr.length - 1] === ']') { + // Case: + // [::1] + host = addr.slice(1, -1); + port = null; + } else { + // Case: + // [::1]:80 + addr = addr.slice(1); + parts = addr.split(']:'); + assert(parts.length === 2, 'Bad IPv6 address.'); + host = parts[0]; + port = parts[1]; + } } else { parts = addr.split(':'); - if (parts.length > 2) { - // ipv6 - no port - assert(IP.isV6Format(addr), 'Bad IPv6 address.'); - parts = [addr]; - } else { - // domain/ipv4:port? - assert(parts.length <= 2, 'Bad host.'); + switch (parts.length) { + case 2: + // Cases: + // 127.0.0.1:80 + // localhost:80 + host = parts[0]; + port = parts[1]; + break; + case 1: + // Cases: + // 127.0.0.1 + // localhost + host = parts[0]; + port = null; + break; + default: + // Case: + // ::1 + assert(IP.isV6Format(addr), 'Bad IPv6 address.'); + host = addr; + port = null; + break; } } - host = parts[0]; assert(host.length > 0, 'Bad host.'); - if (parts.length === 2) { - port = parts[1]; + if (port != null) { assert(/^\d+$/.test(port), 'Bad port.'); port = parseInt(port, 10); + } else { + port = fallback || 0; } version = IP.version(host); @@ -90,6 +113,9 @@ IP.hostname = function hostname(host, port) { version = IP.version(host); + if (host.indexOf(':') !== -1) + assert(version === 6, 'Bad host.'); + if (version !== -1) host = IP.normalize(host); @@ -126,6 +152,10 @@ IP.version = function version(str) { IP.isV4Format = function(str) { if (str.length < 7) return false; + + if (str.length > 15) + return false; + return ipv4Regex.test(str); }; @@ -136,6 +166,12 @@ IP.isV4Format = function(str) { */ IP.isV6Format = function(str) { + if (str.length < 2) + return false; + + if (str.length > 39) + return false; + return ipv6Regex.test(str); };