summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--http/app.hpp6
-rw-r--r--http/http_connection.hpp19
-rw-r--r--http/routing.hpp44
3 files changed, 42 insertions, 27 deletions
diff --git a/http/app.hpp b/http/app.hpp
index d3afe60f05..a2892ced94 100644
--- a/http/app.hpp
+++ b/http/app.hpp
@@ -58,9 +58,11 @@ class App
App& operator=(const App&&) = delete;
template <typename Adaptor>
- void handleUpgrade(const Request& req, Response& res, Adaptor&& adaptor)
+ void handleUpgrade(const Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ Adaptor&& adaptor)
{
- router.handleUpgrade(req, res, std::forward<Adaptor>(adaptor));
+ router.handleUpgrade(req, asyncResp, std::forward<Adaptor>(adaptor));
}
void handle(Request& req,
diff --git a/http/http_connection.hpp b/http/http_connection.hpp
index c28cde37ae..d5d02e545a 100644
--- a/http/http_connection.hpp
+++ b/http/http_connection.hpp
@@ -249,10 +249,21 @@ class Connection :
thisReq.getHeaderValue(boost::beast::http::field::upgrade),
"websocket"))
{
- handler->handleUpgrade(thisReq, res, std::move(adaptor));
- // delete lambda with self shared_ptr
- // to enable connection destruction
- asyncResp->res.setCompleteRequestHandler(nullptr);
+ asyncResp->res.setCompleteRequestHandler(
+ [self(shared_from_this())](crow::Response& thisRes) {
+ if (thisRes.result() != boost::beast::http::status::ok)
+ {
+ // When any error occurs before handle upgradation,
+ // the result in response will be set to respective
+ // error. By default the Result will be OK (200),
+ // which implies successful handle upgrade. Response
+ // needs to be sent over this connection only on
+ // failure.
+ self->completeRequest(thisRes);
+ return;
+ }
+ });
+ handler->handleUpgrade(thisReq, asyncResp, std::move(adaptor));
return;
}
std::string_view expected =
diff --git a/http/routing.hpp b/http/routing.hpp
index 5ebc11fbf4..a85bd3ae59 100644
--- a/http/routing.hpp
+++ b/http/routing.hpp
@@ -55,19 +55,20 @@ class BaseRule
virtual void handle(const Request& /*req*/,
const std::shared_ptr<bmcweb::AsyncResp>&,
const RoutingParams&) = 0;
- virtual void handleUpgrade(const Request& /*req*/, Response& res,
- boost::asio::ip::tcp::socket&& /*adaptor*/)
+ virtual void
+ handleUpgrade(const Request& /*req*/,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ boost::asio::ip::tcp::socket&& /*adaptor*/)
{
- res.result(boost::beast::http::status::not_found);
- res.end();
+ asyncResp->res.result(boost::beast::http::status::not_found);
}
#ifdef BMCWEB_ENABLE_SSL
virtual void handleUpgrade(
- const Request& /*req*/, Response& res,
+ const Request& /*req*/,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
boost::beast::ssl_stream<boost::asio::ip::tcp::socket>&& /*adaptor*/)
{
- res.result(boost::beast::http::status::not_found);
- res.end();
+ asyncResp->res.result(boost::beast::http::status::not_found);
}
#endif
@@ -345,7 +346,8 @@ class WebSocketRule : public BaseRule
asyncResp->res.result(boost::beast::http::status::not_found);
}
- void handleUpgrade(const Request& req, Response& /*res*/,
+ void handleUpgrade(const Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& /*asyncResp*/,
boost::asio::ip::tcp::socket&& adaptor) override
{
BMCWEB_LOG_DEBUG << "Websocket handles upgrade";
@@ -358,7 +360,8 @@ class WebSocketRule : public BaseRule
myConnection->start();
}
#ifdef BMCWEB_ENABLE_SSL
- void handleUpgrade(const Request& req, Response& /*res*/,
+ void handleUpgrade(const Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& /*asyncResp*/,
boost::beast::ssl_stream<boost::asio::ip::tcp::socket>&&
adaptor) override
{
@@ -1239,13 +1242,14 @@ class Router
}
template <typename Adaptor>
- void handleUpgrade(const Request& req, Response& res, Adaptor&& adaptor)
+ void handleUpgrade(const Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ Adaptor&& adaptor)
{
std::optional<HttpVerb> verb = httpVerbFromBoost(req.method());
if (!verb || static_cast<size_t>(*verb) >= perMethods.size())
{
- res.result(boost::beast::http::status::not_found);
- res.end();
+ asyncResp->res.result(boost::beast::http::status::not_found);
return;
}
PerMethod& perMethod = perMethods[static_cast<size_t>(*verb)];
@@ -1259,8 +1263,7 @@ class Router
{
BMCWEB_LOG_DEBUG << "Cannot match rules "
<< req.url().encoded_path();
- res.result(boost::beast::http::status::not_found);
- res.end();
+ asyncResp->res.result(boost::beast::http::status::not_found);
return;
}
@@ -1277,8 +1280,7 @@ class Router
<< req.methodString() << "("
<< static_cast<uint32_t>(*verb) << ") / "
<< rules[ruleIndex]->getMethods();
- res.result(boost::beast::http::status::not_found);
- res.end();
+ asyncResp->res.result(boost::beast::http::status::not_found);
return;
}
@@ -1289,14 +1291,14 @@ class Router
// any uncaught exceptions become 500s
try
{
- rules[ruleIndex]->handleUpgrade(req, res,
+ rules[ruleIndex]->handleUpgrade(req, asyncResp,
std::forward<Adaptor>(adaptor));
}
catch (const std::exception& e)
{
BMCWEB_LOG_ERROR << "An uncaught exception occurred: " << e.what();
- res.result(boost::beast::http::status::internal_server_error);
- res.end();
+ asyncResp->res.result(
+ boost::beast::http::status::internal_server_error);
return;
}
catch (...)
@@ -1304,8 +1306,8 @@ class Router
BMCWEB_LOG_ERROR
<< "An uncaught exception occurred. The type was unknown "
"so no information was available.";
- res.result(boost::beast::http::status::internal_server_error);
- res.end();
+ asyncResp->res.result(
+ boost::beast::http::status::internal_server_error);
return;
}
}