From 9ed498be3e82392ac3273da75e7ed8e6572edaa9 Mon Sep 17 00:00:00 2001 From: 94xhn <87560781+94xhn@users.noreply.github.com> Date: Mon, 20 Jul 2026 09:09:35 +0800 Subject: [PATCH] Fix HttpServerConnection ETag check to use If-None-Match sendResponseHeaders() was checking the If-Match request header to decide whether to return 304 Not Modified for a cached GET/HEAD, but If-Match is for optimistic-concurrency writes (RFC 7232 3.1), not cache revalidation. Real browsers send If-None-Match when revalidating a cached resource, so this code path never actually returned 304 for normal traffic - HTTP_HEADER_IF_NONE_MATCH wasn't even defined, so the header got stored as a custom field and request.headers.contains(HTTP_HEADER_IF_MATCH) was always false for it. Added an If-None-Match entry to the header field map and switched the 304 check to use it, matching the conditional GET semantics in RFC 7232. --- Sming/Components/Network/src/Network/Http/HttpHeaderFields.h | 3 +++ .../Network/src/Network/Http/HttpServerConnection.cpp | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Sming/Components/Network/src/Network/Http/HttpHeaderFields.h b/Sming/Components/Network/src/Network/Http/HttpHeaderFields.h index 0ddce3cd95..886fa5a388 100644 --- a/Sming/Components/Network/src/Network/Http/HttpHeaderFields.h +++ b/Sming/Components/Network/src/Network/Http/HttpHeaderFields.h @@ -59,6 +59,9 @@ "Precondition check using ETag to avoid accidental overwrites when servicing multiple user requests. Ensures " \ "resource entity tag matches before proceeding.") \ XX(IF_MODIFIED_SINCE, "If-Modified-Since", 0, "Precondition check using Date") \ + XX(IF_NONE_MATCH, "If-None-Match", 0, \ + "Precondition check using ETag for cache revalidation. Used by GET/HEAD requests to avoid re-fetching a " \ + "resource which has not changed.") \ XX(LAST_MODIFIED, "Last-Modified", 0, "Server timestamp indicating date and time resource was last modified") \ XX(LOCATION, "Location", 0, "Used in redirect responses, amongst other places") \ XX(SEC_WEBSOCKET_ACCEPT, "Sec-WebSocket-Accept", 0, "Server response to opening Websocket handshake") \ diff --git a/Sming/Components/Network/src/Network/Http/HttpServerConnection.cpp b/Sming/Components/Network/src/Network/Http/HttpServerConnection.cpp index 044a6a6ad8..19d9e605fe 100644 --- a/Sming/Components/Network/src/Network/Http/HttpServerConnection.cpp +++ b/Sming/Components/Network/src/Network/Http/HttpServerConnection.cpp @@ -268,8 +268,8 @@ void HttpServerConnection::sendResponseHeaders(HttpResponse* response) } } - if(request.headers.contains(HTTP_HEADER_IF_MATCH) && response->headers.contains(HTTP_HEADER_ETAG) && - request.headers[HTTP_HEADER_IF_MATCH] == response->headers[HTTP_HEADER_ETAG]) { + if(request.headers.contains(HTTP_HEADER_IF_NONE_MATCH) && response->headers.contains(HTTP_HEADER_ETAG) && + request.headers[HTTP_HEADER_IF_NONE_MATCH] == response->headers[HTTP_HEADER_ETAG]) { if(request.method == HTTP_GET || request.method == HTTP_HEAD) { response->code = HTTP_STATUS_NOT_MODIFIED; response->headers[HTTP_HEADER_CONTENT_LENGTH] = "0";