Skip to content

Commit 6a62e67

Browse files
authored
Merge pull request #1 from nullclaw/fix/windows-rcvtimeo-reset
fix(server): preserve receive timeout on Windows
2 parents 4b2c70d + 3743a02 commit 6a62e67

1 file changed

Lines changed: 16 additions & 1 deletion

File tree

src/server/server.zig

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,9 @@ pub fn Blocking(comptime H: type) type {
408408
// directly when integrating with an http server
409409
pub fn readLoop(self: *Self, hc: *HandlerConn(H)) !void {
410410
defer self.cleanupConn(hc);
411-
try posix.setsockopt(hc.socket, posix.SOL.SOCKET, posix.SO.RCVTIMEO, &Timeout.none);
411+
if (shouldClearReceiveTimeout(builtin.os.tag)) {
412+
try posix.setsockopt(hc.socket, posix.SOL.SOCKET, posix.SO.RCVTIMEO, &Timeout.none);
413+
}
412414

413415
// In BlockingMode, we always assign a reader for the duration of the connection
414416
// In scenarios where client rarely send data, this is going to use up an unecessary amount
@@ -1829,6 +1831,13 @@ fn socketWrite(socket: posix.socket_t, buf: []const u8) !usize {
18291831
return posix.write(socket, buf);
18301832
}
18311833

1834+
fn shouldClearReceiveTimeout(os_tag: std.Target.Os.Tag) bool {
1835+
// Regression: on Windows, resetting SO_RCVTIMEO to a zero timeval after the
1836+
// handshake can cause the next websocket read to fail immediately. Leave the
1837+
// handshake timeout in place there until the underlying socket behavior is fixed.
1838+
return os_tag != .windows;
1839+
}
1840+
18321841
fn timestamp() u32 {
18331842
if (comptime @hasDecl(posix, "CLOCK") == false or posix.CLOCK == void) {
18341843
return @intCast(std.time.timestamp());
@@ -1992,6 +2001,12 @@ test "Conn: close" {
19922001
}
19932002
}
19942003

2004+
test "shouldClearReceiveTimeout skips Windows" {
2005+
try t.expectEqual(false, shouldClearReceiveTimeout(.windows));
2006+
try t.expectEqual(true, shouldClearReceiveTimeout(.linux));
2007+
try t.expectEqual(true, shouldClearReceiveTimeout(.macos));
2008+
}
2009+
19952010
fn testStream(handshake: bool) !net.Stream {
19962011
const timeout = std.mem.toBytes(std.posix.timeval{ .sec = 0, .usec = 20_000 });
19972012
const address = try std.net.Address.parseIp("127.0.0.1", 9292);

0 commit comments

Comments
 (0)