An OCaml webserver, but the allocating version (vs httpz which doesnt)
1(* req.ml - HTTP request type *)
2
3open Base
4
5type t =
6 { meth : Method.t
7 ; target : Span.t
8 ; version : Version.t
9 ; body_off : int
10 ; content_length : int64
11 ; is_chunked : bool
12 ; keep_alive : bool
13 ; expect_continue : bool
14 }
15
16(* Helper to get body length and end position for non-chunked requests.
17 Returns None if content_length <= 0, Some (body_len, body_end) otherwise. *)
18let body_bounds ~len req =
19 let cl = req.content_length in
20 if Int64.(cl <= 0L) then None
21 else
22 let body_len = Int64.to_int_exn cl in
23 let body_end = req.body_off + body_len in
24 Some (body_len, body_end, body_end <= len)
25;;
26
27let body_in_buffer ~len req =
28 if req.is_chunked then false
29 else match body_bounds ~len req with
30 | None -> true
31 | Some (_, _, in_buffer) -> in_buffer
32;;
33
34let body_span ~len req =
35 if req.is_chunked then Span.make ~off:0 ~len:(-1)
36 else match body_bounds ~len req with
37 | None -> Span.make ~off:req.body_off ~len:0
38 | Some (body_len, _, true) -> Span.make ~off:req.body_off ~len:body_len
39 | Some (_, _, false) -> Span.make ~off:0 ~len:(-1)
40;;
41
42let body_bytes_needed ~len req =
43 if req.is_chunked then -1
44 else match body_bounds ~len req with
45 | None -> 0
46 | Some (_, _, true) -> 0
47 | Some (_, body_end, false) -> body_end - len
48;;
49
50let pp_with_buf buf fmt req =
51 Stdlib.Format.fprintf fmt "%s %s %s"
52 (Method.to_string req.meth)
53 (Span.to_string buf req.target)
54 (Version.to_string req.version)
55;;
56
57let pp fmt req =
58 Stdlib.Format.fprintf fmt
59 "{ meth = %a; target = { off = %d; len = %d }; version = %a; body_off = %d; content_length = %Ld; is_chunked = %b; keep_alive = %b; expect_continue = %b }"
60 Method.pp req.meth
61 (Span.off req.target) (Span.len req.target)
62 Version.pp req.version
63 req.body_off
64 req.content_length
65 req.is_chunked
66 req.keep_alive
67 req.expect_continue
68;;