Implement etag headers

This commit implements a limited support for the production of etags on
json resources.  It is intended to cause two things:

1. To get bmcweb to pass the PROTO_ETAG_ON_GET_ACCOUNT check, as well as
   the redfish spec, which states: "Implementations shall support the
   return of ETag headers for GET requests of ManagerAccount resources."

2. Begin discussions on what client-facing caching could look like in
   the future, and to implement the fewest lines of code this author
   could think of, with the hope of extending it later.

As written, it injects into the Response class a method that, for json
responses, uses std::hash<json> to generate an etag.  This was chosen
under the assumption that it caused the least binary impact, and is
already a function provided by nlohmann, so required minimal
implementation effort to get something that functioned to the standard:
https://json.nlohmann.me/api/basic_json/std_hash/#version-history

I'm open to discussions if this should be improved in the future to
include more entropy, or to be a "weak" etag, but I think starting
with std::hash is a good first step.

This patchset intentionally does notimplement handling of the
If-None-Match, or If-Match headers that a caching client would likely
send that implements this.  That is not explicitly required by the spec,
relatively complex, and probably has consequences that this author
doesn't want to write the test cases for (yet).  This lack of support
makes this patchset largely only "useful" in passing the tests, and
implementing the spec to the letter, it does not generalize a caching
client feature that improves performance.

Tested:
curl -vvvv --insecure --user root:0penBmc  https://192.168.7.2/redfish/v1

Contains in the response:
ETag: "765E4548"

The redfish protocol validator now passes the PROTO_ETAG_ON_GET_ACCOUNT
test, which increases our passing test count by 4 compared to previously.

Current counts are 352 passing, 30 failing, 36 not tested.

Signed-off-by: Ed Tanous <edtanous@google.com>
Change-Id: I3389b2ba98bf1276e1cb2d9c5954437b924f2d94
diff --git a/http/http_response.hpp b/http/http_response.hpp
index 3c2a3f9..58a8029 100644
--- a/http/http_response.hpp
+++ b/http/http_response.hpp
@@ -4,6 +4,7 @@
 
 #include <boost/beast/http/message.hpp>
 #include <boost/beast/http/string_body.hpp>
+#include <utils/hex_utils.hpp>
 
 #include <optional>
 #include <string>
@@ -125,6 +126,17 @@
 
     void end()
     {
+        // Only set etag if this request succeeded
+        if (result() == boost::beast::http::status::ok)
+        {
+            // and the json response isn't empty
+            if (!jsonValue.empty())
+            {
+                size_t hashval = std::hash<nlohmann::json>{}(jsonValue);
+                std::string hexVal = "\"" + intToHexString(hashval, 8) + "\"";
+                addHeader(boost::beast::http::field::etag, hexVal);
+            }
+        }
         if (completed)
         {
             BMCWEB_LOG_ERROR << this << " Response was ended twice";