ocaml-gopher/src/lwt_server.ml
orbifx 7b1ec728cf Introduce client & parser, switch to Dune
- 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
2022-01-04 15:20:35 +00:00

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)