Break up router into separate files

The router is a giant behemoth.  Start breaking it down into pieces.

Tested: Redfish service validator passes.

Signed-off-by: Ed Tanous <edtanous@google.com>
Change-Id: I9d04f53a58ffce3ecbd88dded1aa6e9648d2a762
diff --git a/http/routing/baserule.hpp b/http/routing/baserule.hpp
new file mode 100644
index 0000000..0913020
--- /dev/null
+++ b/http/routing/baserule.hpp
@@ -0,0 +1,98 @@
+#pragma once
+
+#include "async_resp.hpp"
+#include "http_request.hpp"
+#include "privileges.hpp"
+#include "verb.hpp"
+
+#include <boost/beast/ssl/ssl_stream.hpp>
+
+#include <memory>
+#include <string>
+
+namespace crow
+{
+class BaseRule
+{
+  public:
+    explicit BaseRule(const std::string& thisRule) : rule(thisRule) {}
+
+    virtual ~BaseRule() = default;
+
+    BaseRule(const BaseRule&) = delete;
+    BaseRule(BaseRule&&) = delete;
+    BaseRule& operator=(const BaseRule&) = delete;
+    BaseRule& operator=(const BaseRule&&) = delete;
+
+    virtual void validate() = 0;
+    std::unique_ptr<BaseRule> upgrade()
+    {
+        if (ruleToUpgrade)
+        {
+            return std::move(ruleToUpgrade);
+        }
+        return {};
+    }
+
+    virtual void handle(const Request& /*req*/,
+                        const std::shared_ptr<bmcweb::AsyncResp>&,
+                        const std::vector<std::string>&) = 0;
+#ifndef BMCWEB_ENABLE_SSL
+    virtual void
+        handleUpgrade(const Request& /*req*/,
+                      const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                      boost::asio::ip::tcp::socket&& /*adaptor*/)
+    {
+        asyncResp->res.result(boost::beast::http::status::not_found);
+    }
+#else
+    virtual void handleUpgrade(
+        const Request& /*req*/,
+        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+        boost::beast::ssl_stream<boost::asio::ip::tcp::socket>&& /*adaptor*/)
+    {
+        asyncResp->res.result(boost::beast::http::status::not_found);
+    }
+#endif
+
+    size_t getMethods() const
+    {
+        return methodsBitfield;
+    }
+
+    bool checkPrivileges(const redfish::Privileges& userPrivileges)
+    {
+        // If there are no privileges assigned, assume no privileges
+        // required
+        if (privilegesSet.empty())
+        {
+            return true;
+        }
+
+        for (const redfish::Privileges& requiredPrivileges : privilegesSet)
+        {
+            if (userPrivileges.isSupersetOf(requiredPrivileges))
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    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");
+
+    std::vector<redfish::Privileges> privilegesSet;
+
+    std::string rule;
+
+    std::unique_ptr<BaseRule> ruleToUpgrade;
+
+    friend class Router;
+    template <typename T>
+    friend struct RuleParameterTraits;
+};
+
+} // namespace crow