Commit Graph

11 Commits

Author SHA1 Message Date
Joseph Doherty
02531dda58 feat(config+ws): add TLS cert reload, WS compression negotiation, WS JWT auth (E9+E10+E11)
E9: TLS Certificate Reload
- Add TlsCertificateProvider with Interlocked-swappable cert field
- New connections get current cert, existing connections keep theirs
- ConfigReloader.ReloadTlsCertificate rebuilds SslServerAuthenticationOptions
- NatsServer.ApplyConfigChanges triggers TLS reload on TLS config changes
- 11 tests covering cert swap, versioning, thread safety, config diff

E10: WebSocket Compression Negotiation (RFC 7692)
- Add WsDeflateNegotiator to parse Sec-WebSocket-Extensions parameters
- Parse server_no_context_takeover, client_no_context_takeover,
  server_max_window_bits, client_max_window_bits
- WsDeflateParams record struct with ToResponseHeaderValue()
- NATS always enforces no_context_takeover (matching Go server)
- WsUpgrade returns negotiated WsDeflateParams in upgrade result
- 22 tests covering parameter parsing, clamping, response headers

E11: WebSocket JWT Authentication
- Extract JWT from Authorization header (Bearer token), cookie, or ?jwt= query param
- Priority: Authorization header > cookie > query parameter
- WsUpgrade.TryUpgradeAsync now parses query string from request URI
- Add FailUnauthorizedAsync for 401 responses
- 24 tests covering all JWT extraction sources and priority ordering
2026-02-24 16:03:46 -05:00
Joseph Doherty
18a6d0f478 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
2026-02-23 05:27:36 -05:00
Joseph Doherty
ca88036126 feat: integrate WebSocket accept loop into NatsServer and NatsClient
Add WebSocket listener support to NatsServer alongside the existing TCP
listener. When WebSocketOptions.Port >= 0, the server binds a second
socket, performs HTTP upgrade via WsUpgrade.TryUpgradeAsync, wraps the
connection in WsConnection for transparent frame/deframe, and hands it
to the standard NatsClient pipeline.

Changes:
- NatsClient: add IsWebSocket and WsInfo properties
- NatsServer: add RunWebSocketAcceptLoopAsync and AcceptWebSocketClientAsync,
  WS listener lifecycle in StartAsync/ShutdownAsync/Dispose
- NatsOptions: change WebSocketOptions.Port default from 0 to -1 (disabled)
- WsConnection.ReadAsync: fix premature end-of-stream when ReadFrames
  returns no payloads by looping until data is available
- Add WsIntegration tests (connect, ping, pub/sub over WebSocket)
- Add WsConnection masked frame and end-of-stream unit tests
2026-02-23 05:16:57 -05:00
Joseph Doherty
6d0a4d259e feat: add WsConnection Stream wrapper for transparent framing 2026-02-23 04:58:56 -05:00
Joseph Doherty
1c948b5b0f feat: add WebSocket HTTP upgrade handshake 2026-02-23 04:53:21 -05:00
Joseph Doherty
bd29c529a8 feat: add WebSocket frame reader state machine 2026-02-23 04:51:54 -05:00
Joseph Doherty
d49bc5b0d7 feat: add WebSocket permessage-deflate compression
Implement WsCompression with Compress/Decompress methods per RFC 7692.
Key .NET adaptation: Flush() without Dispose() on DeflateStream to produce
the correct sync flush marker that can be stripped and re-appended.
2026-02-23 04:42:31 -05:00
Joseph Doherty
8ded10d49b feat: add WebSocket frame writer with masking and close status mapping 2026-02-23 04:40:44 -05:00
Joseph Doherty
6981a38b72 feat: add WebSocket origin checker 2026-02-23 04:35:06 -05:00
Joseph Doherty
72f60054ed feat: add WebSocket protocol constants (RFC 6455)
Port WsConstants from golang/nats-server/server/websocket.go lines 41-106.
Includes opcodes, frame header bits, close status codes, compression
constants, header names, path routing, and the WsClientKind enum.
2026-02-23 04:33:04 -05:00
Joseph Doherty
708e1b4168 feat: add WebSocketOptions configuration class 2026-02-23 04:29:45 -05:00