Using AsyncResp everywhere

Get the core using AsyncResp everywhere, and not have each individual handler
creating its own object.We can call app.handle() without fear of the response
getting ended after the first tree is done populating.
Don't use res.end() anymore.

Tested:
1. Validator passed.

Signed-off-by: zhanghaicheng <zhanghch05@inspur.com>
Change-Id: I867367ce4a0caf8c4b3f4e07e06c11feed0782e8
diff --git a/include/async_resp.hpp b/include/async_resp.hpp
index ac9db19..8e9584c 100644
--- a/include/async_resp.hpp
+++ b/include/async_resp.hpp
@@ -1,5 +1,7 @@
 #pragma once
 
+#include "http_response.hpp"
+
 #include <functional>
 
 namespace bmcweb
diff --git a/include/cors_preflight.hpp b/include/cors_preflight.hpp
index 4bac265..1cd8564 100644
--- a/include/cors_preflight.hpp
+++ b/include/cors_preflight.hpp
@@ -10,10 +10,10 @@
 {
     BMCWEB_ROUTE(app, "<str>")
         .methods(boost::beast::http::verb::options)(
-            [](const crow::Request&, crow::Response& res, const std::string&) {
+            [](const crow::Request&, const std::shared_ptr<bmcweb::AsyncResp>&,
+               const std::string&) {
                 // An empty body handler that simply returns the headers bmcweb
                 // uses This allows browsers to do their CORS preflight checks
-                res.end();
             });
 }
 } // namespace cors_preflight
diff --git a/include/ibm/management_console_rest.hpp b/include/ibm/management_console_rest.hpp
index e6b5cb2..5e49a9a 100644
--- a/include/ibm/management_console_rest.hpp
+++ b/include/ibm/management_console_rest.hpp
@@ -42,7 +42,8 @@
 constexpr size_t maxBroadcastMsgSize =
     1000; // Allow Broadcast message size upto 1KB
 
