mirror of
https://github.com/nodejs/node.git
synced 2025-05-15 19:48:12 +00:00
lib,src: add unix socket getsockname/getpeername
The implementation is a minor API change in that socket.address() now returns a `{ address: '/path/to/socket' }` object, like it does for TCP and UDP sockets. Before this commit, it returned `socket._pipeName`, which is a string when present. Change common.PIPE on Windows from '\\\\.\\pipe\\libuv-test' to '\\\\?\\pipe\\libuv-test'. Windows converts the '.' to a '?' when creating a named pipe, meaning that common.PIPE didn't match the result from NtQueryInformationFile(). Fixes: https://github.com/nodejs/node/issues/954 PR-URL: https://github.com/nodejs/node/pull/956 Reviewed-By: Sam Roberts <vieuxtech@gmail.com> Reviewed-By: Trevor Norris <trev.norris@gmail.com>
This commit is contained in:
parent
a43af39ffc
commit
f337595441
@ -255,6 +255,9 @@ Example:
|
|||||||
|
|
||||||
Don't call `server.address()` until the `'listening'` event has been emitted.
|
Don't call `server.address()` until the `'listening'` event has been emitted.
|
||||||
|
|
||||||
|
This method used to return the file path as a string for UNIX sockets and
|
||||||
|
Windows pipes. As of io.js v1.5.0, it returns the expected object.
|
||||||
|
|
||||||
### server.unref()
|
### server.unref()
|
||||||
|
|
||||||
Calling `unref` on a server will allow the program to exit if this is the only
|
Calling `unref` on a server will allow the program to exit if this is the only
|
||||||
@ -508,14 +511,18 @@ Returns `socket`.
|
|||||||
The string representation of the remote IP address. For example,
|
The string representation of the remote IP address. For example,
|
||||||
`'74.125.127.100'` or `'2001:4860:a005::68'`.
|
`'74.125.127.100'` or `'2001:4860:a005::68'`.
|
||||||
|
|
||||||
|
For UNIX sockets and Windows pipes, the file path the socket is connected
|
||||||
|
to. The remote address for server sockets is always `''`, the empty string.
|
||||||
|
|
||||||
### socket.remoteFamily
|
### socket.remoteFamily
|
||||||
|
|
||||||
The string representation of the remote IP family. `'IPv4'` or `'IPv6'`.
|
The string representation of the remote IP family. `'IPv4'` or `'IPv6'`
|
||||||
|
for TCP sockets, `'pipe'` for UNIX sockets and Windows pipes.
|
||||||
|
|
||||||
### socket.remotePort
|
### socket.remotePort
|
||||||
|
|
||||||
The numeric representation of the remote port. For example,
|
The numeric representation of the remote port. For example, `80` or `21`.
|
||||||
`80` or `21`.
|
`undefined` for UNIX sockets and Windows pipes.
|
||||||
|
|
||||||
### socket.localAddress
|
### socket.localAddress
|
||||||
|
|
||||||
@ -523,10 +530,13 @@ The string representation of the local IP address the remote client is
|
|||||||
connecting on. For example, if you are listening on `'0.0.0.0'` and the
|
connecting on. For example, if you are listening on `'0.0.0.0'` and the
|
||||||
client connects on `'192.168.1.1'`, the value would be `'192.168.1.1'`.
|
client connects on `'192.168.1.1'`, the value would be `'192.168.1.1'`.
|
||||||
|
|
||||||
|
For UNIX sockets and Windows pipes, the file path the socket is listening
|
||||||
|
on. The local address for client sockets is always `''`, the empty string.
|
||||||
|
|
||||||
### socket.localPort
|
### socket.localPort
|
||||||
|
|
||||||
The numeric representation of the local port. For example,
|
The numeric representation of the local port. For example, `80` or `21`.
|
||||||
`80` or `21`.
|
`undefined` for UNIX sockets and Windows pipes.
|
||||||
|
|
||||||
### socket.bytesRead
|
### socket.bytesRead
|
||||||
|
|
||||||
|
@ -1339,16 +1339,14 @@ Server.prototype.listen = function() {
|
|||||||
else
|
else
|
||||||
listen(self, null, h.port | 0, 4, backlog, undefined, h.exclusive);
|
listen(self, null, h.port | 0, 4, backlog, undefined, h.exclusive);
|
||||||
} else if (h.path && isPipeName(h.path)) {
|
} else if (h.path && isPipeName(h.path)) {
|
||||||
var pipeName = self._pipeName = h.path;
|
listen(self, h.path, -1, -1, backlog, undefined, h.exclusive);
|
||||||
listen(self, pipeName, -1, -1, backlog, undefined, h.exclusive);
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Invalid listen argument: ' + h);
|
throw new Error('Invalid listen argument: ' + h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (isPipeName(arguments[0])) {
|
} else if (isPipeName(arguments[0])) {
|
||||||
// UNIX socket or Windows pipe.
|
// UNIX socket or Windows pipe.
|
||||||
var pipeName = self._pipeName = arguments[0];
|
listen(self, arguments[0], -1, -1, backlog);
|
||||||
listen(self, pipeName, -1, -1, backlog);
|
|
||||||
|
|
||||||
} else if (arguments[1] === undefined ||
|
} else if (arguments[1] === undefined ||
|
||||||
typeof arguments[1] === 'function' ||
|
typeof arguments[1] === 'function' ||
|
||||||
@ -1381,8 +1379,6 @@ Server.prototype.address = function() {
|
|||||||
this._handle.getsockname(out);
|
this._handle.getsockname(out);
|
||||||
// TODO(bnoordhuis) Check err and throw?
|
// TODO(bnoordhuis) Check err and throw?
|
||||||
return out;
|
return out;
|
||||||
} else if (this._pipeName) {
|
|
||||||
return this._pipeName;
|
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -89,6 +89,10 @@ void PipeWrap::Initialize(Handle<Object> target,
|
|||||||
env->SetProtoMethod(t, "listen", Listen);
|
env->SetProtoMethod(t, "listen", Listen);
|
||||||
env->SetProtoMethod(t, "connect", Connect);
|
env->SetProtoMethod(t, "connect", Connect);
|
||||||
env->SetProtoMethod(t, "open", Open);
|
env->SetProtoMethod(t, "open", Open);
|
||||||
|
env->SetProtoMethod(t, "getpeername",
|
||||||
|
GetSockOrPeerName<uv_pipe_getpeername>);
|
||||||
|
env->SetProtoMethod(t, "getsockname",
|
||||||
|
GetSockOrPeerName<uv_pipe_getsockname>);
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
env->SetProtoMethod(t, "setPendingInstances", SetPendingInstances);
|
env->SetProtoMethod(t, "setPendingInstances", SetPendingInstances);
|
||||||
@ -276,6 +280,28 @@ void PipeWrap::Connect(const FunctionCallbackInfo<Value>& args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <int (*F)(const uv_pipe_t*, char*, size_t*)>
|
||||||
|
void PipeWrap::GetSockOrPeerName(
|
||||||
|
const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||||
|
CHECK(args[0]->IsObject());
|
||||||
|
char buffer[1024];
|
||||||
|
size_t size = sizeof(buffer);
|
||||||
|
const PipeWrap* wrap = Unwrap<PipeWrap>(args.Holder());
|
||||||
|
const int err = F(&wrap->handle_, buffer, &size);
|
||||||
|
if (err == 0) {
|
||||||
|
const uint8_t* data = reinterpret_cast<const uint8_t*>(buffer);
|
||||||
|
const String::NewStringType type = String::kNormalString;
|
||||||
|
Local<String> path =
|
||||||
|
String::NewFromOneByte(args.GetIsolate(), data, type, size);
|
||||||
|
Environment* env = Environment::GetCurrent(args);
|
||||||
|
Local<Object> out = args[0].As<Object>();
|
||||||
|
out->Set(env->address_string(), path);
|
||||||
|
out->Set(env->family_string(), env->pipe_string());
|
||||||
|
}
|
||||||
|
args.GetReturnValue().Set(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace node
|
} // namespace node
|
||||||
|
|
||||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(pipe_wrap, node::PipeWrap::Initialize)
|
NODE_MODULE_CONTEXT_AWARE_BUILTIN(pipe_wrap, node::PipeWrap::Initialize)
|
||||||
|
@ -30,6 +30,9 @@ class PipeWrap : public StreamWrap {
|
|||||||
static void Connect(const v8::FunctionCallbackInfo<v8::Value>& args);
|
static void Connect(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||||
static void Open(const v8::FunctionCallbackInfo<v8::Value>& args);
|
static void Open(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||||
|
|
||||||
|
template <int (*F)(const uv_pipe_t*, char*, size_t*)>
|
||||||
|
static void GetSockOrPeerName(const v8::FunctionCallbackInfo<v8::Value>&);
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
static void SetPendingInstances(
|
static void SetPendingInstances(
|
||||||
const v8::FunctionCallbackInfo<v8::Value>& args);
|
const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||||
|
@ -134,7 +134,7 @@ Object.defineProperty(exports, 'hasCrypto', {get: function() {
|
|||||||
}});
|
}});
|
||||||
|
|
||||||
if (exports.isWindows) {
|
if (exports.isWindows) {
|
||||||
exports.PIPE = '\\\\.\\pipe\\libuv-test';
|
exports.PIPE = '\\\\?\\pipe\\libuv-test';
|
||||||
} else {
|
} else {
|
||||||
exports.PIPE = exports.tmpDir + '/test.sock';
|
exports.PIPE = exports.tmpDir + '/test.sock';
|
||||||
}
|
}
|
||||||
|
@ -29,8 +29,11 @@ if (cluster.isMaster) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
http.createServer(function(req, res) {
|
http.createServer(function(req, res) {
|
||||||
assert.equal(req.connection.remoteAddress, undefined);
|
assert.equal(req.connection.remoteAddress, '');
|
||||||
assert.equal(req.connection.localAddress, undefined); // TODO common.PIPE?
|
assert.equal(req.connection.remoteFamily, 'pipe');
|
||||||
|
assert.equal(req.connection.remotePort, undefined);
|
||||||
|
assert.equal(req.connection.localAddress, common.PIPE);
|
||||||
|
assert.equal(req.connection.localPort, undefined);
|
||||||
res.writeHead(200);
|
res.writeHead(200);
|
||||||
res.end('OK');
|
res.end('OK');
|
||||||
}).listen(common.PIPE, function() {
|
}).listen(common.PIPE, function() {
|
||||||
|
@ -9,6 +9,7 @@ var headers_ok = false;
|
|||||||
var body_ok = false;
|
var body_ok = false;
|
||||||
|
|
||||||
var server = http.createServer(function(req, res) {
|
var server = http.createServer(function(req, res) {
|
||||||
|
assert.equal(req.socket.address().address, common.PIPE);
|
||||||
res.writeHead(200, {
|
res.writeHead(200, {
|
||||||
'Content-Type': 'text/plain',
|
'Content-Type': 'text/plain',
|
||||||
'Connection': 'close'
|
'Connection': 'close'
|
||||||
@ -19,6 +20,7 @@ var server = http.createServer(function(req, res) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
server.listen(common.PIPE, function() {
|
server.listen(common.PIPE, function() {
|
||||||
|
assert.equal(server.address().address, common.PIPE);
|
||||||
|
|
||||||
var options = {
|
var options = {
|
||||||
socketPath: common.PIPE,
|
socketPath: common.PIPE,
|
||||||
|
@ -15,5 +15,6 @@ server.listen(common.PIPE, function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
process.on('exit', function() {
|
process.on('exit', function() {
|
||||||
assert.equal(address, common.PIPE);
|
assert.equal(address.address, common.PIPE);
|
||||||
|
assert.equal(address.family, 'pipe');
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user