1+ (* A debug tool, intended to check the I/O subsystem is working correctly. *)
2+
3+ open Lwt.Infix
4+
5+ let lookup host =
6+ Host.Dns. getaddrinfo host `INET
7+ >> = function
8+ | [] ->
9+ Lwt. fail_with (Printf. sprintf " unable to lookup %s" host)
10+ | Ipaddr. V6 _ :: _ ->
11+ Lwt. fail_with " IPv6 not currently supported."
12+ | Ipaddr. V4 ipv4 :: _ ->
13+ Lwt. return (Ipaddr. V4 ipv4)
14+
15+ module Client (FLOW : Mirage_flow.S ) = struct
16+ module C = Mirage_channel. Make (FLOW )
17+ let get flow host path =
18+ let request = " GET " ^ path ^ " HTTP/1.0\r\n Host: " ^ host ^ " \r\n Connection: close\r\n\r\n " in
19+ let c = C. create flow in
20+ Printf. printf " writing\n %s\n " request;
21+ C. write_string c request 0 (String. length request);
22+ C. flush c
23+ >> = function
24+ | Error e ->
25+ Printf. printf " error sending request: %s\n " (Fmt. str " %a" C. pp_write_error e);
26+ Lwt. return_unit
27+ | Ok () ->
28+ let rec loop () =
29+ C. read_some c >> = function
30+ | Ok `Eof -> Lwt. return_unit
31+ | Error e ->
32+ Printf. printf " error reading response: %s\n " (Fmt. str " %a" C. pp_error e);
33+ Lwt. return_unit
34+ | Ok (`Data buf ) ->
35+ print_string (Cstruct. to_string buf);
36+ loop () in
37+ loop ()
38+ end
39+
40+ let curl _verbose urls =
41+ let module HTTP = Client (Host.Sockets.Stream. Tcp ) in
42+ let fetch host port path =
43+ let path = if path = " " then " /" else path in
44+ lookup host
45+ >> = fun ipv4 ->
46+ Printf. printf " connecting to %s:%d\n " (Ipaddr. to_string ipv4) port;
47+ Host.Sockets.Stream.Tcp. connect (ipv4, port)
48+ >> = function
49+ | Error (`Msg m ) ->
50+ Printf. printf " unable to connect: %s\n " m;
51+ Lwt. return_unit
52+ | Ok socket ->
53+ Printf. printf " connected\n " ;
54+ Lwt. finalize
55+ (fun () ->
56+ HTTP. get socket host path
57+ ) (fun () -> Host.Sockets.Stream.Tcp. close socket) in
58+ try
59+ Host.Main. run begin
60+ Lwt_list. iter_s (fun url ->
61+ let uri = Uri. of_string url in
62+ if Uri. scheme uri <> Some " http" then begin
63+ Printf. printf " only http:// URLs are currently supported by this debug tool\n " ;
64+ Lwt. return_unit
65+ end else begin
66+ Printf. printf " trying URL %s\n " url;
67+ let path = Uri. path uri in
68+ match Uri. host uri, Uri. port uri with
69+ | Some host , Some port ->
70+ fetch host port path
71+ | Some host , None ->
72+ fetch host 80 path
73+ | _ , _ ->
74+ Printf. printf " unable to parse host and port from URL\n " ;
75+ Lwt. return_unit
76+ end
77+ ) urls
78+ end
79+ with e ->
80+ Printf. printf " Host.Main.run caught exception %s: %s\n " (Printexc. to_string e) (Printexc. get_backtrace () )
0 commit comments