webserverocamlocaml-lwt

Error: Unbound record field Server.callback - Ocaml


I am following a tutorial that explains how to make a simple web server in OCaml with lwt and Cohttp.

I have a _tags file that contains the following:

true: package(lwt), package(cohttp), package(cohttp.lwt)

And a webserver.ml:

open Lwt
open Cohttp
open Cohttp_lwt_unix

let make_server () =
  let callback conn_id req body =
    let uri = Request.uri req in
    match Uri.path uri with
    | "/" -> Server.respond_string ~status:`OK ~body:"hello!\n" ()
    | _ -> Server.respond_string ~status:`Not_found ~body:"Route not found" ()
  in
  let conn_closed conn_id () = () in
  Server.create { Server.callback; Server.conn_closed }

let _ =
  Lwt_unix.run (make_server ())

Then, ocamlbuild -use-ocamlfind webserver.native triggers the following error:

Error: Unbound record field callback
Command exited with code 2.

If I change to: Server.create { callback; conn_closed } it will also trigger:

Error: Unbound record field callback
Command exited with code 2.

I am not sure how to solve this, so thanks in advance for looking into this.


Solution

  • Probably, you are using a very outdated tutorial, that was written for an old cohttp interface. You can try to look at the up-to-date tutorials in the upstream repository.

    In your case, at least the following changes should be made, to compile the program:

    1. You should use function Server.make to create an instance of a server;
    2. The callback and conn_closed values should be passed as function parameters, not as a record, e.g.,

      Server.make ~callback ~conn_closed ()
      
    3. You should use function Server.create and pass a value, that was returned from function Server.make to create a server instance.

    So, probably, the following should work:

    open Lwt
    open Cohttp
    open Cohttp_lwt_unix
    
    let make_server () =
      let callback conn_id req body =
        let uri = Request.uri req in
        match Uri.path uri with
        | "/" -> Server.respond_string ~status:`OK ~body:"hello!\n" ()
        | _ -> Server.respond_string ~status:`Not_found ~body:"Route not found" ()
      in
      Server.create (Server.make ~callback ())
    
    let _ =
      Lwt_unix.run (make_server ())