Browse Source

API: OutgoingMessage.prototype.finish() renamed to close()

v0.7.4-release
Ryan Dahl 15 years ago
parent
commit
5013bf1781
  1. 84
      doc/api.txt
  2. 2
      doc/index.html
  3. 39
      lib/http.js
  4. 2
      test/mjsunit/test-http-1.0.js
  5. 2
      test/mjsunit/test-http-cat.js
  6. 2
      test/mjsunit/test-http-chunked.js
  7. 10
      test/mjsunit/test-http-client-race.js
  8. 3
      test/mjsunit/test-http-client-reconnect-bug.js
  9. 5
      test/mjsunit/test-http-client-upload.js
  10. 2
      test/mjsunit/test-http-malformed-request.js
  11. 10
      test/mjsunit/test-http-proxy.js
  12. 2
      test/mjsunit/test-http-server.js
  13. 8
      test/mjsunit/test-http-tls.js
  14. 2
      test/mjsunit/test-http-wget.js
  15. 8
      test/mjsunit/test-http.js
  16. 2
      test/mjsunit/test-keep-alive.js
  17. 10
      test/mjsunit/test-multipart.js
  18. 2
      test/mjsunit/test-remote-module-loading.js

84
doc/api.txt

@ -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/");
----------------------------------------
@ -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")+ ::
@ -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.
@ -1027,7 +1027,7 @@ 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");
@ -1035,6 +1035,7 @@ request.finish(function (response) {
sys.puts("BODY: " + chunk);
});
});
request.close();
----------------------------------------
+http.createClient(port, host)+ ::
@ -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()+.)
@ -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.
+
@ -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);
});
----------------------------------------
@ -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;
@ -1338,7 +1338,7 @@ http.createServer(function (req, res) {
"content-length" : response.length
});
res.write(response);
res.finish();
res.close();
})
});
----------------------------------------

2
doc/index.html

@ -49,7 +49,7 @@ http.createServer(function (req, res) {
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>

39
lib/http.js

@ -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.
};
@ -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();
@ -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);
};
@ -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;
@ -575,5 +586,11 @@ exports.cat = function (url, encoding, headers) {
});
});
client.addListener("error", function () {
promise.emitError();
});
req.close();
return promise;
};

2
test/mjsunit/test-http-1.0.js

@ -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);

2
test/mjsunit/test-http-cat.js

@ -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);

2
test/mjsunit/test-http-chunked.js

@ -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);

10
test/mjsunit/test-http-client-race.js

@ -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);
@ -21,7 +21,8 @@ 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) {
@ -29,13 +30,16 @@ client.request("/1").finish(function (res1) {
});
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);

3
test/mjsunit/test-http-client-reconnect-bug.js

@ -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();

5
test/mjsunit/test-http-client-upload.js

@ -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);
@ -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);
@ -43,6 +43,7 @@ req.finish(function(res) {
server.close();
});
});
req.close();
process.addListener("exit", function () {
assert.equal("1\n2\n3\n", sent_body);

2
test/mjsunit/test-http-malformed-request.js

@ -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();
});

10
test/mjsunit/test-http-proxy.js

