Diff
Modified: trunk/Source/WebCore/ChangeLog (182270 => 182271)
--- trunk/Source/WebCore/ChangeLog 2015-04-02 08:51:23 UTC (rev 182270)
+++ trunk/Source/WebCore/ChangeLog 2015-04-02 15:45:58 UTC (rev 182271)
@@ -1,3 +1,43 @@
+2015-04-01 Antti Koivisto <an...@apple.com>
+
+ 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.
+
+ 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:
+
2015-04-02 Joonghun Park <jh718.p...@samsung.com>
[CSS MultiColumn] Parse "columns: auto <length>" shorthand property value properly
Modified: trunk/Source/WebCore/dom/Document.cpp (182270 => 182271)
--- trunk/Source/WebCore/dom/Document.cpp 2015-04-02 08:51:23 UTC (rev 182270)
+++ trunk/Source/WebCore/dom/Document.cpp 2015-04-02 15:45:58 UTC (rev 182271)
@@ -4131,11 +4131,10 @@
DateComponents date;
bool foundDate = false;
if (m_frame) {
- String httpLastModified;
- if (DocumentLoader* documentLoader = loader())
- httpLastModified = documentLoader->response().httpHeaderField(HTTPHeaderName::LastModified);
- if (!httpLastModified.isEmpty()) {
- date.setMillisecondsSinceEpochForDateTime(parseDate(httpLastModified));
+ auto lastModifiedDate = loader() ? loader()->response().lastModified() : Nullopt;
+ if (lastModifiedDate) {
+ using namespace std::chrono;
+ date.setMillisecondsSinceEpochForDateTime(duration_cast<milliseconds>(lastModifiedDate.value().time_since_epoch()).count());
foundDate = true;
}
}
Modified: trunk/Source/WebCore/loader/cache/CachedResource.cpp (182270 => 182271)
--- trunk/Source/WebCore/loader/cache/CachedResource.cpp 2015-04-02 08:51:23 UTC (rev 182270)
+++ trunk/Source/WebCore/loader/cache/CachedResource.cpp 2015-04-02 15:45:58 UTC (rev 182271)
@@ -116,7 +116,7 @@
, m_decodedDataDeletionTimer(*this, &CachedResource::decodedDataDeletionTimerFired, deadDecodedDataDeletionIntervalForResourceType(type))
, m_sessionID(sessionID)
, m_loadPriority(defaultPriorityForResourceType(type))
- , m_responseTimestamp(currentTime())
+ , m_responseTimestamp(std::chrono::system_clock::now())
, m_lastDecodedAccessTime(0)
, m_loadFinishTime(0)
, m_encodedSize(0)
@@ -347,16 +347,16 @@
return computeCurrentAge(m_response, m_responseTimestamp) > freshnessLifetime(m_response);
}
-double CachedResource::freshnessLifetime(const ResourceResponse& response) const
+std::chrono::microseconds CachedResource::freshnessLifetime(const ResourceResponse& response) const
{
if (!response.url().protocolIsInHTTPFamily()) {
// Don't cache non-HTTP main resources since we can't check for freshness.
// FIXME: We should not cache subresources either, but when we tried this
// it caused performance and flakiness issues in our test infrastructure.
if (m_type == MainResource && !SchemeRegistry::shouldCacheResponsesFromURLSchemeIndefinitely(response.url().protocol()))
- return 0;
+ return std::chrono::microseconds::zero();
- return std::numeric_limits<double>::max();
+ return std::chrono::microseconds::max();
}
return computeFreshnessLifetimeForHTTPFamily(response, m_responseTimestamp);
@@ -373,7 +373,7 @@
void CachedResource::responseReceived(const ResourceResponse& response)
{
setResponse(response);
- m_responseTimestamp = currentTime();
+ m_responseTimestamp = std::chrono::system_clock::now();
String encoding = response.textEncodingName();
if (!encoding.isNull())
setEncoding(encoding);
@@ -646,7 +646,7 @@
void CachedResource::updateResponseAfterRevalidation(const ResourceResponse& validatingResponse)
{
- m_responseTimestamp = currentTime();
+ m_responseTimestamp = std::chrono::system_clock::now();
updateResponseHeadersAfterRevalidation(m_response, validatingResponse);
}
Modified: trunk/Source/WebCore/loader/cache/CachedResource.h (182270 => 182271)
--- trunk/Source/WebCore/loader/cache/CachedResource.h 2015-04-02 08:51:23 UTC (rev 182270)
+++ trunk/Source/WebCore/loader/cache/CachedResource.h 2015-04-02 15:45:58 UTC (rev 182271)
@@ -280,7 +280,7 @@
virtual void checkNotify();
virtual bool mayTryReplaceEncodedData() const { return false; }
- double freshnessLifetime(const ResourceResponse&) const;
+ std::chrono::microseconds freshnessLifetime(const ResourceResponse&) const;
void addAdditionalRequestHeaders(CachedResourceLoader&);
void failBeforeStarting();
@@ -289,7 +289,7 @@
SessionID m_sessionID;
String m_accept;
ResourceLoadPriority m_loadPriority;
- double m_responseTimestamp;
+ std::chrono::system_clock::time_point m_responseTimestamp;
String m_fragmentIdentifierForRequest;
Modified: trunk/Source/WebCore/platform/network/CacheValidation.cpp (182270 => 182271)
--- trunk/Source/WebCore/platform/network/CacheValidation.cpp 2015-04-02 08:51:23 UTC (rev 182270)
+++ trunk/Source/WebCore/platform/network/CacheValidation.cpp 2015-04-02 15:45:58 UTC (rev 182271)
@@ -89,49 +89,56 @@
}
}
-double computeCurrentAge(const ResourceResponse& response, double responseTimestamp)
+std::chrono::microseconds computeCurrentAge(const ResourceResponse& response, std::chrono::system_clock::time_point responseTimestamp)
{
+ using namespace std::chrono;
+
// RFC2616 13.2.3
// No compensation for latency as that is not terribly important in practice
- double dateValue = response.date();
- double apparentAge = std::isfinite(dateValue) ? std::max(0., responseTimestamp - dateValue) : 0;
- double ageValue = response.age();
- double correctedReceivedAge = std::isfinite(ageValue) ? std::max(apparentAge, ageValue) : apparentAge;
- double residentTime = currentTime() - responseTimestamp;
+ auto dateValue = response.date();
+ auto apparentAge = dateValue ? std::max(microseconds::zero(), duration_cast<microseconds>(responseTimestamp - dateValue.value())) : microseconds::zero();
+ auto ageValue = response.age();
+ auto correctedReceivedAge = ageValue ? std::max(apparentAge, ageValue.value()) : apparentAge;
+ auto residentTime = duration_cast<microseconds>(system_clock::now() - responseTimestamp);
return correctedReceivedAge + residentTime;
}
-double computeFreshnessLifetimeForHTTPFamily(const ResourceResponse& response, double responseTimestamp)
+std::chrono::microseconds computeFreshnessLifetimeForHTTPFamily(const ResourceResponse& response, std::chrono::system_clock::time_point responseTimestamp)
{
+ using namespace std::chrono;
ASSERT(response.url().protocolIsInHTTPFamily());
+
// RFC2616 13.2.4
- double maxAgeValue = response.cacheControlMaxAge();
- if (std::isfinite(maxAgeValue))
- return maxAgeValue;
- double expiresValue = response.expires();
- double dateValue = response.date();
- double creationTime = std::isfinite(dateValue) ? dateValue : responseTimestamp;
- if (std::isfinite(expiresValue))
- return expiresValue - creationTime;
- double lastModifiedValue = response.lastModified();
- if (std::isfinite(lastModifiedValue))
- return (creationTime - lastModifiedValue) * 0.1;
+ auto maxAge = response.cacheControlMaxAge();
+ if (maxAge)
+ return maxAge.value();
+ auto expires = response.expires();
+ auto date = response.date();
+ auto creationTime = date ? date.value() : responseTimestamp;
+ if (expires)
+ return duration_cast<microseconds>(expires.value() - creationTime);
+ auto lastModified = response.lastModified();
+ if (lastModified)
+ return duration_cast<microseconds>((creationTime - lastModified.value()) * 0.1);
// If no cache headers are present, the specification leaves the decision to the UA. Other browsers seem to opt for 0.
- return 0;
+ return microseconds::zero();
}
void updateRedirectChainStatus(RedirectChainCacheStatus& redirectChainCacheStatus, const ResourceResponse& response)
{
+ using namespace std::chrono;
+
if (redirectChainCacheStatus.status == RedirectChainCacheStatus::NotCachedRedirection)
return;
if (response.cacheControlContainsNoStore() || response.cacheControlContainsNoCache() || response.cacheControlContainsMustRevalidate()) {
redirectChainCacheStatus.status = RedirectChainCacheStatus::NotCachedRedirection;
return;
}
+
redirectChainCacheStatus.status = RedirectChainCacheStatus::CachedRedirection;
- double responseTimestamp = currentTime();
+ auto responseTimestamp = system_clock::now();
// Store the nearest end of cache validity date
- double endOfValidity = responseTimestamp + computeFreshnessLifetimeForHTTPFamily(response, responseTimestamp) - computeCurrentAge(response, responseTimestamp);
+ auto endOfValidity = responseTimestamp + computeFreshnessLifetimeForHTTPFamily(response, responseTimestamp) - computeCurrentAge(response, responseTimestamp);
redirectChainCacheStatus.endOfValidity = std::min(redirectChainCacheStatus.endOfValidity, endOfValidity);
}
@@ -143,7 +150,7 @@
case RedirectChainCacheStatus::NotCachedRedirection:
return false;
case RedirectChainCacheStatus::CachedRedirection:
- return reuseExpiredRedirection || currentTime() <= redirectChainCacheStatus.endOfValidity;
+ return reuseExpiredRedirection || std::chrono::system_clock::now() <= redirectChainCacheStatus.endOfValidity;
}
ASSERT_NOT_REACHED();
return false;
@@ -248,6 +255,8 @@
CacheControlDirectives parseCacheControlDirectives(const HTTPHeaderMap& headers)
{
+ using namespace std::chrono;
+
CacheControlDirectives result;
String cacheControlValue = headers.get(HTTPHeaderName::CacheControl);
@@ -265,29 +274,29 @@
else if (equalIgnoringCase(directives[i].first, "must-revalidate"))
result.mustRevalidate = true;
else if (equalIgnoringCase(directives[i].first, "max-age")) {
- if (!std::isnan(result.maxAge)) {
+ if (result.maxAge) {
// First max-age directive wins if there are multiple ones.
continue;
}
bool ok;
double maxAge = directives[i].second.toDouble(&ok);
if (ok)
- result.maxAge = maxAge;
+ result.maxAge = duration_cast<microseconds>(duration<double>(maxAge));
} else if (equalIgnoringCase(directives[i].first, "max-stale")) {
// https://tools.ietf.org/html/rfc7234#section-5.2.1.2
- if (!std::isnan(result.maxStale)) {
+ if (result.maxStale) {
// First max-stale directive wins if there are multiple ones.
continue;
}
if (directives[i].second.isEmpty()) {
// if no value is assigned to max-stale, then the client is willing to accept a stale response of any age.
- result.maxStale = std::numeric_limits<double>::max();
+ result.maxStale = microseconds::max();
continue;
}
bool ok;
double maxStale = directives[i].second.toDouble(&ok);
if (ok)
- result.maxStale = maxStale;
+ result.maxStale = duration_cast<microseconds>(duration<double>(maxStale));
}
}
}
Modified: trunk/Source/WebCore/platform/network/CacheValidation.h (182270 => 182271)
--- trunk/Source/WebCore/platform/network/CacheValidation.h 2015-04-02 08:51:23 UTC (rev 182270)
+++ trunk/Source/WebCore/platform/network/CacheValidation.h 2015-04-02 15:45:58 UTC (rev 182271)
@@ -26,6 +26,8 @@
#ifndef CacheValidation_h
#define CacheValidation_h
+#include <wtf/Optional.h>
+
namespace WebCore {
class HTTPHeaderMap;
@@ -39,14 +41,14 @@
};
RedirectChainCacheStatus()
: status(NoRedirection)
- , endOfValidity(std::numeric_limits<double>::max())
+ , endOfValidity(std::chrono::system_clock::time_point::max())
{ }
Status status;
- double endOfValidity;
+ std::chrono::system_clock::time_point endOfValidity;
};
-WEBCORE_EXPORT double computeCurrentAge(const ResourceResponse&, double responseTimestamp);
-WEBCORE_EXPORT double computeFreshnessLifetimeForHTTPFamily(const ResourceResponse&, double responseTimestamp);
+WEBCORE_EXPORT std::chrono::microseconds computeCurrentAge(const ResourceResponse&, std::chrono::system_clock::time_point responseTimestamp);
+WEBCORE_EXPORT std::chrono::microseconds computeFreshnessLifetimeForHTTPFamily(const ResourceResponse&, std::chrono::system_clock::time_point responseTimestamp);
WEBCORE_EXPORT void updateResponseHeadersAfterRevalidation(ResourceResponse&, const ResourceResponse& validatingResponse);
WEBCORE_EXPORT void updateRedirectChainStatus(RedirectChainCacheStatus&, const ResourceResponse&);
@@ -54,8 +56,8 @@
WEBCORE_EXPORT bool redirectChainAllowsReuse(RedirectChainCacheStatus, ReuseExpiredRedirectionOrNot);
struct CacheControlDirectives {
- double maxAge { std::numeric_limits<double>::quiet_NaN() };
- double maxStale { std::numeric_limits<double>::quiet_NaN() };
+ Optional<std::chrono::microseconds> maxAge;
+ Optional<std::chrono::microseconds> maxStale;
bool noCache { false };
bool noStore { false };
bool mustRevalidate { false };
Modified: trunk/Source/WebCore/platform/network/HTTPParsers.cpp (182270 => 182271)
--- trunk/Source/WebCore/platform/network/HTTPParsers.cpp 2015-04-02 08:51:23 UTC (rev 182270)
+++ trunk/Source/WebCore/platform/network/HTTPParsers.cpp 2015-04-02 15:45:58 UTC (rev 182271)
@@ -234,9 +234,14 @@
}
}
-double parseDate(const String& value)
+Optional<std::chrono::system_clock::time_point> parseHTTPDate(const String& value)
{
- return parseDateFromNullTerminatedCharacters(value.utf8().data());
+ double dateInMillisecondsSinceEpoch = parseDateFromNullTerminatedCharacters(value.utf8().data());
+ if (!std::isfinite(dateInMillisecondsSinceEpoch))
+ return { };
+ // This assumes system_clock epoch equals Unix epoch which is true for all implementations but unspecified.
+ // FIXME: The parsing function should be switched to std::chrono too.
+ return std::chrono::system_clock::time_point(std::chrono::milliseconds(static_cast<long long>(dateInMillisecondsSinceEpoch)));
}
// FIXME: This function doesn't comply with RFC 6266.
Modified: trunk/Source/WebCore/platform/network/HTTPParsers.h (182270 => 182271)
--- trunk/Source/WebCore/platform/network/HTTPParsers.h 2015-04-02 08:51:23 UTC (rev 182270)
+++ trunk/Source/WebCore/platform/network/HTTPParsers.h 2015-04-02 15:45:58 UTC (rev 182271)
@@ -33,6 +33,7 @@
#include "ContentSecurityPolicy.h"
#include <wtf/Forward.h>
+#include <wtf/Optional.h>
#include <wtf/Vector.h>
namespace WebCore {
@@ -64,7 +65,7 @@
bool isValidHTTPHeaderValue(const String&);
bool isValidHTTPToken(const String&);
bool parseHTTPRefresh(const String& refresh, bool fromHttpEquivMeta, double& delay, String& url);
-double parseDate(const String&);
+Optional<std::chrono::system_clock::time_point> parseHTTPDate(const String&);
String filenameFromHTTPContentDisposition(const String&);
String extractMIMETypeFromMediaType(const String&);
String extractCharsetFromMediaType(const String&);
Modified: trunk/Source/WebCore/platform/network/ResourceResponseBase.cpp (182270 => 182271)
--- trunk/Source/WebCore/platform/network/ResourceResponseBase.cpp 2015-04-02 08:51:23 UTC (rev 182270)
+++ trunk/Source/WebCore/platform/network/ResourceResponseBase.cpp 2015-04-02 15:45:58 UTC (rev 182271)
@@ -43,42 +43,22 @@
return *static_cast<const ResourceResponse*>(this);
}
-ResourceResponseBase::ResourceResponseBase()
- : m_expectedContentLength(0)
+ResourceResponseBase::ResourceResponseBase()
+ : m_isNull(true)
+ , m_expectedContentLength(0)
, m_includesCertificateInfo(false)
, m_httpStatusCode(0)
- , m_age(0)
- , m_date(0)
- , m_expires(0)
- , m_lastModified(0)
- , m_isNull(true)
- , m_haveParsedCacheControlHeader(false)
- , m_haveParsedAgeHeader(false)
- , m_haveParsedDateHeader(false)
- , m_haveParsedExpiresHeader(false)
- , m_haveParsedLastModifiedHeader(false)
- , m_source(Source::Unknown)
{
}
ResourceResponseBase::ResourceResponseBase(const URL& url, const String& mimeType, long long expectedLength, const String& textEncodingName)
- : m_url(url)
+ : m_isNull(false)
+ , m_url(url)
, m_mimeType(mimeType)
, m_expectedContentLength(expectedLength)
, m_textEncodingName(textEncodingName)
, m_includesCertificateInfo(true) // Empty but valid for synthetic responses.
, m_httpStatusCode(0)
- , m_age(0)
- , m_date(0)
- , m_expires(0)
- , m_lastModified(0)
- , m_isNull(false)
- , m_haveParsedCacheControlHeader(false)
- , m_haveParsedAgeHeader(false)
- , m_haveParsedDateHeader(false)
- , m_haveParsedExpiresHeader(false)
- , m_haveParsedLastModifiedHeader(false)
- , m_source(Source::Unknown)
{
}
@@ -381,29 +361,26 @@
return !m_httpHeaderFields.get(HTTPHeaderName::LastModified).isEmpty() || !m_httpHeaderFields.get(HTTPHeaderName::ETag).isEmpty();
}
-double ResourceResponseBase::cacheControlMaxAge() const
+Optional<std::chrono::microseconds> ResourceResponseBase::cacheControlMaxAge() const
{
if (!m_haveParsedCacheControlHeader)
parseCacheControlDirectives();
return m_cacheControlDirectives.maxAge;
}
-static double parseDateValueInHeader(const HTTPHeaderMap& headers, HTTPHeaderName headerName)
+static Optional<std::chrono::system_clock::time_point> parseDateValueInHeader(const HTTPHeaderMap& headers, HTTPHeaderName headerName)
{
String headerValue = headers.get(headerName);
if (headerValue.isEmpty())
- return std::numeric_limits<double>::quiet_NaN();
+ return { };
// This handles all date formats required by RFC2616:
// Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123
// Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036
// Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format
- double dateInMilliseconds = parseDate(headerValue);
- if (!std::isfinite(dateInMilliseconds))
- return std::numeric_limits<double>::quiet_NaN();
- return dateInMilliseconds / 1000;
+ return parseHTTPDate(headerValue);
}
-double ResourceResponseBase::date() const
+Optional<std::chrono::system_clock::time_point> ResourceResponseBase::date() const
{
lazyInit(CommonFieldsOnly);
@@ -414,22 +391,24 @@
return m_date;
}
-double ResourceResponseBase::age() const
+Optional<std::chrono::microseconds> ResourceResponseBase::age() const
{
+ using namespace std::chrono;
+
lazyInit(CommonFieldsOnly);
if (!m_haveParsedAgeHeader) {
String headerValue = m_httpHeaderFields.get(HTTPHeaderName::Age);
bool ok;
- m_age = headerValue.toDouble(&ok);
- if (!ok)
- m_age = std::numeric_limits<double>::quiet_NaN();
+ double ageDouble = headerValue.toDouble(&ok);
+ if (ok)
+ m_age = duration_cast<microseconds>(duration<double>(ageDouble));
m_haveParsedAgeHeader = true;
}
return m_age;
}
-double ResourceResponseBase::expires() const
+Optional<std::chrono::system_clock::time_point> ResourceResponseBase::expires() const
{
lazyInit(CommonFieldsOnly);
@@ -440,7 +419,7 @@
return m_expires;
}
-double ResourceResponseBase::lastModified() const
+Optional<std::chrono::system_clock::time_point> ResourceResponseBase::lastModified() const
{
lazyInit(CommonFieldsOnly);
Modified: trunk/Source/WebCore/platform/network/ResourceResponseBase.h (182270 => 182271)
--- trunk/Source/WebCore/platform/network/ResourceResponseBase.h 2015-04-02 08:51:23 UTC (rev 182270)
+++ trunk/Source/WebCore/platform/network/ResourceResponseBase.h 2015-04-02 15:45:58 UTC (rev 182271)
@@ -104,11 +104,11 @@
WEBCORE_EXPORT bool cacheControlContainsNoStore() const;
WEBCORE_EXPORT bool cacheControlContainsMustRevalidate() const;
WEBCORE_EXPORT bool hasCacheValidatorFields() const;
- WEBCORE_EXPORT double cacheControlMaxAge() const;
- double date() const;
- double age() const;
- WEBCORE_EXPORT double expires() const;
- WEBCORE_EXPORT double lastModified() const;
+ WEBCORE_EXPORT Optional<std::chrono::microseconds> cacheControlMaxAge() const;
+ WEBCORE_EXPORT Optional<std::chrono::system_clock::time_point> date() const;
+ WEBCORE_EXPORT Optional<std::chrono::microseconds> age() const;
+ WEBCORE_EXPORT Optional<std::chrono::system_clock::time_point> expires() const;
+ WEBCORE_EXPORT Optional<std::chrono::system_clock::time_point> lastModified() const;
enum class Source { Unknown, Network, DiskCache, DiskCacheAfterValidation };
WEBCORE_EXPORT Source source() const;
@@ -147,6 +147,13 @@
static bool platformCompare(const ResourceResponse&, const ResourceResponse&) { return true; }
+private:
+ const ResourceResponse& asResourceResponse() const;
+ void parseCacheControlDirectives() const;
+ void updateHeaderParsedState(HTTPHeaderName);
+
+protected:
+ bool m_isNull;
URL m_url;
AtomicString m_mimeType;
long long m_expectedContentLength;
@@ -161,27 +168,19 @@
int m_httpStatusCode;
private:
- mutable double m_age;
- mutable double m_date;
- mutable double m_expires;
- mutable double m_lastModified;
+ mutable Optional<std::chrono::microseconds> m_age;
+ mutable Optional<std::chrono::system_clock::time_point> m_date;
+ mutable Optional<std::chrono::system_clock::time_point> m_expires;
+ mutable Optional<std::chrono::system_clock::time_point> m_lastModified;
mutable CacheControlDirectives m_cacheControlDirectives;
-public:
- bool m_isNull : 1;
-
-private:
- const ResourceResponse& asResourceResponse() const;
- void parseCacheControlDirectives() const;
- void updateHeaderParsedState(HTTPHeaderName);
+ mutable bool m_haveParsedCacheControlHeader { false };
+ mutable bool m_haveParsedAgeHeader { false };
+ mutable bool m_haveParsedDateHeader { false };
+ mutable bool m_haveParsedExpiresHeader { false };
+ mutable bool m_haveParsedLastModifiedHeader { false };
- mutable bool m_haveParsedCacheControlHeader : 1;
- mutable bool m_haveParsedAgeHeader : 1;
- mutable bool m_haveParsedDateHeader : 1;
- mutable bool m_haveParsedExpiresHeader : 1;
- mutable bool m_haveParsedLastModifiedHeader : 1;
-
- Source m_source;
+ Source m_source { Source::Unknown };
};
inline bool operator==(const ResourceResponse& a, const ResourceResponse& b) { return ResourceResponseBase::compare(a, b); }
Modified: trunk/Source/WebKit/win/Plugins/PluginStream.cpp (182270 => 182271)
--- trunk/Source/WebKit/win/Plugins/PluginStream.cpp 2015-04-02 08:51:23 UTC (rev 182270)
+++ trunk/Source/WebKit/win/Plugins/PluginStream.cpp 2015-04-02 15:45:58 UTC (rev 182271)
@@ -123,13 +123,13 @@
m_client = 0;
}
-static uint32_t lastModifiedDate(const ResourceResponse& response)
+static uint32_t lastModifiedDateMS(const ResourceResponse& response)
{
- double lastModified = response.lastModified();
- if (!std::isfinite(lastModified))
+ auto lastModified = response.lastModified();
+ if (!lastModified)
return 0;
- return lastModified * 1000;
+ return std::chrono::duration_cast<std::chrono::milliseconds>(lastModified.value().time_since_epoch()).count();
}
void PluginStream::startStream()
@@ -178,7 +178,7 @@
m_stream.pdata = 0;
m_stream.ndata = this;
m_stream.end = max(expectedContentLength, 0LL);
- m_stream.lastmodified = lastModifiedDate(m_resourceResponse);
+ m_stream.lastmodified = lastModifiedDateMS(m_resourceResponse);
m_stream.notifyData = m_notifyData;
m_transferMode = NP_NORMAL;
Modified: trunk/Source/WebKit2/ChangeLog (182270 => 182271)
--- trunk/Source/WebKit2/ChangeLog 2015-04-02 08:51:23 UTC (rev 182270)
+++ trunk/Source/WebKit2/ChangeLog 2015-04-02 15:45:58 UTC (rev 182271)
@@ -1,3 +1,38 @@
+2015-04-01 Antti Koivisto <an...@apple.com>
+
+ 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.
+
+ * 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.
+
2015-04-01 Chris Dumez <cdu...@apple.com>
[WK2][Cocoa] Add didFailProvisionalLoadWithErrorForFrame callback to WKWebProcessPlugInLoadDelegate
Modified: trunk/Source/WebKit2/NetworkProcess/NetworkResourceLoader.cpp (182270 => 182271)
--- trunk/Source/WebKit2/NetworkProcess/NetworkResourceLoader.cpp 2015-04-02 08:51:23 UTC (rev 182270)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkResourceLoader.cpp 2015-04-02 15:45:58 UTC (rev 182271)
@@ -318,9 +318,9 @@
bool allowStale = originalRequest().cachePolicy() >= ReturnCacheDataElseLoad;
bool hasCacheableRedirect = m_response.isHTTP() && WebCore::redirectChainAllowsReuse(m_redirectChainCacheStatus, allowStale ? WebCore::ReuseExpiredRedirection : WebCore::DoNotReuseExpiredRedirection);
if (hasCacheableRedirect && m_redirectChainCacheStatus.status == RedirectChainCacheStatus::CachedRedirection) {
- // FIXME: Cache the actual redirects instead of the end result.
- double now = currentTime();
- double responseEndOfValidity = now + WebCore::computeFreshnessLifetimeForHTTPFamily(m_response, now) - WebCore::computeCurrentAge(m_response, now);
+ // Maybe we should cache the actual redirects instead of the end result?
+ auto now = std::chrono::system_clock::now();
+ auto responseEndOfValidity = now + WebCore::computeFreshnessLifetimeForHTTPFamily(m_response, now) - WebCore::computeCurrentAge(m_response, now);
hasCacheableRedirect = responseEndOfValidity <= m_redirectChainCacheStatus.endOfValidity;
}
Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.cpp (182270 => 182271)
--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.cpp 2015-04-02 08:51:23 UTC (rev 182270)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.cpp 2015-04-02 15:45:58 UTC (rev 182271)
@@ -150,17 +150,16 @@
return false;
}
-static bool responseHasExpired(const WebCore::ResourceResponse& response, std::chrono::milliseconds timestamp, double maxStale)
+static bool responseHasExpired(const WebCore::ResourceResponse& response, std::chrono::system_clock::time_point timestamp, Optional<std::chrono::microseconds> maxStale)
{
if (response.cacheControlContainsNoCache())
return true;
- auto doubleTimeStamp = std::chrono::duration<double>(timestamp);
- double age = WebCore::computeCurrentAge(response, doubleTimeStamp.count());
- double lifetime = WebCore::computeFreshnessLifetimeForHTTPFamily(response, doubleTimeStamp.count());
+ auto age = WebCore::computeCurrentAge(response, timestamp);
+ auto lifetime = WebCore::computeFreshnessLifetimeForHTTPFamily(response, timestamp);
- maxStale = std::isnan(maxStale) ? 0 : maxStale;
- bool hasExpired = age - lifetime > maxStale;
+ auto maximumStaleness = maxStale ? maxStale.value() : 0_ms;
+ bool hasExpired = age - lifetime > maximumStaleness;
#ifndef LOG_DISABLED
if (hasExpired)
@@ -170,13 +169,13 @@
return hasExpired;
}
-static bool responseNeedsRevalidation(const WebCore::ResourceResponse& response, const WebCore::ResourceRequest& request, std::chrono::milliseconds timestamp)
+static bool responseNeedsRevalidation(const WebCore::ResourceResponse& response, const WebCore::ResourceRequest& request, std::chrono::system_clock::time_point timestamp)
{
auto requestDirectives = WebCore::parseCacheControlDirectives(request.httpHeaderFields());
if (requestDirectives.noCache)
return true;
// For requests we ignore max-age values other than zero.
- if (requestDirectives.maxAge == 0)
+ if (requestDirectives.maxAge && requestDirectives.maxAge.value() == 0_ms)
return true;
return responseHasExpired(response, timestamp, requestDirectives.maxStale);
@@ -269,7 +268,7 @@
if (!isStatusCodeCacheableByDefault(response.httpStatusCode())) {
// http://tools.ietf.org/html/rfc7234#section-4.3.2
- bool hasExpirationHeaders = std::isfinite(response.expires()) || std::isfinite(response.cacheControlMaxAge());
+ bool hasExpirationHeaders = response.expires() || response.cacheControlMaxAge();
bool expirationHeadersAllowCaching = isStatusCodePotentiallyCacheable(response.httpStatusCode()) && hasExpirationHeaders;
if (!expirationHeadersAllowCaching)
return StoreDecision::NoDueToHTTPStatusCode;
@@ -278,8 +277,8 @@
// Main resource has ResourceLoadPriorityVeryHigh.
bool storeUnconditionallyForHistoryNavigation = originalRequest.priority() == WebCore::ResourceLoadPriorityVeryHigh;
if (!storeUnconditionallyForHistoryNavigation) {
- auto currentTime = std::chrono::duration<double>(std::chrono::system_clock::now().time_since_epoch());
- bool hasNonZeroLifetime = !response.cacheControlContainsNoCache() && WebCore::computeFreshnessLifetimeForHTTPFamily(response, currentTime.count()) > 0;
+ auto now = std::chrono::system_clock::now();
+ bool hasNonZeroLifetime = !response.cacheControlContainsNoCache() && WebCore::computeFreshnessLifetimeForHTTPFamily(response, now) > 0_ms;
bool possiblyReusable = response.hasCacheValidatorFields() || hasNonZeroLifetime;
if (!possiblyReusable)
@@ -358,7 +357,6 @@
LOG(NetworkCache, "(NetworkProcess) storing %s, partition %s", originalRequest.url().string().latin1().data(), originalRequest.cachePartition().latin1().data());
StoreDecision storeDecision = makeStoreDecision(originalRequest, response);
-
if (storeDecision != StoreDecision::Yes) {
LOG(NetworkCache, "(NetworkProcess) didn't store, storeDecision=%d", storeDecision);
if (m_statistics) {
Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheEntry.cpp (182270 => 182271)
--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheEntry.cpp 2015-04-02 08:51:23 UTC (rev 182270)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheEntry.cpp 2015-04-02 15:45:58 UTC (rev 182271)
@@ -42,7 +42,7 @@
Entry::Entry(const Key& key, const WebCore::ResourceResponse& response, RefPtr<WebCore::SharedBuffer>&& buffer, const Vector<std::pair<String, String>>& varyingRequestHeaders)
: m_key(key)
- , m_timeStamp(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()))
+ , m_timeStamp(std::chrono::system_clock::now())
, m_response(response)
, m_varyingRequestHeaders(varyingRequestHeaders)
, m_buffer(WTF::move(buffer))
@@ -160,7 +160,7 @@
JSC::appendQuotedJSONStringToBuilder(json, m_key.partition());
json.appendLiteral(",\n");
json.appendLiteral("\"timestamp\": ");
- json.appendNumber(m_timeStamp.count());
+ json.appendNumber(std::chrono::duration_cast<std::chrono::milliseconds>(m_timeStamp.time_since_epoch()).count());
json.appendLiteral(",\n");
json.appendLiteral("\"URL\": ");
JSC::appendQuotedJSONStringToBuilder(json, m_response.url().string());
Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheEntry.h (182270 => 182271)
--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheEntry.h 2015-04-02 08:51:23 UTC (rev 182270)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheEntry.h 2015-04-02 15:45:58 UTC (rev 182271)
@@ -51,7 +51,7 @@
static std::unique_ptr<Entry> decodeStorageRecord(const Storage::Record&);
const Key& key() const { return m_key; }
- std::chrono::milliseconds timeStamp() const { return m_timeStamp; }
+ std::chrono::system_clock::time_point timeStamp() const { return m_timeStamp; }
const WebCore::ResourceResponse& response() const { return m_response; }
const Vector<std::pair<String, String>>& varyingRequestHeaders() const { return m_varyingRequestHeaders; }
@@ -72,7 +72,7 @@
void initializeBufferFromStorageRecord() const;
Key m_key;
- std::chrono::milliseconds m_timeStamp;
+ std::chrono::system_clock::time_point m_timeStamp;
WebCore::ResourceResponse m_response;
Vector<std::pair<String, String>> m_varyingRequestHeaders;
Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorage.cpp (182270 => 182271)
--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorage.cpp 2015-04-02 08:51:23 UTC (rev 182270)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorage.cpp 2015-04-02 15:45:58 UTC (rev 182271)
@@ -142,7 +142,8 @@
unsigned cacheStorageVersion;
Key key;
- std::chrono::milliseconds timeStamp;
+ // FIXME: Add encoder/decoder for time_point.
+ std::chrono::milliseconds epochRelativeTimeStamp;
unsigned headerChecksum;
uint64_t headerOffset;
uint64_t headerSize;
@@ -160,7 +161,7 @@
return false;
if (!decoder.decode(metaData.key))
return false;
- if (!decoder.decode(metaData.timeStamp))
+ if (!decoder.decode(metaData.epochRelativeTimeStamp))
return false;
if (!decoder.decode(metaData.headerChecksum))
return false;
@@ -215,6 +216,11 @@
if (metaData.key != key)
return nullptr;
+ // Sanity check against time stamps in future.
+ auto timeStamp = std::chrono::system_clock::time_point(metaData.epochRelativeTimeStamp);
+ if (timeStamp > std::chrono::system_clock::now())
+ return nullptr;
+
Data bodyData;
if (metaData.bodySize) {
if (metaData.bodyOffset + metaData.bodySize != fileData.size())
@@ -234,7 +240,7 @@
return std::make_unique<Storage::Record>(Storage::Record {
metaData.key,
- metaData.timeStamp,
+ timeStamp,
headerData,
bodyData
});
@@ -246,7 +252,7 @@
encoder << metaData.cacheStorageVersion;
encoder << metaData.key;
- encoder << metaData.timeStamp;
+ encoder << metaData.epochRelativeTimeStamp;
encoder << metaData.headerChecksum;
encoder << metaData.headerSize;
encoder << metaData.bodyChecksum;
@@ -260,7 +266,7 @@
static Data encodeRecordHeader(const Storage::Record& record)
{
RecordMetaData metaData(record.key);
- metaData.timeStamp = record.timeStamp;
+ metaData.epochRelativeTimeStamp = std::chrono::duration_cast<std::chrono::milliseconds>(record.timeStamp.time_since_epoch());
metaData.headerChecksum = hashData(record.header);
metaData.headerSize = record.header.size();
metaData.bodyChecksum = hashData(record.body);
@@ -446,7 +452,7 @@
RecordMetaData metaData;
Data headerData;
if (decodeRecordHeader(fileData, metaData, headerData)) {
- Record record { metaData.key, metaData.timeStamp, headerData, { } };
+ Record record { metaData.key, std::chrono::system_clock::time_point(metaData.epochRelativeTimeStamp), headerData, { } };
info.bodySize = metaData.bodySize;
traverseHandler(&record, info);
}
@@ -599,7 +605,7 @@
auto accessAge = times.modification - times.creation;
// For sanity.
- if (age <= seconds::zero() || accessAge < seconds::zero() || accessAge > age)
+ if (age <= 0_s || accessAge < 0_s || accessAge > age)
return 0;
// We like old entries that have been accessed recently.
Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorage.h (182270 => 182271)
--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorage.h 2015-04-02 08:51:23 UTC (rev 182270)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorage.h 2015-04-02 15:45:58 UTC (rev 182271)
@@ -49,7 +49,7 @@
struct Record {
Key key;
- std::chrono::milliseconds timeStamp;
+ std::chrono::system_clock::time_point timeStamp;
Data header;
Data body;
};
Modified: trunk/Source/WebKit2/WebProcess/Plugins/PluginView.cpp (182270 => 182271)
--- trunk/Source/WebKit2/WebProcess/Plugins/PluginView.cpp 2015-04-02 08:51:23 UTC (rev 182270)
+++ trunk/Source/WebKit2/WebProcess/Plugins/PluginView.cpp 2015-04-02 15:45:58 UTC (rev 182271)
@@ -201,13 +201,13 @@
return headers;
}
-static uint32_t lastModifiedDate(const ResourceResponse& response)
+static uint32_t lastModifiedDateMS(const ResourceResponse& response)
{
- double lastModified = response.lastModified();
- if (!std::isfinite(lastModified))
+ auto lastModified = response.lastModified();
+ if (!lastModified)
return 0;
- return lastModified * 1000;
+ return std::chrono::duration_cast<std::chrono::milliseconds>(lastModified.value().time_since_epoch()).count();
}
void PluginView::Stream::didReceiveResponse(NetscapePlugInStreamLoader*, const ResourceResponse& response)
@@ -223,7 +223,7 @@
if (expectedContentLength > 0)
streamLength = expectedContentLength;
- m_pluginView->m_plugin->streamDidReceiveResponse(m_streamID, responseURL, streamLength, lastModifiedDate(response), mimeType, headers, response.suggestedFilename());
+ m_pluginView->m_plugin->streamDidReceiveResponse(m_streamID, responseURL, streamLength, lastModifiedDateMS(response), mimeType, headers, response.suggestedFilename());
}
void PluginView::Stream::didReceiveData(NetscapePlugInStreamLoader*, const char* bytes, int length)
@@ -413,7 +413,7 @@
if (expectedContentLength > 0)
streamLength = expectedContentLength;
- m_plugin->manualStreamDidReceiveResponse(responseURL, streamLength, lastModifiedDate(response), mimeType, headers, response.suggestedFilename());
+ m_plugin->manualStreamDidReceiveResponse(responseURL, streamLength, lastModifiedDateMS(response), mimeType, headers, response.suggestedFilename());
}
void PluginView::manualLoadDidReceiveData(const char* bytes, int length)