|
|
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
|
|
|
|
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
|
|
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
|
|
|
<head>
|
|
|
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
|
|
|
<meta name="generator" content="AsciiDoc 8.4.5" />
|
|
|
|
<title>NODE(1)</title>
|
|
|
|
<link rel="stylesheet" href="./pipe.css" type="text/css" />
|
|
|
|
<link rel="stylesheet" href="./pipe-quirks.css" type="text/css" />
|
|
|
|
<script type="text/javascript">
|
|
|
|
/*<![CDATA[*/
|
|
|
|
window.onload = function(){generateToc(2)}
|
|
|
|
/*]]>*/
|
|
|
|
</script>
|
|
|
|
<script type="text/javascript" src="./toc.js"></script>
|
|
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<div id="header">
|
|
|
|
<h1>NODE(1)</h1>
|
|
|
|
<span id="author">Ryan Dahl</span><br />
|
|
|
|
<span id="email"><tt><<a href="mailto:ry@tinyclouds.org">ry@tinyclouds.org</a>></tt></span><br />
|
|
|
|
<span id="revnumber">version 0.1.10,</span>
|
|
|
|
<span id="revdate">2009.09.11</span>
|
|
|
|
<div id="toc">
|
|
|
|
<div id="toctitle">Table of Contents</div>
|
|
|
|
<noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<h2 id="_name">NAME</h2>
|
|
|
|
<div class="sectionbody">
|
|
|
|
<div class="paragraph"><p>node - evented I/O for V8 javascript</p></div>
|
|
|
|
</div>
|
|
|
|
<h2 id="_synopsis">SYNOPSIS</h2>
|
|
|
|
<div class="sectionbody">
|
|
|
|
<div class="paragraph"><p>An example of a web server written with Node which responds with "Hello
|
|
|
|
World" after waiting two seconds:</p></div>
|
|
|
|
<div class="listingblock">
|
|
|
|
<div class="content">
|
|
|
|
<pre><tt>node.http.createServer(function (request, response) {
|
|
|
|
setTimeout(function () {
|
|
|
|
response.sendHeader(200, {"Content-Type": "text/plain"});
|
|
|
|
response.sendBody("Hello World");
|
|
|
|
response.finish();
|
|
|
|
}, 2000);
|
|
|
|
}).listen(8000);
|
|
|
|
puts("Server running at http://127.0.0.1:8000/");</tt></pre>
|
|
|
|
</div></div>
|
|
|
|
<div class="paragraph"><p>To run the server, put the code into a file called <tt>example.js</tt> and execute
|
|
|
|
it with the node program</p></div>
|
|
|
|
<div class="listingblock">
|
|
|
|
<div class="content">
|
|
|
|
<pre><tt>> node example.js
|
|
|
|
Server running at http://127.0.0.1:8000/</tt></pre>
|
|
|
|
</div></div>
|
|
|
|
</div>
|
|
|
|
<h2 id="_api">API</h2>
|
|
|
|
<div class="sectionbody">
|
|
|
|
<div class="paragraph"><p>Node supports 4 byte-string encodings. ASCII (<tt>"ascii"</tt>), UTF-8 (<tt>"utf8"</tt>)
|
|
|
|
both use the string object, obviously. Then two "raw binary" encodings - one
|
|
|
|
uses an array of integers (<tt>"raw"</tt>) and the other uses a string (<tt>"raws"</tt>).
|
|
|
|
Neither raw encodings are perfect and their implementations are rather
|
|
|
|
inefficient. Hopefully the raw encoding situation will improve in the
|
|
|
|
future.</p></div>
|
|
|
|
<div class="paragraph"><p>Unless otherwise noted, functions are all asynchronous and do not block
|
|
|
|
execution.</p></div>
|
|
|
|
<h3 id="_helpers">Helpers</h3><div style="clear:left"></div>
|
|
|
|
<div class="dlist"><dl>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>puts(string)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Outputs the <tt>string</tt> and a trailing new-line to <tt>stdout</tt>.
|
|
|
|
</p>
|
|
|
|
<div class="paragraph"><p>Everything in node is asynchronous; <tt>puts()</tt> is no exception. This might
|
|
|
|
seem ridiculous but, if for example, one is piping <tt>stdout</tt> into an NFS
|
|
|
|
file, <tt>printf()</tt> will block from network latency. There is an internal
|
|
|
|
queue for <tt>puts()</tt> output, so you can be assured that output will be
|
|
|
|
displayed in the order it was called.</p></div>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>node.debug(string)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
A synchronous output function. Will block the process and
|
|
|
|
output the string immediately to stdout.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>p(object)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Print the JSON representation of <tt>object</tt> to the standard output.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>print(string)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Like <tt>puts()</tt> but without the trailing new-line.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>node.exit(code)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Immediately ends the process with the specified code.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>node.cwd()</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Returns the current working directory of the process.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
</dl></div>
|
|
|
|
<h3 id="_global_variables">Global Variables</h3><div style="clear:left"></div>
|
|
|
|
<div class="dlist"><dl>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>ARGV</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
An array containing the command line arguments.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>ENV</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
An object containing the user environment. See environ(7).
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>__filename</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
The filename of the script being executed.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>process</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
A special global object. The <tt>process</tt> object is like the <tt>window</tt> object of
|
|
|
|
browser-side javascript.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
</dl></div>
|
|
|
|
<h3 id="_events">Events</h3><div style="clear:left"></div>
|
|
|
|
<div class="paragraph"><p>Many objects in Node emit events: a TCP server emits an event each time
|
|
|
|
there is a connection, a child process emits an event when it exits. All
|
|
|
|
objects which emit events are are instances of <tt>node.EventEmitter</tt>.</p></div>
|
|
|
|
<div class="paragraph"><p>Events are represented by a snakecased string. Here are some examples:
|
|
|
|
<tt>"connection"</tt>, <tt>"receive"</tt>, <tt>"message_begin"</tt>.</p></div>
|
|
|
|
<div class="paragraph"><p>Functions can be then be attached to objects, to be executed when an event
|
|
|
|
is emitted. These functions are called <em>listeners</em>.</p></div>
|
|
|
|
<div class="paragraph"><p>Some asynchronous file operations return an <tt>EventEmitter</tt> called a
|
|
|
|
<em>promise</em>. A promise emits just a single event when the operation is
|
|
|
|
complete.</p></div>
|
|
|
|
<h4 id="_tt_node_eventemitter_tt"><tt>node.EventEmitter</tt></h4>
|
|
|
|
<div class="paragraph"><p>All EventEmitters emit the event <tt>"newListener"</tt> when new listeners are
|
|
|
|
added.</p></div>
|
|
|
|
<div class="tableblock">
|
|
|
|
<table rules="all"
|
|
|
|
width="100%"
|
|
|
|
frame="border"
|
|
|
|
cellspacing="0" cellpadding="4">
|
|
|
|
<col width="7%" />
|
|
|
|
<col width="15%" />
|
|
|
|
<col width="76%" />
|
|
|
|
<thead>
|
|
|
|
<tr>
|
|
|
|
<th align="left" valign="top"> Event </th>
|
|
|
|
<th align="left" valign="top"> Parameters </th>
|
|
|
|
<th align="left" valign="top"> Notes</th>
|
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
|
|
|
<tr>
|
|
|
|
<td align="left" valign="top"><p class="table"><tt>"newListener"</tt></p></td>
|
|
|
|
<td align="left" valign="top"><p class="table"><tt>event, listener</tt></p></td>
|
|
|
|
<td align="left" valign="top"><p class="table">This event is made
|
|
|
|
any time someone adds
|
|
|
|
a new listener.</p></td>
|
|
|
|
</tr>
|
|
|
|
</tbody>
|
|
|
|
</table>
|
|
|
|
</div>
|
|
|
|
<div class="dlist"><dl>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>emitter.addListener(event, listener)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Adds a listener to the end of the listeners array for the specified event.
|
|
|
|
</p>
|
|
|
|
<div class="listingblock">
|
|
|
|
<div class="content">
|
|
|
|
<pre><tt>server.addListener("connection", function (socket) {
|
|
|
|
puts("someone connected!");
|
|
|
|
});</tt></pre>
|
|
|
|
</div></div>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>emitter.listeners(event)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Returns an array of listeners for the specified event. This array can be
|
|
|
|
manipulated, e.g. to remove listeners.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>emitter.emit(event, arg1, arg2, …)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Execute each of the listeners in order with the supplied arguments.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
</dl></div>
|
|
|
|
<h4 id="_tt_node_promise_tt"><tt>node.Promise</tt></h4>
|
|
|
|
<div class="paragraph"><p><tt>node.Promise</tt> inherits from <tt>node.eventEmitter</tt>. A promise emits one of two
|
|
|
|
events: <tt>"success"</tt> or <tt>"error"</tt>. After emitting its event, it will not
|
|
|
|
emit anymore events.</p></div>
|
|
|
|
<div class="tableblock">
|
|
|
|
<table rules="all"
|
|
|
|
width="100%"
|
|
|
|
frame="border"
|
|
|
|
cellspacing="0" cellpadding="4">
|
|
|
|
<col width="7%" />
|
|
|
|
<col width="15%" />
|
|
|
|
<col width="76%" />
|
|
|
|
<thead>
|
|
|
|
<tr>
|
|
|
|
<th align="left" valign="top"> Event </th>
|
|
|
|
<th align="left" valign="top"> Parameters </th>
|
|
|
|
<th align="left" valign="top"> Notes</th>
|
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
|
|
|
<tr>
|
|
|
|
<td align="left" valign="top"><p class="table"><tt>"success"</tt></p></td>
|
|
|
|
<td align="left" valign="top"><p class="table">(depends)</p></td>
|
|
|
|
<td align="left" valign="top"><p class="table"></p></td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td align="left" valign="top"><p class="table"><tt>"error"</tt></p></td>
|
|
|
|
<td align="left" valign="top"><p class="table">(depends)</p></td>
|
|
|
|
<td align="left" valign="top"><p class="table"></p></td>
|
|
|
|
</tr>
|
|
|
|
</tbody>
|
|
|
|
</table>
|
|
|
|
</div>
|
|
|
|
<div class="dlist"><dl>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>promise.addCallback(listener)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Adds a listener for the <tt>"success"</tt> event. Returns the same promise object.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>promise.addErrback(listener)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Adds a listener for the <tt>"error"</tt> event. Returns the same promise object.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>promise.wait()</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Blocks futher execution until the promise emits a success or error event.
|
|
|
|
Events setup before the call to <tt>promise.wait()</tt> was made may still be
|
|
|
|
emitted and executed while <tt>promise.wait()</tt> is blocking.
|
|
|
|
</p>
|
|
|
|
<div class="paragraph"><p>If there was a single argument to the <tt>"success"</tt> event then it is returned.
|
|
|
|
If there were multiple arguments to <tt>"success"</tt> then they are returned as an
|
|
|
|
array.</p></div>
|
|
|
|
<div class="paragraph"><p>If <tt>"error"</tt> was emitted instead, <tt>wait()</tt> throws an error.</p></div>
|
|
|
|
<div class="paragraph"><p><strong>IMPORTANT</strong> <tt>promise.wait()</tt> is not a true fiber/coroutine. If any other
|
|
|
|
promises are created and made to wait while the first promise waits, the
|
|
|
|
first promise’s wait will not return until all others return. The benefit of
|
|
|
|
this is a simple implementation and the event loop does not get blocked.
|
|
|
|
Disadvantage is the possibility of situations where the promise stack grows
|
|
|
|
infinitely large because promises keep getting created and keep being told
|
|
|
|
to wait(). Use <tt>promise.wait()</tt> sparingly—probably best used only during
|
|
|
|
program setup, not during busy server activity.</p></div>
|
|
|
|
</dd>
|
|
|
|
</dl></div>
|
|
|
|
<h3 id="_standard_i_o">Standard I/O</h3><div style="clear:left"></div>
|
|
|
|
<div class="paragraph"><p>Standard I/O is handled through a special object <tt>node.stdio</tt>. stdout and
|
|
|
|
stdin are fully non-blocking (even when piping to files). stderr is
|
|
|
|
synchronous.</p></div>
|
|
|
|
<div class="tableblock">
|
|
|
|
<table rules="all"
|
|
|
|
width="100%"
|
|
|
|
frame="border"
|
|
|
|
cellspacing="0" cellpadding="4">
|
|
|
|
<col width="7%" />
|
|
|
|
<col width="15%" />
|
|
|
|
<col width="76%" />
|
|
|
|
<thead>
|
|
|
|
<tr>
|
|
|
|
<th align="left" valign="top"> Event </th>
|
|
|
|
<th align="left" valign="top"> Parameters </th>
|
|
|
|
<th align="left" valign="top"> Notes</th>
|
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
|
|
|
<tr>
|
|
|
|
<td align="left" valign="top"><p class="table"><tt>"data"</tt></p></td>
|
|
|
|
<td align="left" valign="top"><p class="table"><tt>data</tt></p></td>
|
|
|
|
<td align="left" valign="top"><p class="table">Made when stdin has received a chunk of data.
|
|
|
|
Depending on the encoding that stdin was opened
|
|
|
|
with, <tt>data</tt> will be either an array of integers
|
|
|
|
(raw encoding) or a string (ascii or utf8
|
|
|
|
encoding). This event will only be emited after
|
|
|
|
<tt>node.stdio.open()</tt> has been called.</p></td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td align="left" valign="top"><p class="table"><tt>"close"</tt></p></td>
|
|
|
|
<td align="left" valign="top"><p class="table"></p></td>
|
|
|
|
<td align="left" valign="top"><p class="table">Made when stdin has been closed.</p></td>
|
|
|
|
</tr>
|
|
|
|
</tbody>
|
|
|
|
</table>
|
|
|
|
</div>
|
|
|
|
<div class="dlist"><dl>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>node.stdio.open(encoding="utf8")</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Open stdin. The program will not exit until <tt>node.stdio.close()</tt> has been
|
|
|
|
called or the <tt>"close"</tt> event has been emitted.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>node.stdio.write(data)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Write data to stdout.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>node.stdio.writeError(data)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Write data to stderr. Synchronous.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>node.stdio.close()</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Close stdin.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
</dl></div>
|
|
|
|
<h3 id="_modules">Modules</h3><div style="clear:left"></div>
|
|
|
|
<div class="paragraph"><p>Node has a simple module loading system. In Node, files and modules are in
|
|
|
|
one-to-one correspondence. As an example, <tt>foo.js</tt> loads the module
|
|
|
|
<tt>circle.js</tt>.</p></div>
|
|
|
|
<div class="paragraph"><p>The contents of <tt>foo.js</tt>:</p></div>
|
|
|
|
<div class="listingblock">
|
|
|
|
<div class="content">
|
|
|
|
<pre><tt>var circle = require("circle.js");
|
|
|
|
puts("The area of a circle of radius 4 is " + circle.area(4));</tt></pre>
|
|
|
|
</div></div>
|
|
|
|
<div class="paragraph"><p>The contents of <tt>circle.js</tt>:</p></div>
|
|
|
|
<div class="listingblock">
|
|
|
|
<div class="content">
|
|
|
|
<pre><tt>var PI = 3.14;
|
|
|
|
|
|
|
|
exports.area = function (r) {
|
|
|
|
return PI * r * r;
|
|
|
|
};
|
|
|
|
|
|
|
|
exports.circumference = function (r) {
|
|
|
|
return 2 * PI * r;
|
|
|
|
};</tt></pre>
|
|
|
|
</div></div>
|
|
|
|
<div class="paragraph"><p>The module <tt>circle.js</tt> has exported the functions <tt>area()</tt> and
|
|
|
|
<tt>circumference()</tt>. To export an object, add to the special <tt>exports</tt>
|
|
|
|
object. (Alternatively, one can use <tt>this</tt> instead of <tt>exports</tt>.) Variables
|
|
|
|
local to the module will be private. In this example the variable <tt>PI</tt> is
|
|
|
|
private to <tt>circle.js</tt>.</p></div>
|
|
|
|
<div class="paragraph"><p>The module path is relative to the file calling <tt>require()</tt>. That is,
|
|
|
|
<tt>circle.js</tt> must be in the same directory as <tt>foo.js</tt> for <tt>require()</tt> to
|
|
|
|
find it.</p></div>
|
|
|
|
<div class="paragraph"><p>HTTP URLs can also be used to load modules. For example,</p></div>
|
|
|
|
<div class="listingblock">
|
|
|
|
<div class="content">
|
|
|
|
<pre><tt>var circle = require("http://tinyclouds.org/node/circle.js");</tt></pre>
|
|
|
|
</div></div>
|
|
|
|
<div class="paragraph"><p>Like <tt>require()</tt> the function <tt>include()</tt> also loads a module. Instead of
|
|
|
|
returning a namespace object, <tt>include()</tt> will add the module’s exports into
|
|
|
|
the global namespace. For example:</p></div>
|
|
|
|
<div class="listingblock">
|
|
|
|
<div class="content">
|
|
|
|
<pre><tt>include("circle.js");
|
|
|
|
puts("The area of a cirlce of radius 4 is " + area(4));</tt></pre>
|
|
|
|
</div></div>
|
|
|
|
<div class="paragraph"><p>Functions <tt>require_async()</tt> and <tt>include_async()</tt> also exist.</p></div>
|
|
|
|
<h4 id="_tt_process_addlistener_exit_function_tt"><tt>process.addListener("exit", function () { })</tt></h4>
|
|
|
|
<div class="paragraph"><p>When the program exits a special object called <tt>process</tt> will emit an
|
|
|
|
<tt>"exit"</tt> event.</p></div>
|
|
|
|
<div class="paragraph"><p>The <tt>"exit"</tt> event cannot perform I/O since the process is going to
|
|
|
|
forcibly exit in less than microsecond. However, it is a good hook to
|
|
|
|
perform constant time checks of the module’s state. E.G. for unit tests:</p></div>
|
|
|
|
<div class="listingblock">
|
|
|
|
<div class="content">
|
|
|
|
<pre><tt>include("asserts.js");
|
|
|
|
|
|
|
|
var timer_executed = false;
|
|
|
|
|
|
|
|
setTimeout(function () {
|
|
|
|
timer_executed = true
|
|
|
|
}, 1000);
|
|
|
|
|
|
|
|
process.addListener("exit", function () {
|
|
|
|
assertTrue(timer_executed);
|
|
|
|
});</tt></pre>
|
|
|
|
</div></div>
|
|
|
|
<div class="paragraph"><p>Just to reiterate: the <tt>"exit"</tt> event, is not the place to close files or
|
|
|
|
shutdown servers. The process will exit before they get performed.</p></div>
|
|
|
|
<h3 id="_timers">Timers</h3><div style="clear:left"></div>
|
|
|
|
<div class="dlist"><dl>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>setTimeout(callback, delay)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
To schedule execution of callback after delay milliseconds. Returns a
|
|
|
|
<tt>timeoutId</tt> for possible use with <tt>clearTimeout()</tt>.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>clearTimeout(timeoutId)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Prevents said timeout from triggering.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>setInterval(callback, delay)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
To schedule the repeated execution of callback every <tt>delay</tt> milliseconds. Returns
|
|
|
|
a <tt>intervalId</tt> for possible use with <tt>clearInterval()</tt>.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>clearInterval(intervalId)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Stops a interval from triggering.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
</dl></div>
|
|
|
|
<h3 id="_child_processes">Child Processes</h3><div style="clear:left"></div>
|
|
|
|
<div class="paragraph"><p>Node provides a tridirectional <tt>popen(3)</tt> facility through the class
|
|
|
|
<tt>node.ChildProcess</tt>. It is possible to stream data through the child’s <tt>stdin</tt>,
|
|
|
|
<tt>stdout</tt>, and <tt>stderr</tt> in a fully non-blocking way.</p></div>
|
|
|
|
<h4 id="_tt_node_childprocess_tt"><tt>node.ChildProcess</tt></h4>
|
|
|
|
<div class="tableblock">
|
|
|
|
<table rules="all"
|
|
|
|
width="100%"
|
|
|
|
frame="border"
|
|
|
|
cellspacing="0" cellpadding="4">
|
|
|
|
<col width="7%" />
|
|
|
|
<col width="15%" />
|
|
|
|
<col width="76%" />
|
|
|
|
<thead>
|
|
|
|
<tr>
|
|
|
|
<th align="left" valign="top">Event </th>
|
|
|
|
<th align="left" valign="top">Parameters </th>
|
|
|
|
<th align="left" valign="top">Notes</th>
|
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
|
|
|
<tr>
|
|
|
|
<td align="left" valign="top"><p class="table"><tt>"output"</tt></p></td>
|
|
|
|
<td align="left" valign="top"><p class="table"><tt>data</tt></p></td>
|
|
|
|
<td align="left" valign="top"><p class="table">Each time the child process sends data to its <tt>stdout</tt>, this event is
|
|
|
|
emitted. <tt>data</tt> is a string.<br />
|
|
|
|
If the child process closes its <tt>stdout</tt> stream (a common thing to do on
|
|
|
|
exit), this event will be emitted with <tt>data === null</tt>.</p></td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td align="left" valign="top"><p class="table"><tt>"error"</tt></p></td>
|
|
|
|
<td align="left" valign="top"><p class="table"><tt>data</tt></p></td>
|
|
|
|
<td align="left" valign="top"><p class="table">Identical to the <tt>"output"</tt> event except for <tt>stderr</tt> instead of <tt>stdout</tt>.</p></td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td align="left" valign="top"><p class="table"><tt>"exit"</tt></p></td>
|
|
|
|
<td align="left" valign="top"><p class="table"><tt>code</tt></p></td>
|
|
|
|
<td align="left" valign="top"><p class="table">This event is emitted after the child process ends. <tt>code</tt> is the final exit
|
|
|
|
code of the process. One can be assured that after this event is emitted
|
|
|
|
that the <tt>"output"</tt> and <tt>"error"</tt> callbacks will no longer be made.</p></td>
|
|
|
|
</tr>
|
|
|
|
</tbody>
|
|
|
|
</table>
|
|
|
|
</div>
|
|
|
|
<div class="dlist"><dl>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>node.createChildProcess(command)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Launches a new process with the given <tt>command</tt>. For example:
|
|
|
|
</p>
|
|
|
|
<div class="listingblock">
|
|
|
|
<div class="content">
|
|
|
|
<pre><tt>var ls = node.createChildProcess("ls -lh /usr");
|
|
|
|
ls.addListener("output", function (data) {
|
|
|
|
puts(data);
|
|
|
|
});</tt></pre>
|
|
|
|
</div></div>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>child.pid</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
The PID of the child process.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>child.write(data, encoding="ascii")</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Write data to the child process’s <tt>stdin</tt>. The second argument is optional and
|
|
|
|
specifies the encoding: possible values are <tt>"utf8"</tt>, <tt>"ascii"</tt>, and <tt>"raw"</tt>.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>child.close()</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Closes the process’s <tt>stdin</tt> stream.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>child.kill(signal=node.SIGTERM)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Send a single to the child process. If no argument is given, the process
|
|
|
|
will be sent <tt>node.SIGTERM</tt>. The standard POSIX signals are defined under
|
|
|
|
the <tt>node</tt> namespace (<tt>node.SIGINT</tt>, <tt>node.SIGUSR1</tt>, …).
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
</dl></div>
|
|
|
|
<h3 id="_file_i_o">File I/O</h3><div style="clear:left"></div>
|
|
|
|
<div class="paragraph"><p>File I/O is provided by simple wrappers around standard POSIX functions.
|
|
|
|
All POSIX wrappers have a similar form.
|
|
|
|
They return a promise (<tt>node.Promise</tt>). Example:</p></div>
|
|
|
|
<div class="listingblock">
|
|
|
|
<div class="content">
|
|
|
|
<pre><tt>var promise = node.fs.unlink("/tmp/hello");
|
|
|
|
promise.addCallback(function () {
|
|
|
|
puts("successfully deleted /tmp/hello");
|
|
|
|
});</tt></pre>
|
|
|
|
</div></div>
|
|
|
|
<div class="paragraph"><p>There is no guaranteed ordering to the POSIX wrappers. The
|
|
|
|
following is very much prone to error</p></div>
|
|
|
|
<div class="listingblock">
|
|
|
|
<div class="content">
|
|
|
|
<pre><tt>node.fs.rename("/tmp/hello", "/tmp/world");
|
|
|
|
node.fs.stat("/tmp/world").addCallback(function (stats) {
|
|
|
|
puts("stats: " + JSON.stringify(stats));
|
|
|
|
});</tt></pre>
|
|
|
|
</div></div>
|
|
|
|
<div class="paragraph"><p>It could be that <tt>stat()</tt> is executed before the <tt>rename()</tt>.
|
|
|
|
The correct way to do this is to chain the promises.</p></div>
|
|
|
|
<div class="listingblock">
|
|
|
|
<div class="content">
|
|
|
|
<pre><tt>node.fs.rename("/tmp/hello", "/tmp/world").addCallback(function () {
|
|
|
|
node.fs.stat("/tmp/world").addCallback(function (stats) {
|
|
|
|
puts("stats: " + JSON.stringify(stats));
|
|
|
|
});
|
|
|
|
});</tt></pre>
|
|
|
|
</div></div>
|
|
|
|
<div class="paragraph"><p>Or use the <tt>promise.wait()</tt> functionality:</p></div>
|
|
|
|
<div class="listingblock">
|
|
|
|
<div class="content">
|
|
|
|
<pre><tt>node.fs.rename("/tmp/hello", "/tmp/world").wait();
|
|
|
|
node.fs.stat("/tmp/world").addCallback(function (stats) {
|
|
|
|
puts("stats: " + JSON.stringify(stats));
|
|
|
|
});</tt></pre>
|
|
|
|
</div></div>
|
|
|
|
<div class="dlist"><dl>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>node.fs.rename(path1, path2)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
See rename(2).
|
|
|
|
</p>
|
|
|
|
<div class="ulist"><ul>
|
|
|
|
<li>
|
|
|
|
<p>
|
|
|
|
on success: no parameters.
|
|
|
|
</p>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
<p>
|
|
|
|
on error: no parameters.
|
|
|
|
</p>
|
|
|
|
</li>
|
|
|
|
</ul></div>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>node.fs.stat(path)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
See stat(2).
|
|
|
|
</p>
|
|
|
|
<div class="ulist"><ul>
|
|
|
|
<li>
|
|
|
|
<p>
|
|
|
|
on success: Returns <tt>node.fs.Stats</tt> object. It looks like this:
|
|
|
|
<tt>{ dev: 2049, ino: 305352, mode: 16877, nlink: 12, uid: 1000, gid: 1000,
|
|
|
|
rdev: 0, size: 4096, blksize: 4096, blocks: 8, atime:
|
|
|
|
"2009-06-29T11:11:55Z", mtime: "2009-06-29T11:11:40Z", ctime:
|
|
|
|
"2009-06-29T11:11:40Z" }</tt>
|
|
|
|
See the <tt>node.fs.Stats</tt> section below for more information.
|
|
|
|
</p>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
<p>
|
|
|
|
on error: no parameters.
|
|
|
|
</p>
|
|
|
|
</li>
|
|
|
|
</ul></div>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>node.fs.unlink(path)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
See unlink(2)
|
|
|
|
</p>
|
|
|
|
<div class="ulist"><ul>
|
|
|
|
<li>
|
|
|
|
<p>
|
|
|
|
on success: no parameters.
|
|
|
|
</p>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
<p>
|
|
|
|
on error: no parameters.
|
|
|
|
</p>
|
|
|
|
</li>
|
|
|
|
</ul></div>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>node.fs.rmdir(path)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
See rmdir(2)
|
|
|
|
</p>
|
|
|
|
<div class="ulist"><ul>
|
|
|
|
<li>
|
|
|
|
<p>
|
|
|
|
on success: no parameters.
|
|
|
|
</p>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
<p>
|
|
|
|
on error: no parameters.
|
|
|
|
</p>
|
|
|
|
</li>
|
|
|
|
</ul></div>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>node.fs.mkdir(path, mode)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
See mkdir(2)
|
|
|
|
</p>
|
|
|
|
<div class="ulist"><ul>
|
|
|
|
<li>
|
|
|
|
<p>
|
|
|
|
on success: no parameters.
|
|
|
|
</p>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
<p>
|
|
|
|
on error: no parameters.
|
|
|
|
</p>
|
|
|
|
</li>
|
|
|
|
</ul></div>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>node.fs.readdir(path)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Reads the contents of a directory.
|
|
|
|
</p>
|
|
|
|
<div class="ulist"><ul>
|
|
|
|
<li>
|
|
|
|
<p>
|
|
|
|
on success: One argument, an array containing the names (strings) of the
|
|
|
|
files in the directory (excluding "." and "..").
|
|
|
|
</p>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
<p>
|
|
|
|
on error: no parameters.
|
|
|
|
</p>
|
|
|
|
</li>
|
|
|
|
</ul></div>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>node.fs.close(fd)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
See close(2)
|
|
|
|
</p>
|
|
|
|
<div class="ulist"><ul>
|
|
|
|
<li>
|
|
|
|
<p>
|
|
|
|
on success: no parameters.
|
|
|
|
</p>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
<p>
|
|
|
|
on error: no parameters.
|
|
|
|
</p>
|
|
|
|
</li>
|
|
|
|
</ul></div>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>node.fs.open(path, flags, mode)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
See open(2). The constants like <tt>O_CREAT</tt> are defined at <tt>node.O_CREAT</tt>.
|
|
|
|
</p>
|
|
|
|
<div class="ulist"><ul>
|
|
|
|
<li>
|
|
|
|
<p>
|
|
|
|
on success: <tt>fd</tt> is given as the parameter.
|
|
|
|
</p>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
<p>
|
|
|
|
on error: no parameters.
|
|
|
|
</p>
|
|
|
|
</li>
|
|
|
|
</ul></div>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>node.fs.write(fd, data, position)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Write data to the file specified by <tt>fd</tt>. <tt>data</tt> is either an array of
|
|
|
|
integers (for raw data) or a string for UTF-8 encoded characters.
|
|
|
|
<tt>position</tt> refers to the offset from the beginning of the file where this
|
|
|
|
data should be written. If <tt>position</tt> is <tt>null</tt>, the data will be written at
|
|
|
|
the current position. See pwrite(2).
|
|
|
|
</p>
|
|
|
|
<div class="ulist"><ul>
|
|
|
|
<li>
|
|
|
|
<p>
|
|
|
|
on success: returns an integer <tt>written</tt> which specifies how many <em>bytes</em> were written.
|
|
|
|
</p>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
<p>
|
|
|
|
on error: no parameters.
|
|
|
|
</p>
|
|
|
|
</li>
|
|
|
|
</ul></div>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>node.fs.read(fd, length, position, encoding)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Read data from the file specified by <tt>fd</tt>.
|
|
|
|
</p>
|
|
|
|
<div class="paragraph"><p><tt>length</tt> is an integer specifying the number of
|
|
|
|
bytes to read.</p></div>
|
|
|
|
<div class="paragraph"><p><tt>position</tt> is an integer specifying where to begin
|
|
|
|
reading from in the file.</p></div>
|
|
|
|
<div class="paragraph"><p><tt>encoding</tt> is either <tt>node.UTF8</tt>
|
|
|
|
or <tt>node.RAW</tt>.</p></div>
|
|
|
|
<div class="ulist"><ul>
|
|
|
|
<li>
|
|
|
|
<p>
|
|
|
|
on success: returns <tt>data, bytes_read</tt>, what was read from the file.
|
|
|
|
</p>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
<p>
|
|
|
|
on error: no parameters.
|
|
|
|
</p>
|
|
|
|
</li>
|
|
|
|
</ul></div>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>node.fs.cat(filename, encoding)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Outputs the entire contents of a file. Example:
|
|
|
|
</p>
|
|
|
|
<div class="listingblock">
|
|
|
|
<div class="content">
|
|
|
|
<pre><tt>node.fs.cat("/etc/passwd", "utf8").addCallback(function (content) {
|
|
|
|
puts(content);
|
|
|
|
});</tt></pre>
|
|
|
|
</div></div>
|
|
|
|
<div class="ulist"><ul>
|
|
|
|
<li>
|
|
|
|
<p>
|
|
|
|
on success: returns <tt>data</tt>, what was read from the file.
|
|
|
|
</p>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
<p>
|
|
|
|
on error: no parameters.
|
|
|
|
</p>
|
|
|
|
</li>
|
|
|
|
</ul></div>
|
|
|
|
</dd>
|
|
|
|
</dl></div>
|
|
|
|
<h4 id="_tt_node_fs_stats_tt"><tt>node.fs.Stats</tt></h4>
|
|
|
|
<div class="paragraph"><p>Objects returned from <tt>node.fs.stat()</tt> are of this type.</p></div>
|
|
|
|
<div class="dlist"><dl>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>stats.isFile()</tt>
|
|
|
|
</dt>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>stats.isDirectory()</tt>
|
|
|
|
</dt>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>stats.isBlockDevice()</tt>
|
|
|
|
</dt>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>stats.isCharacterDevice()</tt>
|
|
|
|
</dt>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>stats.isSymbolicLink()</tt>
|
|
|
|
</dt>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>stats.isFIFO()</tt>
|
|
|
|
</dt>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>stats.isSocket()</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
…
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
</dl></div>
|
|
|
|
<h3 id="_http">HTTP</h3><div style="clear:left"></div>
|
|
|
|
<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.
|
|
|
|
In particular, large, possibly chunk-encoded, messages. The interface is
|
|
|
|
careful to never buffer entire requests or responses—the
|
|
|
|
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="listingblock">
|
|
|
|
<div class="content">
|
|
|
|
<pre><tt> { "Content-Length": "123"
|
|
|
|
, "Content-Type": "text/plain"
|
|
|
|
, "Connection": "keep-alive"
|
|
|
|
, "Accept": "*/*"
|
|
|
|
}</tt></pre>
|
|
|
|
</div></div>
|
|
|
|
<div class="paragraph"><p>In order to support the full spectrum of possible HTTP applications, Node’s
|
|
|
|
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. <em>This is left to the user.</em></p></div>
|
|
|
|
<h4 id="_tt_node_http_server_tt"><tt>node.http.Server</tt></h4>
|
|
|
|
<div class="tableblock">
|
|
|
|
<table rules="all"
|
|
|
|
width="100%"
|
|
|
|
frame="border"
|
|
|
|
cellspacing="0" cellpadding="4">
|
|
|
|
<col width="7%" />
|
|
|
|
<col width="15%" />
|
|
|
|
<col width="76%" />
|
|
|
|
<thead>
|
|
|
|
<tr>
|
|
|
|
<th align="left" valign="top">Event </th>
|
|
|
|
<th align="left" valign="top"> Parameters </th>
|
|
|
|
<th align="left" valign="top"> Notes</th>
|
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
|
|
|
<tr>
|
|
|
|
<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</tt> is an instance of <tt>node.http.ServerRequest</tt><br />
|
|
|
|
<tt>response</tt> is an instance of <tt>node.http.ServerResponse</tt></p></td>
|
|
|
|
</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">When a new TCP connection is established.
|
|
|
|
<tt>connection</tt> is an object of type <tt>node.http.Connection</tt>. Usually users will not
|
|
|
|
want to access this event. The <tt>connection</tt> can also be accessed at
|
|
|
|
<tt>request.connection</tt>.</p></td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td align="left" valign="top"><p class="table"><tt>"close"</tt></p></td>
|
|
|
|
<td align="left" valign="top"><p class="table"><tt>errorno</tt></p></td>
|
|
|
|
<td align="left" valign="top"><p class="table">Emitted when the server closes. <tt>errorno</tt>
|
|
|
|
is an integer which indicates what, if any,
|
|
|
|
error caused the server to close. If no
|
|
|
|
error occured <tt>errorno</tt> will be 0.</p></td>
|
|
|
|
</tr>
|
|
|
|
</tbody>
|
|
|
|
</table>
|
|
|
|
</div>
|
|
|
|
<div class="dlist"><dl>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>node.http.createServer(request_listener, options);</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Returns a new web server object.
|
|
|
|
</p>
|
|
|
|
<div class="paragraph"><p>The <tt>options</tt> argument is optional. The
|
|
|
|
<tt>options</tt> argument accepts the same values as the
|
|
|
|
options argument for <tt>node.tcp.Server</tt> does.</p></div>
|
|
|
|
<div class="paragraph"><p>The <tt>request_listener</tt> is a function which is automatically
|
|
|
|
added to the <tt>"request"</tt> event.</p></div>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>server.listen(port, hostname)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Begin accepting connections on the specified port and hostname.
|
|
|
|
If the hostname is omitted, the server will accept connections
|
|
|
|
directed to any address. This function is synchronous.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>server.close()</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Stops the server from accepting new connections.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
</dl></div>
|
|
|
|
<h4 id="_tt_node_http_serverrequest_tt"><tt>node.http.ServerRequest</tt></h4>
|
|
|
|
<div class="paragraph"><p>This object is created internally by a HTTP server—not by
|
|
|
|
the user—and passed as the first argument to a <tt>"request"</tt> listener.</p></div>
|
|
|
|
<div class="tableblock">
|
|
|
|
<table rules="all"
|
|
|
|
width="100%"
|
|
|
|
frame="border"
|
|
|
|
cellspacing="0" cellpadding="4">
|
|
|
|
<col width="7%" />
|
|
|
|
<col width="15%" />
|
|
|
|
<col width="76%" />
|
|
|
|
<thead>
|
|
|
|
<tr>
|
|
|
|
<th align="left" valign="top">Event </th>
|
|
|
|
<th align="left" valign="top"> Parameters </th>
|
|
|
|
<th align="left" valign="top"> Notes</th>
|
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
|
|
|
<tr>
|
|
|
|
<td align="left" valign="top"><p class="table"><tt>"body"</tt></p></td>
|
|
|
|
<td align="left" valign="top"><p class="table"><tt>chunk</tt></p></td>
|
|
|
|
<td align="left" valign="top"><p class="table">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 is either a String in the case of UTF-8 encoding or
|
|
|
|
an array of numbers in the case of raw encoding. The body encoding is set
|
|
|
|
with <tt>request.setBodyEncoding()</tt>.</p></td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td align="left" valign="top"><p class="table"><tt>"complete"</tt></p></td>
|
|
|
|
<td align="left" valign="top"><p class="table"></p></td>
|
|
|
|
<td align="left" valign="top"><p class="table">Emitted exactly once for each message. No arguments.
|
|
|
|
After emitted no other events will be emitted on the request.</p></td>
|
|
|
|
</tr>
|
|
|
|
</tbody>
|
|
|
|
</table>
|
|
|
|
</div>
|
|
|
|
<div class="dlist"><dl>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>request.method</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
The request method as a string. Read only. Example:
|
|
|
|
<tt>"GET"</tt>, <tt>"DELETE"</tt>.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>request.uri</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Request URI Object. This contains only the parameters that are
|
|
|
|
present in the actual HTTP request. That is, if the request is
|
|
|
|
</p>
|
|
|
|
<div class="listingblock">
|
|
|
|
<div class="content">
|
|
|
|
<pre><tt>GET /status?name=ryan HTTP/1.1\r\n
|
|
|
|
Accept: */*\r\n
|
|
|
|
\r\n</tt></pre>
|
|
|
|
</div></div>
|
|
|
|
<div class="paragraph"><p>Then <tt>request.uri</tt> will be</p></div>
|
|
|
|
<div class="listingblock">
|
|
|
|
<div class="content">
|
|
|
|
<pre><tt>{ path: "/status",
|
|
|
|
file: "status",
|
|
|
|
directory: "/",
|
|
|
|
params: { "name" : "ryan" }
|
|
|
|
}</tt></pre>
|
|
|
|
</div></div>
|
|
|
|
<div class="paragraph"><p>In particular, note that <tt>request.uri.protocol</tt> is
|
|
|
|
<tt>undefined</tt>. This is because there was no URI protocol given
|
|
|
|
in the actual HTTP Request.</p></div>
|
|
|
|
<div class="paragraph"><p><tt>request.uri.anchor</tt>, <tt>request.uri.query</tt>, <tt>request.uri.file</tt>, <tt>request.uri.directory</tt>, <tt>request.uri.path</tt>, <tt>request.uri.relative</tt>, <tt>request.uri.port</tt>, <tt>request.uri.host</tt>, <tt>request.uri.password</tt>, <tt>request.uri.user</tt>, <tt>request.uri.authority</tt>, <tt>request.uri.protocol</tt>, <tt>request.uri.params</tt>, <tt>request.uri.toString()</tt>, <tt>request.uri.source</tt></p></div>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>request.headers</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Read only.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>request.httpVersion</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
The HTTP protocol version as a string. Read only. Examples:
|
|
|
|
<tt>"1.1"</tt>, <tt>"1.0"</tt>
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>request.setBodyEncoding(encoding)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Set the encoding for the request body. Either <tt>"utf8"</tt> or <tt>"raw"</tt>. Defaults
|
|
|
|
to raw.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>request.pause()</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Pauses request from emitting events. Useful to throttle back an upload.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>request.resume()</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Resumes a paused request.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>request.connection</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
The <tt>node.http.Connection</tt> object.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
</dl></div>
|
|
|
|
<h4 id="_tt_node_http_serverresponse_tt"><tt>node.http.ServerResponse</tt></h4>
|
|
|
|
<div class="paragraph"><p>This object is created internally by a HTTP server—not by the user. It is
|
|
|
|
passed as the second parameter to the <tt>"request"</tt> event.</p></div>
|
|
|
|
<div class="dlist"><dl>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>response.sendHeader(statusCode, headers)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Sends a response header to the request. The status code is a 3-digit HTTP
|
|
|
|
status code, like <tt>404</tt>. The second argument, <tt>headers</tt> are the response headers.
|
|
|
|
</p>
|
|
|
|
<div class="paragraph"><p>Example:</p></div>
|
|
|
|
<div class="listingblock">
|
|
|
|
<div class="content">
|
|
|
|
<pre><tt>var body = "hello world";
|
|
|
|
response.sendHeader(200, {
|
|
|
|
"Content-Length": body.length,
|
|
|
|
"Content-Type": "text/plain"
|
|
|
|
});</tt></pre>
|
|
|
|
</div></div>
|
|
|
|
<div class="paragraph"><p>This method must only be called once on a message and it must
|
|
|
|
be called before <tt>response.finish()</tt> is called.</p></div>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>response.sendBody(chunk, encoding="ascii")</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
This method must be called after <tt>sendHeader</tt> was
|
|
|
|
called. It sends a chunk of the response body. This method may
|
|
|
|
be called multiple times to provide successive parts of the body.
|
|
|
|
</p>
|
|
|
|
<div class="paragraph"><p>If <tt>chunk</tt> is a string, the second parameter
|
|
|
|
specifies how to encode it into a byte stream. By default the
|
|
|
|
<tt>encoding</tt> is <tt>"ascii"</tt>.</p></div>
|
|
|
|
<div class="paragraph"><p>Note: This is the raw HTTP body and has nothing to do with
|
|
|
|
higher-level multi-part body encodings that may be used.</p></div>
|
|
|
|
<div class="paragraph"><p>The first time <tt>sendBody</tt> is called, it will send the buffered header
|
|
|
|
information and the first body to the client. The second time
|
|
|
|
<tt>sendBody</tt> 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.</p></div>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>response.finish()</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
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, <tt>response.finish()</tt>, MUST be called on each
|
|
|
|
response.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
</dl></div>
|
|
|
|
<h4 id="_tt_node_http_client_tt"><tt>node.http.Client</tt></h4>
|
|
|
|
<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
|
|
|
|
requests. Depending on the server connected to, the client might
|
|
|
|
pipeline the requests or reestablish the connection after each
|
|
|
|
connection. <em>Currently the implementation does not pipeline requests.</em></p></div>
|
|
|
|
<div class="paragraph"><p>Example of connecting to <tt>google.com</tt></p></div>
|
|
|
|
<div class="listingblock">
|
|
|
|
<div class="content">
|
|
|
|
<pre><tt>var google = node.http.createClient(80, "google.com");
|
|
|
|
var request = google.get("/");
|
|
|
|
request.finish(function (response) {
|
|
|
|
puts("STATUS: " + response.statusCode);
|
|
|
|
puts("HEADERS: " + JSON.stringify(response.headers));
|
|
|
|
response.setBodyEncoding("utf8");
|
|
|
|
response.addListener("body", function (chunk) {
|
|
|
|
puts("BODY: " + chunk);
|
|
|
|
});
|
|
|
|
});</tt></pre>
|
|
|
|
</div></div>
|
|
|
|
<div class="dlist"><dl>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>node.http.createClient(port, host)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Constructs a new HTTP client. <tt>port</tt> and
|
|
|
|
<tt>host</tt> refer to the server to be connected to. A
|
|
|
|
connection is not established until a request is issued.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>client.get(path, request_headers)</tt>, <tt>client.head(path, request_headers)</tt>, <tt>client.post(path, request_headers)</tt>, <tt>client.del(path, request_headers)</tt>, <tt>client.put(path, request_headers)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Issues a request; if necessary establishes connection. Returns a <tt>node.http.ClientRequest</tt> instance.
|
|
|
|
</p>
|
|
|
|
<div class="paragraph"><p><tt>request_headers</tt> is optional.
|
|
|
|
Additional request headers might be added internally
|
|
|
|
by Node. Returns a <tt>ClientRequest</tt> object.</p></div>
|
|
|
|
<div class="paragraph"><p>Do remember to include the <tt>Content-Length</tt> header if you
|
|
|
|
plan on sending a body. If you plan on streaming the body, perhaps
|
|
|
|
set <tt>Transfer-Encoding: chunked</tt>.</p></div>
|
|
|
|
<div class="admonitionblock">
|
|
|
|
<table><tr>
|
|
|
|
<td class="icon">
|
|
|
|
<div class="title">Note</div>
|
|
|
|
</td>
|
|
|
|
<td class="content">the request is not complete. This method only sends
|
|
|
|
the header of the request. One needs to call
|
|
|
|
<tt>request.finish()</tt> 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
|
|
|
|
<tt>request.sendBody()</tt>.)</td>
|
|
|
|
</tr></table>
|
|
|
|
</div>
|
|
|
|
</dd>
|
|
|
|
</dl></div>
|
|
|
|
<h4 id="_tt_node_http_clientrequest_tt"><tt>node.http.ClientRequest</tt></h4>
|
|
|
|
<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
|
|
|
|
already been sent.</p></div>
|
|
|
|
<div class="tableblock">
|
|
|
|
<table rules="all"
|
|
|
|
width="100%"
|
|
|
|
frame="border"
|
|
|
|
cellspacing="0" cellpadding="4">
|
|
|
|
<col width="7%" />
|
|
|
|
<col width="15%" />
|
|
|
|
<col width="76%" />
|
|
|
|
<thead>
|
|
|
|
<tr>
|
|
|
|
<th align="left" valign="top">Event </th>
|
|
|
|
<th align="left" valign="top"> Parameters </th>
|
|
|
|
<th align="left" valign="top"> Notes</th>
|
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
|
|
|
<tr>
|
|
|
|
<td align="left" valign="top"><p class="table"><tt>"response"</tt></p></td>
|
|
|
|
<td align="left" valign="top"><p class="table"><tt>response</tt></p></td>
|
|
|
|
<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 />
|
|
|
|
This event is emitted only once.<br />
|
|
|
|
The <tt>response</tt> argument will be an instance of <tt>node.http.ClientResponse</tt>.</p></td>
|
|
|
|
</tr>
|
|
|
|
</tbody>
|
|
|
|
</table>
|
|
|
|
</div>
|
|
|
|
<div class="dlist"><dl>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>request.sendBody(chunk, encoding="ascii")</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Sends a chunk of the body. By calling this method
|
|
|
|
many times, the user can stream a request body to a
|
|
|
|
server—in that case it is suggested to use the
|
|
|
|
<tt>["Transfer-Encoding", "chunked"]</tt> header line when
|
|
|
|
creating the request.
|
|
|
|
</p>
|
|
|
|
<div class="paragraph"><p>The <tt>chunk</tt> argument should be an array of integers
|
|
|
|
or a string.</p></div>
|
|
|
|
<div class="paragraph"><p>The <tt>encoding</tt> argument is optional and only
|
|
|
|
applies when <tt>chunk</tt> is a string. The encoding
|
|
|
|
argument should be either <tt>"utf8"</tt> or
|
|
|
|
<tt>"ascii"</tt>. By default the body uses ASCII encoding,
|
|
|
|
as it is faster.</p></div>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>request.finish(response_listener)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
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 <tt>"0\r\n\r\n"</tt>.
|
|
|
|
</p>
|
|
|
|
<div class="paragraph"><p>The parameter <tt>response_listener</tt> is a callback which
|
|
|
|
will be executed when the response headers have been received.
|
|
|
|
The <tt>response_listener</tt> callback is executed with one
|
|
|
|
argument which is an instance of <tt>node.http.ClientResponse</tt>.</p></div>
|
|
|
|
</dd>
|
|
|
|
</dl></div>
|
|
|
|
<h4 id="_tt_node_http_clientresponse_tt"><tt>node.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="tableblock">
|
|
|
|
<table rules="all"
|
|
|
|
width="100%"
|
|
|
|
frame="border"
|
|
|
|
cellspacing="0" cellpadding="4">
|
|
|
|
<col width="7%" />
|
|
|
|
<col width="15%" />
|
|
|
|
<col width="76%" />
|
|
|
|
<thead>
|
|
|
|
<tr>
|
|
|
|
<th align="left" valign="top">Event </th>
|
|
|
|
<th align="left" valign="top"> Parameters </th>
|
|
|
|
<th align="left" valign="top"> Notes</th>
|
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
|
|
|
<tr>
|
|
|
|
<td align="left" valign="top"><p class="table"><tt>"body"</tt></p></td>
|
|
|
|
<td align="left" valign="top"><p class="table"><tt>chunk</tt></p></td>
|
|
|
|
<td align="left" valign="top"><p class="table">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 is either a String in the case of UTF-8 encoding or
|
|
|
|
an array of numbers in the case of raw encoding. The body encoding is set
|
|
|
|
with <tt>response.setBodyEncoding()</tt>.</p></td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td align="left" valign="top"><p class="table"><tt>"complete"</tt></p></td>
|
|
|
|
<td align="left" valign="top"><p class="table"></p></td>
|
|
|
|
<td align="left" valign="top"><p class="table">Emitted exactly once for each message. No arguments.
|
|
|
|
After emitted no other events will be emitted on the response.</p></td>
|
|
|
|
</tr>
|
|
|
|
</tbody>
|
|
|
|
</table>
|
|
|
|
</div>
|
|
|
|
<div class="dlist"><dl>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>response.statusCode</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
The 3-digit HTTP response status code. E.G. <tt>404</tt>.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>response.httpVersion</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
The HTTP version of the connected-to server. Probably either
|
|
|
|
<tt>"1.1"</tt> or <tt>"1.0"</tt>.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>response.headers</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
The response headers.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>response.setBodyEncoding(encoding)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Set the encoding for the response body. Either <tt>"utf8"</tt> or <tt>"raw"</tt>.
|
|
|
|
Defaults to raw.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>response.pause()</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Pauses response from emitting events. Useful to throttle back a download.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>response.resume()</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Resumes a paused response.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>response.client</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
A reference to the <tt>node.http.Client</tt> that this response belongs to.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
</dl></div>
|
|
|
|
<h3 id="_tcp">TCP</h3><div style="clear:left"></div>
|
|
|
|
<h4 id="_tt_node_tcp_server_tt"><tt>node.tcp.Server</tt></h4>
|
|
|
|
<div class="paragraph"><p>Here is an example of a echo server which listens for connections
|
|
|
|
on port 7000</p></div>
|
|
|
|
<div class="listingblock">
|
|
|
|
<div class="content">
|
|
|
|
<pre><tt>function echo (socket) {
|
|
|
|
socket.setEncoding("utf8");
|
|
|
|
socket.addListener("connect", function () {
|
|
|
|
socket.send("hello\r\n");
|
|
|
|
});
|
|
|
|
socket.addListener("receive", function (data) {
|
|
|
|
socket.send(data);
|
|
|
|
});
|
|
|
|
socket.addListener("eof", function () {
|
|
|
|
socket.send("goodbye\r\n");
|
|
|
|
socket.close();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
var server = node.tcp.createServer(echo);
|
|
|
|
server.listen(7000, "localhost");</tt></pre>
|
|
|
|
</div></div>
|
|
|
|
<div class="tableblock">
|
|
|
|
<table rules="all"
|
|
|
|
width="100%"
|
|
|
|
frame="border"
|
|
|
|
cellspacing="0" cellpadding="4">
|
|
|
|
<col width="7%" />
|
|
|
|
<col width="15%" />
|
|
|
|
<col width="76%" />
|
|
|
|
<thead>
|
|
|
|
<tr>
|
|
|
|
<th align="left" valign="top">Event </th>
|
|
|
|
<th align="left" valign="top"> Parameters </th>
|
|
|
|
<th align="left" valign="top"> Notes</th>
|
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
|
|
|
<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">Emitted when a new connection is made.
|
|
|
|
<tt>connection</tt> is an instance of <tt>node.tcp.Connection</tt>.</p></td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td align="left" valign="top"><p class="table"><tt>"close"</tt></p></td>
|
|
|
|
<td align="left" valign="top"><p class="table"><tt>errorno</tt></p></td>
|
|
|
|
<td align="left" valign="top"><p class="table">Emitted when the server closes. <tt>errorno</tt>
|
|
|
|
is an integer which indicates what, if any,
|
|
|
|
error caused the server to close. If no
|
|
|
|
error occurred <tt>errorno</tt> will be 0.</p></td>
|
|
|
|
</tr>
|
|
|
|
</tbody>
|
|
|
|
</table>
|
|
|
|
</div>
|
|
|
|
<div class="dlist"><dl>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>node.tcp.createServer(connection_listener);</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Creates a new TCP server.
|
|
|
|
</p>
|
|
|
|
<div class="paragraph"><p>The <tt>connection_listener</tt> argument is automatically set as a listener for
|
|
|
|
the <tt>"connection"</tt> event.</p></div>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>server.listen(port, host=null, backlog=1024)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Tells the server to listen for TCP connections to <tt>port</tt> and <tt>host</tt>.
|
|
|
|
</p>
|
|
|
|
<div class="paragraph"><p><tt>host</tt> is optional. If <tt>host</tt> is not specified the server will accept client
|
|
|
|
connections on any network address.</p></div>
|
|
|
|
<div class="paragraph"><p>The third argument, <tt>backlog</tt>, is also optional and defaults to 1024. The
|
|
|
|
<tt>backlog</tt> argument defines the maximum length to which the queue of pending
|
|
|
|
connections for the server may grow.</p></div>
|
|
|
|
<div class="paragraph"><p>This function is synchronous.</p></div>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>server.close()</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Stops the server from accepting new connections. This function is
|
|
|
|
asynchronous, the server is finally closed when the server emits a <tt>"close"</tt>
|
|
|
|
event.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
</dl></div>
|
|
|
|
<h4 id="_tt_node_tcp_connection_tt"><tt>node.tcp.Connection</tt></h4>
|
|
|
|
<div class="paragraph"><p>This object is used as a TCP client and also as a server-side
|
|
|
|
socket for <tt>node.tcp.Server</tt>.</p></div>
|
|
|
|
<div class="tableblock">
|
|
|
|
<table rules="all"
|
|
|
|
width="100%"
|
|
|
|
frame="border"
|
|
|
|
cellspacing="0" cellpadding="4">
|
|
|
|
<col width="7%" />
|
|
|
|
<col width="15%" />
|
|
|
|
<col width="76%" />
|
|
|
|
<thead>
|
|
|
|
<tr>
|
|
|
|
<th align="left" valign="top">Event </th>
|
|
|
|
<th align="left" valign="top"> Parameters </th>
|
|
|
|
<th align="left" valign="top"> Notes</th>
|
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
|
|
|
<tr>
|
|
|
|
<td align="left" valign="top"><p class="table"><tt>"connect"</tt></p></td>
|
|
|
|
<td align="left" valign="top"><p class="table"></p></td>
|
|
|
|
<td align="left" valign="top"><p class="table">Call once the connection is established
|
|
|
|
after a call to <tt>createConnection()</tt> or
|
|
|
|
<tt>connect()</tt>.</p></td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td align="left" valign="top"><p class="table"><tt>"receive"</tt></p></td>
|
|
|
|
<td align="left" valign="top"><p class="table"><tt>data</tt></p></td>
|
|
|
|
<td align="left" valign="top"><p class="table">Called when data is received on the
|
|
|
|
connection. Encoding of data is set
|
|
|
|
by <tt>connection.setEncoding()</tt>. <tt>data</tt>
|
|
|
|
will either be a string, in the case of
|
|
|
|
utf8, or an array of integer in the case
|
|
|
|
of raw encoding.</p></td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td align="left" valign="top"><p class="table"><tt>"eof"</tt></p></td>
|
|
|
|
<td align="left" valign="top"><p class="table"></p></td>
|
|
|
|
<td align="left" valign="top"><p class="table">Called when the other end of the
|
|
|
|
connection sends a FIN packet.
|
|
|
|
After this is emitted the <tt>readyState</tt>
|
|
|
|
will be <tt>"writeOnly"</tt>. One should probably
|
|
|
|
just call <tt>connection.close()</tt> when this
|
|
|
|
event is emitted.</p></td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td align="left" valign="top"><p class="table"><tt>"timeout"</tt></p></td>
|
|
|
|
<td align="left" valign="top"><p class="table"></p></td>
|
|
|
|
<td align="left" valign="top"><p class="table">Emitted if the connection times out from
|
|
|
|
inactivity. The <tt>"close"</tt> event will be
|
|
|
|
emitted immediately following this event.</p></td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td align="left" valign="top"><p class="table"><tt>"close"</tt></p></td>
|
|
|
|
<td align="left" valign="top"><p class="table"><tt>had_error</tt></p></td>
|
|
|
|
<td align="left" valign="top"><p class="table">Emitted once the connection is fully
|
|
|
|
closed. The argument <tt>had_error</tt>
|
|
|
|
is a boolean which says if the connection
|
|
|
|
was closed due to a transmission error.
|
|
|
|
(TODO: access error codes.)</p></td>
|
|
|
|
</tr>
|
|
|
|
</tbody>
|
|
|
|
</table>
|
|
|
|
</div>
|
|
|
|
<div class="dlist"><dl>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>node.tcp.createConnection(port, host="127.0.0.1")</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Creates a new connection object and opens a connection to the specified
|
|
|
|
<tt>port</tt> and <tt>host</tt>. If the second parameter is omitted, localhost is assumed.
|
|
|
|
</p>
|
|
|
|
<div class="paragraph"><p>When the connection is established the <tt>"connect"</tt> event will be emitted.</p></div>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>connection.connect(port, host="127.0.0.1")</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Opens a connection to the specified <tt>port</tt> and <tt>host</tt>. <tt>createConnection()</tt>
|
|
|
|
also opens a connection; normally this method is not needed. Use this only
|
|
|
|
if a connection is closed and you want to reuse the object to connect to
|
|
|
|
another server.
|
|
|
|
</p>
|
|
|
|
<div class="paragraph"><p>This function is asynchronous. When the <tt>"connect"</tt> event is emitted the
|
|
|
|
connection is established. If there is a problem connecting, the <tt>"connect"</tt>
|
|
|
|
event will not be emitted, the <tt>"close"</tt> event will be emitted with
|
|
|
|
<tt>had_error == true</tt>.</p></div>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>connection.remoteAddress</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
The string representation of the remote IP address. For example,
|
|
|
|
<tt>"74.125.127.100"</tt> or <tt>"2001:4860:a005::68"</tt>.
|
|
|
|
</p>
|
|
|
|
<div class="paragraph"><p>This member is only present in server-side connections.</p></div>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>connection.readyState</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Either <tt>"closed"</tt>, <tt>"open"</tt>, <tt>"opening"</tt>, <tt>"readOnly"</tt>, or <tt>"writeOnly"</tt>.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>connection.setEncoding(encoding)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Sets the encoding (either <tt>"utf8"</tt> or <tt>"raw"</tt>) for data that is received.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>connection.send(data, encoding="ascii")</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Sends data on the connection. The data should be eithre an array
|
|
|
|
of integers (for raw binary) or a string (for utf8 or ascii).
|
|
|
|
The second parameter specifies the encoding in the case of a
|
|
|
|
string—it defaults to ASCII because encoding to UTF8 is
|
|
|
|
rather slow.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>connection.close()</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Half-closes the connection. I.E., it sends a FIN packet. It is
|
|
|
|
possible the server will still send some data. After calling
|
|
|
|
this <tt>readyState</tt> will be <tt>"readOnly"</tt>.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>connection.forceClose()</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Ensures that no more I/O activity happens on this socket. Only
|
|
|
|
necessary in case of errors (parse error or so).
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>connection.readPause()</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Pauses the reading of data. That is, <tt>"receive"</tt> events will not be emitted.
|
|
|
|
Useful to throttle back an upload.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>connection.readResume()</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Resumes reading if reading was paused by <tt>readPause()</tt>.
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>connection.setTimeout(timeout)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Sets the connection to timeout after <tt>timeout</tt> milliseconds of inactivity on
|
|
|
|
the connection. By default all <tt>node.tcp.Connection</tt> objects have a timeout
|
|
|
|
of 60 seconds (60000 ms).
|
|
|
|
</p>
|
|
|
|
<div class="paragraph"><p>If <tt>timeout</tt> is 0, then the idle timeout is disabled.</p></div>
|
|
|
|
</dd>
|
|
|
|
</dl></div>
|
|
|
|
<h3 id="_dns">DNS</h3><div style="clear:left"></div>
|
|
|
|
<div class="paragraph"><p>Here is an example of which resolves <tt>"www.google.com"</tt> then reverse
|
|
|
|
resolves the IP addresses which are returned.</p></div>
|
|
|
|
<div class="listingblock">
|
|
|
|
<div class="content">
|
|
|
|
<pre><tt>var resolution = node.dns.resolve4("www.google.com");
|
|
|
|
|
|
|
|
resolution.addCallback(function (addresses, ttl, cname) {
|
|
|
|
puts("addresses: " + JSON.stringify(addresses));
|
|
|
|
puts("ttl: " + JSON.stringify(ttl));
|
|
|
|
puts("cname: " + JSON.stringify(cname));
|
|
|
|
|
|
|
|
for (var i = 0; i < addresses.length; i++) {
|
|
|
|
var a = addresses[i];
|
|
|
|
var reversing = node.dns.reverse(a);
|
|
|
|
reversing.addCallback( function (domains, ttl, cname) {
|
|
|
|
puts("reverse for " + a + ": " + JSON.stringify(domains));
|
|
|
|
});
|
|
|
|
reversing.addErrback( function (code, msg) {
|
|
|
|
puts("reverse for " + a + " failed: " + msg);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
resolution.addErrback(function (code, msg) {
|
|
|
|
puts("error: " + msg);
|
|
|
|
});</tt></pre>
|
|
|
|
</div></div>
|
|
|
|
<div class="dlist"><dl>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>node.dns.resolve4(domain)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Resolves a domain (e.g. <tt>"google.com"</tt>) into an array of IPv4 addresses (e.g.
|
|
|
|
<tt>["74.125.79.104", "74.125.79.105", "74.125.79.106"]</tt>).
|
|
|
|
This function returns a promise.
|
|
|
|
</p>
|
|
|
|
<div class="ulist"><ul>
|
|
|
|
<li>
|
|
|
|
<p>
|
|
|
|
on success: returns <tt>addresses, ttl, cname</tt>. <tt>ttl</tt> (time-to-live) is an integer
|
|
|
|
specifying the number of seconds this result is valid for. <tt>cname</tt> is the
|
|
|
|
canonical name for the query.
|
|
|
|
</p>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
<p>
|
|
|
|
on error: returns <tt>code, msg</tt>. <tt>code</tt> is one of the error codes listed
|
|
|
|
below and <tt>msg</tt> is a string describing the error in English.
|
|
|
|
</p>
|
|
|
|
</li>
|
|
|
|
</ul></div>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>node.dns.resolve6(domain)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
The same as <tt>node.dns.resolve4()</tt> except for IPv6 queries (an <tt>AAAA</tt> query).
|
|
|
|
</p>
|
|
|
|
</dd>
|
|
|
|
<dt class="hdlist1">
|
|
|
|
<tt>node.dns.reverse(ip)</tt>
|
|
|
|
</dt>
|
|
|
|
<dd>
|
|
|
|
<p>
|
|
|
|
Reverse resolves an ip address to an array of domain names.
|
|
|
|
</p>
|
|
|
|
<div class="ulist"><ul>
|
|
|
|
<li>
|
|
|
|
<p>
|
|
|
|
on success: returns <tt>domains, ttl, cname</tt>. <tt>ttl</tt> (time-to-live) is an integer
|
|
|
|
specifying the number of seconds this result is valid for. <tt>cname</tt> is the
|
|
|
|
canonical name for the query. <tt>domains</tt> is an array of domains.
|
|
|
|
</p>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
<p>
|
|
|
|
on error: returns <tt>code, msg</tt>. <tt>code</tt> is one of the error codes listed
|
|
|
|
below and <tt>msg</tt> is a string describing the error in English.
|
|
|
|
</p>
|
|
|
|
</li>
|
|
|
|
</ul></div>
|
|
|
|
</dd>
|
|
|
|
</dl></div>
|
|
|
|
<div class="paragraph"><p>Each DNS query can return an error code.</p></div>
|
|
|
|
<div class="ulist"><ul>
|
|
|
|
<li>
|
|
|
|
<p>
|
|
|
|
<tt>node.dns.TEMPFAIL</tt>: timeout, SERVFAIL or similar.
|
|
|
|
</p>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
<p>
|
|
|
|
<tt>node.dns.PROTOCOL</tt>: got garbled reply.
|
|
|
|
</p>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
<p>
|
|
|
|
<tt>node.dns.NXDOMAIN</tt>: domain does not exists.
|
|
|
|
</p>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
<p>
|
|
|
|
<tt>node.dns.NODATA</tt>: domain exists but no data of reqd type.
|
|
|
|
</p>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
<p>
|
|
|
|
<tt>node.dns.NOMEM</tt>: out of memory while processing.
|
|
|
|
</p>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
<p>
|
|
|
|
<tt>node.dns.BADQUERY</tt>: the query is malformed.
|
|
|
|
</p>
|
|
|
|
</li>
|
|
|
|
</ul></div>
|
|
|
|
</div>
|
|
|
|
<h2 id="_extension_api">Extension API</h2>
|
|
|
|
<div class="sectionbody">
|
|
|
|
<div class="paragraph"><p>External modules can be compiled and dynamically linked into Node.
|
|
|
|
Node is more or less glue between several C and C++ libraries:</p></div>
|
|
|
|
<div class="ulist"><ul>
|
|
|
|
<li>
|
|
|
|
<p>
|
|
|
|
V8 Javascript, a C++ library. Used for interfacing with Javascript:
|
|
|
|
creating objects, calling functions, etc. Documented mostly in the
|
|
|
|
<tt>v8.h</tt> header file (<tt>deps/v8/include/v8.h</tt> in the Node source tree).
|
|
|
|
</p>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
<p>
|
|
|
|
libev, C event loop library. Anytime one needs to wait for a file
|
|
|
|
descriptor to become readable, wait for a timer, or wait for a signal to
|
|
|
|
received one will need to interface with libev. That is, if you perform
|
|
|
|
any I/O, libev will need to be used. Node uses the <tt>EV_DEFAULT</tt> event
|
|
|
|
loop. Documentation can be found <a href="http:/cvs.schmorp.de/libev/ev.html">here</a>.
|
|
|
|
</p>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
<p>
|
|
|
|
libeio, C thread pool library. Used to execute blocking POSIX system
|
|
|
|
calls asynchronously. Mostly wrappers already exist for such calls, in
|
|
|
|
<tt>src/file.cc</tt> so you will probably not need to use it. If you do need it,
|
|
|
|
look at the header file <tt>deps/libeio/eio.h</tt>.
|
|
|
|
</p>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
<p>
|
|
|
|
Internal Node libraries. Most importantly is the <tt>node::EventEmitter</tt>
|
|
|
|
class which you will likely want to derive from.
|
|
|
|
</p>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
<p>
|
|
|
|
Others. Look in <tt>deps/</tt> for what else is available.
|
|
|
|
</p>
|
|
|
|
</li>
|
|
|
|
</ul></div>
|
|
|
|
<div class="paragraph"><p>Node statically compiles all its dependencies into the executable. When
|
|
|
|
compiling your module, you don’t need to worry about linking to any of these
|
|
|
|
libraries.</p></div>
|
|
|
|
<div class="paragraph"><p>Here is a sample Makefile taken from
|
|
|
|
<a href="http://github.com/ry/node_postgres">node_postgres</a>:</p></div>
|
|
|
|
<div class="listingblock">
|
|
|
|
<div class="content">
|
|
|
|
<pre><tt>binding.node: binding.o Makefile
|
|
|
|
gcc -shared -o binding.node binding.o \
|
|
|
|
-L`pg_config --libdir` -lpq
|
|
|
|
|
|
|
|
binding.o: binding.cc Makefile
|
|
|
|
gcc `node --cflags` -I`pg_config --includedir` \
|
|
|
|
binding.cc -c -o binding.o
|
|
|
|
|
|
|
|
clean:
|
|
|
|
rm -f binding.o binding.node
|
|
|
|
.PHONY: clean</tt></pre>
|
|
|
|
</div></div>
|
|
|
|
<div class="paragraph"><p>As you can see, the only thing your module needs to know about Node is the
|
|
|
|
CFLAGS that node was compiled with which are gotten from <tt>node --cflags</tt>
|
|
|
|
If you want to make a debug build, then use <tt>node_g --cflags</tt>. (<tt>node_g</tt> is
|
|
|
|
the debug build of node, which can built with <tt>configure --debug; make; make
|
|
|
|
install</tt>.)</p></div>
|
|
|
|
<div class="paragraph"><p>Node extension modules are dynamically linked libraries with a <tt>.node</tt>
|
|
|
|
extension. Node opens this file and looks for a function called <tt>init()</tt>
|
|
|
|
which must be of the form:</p></div>
|
|
|
|
<div class="listingblock">
|
|
|
|
<div class="content">
|
|
|
|
<pre><tt>extern "C" void init (Handle<Object> target)</tt></pre>
|
|
|
|
</div></div>
|
|
|
|
<div class="paragraph"><p>In this function you can create new javascript objects and attach them to
|
|
|
|
<tt>target</tt>. Here is a very simple module:</p></div>
|
|
|
|
<div class="listingblock">
|
|
|
|
<div class="content">
|
|
|
|
<pre><tt>extern "C" void
|
|
|
|
init (Handle<Object> target)
|
|
|
|
{
|
|
|
|
HandleScope scope;
|
|
|
|
target->Set(String::New("hello"), String::New("World"));
|
|
|
|
}</tt></pre>
|
|
|
|
</div></div>
|
|
|
|
<div class="paragraph"><p>Further documentation will come soon. For now see the source code of
|
|
|
|
<a href="http://github.com/ry/node_postgres">node_postgres</a>.</p></div>
|
|
|
|
</div>
|
|
|
|
<div id="footer">
|
|
|
|
<div id="footer-text">
|
|
|
|
Version 0.1.10<br />
|
|
|
|
Last updated 2009-09-12 19:12:41 CEST
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</body>
|
|
|
|
</html>
|