open Cohttp_eio type t = Cohttp_eio.Client.t let authenticator = match Ca_certs.authenticator () with | Ok x -> x | Error (`Msg m) -> Fmt.failwith "Failed to create system store X509 authenticator: %s" m let https ~authenticator = let tls_config = match Tls.Config.client ~authenticator () with | Error (`Msg msg) -> failwith ("tls configuration problem: " ^ msg) | Ok tls_config -> tls_config in fun uri raw -> let host = Uri.host uri |> Option.map (fun x -> Domain_name.(host_exn (of_string_exn x))) in Tls_eio.client_of_flow ?host tls_config raw let v net = Client.make ~https:(Some (https ~authenticator)) net module Progress = struct type t = { flow : Eio.Flow.source_ty Eio.Resource.t; progress : int -> unit } let read_methods = [] let single_read (t : t) buf = let i = Eio.Flow.single_read t.flow buf in t.progress i; i end let progress_handler = Eio.Flow.Pi.source (module Progress) let with_progress ~progress flow = Eio.Resource.T (Progress.{ flow; progress }, progress_handler) let with_body ?(show = true) t display ~default ~uri fn = Eio.Switch.run @@ fun sw -> let uri = Uri.of_string uri in let response, body = Client.get t uri ~sw in match response.status with | `OK -> let total = Http.Response.content_length response |> Option.get in let bar = Display.line ~total:(Optint.Int63.of_int total) (Uri.path uri |> Filename.basename) in Display.with_line ~display ~show (fun _ -> bar) @@ fun r -> let progress = Display.report_int r in fn (with_progress ~progress body) | s -> Eio.traceln "%a: %a" Uri.pp uri Http.Status.pp s; default