std/http/duplex

std/http/src/duplex.trb

The connection a handler is handed after a 101 Switching Protocols (docs/design/NETWORK.md section 13, request 5): what is left of the connection once HTTP is done with it, as a reading half and a writing half. The protocol that follows - WebSocket framing is one, and is std/web's - is a stage over them.

type Duplex

shared type Duplex with Close

A connection switched to another protocol, in both directions at once. Duplex.source first yields whatever the connection had buffered after the request head - a client may send its first bytes with the request - and then reads the connection; Duplex.sink writes to it. Plain TCP and TLS alike: bytes are decrypted and encrypted underneath.

The head, idle and drain limits of the server do not apply to it; its timing is the upgrade handler's. The connection closes once the handler finishes - or is cancelled with a server that shuts down or closes - and is never read as HTTP again.

Examples

fn shout(duplex: Duplex): Task<Result<Void, HttpError>> {
  var incoming = duplex.source()
  var outgoing = duplex.sink()
  if const Some(chunk) = incoming.next().await()? {
    outgoing.add(chunk).await()?
  }
  outgoing.end().await()
}

fn of

static fn of(connection: Connection): Self

The duplex of connection, after the 101 was written.

fn source

fn source(chunk: Int = 65536): Source<Bytes, HttpError>

The reading half: at most chunk bytes per next(), and None once the peer ended its half.

fn sink

fn sink(): Sink<Bytes, HttpError>

The writing half: add writes all of the bytes, end ends this half (with close_notify on TLS).

fn remote

fn remote(): SocketAddress?

The address of the other end, where the system still knows it.

fn isEncrypted

fn isEncrypted(): Bool

Whether the bytes are encrypted: the connection was HTTPS.

fn close

var fn close()

Nothing of its own: the connection closes when the server is done with it.