static bool canUseResponse(ResourceResponse& response, double responseTimestamp)
{
    if (response.isNull())
        return false;

    // FIXME: Why isn't must-revalidate considered a reason we can't use the response?
    if (response.cacheControlContainsNoCache() || response.cacheControlContainsNoStore())
        return false;

    if (response.httpStatusCode() == 303)  {
        // Must not be cached.
        return false;
    }

    if (response.httpStatusCode() == 302 || response.httpStatusCode() == 307) {
        // Default to not cacheable unless explicitly allowed.
        bool hasMaxAge = std::isfinite(response.cacheControlMaxAge());
        bool hasExpires = std::isfinite(response.expires());
        // TODO: consider catching Cache-Control "private" and "public" here.
        if (!hasMaxAge && !hasExpires)
            return false;
    }

    return currentAge(response, responseTimestamp) <= freshnessLifetime(response, responseTimestamp);
}
Example #2
0
static bool canUseResponse(ResourceResponse& response, double responseTimestamp)
{
    if (response.isNull())
        return false;

    // FIXME: Why isn't must-revalidate considered a reason we can't use the response?
    if (response.cacheControlContainsNoCache() || response.cacheControlContainsNoStore())
        return false;

    if (response.httpStatusCode() == 303)  {
        // Must not be cached.
        return false;
    }

    if (response.httpStatusCode() == 302 || response.httpStatusCode() == 307) {
        // Default to not cacheable.
        // FIXME: Consider allowing these to be cached if they have headers permitting caching.
        return false;
    }

    return currentAge(response, responseTimestamp) <= freshnessLifetime(response, responseTimestamp);
}
Example #3
0
bool CurlCacheEntry::parseResponseHeaders(ResourceResponse& response)
{
    double fileTime;
    time_t fileModificationDate;

    if (getFileModificationTime(m_headerFilename, fileModificationDate)) {
        fileTime = difftime(fileModificationDate, 0);
        fileTime *= 1000.0;
    } else
        fileTime = currentTimeMS(); // GMT

    if (response.cacheControlContainsNoCache() || response.cacheControlContainsNoStore())
        return false;


    double maxAge = 0;
    bool maxAgeIsValid = false;

    if (response.cacheControlContainsMustRevalidate())
        maxAge = 0;
    else {
        maxAge = response.cacheControlMaxAge();
        if (std::isnan(maxAge))
            maxAge = 0;
        else
            maxAgeIsValid = true;
    }

    if (!response.hasCacheValidatorFields())
        return false;


    double lastModificationDate = 0;
    double responseDate = 0;
    double expirationDate = 0;

    lastModificationDate = response.lastModified();
    if (std::isnan(lastModificationDate))
        lastModificationDate = 0;

    responseDate = response.date();
    if (std::isnan(responseDate))
        responseDate = 0;

    expirationDate = response.expires();
    if (std::isnan(expirationDate))
        expirationDate = 0;


    if (maxAgeIsValid) {
        // when both the cache entry and the response contain max-age, the lesser one takes priority
        double expires = fileTime + maxAge * 1000;
        if (m_expireDate == -1 || m_expireDate > expires)
            m_expireDate = expires;
    } else if (responseDate > 0 && expirationDate >= responseDate)
        m_expireDate = fileTime + (expirationDate - responseDate);

    // if there were no lifetime information
    if (m_expireDate == -1) {
        if (lastModificationDate > 0)
            m_expireDate = fileTime + (fileTime - lastModificationDate) * 0.1;
        else
            m_expireDate = 0;
    }

    String etag = response.httpHeaderField("ETag");
    if (!etag.isNull())
        m_requestHeaders.set("If-None-Match", etag);

    String lastModified = response.httpHeaderField("Last-Modified");
    if (!lastModified.isNull())
        m_requestHeaders.set("If-Modified-Since", lastModified);

    if (etag.isNull() && lastModified.isNull())
        return false;

    m_headerInMemory = true;
    return true;
}