From ddc989333dced1fd33baf1114fccd15a333771e3 Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Thu, 16 Jun 2011 15:33:47 +0200 Subject: [PATCH] tcp_wrap: implement socket.connect() --- src/tcp_wrap.cc | 50 ++++++++++++++++++++++++++++++++++-- test/simple/test-tcp-wrap-connect.js | 40 +++++++++++++++++++++++++++++ test/simple/test-tcp-wrap-listen.js | 3 ++- 3 files changed, 90 insertions(+), 3 deletions(-) create mode 100644 test/simple/test-tcp-wrap-connect.js diff --git a/src/tcp_wrap.cc b/src/tcp_wrap.cc index 9de6c79..6f7ac5b 100644 --- a/src/tcp_wrap.cc +++ b/src/tcp_wrap.cc @@ -97,6 +97,7 @@ class TCPWrap { NODE_SET_PROTOTYPE_METHOD(t, "readStart", ReadStart); NODE_SET_PROTOTYPE_METHOD(t, "readStop", ReadStop); NODE_SET_PROTOTYPE_METHOD(t, "write", Write); + NODE_SET_PROTOTYPE_METHOD(t, "connect", Connect); NODE_SET_PROTOTYPE_METHOD(t, "close", Close); constructor = Persistent::New(t->GetFunction()); @@ -346,13 +347,14 @@ class TCPWrap { SetErrno(uv_last_error().code); } - Local argv[3] = { + Local argv[4] = { + Integer::New(status), Local::New(wrap->object_), Local::New(req_wrap->object_), req_wrap->object_->GetHiddenValue(buffer_sym), }; - MakeCallback(req_wrap->object_, "oncomplete", 3, argv); + MakeCallback(req_wrap->object_, "oncomplete", 4, argv); delete req_wrap; } @@ -397,6 +399,50 @@ class TCPWrap { return scope.Close(req_wrap->object_); } + static void AfterConnect(uv_req_t* req, int status) { + ReqWrap* req_wrap = (ReqWrap*) req->data; + TCPWrap* wrap = (TCPWrap*) req->handle->data; + + HandleScope scope; + + if (status) { + SetErrno(uv_last_error().code); + } + + Local argv[3] = { + Integer::New(status), + Local::New(wrap->object_), + Local::New(req_wrap->object_) + }; + + MakeCallback(req_wrap->object_, "oncomplete", 3, argv); + + delete req_wrap; + } + + static Handle Connect(const Arguments& args) { + HandleScope scope; + + UNWRAP + + String::AsciiValue ip_address(args[0]->ToString()); + int port = args[1]->Int32Value(); + + struct sockaddr_in address = uv_ip4_addr(*ip_address, port); + + // I hate when people program C++ like it was C, and yet I do it too. + // I'm too lazy to come up with the perfect class hierarchy here. Let's + // just do some type munging. + ReqWrap* req_wrap = new ReqWrap((uv_handle_t*) &wrap->handle_, + (void*)AfterConnect); + + int r = uv_connect(&req_wrap->req_, address); + + if (r) SetErrno(uv_last_error().code); + + return scope.Close(req_wrap->object_); + } + uv_tcp_t handle_; Persistent object_; size_t slab_offset_; diff --git a/test/simple/test-tcp-wrap-connect.js b/test/simple/test-tcp-wrap-connect.js new file mode 100644 index 0000000..bce516b --- /dev/null +++ b/test/simple/test-tcp-wrap-connect.js @@ -0,0 +1,40 @@ +var common = require('../common'); +var assert = require('assert'); +var TCP = process.binding('tcp_wrap').TCP; + +function makeConnection() { + var client = new TCP(); + + var req = client.connect('127.0.0.1', common.PORT); + req.oncomplete = function(status, client_, req_) { + assert.equal(0, status); + assert.equal(client, client_); + assert.equal(req, req_); + + console.log("connected"); + client.close(); + }; +} + +///// + +var connectCount = 0; +var endCount = 0; + +var server = require('net').Server(function(s) { + console.log("got connection"); + connectCount++; + s.on('end', function() { + console.log("got eof"); + endCount++; + s.destroy(); + server.close(); + }); +}); + +server.listen(common.PORT, makeConnection); + +process.on('exit', function() { + assert.equal(1, connectCount); + assert.equal(1, endCount); +}); diff --git a/test/simple/test-tcp-wrap-listen.js b/test/simple/test-tcp-wrap-listen.js index 6ada670..891fa63 100644 --- a/test/simple/test-tcp-wrap-listen.js +++ b/test/simple/test-tcp-wrap-listen.js @@ -34,10 +34,11 @@ server.onconnection = function(client) { var req = client.write(buffer, offset, length); client.pendingWrites.push(req); - req.oncomplete = function(client_, req_, buffer_) { + req.oncomplete = function(status, client_, req_, buffer_) { assert.equal(req, client.pendingWrites.shift()); // Check parameters. + assert.equal(0, status); assert.equal(client, client_); assert.equal(req, req_); assert.equal(buffer, buffer_); -- 2.7.4