diff --git a/http/LICENSE b/http/LICENSE
new file mode 100644
index 0000000..7295908
--- /dev/null
+++ b/http/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2014, ipkn
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+  this list of conditions and the following disclaimer in the documentation
+  and/or other materials provided with the distribution.
+
+* Neither the name of the author nor the names of its
+  contributors may be used to endorse or promote products derived from
+  this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/http/app.h b/http/app.h
new file mode 100644
index 0000000..fd01340
--- /dev/null
+++ b/http/app.h
@@ -0,0 +1,263 @@
+#pragma once
+
+#include "privileges.hpp"
+
+#include <chrono>
+#include <cstdint>
+#include <functional>
+#include <future>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "http_request.h"
+#include "http_server.h"
+#include "logging.h"
+#include "middleware_context.h"
+#include "routing.h"
+#include "utility.h"
+
+#define BMCWEB_ROUTE(app, url)                                                 \
+    app.template route<crow::black_magic::get_parameter_tag(url)>(url)
+
+namespace crow
+{
+#ifdef BMCWEB_ENABLE_SSL
+using ssl_context_t = boost::asio::ssl::context;
+#endif
+template <typename... Middlewares> class Crow
+{
+  public:
+    using self_t = Crow;
+
+#ifdef BMCWEB_ENABLE_SSL
+    using ssl_socket_t = boost::beast::ssl_stream<boost::asio::ip::tcp::socket>;
+    using ssl_server_t = Server<Crow, ssl_socket_t, Middlewares...>;
+#else
+    using socket_t = boost::asio::ip::tcp::socket;
+    using server_t = Server<Crow, socket_t, Middlewares...>;
+#endif
+
+    explicit Crow(std::shared_ptr<boost::asio::io_context> ioIn =
+                      std::make_shared<boost::asio::io_context>()) :
+        io(std::move(ioIn))
+    {
+    }
+    ~Crow()
+    {
+        this->stop();
+    }
+
+    template <typename Adaptor>
+    void handleUpgrade(const Request& req, Response& res, Adaptor&& adaptor)
+    {
+        router.handleUpgrade(req, res, std::move(adaptor));
+    }
+
+    void handle(const Request& req, Response& res)
+    {
+        router.handle(req, res);
+    }
+
+    DynamicRule& routeDynamic(std::string&& rule)
+    {
+        return router.newRuleDynamic(rule);
+    }
+
+    template <uint64_t Tag> auto& route(std::string&& rule)
+    {
+        return router.newRuleTagged<Tag>(std::move(rule));
+    }
+
+    self_t& socket(int existing_socket)
+    {
+        socketFd = existing_socket;
+        return *this;
+    }
+
+    self_t& port(std::uint16_t port)
+    {
+        portUint = port;
+        return *this;
+    }
+
+    self_t& bindaddr(std::string bindaddr)
+    {
+        bindaddrStr = bindaddr;
+        return *this;
+    }
+
+    void validate()
+    {
+        router.validate();
+    }
+
+    void run()
+    {
+        validate();
+#ifdef BMCWEB_ENABLE_SSL
+        if (-1 == socketFd)
+        {
+            sslServer = std::move(std::make_unique<ssl_server_t>(
+                this, bindaddrStr, portUint, sslContext, &middlewares, io));
+        }
+        else
+        {
+            sslServer = std::move(std::make_unique<ssl_server_t>(
+                this, socketFd, sslContext, &middlewares, io));
+        }
+        sslServer->setTickFunction(tickInterval, tickFunction);
+        sslServer->run();
+
+#else
+
+        if (-1 == socketFd)
+        {
+            server = std::move(std::make_unique<server_t>(
+                this, bindaddrStr, portUint, nullptr, &middlewares, io));
+        }
+        else
+        {
+            server = std::move(std::make_unique<server_t>(
+                this, socketFd, nullptr, &middlewares, io));
+        }
+        server->setTickFunction(tickInterval, tickFunction);
+        server->run();
+
+#endif
+    }
+
+    void stop()
+    {
+        io->stop();
+    }
+
+    void debugPrint()
+    {
+        BMCWEB_LOG_DEBUG << "Routing:";
+        router.debugPrint();
+    }
+
+    std::vector<const std::string*> getRoutes()
+    {
+        // TODO(ed) Should this be /?
+        const std::string root("");
+        return router.getRoutes(root);
+    }
+    std::vector<const std::string*> getRoutes(const std::string& parent)
+    {
+        return router.getRoutes(parent);
+    }
+
+#ifdef BMCWEB_ENABLE_SSL
+    self_t& sslFile(const std::string& crt_filename,
+                    const std::string& key_filename)
+    {
+        sslContext = std::make_shared<ssl_context_t>(
+            boost::asio::ssl::context::tls_server);
+        sslContext->set_verify_mode(boost::asio::ssl::verify_peer);
+        sslContext->use_certificate_file(crt_filename, ssl_context_t::pem);
+        sslContext->use_private_key_file(key_filename, ssl_context_t::pem);
+        sslContext->set_options(boost::asio::ssl::context::default_workarounds |
+                                boost::asio::ssl::context::no_sslv2 |
+                                boost::asio::ssl::context::no_sslv3 |
+                                boost::asio::ssl::context::no_tlsv1 |
+                                boost::asio::ssl::context::no_tlsv1_1);
+        return *this;
+    }
+
+    self_t& sslFile(const std::string& pem_filename)
+    {
+        sslContext = std::make_shared<ssl_context_t>(
+            boost::asio::ssl::context::tls_server);
+        sslContext->set_verify_mode(boost::asio::ssl::verify_peer);
+        sslContext->load_verify_file(pem_filename);
+        sslContext->set_options(boost::asio::ssl::context::default_workarounds |
+                                boost::asio::ssl::context::no_sslv2 |
+                                boost::asio::ssl::context::no_sslv3 |
+                                boost::asio::ssl::context::no_tlsv1 |
+                                boost::asio::ssl::context::no_tlsv1_1);
+        return *this;
+    }
+
+    self_t& ssl(std::shared_ptr<boost::asio::ssl::context>&& ctx)
+    {
+        sslContext = std::move(ctx);
+        BMCWEB_LOG_INFO << "app::ssl context use_count="
+                        << sslContext.use_count();
+        return *this;
+    }
+
+    std::shared_ptr<ssl_context_t> sslContext = nullptr;
+
+#else
+    template <typename T, typename... Remain> self_t& ssl_file(T&&, Remain&&...)
+    {
+        // We can't call .ssl() member function unless BMCWEB_ENABLE_SSL is
+        // defined.
+        static_assert(
+            // make static_assert dependent to T; always false
+            std::is_base_of<T, void>::value,
+            "Define BMCWEB_ENABLE_SSL to enable ssl support.");
+        return *this;
+    }
+
+    template <typename T> self_t& ssl(T&&)
+    {
+        // We can't call .ssl() member function unless BMCWEB_ENABLE_SSL is
+        // defined.
+        static_assert(
+            // make static_assert dependent to T; always false
+            std::is_base_of<T, void>::value,
+            "Define BMCWEB_ENABLE_SSL to enable ssl support.");
+        return *this;
+    }
+#endif
+
+    // middleware
+    using context_t = detail::Context<Middlewares...>;
+    template <typename T> typename T::Context& getContext(const Request& req)
+    {
+        static_assert(black_magic::Contains<T, Middlewares...>::value,
+                      "App doesn't have the specified middleware type.");
+        auto& ctx = *reinterpret_cast<context_t*>(req.middlewareContext);
+        return ctx.template get<T>();
+    }
+
+    template <typename T> T& getMiddleware()
+    {
+        return utility::getElementByType<T, Middlewares...>(middlewares);
+    }
+
+    template <typename Duration, typename Func> self_t& tick(Duration d, Func f)
+    {
+        tickInterval = std::chrono::duration_cast<std::chrono::milliseconds>(d);
+        tickFunction = f;
+        return *this;
+    }
+
+  private:
+    std::shared_ptr<asio::io_context> io;
+#ifdef BMCWEB_ENABLE_SSL
+    uint16_t portUint = 443;
+#else
+    uint16_t portUint = 80;
+#endif
+    std::string bindaddrStr = "::";
+    int socketFd = -1;
+    Router router;
+
+    std::chrono::milliseconds tickInterval{};
+    std::function<void()> tickFunction;
+
+    std::tuple<Middlewares...> middlewares;
+
+#ifdef BMCWEB_ENABLE_SSL
+    std::unique_ptr<ssl_server_t> sslServer;
+#else
+    std::unique_ptr<server_t> server;
+#endif
+};
+template <typename... Middlewares> using App = Crow<Middlewares...>;
+using SimpleApp = Crow<>;
+} // namespace crow
diff --git a/http/common.h b/http/common.h
new file mode 100644
index 0000000..77c2074
--- /dev/null
+++ b/http/common.h
@@ -0,0 +1,128 @@
+#pragma once
+
+#include <boost/beast/http/verb.hpp>
+#include <iostream>
+#include <stdexcept>
+#include <string>
+#include <vector>
+
+#include "utility.h"
+
+namespace crow
+{
+
+inline std::string methodName(boost::beast::http::verb method)
+{
+    switch (method)
+    {
+        case boost::beast::http::verb::delete_:
+            return "DELETE";
+        case boost::beast::http::verb::get:
+            return "GET";
+        case boost::beast::http::verb::head:
+            return "HEAD";
+        case boost::beast::http::verb::post:
+            return "POST";
+        case boost::beast::http::verb::put:
+            return "PUT";
+        case boost::beast::http::verb::connect:
+            return "CONNECT";
+        case boost::beast::http::verb::options:
+            return "OPTIONS";
+        case boost::beast::http::verb::trace:
+            return "TRACE";
+        case boost::beast::http::verb::patch:
+            return "PATCH";
+        default:
+            return "invalid";
+    }
+}
+
+enum class ParamType
+{
+    INT,
+    UINT,
+    DOUBLE,
+    STRING,
+    PATH,
+
+    MAX
+};
+
+struct RoutingParams
+{
+    std::vector<int64_t> intParams;
+    std::vector<uint64_t> uintParams;
+    std::vector<double> doubleParams;
+    std::vector<std::string> stringParams;
+
+    void debugPrint() const
+    {
+        std::cerr << "RoutingParams" << std::endl;
+        for (auto i : intParams)
+        {
+            std::cerr << i << ", ";
+        }
+        std::cerr << std::endl;
+        for (auto i : uintParams)
+        {
+            std::cerr << i << ", ";
+        }
+        std::cerr << std::endl;
+        for (auto i : doubleParams)
+        {
+            std::cerr << i << ", ";
+        }
+        std::cerr << std::endl;
+        for (auto& i : stringParams)
+        {
+            std::cerr << i << ", ";
+        }
+        std::cerr << std::endl;
+    }
+
+    template <typename T> T get(unsigned) const;
+};
+
+template <> inline int64_t RoutingParams::get<int64_t>(unsigned index) const
+{
+    return intParams[index];
+}
+
+template <> inline uint64_t RoutingParams::get<uint64_t>(unsigned index) const
+{
+    return uintParams[index];
+}
+
+template <> inline double RoutingParams::get<double>(unsigned index) const
+{
+    return doubleParams[index];
+}
+
+template <>
+inline std::string RoutingParams::get<std::string>(unsigned index) const
+{
+    return stringParams[index];
+}
+
+} // namespace crow
+
+constexpr boost::beast::http::verb operator"" _method(const char* str,
+                                                      size_t /*len*/)
+{
+    using verb = boost::beast::http::verb;
+    // clang-format off
+  return
+    crow::black_magic::isEquP(str, "GET", 3) ? verb::get :
+    crow::black_magic::isEquP(str, "DELETE", 6) ? verb::delete_ :
+    crow::black_magic::isEquP(str, "HEAD", 4) ? verb::head :
+    crow::black_magic::isEquP(str, "POST", 4) ? verb::post :
+    crow::black_magic::isEquP(str, "PUT", 3) ? verb::put :
+    crow::black_magic::isEquP(str, "OPTIONS", 7) ? verb::options :
+    crow::black_magic::isEquP(str, "CONNECT", 7) ? verb::connect :
+    crow::black_magic::isEquP(str, "TRACE", 5) ? verb::trace :
+    crow::black_magic::isEquP(str, "PATCH", 5) ? verb::patch :
+    crow::black_magic::isEquP(str, "PURGE", 5) ? verb::purge :
+    throw std::runtime_error("invalid http method");
+    // clang-format on
+}
diff --git a/http/http_connection.h b/http/http_connection.h
new file mode 100644
index 0000000..ef42f84
--- /dev/null
+++ b/http/http_connection.h
@@ -0,0 +1,671 @@
+#pragma once
+#include "http_utility.hpp"
+
+#include <atomic>
+#include <boost/algorithm/string.hpp>
+#include <boost/algorithm/string/predicate.hpp>
+#include <boost/asio/io_context.hpp>
+#include <boost/asio/ip/tcp.hpp>
+#include <boost/asio/ssl.hpp>
+#include <boost/beast/core/flat_static_buffer.hpp>
+#if BOOST_VERSION >= 107000
+#include <boost/beast/ssl/ssl_stream.hpp>
+#else
+#include <boost/beast/experimental/core/ssl_stream.hpp>
+#endif
+#include <boost/beast/http.hpp>
+#include <boost/beast/websocket.hpp>
+#include <chrono>
+#include <vector>
+
+#include "http_response.h"
+#include "logging.h"
+#include "middleware_context.h"
+#include "timer_queue.h"
+#include "utility.h"
+
+namespace crow
+{
+
+inline void prettyPrintJson(crow::Response& res)
+{
+    std::string value = res.jsonValue.dump(4, ' ', true);
+    utility::escapeHtml(value);
+    utility::convertToLinks(value);
+    res.body() = "<html>\n"
+                 "<head>\n"
+                 "<title>Redfish API</title>\n"
+                 "<link rel=\"stylesheet\" type=\"text/css\" "
+                 "href=\"/styles/default.css\">\n"
+                 "<script src=\"/highlight.pack.js\"></script>"
+                 "<script>hljs.initHighlightingOnLoad();</script>"
+                 "</head>\n"
+                 "<body>\n"
+                 "<div style=\"max-width: 576px;margin:0 auto;\">\n"
+                 "<img src=\"/DMTF_Redfish_logo_2017.svg\" alt=\"redfish\" "
+                 "height=\"406px\" "
+                 "width=\"576px\">\n"
+                 "<br>\n"
+                 "<pre>\n"
+                 "<code class=\"json\">" +
+                 value +
+                 "</code>\n"
+                 "</pre>\n"
+                 "</div>\n"
+                 "</body>\n"
+                 "</html>\n";
+    res.addHeader("Content-Type", "text/html;charset=UTF-8");
+}
+
+using namespace boost;
+using tcp = asio::ip::tcp;
+
+namespace detail
+{
+template <typename MW> struct CheckBeforeHandleArity3Const
+{
+    template <typename T,
+              void (T::*)(Request&, Response&, typename MW::Context&) const =
+                  &T::beforeHandle>
+    struct Get
+    {
+    };
+};
+
+template <typename MW> struct CheckBeforeHandleArity3
+{
+    template <typename T, void (T::*)(Request&, Response&,
+                                      typename MW::Context&) = &T::beforeHandle>
+    struct Get
+    {
+    };
+};
+
+template <typename MW> struct CheckAfterHandleArity3Const
+{
+    template <typename T,
+              void (T::*)(Request&, Response&, typename MW::Context&) const =
+                  &T::afterHandle>
+    struct Get
+    {
+    };
+};
+
+template <typename MW> struct CheckAfterHandleArity3
+{
+    template <typename T, void (T::*)(Request&, Response&,
+                                      typename MW::Context&) = &T::afterHandle>
+    struct Get
+    {
+    };
+};
+
+template <typename T> struct IsBeforeHandleArity3Impl
+{
+    template <typename C>
+    static std::true_type
+        f(typename CheckBeforeHandleArity3Const<T>::template Get<C>*);
+
+    template <typename C>
+    static std::true_type
+        f(typename CheckBeforeHandleArity3<T>::template Get<C>*);
+
+    template <typename C> static std::false_type f(...);
+
+  public:
+    static const bool value = decltype(f<T>(nullptr))::value;
+};
+
+template <typename T> struct IsAfterHandleArity3Impl
+{
+    template <typename C>
+    static std::true_type
+        f(typename CheckAfterHandleArity3Const<T>::template Get<C>*);
+
+    template <typename C>
+    static std::true_type
+        f(typename CheckAfterHandleArity3<T>::template Get<C>*);
+
+    template <typename C> static std::false_type f(...);
+
+  public:
+    static const bool value = decltype(f<T>(nullptr))::value;
+};
+
+template <typename MW, typename Context, typename ParentContext>
+typename std::enable_if<!IsBeforeHandleArity3Impl<MW>::value>::type
+    beforeHandlerCall(MW& mw, Request& req, Response& res, Context& ctx,
+                      ParentContext& /*parent_ctx*/)
+{
+    mw.beforeHandle(req, res, ctx.template get<MW>(), ctx);
+}
+
+template <typename MW, typename Context, typename ParentContext>
+typename std::enable_if<IsBeforeHandleArity3Impl<MW>::value>::type
+    beforeHandlerCall(MW& mw, Request& req, Response& res, Context& ctx,
+                      ParentContext& /*parent_ctx*/)
+{
+    mw.beforeHandle(req, res, ctx.template get<MW>());
+}
+
+template <typename MW, typename Context, typename ParentContext>
+typename std::enable_if<!IsAfterHandleArity3Impl<MW>::value>::type
+    afterHandlerCall(MW& mw, Request& req, Response& res, Context& ctx,
+                     ParentContext& /*parent_ctx*/)
+{
+    mw.afterHandle(req, res, ctx.template get<MW>(), ctx);
+}
+
+template <typename MW, typename Context, typename ParentContext>
+typename std::enable_if<IsAfterHandleArity3Impl<MW>::value>::type
+    afterHandlerCall(MW& mw, Request& req, Response& res, Context& ctx,
+                     ParentContext& /*parent_ctx*/)
+{
+    mw.afterHandle(req, res, ctx.template get<MW>());
+}
+
+template <size_t N, typename Context, typename Container, typename CurrentMW,
+          typename... Middlewares>
+bool middlewareCallHelper(Container& middlewares, Request& req, Response& res,
+                          Context& ctx)
+{
+    using parent_context_t = typename Context::template partial<N - 1>;
+    beforeHandlerCall<CurrentMW, Context, parent_context_t>(
+        std::get<N>(middlewares), req, res, ctx,
+        static_cast<parent_context_t&>(ctx));
+
+    if (res.isCompleted())
+    {
+        afterHandlerCall<CurrentMW, Context, parent_context_t>(
+            std::get<N>(middlewares), req, res, ctx,
+            static_cast<parent_context_t&>(ctx));
+        return true;
+    }
+
+    if (middlewareCallHelper<N + 1, Context, Container, Middlewares...>(
+            middlewares, req, res, ctx))
+    {
+        afterHandlerCall<CurrentMW, Context, parent_context_t>(
+            std::get<N>(middlewares), req, res, ctx,
+            static_cast<parent_context_t&>(ctx));
+        return true;
+    }
+
+    return false;
+}
+
+template <size_t N, typename Context, typename Container>
+bool middlewareCallHelper(Container& /*middlewares*/, Request& /*req*/,
+                          Response& /*res*/, Context& /*ctx*/)
+{
+    return false;
+}
+
+template <size_t N, typename Context, typename Container>
+typename std::enable_if<(N < 0)>::type
+    afterHandlersCallHelper(Container& /*middlewares*/, Context& /*Context*/,
+                            Request& /*req*/, Response& /*res*/)
+{
+}
+
+template <size_t N, typename Context, typename Container>
+typename std::enable_if<(N == 0)>::type
+    afterHandlersCallHelper(Container& middlewares, Context& ctx, Request& req,
+                            Response& res)
+{
+    using parent_context_t = typename Context::template partial<N - 1>;
+    using CurrentMW = typename std::tuple_element<
+        N, typename std::remove_reference<Container>::type>::type;
+    afterHandlerCall<CurrentMW, Context, parent_context_t>(
+        std::get<N>(middlewares), req, res, ctx,
+        static_cast<parent_context_t&>(ctx));
+}
+
+template <size_t N, typename Context, typename Container>
+typename std::enable_if<(N > 0)>::type
+    afterHandlersCallHelper(Container& middlewares, Context& ctx, Request& req,
+                            Response& res)
+{
+    using parent_context_t = typename Context::template partial<N - 1>;
+    using CurrentMW = typename std::tuple_element<
+        N, typename std::remove_reference<Container>::type>::type;
+    afterHandlerCall<CurrentMW, Context, parent_context_t>(
+        std::get<N>(middlewares), req, res, ctx,
+        static_cast<parent_context_t&>(ctx));
+    afterHandlersCallHelper<N - 1, Context, Container>(middlewares, ctx, req,
+                                                       res);
+}
+} // namespace detail
+
+#ifdef BMCWEB_ENABLE_DEBUG
+static std::atomic<int> connectionCount;
+#endif
+
+// request body limit size: 30M
+constexpr unsigned int httpReqBodyLimit = 1024 * 1024 * 30;
+
+template <typename Adaptor, typename Handler, typename... Middlewares>
+class Connection
+{
+  public:
+    Connection(boost::asio::io_context& ioService, Handler* handlerIn,
+               const std::string& ServerNameIn,
+               std::tuple<Middlewares...>* middlewaresIn,
+               std::function<std::string()>& get_cached_date_str_f,
+               detail::TimerQueue& timerQueueIn, Adaptor adaptorIn) :
+        adaptor(std::move(adaptorIn)),
+        handler(handlerIn), serverName(ServerNameIn),
+        middlewares(middlewaresIn), getCachedDateStr(get_cached_date_str_f),
+        timerQueue(timerQueueIn)
+    {
+        parser.emplace(std::piecewise_construct, std::make_tuple());
+        // Temporarily changed to 30MB; Need to modify uploading/authentication
+        // mechanism
+        parser->body_limit(httpReqBodyLimit);
+        req.emplace(parser->get());
+#ifdef BMCWEB_ENABLE_DEBUG
+        connectionCount++;
+        BMCWEB_LOG_DEBUG << this << " Connection open, total "
+                         << connectionCount;
+#endif
+    }
+
+    ~Connection()
+    {
+        res.completeRequestHandler = nullptr;
+        cancelDeadlineTimer();
+#ifdef BMCWEB_ENABLE_DEBUG
+        connectionCount--;
+        BMCWEB_LOG_DEBUG << this << " Connection closed, total "
+                         << connectionCount;
+#endif
+    }
+
+    Adaptor& socket()
+    {
+        return adaptor;
+    }
+
+    void start()
+    {
+
+        startDeadline();
+        // TODO(ed) Abstract this to a more clever class with the idea of an
+        // asynchronous "start"
+        if constexpr (std::is_same_v<Adaptor,
+                                     boost::beast::ssl_stream<
+                                         boost::asio::ip::tcp::socket>>)
+        {
+            adaptor.async_handshake(
+                boost::asio::ssl::stream_base::server,
+                [this](const boost::system::error_code& ec) {
+                    if (ec)
+                    {
+                        checkDestroy();
+                        return;
+                    }
+                    doReadHeaders();
+                });
+        }
+        else
+        {
+            doReadHeaders();
+        }
+    }
+
+    void handle()
+    {
+        cancelDeadlineTimer();
+        bool isInvalidRequest = false;
+
+        // Check for HTTP version 1.1.
+        if (req->version() == 11)
+        {
+            if (req->getHeaderValue(boost::beast::http::field::host).empty())
+            {
+                isInvalidRequest = true;
+                res.result(boost::beast::http::status::bad_request);
+            }
+        }
+
+        BMCWEB_LOG_INFO << "Request: "
+                        << " " << this << " HTTP/" << req->version() / 10 << "."
+                        << req->version() % 10 << ' ' << req->methodString()
+                        << " " << req->target();
+
+        needToCallAfterHandlers = false;
+
+        if (!isInvalidRequest)
+        {
+            res.completeRequestHandler = [] {};
+            res.isAliveHelper = [this]() -> bool { return isAlive(); };
+
+            ctx = detail::Context<Middlewares...>();
+            req->middlewareContext = static_cast<void*>(&ctx);
+            req->ioService = static_cast<decltype(req->ioService)>(
+                &adaptor.get_executor().context());
+            detail::middlewareCallHelper<
+                0U, decltype(ctx), decltype(*middlewares), Middlewares...>(
+                *middlewares, *req, res, ctx);
+
+            if (!res.completed)
+            {
+                if (req->isUpgrade() &&
+                    boost::iequals(
+                        req->getHeaderValue(boost::beast::http::field::upgrade),
+                        "websocket"))
+                {
+                    handler->handleUpgrade(*req, res, std::move(adaptor));
+                    return;
+                }
+                res.completeRequestHandler = [this] {
+                    this->completeRequest();
+                };
+                needToCallAfterHandlers = true;
+                handler->handle(*req, res);
+            }
+            else
+            {
+                completeRequest();
+            }
+        }
+        else
+        {
+            completeRequest();
+        }
+    }
+
+    bool isAlive()
+    {
+
+        if constexpr (std::is_same_v<Adaptor,
+                                     boost::beast::ssl_stream<
+                                         boost::asio::ip::tcp::socket>>)
+        {
+            return adaptor.next_layer().is_open();
+        }
+        else
+        {
+            return adaptor.is_open();
+        }
+    }
+    void close()
+    {
+
+        if constexpr (std::is_same_v<Adaptor,
+                                     boost::beast::ssl_stream<
+                                         boost::asio::ip::tcp::socket>>)
+        {
+            adaptor.next_layer().close();
+        }
+        else
+        {
+            adaptor.close();
+        }
+    }
+
+    void completeRequest()
+    {
+        BMCWEB_LOG_INFO << "Response: " << this << ' ' << req->url << ' '
+                        << res.resultInt() << " keepalive=" << req->keepAlive();
+
+        if (needToCallAfterHandlers)
+        {
+            needToCallAfterHandlers = false;
+
+            // call all afterHandler of middlewares
+            detail::afterHandlersCallHelper<sizeof...(Middlewares) - 1,
+                                            decltype(ctx),
+                                            decltype(*middlewares)>(
+                *middlewares, ctx, *req, res);
+        }
+
+        // auto self = this->shared_from_this();
+        res.completeRequestHandler = res.completeRequestHandler = [] {};
+
+        if (!isAlive())
+        {
+            // BMCWEB_LOG_DEBUG << this << " delete (socket is closed) " <<
+            // isReading
+            // << ' ' << isWriting;
+            // delete this;
+            return;
+        }
+        if (res.body().empty() && !res.jsonValue.empty())
+        {
+            if (http_helpers::requestPrefersHtml(*req))
+            {
+                prettyPrintJson(res);
+            }
+            else
+            {
+                res.jsonMode();
+                res.body() = res.jsonValue.dump(2, ' ', true);
+            }
+        }
+
+        if (res.resultInt() >= 400 && res.body().empty())
+        {
+            res.body() = std::string(res.reason());
+        }
+
+        if (res.result() == boost::beast::http::status::no_content)
+        {
+            // Boost beast throws if content is provided on a no-content
+            // response.  Ideally, this would never happen, but in the case that
+            // it does, we don't want to throw.
+            BMCWEB_LOG_CRITICAL
+                << "Response content provided but code was no-content";
+            res.body().clear();
+        }
+
+        res.addHeader(boost::beast::http::field::server, serverName);
+        res.addHeader(boost::beast::http::field::date, getCachedDateStr());
+
+        res.keepAlive(req->keepAlive());
+
+        doWrite();
+    }
+
+  private:
+    void doReadHeaders()
+    {
+        // auto self = this->shared_from_this();
+        isReading = true;
+        BMCWEB_LOG_DEBUG << this << " doReadHeaders";
+
+        // Clean up any previous Connection.
+        boost::beast::http::async_read_header(
+            adaptor, buffer, *parser,
+            [this](const boost::system::error_code& ec,
+                   std::size_t bytes_transferred) {
+                isReading = false;
+                BMCWEB_LOG_ERROR << this << " async_read_header "
+                                 << bytes_transferred << " Bytes";
+                bool errorWhileReading = false;
+                if (ec)
+                {
+                    errorWhileReading = true;
+                    BMCWEB_LOG_ERROR
+                        << this << " Error while reading: " << ec.message();
+                }
+                else
+                {
+                    // if the adaptor isn't open anymore, and wasn't handed to a
+                    // websocket, treat as an error
+                    if (!isAlive() && !req->isUpgrade())
+                    {
+                        errorWhileReading = true;
+                    }
+                }
+
+                if (errorWhileReading)
+                {
+                    cancelDeadlineTimer();
+                    close();
+                    BMCWEB_LOG_DEBUG << this << " from read(1)";
+                    checkDestroy();
+                    return;
+                }
+
+                // Compute the url parameters for the request
+                req->url = req->target();
+                std::size_t index = req->url.find("?");
+                if (index != std::string_view::npos)
+                {
+                    req->url = req->url.substr(0, index);
+                }
+                req->urlParams = QueryString(std::string(req->target()));
+                doRead();
+            });
+    }
+
+    void doRead()
+    {
+        // auto self = this->shared_from_this();
+        isReading = true;
+        BMCWEB_LOG_DEBUG << this << " doRead";
+
+        boost::beast::http::async_read(
+            adaptor, buffer, *parser,
+            [this](const boost::system::error_code& ec,
+                   std::size_t bytes_transferred) {
+                BMCWEB_LOG_ERROR << this << " async_read " << bytes_transferred
+                                 << " Bytes";
+                isReading = false;
+
+                bool errorWhileReading = false;
+                if (ec)
+                {
+                    BMCWEB_LOG_ERROR << "Error while reading: " << ec.message();
+                    errorWhileReading = true;
+                }
+                else
+                {
+                    if (!isAlive())
+                    {
+                        errorWhileReading = true;
+                    }
+                }
+                if (errorWhileReading)
+                {
+                    cancelDeadlineTimer();
+                    close();
+                    BMCWEB_LOG_DEBUG << this << " from read(1)";
+                    checkDestroy();
+                    return;
+                }
+                handle();
+            });
+    }
+
+    void doWrite()
+    {
+        // auto self = this->shared_from_this();
+        isWriting = true;
+        BMCWEB_LOG_DEBUG << "Doing Write";
+        res.preparePayload();
+        serializer.emplace(*res.stringResponse);
+        boost::beast::http::async_write(
+            adaptor, *serializer,
+            [&](const boost::system::error_code& ec,
+                std::size_t bytes_transferred) {
+                isWriting = false;
+                BMCWEB_LOG_DEBUG << this << " Wrote " << bytes_transferred
+                                 << " bytes";
+
+                if (ec)
+                {
+                    BMCWEB_LOG_DEBUG << this << " from write(2)";
+                    checkDestroy();
+                    return;
+                }
+                if (!res.keepAlive())
+                {
+                    close();
+                    BMCWEB_LOG_DEBUG << this << " from write(1)";
+                    checkDestroy();
+                    return;
+                }
+
+                serializer.reset();
+                BMCWEB_LOG_DEBUG << this << " Clearing response";
+                res.clear();
+                parser.emplace(std::piecewise_construct, std::make_tuple());
+                parser->body_limit(httpReqBodyLimit); // reset body limit for
+                                                      // newly created parser
+                buffer.consume(buffer.size());
+
+                req.emplace(parser->get());
+                doReadHeaders();
+            });
+    }
+
+    void checkDestroy()
+    {
+        BMCWEB_LOG_DEBUG << this << " isReading " << isReading << " isWriting "
+                         << isWriting;
+        if (!isReading && !isWriting)
+        {
+            BMCWEB_LOG_DEBUG << this << " delete (idle) ";
+            delete this;
+        }
+    }
+
+    void cancelDeadlineTimer()
+    {
+        BMCWEB_LOG_DEBUG << this << " timer cancelled: " << &timerQueue << ' '
+                         << timerCancelKey;
+        timerQueue.cancel(timerCancelKey);
+    }
+
+    void startDeadline()
+    {
+        cancelDeadlineTimer();
+
+        timerCancelKey = timerQueue.add([this] {
+            if (!isAlive())
+            {
+                return;
+            }
+            close();
+        });
+        BMCWEB_LOG_DEBUG << this << " timer added: " << &timerQueue << ' '
+                         << timerCancelKey;
+    }
+
+  private:
+    Adaptor adaptor;
+    Handler* handler;
+
+    // Making this a std::optional allows it to be efficiently destroyed and
+    // re-created on Connection reset
+    std::optional<
+        boost::beast::http::request_parser<boost::beast::http::string_body>>
+        parser;
+
+    boost::beast::flat_static_buffer<8192> buffer;
+
+    std::optional<boost::beast::http::response_serializer<
+        boost::beast::http::string_body>>
+        serializer;
+
+    std::optional<crow::Request> req;
+    crow::Response res;
+
+    const std::string& serverName;
+
+    size_t timerCancelKey = 0;
+
+    bool isReading{};
+    bool isWriting{};
+    bool needToCallAfterHandlers{};
+    bool needToStartReadAfterComplete{};
+
+    std::tuple<Middlewares...>* middlewares;
+    detail::Context<Middlewares...> ctx;
+
+    std::function<std::string()>& getCachedDateStr;
+    detail::TimerQueue& timerQueue;
+};
+} // namespace crow
diff --git a/http/http_request.h b/http/http_request.h
new file mode 100644
index 0000000..caae93a
--- /dev/null
+++ b/http/http_request.h
@@ -0,0 +1,77 @@
+#pragma once
+
+#include "sessions.hpp"
+
+#include <boost/asio/io_context.hpp>
+#include <boost/beast/http.hpp>
+#include <boost/beast/websocket.hpp>
+
+#include "common.h"
+#include "query_string.h"
+
+namespace crow
+{
+
+struct Request
+{
+    boost::beast::http::request<boost::beast::http::string_body>& req;
+    std::string_view url{};
+    QueryString urlParams{};
+    bool isSecure{false};
+
+    const std::string& body;
+
+    void* middlewareContext{};
+    boost::asio::io_context* ioService{};
+
+    std::shared_ptr<crow::persistent_data::UserSession> session;
+
+    Request(
+        boost::beast::http::request<boost::beast::http::string_body>& reqIn) :
+        req(reqIn),
+        body(reqIn.body())
+    {
+    }
+
+    boost::beast::http::verb method() const
+    {
+        return req.method();
+    }
+
+    const std::string_view getHeaderValue(std::string_view key) const
+    {
+        return req[key];
+    }
+
+    const std::string_view getHeaderValue(boost::beast::http::field key) const
+    {
+        return req[key];
+    }
+
+    const std::string_view methodString() const
+    {
+        return req.method_string();
+    }
+
+    const std::string_view target() const
+    {
+        return req.target();
+    }
+
+    unsigned version()
+    {
+        return req.version();
+    }
+
+    bool isUpgrade()
+    {
+        return boost::beast::websocket::is_upgrade(req);
+    }
+
+    bool keepAlive()
+    {
+        return req.keep_alive();
+    }
+};
+
+} // namespace crow
diff --git a/http/http_response.h b/http/http_response.h
new file mode 100644
index 0000000..6d7ca26
--- /dev/null
+++ b/http/http_response.h
@@ -0,0 +1,160 @@
+#pragma once
+#include "nlohmann/json.hpp"
+
+#include <boost/beast/http.hpp>
+#include <string>
+
+#include "http_request.h"
+#include "logging.h"
+
+namespace crow
+{
+
+template <typename Adaptor, typename Handler, typename... Middlewares>
+class Connection;
+
+struct Response
+{
+    template <typename Adaptor, typename Handler, typename... Middlewares>
+    friend class crow::Connection;
+    using response_type =
+        boost::beast::http::response<boost::beast::http::string_body>;
+
+    std::optional<response_type> stringResponse;
+
+    nlohmann::json jsonValue;
+
+    void addHeader(const std::string_view key, const std::string_view value)
+    {
+        stringResponse->set(key, value);
+    }
+
+    void addHeader(boost::beast::http::field key, std::string_view value)
+    {
+        stringResponse->set(key, value);
+    }
+
+    Response() : stringResponse(response_type{})
+    {
+    }
+
+    Response(Response&& r)
+    {
+        BMCWEB_LOG_DEBUG << "Moving response containers";
+        *this = std::move(r);
+    }
+
+    ~Response()
+    {
+        BMCWEB_LOG_DEBUG << this << " Destroying response";
+    }
+
+    Response& operator=(const Response& r) = delete;
+
+    Response& operator=(Response&& r) noexcept
+    {
+        BMCWEB_LOG_DEBUG << "Moving response containers";
+        stringResponse = std::move(r.stringResponse);
+        r.stringResponse.emplace(response_type{});
+        jsonValue = std::move(r.jsonValue);
+        completed = r.completed;
+        return *this;
+    }
+
+    void result(boost::beast::http::status v)
+    {
+        stringResponse->result(v);
+    }
+
+    boost::beast::http::status result()
+    {
+        return stringResponse->result();
+    }
+
+    unsigned resultInt()
+    {
+        return stringResponse->result_int();
+    }
+
+    std::string_view reason()
+    {
+        return stringResponse->reason();
+    }
+
+    bool isCompleted() const noexcept
+    {
+        return completed;
+    }
+
+    std::string& body()
+    {
+        return stringResponse->body();
+    }
+
+    void keepAlive(bool k)
+    {
+        stringResponse->keep_alive(k);
+    }
+
+    bool keepAlive()
+    {
+        return stringResponse->keep_alive();
+    }
+
+    void preparePayload()
+    {
+        stringResponse->prepare_payload();
+    };
+
+    void clear()
+    {
+        BMCWEB_LOG_DEBUG << this << " Clearing response containers";
+        stringResponse.emplace(response_type{});
+        jsonValue.clear();
+        completed = false;
+    }
+
+    void write(std::string_view body_part)
+    {
+        stringResponse->body() += std::string(body_part);
+    }
+
+    void end()
+    {
+        if (completed)
+        {
+            BMCWEB_LOG_ERROR << "Response was ended twice";
+            return;
+        }
+        completed = true;
+        BMCWEB_LOG_DEBUG << "calling completion handler";
+        if (completeRequestHandler)
+        {
+            BMCWEB_LOG_DEBUG << "completion handler was valid";
+            completeRequestHandler();
+        }
+    }
+
+    void end(std::string_view body_part)
+    {
+        write(body_part);
+        end();
+    }
+
+    bool isAlive()
+    {
+        return isAliveHelper && isAliveHelper();
+    }
+
+  private:
+    bool completed{};
+    std::function<void()> completeRequestHandler;
+    std::function<bool()> isAliveHelper;
+
+    // In case of a JSON object, set the Content-Type header
+    void jsonMode()
+    {
+        addHeader("Content-Type", "application/json");
+    }
+};
+} // namespace crow
diff --git a/http/http_server.h b/http/http_server.h
new file mode 100644
index 0000000..ef50bf7
--- /dev/null
+++ b/http/http_server.h
@@ -0,0 +1,295 @@
+#pragma once
+
+#include <atomic>
+#include <boost/asio/ip/address.hpp>
+#include <boost/asio/ip/tcp.hpp>
+#include <boost/asio/signal_set.hpp>
+#include <boost/asio/ssl/context.hpp>
+#include <boost/asio/steady_timer.hpp>
+#if BOOST_VERSION >= 107000
+#include <boost/beast/ssl/ssl_stream.hpp>
+#else
+#include <boost/beast/experimental/core/ssl_stream.hpp>
+#endif
+
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <chrono>
+#include <cstdint>
+#include <filesystem>
+#include <future>
+#include <memory>
+#include <ssl_key_handler.hpp>
+#include <utility>
+#include <vector>
+
+#include "http_connection.h"
+#include "logging.h"
+#include "timer_queue.h"
+
+namespace crow
+{
+using namespace boost;
+using tcp = asio::ip::tcp;
+
+template <typename Handler, typename Adaptor = boost::asio::ip::tcp::socket,
+          typename... Middlewares>
+class Server
+{
+  public:
+    Server(Handler* handler, std::unique_ptr<tcp::acceptor>&& acceptor,
+           std::shared_ptr<boost::asio::ssl::context> adaptor_ctx,
+           std::tuple<Middlewares...>* middlewares = nullptr,
+           std::shared_ptr<boost::asio::io_context> io =
+               std::make_shared<boost::asio::io_context>()) :
+        ioService(std::move(io)),
+        acceptor(std::move(acceptor)),
+        signals(*ioService, SIGINT, SIGTERM, SIGHUP), tickTimer(*ioService),
+        handler(handler), middlewares(middlewares), adaptorCtx(adaptor_ctx)
+    {
+    }
+
+    Server(Handler* handler, const std::string& bindaddr, uint16_t port,
+           std::shared_ptr<boost::asio::ssl::context> adaptor_ctx,
+           std::tuple<Middlewares...>* middlewares = nullptr,
+           std::shared_ptr<boost::asio::io_context> io =
+               std::make_shared<boost::asio::io_context>()) :
+        Server(handler,
+               std::make_unique<tcp::acceptor>(
+                   *io, tcp::endpoint(boost::asio::ip::make_address(bindaddr),
+                                      port)),
+               adaptor_ctx, middlewares, io)
+    {
+    }
+
+    Server(Handler* handler, int existing_socket,
+           std::shared_ptr<boost::asio::ssl::context> adaptor_ctx,
+           std::tuple<Middlewares...>* middlewares = nullptr,
+           std::shared_ptr<boost::asio::io_context> io =
+               std::make_shared<boost::asio::io_context>()) :
+        Server(handler,
+               std::make_unique<tcp::acceptor>(*io, boost::asio::ip::tcp::v6(),
+                                               existing_socket),
+               adaptor_ctx, middlewares, io)
+    {
+    }
+
+    void setTickFunction(std::chrono::milliseconds d, std::function<void()> f)
+    {
+        tickInterval = d;
+        tickFunction = f;
+    }
+
+    void onTick()
+    {
+        tickFunction();
+        tickTimer.expires_after(
+            std::chrono::milliseconds(tickInterval.count()));
+        tickTimer.async_wait([this](const boost::system::error_code& ec) {
+            if (ec)
+            {
+                return;
+            }
+            onTick();
+        });
+    }
+
+    void updateDateStr()
+    {
+        time_t lastTimeT = time(0);
+        tm myTm{};
+
+        gmtime_r(&lastTimeT, &myTm);
+
+        dateStr.resize(100);
+        size_t dateStrSz =
+            strftime(&dateStr[0], 99, "%a, %d %b %Y %H:%M:%S GMT", &myTm);
+        dateStr.resize(dateStrSz);
+    };
+
+    void run()
+    {
+        loadCertificate();
+        updateDateStr();
+
+        getCachedDateStr = [this]() -> std::string {
+            static std::chrono::time_point<std::chrono::steady_clock>
+                lastDateUpdate = std::chrono::steady_clock::now();
+            if (std::chrono::steady_clock::now() - lastDateUpdate >=
+                std::chrono::seconds(10))
+            {
+                lastDateUpdate = std::chrono::steady_clock::now();
+                updateDateStr();
+            }
+            return this->dateStr;
+        };
+
+        boost::asio::steady_timer timer(*ioService);
+        timer.expires_after(std::chrono::seconds(1));
+
+        std::function<void(const boost::system::error_code& ec)> timerHandler;
+        timerHandler = [&](const boost::system::error_code& ec) {
+            if (ec)
+            {
+                return;
+            }
+            timerQueue.process();
+            timer.expires_after(std::chrono::seconds(1));
+            timer.async_wait(timerHandler);
+        };
+        timer.async_wait(timerHandler);
+
+        if (tickFunction && tickInterval.count() > 0)
+        {
+            tickTimer.expires_after(
+                std::chrono::milliseconds(tickInterval.count()));
+            tickTimer.async_wait([this](const boost::system::error_code& ec) {
+                if (ec)
+                {
+                    return;
+                }
+                onTick();
+            });
+        }
+
+        BMCWEB_LOG_INFO << serverName << " server is running, local endpoint "
+                        << acceptor->local_endpoint();
+        startAsyncWaitForSignal();
+        doAccept();
+    }
+
+    void loadCertificate()
+    {
+#ifdef BMCWEB_ENABLE_SSL
+        namespace fs = std::filesystem;
+        // Cleanup older certificate file existing in the system
+        fs::path oldCert = "/home/root/server.pem";
+        if (fs::exists(oldCert))
+        {
+            fs::remove("/home/root/server.pem");
+        }
+        fs::path certPath = "/etc/ssl/certs/https/";
+        // if path does not exist create the path so that
+        // self signed certificate can be created in the
+        // path
+        if (!fs::exists(certPath))
+        {
+            fs::create_directories(certPath);
+        }
+        fs::path certFile = certPath / "server.pem";
+        BMCWEB_LOG_INFO << "Building SSL Context file=" << certFile;
+        std::string sslPemFile(certFile);
+        ensuressl::ensureOpensslKeyPresentAndValid(sslPemFile);
+        std::shared_ptr<boost::asio::ssl::context> sslContext =
+            ensuressl::getSslContext(sslPemFile);
+        adaptorCtx = sslContext;
+        handler->ssl(std::move(sslContext));
+#endif
+    }
+
+    void startAsyncWaitForSignal()
+    {
+        signals.async_wait([this](const boost::system::error_code& ec,
+                                  int signalNo) {
+            if (ec)
+            {
+                BMCWEB_LOG_INFO << "Error in signal handler" << ec.message();
+            }
+            else
+            {
+                if (signalNo == SIGHUP)
+                {
+                    BMCWEB_LOG_INFO << "Receivied reload signal";
+                    loadCertificate();
+                    this->startAsyncWaitForSignal();
+                }
+                else
+                {
+                    stop();
+                }
+            }
+        });
+    }
+
+    void stop()
+    {
+        ioService->stop();
+    }
+
+    void doAccept()
+    {
+        std::optional<Adaptor> adaptorTemp;
+        if constexpr (std::is_same<Adaptor,
+                                   boost::beast::ssl_stream<
+                                       boost::asio::ip::tcp::socket>>::value)
+        {
+            adaptorTemp = Adaptor(*ioService, *adaptorCtx);
+            Connection<Adaptor, Handler, Middlewares...>* p =
+                new Connection<Adaptor, Handler, Middlewares...>(
+                    *ioService, handler, serverName, middlewares,
+                    getCachedDateStr, timerQueue,
+                    std::move(adaptorTemp.value()));
+
+            acceptor->async_accept(p->socket().next_layer(),
+                                   [this, p](boost::system::error_code ec) {
+                                       if (!ec)
+                                       {
+                                           boost::asio::post(
+                                               *this->ioService,
+                                               [p] { p->start(); });
+                                       }
+                                       else
+                                       {
+                                           delete p;
+                                       }
+                                       doAccept();
+                                   });
+        }
+        else
+        {
+            adaptorTemp = Adaptor(*ioService);
+            Connection<Adaptor, Handler, Middlewares...>* p =
+                new Connection<Adaptor, Handler, Middlewares...>(
+                    *ioService, handler, serverName, middlewares,
+                    getCachedDateStr, timerQueue,
+                    std::move(adaptorTemp.value()));
+
+            acceptor->async_accept(
+                p->socket(), [this, p](boost::system::error_code ec) {
+                    if (!ec)
+                    {
+                        boost::asio::post(*this->ioService,
+                                          [p] { p->start(); });
+                    }
+                    else
+                    {
+                        delete p;
+                    }
+                    doAccept();
+                });
+        }
+    }
+
+  private:
+    std::shared_ptr<asio::io_context> ioService;
+    detail::TimerQueue timerQueue;
+    std::function<std::string()> getCachedDateStr;
+    std::unique_ptr<tcp::acceptor> acceptor;
+    boost::asio::signal_set signals;
+    boost::asio::steady_timer tickTimer;
+
+    std::string dateStr;
+
+    Handler* handler;
+    std::string serverName = "iBMC";
+
+    std::chrono::milliseconds tickInterval{};
+    std::function<void()> tickFunction;
+
+    std::tuple<Middlewares...>* middlewares;
+
+#ifdef BMCWEB_ENABLE_SSL
+    bool useSsl{false};
+#endif
+    std::shared_ptr<boost::asio::ssl::context> adaptorCtx;
+}; // namespace crow
+} // namespace crow
diff --git a/http/logging.h b/http/logging.h
new file mode 100644
index 0000000..a608f1f
--- /dev/null
+++ b/http/logging.h
@@ -0,0 +1,115 @@
+#pragma once
+
+#include <cstdio>
+#include <cstdlib>
+#include <ctime>
+#include <filesystem>
+#include <iostream>
+#include <sstream>
+#include <string>
+
+namespace crow
+{
+enum class LogLevel
+{
+    Debug = 0,
+    Info,
+    Warning,
+    Error,
+    Critical,
+};
+
+class logger
+{
+  private:
+    //
+    static std::string timestamp()
+    {
+        std::string date;
+        date.resize(32, '\0');
+        time_t t = time(0);
+
+        tm myTm{};
+
+        gmtime_r(&t, &myTm);
+
+        size_t sz =
+            strftime(date.data(), date.size(), "%Y-%m-%d %H:%M:%S", &myTm);
+        date.resize(sz);
+        return date;
+    }
+
+  public:
+    logger(const std::string& prefix, const std::string& filename,
+           const size_t line, LogLevel levelIn) :
+        level(levelIn)
+    {
+#ifdef BMCWEB_ENABLE_LOGGING
+        stringstream << "(" << timestamp() << ") [" << prefix << " "
+                     << std::filesystem::path(filename).filename() << ":"
+                     << line << "] ";
+#endif
+    }
+    ~logger()
+    {
+        if (level >= get_current_log_level())
+        {
+#ifdef BMCWEB_ENABLE_LOGGING
+            stringstream << std::endl;
+            std::cerr << stringstream.str();
+#endif
+        }
+    }
+
+    //
+    template <typename T> logger& operator<<(T const& value)
+    {
+        if (level >= get_current_log_level())
+        {
+#ifdef BMCWEB_ENABLE_LOGGING
+            stringstream << value;
+#endif
+        }
+        return *this;
+    }
+
+    //
+    static void setLogLevel(LogLevel level)
+    {
+        getLogLevelRef() = level;
+    }
+
+    static LogLevel get_current_log_level()
+    {
+        return getLogLevelRef();
+    }
+
+  private:
+    //
+    static LogLevel& getLogLevelRef()
+    {
+        static auto currentLevel = static_cast<LogLevel>(1);
+        return currentLevel;
+    }
+
+    //
+    std::ostringstream stringstream;
+    LogLevel level;
+};
+} // namespace crow
+
+#define BMCWEB_LOG_CRITICAL                                                    \
+    if (crow::logger::get_current_log_level() <= crow::LogLevel::Critical)     \
+    crow::logger("CRITICAL", __FILE__, __LINE__, crow::LogLevel::Critical)
+#define BMCWEB_LOG_ERROR                                                       \
+    if (crow::logger::get_current_log_level() <= crow::LogLevel::Error)        \
+    crow::logger("ERROR", __FILE__, __LINE__, crow::LogLevel::Error)
+#define BMCWEB_LOG_WARNING                                                     \
+    if (crow::logger::get_current_log_level() <= crow::LogLevel::Warning)      \
+    crow::logger("WARNING", __FILE__, __LINE__, crow::LogLevel::Warning)
+#define BMCWEB_LOG_INFO                                                        \
+    if (crow::logger::get_current_log_level() <= crow::LogLevel::Info)         \
+    crow::logger("INFO", __FILE__, __LINE__, crow::LogLevel::Info)
+#define BMCWEB_LOG_DEBUG                                                       \
+    if (crow::logger::get_current_log_level() <= crow::LogLevel::Debug)        \
+    crow::logger("DEBUG", __FILE__, __LINE__, crow::LogLevel::Debug)
diff --git a/http/middleware_context.h b/http/middleware_context.h
new file mode 100644
index 0000000..fbe1d80
--- /dev/null
+++ b/http/middleware_context.h
@@ -0,0 +1,68 @@
+#pragma once
+
+#include "http_request.h"
+#include "http_response.h"
+#include "utility.h"
+
+namespace crow
+{
+namespace detail
+{
+template <typename... Middlewares>
+struct PartialContext
+    : public black_magic::PopBack<Middlewares...>::template rebind<
+          PartialContext>,
+      public black_magic::LastElementType<Middlewares...>::type::Context
+{
+    using parent_context = typename black_magic::PopBack<
+        Middlewares...>::template rebind<::crow::detail::PartialContext>;
+    template <size_t N>
+    using partial = typename std::conditional<
+        N == sizeof...(Middlewares) - 1, PartialContext,
+        typename parent_context::template partial<N>>::type;
+
+    template <typename T> typename T::Context& get()
+    {
+        return static_cast<typename T::Context&>(*this);
+    }
+};
+
+template <> struct PartialContext<>
+{
+    template <size_t> using partial = PartialContext;
+};
+
+template <size_t N, typename Context, typename Container, typename CurrentMW,
+          typename... Middlewares>
+bool middlewareCallHelper(Container& middlewares, Request& req, Response& res,
+                          Context& ctx);
+
+template <typename... Middlewares>
+struct Context : private PartialContext<Middlewares...>
+// struct Context : private Middlewares::context... // simple but less type-safe
+{
+    template <size_t N, typename Context, typename Container>
+    friend typename std::enable_if<(N == 0)>::type
+        afterHandlersCallHelper(Container& middlewares, Context& ctx,
+                                Request& req, Response& res);
+    template <size_t N, typename Context, typename Container>
+    friend typename std::enable_if<(N > 0)>::type
+        afterHandlersCallHelper(Container& middlewares, Context& ctx,
+                                Request& req, Response& res);
+
+    template <size_t N, typename Context, typename Container,
+              typename CurrentMW, typename... Middlewares2>
+    friend bool middlewareCallHelper(Container& middlewares, Request& req,
+                                     Response& res, Context& ctx);
+
+    template <typename T> typename T::Context& get()
+    {
+        return static_cast<typename T::Context&>(*this);
+    }
+
+    template <size_t N>
+    using partial =
+        typename PartialContext<Middlewares...>::template partial<N>;
+};
+} // namespace detail
+} // namespace crow
diff --git a/http/query_string.h b/http/query_string.h
new file mode 100644
index 0000000..0cd21e4
--- /dev/null
+++ b/http/query_string.h
@@ -0,0 +1,418 @@
+#pragma once
+
+#include <cstdio>
+#include <cstring>
+#include <iostream>
+#include <string>
+#include <vector>
+
+namespace crow
+{
+// ----------------------------------------------------------------------------
+// qs_parse (modified)
+// https://github.com/bartgrantham/qs_parse
+// ----------------------------------------------------------------------------
+/*  Similar to strncmp, but handles URL-encoding for either string  */
+int qsStrncmp(const char* s, const char* qs, size_t n);
+
+/*  Finds the beginning of each key/value pair and stores a pointer in qs_kv.
+ *  Also decodes the value portion of the k/v pair *in-place*.  In a future
+ *  enhancement it will also have a compile-time option of sorting qs_kv
+ *  alphabetically by key.  */
+size_t qsParse(char* qs, char* qs_kv[], size_t qs_kv_size);
+
+/*  Used by qs_parse to decode the value portion of a k/v pair  */
+int qsDecode(char* qs);
+
+/*  Looks up the value according to the key on a pre-processed query string
+ *  A future enhancement will be a compile-time option to look up the key
+ *  in a pre-sorted qs_kv array via a binary search.  */
+// char * qs_k2v(const char * key, char * qs_kv[], int qs_kv_size);
+char* qsK2v(const char* key, char* const* qs_kv, int qs_kv_size, int nth);
+
+/*  Non-destructive lookup of value, based on key.  User provides the
+ *  destinaton string and length.  */
+char* qsScanvalue(const char* key, const char* qs, char* val, size_t val_len);
+
+// TODO: implement sorting of the qs_kv array; for now ensure it's not compiled
+#undef _qsSORTING
+
+// isxdigit _is_ available in <ctype.h>, but let's avoid another header instead
+#define BMCWEB_QS_ISHEX(x)                                                     \
+    ((((x) >= '0' && (x) <= '9') || ((x) >= 'A' && (x) <= 'F') ||              \
+      ((x) >= 'a' && (x) <= 'f'))                                              \
+         ? 1                                                                   \
+         : 0)
+#define BMCWEB_QS_HEX2DEC(x)                                                   \
+    (((x) >= '0' && (x) <= '9')                                                \
+         ? (x)-48                                                              \
+         : ((x) >= 'A' && (x) <= 'F')                                          \
+               ? (x)-55                                                        \
+               : ((x) >= 'a' && (x) <= 'f') ? (x)-87 : 0)
+#define BMCWEB_QS_ISQSCHR(x)                                                   \
+    ((((x) == '=') || ((x) == '#') || ((x) == '&') || ((x) == '\0')) ? 0 : 1)
+
+inline int qsStrncmp(const char* s, const char* qs, size_t n)
+{
+    int i = 0;
+    char u1, u2;
+    char unyb, lnyb;
+
+    while (n-- > 0)
+    {
+        u1 = *s++;
+        u2 = *qs++;
+
+        if (!BMCWEB_QS_ISQSCHR(u1))
+        {
+            u1 = '\0';
+        }
+        if (!BMCWEB_QS_ISQSCHR(u2))
+        {
+            u2 = '\0';
+        }
+
+        if (u1 == '+')
+        {
+            u1 = ' ';
+        }
+        if (u1 == '%') // easier/safer than scanf
+        {
+            unyb = static_cast<char>(*s++);
+            lnyb = static_cast<char>(*s++);
+            if (BMCWEB_QS_ISHEX(unyb) && BMCWEB_QS_ISHEX(lnyb))
+            {
+                u1 = static_cast<char>((BMCWEB_QS_HEX2DEC(unyb) * 16) +
+                                       BMCWEB_QS_HEX2DEC(lnyb));
+            }
+            else
+            {
+                u1 = '\0';
+            }
+        }
+
+        if (u2 == '+')
+        {
+            u2 = ' ';
+        }
+        if (u2 == '%') // easier/safer than scanf
+        {
+            unyb = static_cast<char>(*qs++);
+            lnyb = static_cast<char>(*qs++);
+            if (BMCWEB_QS_ISHEX(unyb) && BMCWEB_QS_ISHEX(lnyb))
+            {
+                u2 = static_cast<char>((BMCWEB_QS_HEX2DEC(unyb) * 16) +
+                                       BMCWEB_QS_HEX2DEC(lnyb));
+            }
+            else
+            {
+                u2 = '\0';
+            }
+        }
+
+        if (u1 != u2)
+        {
+            return u1 - u2;
+        }
+        if (u1 == '\0')
+        {
+            return 0;
+        }
+        i++;
+    }
+    if (BMCWEB_QS_ISQSCHR(*qs))
+    {
+        return -1;
+    }
+    else
+    {
+        return 0;
+    }
+}
+
+inline size_t qsParse(char* qs, char* qs_kv[], size_t qs_kv_size)
+{
+    size_t i;
+    size_t j;
+    char* substrPtr;
+
+    for (i = 0; i < qs_kv_size; i++)
+    {
+        qs_kv[i] = NULL;
+    }
+
+    // find the beginning of the k/v substrings or the fragment
+    substrPtr = qs + strcspn(qs, "?#");
+    if (substrPtr[0] != '\0')
+    {
+        substrPtr++;
+    }
+    else
+    {
+        return 0; // no query or fragment
+    }
+
+    i = 0;
+    while (i < qs_kv_size)
+    {
+        qs_kv[i] = substrPtr;
+        j = strcspn(substrPtr, "&");
+        if (substrPtr[j] == '\0')
+        {
+            break;
+        }
+        substrPtr += j + 1;
+        i++;
+    }
+    i++; // x &'s -> means x iterations of this loop -> means *x+1* k/v pairs
+
+    // we only decode the values in place, the keys could have '='s in them
+    // which will hose our ability to distinguish keys from values later
+    for (j = 0; j < i; j++)
+    {
+        substrPtr = qs_kv[j] + strcspn(qs_kv[j], "=&#");
+        if (substrPtr[0] == '&' || substrPtr[0] == '\0')
+        { // blank value: skip decoding
+            substrPtr[0] = '\0';
+        }
+        else
+        {
+            qsDecode(++substrPtr);
+        }
+    }
+
+#ifdef _qsSORTING
+// TODO: qsort qs_kv, using qs_strncmp() for the comparison
+#endif
+
+    return i;
+}
+
+inline int qsDecode(char* qs)
+{
+    int i = 0, j = 0;
+
+    while (BMCWEB_QS_ISQSCHR(qs[j]))
+    {
+        if (qs[j] == '+')
+        {
+            qs[i] = ' ';
+        }
+        else if (qs[j] == '%') // easier/safer than scanf
+        {
+            if (!BMCWEB_QS_ISHEX(qs[j + 1]) || !BMCWEB_QS_ISHEX(qs[j + 2]))
+            {
+                qs[i] = '\0';
+                return i;
+            }
+            qs[i] = static_cast<char>(BMCWEB_QS_HEX2DEC(qs[j + 1] * 16) +
+                                      BMCWEB_QS_HEX2DEC(qs[j + 2]));
+            j += 2;
+        }
+        else
+        {
+            qs[i] = qs[j];
+        }
+        i++;
+        j++;
+    }
+    qs[i] = '\0';
+
+    return i;
+}
+
+inline char* qsK2v(const char* key, char* const* qs_kv, int qs_kv_size,
+                   int nth = 0)
+{
+    int i;
+    size_t keyLen, skip;
+
+    keyLen = strlen(key);
+
+#ifdef _qsSORTING
+// TODO: binary search for key in the sorted qs_kv
+#else  // _qsSORTING
+    for (i = 0; i < qs_kv_size; i++)
+    {
+        // we rely on the unambiguous '=' to find the value in our k/v pair
+        if (qsStrncmp(key, qs_kv[i], keyLen) == 0)
+        {
+            skip = strcspn(qs_kv[i], "=");
+            if (qs_kv[i][skip] == '=')
+            {
+                skip++;
+            }
+            // return (zero-char value) ? ptr to trailing '\0' : ptr to value
+            if (nth == 0)
+            {
+                return qs_kv[i] + skip;
+            }
+            else
+            {
+                --nth;
+            }
+        }
+    }
+#endif // _qsSORTING
+
+    return NULL;
+}
+
+inline char* qsScanvalue(const char* key, const char* qs, char* val,
+                         size_t val_len)
+{
+    size_t i, keyLen;
+    const char* tmp;
+
+    // find the beginning of the k/v substrings
+    if ((tmp = strchr(qs, '?')) != NULL)
+    {
+        qs = tmp + 1;
+    }
+
+    keyLen = strlen(key);
+    while (qs[0] != '#' && qs[0] != '\0')
+    {
+        if (qsStrncmp(key, qs, keyLen) == 0)
+        {
+            break;
+        }
+        qs += strcspn(qs, "&") + 1;
+    }
+
+    if (qs[0] == '\0')
+    {
+        return NULL;
+    }
+
+    qs += strcspn(qs, "=&#");
+    if (qs[0] == '=')
+    {
+        qs++;
+        i = strcspn(qs, "&=#");
+        strncpy(val, qs, (val_len - 1) < (i + 1) ? (val_len - 1) : (i + 1));
+        qsDecode(val);
+    }
+    else
+    {
+        if (val_len > 0)
+        {
+            val[0] = '\0';
+        }
+    }
+
+    return val;
+}
+} // namespace crow
+// ----------------------------------------------------------------------------
+
+namespace crow
+{
+class QueryString
+{
+  public:
+    static const size_t maxKeyValuePairsCount = 256;
+
+    QueryString() = default;
+
+    QueryString(const QueryString& qs) : url(qs.url)
+    {
+        for (auto p : qs.keyValuePairs)
+        {
+            keyValuePairs.push_back(
+                const_cast<char*>(p - qs.url.c_str() + url.c_str()));
+        }
+    }
+
+    QueryString& operator=(const QueryString& qs)
+    {
+        url = qs.url;
+        keyValuePairs.clear();
+        for (auto p : qs.keyValuePairs)
+        {
+            keyValuePairs.push_back(
+                const_cast<char*>(p - qs.url.c_str() + url.c_str()));
+        }
+        return *this;
+    }
+
+    QueryString& operator=(QueryString&& qs)
+    {
+        keyValuePairs = std::move(qs.keyValuePairs);
+        auto* oldData = const_cast<char*>(qs.url.c_str());
+        url = std::move(qs.url);
+        for (auto& p : keyValuePairs)
+        {
+            p += const_cast<char*>(url.c_str()) - oldData;
+        }
+        return *this;
+    }
+
+    explicit QueryString(std::string newUrl) : url(std::move(newUrl))
+    {
+        if (url.empty())
+        {
+            return;
+        }
+
+        keyValuePairs.resize(maxKeyValuePairsCount);
+
+        size_t count =
+            qsParse(&url[0], &keyValuePairs[0], maxKeyValuePairsCount);
+        keyValuePairs.resize(count);
+    }
+
+    void clear()
+    {
+        keyValuePairs.clear();
+        url.clear();
+    }
+
+    friend std::ostream& operator<<(std::ostream& os, const QueryString& qs)
+    {
+        os << "[ ";
+        for (size_t i = 0; i < qs.keyValuePairs.size(); ++i)
+        {
+            if (i != 0u)
+            {
+                os << ", ";
+            }
+            os << qs.keyValuePairs[i];
+        }
+        os << " ]";
+        return os;
+    }
+
+    char* get(const std::string& name) const
+    {
+        char* ret = qsK2v(name.c_str(), keyValuePairs.data(),
+                          static_cast<int>(keyValuePairs.size()));
+        return ret;
+    }
+
+    std::vector<char*> getList(const std::string& name) const
+    {
+        std::vector<char*> ret;
+        std::string plus = name + "[]";
+        char* element = nullptr;
+
+        int count = 0;
+        while (1)
+        {
+            element = qsK2v(plus.c_str(), keyValuePairs.data(),
+                            static_cast<int>(keyValuePairs.size()), count++);
+            if (element == nullptr)
+            {
+                break;
+            }
+            ret.push_back(element);
+        }
+        return ret;
+    }
+
+  private:
+    std::string url;
+    std::vector<char*> keyValuePairs;
+};
+
+} // namespace crow
diff --git a/http/routing.h b/http/routing.h
new file mode 100644
index 0000000..b2355e9
--- /dev/null
+++ b/http/routing.h
@@ -0,0 +1,1334 @@
+#pragma once
+
+#include "privileges.hpp"
+#include "sessions.hpp"
+
+#include <boost/container/flat_map.hpp>
+#include <boost/container/small_vector.hpp>
+#include <boost/lexical_cast.hpp>
+#include <cerrno>
+#include <cstdint>
+#include <cstdlib>
+#include <limits>
+#include <memory>
+#include <tuple>
+#include <utility>
+#include <vector>
+
+#include "common.h"
+#include "http_request.h"
+#include "http_response.h"
+#include "logging.h"
+#include "utility.h"
+#include "websocket.h"
+
+namespace crow
+{
+
+constexpr int maxHttpVerbCount =
+    static_cast<int>(boost::beast::http::verb::unlink);
+
+class BaseRule
+{
+  public:
+    BaseRule(std::string thisRule) : rule(std::move(thisRule))
+    {
+    }
+
+    virtual ~BaseRule()
+    {
+    }
+
+    virtual void validate() = 0;
+    std::unique_ptr<BaseRule> upgrade()
+    {
+        if (ruleToUpgrade)
+            return std::move(ruleToUpgrade);
+        return {};
+    }
+
+    virtual void handle(const Request&, Response&, const RoutingParams&) = 0;
+    virtual void handleUpgrade(const Request&, Response& res,
+                               boost::asio::ip::tcp::socket&&)
+    {
+        res.result(boost::beast::http::status::not_found);
+        res.end();
+    }
+#ifdef BMCWEB_ENABLE_SSL
+    virtual void
+        handleUpgrade(const Request&, Response& res,
+                      boost::beast::ssl_stream<boost::asio::ip::tcp::socket>&&)
+    {
+        res.result(boost::beast::http::status::not_found);
+        res.end();
+    }
+#endif
+
+    size_t getMethods()
+    {
+        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>(boost::beast::http::verb::get)};
+
+    std::vector<redfish::Privileges> privilegesSet;
+
+    std::string rule;
+    std::string nameStr;
+
+    std::unique_ptr<BaseRule> ruleToUpgrade;
+
+    friend class Router;
+    template <typename T> friend struct RuleParameterTraits;
+};
+
+namespace detail
+{
+namespace routing_handler_call_helper
+{
+template <typename T, int Pos> struct CallPair
+{
+    using type = T;
+    static const int pos = Pos;
+};
+
+template <typename H1> struct CallParams
+{
+    H1& handler;
+    const RoutingParams& params;
+    const Request& req;
+    Response& res;
+};
+
+template <typename F, int NInt, int NUint, int NDouble, int NString,
+          typename S1, typename S2>
+struct Call
+{
+};
+
+template <typename F, int NInt, int NUint, int NDouble, int NString,
+          typename... Args1, typename... Args2>
+struct Call<F, NInt, NUint, NDouble, NString, black_magic::S<int64_t, Args1...>,
+            black_magic::S<Args2...>>
+{
+    void operator()(F cparams)
+    {
+        using pushed = typename black_magic::S<Args2...>::template push_back<
+            CallPair<int64_t, NInt>>;
+        Call<F, NInt + 1, NUint, NDouble, NString, black_magic::S<Args1...>,
+             pushed>()(cparams);
+    }
+};
+
+template <typename F, int NInt, int NUint, int NDouble, int NString,
+          typename... Args1, typename... Args2>
+struct Call<F, NInt, NUint, NDouble, NString,
+            black_magic::S<uint64_t, Args1...>, black_magic::S<Args2...>>
+{
+    void operator()(F cparams)
+    {
+        using pushed = typename black_magic::S<Args2...>::template push_back<
+            CallPair<uint64_t, NUint>>;
+        Call<F, NInt, NUint + 1, NDouble, NString, black_magic::S<Args1...>,
+             pushed>()(cparams);
+    }
+};
+
+template <typename F, int NInt, int NUint, int NDouble, int NString,
+          typename... Args1, typename... Args2>
+struct Call<F, NInt, NUint, NDouble, NString, black_magic::S<double, Args1...>,
+            black_magic::S<Args2...>>
+{
+    void operator()(F cparams)
+    {
+        using pushed = typename black_magic::S<Args2...>::template push_back<
+            CallPair<double, NDouble>>;
+        Call<F, NInt, NUint, NDouble + 1, NString, black_magic::S<Args1...>,
+             pushed>()(cparams);
+    }
+};
+
+template <typename F, int NInt, int NUint, int NDouble, int NString,
+          typename... Args1, typename... Args2>
+struct Call<F, NInt, NUint, NDouble, NString,
+            black_magic::S<std::string, Args1...>, black_magic::S<Args2...>>
+{
+    void operator()(F cparams)
+    {
+        using pushed = typename black_magic::S<Args2...>::template push_back<
+            CallPair<std::string, NString>>;
+        Call<F, NInt, NUint, NDouble, NString + 1, black_magic::S<Args1...>,
+             pushed>()(cparams);
+    }
+};
+
+template <typename F, int NInt, int NUint, int NDouble, int NString,
+          typename... Args1>
+struct Call<F, NInt, NUint, NDouble, NString, black_magic::S<>,
+            black_magic::S<Args1...>>
+{
+    void operator()(F cparams)
+    {
+        cparams.handler(
+            cparams.req, cparams.res,
+            cparams.params.template get<typename Args1::type>(Args1::pos)...);
+    }
+};
+
+template <typename Func, typename... ArgsWrapped> struct Wrapped
+{
+    template <typename... Args>
+    void set(
+        Func f,
+        typename std::enable_if<
+            !std::is_same<
+                typename std::tuple_element<0, std::tuple<Args..., void>>::type,
+                const Request&>::value,
+            int>::type = 0)
+    {
+        handler = [f = std::move(f)](const Request&, Response& res,
+                                     Args... args) {
+            res.result(f(args...));
+            res.end();
+        };
+    }
+
+    template <typename Req, typename... Args> struct ReqHandlerWrapper
+    {
+        ReqHandlerWrapper(Func f) : f(std::move(f))
+        {
+        }
+
+        void operator()(const Request& req, Response& res, Args... args)
+        {
+            res.result(f(req, args...));
+            res.end();
+        }
+
+        Func f;
+    };
+
+    template <typename... Args>
+    void set(
+        Func f,
+        typename std::enable_if<
+            std::is_same<
+                typename std::tuple_element<0, std::tuple<Args..., void>>::type,
+                const Request&>::value &&
+                !std::is_same<typename std::tuple_element<
+                                  1, std::tuple<Args..., void, void>>::type,
+                              Response&>::value,
+            int>::type = 0)
+    {
+        handler = ReqHandlerWrapper<Args...>(std::move(f));
+        /*handler = (
+            [f = std::move(f)]
+            (const Request& req, Response& res, Args... args){
+                 res.result(f(req, args...));
+                 res.end();
+            });*/
+    }
+
+    template <typename... Args>
+    void set(
+        Func f,
+        typename std::enable_if<
+            std::is_same<
+                typename std::tuple_element<0, std::tuple<Args..., void>>::type,
+                const Request&>::value &&
+                std::is_same<typename std::tuple_element<
+                                 1, std::tuple<Args..., void, void>>::type,
+                             Response&>::value,
+            int>::type = 0)
+    {
+        handler = std::move(f);
+    }
+
+    template <typename... Args> struct HandlerTypeHelper
+    {
+        using type =
+            std::function<void(const crow::Request&, crow::Response&, Args...)>;
+        using args_type =
+            black_magic::S<typename black_magic::promote_t<Args>...>;
+    };
+
+    template <typename... Args>
+    struct HandlerTypeHelper<const Request&, Args...>
+    {
+        using type =
+            std::function<void(const crow::Request&, crow::Response&, Args...)>;
+        using args_type =
+            black_magic::S<typename black_magic::promote_t<Args>...>;
+    };
+
+    template <typename... Args>
+    struct HandlerTypeHelper<const Request&, Response&, Args...>
+    {
+        using type =
+            std::function<void(const crow::Request&, crow::Response&, Args...)>;
+        using args_type =
+            black_magic::S<typename black_magic::promote_t<Args>...>;
+    };
+
+    typename HandlerTypeHelper<ArgsWrapped...>::type handler;
+
+    void operator()(const Request& req, Response& res,
+                    const RoutingParams& params)
+    {
+        detail::routing_handler_call_helper::Call<
+            detail::routing_handler_call_helper::CallParams<decltype(handler)>,
+            0, 0, 0, 0, typename HandlerTypeHelper<ArgsWrapped...>::args_type,
+            black_magic::S<>>()(
+            detail::routing_handler_call_helper::CallParams<decltype(handler)>{
+                handler, params, req, res});
+    }
+};
+} // namespace routing_handler_call_helper
+} // namespace detail
+
+class WebSocketRule : public BaseRule
+{
+    using self_t = WebSocketRule;
+
+  public:
+    WebSocketRule(std::string rule) : BaseRule(std::move(rule))
+    {
+    }
+
+    void validate() override
+    {
+    }
+
+    void handle(const Request&, Response& res, const RoutingParams&) override
+    {
+        res.result(boost::beast::http::status::not_found);
+        res.end();
+    }
+
+    void handleUpgrade(const Request& req, Response&,
+                       boost::asio::ip::tcp::socket&& adaptor) override
+    {
+        new crow::websocket::ConnectionImpl<boost::asio::ip::tcp::socket>(
+            req, std::move(adaptor), openHandler, messageHandler, closeHandler,
+            errorHandler);
+    }
+#ifdef BMCWEB_ENABLE_SSL
+    void handleUpgrade(const Request& req, Response&,
+                       boost::beast::ssl_stream<boost::asio::ip::tcp::socket>&&
+                           adaptor) override
+    {
+        std::shared_ptr<crow::websocket::ConnectionImpl<
+            boost::beast::ssl_stream<boost::asio::ip::tcp::socket>>>
+            myConnection = std::make_shared<crow::websocket::ConnectionImpl<
+                boost::beast::ssl_stream<boost::asio::ip::tcp::socket>>>(
+                req, std::move(adaptor), openHandler, messageHandler,
+                closeHandler, errorHandler);
+        myConnection->start();
+    }
+#endif
+
+    template <typename Func> self_t& onopen(Func f)
+    {
+        openHandler = f;
+        return *this;
+    }
+
+    template <typename Func> self_t& onmessage(Func f)
+    {
+        messageHandler = f;
+        return *this;
+    }
+
+    template <typename Func> self_t& onclose(Func f)
+    {
+        closeHandler = f;
+        return *this;
+    }
+
+    template <typename Func> self_t& onerror(Func f)
+    {
+        errorHandler = f;
+        return *this;
+    }
+
+  protected:
+    std::function<void(crow::websocket::Connection&)> openHandler;
+    std::function<void(crow::websocket::Connection&, const std::string&, bool)>
+        messageHandler;
+    std::function<void(crow::websocket::Connection&, const std::string&)>
+        closeHandler;
+    std::function<void(crow::websocket::Connection&)> errorHandler;
+};
+
+template <typename T> struct RuleParameterTraits
+{
+    using self_t = T;
+    WebSocketRule& websocket()
+    {
+        self_t* self = static_cast<self_t*>(this);
+        WebSocketRule* p = new WebSocketRule(self->rule);
+        self->ruleToUpgrade.reset(p);
+        return *p;
+    }
+
+    self_t& name(std::string name) noexcept
+    {
+        self_t* self = static_cast<self_t*>(this);
+        self->nameStr = std::move(name);
+        return *self;
+    }
+
+    self_t& methods(boost::beast::http::verb method)
+    {
+        self_t* self = static_cast<self_t*>(this);
+        self->methodsBitfield = 1U << static_cast<size_t>(method);
+        return *self;
+    }
+
+    template <typename... MethodArgs>
+    self_t& methods(boost::beast::http::verb method, MethodArgs... args_method)
+    {
+        self_t* self = static_cast<self_t*>(this);
+        methods(args_method...);
+        self->methodsBitfield |= 1U << static_cast<size_t>(method);
+        return *self;
+    }
+
+    template <typename... MethodArgs>
+    self_t& requires(std::initializer_list<const char*> l)
+    {
+        self_t* self = static_cast<self_t*>(this);
+        self->privilegesSet.emplace_back(l);
+        return *self;
+    }
+
+    template <typename... MethodArgs>
+    self_t& requires(const std::vector<redfish::Privileges>& p)
+    {
+        self_t* self = static_cast<self_t*>(this);
+        for (const redfish::Privileges& privilege : p)
+        {
+            self->privilegesSet.emplace_back(privilege);
+        }
+        return *self;
+    }
+};
+
+class DynamicRule : public BaseRule, public RuleParameterTraits<DynamicRule>
+{
+  public:
+    DynamicRule(std::string rule) : BaseRule(std::move(rule))
+    {
+    }
+
+    void validate() override
+    {
+        if (!erasedHandler)
+        {
+            throw std::runtime_error(nameStr + (!nameStr.empty() ? ": " : "") +
+                                     "no handler for url " + rule);
+        }
+    }
+
+    void handle(const Request& req, Response& res,
+                const RoutingParams& params) override
+    {
+        erasedHandler(req, res, params);
+    }
+
+    template <typename Func> void operator()(Func f)
+    {
+        using function_t = utility::function_traits<Func>;
+
+        erasedHandler =
+            wrap(std::move(f), black_magic::gen_seq<function_t::arity>());
+    }
+
+    // enable_if Arg1 == request && Arg2 == Response
+    // enable_if Arg1 == request && Arg2 != resposne
+    // enable_if Arg1 != request
+
+    template <typename Func, unsigned... Indices>
+
+    std::function<void(const Request&, Response&, const RoutingParams&)>
+        wrap(Func f, black_magic::Seq<Indices...>)
+    {
+        using function_t = utility::function_traits<Func>;
+
+        if (!black_magic::isParameterTagCompatible(
+                black_magic::getParameterTagRuntime(rule.c_str()),
+                black_magic::compute_parameter_tag_from_args_list<
+                    typename function_t::template arg<Indices>...>::value))
+        {
+            throw std::runtime_error("routeDynamic: Handler type is mismatched "
+                                     "with URL parameters: " +
+                                     rule);
+        }
+        auto ret = detail::routing_handler_call_helper::Wrapped<
+            Func, typename function_t::template arg<Indices>...>();
+        ret.template set<typename function_t::template arg<Indices>...>(
+            std::move(f));
+        return ret;
+    }
+
+    template <typename Func> void operator()(std::string name, Func&& f)
+    {
+        nameStr = std::move(name);
+        (*this).template operator()<Func>(std::forward(f));
+    }
+
+  private:
+    std::function<void(const Request&, Response&, const RoutingParams&)>
+        erasedHandler;
+};
+
+template <typename... Args>
+class TaggedRule : public BaseRule,
+                   public RuleParameterTraits<TaggedRule<Args...>>
+{
+  public:
+    using self_t = TaggedRule<Args...>;
+
+    TaggedRule(std::string ruleIn) : BaseRule(std::move(ruleIn))
+    {
+    }
+
+    void validate() override
+    {
+        if (!handler)
+        {
+            throw std::runtime_error(nameStr + (!nameStr.empty() ? ": " : "") +
+                                     "no handler for url " + rule);
+        }
+    }
+
+    template <typename Func>
+    typename std::enable_if<
+        black_magic::CallHelper<Func, black_magic::S<Args...>>::value,
+        void>::type
+        operator()(Func&& f)
+    {
+        static_assert(
+            black_magic::CallHelper<Func, black_magic::S<Args...>>::value ||
+                black_magic::CallHelper<
+                    Func, black_magic::S<crow::Request, Args...>>::value,
+            "Handler type is mismatched with URL parameters");
+        static_assert(
+            !std::is_same<void, decltype(f(std::declval<Args>()...))>::value,
+            "Handler function cannot have void return type; valid return "
+            "types: "
+            "string, int, crow::resposne, nlohmann::json");
+
+        handler = [f = std::move(f)](const Request&, Response& res,
+                                     Args... args) {
+            res.result(f(args...));
+            res.end();
+        };
+    }
+
+    template <typename Func>
+    typename std::enable_if<
+        !black_magic::CallHelper<Func, black_magic::S<Args...>>::value &&
+            black_magic::CallHelper<
+                Func, black_magic::S<crow::Request, Args...>>::value,
+        void>::type
+        operator()(Func&& f)
+    {
+        static_assert(
+            black_magic::CallHelper<Func, black_magic::S<Args...>>::value ||
+                black_magic::CallHelper<
+                    Func, black_magic::S<crow::Request, Args...>>::value,
+            "Handler type is mismatched with URL parameters");
+        static_assert(
+            !std::is_same<void, decltype(f(std::declval<crow::Request>(),
+                                           std::declval<Args>()...))>::value,
+            "Handler function cannot have void return type; valid return "
+            "types: "
+            "string, int, crow::resposne,nlohmann::json");
+
+        handler = [f = std::move(f)](const crow::Request& req,
+                                     crow::Response& res, Args... args) {
+            res.result(f(req, args...));
+            res.end();
+        };
+    }
+
+    template <typename Func>
+    typename std::enable_if<
+        !black_magic::CallHelper<Func, black_magic::S<Args...>>::value &&
+            !black_magic::CallHelper<
+                Func, black_magic::S<crow::Request, Args...>>::value,
+        void>::type
+        operator()(Func&& f)
+    {
+        static_assert(
+            black_magic::CallHelper<Func, black_magic::S<Args...>>::value ||
+                black_magic::CallHelper<
+                    Func, black_magic::S<crow::Request, Args...>>::value ||
+                black_magic::CallHelper<
+                    Func, black_magic::S<crow::Request, crow::Response&,
+                                         Args...>>::value,
+            "Handler type is mismatched with URL parameters");
+        static_assert(
+            std::is_same<void, decltype(f(std::declval<crow::Request>(),
+                                          std::declval<crow::Response&>(),
+                                          std::declval<Args>()...))>::value,
+            "Handler function with response argument should have void "
+            "return "
+            "type");
+
+        handler = std::move(f);
+    }
+
+    template <typename Func> void operator()(std::string name, Func&& f)
+    {
+        nameStr = std::move(name);
+        (*this).template operator()<Func>(std::forward(f));
+    }
+
+    void handle(const Request& req, Response& res,
+                const RoutingParams& params) override
+    {
+        detail::routing_handler_call_helper::Call<
+            detail::routing_handler_call_helper::CallParams<decltype(handler)>,
+            0, 0, 0, 0, black_magic::S<Args...>, black_magic::S<>>()(
+            detail::routing_handler_call_helper::CallParams<decltype(handler)>{
+                handler, params, req, res});
+    }
+
+  private:
+    std::function<void(const crow::Request&, crow::Response&, Args...)> handler;
+};
+
+const int ruleSpecialRedirectSlash = 1;
+
+class Trie
+{
+  public:
+    struct Node
+    {
+        unsigned ruleIndex{};
+        std::array<size_t, static_cast<size_t>(ParamType::MAX)>
+            paramChildrens{};
+        boost::container::flat_map<std::string, unsigned> children;
+
+        bool isSimpleNode() const
+        {
+            return !ruleIndex && std::all_of(std::begin(paramChildrens),
+                                             std::end(paramChildrens),
+                                             [](size_t x) { return !x; });
+        }
+    };
+
+    Trie() : nodes(1)
+    {
+    }
+
+  private:
+    void optimizeNode(Node* node)
+    {
+        for (size_t x : node->paramChildrens)
+        {
+            if (!x)
+                continue;
+            Node* child = &nodes[x];
+            optimizeNode(child);
+        }
+        if (node->children.empty())
+            return;
+        bool mergeWithChild = true;
+        for (const std::pair<std::string, unsigned>& kv : node->children)
+        {
+            Node* child = &nodes[kv.second];
+            if (!child->isSimpleNode())
+            {
+                mergeWithChild = false;
+                break;
+            }
+        }
+        if (mergeWithChild)
+        {
+            decltype(node->children) merged;
+            for (const std::pair<std::string, unsigned>& kv : node->children)
+            {
+                Node* child = &nodes[kv.second];
+                for (const std::pair<std::string, unsigned>& childKv :
+                     child->children)
+                {
+                    merged[kv.first + childKv.first] = childKv.second;
+                }
+            }
+            node->children = std::move(merged);
+            optimizeNode(node);
+        }
+        else
+        {
+            for (const std::pair<std::string, unsigned>& kv : node->children)
+            {
+                Node* child = &nodes[kv.second];
+                optimizeNode(child);
+            }
+        }
+    }
+
+    void optimize()
+    {
+        optimizeNode(head());
+    }
+
+  public:
+    void validate()
+    {
+        if (!head()->isSimpleNode())
+            throw std::runtime_error(
+                "Internal error: Trie header should be simple!");
+        optimize();
+    }
+
+    void findRouteIndexes(const std::string& req_url,
+                          std::vector<unsigned>& route_indexes,
+                          const Node* node = nullptr, unsigned pos = 0) const
+    {
+        if (node == nullptr)
+        {
+            node = head();
+        }
+        for (const std::pair<std::string, unsigned>& kv : node->children)
+        {
+            const std::string& fragment = kv.first;
+            const Node* child = &nodes[kv.second];
+            if (pos >= req_url.size())
+            {
+                if (child->ruleIndex != 0 && fragment != "/")
+                {
+                    route_indexes.push_back(child->ruleIndex);
+                }
+                findRouteIndexes(req_url, route_indexes, child,
+                                 static_cast<unsigned>(pos + fragment.size()));
+            }
+            else
+            {
+                if (req_url.compare(pos, fragment.size(), fragment) == 0)
+                {
+                    findRouteIndexes(
+                        req_url, route_indexes, child,
+                        static_cast<unsigned>(pos + fragment.size()));
+                }
+            }
+        }
+    }
+
+    std::pair<unsigned, RoutingParams>
+        find(const std::string_view req_url, const Node* node = nullptr,
+             size_t pos = 0, RoutingParams* params = nullptr) const
+    {
+        RoutingParams empty;
+        if (params == nullptr)
+            params = &empty;
+
+        unsigned found{};
+        RoutingParams matchParams;
+
+        if (node == nullptr)
+            node = head();
+        if (pos == req_url.size())
+            return {node->ruleIndex, *params};
+
+        auto updateFound =
+            [&found, &matchParams](std::pair<unsigned, RoutingParams>& ret) {
+                if (ret.first && (!found || found > ret.first))
+                {
+                    found = ret.first;
+                    matchParams = std::move(ret.second);
+                }
+            };
+
+        if (node->paramChildrens[static_cast<size_t>(ParamType::INT)])
+        {
+            char c = req_url[pos];
+            if ((c >= '0' && c <= '9') || c == '+' || c == '-')
+            {
+                char* eptr;
+                errno = 0;
+                long long int value =
+                    std::strtoll(req_url.data() + pos, &eptr, 10);
+                if (errno != ERANGE && eptr != req_url.data() + pos)
+                {
+                    params->intParams.push_back(value);
+                    std::pair<unsigned, RoutingParams> ret = find(
+                        req_url,
+                        &nodes[node->paramChildrens[static_cast<size_t>(
+                            ParamType::INT)]],
+                        static_cast<size_t>(eptr - req_url.data()), params);
+                    updateFound(ret);
+                    params->intParams.pop_back();
+                }
+            }
+        }
+
+        if (node->paramChildrens[static_cast<size_t>(ParamType::UINT)])
+        {
+            char c = req_url[pos];
+            if ((c >= '0' && c <= '9') || c == '+')
+            {
+                char* eptr;
+                errno = 0;
+                unsigned long long int value =
+                    std::strtoull(req_url.data() + pos, &eptr, 10);
+                if (errno != ERANGE && eptr != req_url.data() + pos)
+                {
+                    params->uintParams.push_back(value);
+                    std::pair<unsigned, RoutingParams> ret = find(
+                        req_url,
+                        &nodes[node->paramChildrens[static_cast<size_t>(
+                            ParamType::UINT)]],
+                        static_cast<size_t>(eptr - req_url.data()), params);
+                    updateFound(ret);
+                    params->uintParams.pop_back();
+                }
+            }
+        }
+
+        if (node->paramChildrens[static_cast<size_t>(ParamType::DOUBLE)])
+        {
+            char c = req_url[pos];
+            if ((c >= '0' && c <= '9') || c == '+' || c == '-' || c == '.')
+            {
+                char* eptr;
+                errno = 0;
+                double value = std::strtod(req_url.data() + pos, &eptr);
+                if (errno != ERANGE && eptr != req_url.data() + pos)
+                {
+                    params->doubleParams.push_back(value);
+                    std::pair<unsigned, RoutingParams> ret = find(
+                        req_url,
+                        &nodes[node->paramChildrens[static_cast<size_t>(
+                            ParamType::DOUBLE)]],
+                        static_cast<size_t>(eptr - req_url.data()), params);
+                    updateFound(ret);
+                    params->doubleParams.pop_back();
+                }
+            }
+        }
+
+        if (node->paramChildrens[static_cast<size_t>(ParamType::STRING)])
+        {
+            size_t epos = pos;
+            for (; epos < req_url.size(); epos++)
+            {
+                if (req_url[epos] == '/')
+                    break;
+            }
+
+            if (epos != pos)
+            {
+                params->stringParams.emplace_back(
+                    req_url.substr(pos, epos - pos));
+                std::pair<unsigned, RoutingParams> ret =
+                    find(req_url,
+                         &nodes[node->paramChildrens[static_cast<size_t>(
+                             ParamType::STRING)]],
+                         epos, params);
+                updateFound(ret);
+                params->stringParams.pop_back();
+            }
+        }
+
+        if (node->paramChildrens[static_cast<size_t>(ParamType::PATH)])
+        {
+            size_t epos = req_url.size();
+
+            if (epos != pos)
+            {
+                params->stringParams.emplace_back(
+                    req_url.substr(pos, epos - pos));
+                std::pair<unsigned, RoutingParams> ret =
+                    find(req_url,
+                         &nodes[node->paramChildrens[static_cast<size_t>(
+                             ParamType::PATH)]],
+                         epos, params);
+                updateFound(ret);
+                params->stringParams.pop_back();
+            }
+        }
+
+        for (const std::pair<std::string, unsigned>& kv : node->children)
+        {
+            const std::string& fragment = kv.first;
+            const Node* child = &nodes[kv.second];
+
+            if (req_url.compare(pos, fragment.size(), fragment) == 0)
+            {
+                std::pair<unsigned, RoutingParams> ret =
+                    find(req_url, child, pos + fragment.size(), params);
+                updateFound(ret);
+            }
+        }
+
+        return {found, matchParams};
+    }
+
+    void add(const std::string& url, unsigned ruleIndex)
+    {
+        size_t idx = 0;
+
+        for (unsigned i = 0; i < url.size(); i++)
+        {
+            char c = url[i];
+            if (c == '<')
+            {
+                const static std::array<std::pair<ParamType, std::string>, 7>
+                    paramTraits = {{
+                        {ParamType::INT, "<int>"},
+                        {ParamType::UINT, "<uint>"},
+                        {ParamType::DOUBLE, "<float>"},
+                        {ParamType::DOUBLE, "<double>"},
+                        {ParamType::STRING, "<str>"},
+                        {ParamType::STRING, "<string>"},
+                        {ParamType::PATH, "<path>"},
+                    }};
+
+                for (const std::pair<ParamType, std::string>& x : paramTraits)
+                {
+                    if (url.compare(i, x.second.size(), x.second) == 0)
+                    {
+                        size_t index = static_cast<size_t>(x.first);
+                        if (!nodes[idx].paramChildrens[index])
+                        {
+                            unsigned newNodeIdx = newNode();
+                            nodes[idx].paramChildrens[index] = newNodeIdx;
+                        }
+                        idx = nodes[idx].paramChildrens[index];
+                        i += static_cast<unsigned>(x.second.size());
+                        break;
+                    }
+                }
+
+                i--;
+            }
+            else
+            {
+                std::string piece(&c, 1);
+                if (!nodes[idx].children.count(piece))
+                {
+                    unsigned newNodeIdx = newNode();
+                    nodes[idx].children.emplace(piece, newNodeIdx);
+                }
+                idx = nodes[idx].children[piece];
+            }
+        }
+        if (nodes[idx].ruleIndex)
+            throw std::runtime_error("handler already exists for " + url);
+        nodes[idx].ruleIndex = ruleIndex;
+    }
+
+  private:
+    void debugNodePrint(Node* n, size_t level)
+    {
+        for (size_t i = 0; i < static_cast<size_t>(ParamType::MAX); i++)
+        {
+            if (n->paramChildrens[i])
+            {
+                BMCWEB_LOG_DEBUG << std::string(
+                    2U * level, ' ') /*<< "("<<n->paramChildrens[i]<<") "*/;
+                switch (static_cast<ParamType>(i))
+                {
+                    case ParamType::INT:
+                        BMCWEB_LOG_DEBUG << "<int>";
+                        break;
+                    case ParamType::UINT:
+                        BMCWEB_LOG_DEBUG << "<uint>";
+                        break;
+                    case ParamType::DOUBLE:
+                        BMCWEB_LOG_DEBUG << "<float>";
+                        break;
+                    case ParamType::STRING:
+                        BMCWEB_LOG_DEBUG << "<str>";
+                        break;
+                    case ParamType::PATH:
+                        BMCWEB_LOG_DEBUG << "<path>";
+                        break;
+                    default:
+                        BMCWEB_LOG_DEBUG << "<ERROR>";
+                        break;
+                }
+
+                debugNodePrint(&nodes[n->paramChildrens[i]], level + 1);
+            }
+        }
+        for (const std::pair<std::string, unsigned>& kv : n->children)
+        {
+            BMCWEB_LOG_DEBUG
+                << std::string(2U * level, ' ') /*<< "(" << kv.second << ") "*/
+                << kv.first;
+            debugNodePrint(&nodes[kv.second], level + 1);
+        }
+    }
+
+  public:
+    void debugPrint()
+    {
+        debugNodePrint(head(), 0U);
+    }
+
+  private:
+    const Node* head() const
+    {
+        return &nodes.front();
+    }
+
+    Node* head()
+    {
+        return &nodes.front();
+    }
+
+    unsigned newNode()
+    {
+        nodes.resize(nodes.size() + 1);
+        return static_cast<unsigned>(nodes.size() - 1);
+    }
+
+    std::vector<Node> nodes;
+};
+
+class Router
+{
+  public:
+    Router()
+    {
+    }
+
+    DynamicRule& newRuleDynamic(const std::string& rule)
+    {
+        std::unique_ptr<DynamicRule> ruleObject =
+            std::make_unique<DynamicRule>(rule);
+        DynamicRule* ptr = ruleObject.get();
+        allRules.emplace_back(std::move(ruleObject));
+
+        return *ptr;
+    }
+
+    template <uint64_t N>
+    typename black_magic::Arguments<N>::type::template rebind<TaggedRule>&
+        newRuleTagged(const std::string& rule)
+    {
+        using RuleT = typename black_magic::Arguments<N>::type::template rebind<
+            TaggedRule>;
+        std::unique_ptr<RuleT> ruleObject = std::make_unique<RuleT>(rule);
+        RuleT* ptr = ruleObject.get();
+        allRules.emplace_back(std::move(ruleObject));
+
+        return *ptr;
+    }
+
+    void internalAddRuleObject(const std::string& rule, BaseRule* ruleObject)
+    {
+        if (ruleObject == nullptr)
+        {
+            return;
+        }
+        for (uint32_t method = 0, method_bit = 1; method < maxHttpVerbCount;
+             method++, method_bit <<= 1)
+        {
+            if (ruleObject->methodsBitfield & method_bit)
+            {
+                perMethods[method].rules.emplace_back(ruleObject);
+                perMethods[method].trie.add(
+                    rule, static_cast<unsigned>(
+                              perMethods[method].rules.size() - 1U));
+                // directory case:
+                //   request to `/about' url matches `/about/' rule
+                if (rule.size() > 2 && rule.back() == '/')
+                {
+                    perMethods[method].trie.add(
+                        rule.substr(0, rule.size() - 1),
+                        static_cast<unsigned>(perMethods[method].rules.size() -
+                                              1));
+                }
+            }
+        }
+    }
+
+    void validate()
+    {
+        for (std::unique_ptr<BaseRule>& rule : allRules)
+        {
+            if (rule)
+            {
+                std::unique_ptr<BaseRule> upgraded = rule->upgrade();
+                if (upgraded)
+                    rule = std::move(upgraded);
+                rule->validate();
+                internalAddRuleObject(rule->rule, rule.get());
+            }
+        }
+        for (PerMethod& perMethod : perMethods)
+        {
+            perMethod.trie.validate();
+        }
+    }
+
+    template <typename Adaptor>
+    void handleUpgrade(const Request& req, Response& res, Adaptor&& adaptor)
+    {
+        if (static_cast<size_t>(req.method()) >= perMethods.size())
+            return;
+
+        PerMethod& perMethod = perMethods[static_cast<size_t>(req.method())];
+        Trie& trie = perMethod.trie;
+        std::vector<BaseRule*>& rules = perMethod.rules;
+
+        const std::pair<unsigned, RoutingParams>& found = trie.find(req.url);
+        unsigned ruleIndex = found.first;
+        if (!ruleIndex)
+        {
+            BMCWEB_LOG_DEBUG << "Cannot match rules " << req.url;
+            res.result(boost::beast::http::status::not_found);
+            res.end();
+            return;
+        }
+
+        if (ruleIndex >= rules.size())
+            throw std::runtime_error("Trie internal structure corrupted!");
+
+        if (ruleIndex == ruleSpecialRedirectSlash)
+        {
+            BMCWEB_LOG_INFO << "Redirecting to a url with trailing slash: "
+                            << req.url;
+            res.result(boost::beast::http::status::moved_permanently);
+
+            // TODO absolute url building
+            if (req.getHeaderValue("Host").empty())
+            {
+                res.addHeader("Location", std::string(req.url) + "/");
+            }
+            else
+            {
+                res.addHeader(
+                    "Location",
+                    req.isSecure
+                        ? "https://"
+                        : "http://" + std::string(req.getHeaderValue("Host")) +
+                              std::string(req.url) + "/");
+            }
+            res.end();
+            return;
+        }
+
+        if ((rules[ruleIndex]->getMethods() &
+             (1U << static_cast<size_t>(req.method()))) == 0)
+        {
+            BMCWEB_LOG_DEBUG << "Rule found but method mismatch: " << req.url
+                             << " with " << req.methodString() << "("
+                             << static_cast<uint32_t>(req.method()) << ") / "
+                             << rules[ruleIndex]->getMethods();
+            res.result(boost::beast::http::status::not_found);
+            res.end();
+            return;
+        }
+
+        BMCWEB_LOG_DEBUG << "Matched rule (upgrade) '" << rules[ruleIndex]->rule
+                         << "' " << static_cast<uint32_t>(req.method()) << " / "
+                         << rules[ruleIndex]->getMethods();
+
+        // any uncaught exceptions become 500s
+        try
+        {
+            rules[ruleIndex]->handleUpgrade(req, res, std::move(adaptor));
+        }
+        catch (std::exception& e)
+        {
+            BMCWEB_LOG_ERROR << "An uncaught exception occurred: " << e.what();
+            res.result(boost::beast::http::status::internal_server_error);
+            res.end();
+            return;
+        }
+        catch (...)
+        {
+            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();
+            return;
+        }
+    }
+
+    void handle(const Request& req, Response& res)
+    {
+        if (static_cast<size_t>(req.method()) >= perMethods.size())
+            return;
+        PerMethod& perMethod = perMethods[static_cast<size_t>(req.method())];
+        Trie& trie = perMethod.trie;
+        std::vector<BaseRule*>& rules = perMethod.rules;
+
+        const std::pair<unsigned, RoutingParams>& found = trie.find(req.url);
+
+        unsigned ruleIndex = found.first;
+
+        if (!ruleIndex)
+        {
+            // Check to see if this url exists at any verb
+            for (const PerMethod& p : perMethods)
+            {
+                const std::pair<unsigned, RoutingParams>& found =
+                    p.trie.find(req.url);
+                if (found.first > 0)
+                {
+                    res.result(boost::beast::http::status::method_not_allowed);
+                    res.end();
+                    return;
+                }
+            }
+            BMCWEB_LOG_DEBUG << "Cannot match rules " << req.url;
+            res.result(boost::beast::http::status::not_found);
+            res.end();
+            return;
+        }
+
+        if (ruleIndex >= rules.size())
+            throw std::runtime_error("Trie internal structure corrupted!");
+
+        if (ruleIndex == ruleSpecialRedirectSlash)
+        {
+            BMCWEB_LOG_INFO << "Redirecting to a url with trailing slash: "
+                            << req.url;
+            res.result(boost::beast::http::status::moved_permanently);
+
+            // TODO absolute url building
+            if (req.getHeaderValue("Host").empty())
+            {
+                res.addHeader("Location", std::string(req.url) + "/");
+            }
+            else
+            {
+                res.addHeader("Location",
+                              (req.isSecure ? "https://" : "http://") +
+                                  std::string(req.getHeaderValue("Host")) +
+                                  std::string(req.url) + "/");
+            }
+            res.end();
+            return;
+        }
+
+        if ((rules[ruleIndex]->getMethods() &
+             (1U << static_cast<uint32_t>(req.method()))) == 0)
+        {
+            BMCWEB_LOG_DEBUG << "Rule found but method mismatch: " << req.url
+                             << " with " << req.methodString() << "("
+                             << static_cast<uint32_t>(req.method()) << ") / "
+                             << rules[ruleIndex]->getMethods();
+            res.result(boost::beast::http::status::method_not_allowed);
+            res.end();
+            return;
+        }
+
+        BMCWEB_LOG_DEBUG << "Matched rule '" << rules[ruleIndex]->rule << "' "
+                         << static_cast<uint32_t>(req.method()) << " / "
+                         << rules[ruleIndex]->getMethods();
+
+        redfish::Privileges userPrivileges;
+        if (req.session != nullptr)
+        {
+            // Get the user role from the session.
+            const std::string& userRole =
+                persistent_data::UserRoleMap::getInstance().getUserRole(
+                    req.session->username);
+
+            BMCWEB_LOG_DEBUG << "USER ROLE=" << userRole;
+
+            // Get the user privileges from the role
+            userPrivileges = redfish::getUserPrivileges(userRole);
+        }
+
+        if (!rules[ruleIndex]->checkPrivileges(userPrivileges))
+        {
+            res.result(boost::beast::http::status::forbidden);
+            res.end();
+            return;
+        }
+
+        // any uncaught exceptions become 500s
+        try
+        {
+            rules[ruleIndex]->handle(req, res, found.second);
+        }
+        catch (std::exception& e)
+        {
+            BMCWEB_LOG_ERROR << "An uncaught exception occurred: " << e.what();
+            res.result(boost::beast::http::status::internal_server_error);
+            res.end();
+            return;
+        }
+        catch (...)
+        {
+            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();
+            return;
+        }
+    }
+
+    void debugPrint()
+    {
+        for (size_t i = 0; i < perMethods.size(); i++)
+        {
+            BMCWEB_LOG_DEBUG
+                << methodName(static_cast<boost::beast::http::verb>(i));
+            perMethods[i].trie.debugPrint();
+        }
+    }
+
+    std::vector<const std::string*> getRoutes(const std::string& parent)
+    {
+        std::vector<const std::string*> ret;
+
+        for (const PerMethod& pm : perMethods)
+        {
+            std::vector<unsigned> x;
+            pm.trie.findRouteIndexes(parent, x);
+            for (unsigned index : x)
+            {
+                ret.push_back(&pm.rules[index]->rule);
+            }
+        }
+        return ret;
+    }
+
+  private:
+    struct PerMethod
+    {
+        std::vector<BaseRule*> rules;
+        Trie trie;
+        // rule index 0, 1 has special meaning; preallocate it to avoid
+        // duplication.
+        PerMethod() : rules(2)
+        {
+        }
+    };
+    std::array<PerMethod, maxHttpVerbCount> perMethods;
+    std::vector<std::unique_ptr<BaseRule>> allRules;
+};
+} // namespace crow
diff --git a/http/timer_queue.h b/http/timer_queue.h
new file mode 100644
index 0000000..26eea13
--- /dev/null
+++ b/http/timer_queue.h
@@ -0,0 +1,78 @@
+#pragma once
+
+#include <boost/circular_buffer.hpp>
+#include <boost/circular_buffer/space_optimized.hpp>
+#include <chrono>
+#include <functional>
+
+#include "logging.h"
+
+namespace crow
+{
+namespace detail
+{
+// fast timer queue for fixed tick value.
+class TimerQueue
+{
+  public:
+    TimerQueue()
+    {
+        dq.set_capacity(100);
+    }
+
+    void cancel(size_t k)
+    {
+        size_t index = k - step;
+        if (index < dq.size())
+        {
+            dq[index].second = nullptr;
+        }
+    }
+
+    size_t add(std::function<void()> f)
+    {
+        dq.push_back(
+            std::make_pair(std::chrono::steady_clock::now(), std::move(f)));
+        size_t ret = step + dq.size() - 1;
+
+        BMCWEB_LOG_DEBUG << "timer add inside: " << this << ' ' << ret;
+        return ret;
+    }
+
+    void process()
+    {
+        auto now = std::chrono::steady_clock::now();
+        while (!dq.empty())
+        {
+            auto& x = dq.front();
+            if (now - x.first < std::chrono::seconds(5))
+            {
+                break;
+            }
+            if (x.second)
+            {
+                BMCWEB_LOG_DEBUG << "timer call: " << this << ' ' << step;
+                // we know that timer handlers are very simple currenty; call
+                // here
+                x.second();
+            }
+            dq.pop_front();
+            step++;
+        }
+    }
+
+  private:
+    using storage_type =
+        std::pair<std::chrono::time_point<std::chrono::steady_clock>,
+                  std::function<void()>>;
+
+    boost::circular_buffer_space_optimized<storage_type,
+                                           std::allocator<storage_type>>
+        dq{};
+
+    // boost::circular_buffer<storage_type> dq{20};
+    // std::deque<storage_type> dq{};
+    size_t step{};
+};
+} // namespace detail
+} // namespace crow
diff --git a/http/utility.h b/http/utility.h
new file mode 100644
index 0000000..d08d548
--- /dev/null
+++ b/http/utility.h
@@ -0,0 +1,753 @@
+#pragma once
+
+#include "nlohmann/json.hpp"
+
+#include <cstdint>
+#include <cstring>
+#include <functional>
+#include <regex>
+#include <stdexcept>
+#include <string>
+#include <tuple>
+
+namespace crow
+{
+namespace black_magic
+{
+struct OutOfRange
+{
+    OutOfRange(unsigned /*pos*/, unsigned /*length*/)
+    {
+    }
+};
+constexpr unsigned requiresInRange(unsigned i, unsigned len)
+{
+    return i >= len ? throw OutOfRange(i, len) : i;
+}
+
+class ConstStr
+{
+    const char* const beginPtr;
+    unsigned sizeUint;
+
+  public:
+    template <unsigned N>
+    constexpr ConstStr(const char (&arr)[N]) : beginPtr(arr), sizeUint(N - 1)
+    {
+        static_assert(N >= 1, "not a string literal");
+    }
+    constexpr char operator[](unsigned i) const
+    {
+        return requiresInRange(i, sizeUint), beginPtr[i];
+    }
+
+    constexpr operator const char*() const
+    {
+        return beginPtr;
+    }
+
+    constexpr const char* begin() const
+    {
+        return beginPtr;
+    }
+    constexpr const char* end() const
+    {
+        return beginPtr + sizeUint;
+    }
+
+    constexpr unsigned size() const
+    {
+        return sizeUint;
+    }
+};
+
+constexpr unsigned findClosingTag(ConstStr s, unsigned p)
+{
+    return s[p] == '>' ? p : findClosingTag(s, p + 1);
+}
+
+constexpr bool isValid(ConstStr s, unsigned i = 0, int f = 0)
+{
+    return i == s.size()
+               ? f == 0
+               : f < 0 || f >= 2
+                     ? false
+                     : s[i] == '<' ? isValid(s, i + 1, f + 1)
+                                   : s[i] == '>' ? isValid(s, i + 1, f - 1)
+                                                 : isValid(s, i + 1, f);
+}
+
+constexpr bool isEquP(const char* a, const char* b, unsigned n)
+{
+    return *a == 0 && *b == 0 && n == 0
+               ? true
+               : (*a == 0 || *b == 0)
+                     ? false
+                     : n == 0 ? true
+                              : *a != *b ? false : isEquP(a + 1, b + 1, n - 1);
+}
+
+constexpr bool isEquN(ConstStr a, unsigned ai, ConstStr b, unsigned bi,
+                      unsigned n)
+{
+    return ai + n > a.size() || bi + n > b.size()
+               ? false
+               : n == 0 ? true
+                        : a[ai] != b[bi] ? false
+                                         : isEquN(a, ai + 1, b, bi + 1, n - 1);
+}
+
+constexpr bool isInt(ConstStr s, unsigned i)
+{
+    return isEquN(s, i, "<int>", 0, 5);
+}
+
+constexpr bool isUint(ConstStr s, unsigned i)
+{
+    return isEquN(s, i, "<uint>", 0, 6);
+}
+
+constexpr bool isFloat(ConstStr s, unsigned i)
+{
+    return isEquN(s, i, "<float>", 0, 7) || isEquN(s, i, "<double>", 0, 8);
+}
+
+constexpr bool isStr(ConstStr s, unsigned i)
+{
+    return isEquN(s, i, "<str>", 0, 5) || isEquN(s, i, "<string>", 0, 8);
+}
+
+constexpr bool isPath(ConstStr s, unsigned i)
+{
+    return isEquN(s, i, "<path>", 0, 6);
+}
+
+template <typename T> struct parameter_tag
+{
+    static const int value = 0;
+};
+#define BMCWEB_INTERNAL_PARAMETER_TAG(t, i)                                    \
+    template <> struct parameter_tag<t>                                        \
+    {                                                                          \
+        static const int value = i;                                            \
+    }
+BMCWEB_INTERNAL_PARAMETER_TAG(int, 1);
+BMCWEB_INTERNAL_PARAMETER_TAG(char, 1);
+BMCWEB_INTERNAL_PARAMETER_TAG(short, 1);
+BMCWEB_INTERNAL_PARAMETER_TAG(long, 1);
+BMCWEB_INTERNAL_PARAMETER_TAG(long long, 1);
+BMCWEB_INTERNAL_PARAMETER_TAG(unsigned int, 2);
+BMCWEB_INTERNAL_PARAMETER_TAG(unsigned char, 2);
+BMCWEB_INTERNAL_PARAMETER_TAG(unsigned short, 2);
+BMCWEB_INTERNAL_PARAMETER_TAG(unsigned long, 2);
+BMCWEB_INTERNAL_PARAMETER_TAG(unsigned long long, 2);
+BMCWEB_INTERNAL_PARAMETER_TAG(double, 3);
+BMCWEB_INTERNAL_PARAMETER_TAG(std::string, 4);
+#undef BMCWEB_INTERNAL_PARAMETER_TAG
+template <typename... Args> struct compute_parameter_tag_from_args_list;
+
+template <> struct compute_parameter_tag_from_args_list<>
+{
+    static const int value = 0;
+};
+
+template <typename Arg, typename... Args>
+struct compute_parameter_tag_from_args_list<Arg, Args...>
+{
+    static const int subValue =
+        compute_parameter_tag_from_args_list<Args...>::value;
+    static const int value =
+        parameter_tag<typename std::decay<Arg>::type>::value
+            ? subValue * 6 +
+                  parameter_tag<typename std::decay<Arg>::type>::value
+            : subValue;
+};
+
+static inline bool isParameterTagCompatible(uint64_t a, uint64_t b)
+{
+    if (a == 0)
+    {
+        return b == 0;
+    }
+    if (b == 0)
+    {
+        return a == 0;
+    }
+    uint64_t sa = a % 6;
+    uint64_t sb = a % 6;
+    if (sa == 5)
+    {
+        sa = 4;
+    }
+    if (sb == 5)
+    {
+        sb = 4;
+    }
+    if (sa != sb)
+    {
+        return false;
+    }
+    return isParameterTagCompatible(a / 6, b / 6);
+}
+
+static inline unsigned findClosingTagRuntime(const char* s, unsigned p)
+{
+    return s[p] == 0 ? throw std::runtime_error("unmatched tag <")
+                     : s[p] == '>' ? p : findClosingTagRuntime(s, p + 1);
+}
+
+static inline uint64_t getParameterTagRuntime(const char* s, unsigned p = 0)
+{
+    return s[p] == 0
+               ? 0
+               : s[p] == '<'
+                     ? (std::strncmp(s + p, "<int>", 5) == 0
+                            ? getParameterTagRuntime(
+                                  s, findClosingTagRuntime(s, p)) *
+                                      6 +
+                                  1
+                            : std::strncmp(s + p, "<uint>", 6) == 0
+                                  ? getParameterTagRuntime(
+                                        s, findClosingTagRuntime(s, p)) *
+                                            6 +
+                                        2
+                                  : (std::strncmp(s + p, "<float>", 7) == 0 ||
+                                     std::strncmp(s + p, "<double>", 8) == 0)
+                                        ? getParameterTagRuntime(
+                                              s, findClosingTagRuntime(s, p)) *
+                                                  6 +
+                                              3
+                                        : (std::strncmp(s + p, "<str>", 5) ==
+                                               0 ||
+                                           std::strncmp(s + p, "<string>", 8) ==
+                                               0)
+                                              ? getParameterTagRuntime(
+                                                    s, findClosingTagRuntime(
+                                                           s, p)) *
+                                                        6 +
+                                                    4
+                                              : std::strncmp(s + p, "<path>",
+                                                             6) == 0
+                                                    ? getParameterTagRuntime(
+                                                          s,
+                                                          findClosingTagRuntime(
+                                                              s, p)) *
+                                                              6 +
+                                                          5
+                                                    : throw std::runtime_error(
+                                                          "invalid parameter "
+                                                          "type"))
+                     : getParameterTagRuntime(s, p + 1);
+}
+
+constexpr uint64_t get_parameter_tag(ConstStr s, unsigned p = 0)
+{
+    return p == s.size()
+               ? 0
+               : s[p] == '<'
+                     ? (isInt(s, p)
+                            ? get_parameter_tag(s, findClosingTag(s, p)) * 6 + 1
+                            : isUint(s, p)
+                                  ? get_parameter_tag(s, findClosingTag(s, p)) *
+                                            6 +
+                                        2
+                                  : isFloat(s, p)
+                                        ? get_parameter_tag(
+                                              s, findClosingTag(s, p)) *
+                                                  6 +
+                                              3
+                                        : isStr(s, p)
+                                              ? get_parameter_tag(
+                                                    s, findClosingTag(s, p)) *
+                                                        6 +
+                                                    4
+                                              : isPath(s, p)
+                                                    ? get_parameter_tag(
+                                                          s, findClosingTag(
+                                                                 s, p)) *
+                                                              6 +
+                                                          5
+                                                    : throw std::runtime_error(
+                                                          "invalid parameter "
+                                                          "type"))
+                     : get_parameter_tag(s, p + 1);
+}
+
+template <typename... T> struct S
+{
+    template <typename U> using push = S<U, T...>;
+    template <typename U> using push_back = S<T..., U>;
+    template <template <typename... Args> class U> using rebind = U<T...>;
+};
+template <typename F, typename Set> struct CallHelper;
+template <typename F, typename... Args> struct CallHelper<F, S<Args...>>
+{
+    template <typename F1, typename... Args1,
+              typename = decltype(std::declval<F1>()(std::declval<Args1>()...))>
+    static char __test(int);
+
+    template <typename...> static int __test(...);
+
+    static constexpr bool value = sizeof(__test<F, Args...>(0)) == sizeof(char);
+};
+
+template <uint64_t N> struct SingleTagToType
+{
+};
+
+template <> struct SingleTagToType<1>
+{
+    using type = int64_t;
+};
+
+template <> struct SingleTagToType<2>
+{
+    using type = uint64_t;
+};
+
+template <> struct SingleTagToType<3>
+{
+    using type = double;
+};
+
+template <> struct SingleTagToType<4>
+{
+    using type = std::string;
+};
+
+template <> struct SingleTagToType<5>
+{
+    using type = std::string;
+};
+
+template <uint64_t Tag> struct Arguments
+{
+    using subarguments = typename Arguments<Tag / 6>::type;
+    using type = typename subarguments::template push<
+        typename SingleTagToType<Tag % 6>::type>;
+};
+
+template <> struct Arguments<0>
+{
+    using type = S<>;
+};
+
+template <typename... T> struct LastElementType
+{
+    using type =
+        typename std::tuple_element<sizeof...(T) - 1, std::tuple<T...>>::type;
+};
+
+template <> struct LastElementType<>
+{
+};
+
+// from
+// http://stackoverflow.com/questions/13072359/c11-compile-time-array-with-logarithmic-evaluation-depth
+template <class T> using Invoke = typename T::type;
+
+template <unsigned...> struct Seq
+{
+    using type = Seq;
+};
+
+template <class S1, class S2> struct concat;
+
+template <unsigned... I1, unsigned... I2>
+struct concat<Seq<I1...>, Seq<I2...>> : Seq<I1..., (sizeof...(I1) + I2)...>
+{
+};
+
+template <class S1, class S2> using Concat = Invoke<concat<S1, S2>>;
+
+template <size_t N> struct gen_seq;
+template <size_t N> using GenSeq = Invoke<gen_seq<N>>;
+
+template <size_t N> struct gen_seq : Concat<GenSeq<N / 2>, GenSeq<N - N / 2>>
+{
+};
+
+template <> struct gen_seq<0> : Seq<>
+{
+};
+template <> struct gen_seq<1> : Seq<0>
+{
+};
+
+template <typename Seq, typename Tuple> struct PopBackHelper;
+
+template <unsigned... N, typename Tuple> struct PopBackHelper<Seq<N...>, Tuple>
+{
+    template <template <typename... Args> class U>
+    using rebind = U<typename std::tuple_element<N, Tuple>::type...>;
+};
+
+template <typename... T>
+struct PopBack //: public PopBackHelper<typename
+               // gen_seq<sizeof...(T)-1>::type, std::tuple<T...>>
+{
+    template <template <typename... Args> class U>
+    using rebind =
+        typename PopBackHelper<typename gen_seq<sizeof...(T) - 1UL>::type,
+                               std::tuple<T...>>::template rebind<U>;
+};
+
+template <> struct PopBack<>
+{
+    template <template <typename... Args> class U> using rebind = U<>;
+};
+
+// from
+// http://stackoverflow.com/questions/2118541/check-if-c0x-parameter-pack-contains-a-type
+template <typename Tp, typename... List> struct Contains : std::true_type
+{
+};
+
+template <typename Tp, typename Head, typename... Rest>
+struct Contains<Tp, Head, Rest...>
+    : std::conditional<std::is_same<Tp, Head>::value, std::true_type,
+                       Contains<Tp, Rest...>>::type
+{
+};
+
+template <typename Tp> struct Contains<Tp> : std::false_type
+{
+};
+
+template <typename T> struct EmptyContext
+{
+};
+
+template <typename T> struct promote
+{
+    using type = T;
+};
+
+#define BMCWEB_INTERNAL_PROMOTE_TYPE(t1, t2)                                   \
+    template <> struct promote<t1>                                             \
+    {                                                                          \
+        using type = t2;                                                       \
+    }
+
+BMCWEB_INTERNAL_PROMOTE_TYPE(char, int64_t);
+BMCWEB_INTERNAL_PROMOTE_TYPE(short, int64_t);
+BMCWEB_INTERNAL_PROMOTE_TYPE(int, int64_t);
+BMCWEB_INTERNAL_PROMOTE_TYPE(long, int64_t);
+BMCWEB_INTERNAL_PROMOTE_TYPE(long long, int64_t);
+BMCWEB_INTERNAL_PROMOTE_TYPE(unsigned char, uint64_t);
+BMCWEB_INTERNAL_PROMOTE_TYPE(unsigned short, uint64_t);
+BMCWEB_INTERNAL_PROMOTE_TYPE(unsigned int, uint64_t);
+BMCWEB_INTERNAL_PROMOTE_TYPE(unsigned long, uint64_t);
+BMCWEB_INTERNAL_PROMOTE_TYPE(unsigned long long, uint64_t);
+BMCWEB_INTERNAL_PROMOTE_TYPE(float, double);
+#undef BMCWEB_INTERNAL_PROMOTE_TYPE
+
+template <typename T> using promote_t = typename promote<T>::type;
+
+} // namespace black_magic
+
+namespace detail
+{
+
+template <class T, std::size_t N, class... Args>
+struct GetIndexOfElementFromTupleByTypeImpl
+{
+    static constexpr std::size_t value = N;
+};
+
+template <class T, std::size_t N, class... Args>
+struct GetIndexOfElementFromTupleByTypeImpl<T, N, T, Args...>
+{
+    static constexpr std::size_t value = N;
+};
+
+template <class T, std::size_t N, class U, class... Args>
+struct GetIndexOfElementFromTupleByTypeImpl<T, N, U, Args...>
+{
+    static constexpr std::size_t value =
+        GetIndexOfElementFromTupleByTypeImpl<T, N + 1, Args...>::value;
+};
+
+} // namespace detail
+
+namespace utility
+{
+template <class T, class... Args> T& getElementByType(std::tuple<Args...>& t)
+{
+    return std::get<
+        detail::GetIndexOfElementFromTupleByTypeImpl<T, 0, Args...>::value>(t);
+}
+
+template <typename T> struct function_traits;
+
+template <typename T>
+struct function_traits : public function_traits<decltype(&T::operator())>
+{
+    using parent_t = function_traits<decltype(&T::operator())>;
+    static const size_t arity = parent_t::arity;
+    using result_type = typename parent_t::result_type;
+    template <size_t i> using arg = typename parent_t::template arg<i>;
+};
+
+template <typename ClassType, typename r, typename... Args>
+struct function_traits<r (ClassType::*)(Args...) const>
+{
+    static const size_t arity = sizeof...(Args);
+
+    using result_type = r;
+
+    template <size_t i>
+    using arg = typename std::tuple_element<i, std::tuple<Args...>>::type;
+};
+
+template <typename ClassType, typename r, typename... Args>
+struct function_traits<r (ClassType::*)(Args...)>
+{
+    static const size_t arity = sizeof...(Args);
+
+    using result_type = r;
+
+    template <size_t i>
+    using arg = typename std::tuple_element<i, std::tuple<Args...>>::type;
+};
+
+template <typename r, typename... Args>
+struct function_traits<std::function<r(Args...)>>
+{
+    static const size_t arity = sizeof...(Args);
+
+    using result_type = r;
+
+    template <size_t i>
+    using arg = typename std::tuple_element<i, std::tuple<Args...>>::type;
+};
+
+inline static std::string base64encode(
+    const char* data, size_t size,
+    const char* key =
+        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")
+{
+    std::string ret;
+    ret.resize((size + 2) / 3 * 4);
+    auto it = ret.begin();
+    while (size >= 3)
+    {
+        *it++ = key[(static_cast<unsigned char>(*data) & 0xFC) >> 2];
+        unsigned char h = static_cast<unsigned char>(
+            (static_cast<unsigned char>(*data++) & 0x03u) << 4u);
+        *it++ = key[h | ((static_cast<unsigned char>(*data) & 0xF0) >> 4)];
+        h = static_cast<unsigned char>(
+            (static_cast<unsigned char>(*data++) & 0x0F) << 2u);
+        *it++ = key[h | ((static_cast<unsigned char>(*data) & 0xC0) >> 6)];
+        *it++ = key[static_cast<unsigned char>(*data++) & 0x3F];
+
+        size -= 3;
+    }
+    if (size == 1)
+    {
+        *it++ = key[(static_cast<unsigned char>(*data) & 0xFC) >> 2];
+        unsigned char h = static_cast<unsigned char>(
+            (static_cast<unsigned char>(*data++) & 0x03) << 4u);
+        *it++ = key[h];
+        *it++ = '=';
+        *it++ = '=';
+    }
+    else if (size == 2)
+    {
+        *it++ = key[(static_cast<unsigned char>(*data) & 0xFC) >> 2];
+        unsigned char h = static_cast<unsigned char>(
+            (static_cast<unsigned char>(*data++) & 0x03) << 4u);
+        *it++ = key[h | ((static_cast<unsigned char>(*data) & 0xF0) >> 4)];
+        h = static_cast<unsigned char>(
+            (static_cast<unsigned char>(*data++) & 0x0F) << 2u);
+        *it++ = key[h];
+        *it++ = '=';
+    }
+    return ret;
+}
+
+inline static std::string base64encodeUrlsafe(const char* data, size_t size)
+{
+    return base64encode(
+        data, size,
+        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_");
+}
+
+// TODO this is temporary and should be deleted once base64 is refactored out of
+// crow
+inline bool base64Decode(const std::string_view input, std::string& output)
+{
+    static const char nop = static_cast<char>(-1);
+    // See note on encoding_data[] in above function
+    static const char decodingData[] = {
+        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
+        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
+        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
+        nop, 62,  nop, nop, nop, 63,  52,  53,  54,  55,  56,  57,  58,  59,
+        60,  61,  nop, nop, nop, nop, nop, nop, nop, 0,   1,   2,   3,   4,
+        5,   6,   7,   8,   9,   10,  11,  12,  13,  14,  15,  16,  17,  18,
+        19,  20,  21,  22,  23,  24,  25,  nop, nop, nop, nop, nop, nop, 26,
+        27,  28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,
+        41,  42,  43,  44,  45,  46,  47,  48,  49,  50,  51,  nop, nop, nop,
+        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
+        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
+        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
+        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
+        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
+        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
+        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
+        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
+        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
+        nop, nop, nop, nop};
+
+    size_t inputLength = input.size();
+
+    // allocate space for output string
+    output.clear();
+    output.reserve(((inputLength + 2) / 3) * 4);
+
+    // for each 4-bytes sequence from the input, extract 4 6-bits sequences by
+    // droping first two bits
+    // and regenerate into 3 8-bits sequences
+
+    for (size_t i = 0; i < inputLength; i++)
+    {
+        char base64code0;
+        char base64code1;
+        char base64code2 = 0; // initialized to 0 to suppress warnings
+        char base64code3;
+
+        base64code0 = decodingData[static_cast<int>(input[i])]; // NOLINT
+        if (base64code0 == nop)
+        { // non base64 character
+            return false;
+        }
+        if (!(++i < inputLength))
+        { // we need at least two input bytes for first
+          // byte output
+            return false;
+        }
+        base64code1 = decodingData[static_cast<int>(input[i])]; // NOLINT
+        if (base64code1 == nop)
+        { // non base64 character
+            return false;
+        }
+        output +=
+            static_cast<char>((base64code0 << 2) | ((base64code1 >> 4) & 0x3));
+
+        if (++i < inputLength)
+        {
+            char c = input[i];
+            if (c == '=')
+            { // padding , end of input
+                return (base64code1 & 0x0f) == 0;
+            }
+            base64code2 = decodingData[static_cast<int>(input[i])]; // NOLINT
+            if (base64code2 == nop)
+            { // non base64 character
+                return false;
+            }
+            output += static_cast<char>(((base64code1 << 4) & 0xf0) |
+                                        ((base64code2 >> 2) & 0x0f));
+        }
+
+        if (++i < inputLength)
+        {
+            char c = input[i];
+            if (c == '=')
+            { // padding , end of input
+                return (base64code2 & 0x03) == 0;
+            }
+            base64code3 = decodingData[static_cast<int>(input[i])]; // NOLINT
+            if (base64code3 == nop)
+            { // non base64 character
+                return false;
+            }
+            output +=
+                static_cast<char>((((base64code2 << 6) & 0xc0) | base64code3));
+        }
+    }
+
+    return true;
+}
+
+inline void escapeHtml(std::string& data)
+{
+    std::string buffer;
+    // less than 5% of characters should be larger, so reserve a buffer of the
+    // right size
+    buffer.reserve(data.size() * 11 / 10);
+    for (size_t pos = 0; pos != data.size(); ++pos)
+    {
+        switch (data[pos])
+        {
+            case '&':
+                buffer.append("&amp;");
+                break;
+            case '\"':
+                buffer.append("&quot;");
+                break;
+            case '\'':
+                buffer.append("&apos;");
+                break;
+            case '<':
+                buffer.append("&lt;");
+                break;
+            case '>':
+                buffer.append("&gt;");
+                break;
+            default:
+                buffer.append(&data[pos], 1);
+                break;
+        }
+    }
+    data.swap(buffer);
+}
+
+inline void convertToLinks(std::string& s)
+{
+    const static std::regex r{"(&quot;@odata\\.((id)|(Context))&quot;[ \\n]*:[ "
+                              "\\n]*)(&quot;((?!&quot;).*)&quot;)"};
+    s = std::regex_replace(s, r, "$1<a href=\"$6\">$5</a>");
+
+    const static std::regex nextLink{
+        "(&quot;Members@odata\\.((nextLink))&quot;[ \\n]*:[ "
+        "\\n]*)(&quot;((?!&quot;).*)&quot;)"};
+    s = std::regex_replace(s, nextLink, "$1<a href=\"$5\">$4</a>");
+
+    const static std::regex uri{"(&quot;((Uri))&quot;[ \\n]*:[ "
+                                "\\n]*)(&quot;((?!&quot;).*)&quot;)"};
+    s = std::regex_replace(s, uri, "$1<a href=\"$5\">$4</a>");
+}
+
+/**
+ * Method returns Date Time information according to requested format
+ *
+ * @param[in] time time in second since the Epoch
+ *
+ * @return Date Time according to requested format
+ */
+inline std::string getDateTime(const std::time_t& time)
+{
+    std::array<char, 128> dateTime;
+    std::string redfishDateTime("0000-00-00T00:00:00Z00:00");
+
+    if (std::strftime(dateTime.begin(), dateTime.size(), "%FT%T%z",
+                      std::localtime(&time)))
+    {
+        // insert the colon required by the ISO 8601 standard
+        redfishDateTime = std::string(dateTime.data());
+        redfishDateTime.insert(redfishDateTime.end() - 2, ':');
+    }
+
+    return redfishDateTime;
+}
+
+inline std::string dateTimeNow()
+{
+    std::time_t time = std::time(nullptr);
+    return getDateTime(time);
+}
+
+} // namespace utility
+} // namespace crow
diff --git a/http/websocket.h b/http/websocket.h
new file mode 100644
index 0000000..61b3e5a
--- /dev/null
+++ b/http/websocket.h
@@ -0,0 +1,250 @@
+#pragma once
+#include <array>
+#include <boost/algorithm/string/predicate.hpp>
+#include <boost/asio/buffer.hpp>
+#include <boost/beast/websocket.hpp>
+#include <functional>
+
+#include "http_request.h"
+
+#ifdef BMCWEB_ENABLE_SSL
+#include <boost/beast/websocket/ssl.hpp>
+#endif
+
+namespace crow
+{
+namespace websocket
+{
+struct Connection : std::enable_shared_from_this<Connection>
+{
+  public:
+    explicit Connection(const crow::Request& reqIn) :
+        req(reqIn), userdataPtr(nullptr){};
+
+    virtual void sendBinary(const std::string_view msg) = 0;
+    virtual void sendBinary(std::string&& msg) = 0;
+    virtual void sendText(const std::string_view msg) = 0;
+    virtual void sendText(std::string&& msg) = 0;
+    virtual void close(const std::string_view msg = "quit") = 0;
+    virtual boost::asio::io_context& get_io_context() = 0;
+    virtual ~Connection() = default;
+
+    void userdata(void* u)
+    {
+        userdataPtr = u;
+    }
+    void* userdata()
+    {
+        return userdataPtr;
+    }
+
+    crow::Request req;
+
+  private:
+    void* userdataPtr;
+};
+
+template <typename Adaptor> class ConnectionImpl : public Connection
+{
+  public:
+    ConnectionImpl(
+        const crow::Request& reqIn, Adaptor adaptorIn,
+        std::function<void(Connection&)> open_handler,
+        std::function<void(Connection&, const std::string&, bool)>
+            message_handler,
+        std::function<void(Connection&, const std::string&)> close_handler,
+        std::function<void(Connection&)> error_handler) :
+        Connection(reqIn),
+        ws(std::move(adaptorIn)), inString(), inBuffer(inString, 131088),
+        openHandler(std::move(open_handler)),
+        messageHandler(std::move(message_handler)),
+        closeHandler(std::move(close_handler)),
+        errorHandler(std::move(error_handler))
+    {
+        BMCWEB_LOG_DEBUG << "Creating new connection " << this;
+    }
+
+    boost::asio::io_context& get_io_context() override
+    {
+        return static_cast<boost::asio::io_context&>(
+            ws.get_executor().context());
+    }
+
+    void start()
+    {
+        BMCWEB_LOG_DEBUG << "starting connection " << this;
+
+        using bf = boost::beast::http::field;
+
+        std::string_view protocol =
+            req.getHeaderValue(bf::sec_websocket_protocol);
+
+        // Perform the websocket upgrade
+        ws.async_accept_ex(
+            req.req,
+            [protocol{std::string(protocol)}](
+                boost::beast::websocket::response_type& m) {
+                if (!protocol.empty())
+                {
+                    m.insert(bf::sec_websocket_protocol, protocol);
+                }
+
+                m.insert(bf::strict_transport_security, "max-age=31536000; "
+                                                        "includeSubdomains; "
+                                                        "preload");
+                m.insert(bf::pragma, "no-cache");
+                m.insert(bf::cache_control, "no-Store,no-Cache");
+                m.insert("Content-Security-Policy", "default-src 'self'");
+                m.insert("X-XSS-Protection", "1; "
+                                             "mode=block");
+                m.insert("X-Content-Type-Options", "nosniff");
+            },
+            [this, self(shared_from_this())](boost::system::error_code ec) {
+                if (ec)
+                {
+                    BMCWEB_LOG_ERROR << "Error in ws.async_accept " << ec;
+                    return;
+                }
+                acceptDone();
+            });
+    }
+
+    void sendBinary(const std::string_view msg) override
+    {
+        ws.binary(true);
+        outBuffer.emplace_back(msg);
+        doWrite();
+    }
+
+    void sendBinary(std::string&& msg) override
+    {
+        ws.binary(true);
+        outBuffer.emplace_back(std::move(msg));
+        doWrite();
+    }
+
+    void sendText(const std::string_view msg) override
+    {
+        ws.text(true);
+        outBuffer.emplace_back(msg);
+        doWrite();
+    }
+
+    void sendText(std::string&& msg) override
+    {
+        ws.text(true);
+        outBuffer.emplace_back(std::move(msg));
+        doWrite();
+    }
+
+    void close(const std::string_view msg) override
+    {
+        ws.async_close(
+            boost::beast::websocket::close_code::normal,
+            [self(shared_from_this())](boost::system::error_code ec) {
+                if (ec == boost::asio::error::operation_aborted)
+                {
+                    return;
+                }
+                if (ec)
+                {
+                    BMCWEB_LOG_ERROR << "Error closing websocket " << ec;
+                    return;
+                }
+            });
+    }
+
+    void acceptDone()
+    {
+        BMCWEB_LOG_DEBUG << "Websocket accepted connection";
+
+        if (openHandler)
+        {
+            openHandler(*this);
+        }
+        doRead();
+    }
+
+    void doRead()
+    {
+        ws.async_read(inBuffer,
+                      [this, self(shared_from_this())](
+                          boost::beast::error_code ec, std::size_t bytes_read) {
+                          if (ec)
+                          {
+                              if (ec != boost::beast::websocket::error::closed)
+                              {
+                                  BMCWEB_LOG_ERROR << "doRead error " << ec;
+                              }
+                              if (closeHandler)
+                              {
+                                  std::string_view reason = ws.reason().reason;
+                                  closeHandler(*this, std::string(reason));
+                              }
+                              return;
+                          }
+                          if (messageHandler)
+                          {
+                              messageHandler(*this, inString, ws.got_text());
+                          }
+                          inBuffer.consume(bytes_read);
+                          inString.clear();
+                          doRead();
+                      });
+    }
+
+    void doWrite()
+    {
+        // If we're already doing a write, ignore the request, it will be picked
+        // up when the current write is complete
+        if (doingWrite)
+        {
+            return;
+        }
+
+        if (outBuffer.empty())
+        {
+            // Done for now
+            return;
+        }
+        doingWrite = true;
+        ws.async_write(
+            boost::asio::buffer(outBuffer.front()),
+            [this, self(shared_from_this())](boost::beast::error_code ec,
+                                             std::size_t bytes_written) {
+                doingWrite = false;
+                outBuffer.erase(outBuffer.begin());
+                if (ec == boost::beast::websocket::error::closed)
+                {
+                    // Do nothing here.  doRead handler will call the
+                    // closeHandler.
+                    close("Write error");
+                    return;
+                }
+                if (ec)
+                {
+                    BMCWEB_LOG_ERROR << "Error in ws.async_write " << ec;
+                    return;
+                }
+                doWrite();
+            });
+    }
+
+  private:
+    boost::beast::websocket::stream<Adaptor> ws;
+
+    std::string inString;
+    boost::asio::dynamic_string_buffer<std::string::value_type,
+                                       std::string::traits_type,
+                                       std::string::allocator_type>
+        inBuffer;
+    std::vector<std::string> outBuffer;
+    bool doingWrite = false;
+
+    std::function<void(Connection&)> openHandler;
+    std::function<void(Connection&, const std::string&, bool)> messageHandler;
+    std::function<void(Connection&, const std::string&)> closeHandler;
+    std::function<void(Connection&)> errorHandler;
+};
+} // namespace websocket
+} // namespace crow
