Copyright ©2007 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C liability, trademark and document use rules apply.
To enable Web applications to communicate using TCP with it's originating
server this specification introduces the TCPConnection
interface.
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.
The TCPConnection
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 TCPConnection("", "12345"); } catch (ex) { if ("SECURITY_ERR" == ex.message) { alert("unable to connect") } } con.onread = function(o) { if ("pong" == o.data) { alert("'success"); } else { alert("unknown data"); } } con.send("ping");
TCPConnection
objectTCPConnection
objects must also
implement the EventTarget
interface.
[DOM3Events].
In [ECMAScript], an instance of
TCPConnection
can be created using the
TCPConnection
constructor. This is done by calling the
TCPConnection
function as part of a new expression like:
TCPConnection
constructorWhen the TCPConnection
is called as part of a new expression
in ECMAScript, it returns the newly created TCPConnection object which must
be initialized according to the rules below.
out TCPConnection TCPConnection(in DOMString subdomain, in DOMString port, in Boolean secure);
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 doamin.
The port
argument is the target
port. The port argument must not be equal to 80, nor equal to 443, nor
greater than or equal to 1024 and less than or equal to 65535. In such case
an SECURITY_ERR
exception must be thrown.
If the boolean secure
argument is
set to true
, then the user agent must establish a secure
connection with the target host and specified port using TLS or another
protocol, negotiated with the server. [RFC2246] If this fails the user agent
must act as if it had closed the connection.
TCPConnection
objectinterface TCPConnection { readonly attribute DOMString peer; readonly attribute int readyState; attribute EventListener onopen; attribute EventListener onread; attribute EventListener onclose; void send(in DOMString data); void disconnect(); };
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.
The readyState
attribute represents the
state of the connection. When the object is created it must be set to 0. It
can have the following values:
Once a connection is established, the
readyState
attribute's value must be changed to 1, and the open
event must be fired on the
TCPConnection
object.
When data is received, the read
event
will be fired on the TCPConnection
. Should
provide an example of binary protocol. E.g. read from NTP
When the connection is closed, the
readyState
attribute's value must be changed to 2, and the close
event must be fired on the
TCPConnection
object.
The onopen
, onread
, and onclose
attributes must,
when set, register their new value as an event listener for their respective
events (namely open
, read
, close
), and unregister their previous value if
any.
The send(data)
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 disconnect()
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 and the readyState
attribute's value to change, as described above.
All the events described in this section are events in no 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.
No information regarding why the connection was closed is passed to the application in this version of this specification.
The read
event is
fired when when data is received for a connection. UAs must use the
ConnectionReadEvent
interface for this event.
interface ConnectionReadEvent : Event {
readonly attribute DOMString data;
void initConnectionReadEvent(in DOMString typeArg,
in boolean canBubbleArg,
in boolean cancelableArg,
in DOMString dataArg);
void initConnectionReadEventNS(in DOMString namespaceURI,
in DOMString typeArg,
in boolean canBubbleArg,
in boolean cancelableArg,
in DOMString dataArg);
};
The data
attribute must contain the data
that was transmitted from the peer.
The initConnectionReadEvent() and initConnectionReadEventNS() methods must initialize the event in a manner analogous to the similarly-named methods in the DOM3 Events interfaces. [DOM3EVENTS]
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.
TCPConnection
objectWhen a TCPConnection
object is created using this
constructor, the following steps must be followed.
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, if the script's domain is not a host name (e.g. it
is an IP address) then a SECURITY_ERR
should
be raised by the user agent. We currently don't allow
connections to be set up back to an originating IP address, but we could, if
the subdomain is the empty string.
Then, if the subdomain argument is null or the empty string, the target host is the script's domain. Otherwise, the subdomain argument is prepended to the script's domain with a dot separating the two strings, and that is the target host.
If either:
...then the UA must raise a SECURITY_ERR
exception.
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
SECURITY_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
TCPConnection
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.)
If the secure boolean argument is set to true, then the user agent must establish a secure connection with the target host and specified port using TLS or another protocol, negotiated with the server. [RFC2246] If this fails the user agent must act as if it had closed the connection.
Once a secure connection is established, or if the secure boolean argument is not set to true, then the user agent must continue to connect to the server using the protocol described in the section entitled clients connecting over TCP. All data on connections made using TLS must be sent as "application data".
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. In particular, user agents should not apply per-host HTTP connection
limits to connections established with the TCPConnection
constructor.
This section describes how connections are established from the client and server sides, and then describes how data is sent and received over such connections (which is the same for both clients and servers).
This section defines the client-side requirements of the protocol used by
the TCPConnection
.
If a TCP connection to the specified target host and port cannot be established, for example because the target host is a domain name that cannot be resolved to an IP address, or because packets cannot be routed to the host, the user agent should retry creating the connection. If the user agent gives up trying to connect, the user agent must act as if it had closed the connection.
No information regarding the state of the connection is passed to the application while the connection is being established in this version of this specification.
Once a TCP/IP connection to the remote host is established, the user agent must transmit the following sequence of bytes, represented here in hexadecimal form:
0x48 0x65 0x6C 0x6C 0x6F 0x0A
This represents the string "Hello" followed by a newline, encoded in UTF-8.
The user agent must then read all the bytes sent from the remote host, up to the first 0x0A byte (inclusive). That string of bytes is then compared byte-for-byte to the following string of bytes:
0x57 0x65 0x6C 0x63 0x6F 0x6E 0x65 0x0A
This says "Welcome".
If the server sent back a string in any way different to this, then the user agent must close the connection and give up trying to connect.
Otherwise, the user agent must then take the string representing the script's domain in IDNA format, encode it as UTF-8, and send that to the remote host, followed by a 0x0A byte (a U+000A LINE FEED in UTF-8).
The user agent must then read all the bytes sent from the remote host, up to the first 0x0A byte (inclusive). That string of bytes must then be compared byte-for-byte to the string that was just sent to the server (the one with the IDNA domain name and ending with a newline character). If the server sent back a string in any way different to this, then the user agent must close the connection and give up trying to connect.
Otherwise, the connection has been established (and events and so forth get fired, as described above).
If at any point during this process the connection is closed prematurely, then the user agent must close the connection and give up trying to connect.
This section defines the server side of the protocol described in the previous section. For authors, it should be used as a guide for how to implement servers that can communicate with Web pages over TCP.
Once a TCP/IP connection from a remote host is established, the user agent must transmit the following sequence of bytes, represented here in hexadecimal form:
0x57 0x65 0x6C 0x63 0x6F 0x6E 0x65 0x0A
This says "Welcome" and a newline in UTF-8.
The user agent must then read all the bytes sent from the remote host, up to the first 0x0A byte (inclusive). That string of bytes is then compared byte-for-byte to the following string of bytes:
0x48 0x65 0x6C 0x6C 0x6F 0x0A
"Hello" and a newline.
If the remote host sent back a string in any way different to this, then the user agent must close the connection and give up trying to connect.
Otherwise, the user agent must then take the string representing the script's domain in IDNA format, encode it as UTF-8, and send that to the remote host, followed by a 0x0A byte (a U+000A LINE FEED in UTF-8).
The user agent must then read all the bytes sent from the remote host, up to the first 0x0A byte (inclusive). That string of bytes must then be compared byte-for-byte to the string that was just sent to that host (the one with the IDNA domain name and ending with a newline character). If the remote host sent back a string in any way different to this, then the user agent must close the connection and give up trying to connect.
Otherwise, the connection has been established (and events and so forth get fired, as described above).
For author-written servers (as opposed to the server side of a peer-to-peer connection), the script's domain would be replaced by the hostname of the server. Alternatively, such servers might instead wait for the client to send its domain string, and then simply echo it back. This would allow connections from pages on any domain, instead of just pages originating from the same host. The client compares the two strings to ensure they are the same before allowing the connection to be used by author script.
If at any point during this process the connection is closed prematurely, then the user agent must close the connection and give up trying to connect.
When the send(data)
method is invoked on the connection's
corresponding TCPConnection
object,
the user agent must take the data argument, replace any
U+0000 NULL and U+0017 END OF TRANSMISSION BLOCK characters in it with U+FFFD
REPLACEMENT CHARACTER characters, then transmit a U+0002 START OF TEXT
character, this new data string and a single U+0017 END
OF TRANSMISSION BLOCK character (in that order) to the remote host, all
encoded as UTF-8.
When the user agent receives bytes on the connection, the user agent must
buffer received bytes until it receives a 0x17 byte (a U+0017 END OF
TRANSMISSION BLOCK character). If the first buffered byte is not a 0x02 byte
(a U+0002 START OF TEXT character encoded as UTF-8) then all the data up to
the 0x17 byte, inclusive, must be dropped. (This allows for future extension
of this protocol.) Otherwise, all the data from (but not including) the 0x02
byte and up to (but not including) the 0x17 byte must be taken, interpreted
as a UTF-8 string, and a read
event must be fired on the TCPConnection
object with that string as the
data
.
If that string cannot be decoded as UTF-8 without errors, the packet should
be ignored.
This protocol does not yet allow binary data (e.g. an image or video data) to be efficiently transmitted. A future version of this protocol might allow this by using the prefix character U+001F INFORMATION SEPARATOR ONE, followed by binary data which uses a particular byte (e.g. 0xFF) to encode byte 0x17 somehow (since otherwise 0x17 would be treated as transmission end by down-level UAs).
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.
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)
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.