My agentic slop goes here. Not intended for anyone else!
at main 2.0 kB view raw
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