API: Make request/response object closer to stream interface
authorRyan Dahl <ry@tinyclouds.org>
Wed, 17 Feb 2010 06:16:29 +0000 (22:16 -0800)
committerRyan Dahl <ry@tinyclouds.org>
Wed, 17 Feb 2010 06:16:29 +0000 (22:16 -0800)
- sendBody() renamed to write()
- 'body' event renamed to 'data'
- 'complete' event renamed to 'end'

20 files changed:
benchmark/http_simple.js
benchmark/static_http_server.js
doc/api.txt
doc/index.html
lib/http.js
lib/multipart.js
test/mjsunit/test-http-1.0.js
test/mjsunit/test-http-cat.js
test/mjsunit/test-http-chunked.js
test/mjsunit/test-http-client-race.js
test/mjsunit/test-http-client-upload.js
test/mjsunit/test-http-malformed-request.js
test/mjsunit/test-http-proxy.js
test/mjsunit/test-http-server.js
test/mjsunit/test-http-tls.js
test/mjsunit/test-http-wget.js
test/mjsunit/test-http.js
test/mjsunit/test-keep-alive.js
test/mjsunit/test-multipart.js
test/mjsunit/test-remote-module-loading.js

index 37429bf..810633a 100644 (file)
@@ -52,7 +52,7 @@ http.createServer(function (req, res) {
                   , "Content-Length": content_length
                   }
                 );
-  res.sendBody(body);
+  res.write(body);
           
   res.finish();
 }).listen(8000);
index da62434..e3423ea 100644 (file)
@@ -20,13 +20,13 @@ var server = http.createServer(function (req, res) {
     "Content-Type": "text/plain",
     "Content-Length": body.length
   });
