diff --git a/dune b/dune index 00e05f1..dbdc2c7 100644 --- a/dune +++ b/dune @@ -39,6 +39,7 @@ (preprocess (per_module ((pps lwt_ppx) + gzip_io httpev logstash lwt_flag diff --git a/gzip_io.ml b/gzip_io.ml index f962199..57068a4 100644 --- a/gzip_io.ml +++ b/gzip_io.ml @@ -36,6 +36,23 @@ let string s = IO.nwrite out (Bytes.unsafe_of_string s); (* IO wrong type *) IO.close_out out +let string_lwt ?(chunk_size = 3000) ?(yield = Lwt.pause) s = + let out = output (IO.output_string ()) in + let b = Bytes.unsafe_of_string s in + let len = Bytes.length b in + let rec loop offset = + let written = + let len_to_write = Int.min chunk_size (len - offset) in + IO.output out b offset len_to_write in + if offset + written >= len then Lwt.return_unit + else ( + (* Yield after processing a chunk *) + let%lwt () = yield () in + loop (offset + written)) + in + let%lwt () = loop 0 in + Lwt.return @@ IO.close_out out + let to_string s = let inp = input (IO.input_string s) in let out = IO.output_string () in diff --git a/httpev.ml b/httpev.ml index 1e6b847..bf9df19 100644 --- a/httpev.ml +++ b/httpev.ml @@ -928,12 +928,14 @@ let send_reply c cout reply = end in (* possibly apply encoding *) - let (hdrs,body) = + let%lwt (hdrs,body) = (* TODO do not apply encoding to application/gzip *) (* TODO gzip + chunked? *) match body, code, c.req with - | `Body s, `Ok, Ready { encoding=Gzip; _ } when String.length s > 128 -> ("Content-Encoding", "gzip")::hdrs, `Body (Gzip_io.string s) - | _ -> hdrs, body + | `Body s, `Ok, Ready { encoding=Gzip; _ } when String.length s > 128 -> + let%lwt body = Gzip_io.string_lwt s in + Lwt.return (("Content-Encoding", "gzip")::hdrs, `Body body) + | _ -> Lwt.return (hdrs, body) in let hdrs = match body with | `Body s -> ("Content-Length", string_of_int (String.length s)) :: hdrs