This commit is contained in:
chrosey
2017-09-13 07:52:34 +02:00
parent a1f16c37f4
commit 2340b0226b
24621 changed files with 2912161 additions and 149 deletions
+22
View File
@@ -0,0 +1,22 @@
node-portfinder
Copyright (c) 2012 Charlie Robbins
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+55
View File
@@ -0,0 +1,55 @@
# node-portfinder [![Build Status](https://api.travis-ci.org/indexzero/node-portfinder.svg)](https://travis-ci.org/indexzero/node-portfinder)
## Installation
``` bash
$ [sudo] npm install portfinder
```
## Usage
The `portfinder` module has a simple interface:
``` js
var portfinder = require('portfinder');
portfinder.getPort(function (err, port) {
//
// `port` is guaranteed to be a free port
// in this scope.
//
});
```
Or with promise (if Promise are supported) :
``` js
const portfinder = require('portfinder');
portfinder.getPortPromise()
.then((port) => {
//
// `port` is guaranteed to be a free port
// in this scope.
//
})
.catch((err) => {
//
// Could not get a free port, `err` contains the reason.
//
});
```
If `portfinder.getPortPromise()` is called on a Node version without Promise (<4), it will throw an Error unless [Bluebird](http://bluebirdjs.com/docs/getting-started.html) or any Promise pollyfill is used.
By default `portfinder` will start searching from `8000`. To change this simply set `portfinder.basePort`.
## Run Tests
``` bash
$ npm test
```
#### Author: [Charlie Robbins][0]
#### Maintainer: [Erik Trom][1]
#### License: MIT/X11
[0]: http://nodejitsu.com
[1]: https://github.com/eriktrom
+33
View File
@@ -0,0 +1,33 @@
/**
* portfinder.js typescript definitions.
*
* (C) 2011, Charlie Robbins
*/
type PortfinderCallback = (err: Error, port: number) => void;
interface PortFinderOptions{
/**
* Host to find available port on.
*/
host?: string;
/**
* Minimum port (takes precedence over `basePort`).
*/
port?: number;
}
/**
* The lowest port to begin any port search from.
*/
export let basePort: number;
/**
* Responds with a unbound port on the current machine.
*/
export function getPort(callback: PortfinderCallback): void;
export function getPort(options: PortFinderOptions, callback: PortfinderCallback): void;
/**
* Responds a promise of an unbound port on the current machine.
*/
export function getPortPromise(options?: PortFinderOptions): Promise<number>;
+454
View File
@@ -0,0 +1,454 @@
/*
* portfinder.js: A simple tool to find an open port on the current machine.
*
* (C) 2011, Charlie Robbins
*
*/
"use strict";
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 = {};
internals.testPort = function(options, callback) {
if (!callback) {
callback = options;
options = {};
}
options.port = options.port || exports.basePort;
options.host = options.host || null;
options.server = options.server || net.createServer(function () {
//
// Create an empty listener for the port testing server.
//
});
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);
options.server.close();
callback(null, options.port);
}
function onError (err) {
debugTestPort("done w/ testPort(): failed", options.host, "w/ port", options.port, "with error", err.code);
options.server.removeListener('listening', onListen);
if (err.code !== 'EADDRINUSE' && err.code !== 'EACCES') {
return callback(err);
}
internals.testPort({
port: exports.nextPort(options.port),
host: options.host,
server: options.server
}, callback);
}
options.server.once('error', onError);
options.server.once('listening', onListen);
options.server.listen(options.port, options.host);
};
//
// ### @basePort {Number}
// The lowest port to begin any port search from
//
exports.basePort = 8000;
//
// ### @basePath {string}
// Default path to begin any socket search from
//
exports.basePath = '/tmp/portfinder'
//
// ### function getPort (options, callback)
// #### @options {Object} Settings to use when finding the necessary port
// #### @callback {function} Continuation to respond to when complete.
// Responds with a unbound port on the current machine.
//
exports.getPort = function (options, callback) {
if (!callback) {
callback = options;
options = {};
}
if (options.host) {
var hasUserGivenHost;
for (var i = 0; i < exports._defaultHosts.length; i++) {
if (exports._defaultHosts[i] === options.host) {
hasUserGivenHost = true;
break;
}
}
if (!hasUserGivenHost) {
exports._defaultHosts.push(options.host);
}
}
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);
return next();
}
});
}, function(err) {
if (err) {
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));
}
var idx = exports._defaultHosts.indexOf(currentHost);
exports._defaultHosts.splice(idx, 1);
return exports.getPort(options, callback);
} else {
// error is not accounted for, file ticket, handle special case
return callback(err);
}
}
// sort so we can compare first host to last host
openPorts.sort(function(a, b) {
return a - b;
});
debugGetPort("in eachSeries() result callback: openPorts is", openPorts);
if (openPorts[0] === openPorts[openPorts.length-1]) {
// if first === last, we found an open port
return callback(null, openPorts[0]);
} else {
// otherwise, try again, using sorted port, aka, highest open for >= 1 host
return exports.getPort({ port: openPorts.pop(), host: options.host }, callback);
}
});
};
//
// ### function getPortPromise (options)
// #### @options {Object} Settings to use when finding the necessary port
// Responds a promise to an unbound port on the current machine.
//
exports.getPortPromise = function (options) {
if (typeof Promise !== 'function') {
throw Error('Native promise support is not available in this version of node.' +
'Please install a polyfill and assign Promise to global.Promise before calling this method');
}
if (!options) {
options = {};
}
return new Promise(function(resolve, reject) {
exports.getPort(options, function(err, port) {
if (err) {
return reject(err);
}
resolve(port);
});
});
}
//
// ### function getPorts (count, options, callback)
// #### @count {Number} The number of ports to find
// #### @options {Object} Settings to use when finding the necessary port
// #### @callback {function} Continuation to respond to when complete.
// Responds with an array of unbound ports on the current machine.
//
exports.getPorts = function (count, options, callback) {
if (!callback) {
callback = options;
options = {};
}
var lastPort = null;
async.timesSeries(count, function(index, asyncCallback) {
if (lastPort) {
options.port = exports.nextPort(lastPort);
}
exports.getPort(options, function (err, port) {
if (err) {
asyncCallback(err);
} else {
lastPort = port;
asyncCallback(null, port);
}
});
}, callback);
};
//
// ### function getSocket (options, callback)
// #### @options {Object} Settings to use when finding the necessary port
// #### @callback {function} Continuation to respond to when complete.
// Responds with a unbound socket using the specified directory and base
// name on the current machine.
//
exports.getSocket = function (options, callback) {
if (!callback) {
callback = options;
options = {};
}
options.mod = options.mod || parseInt(755, 8);
options.path = options.path || exports.basePath + '.sock';
//
// Tests the specified socket
//
function testSocket () {
fs.stat(options.path, function (err) {
//
// If file we're checking doesn't exist (thus, stating it emits ENOENT),
// we should be OK with listening on this socket.
//
if (err) {
if (err.code == 'ENOENT') {
callback(null, options.path);
}
else {
callback(err);
}
}
else {
//
// This file exists, so it isn't possible to listen on it. Lets try
// next socket.
//
options.path = exports.nextSocket(options.path);
exports.getSocket(options, callback);
}
});
}
//
// Create the target `dir` then test connection
// against the socket.
//
function createAndTestSocket (dir) {
mkdirp(dir, options.mod, function (err) {
if (err) {
return callback(err);
}
options.exists = true;
testSocket();
});
}
//
// Check if the parent directory of the target
// socket path exists. If it does, test connection
// against the socket. Otherwise, create the directory
// then test connection.
//
function checkAndTestSocket () {
var dir = path.dirname(options.path);
fs.stat(dir, function (err, stats) {
if (err || !stats.isDirectory()) {
return createAndTestSocket(dir);
}
options.exists = true;
testSocket();
});
}
//
// If it has been explicitly stated that the
// target `options.path` already exists, then
// simply test the socket.
//
return options.exists
? testSocket()
: checkAndTestSocket();
};
//
// ### function nextPort (port)
// #### @port {Number} Port to increment from.
// Gets the next port in sequence from the
// specified `port`.
//
exports.nextPort = function (port) {
return port + 1;
};
//
// ### function nextSocket (socketPath)
// #### @socketPath {string} Path to increment from
// Gets the next socket path in sequence from the
// specified `socketPath`.
//
exports.nextSocket = function (socketPath) {
var dir = path.dirname(socketPath),
name = path.basename(socketPath, '.sock'),
match = name.match(/^([a-zA-z]+)(\d*)$/i),
index = parseInt(match[2]),
base = match[1];
if (isNaN(index)) {
index = 0;
}
index += 1;
return path.join(dir, base + index + '.sock');
};
/**
* @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 = {};
try{
interfaces = os.networkInterfaces();
}
catch(e) {
// As of October 2016, Windows Subsystem for Linux (WSL) does not support
// the os.networkInterfaces() call and throws instead. For this platform,
// assume 0.0.0.0 as the only address
//
// - https://github.com/Microsoft/BashOnWindows/issues/468
//
// - Workaround is a mix of good work from the community:
// - https://github.com/indexzero/node-portfinder/commit/8d7e30a648ff5034186551fa8a6652669dec2f2f
// - https://github.com/yarnpkg/yarn/pull/772/files
if (e.syscall === 'uv_interface_addresses') {
// swallow error because we're just going to use defaults
// documented @ https://github.com/nodejs/node/blob/4b65a65e75f48ff447cabd5500ce115fb5ad4c57/doc/api/net.md#L231
} else {
throw e;
}
}
var 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;
}());
+107
View File
@@ -0,0 +1,107 @@
{
"_args": [
[
{
"raw": "portfinder@^1.0.9",
"scope": null,
"escapedName": "portfinder",
"name": "portfinder",
"rawSpec": "^1.0.9",
"spec": ">=1.0.9 <2.0.0",
"type": "range"
},
"c:\\xampp\\htdocs\\laravel\\node_modules\\webpack-dev-server"
]
],
"_from": "portfinder@>=1.0.9 <2.0.0",
"_id": "portfinder@1.0.13",
"_inCache": true,
"_location": "/portfinder",
"_nodeVersion": "7.3.0",
"_npmOperationalInternal": {
"host": "packages-18-east.internal.npmjs.com",
"tmp": "tmp/portfinder-1.0.13.tgz_1485873781112_0.17709231283515692"
},
"_npmUser": {
"name": "eriktrom",
"email": "erik.trom.github@gmail.com"
},
"_npmVersion": "4.1.1",
"_phantomChildren": {},
"_requested": {
"raw": "portfinder@^1.0.9",
"scope": null,
"escapedName": "portfinder",
"name": "portfinder",
"rawSpec": "^1.0.9",
"spec": ">=1.0.9 <2.0.0",
"type": "range"
},
"_requiredBy": [
"/webpack-dev-server"
],
"_resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.13.tgz",
"_shasum": "bb32ecd87c27104ae6ee44b5a3ccbf0ebb1aede9",
"_shrinkwrap": null,
"_spec": "portfinder@^1.0.9",
"_where": "c:\\xampp\\htdocs\\laravel\\node_modules\\webpack-dev-server",
"author": {
"name": "Charlie Robbins",
"email": "charlie.robbins@gmail.com"
},
"bugs": {
"url": "https://github.com/indexzero/node-portfinder/issues"
},
"dependencies": {
"async": "^1.5.2",
"debug": "^2.2.0",
"mkdirp": "0.5.x"
},
"description": "A simple tool to find an open port on the current machine",
"devDependencies": {
"glob": "^6.0.4",
"vows": "0.8.0"
},
"directories": {},
"dist": {
"shasum": "bb32ecd87c27104ae6ee44b5a3ccbf0ebb1aede9",
"tarball": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.13.tgz"
},
"engines": {
"node": ">= 0.12.0"
},
"files": [
"lib"
],
"gitHead": "20161e8e00355099c90062a069a7aa68dc9bcf9b",
"homepage": "https://github.com/indexzero/node-portfinder#readme",
"keywords": [
"http",
"ports",
"utilities"
],
"license": "MIT",
"main": "./lib/portfinder",
"maintainers": [
{
"name": "eriktrom",
"email": "erik.trom.github@gmail.com"
},
{
"name": "indexzero",
"email": "charlie.robbins@gmail.com"
}
],
"name": "portfinder",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/indexzero/node-portfinder.git"
},
"scripts": {
"test": "vows test/*-test.js --spec"
},
"types": "./lib/portfinder.d.ts",
"version": "1.0.13"
}