Changeset 182271 in webkit


Ignore:
Timestamp:
Apr 2, 2015 8:45:58 AM (9 years ago)
Author:
Antti Koivisto
Message:

Use std::chrono types to represent time in response and cache classes
https://bugs.webkit.org/show_bug.cgi?id=143316

Reviewed by Andreas Kling.

Source/WebCore:

Use std::chrono::system_clock::time_point to represent clock times and std::chrono::microseconds to
represent durations. Also use WTF::Optional for optional values (instead of coding them as NaNs).

  • dom/Document.cpp:

(WebCore::Document::lastModified):

  • loader/cache/CachedResource.cpp:

(WebCore::CachedResource::CachedResource):
(WebCore::CachedResource::freshnessLifetime):
(WebCore::CachedResource::responseReceived):
(WebCore::CachedResource::updateResponseAfterRevalidation):

  • loader/cache/CachedResource.h:
  • platform/network/CacheValidation.cpp:

(WebCore::computeCurrentAge):
(WebCore::computeFreshnessLifetimeForHTTPFamily):
(WebCore::updateRedirectChainStatus):
(WebCore::redirectChainAllowsReuse):
(WebCore::parseCacheControlDirectives):

  • platform/network/CacheValidation.h:

(WebCore::RedirectChainCacheStatus::RedirectChainCacheStatus):

  • platform/network/HTTPParsers.cpp:

(WebCore::parseHTTPDate):
(WebCore::parseDate): Deleted.

  • platform/network/HTTPParsers.h:
  • platform/network/ResourceResponseBase.cpp:

(WebCore::ResourceResponseBase::ResourceResponseBase):
(WebCore::ResourceResponseBase::cacheControlMaxAge):
(WebCore::parseDateValueInHeader):
(WebCore::ResourceResponseBase::date):
(WebCore::ResourceResponseBase::age):
(WebCore::ResourceResponseBase::expires):
(WebCore::ResourceResponseBase::lastModified):

  • platform/network/ResourceResponseBase.h:

Source/WebKit2:

  • NetworkProcess/NetworkResourceLoader.cpp:

(WebKit::NetworkResourceLoader::didFinishLoading):

  • NetworkProcess/cache/NetworkCache.cpp:

(WebKit::NetworkCache::responseHasExpired):
(WebKit::NetworkCache::responseNeedsRevalidation):
(WebKit::NetworkCache::makeStoreDecision):
(WebKit::NetworkCache::Cache::store):

  • NetworkProcess/cache/NetworkCacheEntry.cpp:

(WebKit::NetworkCache::Entry::Entry):
(WebKit::NetworkCache::Entry::asJSON):

  • NetworkProcess/cache/NetworkCacheEntry.h:

(WebKit::NetworkCache::Entry::timeStamp):

  • NetworkProcess/cache/NetworkCacheStorage.cpp:

(WebKit::NetworkCache::decodeRecordMetaData):
(WebKit::NetworkCache::decodeRecord):

Sanity check the timestamp on decode.

(WebKit::NetworkCache::encodeRecordMetaData):
(WebKit::NetworkCache::encodeRecordHeader):
(WebKit::NetworkCache::Storage::traverse):

  • NetworkProcess/cache/NetworkCacheStorage.h:
  • WebProcess/Plugins/PluginView.cpp:

(WebKit::lastModifiedDateMS):
(WebKit::PluginView::Stream::didReceiveResponse):
(WebKit::PluginView::manualLoadDidReceiveResponse):
(WebKit::lastModifiedDate): Deleted.

