From 790d651f0dfae13f1e2b799820ab18ac09f251b7 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Tue, 4 Sep 2012 21:54:40 +0200 Subject: [PATCH] http: make http.ServerResponse emit 'end' This used to be the internal 'finish' event. Make it public so API users will know when the response has been sent completely. Fixes #3855. --- doc/api/http.markdown | 11 +++++ lib/http.js | 4 +- test/simple/test-http-response-end.js | 59 +++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 test/simple/test-http-response-end.js diff --git a/doc/api/http.markdown b/doc/api/http.markdown index 48c9abaa09..6e2ec3a705 100644 --- a/doc/api/http.markdown +++ b/doc/api/http.markdown @@ -312,6 +312,17 @@ passed as the second parameter to the `'request'` event. The response implements the [Writable Stream][] interface. This is an [EventEmitter][] with the following events: +### Event: 'end' + +`function () { }` + +Emitted when the response has been sent. More specifically, this event is +emitted when the last segment of the response headers and body have been +handed off to the operating system for transmission over the network. It +does not imply that the client has received anything yet. + +After this event, no more events will be emitted on the response object. + ### Event: 'close' `function () { }` diff --git a/lib/http.js b/lib/http.js index 027e5d8c9e..b7e7afcbfb 100644 --- a/lib/http.js +++ b/lib/http.js @@ -833,7 +833,7 @@ OutgoingMessage.prototype._finish = function() { assert(this instanceof ClientRequest); DTRACE_HTTP_CLIENT_REQUEST(this, this.connection); } - this.emit('finish'); + this.emit('end'); }; @@ -1760,7 +1760,7 @@ function connectionListener(socket) { // When we're finished writing the response, check if this is the last // respose, if so destroy the socket. - res.on('finish', function() { + res.on('end', function() { // Usually the first incoming element should be our request. it may // be that in the case abortIncoming() was called that the incoming // array will be empty. diff --git a/test/simple/test-http-response-end.js b/test/simple/test-http-response-end.js new file mode 100644 index 0000000000..3017008d75 --- /dev/null +++ b/test/simple/test-http-response-end.js @@ -0,0 +1,59 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var common = require('../common'); +var assert = require('assert'); +var http = require('http'); + +http.createServer(onRequest).listen(common.PORT, onListen); + +function onRequest(req, res) { + var gotEnd = 0; + + res.on('close', assert.fail); + + res.on('end', function() { + gotEnd++; + }); + + process.on('exit', function() { + assert.equal(gotEnd, 1); + }); + + res.writeHead(200); + res.end(); + this.close(); +} + +function onListen() { + var req = http.get('http://127.0.0.1:' + common.PORT); + var gotEnd = 0; + + req.on('close', assert.fail); + + req.on('end', function() { + gotEnd++; + }); + + process.on('exit', function() { + assert.equal(gotEnd, 1); + }); +}