Geotessera library for OCaml
1open Cohttp_eio
2
3type t = Cohttp_eio.Client.t
4
5let authenticator =
6 match Ca_certs.authenticator () with
7 | Ok x -> x
8 | Error (`Msg m) ->
9 Fmt.failwith "Failed to create system store X509 authenticator: %s" m
10
11let https ~authenticator =
12 let tls_config =
13 match Tls.Config.client ~authenticator () with
14 | Error (`Msg msg) -> failwith ("tls configuration problem: " ^ msg)
15 | Ok tls_config -> tls_config
16 in
17 fun uri raw ->
18 let host =
19 Uri.host uri
20 |> Option.map (fun x -> Domain_name.(host_exn (of_string_exn x)))
21 in
22 Tls_eio.client_of_flow ?host tls_config raw
23
24let v net = Client.make ~https:(Some (https ~authenticator)) net
25
26module Progress = struct
27 type t = { flow : Eio.Flow.source_ty Eio.Resource.t; progress : int -> unit }
28
29 let read_methods = []
30
31 let single_read (t : t) buf =
32 let i = Eio.Flow.single_read t.flow buf in
33 t.progress i;
34 i
35end
36
37let progress_handler = Eio.Flow.Pi.source (module Progress)
38
39let with_progress ~progress flow =
40 Eio.Resource.T (Progress.{ flow; progress }, progress_handler)
41
42let with_body ?(show = true) t display ~default ~uri fn =
43 Eio.Switch.run @@ fun sw ->
44 let uri = Uri.of_string uri in
45 let response, body = Client.get t uri ~sw in
46 match response.status with
47 | `OK ->
48 let total = Http.Response.content_length response |> Option.get in
49 let bar =
50 Display.line
51 ~total:(Optint.Int63.of_int total)
52 (Uri.path uri |> Filename.basename)
53 in
54 Display.with_line ~display ~show (fun _ -> bar) @@ fun r ->
55 let progress = Display.report_int r in
56 fn (with_progress ~progress body)
57 | s ->
58 Eio.traceln "%a: %a" Uri.pp uri Http.Status.pp s;
59 default