This document defines a set of ECMAScript APIs in WebIDL to allow data to be sent and received between a browser and server, implementing pluggable protocols underneath with common APIs on top. APIs specific to QUIC are also provided. This specification is being developed in conjunction with a protocol specification developed by the IETF QUIC Working Group.

Introduction

This specification uses pluggable protocols, with QUIC [[!QUIC-TRANSPORT]] as one such protocol, to send data to and receive data from servers. It can be used like WebSockets but with support for multiple streams, unidirectional streams, out-of-order delivery, and reliable as well as unreliable transport.

The API presented in this specification represents a preliminary proposal based on work-in-progress within the IETF QUIC WG. Since the QUIC transport specification is a work-in-progress, both the protocol and API are likely to change significantly going forward.

This specification defines conformance criteria that apply to a single product: the user agent that implements the interfaces that it contains.

Conformance requirements phrased as algorithms or specific steps may be implemented in any manner, so long as the end result is equivalent. (In particular, the algorithms defined in this specification are intended to be easy to follow, and not intended to be performant.)

Implementations that use ECMAScript to implement the APIs defined in this specification MUST implement them in a manner consistent with the ECMAScript Bindings defined in the Web IDL specification [[!WEBIDL-1]], as this specification uses that specification and terminology.

Terminology

The EventHandler interface, representing a callback used for event handlers, and the ErrorEvent interface are defined in [[!HTML51]].

The concepts queue a task, fires a simple event and networking task source are defined in [[!HTML51]].

The terms event, event handlers and event handler event types are defined in [[!HTML51]].

When referring to exceptions, the terms throw and create are defined in [[!WEBIDL-1]].

The terms fulfilled, rejected, resolved, pending and settled used in the context of Promises are defined in [[!ECMASCRIPT-6.0]].

The terms ReadableStream and WritableStream are defined in [[!WHATWG-STREAMS]]. Note that despite sharing the name "stream", these are distinct from the IncomingStream, OutgoingStream, and BidirectionalStream defined here. The IncomingStream, OutgoingStream, and BidirectionalStream defined here correspend to a higher level of abstraction that contain and depend on the lower-level concepts of "streams" defined in [[!WHATWG-STREAMS]].

UnidirectionalStreamsTransport Mixin

A UnidirectionalStreamsTransport can send and receive unidirectional streams. Data within a stream is delivered in order, but data between streams may be delivered out of order. Data is generally sent reliably, but retransmissions may be disabled or the stream may aborted to produce a form of unreliability. All stream data is encrypted and congestion-controlled.

interface mixin UnidirectionalStreamsTransport {
  Promise<SendStream> createSendStream (optional SendStreamParameters parameters);
  ReadableStream            receiveStreams ();
};

Methods

createSendStream

Creates an SendStream object.

When createSendStream is called, the user agent MUST run the following steps:

  1. Let transport be the UnidirectionalStreamsTransport on which createSendStream is invoked.

  2. If transport's state is "closed" or "failed", immediately return a new rejected promise with a newly created InvalidStateError and abort these steps.

  3. If transport's state is "connected", immediately return a new resolved promise with a newly created SendStream object, add the SendStream to the transport and abort these steps.

  4. Let p be a new promise.

  5. Return p and continue the following steps in the background.

  6. Resolve p with a newly created SendStream object and add the SendStream to the transport when all of the following conditions are met:

    1. The transport's state has transitioned to "connected"

    2. Stream creation flow control is not being violated by exceeding the max stream limit set by the remote endpoint, as specified in [[QUIC-TRANSPORT]].

    3. p has not been settled

  7. Reject p with a newly created InvalidStateError when all of the following conditions are met:

    1. The transport's state transitions to "closed" or "failed"

    2. p has not been settled

No parameters.
Return type: Promise<SendStream>
receiveStreams

Returns a ReadableStream of ReceiveStreams that have been received from the remote host.

