My aggregated monorepo of OCaml code, automaintained
at main 67 lines 2.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 client using the requests library *) 7 8let src = Logs.Src.create "bushel.http" ~doc:"HTTP client" 9module Log = (val Logs.src_log src : Logs.LOG) 10 11type t = Requests.t 12 13let create ~sw env = 14 Requests.create ~sw ~follow_redirects:true env 15 16let get ~http url = 17 Log.debug (fun m -> m "GET %s" url); 18 try 19 let response = Requests.get http url in 20 if Requests.Response.ok response then begin 21 let body = Requests.Response.body response |> Eio.Flow.read_all in 22 Ok body 23 end else begin 24 let status = Requests.Response.status_code response in 25 Error (Printf.sprintf "HTTP %d" status) 26 end 27 with exn -> 28 Error (Printf.sprintf "Request failed: %s" (Printexc.to_string exn)) 29 30let get_with_header ~http ~header url = 31 Log.debug (fun m -> m "GET %s (with header)" url); 32 try 33 (* Parse header "Name: Value" format *) 34 let name, value = match String.index_opt header ':' with 35 | Some i -> 36 let name = String.sub header 0 i in 37 let value = String.trim (String.sub header (i + 1) (String.length header - i - 1)) in 38 (name, value) 39 | None -> (header, "") 40 in 41 let headers = Requests.Headers.empty |> Requests.Headers.add_string name value in 42 let response = Requests.get http ~headers url in 43 if Requests.Response.ok response then begin 44 let body = Requests.Response.body response |> Eio.Flow.read_all in 45 Ok body 46 end else begin 47 let status = Requests.Response.status_code response in 48 Error (Printf.sprintf "HTTP %d" status) 49 end 50 with exn -> 51 Error (Printf.sprintf "Request failed: %s" (Printexc.to_string exn)) 52 53let post ~http ~content_type ~body url = 54 Log.debug (fun m -> m "POST %s" url); 55 try 56 let mime = Requests.Mime.of_string content_type in 57 let body = Requests.Body.of_string mime body in 58 let response = Requests.post http ~body url in 59 if Requests.Response.ok response then begin 60 let body = Requests.Response.body response |> Eio.Flow.read_all in 61 Ok body 62 end else begin 63 let status = Requests.Response.status_code response in 64 Error (Printf.sprintf "HTTP %d" status) 65 end 66 with exn -> 67 Error (Printf.sprintf "Request failed: %s" (Printexc.to_string exn))