Skip to content

Commit

Permalink
Improve arguments parsing
Browse files Browse the repository at this point in the history
Doesn't assume callback is always provided (as a last argument). (preliminary for promise support)

spread arguments instead of passing - `findAPortInUse` used to pass its `arguments` object to `findAPortWithStatus` as a single parameter. It's better to actually spread it like arguments naturally do, also makes it easy to extend them.

More verbose for clarity.
  • Loading branch information
laggingreflex committed Nov 19, 2016
1 parent da1ce58 commit 3b90e2c
Showing 1 changed file with 72 additions and 39 deletions.
111 changes: 72 additions & 39 deletions lib/portscanner.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,20 @@ var async = require('async')
* // scans 3000 and 3002 only, not 3001.
* portscanner.findAPortInUse([3000, 3002], console.log)
*/
function findAPortInUse (params) {
findAPortWithStatus('open', arguments)
function findAPortInUse () {
var params = [].slice.call(arguments)
params.unshift('open')
return findAPortWithStatus.apply(null, params)
}

/**
* Finds the first port with a status of 'closed', implying the port is not in
* use. Accepts identical parameters as {@link findAPortInUse}
*/
function findAPortNotInUse (params) {
findAPortWithStatus('closed', arguments)
function findAPortNotInUse () {
var params = [].slice.call(arguments)
params.unshift('closed')
return findAPortWithStatus.apply(null, params)
}

/**
Expand All @@ -53,25 +57,33 @@ function findAPortNotInUse (params) {
* @param {Number} [opts.timeout=400] - Connection timeout in ms.
* @param {checkPortCallback} callback - Function to call back with error or results.
*/
function checkPortStatus (port, arg2, arg3) {
var options = {}
var callback
function checkPortStatus (port) {
var args, host, opts, callback

if (typeof arg2 === 'string') {
// Assume this param is the host option
options = { host: arg2 }
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]
}

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]
}
opts = opts || {}

/**
* 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.
*/
callback = Array.prototype.slice.call(arguments).slice(-1)[0]
host = host || opts.host || '127.0.0.1'

var host = options.host || '127.0.0.1'
var timeout = options.timeout || 400
var timeout = opts.timeout || 400
var connectionRefused = false

var socket = new Socket()
Expand Down Expand Up @@ -111,6 +123,12 @@ function checkPortStatus (port, arg2, arg3) {

socket.connect(port, host)
}
/**
* 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.
*/

/**
* Internal helper function used by {@link findAPortInUse} and {@link findAPortNotInUse}
Expand All @@ -120,36 +138,45 @@ function checkPortStatus (port, arg2, arg3) {
* @param {String} status - Status to check.
* @param {...params} params - Params as passed exactly to {@link findAPortInUse} and {@link findAPortNotInUse}.
*/
function findAPortWithStatus (status, params) {
var host, callback

if (typeof params[0] === 'object') {
var ports = params[0]
host = typeof params[1] === 'string' ? params[1] : null
} else if (typeof params[0] === 'number') {
var startPort = params[0]
var endPort = params[1]
host = typeof params[2] === 'string' ? params[2] : null
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]
}

/**
* 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.
*/
callback = Array.prototype.slice.call(params).slice(-1)[0]
if (typeof params[3] === 'function') {
callback = params[3]
}

endPort = endPort || 65535

var foundPort = false
var numberOfPortsChecked = 0
var port = ports ? ports[0] : 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 === (ports ? ports.length : endPort - startPort + 1)
return foundPort || numberOfPortsChecked === (portList ? portList.length : endPort - startPort + 1)
}

// Checks the status of the port
Expand All @@ -160,7 +187,7 @@ function findAPortWithStatus (status, params) {
foundPort = true
callback(error)
} else {
port = ports ? ports[numberOfPortsChecked] : port + 1
port = portList ? portList[numberOfPortsChecked] : port + 1
callback(null)
}
})
Expand All @@ -178,6 +205,12 @@ function findAPortWithStatus (status, params) {
}
})
}
/**
* 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
Expand Down

0 comments on commit 3b90e2c

Please sign in to comment.