diff --git a/spec/index.html b/spec/index.html deleted file mode 100644 index a75e25216ca..00000000000 --- a/spec/index.html +++ /dev/null @@ -1,355 +0,0 @@ - - - - Node API - - - - -
- - -

Node API

- -

Draft

- -
-
This version: - -
http://tinyclouds.org/node - -
- - - - -
- -
- -

Abstract

- -

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. - -

Table of contents

- - - - - -
- -

1 Introduction

- -

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—there I will try to note the difference. - -

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). - - -

1.1 The event loop

- -

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. - -

1.2 Execution context

- -

Global data is shared between callbacks. - -

- spawn() to start a new context/event loop? - -

2 HTTP Server

-
[Constructor(in String host, in String port, in Function
-  onrequest)]
-interface HTTPServer  {
-  readonly attribute String host;
-  readonly attribute String port;
-
-  // networking                
-    attribute Function onrequest;
-  void close(); // yet not implemented
-};
- -
-
HTTPServer(host, port, onrequest)
-
- -

error handling?

- - -

2.1 Request object

-
interface HTTPRequest  {
-  readonly attribute String path;
-  readonly attribute String uri;
-  readonly attribute String query_string;
-  readonly attribute String fragment;
-  readonly attribute String method;
-  readonly attribute String http_version;
-  readonly attribute Array headers;
-
-  // ready state
-  const unsigned short HEADERS_RECEIVED = 0;
-  const unsigned short LOADING = 1;
-  const unsigned short DONE = 2;
-  readonly attribute long readyState;
-
-    attribute Function onbody;
-
-  void respondHeader (in short status, in Array headers);
-  void respondBody (in ByteArray data);
-};
- -

issue: client ip address

- -

A request object is what is passed to HTTPServer.onrequest. - it represents a single HTTP request. Clients might preform HTTP - pipelining (Keep-Alive) and send multiple requests per TCP - connection—this does not affect this interface. - -

If any error is encountered either with the request or while using the - two response methods the connection to client immediately terminated. - -

-
respondHeader(status, headers)
-
-

This method sends the response status line and headers. - This method may only be called once. After the first, calling it - will raise an INVALID_STATE_ERR exception. - -

The status argument is an integer HTTP status response code as - defined in 6.1 of RFC 2616. - -

The header argument is an Array of - tuples (a two-element Array). For example - -

[["Content-Type", "text/plain"], ["Content-Length", 10]]
- -

This array determines the response headers. If the - header parameter includes elements that are not tuples it - raises SYNTAX_ERR. If the elements of the tuples do not - respond to toString() the method raises - SYNTAX_ERR. - -

Besides the author response headers interpreters should not - include additional response headers. This ensures that authors - have a reasonably predictable API. - -

If the client connection was closed for any reason, calling - respondHeader() will raise a NETWORK_ERR - exception. -

- -
respondBody(data)
-
-

This method must be called after respondHeader(). If - respondHeader() has not been called it will raise an - INVALID_STATE_ERR exception. - -

When given a String or ByteArray the - interpreter will send the data. - -

Given a null argument signals end-of-response. - -

The author must call respondBody(null) - for each response, even if the response has no body.

- -

After the end-of-response, calling respondHeader() or - respondBody() will raise an INVALID_STATE_ERR exception. - -

If the client connection was closed for any reason, calling - respondBody() will raise a NETWORK_ERR - exception. - -

- - -
- -

3 TCP Client

-
[Constructor(in String host, in String port)]
-interface TCPClient  {
-  readonly attribute String host;
-  readonly attribute String port;
-
-  // ready state
-  const unsigned short CONNECTING = 0;
-  const unsigned short OPEN = 1;
-  const unsigned short CLOSED = 2;
-  readonly attribute long readyState;
-
-  // networking                
-    attribute Function onopen;
-    attribute Function onread;
-    attribute Function onclose;
-  void write(in ByteArray data);
-  void disconnect();           
-};
- -
-
TCPClient(host, port)
-
-

When a TCPClient object is - created, the the interpreter must try to establish a connection. - If the host parameter is not an IP address it - will be looked up using the DNS. -

- -
write(data)
-
-

Transmits data using the connection. If the connection is not yet - established or the connection is closed, calling write() - will raise an INVALID_STATE_ERR exception.

- -

write(null) sends an EOF to the peer. Further writing - is disabled. However the onread callback may still - be executed. -

- -
disconnect()
-
-

