std.net: update to new I/O API

This commit is contained in:
Andrew Kelley 2025-07-11 11:30:58 -07:00
parent 5496901e71
commit 9a1f4cb011
5 changed files with 760 additions and 360 deletions

View File

@ -393,6 +393,32 @@ pub fn writableVectorPosix(w: *Writer, buffer: []std.posix.iovec, limit: Limit)
return buffer[0..i]; return buffer[0..i];
} }
pub fn writableVectorWsa(
w: *Writer,
buffer: []std.os.windows.ws2_32.WSABUF,
limit: Limit,
) Error![]std.os.windows.ws2_32.WSABUF {
var it = try writableVectorIterator(w);
var i: usize = 0;
var remaining = limit;
while (it.next()) |full_buffer| {
if (!remaining.nonzero()) break;
if (buffer.len - i == 0) break;
const buf = remaining.slice(full_buffer);
if (buf.len == 0) continue;
if (std.math.cast(u32, buf.len)) |len| {
buffer[i] = .{ .buf = buf.ptr, .len = len };
i += 1;
remaining = remaining.subtract(len).?;
continue;
}
buffer[i] = .{ .buf = buf.ptr, .len = std.math.maxInt(u32) };
i += 1;
break;
}
return buffer[0..i];
}
pub fn ensureUnusedCapacity(w: *Writer, n: usize) Error!void { pub fn ensureUnusedCapacity(w: *Writer, n: usize) Error!void {
_ = try writableSliceGreedy(w, n); _ = try writableSliceGreedy(w, n);
} }

View File

