Title: [189177] trunk
Revision
189177
Author
[email protected]
Date
2015-08-31 11:31:04 -0700 (Mon, 31 Aug 2015)

Log Message

Network Cache: Stale content after back navigation
https://bugs.webkit.org/show_bug.cgi?id=148634

Reviewed by Chris Dumez.

Source/WebKit2:

It is possible to get an older version of the previous page when navigating back. This can happen
if the main resource load has not completed before navigating away from the page.

Network cache entry is normally updated when the load completes. In case of cancellation we would leave
any existing entry as-is. However we render incrementally and user might have seen some content from
the partial load already. Navigating back to the cached page could show older version of the content.

* NetworkProcess/NetworkResourceLoader.cpp:
(WebKit::NetworkResourceLoader::abort):

    If a network load is canceled by the client after receiving response but before the load has completed
    remove any existing cache entry for it.

LayoutTests:

* http/tests/cache/disk-cache/disk-cache-302-status-code.html:
* http/tests/cache/disk-cache/disk-cache-cancel-expected.txt: Added.
* http/tests/cache/disk-cache/disk-cache-cancel.html: Added.
* http/tests/cache/disk-cache/resources/cache-test.js:

    Support delayed responses so we can test canceling the load.
    Some minor improvements.

(makeHeaderValue):
(generateTestURL):
(loadResource):
(loadResourcesWithOptions):
(generateTests):
* http/tests/cache/disk-cache/resources/generate-response.cgi:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (189176 => 189177)


--- trunk/LayoutTests/ChangeLog	2015-08-31 18:15:09 UTC (rev 189176)
+++ trunk/LayoutTests/ChangeLog	2015-08-31 18:31:04 UTC (rev 189177)
@@ -1,3 +1,25 @@
+2015-08-31  Antti Koivisto  <[email protected]>
+
+        Network Cache: Stale content after back navigation
+        https://bugs.webkit.org/show_bug.cgi?id=148634
+
+        Reviewed by Chris Dumez.
+
+        * http/tests/cache/disk-cache/disk-cache-302-status-code.html:
+        * http/tests/cache/disk-cache/disk-cache-cancel-expected.txt: Added.
+        * http/tests/cache/disk-cache/disk-cache-cancel.html: Added.
+        * http/tests/cache/disk-cache/resources/cache-test.js:
+
+            Support delayed responses so we can test canceling the load.
+            Some minor improvements.
+
+        (makeHeaderValue):
+        (generateTestURL):
+        (loadResource):
+        (loadResourcesWithOptions):
+        (generateTests):
+        * http/tests/cache/disk-cache/resources/generate-response.cgi:
+
 2015-08-31  Zalan Bujtas  <[email protected]>
 
         Repaint cleanup: 4776765.html. Use repaint rect tracking.

Modified: trunk/LayoutTests/http/tests/cache/disk-cache/disk-cache-302-status-code.html (189176 => 189177)


--- trunk/LayoutTests/http/tests/cache/disk-cache/disk-cache-302-status-code.html	2015-08-31 18:15:09 UTC (rev 189176)
+++ trunk/LayoutTests/http/tests/cache/disk-cache/disk-cache-302-status-code.html	2015-08-31 18:31:04 UTC (rev 189177)
@@ -5,8 +5,8 @@
 
 var tests =
 [
- { responseHeaders: {'Status': '302', 'Location': '/', 'Cache-control': 'max-age=0' }, includeBody: false },
- { responseHeaders: {'Status': '302', 'Location': '/', 'Cache-control': 'max-age=100' }, includeBody: false },
+ { responseHeaders: {'Status': '302', 'Location': '/', 'Cache-control': 'max-age=0' }, body: "" },
+ { responseHeaders: {'Status': '302', 'Location': '/', 'Cache-control': 'max-age=100' }, body: "" },
 ];
 
 description("Test that responses with HTTP status code 302 are not cached");

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


