package shuttle_http

  1. Overview
  2. Docs

Stream represents streaming HTTP bodies. This module provides utilities to create and consume streams, while enforcing the invariant that only one consume can read from a stream, and that a stream can only be consumed once.

type t
val sexp_of_t : t -> Sexplib0.Sexp.t
val of_pipe : [ `Chunked | `Fixed of int ] -> string Async.Pipe.Reader.t -> t

of_pipe is a convenience function that creates a stream from a user provided Async_kernel.Pipe.Reader.t. The pipe will be closed whenever the streaming body is closed, or EOF is reached.

val close : t -> unit

close allows for closing/tearing-down any resources that are used to produce the content for a stream. For servers, this function will be called if the underlying client socket connection is closed, or when the body is fully drained.

val encoding : t -> [ `Chunked | `Fixed of int ]

encoding informs whether the body needs to be chunk encoded or not. For servers this function is used to automatically populate the transfer-encoding or content-length headers.

val iter : t -> f:(string -> unit Async.Deferred.t) -> unit Async.Deferred.t

iter t ~f consumes chunks of data one at a time. The stream can only be iterated on once.

val iter_without_pushback : t -> f:(string -> unit) -> unit Async.Deferred.t
val fold : t -> init:'a -> f:('a -> string -> 'a Async.Deferred.t) -> 'a Async.Deferred.t
val fold_without_pushback : t -> init:'a -> f:('a -> string -> 'a) -> 'a Async.Deferred.t
val drain : t -> unit Async.Deferred.t

drain should consume items one at a time from the stream and discard them. This function raises if its called after a consumer has started reading data from the stream.

val closed : t -> unit Async.Deferred.t

closed is a deferred that should be resolved when the stream is closed/drained.

val read_started : t -> bool

read_started indicated whether a user started to consume a stream or not. Servers will use read_started to verify if they should drain before starting the next cycle of the server loop, or if they should wait for the body to be closed by the user.

val to_string : t -> string Async.Deferred.t

to_string consumes the entire stream and converts it into a string. to_string consumes the entire stream so it can only be called once.