Changeset 173173 in webkit
- Timestamp:
- Sep 2, 2014 9:00:14 AM (10 years ago)
- Location:
- trunk
- Files:
-
- 4 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r173169 r173173 1 2014-09-02 Youenn Fablet <youenn.fablet@crf.canon.fr> 2 3 CachedResourceLoader should check redirections to reuse or not cached resources 4 https://bugs.webkit.org/show_bug.cgi?id=131757 5 6 Reviewed by Antti Koivisto. 7 8 Added test checks that fresh redirections allow reuse of cached resoure and expired or not cacheable redirections trigger reloading of resources. 9 10 * http/tests/cache/cache-redirections-expected.txt: Added. 11 * http/tests/cache/cache-redirections.html: Added. 12 * http/tests/cache/resources/cache-control-redirect.php: Added. 13 * http/tests/cache/resources/cacheable-random-text.php: Added. 14 1 15 2014-09-02 Manuel Rego Casasnovas <rego@igalia.com> 2 16 -
trunk/Source/WebCore/ChangeLog
r173172 r173173 1 2014-09-02 Youenn Fablet <youenn.fablet@crf.canon.fr> 2 3 CachedResourceLoader should check redirections to reuse or not cached resources 4 https://bugs.webkit.org/show_bug.cgi?id=131757 5 6 Reviewed by Antti Koivisto. 7 8 Added cache-control redirection check to properly determine revalidation policy. 9 Tightened redirection cache-control header check by testing for no-cache and must-revalidate directives. 10 Added redirection freshness check. 11 12 Test: http/tests/cache/cache-redirections.html 13 14 * loader/cache/CachedRawResource.cpp: 15 (WebCore::CachedRawResource::canReuse): Removed redirection check (now handled by CachedResource::redirectChainAllowsReuse). 16 * loader/cache/CachedResource.cpp: 17 (WebCore::currentAge): Moved from WebCore::CachedResource::currentAge method to static function. Added response and responseTimestamp as parameters. 18 (WebCore::CachedResource::CachedResource): Initialized redirection chain status (no redirection and expiracy date set to never). 19 (WebCore::CachedResource::isExpired): Updated according new currentAge/freshnessLifetime method parameters. 20 (WebCore::CachedResource::freshnessLifetime): Added response as parameter. 21 (WebCore::CachedResource::willSendRequest): Computes whether a redirection can be cached, and if cached for how long it will remain fresh. 22 (WebCore::CachedResource::redirectChainAllowsReuse): Return false if any of the redirection in the redirection chain cannot be cached or expired. 23 * loader/cache/CachedResource.h: Added cache chain member that stores whether the redirection chain can be cached and if so when it will be expired. 24 * loader/cache/CachedResourceLoader.cpp: 25 (WebCore::CachedResourceLoader::determineRevalidationPolicy): Added check of the redirection chain. 26 1 27 2014-09-02 Daewoong Jang <daewoong.jang@navercorp.com> 2 28 -
trunk/Source/WebCore/loader/cache/CachedRawResource.cpp
r171993 r173173 256 256 } 257 257 258 for (size_t i = 0; i < m_redirectChain.size(); i++) {259 if (m_redirectChain[i].m_redirectResponse.cacheControlContainsNoStore())260 return false;261 }262 263 258 return true; 264 259 } -
trunk/Source/WebCore/loader/cache/CachedResource.cpp
r172946 r173173 147 147 } 148 148 149 static double currentAge(const ResourceResponse& response, double responseTimestamp) 150 { 151 // RFC2616 13.2.3 152 // No compensation for latency as that is not terribly important in practice 153 double dateValue = response.date(); 154 double apparentAge = std::isfinite(dateValue) ? std::max(0., responseTimestamp - dateValue) : 0; 155 double ageValue = response.age(); 156 double correctedReceivedAge = std::isfinite(ageValue) ? std::max(apparentAge, ageValue) : apparentAge; 157 double residentTime = currentTime() - responseTimestamp; 158 return correctedReceivedAge + residentTime; 159 } 160 149 161 DEFINE_DEBUG_ONLY_GLOBAL(RefCountedLeakCounter, cachedResourceLeakCounter, ("CachedResource")); 150 162 … … 181 193 , m_resourceToRevalidate(0) 182 194 , m_proxyResource(0) 195 , m_redirectChainCacheStatus(NoRedirection) 196 , m_redirectChainEndOfValidity(std::numeric_limits<double>::max()) 183 197 { 184 198 ASSERT(m_type == unsigned(type)); // m_type is a bitfield, so this tests careless updates of the enum. … … 387 401 return false; 388 402 389 return currentAge() > freshnessLifetime(); 390 } 391 392 double CachedResource::currentAge() const 393 { 394 // RFC2616 13.2.3 395 // No compensation for latency as that is not terribly important in practice 396 double dateValue = m_response.date(); 397 double apparentAge = std::isfinite(dateValue) ? std::max(0., m_responseTimestamp - dateValue) : 0; 398 double ageValue = m_response.age(); 399 double correctedReceivedAge = std::isfinite(ageValue) ? std::max(apparentAge, ageValue) : apparentAge; 400 double residentTime = currentTime() - m_responseTimestamp; 401 return correctedReceivedAge + residentTime; 402 } 403 404 double CachedResource::freshnessLifetime() const 405 { 406 if (!m_response.url().protocolIsInHTTPFamily()) { 403 return currentAge(m_response, m_responseTimestamp) > freshnessLifetime(m_response); 404 } 405 406 double CachedResource::freshnessLifetime(const ResourceResponse& response) const 407 { 408 if (!response.url().protocolIsInHTTPFamily()) { 407 409 // Don't cache non-HTTP main resources since we can't check for freshness. 408 410 // FIXME: We should not cache subresources either, but when we tried this 409 411 // it caused performance and flakiness issues in our test infrastructure. 410 if (m_type == MainResource && !SchemeRegistry::shouldCacheResponsesFromURLSchemeIndefinitely( m_response.url().protocol()))412 if (m_type == MainResource && !SchemeRegistry::shouldCacheResponsesFromURLSchemeIndefinitely(response.url().protocol())) 411 413 return 0; 412 414 … … 415 417 416 418 // RFC2616 13.2.4 417 double maxAgeValue = m_response.cacheControlMaxAge();419 double maxAgeValue = response.cacheControlMaxAge(); 418 420 if (std::isfinite(maxAgeValue)) 419 421 return maxAgeValue; 420 double expiresValue = m_response.expires();421 double dateValue = m_response.date();422 double expiresValue = response.expires(); 423 double dateValue = response.date(); 422 424 double creationTime = std::isfinite(dateValue) ? dateValue : m_responseTimestamp; 423 425 if (std::isfinite(expiresValue)) 424 426 return expiresValue - creationTime; 425 double lastModifiedValue = m_response.lastModified();427 double lastModifiedValue = response.lastModified(); 426 428 if (std::isfinite(lastModifiedValue)) 427 429 return (creationTime - lastModifiedValue) * 0.1; 428 430 // If no cache headers are present, the specification leaves the decision to the UA. Other browsers seem to opt for 0. 429 431 return 0; 432 } 433 434 void CachedResource::willSendRequest(ResourceRequest&, const ResourceResponse& response) 435 { 436 m_requestedFromNetworkingLayer = true; 437 if (response.isNull()) 438 return; 439 if (m_redirectChainCacheStatus == NotCachedRedirection) 440 return; 441 if (response.cacheControlContainsNoStore() 442 || response.cacheControlContainsNoCache() 443 || response.cacheControlContainsMustRevalidate()) 444 m_redirectChainCacheStatus = NotCachedRedirection; 445 else { 446 m_redirectChainCacheStatus = CachedRedirection; 447 double responseTimestamp = currentTime(); 448 // Store the nearest end of cache validity date 449 m_redirectChainEndOfValidity = std::min(m_redirectChainEndOfValidity, 450 responseTimestamp + freshnessLifetime(response) - currentAge(response, responseTimestamp)); 451 } 430 452 } 431 453 … … 784 806 } 785 807 808 bool CachedResource::redirectChainAllowsReuse() const 809 { 810 switch (m_redirectChainCacheStatus) { 811 case NoRedirection: 812 return true; 813 case NotCachedRedirection: 814 return false; 815 case CachedRedirection: 816 return currentTime() <= m_redirectChainEndOfValidity; 817 } 818 return true; 819 } 820 786 821 unsigned CachedResource::overheadSize() const 787 822 { -
trunk/Source/WebCore/loader/cache/CachedResource.h
r172814 r173173 89 89 }; 90 90 91 enum RedirectChainCacheStatus { 92 NoRedirection, 93 NotCachedRedirection, 94 CachedRedirection 95 }; 96 91 97 CachedResource(const ResourceRequest&, Type, SessionID); 92 98 virtual ~CachedResource(); … … 189 195 ResourceBuffer* resourceBuffer() const { return m_data.get(); } 190 196 191 virtual void willSendRequest(ResourceRequest&, const ResourceResponse&) { m_requestedFromNetworkingLayer = true; }197 virtual void willSendRequest(ResourceRequest&, const ResourceResponse&); 192 198 virtual void responseReceived(const ResourceResponse&); 193 199 void setResponse(const ResourceResponse& response) { m_response = response; } … … 226 232 227 233 virtual bool mustRevalidateDueToCacheHeaders(CachePolicy) const; 234 bool redirectChainAllowsReuse() const; 228 235 229 236 bool isCacheValidator() const { return m_resourceToRevalidate; } … … 300 307 virtual bool mayTryReplaceEncodedData() const { return false; } 301 308 302 double currentAge() const; 303 double freshnessLifetime() const; 309 double freshnessLifetime(const ResourceResponse&) const; 304 310 305 311 void addAdditionalRequestHeaders(CachedResourceLoader*); … … 356 362 // These handles will need to be updated to point to the m_resourceToRevalidate in case we get 304 response. 357 363 HashSet<CachedResourceHandleBase*> m_handlesToRevalidate; 364 365 RedirectChainCacheStatus m_redirectChainCacheStatus; 366 double m_redirectChainEndOfValidity; 358 367 }; 359 368 -
trunk/Source/WebCore/loader/cache/CachedResourceLoader.cpp
r171708 r173173 595 595 } 596 596 597 // Validate the redirect chain 598 if (!existingResource->redirectChainAllowsReuse()) { 599 LOG(ResourceLoading, "CachedResourceLoader::determineRevalidationPolicy reloading due to not cached or expired redirections."); 600 return Reload; 601 } 602 597 603 // If credentials were sent with the previous request and won't be 598 604 // with this one, or vice versa, re-fetch the resource.
Note: See TracChangeset
for help on using the changeset viewer.