Hcs.H2_client

hcs · API reference

HTTP/2-specific client.

Use only when you need direct control over HTTP/2 multiplexing behavior. Prefer Client for general application code.

HTTP/2 Client implementation on the http sans-I/O codec (Http2.Client_connection).

Multiplexed HTTP/2 client over Eio with connection pooling. The transport (TCP/TLS), DNS, pooling and timeouts live here; framing/HPACK/flow-control are driven by http. The connection is driven with two fibers (reader + writer) over the same read / next_write_operation surface as the server, with an Eio.Stream wake mailbox.

module C = Http2.Client_connection

Types

type error = 
  | Connection_failed of string
  | Tls_error of string
  | Protocol_error of string
  | Timeout
  | Invalid_response of string
  | Response_body_too_large of int64
type response = {
  status : Status.t;
  headers : Http_core.Headers.t;
  body : string;
}
type request_spec = {
  meth : Method.t;
  headers : (string * string) list;
  body : string;
  url : Uri.t;
}
type config = {
  connect_timeout : float;
  read_timeout : float;
  buffer_size : int;
  max_response_body : int64 option;
  default_headers : (string * string) list;
  pool : Pool.config;
}
val default_config : config
val default_default_headers : (string * string) list
val with_timeout : float -> config -> config
val with_default_header : string -> string -> config -> config
val with_default_headers : (string * string) list -> config -> config
val with_max_response_body : int64 -> config -> config
val with_pool_config : Pool.config -> config -> config

Internal connection type

type conn = {
  flow : Eio.Flow.two_way_ty Eio.Std.r;
  mutable alive : bool;
}
type t = {
  config : config;
  pool : conn Pool.t;
  mutex : Eio.Mutex.t;
  connect : host:string ->
  port:int ->
  is_https:bool ->
  Eio.Flow.two_way_ty Eio.Std.r;
  resolve : string -> bool;
  now : unit -> float;
  with_timeout : 'a. float -> (unit -> 'a) -> 'a option;
}

Internal helpers

val writev : 
  [> Eio.Flow.sink_ty ] Eio.Flow.sink ->
  Http_core.Iovec.t list ->
  int

Write the codec's iovecs to the flow; returns the byte count written.

module Read_buffer : sig ... end
val close_conn : conn -> unit
val drive : 
  [> `Flow | `R | `W ] Eio.Flow.source ->
  C.t ->
  done_:bool ref ->
  unit

Drive one client connection with a reader and writer fiber sharing a wake mailbox (the writer parks on it when there is nothing to send; the reader signals it after each read so flow-control acks / window updates go out). done_ decides when the work is finished so the writer can stop.

val map_error : max_response_body:int64 option -> C.error -> error
val request_parts : Uri.t -> string * bool * string * int * string
val authority : host:string -> port:int -> is_https:bool -> string
val method_has_body : Method.t -> bool

Method may carry a request body (controls the default content-type).

val build_headers : 
  t ->
  has_body:bool ->
  headers:(string * string) list ->
  Http_core.Headers.t

Build the regular header set (no pseudo-headers, no content-length — the codec adds :method/:scheme/:path/:authority and frames the body).

val do_request : 
  ?body:string ->
  ?max_response_body:int64 ->
  [> `Flow | `R | `W ] Eio.Flow.source ->
  meth:Http_core.Method.t ->
  target:string ->
  scheme:string ->
  authority:string ->
  headers:Http_core.Headers.t ->
  (response, error) result

Perform one HTTP/2 request on a connected flow.

val do_requests : 
  ?max_response_body:int64 ->
  [> `Flow | `R | `W ] Eio.Flow.source ->
  (Http_core.Method.t * string * string * string * Http_core.Headers.t * string)
    array ->
  (response, error) result list

Perform many HTTP/2 requests concurrently on one connection.

val create_connection : 
  t ->
  host:string ->
  port:int ->
  is_https:bool ->
  (conn, error) result
val acquire_connection : 
  t ->
  host:string ->
  port:int ->
  is_https:bool ->
  (conn, error) result
val release_connection : 
  t ->
  host:string ->
  port:int ->
  is_https:bool ->
  conn ->
  keep_alive:bool ->
  unit

Public API

val create : 
  sw:Eio.Switch.t ->
  net:[> [> `Generic ] Eio.Net.ty ] Eio.Net.t ->
  clock:[> float Eio.Time.clock_ty ] Eio.Time.clock ->
  ?config:config ->
  unit ->
  t
val close : t -> unit
val request : 
  t ->
  Method.t ->
  ?headers:(string * string) list ->
  ?body:string ->
  Uri.t ->
  (response, error) result

Perform an HTTP/2 request with any method using pooled connections.

val same_origin : 
  ('a * 'b * String.t * 'c * 'd) ->
  ('e * 'b * String.t * 'c * 'f) ->
  bool
val chunks : int -> 'a list -> 'a list list
val request_many : 
  ?max_concurrent:int ->
  t ->
  request_spec list ->
  (response, error) result list

Perform multiple HTTP/2 requests concurrently on one connection per chunk.

Convenience methods

val get : 
  t ->
  ?headers:(string * string) list ->
  Uri.t ->
  (response, error) result
val post : 
  t ->
  ?headers:(string * string) list ->
  Uri.t ->
  body:string ->
  (response, error) result
val put : 
  t ->
  ?headers:(string * string) list ->
  Uri.t ->
  body:string ->
  (response, error) result
val patch : 
  t ->
  ?headers:(string * string) list ->
  Uri.t ->
  body:string ->
  (response, error) result
val delete : 
  t ->
  ?headers:(string * string) list ->
  ?body:string ->
  Uri.t ->
  (response, error) result
val head : 
  t ->
  ?headers:(string * string) list ->
  Uri.t ->
  (response, error) result
val options : 
  t ->
  ?headers:(string * string) list ->
  Uri.t ->
  (response, error) result

Stateless API

val get' : 
  sw:Eio.Switch.t ->
  net:[> [> `Generic ] Eio.Net.ty ] Eio.Net.t ->
  clock:[> float Eio.Time.clock_ty ] Eio.Time.clock ->
  ?config:config ->
  Uri.t ->
  (response, error) result
val post' : 
  sw:Eio.Switch.t ->
  net:[> [> `Generic ] Eio.Net.ty ] Eio.Net.t ->
  clock:[> float Eio.Time.clock_ty ] Eio.Time.clock ->
  ?config:config ->
  Uri.t ->
  body:string ->
  (response, error) result