From 4474b6d11a6a39d14e4baf7c03405a8152707121 Mon Sep 17 00:00:00 2001 From: nick Date: Sun, 7 Jun 2026 19:33:37 -0600 Subject: [PATCH] api: remove status cache validators --- docs/API.md | 15 ------ .../overland-controller.ino | 52 ------------------- tests/test_http_api_contract.py | 9 +--- 3 files changed, 1 insertion(+), 75 deletions(-) diff --git a/docs/API.md b/docs/API.md index 211f433..e8e2a89 100644 --- a/docs/API.md +++ b/docs/API.md @@ -189,21 +189,6 @@ If an unknown field is requested, the Cargo ESP32 returns HTTP `400`: "details": ["Unknown field 'xyz'"] } -#### HTTP caching - -`GET /api/v1/status` returns these cache validation headers: - - ETag - Last-Modified - Cache-Control: no-cache - -Clients may revalidate with `If-None-Match` or `If-Modified-Since`. - -If the selected status payload has not changed, the Cargo ESP32 returns: - - HTTP/1.1 304 Not Modified - -A `304` response has no JSON body. ### battery diff --git a/firmware/esp32/overland-controller/overland-controller.ino b/firmware/esp32/overland-controller/overland-controller.ino index 8ce0bac..a2e2b50 100644 --- a/firmware/esp32/overland-controller/overland-controller.ino +++ b/firmware/esp32/overland-controller/overland-controller.ino @@ -1134,30 +1134,9 @@ int findStatusFieldIndex(const String& field) { return -1; } -uint32_t fnv1a32(const String& value) { - uint32_t hash = 2166136261UL; - for (unsigned int i = 0; i < value.length(); i++) { - hash ^= static_cast(value[i]); - hash *= 16777619UL; - } - return hash; -} -String statusEtagForPayload(const String& payload) { - return String("\"") + String(fnv1a32(payload), HEX) + "-" + String(payload.length(), HEX) + "\""; -} -String lastStatusValidatorEtag = ""; -String lastStatusModified = "Thu, 01 Jan 1970 00:00:00 GMT"; -String formatHttpDateFromUptime(unsigned long seconds) { - char buffer[32]; - snprintf(buffer, sizeof(buffer), "Thu, 01 Jan 1970 %02lu:%02lu:%02lu GMT", - (seconds / 3600UL) % 24UL, - (seconds / 60UL) % 60UL, - seconds % 60UL); - return String(buffer); -} void buildStatusDocument(JsonDocument& doc) { doc["type"] = MSG_STATUS_RESPONSE; @@ -2737,34 +2716,6 @@ void handleStatus() { String output; serializeJson(doc, output); - DynamicJsonDocument validatorDoc(4096); - deserializeJson(validatorDoc, output); - validatorDoc["timestamp"] = 0; - if (validatorDoc["system"].is()) { - validatorDoc["system"]["uptime_seconds"] = 0; - } - - String validatorPayload; - serializeJson(validatorDoc, validatorPayload); - - String etag = statusEtagForPayload(validatorPayload); - if (etag != lastStatusValidatorEtag) { - lastStatusValidatorEtag = etag; - lastStatusModified = formatHttpDateFromUptime(millis() / 1000); - } - - server.sendHeader("ETag", etag); - server.sendHeader("Last-Modified", lastStatusModified); - server.sendHeader("Cache-Control", "no-cache"); - - String ifNoneMatch = server.header("If-None-Match"); - String ifModifiedSince = server.header("If-Modified-Since"); - - if (ifNoneMatch == etag || ifModifiedSince == lastStatusModified) { - server.send(304); - return; - } - server.send(200, "application/json", output); } @@ -2869,9 +2820,6 @@ void setup() { server.on("/bms/select", HTTP_POST, handleSelectBms); - const char* statusCacheHeaders[] = {"If-None-Match", "If-Modified-Since"}; - server.collectHeaders(statusCacheHeaders, 2); - server.begin(); Serial.println("Web Server Started"); diff --git a/tests/test_http_api_contract.py b/tests/test_http_api_contract.py index b3155ff..2442645 100644 --- a/tests/test_http_api_contract.py +++ b/tests/test_http_api_contract.py @@ -284,7 +284,7 @@ def test_http_error_fixture_and_known_error_codes_are_stable(): assert error_code in source -def test_status_endpoint_supports_field_selection_and_cache_headers(): +def test_status_endpoint_supports_field_selection(): source = firmware_source() assert 'server.hasArg("fields")' in source @@ -293,13 +293,6 @@ def test_status_endpoint_supports_field_selection_and_cache_headers(): assert '"invalid_field"' in source assert 'Unknown field' in source assert 'server.send(400, "application/json", errorOutput)' in source - assert 'server.sendHeader("ETag", etag)' in source - assert 'server.sendHeader("Last-Modified", lastStatusModified)' in source - assert 'server.sendHeader("Cache-Control", "no-cache")' in source - assert 'server.header("If-None-Match")' in source - assert 'server.header("If-Modified-Since")' in source - assert 'server.send(304)' in source - assert 'server.collectHeaders(statusCacheHeaders, 2)' in source def test_embedded_webui_uses_partial_status_for_overview_polling():