feat: add handleUpgradeRequest route option#342
Open
infiton wants to merge 1 commit intofastify:mainfrom
Open
Conversation
Author
|
@mcollina any thoughts on this? |
There was a problem hiding this comment.
Pull Request Overview
This PR introduces a new handleUpgradeRequest route-level option to allow custom handling of WebSocket upgrade requests before the standard WebSocket handler is invoked. This enables use cases like implementing a WebSocket proxy that needs to validate upstream connections before upgrading.
- Adds
handleUpgradeRequestfunction option that receives request, socket, and head buffer parameters - Allows custom upgrade logic with error handling and status code customization
- Maintains backward compatibility with existing WebSocket routing behavior
Reviewed Changes
Copilot reviewed 4 out of 5 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| index.js | Implements the core handleUpgradeRequest functionality with custom upgrade handling and error management |
| test/base.test.js | Adds comprehensive tests covering successful upgrades, error handling, and custom status codes |
| types/index.test-d.ts | Provides TypeScript type definitions and validation for the new upgrade handler |
| README.md | Documents the new feature with usage examples and API details |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
mcollina
reviewed
Aug 22, 2025
b3a585c to
7489d07
Compare
Eomm
reviewed
Nov 8, 2025
| const rawRequest = request.raw | ||
| routeOptions.handleUpgradeRequest(request, rawRequest[kWs], rawRequest[kWsHead]) | ||
| .then(socket => { | ||
| process.nextTick(callback,socket) |
Member
There was a problem hiding this comment.
Suggested change
| process.nextTick(callback,socket) | |
| process.nextTick(callback, socket) |
Comment on lines
+159
to
+162
| const handleUpgrade = routeOptions.handleUpgradeRequest | ||
| ? (request, reply, callback) => { | ||
| const rawRequest = request.raw | ||
| routeOptions.handleUpgradeRequest(request, rawRequest[kWs], rawRequest[kWsHead]) |
Member
There was a problem hiding this comment.
I feel we could improve a bit this code to avoid extra clojure
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
At gadget we make extensive use of
@fastify/websocket. One use case is a websocket proxy that connects vite hmr clients in the browser to a developers serverless development environment. The vite client has a ping protocol with the following semantics:We need a way to handle upgrade events in our proxy layer and not upgrade connections until we know that the upstream vite will also upgrade the connection. To do this I have introduced a route level option
handleUpgradeRequestthat allows for a route by route customization of how the upgrade event should be handled.handleUpgradeRequestis a function that takes the incomingFastifyRequest, the source socket and the head buffer; to continue through to the normalwsHandlerthe use should return a promise that resolves to a connected websocket; to reject the connection the user can either throw an error (optionally with astatusCode) or write directly to/teardown the source socketChecklist
npm run test && npm run benchmark --if-presentand the Code of conduct