-inline bool createSaveAreaPath(crow::Response& res)
+inline bool
+    createSaveAreaPath(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
 {
     // The path /var/lib/obmc will be created by initrdscripts
     // Create the directories for the save-area files, when we get
@@ -54,8 +55,9 @@
     }
     if (ec)
     {
-        res.result(boost::beast::http::status::internal_server_error);
-        res.jsonValue["Description"] = internalServerError;
+        asyncResp->res.result(
+            boost::beast::http::status::internal_server_error);
+        asyncResp->res.jsonValue["Description"] = internalServerError;
         BMCWEB_LOG_DEBUG
             << "handleIbmPost: Failed to prepare save-area directory. ec : "
             << ec;
@@ -70,8 +72,9 @@
     }
     if (ec)
     {
-        res.result(boost::beast::http::status::internal_server_error);
-        res.jsonValue["Description"] = internalServerError;
+        asyncResp->res.result(
+            boost::beast::http::status::internal_server_error);
+        asyncResp->res.jsonValue["Description"] = internalServerError;
         BMCWEB_LOG_DEBUG
             << "handleIbmPost: Failed to prepare save-area directory. ec : "
             << ec;
@@ -98,7 +101,7 @@
 
     BMCWEB_LOG_DEBUG
         << "handleIbmPut: Request to create/update the save-area file";
-    if (!createSaveAreaPath(asyncResp->res))
+    if (!createSaveAreaPath(asyncResp))
     {
         asyncResp->res.result(boost::beast::http::status::not_found);
         asyncResp->res.jsonValue["Description"] = resourceNotFoundMsg;
@@ -261,12 +264,11 @@
     }
 }
 
-inline void handleConfigFileList(crow::Response& res)
+inline void
+    handleConfigFileList(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
 {
     std::vector<std::string> pathObjList;
     std::filesystem::path loc("/var/lib/obmc/bmc-console-mgmt/save-area");
-    std::shared_ptr<bmcweb::AsyncResp> asyncResp =
-        std::make_shared<bmcweb::AsyncResp>(res);
     if (std::filesystem::exists(loc) && std::filesystem::is_directory(loc))
     {
         for (const auto& file : std::filesystem::directory_iterator(loc))
@@ -289,13 +291,12 @@
     return;
 }
 
-inline void deleteConfigFiles(crow::Response& res)
+inline void
+    deleteConfigFiles(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
 {
     std::vector<std::string> pathObjList;
     std::error_code ec;
     std::filesystem::path loc("/var/lib/obmc/bmc-console-mgmt/save-area");
-    std::shared_ptr<bmcweb::AsyncResp> asyncResp =
-        std::make_shared<bmcweb::AsyncResp>(res);
     if (std::filesystem::exists(loc) && std::filesystem::is_directory(loc))
     {
         std::filesystem::remove_all(loc, ec);
@@ -312,10 +313,9 @@
     return;
 }
 
-inline void getLockServiceData(crow::Response& res)
+inline void
+    getLockServiceData(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
 {
-    std::shared_ptr<bmcweb::AsyncResp> asyncResp =
-        std::make_shared<bmcweb::AsyncResp>(res);
     asyncResp->res.jsonValue["@odata.type"] = "#LockService.v1_0_0.LockService";
     asyncResp->res.jsonValue["@odata.id"] = "/ibm/v1/HMC/LockService/";
     asyncResp->res.jsonValue["Id"] = "LockService";
@@ -394,15 +394,14 @@
     return;
 }
 
-inline void handleBroadcastService(const crow::Request& req,
-                                   crow::Response& res)
+inline void
+    handleBroadcastService(const crow::Request& req,
+                           const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
 {
     std::string broadcastMsg;
 
-    std::shared_ptr<bmcweb::AsyncResp> asyncResp =
-        std::make_shared<bmcweb::AsyncResp>(res);
-
-    if (!redfish::json_util::readJson(req, res, "Message", broadcastMsg))
+    if (!redfish::json_util::readJson(req, asyncResp->res, "Message",
+                                      broadcastMsg))
     {
         BMCWEB_LOG_DEBUG << "Not a Valid JSON";
         asyncResp->res.result(boost::beast::http::status::bad_request);
@@ -418,12 +417,10 @@
     return;
 }
 
-inline void handleFileUrl(const crow::Request& req, crow::Response& res,
+inline void handleFileUrl(const crow::Request& req,
+                          const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                           const std::string& fileID)
 {
-    std::shared_ptr<bmcweb::AsyncResp> asyncResp =
-        std::make_shared<bmcweb::AsyncResp>(res);
-
     if (req.method() == boost::beast::http::verb::put)
     {
         handleFilePut(req, asyncResp, fileID);
@@ -721,10 +718,8 @@
     BMCWEB_ROUTE(app, "/ibm/v1/")
         .privileges({"ConfigureComponents", "ConfigureManager"})
         .methods(boost::beast::http::verb::get)(
-            [](const crow::Request&, crow::Response& res) {
-                std::shared_ptr<bmcweb::AsyncResp> asyncResp =
-                    std::make_shared<bmcweb::AsyncResp>(res);
-
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
                 asyncResp->res.jsonValue["@odata.type"] =
                     "#ibmServiceRoot.v1_0_0.ibmServiceRoot";
                 asyncResp->res.jsonValue["@odata.id"] = "/ibm/v1/";
@@ -741,113 +736,117 @@
     BMCWEB_ROUTE(app, "/ibm/v1/Host/ConfigFiles")
         .privileges({"ConfigureComponents", "ConfigureManager"})
         .methods(boost::beast::http::verb::get)(
-            [](const crow::Request&, crow::Response& res) {
-                handleConfigFileList(res);
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                handleConfigFileList(asyncResp);
             });
 
     BMCWEB_ROUTE(app,
                  "/ibm/v1/Host/ConfigFiles/Actions/IBMConfigFiles.DeleteAll")
         .privileges({"ConfigureComponents", "ConfigureManager"})
         .methods(boost::beast::http::verb::post)(
-            [](const crow::Request&, crow::Response& res) {
-                deleteConfigFiles(res);
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                deleteConfigFiles(asyncResp);
             });
 
     BMCWEB_ROUTE(app, "/ibm/v1/Host/ConfigFiles/<str>")
         .privileges({"ConfigureComponents", "ConfigureManager"})
-        .methods(
-            boost::beast::http::verb::put, boost::beast::http::verb::get,
-            boost::beast::http::verb::delete_)([](const crow::Request& req,
-                                                  crow::Response& res,
-                                                  const std::string& fileName) {
-            std::shared_ptr<bmcweb::AsyncResp> asyncResp =
-                std::make_shared<bmcweb::AsyncResp>(res);
-            BMCWEB_LOG_DEBUG << "ConfigFile : " << fileName;
-            // Validate the incoming fileName
-            if (!isValidConfigFileName(fileName, res))
-            {
-                asyncResp->res.result(boost::beast::http::status::bad_request);
-                return;
-            }
-            handleFileUrl(req, res, fileName);
-        });
+        .methods(boost::beast::http::verb::put, boost::beast::http::verb::get,
+                 boost::beast::http::verb::delete_)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& fileName) {
+                BMCWEB_LOG_DEBUG << "ConfigFile : " << fileName;
+                // Validate the incoming fileName
+                if (!isValidConfigFileName(fileName, asyncResp->res))
+                {
+                    asyncResp->res.result(
+                        boost::beast::http::status::bad_request);
+                    return;
+                }
+                handleFileUrl(req, asyncResp, fileName);
+            });
 
     BMCWEB_ROUTE(app, "/ibm/v1/HMC/LockService")
         .privileges({"ConfigureComponents", "ConfigureManager"})
         .methods(boost::beast::http::verb::get)(
-            [](const crow::Request&, crow::Response& res) {
-                getLockServiceData(res);
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                getLockServiceData(asyncResp);
             });
 
     BMCWEB_ROUTE(app, "/ibm/v1/HMC/LockService/Actions/LockService.AcquireLock")
         .privileges({"ConfigureComponents", "ConfigureManager"})
-        .methods(boost::beast::http::verb::post)([](const crow::Request& req,
-                                                    crow::Response& res) {
-            std::shared_ptr<bmcweb::AsyncResp> asyncResp =
-                std::make_shared<bmcweb::AsyncResp>(res);
-
-            std::vector<nlohmann::json> body;
-            if (!redfish::json_util::readJson(req, res, "Request", body))
-            {
-                BMCWEB_LOG_DEBUG << "Not a Valid JSON";
-                asyncResp->res.result(boost::beast::http::status::bad_request);
-                return;
-            }
-            handleAcquireLockAPI(req, asyncResp, body);
-        });
+        .methods(boost::beast::http::verb::post)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                std::vector<nlohmann::json> body;
+                if (!redfish::json_util::readJson(req, asyncResp->res,
+                                                  "Request", body))
+                {
+                    BMCWEB_LOG_DEBUG << "Not a Valid JSON";
+                    asyncResp->res.result(
+                        boost::beast::http::status::bad_request);
+                    return;
+                }
+                handleAcquireLockAPI(req, asyncResp, body);
+            });
     BMCWEB_ROUTE(app, "/ibm/v1/HMC/LockService/Actions/LockService.ReleaseLock")
         .privileges({"ConfigureComponents", "ConfigureManager"})
-        .methods(boost::beast::http::verb::post)([](const crow::Request& req,
-                                                    crow::Response& res) {
-            std::string type;
-            std::vector<uint32_t> listTransactionIds;
-            std::shared_ptr<bmcweb::AsyncResp> asyncResp =
-                std::make_shared<bmcweb::AsyncResp>(res);
+        .methods(boost::beast::http::verb::post)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                std::string type;
+                std::vector<uint32_t> listTransactionIds;
 
-            if (!redfish::json_util::readJson(req, res, "Type", type,
-                                              "TransactionIDs",
-                                              listTransactionIds))
-            {
-                asyncResp->res.result(boost::beast::http::status::bad_request);
-                return;
-            }
-            if (type == "Transaction")
-            {
-                handleReleaseLockAPI(req, asyncResp, listTransactionIds);
-            }
-            else if (type == "Session")
-            {
-                handleRelaseAllAPI(req, asyncResp);
-            }
-            else
-            {
-                BMCWEB_LOG_DEBUG << " Value of Type : " << type
-                                 << "is Not a Valid key";
-                redfish::messages::propertyValueNotInList(res, type, "Type");
-            }
-        });
+                if (!redfish::json_util::readJson(req, asyncResp->res, "Type",
+                                                  type, "TransactionIDs",
+                                                  listTransactionIds))
+                {
+                    asyncResp->res.result(
+                        boost::beast::http::status::bad_request);
+                    return;
+                }
+                if (type == "Transaction")
+                {
+                    handleReleaseLockAPI(req, asyncResp, listTransactionIds);
+                }
+                else if (type == "Session")
+                {
+                    handleRelaseAllAPI(req, asyncResp);
+                }
+                else
+                {
+                    BMCWEB_LOG_DEBUG << " Value of Type : " << type
+                                     << "is Not a Valid key";
+                    redfish::messages::propertyValueNotInList(asyncResp->res,
+                                                              type, "Type");
+                }
+            });
     BMCWEB_ROUTE(app, "/ibm/v1/HMC/LockService/Actions/LockService.GetLockList")
         .privileges({"ConfigureComponents", "ConfigureManager"})
-        .methods(boost::beast::http::verb::post)([](const crow::Request& req,
-                                                    crow::Response& res) {
-            ListOfSessionIds listSessionIds;
-            std::shared_ptr<bmcweb::AsyncResp> asyncResp =
-                std::make_shared<bmcweb::AsyncResp>(res);
+        .methods(boost::beast::http::verb::post)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                ListOfSessionIds listSessionIds;
 
-            if (!redfish::json_util::readJson(req, res, "SessionIDs",
-                                              listSessionIds))
-            {
-                asyncResp->res.result(boost::beast::http::status::bad_request);
-                return;
-            }
-            handleGetLockListAPI(asyncResp, listSessionIds);
-        });
+                if (!redfish::json_util::readJson(req, asyncResp->res,
+                                                  "SessionIDs", listSessionIds))
+                {
+                    asyncResp->res.result(
+                        boost::beast::http::status::bad_request);
+                    return;
+                }
+                handleGetLockListAPI(asyncResp, listSessionIds);
+            });
 
     BMCWEB_ROUTE(app, "/ibm/v1/HMC/BroadcastService")
         .privileges({"ConfigureComponents", "ConfigureManager"})
         .methods(boost::beast::http::verb::post)(
-            [](const crow::Request& req, crow::Response& res) {
-                handleBroadcastService(req, res);
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                handleBroadcastService(req, asyncResp);
             });
 }
 
diff --git a/include/image_upload.hpp b/include/image_upload.hpp
index 3786c30..651d242 100644
--- a/include/image_upload.hpp
+++ b/include/image_upload.hpp
@@ -17,14 +17,15 @@
 
 static std::unique_ptr<sdbusplus::bus::match::match> fwUpdateMatcher;
 
-inline void uploadImageHandler(const crow::Request& req, crow::Response& res)
+inline void
+    uploadImageHandler(const crow::Request& req,
+                       const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
 {
     // Only allow one FW update at a time
     if (fwUpdateMatcher != nullptr)
     {
-        res.addHeader("Retry-After", "30");
-        res.result(boost::beast::http::status::service_unavailable);
-        res.end();
+        asyncResp->res.addHeader("Retry-After", "30");
+        asyncResp->res.result(boost::beast::http::status::service_unavailable);
         return;
     }
     // Make this const static so it survives outside this method
@@ -33,7 +34,7 @@
 
     timeout.expires_after(std::chrono::seconds(15));
 
-    auto timeoutHandler = [&res](const boost::system::error_code& ec) {
+    auto timeoutHandler = [asyncResp](const boost::system::error_code& ec) {
         fwUpdateMatcher = nullptr;
         if (ec == boost::asio::error::operation_aborted)
         {
@@ -48,18 +49,17 @@
             return;
         }
 
-        res.result(boost::beast::http::status::bad_request);
-        res.jsonValue = {
+        asyncResp->res.result(boost::beast::http::status::bad_request);
+        asyncResp->res.jsonValue = {
             {"data",
              {{"description",
                "Version already exists or failed to be extracted"}}},
             {"message", "400 Bad Request"},
             {"status", "error"}};
-        res.end();
     };
 
     std::function<void(sdbusplus::message::message&)> callback =
-        [&res](sdbusplus::message::message& m) {
+        [asyncResp](sdbusplus::message::message& m) {
             BMCWEB_LOG_DEBUG << "Match fired";
 
             sdbusplus::message::object_path path;
@@ -82,10 +82,9 @@
                     leaf = path.str;
                 }
 
-                res.jsonValue = {
+                asyncResp->res.jsonValue = {
                     {"data", leaf}, {"message", "200 OK"}, {"status", "ok"}};
                 BMCWEB_LOG_DEBUG << "ending response";
-                res.end();
                 fwUpdateMatcher = nullptr;
             }
         };
@@ -111,14 +110,16 @@
     BMCWEB_ROUTE(app, "/upload/image/<str>")
         .privileges({"ConfigureComponents", "ConfigureManager"})
         .methods(boost::beast::http::verb::post, boost::beast::http::verb::put)(
-            [](const crow::Request& req, crow::Response& res,
-               const std::string&) { uploadImageHandler(req, res); });
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string&) { uploadImageHandler(req, asyncResp); });
 
     BMCWEB_ROUTE(app, "/upload/image")
         .privileges({"ConfigureComponents", "ConfigureManager"})
         .methods(boost::beast::http::verb::post, boost::beast::http::verb::put)(
-            [](const crow::Request& req, crow::Response& res) {
-                uploadImageHandler(req, res);
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                uploadImageHandler(req, asyncResp);
             });
 }
 } // namespace image_upload
diff --git a/include/login_routes.hpp b/include/login_routes.hpp
index 4d42b56..42eebfe 100644
--- a/include/login_routes.hpp
+++ b/include/login_routes.hpp
@@ -19,8 +19,10 @@
 inline void requestRoutes(App& app)
 {
     BMCWEB_ROUTE(app, "/login")
-        .methods(boost::beast::http::verb::post)([](const crow::Request& req,
-                                                    crow::Response& res) {
+        .methods(
+            boost::beast::http::verb::
+                post)([](const crow::Request& req,
+                         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
             std::string_view contentType = req.getHeaderValue("content-type");
             std::string_view username;
             std::string_view password;
@@ -38,8 +40,8 @@
                 if (loginCredentials.is_discarded())
                 {
                     BMCWEB_LOG_DEBUG << "Bad json in request";
-                    res.result(boost::beast::http::status::bad_request);
-                    res.end();
+                    asyncResp->res.result(
+                        boost::beast::http::status::bad_request);
                     return;
                 }
 
@@ -132,7 +134,8 @@
                 bool isConfigureSelfOnly = pamrc == PAM_NEW_AUTHTOK_REQD;
                 if ((pamrc != PAM_SUCCESS) && !isConfigureSelfOnly)
                 {
-                    res.result(boost::beast::http::status::unauthorized);
+                    asyncResp->res.result(
+                        boost::beast::http::status::unauthorized);
                 }
                 else
                 {
@@ -151,7 +154,7 @@
                         // structure, and doesn't actually look at the status
                         // code.
                         // TODO(ed).... Fix that upstream
-                        res.jsonValue = {
+                        asyncResp->res.jsonValue = {
                             {"data",
                              "User '" + std::string(username) + "' logged in"},
                             {"message", "200 OK"},
@@ -167,7 +170,7 @@
                         // "set-cookie" string into the value header, and get
                         // the result we want, even though we are technicaly
                         // declaring two headers here.
-                        res.addHeader(
+                        asyncResp->res.addHeader(
                             "Set-Cookie",
                             "XSRF-TOKEN=" + session->csrfToken +
                                 "; SameSite=Strict; Secure\r\nSet-Cookie: "
@@ -178,25 +181,26 @@
                     else
                     {
                         // if content type is json, assume json token
-                        res.jsonValue = {{"token", session->sessionToken}};
+                        asyncResp->res.jsonValue = {
+                            {"token", session->sessionToken}};
                     }
                 }
             }
             else
             {
                 BMCWEB_LOG_DEBUG << "Couldn't interpret password";
-                res.result(boost::beast::http::status::bad_request);
+                asyncResp->res.result(boost::beast::http::status::bad_request);
             }
-            res.end();
         });
 
     BMCWEB_ROUTE(app, "/logout")
         .methods(boost::beast::http::verb::post)(
-            [](const crow::Request& req, crow::Response& res) {
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
                 auto& session = req.session;
                 if (session != nullptr)
                 {
-                    res.jsonValue = {
+                    asyncResp->res.jsonValue = {
                         {"data", "User '" + session->username + "' logged out"},
                         {"message", "200 OK"},
                         {"status", "ok"}};
@@ -204,7 +208,6 @@
                     persistent_data::SessionStore::getInstance().removeSession(
                         session);
                 }
-                res.end();
                 return;
             });
 }
diff --git a/include/openbmc_dbus_rest.hpp b/include/openbmc_dbus_rest.hpp
index 581e40b..b988095 100644
--- a/include/openbmc_dbus_rest.hpp
+++ b/include/openbmc_dbus_rest.hpp
@@ -205,10 +205,11 @@
 
 struct InProgressEnumerateData
 {
-    InProgressEnumerateData(const std::string& objectPathIn,
-                            std::shared_ptr<bmcweb::AsyncResp> asyncRespIn) :
+    InProgressEnumerateData(
+        const std::string& objectPathIn,
+        const std::shared_ptr<bmcweb::AsyncResp>& asyncRespIn) :
         objectPath(objectPathIn),
-        asyncResp(std::move(asyncRespIn))
+        asyncResp(asyncRespIn)
     {}
 
     ~InProgressEnumerateData()
@@ -1475,7 +1476,8 @@
         "org.freedesktop.DBus.Introspectable", "Introspect");
 }
 
-inline void handleAction(const crow::Request& req, crow::Response& res,
+inline void handleAction(const crow::Request& req,
+                         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                          const std::string& objectPath,
                          const std::string& methodName)
 {
@@ -1486,28 +1488,28 @@
 
     if (requestDbusData.is_discarded())
     {
-        setErrorResponse(res, boost::beast::http::status::bad_request,
-                         noJsonDesc, badReqMsg);
-        res.end();
+        setErrorResponse(asyncResp->res,
+                         boost::beast::http::status::bad_request, noJsonDesc,
+                         badReqMsg);
         return;
     }
     nlohmann::json::iterator data = requestDbusData.find("data");
     if (data == requestDbusData.end())
     {
-        setErrorResponse(res, boost::beast::http::status::bad_request,
-                         noJsonDesc, badReqMsg);
-        res.end();
+        setErrorResponse(asyncResp->res,
+                         boost::beast::http::status::bad_request, noJsonDesc,
+                         badReqMsg);
         return;
     }
 
     if (!data->is_array())
     {
-        setErrorResponse(res, boost::beast::http::status::bad_request,
-                         noJsonDesc, badReqMsg);
-        res.end();
+        setErrorResponse(asyncResp->res,
+                         boost::beast::http::status::bad_request, noJsonDesc,
+                         badReqMsg);
         return;
     }
-    auto transaction = std::make_shared<InProgressActionData>(res);
+    auto transaction = std::make_shared<InProgressActionData>(asyncResp->res);
 
     transaction->path = objectPath;
     transaction->methodName = methodName;
@@ -1541,26 +1543,27 @@
         std::array<std::string, 0>());
 }
 
-inline void handleDelete(crow::Response& res, const std::string& objectPath)
+inline void handleDelete(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                         const std::string& objectPath)
 {
     BMCWEB_LOG_DEBUG << "handleDelete on path: " << objectPath;
 
     crow::connections::systemBus->async_method_call(
-        [&res, objectPath](
+        [asyncResp, objectPath](
             const boost::system::error_code ec,
             const std::vector<std::pair<std::string, std::vector<std::string>>>&
                 interfaceNames) {
             if (ec || interfaceNames.size() <= 0)
             {
                 BMCWEB_LOG_ERROR << "Can't find object";
-                setErrorResponse(res,
+                setErrorResponse(asyncResp->res,
                                  boost::beast::http::status::method_not_allowed,
                                  methodNotAllowedDesc, methodNotAllowedMsg);
-                res.end();
                 return;
             }
 
-            auto transaction = std::make_shared<InProgressActionData>(res);
+            auto transaction =
+                std::make_shared<InProgressActionData>(asyncResp->res);
             transaction->path = objectPath;
             transaction->methodName = "Delete";
             transaction->interfaceName = "xyz.openbmc_project.Object.Delete";
@@ -1577,24 +1580,24 @@
         std::array<const char*, 0>());
 }
 
-inline void handleList(crow::Response& res, const std::string& objectPath,
-                       int32_t depth = 0)
+inline void handleList(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                       const std::string& objectPath, int32_t depth = 0)
 {
     crow::connections::systemBus->async_method_call(
-        [&res](const boost::system::error_code ec,
-               std::vector<std::string>& objectPaths) {
+        [asyncResp](const boost::system::error_code ec,
+                    std::vector<std::string>& objectPaths) {
             if (ec)
             {
-                setErrorResponse(res, boost::beast::http::status::not_found,
+                setErrorResponse(asyncResp->res,
+                                 boost::beast::http::status::not_found,
                                  notFoundDesc, notFoundMsg);
             }
             else
             {
-                res.jsonValue = {{"status", "ok"},
-                                 {"message", "200 OK"},
-                                 {"data", std::move(objectPaths)}};
+                asyncResp->res.jsonValue = {{"status", "ok"},
+                                            {"message", "200 OK"},
+                                            {"data", std::move(objectPaths)}};
             }
-            res.end();
         },
         "xyz.openbmc_project.ObjectMapper",
         "/xyz/openbmc_project/object_mapper",
@@ -1602,10 +1605,10 @@
         depth, std::array<std::string, 0>());
 }
 
-inline void handleEnumerate(crow::Response& res, const std::string& objectPath)
+inline void handleEnumerate(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                            const std::string& objectPath)
 {
     BMCWEB_LOG_DEBUG << "Doing enumerate on " << objectPath;
-    auto asyncResp = std::make_shared<bmcweb::AsyncResp>(res);
 
     asyncResp->res.jsonValue = {{"message", "200 OK"},
                                 {"status", "ok"},
@@ -1640,8 +1643,8 @@
         std::array<const char*, 0>());
 }
 
-inline void handleGet(crow::Response& res, std::string& objectPath,
-                      std::string& destProperty)
+inline void handleGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                      std::string& objectPath, std::string& destProperty)
 {
     BMCWEB_LOG_DEBUG << "handleGet: " << objectPath << " prop:" << destProperty;
     std::shared_ptr<std::string> propertyName =
@@ -1653,13 +1656,13 @@
     using GetObjectType =
         std::vector<std::pair<std::string, std::vector<std::string>>>;
     crow::connections::systemBus->async_method_call(
-        [&res, path, propertyName](const boost::system::error_code ec,
-                                   const GetObjectType& objectNames) {
+        [asyncResp, path, propertyName](const boost::system::error_code ec,
+                                        const GetObjectType& objectNames) {
             if (ec || objectNames.size() <= 0)
             {
-                setErrorResponse(res, boost::beast::http::status::not_found,
+                setErrorResponse(asyncResp->res,
+                                 boost::beast::http::status::not_found,
                                  notFoundDesc, notFoundMsg);
-                res.end();
                 return;
             }
             std::shared_ptr<nlohmann::json> response =
@@ -1674,9 +1677,9 @@
 
                 if (interfaceNames.size() <= 0)
                 {
-                    setErrorResponse(res, boost::beast::http::status::not_found,
+                    setErrorResponse(asyncResp->res,
+                                     boost::beast::http::status::not_found,
                                      notFoundDesc, notFoundMsg);
-                    res.end();
                     return;
                 }
 
@@ -1688,7 +1691,7 @@
                             "org.freedesktop.DBus.Properties", "GetAll");
                     m.append(interface);
                     crow::connections::systemBus->async_send(
-                        m, [&res, response,
+                        m, [asyncResp, response,
                             propertyName](const boost::system::error_code ec2,
                                           sdbusplus::message::message& msg) {
                             if (ec2)
@@ -1731,17 +1734,17 @@
                                 if (!propertyName->empty() && response->empty())
                                 {
                                     setErrorResponse(
-                                        res,
+                                        asyncResp->res,
                                         boost::beast::http::status::not_found,
                                         propNotFoundDesc, notFoundMsg);
                                 }
                                 else
                                 {
-                                    res.jsonValue = {{"status", "ok"},
-                                                     {"message", "200 OK"},
-                                                     {"data", *response}};
+                                    asyncResp->res.jsonValue = {
+                                        {"status", "ok"},
+                                        {"message", "200 OK"},
+                                        {"data", *response}};
                                 }
-                                res.end();
                             }
                         });
                 }
@@ -1755,40 +1758,41 @@
 
 struct AsyncPutRequest
 {
-    AsyncPutRequest(crow::Response& resIn) : res(resIn)
+    AsyncPutRequest(const std::shared_ptr<bmcweb::AsyncResp>& resIn) :
+        asyncResp(resIn)
     {}
     ~AsyncPutRequest()
     {
-        if (res.jsonValue.empty())
+        if (asyncResp->res.jsonValue.empty())
         {
-            setErrorResponse(res, boost::beast::http::status::forbidden,
+            setErrorResponse(asyncResp->res,
+                             boost::beast::http::status::forbidden,
                              forbiddenMsg, forbiddenPropDesc);
         }
-
-        res.end();
     }
 
     void setErrorStatus(const std::string& desc)
     {
-        setErrorResponse(res, boost::beast::http::status::internal_server_error,
+        setErrorResponse(asyncResp->res,
+                         boost::beast::http::status::internal_server_error,
                          desc, badReqMsg);
     }
 
-    crow::Response& res;
+    const std::shared_ptr<bmcweb::AsyncResp> asyncResp;
     std::string objectPath;
     std::string propertyName;
     nlohmann::json propertyValue;
 };
 
-inline void handlePut(const crow::Request& req, crow::Response& res,
+inline void handlePut(const crow::Request& req,
+                      const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                       const std::string& objectPath,
                       const std::string& destProperty)
 {
     if (destProperty.empty())
     {
-        setErrorResponse(res, boost::beast::http::status::forbidden,
+        setErrorResponse(asyncResp->res, boost::beast::http::status::forbidden,
                          forbiddenResDesc, forbiddenMsg);
-        res.end();
         return;
     }
 
@@ -1797,22 +1801,22 @@
 
     if (requestDbusData.is_discarded())
     {
-        setErrorResponse(res, boost::beast::http::status::bad_request,
-                         noJsonDesc, badReqMsg);
-        res.end();
+        setErrorResponse(asyncResp->res,
+                         boost::beast::http::status::bad_request, noJsonDesc,
+                         badReqMsg);
         return;
     }
 
     nlohmann::json::const_iterator propertyIt = requestDbusData.find("data");
     if (propertyIt == requestDbusData.end())
     {
-        setErrorResponse(res, boost::beast::http::status::bad_request,
-                         noJsonDesc, badReqMsg);
-        res.end();
+        setErrorResponse(asyncResp->res,
+                         boost::beast::http::status::bad_request, noJsonDesc,
+                         badReqMsg);
         return;
     }
     const nlohmann::json& propertySetValue = *propertyIt;
-    auto transaction = std::make_shared<AsyncPutRequest>(res);
+    auto transaction = std::make_shared<AsyncPutRequest>(asyncResp);
     transaction->objectPath = objectPath;
     transaction->propertyName = destProperty;
     transaction->propertyValue = propertySetValue;
@@ -1825,7 +1829,7 @@
                       const GetObjectType& objectNames) {
             if (!ec2 && objectNames.size() <= 0)
             {
-                setErrorResponse(transaction->res,
+                setErrorResponse(transaction->asyncResp->res,
                                  boost::beast::http::status::not_found,
                                  propNotFoundDesc, notFoundMsg);
                 return;
@@ -1944,7 +1948,9 @@
                                                         const sd_bus_error* e =
                                                             m2.get_error();
                                                         setErrorResponse(
-                                                            transaction->res,
+                                                            transaction
+                                                                ->asyncResp
+                                                                ->res,
                                                             boost::beast::http::
                                                                 status::
                                                                     forbidden,
@@ -1956,8 +1962,8 @@
                                                     }
                                                     else
                                                     {
-                                                        transaction->res
-                                                            .jsonValue = {
+                                                        transaction->asyncResp
+                                                            ->res.jsonValue = {
                                                             {"status", "ok"},
                                                             {"message",
                                                              "200 OK"},
@@ -1983,7 +1989,8 @@
         transaction->objectPath, std::array<std::string, 0>());
 }
 
-inline void handleDBusUrl(const crow::Request& req, crow::Response& res,
+inline void handleDBusUrl(const crow::Request& req,
+                          const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                           std::string& objectPath)
 {
 
@@ -2009,7 +2016,7 @@
                 objectPath.substr((actionPosition + strlen(actionSeperator)),
                                   objectPath.length());
             objectPath = objectPath.substr(0, actionPosition);
-            handleAction(req, res, objectPath, postProperty);
+            handleAction(req, asyncResp, objectPath, postProperty);
             return;
         }
     }
@@ -2019,13 +2026,13 @@
         {
             objectPath.erase(objectPath.end() - sizeof("enumerate"),
                              objectPath.end());
-            handleEnumerate(res, objectPath);
+            handleEnumerate(asyncResp, objectPath);
         }
         else if (boost::ends_with(objectPath, "/list"))
         {
             objectPath.erase(objectPath.end() - sizeof("list"),
                              objectPath.end());
-            handleList(res, objectPath);
+            handleList(asyncResp, objectPath);
         }
         else
         {
@@ -2033,29 +2040,29 @@
             if (boost::ends_with(objectPath, "/"))
             {
                 objectPath.pop_back();
-                handleList(res, objectPath, 1);
+                handleList(asyncResp, objectPath, 1);
             }
             else
             {
-                handleGet(res, objectPath, destProperty);
+                handleGet(asyncResp, objectPath, destProperty);
             }
         }
         return;
     }
     else if (req.method() == boost::beast::http::verb::put)
     {
-        handlePut(req, res, objectPath, destProperty);
+        handlePut(req, asyncResp, objectPath, destProperty);
         return;
     }
     else if (req.method() == boost::beast::http::verb::delete_)
     {
-        handleDelete(res, objectPath);
+        handleDelete(asyncResp, objectPath);
         return;
     }
 
-    setErrorResponse(res, boost::beast::http::status::method_not_allowed,
+    setErrorResponse(asyncResp->res,
+                     boost::beast::http::status::method_not_allowed,
                      methodNotAllowedDesc, methodNotAllowedMsg);
-    res.end();
 }
 
 inline void requestRoutes(App& app)
@@ -2063,35 +2070,36 @@
     BMCWEB_ROUTE(app, "/bus/")
         .privileges({"Login"})
         .methods(boost::beast::http::verb::get)(
-            [](const crow::Request&, crow::Response& res) {
-                res.jsonValue = {{"buses", {{{"name", "system"}}}},
-                                 {"status", "ok"}};
-                res.end();
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                asyncResp->res.jsonValue = {{"buses", {{{"name", "system"}}}},
+                                            {"status", "ok"}};
             });
 
     BMCWEB_ROUTE(app, "/bus/system/")
         .privileges({"Login"})
         .methods(boost::beast::http::verb::get)(
-            [](const crow::Request&, crow::Response& res) {
-                auto myCallback = [&res](const boost::system::error_code ec,
-                                         std::vector<std::string>& names) {
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                auto myCallback = [&asyncResp](
+                                      const boost::system::error_code ec,
+                                      std::vector<std::string>& names) {
                     if (ec)
                     {
                         BMCWEB_LOG_ERROR << "Dbus call failed with code " << ec;
-                        res.result(
+                        asyncResp->res.result(
                             boost::beast::http::status::internal_server_error);
                     }
                     else
                     {
                         std::sort(names.begin(), names.end());
-                        res.jsonValue = {{"status", "ok"}};
-                        auto& objectsSub = res.jsonValue["objects"];
+                        asyncResp->res.jsonValue = {{"status", "ok"}};
+                        auto& objectsSub = asyncResp->res.jsonValue["objects"];
                         for (auto& name : names)
                         {
                             objectsSub.push_back({{"name", name}});
                         }
                     }
-                    res.end();
                 };
                 crow::connections::systemBus->async_method_call(
                     std::move(myCallback), "org.freedesktop.DBus", "/",
@@ -2101,471 +2109,482 @@
     BMCWEB_ROUTE(app, "/list/")
         .privileges({"Login"})
         .methods(boost::beast::http::verb::get)(
-            [](const crow::Request&, crow::Response& res) {
-                handleList(res, "/");
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                handleList(asyncResp, "/");
             });
 
     BMCWEB_ROUTE(app, "/xyz/<path>")
         .privileges({"Login"})
-        .methods(boost::beast::http::verb::get)([](const crow::Request& req,
-                                                   crow::Response& res,
-                                                   const std::string& path) {
-            std::string objectPath = "/xyz/" + path;
-            handleDBusUrl(req, res, objectPath);
-        });
-
-    BMCWEB_ROUTE(app, "/xyz/<path>")
-        .privileges({"ConfigureComponents", "ConfigureManager"})
-        .methods(boost::beast::http::verb::put, boost::beast::http::verb::post,
-                 boost::beast::http::verb::delete_)(
-            [](const crow::Request& req, crow::Response& res,
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                const std::string& path) {
                 std::string objectPath = "/xyz/" + path;
-                handleDBusUrl(req, res, objectPath);
+                handleDBusUrl(req, asyncResp, objectPath);
+            });
+
+    BMCWEB_ROUTE(app, "/xyz/<path>")
+        .privileges({"ConfigureComponents", "ConfigureManager"})
+        .methods(boost::beast::http::verb::put, boost::beast::http::verb::post,
+                 boost::beast::http::verb::delete_)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& path) {
+                std::string objectPath = "/xyz/" + path;
+                handleDBusUrl(req, asyncResp, objectPath);
             });
 
     BMCWEB_ROUTE(app, "/org/<path>")
         .privileges({"Login"})
-        .methods(boost::beast::http::verb::get)([](const crow::Request& req,
-                                                   crow::Response& res,
-                                                   const std::string& path) {
-            std::string objectPath = "/org/" + path;
-            handleDBusUrl(req, res, objectPath);
-        });
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& path) {
+                std::string objectPath = "/org/" + path;
+                handleDBusUrl(req, asyncResp, objectPath);
+            });
 
     BMCWEB_ROUTE(app, "/org/<path>")
         .privileges({"ConfigureComponents", "ConfigureManager"})
         .methods(boost::beast::http::verb::put, boost::beast::http::verb::post,
                  boost::beast::http::verb::delete_)(
-            [](const crow::Request& req, crow::Response& res,
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                const std::string& path) {
                 std::string objectPath = "/org/" + path;
-                handleDBusUrl(req, res, objectPath);
+                handleDBusUrl(req, asyncResp, objectPath);
             });
 
     BMCWEB_ROUTE(app, "/download/dump/<str>/")
         .privileges({"ConfigureManager"})
-        .methods(boost::beast::http::verb::get)([](const crow::Request&,
-                                                   crow::Response& res,
-                                                   const std::string& dumpId) {
-            std::regex validFilename(R"(^[\w\- ]+(\.?[\w\- ]*)$)");
-            if (!std::regex_match(dumpId, validFilename))
-            {
-                res.result(boost::beast::http::status::bad_request);
-                res.end();
-                return;
-            }
-            std::filesystem::path loc(
-                "/var/lib/phosphor-debug-collector/dumps");
-
-            loc /= dumpId;
-
-            if (!std::filesystem::exists(loc) ||
-                !std::filesystem::is_directory(loc))
-            {
-                BMCWEB_LOG_ERROR << loc << "Not found";
-                res.result(boost::beast::http::status::not_found);
-                res.end();
-                return;
-            }
-            std::filesystem::directory_iterator files(loc);
-
-            for (auto& file : files)
-            {
-                std::ifstream readFile(file.path());
-                if (!readFile.good())
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& dumpId) {
+                std::regex validFilename(R"(^[\w\- ]+(\.?[\w\- ]*)$)");
+                if (!std::regex_match(dumpId, validFilename))
                 {
-                    continue;
-                }
-
-                res.addHeader("Content-Type", "application/octet-stream");
-
-                // Assuming only one dump file will be present in the dump id
-                // directory
-                std::string dumpFileName = file.path().filename().string();
-
-                // Filename should be in alphanumeric, dot and underscore
-                // Its based on phosphor-debug-collector application dumpfile
-                // format
-                std::regex dumpFileRegex("[a-zA-Z0-9\\._]+");
-                if (!std::regex_match(dumpFileName, dumpFileRegex))
-                {
-                    BMCWEB_LOG_ERROR << "Invalid dump filename "
-                                     << dumpFileName;
-                    res.result(boost::beast::http::status::not_found);
-                    res.end();
+                    asyncResp->res.result(
+                        boost::beast::http::status::bad_request);
                     return;
                 }
-                std::string contentDispositionParam =
-                    "attachment; filename=\"" + dumpFileName + "\"";
+                std::filesystem::path loc(
+                    "/var/lib/phosphor-debug-collector/dumps");
 
-                res.addHeader("Content-Disposition", contentDispositionParam);
+                loc /= dumpId;
 
-                res.body() = {std::istreambuf_iterator<char>(readFile),
-                              std::istreambuf_iterator<char>()};
-                res.end();
+                if (!std::filesystem::exists(loc) ||
+                    !std::filesystem::is_directory(loc))
+                {
+                    BMCWEB_LOG_ERROR << loc << "Not found";
+                    asyncResp->res.result(
+                        boost::beast::http::status::not_found);
+                    return;
+                }
+                std::filesystem::directory_iterator files(loc);
+
+                for (auto& file : files)
+                {
+                    std::ifstream readFile(file.path());
+                    if (!readFile.good())
+                    {
+                        continue;
+                    }
+
+                    asyncResp->res.addHeader("Content-Type",
+                                             "application/octet-stream");
+
+                    // Assuming only one dump file will be present in the dump
+                    // id directory
+                    std::string dumpFileName = file.path().filename().string();
+
+                    // Filename should be in alphanumeric, dot and underscore
+                    // Its based on phosphor-debug-collector application
+                    // dumpfile format
+                    std::regex dumpFileRegex("[a-zA-Z0-9\\._]+");
+                    if (!std::regex_match(dumpFileName, dumpFileRegex))
+                    {
+                        BMCWEB_LOG_ERROR << "Invalid dump filename "
+                                         << dumpFileName;
+                        asyncResp->res.result(
+                            boost::beast::http::status::not_found);
+                        return;
+                    }
+                    std::string contentDispositionParam =
+                        "attachment; filename=\"" + dumpFileName + "\"";
+
+                    asyncResp->res.addHeader("Content-Disposition",
+                                             contentDispositionParam);
+
+                    asyncResp->res.body() = {
+                        std::istreambuf_iterator<char>(readFile),
+                        std::istreambuf_iterator<char>()};
+                    return;
+                }
+                asyncResp->res.result(boost::beast::http::status::not_found);
                 return;
-            }
-            res.result(boost::beast::http::status::not_found);
-            res.end();
-            return;
-        });
+            });
 
     BMCWEB_ROUTE(app, "/bus/system/<str>/")
         .privileges({"Login"})
 
         .methods(boost::beast::http::verb::get)(
-            [](const crow::Request&, crow::Response& res,
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                const std::string& connection) {
-                introspectObjects(connection, "/",
-                                  std::make_shared<bmcweb::AsyncResp>(res));
+                introspectObjects(
+                    connection, "/",
+                    std::make_shared<bmcweb::AsyncResp>(asyncResp->res));
             });
 
     BMCWEB_ROUTE(app, "/bus/system/<str>/<path>")
         .privileges({"ConfigureComponents", "ConfigureManager"})
-        .methods(
-            boost::beast::http::verb::get,
-            boost::beast::http::verb::post)([](const crow::Request& req,
-                                               crow::Response& res,
-                                               const std::string& processName,
-                                               const std::string&
-                                                   requestedPath) {
-            std::vector<std::string> strs;
-            boost::split(strs, requestedPath, boost::is_any_of("/"));
-            std::string objectPath;
-            std::string interfaceName;
-            std::string methodName;
-            auto it = strs.begin();
-            if (it == strs.end())
-            {
-                objectPath = "/";
-            }
-            while (it != strs.end())
-            {
-                // Check if segment contains ".".  If it does, it must be an
-                // interface
-                if (it->find(".") != std::string::npos)
+        .methods(boost::beast::http::verb::get, boost::beast::http::verb::post)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& processName,
+               const std::string& requestedPath) {
+                std::vector<std::string> strs;
+                boost::split(strs, requestedPath, boost::is_any_of("/"));
+                std::string objectPath;
+                std::string interfaceName;
+                std::string methodName;
+                auto it = strs.begin();
+                if (it == strs.end())
                 {
-                    break;
-                    // This check is necessary as the trailing slash gets
-                    // parsed as part of our <path> specifier above, which
-                    // causes the normal trailing backslash redirector to
-                    // fail.
+                    objectPath = "/";
                 }
-                if (!it->empty())
+                while (it != strs.end())
                 {
-                    objectPath += "/" + *it;
-                }
-                it++;
-            }
-            if (it != strs.end())
-            {
-                interfaceName = *it;
-                it++;
-
-                // after interface, we might have a method name
-                if (it != strs.end())
-                {
-                    methodName = *it;
+                    // Check if segment contains ".".  If it does, it must be an
+                    // interface
+                    if (it->find(".") != std::string::npos)
+                    {
+                        break;
+                        // This check is necessary as the trailing slash gets
+                        // parsed as part of our <path> specifier above, which
+                        // causes the normal trailing backslash redirector to
+                        // fail.
+                    }
+                    if (!it->empty())
+                    {
+                        objectPath += "/" + *it;
+                    }
                     it++;
                 }
-            }
-            if (it != strs.end())
-            {
-                // if there is more levels past the method name, something
-                // went wrong, return not found
-                res.result(boost::beast::http::status::not_found);
-                res.end();
-                return;
-            }
-            if (interfaceName.empty())
-            {
-                std::shared_ptr<bmcweb::AsyncResp> asyncResp =
-                    std::make_shared<bmcweb::AsyncResp>(res);
+                if (it != strs.end())
+                {
+                    interfaceName = *it;
+                    it++;
 
-                crow::connections::systemBus->async_method_call(
-                    [asyncResp, processName,
-                     objectPath](const boost::system::error_code ec,
-                                 const std::string& introspectXml) {
-                        if (ec)
-                        {
-                            BMCWEB_LOG_ERROR
-                                << "Introspect call failed with error: "
-                                << ec.message()
-                                << " on process: " << processName
-                                << " path: " << objectPath << "\n";
-                            return;
-                        }
-                        tinyxml2::XMLDocument doc;
+                    // after interface, we might have a method name
+                    if (it != strs.end())
+                    {
+                        methodName = *it;
+                        it++;
+                    }
+                }
+                if (it != strs.end())
+                {
+                    // if there is more levels past the method name, something
+                    // went wrong, return not found
+                    asyncResp->res.result(
+                        boost::beast::http::status::not_found);
+                    return;
+                }
+                if (interfaceName.empty())
+                {
+                    crow::connections::systemBus->async_method_call(
+                        [asyncResp, processName,
+                         objectPath](const boost::system::error_code ec,
+                                     const std::string& introspectXml) {
+                            if (ec)
+                            {
+                                BMCWEB_LOG_ERROR
+                                    << "Introspect call failed with error: "
+                                    << ec.message()
+                                    << " on process: " << processName
+                                    << " path: " << objectPath << "\n";
+                                return;
+                            }
+                            tinyxml2::XMLDocument doc;
 
-                        doc.Parse(introspectXml.c_str());
-                        tinyxml2::XMLNode* pRoot =
-                            doc.FirstChildElement("node");
-                        if (pRoot == nullptr)
-                        {
-                            BMCWEB_LOG_ERROR << "XML document failed to parse "
-                                             << processName << " " << objectPath
-                                             << "\n";
+                            doc.Parse(introspectXml.c_str());
+                            tinyxml2::XMLNode* pRoot =
+                                doc.FirstChildElement("node");
+                            if (pRoot == nullptr)
+                            {
+                                BMCWEB_LOG_ERROR
+                                    << "XML document failed to parse "
+                                    << processName << " " << objectPath << "\n";
+                                asyncResp->res.jsonValue = {
+                                    {"status", "XML parse error"}};
+                                asyncResp->res.result(
+                                    boost::beast::http::status::
+                                        internal_server_error);
+                                return;
+                            }
+
+                            BMCWEB_LOG_DEBUG << introspectXml;
                             asyncResp->res.jsonValue = {
-                                {"status", "XML parse error"}};
-                            asyncResp->res.result(boost::beast::http::status::
-                                                      internal_server_error);
-                            return;
-                        }
+                                {"status", "ok"},
+                                {"bus_name", processName},
+                                {"object_path", objectPath}};
+                            nlohmann::json& interfacesArray =
+                                asyncResp->res.jsonValue["interfaces"];
+                            interfacesArray = nlohmann::json::array();
+                            tinyxml2::XMLElement* interface =
+                                pRoot->FirstChildElement("interface");
 
-                        BMCWEB_LOG_DEBUG << introspectXml;
-                        asyncResp->res.jsonValue = {
-                            {"status", "ok"},
-                            {"bus_name", processName},
-                            {"object_path", objectPath}};
-                        nlohmann::json& interfacesArray =
-                            asyncResp->res.jsonValue["interfaces"];
-                        interfacesArray = nlohmann::json::array();
-                        tinyxml2::XMLElement* interface =
-                            pRoot->FirstChildElement("interface");
-
-                        while (interface != nullptr)
-                        {
-                            const char* ifaceName =
-                                interface->Attribute("name");
-                            if (ifaceName != nullptr)
+                            while (interface != nullptr)
                             {
-                                interfacesArray.push_back(
-                                    {{"name", ifaceName}});
-                            }
-
-                            interface =
-                                interface->NextSiblingElement("interface");
-                        }
-                    },
-                    processName, objectPath,
-                    "org.freedesktop.DBus.Introspectable", "Introspect");
-            }
-            else if (methodName.empty())
-            {
-                std::shared_ptr<bmcweb::AsyncResp> asyncResp =
-                    std::make_shared<bmcweb::AsyncResp>(res);
-
-                crow::connections::systemBus->async_method_call(
-                    [asyncResp, processName, objectPath,
-                     interfaceName](const boost::system::error_code ec,
-                                    const std::string& introspectXml) {
-                        if (ec)
-                        {
-                            BMCWEB_LOG_ERROR
-                                << "Introspect call failed with error: "
-                                << ec.message()
-                                << " on process: " << processName
-                                << " path: " << objectPath << "\n";
-                            return;
-                        }
-                        tinyxml2::XMLDocument doc;
-
-                        doc.Parse(introspectXml.data(), introspectXml.size());
-                        tinyxml2::XMLNode* pRoot =
-                            doc.FirstChildElement("node");
-                        if (pRoot == nullptr)
-                        {
-                            BMCWEB_LOG_ERROR << "XML document failed to parse "
-                                             << processName << " " << objectPath
-                                             << "\n";
-                            asyncResp->res.result(boost::beast::http::status::
-                                                      internal_server_error);
-                            return;
-                        }
-                        asyncResp->res.jsonValue = {
-                            {"status", "ok"},
-                            {"bus_name", processName},
-                            {"interface", interfaceName},
-                            {"object_path", objectPath}};
-
-                        nlohmann::json& methodsArray =
-                            asyncResp->res.jsonValue["methods"];
-                        methodsArray = nlohmann::json::array();
-
-                        nlohmann::json& signalsArray =
-                            asyncResp->res.jsonValue["signals"];
-                        signalsArray = nlohmann::json::array();
-
-                        nlohmann::json& propertiesObj =
-                            asyncResp->res.jsonValue["properties"];
-                        propertiesObj = nlohmann::json::object();
-
-                        // if we know we're the only call, build the
-                        // json directly
-                        tinyxml2::XMLElement* interface =
-                            pRoot->FirstChildElement("interface");
-                        while (interface != nullptr)
-                        {
-                            const char* ifaceName =
-                                interface->Attribute("name");
-
-                            if (ifaceName != nullptr &&
-                                ifaceName == interfaceName)
-                            {
-                                break;
-                            }
-
-                            interface =
-                                interface->NextSiblingElement("interface");
-                        }
-                        if (interface == nullptr)
-                        {
-                            // if we got to the end of the list and
-                            // never found a match, throw 404
-                            asyncResp->res.result(
-                                boost::beast::http::status::not_found);
-                            return;
-                        }
-
-                        tinyxml2::XMLElement* methods =
-                            interface->FirstChildElement("method");
-                        while (methods != nullptr)
-                        {
-                            nlohmann::json argsArray = nlohmann::json::array();
-                            tinyxml2::XMLElement* arg =
-                                methods->FirstChildElement("arg");
-                            while (arg != nullptr)
-                            {
-                                nlohmann::json thisArg;
-                                for (const char* fieldName :
-                                     std::array<const char*, 3>{
-                                         "name", "direction", "type"})
+                                const char* ifaceName =
+                                    interface->Attribute("name");
+                                if (ifaceName != nullptr)
                                 {
-                                    const char* fieldValue =
-                                        arg->Attribute(fieldName);
-                                    if (fieldValue != nullptr)
+                                    interfacesArray.push_back(
+                                        {{"name", ifaceName}});
+                                }
+
+                                interface =
+                                    interface->NextSiblingElement("interface");
+                            }
+                        },
+                        processName, objectPath,
+                        "org.freedesktop.DBus.Introspectable", "Introspect");
+                }
+                else if (methodName.empty())
+                {
+                    crow::connections::systemBus->async_method_call(
+                        [asyncResp, processName, objectPath,
+                         interfaceName](const boost::system::error_code ec,
+                                        const std::string& introspectXml) {
+                            if (ec)
+                            {
+                                BMCWEB_LOG_ERROR
+                                    << "Introspect call failed with error: "
+                                    << ec.message()
+                                    << " on process: " << processName
+                                    << " path: " << objectPath << "\n";
+                                return;
+                            }
+                            tinyxml2::XMLDocument doc;
+
+                            doc.Parse(introspectXml.data(),
+                                      introspectXml.size());
+                            tinyxml2::XMLNode* pRoot =
+                                doc.FirstChildElement("node");
+                            if (pRoot == nullptr)
+                            {
+                                BMCWEB_LOG_ERROR
+                                    << "XML document failed to parse "
+                                    << processName << " " << objectPath << "\n";
+                                asyncResp->res.result(
+                                    boost::beast::http::status::
+                                        internal_server_error);
+                                return;
+                            }
+                            asyncResp->res.jsonValue = {
+                                {"status", "ok"},
+                                {"bus_name", processName},
+                                {"interface", interfaceName},
+                                {"object_path", objectPath}};
+
+                            nlohmann::json& methodsArray =
+                                asyncResp->res.jsonValue["methods"];
+                            methodsArray = nlohmann::json::array();
+
+                            nlohmann::json& signalsArray =
+                                asyncResp->res.jsonValue["signals"];
+                            signalsArray = nlohmann::json::array();
+
+                            nlohmann::json& propertiesObj =
+                                asyncResp->res.jsonValue["properties"];
+                            propertiesObj = nlohmann::json::object();
+
+                            // if we know we're the only call, build the
+                            // json directly
+                            tinyxml2::XMLElement* interface =
+                                pRoot->FirstChildElement("interface");
+                            while (interface != nullptr)
+                            {
+                                const char* ifaceName =
+                                    interface->Attribute("name");
+
+                                if (ifaceName != nullptr &&
+                                    ifaceName == interfaceName)
+                                {
+                                    break;
+                                }
+
+                                interface =
+                                    interface->NextSiblingElement("interface");
+                            }
+                            if (interface == nullptr)
+                            {
+                                // if we got to the end of the list and
+                                // never found a match, throw 404
+                                asyncResp->res.result(
+                                    boost::beast::http::status::not_found);
+                                return;
+                            }
+
+                            tinyxml2::XMLElement* methods =
+                                interface->FirstChildElement("method");
+                            while (methods != nullptr)
+                            {
+                                nlohmann::json argsArray =
+                                    nlohmann::json::array();
+                                tinyxml2::XMLElement* arg =
+                                    methods->FirstChildElement("arg");
+                                while (arg != nullptr)
+                                {
+                                    nlohmann::json thisArg;
+                                    for (const char* fieldName :
+                                         std::array<const char*, 3>{
+                                             "name", "direction", "type"})
                                     {
-                                        thisArg[fieldName] = fieldValue;
-                                    }
-                                }
-                                argsArray.push_back(std::move(thisArg));
-                                arg = arg->NextSiblingElement("arg");
-                            }
-
-                            const char* name = methods->Attribute("name");
-                            if (name != nullptr)
-                            {
-                                std::string uri;
-                                uri.reserve(14 + processName.size() +
-                                            objectPath.size() +
-                                            interfaceName.size() +
-                                            strlen(name));
-                                uri += "/bus/system/";
-                                uri += processName;
-                                uri += objectPath;
-                                uri += "/";
-                                uri += interfaceName;
-                                uri += "/";
-                                uri += name;
-                                methodsArray.push_back({{"name", name},
-                                                        {"uri", std::move(uri)},
-                                                        {"args", argsArray}});
-                            }
-                            methods = methods->NextSiblingElement("method");
-                        }
-                        tinyxml2::XMLElement* signals =
-                            interface->FirstChildElement("signal");
-                        while (signals != nullptr)
-                        {
-                            nlohmann::json argsArray = nlohmann::json::array();
-
-                            tinyxml2::XMLElement* arg =
-                                signals->FirstChildElement("arg");
-                            while (arg != nullptr)
-                            {
-                                const char* name = arg->Attribute("name");
-                                const char* type = arg->Attribute("type");
-                                if (name != nullptr && type != nullptr)
-                                {
-                                    argsArray.push_back({
-                                        {"name", name},
-                                        {"type", type},
-                                    });
-                                }
-                                arg = arg->NextSiblingElement("arg");
-                            }
-                            const char* name = signals->Attribute("name");
-                            if (name != nullptr)
-                            {
-                                signalsArray.push_back(
-                                    {{"name", name}, {"args", argsArray}});
-                            }
-
-                            signals = signals->NextSiblingElement("signal");
-                        }
-
-                        tinyxml2::XMLElement* property =
-                            interface->FirstChildElement("property");
-                        while (property != nullptr)
-                        {
-                            const char* name = property->Attribute("name");
-                            const char* type = property->Attribute("type");
-                            if (type != nullptr && name != nullptr)
-                            {
-                                sdbusplus::message::message m =
-                                    crow::connections::systemBus
-                                        ->new_method_call(processName.c_str(),
-                                                          objectPath.c_str(),
-                                                          "org.freedesktop."
-                                                          "DBus."
-                                                          "Properties",
-                                                          "Get");
-                                m.append(interfaceName, name);
-                                nlohmann::json& propertyItem =
-                                    propertiesObj[name];
-                                crow::connections::systemBus->async_send(
-                                    m, [&propertyItem, asyncResp](
-                                           boost::system::error_code& e,
-                                           sdbusplus::message::message& msg) {
-                                        if (e)
+                                        const char* fieldValue =
+                                            arg->Attribute(fieldName);
+                                        if (fieldValue != nullptr)
                                         {
-                                            return;
+                                            thisArg[fieldName] = fieldValue;
                                         }
+                                    }
+                                    argsArray.push_back(std::move(thisArg));
+                                    arg = arg->NextSiblingElement("arg");
+                                }
 
-                                        convertDBusToJSON("v", msg,
-                                                          propertyItem);
-                                    });
+                                const char* name = methods->Attribute("name");
+                                if (name != nullptr)
+                                {
+                                    std::string uri;
+                                    uri.reserve(14 + processName.size() +
+                                                objectPath.size() +
+                                                interfaceName.size() +
+                                                strlen(name));
+                                    uri += "/bus/system/";
+                                    uri += processName;
+                                    uri += objectPath;
+                                    uri += "/";
+                                    uri += interfaceName;
+                                    uri += "/";
+                                    uri += name;
+                                    methodsArray.push_back(
+                                        {{"name", name},
+                                         {"uri", std::move(uri)},
+                                         {"args", argsArray}});
+                                }
+                                methods = methods->NextSiblingElement("method");
                             }
-                            property = property->NextSiblingElement("property");
-                        }
-                    },
-                    processName, objectPath,
-                    "org.freedesktop.DBus.Introspectable", "Introspect");
-            }
-            else
-            {
-                if (req.method() != boost::beast::http::verb::post)
-                {
-                    res.result(boost::beast::http::status::not_found);
-                    res.end();
-                    return;
+                            tinyxml2::XMLElement* signals =
+                                interface->FirstChildElement("signal");
+                            while (signals != nullptr)
+                            {
+                                nlohmann::json argsArray =
+                                    nlohmann::json::array();
+
+                                tinyxml2::XMLElement* arg =
+                                    signals->FirstChildElement("arg");
+                                while (arg != nullptr)
+                                {
+                                    const char* name = arg->Attribute("name");
+                                    const char* type = arg->Attribute("type");
+                                    if (name != nullptr && type != nullptr)
+                                    {
+                                        argsArray.push_back({
+                                            {"name", name},
+                                            {"type", type},
+                                        });
+                                    }
+                                    arg = arg->NextSiblingElement("arg");
+                                }
+                                const char* name = signals->Attribute("name");
+                                if (name != nullptr)
+                                {
+                                    signalsArray.push_back(
+                                        {{"name", name}, {"args", argsArray}});
+                                }
+
+                                signals = signals->NextSiblingElement("signal");
+                            }
+
+                            tinyxml2::XMLElement* property =
+                                interface->FirstChildElement("property");
+                            while (property != nullptr)
+                            {
+                                const char* name = property->Attribute("name");
+                                const char* type = property->Attribute("type");
+                                if (type != nullptr && name != nullptr)
+                                {
+                                    sdbusplus::message::message m =
+                                        crow::connections::systemBus
+                                            ->new_method_call(
+                                                processName.c_str(),
+                                                objectPath.c_str(),
+                                                "org.freedesktop."
+                                                "DBus."
+                                                "Properties",
+                                                "Get");
+                                    m.append(interfaceName, name);
+                                    nlohmann::json& propertyItem =
+                                        propertiesObj[name];
+                                    crow::connections::systemBus->async_send(
+                                        m,
+                                        [&propertyItem, asyncResp](
+                                            boost::system::error_code& e,
+                                            sdbusplus::message::message& msg) {
+                                            if (e)
+                                            {
+                                                return;
+                                            }
+
+                                            convertDBusToJSON("v", msg,
+                                                              propertyItem);
+                                        });
+                                }
+                                property =
+                                    property->NextSiblingElement("property");
+                            }
+                        },
+                        processName, objectPath,
+                        "org.freedesktop.DBus.Introspectable", "Introspect");
                 }
-
-                nlohmann::json requestDbusData =
-                    nlohmann::json::parse(req.body, nullptr, false);
-
-                if (requestDbusData.is_discarded())
+                else
                 {
-                    res.result(boost::beast::http::status::bad_request);
-                    res.end();
-                    return;
-                }
-                if (!requestDbusData.is_array())
-                {
-                    res.result(boost::beast::http::status::bad_request);
-                    res.end();
-                    return;
-                }
-                auto transaction = std::make_shared<InProgressActionData>(res);
+                    if (req.method() != boost::beast::http::verb::post)
+                    {
+                        asyncResp->res.result(
+                            boost::beast::http::status::not_found);
+                        return;
+                    }
 
-                transaction->path = objectPath;
-                transaction->methodName = methodName;
-                transaction->arguments = std::move(requestDbusData);
+                    nlohmann::json requestDbusData =
+                        nlohmann::json::parse(req.body, nullptr, false);
 
-                findActionOnInterface(transaction, processName);
-            }
-        });
+                    if (requestDbusData.is_discarded())
+                    {
+                        asyncResp->res.result(
+                            boost::beast::http::status::bad_request);
+                        return;
+                    }
+                    if (!requestDbusData.is_array())
+                    {
+                        asyncResp->res.result(
+                            boost::beast::http::status::bad_request);
+                        return;
+                    }
+                    auto transaction =
+                        std::make_shared<InProgressActionData>(asyncResp->res);
+
+                    transaction->path = objectPath;
+                    transaction->methodName = methodName;
+                    transaction->arguments = std::move(requestDbusData);
+
+                    findActionOnInterface(transaction, processName);
+                }
+            });
 }
 } // namespace openbmc_mapper
 } // namespace crow
diff --git a/include/redfish_v1.hpp b/include/redfish_v1.hpp
index 76ff457..6d2480e 100644
--- a/include/redfish_v1.hpp
+++ b/include/redfish_v1.hpp
@@ -14,10 +14,9 @@
 {
     BMCWEB_ROUTE(app, "/redfish/")
         .methods(boost::beast::http::verb::get)(
-            [](const crow::Request&, crow::Response& res) {
-                std::shared_ptr<AsyncResp> asyncResp =
-                    std::make_shared<AsyncResp>(res);
-                res.jsonValue = {{"v1", "/redfish/v1/"}};
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                asyncResp->res.jsonValue = {{"v1", "/redfish/v1/"}};
             });
 }
 } // namespace redfish
diff --git a/include/webassets.hpp b/include/webassets.hpp
index 97a0194..070442e 100644
--- a/include/webassets.hpp
+++ b/include/webassets.hpp
@@ -143,16 +143,18 @@
             }
 
             app.routeDynamic(webpath)(
-                [absolutePath, contentType,
-                 contentEncoding](const crow::Request&, crow::Response& res) {
+                [absolutePath, contentType, contentEncoding](
+                    const crow::Request&,
+                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
                     if (contentType != nullptr)
                     {
-                        res.addHeader("Content-Type", contentType);
+                        asyncResp->res.addHeader("Content-Type", contentType);
                     }
 
                     if (contentEncoding != nullptr)
                     {
-                        res.addHeader("Content-Encoding", contentEncoding);
+                        asyncResp->res.addHeader("Content-Encoding",
+                                                 contentEncoding);
                     }
 
                     // res.set_header("Cache-Control", "public, max-age=86400");
@@ -160,15 +162,14 @@
                     if (!inf)
                     {
                         BMCWEB_LOG_DEBUG << "failed to read file";
-                        res.result(
+                        asyncResp->res.result(
                             boost::beast::http::status::internal_server_error);
-                        res.end();
                         return;
                     }
 
-                    res.body() = {std::istreambuf_iterator<char>(inf),
-                                  std::istreambuf_iterator<char>()};
-                    res.end();
+                    asyncResp->res.body() = {
+                        std::istreambuf_iterator<char>(inf),
+                        std::istreambuf_iterator<char>()};
                 });
         }
     }