elysiajs / elysia

Ergonomic Framework for Humans
https://elysiajs.com
MIT License
10.51k stars 223 forks source link

Getting "400 Bad Request" when trying to connect to websocket using `export default app` #831

Open RadhiRasho opened 1 month ago

RadhiRasho commented 1 month ago

What version of Elysia is running?

1.1.12

What platform is your computer?

Linux 5.15.153.1-microsoft-standard-WSL2 x86_64 x86_64

What steps can reproduce the bug?

I'm not actually sure this is a bug entirely. It's just some odd behavior that I have seen.

  1. create a fresh app
  2. Create a web socket endpoint
  3. export the Elysia app by default
  4. Try to connect to the web socket endpoint
import { Elysia } from "elysia";

const app = new Elysia()
    .get("/", () => "Hello Elysia")
    .ws("/realtime", {
        message(ws, message) {
            ws.send(`Got; ${message}`);
        },
    });

export default app;

What is the expected behavior?

I expect to be able to connect to the Websocket endpoint as I would normally

What do you see instead?

I'm running into the following response: image

Additional information

The application works normally when using the .listen(3000) on the application itself, such as the following:

import { Elysia } from "elysia";

new Elysia()
    .get("/", () => "Hello Elysia")
    .ws("/realtime", {
        message(ws, message) {
            ws.send(`Got; ${message}`);
        },
    })
    .listen(3000);

I believe that it should work the same when using .listen(3000) and when using export default app.

Have you try removing the node_modules and bun.lockb and try again yet?

Yes

Renato66 commented 1 month ago

you can pass it like this:

import { Elysia } from "elysia";

const app = new Elysia()
    .get("/", () => "Hello Elysia")
    .ws("/realtime", {
        message(ws, message) {
            ws.send(`Got; ${message}`);
        },
    })
    .listen(3000);

export default app;

just exporting the app, doesn't run the server, so it doesn't know wich port you would serve to allow connections

RadhiRasho commented 1 month ago

@Renato66 When I do that, it complains about port 3000 being in use, so I believe that export default app is running the server just fine.

If I wanted that to work, I could also do this:

export default {
    fetch: app.fetch,
    reusePort: true
}

It's not like the WS endpoint isn't running, it's just returning a bad request when it's supposed to be switching protocal, during the handshake.

RadhiRasho commented 1 month ago

However, it looks like the connection seems to be shaky when doing the above, where if it does connect, if you disconnect and reconnect, it comes back with a 400 Bad Request, I'm assuming it's going through the bad route (export default { fetch: app.fetch, reusePort: true }) when it fails and when it's successful it's going through the listen(3000) side of things.