Draft: draft-vvv-webtransport-http3

Commentary: This replaces a distinct Session ID mechanism with using stream ID of the CONNECT stream as a Session ID . The transport parameter used to opt into WebTransport is replaced with a SETTINGS value . 
 I was reviewing the H2 WT draft , and I now wonder if " connect stream " is really the best terminology . Is " session stream " more representative of what it is -- a stream that represents the WebTransport Session ? CONNECT just happens to be the method used to open the stream . 
 WT currently uses QUIC DATAGRAMS ( eg : no Flow - Id ) , and does it 's own demultiplexing via the session ID . This is incompatible with multiplexing other applications that use H3 DATAGRAMs , since the Flow - ID could collide with the session ID , depending on how it is chosen . There was some discussion of this already in a PR on victor 's repo : 
 We should use whatever H3 DATAGRAM draft decides in order to be able to coexist with MASQUE . I 've mostly not updated the draft because I do n't think there is an exact consensus for H3 DATAGRAM on the exact approach . 
 I think MASQUE and WT have achieved parity for now 
 Http3Transport currently assumes that server - initiated bidirectional streams and datagrams can only be used for WebTransport . I suggest we prefix each server - initiated bidirectional stream and datagram with a new HTTP/3 frame type for WebTransport . This way , a future standard could define it 's own frame type to run alongside WebTransport . 
 Using an H3 frame type for server initiated bidi streams would also make the design more consistent , instead of the asymmetric design there is today . It costs a byte per bidi stream , but it seems worth it for consistency and flexibility . For datagrams , I believe that we 'd want to be able to coexist with other H3 extensions , such as MASQUE , and I believe that 's possible without any extra overhead by adding a Session -Datagram flow ID mapping when a WebTransport session is created . 
 If it 's a single byte , it 's more of a stream type ( like the unidirectional stream - type ) than a frame type , right ? There 's a discussion  pointed me to in , where it 's suggested that datagrams belonging to a WebTransport session use the Flow ID = to the Session ID . It would be nice to avoid the extra state and lookup . 
 Ah yes , it 's more of a stream type . In that case , I 'm unsure of whether there 's a good way of eliminating the asymmetry . The only option I can think of is to not use a stream type for server bidi streams and only use the frame , like for the client initiated bidi streams ? Thanks for the pointer to , it looks like there are a few potential designs for datagrams flow IDs . If in doubt , simpler is probably better . I 'll think more about this one . 
 I agree we should use the same mechanics for client and server bidi streams . 
 After thinking about this more , not having a stream type does n't seem so bad to me and it does provide symmetry . Stream types seem like an obvious design choice , but I believe HTTP/3 is sufficiently constrained that one could infer the stream type based on the first frame on the stream . For example , the control stream MUST start with SETTINGS . In retrospect , having both stream types and frame types is a bit awkward , and it likely would have been cleaner to only have frame types , but that ship has sailed . 
 After having implemented this for hackathon , I can confirm that the lack of stream preface on server - bidi streams is annoying and requires special casing ( I actually simulate receiving one ) . Let 's please add one . I took a bit of a shortcut and treated the stream preface as both a stream type AND a frame type . After peeking at the unidirectional stream input to discover that it 's WT , I let the parser run on that and treat it as a frame type , making it symmetric with the bidi case . Is it possible to define a reserved frame type with the same value as the stream type ? 
 Given HTTP/3 does not have a stream type varint for bidi streams , I think a potential way forward is to say that the first frame on the bidi stream can indicate the ' type ' of the stream , but that there is no explicit type identifier on the wire . Feel free to ignore the below comment , as it 's apparently unchanged from January Looking back , SETTINGS is required to be the first frame on the control stream , so the control stream type is a bit redundant and the same is true for QPACK and I believe could be true for server push ? Obviously we 're not going to redesign HTTP/3 stream and frame types at this stage in the process , but making bidi streams consistent for both perspectives seems preferable to me . 
 Discussed at IETF 110 . There seems to be a general agreement that we should make server - initiated bidi streams use the same encoding as client - initiated ones ( that is to say , frames ) . There was some interest expressed in splitting definition of server - initiated bidi streams into their own draft ; and are to reach out to httpbis about the appropriate venue for that . 
 Just bringing some of the discussion from here : HTTP should provide some consistent guidance for the format of HTTP/3 extension streams . Client - bidi extension streams have to start with a frame or series of frames , to be compatible for H3 . One of these frames has to identify the type of stream . This is how WT is currently specified . Unidirectional streams all start with a Stream Type , but after that are inconsistent in H3 the control stream is : Stream Type + Frames QPACK Streams are : Stream Type + QPACK instructions  streams are : Stream Type + Preface ( Push ID ) + Frames Stream Type seems like a more general extension mechanism , since it can be used to completely decouple from HTTP/3 frame parsing . 
 I find stream types to be less extensible than frames : frames allow you to do anything that stream types do , while additionally providing more opportunity for extensibility . I would prefer server - initiated bidirectional streams to behave like client - initiated bidirectional streams instead of unidirectional streams , as that makes implementations simpler . 
 January Me said : So I think I 'm arguing against myself and I 'm going to stop . My other comments on this thread we that I did n't like was the asymmetry of WT uni streams , which currently are . My past self seemed to be advocating that we change WT uni streams to or perhaps . Do we want general guidance about how extensions should use Stream Type vs Frames on unidirectional streams -- specifically that there should be at least one frame ? 
 The place to put that guidance would have been draft - ietf - quic - http , and I think that ship has sailed . For unidirectional streams , I like your framing proposal as that enables extension frames down the road . 
 Well , not too late to put out a BCP or something , especially if there 's going to be some kind of formal guidance on server - initiated bidi streams . I 'll open a separate issue about changing the WT uni framing . 
 I think this specific issue was fixed by . Please reopen if I 'm wrong . 
 Thanks  , switching to SETTINGs definitely makes sense . Let 's all talk about flow Ids sometime as well .
