[ANN] httpcats, ocaml-h1, vif & hurl: a webstack for OCaml 5

I am delighted to announce the release of httpcats.0.1.0, ocaml-h1 (including WebSockets support), and the experimental release of vif, a web framework for OCaml 5, and hurl, an HTTP client in OCaml.

ocaml-h1

ocaml-h1 is an authorised fork of http/af (after explicit permission from its author) in order to continue its development and release process. It was created in May 2024 and now includes support for websockets (and connection upgrades) thanks to the work of @swrup.

httpcats, a HTTP client/server with miou

It was in 2023 that we began experimenting with OCaml 5 and HTTP requests with the httpcats project:

This project allowed us to consolidate some of our libraries, such asmirage-crypto, in order to move beyond OCaml 5 and, in particular, to resolve the few data-races we had (having started some of our projects before OCaml multicore was even mentioned).

After some fairly extensive maintenance work, we were finally able to lay the groundwork for an OCaml HTTP client that can make parallel requests using Miou.

httpcats has therefore improved over time and offers a fairly simple way to make HTTP requests in OCaml (thanks to our experience with http-lwt-client) and to implement an HTTP server that can handle incoming HTTP requests in parallel. The documentation has been improved and is particularly comprehensive (with examples) so that users have complete control over all the protocol layers required for communication with web service: from the Unix socket to the TLS handshake (including ALPN negotiation), including domain name resolution.

httpcats also partially synthesizes our work on protocols. Everything needed to communicate with web services is implemented in OCaml:

  • ocaml-tls is used for the TLS protocol
  • ocaml-h1 and ocaml-h2 are used for the HTTP protocol (http/1.1 and h2)
  • ocaml-dns and happy-eyeballs are used for domain name resolution and the ability to prefer IPv6 connections or, at best, the fastest TCP/IP connections

Finally, benchmarking work has been initiated, the origins of which can be found here, showing the results that can be achieved with httpcats as a server. The benchmark is reproducible and available here, and here are the results we obtained (on AMD Ryzen 9 7950X 16-Core Processor):

clients threads latencyAvg latencyMax latencyStdev totalRequests
16 16 47.43us 2.27ms 38.48us 5303700
32 32 71.73us 1.04ms 47.58us 7016729
64 32 140.29us 5.72ms 121.50us 7658146
128 32 279.73us 11.35ms 287.92us 7977306
256 32 519.02us 16.89ms 330.20us 7816435
512 32 1.06ms 37.42ms 534.14us 7409781

hurl, a command-line tool to make HTTP requests in OCaml

To complete our work, we have developed a tool that allows HTTP requests to be made from the command line: hurl. This tool is still in the experimental phase, but it allows us to activate an improvement loop between httpcats and the real world by testing certain types of requests.

Here is a screenshot of the tool (hurl https://discuss.ocaml.org --print dishHrR):

The purpose of this tool is to facilitate the tests we would like to perform with a web server by allowing the user to specify the content of requests (and whether this content should be JSON or multipart/form-data) and obtain a whole bunch of information such as the response given by the service, the server’s IP address, and the result of the TLS handshake.

vif, a simple web framework for OCaml 5

Finally, to complete our work, we have also developed a new web framework based on httpcats and miou in order to obtain a web server capable of handling parallel requests: vif. Like hurl, vif is still in the experimental stage. However, we are currently able to produce small web applications and we will present this project at the next FUN OCaml session (come along!).

A tutorial explaining how to make a chatroom in OCaml is available here.

The objective of vif is to provide a small framework for developing web applications. In addition, it offers a tool called vif, which is a native OCaml interpreter that allows you to launch a web server from an OCaml script. Here is a simple example from the command line:

$ opam install -y vif hurl
$ cat >main.ml <<EOF
#require "vif" ;;

let default req server () =
  let open Vif.Response.Syntax in
  let field = "content-type" in
  let* () = Vif.Response.add ~field "text/html; charset=utf-8" in
  let* () = Vif.Response.with_string req "Hello World!" in
  Vif.Response.respond `OK
;;

let routes =
  let open Vif.Uri in
  let open Vif.Route in
  [ get (rel /?? nil) --> default ]

let () =
  Miou_unix.run @@ fun () ->
  Vif.run routes ()
;;
EOF
$ vif --pid vid.pid main.ml &
$ hurl http://localhost:8080/ -p b
Hello World!
$ kill -SIGINT $(cat vid.pid)

Like all projects in our cooperative, it is open to contributions and improvements. The workshop we will be hosting at FUN OCaml will be an opportunity for us and for you to participate in these projects.

Conclusion

Based on the dates provided, it is clear that this was a substantial and lengthy undertaking. It is the result of the work of several individuals and our cooperative (both technical and social).

We would like to thank everyone who participated in any way in the development of this software and its integration into the OCaml ecosystem (notably through miou’s support for certain libraries such as caqti).

We hope that many of you will attend our workshop (for the FUN OCaml itself, and also to meet us) and hope that you will enjoy Vif in particular. If you like our work, you can also make a donation to our cooperative (via GitHub or directly using an IBAN).

Happy hacking!

26 Likes