diff --git a/crow/include/crow.h b/crow/include/crow.h
index edc0d7f..7e31cf3 100644
--- a/crow/include/crow.h
+++ b/crow/include/crow.h
@@ -1,4 +1,6 @@
 #pragma once
+#include "boost/beast/core.hpp"
+
 #include "crow/app.h"
 #include "crow/common.h"
 #include "crow/http_connection.h"
@@ -13,4 +15,3 @@
 #include "crow/timer_queue.h"
 #include "crow/utility.h"
 #include "crow/websocket.h"
-#include "boost/beast/core.hpp"
diff --git a/crow/include/crow/app.h b/crow/include/crow/app.h
index 78d99df..7051ec8 100644
--- a/crow/include/crow/app.h
+++ b/crow/include/crow/app.h
@@ -7,6 +7,7 @@
 #include <memory>
 #include <string>
 #include <utility>
+
 #include "crow/http_request.h"
 #include "crow/http_server.h"
 #include "crow/logging.h"
@@ -14,198 +15,236 @@
 #include "crow/routing.h"
 #include "crow/utility.h"
 
-#define BMCWEB_ROUTE(app, url) \
-  app.template route<crow::black_magic::get_parameter_tag(url)>(url)
+#define BMCWEB_ROUTE(app, url)                                                 \
+    app.template route<crow::black_magic::get_parameter_tag(url)>(url)
 
-namespace crow {
+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;
-  using server_t = Server<Crow, SocketAdaptor, Middlewares...>;
+template <typename... Middlewares> class Crow
+{
+  public:
+    using self_t = Crow;
+    using server_t = Server<Crow, SocketAdaptor, Middlewares...>;
 #ifdef BMCWEB_ENABLE_SSL
-  using ssl_server_t = Server<Crow, SSLAdaptor, Middlewares...>;
+    using ssl_server_t = Server<Crow, SSLAdaptor, Middlewares...>;
 #endif
-  explicit Crow(std::shared_ptr<boost::asio::io_service> io =
-                    std::make_shared<boost::asio::io_service>())
-      : io(std::move(io)) {}
-  ~Crow() { this->stop(); }
-
-  template <typename Adaptor>
-  void handleUpgrade(const Request& req, Response& res, Adaptor&& adaptor) {
-    router.handleUpgrade(req, res, 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) -> typename std::result_of<
-      decltype (&Router::newRuleTagged<Tag>)(Router, std::string&&)>::type {
-    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 (useSsl) {
-      if (-1 == socketFd) {
-        sslServer = std::move(std::make_unique<ssl_server_t>(
-            this, bindaddrStr, portUint, &middlewares, &sslContext, io));
-      } else {
-        sslServer = std::move(std::make_unique<ssl_server_t>(
-            this, socketFd, &middlewares, &sslContext, io));
-      }
-      sslServer->setTickFunction(tickInterval, tickFunction);
-      sslServer->run();
-    } else
-#endif
+    explicit Crow(std::shared_ptr<boost::asio::io_service> io =
+                      std::make_shared<boost::asio::io_service>()) :
+        io(std::move(io))
     {
-      if (-1 == socketFd) {
-        server = std::move(std::make_unique<server_t>(
-            this, bindaddrStr, portUint, &middlewares, nullptr, io));
-      } else {
-        server = std::move(std::make_unique<server_t>(
-            this, socketFd, &middlewares, nullptr, io));
-      }
-      server->setTickFunction(tickInterval, tickFunction);
-      server->run();
     }
-  }
+    ~Crow()
+    {
+        this->stop();
+    }
 
-  void stop() { io->stop(); }
+    template <typename Adaptor>
+    void handleUpgrade(const Request& req, Response& res, Adaptor&& adaptor)
+    {
+        router.handleUpgrade(req, res, adaptor);
+    }
 
-  void debugPrint() {
-    BMCWEB_LOG_DEBUG << "Routing:";
-    router.debugPrint();
-  }
+    void handle(const Request& req, Response& res)
+    {
+        router.handle(req, res);
+    }
 
-  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);
-  }
+    DynamicRule& routeDynamic(std::string&& rule)
+    {
+        return router.newRuleDynamic(rule);
+    }
+
+    template <uint64_t Tag>
+    auto route(std::string&& rule) -> typename std::result_of<
+        decltype (&Router::newRuleTagged<Tag>)(Router, std::string&&)>::type
+    {
+        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 (useSsl)
+        {
+            if (-1 == socketFd)
+            {
+                sslServer = std::move(std::make_unique<ssl_server_t>(
+                    this, bindaddrStr, portUint, &middlewares, &sslContext,
+                    io));
+            }
+            else
+            {
+                sslServer = std::move(std::make_unique<ssl_server_t>(
+                    this, socketFd, &middlewares, &sslContext, io));
+            }
+            sslServer->setTickFunction(tickInterval, tickFunction);
+            sslServer->run();
+        }
+        else
+#endif
+        {
+            if (-1 == socketFd)
+            {
+                server = std::move(std::make_unique<server_t>(
+                    this, bindaddrStr, portUint, &middlewares, nullptr, io));
+            }
+            else
+            {
+                server = std::move(std::make_unique<server_t>(
+                    this, socketFd, &middlewares, nullptr, io));
+            }
+            server->setTickFunction(tickInterval, tickFunction);
+            server->run();
+        }
+    }
+
+    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) {
-    useSsl = true;
-    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);
-    return *this;
-  }
+    self_t& sslFile(const std::string& crt_filename,
+                    const std::string& key_filename)
+    {
+        useSsl = true;
+        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);
+        return *this;
+    }
 
-  self_t& sslFile(const std::string& pem_filename) {
-    useSsl = true;
-    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);
-    return *this;
-  }
+    self_t& sslFile(const std::string& pem_filename)
+    {
+        useSsl = true;
+        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);
+        return *this;
+    }
 
-  self_t& ssl(boost::asio::ssl::context&& ctx) {
-    useSsl = true;
-    sslContext = std::move(ctx);
-    return *this;
-  }
+    self_t& ssl(boost::asio::ssl::context&& ctx)
+    {
+        useSsl = true;
+        sslContext = std::move(ctx);
+        return *this;
+    }
 
-  bool useSsl{false};
-  ssl_context_t sslContext{boost::asio::ssl::context::sslv23};
+    bool useSsl{false};
+    ssl_context_t sslContext{boost::asio::ssl::context::sslv23};
 
 #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, 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;
-  }
+    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>();
-  }
+    // 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 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;
-  }
+    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_service> io;
-  uint16_t portUint = 80;
-  std::string bindaddrStr = "::";
-  int socketFd = -1;
-  Router router;
+  private:
+    std::shared_ptr<asio::io_service> io;
+    uint16_t portUint = 80;
+    std::string bindaddrStr = "::";
+    int socketFd = -1;
+    Router router;
 
-  std::chrono::milliseconds tickInterval{};
-  std::function<void()> tickFunction;
+    std::chrono::milliseconds tickInterval{};
+    std::function<void()> tickFunction;
 
-  std::tuple<Middlewares...> middlewares;
+    std::tuple<Middlewares...> middlewares;
 
 #ifdef BMCWEB_ENABLE_SSL
-  std::unique_ptr<ssl_server_t> sslServer;
+    std::unique_ptr<ssl_server_t> sslServer;
 #endif
-  std::unique_ptr<server_t> server;
+    std::unique_ptr<server_t> server;
 };
-template <typename... Middlewares>
-using App = Crow<Middlewares...>;
+template <typename... Middlewares> using App = Crow<Middlewares...>;
 using SimpleApp = Crow<>;
-}  // namespace crow
+} // namespace crow
diff --git a/crow/include/crow/common.h b/crow/include/crow/common.h
index e155da6..b3e424f 100644
--- a/crow/include/crow/common.h
+++ b/crow/include/crow/common.h
@@ -1,127 +1,140 @@
 #pragma once
 
+#include <boost/beast/http/verb.hpp>
 #include <iostream>
 #include <stdexcept>
 #include <string>
 #include <vector>
-#include "crow/utility.h"
-#include <boost/beast/http/verb.hpp>
 
-namespace crow {
-enum class HTTPMethod {
+#include "crow/utility.h"
+
+namespace crow
+{
+enum class HTTPMethod
+{
 #ifndef DELETE
-  DELETE = 0,
-  GET,
-  HEAD,
-  POST,
-  PUT,
-  CONNECT,
-  OPTIONS,
-  TRACE,
-  PATCH = 24,  // see http_parser_merged.h line 118 for why it is 24
+    DELETE = 0,
+    GET,
+    HEAD,
+    POST,
+    PUT,
+    CONNECT,
+    OPTIONS,
+    TRACE,
+    PATCH = 24, // see http_parser_merged.h line 118 for why it is 24
 #endif
 
-  Delete = 0,
-  Get,
-  Head,
-  Post,
-  Put,
-  Connect,
-  Options,
-  Trace,
-  Patch = 24,
+    Delete = 0,
+    Get,
+    Head,
+    Post,
+    Put,
+    Connect,
+    Options,
+    Trace,
+    Patch = 24,
 };
 
-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";
-  }
-  return "invalid";
+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";
+    }
+    return "invalid";
 }
 
-enum class ParamType {
-  INT,
-  UINT,
-  DOUBLE,
-  STRING,
-  PATH,
+enum class ParamType
+{
+    INT,
+    UINT,
+    DOUBLE,
+    STRING,
+    PATH,
 
-  MAX
+    MAX
 };
 
-struct RoutingParams {
-  std::vector<int64_t> intParams;
-  std::vector<uint64_t> uintParams;
-  std::vector<double> doubleParams;
-  std::vector<std::string> stringParams;
+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 << ", ";
+    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;
     }
-    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 <typename T> T get(unsigned) const;
 };
 
-template <>
-inline int64_t RoutingParams::get<int64_t>(unsigned index) const {
-  return intParams[index];
+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 uint64_t RoutingParams::get<uint64_t>(unsigned index) const {
-  return uintParams[index];
+inline std::string RoutingParams::get<std::string>(unsigned index) const
+{
+    return stringParams[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
+} // namespace crow
 
 constexpr boost::beast::http::verb operator"" _method(const char* str,
-                                                      size_t /*len*/) {
-  using verb = boost::beast::http::verb;
-  // clang-format off
+                                                      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_ :
@@ -134,5 +147,5 @@
     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
+    // clang-format on
 }
\ No newline at end of file
diff --git a/crow/include/crow/http_connection.h b/crow/include/crow/http_connection.h
index 5f2f719..6d62c85 100644
--- a/crow/include/crow/http_connection.h
+++ b/crow/include/crow/http_connection.h
@@ -1,249 +1,279 @@
 #pragma once
+#include "http_utility.hpp"
+
 #include <array>
 #include <atomic>
-#include <chrono>
-#include <regex>
-#include <vector>
-#include "http_utility.hpp"
-#include "crow/http_response.h"
-#include "crow/logging.h"
-#include "crow/middleware_context.h"
-#include "crow/socket_adaptors.h"
-#include "crow/timer_queue.h"
 #include <boost/algorithm/string.hpp>
 #include <boost/algorithm/string/predicate.hpp>
 #include <boost/asio.hpp>
 #include <boost/beast/core.hpp>
 #include <boost/beast/http.hpp>
 #include <boost/beast/websocket.hpp>
+#include <chrono>
+#include <regex>
+#include <vector>
+
+#include "crow/http_response.h"
+#include "crow/logging.h"
+#include "crow/middleware_context.h"
+#include "crow/socket_adaptors.h"
+#include "crow/timer_queue.h"
 
 #ifdef BMCWEB_ENABLE_SSL
 #include <boost/asio/ssl.hpp>
 #endif
 
-namespace crow {
+namespace crow
+{
 
-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() * 1.05);
-  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;
+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() * 1.05);
+    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);
+    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>");
+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>");
 }
 
-inline void prettyPrintJson(crow::Response& res) {
-  std::string value = res.jsonValue.dump(4);
-  escapeHtml(value);
-  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";
+inline void prettyPrintJson(crow::Response& res)
+{
+    std::string value = res.jsonValue.dump(4);
+    escapeHtml(value);
+    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";
 }
 
 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 {};
+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 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 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 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 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::true_type
+        f(typename CheckBeforeHandleArity3<T>::template Get<C>*);
 
-  template <typename C>
-  static std::false_type f(...);
+    template <typename C> static std::false_type f(...);
 
- public:
-  static const bool value = decltype(f<T>(nullptr))::value;
+  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 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::true_type
+        f(typename CheckAfterHandleArity3<T>::template Get<C>*);
 
-  template <typename C>
-  static std::false_type f(...);
+    template <typename C> static std::false_type f(...);
 
- public:
-  static const bool value = decltype(f<T>(nullptr))::value;
+  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);
+    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>());
+    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);
+    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>());
+    afterHandlerCall(MW& mw, Request& req, Response& res, Context& ctx,
+                     ParentContext& /*parent_ctx*/)
+{
+    mw.afterHandle(req, res, ctx.template get<MW>());
 }
 
 template <int 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>(
+                          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));
-    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;
-  }
+    if (res.isCompleted())
+    {
+        afterHandlerCall<CurrentMW, Context, parent_context_t>(
+            std::get<N>(middlewares), req, res, ctx,
+            static_cast<parent_context_t&>(ctx));
+        return true;
+    }
 
-  return false;
+    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 <int N, typename Context, typename Container>
 bool middlewareCallHelper(Container& /*middlewares*/, Request& /*req*/,
-                          Response& /*res*/, Context& /*ctx*/) {
-  return false;
+                          Response& /*res*/, Context& /*ctx*/)
+{
+    return false;
 }
 
 template <int N, typename Context, typename Container>
-typename std::enable_if<(N < 0)>::type afterHandlersCallHelper(
-    Container& /*middlewares*/, Context& /*Context*/, Request& /*req*/,
-    Response& /*res*/) {}
-
-template <int 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));
+typename std::enable_if<(N < 0)>::type
+    afterHandlersCallHelper(Container& /*middlewares*/, Context& /*Context*/,
+                            Request& /*req*/, Response& /*res*/)
+{
 }
 
 template <int 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);
+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));
 }
-}  // namespace detail
+
+template <int 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;
@@ -253,331 +283,382 @@
 constexpr unsigned int httpReqBodyLimit = 1024 * 1024 * 30;
 
 template <typename Adaptor, typename Handler, typename... Middlewares>
