(* req.ml - HTTP request type *) open Base type t = { meth : Method.t ; target : Span.t ; version : Version.t ; body_off : int ; content_length : int64 ; is_chunked : bool ; keep_alive : bool ; expect_continue : bool } (* Helper to get body length and end position for non-chunked requests. Returns None if content_length <= 0, Some (body_len, body_end) otherwise. *) let body_bounds ~len req = let cl = req.content_length in if Int64.(cl <= 0L) then None else let body_len = Int64.to_int_exn cl in let body_end = req.body_off + body_len in Some (body_len, body_end, body_end <= len) ;; let body_in_buffer ~len req = if req.is_chunked then false else match body_bounds ~len req with | None -> true | Some (_, _, in_buffer) -> in_buffer ;; let body_span ~len req = if req.is_chunked then Span.make ~off:0 ~len:(-1) else match body_bounds ~len req with | None -> Span.make ~off:req.body_off ~len:0 | Some (body_len, _, true) -> Span.make ~off:req.body_off ~len:body_len | Some (_, _, false) -> Span.make ~off:0 ~len:(-1) ;; let body_bytes_needed ~len req = if req.is_chunked then -1 else match body_bounds ~len req with | None -> 0 | Some (_, _, true) -> 0 | Some (_, body_end, false) -> body_end - len ;; let pp_with_buf buf fmt req = Stdlib.Format.fprintf fmt "%s %s %s" (Method.to_string req.meth) (Span.to_string buf req.target) (Version.to_string req.version) ;; let pp fmt req = Stdlib.Format.fprintf fmt "{ meth = %a; target = { off = %d; len = %d }; version = %a; body_off = %d; content_length = %Ld; is_chunked = %b; keep_alive = %b; expect_continue = %b }" Method.pp req.meth (Span.off req.target) (Span.len req.target) Version.pp req.version req.body_off req.content_length req.is_chunked req.keep_alive req.expect_continue ;;