forked from
anil.recoil.org/ocaml-requests
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
6(** HTTP request methods per
7 {{:https://datatracker.ietf.org/doc/html/rfc9110#section-9}RFC 9110 Section
8 9}
9
10 HTTP methods indicate the desired action to be performed on a resource. The
11 method token is case-sensitive.
12
13 {2 Safe Methods}
14
15 Methods are considered "safe" if their semantics are read-only (GET, HEAD,
16 OPTIONS, TRACE). Per
17 {{:https://datatracker.ietf.org/doc/html/rfc9110#section-9.2.1}RFC 9110
18 Section 9.2.1}.
19
20 {2 Idempotent Methods}
21
22 A method is "idempotent" if multiple identical requests have the same effect
23 as a single request (GET, HEAD, PUT, DELETE, OPTIONS, TRACE). Per
24 {{:https://datatracker.ietf.org/doc/html/rfc9110#section-9.2.2}RFC 9110
25 Section 9.2.2}. *)
26
27val src : Logs.Src.t
28(** Log source for method operations. *)
29
30type t =
31 [ `GET (** Retrieve a resource *)
32 | `POST (** Submit data to be processed *)
33 | `PUT (** Replace a resource *)
34 | `DELETE (** Delete a resource *)
35 | `HEAD (** Retrieve headers only *)
36 | `OPTIONS (** Retrieve allowed methods *)
37 | `PATCH (** Partial resource modification *)
38 | `CONNECT (** Establish tunnel to server *)
39 | `TRACE (** Echo received request *)
40 | `Other of string (** Non-standard or extension method *) ]
41(** HTTP method type using polymorphic variants for better composability *)
42
43(** {1 Conversion Functions} *)
44
45val to_string : t -> string
46(** Convert method to uppercase string representation. *)
47
48val of_string : string -> t
49(** [of_string s] parses a method from string (case-insensitive). Returns
50 [`Other s] for unrecognized methods. *)
51
52val pp : Format.formatter -> t -> unit
53(** Pretty printer for methods. *)
54
55(** {1 Method Properties} *)
56
57val is_safe : t -> bool
58(** Returns true for safe methods (GET, HEAD, OPTIONS, TRACE). Safe methods
59 should not have side effects. *)
60
61val is_idempotent : t -> bool
62(** Returns true for idempotent methods (GET, HEAD, PUT, DELETE, OPTIONS,
63 TRACE). Idempotent methods can be called multiple times with the same
64 result. *)
65
66(** Request body semantics per RFC 9110 Section 9.3 *)
67type body_semantics =
68 | Body_required (** Method requires a body (POST, PUT, PATCH) *)
69 | Body_optional (** Method MAY have a body (DELETE, OPTIONS, GET) *)
70 | Body_forbidden (** Method MUST NOT have a body (HEAD, TRACE, CONNECT) *)
71
72val request_body_semantics : t -> body_semantics
73(** Returns the request body semantics for a method per RFC 9110.
74
75 - {!Body_required}: POST, PUT, PATCH - body is expected
76 - {!Body_optional}: DELETE, OPTIONS, GET - body allowed but has no defined
77 semantics
78 - {!Body_forbidden}: HEAD, TRACE, CONNECT - body MUST NOT be sent. *)
79
80val has_request_body : t -> bool
81(** Returns true for methods that typically have a request body (POST, PUT,
82 PATCH).
83 @deprecated
84 Use {!request_body_semantics} for more accurate RFC 9110 semantics. *)
85
86val is_cacheable : t -> bool
87(** Returns true for methods whose responses are cacheable by default (GET,
88 HEAD, POST). Note: POST is only cacheable with explicit cache headers. *)
89
90(** {1 Comparison} *)
91
92val equal : t -> t -> bool
93(** Compare two methods for equality. *)
94
95val compare : t -> t -> int
96(** Compare two methods for ordering. *)