My agentic slop goes here. Not intended for anyone else!
at main 5.0 kB view raw
1(** HTTP request body construction 2 3 This module provides various ways to construct HTTP request bodies, 4 including strings, files, streams, forms, and multipart data. 5 6 {2 Examples} 7 8 {[ 9 (* Simple text body *) 10 let body = Body.text "Hello, World!" 11 12 (* JSON body *) 13 let body = Body.json {|{"name": "Alice", "age": 30}|} 14 15 (* Form data *) 16 let body = Body.form [ 17 ("username", "alice"); 18 ("password", "secret") 19 ] 20 21 (* File upload *) 22 let body = Body.of_file ~mime:Mime.pdf (Eio.Path.(fs / "document.pdf")) 23 24 (* Multipart form with file *) 25 let body = Body.multipart [ 26 { name = "field"; filename = None; 27 content_type = Mime.text_plain; 28 content = `String "value" }; 29 { name = "file"; filename = Some "photo.jpg"; 30 content_type = Mime.jpeg; 31 content = `File (Eio.Path.(fs / "photo.jpg")) } 32 ] 33 ]} 34*) 35 36(** Log source for body operations *) 37val src : Logs.Src.t 38 39type t 40(** Abstract body type representing HTTP request body content. *) 41 42(** {1 Basic Constructors} *) 43 44val empty : t 45(** [empty] creates an empty body (no content). *) 46 47val of_string : Mime.t -> string -> t 48(** [of_string mime content] creates a body from a string with the specified MIME type. 49 Example: [of_string Mime.json {|{"key": "value"}|}] *) 50 51val of_stream : ?length:int64 -> Mime.t -> Eio.Flow.source_ty Eio.Resource.t -> t 52(** [of_stream ?length mime stream] creates a streaming body. If [length] is provided, 53 it will be used for the Content-Length header, otherwise chunked encoding is used. *) 54 55val of_file : ?mime:Mime.t -> _ Eio.Path.t -> t 56(** [of_file ?mime path] creates a body from a file. The MIME type is inferred from 57 the file extension if not provided. *) 58 59(** {1 Convenience Constructors} *) 60 61val json : Jsont.json -> t 62(** [json value] creates a JSON body from a Jsont.json value. 63 The value is encoded to a JSON string with Content-Type: application/json. 64 65 Example: 66 {[ 67 let body = Body.json (Jsont.Object ([ 68 ("status", Jsont.String "success"); 69 ("count", Jsont.Number 42.); 70 ("items", Jsont.Array ([Jsont.String "first"; Jsont.String "second"], Jsont.Meta.none)) 71 ], Jsont.Meta.none)) 72 ]} 73*) 74 75val json_stream : Jsont.json -> t 76(** [json_stream json_value] creates a streaming JSON body from a Jsont.json value. 77 The JSON value will be encoded to a minified JSON string and streamed. 78 79 Example: 80 {[ 81 let large_data = Jsont.Object ([ 82 ("users", Jsont.Array ([...], Jsont.Meta.none)) 83 ], Jsont.Meta.none) in 84 let body = Body.json_stream large_data 85 ]} 86*) 87 88val text : string -> t 89(** [text str] creates a plain text body with Content-Type: text/plain. *) 90 91val form : (string * string) list -> t 92(** [form fields] creates a URL-encoded form body with Content-Type: application/x-www-form-urlencoded. 93 Example: [form [("username", "alice"); ("password", "secret")]] *) 94 95(** {1 Multipart Support} *) 96 97type 'a part = { 98 name : string; (** Form field name *) 99 filename : string option; (** Optional filename for file uploads *) 100 content_type : Mime.t; (** MIME type of this part *) 101 content : [ 102 | `String of string (** String content *) 103 | `Stream of Eio.Flow.source_ty Eio.Resource.t (** Streaming content *) 104 | `File of 'a Eio.Path.t (** File content *) 105 ]; 106} 107(** A single part in a multipart body. *) 108 109val multipart : _ part list -> t 110(** [multipart parts] creates a multipart/form-data body from a list of parts. 111 This is commonly used for file uploads and complex form submissions. 112 113 Example: 114 {[ 115 let body = Body.multipart [ 116 { name = "username"; filename = None; 117 content_type = Mime.text_plain; 118 content = `String "alice" }; 119 { name = "avatar"; filename = Some "photo.jpg"; 120 content_type = Mime.jpeg; 121 content = `File (Eio.Path.(fs / "photo.jpg")) } 122 ] 123 ]} 124*) 125 126(** {1 Properties} *) 127 128val content_type : t -> Mime.t option 129(** [content_type body] returns the MIME type of the body, if set. *) 130 131val content_length : t -> int64 option 132(** [content_length body] returns the content length in bytes, if known. 133 Returns [None] for streaming bodies without a predetermined length. *) 134 135(** {1 Private API} *) 136 137(** Internal functions exposed for use by other modules in the library. 138 These are not part of the public API and may change between versions. *) 139module Private : sig 140 val to_cohttp_body : sw:Eio.Switch.t -> t -> Cohttp_eio.Body.t option 141 (** [to_cohttp_body ~sw body] converts the body to cohttp-eio format. 142 Uses the switch to manage resources like file handles. 143 This function is used internally by the Client module. *) 144 145 val to_string : t -> string 146 (** [to_string body] converts the body to a string for HTTP/1.1 requests. 147 Only works for materialized bodies (String type). 148 Raises Failure for streaming/file/multipart bodies. *) 149end