ocaml http/1, http/2 and websocket client and server library
1type config = { secret_key_base : string; health_check : bool }
2
3let default_config = { secret_key_base = ""; health_check = true }
4
5type params_handler = Router.params -> Server.request -> Server.response
6
7type t = {
8 config : config;
9 plugs : Pipeline.t;
10 router : params_handler Router.t option;
11 ws_handler : Server.ws_handler option;
12}
13
14let create config =
15 { config; plugs = Pipeline.empty; router = None; ws_handler = None }
16
17let plug t p = { t with plugs = Pipeline.plug t.plugs p }
18let router t r = { t with router = Some r }
19let websocket t handler = { t with ws_handler = Some handler }
20let ws_handler t = t.ws_handler
21let not_found_handler _req = Server.respond ~status:`Not_found "Not Found"
22
23let health_handler _req =
24 Server.respond ~status:`OK ~headers:[ ("Content-Type", "text/plain") ] "ok"
25
26let to_handler t =
27 let route_handler =
28 match t.router with
29 | None -> not_found_handler
30 | Some r -> (
31 fun req ->
32 let path =
33 match String.index_opt req.Server.target '?' with
34 | Some i -> String.sub req.target 0 i
35 | None -> req.target
36 in
37 match Router.lookup r ~method_:req.meth ~path with
38 | Some { handler; params; plugs } ->
39 let base_handler req = handler params req in
40 let wrapped = Pipeline.apply plugs base_handler in
41 wrapped req
42 | None -> not_found_handler req)
43 in
44 let with_health =
45 if t.config.health_check then fun req ->
46 if req.Server.target = "/_health" || req.Server.target = "/health" then
47 health_handler req
48 else route_handler req
49 else route_handler
50 in
51 Pipeline.apply t.plugs with_health