Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions lib/std/Io/Writer.zig
Original file line number Diff line number Diff line change
Expand Up @@ -271,8 +271,8 @@ fn writeSplatHeaderLimitFinish(
if (remaining == 0) break :v;
}
for (data[0 .. data.len - 1]) |buf| if (buf.len != 0) {
const copy_len = @min(header.len, remaining);
vecs[i] = buf;
const copy_len = @min(buf.len, remaining);
vecs[i] = buf[0..copy_len];
i += 1;
remaining -= copy_len;
if (remaining == 0) break :v;
Expand Down Expand Up @@ -306,6 +306,24 @@ test "writeSplatHeader splatting avoids buffer aliasing temptation" {
);
}

test "writeSplatHeaderLimit limits data" {
var aw: Writer.Allocating = .init(testing.allocator);
defer aw.deinit();

const data = [_][]const u8{ "good", "...not" };
const limit: usize = 4;

const n = try aw.writer.writeSplatHeaderLimit(
&.{},
&data,
1,
@enumFromInt(limit),
);

try testing.expectEqualStrings("good", aw.written());
try testing.expectEqual(limit, n);
}

/// Drains all remaining buffered data.
pub fn flush(w: *Writer) Error!void {
return w.vtable.flush(w);
Expand Down
32 changes: 32 additions & 0 deletions lib/std/http/test.zig
Original file line number Diff line number Diff line change
Expand Up @@ -930,6 +930,38 @@ test "Server streams both reading and writing" {
try expectEqualStrings("ONE FISH", body);
}

test "chunked body writer drains in moderation" {
// Test inspired by a bug in one of Io.Writer's write helpers.
//
// The fix doesn't touch the HTTP code, but the BodyWriter is
// from what I can tell the only affected code in std.
//
// Possibly the cause of https://github.com/ziglang/zig/issues/24944
// wherein the `zig std` server on Windows, due to lack of sendfile,
// drains the streaming sources tarball by doing vector writes
// of file contents in the chunked body stream.
Comment on lines +934 to +942
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This type of information should go in the commit message rather than a comment. I'd say just remove the comment (without moving it to the commit message), since the fix in this PR doesn't actually affect the problem in #24944 (see my other comment)


var peer = std.Io.Writer.Allocating.init(std.testing.allocator);
defer peer.deinit();

const chunk_capacity = 5;

var bw: std.http.BodyWriter = .{
.http_protocol_output = &peer.writer,
.state = .{ .chunk_len = chunk_capacity + "\r\n".len },
.writer = .{
.buffer = &.{},
.vtable = &.{
.drain = std.http.BodyWriter.chunkedDrain,
},
},
};

_ = try bw.writer.writeVec(&.{ "great", "...not" });

try std.testing.expectEqualStrings("great", peer.written());
}

fn echoTests(client: *http.Client, port: u16) !void {
const gpa = std.testing.allocator;
var location_buffer: [100]u8 = undefined;
Expand Down