You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Crow does not return "404 Not Found\r\n" when calling an invalid route because the socket is closed before the response can be asynchronously written to it
#1019
Open
GitGud711 opened this issue
Apr 11, 2025
· 0 comments
In #499 the HTTP parser code was changed so that a route is searched for as soon as the HTTP method and URL are parsed from the request. If no route is found, the parsing is terminated with error CHPE_INVALID_EOF_STATE, causing the crow::Connection<>::do_read() function to terminate the socket early because of the error state. Before the socket was terminated though, crow::Connection<>::handle_url() called crow::Connection<>::complete_request(), which prepared the response buffers and was supposed to write them to the socket asynchronously (do_write_general() -> do_write()), but it never did.
The 2 problems I see are:
Not finding a route is treated as a parsing error, when it in fact shouldn't be. It shouldn't end parsing with CHPE_INVALID_EOF_STATE.
crow::Connection<>'s close_connection_ is not set in crow::Connection<>::handle_url() before calling crow::Connection<>::complete_request() when parsing terminates early because the route was not found. This means that the socket is not closed after the response buffers are written to it.
Overall, finding a route should be treated as a success case, but not as CHPE_OK. My suggestion would be to add another error, something like CHPE_OK_ROUTE_NOT_FOUND or something similar, and handle this case where required.
I tested this on Ubuntu 20.04.6 LTS on a x64 VirtualBox VM, using boost 1.76 and crow v1.2.0. I initiated a crow::SimpleApp and set multithreaded() on it.
For the REST request and socket logic I used:
boost::beast::http::request<boost::beast::http::string_body> and boost::beast::http::response<boost::beast::http::string_body>
boost::asio::io_context and boost::asio::ip::tcp::socket to create the socket
boost::beast::http::write and boost::beast::http::read to write to and read from the socket.
If required I can provide a code sample.
I tested a hacky fix on my setup where I added a new error to the list (CROW_XX(OK_ROUTE_NOT_FOUND, "route not found for request")), and set parser_.http_errno to the error number and close_connection_ to true inside handle_url(), but this is not a proper way to do it. I don't know where and how to set this error using its name, not its index.
The text was updated successfully, but these errors were encountered:
This issue affects crow v1.2.0 and higher.
In #499 the HTTP parser code was changed so that a route is searched for as soon as the HTTP method and URL are parsed from the request. If no route is found, the parsing is terminated with error
CHPE_INVALID_EOF_STATE
, causing thecrow::Connection<>::do_read()
function to terminate the socket early because of the error state. Before the socket was terminated though,crow::Connection<>::handle_url()
calledcrow::Connection<>::complete_request()
, which prepared the response buffers and was supposed to write them to the socket asynchronously (do_write_general()
->do_write()
), but it never did.The 2 problems I see are:
CHPE_INVALID_EOF_STATE
.crow::Connection<>
'sclose_connection_
is not set incrow::Connection<>::handle_url()
before callingcrow::Connection<>::complete_request()
when parsing terminates early because the route was not found. This means that the socket is not closed after the response buffers are written to it.Overall, finding a route should be treated as a success case, but not as
CHPE_OK
. My suggestion would be to add another error, something likeCHPE_OK_ROUTE_NOT_FOUND
or something similar, and handle this case where required.I tested this on Ubuntu 20.04.6 LTS on a x64 VirtualBox VM, using boost 1.76 and crow v1.2.0. I initiated a
crow::SimpleApp
and setmultithreaded()
on it.For the REST request and socket logic I used:
boost::beast::http::request<boost::beast::http::string_body>
andboost::beast::http::response<boost::beast::http::string_body>
boost::asio::io_context
andboost::asio::ip::tcp::socket
to create the socketboost::beast::http::write
andboost::beast::http::read
to write to and read from the socket.If required I can provide a code sample.
I tested a hacky fix on my setup where I added a new error to the list (
CROW_XX(OK_ROUTE_NOT_FOUND, "route not found for request")
), and setparser_.http_errno
to the error number andclose_connection_
totrue
insidehandle_url()
, but this is not a proper way to do it. I don't know where and how to set this error using its name, not its index.The text was updated successfully, but these errors were encountered: