CrowCpp / Crow

A Fast and Easy to use microframework for the web.
https://crowcpp.org
Other
3.13k stars 347 forks source link

`crow::Crow<>::stop()` stops `asio::io_context` too soon #498

Open DisableAsync opened 2 years ago

DisableAsync commented 2 years ago

If one calls crow::websocket::connection::close() followed by crow::Crow<>::stop() right away, they are probably doomed.

I only skimmed through the code. Looks like the issue was, crow::websocket::connection::close() uses asio's dispatch function so if called from a different thread other than within the one(s) running io_context loop, it only post the task to the queue. It will need some time for the io_context to pick it up and execute. And crow::Crow<>::stop() stops io_contexts immediately, so the tasks are untouched and the connections remain in a connected state.

DisableAsync commented 2 years ago

A quick fix could be instead of invoking asio::io_context::stop() directly, we also dispatch the invocation.

Not sure if this has its own pitfalls, just couldn't think of something better ATM.

The-EDev commented 2 years ago

I think another solution would be to have the server wait for all websocket connections to be closed before calling stop()

DisableAsync commented 2 years ago

I think another solution would be to have the server wait for all websocket connections to be closed before calling stop()

I have been thinking, do we have a convenient way to wait for certain events like the closing of WebSocket connection, in Crow or ASIO?

The-EDev commented 2 years ago

Not exactly, what we do have is a list of all open websocket connections. We can use that to check whether or not they were all closed before stopping the server.

z16166 commented 1 year ago

It can be attacked by malicious clients if they hold the connections for ever, to prevent the server from stopping.

I just give up another websocket library called "uWebSockets" and turn to CrowCpp, because uWebSockets can't safely stop, it always crashes on Windows, but the developer of uWebSockets says it's my fault.

Not exactly, what we do have is a list of all open websocket connections. We can use that to check whether or not they were all closed before stopping the server.