http_body: Implement static bmcweb::HttpBody::size() function

In boost::beast::http::message::prepare_payload(), if HttpBody does
not implement a size() function, it defaults to calling chunked(true)
for HTTP/1.1 and chunked(false) for other versions.

We encountered an issue with request data (an extra final chunk) when
`chunked(true)` is called with empty data. To ensure prepare_payload
behaves as expected, we want it to follow the code path that handles the
payload size correctly. Specifically, we want it to:

- Use `content_length(n)` for requests with data.
- Use `chunked(false)` for requests without data.

By adding a static implementation of the bmcweb::HttpBody::size()
function, we ensure the payload size is returned correctly, guiding
prepare_payload to the expected code section[1]

Tested on Catalina with continuous Redfish aggregation queries; no
errors or incorrect responses were observed.

[1] https://github.com/boostorg/beast/blob/fee9be0be10c9c9a22ac1505a710d1d8ed5a3dfb/include/boost/beast/http/impl/message.hpp#L364-L374

Signed-off-by: Potin Lai <potin.lai@quantatw.com>
Signed-off-by: Ed Tanous <etanous@nvidia.com>
Change-Id: I4d84c8b6b9b3d65ce97e010b875ea49b3e1fc9d0
diff --git a/http/http_body.hpp b/http/http_body.hpp
index 4462a50..673058e 100644
--- a/http/http_body.hpp
+++ b/http/http_body.hpp
@@ -12,6 +12,8 @@
 #include <boost/beast/http/message.hpp>
 #include <boost/system/error_code.hpp>
 
+#include <cstdint>
+#include <optional>
 #include <string_view>
 
 namespace bmcweb
@@ -24,6 +26,8 @@
     class reader;
     class value_type;
     // NOLINTEND(readability-identifier-naming)
+
+    static std::uint64_t size(const value_type& body);
 };
 
 enum class EncodingType
@@ -267,4 +271,10 @@
     }
 };
 
+inline std::uint64_t HttpBody::size(const value_type& body)
+{
+    std::optional<size_t> payloadSize = body.payloadSize();
+    return payloadSize.value_or(0U);
+}
+
 } // namespace bmcweb