portfinder
Advanced tools
Comparing version 1.0.6 to 1.0.7-beta.0
@@ -11,7 +11,13 @@ /* | ||
var fs = require('fs'), | ||
os = require('os'), | ||
net = require('net'), | ||
path = require('path'), | ||
async = require('async'), | ||
debug = require('debug'), | ||
mkdirp = require('mkdirp').mkdirp; | ||
var debugTestPort = debug('portfinder:testPort'), | ||
debugGetPort = debug('portfinder:getPort'), | ||
debugDefaultHosts = debug('portfinder:defaultHosts'); | ||
var internals = {}; | ||
@@ -33,3 +39,7 @@ | ||
debugTestPort("entered testPort(): trying", options.host, "port", options.port); | ||
function onListen () { | ||
debugTestPort("done w/ testPort(): OK", options.host, "port", options.port); | ||
options.server.removeListener('error', onError); | ||
@@ -41,2 +51,4 @@ options.server.close(); | ||
function onError (err) { | ||
debugTestPort("done w/ testPort(): failed", options.host, "w/ port", options.port, "with error", err.code); | ||
options.server.removeListener('listening', onListen); | ||
@@ -78,4 +90,2 @@ | ||
// | ||
var defaultHosts = ['::1', '127.0.0.1', '0.0.0.0']; | ||
exports.getPort = function (options, callback) { | ||
@@ -90,4 +100,4 @@ if (!callback) { | ||
var hasUserGivenHost; | ||
for (var i = 0; i < defaultHosts.length; i++) { | ||
if (defaultHosts[i] === options.host) { | ||
for (var i = 0; i < exports._defaultHosts.length; i++) { | ||
if (exports._defaultHosts[i] === options.host) { | ||
hasUserGivenHost = true; | ||
@@ -99,3 +109,3 @@ break; | ||
if (!hasUserGivenHost) { | ||
defaultHosts.push(options.host); | ||
exports._defaultHosts.push(options.host); | ||
} | ||
@@ -105,8 +115,14 @@ | ||
var openPorts = []; | ||
return async.eachSeries(defaultHosts, function(host, next) { | ||
var openPorts = [], currentHost; | ||
return async.eachSeries(exports._defaultHosts, function(host, next) { | ||
debugGetPort("in eachSeries() iteration callback: host is", host); | ||
return internals.testPort({ host: host, port: options.port }, function(err, port) { | ||
if (err) { | ||
debugGetPort("in eachSeries() iteration callback testPort() callback", "with an err:", err.code); | ||
currentHost = host; | ||
return next(err); | ||
} else { | ||
debugGetPort("in eachSeries() iteration callback testPort() callback", | ||
"with a success for port", port); | ||
openPorts.push(port); | ||
@@ -117,19 +133,23 @@ return next(); | ||
}, function(err) { | ||
if (err) { | ||
if (err.address && net.isIPv6(err.address)) { | ||
if (options.host && net.isIPv6(options.host)) { | ||
// let user know if they provided an ipv6 host, bail | ||
var msg = 'Provided host ' + options.host + | ||
' is ipv6 and your system does not support it.'+ | ||
' Please provide a host that is ipv4'; | ||
debugGetPort("in eachSeries() result callback: err is", err); | ||
// If we get EADDRNOTAVAIL it means the host is not bindable, so remove it | ||
// from exports._defaultHosts and start over. For ubuntu, we use EINVAL for the same | ||
if (err.code === 'EADDRNOTAVAIL' || err.code === 'EINVAL') { | ||
if (options.host === currentHost) { | ||
// if bad address matches host given by user, tell them | ||
// | ||
// NOTE: We may need to one day handle `my-non-existent-host.local` if users | ||
// report frustration with passing in hostnames that DONT map to bindable | ||
// hosts, without showing them a good error. | ||
var msg = 'Provided host ' + options.host + ' could NOT be bound. Please provide a different host address or hostname'; | ||
return callback(Error(msg)); | ||
} else { | ||
// filter our defaultHosts to only be ipv4, start over | ||
defaultHosts = defaultHosts.filter(function(_host) { | ||
return net.isIPv4(_host); | ||
}); | ||
return exports.getPort(options, callback); | ||
} | ||
var idx = exports._defaultHosts.indexOf(currentHost); | ||
exports._defaultHosts.splice(idx, 1); | ||
return exports.getPort(options, callback); | ||
} else { | ||
// error is not ipv6 related, file ticket, handle as special case | ||
// error is not accounted for, file ticket, handle special case | ||
return callback(err); | ||
@@ -144,2 +164,4 @@ } | ||
debugGetPort("in eachSeries() result callback: openPorts is", openPorts); | ||
if (openPorts[0] === openPorts[openPorts.length-1]) { | ||
@@ -304,1 +326,95 @@ // if first === last, we found an open port | ||
}; | ||
/** | ||
* @desc List of internal hostnames provided by your machine. A user | ||
* provided hostname may also be provided when calling portfinder.getPort, | ||
* which would then be added to the default hosts we lookup and return here. | ||
* | ||
* @return {array} | ||
* | ||
* Long Form Explantion: | ||
* | ||
* - Input: (os.networkInterfaces() w/ MacOS 10.11.5+ and running a VM) | ||
* | ||
* { lo0: | ||
* [ { address: '::1', | ||
* netmask: 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', | ||
* family: 'IPv6', | ||
* mac: '00:00:00:00:00:00', | ||
* scopeid: 0, | ||
* internal: true }, | ||
* { address: '127.0.0.1', | ||
* netmask: '255.0.0.0', | ||
* family: 'IPv4', | ||
* mac: '00:00:00:00:00:00', | ||
* internal: true }, | ||
* { address: 'fe80::1', | ||
* netmask: 'ffff:ffff:ffff:ffff::', | ||
* family: 'IPv6', | ||
* mac: '00:00:00:00:00:00', | ||
* scopeid: 1, | ||
* internal: true } ], | ||
* en0: | ||
* [ { address: 'fe80::a299:9bff:fe17:766d', | ||
* netmask: 'ffff:ffff:ffff:ffff::', | ||
* family: 'IPv6', | ||
* mac: 'a0:99:9b:17:76:6d', | ||
* scopeid: 4, | ||
* internal: false }, | ||
* { address: '10.0.1.22', | ||
* netmask: '255.255.255.0', | ||
* family: 'IPv4', | ||
* mac: 'a0:99:9b:17:76:6d', | ||
* internal: false } ], | ||
* awdl0: | ||
* [ { address: 'fe80::48a8:37ff:fe34:aaef', | ||
* netmask: 'ffff:ffff:ffff:ffff::', | ||
* family: 'IPv6', | ||
* mac: '4a:a8:37:34:aa:ef', | ||
* scopeid: 8, | ||
* internal: false } ], | ||
* vnic0: | ||
* [ { address: '10.211.55.2', | ||
* netmask: '255.255.255.0', | ||
* family: 'IPv4', | ||
* mac: '00:1c:42:00:00:08', | ||
* internal: false } ], | ||
* vnic1: | ||
* [ { address: '10.37.129.2', | ||
* netmask: '255.255.255.0', | ||
* family: 'IPv4', | ||
* mac: '00:1c:42:00:00:09', | ||
* internal: false } ] } | ||
* | ||
* - Output: | ||
* | ||
* [ | ||
* '0.0.0.0', | ||
* '::1', | ||
* '127.0.0.1', | ||
* 'fe80::1', | ||
* '10.0.1.22', | ||
* 'fe80::48a8:37ff:fe34:aaef', | ||
* '10.211.55.2', | ||
* '10.37.129.2' | ||
* ] | ||
* | ||
* Note we export this so we can use it in our tests, otherwise this API is private | ||
*/ | ||
exports._defaultHosts = (function() { | ||
var interfaces = os.networkInterfaces(), | ||
interfaceNames = Object.keys(interfaces), | ||
hiddenButImportantHost = '0.0.0.0', // !important - dont remove, hence the naming :) | ||
results = [hiddenButImportantHost]; | ||
for (var i = 0; i < interfaceNames.length; i++) { | ||
var _interface = interfaces[interfaceNames[i]]; | ||
for (var j = 0; j < _interface.length; j++) { | ||
var curr = _interface[j]; | ||
results.push(curr.address); | ||
} | ||
} | ||
debugDefaultHosts("exports._defaultHosts is: %o", results); | ||
return results; | ||
}()); |
{ | ||
"name": "portfinder", | ||
"description": "A simple tool to find an open port on the current machine", | ||
"version": "1.0.6", | ||
"version": "1.0.7-beta.0", | ||
"author": "Charlie Robbins <charlie.robbins@gmail.com>", | ||
@@ -20,2 +20,3 @@ "repository": { | ||
"async": "^1.5.2", | ||
"debug": "^2.2.0", | ||
"mkdirp": "0.5.x" | ||
@@ -22,0 +23,0 @@ }, |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
14293
362
3
2
+ Addeddebug@^2.2.0
+ Addeddebug@2.6.9(transitive)
+ Addedms@2.0.0(transitive)