Browse Source

http: fix ServerResponse does not emit 'close'

Refs #2453.
v0.7.4-release
koichik 13 years ago
parent
commit
dd9593ccc4
  1. 7
      doc/api/http.markdown
  2. 36
      lib/http.js
  3. 14
      test/simple/test-http-response-close.js

7
doc/api/http.markdown

@ -247,6 +247,13 @@ authentication details.
This object is created internally by a HTTP server--not by the user. It is This object is created internally by a HTTP server--not by the user. It is
passed as the second parameter to the `'request'` event. It is a `Writable Stream`. passed as the second parameter to the `'request'` event. It is a `Writable Stream`.
### Event: 'close'
`function () { }`
Indicates that the underlaying connection was terminated before
`response.end()` was called or able to flush.
### response.writeContinue() ### response.writeContinue()
Sends a HTTP/1.1 100 Continue message to the client, indicating that Sends a HTTP/1.1 100 Continue message to the client, indicating that

36
lib/http.js

@ -343,22 +343,6 @@ util.inherits(OutgoingMessage, stream.Stream);
exports.OutgoingMessage = OutgoingMessage; exports.OutgoingMessage = OutgoingMessage;
OutgoingMessage.prototype.assignSocket = function(socket) {
assert(!socket._httpMessage);
socket._httpMessage = this;
this.socket = socket;
this.connection = socket;
this._flush();
};
OutgoingMessage.prototype.detachSocket = function(socket) {
assert(socket._httpMessage == this);
socket._httpMessage = null;
this.socket = this.connection = null;
};
OutgoingMessage.prototype.destroy = function(error) { OutgoingMessage.prototype.destroy = function(error) {
this.socket.destroy(error); this.socket.destroy(error);
}; };
@ -792,6 +776,26 @@ exports.ServerResponse = ServerResponse;
ServerResponse.prototype.statusCode = 200; ServerResponse.prototype.statusCode = 200;
function onServerResponseClose() {
this._httpMessage.emit('close');
}
ServerResponse.prototype.assignSocket = function(socket) {
assert(!socket._httpMessage);
socket._httpMessage = this;
socket.on('close', onServerResponseClose);
this.socket = socket;
this.connection = socket;
this._flush();
};
ServerResponse.prototype.detachSocket = function(socket) {
assert(socket._httpMessage == this);
socket.removeListener('close', onServerResponseClose);
socket._httpMessage = null;
this.socket = this.connection = null;
};
ServerResponse.prototype.writeContinue = function() { ServerResponse.prototype.writeContinue = function() {
this._writeRaw('HTTP/1.1 100 Continue' + CRLF + CRLF, 'ascii'); this._writeRaw('HTTP/1.1 100 Continue' + CRLF + CRLF, 'ascii');
this._sent100 = true; this._sent100 = true;

14
test/simple/test-http-response-close.js

@ -23,15 +23,20 @@ var common = require('../common');
var assert = require('assert'); var assert = require('assert');
var http = require('http'); var http = require('http');
var gotEnd = false; var requestGotEnd = false;
var responseGotEnd = false;
var server = http.createServer(function(req, res) { var server = http.createServer(function(req, res) {
res.writeHead(200); res.writeHead(200);
res.write('a'); res.write('a');
req.on('close', function() { req.on('close', function() {
console.error('aborted'); console.error('request aborted');
gotEnd = true; requestGotEnd = true;
});
res.on('close', function() {
console.error('response aborted');
responseGotEnd = true;
}); });
}); });
server.listen(common.PORT); server.listen(common.PORT);
@ -51,5 +56,6 @@ server.on('listening', function() {
}); });
process.on('exit', function() { process.on('exit', function() {
assert.ok(gotEnd); assert.ok(requestGotEnd);
assert.ok(responseGotEnd);
}); });

Loading…
Cancel
Save