When receiveStreams is called, the user agent MUST run the following steps:

  1. Let transport be the UnidirectionalStreamsTransport on which receiveStreams is invoked.

  2. Return the value of the [[\ReceivedStreams]] internal slot.

  3. For each unidirectional stream received, create a corresponding IncomingStream and insert it into [[\ReceivedStreams]]. As data is received over the unidirectional stream, insert that data into the corresponding IncomingStream When the remote side closes or aborts the stream, close or abort the corresponding IncomingStream.

No parameters.
Return type: ReadableStream of ReceiveStreams.

Procedures

Add SendStream to the UnidirectionalStreamsTransport

To add the SendStream to the UnidirectionalStreamsTransport run the following steps:

  1. Let stream be the newly created SendStream object.

  2. Add stream to transport's [[\OutgoingStreams]] internal slot.

  3. Continue the following steps in the background.

  4. Create stream's associated underlying transport.

SendStreamParameters Dictionary

The QuicStreamParameters dictionary includes information relating to stream configuration.

dictionary SendStreamParameters {
              bool disableRetransmissions = false;
};

Dictionary SendStreamParameters Members

disableRetransmissions of type bool, defaulting to false

disableRetransmissions, with a default of false. If true, the stream will be sent without retransmissions. If false, the stream will be sent with retransmissions. If the WebTransport is unable to send without retransmissions, it may ignore this value.

BidirectionalStreamsTransport Mixin

A BidirectionalStreamsTransport can send and receive bidirectional streams. Data within a stream is delivered in order, but data between streams may be delivered out of order. Data is generally sent reliably, but retransmissions may be disabled or the stream may aborted to produce a form of unreliability. All stream data is encrypted and congestion-controlled.

interface BidirectionalStreamsTransport {
    Promise<BidirectionalStream> createBidirectionalStream ();
    ReadableStream                     receiveBidirectionalStreams ();
};

Methods

createBidirectionalStream

Creates an BidirectionalStream object.

When createBidectionalStream is called, the user agent MUST run the following steps:

  1. Let transport be the BidirectionalStreamsTransport on which createBidectionalStream is invoked.

  2. If transport's state is "closed" or "failed", immediately return a new rejected promise with a newly created InvalidStateError and abort these steps.

  3. If transport's state is "connected", immediately return a new resolved promise with a newly created BidirectionalStream object, add the BidirectionalStream to the transport and abort these steps.

  4. Let p be a new promise.

  5. Return p and continue the following steps in the background.

  6. Resolve p with a newly created BidirectionalStream object and add the BidirectionalStream to the transport when all of the following conditions are met:

    1. The transport's state has transitioned to "connected"

    2. Stream creation flow control is not being violated by exceeding the max stream limit set by the remote endpoint, as specified in [[QUIC-TRANSPORT]].

    3. p has not been settled

  7. Reject p with a newly created InvalidStateError when all of the following conditions are met:

    1. The transport's state transitions to "closed" or "failed"

    2. p has not been settled

No parameters.
Return type: Promise<BidirectionalStream>
receiveBidirectionalStreams

Returns a ReadableStream of BidirectionalStreams that have been received from the remote host.

When receiveBidirectionalStreams is called, the user agent MUST run the following steps:

  1. Let transport be the UnidirectionalStreamsTransport on which receiveStreams is invoked.

  2. Return the value of the [[\ReceivedBidirectionalStreams]] internal slot.

  3. For each bidirectional stream received, create a corresponding IncomingStream and insert it into [[\ReceivedBidirectionalStreams]]. As data is received over the bidirectional stream, insert that data into the corresponding IncomingStream. When the remote side closes or aborts the stream, close or abort the corresponding IncomingStream.

No parameters.
Return type: ReadableStream of BidirectionalStreams

Procedures

Add BidirectionalStream to the BidirectionalStreamsTransport

To add the BidirectionalStream to the BidirectionalStreamsTransport run the following steps:

  1. Let stream be the newly created BidirectionalStream object.

  2. Add stream to transport's [[\ReceivedBidirectionalStreams]] internal slot.

  3. Add stream to transport's [[\OutgoingStreams]] internal slot.

  4. Continue the following steps in the background.

  5. Create stream's associated underlying transport.

