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