A batteries included HTTP/1.1 client in OCaml
at main 96 lines 3.5 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 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. *)