|
@ -167,7 +167,7 @@ function onWritable(readable, writable) { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function initStream(self) { |
|
|
function initSocket(self) { |
|
|
self._readWatcher = ioWatchers.alloc(); |
|
|
self._readWatcher = ioWatchers.alloc(); |
|
|
self._readWatcher.socket = self; |
|
|
self._readWatcher.socket = self; |
|
|
self._readWatcher.callback = onReadable; |
|
|
self._readWatcher.callback = onReadable; |
|
@ -185,10 +185,10 @@ function initStream(self) { |
|
|
self.writable = false; |
|
|
self.writable = false; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Deprecated API: Stream(fd, type)
|
|
|
// Deprecated API: Socket(fd, type)
|
|
|
// New API: Stream({ fd: 10, type: 'unix', allowHalfOpen: true })
|
|
|
// New API: Socket({ fd: 10, type: 'unix', allowHalfOpen: true })
|
|
|
function Stream(options) { |
|
|
function Socket(options) { |
|
|
if (!(this instanceof Stream)) return new Stream(arguments[0], arguments[1]); |
|
|
if (!(this instanceof Socket)) return new Socket(arguments[0], arguments[1]); |
|
|
stream.Stream.call(this); |
|
|
stream.Stream.call(this); |
|
|
|
|
|
|
|
|
this.fd = null; |
|
|
this.fd = null; |
|
@ -210,17 +210,19 @@ function Stream(options) { |
|
|
setImplmentationMethods(this); |
|
|
setImplmentationMethods(this); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
util.inherits(Stream, stream.Stream); |
|
|
util.inherits(Socket, stream.Stream); |
|
|
exports.Stream = Stream; |
|
|
exports.Socket = Socket; |
|
|
|
|
|
|
|
|
|
|
|
// Legacy naming.
|
|
|
|
|
|
exports.Stream = Socket; |
|
|
|
|
|
|
|
|
Stream.prototype._onTimeout = function() { |
|
|
Socket.prototype._onTimeout = function() { |
|
|
this.emit('timeout'); |
|
|
this.emit('timeout'); |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Stream.prototype.open = function(fd, type) { |
|
|
Socket.prototype.open = function(fd, type) { |
|
|
initStream(this); |
|
|
initSocket(this); |
|
|
|
|
|
|
|
|
this.fd = fd; |
|
|
this.fd = fd; |
|
|
this.type = type || null; |
|
|
this.type = type || null; |
|
@ -234,13 +236,13 @@ Stream.prototype.open = function(fd, type) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
exports.createConnection = function(port, host) { |
|
|
exports.createConnection = function(port, host) { |
|
|
var s = new Stream(); |
|
|
var s = new Socket(); |
|
|
s.connect(port, host); |
|
|
s.connect(port, host); |
|
|
return s; |
|
|
return s; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Object.defineProperty(Stream.prototype, 'readyState', { |
|
|
Object.defineProperty(Socket.prototype, 'readyState', { |
|
|
get: function() { |
|
|
get: function() { |
|
|
if (this._connecting) { |
|
|
if (this._connecting) { |
|
|
return 'opening'; |
|
|
return 'opening'; |
|
@ -264,7 +266,7 @@ Object.defineProperty(Stream.prototype, 'readyState', { |
|
|
// Returns true if all the data was flushed to socket. Returns false if
|
|
|
// Returns true if all the data was flushed to socket. Returns false if
|
|
|
// something was queued. If data was queued, then the 'drain' event will
|
|
|
// something was queued. If data was queued, then the 'drain' event will
|
|
|
// signal when it has been finally flushed to socket.
|
|
|
// signal when it has been finally flushed to socket.
|
|
|
Stream.prototype.write = function(data /* [encoding], [fd], [cb] */) { |
|
|
Socket.prototype.write = function(data /* [encoding], [fd], [cb] */) { |
|
|
var encoding, fd, cb; |
|
|
var encoding, fd, cb; |
|
|
|
|
|
|
|
|
// parse arguments
|
|
|
// parse arguments
|
|
@ -301,7 +303,7 @@ Stream.prototype.write = function(data /* [encoding], [fd], [cb] */) { |
|
|
|
|
|
|
|
|
// Slow. There is already a write queue, so let's append to it.
|
|
|
// Slow. There is already a write queue, so let's append to it.
|
|
|
if (this._writeQueueLast() === END_OF_FILE) { |
|
|
if (this._writeQueueLast() === END_OF_FILE) { |
|
|
throw new Error('Stream.end() called already; cannot write.'); |
|
|
throw new Error('Socket.end() called already; cannot write.'); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
var last = this._writeQueue.length - 1; |
|
|
var last = this._writeQueue.length - 1; |
|
@ -351,9 +353,9 @@ Stream.prototype.write = function(data /* [encoding], [fd], [cb] */) { |
|
|
// 2. Write data to socket. Return true if flushed.
|
|
|
// 2. Write data to socket. Return true if flushed.
|
|
|
// 3. Slice out remaining
|
|
|
// 3. Slice out remaining
|
|
|
// 4. Unshift remaining onto _writeQueue. Return false.
|
|
|
// 4. Unshift remaining onto _writeQueue. Return false.
|
|
|
Stream.prototype._writeOut = function(data, encoding, fd, cb) { |
|
|
Socket.prototype._writeOut = function(data, encoding, fd, cb) { |
|
|
if (!this.writable) { |
|
|
if (!this.writable) { |
|
|
throw new Error('Stream is not writable'); |
|
|
throw new Error('Socket is not writable'); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
var buffer, off, len; |
|
|
var buffer, off, len; |
|
@ -445,7 +447,7 @@ Stream.prototype._writeOut = function(data, encoding, fd, cb) { |
|
|
leftOver.used = leftOver.length; // used the whole thing...
|
|
|
leftOver.used = leftOver.length; // used the whole thing...
|
|
|
|
|
|
|
|
|
// util.error('data.used = ' + data.used);
|
|
|
// util.error('data.used = ' + data.used);
|
|
|
//if (!this._writeQueue) initWriteStream(this);
|
|
|
//if (!this._writeQueue) initWriteSocket(this);
|
|
|
|
|
|
|
|
|
// data should be the next thing to write.
|
|
|
// data should be the next thing to write.
|
|
|
this._writeQueue.unshift(leftOver); |
|
|
this._writeQueue.unshift(leftOver); |
|
@ -463,7 +465,7 @@ Stream.prototype._writeOut = function(data, encoding, fd, cb) { |
|
|
|
|
|
|
|
|
// Flushes the write buffer out.
|
|
|
// Flushes the write buffer out.
|
|
|
// Returns true if the entire buffer was flushed.
|
|
|
// Returns true if the entire buffer was flushed.
|
|
|
Stream.prototype.flush = function() { |
|
|
Socket.prototype.flush = function() { |
|
|
while (this._writeQueue && this._writeQueue.length) { |
|
|
while (this._writeQueue && this._writeQueue.length) { |
|
|
var data = this._writeQueue.shift(); |
|
|
var data = this._writeQueue.shift(); |
|
|
var encoding = this._writeQueueEncoding.shift(); |
|
|
var encoding = this._writeQueueEncoding.shift(); |
|
@ -483,13 +485,13 @@ Stream.prototype.flush = function() { |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Stream.prototype._writeQueueLast = function() { |
|
|
Socket.prototype._writeQueueLast = function() { |
|
|
return this._writeQueue.length > 0 ? |
|
|
return this._writeQueue.length > 0 ? |
|
|
this._writeQueue[this._writeQueue.length - 1] : null; |
|
|
this._writeQueue[this._writeQueue.length - 1] : null; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Stream.prototype.setEncoding = function(encoding) { |
|
|
Socket.prototype.setEncoding = function(encoding) { |
|
|
var StringDecoder = require('string_decoder').StringDecoder; // lazy load
|
|
|
var StringDecoder = require('string_decoder').StringDecoder; // lazy load
|
|
|
this._decoder = new StringDecoder(encoding); |
|
|
this._decoder = new StringDecoder(encoding); |
|
|
}; |
|
|
}; |
|
@ -521,7 +523,7 @@ function doConnect(socket, port, host) { |
|
|
function toPort(x) { return (x = Number(x)) >= 0 ? x : false; } |
|
|
function toPort(x) { return (x = Number(x)) >= 0 ? x : false; } |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Stream.prototype._onConnect = function() { |
|
|
Socket.prototype._onConnect = function() { |
|
|
var errno = socketError(this.fd); |
|
|
var errno = socketError(this.fd); |
|
|
if (errno == 0) { |
|
|
if (errno == 0) { |
|
|
// connection established
|
|
|
// connection established
|
|
@ -548,8 +550,8 @@ Stream.prototype._onConnect = function() { |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Stream.prototype._onWritable = function() { |
|
|
Socket.prototype._onWritable = function() { |
|
|
// Stream becomes writable on connect() but don't flush if there's
|
|
|
// Socket becomes writable on connect() but don't flush if there's
|
|
|
// nothing actually to write
|
|
|
// nothing actually to write
|
|
|
if (this.flush()) { |
|
|
if (this.flush()) { |
|
|
if (this._events && this._events['drain']) this.emit('drain'); |
|
|
if (this._events && this._events['drain']) this.emit('drain'); |
|
@ -559,7 +561,7 @@ Stream.prototype._onWritable = function() { |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Stream.prototype._onReadable = function() { |
|
|
Socket.prototype._onReadable = function() { |
|
|
var self = this; |
|
|
var self = this; |
|
|
|
|
|
|
|
|
// If this is the first recv (pool doesn't exist) or we've used up
|
|
|
// If this is the first recv (pool doesn't exist) or we've used up
|
|
@ -623,14 +625,14 @@ Stream.prototype._onReadable = function() { |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// var stream = new Stream();
|
|
|
// var socket = new Socket();
|
|
|
// stream.connect(80) - TCP connect to port 80 on the localhost
|
|
|
// socket.connect(80) - TCP connect to port 80 on the localhost
|
|
|
// stream.connect(80, 'nodejs.org') - TCP connect to port 80 on nodejs.org
|
|
|
// socket.connect(80, 'nodejs.org') - TCP connect to port 80 on nodejs.org
|
|
|
// stream.connect('/tmp/socket') - UNIX connect to socket specified by path
|
|
|
// socket.connect('/tmp/socket') - UNIX connect to socket specified by path
|
|
|
Stream.prototype.connect = function() { |
|
|
Socket.prototype.connect = function() { |
|
|
var self = this; |
|
|
var self = this; |
|
|
initStream(self); |
|
|
initSocket(self); |
|
|
if (self.fd) throw new Error('Stream already opened'); |
|
|
if (self.fd) throw new Error('Socket already opened'); |
|
|
if (!self._readWatcher) throw new Error('No readWatcher'); |
|
|
if (!self._readWatcher) throw new Error('No readWatcher'); |
|
|
|
|
|
|
|
|
require('timers').active(socket); |
|
|
require('timers').active(socket); |
|
@ -666,25 +668,25 @@ Stream.prototype.connect = function() { |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Stream.prototype.address = function() { |
|
|
Socket.prototype.address = function() { |
|
|
return getsockname(this.fd); |
|
|
return getsockname(this.fd); |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Stream.prototype.setNoDelay = function(v) { |
|
|
Socket.prototype.setNoDelay = function(v) { |
|
|
if ((this.type == 'tcp4') || (this.type == 'tcp6')) { |
|
|
if ((this.type == 'tcp4') || (this.type == 'tcp6')) { |
|
|
setNoDelay(this.fd, v); |
|
|
setNoDelay(this.fd, v); |
|
|
} |
|
|
} |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
Stream.prototype.setKeepAlive = function(enable, time) { |
|
|
Socket.prototype.setKeepAlive = function(enable, time) { |
|
|
if ((this.type == 'tcp4') || (this.type == 'tcp6')) { |
|
|
if ((this.type == 'tcp4') || (this.type == 'tcp6')) { |
|
|
var secondDelay = Math.ceil(time / 1000); |
|
|
var secondDelay = Math.ceil(time / 1000); |
|
|
setKeepAlive(this.fd, enable, secondDelay); |
|
|
setKeepAlive(this.fd, enable, secondDelay); |
|
|
} |
|
|
} |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
Stream.prototype.setTimeout = function(msecs) { |
|
|
Socket.prototype.setTimeout = function(msecs) { |
|
|
if (msecs > 0) { |
|
|
if (msecs > 0) { |
|
|
require('timers').enroll(this, msecs); |
|
|
require('timers').enroll(this, msecs); |
|
|
if (this.fd) { require('timers').active(this); } |
|
|
if (this.fd) { require('timers').active(this); } |
|
@ -694,13 +696,13 @@ Stream.prototype.setTimeout = function(msecs) { |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Stream.prototype.pause = function() { |
|
|
Socket.prototype.pause = function() { |
|
|
if (this._readWatcher) this._readWatcher.stop(); |
|
|
if (this._readWatcher) this._readWatcher.stop(); |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Stream.prototype.resume = function() { |
|
|
Socket.prototype.resume = function() { |
|
|
if (this.fd === null) throw new Error('Cannot resume() closed Stream.'); |
|
|
if (this.fd === null) throw new Error('Cannot resume() closed Socket.'); |
|
|
if (this._readWatcher) { |
|
|
if (this._readWatcher) { |
|
|
this._readWatcher.stop(); |
|
|
this._readWatcher.stop(); |
|
|
this._readWatcher.set(this.fd, true, false); |
|
|
this._readWatcher.set(this.fd, true, false); |
|
@ -708,7 +710,7 @@ Stream.prototype.resume = function() { |
|
|
} |
|
|
} |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
Stream.prototype.destroySoon = function() { |
|
|
Socket.prototype.destroySoon = function() { |
|
|
if (this.flush()) { |
|
|
if (this.flush()) { |
|
|
this.destroy(); |
|
|
this.destroy(); |
|
|
} else { |
|
|
} else { |
|
@ -716,7 +718,7 @@ Stream.prototype.destroySoon = function() { |
|
|
} |
|
|
} |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
Stream.prototype.destroy = function(exception) { |
|
|
Socket.prototype.destroy = function(exception) { |
|
|
// pool is shared between sockets, so don't need to free it here.
|
|
|
// pool is shared between sockets, so don't need to free it here.
|
|
|
var self = this; |
|
|
var self = this; |
|
|
|
|
|
|
|
@ -758,7 +760,7 @@ Stream.prototype.destroy = function(exception) { |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Stream.prototype._shutdown = function() { |
|
|
Socket.prototype._shutdown = function() { |
|
|
if (!this.writable) { |
|
|
if (!this.writable) { |
|
|
throw new Error('The connection is not writable'); |
|
|
throw new Error('The connection is not writable'); |
|
|
} else { |
|
|
} else { |
|
@ -780,7 +782,7 @@ Stream.prototype._shutdown = function() { |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Stream.prototype.end = function(data, encoding) { |
|
|
Socket.prototype.end = function(data, encoding) { |
|
|
if (this.writable) { |
|
|
if (this.writable) { |
|
|
if (this._writeQueueLast() !== END_OF_FILE) { |
|
|
if (this._writeQueueLast() !== END_OF_FILE) { |
|
|
if (data) this.write(data, encoding); |
|
|
if (data) this.write(data, encoding); |
|
@ -855,7 +857,7 @@ function Server(/* [ options, ] listener */) { |
|
|
var options = { fd: peerInfo.fd, |
|
|
var options = { fd: peerInfo.fd, |
|
|
type: self.type, |
|
|
type: self.type, |
|
|
allowHalfOpen: self.allowHalfOpen }; |
|
|
allowHalfOpen: self.allowHalfOpen }; |
|
|
var s = new Stream(options); |
|
|
var s = new Socket(options); |
|
|
s.remoteAddress = peerInfo.address; |
|
|
s.remoteAddress = peerInfo.address; |
|
|
s.remotePort = peerInfo.port; |
|
|
s.remotePort = peerInfo.port; |
|
|
s.type = self.type; |
|
|
s.type = self.type; |
|
|