1. Introduction
This section is non-normative.
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.
Note: 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.
2. Conformance
As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.
The key words MUST and SHOULD are to be interpreted as described in [RFC2119].
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], as this specification uses that specification and terminology.
3. Terminology
The EventHandler
interface, representing a callback used for event handlers, and the ErrorEvent
interface are defined in [HTML].
The concepts queue a task and networking task source are defined in [HTML].
The terms event, event handlers and event handler event types are defined in [HTML].
When referring to exceptions, the terms throw and create are defined in [WEBIDL].
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].
4. 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();
};
4.1. Methods
createSendStream()
-
Creates a
SendStream
object.When
createSendStream()
method is called, the user agent MUST run the following steps:-
Let transport be the
UnidirectionalStreamsTransport
on whichcreateSendStream
is invoked. -
If transport’s
state
is"closed"
or"failed"
, immediately return a new rejected promise with a newly createdInvalidStateError
and abort these steps. -
Let p be a new promise.
-
Return p and continue the following steps in background.
-
Resolve p with a newly created
SendStream
object and add the SendStream to transport when all of the following conditions are met:-
The transport’s
state
has transitioned to"connected"
. -
Stream creation flow control is not being violated by exceeding the max stream limit set by the remote endpoint. For QUIC, this is specified in [QUIC-TRANSPORT].
-
p has not been settled.
-
-
Reject p with a newly created
InvalidStateError
when all of the following conditions are met:-
The transport’s state transitions to
"closed"
or"failed"
. -
p has not been settled.
-
-
receiveStreams()
-
Returns a
ReadableStream
ofReceiveStream
s that have been received from the remote host.When
receiveStreams
is called, the user agent MUST run the following steps:-
Let transport be the
UnidirectionalStreamsTransport
on whichreceiveStreams
is invoked. -
Return the value of the
[[ReceivedStreams]]
internal slot. -
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 correspondingIncomingStream
. When the remote side closes or aborts the stream, close or abort the correspondingIncomingStream
.
-
4.2. Procedures
4.2.1. Add SendStream to UnidirectionalStreamsTransport
4.3. SendStreamParameters Dictionary
The SendStreamParameters
dictionary includes information relating to stream configuration.
dictionary SendStreamParameters { };
5. 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 mixin BidirectionalStreamsTransport { Promise<BidirectionalStream> createBidirectionalStream(); ReadableStream receiveBidirectionalStreams(); };
5.1. Methods
createBidirectionalStream()
-
Creates a
BidirectionalStream
object.When
createBidirectionalStream
is called, the user agent MUST run the following steps:-
Let transport be the
BidirectionalStreamsTransport
on whichcreateBidirectionalStream
is invoked. -
If transport’s
state
is"closed"
or"failed"
, immediately return a new rejected promise with a newly createdInvalidStateError
and abort these steps. -
If transport’s
state
is"connected"
, immediately return a new fulfilled promise with a newly createdBidirectionalStream
object, add the BidirectionalStream to the transport and abort these steps. -
Let p be a new promise.
-
Return p and continue the following steps in background.
-
Resolve p with a newly created
BidirectionalStream
object and add the BidirectionalStream to transport when all of the following conditions are met:-
The transport’s
state
has transitioned to"connected"
. -
Stream creation flow control is not being violated by exceeding the max stream limit set by the remote endpoint. For QUIC, this is specified in [QUIC-TRANSPORT].
-
p has not been settled.
-
-
Reject p with a newly created
InvalidStateError
when all of the following conditions are met:-
The transport’s state transitions to
"closed"
or"failed"
. -
p has not been settled.
-
-
receiveBidirectionalStreams()
-
Returns a
ReadableStream
ofBidirectionalStream
s that have been received from the remote host.When
receiveBidirectionalStreams
method is called, the user agent MUST run the following steps:-
Let transport be the
BidirectionalStreamsTransport
on whichreceiveBidirectionalStreams
is invoked. -
Return the value of the
[[ReceivedBidirectionalStreams]]
internal slot. -
For each bidirectional stream received, create a corresponding
BidirectionalStream
and insert it into[[ReceivedBidirectionalStreams]]
. As data is received over the bidirectional stream, insert that data into the correspondingBidirectionalStream
. When the remote side closes or aborts the stream, close or abort the correspondingBidirectionalStream
.
-
5.2. Procedures
5.2.1. Add BidirectionalStream to BidirectionalStreamsTransport
6. 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(); };
6.1. Attributes
maxDatagramSize
, of type unsigned short, readonly-
The maximum size data that may be passed to
sendDatagrams
.
6.2. Methods
sendDatagrams()
-
Sends datagrams that are written to the returned
WritableStream
.When
sendDatagrams
is called, the user agent MUST run the following steps:-
Let transport be the
DatagramTransport
on whichsendDatagram
is invoked. -
Return the value of the
[[SentDatagrams]]
internal slot.
-
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).
7. WebTransport
Mixin
The WebTransport
includes the methods common to all transports, such as state, state changes, and the ability to close the transport.
interface mixinWebTransport
{ readonly attribute WebTransportState state; readonly attribute Promise<WebTransportCloseInfo> closed; void close(optional WebTransportCloseInfocloseInfo
= {}); attribute EventHandler onstatechange; };
7.1. Attributes
state
, of type WebTransportState, readonly-
The current state of the transport. On getting, it MUST return the value of the
[[WebTransportState]]
internal slot. closed
, of type Promise<WebTransportCloseInfo>, readonly-
This promise MUST be resolved when the transport is closed; an implementation SHOULD include error information in the
reason
anderrorCode
fields ofWebTransportCloseInfo
. 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 callingclose
.
7.2. 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:
-
Let transport be the WebTransport on which
close
is invoked. -
If transport’s
[[WebTransportState]]
is"closed"
or"failed"
, then abort these steps. -
Set transport’s
[[WebTransportState]]
to"closed"
. -
Let
closeInfo
be the first argument. -
For QUIC, start the Immediate Close procedure by sending an CONNECTION_CLOSE frame with its error code value set to the value of
errorCode
and its reason value set to the value ofreason
.
-
7.3. WebTransportState
Enum
WebTransportState
indicates the state of the transport.
enum WebTransportState { "connecting", "connected", "closed", "failed" };
"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 theWebTransport
's internal[[WebTransportState]]
slot transitions toclosed
the user agent MUST run the following steps:-
Let transport be the
WebTransport
. -
Close the
ReadableStream
in transport’s[[ReceivedStreams]]
internal slot. -
Close the
ReadableStream
in transport’s[[ReceivedBidirectionalStreams]]
internal slot. -
For each
OutgoingStream
in transport’s[[OutgoingStreams]]
internal slot run the following:-
Let stream be the
OutgoingStream
. -
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 tofailed
the user agent MUST run the following steps:-
Close the
ReadableStream
in transport’s[[ReceivedStreams]]
internal slot. -
Close the
ReadableStream
in transport’s[[ReceivedBidirectionalStreams]]
internal slot. -
For each
OutgoingStream
in transport’s[[OutgoingStreams]]
internal slot run the following:-
Remove the stream from the transport’s
[[OutgoingStreams]]
internal slot.
-
-
7.4. 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 = ""; };
The dictionary SHALL have the following attributes:
errorCode
, of type unsigned short, defaulting to0
-
The error code communicated to the peer.
reason
, of type DOMString, defaulting to""
-
The reason for closing the
WebTransport
.
7.5. QuicTransportStats
Dictionary
The QuicTransportStats
dictionary includes information on QUIC connection level stats.
dictionary QuicTransportStats { DOMHighResTimeStamp timestamp; unsigned long long bytesSent; unsigned long long packetsSent; unsigned long numOutgoingStreamsCreated; unsigned long numIncomingStreamsCreated; unsigned long long bytesReceived; unsigned long long packetsReceived; DOMHighResTimeStamp minRtt; unsigned long numReceivedDatagramsDropped; };
The dictionary SHALL have the following attributes:
timestamp
, of type DOMHighResTimeStamp-
The
timestamp
for when the stats are gathered, relative to the UNIX epoch (Jan 1, 1970, UTC). bytesSent
, of type unsigned long long-
The number of bytes sent on the QUIC connection, including retransmissions. Does not include UDP or any other outer framing.
packetsSent
, of type unsigned long long-
The number of packets sent on the QUIC connection, including retransmissions.
numOutgoingStreamsCreated
, of type unsigned long-
The number of outgoing QUIC streams created on the QUIC connection.
numIncomingStreamsCreated
, of type unsigned long-
The number of incoming QUIC streams created on the QUIC connection.
bytesReceived
, of type unsigned long long-
The number of total bytes received on the QUIC connection, including duplicate data for streams. Does not include UDP or any other outer framing.
packetsReceived
, of type unsigned long long-
The number of total packets received on the QUIC connection, including packets that were not processable.
minRtt
, of type DOMHighResTimeStamp-
The minimum RTT observed on the entire connection.
numReceivedDatagramsDropped
, of type unsigned long-
The number of datagrams that were dropped, due to too many datagrams buffered between calls to
receiveDatagrams()
.
8. QuicTransport
Interface
The QuicTransport
is a UnidirectionalStreamsTransport
, a BidirectionalStreamsTransport
, and a DatagramTransport
. SendStream
s and ReceiveStream
s are implemented with unidirectional QUIC streams as defined in [QUIC-TRANSPORT]. BidirectionalStream
s are implemented with bidirectional QUIC streams as defined in [QUIC-TRANSPORT]. Datagrams are implemented with QUIC datagrams as defined in [QUIC-DATAGRAM].
8.1. Configuration
dictionary QuicTransportOptions { sequence<RTCDtlsFingerprint> serverCertificateFingerprints; };
QuicTransportOptions
is a dictionary of parameters that determine how QuicTransport connection is established and used.
serverCertificateFingerprints
, of type sequence<RTCDtlsFingerprint>-
If non-empty, the user agent SHALL deem a server certificate trusted if and only if it can successfully verify a certificate fingerprint against
serverCertificateFingerprints
and satisfies custom certificate requirements. The user agent SHALL ignore any fingerprint that uses an unknownalgorithm
or has a malformedvalue
. If empty, the user agent SHALL use certificate verification procedures it would use for normal fetch operations.
To
compute a certificate fingerprint, do the following:
To
verify a certificate fingerprint, do the following:
-
Let fprs be the input array of fingerprints.
-
Let ref_fpr be the computed fingerprint of the input certificate.
-
For every fingerprint fpr in fprs:
-
Return false.
The custom certificate requirements are as follows: the certificate MUST be an X.509v3 certificate as defined in [RFC5280], the current time MUST be within the validity period of the certificate as defined in Section 4.1.2.5 of [RFC5280] and the total length of the validity period MUST NOT exceed two weeks.
Reconsider the time period above. We want it to be sufficiently large that applications using this for ephemeral certificates can do so without having to fight the clock skew, but small enough to discourage long-term use without key rotation.
8.2. Interface Definition
[Exposed=(Window,Worker)] interface QuicTransport {constructor
(USVStringurl
, optional QuicTransportOptionsoptions
= {}); Promise<QuicTransportStats> getStats(); }; QuicTransport includes UnidirectionalStreamsTransport; QuicTransport includes BidirectionalStreamsTransport; QuicTransport includes DatagramTransport; QuicTransport includes WebTransport;
When the QuicTransport()
constructor is invoked, the user agent MUST run the following steps:
-
Let parsedURL be the URL record resulting from parsing of
url
. -
If parsedURL is a failure, throw a
SyntaxError
exception. -
If parsedURL scheme is not
quic-transport
, throw aSyntaxError
exception. -
If parsedURL fragment is not null, throw a
SyntaxError
exception. -
Let transport be a newly constructed
QuicTransport
object. -
Let transport have a
[[OutgoingStreams]]
internal slot representing a sequence ofOutgoingStream
objects, initialized to empty. -
Let transport have a
[[ReceivedStreams]]
internal slot representing aReadableStream
ofIncomingStream
objects, initialized to empty. -
Let transport have a
[[ReceivedBidirectionalStreams]]
internal slot representing aReadableStream
ofIncomingStream
objects, initialized to empty. -
Let transport have a
[[WebTransportState]]
internal slot, initialized to"connecting"
. -
Let transport have a
[[SentDatagrams]]
internal slot representing aWritableStream
ofUint8Array
s, initialized to empty. -
Let transport have a
[[ReceivedDatagrams]]
internal slot representing aReadableStream
ofUint8Array
s, initialized to empty. -
Run these steps in parallel:
-
Let clientOrigin be transport’s relevant settings object's origin, serialized.
-
Establish a QUIC connection to the address identified by parsedURL following the procedures in [WEB-TRANSPORT-QUIC] section 3 and using clientOrigin as the "origin of the client" referenced in section 3.2.1. While establishing the connection, follow all of the parameters specified in the
options
. -
If the connection fails, set transport’s
[[WebTransportState]]
internal slot to"failed"
and abort these steps. -
Set transport’s
[[WebTransportState]]
internal slot to"connected"
.
-
-
Return transport.
8.3. Methods
getStats()
-
Gathers stats for this
QuicTransport
's QUIC connection and reports the result asynchronously.When close is called, the user agent MUST run the following steps:
-
Let transport be the QuicTransport on which
getStats
is invoked. -
Let p be a new promise.
-
Return p and continue the following steps in background.
-
Gather the stats from the underlying QUIC connection.
-
Once stats have been gathered, resolve p with the
QuicTransportStats
object, representing the gathered stats.
-
-
9. Interface Mixin OutgoingStream
An OutgoingStream
is a stream that can be written to, as either a SendStream
or a BidirectionalStream
.
[ Exposed=(Window,Worker) ]
interface mixin OutgoingStream {
readonly attribute WritableStream writable;
readonly attribute Promise<StreamAbortInfo> writingAborted;
void abortWriting(optional StreamAbortInfo abortInfo
= {});
};
9.1. Overview
The OutgoingStream
will initialize with the following:
-
Let stream be the
OutgoingStream
. -
Let stream have a
[[Writable]]
internal slot initialized to a newWritableStream
.
9.2. Attributes
writable
, of type WritableStream, readonly-
The
writable
attribute represents aWritableStream
(of bytes) that can be used to write to theOutgoingStream
. On getting it MUST return the value of the[[Writable]]
slot. writingAborted
, of type Promise<StreamAbortInfo>, readonly-
The
writingAborted
attribute represents a promise that is fulfilled 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:-
Let stream be the
OutgoingStream
object. -
Let transport be the
WebTransport
, which the stream was created from. -
Remove the stream from the transport’s
[[OutgoingStreams]]
internal slot. -
Resolve the promise with the resulting
StreamAbortInfo
with theerrorCode
set to the value from the aborting message from the remote side.
-
9.3. Methods
abortWriting()
-
A hard shutdown of the
OutgoingStream
. It may be called regardless of whether theOutgoingStream
was created by the local or remote peer. When theabortWriting
method is called, the user agent MUST run the following steps:-
Let stream be the
OutgoingStream
object which is about to abort writing. -
Let transport be the
WebTransport
, which the stream was created from. -
Remove the stream from the transport’s
[[OutgoingStreams]]
internal slot. -
Let abortInfo be the first argument.
-
Start the closing procedure by sending a RST_STREAM frame with its error code set to the value of |abortInfo.errorCode|.
-
9.4. 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; };
The dictionary SHALL have the following fields:
errorCode
, of type unsigned short, defaulting to0
-
The error code. The default value of 0 means "CLOSING."
10. Interface Mixin IncomingStream
An IncomingStream
is a stream that can be read from, as either a ReceiveStream
or a BidirectionalStream
.
[ Exposed=(Window,Worker) ]
interface mixin IncomingStream {
readonly attribute ReadableStream readable;
readonly attribute Promise<StreamAbortInfo> readingAborted;
void abortReading(optional StreamAbortInfo abortInfo
= {});
Promise<ArrayBuffer> arrayBuffer();
};
10.1. Overview
The IncomingStream
will initialize with the following:
-
Let stream be the
IncomingStream
. -
Let stream have a
[[Readable]]
internal slot initialized to a newReadableStream
.
10.2. Attributes
readable
, of type ReadableStream, readonly-
The
readable
attribute represents aReadableStream
that can be used to read from theIncomingStream
. On getting it MUST return the value of theIncomingStream
's[[Readable]]
slot. readingAborted
, of type Promise<StreamAbortInfo>, readonly-
The
readingAborted
attribute represents a promise that is fulfilled when the a message from the remote side aborting the stream is received. For QUIC, that message is a RST_STREAM frame. When the stream receives this mesage, the user agent MUST run the following:-
Let stream be the
IncomingStream
object for which the abort message was received. -
Let transport be the
WebTransport
, which the stream was created from. -
Resolve the promise with the resulting
StreamAbortInfo
with theerrorCode
set to the value from the aborting message from the remote side.
-
10.3. Methods
abortReading()
-
A hard shutdown of the
IncomingStream
. It may be called regardless of whether theIncomingStream
was created by the local or remote peer. When theabortWriting
method is called, the user agent MUST run the following steps:-
Let stream be the
IncomingStream
object which is about to abort reading. -
Let transport be the
WebTransport
, which the stream was created from. -
Let abortInfo be the first argument.
-
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|.
-
arrayBuffer()
-
A convenience method that asynchronously reads all the contents of |IncomingStream.readable| and returns it as an ArrayBuffer. This locks the stream while reading, just as if |IncomingStream.readable.getReader()| were used.
11. Interface BidirectionalStream
[ Exposed=(Window,Worker) ]
interface BidirectionalStream
{
};
BidirectionalStream includes OutgoingStream;
BidirectionalStream includes IncomingStream;
12. Interface SendStream
[ Exposed=(Window,Worker) ]
interface SendStream
{
};
SendStream includes OutgoingStream;
13. Interface ReceiveStream
[ Exposed=(Window,Worker) ]
interface ReceiveStream
{
};
ReceiveStream includes IncomingStream;
14. Http3Transport
Interface
14.1. Overview
An Http3Transport
is a UnidirectionalStreamsTransport
, a BidirectionalStreamsTransport
, and a DatagramTransport
. SendStream
s, ReceiveStream
s and BidirectionalStream
s are implemented with HTTP/3 streams as defined in [WEB-TRANSPORT-HTTP3]. Datagrams are implemented with QUIC datagrams as defined in [WEB-TRANSPORT-HTTP3].
14.2. Interface Definition
[Exposed=(Window,Worker)] interface Http3Transport {constructor
(DOMStringurl
); }; Http3Transport includes UnidirectionalStreamsTransport; Http3Transport includes BidirectionalStreamsTransport; Http3Transport includes DatagramTransport; Http3Transport includes WebTransport;
14.2.1. Constructors
When the Http3Transport()
constructor is invoked, the user agent MUST run the following steps:
-
Let transport be a newly constructed
Http3Transport
object with state "connecting". -
Let transport have a
[[OutgoingStreams]]
internal slot representing a sequence ofOutgoingStream
objects, initialized to empty. -
Let transport have a
[[ReceivedStreams]]
internal slot representing aReadableStream
ofIncomingStream
objects, initialized to empty. -
Let transport have a
[[ReceivedBidirectionalStreams]]
internal slot representing aReadableStream
ofIncomingStream
objects, initialized to empty. -
Let transport have a
[[SentDatagrams]]
internal slot representing aWritableStream
ofUint8Array
s, initialized to empty. -
Let transport have a
[[ReceivedDatagrams]]
internal slot representing aReadableStream
ofUint8Array
s, initialized to empty. -
Run these steps in parallel:
-
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].
-
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. -
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.
-
If the establishment of the WebTransport session fails, set transport’s
[[WebTransportState]]
internal slot to"failed"
and abort these steps. -
Once a session has been established, set transport’s
[[WebTransportState]]
internal slot to"connected"
and abort these steps.
-
-
Return transport.
15. 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.
15.1. 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 [RFC8446] 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.
15.2. 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.
15.3. Protocol Security
WebTransport imposes a common set of requirements on all of the protocols, described in [WEB-TRANSPORT-OVERVIEW]. Notable ones include:
-
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 [RFC7301] for that purpose.
-
All transports must allow the server to filter connections based on the origin of the resource originating the transport session.
-
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.
16. Examples
16.1. Sending a buffer of datagrams
This section is non-normative.
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 writer = transport.sendDatagrams().getWriter(); const datagrams = getDatagramsToSend(); datagrams.forEach((datagram) => { await writer.ready; writer.write(datagram); });
16.2. Sending datagrams at a fixed rate
This section is non-normative.
Sending datagrams at a fixed rate regardless if the transport is ready to send can be achieved by simply using sendDatagrams()
and not using the ready
attribute. More complex scenarios can utilize the ready
attribute.
// Sends datagrams every 100 ms. const transport = getTransport(); const writer = transport.sendDatagrams().getWriter(); setInterval(() => { writer.write(createDatagram()); }, 100);
16.3. Receiving datagrams
This section is non-normative.
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 }
16.4. Receiving from ReceiveStream
This section is non-normative.
Reading from ReceiveStreams can be achieved by calling receiveStreams()
method, then getting the reader for each ReceiveStream
.
const transport = getTransport(); const receiveStreamReader = transport.receiveStreams().getReader(); while (true) { const {value: receiveStream, done: readingReceiveStreamsDone} = await receiveStreamReader.read(); if (readingReceiveStreamsDone) { break; } // Process ReceiveStreams created by remote endpoint. const chunkReader = receiveStream.readable.getReader(); while (true) { const {value: chunk, done: readingChunksDone} = await chunkReader.read(); if (readingChunksDone) { break; } processTheData(chunk); } }
17. 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.
from Hacker News https://ift.tt/2Oxnlu0
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.