Location:
trunk/Source
Files:
19 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r182270 r182271  
     12015-04-01  Antti Koivisto  <antti@apple.com>
     2
     3        Use std::chrono types to represent time in response and cache classes
     4        https://bugs.webkit.org/show_bug.cgi?id=143316
     5
     6        Reviewed by Andreas Kling.
     7
     8        Use std::chrono::system_clock::time_point to represent clock times and std::chrono::microseconds to
     9        represent durations. Also use WTF::Optional for optional values (instead of coding them as NaNs).
     10
     11        * dom/Document.cpp:
     12        (WebCore::Document::lastModified):
     13        * loader/cache/CachedResource.cpp:
     14        (WebCore::CachedResource::CachedResource):
     15        (WebCore::CachedResource::freshnessLifetime):
     16        (WebCore::CachedResource::responseReceived):
     17        (WebCore::CachedResource::updateResponseAfterRevalidation):
     18        * loader/cache/CachedResource.h:
     19        * platform/network/CacheValidation.cpp:
     20        (WebCore::computeCurrentAge):
     21        (WebCore::computeFreshnessLifetimeForHTTPFamily):
     22        (WebCore::updateRedirectChainStatus):
     23        (WebCore::redirectChainAllowsReuse):
     24        (WebCore::parseCacheControlDirectives):
     25        * platform/network/CacheValidation.h:
     26        (WebCore::RedirectChainCacheStatus::RedirectChainCacheStatus):
     27        * platform/network/HTTPParsers.cpp:
     28        (WebCore::parseHTTPDate):
     29        (WebCore::parseDate): Deleted.
     30        * platform/network/HTTPParsers.h:
     31        * platform/network/ResourceResponseBase.cpp:
     32        (WebCore::ResourceResponseBase::ResourceResponseBase):
     33        (WebCore::ResourceResponseBase::cacheControlMaxAge):
     34        (WebCore::parseDateValueInHeader):
     35        (WebCore::ResourceResponseBase::date):
     36        (WebCore::ResourceResponseBase::age):
     37        (WebCore::ResourceResponseBase::expires):
     38        (WebCore::ResourceResponseBase::lastModified):
     39        * platform/network/ResourceResponseBase.h:
     40
    1412015-04-02  Joonghun Park  <jh718.park@samsung.com>
    242
  • trunk/Source/WebCore/dom/Document.cpp

    r182242 r182271  
    41324132    bool foundDate = false;
    41334133    if (m_frame) {
    4134         String httpLastModified;
    4135         if (DocumentLoader* documentLoader = loader())
    4136             httpLastModified = documentLoader->response().httpHeaderField(HTTPHeaderName::LastModified);
    4137         if (!httpLastModified.isEmpty()) {
    4138             date.setMillisecondsSinceEpochForDateTime(parseDate(httpLastModified));
     4134        auto lastModifiedDate = loader() ? loader()->response().lastModified() : Nullopt;
     4135        if (lastModifiedDate) {
     4136            using namespace std::chrono;
     4137            date.setMillisecondsSinceEpochForDateTime(duration_cast<milliseconds>(lastModifiedDate.value().time_since_epoch()).count());
    41394138            foundDate = true;
    41404139        }
  • trunk/Source/WebCore/loader/cache/CachedResource.cpp

    r181766 r182271  
    117117    , m_sessionID(sessionID)
    118118    , m_loadPriority(defaultPriorityForResourceType(type))
    119     , m_responseTimestamp(currentTime())
     119    , m_responseTimestamp(std::chrono::system_clock::now())
    120120    , m_lastDecodedAccessTime(0)
    121121    , m_loadFinishTime(0)
     
    348348}
    349349
    350 double CachedResource::freshnessLifetime(const ResourceResponse& response) const
     350std::chrono::microseconds CachedResource::freshnessLifetime(const ResourceResponse& response) const
    351351{
    352352    if (!response.url().protocolIsInHTTPFamily()) {
     
    355355        // it caused performance and flakiness issues in our test infrastructure.
    356356        if (m_type == MainResource && !SchemeRegistry::shouldCacheResponsesFromURLSchemeIndefinitely(response.url().protocol()))
    357             return 0;
    358 
    359         return std::numeric_limits<double>::max();
     357            return std::chrono::microseconds::zero();
     358
     359        return std::chrono::microseconds::max();
    360360    }
    361361
     
    374374{
    375375    setResponse(response);
    376     m_responseTimestamp = currentTime();
     376    m_responseTimestamp = std::chrono::system_clock::now();
    377377    String encoding = response.textEncodingName();
    378378    if (!encoding.isNull())
     
    647647void CachedResource::updateResponseAfterRevalidation(const ResourceResponse& validatingResponse)
    648648{
    649     m_responseTimestamp = currentTime();
     649    m_responseTimestamp = std::chrono::system_clock::now();
    650650
    651651    updateResponseHeadersAfterRevalidation(m_response, validatingResponse);
  • trunk/Source/WebCore/loader/cache/CachedResource.h

    r181480 r182271  
    281281    virtual bool mayTryReplaceEncodedData() const { return false; }
    282282
    283     double freshnessLifetime(const ResourceResponse&) const;
     283    std::chrono::microseconds freshnessLifetime(const ResourceResponse&) const;
    284284
    285285    void addAdditionalRequestHeaders(CachedResourceLoader&);
     
    290290    String m_accept;
    291291    ResourceLoadPriority m_loadPriority;
    292     double m_responseTimestamp;
     292    std::chrono::system_clock::time_point m_responseTimestamp;
    293293
    294294    String m_fragmentIdentifierForRequest;
  • trunk/Source/WebCore/platform/network/CacheValidation.cpp

    r182157 r182271  
    9090}
    9191
    92 double computeCurrentAge(const ResourceResponse& response, double responseTimestamp)
    93 {
     92std::chrono::microseconds computeCurrentAge(const ResourceResponse& response, std::chrono::system_clock::time_point responseTimestamp)
     93{
     94    using namespace std::chrono;
     95
    9496    // RFC2616 13.2.3
    9597    // No compensation for latency as that is not terribly important in practice
    96     double dateValue = response.date();
    97     double apparentAge = std::isfinite(dateValue) ? std::max(0., responseTimestamp - dateValue) : 0;
    98     double ageValue = response.age();
    99     double correctedReceivedAge = std::isfinite(ageValue) ? std::max(apparentAge, ageValue) : apparentAge;
    100     double residentTime = currentTime() - responseTimestamp;
     98    auto dateValue = response.date();
     99    auto apparentAge = dateValue ? std::max(microseconds::zero(), duration_cast<microseconds>(responseTimestamp - dateValue.value())) : microseconds::zero();
     100    auto ageValue = response.age();
     101    auto correctedReceivedAge = ageValue ? std::max(apparentAge, ageValue.value()) : apparentAge;
     102    auto residentTime = duration_cast<microseconds>(system_clock::now() - responseTimestamp);
    101103    return correctedReceivedAge + residentTime;
    102104}
    103105
    104 double computeFreshnessLifetimeForHTTPFamily(const ResourceResponse& response, double responseTimestamp)
    105 {
     106std::chrono::microseconds computeFreshnessLifetimeForHTTPFamily(const ResourceResponse& response, std::chrono::system_clock::time_point responseTimestamp)
     107{
     108    using namespace std::chrono;
    106109    ASSERT(response.url().protocolIsInHTTPFamily());
     110
    107111    // RFC2616 13.2.4
    108     double maxAgeValue = response.cacheControlMaxAge();
    109     if (std::isfinite(maxAgeValue))
    110         return maxAgeValue;
    111     double expiresValue = response.expires();
    112     double dateValue = response.date();
    113     double creationTime = std::isfinite(dateValue) ? dateValue : responseTimestamp;
    114     if (std::isfinite(expiresValue))
    115         return expiresValue - creationTime;
    116     double lastModifiedValue = response.lastModified();
    117     if (std::isfinite(lastModifiedValue))
    118         return (creationTime - lastModifiedValue) * 0.1;
     112    auto maxAge = response.cacheControlMaxAge();
     113    if (maxAge)
     114        return maxAge.value();
     115    auto expires = response.expires();
     116    auto date = response.date();
     117    auto creationTime = date ? date.value() : responseTimestamp;
     118    if (expires)
     119        return duration_cast<microseconds>(expires.value() - creationTime);
     120    auto lastModified = response.lastModified();
     121    if (lastModified)
     122        return duration_cast<microseconds>((creationTime - lastModified.value()) * 0.1);
    119123    // If no cache headers are present, the specification leaves the decision to the UA. Other browsers seem to opt for 0.
    120     return 0;
     124    return microseconds::zero();
    121125}
    122126
    123127void updateRedirectChainStatus(RedirectChainCacheStatus& redirectChainCacheStatus, const ResourceResponse& response)
    124128{
     129    using namespace std::chrono;
     130
    125131    if (redirectChainCacheStatus.status == RedirectChainCacheStatus::NotCachedRedirection)
    126132        return;
     
    129135        return;
    130136    }
     137
    131138    redirectChainCacheStatus.status = RedirectChainCacheStatus::CachedRedirection;
    132     double responseTimestamp = currentTime();
     139    auto responseTimestamp = system_clock::now();
    133140    // Store the nearest end of cache validity date
    134     double endOfValidity = responseTimestamp + computeFreshnessLifetimeForHTTPFamily(response, responseTimestamp) - computeCurrentAge(response, responseTimestamp);
     141    auto endOfValidity = responseTimestamp + computeFreshnessLifetimeForHTTPFamily(response, responseTimestamp) - computeCurrentAge(response, responseTimestamp);
    135142    redirectChainCacheStatus.endOfValidity = std::min(redirectChainCacheStatus.endOfValidity, endOfValidity);
    136143}
     
    144151        return false;
    145152    case RedirectChainCacheStatus::CachedRedirection:
    146         return reuseExpiredRedirection || currentTime() <= redirectChainCacheStatus.endOfValidity;
     153        return reuseExpiredRedirection || std::chrono::system_clock::now() <= redirectChainCacheStatus.endOfValidity;
    147154    }
    148155    ASSERT_NOT_REACHED();
     
    249256CacheControlDirectives parseCacheControlDirectives(const HTTPHeaderMap& headers)
    250257{
     258    using namespace std::chrono;
     259
    251260    CacheControlDirectives result;
    252261
     
    266275                result.mustRevalidate = true;
    267276            else if (equalIgnoringCase(directives[i].first, "max-age")) {
    268                 if (!std::isnan(result.maxAge)) {
     277                if (result.maxAge) {
    269278                    // First max-age directive wins if there are multiple ones.
    270279                    continue;
     
    273282                double maxAge = directives[i].second.toDouble(&ok);
    274283                if (ok)
    275                     result.maxAge = maxAge;
     284                    result.maxAge = duration_cast<microseconds>(duration<double>(maxAge));
    276285            } else if (equalIgnoringCase(directives[i].first, "max-stale")) {
    277286                // https://tools.ietf.org/html/rfc7234#section-5.2.1.2
    278                 if (!std::isnan(result.maxStale)) {
     287                if (result.maxStale) {
    279288                    // First max-stale directive wins if there are multiple ones.
    280289                    continue;
     
    282291                if (directives[i].second.isEmpty()) {
    283292                    // if no value is assigned to max-stale, then the client is willing to accept a stale response of any age.
    284                     result.maxStale = std::numeric_limits<double>::max();
     293                    result.maxStale = microseconds::max();
    285294                    continue;
    286295                }
     
    288297                double maxStale = directives[i].second.toDouble(&ok);
    289298                if (ok)
    290                     result.maxStale = maxStale;
     299                    result.maxStale = duration_cast<microseconds>(duration<double>(maxStale));
    291300            }
    292301        }
  • trunk/Source/WebCore/platform/network/CacheValidation.h

    r182145 r182271  
    2727#define CacheValidation_h
    2828
     29#include <wtf/Optional.h>
     30
    2931namespace WebCore {
    3032
     
    4042    RedirectChainCacheStatus()
    4143        : status(NoRedirection)
    42         , endOfValidity(std::numeric_limits<double>::max())
     44        , endOfValidity(std::chrono::system_clock::time_point::max())
    4345    { }
    4446    Status status;
    45     double endOfValidity;
     47    std::chrono::system_clock::time_point endOfValidity;
    4648};
    4749
    48 WEBCORE_EXPORT double computeCurrentAge(const ResourceResponse&, double responseTimestamp);
    49 WEBCORE_EXPORT double computeFreshnessLifetimeForHTTPFamily(const ResourceResponse&, double responseTimestamp);
     50WEBCORE_EXPORT std::chrono::microseconds computeCurrentAge(const ResourceResponse&, std::chrono::system_clock::time_point responseTimestamp);
     51WEBCORE_EXPORT std::chrono::microseconds computeFreshnessLifetimeForHTTPFamily(const ResourceResponse&, std::chrono::system_clock::time_point responseTimestamp);
    5052WEBCORE_EXPORT void updateResponseHeadersAfterRevalidation(ResourceResponse&, const ResourceResponse& validatingResponse);
    5153WEBCORE_EXPORT void updateRedirectChainStatus(RedirectChainCacheStatus&, const ResourceResponse&);
     
    5557
    5658struct CacheControlDirectives {
    57     double maxAge { std::numeric_limits<double>::quiet_NaN() };
    58     double maxStale { std::numeric_limits<double>::quiet_NaN() };
     59    Optional<std::chrono::microseconds> maxAge;
     60    Optional<std::chrono::microseconds> maxStale;
    5961    bool noCache { false };
    6062    bool noStore { false };
  • trunk/Source/WebCore/platform/network/HTTPParsers.cpp

    r174920 r182271  
    235235}
    236236
    237 double parseDate(const String& value)
    238 {
    239     return parseDateFromNullTerminatedCharacters(value.utf8().data());
     237Optional<std::chrono::system_clock::time_point> parseHTTPDate(const String& value)
     238{
     239    double dateInMillisecondsSinceEpoch = parseDateFromNullTerminatedCharacters(value.utf8().data());
     240    if (!std::isfinite(dateInMillisecondsSinceEpoch))
     241        return { };
     242    // This assumes system_clock epoch equals Unix epoch which is true for all implementations but unspecified.
     243    // FIXME: The parsing function should be switched to std::chrono too.
     244    return std::chrono::system_clock::time_point(std::chrono::milliseconds(static_cast<long long>(dateInMillisecondsSinceEpoch)));
    240245}
    241246
  • trunk/Source/WebCore/platform/network/HTTPParsers.h

    r170029 r182271  
    3434#include "ContentSecurityPolicy.h"
    3535#include <wtf/Forward.h>
     36#include <wtf/Optional.h>
    3637#include <wtf/Vector.h>
    3738
     
    6566bool isValidHTTPToken(const String&);
    6667bool parseHTTPRefresh(const String& refresh, bool fromHttpEquivMeta, double& delay, String& url);
    67 double parseDate(const String&);
     68Optional<std::chrono::system_clock::time_point> parseHTTPDate(const String&);
    6869String filenameFromHTTPContentDisposition(const String&);
    6970String extractMIMETypeFromMediaType(const String&);
  • trunk/Source/WebCore/platform/network/ResourceResponseBase.cpp

    r182059 r182271  
    4444}
    4545
    46 ResourceResponseBase::ResourceResponseBase() 
    47     : m_expectedContentLength(0)
     46ResourceResponseBase::ResourceResponseBase()
     47    : m_isNull(true)
     48    , m_expectedContentLength(0)
    4849    , m_includesCertificateInfo(false)
    4950    , m_httpStatusCode(0)
    50     , m_age(0)
    51     , m_date(0)
    52     , m_expires(0)
    53     , m_lastModified(0)
    54     , m_isNull(true)
    55     , m_haveParsedCacheControlHeader(false)
    56     , m_haveParsedAgeHeader(false)
    57     , m_haveParsedDateHeader(false)
    58     , m_haveParsedExpiresHeader(false)
    59     , m_haveParsedLastModifiedHeader(false)
    60     , m_source(Source::Unknown)
    6151{
    6252}
    6353
    6454ResourceResponseBase::ResourceResponseBase(const URL& url, const String& mimeType, long long expectedLength, const String& textEncodingName)
    65     : m_url(url)
     55    : m_isNull(false)
     56    , m_url(url)
    6657    , m_mimeType(mimeType)
    6758    , m_expectedContentLength(expectedLength)
     
    6960    , m_includesCertificateInfo(true) // Empty but valid for synthetic responses.
    7061    , m_httpStatusCode(0)
    71     , m_age(0)
    72     , m_date(0)
    73     , m_expires(0)
    74     , m_lastModified(0)
    75     , m_isNull(false)
    76     , m_haveParsedCacheControlHeader(false)
    77     , m_haveParsedAgeHeader(false)
    78     , m_haveParsedDateHeader(false)
    79     , m_haveParsedExpiresHeader(false)
    80     , m_haveParsedLastModifiedHeader(false)
    81     , m_source(Source::Unknown)
    8262{
    8363}
     
    382362}
    383363
    384 double ResourceResponseBase::cacheControlMaxAge() const
     364Optional<std::chrono::microseconds> ResourceResponseBase::cacheControlMaxAge() const
    385365{
    386366    if (!m_haveParsedCacheControlHeader)
     
    389369}
    390370
    391 static double parseDateValueInHeader(const HTTPHeaderMap& headers, HTTPHeaderName headerName)
     371static Optional<std::chrono::system_clock::time_point> parseDateValueInHeader(const HTTPHeaderMap& headers, HTTPHeaderName headerName)
    392372{
    393373    String headerValue = headers.get(headerName);
    394374    if (headerValue.isEmpty())
    395         return std::numeric_limits<double>::quiet_NaN();
     375        return { };
    396376    // This handles all date formats required by RFC2616:
    397377    // Sun, 06 Nov 1994 08:49:37 GMT  ; RFC 822, updated by RFC 1123
    398378    // Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036
    399379    // Sun Nov  6 08:49:37 1994       ; ANSI C's asctime() format
    400     double dateInMilliseconds = parseDate(headerValue);
    401     if (!std::isfinite(dateInMilliseconds))
    402         return std::numeric_limits<double>::quiet_NaN();
    403     return dateInMilliseconds / 1000;
    404 }
    405 
    406 double ResourceResponseBase::date() const
     380    return parseHTTPDate(headerValue);
     381}
     382
     383Optional<std::chrono::system_clock::time_point> ResourceResponseBase::date() const
    407384{
    408385    lazyInit(CommonFieldsOnly);
     
    415392}
    416393
    417 double ResourceResponseBase::age() const
    418 {
     394Optional<std::chrono::microseconds> ResourceResponseBase::age() const
     395{
     396    using namespace std::chrono;
     397
    419398    lazyInit(CommonFieldsOnly);
    420399
     
    422401        String headerValue = m_httpHeaderFields.get(HTTPHeaderName::Age);
    423402        bool ok;
    424         m_age = headerValue.toDouble(&ok);
    425         if (!ok)
    426             m_age = std::numeric_limits<double>::quiet_NaN();
     403        double ageDouble = headerValue.toDouble(&ok);
     404        if (ok)
     405            m_age = duration_cast<microseconds>(duration<double>(ageDouble));
    427406        m_haveParsedAgeHeader = true;
    428407    }
     
    430409}
    431410
    432 double ResourceResponseBase::expires() const
     411Optional<std::chrono::system_clock::time_point> ResourceResponseBase::expires() const
    433412{
    434413    lazyInit(CommonFieldsOnly);
     
    441420}
    442421
    443 double ResourceResponseBase::lastModified() const
     422Optional<std::chrono::system_clock::time_point> ResourceResponseBase::lastModified() const
    444423{
    445424    lazyInit(CommonFieldsOnly);
  • trunk/Source/WebCore/platform/network/ResourceResponseBase.h

    r182071 r182271  
    105105    WEBCORE_EXPORT bool cacheControlContainsMustRevalidate() const;
    106106    WEBCORE_EXPORT bool hasCacheValidatorFields() const;
    107     WEBCORE_EXPORT double cacheControlMaxAge() const;
    108     double date() const;
    109     double age() const;
    110     WEBCORE_EXPORT double expires() const;
    111     WEBCORE_EXPORT double lastModified() const;
     107    WEBCORE_EXPORT Optional<std::chrono::microseconds> cacheControlMaxAge() const;
     108    WEBCORE_EXPORT Optional<std::chrono::system_clock::time_point> date() const;
     109    WEBCORE_EXPORT Optional<std::chrono::microseconds> age() const;
     110    WEBCORE_EXPORT Optional<std::chrono::system_clock::time_point> expires() const;
     111    WEBCORE_EXPORT Optional<std::chrono::system_clock::time_point> lastModified() const;
    112112
    113113    enum class Source { Unknown, Network, DiskCache, DiskCacheAfterValidation };
     
    148148    static bool platformCompare(const ResourceResponse&, const ResourceResponse&) { return true; }
    149149
     150private:
     151    const ResourceResponse& asResourceResponse() const;
     152    void parseCacheControlDirectives() const;
     153    void updateHeaderParsedState(HTTPHeaderName);
     154
     155protected:
     156    bool m_isNull;
    150157    URL m_url;
    151158    AtomicString m_mimeType;
     
    162169
    163170private:
    164     mutable double m_age;
    165     mutable double m_date;
    166     mutable double m_expires;
    167     mutable double m_lastModified;
     171    mutable Optional<std::chrono::microseconds> m_age;
     172    mutable Optional<std::chrono::system_clock::time_point> m_date;
     173    mutable Optional<std::chrono::system_clock::time_point> m_expires;
     174    mutable Optional<std::chrono::system_clock::time_point> m_lastModified;
    168175    mutable CacheControlDirectives m_cacheControlDirectives;
    169176
    170 public:
    171     bool m_isNull : 1;
    172    
    173 private:
    174     const ResourceResponse& asResourceResponse() const;
    175     void parseCacheControlDirectives() const;
    176     void updateHeaderParsedState(HTTPHeaderName);
    177 
    178     mutable bool m_haveParsedCacheControlHeader : 1;
    179     mutable bool m_haveParsedAgeHeader : 1;
    180     mutable bool m_haveParsedDateHeader : 1;
    181     mutable bool m_haveParsedExpiresHeader : 1;
    182     mutable bool m_haveParsedLastModifiedHeader : 1;
    183 
    184     Source m_source;
     177    mutable bool m_haveParsedCacheControlHeader { false };
     178    mutable bool m_haveParsedAgeHeader { false };
     179    mutable bool m_haveParsedDateHeader { false };
     180    mutable bool m_haveParsedExpiresHeader { false };
     181    mutable bool m_haveParsedLastModifiedHeader { false };
     182
     183    Source m_source { Source::Unknown };
    185184};
    186185
  • trunk/Source/WebKit/win/Plugins/PluginStream.cpp

    r178219 r182271  
    124124}
    125125
    126 static uint32_t lastModifiedDate(const ResourceResponse& response)
    127 {
    128     double lastModified = response.lastModified();
    129     if (!std::isfinite(lastModified))
     126static uint32_t lastModifiedDateMS(const ResourceResponse& response)
     127{
     128    auto lastModified = response.lastModified();
     129    if (!lastModified)
    130130        return 0;
    131131
    132     return lastModified * 1000;
     132    return std::chrono::duration_cast<std::chrono::milliseconds>(lastModified.value().time_since_epoch()).count();
    133133}
    134134
     
    179179    m_stream.ndata = this;
    180180    m_stream.end = max(expectedContentLength, 0LL);
    181     m_stream.lastmodified = lastModifiedDate(m_resourceResponse);
     181    m_stream.lastmodified = lastModifiedDateMS(m_resourceResponse);
    182182    m_stream.notifyData = m_notifyData;
    183183
  • trunk/Source/WebKit2/ChangeLog

    r182267 r182271  
     12015-04-01  Antti Koivisto  <antti@apple.com>
     2
     3        Use std::chrono types to represent time in response and cache classes
     4        https://bugs.webkit.org/show_bug.cgi?id=143316
     5
     6        Reviewed by Andreas Kling.
     7
     8        * NetworkProcess/NetworkResourceLoader.cpp:
     9        (WebKit::NetworkResourceLoader::didFinishLoading):
     10        * NetworkProcess/cache/NetworkCache.cpp:
     11        (WebKit::NetworkCache::responseHasExpired):
     12        (WebKit::NetworkCache::responseNeedsRevalidation):
     13        (WebKit::NetworkCache::makeStoreDecision):
     14        (WebKit::NetworkCache::Cache::store):
     15        * NetworkProcess/cache/NetworkCacheEntry.cpp:
     16        (WebKit::NetworkCache::Entry::Entry):
     17        (WebKit::NetworkCache::Entry::asJSON):
     18        * NetworkProcess/cache/NetworkCacheEntry.h:
     19        (WebKit::NetworkCache::Entry::timeStamp):
     20        * NetworkProcess/cache/NetworkCacheStorage.cpp:
     21        (WebKit::NetworkCache::decodeRecordMetaData):
     22        (WebKit::NetworkCache::decodeRecord):
     23
     24            Sanity check the timestamp on decode.
     25
     26        (WebKit::NetworkCache::encodeRecordMetaData):
     27        (WebKit::NetworkCache::encodeRecordHeader):
     28        (WebKit::NetworkCache::Storage::traverse):
     29        * NetworkProcess/cache/NetworkCacheStorage.h:
     30        * WebProcess/Plugins/PluginView.cpp:
     31        (WebKit::lastModifiedDateMS):
     32        (WebKit::PluginView::Stream::didReceiveResponse):
     33        (WebKit::PluginView::manualLoadDidReceiveResponse):
     34        (WebKit::lastModifiedDate): Deleted.
     35
    1362015-04-01  Chris Dumez  <cdumez@apple.com>
    237
  • trunk/Source/WebKit2/NetworkProcess/NetworkResourceLoader.cpp

    r182020 r182271  
    319319        bool hasCacheableRedirect = m_response.isHTTP() && WebCore::redirectChainAllowsReuse(m_redirectChainCacheStatus, allowStale ? WebCore::ReuseExpiredRedirection : WebCore::DoNotReuseExpiredRedirection);
    320320        if (hasCacheableRedirect && m_redirectChainCacheStatus.status == RedirectChainCacheStatus::CachedRedirection) {
    321             // FIXME: Cache the actual redirects instead of the end result.
    322             double now = currentTime();
    323             double responseEndOfValidity = now + WebCore::computeFreshnessLifetimeForHTTPFamily(m_response, now) - WebCore::computeCurrentAge(m_response, now);
     321            // Maybe we should cache the actual redirects instead of the end result?
     322            auto now = std::chrono::system_clock::now();
     323            auto responseEndOfValidity = now + WebCore::computeFreshnessLifetimeForHTTPFamily(m_response, now) - WebCore::computeCurrentAge(m_response, now);
    324324            hasCacheableRedirect = responseEndOfValidity <= m_redirectChainCacheStatus.endOfValidity;
    325325        }
  • trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.cpp

    r182154 r182271  
    151151}
    152152
    153 static bool responseHasExpired(const WebCore::ResourceResponse& response, std::chrono::milliseconds timestamp, double maxStale)
     153static bool responseHasExpired(const WebCore::ResourceResponse& response, std::chrono::system_clock::time_point timestamp, Optional<std::chrono::microseconds> maxStale)
    154154{
    155155    if (response.cacheControlContainsNoCache())
    156156        return true;
    157157
    158     auto doubleTimeStamp = std::chrono::duration<double>(timestamp);
    159     double age = WebCore::computeCurrentAge(response, doubleTimeStamp.count());
    160     double lifetime = WebCore::computeFreshnessLifetimeForHTTPFamily(response, doubleTimeStamp.count());
    161 
    162     maxStale = std::isnan(maxStale) ? 0 : maxStale;
    163     bool hasExpired = age - lifetime > maxStale;
     158    auto age = WebCore::computeCurrentAge(response, timestamp);
     159    auto lifetime = WebCore::computeFreshnessLifetimeForHTTPFamily(response, timestamp);
     160
     161    auto maximumStaleness = maxStale ? maxStale.value() : 0_ms;
     162    bool hasExpired = age - lifetime > maximumStaleness;
    164163
    165164#ifndef LOG_DISABLED
     
    171170}
    172171
    173 static bool responseNeedsRevalidation(const WebCore::ResourceResponse& response, const WebCore::ResourceRequest& request, std::chrono::milliseconds timestamp)
     172static bool responseNeedsRevalidation(const WebCore::ResourceResponse& response, const WebCore::ResourceRequest& request, std::chrono::system_clock::time_point timestamp)
    174173{
    175174    auto requestDirectives = WebCore::parseCacheControlDirectives(request.httpHeaderFields());
     
    177176        return true;
    178177    // For requests we ignore max-age values other than zero.
    179     if (requestDirectives.maxAge == 0)
     178    if (requestDirectives.maxAge && requestDirectives.maxAge.value() == 0_ms)
    180179        return true;
    181180
     
    270269    if (!isStatusCodeCacheableByDefault(response.httpStatusCode())) {
    271270        // http://tools.ietf.org/html/rfc7234#section-4.3.2
    272         bool hasExpirationHeaders = std::isfinite(response.expires()) || std::isfinite(response.cacheControlMaxAge());
     271        bool hasExpirationHeaders = response.expires() || response.cacheControlMaxAge();
    273272        bool expirationHeadersAllowCaching = isStatusCodePotentiallyCacheable(response.httpStatusCode()) && hasExpirationHeaders;
    274273        if (!expirationHeadersAllowCaching)
     
    279278    bool storeUnconditionallyForHistoryNavigation = originalRequest.priority() == WebCore::ResourceLoadPriorityVeryHigh;
    280279    if (!storeUnconditionallyForHistoryNavigation) {
    281         auto currentTime = std::chrono::duration<double>(std::chrono::system_clock::now().time_since_epoch());
    282         bool hasNonZeroLifetime = !response.cacheControlContainsNoCache() && WebCore::computeFreshnessLifetimeForHTTPFamily(response, currentTime.count()) > 0;
     280        auto now = std::chrono::system_clock::now();
     281        bool hasNonZeroLifetime = !response.cacheControlContainsNoCache() && WebCore::computeFreshnessLifetimeForHTTPFamily(response, now) > 0_ms;
    283282
    284283        bool possiblyReusable = response.hasCacheValidatorFields() || hasNonZeroLifetime;
     
    359358
    360359    StoreDecision storeDecision = makeStoreDecision(originalRequest, response);
    361 
    362360    if (storeDecision != StoreDecision::Yes) {
    363361        LOG(NetworkCache, "(NetworkProcess) didn't store, storeDecision=%d", storeDecision);
  • trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheEntry.cpp

    r182136 r182271  
    4343Entry::Entry(const Key& key, const WebCore::ResourceResponse& response, RefPtr<WebCore::SharedBuffer>&& buffer, const Vector<std::pair<String, String>>& varyingRequestHeaders)
    4444    : m_key(key)
    45     , m_timeStamp(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()))
     45    , m_timeStamp(std::chrono::system_clock::now())
    4646    , m_response(response)
    4747    , m_varyingRequestHeaders(varyingRequestHeaders)
     
    161161    json.appendLiteral(",\n");
    162162    json.appendLiteral("\"timestamp\": ");
    163     json.appendNumber(m_timeStamp.count());
     163    json.appendNumber(std::chrono::duration_cast<std::chrono::milliseconds>(m_timeStamp.time_since_epoch()).count());
    164164    json.appendLiteral(",\n");
    165165    json.appendLiteral("\"URL\": ");
  • trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheEntry.h

    r182136 r182271  
    5252
    5353    const Key& key() const { return m_key; }
    54     std::chrono::milliseconds timeStamp() const { return m_timeStamp; }
     54    std::chrono::system_clock::time_point timeStamp() const { return m_timeStamp; }
    5555    const WebCore::ResourceResponse& response() const { return m_response; }
    5656    const Vector<std::pair<String, String>>& varyingRequestHeaders() const { return m_varyingRequestHeaders; }
     
    7373
    7474    Key m_key;
    75     std::chrono::milliseconds m_timeStamp;
     75    std::chrono::system_clock::time_point m_timeStamp;
    7676    WebCore::ResourceResponse m_response;
    7777    Vector<std::pair<String, String>> m_varyingRequestHeaders;
  • trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorage.cpp

    r182153 r182271  
    143143    unsigned cacheStorageVersion;
    144144    Key key;
    145     std::chrono::milliseconds timeStamp;
     145    // FIXME: Add encoder/decoder for time_point.
     146    std::chrono::milliseconds epochRelativeTimeStamp;
    146147    unsigned headerChecksum;
    147148    uint64_t headerOffset;
     
    161162        if (!decoder.decode(metaData.key))
    162163            return false;
    163         if (!decoder.decode(metaData.timeStamp))
     164        if (!decoder.decode(metaData.epochRelativeTimeStamp))
    164165            return false;
    165166        if (!decoder.decode(metaData.headerChecksum))
     
    216217        return nullptr;
    217218
     219    // Sanity check against time stamps in future.
     220    auto timeStamp = std::chrono::system_clock::time_point(metaData.epochRelativeTimeStamp);
     221    if (timeStamp > std::chrono::system_clock::now())
     222        return nullptr;
     223
    218224    Data bodyData;
    219225    if (metaData.bodySize) {
     
    235241    return std::make_unique<Storage::Record>(Storage::Record {
    236242        metaData.key,
    237         metaData.timeStamp,
     243        timeStamp,
    238244        headerData,
    239245        bodyData
     
    247253    encoder << metaData.cacheStorageVersion;
    248254    encoder << metaData.key;
    249     encoder << metaData.timeStamp;
     255    encoder << metaData.epochRelativeTimeStamp;
    250256    encoder << metaData.headerChecksum;
    251257    encoder << metaData.headerSize;
     
    261267{
    262268    RecordMetaData metaData(record.key);
    263     metaData.timeStamp = record.timeStamp;
     269    metaData.epochRelativeTimeStamp = std::chrono::duration_cast<std::chrono::milliseconds>(record.timeStamp.time_since_epoch());
    264270    metaData.headerChecksum = hashData(record.header);
    265271    metaData.headerSize = record.header.size();
     
    447453                Data headerData;
    448454                if (decodeRecordHeader(fileData, metaData, headerData)) {
    449                     Record record { metaData.key, metaData.timeStamp, headerData, { } };
     455                    Record record { metaData.key, std::chrono::system_clock::time_point(metaData.epochRelativeTimeStamp), headerData, { } };
    450456                    info.bodySize = metaData.bodySize;
    451457                    traverseHandler(&record, info);
     
    600606
    601607    // For sanity.
    602     if (age <= seconds::zero() || accessAge < seconds::zero() || accessAge > age)
     608    if (age <= 0_s || accessAge < 0_s || accessAge > age)
    603609        return 0;
    604610
  • trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorage.h

    r182136 r182271  
    5050    struct Record {
    5151        Key key;
    52         std::chrono::milliseconds timeStamp;
     52        std::chrono::system_clock::time_point timeStamp;
    5353        Data header;
    5454        Data body;
  • trunk/Source/WebKit2/WebProcess/Plugins/PluginView.cpp

    r181599 r182271  
    202202}
    203203
    204 static uint32_t lastModifiedDate(const ResourceResponse& response)
    205 {
    206     double lastModified = response.lastModified();
    207     if (!std::isfinite(lastModified))
     204static uint32_t lastModifiedDateMS(const ResourceResponse& response)
     205{
     206    auto lastModified = response.lastModified();
     207    if (!lastModified)
    208208        return 0;
    209209
    210     return lastModified * 1000;
     210    return std::chrono::duration_cast<std::chrono::milliseconds>(lastModified.value().time_since_epoch()).count();
    211211}
    212212
     
    224224        streamLength = expectedContentLength;
    225225
    226     m_pluginView->m_plugin->streamDidReceiveResponse(m_streamID, responseURL, streamLength, lastModifiedDate(response), mimeType, headers, response.suggestedFilename());
     226    m_pluginView->m_plugin->streamDidReceiveResponse(m_streamID, responseURL, streamLength, lastModifiedDateMS(response), mimeType, headers, response.suggestedFilename());
    227227}
    228228
     
    414414        streamLength = expectedContentLength;
    415415
    416     m_plugin->manualStreamDidReceiveResponse(responseURL, streamLength, lastModifiedDate(response), mimeType, headers, response.suggestedFilename());
     416    m_plugin->manualStreamDidReceiveResponse(responseURL, streamLength, lastModifiedDateMS(response), mimeType, headers, response.suggestedFilename());
    417417}
    418418
Note: See TracChangeset for help on using the changeset viewer.