zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 4f639ff8805b33fa6c75416eddfb205e3a04e09a (tree)
parent 5e986fef1fa5cf04f3547cc4f5a8c0f490ea1d3d
Author: Kendall Condon <goon.pri.low@gmail.com>
Date:   Tue, 12 Aug 2025 15:48:45 -0400

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`).

Diffstat:
Mlib/std/Io/Writer.zig | 4+++-
Mlib/std/http.zig | 7+++++--
2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/lib/std/Io/Writer.zig b/lib/std/Io/Writer.zig @@ -868,6 +868,8 @@ pub fn sendFile(w: *Writer, file_reader: *File.Reader, limit: Limit) FileError!u } /// Returns how many bytes from `header` and `file_reader` were consumed. +/// +/// `limit` only applies to `file_reader`. pub fn sendFileHeader( w: *Writer, header: []const u8, @@ -882,7 +884,7 @@ pub fn sendFileHeader( } const buffered_contents = limit.slice(file_reader.interface.buffered()); const n = try w.vtable.drain(w, &.{ header, buffered_contents }, 1); - file_reader.interface.toss(n - header.len); + file_reader.interface.toss(n -| header.len); return n; } diff --git a/lib/std/http.zig b/lib/std/http.zig @@ -1021,8 +1021,11 @@ pub const BodyWriter = struct { continue :l 1; }, else => { - const new_limit = limit.min(.limited(chunk_len - 2)); - const n = try out.sendFileHeader(w.buffered(), file_reader, new_limit); + const chunk_limit: std.Io.Limit = .limited(chunk_len - 2); + const n = if (chunk_limit.subtract(w.buffered().len)) |sendfile_limit| + try out.sendFileHeader(w.buffered(), file_reader, sendfile_limit.min(limit)) + else + try out.write(chunk_limit.slice(w.buffered())); chunked.chunk_len = chunk_len - n; return w.consume(n); },