From e54221dde60cdba723500f7e145e41309723f763 Mon Sep 17 00:00:00 2001 From: Maurus Decimus <11444311+mdecimus@users.noreply.github.com> Date: Tue, 19 May 2026 17:29:12 +0200 Subject: [PATCH] Fix Websocket: Perform case insensitive matching during upgrade --- CHANGELOG.md | 1 + crates/jmap/src/websocket/upgrade.rs | 18 +++++++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e059703..08bb764b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -82,6 +82,7 @@ If you are upgrading from v0.16.x, replace the binary (or run `docker pull`). If - Rout53: Chunk `TXT` records when they exceed 255 characters. - ACME: Update `defaultCertificateId` when renewing a certificate that is currently set as default. - Allow internal TLDs in e-mail addresses. +- Websocket: Perform case insensitive matching during upgrade. ## [0.16.5] - 2026-05-11 diff --git a/crates/jmap/src/websocket/upgrade.rs b/crates/jmap/src/websocket/upgrade.rs index d2a623a5..945b58e0 100644 --- a/crates/jmap/src/websocket/upgrade.rs +++ b/crates/jmap/src/websocket/upgrade.rs @@ -31,14 +31,18 @@ impl WebSocketUpgrade for Server { session: HttpSessionData, ) -> trc::Result { let headers = req.headers(); - if headers - .get(hyper::header::CONNECTION) - .and_then(|h| h.to_str().ok()) - != Some("Upgrade") - || headers - .get(hyper::header::UPGRADE) + let header_has_token = |name: hyper::header::HeaderName, token: &str| { + headers + .get(name) .and_then(|h| h.to_str().ok()) - != Some("websocket") + .is_some_and(|value| { + value + .split(',') + .any(|part| part.trim().eq_ignore_ascii_case(token)) + }) + }; + if !header_has_token(hyper::header::CONNECTION, "Upgrade") + || !header_has_token(hyper::header::UPGRADE, "websocket") { return Err(trc::ResourceEvent::BadParameters .into_err()