A batteries included HTTP/1.1 client in OCaml
at main 61 lines 2.1 kB view raw
1(*--------------------------------------------------------------------------- 2 Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved. 3 SPDX-License-Identifier: ISC 4 ---------------------------------------------------------------------------*) 5 6(** HTTP 100-Continue configuration 7 8 Configuration for the HTTP 100-Continue protocol, which allows clients to 9 check if the server will accept a request before sending a large body. Per 10 RFC 9110 Section 10.1.1 (Expect) and Section 15.2.1 (100 Continue). *) 11 12type config = 13 [ `Disabled (** Never use 100-continue *) 14 | `Always (** Always use 100-continue regardless of body size *) 15 | `Threshold of int64 (** Use 100-continue for bodies >= threshold bytes *) 16 ] 17(** User-facing configuration as a polymorphic variant *) 18 19type t = { enabled : bool; threshold : int64; timeout : float } 20(** Internal representation *) 21 22let default_threshold = 1_048_576L (* 1MB *) 23 24let default = 25 { 26 enabled = true; 27 threshold = default_threshold; 28 timeout = 1.0; 29 (* 1 second *) 30 } 31 32let of_config ?(timeout = 1.0) (config : config) : t = 33 match config with 34 | `Disabled -> { enabled = false; threshold = 0L; timeout } 35 | `Always -> { enabled = true; threshold = 0L; timeout } 36 | `Threshold n -> { enabled = true; threshold = n; timeout } 37 38let v ?(enabled = true) ?(threshold = 1_048_576L) ?(timeout = 1.0) () = 39 { enabled; threshold; timeout } 40 41let disabled = { enabled = false; threshold = 0L; timeout = 0.0 } 42let enabled t = t.enabled 43let threshold t = t.threshold 44let timeout t = t.timeout 45let should_use t body_size = t.enabled && body_size >= t.threshold 46 47let pp fmt t = 48 if not t.enabled then Fmt.pf fmt "100-continue: disabled" 49 else if t.threshold = 0L then 50 Fmt.pf fmt "100-continue: always (timeout: %.2fs)" t.timeout 51 else 52 Fmt.pf fmt "100-continue: threshold %Ld bytes (timeout: %.2fs)" t.threshold 53 t.timeout 54 55let to_string t = Fmt.str "%a" pp t 56 57let pp_config fmt (config : config) = 58 match config with 59 | `Disabled -> Fmt.pf fmt "`Disabled" 60 | `Always -> Fmt.pf fmt "`Always" 61 | `Threshold n -> Fmt.pf fmt "`Threshold %Ld" n