Title: [194313] trunk
Revision
194313
Author
[email protected]
Date
2015-12-19 05:26:38 -0800 (Sat, 19 Dec 2015)

Log Message

Cache redirects as separate entries
https://bugs.webkit.org/show_bug.cgi?id=152424

Reviewed by Alex Christensen.

Source/WebCore:

Test: http/tests/cache/disk-cache/disk-cache-redirect.html

* platform/network/ResourceRequestBase.h:

Source/WebKit2:

We are currently caching redirect chains. This has correctness issues and can be inefficient in cases
where multiple URLs redirect to the same destination.

After this patch we write a cache entry for each redirect individually.

* NetworkProcess/NetworkLoad.cpp:
(WebKit::NetworkLoad::sharedWillSendRedirectedRequest):
* NetworkProcess/NetworkLoad.h:
(WebKit::NetworkLoad::currentRequest):
(WebKit::NetworkLoad::clearCurrentRequest):
* NetworkProcess/NetworkLoadClient.h:

    Add original request as a parameter for willSendRedirectedRequest.

* NetworkProcess/NetworkResourceLoader.cpp:
(WebKit::NetworkResourceLoader::~NetworkResourceLoader):
(WebKit::NetworkResourceLoader::canUseCache):

    Factor to a function.

(WebKit::NetworkResourceLoader::isSynchronous):
(WebKit::NetworkResourceLoader::start):
(WebKit::NetworkResourceLoader::retrieveCacheEntry):

    Factor to a function.
    Call dispatchWillSendRequestForCacheEntry for cached redirects.

(WebKit::NetworkResourceLoader::startNetworkLoad):

    Make this take request as argument instead of always loading originalRequest().

(WebKit::NetworkResourceLoader::abort):
(WebKit::NetworkResourceLoader::didFinishLoading):

    Remove redirect chain code.
    Store cache entry for current request instead of the original request.

(WebKit::NetworkResourceLoader::didFailLoading):
(WebKit::NetworkResourceLoader::willSendRedirectedRequest):

    Write cache entry for redirect.

(WebKit::NetworkResourceLoader::continueWillSendRequest):

    If we are playing back cached redirect continue with another cache lookup.

(WebKit::NetworkResourceLoader::didRetrieveCacheEntry):

    No need to synthesize fake willSendRequest anymore.

(WebKit::NetworkResourceLoader::validateCacheEntry):
(WebKit::NetworkResourceLoader::dispatchWillSendRequestForCacheEntry):

    Route via web process willSendRequest so cached redirects looks exactly like network ones.

(WebKit::NetworkResourceLoader::messageSenderConnection):
* NetworkProcess/NetworkResourceLoader.h:
* NetworkProcess/cache/NetworkCache.cpp:
(WebKit::NetworkCache::makeUseDecision):

    Ignore validation headers for cached redirects.

(WebKit::NetworkCache::makeRetrieveDecision):
(WebKit::NetworkCache::makeStoreDecision):
(WebKit::NetworkCache::Cache::retrieve):
(WebKit::NetworkCache::Cache::store):

    Rename originalRequest -> request since it is not really the original request anymore in all cases.

(WebKit::NetworkCache::Cache::storeRedirect):

    Stored redirects include the network layer generated ResourceRequest instead of body data.

(WebKit::NetworkCache::Cache::update):
* NetworkProcess/cache/NetworkCache.h:
* NetworkProcess/cache/NetworkCacheEntry.cpp:
(WebKit::NetworkCache::Entry::Entry):

    New constructor for making redirect entries.

(WebKit::NetworkCache::Entry::encodeAsStorageRecord):
(WebKit::NetworkCache::Entry::decodeStorageRecord):

    Encoding support.

* NetworkProcess/cache/NetworkCacheEntry.h:
(WebKit::NetworkCache::Entry::varyingRequestHeaders):
(WebKit::NetworkCache::Entry::redirectRequest):
* NetworkProcess/cache/NetworkCacheSpeculativeLoad.cpp:
(WebKit::NetworkCache::SpeculativeLoad::~SpeculativeLoad):
(WebKit::NetworkCache::SpeculativeLoad::willSendRedirectedRequest):
* NetworkProcess/cache/NetworkCacheSpeculativeLoad.h:
* NetworkProcess/cache/NetworkCacheStatistics.cpp:
(WebKit::NetworkCache::cachedEntryReuseFailureToDiagnosticKey):

LayoutTests:

* http/tests/cache/disk-cache/disk-cache-redirect-expected.txt: Added.
* http/tests/cache/disk-cache/disk-cache-redirect.html: Added.
* http/tests/cache/disk-cache/resources/generate-response.cgi:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (194312 => 194313)


--- trunk/LayoutTests/ChangeLog	2015-12-19 09:01:00 UTC (rev 194312)
+++ trunk/LayoutTests/ChangeLog	2015-12-19 13:26:38 UTC (rev 194313)
@@ -1,3 +1,14 @@
+2015-12-18  Antti Koivisto  <[email protected]>
+
+        Cache redirects as separate entries
+        https://bugs.webkit.org/show_bug.cgi?id=152424
+
+        Reviewed by Alex Christensen.
+
+        * http/tests/cache/disk-cache/disk-cache-redirect-expected.txt: Added.
+        * http/tests/cache/disk-cache/disk-cache-redirect.html: Added.
+        * http/tests/cache/disk-cache/resources/generate-response.cgi:
+
 2015-12-18  Michael Catanzaro  <[email protected]>
 
         [GTK] Mark fast/regions/overflow/overflow-region-float.html as passing

Added: trunk/LayoutTests/http/tests/cache/disk-cache/disk-cache-redirect-expected.txt (0 => 194313)


