Title: [237895] trunk
Revision
237895
Author
wilan...@apple.com
Date
2018-11-06 15:10:36 -0800 (Tue, 06 Nov 2018)

Log Message

Resource Load Statistics: Remove cap on partitioned cache max age if it matches a network reload (redirect-only)
https://bugs.webkit.org/show_bug.cgi?id=189760
<rdar://problem/44612242>

Reviewed by Youenn Fablet and Antti Koivisto.

Source/WebCore:

No new tests. Existing test fleshed out.

* platform/network/ResourceResponseBase.cpp:
(WebCore::ResourceResponseBase::isRedirection const):
* platform/network/ResourceResponseBase.h:
(WebCore::ResourceResponseBase::isRedirection const): Deleted.
    Moved to the implementation file so that I can export it without warning.

Source/WebKit:

When a redirect cache entry for a prevalent resource reaches its max
age cap, it is loaded again from the network and the network response
is compared with what's in the cache. If it's a match, the cache entry
is fully accepted. If not, a new capped cache entry is created.

This feature is still off by default.

* NetworkProcess/NetworkResourceLoader.cpp:
(WebKit::NetworkResourceLoader::canUseCachedRedirect const):
    Now checks the new member m_cacheEntryForMaxAgeCapValidation.
(WebKit::NetworkResourceLoader::retrieveCacheEntry):
    New case handled for entry->hasReachedPrevalentResourceAgeCap().
(WebKit::NetworkResourceLoader::validateCacheEntryForMaxAgeCapValidation):
    This is where the new logic compares the incoming redirect with the
    cached one. If they match, an uncapped entry is allowed to be stored.
    If they don't match, a new capped entry will be stored.
(WebKit::NetworkResourceLoader::willSendRedirectedRequest):
    Now calls the new
    NetworkResourceLoader::validateCacheEntryForMaxAgeCapValidation()
    function.
* NetworkProcess/NetworkResourceLoader.h:
    Added the m_cacheEntryForMaxAgeCapValidation member.
* NetworkProcess/cache/NetworkCache.cpp:
(WebKit::NetworkCache::makeUseDecision):
    Restored to previous behavior which means
    UseDecision::NoDueToPrevalentResourceAgeCap was removed.
(WebKit::NetworkCache::Cache::retrieve):
    Restored to previous behavior.
(WebKit::NetworkCache::Cache::storeRedirect):
    Now takes the optional maxAgeCap and caps the entry's max age if it's set.
(WebKit::NetworkCache::hasReachedPrevalentResourceAgeCap): Deleted.
* NetworkProcess/cache/NetworkCache.h:
* NetworkProcess/cache/NetworkCacheEntry.cpp:
(WebKit::NetworkCache::Entry::encodeAsStorageRecord const):
    Now encodes m_maxAgeCap.
(WebKit::NetworkCache::Entry::decodeStorageRecord):
    Now decodes m_maxAgeCap.
(WebKit::NetworkCache::Entry::hasReachedPrevalentResourceAgeCap const):
    Added.
(WebKit::NetworkCache::Entry::capMaxAge):
    Added.
* NetworkProcess/cache/NetworkCacheEntry.h:
    Added the optional m_maxAgeCap.
* NetworkProcess/cache/NetworkCacheSpeculativeLoad.cpp:
(WebKit::NetworkCache::SpeculativeLoad::willSendRedirectedRequest):
    Now gets the optional max age cap from the NetworkStorageSession and sends it
    to Cache::storeRedirect().
* NetworkProcess/cache/NetworkCacheStatistics.cpp:
(WebKit::NetworkCache::cachedEntryReuseFailureToDiagnosticKey):
    Removed handling of UseDecision::NoDueToPrevalentResourceAgeCap.

LayoutTests:

* http/tests/resourceLoadStatistics/cap-cache-max-age-for-prevalent-resource-expected.txt:
* http/tests/resourceLoadStatistics/cap-cache-max-age-for-prevalent-resource.html:
    The test now performs:
    - an initial Fetch request with a permanent redirect to ID 1234. Capped max age.
    - a second Fetch request with a permanent redirect to ID 4321. Capped max age.
    - a third Fetch request with a permanent redirect to and empty ID. Capped max age.
    - a fourth Fetch request with a permanent redirect to and empty ID. Max age cap removed.
    - a fifth Fetch request with a permanent redirect to and empty ID. Regular cache hit.
* http/tests/resourceLoadStatistics/resources/cached-permanent-redirect.php:
    Now returns an HTTP 500 if the request contains validation headers.

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (237894 => 237895)