@ -9,7 +9,7 @@ var backend = http.createServer(function (req, res) {
// debug("backend");
res.sendHeader(200, {"content-type": "text/plain"});
res.write("hello world\n");
res.finish();
res.close();
});
// debug("listen backend")
backend.listen(BACKEND_PORT);
@ -18,16 +18,17 @@ var proxy_client = http.createClient(BACKEND_PORT);
var proxy = http.createServer(function (req, res) {
debug("proxy req headers: " + JSON.stringify(req.headers));
var proxy_req = proxy_client.request(url.parse(req.url).pathname);
proxy_req.finish(function(proxy_res) {
proxy_req.addListener('response', function(proxy_res) {
res.sendHeader(proxy_res.statusCode, proxy_res.headers);
proxy_res.addListener("data", function(chunk) {
res.write(chunk);
});
proxy_res.addListener("end", function() {
res.finish();
res.close();
// debug("proxy res");
});
});
proxy_req.close();
});
// debug("listen proxy")
proxy.listen(PROXY_PORT);
@ -37,7 +38,7 @@ var body = "";
var client = http.createClient(PROXY_PORT);
var req = client.request("/test");
// debug("client req")
req.finish(function (res) {
req.addListener('response', function (res) {
// debug("got res");
assert.equal(200, res.statusCode);
res.setBodyEncoding("utf8");
@ -48,6 +49,7 @@ req.finish(function (res) {
// debug("closed both");
});
});
req.close();
process.addListener("exit", function () {
assert.equal(body, "hello world\n");

2
test/mjsunit/test-http-server.js

@ -40,7 +40,7 @@ http.createServer(function (req, res) {
setTimeout(function () {
res.sendHeader(200, {"Content-Type": "text/plain"});
res.write(url.parse(req.url).pathname);
res.finish();
res.close();
}, 1);
}).listen(port);

8
test/mjsunit/test-http-tls.js

@ -54,7 +54,7 @@ var http_server=http.createServer(function (req, res) {
req.addListener('end', function () {
res.sendHeader(200, {"Content-Type": "text/plain"});
res.write("The path was " + url.parse(req.url).pathname);
res.finish();
res.close();
responses_sent += 1;
});
@ -66,7 +66,7 @@ http_server.listen(PORT);
var client = http.createClient(PORT, HOST);
client.setSecure("x509_PEM", caPem, 0, keyPem, certPem);
var req = client.request("/hello", {"Accept": "*/*", "Foo": "bar"});
req.finish(function (res) {
req.addListener('response', function (res) {
var verified = res.connection.verifyPeer();
var peerDN = res.connection.getPeerCertificate("DNstring");
assert.equal(verified, 1);
@ -78,10 +78,11 @@ req.finish(function (res) {
res.addListener('data', function (chunk) { body0 += chunk; });
debug("Got /hello response");
});
req.close();
setTimeout(function () {
req = client.request("POST", "/world");
req.finish(function (res) {
req.addListener('response', function (res) {
var verified = res.connection.verifyPeer();
var peerDN = res.connection.getPeerCertificate("DNstring");
assert.equal(verified, 1);
@ -93,6 +94,7 @@ setTimeout(function () {
res.addListener('data', function (chunk) { body1 += chunk; });
debug("Got /world response");
});
req.close();
}, 1);
process.addListener("exit", function () {

2
test/mjsunit/test-http-wget.js

@ -27,7 +27,7 @@ var server = http.createServer(function (req, res) {
res.sendHeader(200, {"Content-Type": "text/plain"});
res.write("hello ");
res.write("world\n");
res.finish();
res.close();
})
server.listen(port);

8
test/mjsunit/test-http.js

@ -30,7 +30,7 @@ http.createServer(function (req, res) {
req.addListener('end', function () {
res.sendHeader(200, {"Content-Type": "text/plain"});
res.write("The path was " + url.parse(req.url).pathname);
res.finish();
res.close();
responses_sent += 1;
});
@ -39,23 +39,25 @@ http.createServer(function (req, res) {
var client = http.createClient(PORT);
var req = client.request("/hello", {"Accept": "*/*", "Foo": "bar"});
req.finish(function (res) {
req.addListener('response', function (res) {
assert.equal(200, res.statusCode);
responses_recvd += 1;
res.setBodyEncoding("ascii");
res.addListener('data', function (chunk) { body0 += chunk; });
debug("Got /hello response");
});
req.close();
setTimeout(function () {
req = client.request("POST", "/world");
req.finish(function (res) {
req.addListener('response',function (res) {
assert.equal(200, res.statusCode);
responses_recvd += 1;
res.setBodyEncoding("utf8");
res.addListener('data', function (chunk) { body1 += chunk; });
debug("Got /world response");
});
req.close();
}, 1);
process.addListener("exit", function () {

2
test/mjsunit/test-keep-alive.js

@ -11,7 +11,7 @@ server = http.createServer(function (req, res) {
"Content-Type": "text/plain",
});
res.write(body);
res.finish();
res.close();
});
server.listen(PORT);

10
test/mjsunit/test-multipart.js

@ -81,12 +81,12 @@ var secondPart = new (events.Promise),
sys.puts("!! error occurred");
res.sendHeader(400, {});
res.write("bad");
res.finish();
res.close();
});
mp.addListener("complete", function () {
res.sendHeader(200, {});
res.write("ok");
res.finish();
res.close();
});
}),
message,
@ -106,7 +106,7 @@ firstPart.addCallback(function testGoodMessages () {
sys.puts("test message "+httpMessages.length);
var req = client.request("POST", "/", message.headers);
req.write(message.body, "binary");
req.finish(function (res) {
req.addListener('response', function (res) {
var buff = "";
res.addListener("data", function (chunk) { buff += chunk });
res.addListener("end", function () {
@ -114,6 +114,7 @@ firstPart.addCallback(function testGoodMessages () {
process.nextTick(testHTTP);
});
});
req.close();
})();
});
secondPart.addCallback(function testBadMessages () {
@ -128,7 +129,7 @@ secondPart.addCallback(function testBadMessages () {
sys.puts("test message "+httpMessages.length);
var req = client.request("POST", "/bad", message.headers);
req.write(message.body, "binary");
req.finish(function (res) {
req.addListener('response', function (res) {
var buff = "";
res.addListener("data", function (chunk) { buff += chunk });
res.addListener("end", function () {
@ -136,5 +137,6 @@ secondPart.addCallback(function testBadMessages () {
process.nextTick(testHTTP);
});
});
req.close();
})();
});

2
test/mjsunit/test-remote-module-loading.js

@ -13,7 +13,7 @@ var server = http.createServer(function(req, res) {
res.sendHeader(200, {'Content-Type': 'text/javascript'});
res.write(body);
res.finish();
res.close();
});
server.listen(PORT);

Loading…
Cancel
Save