Make use of filebody for dump offload

Logservice has been rewritten to use file_body to offload dump files
from BMC.

There are two kind of dump files, BMC dump and System dump.While BMC
dump just requires default support from beast::file_body, System dump
requires base64 encoding support from beast. But beast::file_body do not
have ready-made support for base64 encoding. So a custom file_body has
been written for the base64 encoding.

The openFile apis in crow::Response do not have support for unix file
descriptor. Since dump files are accesses via descriptors, added new
openFile api that accepts descriptors.

Tested:
Functionality test have been executed to verify the bmc dump offload.
Did sanity test by invoking bmcweb pages via browser.

Change-Id: I24192657c03d8b2f0394d31e7424c6796ba3227a
Signed-off-by: Abhilash Raju <abhilash.kollam@gmail.com>
diff --git a/http/http_response.hpp b/http/http_response.hpp
index ec54a90..4015899 100644
--- a/http/http_response.hpp
+++ b/http/http_response.hpp
@@ -1,8 +1,8 @@
 #pragma once
+#include "http_file_body.hpp"
 #include "logging.hpp"
 #include "utils/hex_utils.hpp"
 
-#include <boost/beast/http/file_body.hpp>
 #include <boost/beast/http/message.hpp>
 #include <boost/beast/http/message_generator.hpp>
 #include <boost/beast/http/string_body.hpp>
@@ -27,7 +27,7 @@
     friend class crow::Connection;
 
     using string_response = http::response<http::string_body>;
-    using file_response = http::response<http::file_body>;
+    using file_response = http::response<bmcweb::FileBody>;
 
     // Use boost variant2 because it doesn't have valueless by exception
     boost::variant2::variant<string_response, file_response> response;
@@ -356,25 +356,45 @@
             response);
     }
 
-    bool openFile(const std::filesystem::path& path)
+    bool openFile(const std::filesystem::path& path,
+                  bmcweb::EncodingType enc = bmcweb::EncodingType::Raw)
     {
-        http::file_body::value_type file;
+        file_response::body_type::value_type body(enc);
         boost::beast::error_code ec;
-        file.open(path.c_str(), boost::beast::file_mode::read, ec);
+        body.open(path.c_str(), boost::beast::file_mode::read, ec);
         if (ec)
         {
             return false;
         }
+        updateFileBody(std::move(body));
+        return true;
+    }
+
+    bool openFd(int fd, bmcweb::EncodingType enc = bmcweb::EncodingType::Raw)
+    {
+        file_response::body_type::value_type body(enc);
+        boost::beast::error_code ec;
+        body.setFd(fd, ec);
+        if (ec)
+        {
+            BMCWEB_LOG_ERROR("Failed to set fd");
+            return false;
+        }
+        updateFileBody(std::move(body));
+        return true;
+    }
+
+  private:
+    void updateFileBody(file_response::body_type::value_type file)
+    {
         // store the headers on stack temporarily so we can reconstruct the new
         // base with the old headers copied in.
         http::header<false> headTemp = std::move(fields());
         file_response& fileResponse =
             response.emplace<file_response>(std::move(headTemp));
         fileResponse.body() = std::move(file);
-        return true;
     }
 
-  private:
     std::optional<std::string> expectedHash;
     bool completed = false;
     std::function<void(Response&)> completeRequestHandler;