[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: Help with a unikernel webserver
Dear Miroslav, thanks for reaching out. So, your 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 ] Here, you'll need to use & provide the "secret_stack": let main = main ~packages:[package "cohttp-mirage"] "Unikernel.Main"(pclock @-> conduit @-> conduit @-> resolver @-> stackv4v6 @-> job) let () =register "frontend-server" [ main $ default_posix_clock $ conduit_direct stack $ conduit_direct secret_stack $ resolver_dns secret_stack $ stack ] Which will then result in your unikernel being a bit modified: > 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) will now be: module Main (Pclock : Mirage_clock.PCLOCK) (Conduit : Conduit_mirage.S) (Secret_conduit : Conduit_mirage.S) (Secret_resolver : Resolver_mirage.S) (Stack : Tcpip.Stack.V4V6) = structmodule Client = Cohttp_mirage.Client.Make(Pclock)(Secret_resolver)(Secret_conduit) module Server = Cohttp_mirage.Server.Make(Conduit) And then, also your "start" function is slightly adapted: > let start _pclock _conduit _resolver stack = will be: let start _pclock _conduit _secret_conduit _secret_resolver stack =And then your HTTP client will use the secret network stack, while the server uses the default one. Hope this helps, Hannes On 01/05/2025 22:58, Belej, Miroslav wrote: 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.
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |