fix(realtime): resolve the device on the authorized upgrade (lowercase headers); 1.1.1 #30

Merged
james.maes merged 1 commits from fix/realtime-header-case-20261106 into main 2026-11-06 15:31:00 +00:00
Owner

Forge's adoption qualification of released 1.1.0 reproduced a realtime failure before WELCOME when upgrade header names arrive lowercase (ingress normalization): WsContext.header is case-sensitive, so the device was null and channels.put threw. Fix: resolve the device once on the authorized HTTP upgrade and carry it as a connection attribute (same approach as Forge's local patch). Regression test with lowercase header names covers WELCOME, inventory ACK, PRINTERS push and socket replacement; it fails on main with the same NPE. Full gate: 200 tests, 0 failures, 0 Checkstyle. Version 1.1.1; no contract change.

🤖 Generated with Claude Code

Forge's adoption qualification of released 1.1.0 reproduced a realtime failure before WELCOME when upgrade header names arrive lowercase (ingress normalization): WsContext.header is case-sensitive, so the device was null and channels.put threw. Fix: resolve the device once on the authorized HTTP upgrade and carry it as a connection attribute (same approach as Forge's local patch). Regression test with lowercase header names covers WELCOME, inventory ACK, PRINTERS push and socket replacement; it fails on main with the same NPE. Full gate: 200 tests, 0 failures, 0 Checkstyle. Version 1.1.1; no contract change. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
james.maes added 1 commit 2026-11-06 14:24:57 +00:00
fix(realtime): resolve the device on the authorized upgrade so lowercase headers connect; 1.1.1
QRun-IO/ci-policy: ci / fork-guard (pull_request) Skipped
QRun-IO/ci-policy: native / fork-deny (pull_request) Skipped
QRun-IO/ci-policy: native / dotnet-0 (pull_request) Skipped
Shared Java Maven CI / secrets (push) Successful in 21s
QRun-IO/ci-policy: ci / head-profile (pull_request) Skipped
QRun-IO/ci-policy: ci / repository-policy (pull_request) Skipped
QRun-IO/ci-policy: ci / application-template-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / gradle-1 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-core-2-head (pull_request) Skipped
QRun-IO/ci-policy: ci / java-docker-3 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-docker-3-head (pull_request) Skipped
QRun-IO/ci-policy: ci / java-docker-4 (pull_request) Skipped
QRun-IO/ci-policy: native / native-result (pull_request) Successful in 7s
QRun-IO/ci-policy: ci / java-frontend-browser-5 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-6 (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-6-head (pull_request) Skipped
QRun-IO/ci-policy: ci / java-maven-7-head (pull_request) Skipped
QRun-IO/ci-policy: ci / node-8 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-9 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-10 (pull_request) Skipped
QRun-IO/ci-policy: ci / node-playwright-11 (pull_request) Skipped
QRun-IO/ci-policy: ci / repository-policy-12 (pull_request) Skipped
QRun-IO/ci-policy: ci / source-config-13 (pull_request) Skipped
QRun-IO/ci-policy: ci / source-config-14 (pull_request) Skipped
QRun-IO/ci-policy: ci / android-0 (pull_request) Skipped
QRun-IO/ci-policy: ci / original-business (pull_request) Skipped
QRun-IO/ci-policy: ci / original-mcp (pull_request) Skipped
QRun-IO/ci-policy: ci / original-voyage (pull_request) Skipped
QRun-IO/ci-policy: ci / original-cli (pull_request) Skipped
QRun-IO/ci-policy: ci / not-enrolled (pull_request) Skipped
QRun-IO/ci-policy: ci / Scoped workflow [workflow 1e25bb5a243dfdcd95d4b9a4f780200ff8c8778a] (pull_request) Successful in 12s
QRun-IO/ci-policy: ci / shared-pipeline (pull_request) Skipped
QRun-IO/ci-policy: Shared Java Maven CI / secrets (pull_request) Successful in 20s
Shared Java Maven CI / verify (push) Successful in 4m14s
QRun-IO/ci-policy: Shared Java Maven CI / verify (pull_request) Successful in 3m51s
Shared Java Maven CI / gate (push) Successful in 15s
qrun-release / release (push) Successful in 4m32s
QRun-IO/ci-policy: Shared Java Maven CI / gate (pull_request) Successful in 13s
QRun-IO/ci-policy: ci / java-maven-7 (pull_request) Successful in 4m8s
QRun-IO/ci-policy: ci / ci-result (pull_request) Successful in 8s
Shared QRun source version / version (push) Successful in 27s
qrun-release / postpublish (push) Successful in 27s
e7721bdf90
The WebSocket callbacks read X-QQQ-Device-Id from the socket context, whose
header lookup is case-sensitive, while the HTTP upgrade matches names
case-insensitively. Behind an ingress that lowercases header names the device
resolved to null on connect and channels.put threw before WELCOME (Forge's
adoption test of released 1.1.0; Forge had carried a local patch on 1.0.0).
Resolve the device once after authorization on the upgrade and carry it as a
connection attribute for connect, message and close. The new
lowercaseUpgradeHeadersReachWelcomeAndFrames test fails on the previous code
with the same NullPointerException and passes here. No contract change.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: James Maes <james@kof22.com>
james.maes merged commit 2a561815fc into main 2026-11-06 15:31:00 +00:00
Sign in to join this conversation.