open Lwt.Infix open H2 module type HTTP2 = H2_mirage.Server module Dispatch (C : Mirage_console.S) (Http2 : HTTP2) = 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 h2 unikernel" let dispatcher c 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.Writer.write_string response_body "Error handled"; Body.Writer.flush response_body (fun () -> Body.Writer.close response_body) in Http2.create_connection_handler ?config:None ~request_handler:(dispatch c) ~error_handler end (** Server boilerplate *) module Make (C : Mirage_console.S) (Clock : Mirage_clock.PCLOCK) (Http2 : HTTP2) = struct module D = Dispatch (C) (Http2) let log c fmt = Printf.ksprintf (C.log c) fmt let start c _clock http2 = log c "started unikernel listen on port 8001" >>= fun () -> http2 (`TCP 8001) @@ D.serve c D.dispatcher end