summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xconfigure13
-rw-r--r--website/api.html1101
-rw-r--r--website/api.txt1009
3 files changed, 1018 insertions, 1105 deletions
diff --git a/configure b/configure
index a3a2ed6f4..a5865ab28 100755
--- a/configure
+++ b/configure
@@ -96,13 +96,18 @@ uninstall:
test: all
python tools/test.py --mode=release
-
-test-debug: all
- python tools/test.py --mode=debug
test-all: all
python tools/test.py --mode=debug,release
+website: website/api.html website/index.html
+
+website/api.html: website/api.txt
+ asciidoc -a toc -o website/api.html website/api.txt
+
+website-upload: website
+ scp website/* linode:~/tinyclouds/node/
+
clean:
@$WAF clean
@@ -118,7 +123,7 @@ check:
dist:
@$WAF dist
-.PHONY: clean dist distclean check uninstall install all test
+.PHONY: clean dist distclean check uninstall install all test test-all website website-upload
EOF
}
diff --git a/website/api.html b/website/api.html
deleted file mode 100644
index 4b059e4e0..000000000
--- a/website/api.html
+++ /dev/null
@@ -1,1101 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
- <script type="text/javascript" src="sh_main.js"></script>
- <script type="text/javascript" src="sh_javascript.min.js"></script>
- <link type="text/css" rel="stylesheet" href="style.css" />
- <link type="text/css" rel="stylesheet" href="sh_vim-dark.css" />
- <meta http-equiv="content-type" content="text/html; charset=utf-8" />
-
- <title>node.js</title>
-</head>
-<body onload="sh_highlightDocument();">
-<div id="toc">
- <ol>
- <li><a href="#timers">Timers</a></li>
- <li><a href="#processes">Processes</a></li>
- <li>
- <a href="#files">File I/O</a>
- <ol>
- <li><a href="#file_wrappers">Wrappers</a></li>
- <li><a href="#file_file">File</a></li>
- </ol>
- </li>
- <li>
- <a href="#tcp">TCP</a>
- <ol>
- <li><a href="#tcp_server">Server</a></li>
- <li><a href="#tcp_connection">Connection</a></li>
- </ol>
- </li>
- <li>
- <a href="#http">HTTP</a>
- <ol>
- <li>
- <a href="#http_server">Server</a>
- <ol>
- <li><a href="#http_server_request">Request</a></li>
- <li><a href="#http_server_response">Response</a></li>
- </ol>
- </li>
- <li>
- <a href="#http_client">Client</a>
- <ol>
- <li><a href="#http_client_request">Request</a></li>
- <li><a href="#http_client_response">Response</a></li>
- </ol>
- </li>
- </ol>
- </li>
- <li><a href="#modules">Modules</a>
- <ol>
- <li><a href="#onload">onLoad</a></li>
- <li><a href="#onexit">onExit</a></li>
- </ol>
- </ol>
-</div>
-
-<div id="content">
- <h1 id="api">Node API</h1>
- <p>
- Conventions: Callbacks are object members which are prefixed with
- <code>on</code>. All methods and members are camel cased. Constructors
- always have a capital first letter.
- </p>
-
- <p>
- Node supports 3 byte-string encodings: ASCII (<code>"ascii"</code>),
- UTF-8 (<code>"utf8"</code>), and raw binary (<code>"raw"</code>).
- It uses strings to represent ASCII and UTF-8 encoded data. For
- the moment, arrays of integers are used to represent raw binary
- data&mdash;this representation is rather inefficient. This will
- change in the future, when
- <a href="http://code.google.com/p/v8/issues/detail?id=270">
- V8 supports Blob objects
- </a>.
- </p>
-
- <p>The following are global functions:</p>
-
- <dl>
- <dt><code>puts(string, callback)</code></dt>
- <dd>
- Alias for <code>stdout.puts()</code>. Outputs the
- <code>string</code> and a trailing new-line to
- <code>stdout</code>.
-
- <p>
- The <code>callback</code> argument is optional and mostly
- useless: it will notify the user when the operation has
- completed. Everything in node is asynchronous;
- <code>puts()</code> is no exception. This might seem ridiculous
- but, if for example, one is piping <code>stdout</code> into an
- NFS file, <code>printf()</code> will block from network latency.
- There is an internal queue for <code>puts()</code> output, so
- you can be assured that output will be displayed in the order
- it was called.
- </p>
- </dd>
-
- <dt><code>print(string, callback)</code></dt>
- <dd>Like <code>puts()</code> but without the trailing new-line.</dd>
-
- <dt><code>node.debug(string)</code></dt>
- <dd>
- A synchronous output function. Will <i>block</i> the process and
- output the string immediately to stdout. Use with care.
- </dd>
-
- <dt><code>node.exit(code)</code></dt>
- <dd>Immediately ends the process with the specified code.</dd>
-
- <dt><code>ARGV</code></dt>
- <dd>An array containing the command line arguments.</dd>
-
- <dt><code>stdout</code>,
- <code>stderr</code>, and
- <code>stdin</code>
- </dt>
- <dd>Objects of type <code>node.fs.File</code>. (See below)</dd>
- </dl>
-
- <h2 id="timers">Timers</h2>
-
- <dl>
- <dt><code>setTimeout(callback, delay)</code></dt>
- <dd>
- To schedule execution of <code>callback</code> after
- <code>delay</code> milliseconds. Returns a <code>timeoutId</code>
- for possible use with <code>clearTimeout()</code>.
- </dd>
-
- <dt><code>clearTimeout(timeoutId)</code></dt>
- <dd>Prevents said timeout from triggering.</dd>
-
- <dt><code>setInterval(callback, delay)</code></dt>
- <dd>
- To schedule the repeated execution of <code>callback</code>
- every<code>delay</code> milliseconds. Returns a
- <code>intervalId</code> for possible use with
- <code>clearInterval()</code>.
- </dd>
-
- <dt><code>clearInterval(intervalId)</code></dt>
- <dd>Stops a interval from triggering.</dd>
- </dl>
-
- <h2 id="processes">Processes and IPC</h2>
-
- <p>
- Node provides a tridirectional <code>popen(3)</code> facility.
- It is possible to stream data through the child's <code>stdin</code>,
- <code>stdout</code>, and <code>stderr</code> in a fully non-blocking
- way.
- </p>
-
- <dl>
- <dt><code>new node.Process(command)</code></dt>
- <dd>Launches a new process with the given <code>command</code>. For example:
- <pre>var ls = new Process("ls -lh /usr");</pre>
- </dd>
-
- <dt><code>process.pid</code></dt>
- <dd>The PID of the child process.</dd>
-
- <dt><code>process.onOutput = function (chunk) { };</code></dt>
- <dd>A callback to receive output from the process's <code>stdout</code>.
- At the moment the received data is always a string and utf8 encoded.
- (More encodings will be supported in the future.)
-
- <p>If the process closes its <code>stdout</code>, this callback will
- be issued with <code>null</code> as an argument. Be prepared for this
- possibility.
- </dd>
-
- <dt><code>process.onError = function (chunk) { };</code></dt>
- <dd>A callback to receive output from the process's <code>stderr</code>.
- At the moment the received data is always a string and utf8 encoded.
- (More encodings will be supported in the future.)
-
- <p>If the process closes its <code>stderr</code>, this callback will
- be issued with <code>null</code> as an argument. Be prepared for this
- possibility.
- </dd>
-
- <dt><code>process.onExit = function (exit_code) { };</code></dt>
- <dd>A callback which is called when the child process terminates.
- The argument is the exit status of the child.
- </dd>
-
- <dt><code>process.write(data, encoding="ascii");</code></dt>
- <dd>Write data to the child process's <code>stdin</code>. The second
- argument is optional and specifies the encoding: possible values are
- <code>"utf8"</code>, <code>"ascii"</code>, and <code>"raw"</code>.
- </dd>
-
- <dt><code>process.close();</code></dt>
- <dd>Closes the process's <code>stdin</code> stream.</dd>
-
- <dt><code>process.kill(signal=node.SIGTERM);</code></dt>
- <dd>Kills the child process with the given signal. If no argument is
- given, the process will be sent <code>node.SIGTERM</code>. The standard
- POSIX signals are defined under the <code>node</code> namespace (e.g.
- <code>node.SIGINT</code>, <code>node.SIGUSR1</code>).
- </dd>
- </dl>
-
- <h2 id="files"><code>node.fs</code></h2>
-
- <p>
- File I/O is tricky because there are not simple non-blocking ways
- to do it. Node handles file I/O by employing
- <a href="http://software.schmorp.de/pkg/libeio.html">
- an internal thread pool
- </a> to execute file system calls.
- </p>
-
- <p>
- This part of the API is split into two parts: simple wrappers
- around standard POSIX file I/O functions and a user-friendly
- <code>File</code> object.
- </p>
-
- <h3 id="file_wrappers">POSIX Wrappers</h3>
-
- <p>
- All POSIX wrappers have a similar form. They return
- <code>undefined</code> and have a callback called
- <code>on_completion</code> as their last argument. The
- <code>on_completion</code> callback may be passed many parameters,
- but the first parameter is always an integer indicating the error
- status. If the status integer is zero, then the call was successful.
- Example:
- </p>
- <pre>
-node.fs.unlink("/tmp/hello", function (status) {
- if (status == 0)
- puts("successfully deleted /tmp/hello");
-});</pre>
-
- <p>
- There is no guaranteed ordering to the POSIX wrappers. The
- following is very much prone to error
- </p>
- <pre>
-node.fs.rename("/tmp/hello", "/tmp/world");
-node.fs.stat("/tmp/world", function (status, stats) {
- puts("stats: " + JSON.stringify(stats));
-});</pre>
- <p>
- because it could be that <code>stat()</code> is executed before
- the <code>rename()</code>. The correct way to do this, is use the
- <code>on_completion</code> callback for <code>rename()</code>
- </p>
- <pre>
-node.fs.rename("/tmp/hello", "/tmp/world", function (status) {
- if (status != 0) return;
- node.fs.stat("/tmp/world", function (status, stats) {
- puts("stats: " + JSON.stringify(stats));
- });
-});</pre>
-
- <dl>
- <dt><code>node.fs.rename(path1, path2, on_completion(status))</code></dt>
- <dd> <a href="http://opengroup.org/onlinepubs/007908799/xsh/rename.html">rename(2)</a> </dd>
-
- <dt><code>node.fs.stat(path, on_completion(status, stats))</code></dt>
- <dd> <a href="http://opengroup.org/onlinepubs/007908799/xsh/stat.html">stat(2)</a> </dd>
-
- <dt><code>node.fs.unlink(path, on_completion(status))</code></dt>
- <dd> <a href="http://opengroup.org/onlinepubs/007908799/xsh/unlink.html">unlink(2)</a> </dd>
-
- <dt><code>node.fs.rmdir(path, on_completion(status))</code></dt>
- <dd> <a href="http://opengroup.org/onlinepubs/007908799/xsh/rmdir.html">rmdir(2)</a> </dd>
-
- <dt><code>node.fs.close(fd, on_completion(status))</code></dt>
- <dd> <a href="http://opengroup.org/onlinepubs/007908799/xsh/close.html">close(2)</a> </dd>
-
- <dt><code>node.fs.open(path, flags, mode, on_completion(status, fd))</code></dt>
- <dd>
- <a href="http://opengroup.org/onlinepubs/007908799/xsh/open.html">open(2)</a>
- <p>
- The constants like <code>O_CREAT</code> are defined at
- <code>node.O_CREAT</code>.
- </p>
- </dd>
-
- <dt><code>node.fs.write(fd, data, position, on_completion(status, written))</code></dt>
- <dd>
- Write data to the file specified by <code>fd</code>.
- <p>
- <code>data</code> is either an array of integer (for raw
- data) or a string for UTF-8 encoded characters.
- </p>
- <p>
- <code>position</code> refers to the offset from the beginning
- of the file where this data should be written. If
- <code>null</code>, the data will be written at the current
- position.
- </p>
- <p>See also
- <a href="http://opengroup.org/onlinepubs/007908799/xsh/pwrite.html">pwrite(2)</a>
- </p>
- </dd>
-
- <dt><code>node.fs.read(fd, length, position, encoding, on_completion(status, data))</code></dt>
- <dd>
- Read data from the file specified by <code>fd</code>.
-
- <p>
- <code>length</code> is an integer specifying the number of
- bytes to read.
- </p>
-
- <p>
- <code>position</code> is an integer specifying where to begin
- reading from in the file.
- </p>
-
- <p>
- <code>encoding</code> is either <code>node.UTF8</code>
- or <code>node.RAW</code>.
- </p>
- </dd>
- </dl>
-
- <h3 id="file_file"><code>node.fs.File</code></h3>
-
- <p>Easy buffered file object.</p>
-
- <p>
- Internal request queues exist for each file object so that
- multiple commands can be issued at once without worry that they
- will be executed out-of-order. Thus the following is safe:
- </p>
-
- <pre>
-var file = new node.fs.File();
-file.open("/tmp/blah", "w+");
-file.write("hello");
-file.write("world");
-file.close();</pre>
-
- <p>
- Request queues are local to a single file. If one does
- </p>
- <pre>
-fileA.write("hello");
-fileB.write("world");</pre>
- <p>
- it could be that <code>fileB</code> gets written to before
- <code>fileA</code> is written to. If a certain operation order
- is needed involving multiple files, use the completion callbacks:
- </p>
- <pre>
-fileA.write("hello", function () {
- fileB.write("world");
-});</pre>
-
- <dl>
- <dt><code>new node.fs.File(options={})</code></dt>
- <dd>
- Creates a new file object.
-
- <p>
- The <code>options</code> argument is optional. It can contain
- the following fields
- </p>
- <ul>
- <li><code>fd</code> &mdash; a file descriptor for the file.</li>
- <li>
- <code>encoding</code> &mdash; how <code>file.read()</code>
- should return data. Either <code>"raw"</code> or
- <code>"utf8"</code>. Defaults to raw.
- </li>
- </ul>
- </dd>
-
- <dt><code>file.onError = function (method, errno, msg) { }</code></dt>
- <dd>
- Callback. This is called internally anytime an error occurs with
- this file. There are three arguments: the method name, the POSIX
- errno, and a string describing the error.
-
- <p>Example</p>
- <pre>
-var path = "/some/path/that/doesnt/exist";
-var file = new node.fs.File();
-file.onError = function (method, errno, msg) {
- stderr.puts("An error occurred calling " + method);
- stderr.puts(msg);
- node.exit(1);
-}
-file.open(path, "w+")</pre>
- </dd>
-
- <dt><code>file.open(path, mode, on_completion())</code></dt>
- <dd>
- Opens the file at <code>path</code>.
- <p>
- <code>mode</code> is a string: <code>"r"</code> open for
- reading and writing. <code>"r+"</code> open for only reading.
- <code>"w"</code> create a new file for reading and writing;
- if it already exists truncate it. <code>"w+"</code> create a
- new file for writing only; if it already exists truncate it.
- <code>"a"</code> create a new file for writing and reading.
- Writes append to the end of the file.
- <!-- TODO: Describe mode a+ -->
- <code>"a+"</code>
- <!-- TODO: Describe mode a+ -->
- </p>
- <p>
- The <code>on_completion</code> is a callback that is made
- without arguments when the operation completes. It is optional.
- If an error occurred the <code>on_completion</code> callback
- will not be called, but the <code>file.onError</code> will be
- called.
- </p>
- </dd>
-
- <dt><code>file.read(length, position, on_completion(data))</code></dt>
- <dd></dd>
-
- <dt><code>file.write(data, position, on_completion(written))</code></dt>
- <dd></dd>
-
- <dt><code>file.close(on_completion())</code></dt>
- <dd></dd>
- </dl>
-
- <h2 id="tcp"><code>node.tcp</code></h2>
-
- <h3 id="tcp_server"><code>node.tcp.Server</code></h3>
-
- <p>
- Here is an example of a echo server which listens for connections
- on port 7000
- </p>
- <pre>
-function Echo (socket) {
- socket.setEncoding("utf8");
- socket.onConnect = function () {
- socket.send("hello\r\n");
- };
- socket.onReceive = function (data) {
- socket.send(data);
- };
- socket.onEOF = function () {
- socket.send("goodbye\r\n");
- socket.close();
- };
-}
-var server = new node.tcp.Server(Echo, {backlog: 1024});
-server.listen(7000, "localhost");</pre>
-
- <dl>
- <dt><code>new node.tcp.Server(connection_handler(socket), options={});</code></dt>
- <dd>
- Creates a new TCP server.
-
- <p>
- <code>connection_handler</code> is a callback which is called
- on each connection. It is given one argument: an instance of
- <code>node.tcp.Connection</code>.
- </p>
-
- <p>
- <code>options</code> for now only supports one option:
- <code>backlog</code> which should be an integer and describes
- how large of a connection backlog the operating system should
- maintain for this server. The <code>backlog</code> defaults
- to 1024.
- </p>
- </dd>
-
- <dt><code>server.listen(port, host=null)</code></dt>
- <dd>
- Tells the server to listen for TCP connections to <code>port</code>
- and <code>host</code>. Note, <code>host</code> is optional. If
- <code>host</code> is not specified the server will accept
- connections to any IP address on the specified port.
- </dd>
-
- <dt><code>server.close()</code></dt>
- <dd> Stops the server from accepting new connections. </dd>
- </dl>
-
- <h3 id="tcp_connection"><code>node.tcp.Connection</code></h3>
-
- <p>
- This object is used as a TCP client and also as a server-side
- socket for <code>node.tcp.Server</code>s.
- </p>
-
- <dl>
- <dt><code>new node.tcp.Connection()</code></dt>
- <dd>Creates a new connection object.</dd>
-
- <dt><code>connection.connect(port, host="127.0.0.1")</code></dt>
- <dd>
- Opens a connection to the specified <code>port</code> and
- <code>host</code>. If the second parameter is omitted, localhost is
- assumed.
- </dd>
-
- <dt><code>connection.remoteAddress</code></dt>
- <dd>
- The string representation of the remote IP address. For example,
- <code>"74.125.127.100"</code> or <code>"2001:4860:a005::68"</code>.
-
- <p>This member is only present in server-side connections.</p>
- </dd>
-
- <dt><code>connection.readyState</code></dt>
- <dd>
- Either <code>"closed"</code>, <code>"open"</code>, <code>"opening"</code>
- <code>"readOnly"</code>, or <code>"writeOnly"</code>.
- </dd>
-
- <dt><code>connection.setEncoding(encoding)</code></dt>
- <dd>
- Sets the encoding (either <code>"utf8"</code> or
- <code>"raw"</code>) for data that is received.
- </dd>
-
- <dt><code>connection.send(data, encoding="ascii")</code></dt>
- <dd>
- 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&mdash;it defaults to ASCII because encoding to UTF8 is
- rather slow.
- </dd>
-
- <dt><code>connection.close()</code></dt>
- <dd>
- Half-closes the connection. I.E. sends a FIN packet. It is
- possible the server will still send some data. After calling
- this <code>readyState</code> will be <code>"readOnly"</code>.
- </dd>
-
- <dt><code>connection.fullClose()</code></dt>
- <dd>
- Close both ends of the connection. Data that is received
- after this call is responded to with RST packets. If you don't
- know about this, just use <code>close()</code>.
- </dd>
-
- <dt><code>connection.forceClose()</code></dt>
- <dd>
- Ensures that no more I/O activity happens on this socket. Only
- necessary in case of errors (parse error or so).
- </dd>
-
- <dt><code>connection.onConnect = function () { };</code></dt>
- <dd>Call once the connection is established.</dd>
-
- <dt><code>connection.onReceive = function (data) { };</code></dt>
- <dd>
- Called when data is received on the connection. Encoding of data
- is set by <code>connection.setEncoding()</code>.
- <code>data</code> will either be a string, in the case of utf8,
- or an array of integer in the case of raw encoding.
- </dd>
-
- <dt><code>connection.onEOF = function () { };</code></dt>
- <dd>
- Called when the other end of the connection sends a FIN packet.
- <code>onReceive</code> will not be called after this. After
- receiving this <code>readyState</code> will be
- <code>"writeOnly"</code>. You should probably just call
- <code>connection.close()</code> in this callback.
- </dd>
-
- <dt><code>connection.onDisconnect = function (had_error) { };</code></dt>
- <dd>
- Called once the connection is fully disconnected.
-
- <p>
- The callback is passed one boolean argument <code>had_error</code>.
- This lets one know if the connect was closed due to an error.
- (TODO: look up error codes.)
- </p>
- </dd>
-
- <dt><code>connection.onError = function () { };</code></dt>
- <dd>Called on an error.</dd>
- </dl>
-
- <h2 id="http"><code>node.http</code></h2>
-
- <p>
- The HTTP interfaces here are designed to support many features
- of the protocol which have been traditionally difficult to handle.
- In particular, large, possibly chunked, messages. The interface is
- careful to never buffer entire requests or responses&mdash;the
- user is able to stream data.
- </p>
-
- <p>
- HTTP message headers are represented by an array of 2-element
- arrays like this
- </p>
- <pre>
-[ ["Content-Length", "123"]
-, ["Content-Type", "text/plain"]
-, ["Connection", "keep-alive"]
-, ["Accept", "*/*"]
-]</pre>
- <p><i>
- Dictionary-like objects are popularly used to represent HTTP
- headers but they are an incorrect abstraction. It is rare, but
- possible, to have multiple header lines with the same field.
- Setting multiple cookies in a single response, for example, can
- only be done with multiple <code>Cookie</code> lines.
- </i></p>
-
- <p>
- Node's HTTP abstraction deals with connection handling and message
- parsing only. It parses the message into headers and body - but it does
- not parse any of the headers or the body. This is left to the user. That
- means, for example, that Node does not (and will never) provide API
- to access or manipulate Cookies or multi-part bodies.
- </p>
-
- <h3 id="http_server"><code>node.http.Server</code></h3>
-
- <dl>
- <dt><code>new node.http.Server(request_handler, options);</code></dt>
- <dd>
- <p>Creates a new web server.</p>
-
- <p>
- The <code>options</code> argument is optional. The
- <code>options</code> argument accepts the same values as the
- options argument for <code>node.tcp.Server</code> does.
- </p>
-
- <p>
- The <code>request_handler</code> is a callback which is made
- on each request with a <code>ServerRequest</code> and
- <code>ServerResponse</code> arguments.
- </p>
- </dd>
-
- <dt><code>server.listen(port, hostname)</code></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.
- </p>
- </dd>
-
- <dt><code>server.close()</code></dt>
- <dd>
- <p>Stops the server from accepting new connections.</p>
- </dd>
- </dl>
-
- <h3 id="http_server_request"><code>node.http.ServerRequest</code></h3>
-
- <p>
- This object is created internally by a HTTP server&mdash;not by
- the user. It is passed to the user as the first argument to the
- <code>request_handler</code> callback.
- </p>
-
- <dl>
- <dt><code>req.method</code></dt>
- <dd>The request method as a string. Read only. Example:
- <code>"GET"</code>, <code>"DELETE"</code>.
- </dd>
-
- <dt><code>req.uri</code></dt>
- <dd> Request URI Object. This contains only the parameters that are
- present in the actual http request. That is, if the request is
-<pre class="sh_none">GET /status?name=ryan HTTP/1.1\r\n
-Accept: */*\r\n
-\r\n
-</pre>
- Then <code>req.uri</code> will be
-<pre>
-{ path: "/status",
- file: "status",
- directory: "/",
- params: { "name" : "ryan" }
-}</pre>
- In particular, note that <code>req.uri.protocol</code> is
- <code>undefined</code>. This is because there was no URI protocol given
- in the actual HTTP Request.
- </dd>
-
- <dt><code>req.uri.anchor</code></dt>
- <dt><code>req.uri.query</code></dt>
- <dt><code>req.uri.file</code></dt>
- <dt><code>req.uri.directory</code></dt>
- <dt><code>req.uri.path</code></dt>
- <dt><code>req.uri.relative</code></dt>
- <dt><code>req.uri.port</code></dt>
- <dt><code>req.uri.host</code></dt>
- <dt><code>req.uri.password</code></dt>
- <dt><code>req.uri.user</code></dt>
- <dt><code>req.uri.authority</code></dt>
- <dt><code>req.uri.protocol</code></dt>
- <dt><code>req.uri.params</code></dt>
- <dt><code>req.uri.toString()</code>, <code>req.uri.source</code> </dt>
-
- <dt><code>req.headers</code></dt>
- <dd>
- The request headers expressed as an array of 2-element arrays.
- Read only.
- </dd>
-
- <dt><code>req.httpVersion</code></dt>
- <dd>
- The HTTP protocol version as a string. Read only. Examples:
- <code>"1.1"</code>, <code>"1.0"</code>
- </dd>
-
- <dt><code>req.onBody = function (chunk) { }; </code></dt>
- <dd>
- Callback. Should be set by the user to be informed of when a
- piece of the message body is received. Example:
- <pre>
-req.onBody = function (chunk) {
- puts("part of the body: " + chunk);
-};</pre>
- A chunk of the body is given as the single argument. The
- transfer-encoding has been decoded.
-
- <p>
- 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 <code>req.setBodyEncoding()</code>.
- </p>
- </dd>
-
- <dt><code>req.onBodyComplete = function () { };</code></dt>
- <dd>
- Callback. Made exactly once for each message. No arguments.
- After <code>onBodyComplete</code> is executed
- <code>onBody</code> will no longer be called.
- </dd>
-
- <dt><code>req.setBodyEncoding(encoding)</code></dt>
- <dd>
- Set the encoding for the request body. Either <code>"utf8"</code>
- or <code>"raw"</code>. Defaults to raw.
- </dd>
-
- <dt><code>req.interrupt()</code></dt>
- <dd>
- Interrupt the request. You will not receive anymore callbacks.
- This is useful if, for example someone is streaming up a file but it
- is too large and neesd to be stopped. The connection to the client
- will be closed immediately.
- </dd>
- </dl>
-
- <h3 id="http_server_response"><code>node.http.ServerResponse</code></h3>
-
- <p>
- This object is created internally by a HTTP server&mdash;not by
- the user. It is passed to the user as the second argument to the
- <code>request_handler</code> callback.
- </p>
-
- <dl>
- <dt><code>res.sendHeader(statusCode, headers)</code></dt>
- <dd>
- Sends a response header to the request. The status code is a
- 3-digit HTTP status code, like <code>404</code>. The second
- argument, <code>headers</code>, should be an array of 2-element
- arrays, representing the response headers.
-
- <p>Example:</p>
- <pre>
-var body = "hello world";
-res.sendHeader(200, [ ["Content-Length", body.length]
- , ["Content-Type", "text/plain"]
- ]);</pre>
- <p>
- This method must only be called once on a message and it must
- be called before <code>res.finish()</code> is called.
- </p>
- </dd>
-
- <dt><code>res.sendBody(chunk, encoding="ascii")</code></dt>
- <dd>
- This method must be called after <code>sendHeader</code> 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>
- If <code>chunk</code> is a string, the second parameter
- specifies how to encode it into a byte stream. By default the
- <code>encoding</code> is <code>"ascii"</code>.
- </p>
-
- <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>
- </dd>
-
- <dt><code>res.finish()</code></dt>
- <dd>
- This method signals that all of the response headers and body
- has been sent; that server should consider this message complete.
- The method, <code>res.finish()</code>, MUST be called on each
- response.
- </dd>
- </dl>
-
- <h3 id="http_client"><code>node.http.Client</code></h3>
-
- <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. <i>Currently the implementation does not pipeline requests.</i>
- </p>
-
- <p> Example of connecting to <code>google.com</code></p>
- <pre>
-var google = new node.http.Client(80, "google.com");
-var req = google.get("/");
-req.finish(function (res) {
- puts("STATUS: " + res.statusCode);
- puts("HEADERS: " + JSON.stringify(res.headers));
- res.setBodyEncoding("utf8");
- res.onBody = function (chunk) {
- puts("BODY: " + chunk);
- };
-});</pre>
-
- <dl>
- <dt><code>new node.http.Client(port, host);</code></dt>
- <dd>
- Constructs a new HTTP client. <code>port</code> and
- <code>host</code> refer to the server to be connected to. A
- connection is not established until a request is issued.
- </dd>
-
- <dt><code>client.get(path, request_headers);</code></dt>
- <dt><code>client.head(path, request_headers);</code></dt>
- <dt><code>client.post(path, request_headers);</code></dt>
- <dt><code>client.del(path, request_headers);</code></dt>
- <dt><code>client.put(path, request_headers);</code></dt>
- <dd>
- Issues a request; if necessary establishes connection.
-
- <p>
- <code>request_headers</code> is optional.
- <code>request_headers</code> should be an array of 2-element
- arrays. Additional request headers might be added internally
- by Node. Returns a <code>ClientRequest</code> object.
- </p>
-
- <p>
- Do remember to include the <code>Content-Length</code> header if you
- plan on sending a body. If you plan on streaming the body, perhaps
- set <code>Transfer-Encoding: chunked</code>.
- </p>
-
- <p>
- Important: the request is not complete. This method only sends
- the header of the request. One needs to call
- <code>req.finish()</code> 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
- <code>req.sendBody()</code>.)
- </p>
-
- <p><i>
- <code>GET</code> and <code>HEAD</code> requests normally are
- without bodies but HTTP does not forbid it, so neither do we.
- </i></p>
- </dd>
- </dl>
-
- <h3 id="http_client_request"><code>node.http.ClientRequest</code></h3>
-
- <p>
- This object is created internally and returned from the request
- methods of a <code>node.http.Client</code>. It represents an
- <i>in-progress</i> request whose header has already been sent.
- </p>
-
- <dl>
- <dt><code>req.sendBody(chunk, encoding="ascii")</code></dt>
- <dd>
- Sends a sucessive peice of the body. By calling this method
- many times, the user can stream a request body to a
- server&mdash;in that case it is suggested to use the
- <code>["Transfer-Encoding", "chunked"]</code> header line when
- creating the request.
-
- <p>
- The <code>chunk</code> argument should be an array of integers
- or a string.
- </p>
-
- <p>
- The <code>encoding</code> argument is optional and only
- applies when <code>chunk</code> is a string. The encoding
- argument should be either <code>"utf8"</code> or
- <code>"ascii"</code>. By default the body uses ASCII encoding,
- as it is faster.
- </p>
- </dd>
- <dt><code>req.finish(response_handler)</code></dt>
- <dd>
- 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 <code>"0\r\n\r\n"</code>.
-
- <p>
- The parameter <code>response_handler</code> is a user-supplied
- callback which will be executed exactly once when the server
- response headers have been received. The
- <code>response_handler</code> callback is executed with one
- argument: a <code>ClientResponse</code> object.
- </p>
- </dd>
- </dl>
-
- <h3 id="http_client_response"><code>node.http.ClientResponse</code></h3>
-
- <p>
- This object is created internally and passed to the
- <code>response_handler</code> callback (is given to the client in
- <code>req.finish</code> function). The response object appears
- exactly as the header is completely received but before any part
- of the response body has been read.
- </p>
-
- <dl>
- <dt><code>res.statusCode</code></dt>
- <dd>The 3-digit HTTP response status code. E.G. <code>404</code>.</dd>
-
- <dt><code>res.httpVersion</code></dt>
- <dd>
- The HTTP version of the connected-to server. Probably either
- <code>"1.1"</code> or <code>"1.0"</code>.
- </dd>
-
- <dt><code>res.headers</code></dt>
- <dd>The response headers. An Array of 2-element arrays.</dd>
-
- <dt><code>res.onBody</code></dt>
- <dd>
- Callback. Should be set by the user to be informed of when a
- piece of the response body is received. A chunk of the body is
- given as the single argument. The transfer-encoding has been
- removed.
-
- <p>
- The body chunk is either a <code>String</code> in the case of
- UTF-8 encoding or an array of numbers in the case of raw
- encoding. The body encoding is set with <code>res.setBodyEncoding()</code>.
- </p>
- </dd>
-
- <dt><code>res.onBodyComplete</code></dt>
- <dd>
- Callback. Made exactly once for each message. No arguments.
- After <code>onBodyComplete</code> is executed
- <code>onBody</code> will no longer be called.
- </dd>
-
- <dt><code>res.setBodyEncoding(encoding)</code></dt>
- <dd>
- Set the encoding for the response body. Either
- <code>"utf8"</code> or <code>"raw"</code>. Defaults to raw.
- </dd>
- </dl>
-
- <h2 id="modules">Modules</h2>
-
- <p>
- Node has a simple module loading system. In Node, files and
- modules are in one-to-one correspondence. As an example,
- <code>foo.js</code> loads the module <code>mjsunit.js</code>.
- </p>
-
- <p>The contents of <code>foo.js</code>:</p>
-
- <pre>
-include("mjsunit.js");
-function onLoad () {
- assertEquals(1, 2);
-}</pre>
- <p>The contents of <code>mjsunit.js</code>:</p>
-
- <pre>
-function fail (expected, found, name_opt) {
- // ...
-}
-function deepEquals (a, b) {
- // ...
-}
-exports.assertEquals = function (expected, found, name_opt) {
- if (!deepEquals(found, expected)) {
- fail(expected, found, name_opt);
- }
-};</pre>
-
- <p>
- The module <code>mjsunit.js</code> has exported a function
- <code>assertEquals()</code>. <code>mjsunit.js</code> must be
- in the same directory as <code>foo.js</code> for
- <code>include()</code> to find it. The module path is relative
- to the file calling <code>include()</code>.
- </p>
-
- <p>Alternatively one can use HTTP URLs to load modules. For example,
-
- <pre>include("http://tinyclouds.org/node/mjsunit.js");</pre>
-
- <p>
- <code>include()</code> inserts the exported objects from the
- specified module into the global namespace.
- </p>
-
- <h3 id="onload"><code>onLoad</code></h3>
-
- <p>
- Because module loading does not happen instantaneously, and
- because Node has a policy of never blocking, a callback
- <code>onLoad</code> can be set that will notify the user when the
- included modules are loaded. Each file/module can have an
- <code>onLoad</code> callback.
- </p>
-
- <p>
- To export an object, add to the special <code>exports</code>
- object.
- The functions <code>fail</code> and
- <code>deepEquals</code> are not exported and remain private to
- the module.
-
- Alternatively, one can use <code>this</code> instead of
- <code>exports</code>.
- </p>
-
- <p>
- <code>require()</code> is like <code>include()</code> except
- does not polute the global namespace. It returns a namespace
- object. The exported objects can only be guaranteed to exist
- after the <code>onLoad()</code> callback is made. For example:
- </p>
- <pre>
-var mjsunit = require("mjsunit.js");
-function onLoad () {
- mjsunit.assertEquals(1, 2);
-}</pre>
-
- <p>
- <code>include()</code> and <code>require()</code> cannot be
- used after <code>onLoad()</code> is called.
- </p>
-
- <h3 id="onexit"><code>onExit</code></h3>
-
- <p>
- When the program exits a callback <code>onExit()</code> will be
- called for each module (children first).
- </p>
-
- <p>
- The <code>onExit()</code> callback cannot perform I/O as the process is
- going to forcably exit in several microseconds, however it is a good
- hook to perform some constant time checks of the module's state.
- It's useful for unit tests.
- </p>
-
-<pre>
-include("mjsunit.js");
-
-var timer_executed = false;
-
-setTimeout(function () {
- timer_executed = true
-}, 1000);
-
-function onExit () {
- assertTrue(timer_executed);
-}
-</pre>
-
- <p>
- Just to reiterate: <code>onExit()</code>, is not the place to close
- files or shutdown servers. The process will exit before they get
- performed.
- </p>
-
-</div>
-</body>
-</html>
diff --git a/website/api.txt b/website/api.txt
new file mode 100644
index 000000000..7ca8c61b0
--- /dev/null
+++ b/website/api.txt
@@ -0,0 +1,1009 @@
+NODE(1)
+=======
+Ryan Dahl <ry@tinyclouds.org>
+Version, 0.1.0, 2009.06.28
+
+
+== NAME
+
+node - purely event-based I/O for V8 javascript
+
+
+
+== SYNOPSIS
+
+An example of a web server written with Node which responds with "Hello
+World" after waiting two seconds:
+
+----------------------------------------
+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/");
+----------------------------------------
+
+To run the server, put the code into a file called +example.js+ and execute
+it with the node program
+
+----------------------------------------
+> node example.js
+Server running at http://127.0.0.1:8000/
+----------------------------------------
+
+
+== DESCRIPTION
+
+Node provides an easy way to build scalable network programs. In the above
+example, the 2 second delay does not prevent the server from handling new
+requests. Node tells the operating system (through +epoll+, +kqueue+,
++/dev/poll+, or +select+) that it should be notified when the 2 seconds are
+up or if a new connection is made--then it goes to sleep. If someone new
+connects, then it executes the callback, if the timeout expires, it executes
+the inner callback. Each connection is only a small heap allocation.
+
+This is in contrast to today's more common model where OS threads are employed
+for concurrency. Thread-based networking
+http://www.sics.se/~joe/apachevsyaws.html[is]
+http://www.kegel.com/c10k.html[relatively]
+http://bulk.fefe.de/scalable-networking.pdf[inefficient]
+and very difficult to use. Node will show much better memory efficiency
+under high-loads than systems which allocate 2mb thread stacks for each
+connection. Furthermore, users of Node are free from worries of
+dead-locking the process--there are no locks. In fact, no function in Node
+directly performs I/O. Because nothing blocks, less-than-expert programmers
+are able to develop fast systems.
+
+Node is similar in design to systems like Ruby's
+http://rubyeventmachine.com/[Event Machine]
+or Python's http://twistedmatrix.com/[Twisted].
+Node takes the event model a bit further. For example, in other systems there
+is always a blocking call to start the event-loop. Typically one defines
+behavior through callbacks at the beginning of a script and at the end starts a
+server through a call like +EventMachine::run()+. In Node it works differently.
+By default Node enters the event loop after executing the input script. Node
+exits the event loop when there are no more callbacks to perform. Like in
+traditional browser javascript, the event loop is hidden from the user.
+
+Node's HTTP API has grown out of my difficulties developing and working with
+web servers. For example, streaming data through most web frameworks is
+impossible. Or the oft-made false assumption that all message headers have
+unique fields. Node attempts to correct these and other problems in its API.
+Coupled with Node's purely evented infrastructure, it will make a more
+comprehensive foundation for future web libraries/frameworks.
+
+_But what about multiple-processor concurrency? Threads are necessary to scale
+programs to multi-core computers._ The name _Node_ should give some hint at how
+it is envisioned being used. Processes are necessary to scale to multi-core
+computers, not memory-sharing threads. The fundamentals of scalable systems are
+fast networking and non-blocking design--the rest is message passing. In the
+future, I'd like Node to be able to spawn new processes (probably using the
+http://www.whatwg.org/specs/web-workers/current-work/[Web Workers API]),
+but this is something that fits well into the current design.
+
+
+
+== API
+
+Callbacks are object members which are prefixed with
++on+. All methods and members are camel cased. Constructors
+always have a capital first letter.
+
+Node supports 3 byte-string encodings: ASCII (+"ascii"+), UTF-8 (+"utf8"+),
+and raw binary (+"raw"+). It uses strings to represent ASCII and UTF-8
+encoded data. For the moment, arrays of integers are used to represent raw
+binary data--this representation is rather inefficient. This will
+change in the future, when
+http://code.google.com/p/v8/issues/detail?id=270[V8 supports Blob objects].
+
+Unless otherwise noted, functions are all asynchronous and do not block
+execution.
+
+
+=== Helpers
+
++puts(string)+::
+Alias for +stdout.puts()+. Outputs the +string+ and a trailing new-line to
++stdout+.
++
+Everything in node is asynchronous; +puts()+ is no exception. This might
+seem ridiculous but, if for example, one is piping +stdout+ into an NFS
+file, +printf()+ will block from network latency. There is an internal
+queue for +puts()+ output, so you can be assured that output will be
+displayed in the order it was called.
+
+
++node.debug(string)+::
+A synchronous output function. Will block the process and
+output the string immediately to stdout.
+
+
++p(object)+ ::
+Print the JSON representation of +object+ to the standard output.
+
+
++print(string)+::
+Like +puts()+ but without the trailing new-line.
+
+
++node.exit(code)+::
+Immediately ends the process with the specified code.
+
+
+
+=== Global Variables
+
+
+
++ARGV+ ::
+An array containing the command line arguments.
+
+
++stdout+, +stderr+, and +stdin+ ::
+Objects of type +node.fs.File+. (See below.)
+
++__filename+ ::
+The filename of the script being executed.
+
+
+
+=== Events
+
+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 +node.EventEmitter+.
+
+Events are represented by a snakecased string. Here are some examples:
++"connection"+, +"receive"+, +"message_begin"+.
+
+Functions can be then be attached to objects, to be executed when an event
+is emitted. These functions are called _listeners_.
+
+Some asynchronous file operations return an +EventEmitter+ called a
+_promise_. A promise emits just a single event when the operation is
+complete.
+
+==== +node.EventEmitter+
+
++emitter.addListener(event, listener)+ ::
+Adds a listener to the end of the listeners array for the specified event.
++
+----------------------------------------
+server.addListener("connection", function (socket) {
+ puts("someone connected!");
+});
+----------------------------------------
+
+
++emitter.listeners(event)+ ::
+Returns an array of listeners for the specified event. This array can be
+manipulated, e.g. to remove listeners.
+
++emitter.emit(event, args)+ ::
+Execute each of the listeners in order with the array +args+ as arguments.
+
+==== +node.Promise+
+
++node.Promise+ inherits from +node.eventEmitter+. A promise emits one of two
+events: +"success"+ or +"error"+. After emitting its event, it will not
+emit anymore events.
+
++promise.addCallback(listener)+ ::
+Adds a listener for the +"success"+ event. Returns the same promise object.
+
++promise.addErrback(listener)+ ::
+Adds a listener for the +"error"+ event. Returns the same promise object.
+
+
+
+
+=== Modules
+
+Node has a simple module loading system. In Node, files and modules are in
+one-to-one correspondence. As an example, +foo.js+ loads the module
++circle.js+.
+
+The contents of +foo.js+:
+
+----------------------------------------
+var circle = require("circle.js");
+function onLoad () {
+ puts("The area of a cirlce of radius 4 is " + circle.area(4));
+}
+----------------------------------------
+
+The contents of +circle.js+:
+
+----------------------------------------
+var PI = 3.14;
+
+exports.area = function (r) {
+ return PI * r * r;
+};
+
+exports.circumference = function (r) {
+ return 2 * PI * r;
+};
+----------------------------------------
+
+The module +circle.js+ has exported the functions +area()+ and
++circumference()+. To export an object, add to the special +exports+
+object. (Alternatively, one can use +this+ instead of +exports+.) Variables
+local to the module will be private. In this example the variable +PI+ is
+private to +circle.js+.
+
+The module path is relative to the file calling +require()+. That is,
++circle.js+ must be in the same directory as +foo.js+ for +require()+ to
+find it.
+
+HTTP URLs can also be used to load modules. For example,
+
+----------------------------------------
+var circle = require("http://tinyclouds.org/node/circle.js");
+----------------------------------------
+
+Like +require()+ the function +include()+ also loads a module. Instead of
+returning a namespace object, +include()+ will add the module's exports into
+the global namespace. For example:
+
+----------------------------------------
+include("circle.js");
+function onLoad () {
+ puts("The area of a cirlce of radius 4 is " + area(4));
+}
+----------------------------------------
+
+
+==== +onLoad()+
+
+Because module loading does not happen instantaneously and because Node has
+a policy of never blocking, a callback +onLoad+ can be set that will notify
+the user when the included modules are loaded. Each file/module can have
+its own +onLoad+ callback.
+
++include()+ and +require()+ cannot be used after +onLoad()+ is called.
+
+
+==== +onExit()+
+
+When the program exits a callback +onExit()+ will be called for each module
+(children first).
+
+The +onExit()+ callback cannot perform I/O since the process is going to
+forcably 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:
+
+----------------------------------------
+include("asserts.js");
+
+var timer_executed = false;
+
+setTimeout(function () {
+ timer_executed = true
+}, 1000);
+
+function onExit () {
+ assertTrue(timer_executed);
+}
+----------------------------------------
+
+Just to reiterate: +onExit()+, is not the place to close files or shutdown
+servers. The process will exit before they get performed.
+
+
+
+=== Timers
+
+
++setTimeout(callback, delay)+::
+To schedule execution of callback after delay milliseconds. Returns a
++timeoutId+ for possible use with +clearTimeout()+.
+
+
++clearTimeout(timeoutId)+::
+Prevents said timeout from triggering.
+
+
++setInterval(callback, delay)+::
+To schedule the repeated execution of callback everydelay milliseconds. Returns
+a +intervalId+ for possible use with +clearInterval()+.
+
+
++clearInterval(intervalId)+::
+Stops a interval from triggering.
+
+
+=== Child Processes
+
+Node provides a tridirectional +popen(3)+ facility through the class
++node.Process+. It is possible to stream data through the child's +stdin+,
++stdout+, and +stderr+ in a fully non-blocking way.
+
+==== +node.Process+
+
+.Events
+[cols="1,2,10",options="header"]
+|=========================================================
+|Event |Parameters |Notes
+
+|+"output"+ | +data+ |
+Each time the child process sends data to its +stdout+, this event is
+triggered. +data+ is a string. At the moment all data passed to +stdout+ is
+interrpreted as UTF-8 encoded.
++
+If the child process closes its +stdout+ stream (a common thing to do on
+exit), this event will be emitted with +data === null+.
+
+
+|+"error"+ | +data+ |
+Identical to the +"output"+ event except for +stderr+ instead of +stdout+.
+
+|+"exit"+ | +code+ |
+This event is emitted after the child process ends. +code+ is the final exit
+code of the process. One can be assured that after this event is emitted
+that the +"output"+ and +"error"+ callbacks will no longer be made.
+
+|=========================================================
+
++new node.Process(command)+::
+Launches a new process with the given +command+. For example:
++
+----------------------------------------
+var ls = new node.Process("ls -lh /usr");
+ls.addListener("output", function (data) {
+ puts(data);
+});
+----------------------------------------
+
+
++process.pid+ ::
+The PID of the child process.
+
+
++process.write(data, encoding="ascii")+ ::
+Write data to the child process's +stdin+. The second argument is optional and
+specifies the encoding: possible values are +"utf8"+, +"ascii"+, and +"raw"+.
+
+
++process.close()+ ::
+Closes the process's +stdin+ stream.
+
+
++process.kill(signal=node.SIGTERM)+ ::
+Send a single to the child process. If no argument is given, the process
+will be sent +node.SIGTERM+. The standard POSIX signals are defined under
+the +node+ namespace (+node.SIGINT+, +node.SIGUSR1+, ...).
+
+
+
+=== File I/O
+
+This part of the API is split into two parts: simple wrappers
+around standard POSIX file I/O functions and a user-friendly
++File+ object.
+
+==== POSIX Wrappers
+
+All POSIX wrappers have a similar form.
+They return a promise (+node.Promise+). Example:
+
+----------------------------------------
+var promise = node.fs.unlink("/tmp/hello");
+promise.addCallback(function () {
+ puts("successfully deleted /tmp/hello");
+});
+----------------------------------------
+
+There is no guaranteed ordering to the POSIX wrappers. The
+following is very much prone to error
+
+----------------------------------------
+node.fs.rename("/tmp/hello", "/tmp/world");
+node.fs.stat("/tmp/world").addCallback(function (stats) {
+ puts("stats: " + JSON.stringify(stats));
+});
+----------------------------------------
+
+It could be that +stat()+ is executed before the +rename()+.
+The correct way to do this is to chain the promises.
+
+----------------------------------------
+node.fs.rename("/tmp/hello", "/tmp/world")
+ .addCallback(function () {
+ node.fs.stat("/tmp/world")
+ .addCallback(function (stats) {
+ puts("stats: " + JSON.stringify(stats));
+ });
+ });
+----------------------------------------
+
+
++node.fs.rename(path1, path2)+ ::
+ See rename(2).
+ - on success: no parameters.
+ - on error: no parameters.
+
+
+
++node.fs.stat(path)+ ::
+ See stat(2).
+ - on success: Returns +stats+ object. It looks like this:
+ +{ 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" }+
+ - on error: no parameters.
+
++node.fs.unlink(path)+ ::
+ See unlink(2)
+ - on success: no parameters.
+ - on error: no parameters.
+
+
++node.fs.rmdir(path)+ ::
+ See rmdir(2)
+ - on success: no parameters.
+ - on error: no parameters.
+
+
++node.fs.close(fd)+ ::
+ See close(2)
+ - on success: no parameters.
+ - on error: no parameters.
+
+
++node.fs.open(path, flags, mode)+::
+ See open(2). The constants like +O_CREAT+ are defined at +node.O_CREAT+.
+ - on success: +fd+ is given as the parameter.
+ - on error: no parameters.
+
+
++node.fs.write(fd, data, position)+::
+ Write data to the file specified by +fd+. +data+ is either an array of
+ integers (for raw data) or a string for UTF-8 encoded characters.
+ +position+ refers to the offset from the beginning of the file where this
+ data should be written. If +position+ is +null+, the data will be written at
+ the current position. See pwrite(2).
+ - on success: returns an integer +written+ which specifies how many _bytes_ were written.
+ - on error: no parameters.
+
+
++node.fs.read(fd, length, position, encoding)+::
+
+Read data from the file specified by +fd+.
++
++length+ is an integer specifying the number of
+bytes to read.
++
++position+ is an integer specifying where to begin
+reading from in the file.
++
++encoding+ is either +node.UTF8+
+or +node.RAW+.
++
+- on success: returns +data+, what was read from the file.
+- on error: no parameters.
+
+
+==== +node.fs.File+
+
+A buffered file object.
+
+Internal request queues exist for each instance of +node.fs.File+ so that
+multiple commands can be issued at once. Thus the following is safe:
+
+----------------------------------------
+var file = new node.fs.File();
+file.open("/tmp/blah", "w+");
+file.write("hello");
+file.write("world");
+file.close();
+----------------------------------------
+
+[cols="1,2,10",options="header"]
+|=========================================================
+|Event |Parameters | Notes
+|+"error"+ | | Emitted if an error happens.
+|=========================================================
+
++new node.fs.File(options={})+::
+Creates a new file object.
++
+The +options+ argument is optional. It can contain
+the following fields
++
+- +fd+: a file descriptor for the file.
+- +encoding+: how +file.read()+ should return data. Either +"raw"+ or +"utf8"+.
+Defaults to +"raw"+.
+
+
++file.open(path, mode)+::
+Opens the file at +path+.
++
++mode+ is a string:
++
+- "r", open for reading and writing.
+- "r+", open for only reading.
+- "w", create a new file for reading and writing; if it already exists truncate it.
+- "w+", create a new file for writing only; if it already exists truncate it.
+- "a", create a new file for writing and reading. Writes append to the end of the file.
+- "a+"
+
+
++file.read(length, position)+::
+Reads +length+ bytes from the file at +position+. +position+ can be omitted
+to write at the current file position.
+
+
++file.write(data, position)+::
+Writes +data+ to the file. +position+ can be omitted to write at the current
+file position.
+
+
++file.close()+::
+Closes the file.
+
+
+=== HTTP
+
+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.
+
+HTTP message headers are represented by an array of 2-element
+arrays like this
+
+----------------------------------------
+ [ ["Content-Length", "123"]
+ , ["Content-Type", "text/plain"]
+ , ["Connection", "keep-alive"]
+ , ["Accept", "*/*"]
+ ]
+----------------------------------------
+
+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. _This is left to the user._
+
+
+==== +node.http.Server+
+
+[cols="1,2,10",options="header"]
+|=========================================================
+|Event | Parameters | Notes
+
+|+"request"+ | +request, response+ |
++request+ is an instance of +node.http.ServerRequest+
++
++response+ is an instance of +node.http.ServerResponse+
+
+|+"connection"+ | +connection+ |
+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+.
+
+|=========================================================
+
++node.http.createServer(request_listener, options);+ ::
+Returns a new web server object.
++
+The +options+ argument is optional. The
++options+ argument accepts the same values as the
+options argument for +node.tcp.Server+ does.
++
+The +request_listener+ is a function which is automatically
+added to the +"request"+ event.
+
++server.listen(port, hostname)+ ::
+Begin accepting connections on the specified port and hostname.
+If the hostname is omitted, the server will accept connections
+directed to any address.
+
++server.close()+ ::
+Stops the server from accepting new connections.
+
+
+
+==== +node.http.ServerRequest+
+
+This object is created internally by a HTTP server--not by
+the user--and passed as the first argument to a +"request"+ listener.
+
+[cols="1,2,10",options="header"]
+|=========================================================
+|Event | Parameters | Notes
+
+|+"body"+ | +chunk+ |
+Emitted when a piece of the message body is received. Example: A chunk of
+the body is given as the single argument. The transfer-encoding has been
+decoded. The body chunk 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 +request.setBodyEncoding()+.
+
+|+"complete"+ | |
+Emitted exactly once for each message. No arguments.
+After emitted no other events will be emitted on the request.
+
+|=========================================================
+
++request.method+ ::
+The request method as a string. Read only. Example:
++"GET"+, +"DELETE"+.
+
+
++request.uri+ ::
+Request URI Object. This contains only the parameters that are
+present in the actual http request. That is, if the request is
++
+----------------------------------------
+GET /status?name=ryan HTTP/1.1\r\n
+Accept: */*\r\n
+\r\n
+----------------------------------------
++
+Then +request.uri+ will be
++
+----------------------------------------
+{ path: "/status",
+ file: "status",
+ directory: "/",
+ params: { "name" : "ryan" }
+}
+----------------------------------------
++
+In particular, note that +request.uri.protocol+ is
++undefined+. This is because there was no URI protocol given
+in the actual HTTP Request.
++
++request.uri.anchor+, +request.uri.query+, +request.uri.file+, +request.uri.directory+, +request.uri.path+, +request.uri.relative+, +request.uri.port+, +request.uri.host+, +request.uri.password+, +request.uri.user+, +request.uri.authority+, +request.uri.protocol+, +request.uri.params+, +request.uri.toString()+, +request.uri.source+
+
+
++request.headers+ ::
+The request headers expressed as an array of 2-element arrays.
+Read only.
+
+
++request.httpVersion+ ::
+The HTTP protocol version as a string. Read only. Examples:
++"1.1"+, +"1.0"+
+
+
++request.setBodyEncoding(encoding)+ ::
+Set the encoding for the request body. Either +"utf8"+ or +"raw"+. Defaults
+to raw.
+
++request.connection+ ::
+The +node.http.Connection+ object.
+
+
+==== +node.http.ServerResponse+
+
+This object is created internally by a HTTP server--not by the user. It is
+passed as the second parameter to the +"request"+ event.
+
++response.sendHeader(statusCode, headers)+ ::
+
+Sends a response header to the request. The status code is a 3-digit HTTP
+status code, like +404+. The second argument, +headers+, should be an array
+of 2-element arrays, representing the response headers.
++
+Example:
++
+----------------------------------------
+var body = "hello world";
+response.sendHeader(200, [
+ ["Content-Length", body.length],
+ ["Content-Type", "text/plain"]
+]);
+----------------------------------------
++
+This method must only be called once on a message and it must
+be called before +response.finish()+ is called.
+
++response.sendBody(chunk, encoding="ascii")+ ::
+
+This method must be called after +sendHeader+ was
+called. It sends a chunk of the response body. This method may
+be called multiple times to provide successive parts of the body.
++
+If +chunk+ is a string, the second parameter
+specifies how to encode it into a byte stream. By default the
++encoding+ is +"ascii"+.
++
+Note: This is the raw HTTP body and has nothing to do with
+higher-level multi-part body encodings that may be used.
+
+
++response.finish()+ ::
+This method signals to the server that all of the response headers and body
+has been sent; that server should consider this message complete.
+The method, +response.finish()+, MUST be called on each
+response.
+
+
+
+==== +node.http.Client+
+
+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. _Currently the implementation does not pipeline requests._
+
+Example of connecting to +google.com+
+
+----------------------------------------
+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);
+ });
+});
+----------------------------------------
+
++node.http.createClient(port, host)+ ::
+
+Constructs a new HTTP client. +port+ and
++host+ refer to the server to be connected to. A
+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)+ ::
+
+Issues a request; if necessary establishes connection. Returns a +node.http.ClientRequest+ instance.
++
++request_headers+ is optional.
++request_headers+ should be an array of 2-element
+arrays. Additional request headers might be added internally
+by Node. Returns a +ClientRequest+ object.
++
+Do remember to include the +Content-Length+ header if you
+plan on sending a body. If you plan on streaming the body, perhaps
+set +Transfer-Encoding: chunked+.
++
+NOTE: the request is not complete. This method only sends
+the header of the request. One needs to call
++request.finish()+ to finalize the request and retrieve
+the response. (This sounds convoluted but it provides a chance
+for the user to stream a body to the server with
++request.sendBody()+.)
+
+
+==== +node.http.ClientRequest+
+
+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
+already been sent.
+
+[cols="1,2,10",options="header"]
+|=========================================================
+|Event | Parameters | Notes
+|+"response"+ | +response+ |
+Emitted when a response is received to this request. Typically the user will
+set a listener to this via the +request.finish()+ method.
++
+This event is emitted only once.
++
+The +response+ argument will be an instance of +node.http.ClientResponse+.
+|=========================================================
+
+
++request.sendBody(chunk, encoding="ascii")+ ::
+
+Sends a sucessive peice of the body. By calling this method
+many times, the user can stream a request body to a
+server&mdash;in that case it is suggested to use the
++["Transfer-Encoding", "chunked"]+ header line when
+creating the request.
++
+The +chunk+ argument should be an array of integers
+or a string.
++
+The +encoding+ argument is optional and only
+applies when +chunk+ is a string. The encoding
+argument should be either +"utf8"+ or
++"ascii"+. By default the body uses ASCII encoding,
+as it is faster.
+
+
++request.finish(response_listener)+ ::
+
+Finishes sending the request. If any parts of the body are
+unsent, it will flush them to the socket. If the request is
+chunked, this will send the terminating +"0\r\n\r\n"+.
++
+The parameter +response_listener+ is a callback which
+will be executed when the response headers have been received.
+The +response_listener+ callback is executed with one
+argument which is an instance of +node.http.ClientResponse+.
+
+
+
+==== +node.http.ClientResponse+
+
+This object is created internally and passed to the +"response"+ event.
+
+[cols="1,2,10",options="header"]
+|=========================================================
+|Event | Parameters | Notes
+
+|+"body"+ | +chunk+ |
+Emitted when a piece of the message body is received. Example: A chunk of
+the body is given as the single argument. The transfer-encoding has been
+decoded. The body chunk 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 +response.setBodyEncoding()+.
+
+|+"complete"+ | |
+Emitted exactly once for each message. No arguments.
+After emitted no other events will be emitted on the response.
+
+|=========================================================
+
++response.statusCode+ ::
+ The 3-digit HTTP response status code. E.G. +404+.
+
++response.httpVersion+ ::
+ The HTTP version of the connected-to server. Probably either
+ +"1.1"+ or +"1.0"+.
+
++response.headers+ ::
+ The response headers. An Array of 2-element arrays.
+
++response.setBodyEncoding(encoding)+ ::
+ Set the encoding for the response body. Either +"utf8"+ or +"raw"+.
+ Defaults to raw.
+
+
+
+=== TCP
+
+==== +node.tcp.Server+
+
+Here is an example of a echo server which listens for connections
+on port 7000
+
+----------------------------------------
+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, {backlog: 1024});
+server.listen(7000, "localhost");
+----------------------------------------
+
+
+[cols="1,2,10",options="header"]
+|=========================================================
+|Event | Parameters | Notes
+|+"connection"+ | +connection+ | Emitted when a new connection is made.
+ +connection+ is an instance of +node.tcp.Connection+.
+|=========================================================
+
++node.tcp.createServer(connection_listener, options={});+ ::
+Creates a new TCP server.
++
+The +connection_listener+ argument is automatically set as a listener for
+the +"connection"+ event.
++
++options+ for now only supports one option:
++backlog+ which should be an integer and describes
+how large of a connection backlog the operating system should
+maintain for this server. The +backlog+ defaults
+to 1024.
+
+
++server.listen(port, host=null)+ ::
+Tells the server to listen for TCP connections to +port+
+and +host+. Note, +host+ is optional. If
++host+ is not specified the server will accept
+connections to any IP address on the specified port.
+
+
++server.close()+::
+Stops the server from accepting new connections.
+
+
+==== +node.tcp.Connection+
+
+This object is used as a TCP client and also as a server-side
+socket for +node.tcp.Server+.
+
+[cols="1,2,10",options="header"]
+|=========================================================
+|Event | Parameters | Notes
+|+"connect"+ | | Call once the connection is established.
+|+"receive"+ | +data+ | Called when data is received on the
+ connection. Encoding of data is set
+ by +connection.setEncoding()+. +data+
+ will either be a string, in the case of
+ utf8, or an array of integer in the case
+ of raw encoding.
+|+"eof"+ | | Called when the other end of the
+ connection sends a FIN packet.
+ After this is emitted the +readyState+
+ will be +"writeOnly"+. One should probably
+ just call +connection.close()+ when this
+ event is emitted.
+|+"disconnect"+ | +had_error+ | Emitted once the connection is fully
+ disconnected. The argument +had_error+
+ is a boolean which says if the connection
+ was closed due to a transmission error.
+ (TODO: access error codes.)
+|=========================================================
+
++new node.tcp.Connection()+::
+ Creates a new connection object.
+
+
++connection.connect(port, host="127.0.0.1")+::
+ Opens a connection to the specified +port+ and
+ +host+. If the second parameter is omitted, localhost is
+ assumed.
+
+
++connection.remoteAddress+::
+The string representation of the remote IP address. For example,
++"74.125.127.100"+ or +"2001:4860:a005::68"+.
++
+This member is only present in server-side connections.
+
+
++connection.readyState+::
+Either +"closed"+, +"open"+, +"opening"+, +"readOnly"+, or +"writeOnly"+.
+
+
++connection.setEncoding(encoding)+::
+Sets the encoding (either +"utf8"+ or +"raw"+) for data that is received.
+
+
++connection.send(data, encoding="ascii")+::
+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.
+
+
++connection.close()+::
+Half-closes the connection. I.E. sends a FIN packet. It is
+possible the server will still send some data. After calling
+this +readyState+ will be +"readOnly"+.
+
+
++connection.fullClose()+::
+Close both ends of the connection. Data that is received
+after this call is responded to with RST packets. If you don't
+know about this, just use +close()+.
+
+
++connection.forceClose()+::
+Ensures that no more I/O activity happens on this socket. Only
+necessary in case of errors (parse error or so).
+
+
+
+
+
+// vim: set syntax=asciidoc: