Clean up preparePayload
boost::beast::http::message::prepare_payload [1] can throw, which isn't
really the behavior we want (as it throws to the io_context). Luckily,
every part of that function is using public methods, and we can simplify
it.
In past commits, we've worked around this issue:
6295becabb9edba2edb53a3c0dddc13d2ffac8dd
This is an attempt to fix it properly.
[1] https://github.com/boostorg/beast/blob/ae01f0201dbf940cbc32d96d7a78dc584a02ab26/include/boost/beast/http/impl/message.hpp#L398
Redfish service validator passes
Signed-off-by: Ed Tanous <edtanous@google.com>
Change-Id: Ie88ddeecfd226bba75a7659cfb7ddddd38eb27cb
diff --git a/http/http_connection.hpp b/http/http_connection.hpp
index d4428df..24af031 100644
--- a/http/http_connection.hpp
+++ b/http/http_connection.hpp
@@ -377,16 +377,6 @@
res.body() = std::string(res.reason());
}
- if (res.result() == boost::beast::http::status::no_content)
- {
- // Boost beast throws if content is provided on a no-content
- // response. Ideally, this would never happen, but in the case that
- // it does, we don't want to throw.
- BMCWEB_LOG_CRITICAL
- << this << " Response content provided but code was no-content";
- res.body().clear();
- }
-
res.addHeader(boost::beast::http::field::date, getCachedDateStr());
doWrite(res);
diff --git a/http/http_response.hpp b/http/http_response.hpp
index 2af12c9..58e047c 100644
--- a/http/http_response.hpp
+++ b/http/http_response.hpp
@@ -143,7 +143,33 @@
void preparePayload()
{
- stringResponse->prepare_payload();
+ // This code is a throw-free equivalent to
+ // beast::http::message::prepare_payload
+ boost::optional<uint64_t> pSize = stringResponse->payload_size();
+ using boost::beast::http::status;
+ using boost::beast::http::status_class;
+ using boost::beast::http::to_status_class;
+ if (!pSize)
+ {
+ pSize = 0;
+ }
+ else
+ {
+ bool is1XXReturn = to_status_class(stringResponse->result()) ==
+ status_class::informational;
+ if (*pSize > 0 &&
+ (is1XXReturn ||
+ stringResponse->result() == status::no_content ||
+ stringResponse->result() == status::not_modified))
+ {
+ BMCWEB_LOG_CRITICAL
+ << this
+ << " Response content provided but code was no-content or not_modified, which aren't allowed to have a body";
+ pSize = 0;
+ body().clear();
+ }
+ }
+ stringResponse->content_length(*pSize);
}
void clear()