Closes the connection, if it is open. If the connection is already - closed, it does nothing. Closing the connection causes a - onclose callback to be made and the - readyState attribute's value to - change to CLOSED. - Note that a connection might not be closed instantaniously. In the - case of secure connection some "goodbye" transmission might be sent. -

-
- -

The readyState attribute - represents the state of the connection. When the object is created it must - be set to CONNECTING. - -

Once a connection is established, the - readyState attribute's value must be changed to - OPEN, and the onopen callback will be made. - -

When data is received, the onread callback - will be made with a single parameter: a ByteArray 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. - - - -

When the connection is closed, the readyState -attribute's value must be changed to CLOSED, and the onclose callback -will be made. - - -

4 Timers

- - -

Timers allow one to schedule an event at a later date. - There are four globally exposed functions - setTimeout, - clearTimeout, - setInterval, and - clearInterval. - These functions work similarly - as in the browser except that - the timerID and intervalID do not necessarily have - type long but are rather opaque objects. - -

-
setTimeout(function, milliseconds)
-
-

This method calls the function once after a specified number of - milliseconds elapses, until canceled by a call to clearTimeout. - The methods returns a timerID which may be used in a - subsequent call to clearTimeout to cancel the callback. -

- - -
setInterval(function, milliseconds)
-
-

This method calls the function every time a specified number of - milliseconds elapses, until canceled by a call to clearInterval. - The methods returns a intervalID which may be used in a - subsequent call to clearInterval to cancel the interval. -

- -
clearTimeout(timerID)
-
-

Cancels a timeout that was set with the setTimeout - method. -

- - -
clearInterval(intervalID)
-
-

Cancels an interval that was set with the setInterval method. -

- -
- -

5 Blocking Functions

- -

Node includes a number of blocking functions in its API. Some of these - will be removed in the future as the software improves. - -

-
log(string)
-
-

This function outputs the string to the stadard output device - (usually the console). - Its speed is dependent on where stdout is piped to. -

- - -
blockingFileRead(filename)
-
-

This method opens a file from the file system and returns its - contents as a ByteArray. This function can be extremely - expensive depending on the response time of the file system. It should - only be used in start up. -

- -
- - - -

References