--- trunk/LayoutTests/http/tests/cache/disk-cache/disk-cache-redirect-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/cache/disk-cache/disk-cache-redirect-expected.txt	2015-12-19 13:26:38 UTC (rev 194313)
@@ -0,0 +1,122 @@
+Test redirect caching
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+running 12 tests
+
+--------Testing loads from disk cache--------
+response headers: {"Status":"301","Location":"unique-cacheable"}
+response source: Disk cache
+
+response headers: {"Status":"302","Location":"unique-cacheable"}
+response source: Network
+
+response headers: {"Status":"303","Location":"unique-cacheable"}
+response source: Network
+
+response headers: {"Status":"307","Location":"unique-cacheable"}
+response source: Network
+
+response headers: {"Status":"301","Location":"unique-cacheable","Cache-control":"max-age=0"}
+response source: Network
+
+response headers: {"Status":"302","Location":"unique-cacheable","Cache-control":"max-age=0"}
+response source: Network
+
+response headers: {"Status":"303","Location":"unique-cacheable","Cache-control":"max-age=0"}
+response source: Network
+
+response headers: {"Status":"307","Location":"unique-cacheable","Cache-control":"max-age=0"}
+response source: Network
+
+response headers: {"Status":"301","Location":"unique-cacheable","Cache-control":"max-age=100"}
+response source: Disk cache
+
+response headers: {"Status":"302","Location":"unique-cacheable","Cache-control":"max-age=100"}
+response source: Disk cache
+
+response headers: {"Status":"303","Location":"unique-cacheable","Cache-control":"max-age=100"}
+response source: Disk cache
+
+response headers: {"Status":"307","Location":"unique-cacheable","Cache-control":"max-age=100"}
+response source: Disk cache
+
+--------Testing loads through memory cache (XHR behavior)--------
+response headers: {"Status":"301","Location":"unique-cacheable"}
+response source: Memory cache
+
+response headers: {"Status":"302","Location":"unique-cacheable"}
+response source: Network
+
+response headers: {"Status":"303","Location":"unique-cacheable"}
+response source: Network
+
+response headers: {"Status":"307","Location":"unique-cacheable"}
+response source: Network
+
+response headers: {"Status":"301","Location":"unique-cacheable","Cache-control":"max-age=0"}
+response source: Network
+
+response headers: {"Status":"302","Location":"unique-cacheable","Cache-control":"max-age=0"}
+response source: Network
+
+response headers: {"Status":"303","Location":"unique-cacheable","Cache-control":"max-age=0"}
+response source: Network
+
+response headers: {"Status":"307","Location":"unique-cacheable","Cache-control":"max-age=0"}
+response source: Network
+
+response headers: {"Status":"301","Location":"unique-cacheable","Cache-control":"max-age=100"}
+response source: Memory cache
+
+response headers: {"Status":"302","Location":"unique-cacheable","Cache-control":"max-age=100"}
+response source: Memory cache
+
+response headers: {"Status":"303","Location":"unique-cacheable","Cache-control":"max-age=100"}
+response source: Memory cache
+
+response headers: {"Status":"307","Location":"unique-cacheable","Cache-control":"max-age=100"}
+response source: Memory cache
+
+--------Testing loads through memory cache (subresource behavior)--------
+response headers: {"Status":"301","Location":"unique-cacheable"}
+response source: Memory cache
+
+response headers: {"Status":"302","Location":"unique-cacheable"}
+response source: Network
+
+response headers: {"Status":"303","Location":"unique-cacheable"}
+response source: Network
+
+response headers: {"Status":"307","Location":"unique-cacheable"}
+response source: Network
+
+response headers: {"Status":"301","Location":"unique-cacheable","Cache-control":"max-age=0"}
+response source: Network
+
+response headers: {"Status":"302","Location":"unique-cacheable","Cache-control":"max-age=0"}
+response source: Network
+
+response headers: {"Status":"303","Location":"unique-cacheable","Cache-control":"max-age=0"}
+response source: Network
+
+response headers: {"Status":"307","Location":"unique-cacheable","Cache-control":"max-age=0"}
+response source: Network
+
+response headers: {"Status":"301","Location":"unique-cacheable","Cache-control":"max-age=100"}
+response source: Memory cache
+
+response headers: {"Status":"302","Location":"unique-cacheable","Cache-control":"max-age=100"}
+response source: Memory cache
+
+response headers: {"Status":"303","Location":"unique-cacheable","Cache-control":"max-age=100"}
+response source: Memory cache
+
+response headers: {"Status":"307","Location":"unique-cacheable","Cache-control":"max-age=100"}
+response source: Memory cache
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/http/tests/cache/disk-cache/disk-cache-redirect.html (0 => 194313)


--- trunk/LayoutTests/http/tests/cache/disk-cache/disk-cache-redirect.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/cache/disk-cache/disk-cache-redirect.html	2015-12-19 13:26:38 UTC (rev 194313)
@@ -0,0 +1,31 @@
+<script src=""
+<script src=""
+<body>
+<script>
+
+var testMatrix =
+[
+ [
+  { responseHeaders: {'Status': '301', 'Location': 'unique-cacheable' } },
+  { responseHeaders: {'Status': '302', 'Location': 'unique-cacheable' } },
+  { responseHeaders: {'Status': '303', 'Location': 'unique-cacheable' } },
+  { responseHeaders: {'Status': '307', 'Location': 'unique-cacheable' } },
+  ],
+ [
+  { },
+  { responseHeaders: {'Cache-control': 'max-age=0' } },
+  { responseHeaders: {'Cache-control': 'max-age=100' } },
+  ],
+ ];
+
+description("Test redirect caching");
+
+var tests = generateTests(testMatrix);
+
+debug("running " + tests.length + " tests");
+debug("");
+
+runTests(tests);
+
+</script>
+<script src=""

Modified: trunk/LayoutTests/http/tests/cache/disk-cache/resources/generate-response.cgi (194312 => 194313)


--- trunk/LayoutTests/http/tests/cache/disk-cache/resources/generate-response.cgi	2015-12-19 09:01:00 UTC (rev 194312)
+++ trunk/LayoutTests/http/tests/cache/disk-cache/resources/generate-response.cgi	2015-12-19 13:26:38 UTC (rev 194313)
@@ -8,12 +8,24 @@
 my $expiresInFutureIn304 = $query->param('expires-in-future-in-304') || 0;
 my $delay = $query->param('delay') || 0;
 my $body = $query->param('body') || 0;
+my $status = $query->param('Status') || 0;
 
 if ($body eq "unique") {
     $body = sprintf "%08X\n", rand(0xffffffff)
 }
 
 my $hasStatusCode = 0;