-class Connection {
- public:
-  Connection(boost::asio::io_service& ioService, Handler* handler,
-             const std::string& server_name,
-             std::tuple<Middlewares...>* middlewares,
-             std::function<std::string()>& get_cached_date_str_f,
-             detail::TimerQueue& timerQueue,
-             typename Adaptor::context* adaptorCtx)
-      : adaptor(ioService, adaptorCtx),
-        handler(handler),
-        serverName(server_name),
-        middlewares(middlewares),
-        getCachedDateStr(get_cached_date_str_f),
-        timerQueue(timerQueue) {
-    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());
+class Connection
+{
+  public:
+    Connection(boost::asio::io_service& ioService, Handler* handler,
+               const std::string& server_name,
+               std::tuple<Middlewares...>* middlewares,
+               std::function<std::string()>& get_cached_date_str_f,
+               detail::TimerQueue& timerQueue,
+               typename Adaptor::context* adaptorCtx) :
+        adaptor(ioService, adaptorCtx),
+        handler(handler), serverName(server_name), middlewares(middlewares),
+        getCachedDateStr(get_cached_date_str_f), timerQueue(timerQueue)
+    {
+        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;
+        connectionCount++;
+        BMCWEB_LOG_DEBUG << this << " Connection open, total "
+                         << connectionCount;
 #endif
-  }
+    }
 
-  ~Connection() {
-    res.completeRequestHandler = nullptr;
-    cancelDeadlineTimer();
+    ~Connection()
+    {
+        res.completeRequestHandler = nullptr;
+        cancelDeadlineTimer();
 #ifdef BMCWEB_ENABLE_DEBUG
-    connectionCount--;
-    BMCWEB_LOG_DEBUG << this << " Connection closed, total " << connectionCount;
+        connectionCount--;
+        BMCWEB_LOG_DEBUG << this << " Connection closed, total "
+                         << connectionCount;
 #endif
-  }
-
-  decltype(std::declval<Adaptor>().rawSocket()) & socket() {
-    return adaptor.rawSocket();
-  }
-
-  void start() {
-    adaptor.start([this](const boost::system::error_code& ec) {
-      if (!ec) {
-        startDeadline();
-
-        doReadHeaders();
-      } else {
-        checkDestroy();
-      }
-    });
-  }
-
-  void handle() {
-    cancelDeadlineTimer();
-    bool isInvalidRequest = false;
-    const boost::string_view connection =
-        req->getHeaderValue(boost::beast::http::field::connection);
-
-    // Check for HTTP version 1.1.
-    if (req->version() == 11) {
-      if (req->getHeaderValue(boost::beast::http::field::host).empty()) {
-        isInvalidRequest = true;
-        res = Response(boost::beast::http::status::bad_request);
-      }
     }
 
-    BMCWEB_LOG_INFO << "Request: " << adaptor.remoteEndpoint() << " " << this
-                    << " HTTP/" << req->version() / 10 << "."
-                    << req->version() % 10 << ' ' << req->methodString() << " "
-                    << req->target();
-
-    needToCallAfterHandlers = false;
-
-    if (!isInvalidRequest) {
-      res.completeRequestHandler = [] {};
-      res.isAliveHelper = [this]() -> bool { return adaptor.isOpen(); };
-
-      ctx = detail::Context<Middlewares...>();
-      req->middlewareContext = (void*)&ctx;
-      req->ioService = &adaptor.getIoService();
-      detail::middlewareCallHelper<0, 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);
-        if (req->keepAlive()) {
-          res.addHeader("connection", "Keep-Alive");
-        }
-      } else {
-        completeRequest();
-      }
-    } else {
-      completeRequest();
-    }
-  }
-
-  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<((int)sizeof...(Middlewares) - 1),
-                                      decltype(ctx), decltype(*middlewares)>(
-          *middlewares, ctx, *req, res);
+    decltype(std::declval<Adaptor>().rawSocket())& socket()
+    {
+        return adaptor.rawSocket();
     }
 
-    // auto self = this->shared_from_this();
-    res.completeRequestHandler = nullptr;
+    void start()
+    {
+        adaptor.start([this](const boost::system::error_code& ec) {
+            if (!ec)
+            {
+                startDeadline();
 
-    if (!adaptor.isOpen()) {
-      // 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);
-      }
-    }
-
-    if (res.resultInt() >= 400 && res.body().empty()) {
-      res.body() = std::string(res.reason());
-    }
-    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.socket(), 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 (!adaptor.isOpen() && !req->isUpgrade()) {
-              errorWhileReading = true;
+                doReadHeaders();
             }
-          }
-
-          if (errorWhileReading) {
-            cancelDeadlineTimer();
-            adaptor.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 != boost::string_view::npos) {
-            req->url = req->url.substr(0, index - 1);
-          }
-          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.socket(), 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 (!adaptor.isOpen()) {
-              errorWhileReading = true;
+            else
+            {
+                checkDestroy();
             }
-          }
-          if (errorWhileReading) {
-            cancelDeadlineTimer();
-            adaptor.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.socket(), *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 (!req->keepAlive()) {
-            adaptor.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 handle()
+    {
+        cancelDeadlineTimer();
+        bool isInvalidRequest = false;
+        const boost::string_view connection =
+            req->getHeaderValue(boost::beast::http::field::connection);
 
-  void startDeadline() {
-    cancelDeadlineTimer();
+        // Check for HTTP version 1.1.
+        if (req->version() == 11)
+        {
+            if (req->getHeaderValue(boost::beast::http::field::host).empty())
+            {
+                isInvalidRequest = true;
+                res = Response(boost::beast::http::status::bad_request);
+            }
+        }
 
-    timerCancelKey = timerQueue.add([this] {
-      if (!adaptor.isOpen()) {
-        return;
-      }
-      adaptor.close();
-    });
-    BMCWEB_LOG_DEBUG << this << " timer added: " << &timerQueue << ' '
-                     << timerCancelKey;
-  }
+        BMCWEB_LOG_INFO << "Request: " << adaptor.remoteEndpoint() << " "
+                        << this << " HTTP/" << req->version() / 10 << "."
+                        << req->version() % 10 << ' ' << req->methodString()
+                        << " " << req->target();
 
- private:
-  Adaptor adaptor;
-  Handler* handler;
+        needToCallAfterHandlers = false;
 
-  // Making this a boost::optional allows it to be efficiently destroyed and
-  // re-created on Connection reset
-  boost::optional<
-      boost::beast::http::request_parser<boost::beast::http::string_body>>
-      parser;
+        if (!isInvalidRequest)
+        {
+            res.completeRequestHandler = [] {};
+            res.isAliveHelper = [this]() -> bool { return adaptor.isOpen(); };
 
-  boost::beast::flat_buffer buffer{8192};
+            ctx = detail::Context<Middlewares...>();
+            req->middlewareContext = (void*)&ctx;
+            req->ioService = &adaptor.getIoService();
+            detail::middlewareCallHelper<
+                0, decltype(ctx), decltype(*middlewares), Middlewares...>(
+                *middlewares, *req, res, ctx);
 
-  boost::optional<
-      boost::beast::http::response_serializer<boost::beast::http::string_body>>
-      serializer;
+            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);
+                if (req->keepAlive())
+                {
+                    res.addHeader("connection", "Keep-Alive");
+                }
+            }
+            else
+            {
+                completeRequest();
+            }
+        }
+        else
+        {
+            completeRequest();
+        }
+    }
 
-  boost::optional<crow::Request> req;
-  crow::Response res;
+    void completeRequest()
+    {
+        BMCWEB_LOG_INFO << "Response: " << this << ' ' << req->url << ' '
+                        << res.resultInt() << " keepalive=" << req->keepAlive();
 
-  const std::string& serverName;
+        if (needToCallAfterHandlers)
+        {
+            needToCallAfterHandlers = false;
 
-  int timerCancelKey{-1};
+            // call all afterHandler of middlewares
+            detail::afterHandlersCallHelper<((int)sizeof...(Middlewares) - 1),
+                                            decltype(ctx),
+                                            decltype(*middlewares)>(
+                *middlewares, ctx, *req, res);
+        }
 
-  bool isReading{};
-  bool isWriting{};
-  bool needToCallAfterHandlers{};
-  bool needToStartReadAfterComplete{};
-  bool addKeepAlive{};
+        // auto self = this->shared_from_this();
+        res.completeRequestHandler = nullptr;
 
-  std::tuple<Middlewares...>* middlewares;
-  detail::Context<Middlewares...> ctx;
+        if (!adaptor.isOpen())
+        {
+            // 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);
+            }
+        }
 
-  std::function<std::string()>& getCachedDateStr;
-  detail::TimerQueue& timerQueue;
-};  // namespace crow
-}  // namespace crow
+        if (res.resultInt() >= 400 && res.body().empty())
+        {
+            res.body() = std::string(res.reason());
+        }
+        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.socket(), 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 (!adaptor.isOpen() && !req->isUpgrade())
+                    {
+                        errorWhileReading = true;
+                    }
+                }
+
+                if (errorWhileReading)
+                {
+                    cancelDeadlineTimer();
+                    adaptor.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 != boost::string_view::npos)
+                {
+                    req->url = req->url.substr(0, index - 1);
+                }
+                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.socket(), 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 (!adaptor.isOpen())
+                    {
+                        errorWhileReading = true;
+                    }
+                }
+                if (errorWhileReading)
+                {
+                    cancelDeadlineTimer();
+                    adaptor.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.socket(), *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 (!req->keepAlive())
+                {
+                    adaptor.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 (!adaptor.isOpen())
+            {
+                return;
+            }
+            adaptor.close();
+        });
+        BMCWEB_LOG_DEBUG << this << " timer added: " << &timerQueue << ' '
+                         << timerCancelKey;
+    }
+
+  private:
+    Adaptor adaptor;
+    Handler* handler;
+
+    // Making this a boost::optional allows it to be efficiently destroyed and
+    // re-created on Connection reset
+    boost::optional<
+        boost::beast::http::request_parser<boost::beast::http::string_body>>
+        parser;
+
+    boost::beast::flat_buffer buffer{8192};
+
+    boost::optional<boost::beast::http::response_serializer<
+        boost::beast::http::string_body>>
+        serializer;
+
+    boost::optional<crow::Request> req;
+    crow::Response res;
+
+    const std::string& serverName;
+
+    int timerCancelKey{-1};
+
+    bool isReading{};
+    bool isWriting{};
+    bool needToCallAfterHandlers{};
+    bool needToStartReadAfterComplete{};
+    bool addKeepAlive{};
+
+    std::tuple<Middlewares...>* middlewares;
+    detail::Context<Middlewares...> ctx;
+
+    std::function<std::string()>& getCachedDateStr;
+    detail::TimerQueue& timerQueue;
+}; // namespace crow
+} // namespace crow
diff --git a/crow/include/crow/http_request.h b/crow/include/crow/http_request.h
index 7e95bc6..0e6dd12 100644
--- a/crow/include/crow/http_request.h
+++ b/crow/include/crow/http_request.h
@@ -7,42 +7,66 @@
 #include "crow/common.h"
 #include "crow/query_string.h"
 