--- trunk/LayoutTests/http/tests/cache/disk-cache/disk-cache-cancel-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/cache/disk-cache/disk-cache-cancel-expected.txt	2015-08-31 18:31:04 UTC (rev 189177)
@@ -0,0 +1,23 @@
+Test that canceled network loads don't leave behind stale cache entries
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+running 3 tests
+
+Warming cache
+Starting loads, then canceling
+Loading again with back navigation cache policy
+response headers: {"Cache-control":"max-age=0"}
+response source: Network
+
+response headers: {"Cache-control":"max-age=100"}
+response source: Network
+
+response headers: {"Cache-control":"max-age=0","ETag":"match"}
+response source: Network
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

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


--- trunk/LayoutTests/http/tests/cache/disk-cache/disk-cache-cancel.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/cache/disk-cache/disk-cache-cancel.html	2015-08-31 18:31:04 UTC (rev 189177)
@@ -0,0 +1,45 @@
+<script src=""
+<script src=""
+<body>
+<script>
+
+var tests =
+[
+ { responseHeaders: {'Cache-control': 'max-age=0' }, body: "unique", delay: 1 },
+ { responseHeaders: {'Cache-control': 'max-age=100' }, body: "unique", delay: 1 },
+ { responseHeaders: {'Cache-control': 'max-age=0', 'ETag': 'match' }, body: "unique", delay: 1 },
+];
+
+description("Test that canceled network loads don't leave behind stale cache entries");
+
+debug("running " + tests.length + " tests");
+debug("");
+
+function runTests(tests)
+{
+    debug("Warming cache");
+    internals.setOverrideCachePolicy("ReloadIgnoringCacheData");
+    loadResources(tests, function () {
+        debug("Starting loads, then canceling");
+        loadResources(tests, function (ev) {
+            debug("Loading again with back navigation cache policy");
+            internals.setOverrideCachePolicy("ReturnCacheDataElseLoad");
+            loadResources(tests, function (ev) {
+                printResults(tests);
+                finishJSTest();
+            });
+        });
+
+        setTimeout(function () {
+            for (var i = 0; i < tests.length; ++i) {
+                var test = tests[i];
+                test.xhr.abort();
+            }
+        }, 200);
+    });
+}
+
+runTests(tests);
+
+</script>
+<script src=""

Modified: trunk/LayoutTests/http/tests/cache/disk-cache/resources/cache-test.js (189176 => 189177)


--- trunk/LayoutTests/http/tests/cache/disk-cache/resources/cache-test.js	2015-08-31 18:15:09 UTC (rev 189176)
+++ trunk/LayoutTests/http/tests/cache/disk-cache/resources/cache-test.js	2015-08-31 18:31:04 UTC (rev 189177)
@@ -40,14 +40,16 @@
     return value;
 }
 
-function generateTestURL(test, includeBody, expiresInFutureIn304)
+function generateTestURL(test)
 {
-    includeBody = typeof includeBody !== 'undefined' ? includeBody : true;
-    expiresInFutureIn304 = typeof expiresInFutureIn304 !== 'undefined' ? expiresInFutureIn304 : false;
+    var body = typeof test.body !== 'undefined' ? test.body : "";
+    var expiresInFutureIn304 = typeof test.expiresInFutureIn304 !== 'undefined' ? test.expiresInFutureIn304 : false;
     var uniqueTestId = Math.floor((Math.random() * 1000000000000));
-    var testURL = "resources/generate-response.cgi?include-body=" + (includeBody ? "1" : "0");
+    var testURL = "resources/generate-response.cgi?body=" + body;
     if (expiresInFutureIn304)
         testURL += "&expires-in-future-in-304=1";
+    if (test.delay)
+        testURL += "&delay=" + test.delay;
     testURL += "&uniqueId=" + uniqueTestId++;
     if (!test.responseHeaders || !test.responseHeaders["Content-Type"])
         testURL += "&Content-Type=text/plain";
@@ -59,10 +61,12 @@
 function loadResource(test, onload)
 {
     if (!test.url)
-        test.url = "" test.includeBody, test.expiresInFutureIn304);
+        test.url = ""
 
     test.xhr = new XMLHttpRequest();
     test.xhr._onload_ = onload;
+    test.xhr._onerror_ = onload;
+    test.xhr._onabort_ = onload;
     test.xhr.open("get", test.url, true);
 
     for (var header in test.requestHeaders)
@@ -82,7 +86,7 @@
         loadResource(tests[i], function (ev) {
             --pendingCount;
             if (!pendingCount)
-                completetion();
+                completetion(ev);
          });
     }
 }