--- trunk/LayoutTests/ChangeLog	2018-11-06 23:08:51 UTC (rev 237894)
+++ trunk/LayoutTests/ChangeLog	2018-11-06 23:10:36 UTC (rev 237895)
@@ -1,3 +1,22 @@
+2018-11-06  John Wilander  <wilan...@apple.com>
+
+        Resource Load Statistics: Remove cap on partitioned cache max age if it matches a network reload (redirect-only)
+        https://bugs.webkit.org/show_bug.cgi?id=189760
+        <rdar://problem/44612242>
+
+        Reviewed by Youenn Fablet and Antti Koivisto.
+
+        * http/tests/resourceLoadStatistics/cap-cache-max-age-for-prevalent-resource-expected.txt:
+        * http/tests/resourceLoadStatistics/cap-cache-max-age-for-prevalent-resource.html:
+            The test now performs:
+            - an initial Fetch request with a permanent redirect to ID 1234. Capped max age.
+            - a second Fetch request with a permanent redirect to ID 4321. Capped max age.
+            - a third Fetch request with a permanent redirect to and empty ID. Capped max age.
+            - a fourth Fetch request with a permanent redirect to and empty ID. Max age cap removed.
+            - a fifth Fetch request with a permanent redirect to and empty ID. Regular cache hit.
+        * http/tests/resourceLoadStatistics/resources/cached-permanent-redirect.php:
+            Now returns an HTTP 500 if the request contains validation headers.
+
 2018-11-06  Myles C. Maxfield  <mmaxfi...@apple.com>
 
         Spelling dots are drawn in the wrong place

Modified: trunk/LayoutTests/http/tests/resourceLoadStatistics/cap-cache-max-age-for-prevalent-resource-expected.txt (237894 => 237895)


--- trunk/LayoutTests/http/tests/resourceLoadStatistics/cap-cache-max-age-for-prevalent-resource-expected.txt	2018-11-06 23:08:51 UTC (rev 237894)
+++ trunk/LayoutTests/http/tests/resourceLoadStatistics/cap-cache-max-age-for-prevalent-resource-expected.txt	2018-11-06 23:10:36 UTC (rev 237895)
@@ -4,7 +4,10 @@
 
 
 PASS loadedUrl is "http://localhost:8000/resourceLoadStatistics/resources/echo-query.php?value=1234"
+PASS loadedUrl is "http://localhost:8000/resourceLoadStatistics/resources/echo-query.php?value=4321"
 PASS loadedUrl is "http://localhost:8000/resourceLoadStatistics/resources/echo-query.php?value="
+PASS loadedUrl is "http://localhost:8000/resourceLoadStatistics/resources/echo-query.php?value="
+PASS loadedUrl is "http://localhost:8000/resourceLoadStatistics/resources/echo-query.php?value="
 PASS successfullyParsed is true
 
 TEST COMPLETE

Modified: trunk/LayoutTests/http/tests/resourceLoadStatistics/cap-cache-max-age-for-prevalent-resource.html (237894 => 237895)


--- trunk/LayoutTests/http/tests/resourceLoadStatistics/cap-cache-max-age-for-prevalent-resource.html	2018-11-06 23:08:51 UTC (rev 237894)
+++ trunk/LayoutTests/http/tests/resourceLoadStatistics/cap-cache-max-age-for-prevalent-resource.html	2018-11-06 23:10:36 UTC (rev 237895)
@@ -31,15 +31,50 @@
     }
 
     function secondFetch() {
-        // This should not trigger a successful cache hit.
+        // This should not trigger a successful cache hit and instead create another capped cache entry.
         fetch("http://localhost:8000/resourceLoadStatistics/resources/cached-permanent-redirect.php",
             {
                 cache: "force-cache",
+                headers: {
+                    "X-WebKit": "4321",
+                }
             }
         ).then(function(response) {
             loadedUrl = response.url;
+            shouldBeEqualToString("loadedUrl", "http://localhost:8000/resourceLoadStatistics/resources/echo-query.php?value=4321");
+            thirdFetch();
+        }).catch(function(error) {
+            testFailed(error.message);
+            setEnableFeature(false, finishJSTest);
+        });
+    }
+
+    function thirdFetch() {
+        // This should not trigger a successful cache hit and instead create another capped cache entry.
+        fetch("http://localhost:8000/resourceLoadStatistics/resources/cached-permanent-redirect.php",
+            {
+                cache: "force-cache",
+            }
+        ).then(function(response) {
+            loadedUrl = response.url;
             shouldBeEqualToString("loadedUrl", "http://localhost:8000/resourceLoadStatistics/resources/echo-query.php?value=");
+            fourthFetch();
+        }).catch(function(error) {
+            testFailed(error.message);
             setEnableFeature(false, finishJSTest);
+        });
+    }
+
+    function fourthFetch() {
+        // This should not trigger a successful cache hit but clear capping.
+        fetch("http://localhost:8000/resourceLoadStatistics/resources/cached-permanent-redirect.php",
+            {
+                cache: "force-cache",
+            }
+        ).then(function(response) {
+            loadedUrl = response.url;
+            shouldBeEqualToString("loadedUrl", "http://localhost:8000/resourceLoadStatistics/resources/echo-query.php?value=");
+            fifthFetch();
         }).catch(function(error) {
             testFailed(error.message);
             setEnableFeature(false, finishJSTest);
@@ -46,6 +81,24 @@
         });
     }
 