- - -
- -
[RFC2616] - -
Hypertext Transfer - Protocol -- HTTP/1.1, R. Fielding, J. Gettys, J. Mogul, - H. Frystyk, L. Masinter, P. Leach, T. Berners-Lee, editors. IETF, - June 1999. - diff --git a/spec/specification.css b/spec/specification.css deleted file mode 100644 index c7073f0b87c..00000000000 --- a/spec/specification.css +++ /dev/null @@ -1,217 +0,0 @@ -/* WHATWG Green: sRGB #3c790a, rgb(60, 121, 10) */ - -html { margin: 0; padding: 0; color: black; background: #eeeeee; } -body { margin: 0 0 30%; padding: 0 1em 2em 8.5em; line-height: 1.35; color: black; background: white top left repeat-y; border-bottom: thin solid #3c790a; } - -:link { color: #00C; background: transparent } -:visited { color: #609; background: transparent } -:link:active, :visited:active { color: #C00; background: transparent } -:link:hover, :visited:hover { background: #ffa; } -code :link, code :visited { color: inherit; } - -body, th, td { font-family: sans-serif; } - -h1, h2, h3, h4, h5, h6 { text-align: left } -h1, h2, h3 { color: #3c790a; background: transparent; } -h1 { font: 900 170% sans-serif } -h2 { font: 800 140% sans-serif } -h3 { font: 800 125% sans-serif } -h4 { font: 800 110% sans-serif } -h5 { font: 800 100% sans-serif } -h6 { font: 600 italic 100% sans-serif } - -pre { margin-left: 2em; white-space: pre-wrap; } -h2 { margin: 3em 0 1em 0; } -h3 { margin: 2.5em 0 1em 0; } -h4 { margin: 2.5em 0 0.75em 0; } -h5, h6 { margin: 2.5em 0 1em; } -h1 + h2, h2 + h3, h3 + h4, h4 + h5, h5 + h6 { margin-top: 0.5em; } -p { margin: 1em 0; } -hr { display: block; background: none; border: none; padding: 0; margin: 2em 0; height: auto; } -dl, dd { margin-top: 0; margin-bottom: 0; } -dt { margin-top: 0.75em; margin-bottom: 0.25em; clear: left; } -dt + dt { margin-top: 0; } -dd dt { margin-top: 0.25em; margin-bottom: 0; } -dd p { margin-top: 0; } -dd dl + p { margin-top: 1em; } -dd table + p { margin-top: 1em; } -p + * > li, dd li { margin: 1em 0; } -dt, dfn { font-weight: bold; font-style: normal; } -dt dfn { font-style: italic; } -pre, code { font-size: inherit; font-family: monospace; font-variant: normal; } -pre strong { color: black; font: inherit; font-weight: bold; background: yellow; } -pre em { font-weight: bolder; font-style: normal; } -@media screen { code { color: orangered; } } -var sub { vertical-align: bottom; font-size: smaller; position: relative; top: 0.1em; } -table { border-collapse: collapse; border-style: hidden hidden none hidden; } -table thead { border-bottom: solid; } -table tbody th:first-child { border-left: solid; } -table td, table th { border-left: solid; border-right: solid; border-bottom: solid thin; vertical-align: top; padding: 0.2em; } -blockquote { margin: 0 0 0 2em; border: 0; padding: 0; font-style: italic; } -ins { background: green; color: white; /* color: green; border: solid thin lime; padding: 0.3em; line-height: 1.6em; */ text-decoration: none; } -del { background: maroon; color: white; /* color: maroon; border: solid thin red; padding: 0.3em; line-height: 1.6em; */ text-decoration: line-through; } -body ins, body del { display: block; } -body * ins, body * del { display: inline; } - - -/* classes and other specifics */ - -.toc dfn, h1 dfn, h2 dfn, h3 dfn, h4 dfn, h5 dfn, h6 dfn { font: inherit; } -img.extra { float: right; } -hr.bookmark { border: dashed 2em black; background: yellow; } -pre.idl { border: solid thin; background: #EEEEEE; color: black; padding: 0.5em 1em; } -pre.idl :link, pre.idl :visited { color: inherit; background: transparent; } -pre.css { border: solid thin; background: #FFFFEE; color: black; padding: 0.5em 1em; } -pre.css:first-line { color: #AAAA50; } -dl.domintro { color: green; margin: 2em 0 2em 2em; padding: 0.5em 1em; border: none; background: #EEFFEE; } -hr + dl.domintro, div.impl + dl.domintro { margin-top: 2.5em; margin-bottom: 1.5em; } -dl.domintro dt, dl.domintro dt * { color: black; text-decoration: none; } -dl.domintro dd { margin: 0.5em 0 1em 2em; padding: 0; } -dl.domintro dd p { margin: 0.5em 0; } -dl.switch { padding-left: 2em; } -dl.switch > dt { text-indent: -1.5em; } -dl.switch > dt:before { content: '\21AA'; padding: 0 0.5em 0 0; display: inline-block; width: 1em; text-align: right; line-height: 0.5em; } -.diff-old { text-decoration: line-through; color: silver; background: transparent; } -.diff-chg, .diff-new { text-decoration: underline; color: green; background: transparent; } -a .diff-new { border-bottom: 1px blue solid; } - -h2 { page-break-before: always; } -h1 + h2, hr + h2.no-toc { page-break-before: auto; } - -div.head { margin: 0 0 1em; padding: 1em 0 0 0; } -div.head p { margin: 0; } -div.head h1 { margin: 0; } -div.head .logo { float: right; margin: 0 1em; } -div.head .logo img { border: none } /* remove border from top image */ -div.head dl { margin: 1em 0; } -p.copyright { font-size: x-small; font-style: oblique; margin: 0; } - -body > .toc > li { margin-top: 1em; margin-bottom: 1em; } -body > .toc.brief > li { margin-top: 0.35em; margin-bottom: 0.35em; } -body > .toc > li > * { margin-bottom: 0.5em; } -body > .toc > li > * > li > * { margin-bottom: 0.25em; } -.toc, .toc li { list-style: none; } - -.brief { margin-top: 1em; margin-bottom: 1em; line-height: 1.1; } -.brief li { margin: 0; padding: 0; } -.brief li p { margin: 0; padding: 0; } - -[title=WIP], [title=TBW] { background: red; color: yellow; padding: 0.1em 0.3em; border: dotted white; margin: 0 0.7em 0 0.2em; } -[title=SCS] { background: green; color: white; padding: 0.1em 0.3em; border-style: none dashed; margin: 0 0.7em 0 0.2em; } -[title=WIP] :link, [title=WIP] :visited, -[title=TBW] :link, [title=TBW] :visited, -[title=SCS] :link, [title=SCS] :visited { background: transparent; color: inherit; } - -.big-issue, .XXX { color: #E50000; background: white; border: solid red; padding: 0.5em; margin: 1em 0; } -.big-issue > :first-child, .XXX > :first-child { margin-top: 0; } -p .big-issue, p .XXX { line-height: 3em; } -.note { color: green; background: transparent; font-family: sans-serif; } -.warning { color: red; background: transparent; } -.note, .warning { font-weight: bolder; font-style: italic; } -p.note, div.note { padding: 0.5em 2em; } -span.note { padding: 0 2em; } -.note p:first-child, .warning p:first-child { margin-top: 0; } -.note p:last-child, .warning p:last-child { margin-bottom: 0; } -.warning:before { font-style: normal; } - -.XXX:before, .XXX:after { content: " ** "; position: absolute; left: 0; width: 8em; text-align: right; } -p.note:before { content: 'Note: '; } -p.warning:before { content: '\26A0 Warning! '; } - -.applies thead code { display: block; } -.applies td { text-align: center; } -.applies .yes { background: yellow; } - -.bookkeeping:before { display: block; content: 'Bookkeeping details'; font-weight: bolder; font-style: italic; } -.bookkeeping { font-size: 0.8em; margin: 2em 0; } -.bookkeeping p { margin: 0.5em 2em; display: list-item; list-style: square; } - -.critical { margin: 1em; border: double thick red; padding: 1em; background: #FFFFCC; } -.critical > :first-child { margin-top: 0; } - -h4 { position: relative; z-index: 3; } -h4 + .element, h4 + div + .element { margin-top: -2.5em; padding-top: 2em; } -.element { background: #EEFFEE; color: black; margin: 0 0 1em 0.15em; padding: 0 1em 0.25em 0.75em; border-left: solid #99FF99 0.25em; position: relative; z-index: 1; } -.element:before { position: absolute; z-index: 2; top: 0; left: -1.15em; height: 2em; width: 0.9em; background: #EEFFEE; content: ' '; border-style: none none solid solid; border-color: #99FF99; border-width: 0.25em; } - -.example { - display: block; - color: #222222; - background: #FCFCFC; - border-left: double; - margin-left: 2em; - padding-left: 1em; -} - -.tall-and-narrow { - font-size: 0.6em; - column-width: 25em; - column-gap: 1em; - -moz-column-width: 25em; - -moz-column-gap: 1em; - -webkit-column-width: 25em; - -webkit-column-gap: 1em; -} - -.hide { display: none } - -body.dfnEnabled dfn { cursor: pointer; } -.dfnPanel { - display: inline; - position: absolute; - height: auto; - width: auto; - padding: 0.5em 0.75em; - font: small sans-serif; - background: #DDDDDD; - color: black; - border: outset 0.2em; -} -.dfnPanel * { margin: 0; padding: 0; font: inherit; text-indent: 0; } -.dfnPanel :link, .dfnPanel :visited { color: black; } -.dfnPanel p { font-weight: bolder; } -.dfnPanel * + p { margin-top: 0.25em; } -.dfnPanel li { list-style-position: inside; } - -@media aural { - h1, h2, h3 { stress: 20; richness: 90 } - .hide { speak: none } - p.copyright { volume: x-soft; speech-rate: x-fast } - dt { pause-before: 20% } - code, pre { speak-punctuation: code } -} - -@media screen { - body.draft { background-image: url(http://whatwg.org/images/WD); } - body.cfc { background-image: url(http://whatwg.org/images/CFC); } - body.cfi { background-image: url(http://whatwg.org/images/CFI); } - body.spec { background-image: url(http://whatwg.org/images/REC); } -} - -@media print { - html { font-size: 10pt; } - @page { margin: 2cm 0.5cm 2cm 0.5cm; } - @page :left { - @bottom-left { - font: 10pt sans-serif; - content: counter(page); - padding-top: 0em; - vertical-align: top; - } - } - @page :right { - @bottom-right { - font: 10pt sans-serif; - content: counter(page); - text-align: right; - vertical-align: top; - padding-top: 0em; - } - } - .toc a::after { content: leader('.') target-counter(attr(href), page); } - a[href^="#"]::after { content: " (page " target-counter(attr(href), page) ")"; } - pre a[href^="#"]::after, blockquote a[href^="#"]::after, var a[href^="#"]::after, - code a[href^="#"]::after, a[href^="#refs"]::after { content: ""; } - table { font-size: smaller; } - :link, :visited { text-decoration: none; color: inherit; background: transparent; } -}