module Arg = Stdlib.Arg open Httpun module Client = Httpun_eio.Client let () = Ssl.init ~thread_safe:true () let handler ~on_eof response response_body = match response with | { Response.status = `OK; _ } as response -> Format.fprintf Format.std_formatter "%a\n%!" Response.pp_hum response; let rec on_read _bs ~off:_ ~len:_ = (* Bigstringaf.substring ~off ~len bs |> print_string; *) Body.Reader.schedule_read response_body ~on_read ~on_eof in Body.Reader.schedule_read response_body ~on_read ~on_eof; | response -> Format.fprintf Format.err_formatter "%a\n%!" Response.pp_hum response; Stdlib.exit 124 ;; let main port host = Eio_main.run (fun env -> Eio.Switch.run (fun sw -> let addrs = let addrs = Eio_unix.run_in_systhread (fun () -> Unix.getaddrinfo host (string_of_int port) [ Unix.(AI_FAMILY PF_INET) ]) in List.filter_map (fun (addr : Unix.addr_info) -> match addr.ai_addr with | Unix.ADDR_UNIX _ -> None | ADDR_INET (addr, port) -> Some (addr, port)) addrs in let addr = let inet, port = List.hd addrs in `Tcp (Eio_unix.Net.Ipaddr.of_unix inet, port) in let socket = Eio.Net.connect ~sw (Eio.Stdenv.net env) addr in let ctx = Ssl.create_context (Ssl.SSLv23 [@ocaml.warning "-3"]) Ssl.Client_context in Ssl.disable_protocols ctx [ (Ssl.SSLv23 [@ocaml.warning "-3"]) ]; Ssl.honor_cipher_order ctx; Ssl.set_context_alpn_protos ctx [ "h2" ]; let ssl_ctx = Eio_ssl.Context.create ~ctx socket in let ssl_sock = Eio_ssl.Context.ssl_socket ssl_ctx in Ssl.set_client_SNI_hostname ssl_sock host; Ssl.set_hostflags ssl_sock [ No_partial_wildcards ]; Ssl.set_host ssl_sock host; let ssl_sock = Eio_ssl.connect ssl_ctx in let headers = Headers.of_list [ "host", host ] in let connection = Client.create_connection ~sw ssl_sock in let response_handler = handler ~on_eof:(fun () -> Stdlib.Format.eprintf "eof@."; Client.shutdown connection |> Eio.Promise.await) in let request_body = Client.request connection ~flush_headers_immediately:true ~error_handler:Httpun_examples.Client.error_handler ~response_handler (Request.create ~headers `GET "/") in Body.Writer.close request_body)); ;; let () = let host = ref None in let port = ref 443 in Arg.parse ["-p", Set_int port, " Port number (80 by default)"] (fun host_argument -> host := Some host_argument) "lwt_get.exe [-p N] HOST"; let host = match !host with | None -> failwith "No hostname provided" | Some host -> host in main !port host ;;