+my $hasLocation = 0;
+if ($status == 301 || $status == 302 || $status == 303 || $status == 307) {
+    if ($query->param('Location') eq "unique-cacheable") {
+        my $redirectBody = sprintf "%08X", rand(0xffffffff);
+        print "Status: ". $status . "\n";
+        print "Location: generate-response.cgi?body=" . $redirectBody . "&Cache-control=max-age%3D1000&uniqueId=" . $query->param('uniqueId') . "\n";
+        $hasLocation = 1;
+        $hasStatusCode = 1;
+    }
+}
+
 my $hasExpiresHeader = 0;
 if ($query->http && $query->http("If-None-Match") eq "match") {
     print "Status: 304\n";
@@ -29,7 +41,7 @@
     if ($1 < 6 && $2 < 6) {
         print "Status: 206\n";
     } else {
-	print "Status: 416\n";
+        print "Status: 416\n";
     }
 
     $hasStatusCode = 1;
@@ -39,6 +51,7 @@
     next if ($_ eq "uniqueId");
     next if ($_ eq "delay");
     next if ($_ eq "body");
+    next if ($_ eq "Location" and $hasLocation);
     next if ($_ eq "Status" and $hasStatusCode);
     next if ($_ eq "Expires" and $hasExpiresHeader);
     print $_ . ": " . $query->param($_) . "\n";

Modified: trunk/Source/WebCore/ChangeLog (194312 => 194313)


--- trunk/Source/WebCore/ChangeLog	2015-12-19 09:01:00 UTC (rev 194312)
+++ trunk/Source/WebCore/ChangeLog	2015-12-19 13:26:38 UTC (rev 194313)
@@ -1,3 +1,14 @@
+2015-12-18  Antti Koivisto  <[email protected]>
+
+        Cache redirects as separate entries
+        https://bugs.webkit.org/show_bug.cgi?id=152424
+
+        Reviewed by Alex Christensen.
+
+        Test: http/tests/cache/disk-cache/disk-cache-redirect.html
+
+        * platform/network/ResourceRequestBase.h:
+
 2015-12-18  Per Arne Vollan  <[email protected]>
 
         [WinCairo] Empty context menu item.

Modified: trunk/Source/WebCore/platform/network/ResourceRequestBase.h (194312 => 194313)


--- trunk/Source/WebCore/platform/network/ResourceRequestBase.h	2015-12-19 09:01:00 UTC (rev 194312)
+++ trunk/Source/WebCore/platform/network/ResourceRequestBase.h	2015-12-19 13:26:38 UTC (rev 194313)
@@ -54,10 +54,10 @@
     class ResourceRequestBase {
         WTF_MAKE_FAST_ALLOCATED;
     public:
-        static std::unique_ptr<ResourceRequest> adopt(std::unique_ptr<CrossThreadResourceRequestData>);
+        WEBCORE_EXPORT static std::unique_ptr<ResourceRequest> adopt(std::unique_ptr<CrossThreadResourceRequestData>);
 
         // Gets a copy of the data suitable for passing to another thread.
-        std::unique_ptr<CrossThreadResourceRequestData> copyData() const;
+        WEBCORE_EXPORT std::unique_ptr<CrossThreadResourceRequestData> copyData() const;
 
         WEBCORE_EXPORT bool isNull() const;
         WEBCORE_EXPORT bool isEmpty() const;

Modified: trunk/Source/WebKit2/ChangeLog (194312 => 194313)


--- trunk/Source/WebKit2/ChangeLog	2015-12-19 09:01:00 UTC (rev 194312)
+++ trunk/Source/WebKit2/ChangeLog	2015-12-19 13:26:38 UTC (rev 194313)
@@ -1,3 +1,105 @@
+2015-12-18  Antti Koivisto  <[email protected]>
+
+        Cache redirects as separate entries
+        https://bugs.webkit.org/show_bug.cgi?id=152424
+
+        Reviewed by Alex Christensen.
+
+        We are currently caching redirect chains. This has correctness issues and can be inefficient in cases
+        where multiple URLs redirect to the same destination.
+
+        After this patch we write a cache entry for each redirect individually.
+
+        * NetworkProcess/NetworkLoad.cpp:
+        (WebKit::NetworkLoad::sharedWillSendRedirectedRequest):
+        * NetworkProcess/NetworkLoad.h:
+        (WebKit::NetworkLoad::currentRequest):
+        (WebKit::NetworkLoad::clearCurrentRequest):
+        * NetworkProcess/NetworkLoadClient.h:
+
+            Add original request as a parameter for willSendRedirectedRequest.
+
+        * NetworkProcess/NetworkResourceLoader.cpp:
+        (WebKit::NetworkResourceLoader::~NetworkResourceLoader):
+        (WebKit::NetworkResourceLoader::canUseCache):
+
+            Factor to a function.
+
+        (WebKit::NetworkResourceLoader::isSynchronous):
+        (WebKit::NetworkResourceLoader::start):
+        (WebKit::NetworkResourceLoader::retrieveCacheEntry):
+
+            Factor to a function.
+            Call dispatchWillSendRequestForCacheEntry for cached redirects.
+
+        (WebKit::NetworkResourceLoader::startNetworkLoad):
+
+            Make this take request as argument instead of always loading originalRequest().
+
+        (WebKit::NetworkResourceLoader::abort):
+        (WebKit::NetworkResourceLoader::didFinishLoading):
+
+            Remove redirect chain code.
+            Store cache entry for current request instead of the original request.
+
+        (WebKit::NetworkResourceLoader::didFailLoading):
+        (WebKit::NetworkResourceLoader::willSendRedirectedRequest):
+
+            Write cache entry for redirect.
+
+        (WebKit::NetworkResourceLoader::continueWillSendRequest):
+
+            If we are playing back cached redirect continue with another cache lookup.
+
+        (WebKit::NetworkResourceLoader::didRetrieveCacheEntry):
+
+            No need to synthesize fake willSendRequest anymore.
+
+        (WebKit::NetworkResourceLoader::validateCacheEntry):
+        (WebKit::NetworkResourceLoader::dispatchWillSendRequestForCacheEntry):
+
+            Route via web process willSendRequest so cached redirects looks exactly like network ones.
+
+        (WebKit::NetworkResourceLoader::messageSenderConnection):
+        * NetworkProcess/NetworkResourceLoader.h:
+        * NetworkProcess/cache/NetworkCache.cpp:
+        (WebKit::NetworkCache::makeUseDecision):
+
+            Ignore validation headers for cached redirects.
+
+        (WebKit::NetworkCache::makeRetrieveDecision):
+        (WebKit::NetworkCache::makeStoreDecision):
+        (WebKit::NetworkCache::Cache::retrieve):
+        (WebKit::NetworkCache::Cache::store):
+
+            Rename originalRequest -> request since it is not really the original request anymore in all cases.
+
+        (WebKit::NetworkCache::Cache::storeRedirect):
+
+            Stored redirects include the network layer generated ResourceRequest instead of body data.
+
+        (WebKit::NetworkCache::Cache::update):
+        * NetworkProcess/cache/NetworkCache.h:
+        * NetworkProcess/cache/NetworkCacheEntry.cpp:
+        (WebKit::NetworkCache::Entry::Entry):
+
+            New constructor for making redirect entries.
+
+        (WebKit::NetworkCache::Entry::encodeAsStorageRecord):
+        (WebKit::NetworkCache::Entry::decodeStorageRecord):
+
+            Encoding support.
+
+        * NetworkProcess/cache/NetworkCacheEntry.h:
+        (WebKit::NetworkCache::Entry::varyingRequestHeaders):
+        (WebKit::NetworkCache::Entry::redirectRequest):
+        * NetworkProcess/cache/NetworkCacheSpeculativeLoad.cpp:
+        (WebKit::NetworkCache::SpeculativeLoad::~SpeculativeLoad):
+        (WebKit::NetworkCache::SpeculativeLoad::willSendRedirectedRequest):
+        * NetworkProcess/cache/NetworkCacheSpeculativeLoad.h:
+        * NetworkProcess/cache/NetworkCacheStatistics.cpp:
+        (WebKit::NetworkCache::cachedEntryReuseFailureToDiagnosticKey):
+
 2015-12-18  Michael Catanzaro  <[email protected]>
 
         Avoid triggering clang's -Wundefined-bool-conversion

Modified: trunk/Source/WebKit2/NetworkProcess/NetworkLoad.cpp (194312 => 194313)


--- trunk/Source/WebKit2/NetworkProcess/NetworkLoad.cpp	2015-12-19 09:01:00 UTC (rev 194312)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkLoad.cpp	2015-12-19 13:26:38 UTC (rev 194313)
@@ -149,8 +149,9 @@
     ASSERT(!redirectResponse.isNull());
     ASSERT(RunLoop::isMain());
 
+    auto oldRequest = m_currentRequest;
     m_currentRequest = request;
-    m_client.willSendRedirectedRequest(request, redirectResponse);
+    m_client.willSendRedirectedRequest(oldRequest, request, redirectResponse);
 }
 
 #if USE(NETWORK_SESSION)

Modified: trunk/Source/WebKit2/NetworkProcess/NetworkLoad.h (194312 => 194313)


--- trunk/Source/WebKit2/NetworkProcess/NetworkLoad.h	2015-12-19 09:01:00 UTC (rev 194312)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkLoad.h	2015-12-19 13:26:38 UTC (rev 194313)
@@ -53,6 +53,7 @@
     void setDefersLoading(bool);
     void cancel();
 
+    const WebCore::ResourceRequest& currentRequest() const { return m_currentRequest; }
     void clearCurrentRequest() { m_currentRequest = WebCore::ResourceRequest(); }
 
     void continueWillSendRequest(const WebCore::ResourceRequest&);

Modified: trunk/Source/WebKit2/NetworkProcess/NetworkLoadClient.h (194312 => 194313)


--- trunk/Source/WebKit2/NetworkProcess/NetworkLoadClient.h	2015-12-19 09:01:00 UTC (rev 194312)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkLoadClient.h	2015-12-19 13:26:38 UTC (rev 194313)
@@ -50,7 +50,7 @@
 
     virtual void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) = 0;
     virtual void canAuthenticateAgainstProtectionSpaceAsync(const WebCore::ProtectionSpace&) = 0;
