Add check to omit `DateTime` from etag calculation
Ignores any json property named `DateTime` when calculating
the etag value of an HTTP response as per the updated
Redfish Spec (section 6.5: ETags)
Tested:
- Redfish Service Validator passes
- Tested on romulus:
1. GET resource with a "DateTime" field
```
curl -k -H "X-Auth-Token: $XAUTH_TOKEN" "https://$BMC/redfish/v1/TaskService" \
--etag-save ./etag.txt -v
...
< etag: "6A4CE897"
...
{
"@odata.id": "/redfish/v1/TaskService",
"@odata.type": "#TaskService.v1_1_4.TaskService",
"CompletedTaskOverWritePolicy": "Oldest",
"DateTime": "2025-07-23T17:08:20+00:00",
"Id": "TaskService",
"LifeCycleEventOnTaskStateChange": true,
"Name": "Task Service",
"ServiceEnabled": true,
"Status": {
"State": "Enabled"
},
"Tasks": {
"@odata.id": "/redfish/v1/TaskService/Tasks"
}
```
2. GET same resource again later, etag is same as before
```
curl -k -H "X-Auth-Token: $XAUTH_TOKEN" "https://$BMC/redfish/v1/TaskService" \
--etag-save ./etag.txt -v
...
< etag: "6A4CE897"
...
{
"@odata.id": "/redfish/v1/TaskService",
"@odata.type": "#TaskService.v1_1_4.TaskService",
"CompletedTaskOverWritePolicy": "Oldest",
"DateTime": "2025-07-23T17:10:48+00:00",
"Id": "TaskService",
"LifeCycleEventOnTaskStateChange": true,
"Name": "Task Service",
"ServiceEnabled": true,
"Status": {
"State": "Enabled"
},
"Tasks": {
"@odata.id": "/redfish/v1/TaskService/Tasks"
}
```
"DateTime" is the only value to have changed, but since
it is ignored the etag did not change
3. GET with if-none-match returns 304
```
curl -k -H "X-Auth-Token: $XAUTH_TOKEN" "https://$BMC/redfish/v1/TaskService" \
--etag-save ./etag.txt --etag-compare ./etag.txt -v
...
> if-none-match: "6A4CE897"
...
< HTTP/2 304
< allow: GET
< odata-version: 4.0
< strict-transport-security: max-age=31536000; includeSubdomains
< pragma: no-cache
< cache-control: no-store, max-age=0
< x-content-type-options: nosniff
< etag: "6A4CE897"
< date: Wed, 23 Jul 2025 17:14:39 GMT
< content-length: 0
<
...
```
Change-Id: I51f7668e75719c69c55535e4a1e48c8bae7c9488
Signed-off-by: Corey Ethington <cethington@coreweave.com>
diff --git a/http/http_connection.hpp b/http/http_connection.hpp
index 64aac00..8e68bf5 100644
--- a/http/http_connection.hpp
+++ b/http/http_connection.hpp
@@ -440,11 +440,11 @@
{
return;
}
- std::string_view expected =
+ std::string_view expectedEtag =
req->getHeaderValue(boost::beast::http::field::if_none_match);
- if (!expected.empty())
+ if (!expectedEtag.empty())
{
- asyncResp->res.setExpectedHash(expected);
+ asyncResp->res.setExpectedEtag(expectedEtag);
}
handler->handle(req, asyncResp);
}