-  res.sendBody(body);
+  res.write(body);
   res.finish();
 })
 server.listen(port);
 
 function responseListener (res) {
-  res.addListener("complete", function () {
+  res.addListener("end", function () {
     if (requests < n) {
       res.client.request("/").finish(responseListener);
       requests++;
index 8a3d272..bc1fe9f 100644 (file)
@@ -20,7 +20,7 @@ var sys = require("sys"),
    http = require("http");
 http.createServer(function (request, response) {
   response.sendHeader(200, {"Content-Type": "text/plain"});
-  response.sendBody("Hello World\n");
+  response.write("Hello World\n");
   response.finish();
 }).listen(8000);
 sys.puts("Server running at http://127.0.0.1:8000/");
@@ -856,7 +856,7 @@ the user--and passed as the first argument to a +"request"+ listener.
 |=========================================================
 |Event           | Parameters   | Notes
 
-|+"body"+        | +chunk+      | Emitted when a piece of the 
+|+"data"+        | +chunk+      | Emitted when a piece of the 
                                   message body is received. Example: A chunk
                                   of the body is given as the single
                                   argument. The transfer-encoding has been
@@ -864,7 +864,7 @@ the user--and passed as the first argument to a +"request"+ listener.
                                   body encoding is set with
                                   +request.setBodyEncoding()+.
 
-|+"complete"+    | (none)       | Emitted exactly once for each message. 
+|+"end"+         | (none)       | Emitted exactly once for each message. 
                                   No arguments.  After emitted no other
                                   events will be emitted on the request.
 |=========================================================
@@ -970,7 +970,7 @@ response.sendHeader(200, {
 This method must only be called once on a message and it must
 be called before +response.finish()+ is called.
 
-+response.sendBody(chunk, encoding="ascii")+ ::
++response.write(chunk, encoding="ascii")+ ::
 
 This method must be called after +sendHeader+ was
 called. It sends a chunk of the response body. This method may
@@ -983,10 +983,10 @@ specifies how to encode it into a byte stream. By default the
 Note: This is the raw HTTP body and has nothing to do with
 higher-level multi-part body encodings that may be used.
 +
-The first time +sendBody+ is called, it will send the buffered header
-information and the first body to the client. The second time
-+sendBody+ is called, Node assumes you're going to be streaming data, and
-sends that seperately. That is, the response is buffered up to the
+The first time +response.write()+ is called, it will send the buffered
+header information and the first body to the client. The second time
++response.write()+ is called, Node assumes you're going to be streaming
+data, and sends that seperately. That is, the response is buffered up to the
 first chunk of body.
 
 
@@ -1017,7 +1017,7 @@ request.finish(function (response) {
   sys.puts("STATUS: " + response.statusCode);
   sys.puts("HEADERS: " + JSON.stringify(response.headers));
   response.setBodyEncoding("utf8");
-  response.addListener("body", function (chunk) {
+  response.addListener("data", function (chunk) {
     sys.puts("BODY: " + chunk);
   });
 });
@@ -1049,7 +1049,7 @@ the header of the request. One needs to call
 +request.finish()+ 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.sendBody()+.)
++request.write()+.)
 
 +client.setSecure(format_type, ca_certs, crl_list, private_key, certificate)+ ::
 Enable TLS for the client connection, with the specified credentials.
@@ -1082,7 +1082,7 @@ The +response+ argument will be an instance of +http.ClientResponse+.
 |=========================================================
 
 
-+request.sendBody(chunk, encoding="ascii")+ ::
++request.write(chunk, encoding="ascii")+ ::
 
 Sends a chunk of the body.  By calling this method
 many times, the user can stream a request body to a
@@ -1112,16 +1112,16 @@ 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 +"body"+ event. Note that
+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 +"body"+ is added during 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("body", function (chunk) {
+  response.addListener("data", function (chunk) {
     sys.puts("BODY: " + chunk);
   });
 });
@@ -1129,7 +1129,7 @@ request.finish(function (response) {
 // Bad - misses all or part of the body
 request.finish(function (response) {
   setTimeout(function () {
-    response.addListener("body", function (chunk) {
+    response.addListener("data", function (chunk) {
       sys.puts("BODY: " + chunk);
     });
   }, 10);
@@ -1147,13 +1147,13 @@ This object is created internally and passed to the +"response"+ event.
 |=========================================================
 |Event           | Parameters   | Notes
 
-|+"body"+        | +chunk+ |
+|+"data"+        | +chunk+ |
 Emitted when a piece of the message body is received. Example: A chunk of
 the body is given as the single argument. The transfer-encoding has been
 decoded.  The body chunk a String.  The body encoding is set with
 +response.setBodyEncoding()+.
 
-|+"complete"+    |        |
+|+"end"+    |        |
 Emitted exactly once for each message. No arguments.
 After emitted no other events will be emitted on the response.
 
@@ -1300,7 +1300,7 @@ http.createServer(function (req, res) {
     name, filename;
   mp.addListener("error", function (er) {
     res.sendHeader(400, {"content-type":"text/plain"});
-    res.sendBody("You sent a bad message!\n"+er.message);
+    res.write("You sent a bad message!\n"+er.message);
     res.finish();
   });
   mp.addListener("partBegin", function (part) {
@@ -1323,7 +1323,7 @@ http.createServer(function (req, res) {
       "content-type" : "text/plain",
       "content-length" : response.length
     });
-    res.sendBody(response);
+    res.write(response);
     res.finish();
   })
 });
index 04945ca..5c6539d 100644 (file)
@@ -48,7 +48,7 @@ var sys = require('sys'),
 http.createServer(function (req, res) {
   setTimeout(function () {
     res.sendHeader(200, {'Content-Type': 'text/plain'});
-    res.sendBody('Hello World');
+    res.write('Hello World');
     res.finish();
   }, 2000);
 }).listen(8000);
index 4260984..d37cd1e 100644 (file)
@@ -114,7 +114,7 @@ function OutgoingMessage () {
 sys.inherits(OutgoingMessage, events.EventEmitter);
 exports.OutgoingMessage = OutgoingMessage;
 
-OutgoingMessage.prototype.send = function (data, encoding) {
+OutgoingMessage.prototype._send = function (data, encoding) {
   var length = this.output.length;
 
   if (length === 0) {
@@ -200,19 +200,27 @@ OutgoingMessage.prototype.sendHeaderLines = function (first_line, headers) {
 
   message_header += CRLF;
 
-  this.send(message_header);
+  this._send(message_header);
   // wait until the first body chunk, or finish(), is sent to flush.
 };
 
-OutgoingMessage.prototype.sendBody = function (chunk, encoding) {
+
+OutgoingMessage.prototype.sendBody = function () {
+  throw new Error("sendBody() has been renamed to write(). " + 
+                  "The 'body' event has been renamed to 'data' and " +
+                  "the 'complete' event has been renamed to 'end'.");
+};
+
+
+OutgoingMessage.prototype.write = function (chunk, encoding) {
   encoding = encoding || "ascii";
   if (this.chunked_encoding) {
-    this.send(process._byteLength(chunk, encoding).toString(16));
-    this.send(CRLF);
-    this.send(chunk, encoding);
-    this.send(CRLF);
+    this._send(process._byteLength(chunk, encoding).toString(16));
+    this._send(CRLF);
+    this._send(chunk, encoding);
+    this._send(CRLF);
   } else {
-    this.send(chunk, encoding);
+    this._send(chunk, encoding);
   }
 
   if (this.flushing) {
@@ -227,7 +235,7 @@ OutgoingMessage.prototype.flush = function () {
 };
 
 OutgoingMessage.prototype.finish = function () {
-  if (this.chunked_encoding) this.send("0\r\n\r\n"); // last chunk
+  if (this.chunked_encoding) this._send("0\r\n\r\n"); // last chunk
   this.finished = true;
   this.flush();
 };
@@ -333,11 +341,11 @@ function createIncomingMessageStream (connection, incoming_listener) {
   });
 
   connection.addListener("body", function (chunk) {
-    incoming.emit("body", chunk);
+    incoming.emit('data', chunk);
   });
 
   connection.addListener("messageComplete", function () {
-    incoming.emit("complete");
+    incoming.emit('end');
   });
 
   return stream;
@@ -486,7 +494,7 @@ exports.createClient = function (port, host) {
   createIncomingMessageStream(client, function (res) {
    //sys.debug("incoming response!");
 
-    res.addListener("complete", function ( ) {
+    res.addListener('end', function ( ) {
       //sys.debug("request complete disconnecting. readyState = " + client.readyState);
       client.close();
     });
@@ -561,8 +569,8 @@ exports.cat = function (url, encoding, headers) {
       return;
     }
     res.setBodyEncoding(encoding);
-    res.addListener("body", function (chunk) { content += chunk; });
-    res.addListener("complete", function () {
+    res.addListener('data', function (chunk) { content += chunk; });
+    res.addListener('end', function () {
       promise.emitSuccess(content);
     });
   });
index 15fb068..9dff309 100644 (file)
@@ -69,8 +69,8 @@ function Stream (message) {
     w = isMultiPart ? writer(this) : simpleWriter(this),
     e = ender(this);
   if (message.addListener) {
-    message.addListener("body", w);
-    message.addListener("complete", e);
+    message.addListener("data", w);
+    message.addListener("end", e);
     if (message.pause && message.resume) {
       this._pause = message;
     }
index 0a90478..1fd1cf2 100644 (file)
@@ -10,7 +10,7 @@ var client_got_eof = false;
 
 var server = http.createServer(function (req, res) {
   res.sendHeader(200, {"Content-Type": "text/plain"});
-  res.sendBody(body);
+  res.write(body);
   res.finish();
 })
 server.listen(port);
index 19ccab7..1c962eb 100644 (file)
@@ -9,7 +9,7 @@ var server = http.createServer(function (req, res) {
     ["Content-Length", body.length],
     ["Content-Type", "text/plain"]
   ]);
-  res.sendBody(body);
+  res.write(body);
   res.finish();
 });
 server.listen(PORT);
index d5a9a31..f566117 100644 (file)
@@ -6,7 +6,7 @@ var UTF8_STRING = "Il était tué";
 
 var server = http.createServer(function(req, res) {
   res.sendHeader(200, {"Content-Type": "text/plain; charset=utf8"});
-  res.sendBody(UTF8_STRING, 'utf8');
+  res.write(UTF8_STRING, 'utf8');
   res.finish();
 });
 server.listen(PORT);
@@ -19,4 +19,4 @@ http.cat("http://localhost:"+PORT+"/", "utf8")
   .addErrback(function() {
     assert.ok(false, 'http.cat should succeed in < 1000ms');
   })
-  .timeout(1000);
\ No newline at end of file
+  .timeout(1000);
index 1bcd342..79422db 100644 (file)
@@ -11,7 +11,7 @@ var server = http.createServer(function (req, res) {
   res.sendHeader(200, { "Content-Type": "text/plain"
                       , "Content-Length": body.length
                       });
-  res.sendBody(body);
+  res.write(body);
   res.finish();
 });
 server.listen(PORT);
@@ -24,15 +24,15 @@ var body2 = "";
 client.request("/1").finish(function (res1) {
   res1.setBodyEncoding("utf8");
 
-  res1.addListener("body", function (chunk) {
+  res1.addListener('data', function (chunk) {
     body1 += chunk;
   });
 
-  res1.addListener("complete", function () {
+  res1.addListener('end', function () {
     client.request("/2").finish(function (res2) {
       res2.setBodyEncoding("utf8");
-      res2.addListener("body", function (chunk) { body2 += chunk; });
-      res2.addListener("complete", function () { server.close(); });
+      res2.addListener('data', function (chunk) { body2 += chunk; });
+      res2.addListener('end', function () { server.close(); });
     });
   });
 });
index 73d95d5..83710c2 100644 (file)
@@ -10,16 +10,16 @@ var server = http.createServer(function(req, res) {
   assert.equal("POST", req.method);
   req.setBodyEncoding("utf8");
 
-  req.addListener("body", function (chunk) {
+  req.addListener('data', function (chunk) {
     puts("server got: " + JSON.stringify(chunk));
     sent_body += chunk;
   });
 
-  req.addListener("complete", function () {
+  req.addListener('end', function () {
     server_req_complete = true;
     puts("request complete from server");
     res.sendHeader(200, {'Content-Type': 'text/plain'});
-    res.sendBody('hello\n');
+    res.write('hello\n');
     res.finish();
   });
 });
@@ -28,17 +28,17 @@ server.listen(PORT);
 var client = http.createClient(PORT);
 var req = client.request('POST', '/');
 
-req.sendBody('1\n');
-req.sendBody('2\n');
-req.sendBody('3\n');
+req.write('1\n');
+req.write('2\n');
+req.write('3\n');
 
 puts("client finished sending request");
 req.finish(function(res) {
   res.setBodyEncoding("utf8");
-  res.addListener('body', function(chunk) {
+  res.addListener('data', function(chunk) {
     puts(chunk);
   });
-  res.addListener('complete', function() {
+  res.addListener('end', function() {
     client_res_complete = true;
     server.close();
   });
index 160da46..d3b1131 100644 (file)
@@ -14,7 +14,7 @@ var s = http.createServer(function (req, res) {
   puts("req: " + JSON.stringify(url.parse(req.url)));
 
   res.sendHeader(200, {"Content-Type": "text/plain"});
-  res.sendBody("Hello World");
+  res.write("Hello World");
   res.finish();
 
   if (++nrequests_completed == nrequests_expected) s.close();
index 220ffcb..b61aada 100644 (file)
@@ -8,7 +8,7 @@ var BACKEND_PORT = 8870;
 var backend = http.createServer(function (req, res) {
   // debug("backend");
   res.sendHeader(200, {"content-type": "text/plain"});
-  res.sendBody("hello world\n");
+  res.write("hello world\n");
   res.finish();
 });
 // debug("listen backend")
@@ -20,10 +20,10 @@ var proxy = http.createServer(function (req, res) {
   var proxy_req = proxy_client.request(url.parse(req.url).pathname);
   proxy_req.finish(function(proxy_res) {
     res.sendHeader(proxy_res.statusCode, proxy_res.headers);
-    proxy_res.addListener("body", function(chunk) {
-      res.sendBody(chunk);
+    proxy_res.addListener("data", function(chunk) {
+      res.write(chunk);
     });
-    proxy_res.addListener("complete", function() {
+    proxy_res.addListener("end", function() {
       res.finish();
       // debug("proxy res");
     });
@@ -41,8 +41,8 @@ req.finish(function (res) {
   // debug("got res");
   assert.equal(200, res.statusCode);
   res.setBodyEncoding("utf8");
-  res.addListener("body", function (chunk) { body += chunk; });
-  res.addListener("complete", function () {
+  res.addListener('data', function (chunk) { body += chunk; });
+  res.addListener('end', function () {
     proxy.close();
     backend.close();
     // debug("closed both");
index 0dec3ad..e1c2953 100644 (file)
@@ -39,7 +39,7 @@ http.createServer(function (req, res) {
 
   setTimeout(function () {
     res.sendHeader(200, {"Content-Type": "text/plain"});
-    res.sendBody(url.parse(req.url).pathname);
+    res.write(url.parse(req.url).pathname);
     res.finish();
   }, 1);
 
index d4b91ad..f55060a 100644 (file)
@@ -51,9 +51,9 @@ var http_server=http.createServer(function (req, res) {
     this.close();
   }
 
-  req.addListener("complete", function () {
+  req.addListener('end', function () {
     res.sendHeader(200, {"Content-Type": "text/plain"});
-    res.sendBody("The path was " + url.parse(req.url).pathname);
+    res.write("The path was " + url.parse(req.url).pathname);
     res.finish();
     responses_sent += 1;
   });
@@ -75,7 +75,7 @@ req.finish(function (res) {
   assert.equal(200, res.statusCode);
   responses_recvd += 1;
   res.setBodyEncoding("ascii");
-  res.addListener("body", function (chunk) { body0 += chunk; });
+  res.addListener('data', function (chunk) { body0 += chunk; });
   debug("Got /hello response");
 });
 
@@ -90,7 +90,7 @@ setTimeout(function () {
     assert.equal(200, res.statusCode);
     responses_recvd += 1;
     res.setBodyEncoding("utf8");
-    res.addListener("body", function (chunk) { body1 += chunk; });
+    res.addListener('data', function (chunk) { body1 += chunk; });
     debug("Got /world response");
   });
 }, 1);
index e4c5b74..1ae258c 100644 (file)
@@ -25,8 +25,8 @@ var connection_was_closed = false;
 
 var server = http.createServer(function (req, res) {
   res.sendHeader(200, {"Content-Type": "text/plain"});
-  res.sendBody("hello ");
-  res.sendBody("world\n");
+  res.write("hello ");
+  res.write("world\n");
   res.finish();
 })
 server.listen(port);
index 030f2ab..64baf9c 100644 (file)
@@ -27,9 +27,9 @@ http.createServer(function (req, res) {
     this.close();
   }
 
-  req.addListener("complete", function () {
+  req.addListener('end', function () {
     res.sendHeader(200, {"Content-Type": "text/plain"});
-    res.sendBody("The path was " + url.parse(req.url).pathname);
+    res.write("The path was " + url.parse(req.url).pathname);
     res.finish();
     responses_sent += 1;
   });
@@ -43,7 +43,7 @@ req.finish(function (res) {
   assert.equal(200, res.statusCode);
   responses_recvd += 1;
   res.setBodyEncoding("ascii");
-  res.addListener("body", function (chunk) { body0 += chunk; });
+  res.addListener('data', function (chunk) { body0 += chunk; });
   debug("Got /hello response");
 });
 
@@ -53,7 +53,7 @@ setTimeout(function () {
     assert.equal(200, res.statusCode);
     responses_recvd += 1;
     res.setBodyEncoding("utf8");
-    res.addListener("body", function (chunk) { body1 += chunk; });
+    res.addListener('data', function (chunk) { body1 += chunk; });
     debug("Got /world response");
   });
 }, 1);
index 1818630..dcf1ac2 100644 (file)
@@ -10,7 +10,7 @@ server = http.createServer(function (req, res) {
     "Content-Length": body.length, 
     "Content-Type": "text/plain", 
   });
-  res.sendBody(body);
+  res.write(body);
   res.finish();
 });
 server.listen(PORT);
index a0ca434..878c190 100644 (file)
@@ -52,11 +52,11 @@ sys.puts("test "+emails.length+" emails");
   var emailBody = email.body;
   process.nextTick(function s () {
     if (emailBody) {
-      message.emit("body", emailBody.substr(0, chunkSize));
+      message.emit("data", emailBody.substr(0, chunkSize));
       emailBody = emailBody.substr(chunkSize);
       process.nextTick(s);
     } else {
-      message.emit("complete");
+      message.emit("end");
     }
   });
 })();
@@ -80,12 +80,12 @@ var secondPart = new (events.Promise),
     mp.addListener("error", function (er) {
       sys.puts("!! error occurred");
       res.sendHeader(400, {});
-      res.sendBody("bad");
+      res.write("bad");
       res.finish();
     });
     mp.addListener("complete", function () {
       res.sendHeader(200, {});
-      res.sendBody("ok");
+      res.write("ok");
       res.finish();
     });
   }),
@@ -105,11 +105,11 @@ firstPart.addCallback(function testGoodMessages () {
     }
     sys.puts("test message "+httpMessages.length);
     var req = client.request("POST", "/", message.headers);
-    req.sendBody(message.body, "binary");
+    req.write(message.body, "binary");
     req.finish(function (res) {
       var buff = "";
-      res.addListener("body", function (chunk) { buff += chunk });
-      res.addListener("complete", function () {
+      res.addListener("data", function (chunk) { buff += chunk });
+      res.addListener("end", function () {
         assert.equal(buff, "ok");
         process.nextTick(testHTTP);
       });
@@ -127,14 +127,14 @@ secondPart.addCallback(function testBadMessages () {
     }
     sys.puts("test message "+httpMessages.length);
     var req = client.request("POST", "/bad", message.headers);
-    req.sendBody(message.body, "binary");
+    req.write(message.body, "binary");
     req.finish(function (res) {
       var buff = "";
-      res.addListener("body", function (chunk) { buff += chunk });
-      res.addListener("complete", function () {
+      res.addListener("data", function (chunk) { buff += chunk });
+      res.addListener("end", function () {
         assert.equal(buff, "bad");
         process.nextTick(testHTTP);
       });
     });
   })();
-});
\ No newline at end of file
+});
index b4f18a0..61963b9 100644 (file)
@@ -12,7 +12,7 @@ var server = http.createServer(function(req, res) {
              '};';
 
   res.sendHeader(200, {'Content-Type': 'text/javascript'});
-  res.sendBody(body);
+  res.write(body);
   res.finish();
 });
 server.listen(PORT);