open Lwt.Infix open Httpun module type HTTP = httpun_mirage.Server module Dispatch (C: Mirage_console.S) (Http: HTTP) = struct let log c fmt = Printf.ksprintf (C.log c) fmt let get_content c path = log c "Replying: %s" path >|= fun () -> "Hello from the httpun unikernel" let dispatcher c { Gluten.reqd; _ } = let {Request.target; _} = Reqd.request reqd in Lwt.catch (fun () -> get_content c target >|= fun body -> let response = Response.create ~headers:(Headers.of_list ["Content-Length", body |> String.length |> string_of_int]) `OK in Reqd.respond_with_string reqd response body) (fun exn -> let response = Response.create `Internal_server_error in Lwt.return (Reqd.respond_with_string reqd response (Printexc.to_string exn))) |> ignore let serve c dispatch = let error_handler ?request:_ _error mk_response = let response_body = mk_response Headers.empty in Body.write_string response_body "Error handled"; Body.flush response_body (fun () -> Body.close_writer response_body) in Http.create_connection_handler ?config:None ~request_handler:(dispatch c) ~error_handler end (** Server boilerplate *) module Make (C : Mirage_console.S) (Clock : Mirage_clock.PCLOCK) (Http: HTTP) = struct module D = Dispatch (C) (Http) let log c fmt = Printf.ksprintf (C.log c) fmt let start c _clock http = log c "started unikernel listen on port 8001" >>= fun () -> http (`TCP 8001) @@ D.serve c D.dispatcher end