-    virtual void willSendRedirectedRequest(const WebCore::ResourceRequest&, const WebCore::ResourceResponse& redirectResponse) = 0;
+    virtual void willSendRedirectedRequest(const WebCore::ResourceRequest&, const WebCore::ResourceRequest& redirectRequest, const WebCore::ResourceResponse& redirectResponse) = 0;
     enum class ShouldContinueDidReceiveResponse { No, Yes };
     virtual ShouldContinueDidReceiveResponse didReceiveResponse(const WebCore::ResourceResponse&) = 0;
     virtual void didReceiveBuffer(RefPtr<WebCore::SharedBuffer>&&, int reportedEncodedDataLength) = 0;

Modified: trunk/Source/WebKit2/NetworkProcess/NetworkResourceLoader.cpp (194312 => 194313)


--- trunk/Source/WebKit2/NetworkProcess/NetworkResourceLoader.cpp	2015-12-19 09:01:00 UTC (rev 194312)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkResourceLoader.cpp	2015-12-19 13:26:38 UTC (rev 194313)
@@ -107,6 +107,19 @@
     ASSERT(!isSynchronous() || !m_synchronousLoadData->delayedReply);
 }
 
+#if ENABLE(NETWORK_CACHE)
+bool NetworkResourceLoader::canUseCache(const ResourceRequest& request) const
+{
+    if (!NetworkCache::singleton().isEnabled())
+        return false;
+    if (sessionID().isEphemeral())
+        return false;
+    if (!request.url().protocolIsInHTTPFamily())
+        return false;
+    return true;
+}
+#endif
+
 bool NetworkResourceLoader::isSynchronous() const
 {
     return !!m_synchronousLoadData;
@@ -120,23 +133,36 @@
         return;
 
 #if ENABLE(NETWORK_CACHE)
-    if (!NetworkCache::singleton().isEnabled() || sessionID().isEphemeral() || !originalRequest().url().protocolIsInHTTPFamily()) {
-        startNetworkLoad();
+    if (canUseCache(originalRequest())) {
+        retrieveCacheEntry(originalRequest());
         return;
     }
+#endif
 
+    startNetworkLoad(originalRequest());
+}
+
+#if ENABLE(NETWORK_CACHE)
+void NetworkResourceLoader::retrieveCacheEntry(const ResourceRequest& request)
+{
+    ASSERT(canUseCache(request));
+
     RefPtr<NetworkResourceLoader> loader(this);
-    NetworkCache::singleton().retrieve(originalRequest(), { m_parameters.webPageID, m_parameters.webFrameID }, [loader](std::unique_ptr<NetworkCache::Entry> entry) {
+    NetworkCache::singleton().retrieve(request, { m_parameters.webPageID, m_parameters.webFrameID }, [loader, request](std::unique_ptr<NetworkCache::Entry> entry) {
         if (loader->hasOneRef()) {
             // The loader has been aborted and is only held alive by this lambda.
             return;
         }
         if (!entry) {
-            loader->startNetworkLoad();
+            loader->startNetworkLoad(request);
             return;
         }
+        if (entry->redirectRequest()) {
+            loader->dispatchWillSendRequestForCacheEntry(WTF::move(entry));
+            return;
+        }
         if (loader->m_parameters.needsCertificateInfo && !entry->response().containsCertificateInfo()) {
-            loader->startNetworkLoad();
+            loader->startNetworkLoad(request);
             return;
         }
         if (entry->needsValidation()) {
@@ -145,12 +171,10 @@
         }
         loader->didRetrieveCacheEntry(WTF::move(entry));
     });
-#else
-    startNetworkLoad();
+}
 #endif
-}
 
-void NetworkResourceLoader::startNetworkLoad(const Optional<ResourceRequest>& updatedRequest)
+void NetworkResourceLoader::startNetworkLoad(const ResourceRequest& request)
 {
     consumeSandboxExtensions();
 
@@ -158,14 +182,13 @@
         m_bufferedData = SharedBuffer::create();
 
 #if ENABLE(NETWORK_CACHE)
-    if (NetworkCache::singleton().isEnabled())
+    if (canUseCache(request))
         m_bufferedDataForCache = SharedBuffer::create();
 #endif
 
     NetworkLoadParameters parameters = m_parameters;
     parameters.defersLoading = m_defersLoading;
-    if (updatedRequest)
-        parameters.request = updatedRequest.value();
+    parameters.request = request;
     m_networkLoad = std::make_unique<NetworkLoad>(*this, parameters);
 }
 
@@ -212,15 +235,14 @@
     ASSERT(RunLoop::isMain());
 
     if (m_networkLoad && !m_didConvertToDownload) {
-        m_networkLoad->cancel();
-
 #if ENABLE(NETWORK_CACHE)
-        if (NetworkCache::singleton().isEnabled()) {
+        if (canUseCache(m_networkLoad->currentRequest())) {
             // We might already have used data from this incomplete load. Ensure older versions don't remain in the cache after cancel.
             if (!m_response.isNull())
-                NetworkCache::singleton().remove(originalRequest());
+                NetworkCache::singleton().remove(m_networkLoad->currentRequest());
         }
 #endif
+        m_networkLoad->cancel();
     }
 
     cleanup();
@@ -302,7 +324,7 @@
 void NetworkResourceLoader::didFinishLoading(double finishTime)
 {
 #if ENABLE(NETWORK_CACHE)
-    if (NetworkCache::singleton().isEnabled()) {
+    if (canUseCache(m_networkLoad->currentRequest())) {
         if (m_cacheEntryForValidation) {
             // 304 Not Modified
             ASSERT(m_response.httpStatusCode() == 304);
@@ -310,21 +332,13 @@
             didRetrieveCacheEntry(WTF::move(m_cacheEntryForValidation));
             return;
         }
-        bool allowStale = originalRequest().cachePolicy() >= ReturnCacheDataElseLoad;
-        bool hasCacheableRedirect = m_response.isHTTP() && redirectChainAllowsReuse(m_redirectChainCacheStatus, allowStale ? ReuseExpiredRedirection : DoNotReuseExpiredRedirection);
-        if (hasCacheableRedirect && m_redirectChainCacheStatus.status == RedirectChainCacheStatus::CachedRedirection) {
-            // Maybe we should cache the actual redirects instead of the end result?
-            auto now = std::chrono::system_clock::now();
-            auto responseEndOfValidity = now + computeFreshnessLifetimeForHTTPFamily(m_response, now) - computeCurrentAge(m_response, now);
-            hasCacheableRedirect = responseEndOfValidity <= m_redirectChainCacheStatus.endOfValidity;
-        }
 
         bool isPrivateSession = sessionID().isEphemeral();
-        if (m_bufferedDataForCache && hasCacheableRedirect && !isPrivateSession) {
+        if (m_bufferedDataForCache && m_response.isHTTP() && !isPrivateSession) {
             // Keep the connection alive.
             RefPtr<NetworkConnectionToWebProcess> connection(&connectionToWebProcess());
             RefPtr<NetworkResourceLoader> loader(this);
-            NetworkCache::singleton().store(originalRequest(), m_response, WTF::move(m_bufferedDataForCache), [loader, connection](NetworkCache::MappedBody& mappedBody) {
+            NetworkCache::singleton().store(m_networkLoad->currentRequest(), m_response, WTF::move(m_bufferedDataForCache), [loader, connection](NetworkCache::MappedBody& mappedBody) {
 #if ENABLE(SHAREABLE_RESOURCE)
                 if (mappedBody.shareableResourceHandle.isNull())
                     return;
@@ -332,9 +346,6 @@
                 loader->send(Messages::NetworkProcessConnection::DidCacheResource(loader->originalRequest(), mappedBody.shareableResourceHandle, loader->sessionID()));
 #endif
             });
-        } else if (!hasCacheableRedirect) {
-            // Make sure we don't keep a stale entry in the cache.
-            NetworkCache::singleton().remove(originalRequest());
         }
     }
 #endif
@@ -371,17 +382,13 @@
     cleanup();
 }
 
-void NetworkResourceLoader::willSendRedirectedRequest(const ResourceRequest& request, const ResourceResponse& redirectResponse)
+void NetworkResourceLoader::willSendRedirectedRequest(const ResourceRequest& request, const WebCore::ResourceRequest& redirectRequest, const ResourceResponse& redirectResponse)
 {
-#if ENABLE(NETWORK_CACHE)
-    updateRedirectChainStatus(m_redirectChainCacheStatus, redirectResponse);
-#endif
-
     if (isSynchronous()) {
-        ResourceRequest overridenRequest = request;
+        ResourceRequest overridenRequest = redirectRequest;
         // FIXME: This needs to be fixed to follow the redirect correctly even for cross-domain requests.
         // This includes at least updating host records, and comparing the current request instead of the original request here.
-        if (!protocolHostAndPortAreEqual(originalRequest().url(), request.url())) {
+        if (!protocolHostAndPortAreEqual(originalRequest().url(), redirectRequest.url())) {
             ASSERT(m_synchronousLoadData->error.isNull());
             m_synchronousLoadData->error = SynchronousLoaderClient::platformBadResponseError();
             m_networkLoad->clearCurrentRequest();
@@ -390,11 +397,30 @@
         continueWillSendRequest(overridenRequest);
         return;
     }
-    sendAbortingOnFailure(Messages::WebResourceLoader::WillSendRequest(request, redirectResponse));
+    sendAbortingOnFailure(Messages::WebResourceLoader::WillSendRequest(redirectRequest, redirectResponse));
+
+#if ENABLE(NETWORK_CACHE)
+    if (canUseCache(request))
+        NetworkCache::singleton().storeRedirect(request, redirectResponse, redirectRequest);
+#else
+    UNUSED_PARAM(request);
+#endif
 }
-    
+
 void NetworkResourceLoader::continueWillSendRequest(const ResourceRequest& newRequest)
 {
+#if ENABLE(NETWORK_CACHE)
+    if (m_isWaitingContinueWillSendRequestForCachedRedirect) {
+        LOG(NetworkCache, "(NetworkProcess) Retrieving cached redirect");
+        if (canUseCache(newRequest))
+            retrieveCacheEntry(newRequest);
+        else
+            startNetworkLoad(newRequest);
+
+        m_isWaitingContinueWillSendRequestForCachedRedirect = false;
+        return;
+    }
+#endif
     m_networkLoad->continueWillSendRequest(newRequest);
 }
 
@@ -463,14 +489,6 @@
         m_synchronousLoadData->response = entry->response();
         sendReplyToSynchronousRequest(*m_synchronousLoadData, entry->buffer());
     } else {
-        if (entry->response().url() != originalRequest().url()) {
-            // This is a cached redirect. Synthesize a minimal redirect so we get things like referer header right.
-            // FIXME: We should cache the actual redirects.
-            ResourceRequest syntheticRedirectRequest(entry->response().url());
-            ResourceResponse syntheticRedirectResponse(originalRequest().url(), { }, 0, { });
-            sendAbortingOnFailure(Messages::WebResourceLoader::WillSendRequest(syntheticRedirectRequest, syntheticRedirectResponse));
-        }
-
         bool needsContinueDidReceiveResponseMessage = originalRequest().requester() == ResourceRequest::Requester::Main;
         sendAbortingOnFailure(Messages::WebResourceLoader::DidReceiveResponse(entry->response(), needsContinueDidReceiveResponseMessage));
 
@@ -511,6 +529,15 @@
 
     startNetworkLoad(revalidationRequest);
 }
+
+void NetworkResourceLoader::dispatchWillSendRequestForCacheEntry(std::unique_ptr<NetworkCache::Entry> entry)
+{
+    ASSERT(entry->redirectRequest());
+    LOG(NetworkCache, "(NetworkProcess) Executing cached redirect");
+
+    sendAbortingOnFailure(Messages::WebResourceLoader::WillSendRequest(*entry->redirectRequest(), entry->response()));
+    m_isWaitingContinueWillSendRequestForCachedRedirect = true;
+}
 #endif
 
 IPC::Connection* NetworkResourceLoader::messageSenderConnection()

Modified: trunk/Source/WebKit2/NetworkProcess/NetworkResourceLoader.h (194312 => 194313)


--- trunk/Source/WebKit2/NetworkProcess/NetworkResourceLoader.h	2015-12-19 09:01:00 UTC (rev 194312)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkResourceLoader.h	2015-12-19 13:26:38 UTC (rev 194313)
@@ -61,6 +61,10 @@
 
     NetworkLoad* networkLoad() const { return m_networkLoad.get(); }
 
+#if ENABLE(NETWORK_CACHE)
+    bool canUseCache(const WebCore::ResourceRequest&) const;
+#endif
+
     void start();
     void abort();
 
@@ -97,7 +101,7 @@
     virtual void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) override;
     virtual void canAuthenticateAgainstProtectionSpaceAsync(const WebCore::ProtectionSpace&) override;
     virtual bool isSynchronous() const override;
-    virtual void willSendRedirectedRequest(const WebCore::ResourceRequest&, const WebCore::ResourceResponse& redirectResponse) override;
+    virtual void willSendRedirectedRequest(const WebCore::ResourceRequest&, const WebCore::ResourceRequest& redirectRequest, const WebCore::ResourceResponse& redirectResponse) override;
     virtual ShouldContinueDidReceiveResponse didReceiveResponse(const WebCore::ResourceResponse&) override;
     virtual void didReceiveBuffer(RefPtr<WebCore::SharedBuffer>&&, int reportedEncodedDataLength) override;
     virtual void didFinishLoading(double finishTime) override;
@@ -112,11 +116,13 @@
     virtual uint64_t messageSenderDestinationID() override { return m_parameters.identifier; }
 
 #if ENABLE(NETWORK_CACHE)
+    void retrieveCacheEntry(const WebCore::ResourceRequest&);
     void didRetrieveCacheEntry(std::unique_ptr<NetworkCache::Entry>);
     void validateCacheEntry(std::unique_ptr<NetworkCache::Entry>);
+    void dispatchWillSendRequestForCacheEntry(std::unique_ptr<NetworkCache::Entry>);
 #endif
 
-    void startNetworkLoad(const Optional<WebCore::ResourceRequest>& updatedRequest = { });
+    void startNetworkLoad(const WebCore::ResourceRequest&);
     void continueDidReceiveResponse();
 
     void cleanup();
@@ -155,8 +161,7 @@
 #if ENABLE(NETWORK_CACHE)
     RefPtr<WebCore::SharedBuffer> m_bufferedDataForCache;
     std::unique_ptr<NetworkCache::Entry> m_cacheEntryForValidation;
-
-    WebCore::RedirectChainCacheStatus m_redirectChainCacheStatus;
+    bool m_isWaitingContinueWillSendRequestForCachedRedirect { false };
 #endif
 };
 

Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.cpp (194312 => 194313)


--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.cpp	2015-12-19 09:01:00 UTC (rev 194312)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.cpp	2015-12-19 13:26:38 UTC (rev 194313)
@@ -220,7 +220,7 @@
 {
     // 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())
+    if (request.isConditional() && !entry.redirectRequest())
         return UseDecision::Validate;
 
     if (!verifyVaryingRequestHeaders(entry.varyingRequestHeaders(), request))
@@ -236,7 +236,7 @@
     if (!entry.response().hasCacheValidatorFields())
         return UseDecision::NoDueToMissingValidatorFields;
 
-    return UseDecision::Validate;
+    return entry.redirectRequest() ? UseDecision::NoDueToExpiredRedirect : UseDecision::Validate;
 }
 
 static RetrieveDecision makeRetrieveDecision(const WebCore::ResourceRequest& request)
@@ -343,35 +343,35 @@
     return StoreDecision::Yes;
 }
 
-void Cache::retrieve(const WebCore::ResourceRequest& originalRequest, const GlobalFrameID& frameID, std::function<void (std::unique_ptr<Entry>)> completionHandler)
+void Cache::retrieve(const WebCore::ResourceRequest& request, const GlobalFrameID& frameID, std::function<void (std::unique_ptr<Entry>)> completionHandler)
 {
     ASSERT(isEnabled());
-    ASSERT(originalRequest.url().protocolIsInHTTPFamily());
+    ASSERT(request.url().protocolIsInHTTPFamily());
 
-    LOG(NetworkCache, "(NetworkProcess) retrieving %s priority %d", originalRequest.url().string().ascii().data(), static_cast<int>(originalRequest.priority()));
+    LOG(NetworkCache, "(NetworkProcess) retrieving %s priority %d", request.url().string().ascii().data(), static_cast<int>(request.priority()));
 
     if (m_statistics)
         m_statistics->recordRetrievalRequest(frameID.first);
 
-    Key storageKey = makeCacheKey(originalRequest);
+    Key storageKey = makeCacheKey(request);
 
 #if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
     if (m_speculativeLoadManager)
-        m_speculativeLoadManager->registerLoad(frameID, originalRequest, storageKey);
+        m_speculativeLoadManager->registerLoad(frameID, request, storageKey);
 #endif
 
-    auto retrieveDecision = makeRetrieveDecision(originalRequest);
+    auto retrieveDecision = makeRetrieveDecision(request);
     if (retrieveDecision != RetrieveDecision::Yes) {
         if (m_statistics)
-            m_statistics->recordNotUsingCacheForRequest(frameID.first, storageKey, originalRequest, retrieveDecision);
+            m_statistics->recordNotUsingCacheForRequest(frameID.first, storageKey, request, retrieveDecision);
 
         completionHandler(nullptr);
         return;
     }
 
 #if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
-    if (m_speculativeLoadManager && m_speculativeLoadManager->retrieve(frameID, storageKey, [originalRequest, completionHandler](std::unique_ptr<Entry> entry) {
-        if (entry && verifyVaryingRequestHeaders(entry->varyingRequestHeaders(), originalRequest))
+    if (m_speculativeLoadManager && m_speculativeLoadManager->retrieve(frameID, storageKey, [request, completionHandler](std::unique_ptr<Entry> entry) {
+        if (entry && verifyVaryingRequestHeaders(entry->varyingRequestHeaders(), request))
             completionHandler(WTF::move(entry));
         else
             completionHandler(nullptr);
@@ -380,14 +380,14 @@
 #endif
 
     auto startTime = std::chrono::system_clock::now();
-    auto priority = static_cast<unsigned>(originalRequest.priority());
+    auto priority = static_cast<unsigned>(request.priority());
 
-    m_storage->retrieve(storageKey, priority, [this, originalRequest, completionHandler, startTime, storageKey, frameID](std::unique_ptr<Storage::Record> record) {
+    m_storage->retrieve(storageKey, priority, [this, request, completionHandler, startTime, storageKey, frameID](std::unique_ptr<Storage::Record> record) {
         if (!record) {
             LOG(NetworkCache, "(NetworkProcess) not found in storage");
 
             if (m_statistics)
-                m_statistics->recordRetrievalFailure(frameID.first, storageKey, originalRequest);
+                m_statistics->recordRetrievalFailure(frameID.first, storageKey, request);
 
             completionHandler(nullptr);
             return false;
@@ -397,7 +397,7 @@
 
         auto entry = Entry::decodeStorageRecord(*record);
 
-        auto useDecision = entry ? makeUseDecision(*entry, originalRequest) : UseDecision::NoDueToDecodeFailure;
+        auto useDecision = entry ? makeUseDecision(*entry, request) : UseDecision::NoDueToDecodeFailure;
         switch (useDecision) {
         case UseDecision::Use:
             break;
@@ -410,34 +410,27 @@
 
 #if !LOG_DISABLED
         auto elapsedMS = static_cast<int64_t>(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - startTime).count());
-        LOG(NetworkCache, "(NetworkProcess) retrieve complete useDecision=%d priority=%d time=%" PRIi64 "ms", static_cast<int>(useDecision), static_cast<int>(originalRequest.priority()), elapsedMS);
+        LOG(NetworkCache, "(NetworkProcess) retrieve complete useDecision=%d priority=%d time=%" PRIi64 "ms", static_cast<int>(useDecision), static_cast<int>(request.priority()), elapsedMS);
 #endif
         completionHandler(WTF::move(entry));
 
         if (m_statistics)
-            m_statistics->recordRetrievedCachedEntry(frameID.first, storageKey, originalRequest, useDecision);
+            m_statistics->recordRetrievedCachedEntry(frameID.first, storageKey, request, useDecision);
         return useDecision != UseDecision::NoDueToDecodeFailure;
     });
 }
 
-std::unique_ptr<Entry> Cache::store(const WebCore::ResourceRequest& originalRequest, const WebCore::ResourceResponse& response, RefPtr<WebCore::SharedBuffer>&& responseData, std::function<void (MappedBody&)> completionHandler)
+std::unique_ptr<Entry> Cache::store(const WebCore::ResourceRequest& request, const WebCore::ResourceResponse& response, RefPtr<WebCore::SharedBuffer>&& responseData, std::function<void (MappedBody&)> completionHandler)
 {
     ASSERT(isEnabled());
     ASSERT(responseData);
 
-#if !LOG_DISABLED
-#if ENABLE(CACHE_PARTITIONING)
-    CString partition = originalRequest.cachePartition().latin1();
-#else
-    CString partition = "No partition";
-#endif
-    LOG(NetworkCache, "(NetworkProcess) storing %s, partition %s", originalRequest.url().string().latin1().data(), partition.data());
-#endif // !LOG_DISABLED
+    LOG(NetworkCache, "(NetworkProcess) storing %s, partition %s", request.url().string().latin1().data(), makeCacheKey(request).partition().latin1().data());
 
-    StoreDecision storeDecision = makeStoreDecision(originalRequest, response);
+    StoreDecision storeDecision = makeStoreDecision(request, response);
     if (storeDecision != StoreDecision::Yes) {
         LOG(NetworkCache, "(NetworkProcess) didn't store, storeDecision=%d", static_cast<int>(storeDecision));
-        auto key = makeCacheKey(originalRequest);
+        auto key = makeCacheKey(request);
 
         auto isSuccessfulRevalidation = response.httpStatusCode() == 304;
         if (!isSuccessfulRevalidation) {
@@ -451,7 +444,7 @@
         return nullptr;
     }
 
-    std::unique_ptr<Entry> cacheEntry = std::make_unique<Entry>(makeCacheKey(originalRequest), response, WTF::move(responseData), collectVaryingRequestHeaders(originalRequest, response));
+    std::unique_ptr<Entry> cacheEntry = std::make_unique<Entry>(makeCacheKey(request), response, WTF::move(responseData), collectVaryingRequestHeaders(request, response));
 
     auto record = cacheEntry->encodeAsStorageRecord();
 
@@ -471,6 +464,31 @@
     return cacheEntry;
 }
 
+std::unique_ptr<Entry> Cache::storeRedirect(const WebCore::ResourceRequest& request, const WebCore::ResourceResponse& response, const WebCore::ResourceRequest& redirectRequest)
+{
+    ASSERT(isEnabled());
+
+    LOG(NetworkCache, "(NetworkProcess) storing redirect %s -> %s", request.url().string().latin1().data(), redirectRequest.url().string().latin1().data());
+
+    StoreDecision storeDecision = makeStoreDecision(request, response);
+    if (storeDecision != StoreDecision::Yes) {
+        LOG(NetworkCache, "(NetworkProcess) didn't store redirect, storeDecision=%d", static_cast<int>(storeDecision));
+        auto key = makeCacheKey(request);
+        if (m_statistics)
+            m_statistics->recordNotCachingResponse(key, storeDecision);
+
+        return nullptr;
+    }
+
+    std::unique_ptr<Entry> cacheEntry = std::make_unique<Entry>(makeCacheKey(request), response, redirectRequest, collectVaryingRequestHeaders(request, response));
+
+    auto record = cacheEntry->encodeAsStorageRecord();
+
+    m_storage->store(record, nullptr);
+    
+    return cacheEntry;
+}
+
 std::unique_ptr<Entry> Cache::update(const WebCore::ResourceRequest& originalRequest, const GlobalFrameID& frameID, const Entry& existingEntry, const WebCore::ResourceResponse& validatingResponse)
 {
     LOG(NetworkCache, "(NetworkProcess) updating %s", originalRequest.url().string().latin1().data());

Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.h (194312 => 194313)


--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.h	2015-12-19 09:01:00 UTC (rev 194312)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.h	2015-12-19 13:26:38 UTC (rev 194313)
@@ -82,6 +82,7 @@
     NoDueToVaryingHeaderMismatch,
     NoDueToMissingValidatorFields,
     NoDueToDecodeFailure,
+    NoDueToExpiredRedirect,
 };
 
 using GlobalFrameID = std::pair<uint64_t /*webPageID*/, uint64_t /*webFrameID*/>;
@@ -104,6 +105,7 @@
     // Completion handler may get called back synchronously on failure.
     void retrieve(const WebCore::ResourceRequest&, const GlobalFrameID&, std::function<void (std::unique_ptr<Entry>)>);
     std::unique_ptr<Entry> store(const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, RefPtr<WebCore::SharedBuffer>&&, std::function<void (MappedBody&)>);
+    std::unique_ptr<Entry> storeRedirect(const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, const WebCore::ResourceRequest& redirectRequest);
     std::unique_ptr<Entry> update(const WebCore::ResourceRequest&, const GlobalFrameID&, const Entry&, const WebCore::ResourceResponse& validatingResponse);
 
     void traverse(std::function<void (const Entry*)>&&);

Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheEntry.cpp (194312 => 194313)


--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheEntry.cpp	2015-12-19 09:01:00 UTC (rev 194312)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheEntry.cpp	2015-12-19 13:26:38 UTC (rev 194313)
@@ -49,6 +49,18 @@
     ASSERT(m_key.type() == "resource");
 }
 
+Entry::Entry(const Key& key, const WebCore::ResourceResponse& response, const WebCore::ResourceRequest& redirectRequest, const Vector<std::pair<String, String>>& varyingRequestHeaders)
+    : m_key(key)
+    , m_timeStamp(std::chrono::system_clock::now())
+    , m_response(response)
+    , m_varyingRequestHeaders(varyingRequestHeaders)
+    , m_redirectRequest(WebCore::ResourceRequest::adopt(redirectRequest.copyData())) // Don't include the underlying platform request object.
+{
+    ASSERT(m_key.type() == "resource");
+    // Redirect body is not needed even if exists.
+    m_redirectRequest->setHTTPBody(nullptr);
+}
+
 Entry::Entry(const Entry& other)
     : m_key(other.m_key)
     , m_timeStamp(other.m_timeStamp)
@@ -77,6 +89,11 @@
     if (hasVaryingRequestHeaders)
         encoder << m_varyingRequestHeaders;
 
+    bool isRedirect = !!m_redirectRequest;
+    encoder << isRedirect;
+    if (isRedirect)
+        m_redirectRequest->encodeWithoutPlatformData(encoder);
+
     encoder.encodeChecksum();
 
     Data header(encoder.buffer(), encoder.bufferSize());
@@ -105,6 +122,16 @@
             return nullptr;
     }
 
+    bool isRedirect;
+    if (!decoder.decode(isRedirect))
+        return nullptr;
+
+    if (isRedirect) {
+        entry->m_redirectRequest = std::make_unique<WebCore::ResourceRequest>();
+        if (!entry->m_redirectRequest->decodeWithoutPlatformData(decoder))
+            return nullptr;
+    }
+
     if (!decoder.verifyChecksum()) {
         LOG(NetworkCache, "(NetworkProcess) checksum verification failure\n");
         return nullptr;

Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheEntry.h (194312 => 194313)


--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheEntry.h	2015-12-19 09:01:00 UTC (rev 194312)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheEntry.h	2015-12-19 13:26:38 UTC (rev 194313)
@@ -30,12 +30,12 @@
 
 #include "NetworkCacheStorage.h"
 #include "ShareableResource.h"
+#include <WebCore/ResourceRequest.h>
 #include <WebCore/ResourceResponse.h>
 #include <wtf/Noncopyable.h>
 #include <wtf/text/WTFString.h>
 
 namespace WebCore {
-class ResourceRequest;
 class SharedBuffer;
 }
 
@@ -46,6 +46,7 @@
     WTF_MAKE_FAST_ALLOCATED;
 public:
     Entry(const Key&, const WebCore::ResourceResponse&, RefPtr<WebCore::SharedBuffer>&&, const Vector<std::pair<String, String>>& varyingRequestHeaders);
+    Entry(const Key&, const WebCore::ResourceResponse&, const WebCore::ResourceRequest& redirectRequest, const Vector<std::pair<String, String>>& varyingRequestHeaders);
     explicit Entry(const Storage::Record&);
     Entry(const Entry&);
 
@@ -58,6 +59,8 @@
     const Vector<std::pair<String, String>>& varyingRequestHeaders() const { return m_varyingRequestHeaders; }
 
     WebCore::SharedBuffer* buffer() const;
+    const WebCore::ResourceRequest* redirectRequest() const { return m_redirectRequest.get(); }
+
 #if ENABLE(SHAREABLE_RESOURCE)
     ShareableResource::Handle& shareableResourceHandle() const;
 #endif
@@ -80,6 +83,7 @@
     WebCore::ResourceResponse m_response;
     Vector<std::pair<String, String>> m_varyingRequestHeaders;
 
+    std::unique_ptr<WebCore::ResourceRequest> m_redirectRequest;
     mutable RefPtr<WebCore::SharedBuffer> m_buffer;
 #if ENABLE(SHAREABLE_RESOURCE)
     mutable ShareableResource::Handle m_shareableResourceHandle;

Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoad.cpp (194312 => 194313)


--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoad.cpp	2015-12-19 09:01:00 UTC (rev 194312)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoad.cpp	2015-12-19 13:26:38 UTC (rev 194313)
@@ -63,7 +63,7 @@
     ASSERT(!m_networkLoad);
 }
 
-void SpeculativeLoad::willSendRedirectedRequest(const ResourceRequest& request, const ResourceResponse& redirectResponse)
+void SpeculativeLoad::willSendRedirectedRequest(const ResourceRequest& request, const ResourceRequest& redirectRequest, const ResourceResponse& redirectResponse)
 {
     updateRedirectChainStatus(m_redirectChainCacheStatus, redirectResponse);
 }

Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoad.h (194312 => 194313)


--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoad.h	2015-12-19 09:01:00 UTC (rev 194312)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoad.h	2015-12-19 13:26:38 UTC (rev 194313)
@@ -54,7 +54,7 @@
     virtual void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) override { }
     virtual void canAuthenticateAgainstProtectionSpaceAsync(const WebCore::ProtectionSpace&) override { }
     virtual bool isSynchronous() const override { return false; }
-    virtual void willSendRedirectedRequest(const WebCore::ResourceRequest&, const WebCore::ResourceResponse& redirectResponse) override;
+    virtual void willSendRedirectedRequest(const WebCore::ResourceRequest&, const WebCore::ResourceRequest& redirectRequest, const WebCore::ResourceResponse& redirectResponse) override;
     virtual ShouldContinueDidReceiveResponse didReceiveResponse(const WebCore::ResourceResponse&) override;
     virtual void didReceiveBuffer(RefPtr<WebCore::SharedBuffer>&&, int reportedEncodedDataLength) override;
     virtual void didFinishLoading(double finishTime) override;

Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStatistics.cpp (194312 => 194313)


--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStatistics.cpp	2015-12-19 09:01:00 UTC (rev 194312)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStatistics.cpp	2015-12-19 13:26:38 UTC (rev 194313)
@@ -280,6 +280,7 @@
     case UseDecision::NoDueToMissingValidatorFields:
         return WebCore::DiagnosticLoggingKeys::missingValidatorFieldsKey();
     case UseDecision::NoDueToDecodeFailure:
+    case UseDecision::NoDueToExpiredRedirect:
         return WebCore::DiagnosticLoggingKeys::otherKey();
     case UseDecision::Use:
     case UseDecision::Validate:
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to