-namespace crow {
+namespace crow
+{
 
-struct Request {
-  boost::string_view url{};
-  QueryString urlParams{};
-  bool isSecure{false};
+struct Request
+{
+    boost::string_view url{};
+    QueryString urlParams{};
+    bool isSecure{false};
 
-  const std::string& body;
+    const std::string& body;
 
-  void* middlewareContext{};
-  boost::asio::io_service* ioService{};
+    void* middlewareContext{};
+    boost::asio::io_service* ioService{};
 
-  Request(boost::beast::http::request<boost::beast::http::string_body>& req)
-      : req(req), body(req.body()) {}
+    Request(boost::beast::http::request<boost::beast::http::string_body>& req) :
+        req(req), body(req.body())
+    {
+    }
 
-  const boost::beast::http::verb method() const { return req.method(); }
+    const boost::beast::http::verb method() const
+    {
+        return req.method();
+    }
 
-  const boost::string_view getHeaderValue(boost::string_view key) const {
-    return req[key];
-  }
+    const boost::string_view getHeaderValue(boost::string_view key) const
+    {
+        return req[key];
+    }
 
-  const boost::string_view getHeaderValue(boost::beast::http::field key) const {
-    return req[key];
-  }
+    const boost::string_view getHeaderValue(boost::beast::http::field key) const
+    {
+        return req[key];
+    }
 
-  const boost::string_view methodString() const { return req.method_string(); }
+    const boost::string_view methodString() const
+    {
+        return req.method_string();
+    }
 
-  const boost::string_view target() const { return req.target(); }
+    const boost::string_view target() const
+    {
+        return req.target();
+    }
 
-  unsigned version() { return req.version(); }
+    unsigned version()
+    {
+        return req.version();
+    }
 
-  bool isUpgrade() { return boost::beast::websocket::is_upgrade(req); }
+    bool isUpgrade()
+    {
+        return boost::beast::websocket::is_upgrade(req);
+    }
 
-  bool keepAlive() { return req.keep_alive(); }
+    bool keepAlive()
+    {
+        return req.keep_alive();
+    }
 
-  boost::beast::http::request<boost::beast::http::string_body>& req;
+    boost::beast::http::request<boost::beast::http::string_body>& req;
 };
 
-}  // namespace crow
+} // namespace crow
diff --git a/crow/include/crow/http_response.h b/crow/include/crow/http_response.h
index 560eef4..d66bf47 100644
--- a/crow/include/crow/http_response.h
+++ b/crow/include/crow/http_response.h
@@ -1,121 +1,173 @@
 #pragma once
+#include "nlohmann/json.hpp"
+
+#include <boost/beast/http.hpp>
 #include <string>
 
-#include "nlohmann/json.hpp"
 #include "crow/http_request.h"
 #include "crow/logging.h"
-#include <boost/beast/http.hpp>
 
-namespace crow {
+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>;
+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>;
 
-  boost::optional<response_type> stringResponse;
+    boost::optional<response_type> stringResponse;
 
-  nlohmann::json jsonValue;
+    nlohmann::json jsonValue;
 
-  void addHeader(const boost::string_view key, const boost::string_view value) {
-    stringResponse->set(key, value);
-  }
-
-  void addHeader(boost::beast::http::field key, boost::string_view value) {
-    stringResponse->set(key, value);
-  }
-
-  Response() : stringResponse(response_type{}) {}
-
-  explicit Response(boost::beast::http::status code)
-      : stringResponse(response_type{}) {}
-
-  explicit Response(boost::string_view body_)
-      : stringResponse(response_type{}) {
-    stringResponse->body() = std::string(body_);
-  }
-
-  Response(boost::beast::http::status code, boost::string_view s)
-      : stringResponse(response_type{}) {
-    stringResponse->result(code);
-    stringResponse->body() = std::string(s);
-  }
-
-  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(); }
-
-  boost::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); }
-
-  void preparePayload() { stringResponse->prepare_payload(); };
-
-  void clear() {
-    BMCWEB_LOG_DEBUG << this << " Clearing response containers";
-    stringResponse.emplace(response_type{});
-    jsonValue.clear();
-    completed = false;
-  }
-
-  void write(boost::string_view body_part) {
-    stringResponse->body() += std::string(body_part);
-  }
-
-  void end() {
-    if (completed) {
-      BMCWEB_LOG_ERROR << "Response was ended twice";
-      return;
+    void addHeader(const boost::string_view key, const boost::string_view value)
+    {
+        stringResponse->set(key, value);
     }
-    completed = true;
-    BMCWEB_LOG_DEBUG << "calling completion handler";
-    if (completeRequestHandler) {
-      BMCWEB_LOG_DEBUG << "completion handler was valid";
-      completeRequestHandler();
+
+    void addHeader(boost::beast::http::field key, boost::string_view value)
+    {
+        stringResponse->set(key, value);
     }
-  }
 
-  void end(boost::string_view body_part) {
-    write(body_part);
-    end();
-  }
+    Response() : stringResponse(response_type{})
+    {
+    }
 
-  bool isAlive() { return isAliveHelper && isAliveHelper(); }
+    explicit Response(boost::beast::http::status code) :
+        stringResponse(response_type{})
+    {
+    }
 
- private:
-  bool completed{};
-  std::function<void()> completeRequestHandler;
-  std::function<bool()> isAliveHelper;
+    explicit Response(boost::string_view body_) :
+        stringResponse(response_type{})
+    {
+        stringResponse->body() = std::string(body_);
+    }
 
-  // In case of a JSON object, set the Content-Type header
-  void jsonMode() { addHeader("Content-Type", "application/json"); }
+    Response(boost::beast::http::status code, boost::string_view s) :
+        stringResponse(response_type{})
+    {
+        stringResponse->result(code);
+        stringResponse->body() = std::string(s);
+    }
+
+    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();
+    }
+
+    boost::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);
+    }
+
+    void preparePayload()
+    {
+        stringResponse->prepare_payload();
+    };
+
+    void clear()
+    {
+        BMCWEB_LOG_DEBUG << this << " Clearing response containers";
+        stringResponse.emplace(response_type{});
+        jsonValue.clear();
+        completed = false;
+    }
+
+    void write(boost::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(boost::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
+} // namespace crow
diff --git a/crow/include/crow/http_server.h b/crow/include/crow/http_server.h
index 96b85dc..173d0d1 100644
--- a/crow/include/crow/http_server.h
+++ b/crow/include/crow/http_server.h
@@ -1,183 +1,205 @@
 #pragma once
 
 #include <atomic>
+#include <boost/asio.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
 #include <chrono>
 #include <cstdint>
 #include <future>
 #include <memory>
 #include <utility>
 #include <vector>
+
 #include "crow/http_connection.h"
 #include "crow/logging.h"
 #include "crow/timer_queue.h"
-#include <boost/asio.hpp>
-#include <boost/date_time/posix_time/posix_time.hpp>
 #ifdef BMCWEB_ENABLE_SSL
 #include <boost/asio/ssl.hpp>
 #endif
 
-namespace crow {
+namespace crow
+{
 using namespace boost;
 using tcp = asio::ip::tcp;
 
 template <typename Handler, typename Adaptor = SocketAdaptor,
           typename... Middlewares>
-class Server {
- public:
-  Server(Handler* handler, std::unique_ptr<tcp::acceptor>&& acceptor,
-         std::tuple<Middlewares...>* middlewares = nullptr,
-         typename Adaptor::context* adaptor_ctx = nullptr,
-         std::shared_ptr<boost::asio::io_service> io =
-             std::make_shared<boost::asio::io_service>())
-      : ioService(std::move(io)),
-        acceptor(std::move(acceptor)),
-        signals(*ioService, SIGINT, SIGTERM),
-        tickTimer(*ioService),
-        handler(handler),
-        middlewares(middlewares),
-        adaptorCtx(adaptor_ctx) {}
+class Server
+{
+  public:
+    Server(Handler* handler, std::unique_ptr<tcp::acceptor>&& acceptor,
+           std::tuple<Middlewares...>* middlewares = nullptr,
+           typename Adaptor::context* adaptor_ctx = nullptr,
+           std::shared_ptr<boost::asio::io_service> io =
+               std::make_shared<boost::asio::io_service>()) :
+        ioService(std::move(io)),
+        acceptor(std::move(acceptor)), signals(*ioService, SIGINT, SIGTERM),
+        tickTimer(*ioService), handler(handler), middlewares(middlewares),
+        adaptorCtx(adaptor_ctx)
+    {
+    }
 
-  Server(Handler* handler, const std::string& bindaddr, uint16_t port,
-         std::tuple<Middlewares...>* middlewares = nullptr,
-         typename Adaptor::context* adaptor_ctx = nullptr,
-         std::shared_ptr<boost::asio::io_service> io =
-             std::make_shared<boost::asio::io_service>())
-      : Server(handler,
+    Server(Handler* handler, const std::string& bindaddr, uint16_t port,
+           std::tuple<Middlewares...>* middlewares = nullptr,
+           typename Adaptor::context* adaptor_ctx = nullptr,
+           std::shared_ptr<boost::asio::io_service> io =
+               std::make_shared<boost::asio::io_service>()) :
+        Server(handler,
                std::make_unique<tcp::acceptor>(
                    *io,
                    tcp::endpoint(
                        boost::asio::ip::address::from_string(bindaddr), port)),
-               middlewares, adaptor_ctx, io) {}
-
-  Server(Handler* handler, int existing_socket,
-         std::tuple<Middlewares...>* middlewares = nullptr,
-         typename Adaptor::context* adaptor_ctx = nullptr,
-         std::shared_ptr<boost::asio::io_service> io =
-             std::make_shared<boost::asio::io_service>())
-      : Server(handler,
-               std::make_unique<tcp::acceptor>(*io, boost::asio::ip::tcp::v6(),
-                                               existing_socket),
-               middlewares, adaptor_ctx, io) {}
-
-  void setTickFunction(std::chrono::milliseconds d, std::function<void()> f) {
-    tickInterval = d;
-    tickFunction = f;
-  }
-
-  void onTick() {
-    tickFunction();
-    tickTimer.expires_from_now(
-        boost::posix_time::milliseconds(tickInterval.count()));
-    tickTimer.async_wait([this](const boost::system::error_code& ec) {
-      if (ec) {
-        return;
-      }
-      onTick();
-    });
-  }
-
-  void updateDateStr() {
-    auto lastTimeT = time(0);
-    tm myTm{};
-
-#ifdef _MSC_VER
-    gmtime_s(&my_tm, &last_time_t);
-#else
-    gmtime_r(&lastTimeT, &myTm);
-#endif
-    dateStr.resize(100);
-    size_t dateStrSz =
-        strftime(&dateStr[0], 99, "%a, %d %b %Y %H:%M:%S GMT", &myTm);
-    dateStr.resize(dateStrSz);
-  };
-
-  void run() {
-    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::deadline_timer timer(*ioService);
-    timer.expires_from_now(boost::posix_time::seconds(1));
-
-    std::function<void(const boost::system::error_code& ec)> handler;
-    handler = [&](const boost::system::error_code& ec) {
-      if (ec) {
-        return;
-      }
-      timerQueue.process();
-      timer.expires_from_now(boost::posix_time::seconds(1));
-      timer.async_wait(handler);
-    };
-    timer.async_wait(handler);
-
-    if (tickFunction && tickInterval.count() > 0) {
-      tickTimer.expires_from_now(
-          boost::posix_time::milliseconds(tickInterval.count()));
-      tickTimer.async_wait([this](const boost::system::error_code& ec) {
-        if (ec) {
-          return;
-        }
-        onTick();
-      });
+               middlewares, adaptor_ctx, io)
+    {
     }
 
-    BMCWEB_LOG_INFO << serverName << " server is running, local endpoint "
-                    << acceptor->local_endpoint();
+    Server(Handler* handler, int existing_socket,
+           std::tuple<Middlewares...>* middlewares = nullptr,
+           typename Adaptor::context* adaptor_ctx = nullptr,
+           std::shared_ptr<boost::asio::io_service> io =
+               std::make_shared<boost::asio::io_service>()) :
+        Server(handler,
+               std::make_unique<tcp::acceptor>(*io, boost::asio::ip::tcp::v6(),
+                                               existing_socket),
+               middlewares, adaptor_ctx, io)
+    {
+    }
 
-    signals.async_wait([&](const boost::system::error_code& /*error*/,
-                           int /*signal_number*/) { stop(); });
+    void setTickFunction(std::chrono::milliseconds d, std::function<void()> f)
+    {
+        tickInterval = d;
+        tickFunction = f;
+    }
 
-    doAccept();
-  }
+    void onTick()
+    {
+        tickFunction();
+        tickTimer.expires_from_now(
+            boost::posix_time::milliseconds(tickInterval.count()));
+        tickTimer.async_wait([this](const boost::system::error_code& ec) {
+            if (ec)
+            {
+                return;
+            }
+            onTick();
+        });
+    }
 
-  void stop() { ioService->stop(); }
+    void updateDateStr()
+    {
+        auto lastTimeT = time(0);
+        tm myTm{};
 
-  void doAccept() {
-    auto p = new Connection<Adaptor, Handler, Middlewares...>(
-        *ioService, handler, serverName, middlewares, getCachedDateStr,
-        timerQueue, adaptorCtx);
-    acceptor->async_accept(p->socket(),
-                           [this, p](boost::system::error_code ec) {
-                             if (!ec) {
-                               this->ioService->post([p] { p->start(); });
-                             } else {
-                               delete p;
-                             }
-                             doAccept();
-                           });
-  }
+#ifdef _MSC_VER
+        gmtime_s(&my_tm, &last_time_t);
+#else
+        gmtime_r(&lastTimeT, &myTm);
+#endif
+        dateStr.resize(100);
+        size_t dateStrSz =
+            strftime(&dateStr[0], 99, "%a, %d %b %Y %H:%M:%S GMT", &myTm);
+        dateStr.resize(dateStrSz);
+    };
 
- private:
-  std::shared_ptr<asio::io_service> ioService;
-  detail::TimerQueue timerQueue;
-  std::function<std::string()> getCachedDateStr;
-  std::unique_ptr<tcp::acceptor> acceptor;
-  boost::asio::signal_set signals;
-  boost::asio::deadline_timer tickTimer;
+    void run()
+    {
+        updateDateStr();
 
-  std::string dateStr;
+        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;
+        };
 
-  Handler* handler;
-  std::string serverName = "iBMC";
+        boost::asio::deadline_timer timer(*ioService);
+        timer.expires_from_now(boost::posix_time::seconds(1));
 
-  std::chrono::milliseconds tickInterval{};
-  std::function<void()> tickFunction;
+        std::function<void(const boost::system::error_code& ec)> handler;
+        handler = [&](const boost::system::error_code& ec) {
+            if (ec)
+            {
+                return;
+            }
+            timerQueue.process();
+            timer.expires_from_now(boost::posix_time::seconds(1));
+            timer.async_wait(handler);
+        };
+        timer.async_wait(handler);
 
-  std::tuple<Middlewares...>* middlewares;
+        if (tickFunction && tickInterval.count() > 0)
+        {
+            tickTimer.expires_from_now(
+                boost::posix_time::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();
+
+        signals.async_wait([&](const boost::system::error_code& /*error*/,
+                               int /*signal_number*/) { stop(); });
+
+        doAccept();
+    }
+
+    void stop()
+    {
+        ioService->stop();
+    }
+
+    void doAccept()
+    {
+        auto p = new Connection<Adaptor, Handler, Middlewares...>(
+            *ioService, handler, serverName, middlewares, getCachedDateStr,
+            timerQueue, adaptorCtx);
+        acceptor->async_accept(
+            p->socket(), [this, p](boost::system::error_code ec) {
+                if (!ec)
+                {
+                    this->ioService->post([p] { p->start(); });
+                }
+                else
+                {
+                    delete p;
+                }
+                doAccept();
+            });
+    }
+
+  private:
+    std::shared_ptr<asio::io_service> ioService;
+    detail::TimerQueue timerQueue;
+    std::function<std::string()> getCachedDateStr;
+    std::unique_ptr<tcp::acceptor> acceptor;
+    boost::asio::signal_set signals;
+    boost::asio::deadline_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};
-  boost::asio::ssl::context sslContext{boost::asio::ssl::context::sslv23};
+    bool useSsl{false};
+    boost::asio::ssl::context sslContext{boost::asio::ssl::context::sslv23};
 #endif
-  typename Adaptor::context* adaptorCtx;
-};  // namespace crow
-}  // namespace crow
+    typename Adaptor::context* adaptorCtx;
+}; // namespace crow
+} // namespace crow
diff --git a/crow/include/crow/logging.h b/crow/include/crow/logging.h
index 4a68df3..353a448 100644
--- a/crow/include/crow/logging.h
+++ b/crow/include/crow/logging.h
@@ -7,117 +7,139 @@
 #include <sstream>
 #include <string>
 
-namespace crow {
-enum class LogLevel {
+namespace crow
+{
+enum class LogLevel
+{
 #ifndef ERROR
-  DEBUG = 0,
-  INFO,
-  WARNING,
-  ERROR,
-  CRITICAL,
+    DEBUG = 0,
+    INFO,
+    WARNING,
+    ERROR,
+    CRITICAL,
 #endif
 
-  Debug = 0,
-  Info,
-  Warning,
-  Error,
-  Critical,
+    Debug = 0,
+    Info,
+    Warning,
+    Error,
+    Critical,
 };
 
-class ILogHandler {
- public:
-  virtual void log(std::string message, LogLevel level) = 0;
+class ILogHandler
+{
+  public:
+    virtual void log(std::string message, LogLevel level) = 0;
 };
 
-class CerrLogHandler : public ILogHandler {
- public:
-  void log(std::string message, LogLevel /*level*/) override {
-    std::cerr << message;
-  }
+class CerrLogHandler : public ILogHandler
+{
+  public:
+    void log(std::string message, LogLevel /*level*/) override
+    {
+        std::cerr << message;
+    }
 };
 
-class logger {
- private:
-  //
-  static std::string timestamp() {
-    char date[32];
-    time_t t = time(0);
+class logger
+{
+  private:
+    //
+    static std::string timestamp()
+    {
+        char date[32];
+        time_t t = time(0);
 
-    tm myTm{};
+        tm myTm{};
 
 #ifdef _MSC_VER
-    gmtime_s(&my_tm, &t);
+        gmtime_s(&my_tm, &t);
 #else
-    gmtime_r(&t, &myTm);
+        gmtime_r(&t, &myTm);
 #endif
 
-    size_t sz = strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", &myTm);
-    return std::string(date, date + sz);
-  }
-
- public:
-  logger(const std::string& prefix, LogLevel level) : level(level) {
-#ifdef BMCWEB_ENABLE_LOGGING
-    stringstream << "(" << timestamp() << ") [" << prefix << "] ";
-#endif
-  }
-  ~logger() {
-#ifdef BMCWEB_ENABLE_LOGGING
-    if (level >= get_current_log_level()) {
-      stringstream << std::endl;
-      getHandlerRef()->log(stringstream.str(), level);
+        size_t sz = strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", &myTm);
+        return std::string(date, date + sz);
     }
-#endif
-  }
 
-  //
-  template <typename T>
-  logger& operator<<(T const& value) {
+  public:
+    logger(const std::string& prefix, LogLevel level) : level(level)
+    {
 #ifdef BMCWEB_ENABLE_LOGGING
-    if (level >= get_current_log_level()) {
-      stringstream << value;
-    }
+        stringstream << "(" << timestamp() << ") [" << prefix << "] ";
 #endif
-    return *this;
-  }
+    }
+    ~logger()
+    {
+#ifdef BMCWEB_ENABLE_LOGGING
+        if (level >= get_current_log_level())
+        {
+            stringstream << std::endl;
+            getHandlerRef()->log(stringstream.str(), level);
+        }
+#endif
+    }
 
-  //
-  static void setLogLevel(LogLevel level) { getLogLevelRef() = level; }
+    //
+    template <typename T> logger& operator<<(T const& value)
+    {
+#ifdef BMCWEB_ENABLE_LOGGING
+        if (level >= get_current_log_level())
+        {
+            stringstream << value;
+        }
+#endif
+        return *this;
+    }
 
-  static void setHandler(ILogHandler* handler) { getHandlerRef() = handler; }
+    //
+    static void setLogLevel(LogLevel level)
+    {
+        getLogLevelRef() = level;
+    }
 
-  static LogLevel get_current_log_level() { return getLogLevelRef(); }
+    static void setHandler(ILogHandler* handler)
+    {
+        getHandlerRef() = handler;
+    }
 
- private:
-  //
-  static LogLevel& getLogLevelRef() {
-    static auto currentLevel = static_cast<LogLevel>(1);
-    return currentLevel;
-  }
-  static ILogHandler*& getHandlerRef() {
-    static CerrLogHandler defaultHandler;
-    static ILogHandler* currentHandler = &defaultHandler;
-    return currentHandler;
-  }
+    static LogLevel get_current_log_level()
+    {
+        return getLogLevelRef();
+    }
 
-  //
-  std::ostringstream stringstream;
-  LogLevel level;
+  private:
+    //
+    static LogLevel& getLogLevelRef()
+    {
+        static auto currentLevel = static_cast<LogLevel>(1);
+        return currentLevel;
+    }
+    static ILogHandler*& getHandlerRef()
+    {
+        static CerrLogHandler defaultHandler;
+        static ILogHandler* currentHandler = &defaultHandler;
+        return currentHandler;
+    }
+
+    //
+    std::ostringstream stringstream;
+    LogLevel level;
 };
-}  // namespace crow
+} // namespace crow
 
-#define BMCWEB_LOG_CRITICAL                                              \
-  if (crow::logger::get_current_log_level() <= crow::LogLevel::Critical) \
-  crow::logger("CRITICAL", crow::LogLevel::Critical)
-#define BMCWEB_LOG_ERROR                                              \
-  if (crow::logger::get_current_log_level() <= crow::LogLevel::Error) \
-  crow::logger("ERROR   ", crow::LogLevel::Error)
-#define BMCWEB_LOG_WARNING                                              \
-  if (crow::logger::get_current_log_level() <= crow::LogLevel::Warning) \
-  crow::logger("WARNING ", crow::LogLevel::Warning)
-#define BMCWEB_LOG_INFO                                              \
-  if (crow::logger::get_current_log_level() <= crow::LogLevel::Info) \
-  crow::logger("INFO    ", crow::LogLevel::Info)
-#define BMCWEB_LOG_DEBUG                                              \
-  if (crow::logger::get_current_log_level() <= crow::LogLevel::Debug) \
-  crow::logger("DEBUG   ", crow::LogLevel::Debug)
+#define BMCWEB_LOG_CRITICAL                                                    \
+    if (crow::logger::get_current_log_level() <= crow::LogLevel::Critical)     \
+    crow::logger("CRITICAL", crow::LogLevel::Critical)
+#define BMCWEB_LOG_ERROR                                                       \
+    if (crow::logger::get_current_log_level() <= crow::LogLevel::Error)        \
+    crow::logger("ERROR   ", crow::LogLevel::Error)
+#define BMCWEB_LOG_WARNING                                                     \
+    if (crow::logger::get_current_log_level() <= crow::LogLevel::Warning)      \
+    crow::logger("WARNING ", crow::LogLevel::Warning)
+#define BMCWEB_LOG_INFO                                                        \
+    if (crow::logger::get_current_log_level() <= crow::LogLevel::Info)         \
+    crow::logger("INFO    ", crow::LogLevel::Info)
+#define BMCWEB_LOG_DEBUG                                                       \
+    if (crow::logger::get_current_log_level() <= crow::LogLevel::Debug)        \
+    crow::logger("DEBUG   ", crow::LogLevel::Debug)
diff --git a/crow/include/crow/middleware_context.h b/crow/include/crow/middleware_context.h
index 03309f6..f109a44 100644
--- a/crow/include/crow/middleware_context.h
+++ b/crow/include/crow/middleware_context.h
@@ -4,30 +4,32 @@
 #include "crow/http_response.h"
 #include "crow/utility.h"
 
-namespace crow {
-namespace detail {
+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 <int N>
-  using partial = typename std::conditional<
-      N == sizeof...(Middlewares) - 1, PartialContext,
-      typename parent_context::template partial<N>>::type;
+      public black_magic::LastElementType<Middlewares...>::type::Context
+{
+    using parent_context = typename black_magic::PopBack<
+        Middlewares...>::template rebind<::crow::detail::PartialContext>;
+    template <int 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 <typename T> typename T::Context& get()
+    {
+        return static_cast<typename T::Context&>(*this);
+    }
 };
 
-template <>
-struct PartialContext<> {
-  template <int>
-  using partial = PartialContext;
+template <> struct PartialContext<>
+{
+    template <int> using partial = PartialContext;
 };
 
 template <int N, typename Context, typename Container, typename CurrentMW,
@@ -39,25 +41,28 @@
 struct Context : private PartialContext<Middlewares...>
 // struct Context : private Middlewares::context... // simple but less type-safe
 {
-  template <int N, typename Context, typename Container>
-  friend typename std::enable_if<(N == 0)>::type afterHandlersCallHelper(
-      Container& middlewares, Context& ctx, Request& req, Response& res);
-  template <int N, typename Context, typename Container>
-  friend typename std::enable_if<(N > 0)>::type afterHandlersCallHelper(
-      Container& middlewares, Context& ctx, Request& req, Response& res);
+    template <int N, typename Context, typename Container>
+    friend typename std::enable_if<(N == 0)>::type
+        afterHandlersCallHelper(Container& middlewares, Context& ctx,
+                                Request& req, Response& res);
+    template <int N, typename Context, typename Container>
+    friend typename std::enable_if<(N > 0)>::type
+        afterHandlersCallHelper(Container& middlewares, Context& ctx,
+                                Request& req, Response& res);
 
-  template <int N, typename Context, typename Container, typename CurrentMW,
-            typename... Middlewares2>
-  friend bool middlewareCallHelper(Container& middlewares, Request& req,
-                                   Response& res, Context& ctx);
+    template <int 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 <typename T> typename T::Context& get()
+    {
+        return static_cast<typename T::Context&>(*this);
+    }
 
-  template <int N>
-  using partial = typename PartialContext<Middlewares...>::template partial<N>;
+    template <int N>
+    using partial =
+        typename PartialContext<Middlewares...>::template partial<N>;
 };
-}  // namespace detail
-}  // namespace crow
+} // namespace detail
+} // namespace crow
diff --git a/crow/include/crow/query_string.h b/crow/include/crow/query_string.h
index 0606994..67e426a 100644
--- a/crow/include/crow/query_string.h
+++ b/crow/include/crow/query_string.h
@@ -6,7 +6,8 @@
 #include <string>
 #include <vector>
 
-namespace crow {
+namespace crow
+{
 // ----------------------------------------------------------------------------
 // qs_parse (modified)
 // https://github.com/bartgrantham/qs_parse
@@ -37,306 +38,376 @@
 #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)
+#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;
-  unsigned char u1, u2, unyb, lnyb;
+inline int qsStrncmp(const char* s, const char* qs, size_t n)
+{
+    int i = 0;
+    unsigned char u1, u2, unyb, lnyb;
 
-  while (n-- > 0) {
-    u1 = static_cast<unsigned char>(*s++);
-    u2 = static_cast<unsigned char>(*qs++);
-
-    if (!BMCWEB_QS_ISQSCHR(u1)) {
-      u1 = '\0';
-    }
-    if (!BMCWEB_QS_ISQSCHR(u2)) {
-      u2 = '\0';
-    }
-
-    if (u1 == '+') {
-      u1 = ' ';
-    }
-    if (u1 == '%')  // easier/safer than scanf
+    while (n-- > 0)
     {
-      unyb = static_cast<unsigned char>(*s++);
-      lnyb = static_cast<unsigned char>(*s++);
-      if (BMCWEB_QS_ISHEX(unyb) && BMCWEB_QS_ISHEX(lnyb)) {
-        u1 = (BMCWEB_QS_HEX2DEC(unyb) * 16) + BMCWEB_QS_HEX2DEC(lnyb);
-      } else {
-        u1 = '\0';
-      }
-    }
+        u1 = static_cast<unsigned char>(*s++);
+        u2 = static_cast<unsigned char>(*qs++);
 
-    if (u2 == '+') {
-      u2 = ' ';
+        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<unsigned char>(*s++);
+            lnyb = static_cast<unsigned char>(*s++);
+            if (BMCWEB_QS_ISHEX(unyb) && BMCWEB_QS_ISHEX(lnyb))
+            {
+                u1 = (BMCWEB_QS_HEX2DEC(unyb) * 16) + BMCWEB_QS_HEX2DEC(lnyb);
+            }
+            else
+            {
+                u1 = '\0';
+            }
+        }
+
+        if (u2 == '+')
+        {
+            u2 = ' ';
+        }
+        if (u2 == '%') // easier/safer than scanf
+        {
+            unyb = static_cast<unsigned char>(*qs++);
+            lnyb = static_cast<unsigned char>(*qs++);
+            if (BMCWEB_QS_ISHEX(unyb) && BMCWEB_QS_ISHEX(lnyb))
+            {
+                u2 = (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 (u2 == '%')  // easier/safer than scanf
+    if (BMCWEB_QS_ISQSCHR(*qs))
     {
-      unyb = static_cast<unsigned char>(*qs++);
-      lnyb = static_cast<unsigned char>(*qs++);
-      if (BMCWEB_QS_ISHEX(unyb) && BMCWEB_QS_ISHEX(lnyb)) {
-        u2 = (BMCWEB_QS_HEX2DEC(unyb) * 16) + BMCWEB_QS_HEX2DEC(lnyb);
-      } else {
-        u2 = '\0';
-      }
+        return -1;
     }
-
-    if (u1 != u2) {
-      return u1 - u2;
+    else
+    {
+        return 0;
     }
-    if (u1 == '\0') {
-      return 0;
-    }
-    i++;
-  }
-  if (BMCWEB_QS_ISQSCHR(*qs)) {
-    return -1;
-  } else {
-    return 0;
-  }
 }
 
-inline int qsParse(char* qs, char* qs_kv[], int qs_kv_size) {
-  int i, j;
-  char* substrPtr;
+inline int qsParse(char* qs, char* qs_kv[], int qs_kv_size)
+{
+    int i, 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;
+    for (i = 0; i < qs_kv_size; i++)
+    {
+        qs_kv[i] = NULL;
     }
-    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);
+    // 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;
+    return i;
 }
 
-inline int qsDecode(char* qs) {
-  int i = 0, j = 0;
+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
+    while (BMCWEB_QS_ISQSCHR(qs[j]))
     {
-      if (!BMCWEB_QS_ISHEX(qs[j + 1]) || !BMCWEB_QS_ISHEX(qs[j + 2])) {
-        qs[i] = '\0';
-        return i;
-      }
-      qs[i] =
-          (BMCWEB_QS_HEX2DEC(qs[j + 1]) * 16) + BMCWEB_QS_HEX2DEC(qs[j + 2]);
-      j += 2;
-    } else {
-      qs[i] = 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] = (BMCWEB_QS_HEX2DEC(qs[j + 1]) * 16) +
+                    BMCWEB_QS_HEX2DEC(qs[j + 2]);
+            j += 2;
+        }
+        else
+        {
+            qs[i] = qs[j];
+        }
+        i++;
+        j++;
     }
-    i++;
-    j++;
-  }
-  qs[i] = '\0';
+    qs[i] = '\0';
 
-  return i;
+    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;
+                   int nth = 0)
+{
+    int i;
+    size_t keyLen, skip;
 
-  keyLen = strlen(key);
+    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;
-      }
+#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
+#endif // _qsSORTING
 
-  return NULL;
+    return NULL;
 }
 
 inline char* qsScanvalue(const char* key, const char* qs, char* val,
-                         size_t val_len) {
-  size_t i, keyLen;
-  const char* tmp;
+                         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;
+    // find the beginning of the k/v substrings
+    if ((tmp = strchr(qs, '?')) != NULL)
+    {
+        qs = tmp + 1;
     }
-    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';
+    keyLen = strlen(key);
+    while (qs[0] != '#' && qs[0] != '\0')
+    {
+        if (qsStrncmp(key, qs, keyLen) == 0)
+        {
+            break;
+        }
+        qs += strcspn(qs, "&") + 1;
     }
-  }
 
-  return val;
+    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
 // ----------------------------------------------------------------------------
 
-namespace crow {
-class QueryString {
- public:
-  static const int maxKeyValuePairsCount = 256;
+namespace crow
+{
+class QueryString
+{
+  public:
+    static const int maxKeyValuePairsCount = 256;
 
-  QueryString() = default;
+    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 url) : url(std::move(url)) {
-    if (url.empty()) {
-      return;
+    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()));
+        }
     }
 
-    keyValuePairs.resize(maxKeyValuePairsCount);
-
-    int 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];
+    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;
     }
-    os << " ]";
-    return os;
-  }
 
-  char* get(const std::string& name) const {
-    char* ret = qsK2v(name.c_str(), keyValuePairs.data(), 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(), keyValuePairs.size(),
-                      count++);
-      if (element == nullptr) {
-        break;
-      }
-      ret.push_back(element);
+    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;
     }
-    return ret;
-  }
 
- private:
-  std::string url;
-  std::vector<char*> keyValuePairs;
+    explicit QueryString(std::string url) : url(std::move(url))
+    {
+        if (url.empty())
+        {
+            return;
+        }
+
+        keyValuePairs.resize(maxKeyValuePairsCount);
+
+        int 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(), 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(),
+                            keyValuePairs.size(), count++);
+            if (element == nullptr)
+            {
+                break;
+            }
+            ret.push_back(element);
+        }
+        return ret;
+    }
+
+  private:
+    std::string url;
+    std::vector<char*> keyValuePairs;
 };
 
-}  // namespace crow
+} // namespace crow
diff --git a/crow/include/crow/routing.h b/crow/include/crow/routing.h
index ddf307a..945f361 100644
--- a/crow/include/crow/routing.h
+++ b/crow/include/crow/routing.h
@@ -1,5 +1,8 @@
 #pragma once
 
