Skip to content

Commit

Permalink
API: OutgoingMessage.prototype.finish() renamed to close()
Browse files Browse the repository at this point in the history
  • Loading branch information
ry committed Feb 17, 2010
1 parent 6115df6 commit 5013bf1
Show file tree
Hide file tree
Showing 18 changed files with 113 additions and 82 deletions.
84 changes: 42 additions & 42 deletions doc/api.txt
Expand Up @@ -21,7 +21,7 @@ var sys = require("sys"),
http.createServer(function (request, response) {
response.sendHeader(200, {"Content-Type": "text/plain"});
response.write("Hello World\n");
response.finish();
response.close();
}).listen(8000);
sys.puts("Server running at http://127.0.0.1:8000/");
----------------------------------------
Expand Down Expand Up @@ -982,7 +982,7 @@ response.sendHeader(200, {
----------------------------------------
+
This method must only be called once on a message and it must
be called before +response.finish()+ is called.
be called before +response.close()+ is called.

+response.write(chunk, encoding="ascii")+ ::

Expand All @@ -1004,10 +1004,10 @@ data, and sends that seperately. That is, the response is buffered up to the
first chunk of body.


+response.finish()+ ::
+response.close()+ ::
This method signals to the server that all of the response headers and body
has been sent; that server should consider this message complete.
The method, +response.finish()+, MUST be called on each
The method, +response.close()+, MUST be called on each
response.


Expand All @@ -1027,14 +1027,15 @@ var sys = require("sys"),
http = require("http");
var google = http.createClient(80, "www.google.com");
var request = google.request("GET", "/", {"host": "www.google.com"});
request.finish(function (response) {
request.addListener('response', function (response) {
sys.puts("STATUS: " + response.statusCode);
sys.puts("HEADERS: " + JSON.stringify(response.headers));
response.setBodyEncoding("utf8");
response.addListener("data", function (chunk) {
sys.puts("BODY: " + chunk);
});
});
request.close();
----------------------------------------

+http.createClient(port, host)+ ::
Expand All @@ -1060,7 +1061,7 @@ set +Transfer-Encoding: chunked+.
+
NOTE: the request is not complete. This method only sends
the header of the request. One needs to call
+request.finish()+ to finalize the request and retrieve
+request.close()+ to finalize the request and retrieve
the response. (This sounds convoluted but it provides a chance
for the user to stream a body to the server with
+request.write()+.)
Expand All @@ -1083,12 +1084,42 @@ This object is created internally and returned from the request methods of a
+http.Client+. It represents an _in-progress_ request whose header has
already been sent.

To get the response, add a listener for +'response'+ to the request object.
+'response'+ will be emitted from the request object when the response
headers have been received. The +'response'+ event is executed with one
argument which is an instance of +http.ClientResponse+.

During the +'response'+ event, one can add listeners to the
response object; particularly to listen for the +"data"+ event. Note that
the +'response' event is called before any part of the response body is received,
so there is no need to worry about racing to catch the first part of the
body. As long as a listener for +'data'+ is added during the +'response'
event, the entire body will be caught.

----------------------------------------
// Good
request.addListener('response', function (response) {
response.addListener("data", function (chunk) {
sys.puts("BODY: " + chunk);
});
});
// Bad - misses all or part of the body
request.addListener('response', function (response) {
setTimeout(function () {
response.addListener("data", function (chunk) {
sys.puts("BODY: " + chunk);
});
}, 10);
});
----------------------------------------


[cols="1,2,10",options="header"]
|=========================================================
|Event | Parameters | Notes
|+"response"+ | +response+ |
Emitted when a response is received to this request. Typically the user will
set a listener to this via the +request.finish()+ method.
Emitted when a response is received to this request.
+
This event is emitted only once.
+
Expand All @@ -1114,42 +1145,11 @@ argument should be either +"utf8"+ or
as it is faster.


+request.finish(responseListener)+ ::
+request.close()+ ::

Finishes sending the request. If any parts of the body are
unsent, it will flush them to the socket. If the request is
chunked, this will send the terminating +"0\r\n\r\n"+.
+
The parameter +responseListener+ is a callback which
will be executed when the response headers have been received.
The +responseListener+ callback is executed with one
argument which is an instance of +http.ClientResponse+.
+
In the +responseListener+ callback, one can add more listeners to the
response, in particular listening for the +"data"+ event. Note that
the +responseListener+ is called before any part of the body is received,
so there is no need to worry about racing to catch the first part of the
body. As long as a listener for +"data"+ is added during the
+responseListener+ callback, the entire body will be caught.
+
----------------------------------------
// Good
request.finish(function (response) {
response.addListener("data", function (chunk) {
sys.puts("BODY: " + chunk);
});
});
// Bad - misses all or part of the body
request.finish(function (response) {
setTimeout(function () {
response.addListener("data", function (chunk) {
sys.puts("BODY: " + chunk);
});
}, 10);
});
----------------------------------------




Expand Down Expand Up @@ -1315,7 +1315,7 @@ http.createServer(function (req, res) {
mp.addListener("error", function (er) {
res.sendHeader(400, {"content-type":"text/plain"});
res.write("You sent a bad message!\n"+er.message);
res.finish();
res.close();
});
mp.addListener("partBegin", function (part) {
name = part.name;
Expand All @@ -1338,7 +1338,7 @@ http.createServer(function (req, res) {
"content-length" : response.length
});
res.write(response);
res.finish();
res.close();
})
});
----------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion doc/index.html
Expand Up @@ -49,7 +49,7 @@
setTimeout(function () {
res.sendHeader(200, {'Content-Type': 'text/plain'});
res.write('Hello World');
res.finish();
res.close();
}, 2000);
}).listen(8000);
sys.puts('Server running at http://127.0.0.1:8000/');</pre>
Expand Down
39 changes: 28 additions & 11 deletions lib/http.js
Expand Up @@ -201,7 +201,7 @@ OutgoingMessage.prototype.sendHeaderLines = function (first_line, headers) {
message_header += CRLF;

this._send(message_header);
// wait until the first body chunk, or finish(), is sent to flush.
// wait until the first body chunk, or close(), is sent to flush.
};


Expand Down Expand Up @@ -235,6 +235,10 @@ OutgoingMessage.prototype.flush = function () {
};

OutgoingMessage.prototype.finish = function () {
throw new Error("finish() has been renamed to close().");
};

OutgoingMessage.prototype.close = function () {
if (this.chunked_encoding) this._send("0\r\n\r\n"); // last chunk
this.finished = true;
this.flush();
Expand Down Expand Up @@ -275,9 +279,20 @@ function ClientRequest (method, url, headers) {
sys.inherits(ClientRequest, OutgoingMessage);
exports.ClientRequest = ClientRequest;

ClientRequest.prototype.finish = function (responseListener) {
this.addListener("response", responseListener);
OutgoingMessage.prototype.finish.call(this);
ClientRequest.prototype.finish = function () {
throw new Error( "finish() has been renamed to close() and no longer takes "
+ "a response handler as an argument. Manually add a 'response' listener "
+ "to the request object."
);
};

ClientRequest.prototype.close = function () {
if (arguments.length > 0) {
throw new Error( "ClientRequest.prototype.close does not take any arguments. "
+ "Add a response listener manually to the request object."
);
}
OutgoingMessage.prototype.close.call(this);
};


Expand Down Expand Up @@ -553,17 +568,13 @@ exports.cat = function (url, encoding, headers) {
if (!hasHost) {
headers["Host"] = url.hostname;
}

var content = "";

var client = exports.createClient(url.port || 80, url.hostname);
var req = client.request((url.pathname || "/")+(url.search || "")+(url.hash || ""), headers);

client.addListener("error", function () {
promise.emitError();
});

var content = "";

req.finish(function (res) {
req.addListener('response', function (res) {
if (res.statusCode < 200 || res.statusCode >= 300) {
promise.emitError(res.statusCode);
return;
Expand All @@ -575,5 +586,11 @@ exports.cat = function (url, encoding, headers) {
});
});

client.addListener("error", function () {
promise.emitError();
});

req.close();

return promise;
};
2 changes: 1 addition & 1 deletion test/mjsunit/test-http-1.0.js
Expand Up @@ -11,7 +11,7 @@ var client_got_eof = false;
var server = http.createServer(function (req, res) {
res.sendHeader(200, {"Content-Type": "text/plain"});
res.write(body);
res.finish();
res.close();
})
server.listen(port);

Expand Down
2 changes: 1 addition & 1 deletion test/mjsunit/test-http-cat.js
Expand Up @@ -10,7 +10,7 @@ var server = http.createServer(function (req, res) {
["Content-Type", "text/plain"]
]);
res.write(body);
res.finish();
res.close();
});
server.listen(PORT);

Expand Down
2 changes: 1 addition & 1 deletion test/mjsunit/test-http-chunked.js
Expand Up @@ -7,7 +7,7 @@ var UTF8_STRING = "Il était tué";
var server = http.createServer(function(req, res) {
res.sendHeader(200, {"Content-Type": "text/plain; charset=utf8"});
res.write(UTF8_STRING, 'utf8');
res.finish();
res.close();
});
server.listen(PORT);

Expand Down
10 changes: 7 additions & 3 deletions test/mjsunit/test-http-client-race.js
Expand Up @@ -12,7 +12,7 @@ var server = http.createServer(function (req, res) {
, "Content-Length": body.length
});
res.write(body);
res.finish();
res.close();
});
server.listen(PORT);

Expand All @@ -21,21 +21,25 @@ var client = http.createClient(PORT);
var body1 = "";
var body2 = "";

client.request("/1").finish(function (res1) {
var req1 = client.request("/1")
req1.addListener('response', function (res1) {
res1.setBodyEncoding("utf8");

res1.addListener('data', function (chunk) {
body1 += chunk;
});

res1.addListener('end', function () {
client.request("/2").finish(function (res2) {
var req2 = client.request("/2");
req2.addListener('response', function (res2) {
res2.setBodyEncoding("utf8");
res2.addListener('data', function (chunk) { body2 += chunk; });
res2.addListener('end', function () { server.close(); });
});
req2.close();
});
});
req1.close();

process.addListener("exit", function () {
assert.equal(body1_s, body1);
Expand Down
3 changes: 2 additions & 1 deletion test/mjsunit/test-http-client-reconnect-bug.js
Expand Up @@ -27,9 +27,10 @@ client.addListener("end", function() {
});

var request = client.request("GET", "/", {"host": "localhost"});
request.finish(function(response) {
request.addListener('response', function(response) {
sys.puts("STATUS: " + response.statusCode);
});
request.close();

setTimeout(function () {
server.close();
Expand Down
5 changes: 3 additions & 2 deletions test/mjsunit/test-http-client-upload.js
Expand Up @@ -20,7 +20,7 @@ var server = http.createServer(function(req, res) {
puts("request complete from server");
res.sendHeader(200, {'Content-Type': 'text/plain'});
res.write('hello\n');
res.finish();
res.close();
});
});
server.listen(PORT);
Expand All @@ -33,7 +33,7 @@ req.write('2\n');
req.write('3\n');

puts("client finished sending request");
req.finish(function(res) {
req.addListener('response', function(res) {
res.setBodyEncoding("utf8");
res.addListener('data', function(chunk) {
puts(chunk);
Expand All @@ -43,6 +43,7 @@ req.finish(function(res) {
server.close();
});
});
req.close();

process.addListener("exit", function () {
assert.equal("1\n2\n3\n", sent_body);
Expand Down
2 changes: 1 addition & 1 deletion test/mjsunit/test-http-malformed-request.js
Expand Up @@ -15,7 +15,7 @@ var s = http.createServer(function (req, res) {

res.sendHeader(200, {"Content-Type": "text/plain"});
res.write("Hello World");
res.finish();
res.close();

if (++nrequests_completed == nrequests_expected) s.close();
});
Expand Down

0 comments on commit 5013bf1

Please sign in to comment.