Browse Source

Move http library to /http.js

v0.7.4-release
Ryan Dahl 15 years ago
parent
commit
f6657c3c9d
  1. 8
      benchmark/http_simple.js
  2. 3
      benchmark/process_loop.js
  3. 3
      benchmark/run.js
  4. 7
      benchmark/static_http_server.js
  5. 53
      doc/api.html
  6. 52
      doc/api.txt
  7. 63
      doc/api.xml
  8. 10
      doc/index.html
  9. 49
      doc/node.1
  10. 43
      lib/http.js
  11. 1
      src/node.cc
  12. 8
      src/node.js
  13. 8
      src/util.js
  14. 3
      test/mjsunit/disabled/test-cat.js
  15. 8
      test/mjsunit/test-http-cat.js
  16. 5
      test/mjsunit/test-http-client-race.js
  17. 5
      test/mjsunit/test-http-client-upload.js
  18. 3
      test/mjsunit/test-http-malformed-request.js
  19. 9
      test/mjsunit/test-http-proxy.js
  20. 3
      test/mjsunit/test-http-server.js
  21. 5
      test/mjsunit/test-http.js
  22. 3
      test/mjsunit/test-multipart.js
  23. 1
      wscript

8
benchmark/http_simple.js

@ -1,9 +1,15 @@
libDir = node.path.join(node.path.dirname(__filename), "../lib");
node.libraryPaths.unshift(libDir);
include("/utils.js");
http = require("/http.js");
fixed = "" fixed = ""
for (var i = 0; i < 20*1024; i++) { for (var i = 0; i < 20*1024; i++) {
fixed += "C"; fixed += "C";
} }
stored = {}; stored = {};
node.http.createServer(function (req, res) { http.createServer(function (req, res) {
var commands = req.uri.path.split("/"); var commands = req.uri.path.split("/");
var command = commands[1]; var command = commands[1];
var body = ""; var body = "";

3
benchmark/process_loop.js

@ -1,3 +1,6 @@
libDir = node.path.join(node.path.dirname(__filename), "../lib");
node.libraryPaths.unshift(libDir);
include("/utils.js");
function next (i) { function next (i) {
if (i <= 0) return; if (i <= 0) return;

3
benchmark/run.js

@ -1,3 +1,6 @@
libDir = node.path.join(node.path.dirname(__filename), "../lib");
node.libraryPaths.unshift(libDir);
include("/utils.js");
var benchmarks = [ "static_http_server.js" var benchmarks = [ "static_http_server.js"
, "timers.js" , "timers.js"
, "process_loop.js" , "process_loop.js"

7
benchmark/static_http_server.js

@ -1,3 +1,6 @@
libDir = node.path.join(node.path.dirname(__filename), "../lib");
node.libraryPaths.unshift(libDir);
http = require("/http.js");
var concurrency = 30; var concurrency = 30;
var port = 8000; var port = 8000;
var n = 700; var n = 700;
@ -11,7 +14,7 @@ for (var i = 0; i < bytes; i++) {
body += "C"; body += "C";
} }
var server = node.http.createServer(function (req, res) { var server = http.createServer(function (req, res) {
res.sendHeader(200, { res.sendHeader(200, {
"Content-Type": "text/plain", "Content-Type": "text/plain",
"Content-Length": body.length "Content-Length": body.length
@ -35,7 +38,7 @@ function responseListener (res) {
} }
for (var i = 0; i < concurrency; i++) { for (var i = 0; i < concurrency; i++) {
var client = node.http.createClient(port); var client = http.createClient(port);
client.id = i; client.id = i;
client.get("/").finish(responseListener); client.get("/").finish(responseListener);
requests++; requests++;

53
doc/api.html

@ -37,7 +37,8 @@ World":</p></div>
<div class="listingblock"> <div class="listingblock">
<div class="content"> <div class="content">
<pre><tt>include("/utils.js"); <pre><tt>include("/utils.js");
node.http.createServer(function (request, response) { include("/http.js");
createServer(function (request, response) {
response.sendHeader(200, {"Content-Type": "text/plain"}); response.sendHeader(200, {"Content-Type": "text/plain"});
response.sendBody("Hello World\n"); response.sendBody("Hello World\n");
response.finish(); response.finish();
@ -940,6 +941,8 @@ on error: no parameters.
</dd> </dd>
</dl></div> </dl></div>
<h3 id="_http">HTTP</h3><div style="clear:left"></div> <h3 id="_http">HTTP</h3><div style="clear:left"></div>
<div class="paragraph"><p>To use the HTTP server and client one must <tt>require("/http.js")</tt> or
<tt>include("/http.js")</tt>.</p></div>
<div class="paragraph"><p>The HTTP interfaces in Node are designed to support many features <div class="paragraph"><p>The HTTP interfaces in Node are designed to support many features
of the protocol which have been traditionally difficult to use. of the protocol which have been traditionally difficult to use.
In particular, large, possibly chunk-encoded, messages. The interface is In particular, large, possibly chunk-encoded, messages. The interface is
@ -948,11 +951,11 @@ user is able to stream data.</p></div>
<div class="paragraph"><p>HTTP message headers are represented by an object like this</p></div> <div class="paragraph"><p>HTTP message headers are represented by an object like this</p></div>
<div class="listingblock"> <div class="listingblock">
<div class="content"> <div class="content">
<pre><tt> { "Content-Length": "123" <pre><tt>{ "Content-Length": "123"
, "Content-Type": "text/plain" , "Content-Type": "text/plain"
, "Connection": "keep-alive" , "Connection": "keep-alive"
, "Accept": "*/*" , "Accept": "*/*"
}</tt></pre> }</tt></pre>
</div></div> </div></div>
<div class="paragraph"><p>In order to support the full spectrum of possible HTTP applications, Node&#8217;s <div class="paragraph"><p>In order to support the full spectrum of possible HTTP applications, Node&#8217;s
HTTP API is very low-level. It deals with connection handling and message HTTP API is very low-level. It deals with connection handling and message
@ -960,7 +963,7 @@ parsing only. It parses a message into headers and body but it does not
parse the actual headers or the body. That means, for example, that Node parse the actual headers or the body. That means, for example, that Node
does not, and will never, provide API to access or manipulate Cookies or does not, and will never, provide API to access or manipulate Cookies or
multi-part bodies. <em>This is left to the user.</em></p></div> multi-part bodies. <em>This is left to the user.</em></p></div>
<h4 id="_tt_node_http_server_tt"><tt>node.http.Server</tt></h4> <h4 id="_tt_http_server_tt"><tt>http.Server</tt></h4>
<div class="tableblock"> <div class="tableblock">
<table rules="all" <table rules="all"
width="100%" width="100%"
@ -980,14 +983,14 @@ cellspacing="0" cellpadding="4">
<tr> <tr>
<td align="left" valign="top"><p class="table"><tt>"request"</tt></p></td> <td align="left" valign="top"><p class="table"><tt>"request"</tt></p></td>
<td align="left" valign="top"><p class="table"><tt>request, response</tt></p></td> <td align="left" valign="top"><p class="table"><tt>request, response</tt></p></td>
<td align="left" valign="top"><p class="table"><tt>request</tt> is an instance of <tt>node.http.ServerRequest</tt><br /> <td align="left" valign="top"><p class="table"><tt>request</tt> is an instance of <tt>http.ServerRequest</tt><br />
<tt>response</tt> is an instance of <tt>node.http.ServerResponse</tt></p></td> <tt>response</tt> is an instance of <tt>http.ServerResponse</tt></p></td>
</tr> </tr>
<tr> <tr>
<td align="left" valign="top"><p class="table"><tt>"connection"</tt></p></td> <td align="left" valign="top"><p class="table"><tt>"connection"</tt></p></td>
<td align="left" valign="top"><p class="table"><tt>connection</tt></p></td> <td align="left" valign="top"><p class="table"><tt>connection</tt></p></td>
<td align="left" valign="top"><p class="table">When a new TCP connection is established. <td align="left" valign="top"><p class="table">When a new TCP connection is established.
<tt>connection</tt> is an object of type <tt>node.http.Connection</tt>. Usually users will not <tt>connection</tt> is an object of type <tt>http.Connection</tt>. Usually users will not
want to access this event. The <tt>connection</tt> can also be accessed at want to access this event. The <tt>connection</tt> can also be accessed at
<tt>request.connection</tt>.</p></td> <tt>request.connection</tt>.</p></td>
</tr> </tr>
@ -1004,7 +1007,7 @@ want to access this event. The <tt>connection</tt> can also be accessed at
</div> </div>
<div class="dlist"><dl> <div class="dlist"><dl>
<dt class="hdlist1"> <dt class="hdlist1">
<tt>node.http.createServer(request_listener, options);</tt> <tt>http.createServer(request_listener, options);</tt>
</dt> </dt>
<dd> <dd>
<p> <p>
@ -1035,7 +1038,7 @@ Stops the server from accepting new connections.
</p> </p>
</dd> </dd>
</dl></div> </dl></div>
<h4 id="_tt_node_http_serverrequest_tt"><tt>node.http.ServerRequest</tt></h4> <h4 id="_tt_http_serverrequest_tt"><tt>http.ServerRequest</tt></h4>
<div class="paragraph"><p>This object is created internally by a HTTP server&#8212;not by <div class="paragraph"><p>This object is created internally by a HTTP server&#8212;not by
the user&#8212;and passed as the first argument to a <tt>"request"</tt> listener.</p></div> the user&#8212;and passed as the first argument to a <tt>"request"</tt> listener.</p></div>
<div class="tableblock"> <div class="tableblock">
@ -1156,11 +1159,11 @@ Resumes a paused request.
</dt> </dt>
<dd> <dd>
<p> <p>
The <tt>node.http.Connection</tt> object. The <tt>http.Connection</tt> object.
</p> </p>
</dd> </dd>
</dl></div> </dl></div>
<h4 id="_tt_node_http_serverresponse_tt"><tt>node.http.ServerResponse</tt></h4> <h4 id="_tt_http_serverresponse_tt"><tt>http.ServerResponse</tt></h4>
<div class="paragraph"><p>This object is created internally by a HTTP server&#8212;not by the user. It is <div class="paragraph"><p>This object is created internally by a HTTP server&#8212;not by the user. It is
passed as the second parameter to the <tt>"request"</tt> event.</p></div> passed as the second parameter to the <tt>"request"</tt> event.</p></div>
<div class="dlist"><dl> <div class="dlist"><dl>
@ -1216,7 +1219,7 @@ response.
</p> </p>
</dd> </dd>
</dl></div> </dl></div>
<h4 id="_tt_node_http_client_tt"><tt>node.http.Client</tt></h4> <h4 id="_tt_http_client_tt"><tt>http.Client</tt></h4>
<div class="paragraph"><p>An HTTP client is constructed with a server address as its <div class="paragraph"><p>An HTTP client is constructed with a server address as its
argument, the returned handle is then used to issue one or more argument, the returned handle is then used to issue one or more
requests. Depending on the server connected to, the client might requests. Depending on the server connected to, the client might
@ -1225,7 +1228,7 @@ connection. <em>Currently the implementation does not pipeline requests.</em></p
<div class="paragraph"><p>Example of connecting to <tt>google.com</tt></p></div> <div class="paragraph"><p>Example of connecting to <tt>google.com</tt></p></div>
<div class="listingblock"> <div class="listingblock">
<div class="content"> <div class="content">
<pre><tt>var google = node.http.createClient(80, "google.com"); <pre><tt>var google = http.createClient(80, "google.com");
var request = google.get("/"); var request = google.get("/");
request.finish(function (response) { request.finish(function (response) {
puts("STATUS: " + response.statusCode); puts("STATUS: " + response.statusCode);
@ -1238,7 +1241,7 @@ request.finish(function (response) {
</div></div> </div></div>
<div class="dlist"><dl> <div class="dlist"><dl>
<dt class="hdlist1"> <dt class="hdlist1">
<tt>node.http.createClient(port, host)</tt> <tt>http.createClient(port, host)</tt>
</dt> </dt>
<dd> <dd>
<p> <p>
@ -1252,7 +1255,7 @@ connection is not established until a request is issued.
</dt> </dt>
<dd> <dd>
<p> <p>
Issues a request; if necessary establishes connection. Returns a <tt>node.http.ClientRequest</tt> instance. Issues a request; if necessary establishes connection. Returns a <tt>http.ClientRequest</tt> instance.
</p> </p>
<div class="paragraph"><p><tt>request_headers</tt> is optional. <div class="paragraph"><p><tt>request_headers</tt> is optional.
Additional request headers might be added internally Additional request headers might be added internally
@ -1275,9 +1278,9 @@ for the user to stream a body to the server with
</div> </div>
</dd> </dd>
</dl></div> </dl></div>
<h4 id="_tt_node_http_clientrequest_tt"><tt>node.http.ClientRequest</tt></h4> <h4 id="_tt_http_clientrequest_tt"><tt>http.ClientRequest</tt></h4>
<div class="paragraph"><p>This object is created internally and returned from the request methods of a <div class="paragraph"><p>This object is created internally and returned from the request methods of a
<tt>node.http.Client</tt>. It represents an <em>in-progress</em> request whose header has <tt>http.Client</tt>. It represents an <em>in-progress</em> request whose header has
already been sent.</p></div> already been sent.</p></div>
<div class="tableblock"> <div class="tableblock">
<table rules="all" <table rules="all"
@ -1301,7 +1304,7 @@ cellspacing="0" cellpadding="4">
<td align="left" valign="top"><p class="table">Emitted when a response is received to this request. Typically the user will <td align="left" valign="top"><p class="table">Emitted when a response is received to this request. Typically the user will
set a listener to this via the <tt>request.finish()</tt> method.<br /> set a listener to this via the <tt>request.finish()</tt> method.<br />
This event is emitted only once.<br /> This event is emitted only once.<br />
The <tt>response</tt> argument will be an instance of <tt>node.http.ClientResponse</tt>.</p></td> The <tt>response</tt> argument will be an instance of <tt>http.ClientResponse</tt>.</p></td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
@ -1338,7 +1341,7 @@ chunked, this will send the terminating <tt>"0\r\n\r\n"</tt>.
<div class="paragraph"><p>The parameter <tt>responseListener</tt> is a callback which <div class="paragraph"><p>The parameter <tt>responseListener</tt> is a callback which
will be executed when the response headers have been received. will be executed when the response headers have been received.
The <tt>responseListener</tt> callback is executed with one The <tt>responseListener</tt> callback is executed with one
argument which is an instance of <tt>node.http.ClientResponse</tt>.</p></div> argument which is an instance of <tt>http.ClientResponse</tt>.</p></div>
<div class="paragraph"><p>In the <tt>responseListener</tt> callback, one can add more listeners to the <div class="paragraph"><p>In the <tt>responseListener</tt> callback, one can add more listeners to the
response, in particular listening for the <tt>"body"</tt> event. Note that response, in particular listening for the <tt>"body"</tt> event. Note that
the <tt>responseListener</tt> is called before any part of the body is receieved, the <tt>responseListener</tt> is called before any part of the body is receieved,
@ -1365,7 +1368,7 @@ request.finish(function (response) {
</div></div> </div></div>
</dd> </dd>
</dl></div> </dl></div>
<h4 id="_tt_node_http_clientresponse_tt"><tt>node.http.ClientResponse</tt></h4> <h4 id="_tt_http_clientresponse_tt"><tt>http.ClientResponse</tt></h4>
<div class="paragraph"><p>This object is created internally and passed to the <tt>"response"</tt> event.</p></div> <div class="paragraph"><p>This object is created internally and passed to the <tt>"response"</tt> event.</p></div>
<div class="tableblock"> <div class="tableblock">
<table rules="all" <table rules="all"
@ -1456,7 +1459,7 @@ After emitted no other events will be emitted on the response.</p></td>
</dt> </dt>
<dd> <dd>
<p> <p>
A reference to the <tt>node.http.Client</tt> that this response belongs to. A reference to the <tt>http.Client</tt> that this response belongs to.
</p> </p>
</dd> </dd>
</dl></div> </dl></div>
@ -1943,7 +1946,7 @@ init (Handle&lt;Object&gt; target)
<div id="footer"> <div id="footer">
<div id="footer-text"> <div id="footer-text">
Version 0.1.12<br /> Version 0.1.12<br />
Last updated 2009-09-28 12:04:19 CEST Last updated 2009-09-28 12:23:06 CEST
</div> </div>
</div> </div>
</body> </body>

52
doc/api.txt

@ -17,7 +17,8 @@ World":
---------------------------------------- ----------------------------------------
include("/utils.js"); include("/utils.js");
node.http.createServer(function (request, response) { include("/http.js");
createServer(function (request, response) {
response.sendHeader(200, {"Content-Type": "text/plain"}); response.sendHeader(200, {"Content-Type": "text/plain"});
response.sendBody("Hello World\n"); response.sendBody("Hello World\n");
response.finish(); response.finish();
@ -568,6 +569,9 @@ Objects returned from +node.fs.stat()+ are of this type.
=== HTTP === HTTP
To use the HTTP server and client one must +require("/http.js")+ or
+include("/http.js")+.
The HTTP interfaces in Node are designed to support many features The HTTP interfaces in Node are designed to support many features
of the protocol which have been traditionally difficult to use. of the protocol which have been traditionally difficult to use.
In particular, large, possibly chunk-encoded, messages. The interface is In particular, large, possibly chunk-encoded, messages. The interface is
@ -577,11 +581,11 @@ user is able to stream data.
HTTP message headers are represented by an object like this HTTP message headers are represented by an object like this
---------------------------------------- ----------------------------------------
{ "Content-Length": "123" { "Content-Length": "123"
, "Content-Type": "text/plain" , "Content-Type": "text/plain"
, "Connection": "keep-alive" , "Connection": "keep-alive"
, "Accept": "*/*" , "Accept": "*/*"
} }
---------------------------------------- ----------------------------------------
In order to support the full spectrum of possible HTTP applications, Node's In order to support the full spectrum of possible HTTP applications, Node's
@ -592,20 +596,20 @@ does not, and will never, provide API to access or manipulate Cookies or
multi-part bodies. _This is left to the user._ multi-part bodies. _This is left to the user._
==== +node.http.Server+ ==== +http.Server+
[cols="1,2,10",options="header"] [cols="1,2,10",options="header"]
|========================================================= |=========================================================
|Event | Parameters | Notes |Event | Parameters | Notes
|+"request"+ | +request, response+ | |+"request"+ | +request, response+ |
+request+ is an instance of +node.http.ServerRequest+ +request+ is an instance of +http.ServerRequest+
+ +
+response+ is an instance of +node.http.ServerResponse+ +response+ is an instance of +http.ServerResponse+
|+"connection"+ | +connection+ | |+"connection"+ | +connection+ |
When a new TCP connection is established. When a new TCP connection is established.
+connection+ is an object of type +node.http.Connection+. Usually users will not +connection+ is an object of type +http.Connection+. Usually users will not
want to access this event. The +connection+ can also be accessed at want to access this event. The +connection+ can also be accessed at
+request.connection+. +request.connection+.
@ -616,7 +620,7 @@ want to access this event. The +connection+ can also be accessed at
|========================================================= |=========================================================
+node.http.createServer(request_listener, options);+ :: +http.createServer(request_listener, options);+ ::
Returns a new web server object. Returns a new web server object.
+ +
The +options+ argument is optional. The The +options+ argument is optional. The
@ -636,7 +640,7 @@ Stops the server from accepting new connections.
==== +node.http.ServerRequest+ ==== +http.ServerRequest+
This object is created internally by a HTTP server--not by This object is created internally by a HTTP server--not by
the user--and passed as the first argument to a +"request"+ listener. the user--and passed as the first argument to a +"request"+ listener.
@ -712,10 +716,10 @@ Resumes a paused request.
+request.connection+ :: +request.connection+ ::
The +node.http.Connection+ object. The +http.Connection+ object.
==== +node.http.ServerResponse+ ==== +http.ServerResponse+
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. passed as the second parameter to the +"request"+ event.
@ -766,7 +770,7 @@ response.
==== +node.http.Client+ ==== +http.Client+
An HTTP client is constructed with a server address as its An HTTP client is constructed with a server address as its
argument, the returned handle is then used to issue one or more argument, the returned handle is then used to issue one or more
@ -777,7 +781,7 @@ connection. _Currently the implementation does not pipeline requests._
Example of connecting to +google.com+ Example of connecting to +google.com+
---------------------------------------- ----------------------------------------
var google = node.http.createClient(80, "google.com"); var google = http.createClient(80, "google.com");
var request = google.get("/"); var request = google.get("/");
request.finish(function (response) { request.finish(function (response) {
puts("STATUS: " + response.statusCode); puts("STATUS: " + response.statusCode);
@ -789,7 +793,7 @@ request.finish(function (response) {
}); });
---------------------------------------- ----------------------------------------
+node.http.createClient(port, host)+ :: +http.createClient(port, host)+ ::
Constructs a new HTTP client. +port+ and Constructs a new HTTP client. +port+ and
+host+ refer to the server to be connected to. A +host+ refer to the server to be connected to. A
@ -797,7 +801,7 @@ connection is not established until a request is issued.
+client.get(path, request_headers)+, +client.head(path, request_headers)+, +client.post(path, request_headers)+, +client.del(path, request_headers)+, +client.put(path, request_headers)+ :: +client.get(path, request_headers)+, +client.head(path, request_headers)+, +client.post(path, request_headers)+, +client.del(path, request_headers)+, +client.put(path, request_headers)+ ::
Issues a request; if necessary establishes connection. Returns a +node.http.ClientRequest+ instance. Issues a request; if necessary establishes connection. Returns a +http.ClientRequest+ instance.
+ +
+request_headers+ is optional. +request_headers+ is optional.
Additional request headers might be added internally Additional request headers might be added internally
@ -815,10 +819,10 @@ for the user to stream a body to the server with
+request.sendBody()+.) +request.sendBody()+.)
==== +node.http.ClientRequest+ ==== +http.ClientRequest+
This object is created internally and returned from the request methods of a This object is created internally and returned from the request methods of a
+node.http.Client+. It represents an _in-progress_ request whose header has +http.Client+. It represents an _in-progress_ request whose header has
already been sent. already been sent.
[cols="1,2,10",options="header"] [cols="1,2,10",options="header"]
@ -830,7 +834,7 @@ set a listener to this via the +request.finish()+ method.
+ +
This event is emitted only once. This event is emitted only once.
+ +
The +response+ argument will be an instance of +node.http.ClientResponse+. The +response+ argument will be an instance of +http.ClientResponse+.
|========================================================= |=========================================================
@ -861,7 +865,7 @@ chunked, this will send the terminating +"0\r\n\r\n"+.
The parameter +responseListener+ is a callback which The parameter +responseListener+ is a callback which
will be executed when the response headers have been received. will be executed when the response headers have been received.
The +responseListener+ callback is executed with one The +responseListener+ callback is executed with one
argument which is an instance of +node.http.ClientResponse+. argument which is an instance of +http.ClientResponse+.
+ +
In the +responseListener+ callback, one can add more listeners to the 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 +"body"+ event. Note that
@ -891,7 +895,7 @@ request.finish(function (response) {
==== +node.http.ClientResponse+ ==== +http.ClientResponse+
This object is created internally and passed to the +"response"+ event. This object is created internally and passed to the +"response"+ event.
@ -932,7 +936,7 @@ After emitted no other events will be emitted on the response.
Resumes a paused response. Resumes a paused response.
+response.client+ :: +response.client+ ::
A reference to the +node.http.Client+ that this response belongs to. A reference to the +http.Client+ that this response belongs to.

63
doc/api.xml

@ -13,7 +13,8 @@
<simpara>An example of a web server written with Node which responds with "Hello <simpara>An example of a web server written with Node which responds with "Hello
World":</simpara> World":</simpara>
<screen>include("/utils.js"); <screen>include("/utils.js");
node.http.createServer(function (request, response) { include("/http.js");
createServer(function (request, response) {
response.sendHeader(200, {"Content-Type": "text/plain"}); response.sendHeader(200, {"Content-Type": "text/plain"});
response.sendBody("Hello World\n"); response.sendBody("Hello World\n");
response.finish(); response.finish();
@ -988,25 +989,27 @@ on error: no parameters.
</refsect2> </refsect2>
<refsect2 id="_http"> <refsect2 id="_http">
<title>HTTP</title> <title>HTTP</title>
<simpara>To use the HTTP server and client one must <literal>require("/http.js")</literal> or
<literal>include("/http.js")</literal>.</simpara>
<simpara>The HTTP interfaces in Node are designed to support many features <simpara>The HTTP interfaces in Node are designed to support many features
of the protocol which have been traditionally difficult to use. of the protocol which have been traditionally difficult to use.
In particular, large, possibly chunk-encoded, messages. The interface is In particular, large, possibly chunk-encoded, messages. The interface is
careful to never buffer entire requests or responses&#8212;the careful to never buffer entire requests or responses&#8212;the
user is able to stream data.</simpara> user is able to stream data.</simpara>
<simpara>HTTP message headers are represented by an object like this</simpara> <simpara>HTTP message headers are represented by an object like this</simpara>
<screen> { "Content-Length": "123" <screen>{ "Content-Length": "123"
, "Content-Type": "text/plain" , "Content-Type": "text/plain"
, "Connection": "keep-alive" , "Connection": "keep-alive"
, "Accept": "*/*" , "Accept": "*/*"
}</screen> }</screen>
<simpara>In order to support the full spectrum of possible HTTP applications, Node&#8217;s <simpara>In order to support the full spectrum of possible HTTP applications, Node&#8217;s
HTTP API is very low-level. It deals with connection handling and message HTTP API is very low-level. It deals with connection handling and message
parsing only. It parses a message into headers and body but it does not parsing only. It parses a message into headers and body but it does not
parse the actual headers or the body. That means, for example, that Node parse the actual headers or the body. That means, for example, that Node
does not, and will never, provide API to access or manipulate Cookies or does not, and will never, provide API to access or manipulate Cookies or
multi-part bodies. <emphasis>This is left to the user.</emphasis></simpara> multi-part bodies. <emphasis>This is left to the user.</emphasis></simpara>
<refsect3 id="_literal_node_http_server_literal"> <refsect3 id="_literal_http_server_literal">
<title><literal>node.http.Server</literal></title> <title><literal>http.Server</literal></title>
<informaltable <informaltable
frame="all" frame="all"
rowsep="1" colsep="1" rowsep="1" colsep="1"
@ -1026,14 +1029,14 @@ rowsep="1" colsep="1"
<row> <row>
<entry align="left" valign="top"><simpara><literal>"request"</literal></simpara></entry> <entry align="left" valign="top"><simpara><literal>"request"</literal></simpara></entry>
<entry align="left" valign="top"><simpara><literal>request, response</literal></simpara></entry> <entry align="left" valign="top"><simpara><literal>request, response</literal></simpara></entry>
<entry align="left" valign="top"><simpara><literal>request</literal> is an instance of <literal>node.http.ServerRequest</literal><?asciidoc-br?> <entry align="left" valign="top"><simpara><literal>request</literal> is an instance of <literal>http.ServerRequest</literal><?asciidoc-br?>
<literal>response</literal> is an instance of <literal>node.http.ServerResponse</literal></simpara></entry> <literal>response</literal> is an instance of <literal>http.ServerResponse</literal></simpara></entry>
</row> </row>
<row> <row>
<entry align="left" valign="top"><simpara><literal>"connection"</literal></simpara></entry> <entry align="left" valign="top"><simpara><literal>"connection"</literal></simpara></entry>
<entry align="left" valign="top"><simpara><literal>connection</literal></simpara></entry> <entry align="left" valign="top"><simpara><literal>connection</literal></simpara></entry>
<entry align="left" valign="top"><simpara>When a new TCP connection is established. <entry align="left" valign="top"><simpara>When a new TCP connection is established.
<literal>connection</literal> is an object of type <literal>node.http.Connection</literal>. Usually users will not <literal>connection</literal> is an object of type <literal>http.Connection</literal>. Usually users will not
want to access this event. The <literal>connection</literal> can also be accessed at want to access this event. The <literal>connection</literal> can also be accessed at
<literal>request.connection</literal>.</simpara></entry> <literal>request.connection</literal>.</simpara></entry>
</row> </row>
@ -1051,7 +1054,7 @@ want to access this event. The <literal>connection</literal> can also be accesse
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<term> <term>
<literal>node.http.createServer(request_listener, options);</literal> <literal>http.createServer(request_listener, options);</literal>
</term> </term>
<listitem> <listitem>
<simpara> <simpara>
@ -1088,8 +1091,8 @@ Stops the server from accepting new connections.
</varlistentry> </varlistentry>
</variablelist> </variablelist>
</refsect3> </refsect3>
<refsect3 id="_literal_node_http_serverrequest_literal"> <refsect3 id="_literal_http_serverrequest_literal">
<title><literal>node.http.ServerRequest</literal></title> <title><literal>http.ServerRequest</literal></title>
<simpara>This object is created internally by a HTTP server&#8212;not by <simpara>This object is created internally by a HTTP server&#8212;not by
the user&#8212;and passed as the first argument to a <literal>"request"</literal> listener.</simpara> the user&#8212;and passed as the first argument to a <literal>"request"</literal> listener.</simpara>
<informaltable <informaltable
@ -1219,14 +1222,14 @@ Resumes a paused request.
</term> </term>
<listitem> <listitem>
<simpara> <simpara>
The <literal>node.http.Connection</literal> object. The <literal>http.Connection</literal> object.
</simpara> </simpara>
</listitem> </listitem>
</varlistentry> </varlistentry>
</variablelist> </variablelist>
</refsect3> </refsect3>
<refsect3 id="_literal_node_http_serverresponse_literal"> <refsect3 id="_literal_http_serverresponse_literal">
<title><literal>node.http.ServerResponse</literal></title> <title><literal>http.ServerResponse</literal></title>
<simpara>This object is created internally by a HTTP server&#8212;not by the user. It is <simpara>This object is created internally by a HTTP server&#8212;not by the user. It is
passed as the second parameter to the <literal>"request"</literal> event.</simpara> passed as the second parameter to the <literal>"request"</literal> event.</simpara>
<variablelist> <variablelist>
@ -1286,15 +1289,15 @@ response.
</varlistentry> </varlistentry>
</variablelist> </variablelist>
</refsect3> </refsect3>
<refsect3 id="_literal_node_http_client_literal"> <refsect3 id="_literal_http_client_literal">
<title><literal>node.http.Client</literal></title> <title><literal>http.Client</literal></title>
<simpara>An HTTP client is constructed with a server address as its <simpara>An HTTP client is constructed with a server address as its
argument, the returned handle is then used to issue one or more argument, the returned handle is then used to issue one or more
requests. Depending on the server connected to, the client might requests. Depending on the server connected to, the client might
pipeline the requests or reestablish the connection after each pipeline the requests or reestablish the connection after each
connection. <emphasis>Currently the implementation does not pipeline requests.</emphasis></simpara> connection. <emphasis>Currently the implementation does not pipeline requests.</emphasis></simpara>
<simpara>Example of connecting to <literal>google.com</literal></simpara> <simpara>Example of connecting to <literal>google.com</literal></simpara>
<screen>var google = node.http.createClient(80, "google.com"); <screen>var google = http.createClient(80, "google.com");
var request = google.get("/"); var request = google.get("/");
request.finish(function (response) { request.finish(function (response) {
puts("STATUS: " + response.statusCode); puts("STATUS: " + response.statusCode);
@ -1307,7 +1310,7 @@ request.finish(function (response) {
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<term> <term>
<literal>node.http.createClient(port, host)</literal> <literal>http.createClient(port, host)</literal>
</term> </term>
<listitem> <listitem>
<simpara> <simpara>
@ -1323,7 +1326,7 @@ connection is not established until a request is issued.
</term> </term>
<listitem> <listitem>
<simpara> <simpara>
Issues a request; if necessary establishes connection. Returns a <literal>node.http.ClientRequest</literal> instance. Issues a request; if necessary establishes connection. Returns a <literal>http.ClientRequest</literal> instance.
</simpara> </simpara>
<simpara><literal>request_headers</literal> is optional. <simpara><literal>request_headers</literal> is optional.
Additional request headers might be added internally Additional request headers might be added internally
@ -1341,10 +1344,10 @@ for the user to stream a body to the server with
</varlistentry> </varlistentry>
</variablelist> </variablelist>
</refsect3> </refsect3>
<refsect3 id="_literal_node_http_clientrequest_literal"> <refsect3 id="_literal_http_clientrequest_literal">
<title><literal>node.http.ClientRequest</literal></title> <title><literal>http.ClientRequest</literal></title>
<simpara>This object is created internally and returned from the request methods of a <simpara>This object is created internally and returned from the request methods of a
<literal>node.http.Client</literal>. It represents an <emphasis>in-progress</emphasis> request whose header has <literal>http.Client</literal>. It represents an <emphasis>in-progress</emphasis> request whose header has
already been sent.</simpara> already been sent.</simpara>
<informaltable <informaltable
frame="all" frame="all"
@ -1368,7 +1371,7 @@ rowsep="1" colsep="1"
<entry align="left" valign="top"><simpara>Emitted when a response is received to this request. Typically the user will <entry align="left" valign="top"><simpara>Emitted when a response is received to this request. Typically the user will
set a listener to this via the <literal>request.finish()</literal> method.<?asciidoc-br?> set a listener to this via the <literal>request.finish()</literal> method.<?asciidoc-br?>
This event is emitted only once.<?asciidoc-br?> This event is emitted only once.<?asciidoc-br?>
The <literal>response</literal> argument will be an instance of <literal>node.http.ClientResponse</literal>.</simpara></entry> The <literal>response</literal> argument will be an instance of <literal>http.ClientResponse</literal>.</simpara></entry>
</row> </row>
</tbody> </tbody>
</tgroup> </tgroup>
@ -1408,7 +1411,7 @@ chunked, this will send the terminating <literal>"0\r\n\r\n"</literal>.
<simpara>The parameter <literal>responseListener</literal> is a callback which <simpara>The parameter <literal>responseListener</literal> is a callback which
will be executed when the response headers have been received. will be executed when the response headers have been received.
The <literal>responseListener</literal> callback is executed with one The <literal>responseListener</literal> callback is executed with one
argument which is an instance of <literal>node.http.ClientResponse</literal>.</simpara> argument which is an instance of <literal>http.ClientResponse</literal>.</simpara>
<simpara>In the <literal>responseListener</literal> callback, one can add more listeners to the <simpara>In the <literal>responseListener</literal> callback, one can add more listeners to the
response, in particular listening for the <literal>"body"</literal> event. Note that response, in particular listening for the <literal>"body"</literal> event. Note that
the <literal>responseListener</literal> is called before any part of the body is receieved, the <literal>responseListener</literal> is called before any part of the body is receieved,
@ -1434,8 +1437,8 @@ request.finish(function (response) {
</varlistentry> </varlistentry>
</variablelist> </variablelist>
</refsect3> </refsect3>
<refsect3 id="_literal_node_http_clientresponse_literal"> <refsect3 id="_literal_http_clientresponse_literal">
<title><literal>node.http.ClientResponse</literal></title> <title><literal>http.ClientResponse</literal></title>
<simpara>This object is created internally and passed to the <literal>"response"</literal> event.</simpara> <simpara>This object is created internally and passed to the <literal>"response"</literal> event.</simpara>
<informaltable <informaltable
frame="all" frame="all"
@ -1539,7 +1542,7 @@ After emitted no other events will be emitted on the response.</simpara></entry>
</term> </term>
<listitem> <listitem>
<simpara> <simpara>
A reference to the <literal>node.http.Client</literal> that this response belongs to. A reference to the <literal>http.Client</literal> that this response belongs to.
</simpara> </simpara>
</listitem> </listitem>
</varlistentry> </varlistentry>

10
doc/index.html

@ -41,16 +41,16 @@
</p> </p>
<pre> <pre>
utils = require("/utils.js"); include("/utils.js");
server = node.http.createServer(function (req, res) { include("/http.js");
createServer(function (req, res) {
setTimeout(function () { setTimeout(function () {
res.sendHeader(200, {"Content-Type": "text/plain"}); res.sendHeader(200, {"Content-Type": "text/plain"});
res.sendBody("Hello World"); res.sendBody("Hello World");
res.finish(); res.finish();
}, 2000); }, 2000);
}); }).listen(8000);
server.listen(8000); puts("Server running at http://127.0.0.1:8000/");</pre>
utils.puts("Server running at http://127.0.0.1:8000/");</pre>
</pre> </pre>
<p> <p>

49
doc/node.1

@ -19,7 +19,8 @@ An example of a web server written with Node which responds with "Hello World":
.RS 4 .RS 4
.nf .nf
include("/utils\.js"); include("/utils\.js");
node\.http\.createServer(function (request, response) { include("/http\.js");
createServer(function (request, response) {
response\.sendHeader(200, {"Content\-Type": "text/plain"}); response\.sendHeader(200, {"Content\-Type": "text/plain"});
response\.sendBody("Hello World\en"); response\.sendBody("Hello World\en");
response\.finish(); response\.finish();
@ -819,6 +820,8 @@ stats\.isFile(), stats\.isDirectory(), stats\.isBlockDevice(), stats\.isCharacte
.RE .RE
.RE .RE
.SS "HTTP" .SS "HTTP"
To use the HTTP server and client one must require("/http\.js") or include("/http\.js")\.
.sp
The HTTP interfaces in Node are designed to support many features of the protocol which have been traditionally difficult to use\. In particular, large, possibly chunk\-encoded, messages\. The interface is careful to never buffer entire requests or responses\(emthe user is able to stream data\. The HTTP interfaces in Node are designed to support many features of the protocol which have been traditionally difficult to use\. In particular, large, possibly chunk\-encoded, messages\. The interface is careful to never buffer entire requests or responses\(emthe user is able to stream data\.
.sp .sp
HTTP message headers are represented by an object like this HTTP message headers are represented by an object like this
@ -826,11 +829,11 @@ HTTP message headers are represented by an object like this
.sp .sp
.RS 4 .RS 4
.nf .nf
{ "Content\-Length": "123" { "Content\-Length": "123"
, "Content\-Type": "text/plain" , "Content\-Type": "text/plain"
, "Connection": "keep\-alive" , "Connection": "keep\-alive"
, "Accept": "*/*" , "Accept": "*/*"
} }
.fi .fi
.RE .RE
In order to support the full spectrum of possible HTTP applications, Node\(cqs HTTP API is very low\-level\. It deals with connection handling and message parsing only\. It parses a message into headers and body but it does not parse the actual headers or the body\. That means, for example, that Node does not, and will never, provide API to access or manipulate Cookies or multi\-part bodies\. \fIThis is left to the user\.\fR In order to support the full spectrum of possible HTTP applications, Node\(cqs HTTP API is very low\-level\. It deals with connection handling and message parsing only\. It parses a message into headers and body but it does not parse the actual headers or the body\. That means, for example, that Node does not, and will never, provide API to access or manipulate Cookies or multi\-part bodies\. \fIThis is left to the user\.\fR
@ -840,7 +843,7 @@ In order to support the full spectrum of possible HTTP applications, Node\(cqs H
.nr an-no-space-flag 1 .nr an-no-space-flag 1
.nr an-break-flag 1 .nr an-break-flag 1
.br .br
node.http.Server http.Server
.RS .RS
.TS .TS
allbox tab(:); allbox tab(:);
@ -863,7 +866,7 @@ T}:T{
request, response request, response
.sp .sp
T}:T{ T}:T{
request is an instance of node\.http\.ServerRequest response is an instance of node\.http\.ServerResponse request is an instance of http\.ServerRequest response is an instance of http\.ServerResponse
.sp .sp
T} T}
T{ T{
@ -873,7 +876,7 @@ T}:T{
connection connection
.sp .sp
T}:T{ T}:T{
When a new TCP connection is established\. connection is an object of type node\.http\.Connection\. Usually users will not want to access this event\. The connection can also be accessed at request\.connection\. When a new TCP connection is established\. connection is an object of type http\.Connection\. Usually users will not want to access this event\. The connection can also be accessed at request\.connection\.
.sp .sp
T} T}
T{ T{
@ -888,7 +891,7 @@ Emitted when the server closes\. errorno is an integer which indicates what, if
T} T}
.TE .TE
.PP .PP
node\.http\.createServer(request_listener, options); http\.createServer(request_listener, options);
.RS 4 .RS 4
Returns a new web server object\. Returns a new web server object\.
.sp .sp
@ -922,7 +925,7 @@ Stops the server from accepting new connections\.
.nr an-no-space-flag 1 .nr an-no-space-flag 1
.nr an-break-flag 1 .nr an-break-flag 1
.br .br
node.http.ServerRequest http.ServerRequest
.RS .RS
This object is created internally by a HTTP server\(emnot by the user\(emand passed as the first argument to a "request" listener\. This object is created internally by a HTTP server\(emnot by the user\(emand passed as the first argument to a "request" listener\.
.sp .sp
@ -1047,7 +1050,7 @@ Resumes a paused request\.
request\.connection request\.connection
.RS 4 .RS 4
The The
node\.http\.Connection http\.Connection
object\. object\.
.RE .RE
.RE .RE
@ -1056,7 +1059,7 @@ object\.
.nr an-no-space-flag 1 .nr an-no-space-flag 1
.nr an-break-flag 1 .nr an-break-flag 1
.br .br
node.http.ServerResponse http.ServerResponse
.RS .RS
This object is created internally by a HTTP server\(emnot by the user\. It is passed as the second parameter to the "request" event\. This object is created internally by a HTTP server\(emnot by the user\. It is passed as the second parameter to the "request" event\.
.PP .PP
@ -1116,7 +1119,7 @@ response\.finish(), MUST be called on each response\.
.nr an-no-space-flag 1 .nr an-no-space-flag 1
.nr an-break-flag 1 .nr an-break-flag 1
.br .br
node.http.Client http.Client
.RS .RS
An HTTP client is constructed with a server address as its argument, the returned handle is then used to issue one or more requests\. Depending on the server connected to, the client might pipeline the requests or reestablish the connection after each connection\. \fICurrently the implementation does not pipeline requests\.\fR An HTTP client is constructed with a server address as its argument, the returned handle is then used to issue one or more requests\. Depending on the server connected to, the client might pipeline the requests or reestablish the connection after each connection\. \fICurrently the implementation does not pipeline requests\.\fR
.sp .sp
@ -1125,7 +1128,7 @@ Example of connecting to google\.com
.sp .sp
.RS 4 .RS 4
.nf .nf
var google = node\.http\.createClient(80, "google\.com"); var google = http\.createClient(80, "google\.com");
var request = google\.get("/"); var request = google\.get("/");
request\.finish(function (response) { request\.finish(function (response) {
puts("STATUS: " + response\.statusCode); puts("STATUS: " + response\.statusCode);
@ -1138,7 +1141,7 @@ request\.finish(function (response) {
.fi .fi
.RE .RE
.PP .PP
node\.http\.createClient(port, host) http\.createClient(port, host)
.RS 4 .RS 4
Constructs a new HTTP client\. Constructs a new HTTP client\.
port port
@ -1150,7 +1153,7 @@ refer to the server to be connected to\. A connection is not established until a
client\.get(path, request_headers), client\.head(path, request_headers), client\.post(path, request_headers), client\.del(path, request_headers), client\.put(path, request_headers) client\.get(path, request_headers), client\.head(path, request_headers), client\.post(path, request_headers), client\.del(path, request_headers), client\.put(path, request_headers)
.RS 4 .RS 4
Issues a request; if necessary establishes connection\. Returns a Issues a request; if necessary establishes connection\. Returns a
node\.http\.ClientRequest http\.ClientRequest
instance\. instance\.
.sp .sp
request_headers request_headers
@ -1179,9 +1182,9 @@ request\.sendBody()\.)
.nr an-no-space-flag 1 .nr an-no-space-flag 1
.nr an-break-flag 1 .nr an-break-flag 1
.br .br
node.http.ClientRequest http.ClientRequest
.RS .RS
This object is created internally and returned from the request methods of a node\.http\.Client\. It represents an \fIin\-progress\fR request whose header has already been sent\. This object is created internally and returned from the request methods of a http\.Client\. It represents an \fIin\-progress\fR request whose header has already been sent\.
.sp .sp
.TS .TS
allbox tab(:); allbox tab(:);
@ -1202,7 +1205,7 @@ T}:T{
response response
.sp .sp
T}:T{ T}:T{
Emitted when a response is received to this request\. Typically the user will set a listener to this via the request\.finish() method\. This event is emitted only once\. The response argument will be an instance of node\.http\.ClientResponse\. Emitted when a response is received to this request\. Typically the user will set a listener to this via the request\.finish() method\. This event is emitted only once\. The response argument will be an instance of http\.ClientResponse\.
.sp .sp
T} T}
.TE .TE
@ -1237,7 +1240,7 @@ responseListener
is a callback which will be executed when the response headers have been received\. The is a callback which will be executed when the response headers have been received\. The
responseListener responseListener
callback is executed with one argument which is an instance of callback is executed with one argument which is an instance of
node\.http\.ClientResponse\. http\.ClientResponse\.
.sp .sp
In the In the
responseListener responseListener
@ -1277,7 +1280,7 @@ request\.finish(function (response) {
.nr an-no-space-flag 1 .nr an-no-space-flag 1
.nr an-break-flag 1 .nr an-break-flag 1
.br .br
node.http.ClientResponse http.ClientResponse
.RS .RS
This object is created internally and passed to the "response" event\. This object is created internally and passed to the "response" event\.
.sp .sp
@ -1356,7 +1359,7 @@ Resumes a paused response\.
response\.client response\.client
.RS 4 .RS 4
A reference to the A reference to the
node\.http\.Client http\.Client
that this response belongs to\. that this response belongs to\.
.RE .RE
.RE .RE

43
src/http.js → lib/http.js

@ -1,6 +1,7 @@
(function () { var utils = require("/utils.js");
CRLF = "\r\n";
node.http.STATUS_CODES = { var CRLF = "\r\n";
var STATUS_CODES = {
100 : 'Continue', 100 : 'Continue',
101 : 'Switching Protocols', 101 : 'Switching Protocols',
200 : 'OK', 200 : 'OK',
@ -50,8 +51,8 @@ function decode (s) {
return decodeURIComponent(s.replace(/\+/g, ' ')); return decodeURIComponent(s.replace(/\+/g, ' '));
} }
node.http.parseUri = function (str) { exports.parseUri = function (str) {
var o = node.http.parseUri.options, var o = exports.parseUri.options,
m = o.parser[o.strictMode ? "strict" : "loose"].exec(str), m = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
uri = {}, uri = {},
i = 14; i = 14;
@ -79,7 +80,7 @@ node.http.parseUri = function (str) {
return uri; return uri;
}; };
node.http.parseUri.options = { exports.parseUri.options = {
strictMode: false, strictMode: false,
key: [ key: [
"source", "source",
@ -296,7 +297,7 @@ function ServerResponse () {
node.inherits(ServerResponse, OutgoingMessage); node.inherits(ServerResponse, OutgoingMessage);
ServerResponse.prototype.sendHeader = function (statusCode, headers) { ServerResponse.prototype.sendHeader = function (statusCode, headers) {
var reason = node.http.STATUS_CODES[statusCode] || "unknown"; var reason = STATUS_CODES[statusCode] || "unknown";
var status_line = "HTTP/1.1 " + statusCode.toString() + " " + reason + CRLF; var status_line = "HTTP/1.1 " + statusCode.toString() + " " + reason + CRLF;
this.sendHeaderLines(status_line, headers); this.sendHeaderLines(status_line, headers);
}; };
@ -371,7 +372,7 @@ function createIncomingMessageStream (connection, incoming_listener) {
if (info.method) { if (info.method) {
// server only // server only
incoming.method = info.method; incoming.method = info.method;
incoming.uri = node.http.parseUri(incoming.uri); // TODO parse the URI lazily? incoming.uri = exports.parseUri(incoming.uri); // TODO parse the URI lazily?
} else { } else {
// client only // client only
incoming.statusCode = info.statusCode; incoming.statusCode = info.statusCode;
@ -419,7 +420,7 @@ function flushMessageQueue (connection, queue) {
} }
node.http.createServer = function (requestListener, options) { exports.createServer = function (requestListener, options) {
var server = new node.http.Server(); var server = new node.http.Server();
//server.setOptions(options); //server.setOptions(options);
server.addListener("request", requestListener); server.addListener("request", requestListener);
@ -459,7 +460,7 @@ function connectionListener (connection) {
} }
node.http.createClient = function (port, host) { exports.createClient = function (port, host) {
var client = new node.http.Client(); var client = new node.http.Client();
var requests = []; var requests = [];
@ -467,11 +468,11 @@ node.http.createClient = function (port, host) {
client._pushRequest = function (req) { client._pushRequest = function (req) {
req.addListener("flush", function () { req.addListener("flush", function () {
if (client.readyState == "closed") { if (client.readyState == "closed") {
//node.debug("HTTP CLIENT request flush. reconnect. readyState = " + client.readyState); //utils.debug("HTTP CLIENT request flush. reconnect. readyState = " + client.readyState);
client.connect(port, host); // reconnect client.connect(port, host); // reconnect
return; return;
} }
//node.debug("client flush readyState = " + client.readyState); //utils.debug("client flush readyState = " + client.readyState);
if (req == requests[0]) flushMessageQueue(client, [req]); if (req == requests[0]) flushMessageQueue(client, [req]);
}); });
requests.push(req); requests.push(req);
@ -482,7 +483,7 @@ node.http.createClient = function (port, host) {
}); });
client.addListener("eof", function () { client.addListener("eof", function () {
//node.debug("client got eof closing. readyState = " + client.readyState); //utils.debug("client got eof closing. readyState = " + client.readyState);
client.close(); client.close();
}); });
@ -492,20 +493,20 @@ node.http.createClient = function (port, host) {
return; return;
} }
//node.debug("HTTP CLIENT onClose. readyState = " + client.readyState); //utils.debug("HTTP CLIENT onClose. readyState = " + client.readyState);
// If there are more requests to handle, reconnect. // If there are more requests to handle, reconnect.
if (requests.length > 0 && client.readyState != "opening") { if (requests.length > 0 && client.readyState != "opening") {
//node.debug("HTTP CLIENT: reconnecting readyState = " + client.readyState); //utils.debug("HTTP CLIENT: reconnecting readyState = " + client.readyState);
client.connect(port, host); // reconnect client.connect(port, host); // reconnect
} }
}); });
createIncomingMessageStream(client, function (res) { createIncomingMessageStream(client, function (res) {
//node.debug("incoming response!"); //utils.debug("incoming response!");
res.addListener("complete", function ( ) { res.addListener("complete", function ( ) {
//node.debug("request complete disconnecting. readyState = " + client.readyState); //utils.debug("request complete disconnecting. readyState = " + client.readyState);
client.close(); client.close();
}); });
@ -547,13 +548,13 @@ node.http.Client.prototype.put = function (uri, headers) {
}; };
node.http.cat = function (url, encoding) { exports.cat = function (url, encoding) {
var promise = new node.Promise(); var promise = new node.Promise();
encoding = encoding || "utf8"; encoding = encoding || "utf8";
var uri = node.http.parseUri(url); var uri = exports.parseUri(url);
var client = node.http.createClient(uri.port || 80, uri.host); var client = exports.createClient(uri.port || 80, uri.host);
var req = client.get(uri.path || "/"); var req = client.get(uri.path || "/");
client.addListener("error", function () { client.addListener("error", function () {
@ -576,5 +577,3 @@ node.http.cat = function (url, encoding) {
return promise; return promise;
}; };
})(); // anonymous namespace

1
src/node.cc

@ -402,7 +402,6 @@ static Local<Object> Load(int argc, char *argv[]) {
ExecuteNativeJS("util.js", native_util); ExecuteNativeJS("util.js", native_util);
ExecuteNativeJS("events.js", native_events); ExecuteNativeJS("events.js", native_events);
ExecuteNativeJS("http.js", native_http);
ExecuteNativeJS("file.js", native_file); ExecuteNativeJS("file.js", native_file);
ExecuteNativeJS("node.js", native_node); ExecuteNativeJS("node.js", native_node);

8
src/node.js

@ -19,6 +19,14 @@ node.exec = function () {
throw new Error("node.exec() has moved. Use include('/utils.js') to bring it back."); throw new Error("node.exec() has moved. Use include('/utils.js') to bring it back.");
} }
node.http.createServer = function () {
throw new Error("node.http.createServer() has moved. Use require('/http.js') to access it.");
}
node.http.createClient = function () {
throw new Error("node.http.createClient() has moved. Use require('/http.js') to access it.");
}
node.tcp.createConnection = function (port, host) { node.tcp.createConnection = function (port, host) {
var connection = new node.tcp.Connection(); var connection = new node.tcp.Connection();
connection.connect(port, host); connection.connect(port, host);

8
src/util.js

@ -25,8 +25,12 @@ node.assert = function (x, msg) {
node.cat = function(location, encoding) { node.cat = function(location, encoding) {
var url_re = new RegExp("^http:\/\/"); var url_re = new RegExp("^http:\/\/");
var f = url_re.exec(location) ? node.http.cat : node.fs.cat; if (url_re.exec(location)) {
return f(location, encoding); throw new Error("node.cat for http urls is temporarally disabled.");
}
//var f = url_re.exec(location) ? node.http.cat : node.fs.cat;
//return f(location, encoding);
return node.fs.cat(location, encoding);
}; };
node.path = new function () { node.path = new function () {

3
test/mjsunit/test-node-cat.js → test/mjsunit/disabled/test-cat.js

@ -1,10 +1,11 @@
include("common.js"); include("common.js");
http = require("/http.js");
PORT = 8888; PORT = 8888;
puts("hello world"); puts("hello world");
var body = "exports.A = function() { return 'A';}"; var body = "exports.A = function() { return 'A';}";
var server = node.http.createServer(function (req, res) { var server = http.createServer(function (req, res) {
puts("req?"); puts("req?");
res.sendHeader(200, { res.sendHeader(200, {
"Content-Length": body.length, "Content-Length": body.length,

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

@ -1,8 +1,9 @@
include("common.js"); include("common.js");
http = require("/http.js");
PORT = 8888; PORT = 8888;
var body = "exports.A = function() { return 'A';}"; var body = "exports.A = function() { return 'A';}";
var server = node.http.createServer(function (req, res) { var server = http.createServer(function (req, res) {
puts("got request"); puts("got request");
res.sendHeader(200, [ res.sendHeader(200, [
["Content-Length", body.length], ["Content-Length", body.length],
@ -16,19 +17,20 @@ server.listen(PORT);
var got_good_server_content = false; var got_good_server_content = false;
var bad_server_got_error = false; var bad_server_got_error = false;
node.http.cat("http://localhost:"+PORT+"/", "utf8").addCallback(function (content) { http.cat("http://localhost:"+PORT+"/", "utf8").addCallback(function (content) {
puts("got response"); puts("got response");
got_good_server_content = true; got_good_server_content = true;
assertEquals(body, content); assertEquals(body, content);
server.close(); server.close();
}); });
node.http.cat("http://localhost:12312/", "utf8").addErrback(function () { http.cat("http://localhost:12312/", "utf8").addErrback(function () {
puts("got error (this should happen)"); puts("got error (this should happen)");
bad_server_got_error = true; bad_server_got_error = true;
}); });
process.addListener("exit", function () { process.addListener("exit", function () {
puts("exit");
assertTrue(got_good_server_content); assertTrue(got_good_server_content);
assertTrue(bad_server_got_error); assertTrue(bad_server_got_error);
}); });

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

@ -1,10 +1,11 @@
include("common.js"); include("common.js");
http = require("/http.js");
PORT = 8888; PORT = 8888;
var body1_s = "1111111111111111"; var body1_s = "1111111111111111";
var body2_s = "22222"; var body2_s = "22222";
var server = node.http.createServer(function (req, res) { var server = http.createServer(function (req, res) {
var body = req.uri.path === "/1" ? body1_s : body2_s; var body = req.uri.path === "/1" ? body1_s : body2_s;
res.sendHeader(200, { "Content-Type": "text/plain" res.sendHeader(200, { "Content-Type": "text/plain"
, "Content-Length": body.length , "Content-Length": body.length
@ -14,7 +15,7 @@ var server = node.http.createServer(function (req, res) {
}); });
server.listen(PORT); server.listen(PORT);
var client = node.http.createClient(PORT); var client = http.createClient(PORT);
var body1 = ""; var body1 = "";
var body2 = ""; var body2 = "";

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

@ -1,11 +1,12 @@
include("common.js"); include("common.js");
http = require("/http.js");
var PORT = 18032; var PORT = 18032;
var sent_body = ""; var sent_body = "";
var server_req_complete = false; var server_req_complete = false;
var client_res_complete = false; var client_res_complete = false;
var server = node.http.createServer(function(req, res) { var server = http.createServer(function(req, res) {
assertEquals("POST", req.method); assertEquals("POST", req.method);
req.setBodyEncoding("utf8"); req.setBodyEncoding("utf8");
@ -24,7 +25,7 @@ var server = node.http.createServer(function(req, res) {
}); });
server.listen(PORT); server.listen(PORT);
var client = node.http.createClient(PORT); var client = http.createClient(PORT);
var req = client.post('/'); var req = client.post('/');
req.sendBody('1\n'); req.sendBody('1\n');

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

@ -1,4 +1,5 @@
include("common.js"); include("common.js");
http = require("/http.js");
// Make sure no exceptions are thrown when receiving malformed HTTP // Make sure no exceptions are thrown when receiving malformed HTTP
// requests. // requests.
@ -7,7 +8,7 @@ port = 9999;
nrequests_completed = 0; nrequests_completed = 0;
nrequests_expected = 1; nrequests_expected = 1;
var s = node.http.createServer(function (req, res) { var s = http.createServer(function (req, res) {
puts("req: " + JSON.stringify(req.uri)); puts("req: " + JSON.stringify(req.uri));
res.sendHeader(200, {"Content-Type": "text/plain"}); res.sendHeader(200, {"Content-Type": "text/plain"});

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

@ -1,9 +1,10 @@
include("common.js"); include("common.js");
http = require("/http.js");
var PROXY_PORT = 8869; var PROXY_PORT = 8869;
var BACKEND_PORT = 8870; var BACKEND_PORT = 8870;
var backend = node.http.createServer(function (req, res) { var backend = http.createServer(function (req, res) {
// debug("backend"); // debug("backend");
res.sendHeader(200, {"content-type": "text/plain"}); res.sendHeader(200, {"content-type": "text/plain"});
res.sendBody("hello world\n"); res.sendBody("hello world\n");
@ -12,8 +13,8 @@ var backend = node.http.createServer(function (req, res) {
// debug("listen backend") // debug("listen backend")
backend.listen(BACKEND_PORT); backend.listen(BACKEND_PORT);
var proxy_client = node.http.createClient(BACKEND_PORT); var proxy_client = http.createClient(BACKEND_PORT);
var proxy = node.http.createServer(function (req, res) { var proxy = http.createServer(function (req, res) {
debug("proxy req headers: " + JSON.stringify(req.headers)); debug("proxy req headers: " + JSON.stringify(req.headers));
var proxy_req = proxy_client.get(req.uri.path); var proxy_req = proxy_client.get(req.uri.path);
proxy_req.finish(function(proxy_res) { proxy_req.finish(function(proxy_res) {
@ -32,7 +33,7 @@ proxy.listen(PROXY_PORT);
var body = ""; var body = "";
var client = node.http.createClient(PROXY_PORT); var client = http.createClient(PROXY_PORT);
var req = client.get("/test"); var req = client.get("/test");
// debug("client req") // debug("client req")
req.finish(function (res) { req.finish(function (res) {

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

@ -1,4 +1,5 @@
include("common.js"); include("common.js");
http = require("/http.js");
var port = 8222; var port = 8222;
@ -7,7 +8,7 @@ var requests_sent = 0;
var server_response = ""; var server_response = "";
var client_got_eof = false; var client_got_eof = false;
node.http.createServer(function (req, res) { http.createServer(function (req, res) {
res.id = request_number; res.id = request_number;
req.id = request_number++; req.id = request_number++;

5
test/mjsunit/test-http.js

@ -1,4 +1,5 @@
include("common.js"); include("common.js");
http = require("/http.js");
PORT = 8888; PORT = 8888;
var responses_sent = 0; var responses_sent = 0;
@ -6,7 +7,7 @@ var responses_recvd = 0;
var body0 = ""; var body0 = "";
var body1 = ""; var body1 = "";
node.http.createServer(function (req, res) { http.createServer(function (req, res) {
if (responses_sent == 0) { if (responses_sent == 0) {
assertEquals("GET", req.method); assertEquals("GET", req.method);
assertEquals("/hello", req.uri.path); assertEquals("/hello", req.uri.path);
@ -35,7 +36,7 @@ node.http.createServer(function (req, res) {
//assertEquals("127.0.0.1", res.connection.remoteAddress); //assertEquals("127.0.0.1", res.connection.remoteAddress);
}).listen(PORT); }).listen(PORT);
var client = node.http.createClient(PORT); var client = http.createClient(PORT);
var req = client.get("/hello", {"Accept": "*/*", "Foo": "bar"}); var req = client.get("/hello", {"Accept": "*/*", "Foo": "bar"});
req.finish(function (res) { req.finish(function (res) {
assertEquals(200, res.statusCode); assertEquals(200, res.statusCode);

3
test/mjsunit/test-multipart.js

@ -1,4 +1,5 @@
include("common.js"); include("common.js");
http = require("/http.js");
var multipart = require('/multipart.js'); var multipart = require('/multipart.js');
var port = 8222; var port = 8222;
@ -6,7 +7,7 @@ var parts_reveived = 0;
var parts_complete = 0; var parts_complete = 0;
var parts = {}; var parts = {};
var server = node.http.createServer(function(req, res) { var server = http.createServer(function(req, res) {
var stream = new multipart.Stream(req); var stream = new multipart.Stream(req);
stream.addListener('part', function(part) { stream.addListener('part', function(part) {

1
wscript

@ -241,7 +241,6 @@ def build(bld):
source = """ source = """
src/util.js src/util.js
src/events.js src/events.js
src/http.js
src/file.js src/file.js
src/node.js src/node.js
""", """,

Loading…
Cancel
Save