+#include "boost/container/flat_map.hpp"
+
+#include <boost/lexical_cast.hpp>
 #include <cerrno>
 #include <cstdint>
 #include <cstdlib>
@@ -8,9 +11,6 @@
 #include <tuple>
 #include <utility>
 #include <vector>
-#include <boost/lexical_cast.hpp>
-
-#include "boost/container/flat_map.hpp"
 
 #include "crow/common.h"
 #include "crow/http_request.h"
@@ -19,969 +19,1174 @@
 #include "crow/utility.h"
 #include "crow/websocket.h"
 
-namespace crow {
-class BaseRule {
- public:
-  BaseRule(std::string rule) : rule(std::move(rule)) {}
+namespace crow
+{
+class BaseRule
+{
+  public:
+    BaseRule(std::string rule) : rule(std::move(rule))
+    {
+    }
 
-  virtual ~BaseRule() {}
+    virtual ~BaseRule()
+    {
+    }
 
-  virtual void validate() = 0;
-  std::unique_ptr<BaseRule> upgrade() {
-    if (ruleToUpgrade) return std::move(ruleToUpgrade);
-    return {};
-  }
+    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, SocketAdaptor&&) {
-    res = Response(boost::beast::http::status::not_found);
-    res.end();
-  }
+    virtual void handle(const Request&, Response&, const RoutingParams&) = 0;
+    virtual void handleUpgrade(const Request&, Response& res, SocketAdaptor&&)
+    {
+        res = Response(boost::beast::http::status::not_found);
+        res.end();
+    }
 #ifdef BMCWEB_ENABLE_SSL
-  virtual void handleUpgrade(const Request&, Response& res, SSLAdaptor&&) {
-    res = Response(boost::beast::http::status::not_found);
-    res.end();
-  }
+    virtual void handleUpgrade(const Request&, Response& res, SSLAdaptor&&)
+    {
+        res = Response(boost::beast::http::status::not_found);
+        res.end();
+    }
 #endif
 
-  uint32_t getMethods() { return methodsBitfield; }
+    uint32_t getMethods()
+    {
+        return methodsBitfield;
+    }
 
- protected:
-  uint32_t methodsBitfield{1 << (int)boost::beast::http::verb::get};
+  protected:
+    uint32_t methodsBitfield{1 << (int)boost::beast::http::verb::get};
 
-  std::string rule;
-  std::string nameStr;
+    std::string rule;
+    std::string nameStr;
 
-  std::unique_ptr<BaseRule> ruleToUpgrade;
+    std::unique_ptr<BaseRule> ruleToUpgrade;
 
-  friend class Router;
-  template <typename T>
-  friend struct RuleParameterTraits;
+    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;
+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 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 {};
+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);
-  }
+            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);
-  }
+            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);
-  }
+            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);
-  }
+            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)...);
-  }
+            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 = (
+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 = (
 #ifdef BMCWEB_CAN_USE_CPP14
-        [f = std::move(f)]
+            [f = std::move(f)]
 #else
-        [f]
+            [f]
 #endif
-        (const Request&, Response& res, Args... args) {
-          res = Response(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 = Response(f(req, args...));
-      res.end();
+            (const Request&, Response& res, Args... args) {
+                res = Response(f(args...));
+                res.end();
+            });
     }
 
-    Func f;
-  };
+    template <typename Req, typename... Args> struct ReqHandlerWrapper
+    {
+        ReqHandlerWrapper(Func f) : f(std::move(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 = Response(f(req, args...));
-             res.end();
-        });*/
-  }
+        void operator()(const Request& req, Response& res, Args... args)
+        {
+            res = Response(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);
-  }
+        Func 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>
+    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 = Response(f(req, args...));
+                 res.end();
+            });*/
+    }
 
