Skip to content

fix(deno): echo negotiated WebSocket subprotocol in upgrade response#4955

Merged
yusukebe merged 2 commits into
honojs:mainfrom
ATOM00blue:fix/deno-ws-subprotocol
May 22, 2026
Merged

fix(deno): echo negotiated WebSocket subprotocol in upgrade response#4955
yusukebe merged 2 commits into
honojs:mainfrom
ATOM00blue:fix/deno-ws-subprotocol

Conversation

@ATOM00blue

Copy link
Copy Markdown
Contributor

What

The Deno adapter's upgradeWebSocket does not set the Sec-WebSocket-Protocol header on the upgrade response. When a client opens a socket with a subprotocol (e.g. new WebSocket(url, ["foobar"])), Chrome rejects the connection because the negotiated subprotocol is missing from the 101 response. Firefox is more lenient, which is why this looked Chrome-specific.

How

Deno.upgradeWebSocket only emits the Sec-WebSocket-Protocol response header when given a protocol option. This reads the first value from the request's Sec-WebSocket-Protocol header and passes it through as protocol. An explicitly provided protocol option still takes precedence, so existing behavior is preserved.

Tests

Added unit tests that mock the Deno.upgradeWebSocket global and assert the protocol option is derived from the request header (and left unset when no subprotocol is requested). tsc --noEmit, eslint, and prettier all pass.

Closes #4439

The Deno adapter did not set the `Sec-WebSocket-Protocol` header on the
upgrade response, so browsers such as Chrome rejected connections that
requested a subprotocol. Read the first value from the request's
`Sec-WebSocket-Protocol` header and pass it as the `protocol` option to
`Deno.upgradeWebSocket`, while still honoring an explicitly provided
`protocol` option.

Closes honojs#4439
Copilot AI review requested due to automatic review settings May 21, 2026 02:21

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR updates the Deno WebSocket upgrade adapter to echo a requested subprotocol back to the client (to avoid browser handshake rejection) and adds tests to validate the behavior.

Changes:

  • Read Sec-WebSocket-Protocol from the request and pass the first value to Deno.upgradeWebSocket as the protocol option.
  • Add test coverage for protocol header present/absent scenarios.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
src/adapter/deno/websocket.ts Adds logic to forward the request’s subprotocol into the upgrade options.
src/adapter/deno/websocket.test.ts Adds tests ensuring the protocol option is set/unset based on request headers.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


const { response, socket } = Deno.upgradeWebSocket(c.req.raw, {
...(subprotocol ? { protocol: subprotocol } : {}),
...options,
Comment on lines +10 to +12
// Echo the negotiated subprotocol back to the client. Browsers (e.g. Chrome)
// reject the connection when a subprotocol was requested but the response is
// missing the `Sec-WebSocket-Protocol` header.
Comment on lines +86 to +92
Deno.upgradeWebSocket = (_req, options) => {
passedOptions = options
return {
response: new Response(),
socket,
}
}
@codecov

codecov Bot commented May 21, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.97%. Comparing base (a83ddb8) to head (dced0f6).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #4955   +/-   ##
=======================================
  Coverage   92.97%   92.97%           
=======================================
  Files         177      177           
  Lines       12226    12230    +4     
  Branches     3711     3713    +2     
=======================================
+ Hits        11367    11371    +4     
  Misses        859      859           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@yusukebe yusukebe left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@yusukebe yusukebe merged commit 7e0555d into honojs:main May 22, 2026
21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Deno upgradeWebSocket missing Sec-WebSocket-Protocol header in response

3 participants