Browse Source

allowHalfOpen disabled by default

Users too often would forget to add

  socket.on('end', function () {
    socket.end();
  });

Which is a mistake. Therefore we default to this behavior and
only optionally let people handle the 'end' case themselves.
v0.7.4-release
Ryan Dahl 14 years ago
parent
commit
2470d2ee92
  1. 13
      doc/api.markdown
  2. 4
      doc/index.html
  3. 6
      lib/http.js
  4. 51
      lib/net.js
  5. 2
      test/pummel/test-net-pingpong-delay.js
  6. 2
      test/pummel/test-net-pingpong.js
  7. 4
      test/simple/test-net-pingpong.js

13
doc/api.markdown

@ -2311,9 +2311,16 @@ Emitted when data is received. The argument `data` will be a `Buffer` or
`function () { }` `function () { }`
Emitted when the other end of the stream sends a FIN packet. After this is Emitted when the other end of the stream sends a FIN packet.
emitted the `readyState` will be `'writeOnly'`. One should probably just
call `stream.end()` when this event is emitted. By default (`allowHalfOpen == false`) the stream will destroy its file
descriptor once it has written out its pending write queue. However, by
setting `allowHalfOpen == true` the stream will not automatically `end()`
its side allowing the user to write arbitrary amounts of data, with the
caviot that the user is required to `end()` thier side now. In the
`allowHalfOpen == true` case after `'end'` is emitted the `readyState` will
be `'writeOnly'`.
### Event: 'timeout' ### Event: 'timeout'

4
doc/index.html

@ -67,14 +67,10 @@ Server running at http://127.0.0.1:8124/</pre>
<pre> <pre>
var net = require('net'); var net = require('net');
net.createServer(function (socket) { net.createServer(function (socket) {
socket.setEncoding("utf8");
socket.write("Echo server\r\n"); socket.write("Echo server\r\n");
socket.on("data", function (data) { socket.on("data", function (data) {
socket.write(data); socket.write(data);
}); });
socket.on("end", function () {
socket.end();
});
}).listen(8124, "127.0.0.1"); }).listen(8124, "127.0.0.1");
</pre> </pre>

6
lib/http.js