-  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>
+    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<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>...>;
-  };
+    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>...>;
+    };
 
-  typename HandlerTypeHelper<ArgsWrapped...>::type handler;
+    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>...>;
+    };
 
-  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});
-  }
+    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
+} // namespace routing_handler_call_helper
+} // namespace detail
 
-class WebSocketRule : public BaseRule {
-  using self_t = WebSocketRule;
+class WebSocketRule : public BaseRule
+{
+    using self_t = WebSocketRule;
 
- public:
-  WebSocketRule(std::string rule) : BaseRule(std::move(rule)) {}
+  public:
+    WebSocketRule(std::string rule) : BaseRule(std::move(rule))
+    {
+    }
 
-  void validate() override {}
+    void validate() override
+    {
+    }
 
-  void handle(const Request&, Response& res, const RoutingParams&) override {
-    res = Response(boost::beast::http::status::not_found);
-    res.end();
-  }
+    void handle(const Request&, Response& res, const RoutingParams&) override
+    {
+        res = Response(boost::beast::http::status::not_found);
+        res.end();
+    }
 
-  void handleUpgrade(const Request& req, Response&,
-                     SocketAdaptor&& adaptor) override {
-    new crow::websocket::ConnectionImpl<SocketAdaptor>(
-        req, std::move(adaptor), openHandler, messageHandler, closeHandler,
-        errorHandler);
-  }
-#ifdef BMCWEB_ENABLE_SSL
-  void handleUpgrade(const Request& req, Response&,
-                     SSLAdaptor&& adaptor) override {
-    std::shared_ptr<crow::websocket::ConnectionImpl<SSLAdaptor>> myConnection =
-        std::make_shared<crow::websocket::ConnectionImpl<SSLAdaptor>>(
+    void handleUpgrade(const Request& req, Response&,
+                       SocketAdaptor&& adaptor) override
+    {
+        new crow::websocket::ConnectionImpl<SocketAdaptor>(
             req, std::move(adaptor), openHandler, messageHandler, closeHandler,
             errorHandler);
-    myConnection->start();
-  }
+    }
+#ifdef BMCWEB_ENABLE_SSL
+    void handleUpgrade(const Request& req, Response&,
+                       SSLAdaptor&& adaptor) override
+    {
+        std::shared_ptr<crow::websocket::ConnectionImpl<SSLAdaptor>>
+            myConnection =
+                std::make_shared<crow::websocket::ConnectionImpl<SSLAdaptor>>(
+                    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& onopen(Func f)
+    {
+        openHandler = f;
+        return *this;
+    }
 
-  template <typename Func>
-  self_t& onmessage(Func f) {
-    messageHandler = 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& onclose(Func f)
+    {
+        closeHandler = f;
+        return *this;
+    }
 
-  template <typename Func>
-  self_t& onerror(Func f) {
-    errorHandler = 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;
+  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() {
-    auto p = new WebSocketRule(((self_t*)this)->rule);
-    ((self_t*)this)->ruleToUpgrade.reset(p);
-    return *p;
-  }
+template <typename T> struct RuleParameterTraits
+{
+    using self_t = T;
+    WebSocketRule& websocket()
+    {
+        auto p = new WebSocketRule(((self_t*)this)->rule);
+        ((self_t*)this)->ruleToUpgrade.reset(p);
+        return *p;
+    }
 
-  self_t& name(std::string name) noexcept {
-    ((self_t*)this)->nameStr = std::move(name);
-    return (self_t&)*this;
-  }
+    self_t& name(std::string name) noexcept
+    {
+        ((self_t*)this)->nameStr = std::move(name);
+        return (self_t&)*this;
+    }
 
-  self_t& methods(boost::beast::http::verb method) {
-    ((self_t*)this)->methodsBitfield = 1 << (int)method;
-    return (self_t&)*this;
-  }
+    self_t& methods(boost::beast::http::verb method)
+    {
+        ((self_t*)this)->methodsBitfield = 1 << (int)method;
+        return (self_t&)*this;
+    }
 
-  template <typename... MethodArgs>
-  self_t& methods(boost::beast::http::verb method, MethodArgs... args_method) {
-    methods(args_method...);
-    ((self_t*)this)->methodsBitfield |= 1 << (int)method;
-    return (self_t&)*this;
-  }
+    template <typename... MethodArgs>
+    self_t& methods(boost::beast::http::verb method, MethodArgs... args_method)
+    {
+        methods(args_method...);
+        ((self_t*)this)->methodsBitfield |= 1 << (int)method;
+        return (self_t&)*this;
+    }
 };
 
-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);
+class DynamicRule : public BaseRule, public RuleParameterTraits<DynamicRule>
+{
+  public:
+    DynamicRule(std::string rule) : BaseRule(std::move(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);
+    void validate() override
+    {
+        if (!erasedHandler)
+        {
+            throw std::runtime_error(nameStr + (!nameStr.empty() ? ": " : "") +
+                                     "no handler for url " + 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));
-  }
+    void handle(const Request& req, Response& res,
+                const RoutingParams& params) override
+    {
+        erasedHandler(req, res, params);
+    }
 
- private:
-  std::function<void(const Request&, Response&, const RoutingParams&)>
-      erasedHandler;
+    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...>;
+                   public RuleParameterTraits<TaggedRule<Args...>>
+{
+  public:
+    using self_t = TaggedRule<Args...>;
 
-  TaggedRule(std::string rule) : BaseRule(std::move(rule)) {}
-
-  void validate() override {
-    if (!handler) {
-      throw std::runtime_error(nameStr + (!nameStr.empty() ? ": " : "") +
-                               "no handler for url " + rule);
+    TaggedRule(std::string rule) : BaseRule(std::move(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 ||
+    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 = Response(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,
-        "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");
+        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 Request&, Response& res, Args... args) {
-      res = Response(f(args...));
-      res.end();
-    };
-  }
+        handler = [f = std::move(f)](const crow::Request& req,
+                                     crow::Response& res, Args... args) {
+            res = Response(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<
+    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,
-        "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");
+        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 = [f = std::move(f)](const crow::Request& req, crow::Response& res,
-                                 Args... args) {
-      res = Response(f(req, args...));
-      res.end();
-    };
-  }
+        handler = std::move(f);
+    }
 
-  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");
+    template <typename Func> void operator()(std::string name, Func&& f)
+    {
+        nameStr = std::move(name);
+        (*this).template operator()<Func>(std::forward(f));
+    }
 
-    handler = std::move(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});
+    }
 
-  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;
+  private:
+    std::function<void(const crow::Request&, crow::Response&, Args...)> handler;
 };
 
 const int ruleSpecialRedirectSlash = 1;
 
-class Trie {
- public:
-  struct Node {
-    unsigned ruleIndex{};
-    std::array<unsigned, (int)ParamType::MAX> paramChildrens{};
-    boost::container::flat_map<std::string, unsigned> children;
+class Trie
+{
+  public:
+    struct Node
+    {
+        unsigned ruleIndex{};
+        std::array<unsigned, (int)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),
-                         [](unsigned x) { return !x; });
-    }
-  };
-
-  Trie() : nodes(1) {}
-
- private:
-  void optimizeNode(Node* node) {
-    for (auto x : node->paramChildrens) {
-      if (!x) continue;
-      Node* child = &nodes[x];
-      optimizeNode(child);
-    }
-    if (node->children.empty()) return;
-    bool mergeWithChild = true;
-    for (auto& kv : node->children) {
-      Node* child = &nodes[kv.second];
-      if (!child->isSimpleNode()) {
-        mergeWithChild = false;
-        break;
-      }
-    }
-    if (mergeWithChild) {
-      decltype(node->children) merged;
-      for (auto& kv : node->children) {
-        Node* child = &nodes[kv.second];
-        for (auto& childKv : child->children) {
-          merged[kv.first + childKv.first] = childKv.second;
+        bool isSimpleNode() const
+        {
+            return !ruleIndex && std::all_of(std::begin(paramChildrens),
+                                             std::end(paramChildrens),
+                                             [](unsigned x) { return !x; });
         }
-      }
-      node->children = std::move(merged);
-      optimizeNode(node);
-    } else {
-      for (auto& 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) {
-    if (node == nullptr) {
-      node = head();
-    }
-    for (auto& 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, pos + fragment.size());
-      } else {
-        if (req_url.compare(pos, fragment.size(), fragment) == 0) {
-          findRouteIndexes(req_url, route_indexes, child,
-                           pos + fragment.size());
-        }
-      }
-    }
-  }
-
-  std::pair<unsigned, RoutingParams> find(
-      const boost::string_view req_url, const Node* node = nullptr,
-      unsigned 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[(int)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);
-          auto ret =
-              find(req_url, &nodes[node->paramChildrens[(int)ParamType::INT]],
-                   eptr - req_url.data(), params);
-          updateFound(ret);
-          params->intParams.pop_back();
+    Trie() : nodes(1)
+    {
+    }
+
+  private:
+    void optimizeNode(Node* node)
+    {
+        for (auto x : node->paramChildrens)
+        {
+            if (!x)
+                continue;
+            Node* child = &nodes[x];
+            optimizeNode(child);
         }
-      }
-    }
-
-    if (node->paramChildrens[(int)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);
-          auto ret =
-              find(req_url, &nodes[node->paramChildrens[(int)ParamType::UINT]],
-                   eptr - req_url.data(), params);
-          updateFound(ret);
-          params->uintParams.pop_back();
-        }
-      }
-    }
-
-    if (node->paramChildrens[(int)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);
-          auto ret = find(req_url,
-                          &nodes[node->paramChildrens[(int)ParamType::DOUBLE]],
-                          eptr - req_url.data(), params);
-          updateFound(ret);
-          params->doubleParams.pop_back();
-        }
-      }
-    }
-
-    if (node->paramChildrens[(int)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));
-        auto ret =
-            find(req_url, &nodes[node->paramChildrens[(int)ParamType::STRING]],
-                 epos, params);
-        updateFound(ret);
-        params->stringParams.pop_back();
-      }
-    }
-
-    if (node->paramChildrens[(int)ParamType::PATH]) {
-      size_t epos = req_url.size();
-
-      if (epos != pos) {
-        params->stringParams.emplace_back(req_url.substr(pos, epos - pos));
-        auto ret =
-            find(req_url, &nodes[node->paramChildrens[(int)ParamType::PATH]],
-                 epos, params);
-        updateFound(ret);
-        params->stringParams.pop_back();
-      }
-    }
-
-    for (auto& kv : node->children) {
-      const std::string& fragment = kv.first;
-      const Node* child = &nodes[kv.second];
-
-      if (req_url.compare(pos, fragment.size(), fragment) == 0) {
-        auto ret = find(req_url, child, pos + fragment.size(), params);
-        updateFound(ret);
-      }
-    }
-
-    return {found, matchParams};
-  }
-
-  void add(const std::string& url, unsigned ruleIndex) {
-    unsigned idx{0};
-
-    for (unsigned i = 0; i < url.size(); i++) {
-      char c = url[i];
-      if (c == '<') {
-        static struct ParamTraits {
-          ParamType type;
-          std::string name;
-        } paramTraits[] = {
-            {ParamType::INT, "<int>"},      {ParamType::UINT, "<uint>"},
-            {ParamType::DOUBLE, "<float>"}, {ParamType::DOUBLE, "<double>"},
-            {ParamType::STRING, "<str>"},   {ParamType::STRING, "<string>"},
-            {ParamType::PATH, "<path>"},
-        };
-
-        for (auto& x : paramTraits) {
-          if (url.compare(i, x.name.size(), x.name) == 0) {
-            if (!nodes[idx].paramChildrens[(int)x.type]) {
-              auto newNodeIdx = newNode();
-              nodes[idx].paramChildrens[(int)x.type] = newNodeIdx;
+        if (node->children.empty())
+            return;
+        bool mergeWithChild = true;
+        for (auto& kv : node->children)
+        {
+            Node* child = &nodes[kv.second];
+            if (!child->isSimpleNode())
+            {
+                mergeWithChild = false;
+                break;
             }
-            idx = nodes[idx].paramChildrens[(int)x.type];
-            i += x.name.size();
-            break;
-          }
+        }
+        if (mergeWithChild)
+        {
+            decltype(node->children) merged;
+            for (auto& kv : node->children)
+            {
+                Node* child = &nodes[kv.second];
+                for (auto& childKv : child->children)
+                {
+                    merged[kv.first + childKv.first] = childKv.second;
+                }
+            }
+            node->children = std::move(merged);
+            optimizeNode(node);
+        }
+        else
+        {
+            for (auto& 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)
+    {
+        if (node == nullptr)
+        {
+            node = head();
+        }
+        for (auto& 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,
+                                 pos + fragment.size());
+            }
+            else
+            {
+                if (req_url.compare(pos, fragment.size(), fragment) == 0)
+                {
+                    findRouteIndexes(req_url, route_indexes, child,
+                                     pos + fragment.size());
+                }
+            }
+        }
+    }
+
+    std::pair<unsigned, RoutingParams>
+        find(const boost::string_view req_url, const Node* node = nullptr,
+             unsigned 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[(int)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);
+                    auto ret =
+                        find(req_url,
+                             &nodes[node->paramChildrens[(int)ParamType::INT]],
+                             eptr - req_url.data(), params);
+                    updateFound(ret);
+                    params->intParams.pop_back();
+                }
+            }
         }
 
-        i--;
-      } else {
-        std::string piece(&c, 1);
-        if (!nodes[idx].children.count(piece)) {
-          auto 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, int level) {
-    for (int i = 0; i < (int)ParamType::MAX; i++) {
-      if (n->paramChildrens[i]) {
-        BMCWEB_LOG_DEBUG << std::string(
-            2 * level, ' ') /*<< "("<<n->paramChildrens[i]<<") "*/;
-        switch ((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;
+        if (node->paramChildrens[(int)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);
+                    auto ret =
+                        find(req_url,
+                             &nodes[node->paramChildrens[(int)ParamType::UINT]],
+                             eptr - req_url.data(), params);
+                    updateFound(ret);
+                    params->uintParams.pop_back();
+                }
+            }
         }
 
-        debugNodePrint(&nodes[n->paramChildrens[i]], level + 1);
-      }
+        if (node->paramChildrens[(int)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);
+                    auto ret = find(
+                        req_url,
+                        &nodes[node->paramChildrens[(int)ParamType::DOUBLE]],
+                        eptr - req_url.data(), params);
+                    updateFound(ret);
+                    params->doubleParams.pop_back();
+                }
+            }
+        }
+
+        if (node->paramChildrens[(int)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));
+                auto ret =
+                    find(req_url,
+                         &nodes[node->paramChildrens[(int)ParamType::STRING]],
+                         epos, params);
+                updateFound(ret);
+                params->stringParams.pop_back();
+            }
+        }
+
+        if (node->paramChildrens[(int)ParamType::PATH])
+        {
+            size_t epos = req_url.size();
+
+            if (epos != pos)
+            {
+                params->stringParams.emplace_back(
+                    req_url.substr(pos, epos - pos));
+                auto ret = find(
+                    req_url, &nodes[node->paramChildrens[(int)ParamType::PATH]],
+                    epos, params);
+                updateFound(ret);
+                params->stringParams.pop_back();
+            }
+        }
+
+        for (auto& kv : node->children)
+        {
+            const std::string& fragment = kv.first;
+            const Node* child = &nodes[kv.second];
+
+            if (req_url.compare(pos, fragment.size(), fragment) == 0)
+            {
+                auto ret = find(req_url, child, pos + fragment.size(), params);
+                updateFound(ret);
+            }
+        }
+
+        return {found, matchParams};
     }
