- Server and client now have dedicated module files - Menu and Item have their own module files - Wrote parsers for Menu and Item - Switch from jbuilder to dune - Introducing gopher client - IPv6
24 lines
1.1 KiB
OCaml
24 lines
1.1 KiB
OCaml
let apply handler (file_descr, _socket) =
|
|
let open Lwt.Infix in
|
|
let buf = Bytes.create 256 in
|
|
Lwt_unix.read file_descr buf 0 (Bytes.length buf)
|
|
>>= (fun x ->
|
|
let response = handler @@ Bytes.(to_string (sub buf 0 x)) in
|
|
Lwt_unix.write_string file_descr response 0 (String.length response)
|
|
)
|
|
>>= (fun _ -> Lwt_unix.(shutdown file_descr SHUTDOWN_ALL); Lwt.return_unit)
|
|
|
|
let rec accept_all handler socket () =
|
|
let open Lwt.Infix in
|
|
Lwt_unix.accept socket
|
|
>>= (fun pair -> Lwt.catch (fun () -> apply handler pair) (fun exn -> prerr_endline (Printexc.to_string exn); Lwt.return_unit))
|
|
>>= accept_all handler socket
|
|
|
|
let gopherd ?(host="") ?(port=70) ?(request_queue_size=128) handler =
|
|
let open Lwt.Infix in
|
|
let socket = Lwt_unix.(socket PF_INET6 SOCK_STREAM 0) in
|
|
Lwt_unix.setsockopt socket SO_REUSEADDR true;
|
|
let host = if host = "" then Unix.inet6_addr_any else Unix.inet_addr_of_string host in
|
|
let bind = Lwt_unix.bind socket Unix.(ADDR_INET (host, port)) in
|
|
Lwt_unix.listen socket request_queue_size;
|
|
Lwt_main.run (bind >>= accept_all handler socket)
|