-
Notifications
You must be signed in to change notification settings - Fork 140
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Crash with fallback GET route #64
Comments
I'll have to look into this further to confirm, but I'm fairly sure that the issue is caused by the 'fake' GET route that's created for each |
Another case from #46:
Two other cases from #65:
And the culprit here would probably be:
In other words, the culprit seems to be with with any kind of wildcard-y route or middleware that matches the fake GET route created by |
Maybe this is a dumb question, but I still don't get why the |
Express has no awareness of "protocol" - all it sees is HTTP requests and responses, with methods. Technically speaking, WebSockets aren't an independent protocol anyway; a WebSocket connection is established using an upgrade request, which is the same as a regular HTTP request from a protocol perspective. Express also has no concept of WebSockets - it expects every HTTP request to be followed up by a HTTP response, after which the connection is closed. So what However, you can't just create a regular GET route at the same path as every WebSocket path - if an application does the following: router.get("/foo", (req, res) => {
// ...
});
router.ws("/foo", (ws, req) => {
// ...
}); ... then you want to treat these two routes as entirely separate routes with entirely separate behaviour. If That's why |
Interesting. I was fully aware that websockets were just upgraded HTTP requests. But I didn't realize that there were no artifacts in the request that pointed to a websocket request. I also understand the fact that you can't really have two handlers for the same HTTP request absent some way within the request itself to disambiguate them (what I thought the protocol would do, but apparently not). So in that sense, I understand the need now for the fake I'm curious, wouldn't it be better to prefix the requests? It is seems quite easy for the developer of the application to carve out some part of the hierarchy for web socket handlers. In fact, a simple solution of prepending
This rule about building the fake handlers is encapsulated in the library. Wouldn't it be simple to switch to this alternative strategy? I could even imagine allowing users to override this by providing their own transformation function that takes the original path as an input and returns the fake path. Just some ideas. |
Prefixing was how it was implemented previously, but this breaks when using routers (see also this comment). Routers will 'chomp off' a part of the path when mounted as a prefix, which means that the This is a problem because the 'fake' GET request is created in the server connection handler (here), and that code has no knowledge of which WebSocket routes are defined on what routers mounted at which paths, so it will just prefix the entire path with This means that if you do the following: const express = require("express");
let app = express();
let router = express.Router();
router.ws("/bar", (ws, req) => {
// ...
});
app.use("/foo", router);
app.listen(3000); ... then when a WebSocket request for
That's why the
|
Actually, I was just reading RFC 6455. Why can't you simply differentiate the requests based on the presence of the header |
Because this would require changes to Express core, since it has no awareness of WebSockets whatsoever. The reason it works how it does now, is so that The problem isn't that |
Is there any workaround on this? |
@suhasdeshpande just make sure any wildcard routes you have defined do not match the 'fake' route. |
@ryanph how can I do this if I want to match all routes and render a default page for them? |
Ok I solved it the
move the websocket to
|
The root cause of the error is that the module is incorrectly overwriting the Node.js core method The problem is that Node.js core is expecting that the call to I hope this helps. I'll funnel over the Express users who are encountering this issue to this thread. |
Any progress? |
Updated packages.
I'm working on a project that has a middleware to catch all paths that don't match any route and return an HTML file. To overcome the problem described in this issue, we added a check in the middleware to skip its action if the request contains the WebSocket header: const frontendMiddleware = (req, res) => {
if (req.header('sec-websocket-version') === undefined) {
res.sendFile(path.join(FRONTEND_ROOT, 'build', 'index.html'))
}
}
app.use(frontendMiddleware) |
If you run the following test app:
When you make a WebSocket request to ws://localhost:3000/invalidroute, the process crashes with the following exception:
The text was updated successfully, but these errors were encountered: