My agentic slop goes here. Not intended for anyone else!
1let src = Logs.Src.create "requests.response" ~doc:"HTTP Response"
2module Log = (val Logs.src_log src : Logs.LOG)
3
4type t = {
5 status : int;
6 headers : Headers.t;
7 body : Eio.Flow.source_ty Eio.Resource.t;
8 url : string;
9 elapsed : float;
10 mutable closed : bool;
11}
12
13let make ~sw ~status ~headers ~body ~url ~elapsed =
14 Log.debug (fun m -> m "Creating response: status=%d url=%s elapsed=%.3fs" status url elapsed);
15 let response = { status; headers; body; url; elapsed; closed = false } in
16
17 (* Register cleanup with switch *)
18 Eio.Switch.on_release sw (fun () ->
19 if not response.closed then begin
20 Log.debug (fun m -> m "Auto-closing response for %s via switch" url);
21 response.closed <- true;
22 (* TODO Body cleanup is handled by the underlying HTTP library but test this *)
23 end
24 );
25
26 response
27
28let status t = Status.of_int t.status
29
30let status_code t = t.status
31
32let ok t = Status.is_success (Status.of_int t.status)
33
34let headers t = t.headers
35
36let header name t = Headers.get name t.headers
37
38let content_type t =
39 match Headers.get "content-type" t.headers with
40 | None -> None
41 | Some ct -> Some (Mime.of_string ct)
42
43let content_length t =
44 match Headers.get "content-length" t.headers with
45 | None -> None
46 | Some len ->
47 try Some (Int64.of_string len)
48 with _ -> None
49
50let location t = Headers.get "location" t.headers
51
52let url t = t.url
53
54let elapsed t = t.elapsed
55
56let body t =
57 if t.closed then
58 failwith "Response has been closed"
59 else
60 t.body
61
62
63(* Pretty printers *)
64let pp ppf t =
65 Format.fprintf ppf "@[<v>Response:@,\
66 status: %a@,\
67 url: %s@,\
68 elapsed: %.3fs@,\
69 headers: @[%a@]@]"
70 Status.pp (Status.of_int t.status) t.url t.elapsed
71 Headers.pp_brief t.headers
72
73let pp_detailed ppf t =
74 Format.fprintf ppf "@[<v>Response:@,\
75 status: %a@,\
76 url: %s@,\
77 elapsed: %.3fs@,\
78 @[%a@]@]"
79 Status.pp_hum (Status.of_int t.status) t.url t.elapsed
80 Headers.pp t.headers
81
82(* Private module *)
83module Private = struct
84 let make = make
85end