You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

350 lines
13 KiB

<html lang=en-US-x-hixie>
<head>
<title>Node API</title>
<!-- <link href="specification.css" rel=stylesheet>-->
<link href="http://www.whatwg.org/style/specification" rel=stylesheet>
<body class=draft>
<div class=head>
<!--
<p><a class=logo href="http://www.whatwg.org/" rel=home><img alt=WHATWG
src="../../../images/logo"></a></p>
-->
<h1>Node API</h1>
<h2 class="no-num no-toc"
id=draft-recommendation-mdash-date-01-jan-1>Draft</h2>
<dl>
<dt>This version:
<dd><a href="index.html">http://tinyclouds.org/node</a>
</dl>
<p class=copyright>&copy; Copyright 2009 Ryan Dahl</p>
<p class=copyright>You are granted a license to use, reproduce and create
derivative works of this document.</p>
</div>
<hr>
<h2 class="no-num no-toc" id=abstract>Abstract</h2>
<p>This specification defines a javascript API for creating
servers and clients based around an event loop. It is provided to document
Node's interface and provide a specification for similar efforts.
<h2 class="no-num no-toc" id=contents>Table of contents</h2>
<!--begin-toc-->
<ul class=toc>
<li><a href="index.html#introduction"><span class=secno>1 </span>Introduction</a>
<ul class=toc>
<li><a href="index.html#the-event-loop"><span class=secno>1.1 </span>The event loop</a>
<li><a href="index.html#execution-context"><span class=secno>1.2 </span>Execution context</a>
</ul>
<li><a href="index.html#http_server"><span class=secno>2 </span>HTTP Server</a>
<ul class=toc>
<li><a href="index.html#http_request"><span class=secno>2.1 </span>Request object</a>
</ul>
<li><a href="index.html#tcp_client"><span class=secno>3 </span>TCP Client</a>
<li><a href="index.html#timers"><span class=secno>4 </span>Timers</a>
<li><a href="index.html#blocking"><span class=secno>5 </span>Blocking
Functions</a>
</ul>
<!--end-toc-->
<hr>
<h2 id=introduction><span class=secno>1 </span>Introduction</h2>
<p>This specification defines an API for creating evented servers and
clients in javascript. It can be considered documentation for the Node
project and will be versioned with that software. However, in places the
API is only a specification and does not reflect Node's
behavior&mdash;there I will try to note the difference.
<p>Unless otherwise noted, a function is non-blocking. Non-blocking means
that program execution will continue without waiting for an I/O event
(be that network or device).
<h3 id=the-event-loop><span class=secno>1.1 </span>The event loop</h3>
<p>The program is run event loop. There are no concurrent
operations. As long as there are pending events the program will continue
running. If however there arn't any pending callbacks waiting for
something to happen, the program will exit.
<h3 id=execution-context><span class=secno>1.2 </span>Execution context</h3>
<p>Global data is shared between callbacks.
<p>
<code>spawn()</code> to start a new context/event loop?
<h2 id=http_server><span class=secno>2 </span>HTTP Server</h2>
<pre class=idl>[Constructor(in String host, in String port)]
interface <dfn id=httpserver>HTTPServer</dfn> {
readonly attribute String <a href="index.html#host">host</a>;
readonly attribute String <a href="index.html#port">port</a>;
// networking
attribute Function <a href="index.html#onrequest">onrequest</a>;
void close(); // yet not implemented
};</pre>
<p class="big-issue"> error handling? </p>
<h3 id=http_request><span class=secno>2.1 </span>Request object</h3>
<pre class=idl>interface <dfn id=httprequest>HTTPRequest</dfn> {
readonly attribute String <a href="index.html#path">path</a>;
readonly attribute String <a href="index.html#uri">uri</a>;
readonly attribute String <a href="index.html#query_string">query_string</a>;
readonly attribute String <a href="index.html#fragment">fragment</a>;
readonly attribute String <a href="index.html#method">method</a>;
readonly attribute String <a href="index.html#http_version">http_version</a>;
readonly attribute Array <a href="index.html#headers">headers</a>;
// ready state
const unsigned short HEADERS_RECEIVED = 0;
const unsigned short LOADING = 1;
const unsigned short DONE = 2;
readonly attribute long readyState;
attribute Function <a href="index.html#onbody">onbody</a>;
void respondHeader (in short status, in Array headers);
void respondBody (in ByteArray data);
};</pre>
<p class="big-issue">issue: client ip address</p>
<p> A request object is what is passed to <code>HTTPServer.onrequest</code>.
it represents a single HTTP request. Clients might preform HTTP
pipelining (Keep-Alive) and send multiple requests per TCP
connection&mdash;this does not affect this interface.
<p> If any error is encountered either with the request or while using the
two response methods the connection to client immediately terminated.
<dl>
<dt><code>respondHeader(status, headers)</code></dt>
<dd>
<p>This method sends the response status line and headers.
This method may only be called once. After the first, calling it
will raise an <code>INVALID_STATE_ERR</code> exception.
<p>The <code>status</code> argument is an integer HTTP status response code as
defined in 6.1 of <a href="#rfc2616">RFC 2616</a>.
<p>The <code>header</code> argument is an <code>Array</code> of
tuples (a two-element <code>Array</code>). For example
<pre>[["Content-Type", "text/plain"], ["Content-Length", 10]]</pre>
<p>This array determines the response headers. If the
<code>header</code> parameter includes elements that are not tuples it
raises <code>SYNTAX_ERR</code>. If the elements of the tuples do not
respond to <code>toString()</code> the method raises
<code>SYNTAX_ERR</code>.
<p>Besides the author response headers interpreters should not
include additional response headers. This ensures that authors
have a reasonably predictable API.
<p>If the client connection was closed for any reason, calling
<code>respondHeader()</code> will raise a <code>NETWORK_ERR</code>
exception.
</dd>
<dt><code>respondBody(data)</code></dt>
<dd>
<p>This method must be called after <code>respondHeader()</code>. If
<code>respondHeader()</code> has not been called it will raise an
<code>INVALID_STATE_ERR</code> exception.
<p>When given a <code>String</code> or <code>ByteArray</code> the
interpreter will send the data.
<p>Given a <code>null</code> argument signals end-of-response.
<p class="note"> The author must call <code>respondBody(null)</code>
for each response, even if the response has no body.</p>
<p>After the end-of-response, calling <code>respondHeader()</code> or
<code>respondBody()</code> will raise an <code>INVALID_STATE_ERR</code> exception.
<p>If the client connection was closed for any reason, calling
<code>respondBody()</code> will raise a <code>NETWORK_ERR</code>
exception.
</dd>
</dl>
<h2 id=tcp_client><span class=secno>3 </span>TCP Client</h2>
<pre class=idl>[Constructor(in String host, in String port)]
interface <dfn id=tcpclient>TCPClient</dfn> {
readonly attribute String <a href="index.html#host">host</a>;
readonly attribute String <a href="index.html#port">port</a>;
// ready state
const unsigned short CONNECTING = 0;
const unsigned short OPEN = 1;
const unsigned short CLOSED = 2;
readonly attribute long readyState;
// networking
attribute Function <a href="index.html#onopen">onopen</a>;
attribute Function <a href="index.html#onread">onread</a>;
attribute Function <a href="index.html#onclose">onclose</a>;
void write(in ByteArray data);
void disconnect();
};</pre>
<dl>
<dt><code>TCPClient(host, port)</code></dt>
<dd>
<p>When a <code><a href="#connection0">TCPClient</a></code> object is
created, the the interpreter must try to establish a connection.
If the <code>host</code> parameter is not an IP address it
will be looked up using the DNS.
</dd>
<dt><code>write(data)</code></dt>
<dd>
<p>Transmits data using the connection. If the connection is not yet
established or the connection is closed, calling <code>write()</code>
will raise an <code>INVALID_STATE_ERR</code> exception. </p>
<p><code>write(null)</code> sends an EOF to the peer. Further writing
is disabled. However the <code>onread</code> callback may still
be executed.
</dd>
<dt><code>disconnect()</code></dt>
<dd>
<p>Closes the connection, if it is open. If the connection is already
closed, it does nothing. Closing the connection causes a
<code>onclose</code> callback to be made and the
<code><a href="#readystate0">readyState</a></code> attribute's value to
change to <code>CLOSED</code>.
Note that a connection might not be closed instantaniously. In the
case of secure connection some "goodbye" transmission might be sent.
</dd>
</dl>
<p>The <dfn id="readystate0"><code>readyState</code></dfn> attribute
represents the state of the connection. When the object is created it must
be set to <code>CONNECTING</code>.
<p id="onopen">Once a connection is established, the
<code>readyState</a></code> attribute's value must be changed to
<code>OPEN</code>, and the <code>onopen</code> callback will be made.
<p id="onread">When data is received, the <code>onread</code> callback
will be made with a single parameter: a <code>ByteArray</code> containing a
chunk of data. The author does not have the ability to control how much data
is received nor the ability to stop the input besides disconnecting.
<!-- conf crit for this
statement is in the various protocol-specific sections below. -->
<p id="onclose">When the connection is closed, the <code
>readyState</a></code>
attribute's value must be changed to <code>CLOSED</code>, and the <code
>onclose</a></code> callback
will be made.
<h2 id=timers><span class=secno>4 </span>Timers</h2>
<p>Timers allow one to schedule an event at a later date.
There are four globally exposed functions
<code>setTimeout</code>,
<code>clearTimeout</code>,
<code>setInterval</code>, and
<code>clearInterval</code>.
These functions work similarly
<a href="http://www.w3.org/TR/Window/#window-timers">as in the browser</a> except that
the <code>timerID</code> and <code>intervalID</code> do not necessarily have
type <code>long</code> but are rather opaque objects.
<dl>
<dt><code>setTimeout(function, milliseconds)</code></dt>
<dd>
<p>This method calls the function once after a specified number of
milliseconds elapses, until canceled by a call to <code>clearTimeout</code>.
The methods returns a <code>timerID</code> which may be used in a
subsequent call to <code>clearTimeout</code> to cancel the callback.
</dd>
<dt><code>setInterval(function, milliseconds)</code></dt>
<dd>
<p>This method calls the function every time a specified number of
milliseconds elapses, until canceled by a call to <code>clearInterval</code>.
The methods returns a <code>intervalID</code> which may be used in a
subsequent call to <code>clearInterval</code> to cancel the interval.
</dd>
<dt><code>clearTimeout(timerID)</code></dt>
<dd>
<p>Cancels a timeout that was set with the <code>setTimeout</code>
method.
</dd>
<dt><code>clearInterval(intervalID)</code></dt>
<dd>
<p>Cancels an interval that was set with the <code>setInterval</code> method.
</dd>
</dl>
<h2 id=blocking><span class=secno>5 </span>Blocking Functions</h2>
<p>Node includes a number of blocking functions in its API. Some of these
will be removed in the future as the software improves.
<dl>
<dt><code>log(string)</code></dt>
<dd>
<p>This function outputs the string to the stadard output device
(usually the console).
Its speed is dependent on where stdout is piped to.
</dd>
<dt><code>blockingFileRead(filename)</code></dt>
<dd>
<p>This method opens a file from the file system and returns its
contents as a <code>ByteArray</code>. This function can be extremely
expensive depending on the response time of the file system. It should
only be used in start up.
</dd>
</dl>
<h2 class=no-num id=references>References</h2>
<dl>
<dt>[<dfn id=rfc2616>RFC2616</dfn>]
<dd><cite><a href="http://ietf.org/rfc/rfc2616">Hypertext Transfer
Protocol -- HTTP/1.1</a></cite>, R. Fielding, J. Gettys, J. Mogul,
H. Frystyk, L. Masinter, P. Leach, T. Berners-Lee, editors. IETF,
June 1999.