Hi, I am developing a unikernel webserver for my thesis and I would be glad for help, as I am not really good with OCaml. I already have a running
and functional webserver, which acts as proxy between user and backend. Right now, it uses the same tcp/ip stack for both the user and for forwarding and receiving request from backend. I need to have separate stack for both of them. I am using Cohttp_mirage
library. Here is the code for the unikernel I currently have :
open Lwt.Infix
let target_host = "http://192.168.254.11"
let target_port = 8081
module Main
(Pclock : Mirage_clock.PCLOCK)
(Conduit : Conduit_mirage.S)
(Resolver : Resolver_mirage.S)
(Stack : Tcpip.Stack.V4V6) = struct
module Client = Cohttp_mirage.Client.Make(Pclock)(Resolver)(Conduit)
module Server = Cohttp_mirage.Server.Make(Conduit)
(*Define the forwarding logic*)
let forward_request uri body resolver conduit =
let target_uri = Uri.of_string target_host in
let target_uri = Uri.with_port target_uri (Some target_port) in
let target_uri = Uri.with_path target_uri (Uri.path uri ) in
Logs.info (fun f -> f "Forwarding to %s" (Uri.to_string target_uri));
let headers = Cohttp.Header.init () in
let body = Cohttp_lwt.Body.of_string body in
let ctx = Client.ctx resolver conduit in
Client.post ~ctx ~headers ~body target_uri >>= fun (resp, resp_body) ->
Cohttp_lwt.Body.to_string resp_body >|= fun body_str ->
Logs.info (fun f -> f "Received response from %s" (Uri.to_string target_uri));
(resp, body_str)
(* Define the HTTP server callback *)
let server_callback _conn req body resolver conduit =
let uri = Cohttp.Request.uri req in
let method_ = Cohttp.Request.meth req in
Logs.info (fun f ->
f "Received %s request for %s"
(Cohttp.Code.string_of_method method_)
(Uri.to_string uri));
Cohttp_lwt.Body.to_string body >>= fun body_str ->
let response_body = "This will be hashed-> " ^ body_str in
Logs.info (fun f -> f "Response Body: %s" response_body);
forward_request uri body_str resolver conduit >>= fun (response, response_body) ->
Logs.info (fun f -> f "Response body from forwarded request: %s" response_body);
Lwt.return (response, Cohttp_lwt.Body.of_string response_body)
(* Start the HTTP server *)
let start _pclock _conduit _resolver stack =
Logs.info (fun f -> f "Before port");
let port = 8080 in
Logs.info (fun f -> f "Defined port");
Logs.info (fun f -> f "Starting MirageOS HTTP server on port %d" port);
let callback _conn req body = server_callback _conn req body _resolver _conduit in
let mode : Conduit_mirage.server = `TCP port in
let server = Server.make ~callback () in
Server.listen stack mode server
end
with config.ml :
open Mirage
let stack = generic_stackv4v6 default_network
let net = netif “secret”
let secret_stack = generic_stackv4v6 net
(* Main unikernel module *)
let main =
main
~packages:[package "cohttp-mirage"]
"Unikernel.Main"
(pclock @-> conduit @-> resolver @-> stackv4v6 @-> job)
let () =
register "frontend-server" [ main $ default_posix_clock $ conduit_direct stack $ resolver_dns stack $ stack ]
So I would like to use the secret_stack for communicating with the backend. I am thankful for any response.
|