DatagramTransport Mixin

A DatagramTransport can send and receive datagrams. Datagrams are sent out of order, unreliably, and have a limited maximum size. Datagrams are encrypted and congestion controlled.

interface mixin DatagramTransport {
    readonly attribute unsigned short maxDatagramSize;
    WritableStream                    sendDatagrams ();
    ReadableStream                    receiveDatagrams ();
};

Attributes

maxDatagramSize of type unsigned short, readonly

The maximum size data that may be passed to sendDatagram.

Methods

sendDatagrams

Sends datagrams that are written to the returned WritableStream.

When sendDatagram is called, the user agent MUST run the following steps:

  1. Let transport be the DatagramTransport on which sendDatagram is invoked.

  2. Return the value of the [[\SentDatagrams]] internal slot.

Return type: WritableStream of Uint8Array.
receiveDatagrams

Return the value of the [[\ReceivedDatagrams]] internal slot.

For each datagram received, insert it into [[\ReceivedDatagrams]]. If too many datagrams are queued because the stream is not being read quickly enough, drop datagrams to avoid queueing. Implementations should drop older datagrams in favor of newer datagrams. The number of datagrams to queue should be kept small enough to avoid adding significant latency to packet delivery when the stream is being read slowly (due to the reader being slow) but large enough to avoid dropping packets when for the stream is not read for short periods of time (due to the reader being paused).

Return type: ReadableStream of Uint8Array

WebTransport Mixin

The WebTransport includes the methods common to all transports, such as state, state changes, and the ability to close the transport.

interface mixin WebTransport {
  readonly attribute WebTransportState state;
  void                                  close (WebTransportCloseInfo closeInfo);
           attribute EventHandler       onstatechange;
           attribute EventHandler       onerror;
};

Attributes

state of type WebTransportState, readonly

The current state of the transport. On getting, it MUST return the value of the [[\WebTransportState]] internal slot.

onstatechange of type EventHandler

This event handler, of event handler event type statechange, MUST be fired any time the [[\WebTransportState]] slot changes, unless the state changes due to calling close.

onerror of type EventHandler

This event handler, of event handler event type error, MUST be fired on reception of an error; an implementation SHOULD include error information in error.message (defined in [[!HTML51]] Section 7.1.3.8.2). This event MUST be fired before the onstatechange event.

Methods

close

Closes the WebTransport object. For QUIC, this triggers an Immediate Close as described in [[QUIC-TRANSPORT]] section 10.3.

When close is called, the user agent MUST run the following steps:

  1. Let transport be the WebTransport on which close is invoked.
  2. If transport's [[\WebTransportState]] is "closed" then abort these steps.
  3. Set transport's [[\WebTransportState]] to "closed".
  4. Let closeInfo be the first argument.
  5. For QUIC, start the Immediate Close procedure by sending an CONNECTION_CLOSE frame with its error code value set to the value of closeInfo.errorCode and its reason value set to the value of closeInfo.reason.
No parameters.
Return type: void
Parameter Type Nullable Optional Description
closeInfo WebTransportCloseInfo

WebTransportState Enum

WebTransportState indicates the state of the transport.

enum WebTransportState {
    "new",
    "connecting",
    "connected",
    "closed",
    "failed"
};
Enumeration description
new

The WebTransport object has been created and has not started negotiating yet.

connecting

The transport is in the process of negotiating a secure connection. Once a secure connection is negotiated, incoming data can flow through.

connected

The transport has completed negotiation of a secure connection. Outgoing data and media can now flow through.

closed

The transport has been closed intentionally via a call to close() or receipt of a closing message from the remote side. When the WebTransport's internal [[\WebTransportState]] slot transitions to closed the user agent MUST run the following steps:

  1. Let transport be the WebTransport.
  2. Close the ReadableStream in transport's [[\ReceivedStreams]] internal slot.
  3. Close the ReadableStream in transport's [[\ReceivedBidirectionalStreams]] internal slot.
  4. For each OutgoingStream in transport's [[\OutgoingStreams]] internal slot run the following:
    1. Let stream be the OutgoingStream.
    2. Remove the stream from the transport's [[\OutgoingStreams]] internal slot.
