Repository: LadybirdBrowser/ladybird
File: Libraries/LibHTTP/Cache/Utilities.cpp (C++)

Code before:
    result |= static_cast<u64>(bytes[1]) << 48;
    result |= static_cast<u64>(bytes[2]) << 40;
    result |= static_cast<u64>(bytes[3]) << 32;
    result |= static_cast<u64>(bytes[4]) << 24;
    result |= static_cast<u64>(bytes[5]) << 16;
    result |= static_cast<u64>(bytes[6]) << 8;
    result |= static_cast<u64>(bytes[7]);

    return result;
}

LexicalPath path_for_cache_key(LexicalPath const& cache_directory, u64 cache_key)
{
    return cache_directory.append(MUST(String::formatted("{:016x}", cache_key)));
}

// https://httpwg.org/specs/rfc9111.html#response.cacheability
bool is_cacheable(StringView method, HTTP::HeaderList const& request_headers)
{
    // A cache MUST NOT store a response to a request unless:

    // * the request method is understood by the cache;
    if (!method.is_one_of("GET"sv, "HEAD"sv))
        return false;

    // AD-HOC: Neither the disk cache nor the memory cache handle partial responses yet. So we don't cache them for now.
    return !request_headers.contains("Range"sv);
}

// https://datatracker.ietf.org/doc/html/rfc9110#name-overview-of-status-codes
static bool is_heuristically_cacheable_status(u32 status_code)
{
    // Responses with status codes that are defined as heuristically cacheable
    // (e.g., 200, 203, 204, 206, 300, 301, 308, 404, 405, 410, 414, and 501)
    // can be reused by a cache with heuristic expiration [...]
    switch (status_code) {
    case 200:
    case 203:
    case 204:
    case 206:
    case 300:
    case 301:
    case 308:
    case 404:
    case 405:
    case 410:
    case 414:
    case 501:
        return true;
    default:
        return false;

Review comment (performance):
Imo these should be `// FIXME: ..`s since the intention is to remove this condition once the caches support partial responses.

Code after:
    result |= static_cast<u64>(bytes[1]) << 48;
    result |= static_cast<u64>(bytes[2]) << 40;
    result |= static_cast<u64>(bytes[3]) << 32;
    result |= static_cast<u64>(bytes[4]) << 24;
    result |= static_cast<u64>(bytes[5]) << 16;
    result |= static_cast<u64>(bytes[6]) << 8;
    result |= static_cast<u64>(bytes[7]);

    return result;
}

LexicalPath path_for_cache_key(LexicalPath const& cache_directory, u64 cache_key)
{
    return cache_directory.append(MUST(String::formatted("{:016x}", cache_key)));
}

// https://httpwg.org/specs/rfc9111.html#response.cacheability
bool is_cacheable(StringView method, HTTP::HeaderList const& request_headers)
{
    // A cache MUST NOT store a response to a request unless:

    // * the request method is understood by the cache;
    if (!method.is_one_of("GET"sv, "HEAD"sv))
        return false;

    // FIXME: Neither the disk cache nor the memory cache handle partial responses yet. So we don't cache them for now.
    return !request_headers.contains("Range"sv);
}

// https://datatracker.ietf.org/doc/html/rfc9110#name-overview-of-status-codes
static bool is_heuristically_cacheable_status(u32 status_code)
{
    // Responses with status codes that are defined as heuristically cacheable
    // (e.g., 200, 203, 204, 206, 300, 301, 308, 404, 405, 410, 414, and 501)
    // can be reused by a cache with heuristic expiration [...]
    switch (status_code) {
    case 200:
    case 203:
    case 204:
    case 206:
    case 300:
    case 301:
    case 308:
    case 404:
    case 405:
    case 410:
    case 414:
    case 501:
        return true;
    default:
        return false;