Add CBOR support
CBOR is a more efficient way to represent json, and something that, as
you can see from this patch, is relatively trivial to implement in our
current nlohmann json handlers. This allows users that specify an
accepts header of "application/cbor" to request the BMC produce a cbor
response.
This feature adds 1520 bytes (1.48KB) to the binary size of bmcweb.
For ServiceRoot
GET /redfish/v1 Accepts: application/json - returns json
GET /redfish/v1 Accepts: application/cbor - returns cbor
GET /redfish/v1 Accepts: */* - returns json
GET /redfish/v1 Accepts: text/html - returns html
GET /redfish/v1 no-accepts header - returns json
For service root, CBOR encoding drops the payload size from 1520 bytes
on my system, to 1021 byes, which is a significant improvement in the
number of bytes we need to compress.
Redfish-service-validator passes.
Signed-off-by: Ed Tanous <edtanous@google.com>
Change-Id: I847e678cf79dfd7d55e6d3b26960c419e47063af
diff --git a/http/http_connection.hpp b/http/http_connection.hpp
index 115b7ff..efd4313 100644
--- a/http/http_connection.hpp
+++ b/http/http_connection.hpp
@@ -465,8 +465,8 @@
if (res.body().empty() && !res.jsonValue.empty())
{
using http_helpers::ContentType;
- std::array<ContentType, 2> allowed{ContentType::JSON,
- ContentType::HTML};
+ std::array<ContentType, 3> allowed{
+ ContentType::CBOR, ContentType::JSON, ContentType::HTML};
ContentType prefered =
getPreferedContentType(req->getHeaderValue("Accept"), allowed);
@@ -474,6 +474,12 @@
{
prettyPrintJson(res);
}
+ else if (prefered == ContentType::CBOR)
+ {
+ res.addHeader(boost::beast::http::field::content_type,
+ "application/cbor");
+ nlohmann::json::to_cbor(res.jsonValue, res.body());
+ }
else
{
// Technically prefered could also be NoMatch here, but we'd
diff --git a/include/http_utility.hpp b/include/http_utility.hpp
index e1a8e2a..cf3ddc2 100644
--- a/include/http_utility.hpp
+++ b/include/http_utility.hpp
@@ -41,8 +41,9 @@
{"text/html", ContentType::HTML},
}};
-inline ContentType getPreferedContentType(std::string_view header,
- std::span<ContentType> preferedOrder)
+inline ContentType
+ getPreferedContentType(std::string_view header,
+ std::span<const ContentType> preferedOrder)
{
size_t lastIndex = 0;
while (lastIndex < header.size() + 1)