RequestServer: Implement stale cache revalidation

When a request becomes stale, we will now issue a revalidation request
(if the response indicates it may be revalidated). We do this by issuing
a normal fetch request, with If-None-Match and/or If-Modified-Since
request headers.

If the server replies with an HTTP 304 status, we update the stored
response headers to match the 304's headers, and serve the response to
the client from the cache.

If the server replies with any other code, we remove the cache entry.
We will open a new cache entry to cache the new response, if possible.
This commit is contained in:
Timothy Flynn 2025-10-28 17:09:35 -04:00 committed by Tim Flynn
parent 3d45a209b6
commit a4e3890c05
Notes: github-actions[bot] 2025-11-02 18:04:24 +00:00
9 changed files with 263 additions and 65 deletions

View file

@ -99,6 +99,7 @@ ErrorOr<CacheIndex> CacheIndex::create(Database::Database& database)
statements.remove_entry = TRY(database.prepare_statement("DELETE FROM CacheIndex WHERE cache_key = ?;"sv));
statements.remove_all_entries = TRY(database.prepare_statement("DELETE FROM CacheIndex;"sv));
statements.select_entry = TRY(database.prepare_statement("SELECT * FROM CacheIndex WHERE cache_key = ?;"sv));
statements.update_response_headers = TRY(database.prepare_statement("UPDATE CacheIndex SET response_headers = ? WHERE cache_key = ?;"sv));
statements.update_last_access_time = TRY(database.prepare_statement("UPDATE CacheIndex SET last_access_time = ? WHERE cache_key = ?;"sv));
return CacheIndex { database, statements };
@ -140,6 +141,16 @@ void CacheIndex::remove_all_entries()
m_entries.clear();
}
void CacheIndex::update_response_headers(u64 cache_key, HTTP::HeaderMap response_headers)
{
auto entry = m_entries.get(cache_key);
if (!entry.has_value())
return;
m_database.execute_statement(m_statements.update_response_headers, {}, serialize_headers(response_headers), cache_key);
entry->response_headers = move(response_headers);
}
void CacheIndex::update_last_access_time(u64 cache_key)
{
auto entry = m_entries.get(cache_key);