Compare commits
No commits in common. "master" and "v1.0.0" have entirely different histories.
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
node_modules/
|
|
41
LICENSE
41
LICENSE
@ -1,41 +0,0 @@
|
|||||||
Copyright 2017 AJ ONeal
|
|
||||||
|
|
||||||
This is open source software; you can redistribute it and/or modify it under the
|
|
||||||
terms of either:
|
|
||||||
|
|
||||||
a) the "MIT License"
|
|
||||||
b) the "Apache-2.0 License"
|
|
||||||
|
|
||||||
MIT License
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
Apache-2.0 License Summary
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
11
README.md
11
README.md
@ -1,15 +1,10 @@
|
|||||||
# SocketPair
|
# StreamPair
|
||||||
|
|
||||||
[](http://badge.fury.io/js/socket-pair)
|
[](http://badge.fury.io/js/socket-pair)
|
||||||
|
|
||||||
A pair of coupled Unix sockets (or Windows pipes).
|
A pair of coupled Unix sockets (or Windows pipes).
|
||||||
|
|
||||||
Similar to `stream-pair`, but with sockets with real fds and `.setTimeout()`.
|
Similar to `stream-pair`, but with sockets with real fds. A workaround for <https://github.com/nodejs/node/issues/12716>.
|
||||||
Originally a workaround for <https://github.com/nodejs/node/issues/12716>,
|
|
||||||
but still has some use relevant cases, particularly when building proxies.
|
|
||||||
|
|
||||||
**Note**: This workaround is necessary in node v6.11.1, but not necessary in node v8.2.1.
|
|
||||||
I would assume it is also not necessary in later versions.
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
@ -17,7 +12,7 @@ I would assume it is also not necessary in later versions.
|
|||||||
var socketPair = require('socket-pair');
|
var socketPair = require('socket-pair');
|
||||||
|
|
||||||
var socket = socketPair.create(function (err, other) {
|
var socket = socketPair.create(function (err, other) {
|
||||||
// socket as in `client = new net.Socket(); client.connect(...);`
|
// socket as in `client = net.connect()`
|
||||||
// other as in `server.on('connection', function (conn) { ... })`
|
// other as in `server.on('connection', function (conn) { ... })`
|
||||||
|
|
||||||
socket.write('123');
|
socket.write('123');
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var PromiseA = require('bluebird');
|
var server;
|
||||||
var promises = {};
|
var listening = false;
|
||||||
|
var sock;
|
||||||
|
|
||||||
function createServer(prefix) {
|
function createServer(cb, prefix) {
|
||||||
var os = require('os');
|
var os = require('os');
|
||||||
var net = require('net');
|
var net = require('net');
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
var sockname = prefix + '.' + require('crypto').randomBytes(16).toString('hex') + '.sock';
|
var sockname = (prefix || 'node-socket-pair') + '.' + require('crypto').randomBytes(16).toString('hex') + '.sock';
|
||||||
|
|
||||||
var sock;
|
|
||||||
if (/^win/.test(os.platform())) {
|
if (/^win/.test(os.platform())) {
|
||||||
sock = path.join('\\\\?\\pipe', process.cwd(), sockname);
|
sock = path.join('\\\\?\\pipe', process.cwd(), sockname);
|
||||||
}
|
}
|
||||||
@ -17,68 +17,52 @@ function createServer(prefix) {
|
|||||||
sock = path.join(os.tmpdir(), sockname);
|
sock = path.join(os.tmpdir(), sockname);
|
||||||
}
|
}
|
||||||
|
|
||||||
var server = net.createServer({allowHalfOpen: true});
|
server = net.createServer();
|
||||||
server.unref();
|
function onServerError(err) {
|
||||||
promises[prefix] = new PromiseA(function (resolve, reject) {
|
cb(err);
|
||||||
server.once('error', reject);
|
}
|
||||||
|
server.once('error', onServerError);
|
||||||
server.listen(sock, function () {
|
server.once('listening', function () {
|
||||||
server.removeListener('error', reject);
|
listening = true;
|
||||||
resolve({sock: sock, server: server});
|
server.removeListener('error', onServerError);
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on('close', function () {
|
|
||||||
delete promises[prefix];
|
|
||||||
});
|
|
||||||
|
|
||||||
return promises[prefix];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.create = function create(cb, prefix) {
|
exports.create = function create(cb, prefix) {
|
||||||
prefix = prefix || 'node-socket-pair';
|
|
||||||
var net = require('net');
|
var net = require('net');
|
||||||
var client = new net.Socket({allowHalfOpen: true});
|
var client = new net.Socket();
|
||||||
|
|
||||||
if (!promises[prefix]) {
|
function createConnection() {
|
||||||
createServer(prefix);
|
function onClientError(err) {
|
||||||
|
cb(err);
|
||||||
|
}
|
||||||
|
client.connect(sock, function () {
|
||||||
|
client.removeListener('error', onClientError);
|
||||||
|
});
|
||||||
|
client.once('error', onClientError);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We chain the promises to make sure that we never have multiple pending connections at
|
// This server listens on a Unix socket or Windows pipe at 'sock'
|
||||||
// the same time to make sure the pairs are always matched correctly. Otherwise two different
|
if (!server) {
|
||||||
// `onConn` listeners might end up with the same connection.
|
createServer(cb, prefix);
|
||||||
promises[prefix] = promises[prefix].then(function (result) {
|
}
|
||||||
return new PromiseA(function (resolve) {
|
|
||||||
function onConn(conn) {
|
|
||||||
cb(null, conn);
|
|
||||||
resolve(result);
|
|
||||||
}
|
|
||||||
result.server.once('connection', onConn);
|
|
||||||
|
|
||||||
function onErr(err) {
|
server.once('connection', function onEach(connection) {
|
||||||
result.server.removeListener('connection', onConn);
|
cb(null, connection);
|
||||||
cb(err);
|
|
||||||
resolve(result);
|
|
||||||
}
|
|
||||||
client.once('error', onErr);
|
|
||||||
client.connect(result.sock, function () {
|
|
||||||
client.removeListener('error', onErr);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}, function (err) {
|
|
||||||
cb(err);
|
|
||||||
return PromiseA.reject(err);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!listening) {
|
||||||
|
server.listen(sock, createConnection);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
createConnection();
|
||||||
|
}
|
||||||
|
|
||||||
return client;
|
return client;
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.closeAll = function () {
|
exports.closeAll = function () {
|
||||||
Object.keys(promises).forEach(function (key) {
|
if (server) {
|
||||||
promises[key].then(function (result) {
|
server.close();
|
||||||
result.server.close();
|
}
|
||||||
}, function () {
|
|
||||||
delete promises[key];
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
12
package.json
12
package.json
@ -1,15 +1,14 @@
|
|||||||
{
|
{
|
||||||
"name": "socket-pair",
|
"name": "socket-pair",
|
||||||
"version": "1.0.4",
|
"version": "1.0.0",
|
||||||
"description": "Similar to stream-pair, but with sockets with real fds. A workaround for https://github.com/nodejs/node/issues/12716",
|
"description": "Similar to stream-pair, but with sockets with real fds. A workaround for https://github.com/nodejs/node/issues/12716",
|
||||||
"homepage": "https://git.coolaj86.com/coolaj86/socket-pair.js",
|
|
||||||
"main": "lib/socket-pair.js",
|
"main": "lib/socket-pair.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://git.coolaj86.com/coolaj86/socket-pair.js.git"
|
"url": "git@git.daplie.com:Daplie/socket-pair.git"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"tls",
|
"tls",
|
||||||
@ -23,9 +22,6 @@
|
|||||||
"coupled",
|
"coupled",
|
||||||
"writer"
|
"writer"
|
||||||
],
|
],
|
||||||
"author": "AJ ONeal <coolaj86@gmail.com> (https://coolaj86.com)",
|
"author": "AJ ONeal <aj@daplie.com> (https://coolaj86.com)",
|
||||||
"license": "MIT OR Apache-2.0",
|
"license": "MIT OR Apache-2.0"
|
||||||
"dependencies": {
|
|
||||||
"bluebird": "^3.5.1"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user