89 lines
2.8 KiB
OCaml
89 lines
2.8 KiB
OCaml
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
|
|
;;
|