failed

The transport has been closed as the result of an error (such as receipt of an error alert). When the WebTransport's internal [[\WebTransportState]] slot transitions to failed the user agent MUST run the following steps:

  1. Close the ReadableStream in transport's [[\ReceivedStreams]] internal slot.
  2. Close the ReadableStream in transport's [[\ReceivedBidirectionalStreams]] internal slot.
  3. For each OutgoingStream in transport's [[\OutgoingStreams]] internal slot run the following:
    1. Remove the stream from the transport's [[\OutgoingStreams]] internal slot.

WebTransportCloseInfo Dictionary

The WebTransportCloseInfo dictionary includes information relating to the error code for closing a WebTransport. For QUIC, this information is used to set the error code and reason for an CONNECTION_CLOSE frame.

dictionary WebTransportCloseInfo {
    unsigned short errorCode = 0;
    DOMString reason = "";
};

Dictionary WebTransportCloseInfo Members

errorCode of type unsigned short, defaulting to 0.

The error code.

reason of type DOMString, defaulting to ""

The reason for closing the WebTransport

QuicTransportBase Interface

The QuicTransportBase is the base interface for QuicTransport. Most of the functionality of a QuicTransport is in the base class to allow for other subclasses (such as a p2p variant) to share the same interface.

Overview

A QuicTransportBase is a UnidirectionalStreamsTransport, a BidirectionalStreamsTransport, and a DatagramTransport. SendStreams and ReceiveStreams are implemented with unidirectional QUIC streams as defined in [[!QUIC-TRANSPORT]]. BidirectionalStreams are implemented with bidirectional QUIC streams as defined in [[!QUIC-TRANSPORT]]. Datagrams are implemented with QUIC datagrams as defined in [[QUIC-DATAGRAM]].

Interface Definition

interface QuicTransportBase {
};

QuicTransportBase includes UnidirectionalStreamsTransport;
QuicTransportBase includes BidirectionalStreamsTransport;
QuicTransportBase includes DatagramTransport;
QuicTransportBase includes WebTransport;

QuicTransport Interface

The QuicTransport is a subclass of QuicTransportBase focused on client/server use cases.

Interface Definition

[ Constructor (DOMString host, unsigned short port), Exposed=Window]
interface QuicTransport : QuicTransportBase {
};

Constructors

When the QuicTransport constructor is invoked, the user agent MUST run the following steps:
  1. If port is 0, throw an NotSupportedError and abort these steps.
  2. Let transport be a newly constructed QuicTransport object.
  3. Let transport have a [[\OutgoingStreams]] internal slot representing a sequence of OutgoingStream objects, initialized to empty.
  4. Let transport have a [[\ReceivedStreams]] internal slot representing a ReadableStream of IncomingStream objects, initialized to empty.
  5. Let transport have a [[\ReceivedBidirectionalStreams]] internal slot representing a ReadableStream of IncomingStream objects, initialized to empty.
  6. Let transport have a [[\WebTransportState]] internal slot, initialized to "connecting".
  7. Let transport have a [[\SentDatagrams]] internal slot representing a WritableStream of Uint8Arrays, initialized to empty.
  8. Let transport have a [[\ReceivedDatagrams]] internal slot representing a ReadableStream of Uint8Arrays, initialized to empty.
  9. Run these steps in parallel:
    1. Let clientOrigin be transport's relevant settings object's origin, serialized.
    2. Establish a QUIC connection to the address identified by the given host and port following the procedures in [[WEB-TRANSPORT-QUIC]] section 3 and using clientOrigin as the "origin of the client" referenced in section 3.2.
    3. If the connection fails, set transport's [[\WebTransportState]] internal slot to "failed" and abort these steps.
    4. Set transport's [[\WebTransportState]] internal slot to "connected".
  10. Return transport.
QuicTransport
Parameter Type Nullable Optional Description
host DOMString The host to connect to.
port unsigned short The port to connect to.

Interface Mixin OutgoingStream

