diff --git a/src/Tiny_httpd_server.ml b/src/Tiny_httpd_server.ml index 7547ee5e..f40447db 100644 --- a/src/Tiny_httpd_server.ml +++ b/src/Tiny_httpd_server.ml @@ -756,10 +756,9 @@ let find_map f l = let handle_client_ (self:t) (client_sock:Unix.file_descr) : unit = Unix.(setsockopt_float client_sock SO_RCVTIMEO self.timeout); Unix.(setsockopt_float client_sock SO_SNDTIMEO self.timeout); - let ic = Unix.in_channel_of_descr client_sock in let oc = Unix.out_channel_of_descr client_sock in let buf = Buf.create ~size:self.buf_size () in - let is = Byte_stream.of_chan ~buf_size:self.buf_size ic in + let is = Byte_stream.of_fd ~buf_size:self.buf_size client_sock in let continue = ref true in while !continue && self.running do _debug (fun k->k "read next request"); diff --git a/src/Tiny_httpd_stream.ml b/src/Tiny_httpd_stream.ml index af057500..2b12ab02 100644 --- a/src/Tiny_httpd_stream.ml +++ b/src/Tiny_httpd_stream.ml @@ -61,6 +61,24 @@ let of_chan_ ?(buf_size=16 * 1024) ~close ic : t = let of_chan = of_chan_ ~close:close_in let of_chan_close_noerr = of_chan_ ~close:close_in_noerr +let of_fd_ ?(buf_size=16 * 1024) ~close ic : t = + make + ~bs:(Bytes.create buf_size) + ~close:(fun _ -> close ic) + ~consume:(fun self n -> + self.off <- self.off + n; + self.len <- self.len - n) + ~fill:(fun self -> + if self.off >= self.len then ( + self.off <- 0; + self.len <- Unix.read ic self.bs 0 (Bytes.length self.bs); + ) + ) + () + +let of_fd = of_fd_ ~close:Unix.close +let of_fd_close_noerr = of_fd_ ~close:(fun f -> try Unix.close f with _ -> ()) + let rec iter f (self:t) : unit = self.fill_buf(); if self.len=0 then ( diff --git a/src/Tiny_httpd_stream.mli b/src/Tiny_httpd_stream.mli index fbb2d287..4a7cb4f9 100644 --- a/src/Tiny_httpd_stream.mli +++ b/src/Tiny_httpd_stream.mli @@ -50,6 +50,12 @@ val of_chan : ?buf_size:int -> in_channel -> t val of_chan_close_noerr : ?buf_size:int -> in_channel -> t (** Same as {!of_chan} but the [close] method will never fail. *) +val of_fd : ?buf_size:int -> Unix.file_descr -> t +(** Make a buffered stream from the given file descriptor. *) + +val of_fd_close_noerr : ?buf_size:int -> Unix.file_descr -> t +(** Same as {!of_fd} but the [close] method will never fail. *) + val of_bytes : ?i:int -> ?len:int -> bytes -> t (** A stream that just returns the slice of bytes starting from [i] and of length [len]. *)