Network Communication API

Editors' Draft 27 July 2007

This Version:
Latest Version:
Previous Version:
Gorm Haug Eriksen (Opera Software ASA) <gormer@opera.com>
Charles McCathieNevile (Opera Software ASA) <chaals@opera.com>


To enable Web applications to communicate using TCP this specification introduces the TCPSocket interface and a corresponding optional security model.

Status of this Document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.

This document is a first editors' draft specification of the network API from the Web API group, part of the Rich Web Client Activity. This editor's draft does not imply any consensus of or endorsement by any member of the working group, and may contain minor or major errors. (Currently it probably contains some of both).

This document is published to solicit comments from interested parties. All comments are welcome and may be sent to public-webapi@w3.org. All messages received at this address are viewable in a public archive. This document will hopefully be published as a first W3C Working Draft in March 2007.

This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

Publication as a Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

Table of Contents


The TCPSocket interface enables a TCP connection from the client to the server from which the script was downloaded and executed from. Instances of this object can be made using a constructor on the Window object.

This interface does not allow for raw access to the underlying network. For example, this interface could not be used to implement an IRC client without proxying messages through a custom server.

Add an introduction to the client-side and server-side of using the direct connection APIs. The example below could be better.

Provide an example here

  var con = null;
  try { 
    con = new TCPSocket("www.example.com, "12345");
  catch (ex) { 
    if ("SECURITY_ERR" == ex.message) { 
      alert("unable to connect") 
  con.addEventListener("socketdata", function(ev) {
    if ("pong" == ev.data) { alert("Success"); }
    else { alert("Failure"); }

The TCPSocket object

TCPSocket objects must also implement the EventTarget interface. [DOM3Events].

In [ECMAScript], an instance of TCPSocket can be created using the TCPSocket constructor. This is done by calling the TCPSocket function as part of a new expression like:

var ircConnection = new TCPSocket("example.com", "6667");

The TCPSocket constructor

When the TCPSocket is called as part of a new expression in ECMAScript, it returns the newly created TCPSocket object which must be initialized according to the rules below.

out TCPSocket TCPSocket(in DOMString subdomain, in DOMString port); 

The subdomain argument is prepended to the script's domain with a dot separating the two strings, and that is the target host. If null or an empty string the target host is the scripts domain.

Should the syntax example.com:12345 be allowed as subdomain argument?

Members of the TCPSocket object

interface TCPSocket {
  readonly attribute DOMString     peer;
           attribute EventListener socketdata;
           attribute EventListener onconnect;
           attribute EventListener onclose;
                     DOMString     read();
                     void          write(in DOMString data);
                     void          flush();
                     void          close();

The peer attribute identifies the remote host for direct (non-broadcast) connections. The peer attribute must initially be set to the empty string and must be updated once, when the connection is established, after which point it must keep the same value for the lifetime of the object.

Once a connection is established the connect event must be fired on the TCPSocket object.

When data is received, the socketdata event will be fired on the TCPSocket.

Should define further when the socketdata event should fire

When the connection is closed, the close event must be fired on the TCPSocket object.

The onopen, onsocketdata, and onclose attributes must, when set, register their new value as an event listener for their respective events (namely open, socketdata, close), and unregister their previous value if any.

The read() method reads a DOMString from the TCPSocket. It's assumed that the DOMString is prefixed with an unsigned short integer that indicates the length in bytes. If the connection is not yet established, it must raise an INVALID_STATE_ERR exception.

The write(data) method queues data on the socket for writing. If the connection is not yet established, it must raise an INVALID_STATE_ERR exception. Note that the flush method must be called before any data is transmitted on the socket.

The flush() method transmits data using the connection. If the connection is not yet established, it must raise an INVALID_STATE_ERR exception. If the connection is established, then the behavior depends on the connection type, as described below.

The close() method must close the connection, if it is open. If the connection is already closed, it must do nothing. Closing the connection causes a close event to be fired.

TCPSocket Events

All the events described in this section are events in the null namespace, which do not bubble, are not cancelable, and have no default action.

The open event is fired when the connection is established. UAs must use the normal Event interface when firing this event.

The close event is fired when the connection is closed (whether by the author, calling the disconnect() method, or by the server, or by a network error). UAs must use the normal Event interface when firing this event as well.

The socketdata event is fired when when data is received for a connection. UAs must follow the "Progress events 1.0" specification [ProgressEvent1.0] for this event.

interface ProgressEvent : events::Event {
     readonly attribute boolean         lengthComputable;
     readonly attribute unsigned long   loaded;
     readonly attribute unsigned long   total;
     void               initProgressEvent(in DOMString typeArg,
                                          in boolean       canBubbleArg,
                                          in boolean       cancelableArg,
                                          in boolean       lengthComputableArg,
                                          in unsigned long loadedArg,
                                          in unsigned long totalArg);
     void               initProgressEventNS(in DOMString namespaceURI,
                                            in DOMString typeArg,
                                            in boolean       canBubbleArg,
                                            in boolean       cancelableArg,
                                            in boolean       lengthComputableArg,
                                            in unsigned long loadedArg,
                                            in unsigned long totalArg);

The variables for the initProgressEvent and initProgressEventNS functions should by default be set according to the "Progress events 1.0" specification [ProgressEvent1.0] with the following exceptions:

loadedArg must be set to the number of readable bytes loaded when the event was dispatched. This number must not change while the EventListeners are processing the event.

Events that would be fired during script execution (e.g. between the connection object being created — and thus the connection being established — and the current script completing; or, during the execution of a read event handler) must be buffered, and those events queued up and each one individually fired after the script has completed.

Initializing the TCPSocket object

When a TCPSocket object is created using this constructor, the following steps must be performed.

First, a pointer must be stored on the newly created object, called the Window pointer. This pointer must persist even if the browsing context in which the Window is located is destroyed (by removing it from a parent browsing context, for instance). The term browsing context is defined by the Window Object 1.0 specification. [Window]

Secondly, the user agent must verify that the string representing the script's hostname is a valid hostname in the IDNA format or an IP address. If this is not valid a

Otherwise, the user agent must verify that the the string representing the script's domain in IDNA format can be obtained without errors. If it cannot, then the user agent must raise a NETWORK_ERR exception.

The user agent may also raise a SECURITY_ERR exception at this time if, for some reason, permission to create a direct TCP connection to the relevant host is denied. Reasons could include the UA being instructed by the user to not allow direct connections, or the UA establishing (for instance using UPnP) that the network topology will cause connections on the specified port to be directed at the wrong host.

If no exceptions are raised by the previous steps, then a new TCPSocket object must be created, its peer attribute must be set to a string consisting of the name of the target host, a colon (U+003A COLON), and the port number as decimal digits.

This object must then be returned.

The user agent must then begin trying to establish a connection with the target host and specified port. (This typically would begin in the background, while the script continues to execute.)

Once the connection is established, the UA must act as described in the section entitled sending and receiving data over TCP.

User agents should allow multiple TCP connections to be established per host.


Need to write this section.

If you have an unencrypted page that is (through a man-in-the-middle attack) changed, it can access a secure service that is using IP authentication and then send that data back to the attacker. Ergo we should probably stop unencrypted pages from accessing encrypted services, on the principle that the actual level of security is zero. Then again, if we do that, we prevent insecure sites from using SSL as a tunneling mechanism.

Should consider dropping the subdomain-only restriction. It doesn't seem to add anything, and prevents cross-domain chatter.

Relationship to other standards

Should have a section talking about the fact that we blithely ignoring IANA's port assignments here.

Should explain why we are not reusing HTTP for this. (HTTP is too heavy-weight for such a simple need; requiring authors to implement an HTTP server just to have a party line is too much of a barrier to entry; cannot rely on prebuilt components; having a simple protocol makes it much easier to do RAD; HTTP doesn't fit the needs and doesn't have the security model needed; etc)


ECMAScript Language Specification, Third Edition. ECMA, December 1999.
Document Object Model (DOM) Level 3 Events Specification, Björn Höhrmann, editor. World Wide Web Consortium, April 2006.
Window Object 1.0, I. Davis, M. Stachowiak, editors. W3C, April 2006.
The TLS Protocol, Version 1.0, T. Dierks. Certicom, C. Allen. Certicom, January 1999.
Progress events 1.0, C. McCathieNevile, editor. W3C Working Draft, 19 April 2007.


This section is non normative.

The editor would like to thank Ian Hickson and everyone in the WHATWG community who has written the initial proposal for this specification.