diff --git a/lib/net_uv.js b/lib/net_uv.js index 484e61e9c4c..63f0a15080b 100644 --- a/lib/net_uv.js +++ b/lib/net_uv.js @@ -38,7 +38,7 @@ function initSocketHandle(self) { self._writeRequests = []; self._flags = 0; - + self._connectQueueSize = 0; self.destroyed = false; } @@ -111,7 +111,7 @@ Object.defineProperty(Socket.prototype, 'readyState', { Object.defineProperty(Socket.prototype, 'bufferSize', { get: function() { - return this._handle.writeQueueSize; + return this._handle.writeQueueSize + this._connectQueueSize; } }); @@ -165,9 +165,18 @@ Socket.prototype.destroySoon = function() { }; +Socket.prototype._connectQueueCleanUp = function(exception) { + this._connecting = false; + this._connectQueueSize = 0; + this._connectQueue = null; +}; + + Socket.prototype.destroy = function(exception) { var self = this; + self._connectQueueCleanUp(); + debug('destroy ' + this.fd); this.readable = this.writable = false; @@ -271,6 +280,18 @@ Socket.prototype.write = function(data /* [encoding], [fd], [cb] */) { data = new Buffer(data, encoding); } + // If we are still connecting, then buffer this for later. + if (this._connecting) { + this._connectQueueSize += data.length; + if (this._connectQueue) { + this._connectQueue.push([data, null, fd, cb]); + } else { + this._connectQueue = [ [data, null, fd, cb] ]; + } + return false; + } + + var writeReq = this._handle.write(data); writeReq.oncomplete = afterWrite; writeReq.cb = cb; @@ -307,12 +328,11 @@ function connectip(self, port, ip) { // TODO return promise from Socket.prototype.connect which // wraps _connectReq. - assert.ok(!self._connecting); + assert.ok(self._connecting); var connectReq = self._handle.connect(ip, port); if (connectReq) { - self._connecting = true; connectReq.oncomplete = afterConnect; } else { self.destroy(errnoException(errno, 'connect')); @@ -334,9 +354,10 @@ Socket.prototype.connect = function(port, host /* [cb] */) { timers.active(this); - if (typeof host == 'undefined') { - connectip(self, port, '127.0.0.1'); - } else { + self._connecting = true; + + if (typeof host == 'string') { + debug("connect: find host " + host); require('dns').lookup(host, function(err, ip, addressType) { if (err) { self.emit('error', err); @@ -350,6 +371,9 @@ Socket.prototype.connect = function(port, host /* [cb] */) { connectip(self, port, ip || '127.0.0.1'); } }); + } else { + debug("connect: missing host"); + connectip(self, port, '127.0.0.1'); } }; @@ -358,15 +382,28 @@ function afterConnect(status, handle, req) { var self = handle.socket; assert.equal(handle, self._handle); + debug("afterConnect"); + assert.ok(self._connecting); self._connecting = false; if (status == 0) { self.readable = self.writable = true; timers.active(self); + handle.readStart(); + + if (self._connectQueue) { + debug('Drain the connect queue'); + for (var i = 0; i < self._connectQueue.length; i++) { + self.write.apply(self, self._connectQueue[i]); + } + self._connectQueueCleanUp() + } + self.emit('connect'); } else { + self._connectQueueCleanUp() self.destroy(errnoException(errno, 'connect')); } } @@ -477,6 +514,8 @@ function onconnection(clientHandle) { var handle = this; var self = handle.socket; + debug("onconnection"); + var socket = new Socket({ handle: clientHandle, allowHalfOpen: self.allowHalfOpen diff --git a/test/simple/test-net-connect-buffer.js b/test/simple/test-net-connect-buffer.js index 42cda79796d..8cda2fb41cc 100644 --- a/test/simple/test-net-connect-buffer.js +++ b/test/simple/test-net-connect-buffer.js @@ -52,13 +52,15 @@ var tcp = net.Server(function(s) { tcp.listen(common.PORT, function () { var socket = net.Stream(); - console.log('Connecting to socket'); + console.log('Connecting to socket '); socket.connect(tcpPort, function() { console.log('socket connected'); connectHappened = true; }); + console.log('_connecting = ' + socket._connecting); + assert.equal('opening', socket.readyState); var r = socket.write('foo', function () {