Skip to content

http3.Session

Randy Reddig edited this page Aug 12, 2021 · 5 revisions

These are rough notes, some (most) of which are either obsolete or implemented.

An http3.Session would be created and used by a client and a server. It would contain:

  • an http3.Stream
  • headers
  • trailers
  • authority
  • method
  • request body

It can be created from an http3.Conn via:

type SessionConn interface {
        Open(context.Context, []qpack.HeaderField) (http3.Session, error)
        Accept(context.Context) (http3.Session, error)
}

An http3.Server could handle an http3.Session with:

type HTTP3Server interface {
        ServeHTTP3(http3.Session) error
}

Interface

An http3.Session can vend datagram contexts via two methods, which supply a DatagramContext.

type Session interface {
        // Headers returns the headers sent by the peer.
        Headers() ([]qpack.HeaderField, error)

        // Trailers returns the trailers sent by the peer.
        // If no trailers have been received yet, it will return an ErrTODO.
        Trailers() ([]qpack.HeaderField, error)

        // Stream is the request stream for this session.
        Stream() Stream

        BodyReader() io.ReadCloser
        BodyWriter() io.WriteCloser

        // AcceptStream is used by WebTransport or other HTTP/3 extensions.
        AcceptStream(context.Context) (Stream, error)

        // AcceptUniStream is used by WebTransport or other HTTP/3 extensions.
        AcceptUniStream(context.Context) (ReadableStream, error)

        // OpenStream is used by WebTransport or other HTTP/3 extensions.
        OpenStream() (Stream, error)
        OpenStreamSync(context.Context) (Stream, error)

        // OpenUniStream is used for opening a unidirectional stream.
        // Examples include push streams or unidirectional WebTransport streams.
        OpenUniStream(StreamType) (WritableStream, error)
        OpenUniStreamSync(context.Context, StreamType) (WritableStream, error)

	// AcceptDatagramContext receives a datagram context from a peer.
	// This allows a server, for instance, to start receiving datagrams on a
	// client-initiated datagram context.
	AcceptDatagramContext() (DatagramContext, error)

	// RegisterDatagramContext allocates a new datagram context for the request.
	// It returns an error if a context cannot be allocated or datagrams are not enabled.
	// https://www.ietf.org/archive/id/draft-ietf-masque-h3-datagram-03.html#name-the-register_datagram_conte
	RegisterDatagramContext() (DatagramContext, error)

	// DatagramNoContext signals to the server that datagrams associated with this request
	// will not use datagram context IDs.
	// It returns an error if a context cannot be allocated or datagrams are not enabled.
	// Multiple calls will return the same database context.
	// Calling DatagramContext after DatagramNoContext will return an error.
	// https://www.ietf.org/archive/id/draft-ietf-masque-h3-datagram-03.html#name-the-register_datagram_no_co
	DatagramNoContext() (DatagramContext, error)
}

A DatagramContext provides the necessary multiplexing to allow different applications to coexist on the same HTTP/3 request stream.

type DatagramContext interface {
	ContextID() uint64 // Necessary?
	ReadDatagram() ([]byte, error)
	WriteDatagram([]byte) error
	io.Closer
}
Clone this wiki locally