A batteries included HTTP/1.1 client in OCaml
1(*---------------------------------------------------------------------------
2 Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved.
3 SPDX-License-Identifier: ISC
4 ---------------------------------------------------------------------------*)
5
6let src = Logs.Src.create "requests.timeout" ~doc:"HTTP Request Timeouts"
7module Log = (val Logs.src_log src : Logs.LOG)
8
9type t = {
10 connect : float option;
11 read : float option;
12 total : float option;
13 expect_100_continue : float option; (** Timeout for 100-continue response *)
14}
15
16let none = {
17 connect = None;
18 read = None;
19 total = None;
20 expect_100_continue = None;
21}
22
23let create ?connect ?read ?total ?expect_100_continue () = {
24 connect;
25 read;
26 total;
27 expect_100_continue;
28}
29
30let default = {
31 connect = Some 10.0;
32 read = Some 30.0;
33 total = None;
34 expect_100_continue = Some 1.0; (* 1 second default for 100-continue *)
35}
36
37let connect t = t.connect
38let read t = t.read
39let total t = t.total
40let expect_100_continue t = t.expect_100_continue
41
42let pp ppf t =
43 let items = [] in
44 let items = match t.connect with
45 | Some c -> (Printf.sprintf "connect:%.1fs" c) :: items
46 | None -> items
47 in
48 let items = match t.read with
49 | Some r -> (Printf.sprintf "read:%.1fs" r) :: items
50 | None -> items
51 in
52 let items = match t.total with
53 | Some tot -> (Printf.sprintf "total:%.1fs" tot) :: items
54 | None -> items
55 in
56 let items = match t.expect_100_continue with
57 | Some e -> (Printf.sprintf "expect:%.1fs" e) :: items
58 | None -> items
59 in
60 match items with
61 | [] -> Format.fprintf ppf "no timeouts"
62 | _ -> Format.fprintf ppf "%s" (String.concat ", " (List.rev items))