@ -743,9 +743,9 @@ function httpSocketSetup (socket) {
function Server (requestListener) { function Server (requestListener) {
if (!(this instanceof Server)) return new Server(requestListener); if (!(this instanceof Server)) return new Server(requestListener);
net.Server.call(this); net.Server.call(this, { allowHalfOpen: true });
if(requestListener){ if (requestListener) {
this.addListener("request", requestListener); this.addListener("request", requestListener);
} }
@ -877,7 +877,7 @@ function connectionListener (socket) {
function Client ( ) { function Client ( ) {
if (!(this instanceof Client)) return new Client(); if (!(this instanceof Client)) return new Client();
net.Stream.call(this); net.Stream.call(this, { allowHalfOpen: true });
var self = this; var self = this;
httpSocketSetup(self); httpSocketSetup(self);

51
lib/net.js

@ -475,6 +475,7 @@ function initStream (self) {
if (!self.writable) self.destroy(); if (!self.writable) self.destroy();
// Note: 'close' not emitted until nextTick. // Note: 'close' not emitted until nextTick.
if (!self.allowHalfOpen) self.end();
if (self._events && self._events['end']) self.emit('end'); if (self._events && self._events['end']) self.emit('end');
if (self.onend) self.onend(); if (self.onend) self.onend();
} else if (bytesRead > 0) { } else if (bytesRead > 0) {
@ -519,16 +520,29 @@ function initStream (self) {
self.writable = false; self.writable = false;
} }
function Stream (fd, type) { // Deprecated API: Stream(fd, type)
if (!(this instanceof Stream)) return new Stream(fd, type); // New API: Stream({ fd: 10, type: "unix", allowHalfOpen: true })
function Stream (options) {
if (!(this instanceof Stream)) return new Stream(arguments[0], arguments[1]);
stream.Stream.call(this); stream.Stream.call(this);
this.fd = null; this.fd = null;
this.type = null; this.type = null;
this.secure = false; this.secure = false;
this.allowHalfOpen = false;
if (typeof options == "object") {
this.fd = options.fd !== undefined ? parseInt(options.fd, 10) : null;
this.type = options.type || null;
this.secure = options.secure || false;
this.allowHalfOpen = options.allowHalfOpen || false;
} else if (typeof options == "number") {
this.fd = arguments[0];
this.type = arguments[1];
}
if (parseInt(fd, 10) >= 0) { if (parseInt(this.fd, 10) >= 0) {
this.open(fd, type); this.open(this.fd, this.type);
} else { } else {
setImplmentationMethods(this); setImplmentationMethods(this);
} }
@ -1030,8 +1044,8 @@ Stream.prototype._shutdown = function () {
Stream.prototype.end = function (data, encoding) { Stream.prototype.end = function (data, encoding) {
if (this.writable) { if (this.writable) {
if (data) this.write(data, encoding);
if (this._writeQueueLast() !== END_OF_FILE) { if (this._writeQueueLast() !== END_OF_FILE) {
if (data) this.write(data, encoding);
this._writeQueue.push(END_OF_FILE); this._writeQueue.push(END_OF_FILE);
if (!this._connecting) { if (!this._connecting) {
this.flush(); this.flush();
@ -1041,13 +1055,22 @@ Stream.prototype.end = function (data, encoding) {
}; };
function Server (listener) { function Server (/* [ options, ] listener */) {
if (!(this instanceof Server)) return new Server(listener); if (!(this instanceof Server)) return new Server(arguments[0], arguments[1]);
events.EventEmitter.call(this); events.EventEmitter.call(this);
var self = this; var self = this;
if (listener) { var options = {};
self.addListener('connection', listener); if (typeof arguments[0] == "object") {
options = arguments[0];
}
// listener: find the last argument that is a function
for (var l = arguments.length - 1; l >= 0; l--) {
if (typeof arguments[l] == "function") {
self.addListener('connection', arguments[l]);
}
if (arguments[l] !== undefined) break;
} }
self.connections = 0; self.connections = 0;
@ -1055,6 +1078,8 @@ function Server (listener) {
self.paused = false; self.paused = false;
self.pauseTimeout = 1000; self.pauseTimeout = 1000;
self.allowHalfOpen = options.allowHalfOpen || false;
function pause () { function pause () {
// We've hit the maximum file limit. What to do? // We've hit the maximum file limit. What to do?
// Let's try again in 1 second. // Let's try again in 1 second.
@ -1094,7 +1119,9 @@ function Server (listener) {
self.connections++; self.connections++;
var s = new Stream(peerInfo.fd, self.type); var s = new Stream({ fd: peerInfo.fd,
type: self.type,
allowHalfOpen: self.allowHalfOpen });
s.remoteAddress = peerInfo.address; s.remoteAddress = peerInfo.address;
s.remotePort = peerInfo.port; s.remotePort = peerInfo.port;
s.type = self.type; s.type = self.type;
@ -1118,8 +1145,8 @@ util.inherits(Server, events.EventEmitter);
exports.Server = Server; exports.Server = Server;
exports.createServer = function (listener) { exports.createServer = function () {
return new Server(listener); return new Server(arguments[0], arguments[1]);
}; };

2
test/pummel/test-net-pingpong-delay.js

@ -11,7 +11,7 @@ function pingPongTest (port, host, on_complete) {
var count = 0; var count = 0;
var client_ended = false; var client_ended = false;
var server = net.createServer(function (socket) { var server = net.createServer({ allowHalfOpen: true }, function (socket) {
socket.setEncoding("utf8"); socket.setEncoding("utf8");
socket.addListener("data", function (data) { socket.addListener("data", function (data) {

2
test/pummel/test-net-pingpong.js

@ -9,7 +9,7 @@ function pingPongTest (port, host, on_complete) {
var count = 0; var count = 0;
var sent_final_ping = false; var sent_final_ping = false;
var server = net.createServer(function (socket) { var server = net.createServer({ allowHalfOpen: true }, function (socket) {
assert.equal(true, socket.remoteAddress !== null); assert.equal(true, socket.remoteAddress !== null);
assert.equal(true, socket.remoteAddress !== undefined); assert.equal(true, socket.remoteAddress !== undefined);
if (host === "127.0.0.1" || host === "localhost" || !host) { if (host === "127.0.0.1" || host === "localhost" || !host) {

4
test/simple/test-net-pingpong.js

@ -10,7 +10,7 @@ function pingPongTest (port, host) {
var count = 0; var count = 0;
var sent_final_ping = false; var sent_final_ping = false;
var server = net.createServer(function (socket) { var server = net.createServer({ allowHalfOpen: true }, function (socket) {
console.log("connection: " + socket.remoteAddress); console.log("connection: " + socket.remoteAddress);
assert.equal(server, socket.server); assert.equal(server, socket.server);
assert.equal(1, server.connections); assert.equal(1, server.connections);
@ -30,7 +30,7 @@ function pingPongTest (port, host) {
}); });
socket.addListener("end", function () { socket.addListener("end", function () {
assert.equal(true, socket.writable); assert.equal(true, socket.writable); // because allowHalfOpen
assert.equal(false, socket.readable); assert.equal(false, socket.readable);
socket.end(); socket.end();
}); });

Loading…
Cancel
Save