-    for (auto& kv : n->children) {
-      BMCWEB_LOG_DEBUG << std::string(2 * level,
-                                      ' ') /*<< "(" << kv.second << ") "*/
-                       << kv.first;
-      debugNodePrint(&nodes[kv.second], level + 1);
+
+    void add(const std::string& url, unsigned ruleIndex)
+    {
+        unsigned idx{0};
+
+        for (unsigned i = 0; i < url.size(); i++)
+        {
+            char c = url[i];
+            if (c == '<')
+            {
+                static struct ParamTraits
+                {
+                    ParamType type;
+                    std::string name;
+                } paramTraits[] = {
+                    {ParamType::INT, "<int>"},
+                    {ParamType::UINT, "<uint>"},
+                    {ParamType::DOUBLE, "<float>"},
+                    {ParamType::DOUBLE, "<double>"},
+                    {ParamType::STRING, "<str>"},
+                    {ParamType::STRING, "<string>"},
+                    {ParamType::PATH, "<path>"},
+                };
+
+                for (auto& x : paramTraits)
+                {
+                    if (url.compare(i, x.name.size(), x.name) == 0)
+                    {
+                        if (!nodes[idx].paramChildrens[(int)x.type])
+                        {
+                            auto newNodeIdx = newNode();
+                            nodes[idx].paramChildrens[(int)x.type] = newNodeIdx;
+                        }
+                        idx = nodes[idx].paramChildrens[(int)x.type];
+                        i += x.name.size();
+                        break;
+                    }
+                }
+
+                i--;
+            }
+            else
+            {
+                std::string piece(&c, 1);
+                if (!nodes[idx].children.count(piece))
+                {
+                    auto 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;
     }
-  }
 
- public:
-  void debugPrint() { debugNodePrint(head(), 0); }
+  private:
+    void debugNodePrint(Node* n, int level)
+    {
+        for (int i = 0; i < (int)ParamType::MAX; i++)
+        {
+            if (n->paramChildrens[i])
+            {
+                BMCWEB_LOG_DEBUG << std::string(
+                    2 * level, ' ') /*<< "("<<n->paramChildrens[i]<<") "*/;
+                switch ((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;
+                }
 
- private:
-  const Node* head() const { return &nodes.front(); }
+                debugNodePrint(&nodes[n->paramChildrens[i]], level + 1);
+            }
+        }
+        for (auto& kv : n->children)
+        {
+            BMCWEB_LOG_DEBUG
+                << std::string(2 * level, ' ') /*<< "(" << kv.second << ") "*/
+                << kv.first;
+            debugNodePrint(&nodes[kv.second], level + 1);
+        }
+    }
 
-  Node* head() { return &nodes.front(); }
+  public:
+    void debugPrint()
+    {
+        debugNodePrint(head(), 0);
+    }
 
-  unsigned newNode() {
-    nodes.resize(nodes.size() + 1);
-    return nodes.size() - 1;
-  }
+  private:
+    const Node* head() const
+    {
+        return &nodes.front();
+    }
 
-  std::vector<Node> nodes;
+    Node* head()
+    {
+        return &nodes.front();
+    }
+
+    unsigned newNode()
+    {
+        nodes.resize(nodes.size() + 1);
+        return nodes.size() - 1;
+    }
+
+    std::vector<Node> nodes;
 };
 
-class Router {
- public:
-  Router() : rules(2) {}
-
-  DynamicRule& newRuleDynamic(const std::string& rule) {
-    std::unique_ptr<DynamicRule> ruleObject =
-        std::make_unique<DynamicRule>(rule);
-    DynamicRule* ptr = ruleObject.get();
-    internalAddRuleObject(rule, 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();
-
-    internalAddRuleObject(rule, std::move(ruleObject));
-
-    return *ptr;
-  }
-
-  void internalAddRuleObject(const std::string& rule,
-                             std::unique_ptr<BaseRule> ruleObject) {
-    rules.emplace_back(std::move(ruleObject));
-    trie.add(rule, rules.size() - 1);
-
-    // directory case:
-    //   request to `/about' url matches `/about/' rule
-    if (rule.size() > 2 && rule.back() == '/') {
-      trie.add(rule.substr(0, rule.size() - 1), rules.size() - 1);
-    }
-  }
-
-  void validate() {
-    trie.validate();
-    for (auto& rule : rules) {
-      if (rule) {
-        auto upgraded = rule->upgrade();
-        if (upgraded) rule = std::move(upgraded);
-        rule->validate();
-      }
-    }
-  }
-
-  template <typename Adaptor>
-  void handleUpgrade(const Request& req, Response& res, Adaptor&& adaptor) {
-    auto found = trie.find(req.url);
-    unsigned ruleIndex = found.first;
-    if (!ruleIndex) {
-      BMCWEB_LOG_DEBUG << "Cannot match rules " << req.url;
-      res = Response(boost::beast::http::status::not_found);
-      res.end();
-      return;
+class Router
+{
+  public:
+    Router() : rules(2)
+    {
     }
 
-    if (ruleIndex >= rules.size())
-      throw std::runtime_error("Trie internal structure corrupted!");
+    DynamicRule& newRuleDynamic(const std::string& rule)
+    {
+        std::unique_ptr<DynamicRule> ruleObject =
+            std::make_unique<DynamicRule>(rule);
+        DynamicRule* ptr = ruleObject.get();
+        internalAddRuleObject(rule, std::move(ruleObject));
 
-    if (ruleIndex == ruleSpecialRedirectSlash) {
-      BMCWEB_LOG_INFO << "Redirecting to a url with trailing slash: "
-                      << req.url;
-      res = Response(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;
+        return *ptr;
     }
 
-    if ((rules[ruleIndex]->getMethods() & (1 << (uint32_t)req.method())) == 0) {
-      BMCWEB_LOG_DEBUG << "Rule found but method mismatch: " << req.url
-                       << " with " << req.methodString() << "("
-                       << (uint32_t)req.method() << ") / "
-                       << rules[ruleIndex]->getMethods();
-      res = Response(boost::beast::http::status::not_found);
-      res.end();
-      return;
+    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();
+
+        internalAddRuleObject(rule, std::move(ruleObject));
+
+        return *ptr;
     }
 
-    BMCWEB_LOG_DEBUG << "Matched rule (upgrade) '" << rules[ruleIndex]->rule
-                     << "' " << (uint32_t)req.method() << " / "
-                     << rules[ruleIndex]->getMethods();
+    void internalAddRuleObject(const std::string& rule,
+                               std::unique_ptr<BaseRule> ruleObject)
+    {
+        rules.emplace_back(std::move(ruleObject));
+        trie.add(rule, rules.size() - 1);
 
-    // 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 = Response(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 = Response(boost::beast::http::status::internal_server_error);
-      res.end();
-      return;
-    }
-  }
-
-  void handle(const Request& req, Response& res) {
-    auto 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;
+        // directory case:
+        //   request to `/about' url matches `/about/' rule
+        if (rule.size() > 2 && rule.back() == '/')
+        {
+            trie.add(rule.substr(0, rule.size() - 1), rules.size() - 1);
+        }
     }
 
-    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 = Response(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;
+    void validate()
+    {
+        trie.validate();
+        for (auto& rule : rules)
+        {
+            if (rule)
+            {
+                auto upgraded = rule->upgrade();
+                if (upgraded)
+                    rule = std::move(upgraded);
+                rule->validate();
+            }
+        }
     }
 
-    if ((rules[ruleIndex]->getMethods() & (1 << (uint32_t)req.method())) == 0) {
-      BMCWEB_LOG_DEBUG << "Rule found but method mismatch: " << req.url
-                       << " with " << req.methodString() << "("
-                       << (uint32_t)req.method() << ") / "
-                       << rules[ruleIndex]->getMethods();
-      res = Response(boost::beast::http::status::not_found);
-      res.end();
-      return;
+    template <typename Adaptor>
+    void handleUpgrade(const Request& req, Response& res, Adaptor&& adaptor)
+    {
+        auto found = trie.find(req.url);
+        unsigned ruleIndex = found.first;
+        if (!ruleIndex)
+        {
+            BMCWEB_LOG_DEBUG << "Cannot match rules " << req.url;
+            res = Response(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 = Response(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() & (1 << (uint32_t)req.method())) ==
+            0)
+        {
+            BMCWEB_LOG_DEBUG << "Rule found but method mismatch: " << req.url
+                             << " with " << req.methodString() << "("
+                             << (uint32_t)req.method() << ") / "
+                             << rules[ruleIndex]->getMethods();
+            res = Response(boost::beast::http::status::not_found);
+            res.end();
+            return;
+        }
+
+        BMCWEB_LOG_DEBUG << "Matched rule (upgrade) '" << rules[ruleIndex]->rule
+                         << "' " << (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 = Response(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 = Response(boost::beast::http::status::internal_server_error);
+            res.end();
+            return;
+        }
     }
 
-    BMCWEB_LOG_DEBUG << "Matched rule '" << rules[ruleIndex]->rule << "' "
-                     << (uint32_t)req.method() << " / "
-                     << rules[ruleIndex]->getMethods();
+    void handle(const Request& req, Response& res)
+    {
+        auto found = trie.find(req.url);
 
-    // 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 = Response(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 = Response(boost::beast::http::status::internal_server_error);
-      res.end();
-      return;
+        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 = Response(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() & (1 << (uint32_t)req.method())) ==
+            0)
+        {
+            BMCWEB_LOG_DEBUG << "Rule found but method mismatch: " << req.url
+                             << " with " << req.methodString() << "("
+                             << (uint32_t)req.method() << ") / "
+                             << rules[ruleIndex]->getMethods();
+            res = Response(boost::beast::http::status::not_found);
+            res.end();
+            return;
+        }
+
+        BMCWEB_LOG_DEBUG << "Matched rule '" << rules[ruleIndex]->rule << "' "
+                         << (uint32_t)req.method() << " / "
+                         << rules[ruleIndex]->getMethods();
+
+        // 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 = Response(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 = Response(boost::beast::http::status::internal_server_error);
+            res.end();
+            return;
+        }
     }
-  }
 
-  void debugPrint() { trie.debugPrint(); }
-
-  std::vector<const std::string*> getRoutes(const std::string& parent) {
-    std::vector<unsigned> x;
-    std::vector<const std::string*> ret;
-    trie.findRouteIndexes(parent, x);
-    for (unsigned index : x) {
-      ret.push_back(&rules[index]->rule);
+    void debugPrint()
+    {
+        trie.debugPrint();
     }
-    return ret;
-  }
 
- private:
-  std::vector<std::unique_ptr<BaseRule>> rules;
-  Trie trie;
+    std::vector<const std::string*> getRoutes(const std::string& parent)
+    {
+        std::vector<unsigned> x;
+        std::vector<const std::string*> ret;
+        trie.findRouteIndexes(parent, x);
+        for (unsigned index : x)
+        {
+            ret.push_back(&rules[index]->rule);
+        }
+        return ret;
+    }
+
+  private:
+    std::vector<std::unique_ptr<BaseRule>> rules;
+    Trie trie;
 };
-}  // namespace crow
+} // namespace crow
diff --git a/crow/include/crow/socket_adaptors.h b/crow/include/crow/socket_adaptors.h
index 1d43ca2..a47697f 100644
--- a/crow/include/crow/socket_adaptors.h
+++ b/crow/include/crow/socket_adaptors.h
@@ -1,144 +1,200 @@
 #pragma once
-#include "crow/logging.h"
-
 #include <boost/asio.hpp>
 #include <boost/lexical_cast.hpp>
 
+#include "crow/logging.h"
+
 #ifdef BMCWEB_ENABLE_SSL
 #include <boost/asio/ssl.hpp>
 #endif
-namespace crow {
+namespace crow
+{
 using namespace boost;
 using tcp = asio::ip::tcp;
 
-struct SocketAdaptor {
-  using streamType = tcp::socket;
-  using secure = std::false_type;
-  using context = void;
-  SocketAdaptor(boost::asio::io_service& ioService, context* /*unused*/)
-      : socketCls(ioService) {}
-
-  boost::asio::io_service& getIoService() { return socketCls.get_io_service(); }
-
-  tcp::socket& rawSocket() { return socketCls; }
-
-  tcp::socket& socket() { return socketCls; }
-
-  std::string remoteEndpoint() {
-    boost::system::error_code ec;
-    tcp::endpoint ep = socketCls.remote_endpoint(ec);
-    if (ec) {
-      return "";
+struct SocketAdaptor
+{
+    using streamType = tcp::socket;
+    using secure = std::false_type;
+    using context = void;
+    SocketAdaptor(boost::asio::io_service& ioService, context* /*unused*/) :
+        socketCls(ioService)
+    {
     }
-    return boost::lexical_cast<std::string>(ep);
-  }
 
-  bool isOpen() { return socketCls.is_open(); }
+    boost::asio::io_service& getIoService()
+    {
+        return socketCls.get_io_service();
+    }
 
-  void close() { socketCls.close(); }
+    tcp::socket& rawSocket()
+    {
+        return socketCls;
+    }
 
-  template <typename F>
-  void start(F f) {
-    boost::system::error_code ec;
-    f(ec);
-  }
+    tcp::socket& socket()
+    {
+        return socketCls;
+    }
 
-  tcp::socket socketCls;
+    std::string remoteEndpoint()
+    {
+        boost::system::error_code ec;
+        tcp::endpoint ep = socketCls.remote_endpoint(ec);
+        if (ec)
+        {
+            return "";
+        }
+        return boost::lexical_cast<std::string>(ep);
+    }
+
+    bool isOpen()
+    {
+        return socketCls.is_open();
+    }
+
+    void close()
+    {
+        socketCls.close();
+    }
+
+    template <typename F> void start(F f)
+    {
+        boost::system::error_code ec;
+        f(ec);
+    }
+
+    tcp::socket socketCls;
 };
 
-struct TestSocketAdaptor {
-  using secure = std::false_type;
-  using context = void;
-  TestSocketAdaptor(boost::asio::io_service& ioService, context* /*unused*/)
-      : socketCls(ioService) {}
+struct TestSocketAdaptor
+{
+    using secure = std::false_type;
+    using context = void;
+    TestSocketAdaptor(boost::asio::io_service& ioService, context* /*unused*/) :
+        socketCls(ioService)
+    {
+    }
 
-  boost::asio::io_service& getIoService() { return socketCls.get_io_service(); }
+    boost::asio::io_service& getIoService()
+    {
+        return socketCls.get_io_service();
+    }
 
-  tcp::socket& rawSocket() { return socketCls; }
+    tcp::socket& rawSocket()
+    {
+        return socketCls;
+    }
 
-  tcp::socket& socket() { return socketCls; }
+    tcp::socket& socket()
+    {
+        return socketCls;
+    }
 
-  std::string remoteEndpoint() { return "Testhost"; }
+    std::string remoteEndpoint()
+    {
+        return "Testhost";
+    }
 
-  bool isOpen() { return socketCls.is_open(); }
+    bool isOpen()
+    {
+        return socketCls.is_open();
+    }
 
-  void close() { socketCls.close(); }
+    void close()
+    {
+        socketCls.close();
+    }
 
-  template <typename F>
-  void start(F f) {
-    f(boost::system::error_code());
-  }
+    template <typename F> void start(F f)
+    {
+        f(boost::system::error_code());
+    }
 
-  tcp::socket socketCls;
+    tcp::socket socketCls;
 };
 
 #ifdef BMCWEB_ENABLE_SSL
-struct SSLAdaptor {
-  using streamType = boost::asio::ssl::stream<tcp::socket>;
-  using secure = std::true_type;
-  using context = boost::asio::ssl::context;
-  using ssl_socket_t = boost::asio::ssl::stream<tcp::socket>;
-  SSLAdaptor(boost::asio::io_service& ioService, context* ctx)
-      : sslSocket(new ssl_socket_t(ioService, *ctx)) {}
-
-  boost::asio::ssl::stream<tcp::socket>& socket() { return *sslSocket; }
-
-  tcp::socket::lowest_layer_type& rawSocket() {
-    return sslSocket->lowest_layer();
-  }
-
-  std::string remoteEndpoint() {
-    boost::system::error_code ec;
-    tcp::endpoint ep = rawSocket().remote_endpoint(ec);
-    if (ec) {
-      return "";
+struct SSLAdaptor
+{
+    using streamType = boost::asio::ssl::stream<tcp::socket>;
+    using secure = std::true_type;
+    using context = boost::asio::ssl::context;
+    using ssl_socket_t = boost::asio::ssl::stream<tcp::socket>;
+    SSLAdaptor(boost::asio::io_service& ioService, context* ctx) :
+        sslSocket(new ssl_socket_t(ioService, *ctx))
+    {
     }
-    return boost::lexical_cast<std::string>(ep);
-  }
 
-  bool isOpen() {
-    /*TODO(ed) this is a bit of a cheat.
-     There are cases  when running a websocket where sslSocket might have
-    std::move() called on it (to transfer ownership to websocket::Connection)
-    and be empty.  This (and the check on close()) is a cheat to do something
-    sane in this scenario. the correct fix would likely involve changing the
-    http parser to return a specific code meaning "has been upgraded" so that
-    the doRead function knows not to try to close the Connection which would
-    fail, because the adapter is gone.  As is, doRead believes the parse
-    failed, because isOpen now returns False (which could also mean the client
-    disconnected during parse)
-    UPdate: The parser does in fact have an "isUpgrade" method that is
-    intended for exactly this purpose.  Todo is now to make doRead obey the
-    flag appropriately so this code can be changed back.
-    */
-    if (sslSocket != nullptr) {
-      return sslSocket->lowest_layer().is_open();
+    boost::asio::ssl::stream<tcp::socket>& socket()
+    {
+        return *sslSocket;
     }
-    return false;
-  }
 
-  void close() {
-    if (sslSocket == nullptr) {
-      return;
+    tcp::socket::lowest_layer_type& rawSocket()
+    {
+        return sslSocket->lowest_layer();
     }
-    boost::system::error_code ec;
 
-    // Shut it down
-    this->sslSocket->lowest_layer().close();
-  }
+    std::string remoteEndpoint()
+    {
+        boost::system::error_code ec;
+        tcp::endpoint ep = rawSocket().remote_endpoint(ec);
+        if (ec)
+        {
+            return "";
+        }
+        return boost::lexical_cast<std::string>(ep);
+    }
 
-  boost::asio::io_service& getIoService() {
-    return rawSocket().get_io_service();
-  }
+    bool isOpen()
+    {
+        /*TODO(ed) this is a bit of a cheat.
+         There are cases  when running a websocket where sslSocket might have
+        std::move() called on it (to transfer ownership to
+        websocket::Connection) and be empty.  This (and the check on close()) is
+        a cheat to do something sane in this scenario. the correct fix would
+        likely involve changing the http parser to return a specific code
+        meaning "has been upgraded" so that the doRead function knows not to try
+        to close the Connection which would fail, because the adapter is gone.
+        As is, doRead believes the parse failed, because isOpen now returns
+        False (which could also mean the client disconnected during parse)
+        UPdate: The parser does in fact have an "isUpgrade" method that is
+        intended for exactly this purpose.  Todo is now to make doRead obey the
+        flag appropriately so this code can be changed back.
+        */
+        if (sslSocket != nullptr)
+        {
+            return sslSocket->lowest_layer().is_open();
+        }
+        return false;
+    }
 
-  template <typename F>
-  void start(F f) {
-    sslSocket->async_handshake(
-        boost::asio::ssl::stream_base::server,
-        [f](const boost::system::error_code& ec) { f(ec); });
-  }
+    void close()
+    {
+        if (sslSocket == nullptr)
+        {
+            return;
+        }
+        boost::system::error_code ec;
 
-  std::unique_ptr<boost::asio::ssl::stream<tcp::socket>> sslSocket;
+        // Shut it down
+        this->sslSocket->lowest_layer().close();
+    }
+
+    boost::asio::io_service& getIoService()
+    {
+        return rawSocket().get_io_service();
+    }
+
+    template <typename F> void start(F f)
+    {
+        sslSocket->async_handshake(
+            boost::asio::ssl::stream_base::server,
+            [f](const boost::system::error_code& ec) { f(ec); });
+    }
+
+    std::unique_ptr<boost::asio::ssl::stream<tcp::socket>> sslSocket;
 };
 #endif
-}  // namespace crow
+} // namespace crow
diff --git a/crow/include/crow/timer_queue.h b/crow/include/crow/timer_queue.h
index f5bb467..bf1e084 100644
--- a/crow/include/crow/timer_queue.h
+++ b/crow/include/crow/timer_queue.h
@@ -1,63 +1,78 @@
 #pragma once
 
-#include <chrono>
-#include <functional>
-#include "crow/logging.h"
 #include <boost/circular_buffer.hpp>
 #include <boost/circular_buffer/space_optimized.hpp>
+#include <chrono>
+#include <functional>
 
-namespace crow {
-namespace detail {
+#include "crow/logging.h"
+
+namespace crow
+{
+namespace detail
+{
 // fast timer queue for fixed tick value.
-class TimerQueue {
- public:
-  TimerQueue() { dq.set_capacity(100); }
-
-  void cancel(int k) {
-    unsigned int index = static_cast<unsigned int>(k - step);
-    if (index < dq.size()) {
-      dq[index].second = nullptr;
+class TimerQueue
+{
+  public:
+    TimerQueue()
+    {
+        dq.set_capacity(100);
     }
-  }
 
-  int add(std::function<void()> f) {
-    dq.push_back(
-        std::make_pair(std::chrono::steady_clock::now(), std::move(f)));
-    int 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++;
+    void cancel(int k)
+    {
+        unsigned int index = static_cast<unsigned int>(k - step);
+        if (index < dq.size())
+        {
+            dq[index].second = nullptr;
+        }
     }
-  }
 
- private:
-  using storage_type =
-      std::pair<std::chrono::time_point<std::chrono::steady_clock>,
-                std::function<void()>>;
+    int add(std::function<void()> f)
+    {
+        dq.push_back(
+            std::make_pair(std::chrono::steady_clock::now(), std::move(f)));
+        int ret = step + dq.size() - 1;
 
-  boost::circular_buffer_space_optimized<storage_type,
-                                         std::allocator<storage_type>>
-      dq{};
+        BMCWEB_LOG_DEBUG << "timer add inside: " << this << ' ' << ret;
+        return ret;
+    }
 
-  // boost::circular_buffer<storage_type> dq{20};
-  // std::deque<storage_type> dq{};
-  int step{};
+    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{};
+    int step{};
 };
-}  // namespace detail
-}  // namespace crow
+} // namespace detail
+} // namespace crow
diff --git a/crow/include/crow/utility.h b/crow/include/crow/utility.h
index d2557b0..9d34e71 100644
--- a/crow/include/crow/utility.h
+++ b/crow/include/crow/utility.h
@@ -1,105 +1,136 @@
 #pragma once
 
+#include "nlohmann/json.hpp"
+
+#include <boost/utility/string_view.hpp>
 #include <cstdint>
 #include <cstring>
 #include <functional>
 #include <stdexcept>
 #include <string>
 #include <tuple>
-#include "nlohmann/json.hpp"
-#include <boost/utility/string_view.hpp>
 
-namespace crow {
-namespace black_magic {
-struct OutOfRange {
-  OutOfRange(unsigned /*pos*/, unsigned /*length*/) {}
+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;
+constexpr unsigned requiresInRange(unsigned i, unsigned len)
+{
+    return i >= len ? throw OutOfRange(i, len) : i;
 }
 
-class ConstStr {
-  const char* const beginPtr;
-  unsigned sizeUint;
+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];
-  }
+  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 operator const char*() const
+    {
+        return beginPtr;
+    }
 
-  constexpr const char* begin() const { return beginPtr; }
-  constexpr const char* end() const { return beginPtr + sizeUint; }
+    constexpr const char* begin() const
+    {
+        return beginPtr;
+    }
+    constexpr const char* end() const
+    {
+        return beginPtr + sizeUint;
+    }
 
-  constexpr unsigned size() const { return sizeUint; }
+    constexpr unsigned size() const
+    {
+        return sizeUint;
+    }
 };
 
-constexpr unsigned findClosingTag(ConstStr s, unsigned p) {
-  return s[p] == '>' ? p : findClosingTag(s, p + 1);
+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 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 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);
+                      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 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 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 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 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);
+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;
+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;             \
-  }
+#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);
@@ -113,279 +144,290 @@
 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 <typename... Args> struct compute_parameter_tag_from_args_list;
 
-template <>
-struct compute_parameter_tag_from_args_list<> {
-  static const int value = 0;
+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;
+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;
-  }
-  int sa = a % 6;
-  int 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 bool isParameterTagCompatible(uint64_t a, uint64_t b)
+{
+    if (a == 0)
+    {
+        return b == 0;
+    }
+    if (b == 0)
+    {
+        return a == 0;
+    }
+    int sa = a % 6;
+    int 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 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);
+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);
+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... 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 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(...);
+    template <typename...> static int __test(...);
 
-  static constexpr bool value = sizeof(__test<F, Args...>(0)) == sizeof(char);
+    static constexpr bool value = sizeof(__test<F, Args...>(0)) == sizeof(char);
 };
 
-template <int N>
-struct SingleTagToType {};
-
-template <>
-struct SingleTagToType<1> {
-  using type = int64_t;
+template <int N> struct SingleTagToType
+{
 };
 
-template <>
-struct SingleTagToType<2> {
-  using type = uint64_t;
+template <> struct SingleTagToType<1>
+{
+    using type = int64_t;
 };
 
-template <>
-struct SingleTagToType<3> {
-  using type = double;
+template <> struct SingleTagToType<2>
+{
+    using type = uint64_t;
 };
 
-template <>
-struct SingleTagToType<4> {
-  using type = std::string;
+template <> struct SingleTagToType<3>
+{
+    using type = double;
 };
 
-template <>
-struct SingleTagToType<5> {
-  using type = std::string;
+template <> struct SingleTagToType<4>
+{
+    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 SingleTagToType<5>
+{
+    using type = std::string;
 };
 
-template <>
-struct Arguments<0> {
-  using type = S<>;
+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 <typename... T>
-struct LastElementType {
-  using type =
-      typename std::tuple_element<sizeof...(T) - 1, std::tuple<T...>>::type;
+template <> struct Arguments<0>
+{
+    using type = S<>;
 };
 
-template <>
-struct LastElementType<> {};
+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 <class T> using Invoke = typename T::type;
 
-template <unsigned...>
-struct Seq {
-  using type = Seq;
+template <unsigned...> struct Seq
+{
+    using type = Seq;
 };
 
-template <class S1, class S2>
-struct concat;
+template <class S1, class S2> struct concat;
 
 template <unsigned... I1, unsigned... I2>
-struct concat<Seq<I1...>, Seq<I2...>> : Seq<I1..., (sizeof...(I1) + I2)...> {};
+struct concat<Seq<I1...>, Seq<I2...>> : Seq<I1..., (sizeof...(I1) + I2)...>
+{
+};
 
-template <class S1, class S2>
-using Concat = Invoke<concat<S1, S2>>;
+template <class S1, class S2> using Concat = Invoke<concat<S1, S2>>;
 
-template <unsigned N>
-struct gen_seq;
-template <unsigned N>
-using GenSeq = Invoke<gen_seq<N>>;
+template <unsigned N> struct gen_seq;
+template <unsigned N> using GenSeq = Invoke<gen_seq<N>>;
 
-template <unsigned N>
-struct gen_seq : Concat<GenSeq<N / 2>, GenSeq<N - N / 2>> {};
+template <unsigned 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 <> struct gen_seq<0> : Seq<>
+{
+};
+template <> struct gen_seq<1> : Seq<0>
+{
+};
 
-template <typename Seq, typename Tuple>
-struct PopBackHelper;
+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 <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...>>
+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) - 1>::type,
-                             std::tuple<T...>>::template rebind<U>;
+    template <template <typename... Args> class U>
+    using rebind =
+        typename PopBackHelper<typename gen_seq<sizeof...(T) - 1>::type,
+                               std::tuple<T...>>::template rebind<U>;
 };
 
-template <>
-struct PopBack<> {
-  template <template <typename... Args> class U>
-  using 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... 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;
+                       Contains<Tp, Rest...>>::type
+{
 };
 
-#define BMCWEB_INTERNAL_PROMOTE_TYPE(t1, t2) \
-  template <>                                \
-  struct promote<t1> {                       \
-    using type = t2;                         \
-  }
+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);
@@ -400,204 +442,229 @@
 BMCWEB_INTERNAL_PROMOTE_TYPE(float, double);
 #undef BMCWEB_INTERNAL_PROMOTE_TYPE
 
-template <typename T>
-using promote_t = typename promote<T>::type;
+template <typename T> using promote_t = typename promote<T>::type;
 
-}  // namespace black_magic
+} // namespace black_magic
 
-namespace detail {
+namespace detail
+{
 
 template <class T, std::size_t N, class... Args>
-struct GetIndexOfElementFromTupleByTypeImpl {
-  static constexpr auto value = N;
+struct GetIndexOfElementFromTupleByTypeImpl
+{
+    static constexpr auto value = N;
 };
 
 template <class T, std::size_t N, class... Args>
-struct GetIndexOfElementFromTupleByTypeImpl<T, N, T, Args...> {
-  static constexpr auto value = N;
+struct GetIndexOfElementFromTupleByTypeImpl<T, N, T, Args...>
+{
+    static constexpr auto value = N;
 };
 
 template <class T, std::size_t N, class U, class... Args>
-struct GetIndexOfElementFromTupleByTypeImpl<T, N, U, Args...> {
-  static constexpr auto value =
-      GetIndexOfElementFromTupleByTypeImpl<T, N + 1, Args...>::value;
+struct GetIndexOfElementFromTupleByTypeImpl<T, N, U, Args...>
+{
+    static constexpr auto value =
+        GetIndexOfElementFromTupleByTypeImpl<T, N + 1, Args...>::value;
 };
 
-}  // namespace detail
+} // 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);
+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;
 
 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>;
+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);
+struct function_traits<r (ClassType::*)(Args...) const>
+{
+    static const size_t arity = sizeof...(Args);
 
-  using result_type = r;
+    using result_type = r;
 
-  template <size_t i>
-  using arg = typename std::tuple_element<i, std::tuple<Args...>>::type;
+    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);
+struct function_traits<r (ClassType::*)(Args...)>
+{
+    static const size_t arity = sizeof...(Args);
 
-  using result_type = r;
+    using result_type = r;
 
-  template <size_t i>
-  using arg = typename std::tuple_element<i, std::tuple<Args...>>::type;
+    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);
+struct function_traits<std::function<r(Args...)>>
+{
+    static const size_t arity = sizeof...(Args);
 
-  using result_type = r;
+    using result_type = r;
 
-  template <size_t i>
-  using arg = typename std::tuple_element<i, std::tuple<Args...>>::type;
+    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[(((unsigned char)*data) & 0xFC) >> 2];
-    unsigned char h = (((unsigned char)*data++) & 0x03) << 4;
-    *it++ = key[h | ((((unsigned char)*data) & 0xF0) >> 4)];
-    h = (((unsigned char)*data++) & 0x0F) << 2;
-    *it++ = key[h | ((((unsigned char)*data) & 0xC0) >> 6)];
-    *it++ = key[((unsigned char)*data++) & 0x3F];
+        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")
+{
+    std::string ret;
+    ret.resize((size + 2) / 3 * 4);
+    auto it = ret.begin();
+    while (size >= 3)
+    {
+        *it++ = key[(((unsigned char)*data) & 0xFC) >> 2];
+        unsigned char h = (((unsigned char)*data++) & 0x03) << 4;
+        *it++ = key[h | ((((unsigned char)*data) & 0xF0) >> 4)];
+        h = (((unsigned char)*data++) & 0x0F) << 2;
+        *it++ = key[h | ((((unsigned char)*data) & 0xC0) >> 6)];
+        *it++ = key[((unsigned char)*data++) & 0x3F];
 
-    size -= 3;
-  }
-  if (size == 1) {
-    *it++ = key[(((unsigned char)*data) & 0xFC) >> 2];
-    unsigned char h = (((unsigned char)*data++) & 0x03) << 4;
-    *it++ = key[h];
-    *it++ = '=';
-    *it++ = '=';
-  } else if (size == 2) {
-    *it++ = key[(((unsigned char)*data) & 0xFC) >> 2];
-    unsigned char h = (((unsigned char)*data++) & 0x03) << 4;
-    *it++ = key[h | ((((unsigned char)*data) & 0xF0) >> 4)];
-    h = (((unsigned char)*data++) & 0x0F) << 2;
-    *it++ = key[h];
-    *it++ = '=';
-  }
-  return ret;
+        size -= 3;
+    }
+    if (size == 1)
+    {
+        *it++ = key[(((unsigned char)*data) & 0xFC) >> 2];
+        unsigned char h = (((unsigned char)*data++) & 0x03) << 4;
+        *it++ = key[h];
+        *it++ = '=';
+        *it++ = '=';
+    }
+    else if (size == 2)
+    {
+        *it++ = key[(((unsigned char)*data) & 0xFC) >> 2];
+        unsigned char h = (((unsigned char)*data++) & 0x03) << 4;
+        *it++ = key[h | ((((unsigned char)*data) & 0xF0) >> 4)];
+        h = (((unsigned char)*data++) & 0x0F) << 2;
+        *it++ = key[h];
+        *it++ = '=';
+    }
+    return ret;
 }
 
-inline static std::string base64encodeUrlsafe(const char* data, size_t size) {
-  return base64encode(
-      data, size,
-      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_");
+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 boost::string_view input, std::string& output) {
-  static const char nop = -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};
+inline bool base64Decode(const boost::string_view input, std::string& output)
+{
+    static const char nop = -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();
+    size_t inputLength = input.size();
 
-  // allocate space for output string
-  output.clear();
-  output.reserve(((inputLength + 2) / 3) * 4);
+    // 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 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;
+    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));
+        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 (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));
+        }
     }
 
-    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;
+    return true;
 }
 
-}  // namespace utility
-}  // namespace crow
+} // namespace utility
+} // namespace crow
diff --git a/crow/include/crow/websocket.h b/crow/include/crow/websocket.h
index 82c6db8..f345223 100644
--- a/crow/include/crow/websocket.h
+++ b/crow/include/crow/websocket.h
@@ -1,206 +1,240 @@
 #pragma once
 #include <array>
-#include <functional>
-#include "crow/http_request.h"
-#include "crow/socket_adaptors.h"
 #include <boost/algorithm/string/predicate.hpp>
 #include <boost/beast/websocket.hpp>
+#include <functional>
+
+#include "crow/http_request.h"
+#include "crow/socket_adaptors.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& req)
-      : req(req), userdataPtr(nullptr){};
+namespace crow
+{
+namespace websocket
+{
+struct Connection : std::enable_shared_from_this<Connection>
+{
+  public:
+    explicit Connection(const crow::Request& req) :
+        req(req), userdataPtr(nullptr){};
 
-  virtual void sendBinary(const boost::beast::string_view msg) = 0;
-  virtual void sendBinary(std::string&& msg) = 0;
-  virtual void sendText(const boost::beast::string_view msg) = 0;
-  virtual void sendText(std::string&& msg) = 0;
-  virtual void close(const boost::beast::string_view msg = "quit") = 0;
-  virtual boost::asio::io_service& getIoService() = 0;
-  virtual ~Connection() = default;
+    virtual void sendBinary(const boost::beast::string_view msg) = 0;
+    virtual void sendBinary(std::string&& msg) = 0;
+    virtual void sendText(const boost::beast::string_view msg) = 0;
+    virtual void sendText(std::string&& msg) = 0;
+    virtual void close(const boost::beast::string_view msg = "quit") = 0;
+    virtual boost::asio::io_service& getIoService() = 0;
+    virtual ~Connection() = default;
 
-  void userdata(void* u) { userdataPtr = u; }
-  void* userdata() { return userdataPtr; }
+    void userdata(void* u)
+    {
+        userdataPtr = u;
+    }
+    void* userdata()
+    {
+        return userdataPtr;
+    }
 
-  crow::Request req;
+    crow::Request req;
 
- private:
-  void* userdataPtr;
+  private:
+    void* userdataPtr;
 };
 
-template <typename Adaptor>
-class ConnectionImpl : public Connection {
- public:
-  ConnectionImpl(
-      const crow::Request& req, 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)
-      : adaptor(std::move(adaptorIn)),
-        ws(adaptor.socket()),
-        Connection(req),
+template <typename Adaptor> class ConnectionImpl : public Connection
+{
+  public:
+    ConnectionImpl(
+        const crow::Request& req, 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) :
+        adaptor(std::move(adaptorIn)),
+        ws(adaptor.socket()), Connection(req),
         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_service& getIoService() override {
-    return adaptor.getIoService();
-  }
-
-  void start() {
-    BMCWEB_LOG_DEBUG << "starting connection " << this;
-
-    boost::string_view protocol =
-        req.getHeaderValue(boost::beast::http::field::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(boost::beast::http::field::sec_websocket_protocol,
-                     protocol);
-          }
-        },
-        [ 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 boost::beast::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 boost::beast::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 boost::beast::string_view msg) override {
-    ws.async_close(
-        boost::beast::websocket::close_code::normal,
-        [ this, self(shared_from_this()) ](boost::system::error_code ec) {
-          if (ec) {
-            BMCWEB_LOG_ERROR << "Error closing websocket " << ec;
-            return;
-          }
-          adaptor.close();
-        });
-  }
-
-  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) {
-              boost::beast::string_view reason = ws.reason().reason;
-              closeHandler(*this, std::string(reason));
-            }
-            return;
-          }
-          if (messageHandler) {
-            // TODO(Ed) There must be a more direct way to do this conversion,
-            // but I can't find it at the moment.  It should get optimized away
-            boost::asio::const_buffer cb =
-                boost::beast::buffers_front(inBuffer.data());
-            boost::beast::string_view message(
-                reinterpret_cast<char const*>(cb.data()), cb.size());
-            messageHandler(*this, std::string(message), ws.got_text());
-          }
-          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;
+        errorHandler(std::move(error_handler))
+    {
+        BMCWEB_LOG_DEBUG << "Creating new connection " << this;
     }
 
-    if (outBuffer.empty()) {
-      // Done for now
-      return;
+    boost::asio::io_service& getIoService() override
+    {
+        return adaptor.getIoService();
     }
-    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:
-  Adaptor adaptor;
+    void start()
+    {
+        BMCWEB_LOG_DEBUG << "starting connection " << this;
 
-  boost::beast::websocket::stream<
-      std::add_lvalue_reference_t<typename Adaptor::streamType>>
-      ws;
+        boost::string_view protocol = req.getHeaderValue(
+            boost::beast::http::field::sec_websocket_protocol);
 
-  boost::beast::flat_static_buffer<4096> inBuffer;
-  std::vector<std::string> outBuffer;
-  bool doingWrite = false;
+        // 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(boost::beast::http::field::sec_websocket_protocol,
+                             protocol);
+                }
+            },
+            [this, self(shared_from_this())](boost::system::error_code ec) {
+                if (ec)
+                {
+                    BMCWEB_LOG_ERROR << "Error in ws.async_accept " << ec;
+                    return;
+                }
+                acceptDone();
+            });
+    }
 
-  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;
+    void sendBinary(const boost::beast::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 boost::beast::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 boost::beast::string_view msg) override
+    {
+        ws.async_close(
+            boost::beast::websocket::close_code::normal,
+            [this, self(shared_from_this())](boost::system::error_code ec) {
+                if (ec)
+                {
+                    BMCWEB_LOG_ERROR << "Error closing websocket " << ec;
+                    return;
+                }
+                adaptor.close();
+            });
+    }
+
+    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)
+                    {
+                        boost::beast::string_view reason = ws.reason().reason;
+                        closeHandler(*this, std::string(reason));
+                    }
+                    return;
+                }
+                if (messageHandler)
+                {
+                    // TODO(Ed) There must be a more direct way to do this
+                    // conversion, but I can't find it at the moment.  It should
+                    // get optimized away
+                    boost::asio::const_buffer cb =
+                        boost::beast::buffers_front(inBuffer.data());
+                    boost::beast::string_view message(
+                        reinterpret_cast<char const*>(cb.data()), cb.size());
+                    messageHandler(*this, std::string(message), ws.got_text());
+                }
+                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:
+    Adaptor adaptor;
+
+    boost::beast::websocket::stream<
+        std::add_lvalue_reference_t<typename Adaptor::streamType>>
+        ws;
+
+    boost::beast::flat_static_buffer<4096> 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
+} // namespace websocket
+} // namespace crow
