···29 | None ->
30 (* Guess MIME type from filename if available *)
31 let path = Eio.Path.native_exn file in
00000032 let guessed =
33- if String.ends_with ~suffix:".json" path then Mime.json
34- else if String.ends_with ~suffix:".html" path then Mime.html
35- else if String.ends_with ~suffix:".xml" path then Mime.xml
36- else if String.ends_with ~suffix:".txt" path then Mime.text
37- else Mime.octet_stream
38 in
39 Log.debug (fun m -> m "Guessed MIME type %s for file %s" (Mime.to_string guessed) path);
40 guessed
···42 Log.debug (fun m -> m "Creating file body from %s with MIME type %s"
43 (Eio.Path.native_exn file) (Mime.to_string mime));
44 File { file; mime }
00004546(* For simple JSON encoding, we just take a Jsont.json value and encode it *)
47let json (json_value : Jsont.json) =
48 let content = match Jsont_bytesrw.encode_string' ~format:Jsont.Minify Jsont.json json_value with
49 | Ok s -> s
50- | Error e ->
51- let msg = Jsont.Error.to_string e in
52- failwith (Printf.sprintf "Failed to encode JSON: %s" msg)
53 in
54 String { content; mime = Mime.json }
55···78 (* Encode the entire JSON value to string with minified format *)
79 let content = match Jsont_bytesrw.encode_string' ~format:Jsont.Minify Jsont.json json_value with
80 | Ok s -> s
81- | Error e ->
82- let msg = Jsont.Error.to_string e in
83- failwith (Printf.sprintf "Failed to encode JSON stream: %s" msg)
84 in
85 let t = { Json_stream_source.content; offset = 0 } in
86 let ops = Eio.Flow.Pi.source (module Json_stream_source) in
···29 | None ->
30 (* Guess MIME type from filename if available *)
31 let path = Eio.Path.native_exn file in
32+ let mime_map = [
33+ (".json", Mime.json);
34+ (".html", Mime.html);
35+ (".xml", Mime.xml);
36+ (".txt", Mime.text);
37+ ] in
38 let guessed =
39+ List.find_map (fun (suffix, mime_type) ->
40+ if String.ends_with ~suffix path then Some mime_type else None
41+ ) mime_map
42+ |> Option.value ~default:Mime.octet_stream
043 in
44 Log.debug (fun m -> m "Guessed MIME type %s for file %s" (Mime.to_string guessed) path);
45 guessed
···47 Log.debug (fun m -> m "Creating file body from %s with MIME type %s"
48 (Eio.Path.native_exn file) (Mime.to_string mime));
49 File { file; mime }
50+51+let json_encoding_error e =
52+ let msg = Jsont.Error.to_string e in
53+ failwith (Printf.sprintf "Failed to encode JSON: %s" msg)
5455(* For simple JSON encoding, we just take a Jsont.json value and encode it *)
56let json (json_value : Jsont.json) =
57 let content = match Jsont_bytesrw.encode_string' ~format:Jsont.Minify Jsont.json json_value with
58 | Ok s -> s
59+ | Error e -> json_encoding_error e
0060 in
61 String { content; mime = Mime.json }
62···85 (* Encode the entire JSON value to string with minified format *)
86 let content = match Jsont_bytesrw.encode_string' ~format:Jsont.Minify Jsont.json json_value with
87 | Ok s -> s
88+ | Error e -> json_encoding_error e
0089 in
90 let t = { Json_stream_source.content; offset = 0 } in
91 let ops = Eio.Flow.Pi.source (module Json_stream_source) in
+10-22
lib/one.ml
···78 (tcp_flow :> [`Close | `Flow | `R | `Shutdown | `W] Eio.Resource.t)
79 in
8081- match timeout with
82- | Some t ->
83- let timeout_seconds = Timeout.total t in
84- (match timeout_seconds with
85- | Some seconds ->
86- Log.debug (fun m -> m "Setting connection timeout: %.2f seconds" seconds);
87- Eio.Time.with_timeout_exn clock seconds connect_fn
88- | None -> connect_fn ())
89 | None -> connect_fn ()
9091(* Main request implementation - completely stateless *)
···101 let headers = Option.value headers ~default:Headers.empty in
102103 (* Apply auth *)
104- let headers = match auth with
105- | Some a ->
106- Log.debug (fun m -> m "Applying authentication");
107- Auth.apply a headers
108- | None -> headers
109 in
110111 (* Add content type from body *)
112- let headers = match body with
113- | Some b -> (match Body.content_type b with
114- | Some mime -> Headers.content_type mime headers
115- | None -> headers)
116- | None -> headers
117 in
118119 (* Convert body to string for sending *)
120- let request_body_str = match body with
121- | None -> ""
122- | Some b -> Body.Private.to_string b
123- in
124125 (* Execute request with redirects *)
126 let rec make_with_redirects url_to_fetch redirects_left =
···78 (tcp_flow :> [`Close | `Flow | `R | `Shutdown | `W] Eio.Resource.t)
79 in
8081+ match Option.bind timeout Timeout.total with
82+ | Some seconds ->
83+ Log.debug (fun m -> m "Setting connection timeout: %.2f seconds" seconds);
84+ Eio.Time.with_timeout_exn clock seconds connect_fn
000085 | None -> connect_fn ()
8687(* Main request implementation - completely stateless *)
···97 let headers = Option.value headers ~default:Headers.empty in
9899 (* Apply auth *)
100+ let headers = Option.fold ~none:headers auth ~some:(fun a ->
101+ Log.debug (fun m -> m "Applying authentication");
102+ Auth.apply a headers)
00103 in
104105 (* Add content type from body *)
106+ let headers = Option.bind body Body.content_type
107+ |> Option.fold ~none:headers ~some:(fun mime -> Headers.content_type mime headers)
000108 in
109110 (* Convert body to string for sending *)
111+ let request_body_str = Option.fold ~none:"" ~some:Body.Private.to_string body in
000112113 (* Execute request with redirects *)
114 let rec make_with_redirects url_to_fetch redirects_left =
+2-3
lib/response.ml
···39let header name t = Headers.get name t.headers
4041let content_type t =
42- match Headers.get "content-type" t.headers with
43- | None -> None
44- | Some ct -> Some (Mime.of_string ct)
4546let content_length t =
47 match Headers.get "content-length" t.headers with
···39let header name t = Headers.get name t.headers
4041let content_type t =
42+ Headers.get "content-type" t.headers
43+ |> Option.map Mime.of_string
04445let content_length t =
46 match Headers.get "content-length" t.headers with