@@ -166,7 +170,8 @@
                 mergeFields(test[field], component[field]);
             }
         }
-        test.includeBody = includeBody;
+        if (includeBody && !test.body)
+            test.body = "test body";
         tests.push(test);
     }
     return tests;

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


--- trunk/LayoutTests/http/tests/cache/disk-cache/resources/generate-response.cgi	2015-08-31 18:15:09 UTC (rev 189176)
+++ trunk/LayoutTests/http/tests/cache/disk-cache/resources/generate-response.cgi	2015-08-31 18:31:04 UTC (rev 189177)
@@ -5,9 +5,14 @@
 
 my $query = new CGI;
 @names = $query->param;
-my $includeBody = $query->param('include-body') || 0;
 my $expiresInFutureIn304 = $query->param('expires-in-future-in-304') || 0;
+my $delay = $query->param('delay') || 0;
+my $body = $query->param('body') || 0;
 
+if ($body eq "unique") {
+    $body = sprintf "%08X\n", rand(0xffffffff)
+}
+
 my $hasStatusCode = 0;
 my $hasExpiresHeader = 0;
 if ($query->http && $query->http("If-None-Match") eq "match") {
@@ -32,10 +37,18 @@
 
 foreach (@names) {
     next if ($_ eq "uniqueId");
-    next if ($_ eq "include-body");
+    next if ($_ eq "delay");
+    next if ($_ eq "body");
     next if ($_ eq "Status" and $hasStatusCode);
     next if ($_ eq "Expires" and $hasExpiresHeader);
     print $_ . ": " . $query->param($_) . "\n";
 }
 print "\n";
-print "test" if $includeBody;
+if ($delay) {
+    # Include some padding so headers and full body are sent separately.
+    for (my $i=0; $i < 1024; $i++) {
+        print "                                                                                ";
+    }
+    sleep $delay;
+}
+print $body if $body;

Modified: trunk/Source/WebKit2/ChangeLog (189176 => 189177)


--- trunk/Source/WebKit2/ChangeLog	2015-08-31 18:15:09 UTC (rev 189176)
+++ trunk/Source/WebKit2/ChangeLog	2015-08-31 18:31:04 UTC (rev 189177)
@@ -1,3 +1,23 @@
+2015-08-31  Antti Koivisto  <[email protected]>
+
+        Network Cache: Stale content after back navigation
+        https://bugs.webkit.org/show_bug.cgi?id=148634
+
+        Reviewed by Chris Dumez.
+
+        It is possible to get an older version of the previous page when navigating back. This can happen
+        if the main resource load has not completed before navigating away from the page.
+
+        Network cache entry is normally updated when the load completes. In case of cancellation we would leave
+        any existing entry as-is. However we render incrementally and user might have seen some content from
+        the partial load already. Navigating back to the cached page could show older version of the content.
+
+        * NetworkProcess/NetworkResourceLoader.cpp:
+        (WebKit::NetworkResourceLoader::abort):
+
+            If a network load is canceled by the client after receiving response but before the load has completed
+            remove any existing cache entry for it.
+
 2015-08-28  Myles C. Maxfield  <[email protected]>
 
         Migrate GraphicsContexts from pointers to references

Modified: trunk/Source/WebKit2/NetworkProcess/NetworkResourceLoader.cpp (189176 => 189177)


--- trunk/Source/WebKit2/NetworkProcess/NetworkResourceLoader.cpp	2015-08-31 18:15:09 UTC (rev 189176)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkResourceLoader.cpp	2015-08-31 18:31:04 UTC (rev 189177)
@@ -223,9 +223,18 @@
 {
     ASSERT(RunLoop::isMain());
 
-    if (m_handle && !m_didConvertHandleToDownload)
+    if (m_handle && !m_didConvertHandleToDownload) {
         m_handle->cancel();
 
+#if ENABLE(NETWORK_CACHE)
+        if (NetworkCache::singleton().isEnabled()) {
+            // 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());
+        }
+#endif
+    }
+
     cleanup();
 }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to