···1+ISC License
2+3+Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>
4+5+Permission to use, copy, modify, and distribute this software for any
6+purpose with or without fee is hereby granted, provided that the above
7+copyright notice and this permission notice appear in all copies.
8+9+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
···1+# requests - HTTP Client Library for OCaml
2+3+A modern HTTP(S) client library for OCaml with Eio support, providing a clean API for making web requests with automatic TLS/CA certificate handling. Inspired by Python's requests library.
4+5+## Key Features
6+7+- **Clean Eio-style API**: Async I/O using OCaml 5's Eio library
8+- **Automatic TLS**: Built-in TLS support with automatic CA certificate handling
9+- **Simple Interface**: Intuitive API similar to Python's requests library
10+- **Type-safe**: Leverages OCaml's type system for safer HTTP operations
11+- **Comprehensive**: Support for common HTTP methods, headers, authentication, retries, and timeouts
12+13+## Usage
14+15+Basic GET request:
16+17+```ocaml
18+let () =
19+ Eio_main.run @@ fun env ->
20+ let response = Requests.get ~env (Uri.of_string "https://example.com") in
21+ print_endline (Requests.Response.body_string response)
22+```
23+24+POST request with JSON body:
25+26+```ocaml
27+let () =
28+ Eio_main.run @@ fun env ->
29+ let uri = Uri.of_string "https://api.example.com/data" in
30+ let body = {|{"key": "value"}|} in
31+ let headers = Requests.Headers.of_list [
32+ ("content-type", "application/json")
33+ ] in
34+ let response = Requests.post ~env ~headers ~body uri in
35+ Printf.printf "Status: %d\n" (Requests.Response.status_code response)
36+```
37+38+Using authentication and custom headers:
39+40+```ocaml
41+let () =
42+ Eio_main.run @@ fun env ->
43+ let auth = Requests.Auth.basic ~username:"user" ~password:"pass" in
44+ let headers = Requests.Headers.add
45+ (Requests.Headers.init ())
46+ "user-agent" "my-app/1.0" in
47+ let response = Requests.get ~env ~auth ~headers
48+ (Uri.of_string "https://api.example.com") in
49+ (* Process response *)
50+ ()
51+```
52+53+## Installation
54+55+```
56+opam install requests
57+```
58+59+## Documentation
60+61+API documentation is available at https://tangled.org/@anil.recoil.org/ocaml-requests or via:
62+63+```
64+opam install requests
65+odig doc requests
66+```
67+68+## License
69+70+ISC
···1+(*---------------------------------------------------------------------------
2+ Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved.
3+ SPDX-License-Identifier: ISC
4+ ---------------------------------------------------------------------------*)
5+6(** Authentication mechanisms *)
78(** Log source for authentication operations *)
+6-1
lib/body.ml
···000001let src = Logs.Src.create "requests.body" ~doc:"HTTP Request/Response Body"
2module Log = (val Logs.src_log src : Logs.LOG)
3···63(* JSON streaming using jsont - we encode the value to string and stream it *)
64module Json_stream_source = struct
65 type t = {
66- mutable content : string;
67 mutable offset : int;
68 }
69
···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.body" ~doc:"HTTP Request/Response Body"
7module Log = (val Logs.src_log src : Logs.LOG)
8···68(* JSON streaming using jsont - we encode the value to string and stream it *)
69module Json_stream_source = struct
70 type t = {
71+ content : string;
72 mutable offset : int;
73 }
74
+5
lib/body.mli
···000001(** HTTP request body construction
23 This module provides various ways to construct HTTP request bodies,
···1+(*---------------------------------------------------------------------------
2+ Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved.
3+ SPDX-License-Identifier: ISC
4+ ---------------------------------------------------------------------------*)
5+6(** HTTP request body construction
78 This module provides various ways to construct HTTP request bodies,
+5
lib/error.ml
···000001(** Centralized error handling for the Requests library *)
23let src = Logs.Src.create "requests.error" ~doc:"HTTP Request Errors"
···1+(*---------------------------------------------------------------------------
2+ Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved.
3+ SPDX-License-Identifier: ISC
4+ ---------------------------------------------------------------------------*)
5+6(** Centralized error handling for the Requests library *)
78let src = Logs.Src.create "requests.error" ~doc:"HTTP Request Errors"
+5
lib/error.mli
···000001(** Centralized error handling for the Requests library *)
23(** Log source for error reporting *)
···1+(*---------------------------------------------------------------------------
2+ Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved.
3+ SPDX-License-Identifier: ISC
4+ ---------------------------------------------------------------------------*)
5+6(** Centralized error handling for the Requests library *)
78(** Log source for error reporting *)
···000001(** HTTP headers management with case-insensitive keys
23 This module provides an efficient implementation of HTTP headers with
···1+(*---------------------------------------------------------------------------
2+ Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved.
3+ SPDX-License-Identifier: ISC
4+ ---------------------------------------------------------------------------*)
5+6(** HTTP headers management with case-insensitive keys
78 This module provides an efficient implementation of HTTP headers with
+5
lib/http_client.ml
···000001(** Low-level HTTP/1.1 client over raw TCP connections for connection pooling *)
23let src = Logs.Src.create "requests.http_client" ~doc:"Low-level HTTP client"
···1+(*---------------------------------------------------------------------------
2+ Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved.
3+ SPDX-License-Identifier: ISC
4+ ---------------------------------------------------------------------------*)
5+6(** Low-level HTTP/1.1 client over raw TCP connections for connection pooling *)
78let src = Logs.Src.create "requests.http_client" ~doc:"Low-level HTTP client"
···000001(** One-shot HTTP client for stateless requests
23 The One module provides a stateless HTTP client for single requests without
···1+(*---------------------------------------------------------------------------
2+ Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved.
3+ SPDX-License-Identifier: ISC
4+ ---------------------------------------------------------------------------*)
5+6(** One-shot HTTP client for stateless requests
78 The One module provides a stateless HTTP client for single requests without
+5
lib/requests.ml
···000001(** OCaml HTTP client library with streaming support *)
23let src = Logs.Src.create "requests" ~doc:"HTTP Client Library"
···1+(*---------------------------------------------------------------------------
2+ Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved.
3+ SPDX-License-Identifier: ISC
4+ ---------------------------------------------------------------------------*)
5+6(** OCaml HTTP client library with streaming support *)
78let src = Logs.Src.create "requests" ~doc:"HTTP Client Library"
+5
lib/requests.mli
···000001(** Requests - A modern HTTP client library for OCaml
23 Requests is an HTTP client library for OCaml inspired by Python's requests
···1+(*---------------------------------------------------------------------------
2+ Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved.
3+ SPDX-License-Identifier: ISC
4+ ---------------------------------------------------------------------------*)
5+6(** Requests - A modern HTTP client library for OCaml
78 Requests is an HTTP client library for OCaml inspired by Python's requests
···1+(*---------------------------------------------------------------------------
2+ Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved.
3+ SPDX-License-Identifier: ISC
4+ ---------------------------------------------------------------------------*)
5+6(** HTTP request retry logic with exponential backoff *)
78open Eio
+5
lib/status.ml
···000001(** HTTP status codes following RFC 7231 and extensions *)
23let src = Logs.Src.create "requests.status" ~doc:"HTTP Status Codes"
···1+(*---------------------------------------------------------------------------
2+ Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved.
3+ SPDX-License-Identifier: ISC
4+ ---------------------------------------------------------------------------*)
5+6(** HTTP status codes following RFC 7231 and extensions *)
78let src = Logs.Src.create "requests.status" ~doc:"HTTP Status Codes"
+5
lib/status.mli
···000001(** HTTP status codes following RFC 7231 and extensions *)
23(** Log source for status code operations *)
···1+(*---------------------------------------------------------------------------
2+ Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved.
3+ SPDX-License-Identifier: ISC
4+ ---------------------------------------------------------------------------*)
5+6(** HTTP status codes following RFC 7231 and extensions *)
78(** Log source for status code operations *)
···1+(*---------------------------------------------------------------------------
2+ Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved.
3+ SPDX-License-Identifier: ISC
4+ ---------------------------------------------------------------------------*)
5+6(** Timeout configuration *)
78(** Log source for timeout operations *)
+11-9
requests.opam
···2opam-version: "2.0"
3synopsis: "Clean Eio-style HTTPS client library for OCaml"
4description:
5- "A modern HTTP(S) client library for OCaml with Eio support, providing a clean API for making web requests with automatic TLS/CA certificate handling"
6-maintainer: ["Your Name"]
7-authors: ["Your Name"]
8-license: "MIT"
9-homepage: "https://github.com/username/requests"
10-bug-reports: "https://github.com/username/requests/issues"
11depends: [
12- "ocaml"
13- "dune" {>= "3.0" & >= "3.0"}
14 "eio"
15 "cohttp-eio"
16 "tls-eio"
···21 "base64"
22 "logs"
23 "odoc" {with-doc}
0024]
25build: [
26 ["dune" "subst"] {dev}
···36 "@doc" {with-doc}
37 ]
38]
39-dev-repo: "git+https://github.com/username/requests.git"
···2opam-version: "2.0"
3synopsis: "Clean Eio-style HTTPS client library for OCaml"
4description:
5+ "A modern HTTP(S) client library for OCaml with Eio support, providing a clean API for making web requests with automatic TLS/CA certificate handling. Inspired by Python's requests library, this provides a simple, intuitive interface for HTTP operations."
6+maintainer: ["Anil Madhavapeddy <anil@recoil.org>"]
7+authors: ["Anil Madhavapeddy"]
8+license: "ISC"
9+homepage: "https://tangled.org/@anil.recoil.org/ocaml-requests"
10+bug-reports: "https://tangled.org/@anil.recoil.org/ocaml-requests/issues"
11depends: [
12+ "ocaml" {>= "5.1.0"}
13+ "dune" {>= "3.20" & >= "3.20"}
14 "eio"
15 "cohttp-eio"
16 "tls-eio"
···21 "base64"
22 "logs"
23 "odoc" {with-doc}
24+ "alcotest" {with-test & >= "1.7.0"}
25+ "eio_main" {with-test}
26]
27build: [
28 ["dune" "subst"] {dev}
···38 "@doc" {with-doc}
39 ]
40]
41+x-maintenance-intent: ["(latest)"]
+5
test/test_localhost.ml
···000001(* Test conpool with 16 localhost servers on different 127.0.* addresses *)
23open Eio.Std
···1+(*---------------------------------------------------------------------------
2+ Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved.
3+ SPDX-License-Identifier: ISC
4+ ---------------------------------------------------------------------------*)
5+6(* Test conpool with 16 localhost servers on different 127.0.* addresses *)
78open Eio.Std
+5
test/test_localhost.mli
···00000
···1+(*---------------------------------------------------------------------------
2+ Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved.
3+ SPDX-License-Identifier: ISC
4+ ---------------------------------------------------------------------------*)
5+
+5
test/test_simple.ml
···000001(* Simple test to debug connection issues *)
23open Eio.Std
···1+(*---------------------------------------------------------------------------
2+ Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved.
3+ SPDX-License-Identifier: ISC
4+ ---------------------------------------------------------------------------*)
5+6(* Simple test to debug connection issues *)
78open Eio.Std
+5
test/test_simple.mli
···00000
···1+(*---------------------------------------------------------------------------
2+ Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved.
3+ SPDX-License-Identifier: ISC
4+ ---------------------------------------------------------------------------*)
5+