Http Server in OCaml

Here’s the translation of the HTTP Server example from Go to OCaml:

open Lwt
open Cohttp_lwt_unix

(* A fundamental concept in Cohttp servers is handlers. A handler is a function
   that takes a request and returns a response. *)

(* This handler simply returns "hello\n" *)
let hello _conn _req body =
  let open Cohttp in
  let open Cohttp_lwt in
  body |> Cohttp_lwt.Body.drain_body >>= fun () ->
  Server.respond_string ~status:`OK ~body:"hello\n" ()

(* This handler does something a little more sophisticated by reading all 
   the HTTP request headers and echoing them into the response body. *)
let headers _conn req _body =
  let headers = Request.headers req in
  let body = 
    Header.to_list headers
    |> List.map (fun (name, value) -> Printf.sprintf "%s: %s\n" name value)
    |> String.concat ""
  in
  Server.respond_string ~status:`OK ~body ()

(* We set up our handlers on server routes *)
let server =
  let callback _conn req body =
    let uri = req |> Request.uri |> Uri.path in
    match uri with
    | "/hello" -> hello _conn req body
    | "/headers" -> headers _conn req body
    | _ -> Server.respond_string ~status:`Not_found ~body:"Not found" ()
  in
  Server.create ~mode:(`TCP (`Port 8090)) (Server.make ~callback ())

(* Finally, we start the server *)
let () =
  ignore (Lwt_main.run server)

This OCaml code creates a simple HTTP server using the cohttp and lwt libraries, which are commonly used for network programming in OCaml.

To run this server:

  1. First, make sure you have the necessary libraries installed. You can do this using OPAM:

    $ opam install cohttp-lwt-unix lwt
  2. Save the code in a file, for example http_server.ml.

  3. Compile and run the server:

    $ ocamlfind ocamlc -package cohttp-lwt-unix -linkpkg -o http_server http_server.ml
    $ ./http_server

The server will start and listen on port 8090.

You can then access the server:

$ curl localhost:8090/hello
hello

$ curl localhost:8090/headers
User-Agent: curl/7.68.0
Accept: */*

In this OCaml version:

  • We use the Cohttp and Lwt libraries to create an asynchronous HTTP server.
  • Handlers are functions that take a connection, request, and body, and return a response.
  • We set up routing in the callback function, which matches the URI path to the appropriate handler.
  • The server is created and started using Server.create and Lwt_main.run.

Note that OCaml’s approach to HTTP servers is quite different from Go’s. OCaml typically uses higher-order functions and pattern matching where Go would use interfaces and methods. The concept of handlers exists in both, but they’re implemented differently.