An OutgoingStream is a stream that can be written to, as either a SendStream or a BidirectionalStream

      [ Exposed=Window ]
interface mixin OutgoingStream {
    readonly attribute WritableStream writable;
    readonly attribute Promise<StreamAbortInfo> writingAborted;
    void abortWriting (StreamAbortInfo abortInfo);
};

Overview

The OutgoingStream will initialize with the following:

  1. Let stream be the OutgoingStream.
  2. Let stream have a [[\Writable]] internal slot initialized to a new WritableStream.

Attributes

writable of type WritableStream readonly

The writable attribute represents a WritableStream (of bytes) that can be used to write to the OutgoingStream. On getting it MUST return the value of the [[\Writable]] slot.

The writingAborted attribute represents a promise that resolves when the a message from the remote side aborting the stream is received. For QUIC, that message is a STOP_SENDING frame. When the stream receives this mesage, the user agent MUST run the following:

  1. Let stream be the OutgoingStream object.
  2. Let transport be the WebTransport, which the stream was created from.
  3. Remove the stream from the transport's [[\OutgoingStreams]] internal slot.
  4. resolve the promise with the resulting StreamAbortInfo with the errorCode set to the value from the aborting message from the remote side.

Methods

abortWriting

A hard shutdown of the OutgoingStream. It may be called regardless of whether the OutgoingStream was created by the local or remote peer. When the abortWriting() method is called, the user agent MUST run the following steps:

  1. Let stream be the OutgoingStream object which is about to abort writing.
  2. Let transport be the WebTransport, which the stream was created from.
  3. Remove the stream from the transport's [[\OutgoingStreams]] internal slot.
  4. Let abortInfo be the first argument.
  5. Start the closing procedure by sending a RST_STREAM frame with its error code set to the value of abortInfo.errorCode.
Parameter Type Nullable Optional Description
abortInfo StreamAbortInfo
Return type: void

StreamAbortInfo Dictionary

The StreamAbortInfo dictionary includes information relating to the error code for aborting an incoming or outgoing stream. (For QUIC, in either a RST_STREAM frame or a STOP_SENDING frame).

dictionary StreamAbortInfo {
                unsigned short errorCode = 0;
          };
          

Dictionary StreamAbortInfo Members

errorCode of type unsigned short.

The error code. The default value of 0 means "CLOSING."

Interface Mixin IncomingStream

An IncomingStream is a stream that can be read from, as either a ReceiveStream or a BidirectionalStream

[ Exposed=Window ]
interface mixin IncomingStream {
    readonly attribute ReadableStream readable;
    readonly attribute Promise<StreamAbortInfo> readingAborted;
    void abortReading (StreamAbortInfo abortInfo);
};

Overview

The IncomingStream will initialize with the following:

  1. Let stream be the IncomingStream.
  2. Let stream have a [[\Readable]] internal slot initialized to a new ReadableStream.

Attributes

readable of type ReadableStream, readonly

The readable attribute gives a ReadableStream which can be used to read from the IncomingStream. On getting, it MUST return the value of the IncomingStream's [[\Readable]] slot.

readingAborted of type StreamAbortInfo readonly

The readingAborted attribute represents a promise that resolves when the a message is received inidicating the remote side aborted the stream. For QUIC, this is a RST_STREAM frame. When the stream receives this message, the user agent MUST run the following:

  1. Let stream be the IncomingStream object for which the abort message was received.
  2. Let transport be the WebTransport, which the stream was created from.
  3. resolve the promise with the resulting StreamAbortInfo with errorCode set to the value of the errror code from the abot message.

Methods

abortReading

A hard shutdown of the IncomingStream. It may be called regardless of whether the IncomingStream object was created by the local or remote peer. When the abortReading() method is called, the user agent MUST run the following steps:

  1. Let stream be the IncomingStream object which is about to abort reading.
  2. Let transport be the WebTransport, which the stream was created from.
  3. Let abortInfo be the first argument.
  4. Start the closing procedure by sending a message to the remote side indicating that the stream has been aborted (for QUIC, this is a STOP_SENDING frame) with its error code set to the value of abortInfo.errorCode.
Parameter Type Nullable Optional Description
abortInfo StreamAbortInfo
Return type: void

Interface WebTransportStream

A collection of common attributes and methods of all streams.

      [ Exposed=Window ]
      interface WebTransportStream {
          readonly attribute unsigned long long streamId;
          readonly attribute WebTransport transport;
      };
      

Attributes

streamId of type unsigned long long, readonly

The readonly attribute referring to the ID of the TransportStream object.

transport of type WebTransport, readonly

The readonly attribute referring to the related WebTransport object.

Interface BidirectionalStream

      [ Exposed=Window ]
      interface BidirectionalStream : WebTransportStream {
      };
      BidirectionalStream includes OutgoingStream;
      BidirectionalStream includes IncomingStream;
      

Interface SendStream

      [ Exposed=Window ]
      interface SendStream : WebTransportStream {
      };
      SendStream includes OutgoingStream;
      

Interface ReceiveStream

      [ Exposed=Window ]
      interface ReceiveStream : WebTransportStream {
      };
      ReceiveStream includes IncomingStream;
      

Http3Transport Interface

Overview

An Http3Transport is a UnidirectionalStreamsTransport, a BidirectionalStreamsTransport, and a DatagramTransport. SendStreams, ReceiveStreams, and BidirectionalStreams are implemented with HTTP/3 streams as defined in [[WEB-TRANSPORT-HTTP3]]. Datagrams are implemented with QUIC datagrams as defined in [[WEB-TRANSPORT-HTTP3]].

Interface Definition

[ Constructor (DOMString url), Exposed=Window]
interface Http3Transport {
};

Http3Transport includes UnidirectionalStreamsTransport;
Http3Transport includes BidirectionalStreamsTransport;
Http3Transport includes DatagramTransport;
Http3Transport includes WebTransport;

Constructors

When the Http3Transport constructor is invoked, the user agent MUST run the following steps:
  1. Let transport be a newly constructed Http3Transport object with state "connecting".
  2. Let transport have a [[\OutgoingStreams]] internal slot representing a sequence of OutgoingStream objects, initialized to empty.
  3. Let transport have a [[\ReceivedStreams]] internal slot representing a ReadableStream of IncomingStream objects, initialized to empty.
  4. Let transport have a [[\ReceivedBidirectionalStreams]] internal slot representing a ReadableStream of IncomingStream objects, initialized to empty.
  5. Let transport have a [[\SentDatagrams]] internal slot representing a WritableStream of Uint8Arrays, initialized to empty.
  6. Let transport have a [[\ReceivedDatagrams]] internal slot representing a ReadableStream of Uint8Arrays, initialized to empty.
  7. Run these steps in parallel:
    1. Either establish an HTTP/3 connection or reuse an existing HTTP/3 connection to the host specificed by the url, as specified in [[WEB-TRANSPORT-HTTP3]].
    2. If there is no such HTTP/3 connection to reuse and the establishment of a new HTTP/3 connection, set transport's [[\WebTransportState]] internal slot to "failed" and abort these steps.
    3. Once a connection an HTTP/3 connection is established, follow the steps specified in [[WEB-TRANSPORT-HTTP3]] section 4 for establishing a WebTransport session within the HTTP/3 connection.
    4. If the establishment of the WebTransport session fails, set transport's [[\WebTransportState]] internal slot to "failed" and abort these steps.
    5. Once a session has been established, set transport's [[\WebTransportState]] internal slot to "connected" and abort these steps.
  8. Return transport.
Http3Transport
Parameter Type Nullable Optional Description
url DOMString The url specifying the host to connect to and the path to pass to it.

Privacy and Security Considerations

This section is non-normative; it specifies no new behaviour, but instead summarizes information already present in other parts of the specification.

Confidentiality of Communications

The fact that communication is taking place cannot be hidden from adversaries that can observe the network, so this has to be regarded as public information.

