multiserver
Advanced tools
Comparing version 3.3.5 to 3.3.6
{ | ||
"name": "multiserver", | ||
"description": "write a server which works over many protocols at once, or connect to the same", | ||
"version": "3.3.5", | ||
"version": "3.3.6", | ||
"homepage": "https://github.com/dominictarr/multiserver", | ||
@@ -6,0 +6,0 @@ "repository": { |
var net | ||
try { | ||
net = require('net') | ||
} catch (_) {} | ||
function isString(s) { | ||
return 'string' == typeof s | ||
} catch (_) { | ||
// This only throws in browsers because they don't have access to the Node | ||
// net library, which is safe to ignore because they shouldn't be running | ||
// any methods that require the net library. Maybe we should be setting a | ||
// flag somewhere rather than checking whether `net == null`? | ||
} | ||
@@ -14,20 +15,24 @@ | ||
const isString = (s) => 'string' == typeof s | ||
const toAddress = (host, port) => ['net', host, port ].join(':') | ||
function toDuplex (str) { | ||
var stream = toPull.duplex(str) | ||
stream.address = 'net:'+str.remoteAddress+':'+str.remotePort | ||
stream.address = toAddress(str.remoteAddress, str.remotePort) | ||
return stream | ||
} | ||
module.exports = function (opts) { | ||
// Choose a dynamic port between 49152 and 65535 | ||
// https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers#Dynamic,_private_or_ephemeral_ports | ||
var port = opts.port || Math.floor(49152 + (65535 - 49152 + 1) * Math.random()) | ||
//does this actually need to set host from the scope here? | ||
var host = opts.host || (isString(opts.scope) && scopes.host(opts.scope)) | ||
var scope = opts.scope || 'device' | ||
// FIXME: does this even work anymore? | ||
opts.allowHalfOpen = opts.allowHalfOpen !== false | ||
// Choose a dynamic port between 49152 and 65535 | ||
// https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers#Dynamic,_private_or_ephemeral_ports | ||
const getRandomPort = () => | ||
Math.floor(49152 + (65535 - 49152 + 1) * Math.random()) | ||
function isScoped (s) { | ||
return s === scope || Array.isArray(scope) && ~scope.indexOf(s) | ||
module.exports = ({ scope = 'device', host, port, external, allowHalfOpen, pauseOnConnect }) => { | ||
// Arguments are `scope` and `external` plus selected options for | ||
// `net.createServer()` and `server.listen()`. | ||
host = host || (isString(scope) && scopes.host(scope)) | ||
port = port || getRandomPort() | ||
function isAllowedScope (s) { | ||
return s === scope || Array.isArray(scope) && scope.includes(s) | ||
} | ||
@@ -37,8 +42,15 @@ | ||
name: 'net', | ||
scope: function() { | ||
return scope | ||
}, | ||
scope: () => scope, | ||
server: function (onConnection, startedCb) { | ||
debug('Listening on %s:%d', host, port) | ||
var server = net.createServer(opts, function (stream) { | ||
// TODO: We convert `allowHalfOpen` to boolean for legacy reasons, this | ||
// might not be getting used anywhere but I'm too scared to change it. | ||
// This should probably be removed when we do a major version bump. | ||
const serverOpts = { | ||
allowHalfOpen: Boolean(allowHalfOpen), | ||
pauseOnConnect | ||
} | ||
var server = net.createServer(serverOpts, function (stream) { | ||
onConnection(toDuplex(stream)) | ||
@@ -56,3 +68,2 @@ }).listen(port, host, startedCb) | ||
client: function (opts, cb) { | ||
var addr = 'net:'+opts.host+':'+opts.port | ||
var started = false | ||
@@ -80,7 +91,7 @@ var stream = net.connect(opts) | ||
parse: function (s) { | ||
if(!net) return null | ||
if (net == null) return null | ||
var ary = s.split(':') | ||
if(ary.length < 3) return null | ||
if('net' !== ary.shift()) return null | ||
var port = +ary.pop() | ||
var port = Number(ary.pop()) | ||
if(isNaN(port)) return null | ||
@@ -93,8 +104,18 @@ return { | ||
}, | ||
stringify: function (scope) { | ||
scope = scope || 'device' | ||
if(!isScoped(scope)) return | ||
var _host = (scope == 'public' && opts.external) || scopes.host(scope) | ||
if(!_host) return null | ||
return ['net', _host, port].join(':') | ||
stringify: function (targetScope = 'device') { | ||
if (isAllowedScope(targetScope) === false) { | ||
return null | ||
} | ||
// We want to avoid using `host` if the target scope is public and some | ||
// external host (like example.com) is defined. | ||
const externalHost = targetScope === 'public' && external | ||
const resultHost = externalHost || host || scopes.host(targetScope) | ||
if (resultHost == null) { | ||
// The device has no network interface for a given `targetScope`. | ||
return null | ||
} | ||
return toAddress(resultHost, port) | ||
} | ||
@@ -101,0 +122,0 @@ } |
@@ -31,7 +31,15 @@ var WS = require('pull-ws') | ||
module.exports = function (opts) { | ||
opts = opts || {} | ||
opts.binaryType = (opts.binaryType || 'arraybuffer') | ||
var scope = opts.scope || 'device' | ||
function isScoped (s) { | ||
// Choose a dynamic port between 49152 and 65535 | ||
// https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers#Dynamic,_private_or_ephemeral_ports | ||
const getRandomPort = () => | ||
Math.floor(49152 + (65535 - 49152 + 1) * Math.random()) | ||
module.exports = function (opts = {}) { | ||
// This takes options for `WebSocket.Server()`: | ||
// https://github.com/websockets/ws/blob/master/doc/ws.md#new-websocketserveroptions-callback | ||
opts.binaryType = opts.binaryType || 'arraybuffer' | ||
const scope = opts.scope || 'device' | ||
function isAllowedScope (s) { | ||
return s === scope || Array.isArray(scope) && ~scope.indexOf(s) | ||
@@ -43,13 +51,18 @@ } | ||
name: 'ws', | ||
scope: function() { return opts.scope || 'device' }, | ||
scope: () => scope, | ||
server: function (onConnect, startedCb) { | ||
if (WS.createServer == null) { | ||
return null | ||
} | ||
if(!WS.createServer) return | ||
// Choose a dynamic port between 49152 and 65535 | ||
// https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers#Dynamic,_private_or_ephemeral_ports | ||
opts.port = opts.port || Math.floor(49152 + (65535 - 49152 + 1) * Math.random()) | ||
// Maybe weird: this sets a random port each time that `server()` is run | ||
// whereas the net plugin sets the port when the outer function is run. | ||
// | ||
// This server has a random port generated at runtime rather than when | ||
// the interface is instantiated. Is that the way it should work? | ||
opts.port = opts.port || getRandomPort() | ||
var server = opts.server || http.createServer(opts.handler) | ||
var ws_server = WS.createServer(Object.assign({}, opts, {server: server}), function (stream) { | ||
WS.createServer(Object.assign({}, opts, {server: server}), function (stream) { | ||
stream.address = safe_origin( | ||
@@ -104,20 +117,23 @@ stream.headers.origin, | ||
}, | ||
stringify: function (scope) { | ||
scope = scope || 'device' | ||
if(!isScoped(scope)) return null | ||
if(!WS.createServer) return null | ||
var port | ||
if(opts.server) | ||
port = opts.server.address().port | ||
else | ||
port = opts.port | ||
stringify: function (targetScope = 'device') { | ||
if (WS.createServer == null) { | ||
return null | ||
} | ||
if (isAllowedScope(targetScope) === false) { | ||
return null | ||
} | ||
var host = (scope == 'public' && opts.external) || scopes.host(scope) | ||
//if a public scope was requested, but a public ip is not available, return | ||
if(!host) return null | ||
const port = opts.server ? opts.server.address().port : opts.port | ||
const externalHost = targetScope === 'public' && opts.external | ||
const resultHost = externalHost || opts.host || scopes.host(targetScope) | ||
if (resultHost == null) { | ||
// The device has no network interface for a given `targetScope`. | ||
return null | ||
} | ||
return URL.format({ | ||
protocol: secure ? 'wss' : 'ws', | ||
slashes: true, | ||
hostname: host, | ||
hostname: resultHost, | ||
port: (secure ? port == 443 : port == 80) ? undefined : port | ||
@@ -124,0 +140,0 @@ }) |
@@ -81,3 +81,2 @@ var tape = require('tape') | ||
tape('connect to either server', function (t) { | ||
multi_ws.client(server_addr, function (err, stream) { | ||
@@ -100,3 +99,2 @@ if(err) throw err | ||
tape('connect to either server', function (t) { | ||
multi_net.client(server_addr, function (err, stream) { | ||
@@ -103,0 +101,0 @@ if(err) throw err |
@@ -400,1 +400,30 @@ var fs = require('fs') | ||
tape('multiple public different hosts', function(t) { | ||
var net1 = Net({ host: '127.0.0.1', port: 4848, scope: 'public'}) | ||
var net2 = Net({ host: '::1', port: 4847, scope: 'public'}) | ||
var combined1 = Compose([net1, shs]) | ||
var combined2 = Compose([net2, shs]) | ||
t.equal( | ||
MultiServer([combined1, combined2]).stringify('public'), | ||
[combined1.stringify('public'), combined2.stringify('public')].join(';') | ||
) | ||
t.end() | ||
}) | ||
tape('multiple scopes different hosts', function(t) { | ||
var net1 = Net({ host: '127.0.0.1', port: 4848, scope: ['local', 'device', 'public']}) | ||
var net2 = Net({ host: '::1', port: 4847, scope: ['local', 'device', 'public']}) | ||
var combined1 = Compose([net1, shs]) | ||
var combined2 = Compose([net2, shs]) | ||
t.equal( | ||
MultiServer([combined1, combined2]).stringify('public'), | ||
[combined1.stringify('public'), combined2.stringify('public')].join(';') | ||
) | ||
t.end() | ||
}) |
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
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
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
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
3
54332
17
1203
4