Commit graph

5 commits

Author SHA1 Message Date
Timothy Flynn
9b8f6b8108 RequestServer: Issue a network request for failed cached responses
If transferring a cached response body fails for any reason, we will now
issue a network request instead of failing the request outright.

The catch here is that we will have already transferred the response
code and headers to the client, and potentially some of the body. So we
attempt to only request the remaining data over the network using a
range request. This feels a bit sketchy, but this is also how Chromium
behaves.

However, the server may or may not support range requests. If they do,
we can expect an HTTP 206 response with the bytes we need. If not, we
will receive an HTTP 200 (assuming the request succeeded), along with
the entire object's body. In this case, we also behave like Chromium,
and internally drop number of bytes we had already transferred.
2025-10-16 09:06:48 -04:00
Timothy Flynn
3516a2344f LibRequests+RequestServer: Begin implementing an HTTP disk cache
This adds a disk cache for HTTP responses received from the network. For
now, we take a rather conservative approach to caching. We don't cache a
response until we're 100% sure it is cacheable (there are heuristics we
can implement in the future based on the absence of specific headers).

The cache is broken into 2 categories of files:

1. An index file. This is a SQL database containing metadata about each
   cache entry (URL, timestamps, etc.).
2. Cache files. Each cached response is in its own file. The file is an
   amalgamation of all info needed to reconstruct an HTTP response. This
   includes the status code, headers, body, etc.

A cache entry is created once we receive the headers for a response. The
index, however, is not updated at this point. We stream the body into
the cache entry as it is received. Once we've successfully cached the
entire body, we create an index entry in the database. If any of these
steps failed along the way, the cache entry is removed and the index is
left untouched.

Subsequent requests are checked for cache hits from the index. If a hit
is found, we read just enough of the cache entry to inform WebContent of
the status code and headers. The body of the response is piped to WC via
syscalls, such that the transfer happens entirely in the kernel; no need
to allocate the memory for the body in userspace (WC still allocates a
buffer to hold the data, of course). If an error occurs while piping the
body, we currently error out the request. There is a FIXME to switch to
a network request.

Cache hits are also validated for freshness before they are used. If a
response has expired, we remove it and its index entry, and proceed with
a network request.
2025-10-14 13:40:33 +02:00
Timothy Flynn
6f4be4791a LibRequests: Add hooks to handle RequestServer death 2025-08-10 11:02:50 +02:00
Timothy Flynn
b54a520b69 LibRequests+RequestServer: Add an error code for bad content encoding
This error is set by curl when, e.g., a gzipped response body has an
invalid gzip encoding.
2025-04-20 16:50:37 +02:00
Timothy Flynn
0de017df9b LibRequests: Move NetworkError stringification to LibRequests
Let's also rename the file to NetworkError.h while we're here. No need
to have "Enum" in the name.
2025-04-02 08:52:45 -04:00