When an HTTP/3 connection is established, the client and server have
to negotiate a specific set of QUIC transport parameters that
indicate support for various WebTransport features.  Most notably,
the "http3_transport_support" parameter signals WebTransport support
to the peer.
WebTransport sessions are initiated inside a given HTTP/3 connection
by the client, who sends an extended CONNECT request RFC8441.  If the
server accepts the request, an WebTransport session is established.
As a part of this process, the client proposes, and the server
confirms, a session ID.  A session ID (SID) is unique within a given
HTTP/3 connection, and is used to associate all of the streams and
datagrams with the specific session.
When an HTTP/3 connection is established, both the client and server
have to send a SETTINGS_ENABLE_WEBTRANSPORT setting in order to
indicate that they both support WebTransport over HTTP/3.
WebTransport sessions are initiated inside a given HTTP/3 connection
by the client, who sends an extended CONNECT request RFC8441.  If the
server accepts the request, an WebTransport session is established.
The resulting stream will be further referred to as a _CONNECT
stream_, and its stream ID is used to uniquely identify a given
WebTransport session within the connection.  The ID of the CONNECT
stream that established a given WebTransport session will be further
referred to as a _Session ID_.
In order to allow multiple WebTransport sessions to occur within the
same HTTP/3 connection, WebTransport assigns every session a unique
ID, further referred to as session ID.  A session ID is a 62-bit
number that is unique within the scope of an HTTP/3 connection, and
is never reused even after the session is closed.  The client
unilaterally picks the session ID.  As the IDs are encoded using QUIC
variable length integers, the client SHOULD start with zero and then
sequentially increment the IDs.  A session ID is considered to be
used, and thus ineligible for new transports, as soon as the client
sends a request proposing it.  These reuse requirements guarantee
that both HTTP/3 endpoints have a consistent view of the session ID
space.
The Session ID is a hop-by-hop property: if WebTransport is proxied,
the same session can have different IDs from the client's and
server's perspective.  Because of that, session IDs SHOULD NOT be
exposed to the application.
In order to indicate support for WebTransport, both the client and
server MUST send an empty "http3_transport_support" transport
parameter.  Endpoints MUST NOT use any WebTransport-related
functionality unless the parameter has been negotiated.  The
negotiation is done through a QUIC transport parameter instead of an
HTTP/3-level setting as it allows the server to customize the
transport parameters it intends to send based on whether the client
has indicated support for WebTransport.
If "http3_transport_support" is negotiated, support for the QUIC
DATAGRAM extension MUST be negotiated.  The
"initial_max_bidi_streams" MUST be greater than zero, overriding the
existing requirement in HTTP3.
RFC8441 defines an extended CONNECT method in Section 4, enabled by
the SETTINGS_ENABLE_CONNECT_PROTOCOL parameter.  That parameter is
only defined for HTTP/2.  This document does not create a new multi-
purpose parameter to indicate support for extended CONNECT in HTTP/3;
instead, the "http3_transport_support" transport parameter implies
that an endpoint supports extended CONNECT.
In order to create a new WebTransport session, a client can send an
HTTP CONNECT request.  The ":protocol" pseudo-header field MUST be
set to "webtransport".  The ":scheme" field MUST be "https".  Both
the ":authority" and the ":path" value MUST be set; those fields
indicate the desired WebTransport server.  The client MUST pick a new
session ID as described in session-ids and send it encoded as a
hexadecimal literal in ":sessionid" header.  An "Origin" header
RFC6454 MUST be provided within the request.
Upon receiving an extended CONNECT request with a ":protocol" field
set to ":webtransport", the HTTP/3 server can check if it has a
WebTransport server associated with the specified ":authority" and
":path" values.  If it does not, it SHOULD reply with status code 404
(Section 6.5.4, RFC7231).  If it does, it MAY accept the session by
replying with status code 200.  Before accepting it, the HTTP/3
server MUST verify that the proposed session ID does not conflict
with any currently open sessions, and it MAY verify that it was not
used ever before on this connection.  The WebTransport server MUST
verify the "Origin" header to ensure that the specified origin is
allowed to access the server in question.
In order to indicate support for WebTransport, both the client and
the server MUST send a SETTINGS_ENABLE_WEBTRANSPORT value set to "1"
in their SETTINGS frame.  Endpoints MUST NOT use any WebTransport-
related functionality unless the parameter has been negotiated.
If SETTINGS_ENABLE_WEBTRANSPORT is negotiated, support for the QUIC
DATAGRAMs within HTTP/3 MUST be negotiated as described in
HTTP3-DATAGRAM; negotiating WebTransport support without negotiating
QUIC DATAGRAM extension SHALL result in a H3_SETTINGS_ERROR error.
HTTP3 requires client's "initial_max_bidi_streams" transport
parameter to be set to zero.  Existing implementation might enforce
this requirement before negotiating settings; thus, the client MUST
send a non-zero MAX_STREAMS for client-initiated bidirectional
streams after receiving an appropriate SETTINGS frame from the
server.
RFC8441 defines an extended CONNECT method in Section 4, enabled by
the SETTINGS_ENABLE_CONNECT_PROTOCOL parameter.  That parameter is
only defined for HTTP/2.  This document does not create a new multi-
purpose parameter to indicate support for extended CONNECT in HTTP/3;
instead, the SETTINGS_ENABLE_WEBTRANSPORT setting implies that an
endpoint supports extended CONNECT.
In order to create a new WebTransport session, a client can send an
HTTP CONNECT request.  The ":protocol" pseudo-header field (RFC8441)
MUST be set to "webtransport".  The ":scheme" field MUST be "https".
Both the ":authority" and the ":path" value MUST be set; those fields
indicate the desired WebTransport server.  An "Origin" header RFC6454
MUST be provided within the request.
Upon receiving an extended CONNECT request with a ":protocol" field
set to "webtransport", the HTTP/3 server can check if it has a
WebTransport server associated with the specified ":authority" and
":path" values.  If it does not, it SHOULD reply with status code 404
(Section 6.5.4, RFC7231).  If it does, it MAY accept the session by
replying with status code 200.  The WebTransport server MUST verify
the "Origin" header to ensure that the specified origin is allowed to
access the server in question.
WebTransport servers can initiate bidirectional streams by opening a
bidirectional stream within the HTTP/3 connection.  Note that since
HTTP/3 does not define any semantics for server-initiated
bidirectional streams, this document is a normative reference for the
semantics of such streams for all HTTP/3 connections in which the
"http3_transport_support" option is negotiated.  The format of those
streams SHALL be the session ID, encoded as a variable-length
integer, followed by the user-specified stream data (fig-bidi-
server).
Datagrams can be sent using the DATAGRAM frame as defined in QUIC-
DATAGRAM and H3-DATAGRAM.  For all HTTP/3 connections in which the
"http3_transport_support" option is negotiated, the Flow Identifier
is set to the session ID.  In other words, the format of datagrams
SHALL be the session ID, followed by the user-specified payload (fig-
datagram).
WebTransport servers can initiate bidirectional streams by opening a
bidirectional stream within the HTTP/3 connection.  Note that since
HTTP/3 does not define any semantics for server-initiated
bidirectional streams, this document is a normative reference for the
semantics of such streams for all HTTP/3 connections in which the
SETTINGS_ENABLE_WEBTRANSPORT option is negotiated.  The format of
those streams SHALL be the session ID, encoded as a variable-length
integer, followed by the user-specified stream data (fig-bidi-
server).
Datagrams can be sent using the DATAGRAM frame as defined in QUIC-
DATAGRAM and HTTP3-DATAGRAM.  For all HTTP/3 connections in which the
SETTINGS_ENABLE_WEBTRANSPORT option is negotiated, the Flow
Identifier is set to the session ID.  In other words, the format of
datagrams SHALL be the session ID, followed by the user-specified
payload (fig-datagram).
The "http3_transport_support" parameter indicates that the specified
HTTP/3 connection is WebTransport-capable.
0x????
The "SETTINGS_ENABLE_WEBTRANSPORT" parameter indicates that the
specified HTTP/3 connection is WebTransport-capable.