]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
fix(http): Treat HTTP 2xx with empty body as cache miss (#1707)
authorBjörn Svensson <bjorn.a.svensson@est.tech>
Mon, 23 Mar 2026 19:29:32 +0000 (20:29 +0100)
committerGitHub <noreply@github.com>
Mon, 23 Mar 2026 19:29:32 +0000 (20:29 +0100)
fix(storage): Treat empty remote storage entries as errors

A remote storage backend returning a value with an empty body indicates
a corrupt or misconfigured entry, not a cache miss. Check for empty
values in the storage layer so that all current and future backends are
covered. The error is logged but the backend is not marked as failed,
since other entries may still be valid.

Signed-off-by: Björn Svensson <bjorn.a.svensson@est.tech>
src/ccache/storage/storage.cpp
test/suites/remote_http.bash

index 3282cd97123efb69895d1bc1413867b5661d04ef..61942e47f384c5402f40b9dc4eb3795bbda8035c 100644 (file)
@@ -642,7 +642,7 @@ Storage::get_from_remote_storage(const Hash::Digest& key,
     }
 
     auto& value = *result;
-    if (value) {
+    if (value && !value->empty()) {
       LOG("Retrieved {} from {} ({:.2f} ms)",
           util::format_base16(key),
           backend->url_for_logging,
@@ -654,6 +654,12 @@ Storage::get_from_remote_storage(const Hash::Digest& key,
       if (entry_receiver(std::move(*value))) {
         return;
       }
+    } else if (value) {
+      LOG("Got empty entry for {} from {} ({:.2f} ms)",
+          util::format_base16(key),
+          backend->url_for_logging,
+          ms);
+      local.increment_statistic(core::Statistic::remote_storage_error);
     } else {
       LOG("No {} in {} ({:.2f} ms)",
           util::format_base16(key),
index 072ceb16d9fb316adea581b59e31b94cd18c6bea..ac07cee219e25ff40f7027e9d714a730209211b6 100644 (file)
@@ -238,4 +238,33 @@ fi
         expect_stat files_in_cache 2 # fetched from remote
         expect_file_count 2 '*' remote # result + manifest
     fi
+
+    # -------------------------------------------------------------------------
+    TEST "Empty body on HTTP 2xx treated as error"
+
+    start_http_server 12780 remote
+    export CCACHE_REMOTE_STORAGE="http://localhost:12780 helper=_builtin_"
+
+    # Populate remote cache.
+    $CCACHE_COMPILE -c test.c
+    expect_stat direct_cache_hit 0
+    expect_stat cache_miss 1
+    expect_stat files_in_cache 2
+    expect_file_count 2 '*' remote # result + manifest
+
+    # Truncate all remote entries to 0 bytes. Uses '> file' redirection to
+    # open each file for writing with no input, emptying it.
+    find remote -type f -exec sh -c '> "$1"' _ {} \;
+
+    # Clear local cache.
+    $CCACHE -C >/dev/null
+    expect_stat files_in_cache 0
+
+    # Should be an error, not a hit, since remote entries are empty.
+    $CCACHE_COMPILE -c test.c
+    expect_stat direct_cache_hit 0
+    expect_stat cache_miss 2
+    expect_stat remote_storage_hit 0
+    expect_stat remote_storage_error 2 # result + manifest
+    expect_stat remote_storage_read_hit 0
 }