+    function fifthFetch() {
+        // This should trigger a regular, successful cache hit.
+        fetch("http://localhost:8000/resourceLoadStatistics/resources/cached-permanent-redirect.php",
+            {
+                headers: {
+                    "X-WebKit": "1234",
+                }
+            }
+        ).then(function(response) {
+            loadedUrl = response.url;
+            shouldBeEqualToString("loadedUrl", "http://localhost:8000/resourceLoadStatistics/resources/echo-query.php?value=");
+            setEnableFeature(false, finishJSTest);
+        }).catch(function(error) {
+            testFailed(error.message);
+            setEnableFeature(false, finishJSTest);
+        });
+    }
+
     setEnableFeature(true, function() {
         if (testRunner.isStatisticsPrevalentResource("http://localhost"))
             testFailed("Localhost was classified as prevalent resource before the test started.");

Modified: trunk/LayoutTests/http/tests/resourceLoadStatistics/resources/cached-permanent-redirect.php (237894 => 237895)


--- trunk/LayoutTests/http/tests/resourceLoadStatistics/resources/cached-permanent-redirect.php	2018-11-06 23:08:51 UTC (rev 237894)
+++ trunk/LayoutTests/http/tests/resourceLoadStatistics/resources/cached-permanent-redirect.php	2018-11-06 23:10:36 UTC (rev 237895)
@@ -1,11 +1,15 @@
 <?php
+if (isset($_SERVER["HTTP_IF_NONE_MATCH"]) || isset($_SERVER["HTTP_IF_MODIFIED_SINCE"])) {
+    header($_SERVER["SERVER_PROTOCOL"] . " 500 Internal Server Error", true, 500);
+    exit;
+}
 header("Access-Control-Allow-Origin: http://127.0.0.1:8000");
 header("Access-Control-Allow-Headers: X-WebKit");
 if ($_SERVER["REQUEST_METHOD"] == "OPTIONS" && isset($_SERVER["HTTP_ACCESS_CONTROL_REQUEST_METHOD"]) && $_SERVER["HTTP_ACCESS_CONTROL_REQUEST_METHOD"] == "GET") {
-  exit;
+    exit;
 }
 $headerStringValue = $_SERVER["HTTP_X_WEBKIT"];
-header("HTTP/1.1 301 Moved Permanently");
+header($_SERVER["SERVER_PROTOCOL"] . " 301 Moved Permanently", true, 301);
 header("Cache-Control: private, max-age=31536000", true);
 header('ETag: "WebKitTest"', true);
 header("Location: http://localhost:8000/resourceLoadStatistics/resources/echo-query.php?value=" . $headerStringValue);

Modified: trunk/Source/WebCore/ChangeLog (237894 => 237895)


--- trunk/Source/WebCore/ChangeLog	2018-11-06 23:08:51 UTC (rev 237894)
+++ trunk/Source/WebCore/ChangeLog	2018-11-06 23:10:36 UTC (rev 237895)
@@ -1,3 +1,19 @@
+2018-11-06  John Wilander  <wilan...@apple.com>
+
+        Resource Load Statistics: Remove cap on partitioned cache max age if it matches a network reload (redirect-only)
+        https://bugs.webkit.org/show_bug.cgi?id=189760
+        <rdar://problem/44612242>
+
+        Reviewed by Youenn Fablet and Antti Koivisto.
+
+        No new tests. Existing test fleshed out.
+
+        * platform/network/ResourceResponseBase.cpp:
+        (WebCore::ResourceResponseBase::isRedirection const):
+        * platform/network/ResourceResponseBase.h:
+        (WebCore::ResourceResponseBase::isRedirection const): Deleted.
+            Moved to the implementation file so that I can export it without warning.
+
 2018-11-06  Myles C. Maxfield  <mmaxfi...@apple.com>
 
         Spelling dots are drawn in the wrong place

Modified: trunk/Source/WebCore/platform/network/ResourceResponseBase.cpp (237894 => 237895)


--- trunk/Source/WebCore/platform/network/ResourceResponseBase.cpp	2018-11-06 23:08:51 UTC (rev 237894)
+++ trunk/Source/WebCore/platform/network/ResourceResponseBase.cpp	2018-11-06 23:10:36 UTC (rev 237895)
@@ -296,6 +296,11 @@
     // FIXME: Should invalidate or update platform response if present.
 }
 
+bool ResourceResponseBase::isRedirection() const
+{
+    return isRedirectionStatusCode(m_httpStatusCode);
+}
+
 const String& ResourceResponseBase::httpStatusText() const 
 {
     lazyInit(AllFields);

Modified: trunk/Source/WebCore/platform/network/ResourceResponseBase.h (237894 => 237895)


--- trunk/Source/WebCore/platform/network/ResourceResponseBase.h	2018-11-06 23:08:51 UTC (rev 237894)
+++ trunk/Source/WebCore/platform/network/ResourceResponseBase.h	2018-11-06 23:10:36 UTC (rev 237895)
@@ -91,7 +91,7 @@
 
     WEBCORE_EXPORT int httpStatusCode() const;
     WEBCORE_EXPORT void setHTTPStatusCode(int);
-    bool isRedirection() const { return isRedirectionStatusCode(m_httpStatusCode); }
+    WEBCORE_EXPORT bool isRedirection() const;
 
     WEBCORE_EXPORT const String& httpStatusText() const;
     WEBCORE_EXPORT void setHTTPStatusText(const String&);

Modified: trunk/Source/WebKit/ChangeLog (237894 => 237895)


--- trunk/Source/WebKit/ChangeLog	2018-11-06 23:08:51 UTC (rev 237894)
+++ trunk/Source/WebKit/ChangeLog	2018-11-06 23:10:36 UTC (rev 237895)
@@ -1,3 +1,62 @@
+2018-11-06  John Wilander  <wilan...@apple.com>
+
+        Resource Load Statistics: Remove cap on partitioned cache max age if it matches a network reload (redirect-only)
+        https://bugs.webkit.org/show_bug.cgi?id=189760
+        <rdar://problem/44612242>
+
+        Reviewed by Youenn Fablet and Antti Koivisto.
+
+        When a redirect cache entry for a prevalent resource reaches its max
+        age cap, it is loaded again from the network and the network response
+        is compared with what's in the cache. If it's a match, the cache entry
+        is fully accepted. If not, a new capped cache entry is created.
+
+        This feature is still off by default.
+
+        * NetworkProcess/NetworkResourceLoader.cpp:
+        (WebKit::NetworkResourceLoader::canUseCachedRedirect const):
+            Now checks the new member m_cacheEntryForMaxAgeCapValidation.
+        (WebKit::NetworkResourceLoader::retrieveCacheEntry):
+            New case handled for entry->hasReachedPrevalentResourceAgeCap().
+        (WebKit::NetworkResourceLoader::validateCacheEntryForMaxAgeCapValidation):
+            This is where the new logic compares the incoming redirect with the
+            cached one. If they match, an uncapped entry is allowed to be stored.
+            If they don't match, a new capped entry will be stored.
+        (WebKit::NetworkResourceLoader::willSendRedirectedRequest):
+            Now calls the new
+            NetworkResourceLoader::validateCacheEntryForMaxAgeCapValidation()
+            function.
+        * NetworkProcess/NetworkResourceLoader.h:
+            Added the m_cacheEntryForMaxAgeCapValidation member.
+        * NetworkProcess/cache/NetworkCache.cpp:
+        (WebKit::NetworkCache::makeUseDecision):
+            Restored to previous behavior which means
+            UseDecision::NoDueToPrevalentResourceAgeCap was removed.
+        (WebKit::NetworkCache::Cache::retrieve):
+            Restored to previous behavior.
+        (WebKit::NetworkCache::Cache::storeRedirect):
+            Now takes the optional maxAgeCap and caps the entry's max age if it's set.
+        (WebKit::NetworkCache::hasReachedPrevalentResourceAgeCap): Deleted.
+        * NetworkProcess/cache/NetworkCache.h:
+        * NetworkProcess/cache/NetworkCacheEntry.cpp:
+        (WebKit::NetworkCache::Entry::encodeAsStorageRecord const):
+            Now encodes m_maxAgeCap.
+        (WebKit::NetworkCache::Entry::decodeStorageRecord):
+            Now decodes m_maxAgeCap.
+        (WebKit::NetworkCache::Entry::hasReachedPrevalentResourceAgeCap const):
+            Added.
+        (WebKit::NetworkCache::Entry::capMaxAge):
+            Added.
+        * NetworkProcess/cache/NetworkCacheEntry.h:
+            Added the optional m_maxAgeCap.
+        * NetworkProcess/cache/NetworkCacheSpeculativeLoad.cpp:
+        (WebKit::NetworkCache::SpeculativeLoad::willSendRedirectedRequest):
+            Now gets the optional max age cap from the NetworkStorageSession and sends it
+            to Cache::storeRedirect().
+        * NetworkProcess/cache/NetworkCacheStatistics.cpp:
+        (WebKit::NetworkCache::cachedEntryReuseFailureToDiagnosticKey):
+            Removed handling of UseDecision::NoDueToPrevalentResourceAgeCap.
+
 2018-11-06  Per Arne Vollan  <pvol...@apple.com>
 
         REGRESSION (r230523): Caps lock indicator not shown in password field

Modified: trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp (237894 => 237895)


--- trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp	2018-11-06 23:08:51 UTC (rev 237894)
+++ trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp	2018-11-06 23:10:36 UTC (rev 237895)
@@ -51,6 +51,7 @@
 #include <WebCore/HTTPHeaderNames.h>
 #include <WebCore/HTTPParsers.h>
 #include <WebCore/NetworkLoadMetrics.h>
+#include <WebCore/NetworkStorageSession.h>
 #include <WebCore/ProtectionSpace.h>
 #include <WebCore/SameSiteInfo.h>
 #include <WebCore/SecurityOrigin.h>
@@ -154,7 +155,7 @@
 
 bool NetworkResourceLoader::canUseCachedRedirect(const ResourceRequest& request) const
 {
-    if (!canUseCache(request))
+    if (!canUseCache(request) || m_cacheEntryForMaxAgeCapValidation)
         return false;
     // Limit cached redirects to avoid cycles and other trouble.
     // Networking layer follows over 30 redirects but caching that many seems unnecessary.
@@ -216,7 +217,7 @@
     ASSERT(canUseCache(request));
 
     RefPtr<NetworkResourceLoader> loader(this);
-    m_cache->retrieve(request, { m_parameters.webPageID, m_parameters.webFrameID }, sessionID(), [this, loader = WTFMove(loader), request = ResourceRequest { request }](auto entry, auto info) mutable {
+    m_cache->retrieve(request, { m_parameters.webPageID, m_parameters.webFrameID }, [this, loader = WTFMove(loader), request = ResourceRequest { request }](auto entry, auto info) mutable {
         if (loader->hasOneRef()) {
             // The loader has been aborted and is only held alive by this lambda.
             return;
@@ -229,6 +230,15 @@
             loader->startNetworkLoad(WTFMove(request), FirstLoad::Yes);
             return;
         }
+#if ENABLE(RESOURCE_LOAD_STATISTICS)
+        if (entry->hasReachedPrevalentResourceAgeCap()) {
+            RELEASE_LOG_IF_ALLOWED("retrieveCacheEntry: Resource has reached prevalent resource age cap (pageID = %" PRIu64 ", frameID = %" PRIu64 ", resourceID = %" PRIu64 ", isMainResource = %d, isSynchronous = %d)", m_parameters.webPageID, m_parameters.webFrameID, m_parameters.identifier, isMainResource(), isSynchronous());
+            m_cacheEntryForMaxAgeCapValidation = WTFMove(entry);
+            ResourceRequest revalidationRequest = originalRequest();
+            loader->startNetworkLoad(WTFMove(revalidationRequest), FirstLoad::Yes);
+            return;
+        }
+#endif
         if (entry->redirectRequest()) {
             RELEASE_LOG_IF_ALLOWED("retrieveCacheEntry: Handling redirect (pageID = %" PRIu64 ", frameID = %" PRIu64 ", resourceID = %" PRIu64 ", isMainResource = %d, isSynchronous = %d)", m_parameters.webPageID, m_parameters.webFrameID, m_parameters.identifier, isMainResource(), isSynchronous());
             loader->dispatchWillSendRequestForCacheEntry(WTFMove(request), WTFMove(entry));
@@ -584,12 +594,35 @@
     send(Messages::WebResourceLoader::DidBlockAuthenticationChallenge());
 }
 
+std::optional<Seconds> NetworkResourceLoader::validateCacheEntryForMaxAgeCapValidation(const ResourceRequest& request, const ResourceRequest& redirectRequest, const ResourceResponse& redirectResponse)
+{
+#if ENABLE(RESOURCE_LOAD_STATISTICS)
+    bool existingCacheEntryMatchesNewResponse = false;
+    if (m_cacheEntryForMaxAgeCapValidation) {
+        ASSERT(redirectResponse.source() == ResourceResponse::Source::Network);
+        ASSERT(redirectResponse.isRedirection());
+        if (redirectResponse.httpHeaderField(WebCore::HTTPHeaderName::Location) == m_cacheEntryForMaxAgeCapValidation->response().httpHeaderField(WebCore::HTTPHeaderName::Location))
+            existingCacheEntryMatchesNewResponse = true;
+
+        m_cache->remove(m_cacheEntryForMaxAgeCapValidation->key());
+        m_cacheEntryForMaxAgeCapValidation = nullptr;
+    }
+    
+    if (!existingCacheEntryMatchesNewResponse) {
+        if (auto networkStorageSession = WebCore::NetworkStorageSession::storageSession(sessionID()))
+            return networkStorageSession->maxAgeCacheCap(request);
+    }
+#endif
+    return std::nullopt;
+}
+
 void NetworkResourceLoader::willSendRedirectedRequest(ResourceRequest&& request, ResourceRequest&& redirectRequest, ResourceResponse&& redirectResponse)
 {
     ++m_redirectCount;
 
+    auto maxAgeCap = validateCacheEntryForMaxAgeCapValidation(request, redirectRequest, redirectResponse);
     if (redirectResponse.source() == ResourceResponse::Source::Network && canUseCachedRedirect(request))
-        m_cache->storeRedirect(request, redirectResponse, redirectRequest);
+        m_cache->storeRedirect(request, redirectResponse, redirectRequest, maxAgeCap);
 
     if (m_networkLoadChecker) {
         m_networkLoadChecker->storeRedirectionIfNeeded(request, redirectResponse);

Modified: trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.h (237894 => 237895)


--- trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.h	2018-11-06 23:08:51 UTC (rev 237894)
+++ trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.h	2018-11-06 23:10:36 UTC (rev 237895)
@@ -174,6 +174,8 @@
 
     void logSlowCacheRetrieveIfNeeded(const NetworkCache::Cache::RetrieveInfo&);
 
+    std::optional<Seconds> validateCacheEntryForMaxAgeCapValidation(const WebCore::ResourceRequest&, const WebCore::ResourceRequest& redirectRequest, const WebCore::ResourceResponse&);
+
     const NetworkResourceLoadParameters m_parameters;
 
     Ref<NetworkConnectionToWebProcess> m_connection;
@@ -202,6 +204,7 @@
     RefPtr<NetworkCache::Cache> m_cache;
     RefPtr<WebCore::SharedBuffer> m_bufferedDataForCache;
     std::unique_ptr<NetworkCache::Entry> m_cacheEntryForValidation;
+    std::unique_ptr<NetworkCache::Entry> m_cacheEntryForMaxAgeCapValidation;
     bool m_isWaitingContinueWillSendRequestForCachedRedirect { false };
     std::unique_ptr<NetworkCache::Entry> m_cacheEntryWaitingForContinueDidReceiveResponse;
     std::unique_ptr<NetworkLoadChecker> m_networkLoadChecker;

Modified: trunk/Source/WebKit/NetworkProcess/cache/NetworkCache.cpp (237894 => 237895)


--- trunk/Source/WebKit/NetworkProcess/cache/NetworkCache.cpp	2018-11-06 23:08:51 UTC (rev 237894)
+++ trunk/Source/WebKit/NetworkProcess/cache/NetworkCache.cpp	2018-11-06 23:10:36 UTC (rev 237895)
@@ -152,11 +152,6 @@
     return false;
 }
 
-static bool hasReachedPrevalentResourceAgeCap(const WebCore::ResourceResponse& response, WallTime timestamp, const Seconds maxAge)
-{
-    return WebCore::computeCurrentAge(response, timestamp) > maxAge;
-}
-
 static bool responseHasExpired(const WebCore::ResourceResponse& response, WallTime timestamp, std::optional<Seconds> maxStale)
 {
     if (response.cacheControlContainsNoCache())
@@ -188,11 +183,8 @@
     return responseHasExpired(response, timestamp, requestDirectives.maxStale);
 }
 
-static UseDecision makeUseDecision(const Entry& entry, const WebCore::ResourceRequest& request, std::optional<Seconds> maxAge)
+static UseDecision makeUseDecision(const Entry& entry, const WebCore::ResourceRequest& request)
 {
-    if (maxAge && hasReachedPrevalentResourceAgeCap(entry.response(), entry.timeStamp(), maxAge.value()))
-        return UseDecision::NoDueToPrevalentResourceAgeCap;
-    
     // The request is conditional so we force revalidation from the network. We merely check the disk cache
     // so we can update the cache entry.
     if (request.isConditional() && !entry.redirectRequest())
@@ -279,7 +271,7 @@
     return StoreDecision::Yes;
 }
 
-void Cache::retrieve(const WebCore::ResourceRequest& request, const GlobalFrameID& frameID, PAL::SessionID sessionID, RetrieveCompletionHandler&& completionHandler)
+void Cache::retrieve(const WebCore::ResourceRequest& request, const GlobalFrameID& frameID, RetrieveCompletionHandler&& completionHandler)
 {
     ASSERT(request.url().protocolIsInHTTPFamily());
 
@@ -323,7 +315,7 @@
     }
 #endif
 
-    m_storage->retrieve(storageKey, priority, [this, protectedThis = makeRef(*this), request, completionHandler = WTFMove(completionHandler), info = WTFMove(info), storageKey, frameID, sessionID](auto record, auto timings) mutable {
+    m_storage->retrieve(storageKey, priority, [this, protectedThis = makeRef(*this), request, completionHandler = WTFMove(completionHandler), info = WTFMove(info), storageKey, frameID](auto record, auto timings) mutable {
         info.storageTimings = timings;
 
         if (!record) {
@@ -340,12 +332,7 @@
 
         auto entry = Entry::decodeStorageRecord(*record);
 
-        std::optional<Seconds> maxAgeCap;
-#if ENABLE(RESOURCE_LOAD_STATISTICS)
-        if (auto networkStorageSession = WebCore::NetworkStorageSession::storageSession(sessionID))
-            maxAgeCap = networkStorageSession->maxAgeCacheCap(request);
-#endif
-        auto useDecision = entry ? makeUseDecision(*entry, request, maxAgeCap) : UseDecision::NoDueToDecodeFailure;
+        auto useDecision = entry ? makeUseDecision(*entry, request) : UseDecision::NoDueToDecodeFailure;
         switch (useDecision) {
         case UseDecision::Use:
             break;
@@ -352,10 +339,6 @@
         case UseDecision::Validate:
             entry->setNeedsValidation(true);
             break;
-        case UseDecision::NoDueToPrevalentResourceAgeCap:
-            entry = nullptr;
-            m_storage->remove(storageKey);
-            break;
         default:
             entry = nullptr;
         };
@@ -430,7 +413,7 @@
     return cacheEntry;
 }
 
-std::unique_ptr<Entry> Cache::storeRedirect(const WebCore::ResourceRequest& request, const WebCore::ResourceResponse& response, const WebCore::ResourceRequest& redirectRequest)
+std::unique_ptr<Entry> Cache::storeRedirect(const WebCore::ResourceRequest& request, const WebCore::ResourceResponse& response, const WebCore::ResourceRequest& redirectRequest, std::optional<Seconds> maxAgeCap)
 {
     LOG(NetworkCache, "(NetworkProcess) storing redirect %s -> %s", request.url().string().latin1().data(), redirectRequest.url().string().latin1().data());
 
@@ -445,6 +428,16 @@
     }
 
     auto cacheEntry = makeRedirectEntry(request, response, redirectRequest);
+
+#if ENABLE(RESOURCE_LOAD_STATISTICS)
+    if (maxAgeCap) {
+        LOG(NetworkCache, "(NetworkProcess) capping max age for redirect %s -> %s", request.url().string().latin1().data(), redirectRequest.url().string().latin1().data());
+        cacheEntry->capMaxAge(maxAgeCap.value());
+    }
+#else
+    UNUSED_PARAM(maxAgeCap);
+#endif
+
     auto record = cacheEntry->encodeAsStorageRecord();
 
     m_storage->store(record, nullptr);

Modified: trunk/Source/WebKit/NetworkProcess/cache/NetworkCache.h (237894 => 237895)


--- trunk/Source/WebKit/NetworkProcess/cache/NetworkCache.h	2018-11-06 23:08:51 UTC (rev 237894)
+++ trunk/Source/WebKit/NetworkProcess/cache/NetworkCache.h	2018-11-06 23:10:36 UTC (rev 237895)
@@ -31,6 +31,7 @@
 #include <WebCore/ResourceResponse.h>
 #include <wtf/Function.h>
 #include <wtf/OptionSet.h>
+#include <wtf/Seconds.h>
 #include <wtf/text/WTFString.h>
 
 namespace WebCore {
@@ -81,8 +82,7 @@
     NoDueToVaryingHeaderMismatch,
     NoDueToMissingValidatorFields,
     NoDueToDecodeFailure,
-    NoDueToExpiredRedirect,
-    NoDueToPrevalentResourceAgeCap
+    NoDueToExpiredRedirect
 };
 
 using GlobalFrameID = std::pair<uint64_t /*webPageID*/, uint64_t /*webFrameID*/>;
@@ -113,9 +113,9 @@
         WTF_MAKE_FAST_ALLOCATED;
     };
     using RetrieveCompletionHandler = Function<void (std::unique_ptr<Entry>, const RetrieveInfo&)>;
-    void retrieve(const WebCore::ResourceRequest&, const GlobalFrameID&, PAL::SessionID, RetrieveCompletionHandler&&);
+    void retrieve(const WebCore::ResourceRequest&, const GlobalFrameID&, RetrieveCompletionHandler&&);
     std::unique_ptr<Entry> store(const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, RefPtr<WebCore::SharedBuffer>&&, Function<void (MappedBody&)>&&);
-    std::unique_ptr<Entry> storeRedirect(const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, const WebCore::ResourceRequest& redirectRequest);
+    std::unique_ptr<Entry> storeRedirect(const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, const WebCore::ResourceRequest& redirectRequest, std::optional<Seconds> maxAgeCap);
     std::unique_ptr<Entry> update(const WebCore::ResourceRequest&, const GlobalFrameID&, const Entry&, const WebCore::ResourceResponse& validatingResponse);
 
     struct TraversalEntry {
@@ -156,6 +156,8 @@
     String dumpFilePath() const;
     void deleteDumpFile();
 
+    std::optional<Seconds> maxAgeCap(Entry&, const WebCore::ResourceRequest&, PAL::SessionID);
+
     Ref<Storage> m_storage;
 
 #if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)

Modified: trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheEntry.cpp (237894 => 237895)


--- trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheEntry.cpp	2018-11-06 23:08:51 UTC (rev 237894)
+++ trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheEntry.cpp	2018-11-06 23:10:36 UTC (rev 237895)
@@ -95,6 +95,8 @@
     if (isRedirect)
         m_redirectRequest->encodeWithoutPlatformData(encoder);
 
+    encoder << m_maxAgeCap;
+    
     encoder.encodeChecksum();
 
     Data header(encoder.buffer(), encoder.bufferSize());
@@ -133,6 +135,8 @@
             return nullptr;
     }
 
+    decoder.decode(entry->m_maxAgeCap);
+    
     if (!decoder.verifyChecksum()) {
         LOG(NetworkCache, "(NetworkProcess) checksum verification failure\n");
         return nullptr;
@@ -141,6 +145,18 @@
     return entry;
 }
 
+#if ENABLE(RESOURCE_LOAD_STATISTICS)
+bool Entry::hasReachedPrevalentResourceAgeCap() const
+{
+    return m_maxAgeCap && WebCore::computeCurrentAge(response(), timeStamp()) > m_maxAgeCap;
+}
+
+void Entry::capMaxAge(const Seconds seconds)
+{
+    m_maxAgeCap = seconds;
+}
+#endif
+
 #if ENABLE(SHAREABLE_RESOURCE)
 void Entry::initializeShareableResourceHandleFromStorageRecord() const
 {

Modified: trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheEntry.h (237894 => 237895)


--- trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheEntry.h	2018-11-06 23:08:51 UTC (rev 237894)
+++ trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheEntry.h	2018-11-06 23:10:36 UTC (rev 237895)
@@ -31,6 +31,7 @@
 #include <WebCore/ResourceRequest.h>
 #include <WebCore/ResourceResponse.h>
 #include <wtf/Noncopyable.h>
+#include <wtf/Seconds.h>
 #include <wtf/text/WTFString.h>
 
 namespace WebCore {
@@ -70,6 +71,11 @@
 
     void asJSON(StringBuilder&, const Storage::RecordInfo&) const;
 
+#if ENABLE(RESOURCE_LOAD_STATISTICS)
+    bool hasReachedPrevalentResourceAgeCap() const;
+    void capMaxAge(const Seconds);
+#endif
+
 private:
     void initializeBufferFromStorageRecord() const;
 #if ENABLE(SHAREABLE_RESOURCE)
@@ -88,6 +94,8 @@
 #endif
 
     Storage::Record m_sourceStorageRecord { };
+    
+    std::optional<Seconds> m_maxAgeCap;
 };
 
 }

Modified: trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoad.cpp (237894 => 237895)


--- trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoad.cpp	2018-11-06 23:08:51 UTC (rev 237894)
+++ trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoad.cpp	2018-11-06 23:10:36 UTC (rev 237895)
@@ -33,6 +33,7 @@
 #include "NetworkLoad.h"
 #include "NetworkSession.h"
 #include "SessionTracker.h"
+#include <WebCore/NetworkStorageSession.h>
 #include <pal/SessionID.h>
 #include <wtf/RunLoop.h>
 
@@ -71,7 +72,12 @@
 {
     LOG(NetworkCacheSpeculativePreloading, "Speculative redirect %s -> %s", request.url().string().utf8().data(), redirectRequest.url().string().utf8().data());
 
-    m_cacheEntry = m_cache->storeRedirect(request, redirectResponse, redirectRequest);
+    std::optional<Seconds> maxAgeCap;
+#if ENABLE(RESOURCE_LOAD_STATISTICS)
+    if (auto networkStorageSession = WebCore::NetworkStorageSession::storageSession(PAL::SessionID::defaultSessionID()))
+        maxAgeCap = networkStorageSession->maxAgeCacheCap(request);
+#endif
+    m_cacheEntry = m_cache->storeRedirect(request, redirectResponse, redirectRequest, maxAgeCap);
     // Create a synthetic cache entry if we can't store.
     if (!m_cacheEntry)
         m_cacheEntry = m_cache->makeRedirectEntry(request, redirectResponse, redirectRequest);

Modified: trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheStatistics.cpp (237894 => 237895)


--- trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheStatistics.cpp	2018-11-06 23:08:51 UTC (rev 237894)
+++ trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheStatistics.cpp	2018-11-06 23:10:36 UTC (rev 237895)
@@ -282,8 +282,6 @@
         return WebCore::DiagnosticLoggingKeys::missingValidatorFieldsKey();
     case UseDecision::NoDueToDecodeFailure:
     case UseDecision::NoDueToExpiredRedirect:
-    case UseDecision::NoDueToPrevalentResourceAgeCap:
-        return WebCore::DiagnosticLoggingKeys::otherKey();
     case UseDecision::Use:
     case UseDecision::Validate:
         ASSERT_NOT_REACHED();
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to