You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
turnloop-http servers close with unread peer bytes (RST drops the final response on macOS/Windows) #21
turnloop-http servers close their TCP socket as soon as a connection is drained. server::http2 does this on core.is_drained() and server::http1 after the final response. The close happens even if the peer's last frames are still unread (for example HTTP/2 SETTINGS or WINDOW_UPDATE acknowledgements, or a pipelined HTTP/1 request). Closing a socket with unread bytes sends RST. On macOS and Windows, a received RST discards data the client hasn't read yet, so the client can lose the tail of the final response.
Evidence: PR #20's CI run 34932385239 (test-native (macos-15, all-features)) failed node_https_and_http2_against_async_tls_server. The Node HTTP/2 client got Error: read ECONNRESET on its ClientHttp2Stream before its end event, so child.wait().success() failed. Linux, Windows and web passed in the same run. The same RST mechanism caused the async TLS test failure fixed in #5 (eeb626e).
Expected (lingering close, as nginx lingering_close and Node's graceful server shutdown do):
Flush the final response and GOAWAY.
Half-close the write side (shutdown(SHUT_WR)); the backend already supports Operation::Shutdown.
Read and discard until peer EOF or a bounded linger deadline.
Close.
Needed pieces:
A half-close API on turnloop_io::AsyncIo / TlsStream: TLS close_notify followed by TCP shutdown, without closing the handle.
Lingering close in server::http1 and server::http2, with a bounded, configurable linger timeout.
Tests with a peer that writes after the final response (for example unread WINDOW_UPDATE frames, or a pipelined extra HTTP/1 request). They must assert that the client receives the whole final response on macOS, Linux and Windows, with no-spin and zero allocation in steady state.
Activity
Lingering close for HTTP and WebSocket servers; half-close API (#23)