Added checkPortStatuses method #5

Closed
wants to merge 1 commit into from
View
123 README.md
@@ -1,58 +1,65 @@
-
-## The What
-
-The portscanner module is an asynchronous JavaScript port scanner for Node.js.
-
-Portscanner can check a port, or range of ports, for 'open' or 'closed'
-statuses.
-
-## The How
-
-### To Install
-
-```bash
-npm install portscanner
-```
-
-### To Use
-
-A brief example:
-
-```javascript
-var portscanner = require('portscanner')
-
-// Checks the status of a single port
-portscanner.checkPortStatus(3000, 'localhost', function(error, status) {
- // Status is 'open' if currently in use or 'closed' if available
- console.log(status)
-})
-
-// Find the first available port. Asynchronously checks, so first port
-// determined as available is returned.
-portscanner.findAPortNotInUse(3000, 3010, 'localhost', function(error, port) {
- console.log('AVAILABLE PORT AT: ' + port)
-})
-
-// Find the first port in use or blocked. Asynchronously checks, so first port
-// to respond is returned.
-portscanner.findAPortInUse(3000, 3010, 'localhost', function(error, port) {
- console.log('PORT IN USE AT: ' + port)
-})
-```
-
-The example directory contains a more detailed example.
-
-### To Test
-
-Bleh. I am a fan of testing, but currently looking into an easier way to test
-several HTTP connections. If any ideas, please message me.
-
-## The Future
-
-Please create issues, or better yet, pull requests, for port scanning related
-features you'd like to see included.
-
-## The License (MIT)
-
-Released under the MIT license. See the LICENSE file for the complete wording.
-
+
+## The What
+
+The portscanner module is an asynchronous JavaScript port scanner for Node.js.
+
+Portscanner can check a port, or range of ports, for 'open' or 'closed'
+statuses.
+
+## The How
+
+### To Install
+
+```bash
+npm install portscanner
+```
+
+### To Use
+
+A brief example:
+
+```javascript
+var portscanner = require('portscanner')
+
+// Checks the status of a single port
+portscanner.checkPortStatus(3000, 'localhost', function(error, status) {
+ // Status is 'open' if currently in use or 'closed' if available
+ console.log(status)
+})
+
+// Checks the status of a all ports in a range
+portscanner.checkPortStatuses(3000, 4000, 'localhost', function(error, statuses) {
+ // Statuses is an array of status objects,
+ // in the format of {port: port, status: status}
+ console.log(statuses)
+})
+
+// Find the first available port. Asynchronously checks, so first port
+// determined as available is returned.
+portscanner.findAPortNotInUse(3000, 3010, 'localhost', function(error, port) {
+ console.log('AVAILABLE PORT AT: ' + port)
+})
+
+// Find the first port in use or blocked. Asynchronously checks, so first port
+// to respond is returned.
+portscanner.findAPortInUse(3000, 3010, 'localhost', function(error, port) {
+ console.log('PORT IN USE AT: ' + port)
+})
+```
+
+The example directory contains a more detailed example.
+
+### To Test
+
+Bleh. I am a fan of testing, but currently looking into an easier way to test
+several HTTP connections. If any ideas, please message me.
+
+## The Future
+
+Please create issues, or better yet, pull requests, for port scanning related
+features you'd like to see included.
+
+## The License (MIT)
+
+Released under the MIT license. See the LICENSE file for the complete wording.
+
View
309 lib/portscanner.js
@@ -1,131 +1,178 @@
-var net = require('net')
- , Socket = net.Socket
- , async = require('async')
-
-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 'localhost'.
- * @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)
-}
-
-/**
- * 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 'localhost'.
- * @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.
- */
-portscanner.findAPortNotInUse = function(startPort, endPort, host, callback) {
- findAPortWithStatus('closed', startPort, endPort, host, callback)
-}
-
-/**
- * Checks the status of an individual port.
- *
- * @param {Number} port - Port to check status on.
- * @param {String} host - Where to scan. Defaults to 'localhost'.
- * @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, host, callback) {
- host = host || 'localhost'
- var socket = new Socket()
- , status = null
-
- // Socket connection established, port is open
- socket.on('connect', function() {
- status = 'open'
- socket.end()
- })
-
- // If no response, assume port is not listening
- socket.setTimeout(400)
- socket.on('timeout', function() {
- status = 'closed'
- socket.destroy()
- })
-
- // Assuming the port is not open if an error. May need to refine based on
- // exception
- socket.on('error', function(exception) {
- status = 'closed'
- })
-
- // Return after the socket has closed
- socket.on('close', function(exception) {
- callback(null, status)
- })
-
- socket.connect(port, host)
-}
-
-function findAPortWithStatus(status, startPort, endPort, host, callback) {
- endPort = endPort || 65535
- var foundPort = false
- var numberOfPortsChecked = 0
- var port = 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)
- }
-
- // Checks the status of the port
- var checkNextPort = function(callback) {
- portscanner.checkPortStatus(port, host, function(error, statusOfPort) {
- numberOfPortsChecked++
- if (error) {
- callback(error)
- }
- else if (statusOfPort === status) {
- foundPort = true
- callback(null, port)
- }
- else {
- port++
- callback(null, false)
- }
- })
- }
-
- // Check the status of each port until one with a matching status has been
- // found or the range of ports has been exhausted
- async.until(hasFoundPort, checkNextPort, function(error) {
- if (error) {
- callback(error)
- }
- else if (foundPort) {
- callback(null, port)
- }
- else {
- callback(null, false)
- }
- })
-}
-
+var net = require('net')
+ , Socket = net.Socket
+ , async = require('async')
+
+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 'localhost'.
+ * @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)
+}
+
+/**
+ * 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 'localhost'.
+ * @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.
+ */
+portscanner.findAPortNotInUse = function(startPort, endPort, host, callback) {
+ findAPortWithStatus('closed', startPort, endPort, host, callback)
+}
+
+/**
+ * Checks the status of an individual port.
+ *
+ * @param {Number} port - Port to check status on.
+ * @param {String} host - Where to scan. Defaults to 'localhost'.
+ * @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, host, callback) {
+ host = host || 'localhost'
+ var socket = new Socket()
+ , status = null
+
+ // Socket connection established, port is open
+ socket.on('connect', function() {
+ status = 'open'
+ socket.end()
+ })
+
+ // If no response, assume port is not listening
+ socket.setTimeout(400)
+ socket.on('timeout', function() {
+ status = 'closed'
+ socket.destroy()
+ })
+
+ // Assuming the port is not open if an error. May need to refine based on
+ // exception
+ socket.on('error', function(exception) {
+ status = 'closed'
+ })
+
+ // Return after the socket has closed
+ socket.on('close', function(exception) {
+ callback(null, status)
+ })
+
+ socket.connect(port, host)
+}
+
+/**
+ * Checks the status of a range of ports.
+ *
+ * @param {Number} startPort - Port to start scan on.
+ * @param {Number} endPort - Port to end scan on.
+ * @param {String} host - Where to scan. Defaults to 'localhost'.
+ * @param {Function} callback - function (error, port) { ... }
+ * - {Object|null} error - Any errors that occurred while port scanning.
+ * - {Array} statuses - An array of port statuses discovered in the scan
+ * Takes the form of [{port: port, status: status}]
+ */
+portscanner.checkPortStatuses = function(startPort, endPort, host, callback) {
+ endPort = endPort || 65535
+ var port = startPort
+ var statuses = []
+
+ // Have we reached the end?
+ var hasReachedEndPort = function(){
+ return port == endPort + 1;
+ }
+
+ // Checks the status of the port
+ var checkNextPort = function(callback) {
+ portscanner.checkPortStatus(port, host, function(error, statusOfPort) {
+ if (error) {
+ callback(error)
+ }
+ else {
+ statuses.push({port: port, status: statusOfPort})
+
+ port++
+ callback(null, port)
+ }
+ })
+ }
+
+ // Check the status of all ports, until we've reached the endPort
+ async.until(hasReachedEndPort, checkNextPort, function(error) {
+ if (error) {
+ callback(error)
+ }
+ else {
+ callback(null, statuses)
+ }
+ });
+}
+
+function findAPortWithStatus(status, startPort, endPort, host, callback) {
+ endPort = endPort || 65535
+ var foundPort = false
+ var numberOfPortsChecked = 0
+ var port = 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)
+ }
+
+ // Checks the status of the port
+ var checkNextPort = function(callback) {
+ portscanner.checkPortStatus(port, host, function(error, statusOfPort) {
+ numberOfPortsChecked++
+ if (error) {
+ callback(error)
+ }
+ else if (statusOfPort === status) {
+ foundPort = true
+ callback(null, port)
+ }
+ else {
+ port++
+ callback(null, false)
+ }
+ })
+ }
+
+ // Check the status of each port until one with a matching status has been
+ // found or the range of ports has been exhausted
+ async.until(hasFoundPort, checkNextPort, function(error) {
+ if (error) {
+ callback(error)
+ }
+ else if (foundPort) {
+ callback(null, port)
+ }
+ else {
+ callback(null, false)
+ }
+ })
+}
+