summaryrefslogtreecommitdiff
path: root/http/routing.hpp
diff options
context:
space:
mode:
authorEd Tanous <edtanous@google.com>2022-08-01 08:08:26 +0300
committerEd Tanous <ed@tanous.net>2022-12-06 02:18:32 +0300
commit2c9efc3cb140e5c1d4d57b73f0a511880ac7a11f (patch)
tree41700c098e51c56cdc107df78c82b14b6d429b9f /http/routing.hpp
parentddfc67521c537c372d54bc662c74c6e6b73be1c9 (diff)
downloadbmcweb-2c9efc3cb140e5c1d4d57b73f0a511880ac7a11f.tar.xz
Make router take up less space for verbs
As is, the router designates routes for every possible boost verb, of which there are 31. In bmcweb, we only make use of 6 of those verbs, so that ends up being quite a bit of wasted space and cache non-locality. This commit invents a new enum class for declaring a subset of boost verbs that we support, and a mapping between bmcweb verbs and boost verbs. Then it walks through and updates the router to support converting one to another. Tested: Unit Tested Redfish Service Validator performed on future commit Signed-off-by: Ed Tanous <edtanous@google.com> Signed-off-by: Edward Lee <edwarddl@google.com> Change-Id: I3c89e896c632a5d4134dbd08a30b313c12a60de6
Diffstat (limited to 'http/routing.hpp')
-rw-r--r--http/routing.hpp45
1 files changed, 27 insertions, 18 deletions
diff --git a/http/routing.hpp b/http/routing.hpp
index 870a62c9ed..6c393ab33b 100644
--- a/http/routing.hpp
+++ b/http/routing.hpp
@@ -9,6 +9,7 @@
#include "privileges.hpp"
#include "sessions.hpp"
#include "utility.hpp"
+#include "verb.hpp"
#include "websocket.hpp"
#include <async_resp.hpp>
@@ -20,6 +21,7 @@
#include <cstdlib>
#include <limits>
#include <memory>
+#include <optional>
#include <tuple>
#include <utility>
#include <vector>
@@ -27,13 +29,7 @@
namespace crow
{
-// Note, this is an imperfect abstraction. There are a lot of verbs that we
-// use memory for, but are basically unused by most implementations.
-// Ideally we would have a list of verbs that we do use, and only index in
-// to a smaller array of those, but that would require a translation from
-// boost::beast::http::verb, to the bmcweb index.
-static constexpr size_t maxVerbIndex =
- static_cast<size_t>(boost::beast::http::verb::patch);
+static constexpr size_t maxVerbIndex = static_cast<size_t>(HttpVerb::Max) - 1U;
// MaxVerb + 1 is designated as the "not found" verb. It is done this way
// to keep the BaseRule as a single bitfield (thus keeping the struct small)
@@ -107,8 +103,7 @@ class BaseRule
return false;
}
- size_t methodsBitfield{
- 1 << static_cast<size_t>(boost::beast::http::verb::get)};
+ size_t methodsBitfield{1 << static_cast<size_t>(HttpVerb::Get)};
static_assert(std::numeric_limits<decltype(methodsBitfield)>::digits >
methodNotAllowedIndex,
"Not enough bits to store bitfield");
@@ -445,7 +440,11 @@ struct RuleParameterTraits
self_t& methods(boost::beast::http::verb method)
{
self_t* self = static_cast<self_t*>(this);
- self->methodsBitfield = 1U << static_cast<size_t>(method);
+ std::optional<HttpVerb> verb = httpVerbFromBoost(method);
+ if (verb)
+ {
+ self->methodsBitfield = 1U << static_cast<size_t>(*verb);
+ }
return *self;
}
@@ -454,7 +453,11 @@ struct RuleParameterTraits
{
self_t* self = static_cast<self_t*>(this);
methods(argsMethod...);
- self->methodsBitfield |= 1U << static_cast<size_t>(method);
+ std::optional<HttpVerb> verb = httpVerbFromBoost(method);
+ if (verb)
+ {
+ self->methodsBitfield |= 1U << static_cast<size_t>(*verb);
+ }
return *self;
}
@@ -1210,7 +1213,12 @@ class Router
{
FindRouteResponse findRoute;
- size_t reqMethodIndex = static_cast<size_t>(req.method());
+ std::optional<HttpVerb> verb = httpVerbFromBoost(req.method());
+ if (!verb)
+ {
+ return findRoute;
+ }
+ size_t reqMethodIndex = static_cast<size_t>(*verb);
// Check to see if this url exists at any verb
for (size_t perMethodIndex = 0; perMethodIndex <= maxVerbIndex;
perMethodIndex++)
@@ -1227,8 +1235,8 @@ class Router
{
findRoute.allowHeader += ", ";
}
- findRoute.allowHeader += boost::beast::http::to_string(
- static_cast<boost::beast::http::verb>(perMethodIndex));
+ HttpVerb thisVerb = static_cast<HttpVerb>(perMethodIndex);
+ findRoute.allowHeader += httpVerbToString(thisVerb);
if (perMethodIndex == reqMethodIndex)
{
findRoute.route = route;
@@ -1240,14 +1248,14 @@ class Router
template <typename Adaptor>
void handleUpgrade(const Request& req, Response& res, Adaptor&& adaptor)
{
- if (static_cast<size_t>(req.method()) >= perMethods.size())
+ 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();
return;
}
-
- PerMethod& perMethod = perMethods[static_cast<size_t>(req.method())];
+ PerMethod& perMethod = perMethods[static_cast<size_t>(*verb)];
Trie& trie = perMethod.trie;
std::vector<BaseRule*>& rules = perMethod.rules;
@@ -1309,7 +1317,8 @@ class Router
void handle(Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
- if (static_cast<size_t>(req.method()) >= perMethods.size())
+ std::optional<HttpVerb> verb = httpVerbFromBoost(req.method());
+ if (!verb || static_cast<size_t>(*verb) >= perMethods.size())
{
asyncResp->res.result(boost::beast::http::status::not_found);
return;