authorgravatar for goon.pri.low@gmail.comKendall Condon <goon.pri.low@gmail.com> 2025-08-12 15:48:45-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-08-13 13:14:01-07:00
log4f639ff8805b33fa6c75416eddfb205e3a04e09a
tree8ac225b01276c0dfa2d513b4aaa3b4fc99d1f665
parent5e986fef1fa5cf04f3547cc4f5a8c0f490ea1d3d

http: fix handling of limit in chunkedSendFile

`limit` in chunkedSendFile applies only to the file, not the entire chunk. `limit` in sendFileHeader does not include the header. Additionally adds a comment to clarify what `limit` applies to in sendFileHeader and fixed a small bug in it (`drain` is able to return less then `header.len`).

2 files changed, 8 insertions(+), 3 deletions(-)

lib/std/Io/Writer.zig+3-1
...@@ -868,6 +868,8 @@ pub fn sendFile(w: *Writer, file_reader: *File.Reader, limit: Limit) FileError!u...@@ -868,6 +868,8 @@ pub fn sendFile(w: *Writer, file_reader: *File.Reader, limit: Limit) FileError!u
868}868}
869869
870/// Returns how many bytes from `header` and `file_reader` were consumed.870/// Returns how many bytes from `header` and `file_reader` were consumed.
871///
872/// `limit` only applies to `file_reader`.
871pub fn sendFileHeader(873pub fn sendFileHeader(
872 w: *Writer,874 w: *Writer,
873 header: []const u8,875 header: []const u8,
...@@ -882,7 +884,7 @@ pub fn sendFileHeader(...@@ -882,7 +884,7 @@ pub fn sendFileHeader(
882 }884 }
883 const buffered_contents = limit.slice(file_reader.interface.buffered());885 const buffered_contents = limit.slice(file_reader.interface.buffered());
884 const n = try w.vtable.drain(w, &.{ header, buffered_contents }, 1);886 const n = try w.vtable.drain(w, &.{ header, buffered_contents }, 1);
885 file_reader.interface.toss(n - header.len);887 file_reader.interface.toss(n -| header.len);
886 return n;888 return n;
887}889}
888890
lib/std/http.zig+5-2
...@@ -1021,8 +1021,11 @@ pub const BodyWriter = struct {...@@ -1021,8 +1021,11 @@ pub const BodyWriter = struct {
1021 continue :l 1;1021 continue :l 1;
1022 },1022 },
1023 else => {1023 else => {
1024 const new_limit = limit.min(.limited(chunk_len - 2));1024 const chunk_limit: std.Io.Limit = .limited(chunk_len - 2);
1025 const n = try out.sendFileHeader(w.buffered(), file_reader, new_limit);1025 const n = if (chunk_limit.subtract(w.buffered().len)) |sendfile_limit|
1026 try out.sendFileHeader(w.buffered(), file_reader, sendfile_limit.min(limit))
1027 else
1028 try out.write(chunk_limit.slice(w.buffered()));
1026 chunked.chunk_len = chunk_len - n;1029 chunked.chunk_len = chunk_len - n;
1027 return w.consume(n);1030 return w.consume(n);
1028 },1031 },