All of the transport protocols described in this document use either TLS [[TLS13]] or a semantically equivalent protocol, thus providing all of the security properties of TLS, including confidentiality and integrity of the traffic. Both QuicTransport and Http3Transport use the same certificate verification mechanism as outbound HTTP requests, thus relying on the same public key infrastructure for authentication of the remote server. In WebTransport, certificate verification errors are fatal; no interstitial allowing bypassing certificate validation is available.

State Persistence

WebTransport by itself does not create any new unique identifiers or new ways to persistently store state, nor does it automatically expose any of the existing persistent state to the server. For instance, none of the transports defined in this document automatically send cookies, support HTTP authentication or caching invalidation mechanisms. Since they use TLS, they may support TLS session tickets, which could be used by the server (though not by passive network observers) to correlate different connections from the same client. This is not specific to WebTransport by itself, but rather an inherent property of all TLS-based protocols; thus, this is out-of-scope for this specification.

Protocol Security

WebTransport imposes a common set of requirements on all of the protocols, described in [[WEB-TRANSPORT-OVERVIEW]]. Notable ones include:

  1. All transports must ensure that the remote server is aware that the connection in question originates from a Web application; this is required to prevent cross-protocol attacks. QUIC-based transports use [[ALPN]] for that purpose.
  2. All transports must allow the server to filter connections based on the origin of the resource originating the transport session.
  3. All transports require the user agents to continually verify that the server is still interested in talking to them (concept commonly known as "Consent Freshness").

Protocol security considersations related to the individual transports are described in the Security Considerations sections of the corresponding protocol documents, [[WEB-TRANSPORT-QUIC]] and [[WEB-TRANSPORT-HTTP3]].

Networking APIs can be commonly used to scan the local network for available hosts, and thus be used for fingerprinting and other forms of attacks. WebTransport follows the WebSocket approach to this problem: the specific connection error is not returned until an endpoint is verified to be a WebTransport endpoint; thus, the Web application cannot distinguish between a non-existing endpoint and the endpoint that is not willing to accept connections from the Web.

Event summary

The following events fire on transport objects:

Event name Interface Fired when...
error ErrorEvent The WebTransport object has encountered an error.
statechange Event The WebTransportState changed.

Examples

Unreliable delivery

Unreliable delivery can be achieved by creating many streams with retransmissions disabled, each transporting a single small message.

let transport = getTransport();
let messages = getMessages();
for (msg in messages) {
  transport.createSendStream({disableRetransmissions: true}).writable.getWriter().write({data: msg, finished: true});
}

Sending a buffer of datagrams

Sending a buffer of datagrams can be achieved by using the sendDatagrams method. In the following example datagrams are only sent if the DatagramTransport is ready to send.

const transport = getTransport();
const datagramWritableStream = transport.sendDatagrams();
const datagrams = getDatagramsToSend();
datagrams.forEach((datagram) => {
  await datagramWritableStream.getWriter().ready;
  datagramWritableStream.getWriter().write(datagram);
});

Sending datagrams at a fixed rate

Sending datagrams at a fixed rate regardless if the transport is ready to send can be achieved by simply using sendDatagram and not using the ready attribute. More complex scenarios can utilize the ready attribute.

// Sends datagrams every 100 ms.
const transport = getTransport();
const datagramWritableStream = transport.sendDatagrams();
setInterval(() => {
  datagramWritableStream.getWriter().write(createDatagram());
}, 100);

Receiving datagrams

Receiving datagrams can be achieved by calling receiveDatagrams() method, remembering to check for null values indicating that packets are not being processed quickly enough.

      const transport = getTransport();
      const reader = transport.receiveDatagrams().getReader();
      while (true) {
        const {value: datagram, done} = await reader.read();
        if (done) {
          break;
        }
        // Process the data
      }
      

Change Log

This section will be removed before publication.

Acknowledgements

The editors wish to thank the Working Group chairs and Team Contact, Harald Alvestrand, Stefan Håkansson, Bernard Aboba and Dominique Hazaël-Massieux, for their support. Contributions to this specification were provided by Robin Raymond.

The QuicTransport and QuicStream objects were initially described in the W3C ORTC CG, and have been adapted for use in this specification.