Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
297fd28590 | ||
|
3325cff2a2 | ||
|
028d26e888 | ||
|
5fbbc0fa55 | ||
|
d2769ebd6e | ||
|
6ac3e1dd54 | ||
|
fef369519c | ||
|
a1ac58ddfc | ||
|
aa92e55145 |
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
node_modules/
|
41
LICENSE
Normal file
41
LICENSE
Normal file
@ -0,0 +1,41 @@
|
||||
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,10 +1,15 @@
|
||||
# StreamPair
|
||||
# SocketPair
|
||||
|
||||
[](http://badge.fury.io/js/socket-pair)
|
||||
|
||||
A pair of coupled Unix sockets (or Windows pipes).
|
||||
|
||||
Similar to `stream-pair`, but with sockets with real fds. A workaround for <https://github.com/nodejs/node/issues/12716>.
|
||||
Similar to `stream-pair`, but with sockets with real fds and `.setTimeout()`.
|
||||
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
|
||||
|
||||
@ -12,7 +17,7 @@ Similar to `stream-pair`, but with sockets with real fds. A workaround for <http
|
||||
var socketPair = require('socket-pair');
|
||||
|
||||
var socket = socketPair.create(function (err, other) {
|
||||
// socket as in `client = net.connect()`
|
||||
// socket as in `client = new net.Socket(); client.connect(...);`
|
||||
// other as in `server.on('connection', function (conn) { ... })`
|
||||
|
||||
socket.write('123');
|
||||
|
@ -1,15 +1,15 @@
|
||||
'use strict';
|
||||
|
||||
var server;
|
||||
var listening = false;
|
||||
var sock;
|
||||
var PromiseA = require('bluebird');
|
||||
var promises = {};
|
||||
|
||||
function createServer(cb, prefix) {
|
||||
function createServer(prefix) {
|
||||
var os = require('os');
|
||||
var net = require('net');
|
||||
var path = require('path');
|
||||
var sockname = (prefix || 'node-socket-pair') + '.' + require('crypto').randomBytes(16).toString('hex') + '.sock';
|
||||
var sockname = prefix + '.' + require('crypto').randomBytes(16).toString('hex') + '.sock';
|
||||
|
||||
var sock;
|
||||
if (/^win/.test(os.platform())) {
|
||||
sock = path.join('\\\\?\\pipe', process.cwd(), sockname);
|
||||
}
|
||||
@ -17,52 +17,68 @@ function createServer(cb, prefix) {
|
||||
sock = path.join(os.tmpdir(), sockname);
|
||||
}
|
||||
|
||||
server = net.createServer();
|
||||
function onServerError(err) {
|
||||
cb(err);
|
||||
}
|
||||
server.once('error', onServerError);
|
||||
server.once('listening', function () {
|
||||
listening = true;
|
||||
server.removeListener('error', onServerError);
|
||||
var server = net.createServer({allowHalfOpen: true});
|
||||
server.unref();
|
||||
promises[prefix] = new PromiseA(function (resolve, reject) {
|
||||
server.once('error', reject);
|
||||
|
||||
server.listen(sock, function () {
|
||||
server.removeListener('error', reject);
|
||||
resolve({sock: sock, server: server});
|
||||
});
|
||||
});
|
||||
|
||||
server.on('close', function () {
|
||||
delete promises[prefix];
|
||||
});
|
||||
|
||||
return promises[prefix];
|
||||
}
|
||||
|
||||
exports.create = function create(cb, prefix) {
|
||||
prefix = prefix || 'node-socket-pair';
|
||||
var net = require('net');
|
||||
var client = new net.Socket();
|
||||
var client = new net.Socket({allowHalfOpen: true});
|
||||
|
||||
function createConnection() {
|
||||
function onClientError(err) {
|
||||
cb(err);
|
||||
}
|
||||
client.connect(sock, function () {
|
||||
client.removeListener('error', onClientError);
|
||||
if (!promises[prefix]) {
|
||||
createServer(prefix);
|
||||
}
|
||||
|
||||
// We chain the promises to make sure that we never have multiple pending connections at
|
||||
// the same time to make sure the pairs are always matched correctly. Otherwise two different
|
||||
// `onConn` listeners might end up with the same connection.
|
||||
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) {
|
||||
result.server.removeListener('connection', onConn);
|
||||
cb(err);
|
||||
resolve(result);
|
||||
}
|
||||
client.once('error', onErr);
|
||||
client.connect(result.sock, function () {
|
||||
client.removeListener('error', onErr);
|
||||
});
|
||||
});
|
||||
client.once('error', onClientError);
|
||||
}
|
||||
|
||||
// This server listens on a Unix socket or Windows pipe at 'sock'
|
||||
if (!server) {
|
||||
createServer(cb, prefix);
|
||||
}
|
||||
|
||||
server.once('connection', function onEach(connection) {
|
||||
cb(null, connection);
|
||||
}, function (err) {
|
||||
cb(err);
|
||||
return PromiseA.reject(err);
|
||||
});
|
||||
|
||||
if (!listening) {
|
||||
server.listen(sock, createConnection);
|
||||
}
|
||||
else {
|
||||
createConnection();
|
||||
}
|
||||
|
||||
return client;
|
||||
};
|
||||
|
||||
exports.closeAll = function () {
|
||||
if (server) {
|
||||
server.close();
|
||||
}
|
||||
Object.keys(promises).forEach(function (key) {
|
||||
promises[key].then(function (result) {
|
||||
result.server.close();
|
||||
}, function () {
|
||||
delete promises[key];
|
||||
});
|
||||
});
|
||||
};
|
||||
|
12
package.json
12
package.json
@ -1,14 +1,15 @@
|
||||
{
|
||||
"name": "socket-pair",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.4",
|
||||
"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",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git@git.daplie.com:Daplie/socket-pair.git"
|
||||
"url": "https://git.coolaj86.com/coolaj86/socket-pair.js.git"
|
||||
},
|
||||
"keywords": [
|
||||
"tls",
|
||||
@ -22,6 +23,9 @@
|
||||
"coupled",
|
||||
"writer"
|
||||
],
|
||||
"author": "AJ ONeal <aj@daplie.com> (https://coolaj86.com)",
|
||||
"license": "MIT OR Apache-2.0"
|
||||
"author": "AJ ONeal <coolaj86@gmail.com> (https://coolaj86.com)",
|
||||
"license": "MIT OR Apache-2.0",
|
||||
"dependencies": {
|
||||
"bluebird": "^3.5.1"
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user