fix: address code review findings for WebSocket implementation

- Convert WsReadInfo from mutable struct to class (prevents silent copy bugs)
- Add handshake timeout enforcement via CancellationToken in WsUpgrade
- Use buffered reading (512 bytes) in ReadHttpRequestAsync instead of byte-at-a-time
- Add IAsyncDisposable to WsConnection for proper async cleanup
- Simplify redundant mask bit check in WsReadInfo
- Remove unused WsGuid and CompressLastBlock dead code from WsConstants
- Document single-reader assumption on WsConnection read-side state
This commit is contained in:
Joseph Doherty
2026-02-23 05:27:36 -05:00
parent 5fd2cf040d
commit 18a6d0f478
6 changed files with 42 additions and 33 deletions

View File

@@ -62,7 +62,7 @@ public class WsFrameReadTests
var readInfo = new WsReadInfo(expectMask: false);
var stream = new MemoryStream(frame);
var result = WsReadInfo.ReadFrames(ref readInfo, stream, frame.Length, maxPayload: 1024);
var result = WsReadInfo.ReadFrames(readInfo, stream, frame.Length, maxPayload: 1024);
result.Count.ShouldBe(1);
result[0].ShouldBe(payload);
@@ -77,7 +77,7 @@ public class WsFrameReadTests
var readInfo = new WsReadInfo(expectMask: true);
var stream = new MemoryStream(frame);
var result = WsReadInfo.ReadFrames(ref readInfo, stream, frame.Length, maxPayload: 1024);
var result = WsReadInfo.ReadFrames(readInfo, stream, frame.Length, maxPayload: 1024);
result.Count.ShouldBe(1);
result[0].ShouldBe(payload);
@@ -92,7 +92,7 @@ public class WsFrameReadTests
var readInfo = new WsReadInfo(expectMask: false);
var stream = new MemoryStream(frame);
var result = WsReadInfo.ReadFrames(ref readInfo, stream, frame.Length, maxPayload: 1024);
var result = WsReadInfo.ReadFrames(readInfo, stream, frame.Length, maxPayload: 1024);
result.Count.ShouldBe(1);
result[0].ShouldBe(payload);
@@ -105,7 +105,7 @@ public class WsFrameReadTests
var readInfo = new WsReadInfo(expectMask: false);
var stream = new MemoryStream(frame);
var result = WsReadInfo.ReadFrames(ref readInfo, stream, frame.Length, maxPayload: 1024);
var result = WsReadInfo.ReadFrames(readInfo, stream, frame.Length, maxPayload: 1024);
result.Count.ShouldBe(0); // control frames don't produce payload
readInfo.PendingControlFrames.Count.ShouldBe(1);
@@ -121,7 +121,7 @@ public class WsFrameReadTests
var readInfo = new WsReadInfo(expectMask: false);
var stream = new MemoryStream(frame);
var result = WsReadInfo.ReadFrames(ref readInfo, stream, frame.Length, maxPayload: 1024);
var result = WsReadInfo.ReadFrames(readInfo, stream, frame.Length, maxPayload: 1024);
result.Count.ShouldBe(0);
readInfo.CloseReceived.ShouldBeTrue();
@@ -135,7 +135,7 @@ public class WsFrameReadTests
var readInfo = new WsReadInfo(expectMask: false);
var stream = new MemoryStream(frame);
var result = WsReadInfo.ReadFrames(ref readInfo, stream, frame.Length, maxPayload: 1024);
var result = WsReadInfo.ReadFrames(readInfo, stream, frame.Length, maxPayload: 1024);
result.Count.ShouldBe(0);
readInfo.PendingControlFrames.Count.ShouldBe(0);