@ -135,7 +135,8 @@ test "HTTP server handles a chunked transfer coding request" {
const gpa = std.testing.allocator; const gpa = std.testing.allocator;
const stream = try std.net.tcpConnectToHost(gpa, "127.0.0.1", test_server.port()); const stream = try std.net.tcpConnectToHost(gpa, "127.0.0.1", test_server.port());
defer stream.close(); defer stream.close();
try stream.writeAll(request_bytes); var stream_writer = stream.writer(&.{});
try stream_writer.interface.writeAll(request_bytes);
const expected_response = const expected_response =
"HTTP/1.1 200 OK\r\n" ++ "HTTP/1.1 200 OK\r\n" ++
@ -144,7 +145,9 @@ test "HTTP server handles a chunked transfer coding request" {
"content-type: text/plain\r\n" ++ "content-type: text/plain\r\n" ++
"\r\n" ++ "\r\n" ++
"message from server!\n"; "message from server!\n";
const response = try stream.reader().readAllAlloc(gpa, expected_response.len); var tiny_buffer: [1]u8 = undefined; // allows allocRemaining to detect limit exceeded
var stream_reader = stream.reader(&tiny_buffer);
const response = try stream_reader.interface().allocRemaining(gpa, .limited(expected_response.len));
defer gpa.free(response); defer gpa.free(response);
try expectEqualStrings(expected_response, response); try expectEqualStrings(expected_response, response);
} }
@ -276,9 +279,12 @@ test "Server.Request.respondStreaming non-chunked, unknown content-length" {
const gpa = std.testing.allocator; const gpa = std.testing.allocator;
const stream = try std.net.tcpConnectToHost(gpa, "127.0.0.1", test_server.port()); const stream = try std.net.tcpConnectToHost(gpa, "127.0.0.1", test_server.port());
defer stream.close(); defer stream.close();
try stream.writeAll(request_bytes); var stream_writer = stream.writer(&.{});
try stream_writer.interface.writeAll(request_bytes);
const response = try stream.reader().readAllAlloc(gpa, 8192); var tiny_buffer: [1]u8 = undefined; // allows allocRemaining to detect limit exceeded
var stream_reader = stream.reader(&tiny_buffer);
const response = try stream_reader.interface().allocRemaining(gpa, .limited(8192));
defer gpa.free(response); defer gpa.free(response);
var expected_response = std.ArrayList(u8).init(gpa); var expected_response = std.ArrayList(u8).init(gpa);
@ -339,9 +345,12 @@ test "receiving arbitrary http headers from the client" {
const gpa = std.testing.allocator; const gpa = std.testing.allocator;
const stream = try std.net.tcpConnectToHost(gpa, "127.0.0.1", test_server.port()); const stream = try std.net.tcpConnectToHost(gpa, "127.0.0.1", test_server.port());
defer stream.close(); defer stream.close();
try stream.writeAll(request_bytes); var stream_writer = stream.writer(&.{});
try stream_writer.interface.writeAll(request_bytes);
const response = try stream.reader().readAllAlloc(gpa, 8192); var tiny_buffer: [1]u8 = undefined; // allows allocRemaining to detect limit exceeded
var stream_reader = stream.reader(&tiny_buffer);
const response = try stream_reader.interface().allocRemaining(gpa, .limited(8192));
defer gpa.free(response); defer gpa.free(response);
var expected_response = std.ArrayList(u8).init(gpa); var expected_response = std.ArrayList(u8).init(gpa);

File diff suppressed because it is too large Load Diff

View File

@ -208,7 +208,8 @@ test "listen on a port, send bytes, receive bytes" {
const socket = try net.tcpConnectToAddress(server_address); const socket = try net.tcpConnectToAddress(server_address);
defer socket.close(); defer socket.close();
_ = try socket.writer().writeAll("Hello world!"); var stream_writer = socket.writer(&.{});
try stream_writer.interface.writeAll("Hello world!");
} }
}; };
@ -218,7 +219,8 @@ test "listen on a port, send bytes, receive bytes" {
var client = try server.accept(); var client = try server.accept();
defer client.stream.close(); defer client.stream.close();
var buf: [16]u8 = undefined; var buf: [16]u8 = undefined;
const n = try client.stream.reader().read(&buf); var stream_reader = client.stream.reader(&.{});
const n = try stream_reader.interface().readSliceShort(&buf);
try testing.expectEqual(@as(usize, 12), n); try testing.expectEqual(@as(usize, 12), n);
try testing.expectEqualSlices(u8, "Hello world!", buf[0..n]); try testing.expectEqualSlices(u8, "Hello world!", buf[0..n]);
@ -299,7 +301,8 @@ test "listen on a unix socket, send bytes, receive bytes" {
const socket = try net.connectUnixSocket(path); const socket = try net.connectUnixSocket(path);
defer socket.close(); defer socket.close();
_ = try socket.writer().writeAll("Hello world!"); var stream_writer = socket.writer(&.{});
try stream_writer.interface.writeAll("Hello world!");
} }
}; };
@ -309,7 +312,8 @@ test "listen on a unix socket, send bytes, receive bytes" {
var client = try server.accept(); var client = try server.accept();
defer client.stream.close(); defer client.stream.close();
var buf: [16]u8 = undefined; var buf: [16]u8 = undefined;
const n = try client.stream.reader().read(&buf); var stream_reader = client.stream.reader(&.{});
const n = try stream_reader.interface().readSliceShort(&buf);
try testing.expectEqual(@as(usize, 12), n); try testing.expectEqual(@as(usize, 12), n);
try testing.expectEqualSlices(u8, "Hello world!", buf[0..n]); try testing.expectEqualSlices(u8, "Hello world!", buf[0..n]);

View File

@ -55,14 +55,15 @@ fn runThread(ids: *IncrementalDebugServer) void {
const conn = server.accept() catch @panic("IncrementalDebugServer: failed to accept"); const conn = server.accept() catch @panic("IncrementalDebugServer: failed to accept");
defer conn.stream.close(); defer conn.stream.close();
var stream_reader = conn.stream.reader(&cmd_buf);
while (ids.running.load(.monotonic)) { while (ids.running.load(.monotonic)) {
conn.stream.writeAll("zig> ") catch @panic("IncrementalDebugServer: failed to write"); conn.stream.writeAll("zig> ") catch @panic("IncrementalDebugServer: failed to write");
var fbs = std.io.fixedBufferStream(&cmd_buf); const untrimmed = stream_reader.interface().takeSentinel('\n') catch |err| switch (err) {
conn.stream.reader().streamUntilDelimiter(fbs.writer(), '\n', cmd_buf.len) catch |err| switch (err) {
error.EndOfStream => break, error.EndOfStream => break,
else => @panic("IncrementalDebugServer: failed to read command"), else => @panic("IncrementalDebugServer: failed to read command"),
}; };
const cmd_and_arg = std.mem.trim(u8, fbs.getWritten(), " \t\r\n"); const cmd_and_arg = std.mem.trim(u8, untrimmed, " \t\r\n");
const cmd: []const u8, const arg: []const u8 = if (std.mem.indexOfScalar(u8, cmd_and_arg, ' ')) |i| const cmd: []const u8, const arg: []const u8 = if (std.mem.indexOfScalar(u8, cmd_and_arg, ' ')) |i|
.{ cmd_and_arg[0..i], cmd_and_arg[i + 1 ..] } .{ cmd_and_arg[0..i], cmd_and_arg[i + 1 ..] }
else else