portscanner
Advanced tools
Comparing version 1.0.0 to 1.1.0
@@ -1,24 +0,38 @@ | ||
var net = require('net') | ||
, Socket = net.Socket | ||
, async = require('async') | ||
var net = require('net') | ||
var Socket = net.Socket | ||
var async = require('async') | ||
var promisify = require('./promisify') | ||
var portscanner = exports | ||
/** | ||
* Finds the first port with a status of 'open', implying the port is in use and | ||
* there is likely a service listening on it. | ||
* | ||
* @param {Number} startPort - Port to begin status check on (inclusive). | ||
* @param {Number} endPort - Last port to check status on (inclusive). | ||
* Defaults to 65535. | ||
* @param {String} host - Where to scan. Defaults to '127.0.0.1'. | ||
* @param {Function} callback - function (error, port) { ... } | ||
* - {Object|null} error - Any errors that occurred while port scanning. | ||
* - {Number|Boolean} port - The first open port found. Note, this is the | ||
* first port that returns status as 'open', not | ||
* necessarily the first open port checked. If no | ||
* open port is found, the value is false. | ||
*/ | ||
portscanner.findAPortInUse = function(startPort, endPort, host, callback) { | ||
findAPortWithStatus('open', startPort, endPort, host, callback) | ||
/** | ||
* @param {Number} startPort - Port to begin status check on (inclusive). | ||
* @param {Number} [endPort=65535] - Last port to check status on (inclusive). | ||
* @param {String} [host='127.0.0.1'] - Host of where to scan. | ||
* @param {findPortCallback} [callback] - Function to call back with error or results. | ||
* @returns {Promise} | ||
* @example | ||
* // scans through 3000 to 3002 (inclusive) | ||
* portscanner.findAPortInUse(3000, 3002, '127.0.0.1', console.log) | ||
* // returns a promise in the absence of a callback | ||
* portscanner.findAPortInUse(3000, 3002, '127.0.0.1').then(console.log) | ||
* @example | ||
* // scans through 3000 to 65535 on '127.0.0.1' | ||
* portscanner.findAPortInUse(3000, console.log) | ||
*/ | ||
/** | ||
* @param {Array} postList - Array of ports to check status on. | ||
* @param {String} [host='127.0.0.1'] - Host of where to scan. | ||
* @param {findPortCallback} [callback] - Function to call back with error or results. | ||
* @returns {Promise} | ||
* @example | ||
* // scans 3000 and 3002 only, not 3001. | ||
* portscanner.findAPortInUse([3000, 3002], console.log) | ||
*/ | ||
function findAPortInUse () { | ||
var params = [].slice.call(arguments) | ||
params.unshift('open') | ||
return findAPortWithStatus.apply(null, params) | ||
} | ||
@@ -28,17 +42,8 @@ | ||
* Finds the first port with a status of 'closed', implying the port is not in | ||
* use. | ||
* | ||
* @param {Number} startPort - Port to begin status check on (inclusive). | ||
* @param {Number} endPort - Last port to check status on (inclusive). | ||
* Defaults to 65535. | ||
* @param {String} host - Where to scan. Defaults to '127.0.0.1'. | ||
* @param {Function} callback - function (error, port) { ... } | ||
* - {Object|null} error - Any errors that occurred while port scanning. | ||
* - {Number|Boolean} port - The first closed port found. Note, this is the | ||
* first port that returns status as 'closed', not | ||
* necessarily the first closed port checked. If no | ||
* closed port is found, the value is false. | ||
* use. Accepts identical parameters as {@link findAPortInUse} | ||
*/ | ||
portscanner.findAPortNotInUse = function(startPort, endPort, host, callback) { | ||
findAPortWithStatus('closed', startPort, endPort, host, callback) | ||
function findAPortNotInUse () { | ||
var params = [].slice.call(arguments) | ||
params.unshift('closed') | ||
return findAPortWithStatus.apply(null, params) | ||
} | ||
@@ -48,30 +53,55 @@ | ||
* Checks the status of an individual port. | ||
* | ||
* @param {Number} port - Port to check status on. | ||
* @param {String|Object} options - host or options | ||
* - {String} host - Host of where to scan. Defaults to '127.0.0.1'. | ||
* - {Object} options | ||
* - {String} host - Host of where to scan. Defaults to '127.0.0.1'. | ||
* - {Number} timeout - Connection timeout. Defaults to 400ms. | ||
* @param {Function} callback - function (error, port) { ... } | ||
* - {Object|null} error - Any errors that occurred while port scanning. | ||
* - {String} status - 'open' if the port is in use. | ||
* 'closed' if the port is available. | ||
*/ | ||
portscanner.checkPortStatus = function(port, options, callback) { | ||
if (typeof options === 'string') { | ||
// Assume this param is the host option | ||
options = {host: options} | ||
/** | ||
* @param {Number} port - Port to check status on. | ||
* @param {String} [host='127.0.0.1'] - Host of where to scan. | ||
* @param {checkPortCallback} [callback] - Function to call back with error or results. | ||
* @returns {Promise} | ||
*/ | ||
/** | ||
* @param {Number} port - Port to check status on. | ||
* @param {Object} [opts={}] - Options object. | ||
* @param {String} [opts.host='127.0.0.1'] - Host of where to scan. | ||
* @param {Number} [opts.timeout=400] - Connection timeout in ms. | ||
* @param {checkPortCallback} [callback] - Function to call back with error or results. | ||
* @returns {Promise} | ||
*/ | ||
function checkPortStatus (port) { | ||
var args, host, opts, callback | ||
args = [].slice.call(arguments, 1) | ||
if (typeof args[0] === 'string') { | ||
host = args[0] | ||
} else if (typeof args[0] === 'object') { | ||
opts = args[0] | ||
} else if (typeof args[0] === 'function') { | ||
callback = args[0] | ||
} | ||
var host = options.host || '127.0.0.1' | ||
var timeout = options.timeout || 400 | ||
var connectionRefused = false; | ||
if (typeof args[1] === 'object') { | ||
opts = args[1] | ||
} else if (typeof args[1] === 'function') { | ||
callback = args[1] | ||
} | ||
if (typeof args[2] === 'function') { | ||
callback = args[2] | ||
} | ||
if (!callback) return promisify(checkPortStatus, arguments) | ||
opts = opts || {} | ||
host = host || opts.host || '127.0.0.1' | ||
var timeout = opts.timeout || 400 | ||
var connectionRefused = false | ||
var socket = new Socket() | ||
, status = null | ||
, error = null | ||
var status = null | ||
var error = null | ||
// Socket connection established, port is open | ||
socket.on('connect', function() { | ||
socket.on('connect', function () { | ||
status = 'open' | ||
@@ -83,3 +113,3 @@ socket.destroy() | ||
socket.setTimeout(timeout) | ||
socket.on('timeout', function() { | ||
socket.on('timeout', function () { | ||
status = 'closed' | ||
@@ -92,8 +122,8 @@ error = new Error('Timeout (' + timeout + 'ms) occurred waiting for ' + host + ':' + port + ' to be available') | ||
// exception | ||
socket.on('error', function(exception) { | ||
if(exception.code !== "ECONNREFUSED") { | ||
socket.on('error', function (exception) { | ||
if (exception.code !== 'ECONNREFUSED') { | ||
error = exception | ||
} else { | ||
connectionRefused = true | ||
} | ||
else | ||
connectionRefused = true; | ||
status = 'closed' | ||
@@ -103,7 +133,4 @@ }) | ||
// Return after the socket has closed | ||
socket.on('close', function(exception) { | ||
if(exception && !connectionRefused) | ||
error = exception; | ||
else | ||
error = null; | ||
socket.on('close', function (exception) { | ||
if (exception && !connectionRefused) { error = error || exception } else { error = null } | ||
callback(error, status) | ||
@@ -114,18 +141,70 @@ }) | ||
} | ||
/** | ||
* Callback for {@link checkPortStatus} | ||
* @callback checkPortCallback | ||
* @param {Error|null} error - Any error that occurred while port scanning, or null. | ||
* @param {String} status - Status: 'open' if the port is in use, 'closed' if the port is available. | ||
*/ | ||
function findAPortWithStatus(status, startPort, endPort, host, callback) { | ||
/** | ||
* Internal helper function used by {@link findAPortInUse} and {@link findAPortNotInUse} | ||
* to find a port from a range or a list with a specific status. | ||
*/ | ||
/** | ||
* @param {String} status - Status to check. | ||
* @param {...params} params - Params as passed exactly to {@link findAPortInUse} and {@link findAPortNotInUse}. | ||
*/ | ||
function findAPortWithStatus (status) { | ||
var params, startPort, endPort, portList, host, callback | ||
params = [].slice.call(arguments, 1) | ||
if (typeof params[0] === 'number') { | ||
startPort = params[0] | ||
} else if (params[0] instanceof Array) { | ||
portList = params[0] | ||
} | ||
if (typeof params[1] === 'number') { | ||
endPort = params[1] | ||
} else if (typeof params[1] === 'string') { | ||
host = params[1] | ||
} else if (typeof params[1] === 'function') { | ||
callback = params[1] | ||
} | ||
if (typeof params[2] === 'string') { | ||
host = params[2] | ||
} else if (typeof params[2] === 'function') { | ||
callback = params[2] | ||
} | ||
if (typeof params[3] === 'function') { | ||
callback = params[3] | ||
} | ||
if (!callback) return promisify(findAPortWithStatus, arguments) | ||
if (startPort && endPort && endPort < startPort) { | ||
// WARNING: endPort less than startPort. Using endPort as startPort & vice versa. | ||
var tempStartPort = startPort | ||
startPort = endPort | ||
endPort = tempStartPort | ||
} | ||
endPort = endPort || 65535 | ||
var foundPort = false | ||
var numberOfPortsChecked = 0 | ||
var port = startPort | ||
var port = portList ? portList[0] : startPort | ||
// Returns true if a port with matching status has been found or if checked | ||
// the entire range of ports | ||
var hasFoundPort = function() { | ||
return foundPort || numberOfPortsChecked === (endPort - startPort + 1) | ||
var hasFoundPort = function () { | ||
return foundPort || numberOfPortsChecked === (portList ? portList.length : endPort - startPort + 1) | ||
} | ||
// Checks the status of the port | ||
var checkNextPort = function(callback) { | ||
portscanner.checkPortStatus(port, host, function(error, statusOfPort) { | ||
var checkNextPort = function (callback) { | ||
checkPortStatus(port, host, function (error, statusOfPort) { | ||
numberOfPortsChecked++ | ||
@@ -135,5 +214,4 @@ if (statusOfPort === status) { | ||
callback(error) | ||
} | ||
else { | ||
port++ | ||
} else { | ||
port = portList ? portList[numberOfPortsChecked] : port + 1 | ||
callback(null) | ||
@@ -146,10 +224,8 @@ } | ||
// found or the range of ports has been exhausted | ||
async.until(hasFoundPort, checkNextPort, function(error) { | ||
async.until(hasFoundPort, checkNextPort, function (error) { | ||
if (error) { | ||
callback(error, port) | ||
} | ||
else if (foundPort) { | ||
} else if (foundPort) { | ||
callback(null, port) | ||
} | ||
else { | ||
} else { | ||
callback(null, false) | ||
@@ -159,2 +235,17 @@ } | ||
} | ||
/** | ||
* Callback for {@link findAPortWithStatus}, and by that extension, for {@link findAPortInUse} and {@link findAPortNotInUse}. | ||
* @callback findPortCallback | ||
* @param {Error|null} error - Any error that occurred while port scanning, or null. | ||
* @param {Number|Boolean} port - The first open port found. Note, this is the first port that returns status as 'open', not necessarily the first open port checked. If no open port is found, the value is false. | ||
*/ | ||
/** | ||
* @exports portscanner | ||
*/ | ||
module.exports = { | ||
findAPortInUse: findAPortInUse, | ||
findAPortNotInUse: findAPortNotInUse, | ||
checkPortStatus: checkPortStatus | ||
} |
{ | ||
"name": "portscanner", | ||
"description": "Asynchronous port scanner for Node.js", | ||
"scripts": { | ||
"test": "ava", | ||
"lint": "standard" | ||
}, | ||
"keywords": [ | ||
@@ -11,3 +15,3 @@ "portscanner", | ||
], | ||
"version": "1.0.0", | ||
"version": "1.1.0", | ||
"preferGlobal": false, | ||
@@ -31,5 +35,10 @@ "homepage": "https://github.com/baalexander/node-portscanner", | ||
"dependencies": { | ||
"async": "0.1.15" | ||
"async": "1.5.2" | ||
}, | ||
"devDependencies": {}, | ||
"devDependencies": { | ||
"ava": "^0.4.2", | ||
"eslint": "^3.10.2", | ||
"eslint-config-standard": "^6.2.1", | ||
"standard": "^8.5.0" | ||
}, | ||
"engines": { | ||
@@ -39,8 +48,3 @@ "node": ">=0.4", | ||
}, | ||
"licenses": [ | ||
{ | ||
"type": "MIT", | ||
"url": "https://github.com/baalexander/node-portscanner/raw/master/LICENSE" | ||
} | ||
] | ||
"license": "MIT" | ||
} |
@@ -1,3 +0,6 @@ | ||
# node-portscanner | ||
# portscanner | ||
[![npm](https://img.shields.io/npm/v/portscanner.svg)](https://www.npmjs.com/package/portscanner) | ||
[![JavaScript Style Guide](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/) | ||
The portscanner module is | ||
@@ -10,2 +13,4 @@ an asynchronous JavaScript port scanner for Node.js. | ||
[Looking for maintainer](https://github.com/baalexander/node-portscanner/issues/25)! | ||
## Install | ||
@@ -41,2 +46,17 @@ | ||
}) | ||
// You can also pass array of ports to check | ||
portscanner.findAPortInUse([3000, 3005, 3006], '127.0.0.1', function(error, port) { | ||
console.log('PORT IN USE AT: ' + port) | ||
}) | ||
// And skip host param. Default is '127.0.0.1' | ||
portscanner.findAPortNotInUse(3000, 4000, function(error, port) { | ||
console.log('PORT IN USE AT: ' + port) | ||
}) | ||
// And use promises | ||
portscanner.findAPortNotInUse(3000, 4000).then(function(port) { | ||
console.log('PORT IN USE AT: ' + port) | ||
}) | ||
``` | ||
@@ -48,5 +68,5 @@ | ||
There are currently no tests. | ||
If you have ideas, | ||
please open an issue. | ||
```sh | ||
npm test | ||
``` | ||
@@ -53,0 +73,0 @@ ## Future |
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
Deprecated
MaintenanceThe maintainer of the package marked it as deprecated. This could indicate that a single version should not be used, or that the package is no longer maintained and any new vulnerabilities will not be fixed.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
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
12028
227
80
4
1
3
+ Addedasync@1.5.2(transitive)
- Removedasync@0.1.15(transitive)
Updatedasync@1.5.2