Module Ohttp.ChunkedSource

Chunked Oblivious HTTP (draft-ietf-ohai-chunked-ohttp-08).

Experimental. The draft is in the RFC Editor's queue, so its wire format is settled, but this interface may still change, and only some implementations provide the chunked variant.

A chunked message is sealed and opened piece by piece, so that a request or a response can be produced and consumed before all of it exists. The header and the key schedule are those of Ohttp.Client and Ohttp.Gateway under other labels; what follows the header is a sequence of chunks, each sealed on its own and preceded by its length. The last chunk has a length of zero, runs to the end of the stream, and is sealed with the additional data "final", so that a message cut short cannot pass for a complete one.

Nothing here performs I/O. A Sender turns pieces of a message into bytes to write, and a Receiver turns bytes read, split in any way at all, into pieces of the message.

A chunked request is sent as Media_type.ohttp_chunked_request and must be answered with Media_type.ohttp_chunked_response. Both should carry the field incremental: ?1, so that intermediaries forward them as they arrive. A client that is set up for chunked messages should not fall back to plain ones (Section 7 of the draft): a gateway that refuses one kind and accepts the other could otherwise tell clients apart.

"message/bhttp chunked request" and "message/bhttp chunked response".

Sourceval max_chunk_size : int

16384. Every receiver accepts a chunk that holds this much data before it is sealed, and a sender should produce no larger one unless it knows that its peer accepts it (Section 3 of the draft).

Sourceval chunk_nonce : nonce:string -> counter:int -> string

The nonce of the response chunk number counter, counting from 0: the response nonce of Encapsulation.response_keys XORed with the counter as a big-endian integer of the same length (Section 6.2 of the draft).

Sourcemodule Sender : sig ... end
Sourcemodule Receiver : sig ... end
Sourcemodule Client : sig ... end
Sourcemodule Gateway : sig ... end

Building blocks

Sourceval response_receiver : ?max_chunk_size:int -> Suite.t -> enc:string -> secret:string -> Receiver.t

The receiver for a response, from the encapsulated key of its request and the secret that the HPKE context exports for the response label. Like the functions of Encapsulation, it takes the secret as an argument, so that a recorded exchange can be opened from the gateway's side of the context. Applications should use Client.response.

Whole messages

Sourceval seal_all : ?chunk_size:int -> Sender.t -> string -> (string, Error.t) result

seal_all sender message is every chunk of a message that is already complete: pieces of chunk_size bytes, max_chunk_size by default, and whatever remains, which may be nothing, as the final chunk.

Sourceval open_all : Receiver.t -> string -> (string, Error.t) result

open_all receiver bytes is the message of a stream that is already complete.