An OCaml webserver, but the allocating version (vs httpz which doesnt)
at main 68 lines 1.9 kB view raw
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;;