Skip to content

fix(ws): handle multi-server upgrade subscription and safe proxy shutdown - #1237

Merged
chimurai merged 1 commit into
masterfrom
fix-ws-multi-server-upgrade
May 23, 2026
Merged

fix(ws): handle multi-server upgrade subscription and safe proxy shutdown#1237
chimurai merged 1 commit into
masterfrom
fix-ws-multi-server-upgrade

Conversation

@chimurai

@chimurai chimurai commented May 23, 2026

Copy link
Copy Markdown
Owner

fixes: #1149

Summary by CodeRabbit

  • Bug Fixes
    • WebSocket upgrade requests are now correctly handled when multiple HTTP servers use the same proxy middleware.
    • Graceful proxy shutdown now properly tracks multiple server instances and defers closure until all servers have closed.

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 23, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2a3d5a44-9575-423f-a946-be6652b74d07

📥 Commits

Reviewing files that changed from the base of the PR and between 31429ad and 2a80bd3.

📒 Files selected for processing (4)
  • CHANGELOG.md
  • src/http-proxy-middleware.ts
  • test/e2e/graceful-shutdown.spec.ts
  • test/e2e/websocket.spec.ts

📝 Walkthrough

Walkthrough

This PR fixes WebSocket proxying across multiple servers by replacing global boolean tracking with per-server subscription and lifecycle management. The middleware now tracks which servers have had their upgrade handler subscribed via a WeakSet, manages a set of active servers for graceful shutdown, and defers proxy closure until all servers have closed.

Changes

Multi-server WebSocket and shutdown handling

Layer / File(s) Summary
Per-server state tracking
src/http-proxy-middleware.ts
Introduces WeakSet to track per-server WebSocket upgrade subscriptions and Set to track active servers, replacing global boolean flags.
Upgrade handler per-server logic
src/http-proxy-middleware.ts
Implements #getServer helper and updates middleware.upgrade to resolve the originating server and conditionally call handleUpgrade only once per server. catchUpgradeRequest now records subscriptions in the WeakSet per server.
Per-server graceful shutdown
src/http-proxy-middleware.ts
Registers a close listener per discovered server, updates activeServers on close, and closes the proxy only when no active servers remain.
Graceful shutdown E2E test
test/e2e/graceful-shutdown.spec.ts
Tests that the same proxy middleware attached to two HTTP servers defers proxy.close() until all servers close and calls it exactly once.
WebSocket multi-server E2E test
test/e2e/websocket.spec.ts
Verifies that WebSocket upgrade requests successfully proxy across multiple independent proxy servers on distinct ports using the same middleware instance.
Changelog documentation
CHANGELOG.md
Documents the fix for handling multi-server upgrade subscription and safe proxy shutdown.

Sequence Diagram

sequenceDiagram
  participant Server1
  participant Server2
  participant HttpProxyMiddleware
  participant WebSocketUpgrade as WebSocket Upgrade<br/>(per server)
  participant GracefulShutdown as Graceful Shutdown<br/>(per server)

  Server1->>HttpProxyMiddleware: Attach middleware via use()
  Server2->>HttpProxyMiddleware: Attach middleware via use()
  
  Server1->>HttpProxyMiddleware: First upgrade request on Server1
  HttpProxyMiddleware->>WebSocketUpgrade: Check WeakSet for Server1
  WebSocketUpgrade->>HttpProxyMiddleware: Not subscribed, subscribe now
  HttpProxyMiddleware->>WebSocketUpgrade: Register upgrade handler on Server1
  
  Server2->>HttpProxyMiddleware: First upgrade request on Server2
  HttpProxyMiddleware->>WebSocketUpgrade: Check WeakSet for Server2
  WebSocketUpgrade->>HttpProxyMiddleware: Not subscribed, subscribe now
  HttpProxyMiddleware->>WebSocketUpgrade: Register upgrade handler on Server2
  
  Server1->>HttpProxyMiddleware: close()
  HttpProxyMiddleware->>GracefulShutdown: Remove Server1 from activeServers
  GracefulShutdown->>HttpProxyMiddleware: activeServers not empty, defer proxy.close()
  
  Server2->>HttpProxyMiddleware: close()
  HttpProxyMiddleware->>GracefulShutdown: Remove Server2 from activeServers
  GracefulShutdown->>HttpProxyMiddleware: activeServers empty, call proxy.close()
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 Hops through the servers, one and then two,
WebSocket subscriptions now track what is true,
No global flags to confuse the way,
Each server waits till siblings have their say,
Graceful shutdown with nothing left behind! 🎉

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly matches the main change: fixing WebSocket upgrade subscription handling and safe proxy shutdown for multi-server scenarios.
Linked Issues check ✅ Passed The PR addresses issue #1149 by implementing per-server WebSocket upgrade tracking and safe shutdown, enabling the proxy to handle both ws and wss protocols regardless of request order.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing multi-server WebSocket upgrade subscriptions and graceful shutdown; no unrelated modifications detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-ws-multi-server-upgrade

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@pkg-pr-new

pkg-pr-new Bot commented May 23, 2026

Copy link
Copy Markdown
npm i https://pkg.pr.new/http-proxy-middleware@1237

commit: 2a80bd3

@coveralls

Copy link
Copy Markdown

Coverage Status

coverage: 94.67% (+0.4%) from 94.315% — fix-ws-multi-server-upgrade into master

@chimurai
chimurai merged commit b2f36be into master May 23, 2026
26 checks passed
@chimurai
chimurai deleted the fix-ws-multi-server-upgrade branch May 23, 2026 10:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Websocket only works on initial protocol Declare two different proxies with Websocket enabled does not work, or probably pathrewrite does not work

2 participants