<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[178012] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/178012">178012</a></dd>
<dt>Author</dt> <dd>cdumez@apple.com</dd>
<dt>Date</dt> <dd>2015-01-06 17:59:10 -0800 (Tue, 06 Jan 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Do not attempt to revalidate cached main resource on back/forward navigation
https://bugs.webkit.org/show_bug.cgi?id=139263

Reviewed by Darin Adler.

Source/WebCore:

Do not attempt to revalidate cached main resource on back/forward
navigation, as allowed by RFC2616 &amp; newer RFC7234 which distinguish
history mechanisms and caches, stating:

   The freshness model (Section 4.2) does not necessarily apply to
   history mechanisms.  That is, a history mechanism can display a
   previous representation even if it has expired.

Previously, we would bypass revalidation on back/forward navigation
only for sub-resources. This patch extends this policy to the main
resource as well.

This behavior is also consistent with IE10+ and Chrome. It makes it more
likely we return cached content to the user on back/forward navigation
and avoids making network requests in this case.

Test: http/tests/cache/history-navigation-no-resource-revalidation.html

* loader/cache/CacheValidation.cpp:
(WebCore::redirectChainAllowsReuse):
* loader/cache/CacheValidation.h:
* loader/cache/CachedResource.cpp:
(WebCore::CachedResource::redirectChainAllowsReuse):
Add a &quot;ReuseExpiredRedirectionOrNot&quot; flag argument because in the case
of an HistoryBuffer navigation, we don't mind reuse an expired
redirection. However, we still need to make sure that the redirection
is actually cached before reusing it.

* loader/cache/CachedResource.h:
* loader/cache/CachedResourceLoader.cpp:
(WebCore::CachedResourceLoader::determineRevalidationPolicy):
- Do the redirectChainAllowsReuse() check *before* checking if the cache
  policy is CachePolicyHistoryBuffer. This is needed because
  redirectChainAllowsReuse() will return false if the redirection is not
  cached. Loading from the cache in this case will cause us to load the
  wrong resource (the one before the redirection). This case is covered
  by http/tests/navigation/redirect-on-reload-updates-history-item.html.
- Do not use the cached main resource if it has &quot;cache-control: no-store&quot;,
  even if it is a history navigation (cachePolicy is
  CachePolicyHistoryBuffer). This maintains the previous behavior, and
  some layout tests rely on this. We now have to be explicit about it
  because cachePolicy() can now return CachePolicyHistoryBuffer for the
  main resource (not just sub-resources). This difference in behavior
  on history navigation for the main resource and sub-resources is not
  great. However, I chose to maintain this pre-existing behavior in this
  patch to do one behavior change at a time. We can harmonize this later.

Previously, the order was not an issue because the main resource was
always revalidated on back/forward navigation.

(WebCore::CachedResourceLoader::cachePolicy):
Return CachePolicyHistoryBuffer for the main resource in case of
history navigation, instead of CachePolicyVerify so that we don't
attempt to revalidate.

LayoutTests:

Add layout test to make sure we don't attempt to revalidate a cached
main resource on back/forward navigation.

* http/tests/cache/history-navigation-no-resource-revalidation-expected.txt: Added.
* http/tests/cache/history-navigation-no-resource-revalidation.html: Added.
* http/tests/cache/resources/history-back.html: Renamed from LayoutTests/http/tests/cache/resources/no-store-resource-forward.html.
* http/tests/cache/resources/max-age-resource-forward.html: Removed.
* http/tests/cache/resources/max-age-resource.html:
* http/tests/cache/resources/no-cache-main-resource-next.php: Added.
* http/tests/cache/resources/no-cache-main-resource.php: Copied from LayoutTests/http/tests/cache/resources/no-store-resource.html.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestshttptestscacheresourcesmaxageresourcehtml">trunk/LayoutTests/http/tests/cache/resources/max-age-resource.html</a></li>
<li><a href="#trunkLayoutTestshttptestscacheresourcesnostoreresourcehtml">trunk/LayoutTests/http/tests/cache/resources/no-store-resource.html</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCoreexpin">trunk/Source/WebCore/WebCore.exp.in</a></li>
<li><a href="#trunkSourceWebCoreloadercacheCacheValidationcpp">trunk/Source/WebCore/loader/cache/CacheValidation.cpp</a></li>
<li><a href="#trunkSourceWebCoreloadercacheCacheValidationh">trunk/Source/WebCore/loader/cache/CacheValidation.h</a></li>
<li><a href="#trunkSourceWebCoreloadercacheCachedResourcecpp">trunk/Source/WebCore/loader/cache/CachedResource.cpp</a></li>
<li><a href="#trunkSourceWebCoreloadercacheCachedResourceh">trunk/Source/WebCore/loader/cache/CachedResource.h</a></li>
<li><a href="#trunkSourceWebCoreloadercacheCachedResourceLoadercpp">trunk/Source/WebCore/loader/cache/CachedResourceLoader.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestshttptestscachehistorynavigationnoresourcerevalidationexpectedtxt">trunk/LayoutTests/http/tests/cache/history-navigation-no-resource-revalidation-expected.txt</a></li>
<li><a href="#trunkLayoutTestshttptestscachehistorynavigationnoresourcerevalidationhtml">trunk/LayoutTests/http/tests/cache/history-navigation-no-resource-revalidation.html</a></li>
<li><a href="#trunkLayoutTestshttptestscacheresourceshistorybackhtml">trunk/LayoutTests/http/tests/cache/resources/history-back.html</a></li>
<li><a href="#trunkLayoutTestshttptestscacheresourcesnocachemainresourcenextphp">trunk/LayoutTests/http/tests/cache/resources/no-cache-main-resource-next.php</a></li>
<li><a href="#trunkLayoutTestshttptestscacheresourcesnocachemainresourcephp">trunk/LayoutTests/http/tests/cache/resources/no-cache-main-resource.php</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkLayoutTestshttptestscacheresourcesmaxageresourceforwardhtml">trunk/LayoutTests/http/tests/cache/resources/max-age-resource-forward.html</a></li>
<li><a href="#trunkLayoutTestshttptestscacheresourcesnostoreresourceforwardhtml">trunk/LayoutTests/http/tests/cache/resources/no-store-resource-forward.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (178011 => 178012)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-01-07 01:57:00 UTC (rev 178011)
+++ trunk/LayoutTests/ChangeLog        2015-01-07 01:59:10 UTC (rev 178012)
</span><span class="lines">@@ -1,5 +1,23 @@
</span><span class="cx"> 2015-01-06  Chris Dumez  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Do not attempt to revalidate cached main resource on back/forward navigation
+        https://bugs.webkit.org/show_bug.cgi?id=139263
+
+        Reviewed by Darin Adler.
+
+        Add layout test to make sure we don't attempt to revalidate a cached
+        main resource on back/forward navigation.
+
+        * http/tests/cache/history-navigation-no-resource-revalidation-expected.txt: Added.
+        * http/tests/cache/history-navigation-no-resource-revalidation.html: Added.
+        * http/tests/cache/resources/history-back.html: Renamed from LayoutTests/http/tests/cache/resources/no-store-resource-forward.html.
+        * http/tests/cache/resources/max-age-resource-forward.html: Removed.
+        * http/tests/cache/resources/max-age-resource.html:
+        * http/tests/cache/resources/no-cache-main-resource-next.php: Added.
+        * http/tests/cache/resources/no-cache-main-resource.php: Copied from LayoutTests/http/tests/cache/resources/no-store-resource.html.
+
+2015-01-06  Chris Dumez  &lt;cdumez@apple.com&gt;
+
</ins><span class="cx">         Setting '-webkit-filter' to 'brightness(calc(10% * 2))' does not work
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=140149
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestshttptestscachehistorynavigationnoresourcerevalidationexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/cache/history-navigation-no-resource-revalidation-expected.txt (0 => 178012)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/cache/history-navigation-no-resource-revalidation-expected.txt                                (rev 0)
+++ trunk/LayoutTests/http/tests/cache/history-navigation-no-resource-revalidation-expected.txt        2015-01-07 01:59:10 UTC (rev 178012)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+Test that we don't attempt to revalidate the cached main resource on history navigation
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS no-cache subresource was cached and used for a back navigation
+PASS no-cache subresource was refetched with a reload
+PASS no-cache subresource was refetched with a normal navigation
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestshttptestscachehistorynavigationnoresourcerevalidationhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/cache/history-navigation-no-resource-revalidation.html (0 => 178012)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/cache/history-navigation-no-resource-revalidation.html                                (rev 0)
+++ trunk/LayoutTests/http/tests/cache/history-navigation-no-resource-revalidation.html        2015-01-07 01:59:10 UTC (rev 178012)
</span><span class="lines">@@ -0,0 +1,81 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;body onLoad=&quot;runTest()&quot;&gt;
+    &lt;script src=&quot;/js-test-resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+    &lt;script&gt;
+    description(&quot;Test that we don't attempt to revalidate the cached main resource on history navigation&quot;);
+    jsTestIsAsync = true;
+
+    if (window.testRunner)
+        testRunner.setCanOpenWindows();
+
+    // Values to check.
+    var originalRandomNumber = 0;
+    var backLoadRandomNumber = 0;
+    var refreshRandomNumber  = 0;
+    var nextLoadRandomNumber = 0;
+
+    // Window we will be controlling.
+    var target;
+
+    // Pass messages between windows to control the navigation types.
+    var pre = document.getElementById('console');
+    window.addEventListener('message', function(event) {
+
+        // First time, record the first number, and tell the target window to trigger a back navigation.
+        if (!originalRandomNumber) {
+            originalRandomNumber = event.data;
+            target.postMessage('go-forward-and-back', '*');
+            return;
+        }
+
+        // Second time, record the second number. It should be identical. Also tell the target window to reload.
+        if (!backLoadRandomNumber) {
+            backLoadRandomNumber = event.data;
+            var wasCached = (backLoadRandomNumber === originalRandomNumber);
+            if (wasCached)
+                testPassed('no-cache subresource was cached and used for a back navigation');
+            else
+                testFailed('no-cache subresource should have been cached and used in a back navigation');
+
+            target.postMessage('reload', '*');
+            return;
+        }
+
+        // Third time, record the third number. It should not match. Also tell the target window to navigate forward.
+        if (!refreshRandomNumber) {
+            refreshRandomNumber = event.data;
+            var wasCached = (refreshRandomNumber === originalRandomNumber);
+            if (wasCached)
+                testFailed('no-cache subresource should have been refetched with a reload');
+            else
+                testPassed('no-cache subresource was refetched with a reload');
+
+            target.postMessage('next', '*');
+            return;
+        }
+
+        // Fourth time, record the fourth number. It should not match any numbers so far.
+        if (!nextLoadRandomNumber) {
+            nextLoadRandomNumber = event.data;
+            var wasCached = (nextLoadRandomNumber === originalRandomNumber || nextLoadRandomNumber === refreshRandomNumber);
+            if (wasCached)
+                testFailed('no-cache subresource should have been refetched with a normal navigation');
+            else
+                testPassed('no-cache subresource was refetched with a normal navigation');
+        }
+
+        // Test completed.
+        target.close();
+        finishJSTest();
+
+    }, false);
+
+    function runTest() {
+        // Open the target window and it will begin to send us messages.
+        target = window.open('https://127.0.0.1:8443/cache/resources/no-cache-main-resource.php');
+    }
+    &lt;/script&gt;
+    &lt;script src=&quot;/js-test-resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestshttptestscacheresourceshistorybackhtmlfromrev178011trunkLayoutTestshttptestscacheresourcesmaxageresourceforwardhtml"></a>
<div class="copfile"><h4>Copied: trunk/LayoutTests/http/tests/cache/resources/history-back.html (from rev 178011, trunk/LayoutTests/http/tests/cache/resources/max-age-resource-forward.html) (0 => 178012)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/cache/resources/history-back.html                                (rev 0)
+++ trunk/LayoutTests/http/tests/cache/resources/history-back.html        2015-01-07 01:59:10 UTC (rev 178012)
</span><span class="lines">@@ -0,0 +1,4 @@
</span><ins>+&lt;p&gt;Now go back&lt;/p&gt;
+&lt;script&gt;
+window.history.back();
+&lt;/script&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestshttptestscacheresourcesmaxageresourceforwardhtml"></a>
<div class="delfile"><h4>Deleted: trunk/LayoutTests/http/tests/cache/resources/max-age-resource-forward.html (178011 => 178012)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/cache/resources/max-age-resource-forward.html        2015-01-07 01:57:00 UTC (rev 178011)
+++ trunk/LayoutTests/http/tests/cache/resources/max-age-resource-forward.html        2015-01-07 01:59:10 UTC (rev 178012)
</span><span class="lines">@@ -1,4 +0,0 @@
</span><del>-&lt;p&gt;Now go back&lt;/p&gt;
-&lt;script&gt;
-window.history.back();
-&lt;/script&gt;
</del></span></pre></div>
<a id="trunkLayoutTestshttptestscacheresourcesmaxageresourcehtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/http/tests/cache/resources/max-age-resource.html (178011 => 178012)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/cache/resources/max-age-resource.html        2015-01-07 01:57:00 UTC (rev 178011)
+++ trunk/LayoutTests/http/tests/cache/resources/max-age-resource.html        2015-01-07 01:59:10 UTC (rev 178012)
</span><span class="lines">@@ -10,7 +10,7 @@
</span><span class="cx"> 
</span><span class="cx">     // Go forward and back.
</span><span class="cx">     if (event.data === 'go-forward-and-back') {
</span><del>-        window.location = 'max-age-resource-forward.html';
</del><ins>+        window.location = 'history-back.html';
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestshttptestscacheresourcesnocachemainresourcenextphp"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/cache/resources/no-cache-main-resource-next.php (0 => 178012)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/cache/resources/no-cache-main-resource-next.php                                (rev 0)
+++ trunk/LayoutTests/http/tests/cache/resources/no-cache-main-resource-next.php        2015-01-07 01:59:10 UTC (rev 178012)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+&lt;?php
+header(&quot;Cache-control: no-cache, max-age=0&quot;);
+header(&quot;Last-Modified: Thu, 01 Jan 1970 00:00:00 GMT&quot;);
+header('Content-Type: text/html');
+
+print &quot;&lt;script&gt;\n&quot;;
+print &quot;var randomNumber = &quot; . rand() . &quot;;\n&quot;;
+?&gt;
+
+opener.postMessage(randomNumber, '*');
+&lt;/script&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestshttptestscacheresourcesnocachemainresourcephpfromrev178011trunkLayoutTestshttptestscacheresourcesnostoreresourcehtml"></a>
<div class="copfile"><h4>Copied: trunk/LayoutTests/http/tests/cache/resources/no-cache-main-resource.php (from rev 178011, trunk/LayoutTests/http/tests/cache/resources/no-store-resource.html) (0 => 178012)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/cache/resources/no-cache-main-resource.php                                (rev 0)
+++ trunk/LayoutTests/http/tests/cache/resources/no-cache-main-resource.php        2015-01-07 01:59:10 UTC (rev 178012)
</span><span class="lines">@@ -0,0 +1,34 @@
</span><ins>+&lt;?php
+header(&quot;Cache-control: no-cache, max-age=0&quot;);
+header(&quot;Last-Modified: Thu, 01 Jan 1970 00:00:00 GMT&quot;);
+header('Content-Type: text/html');
+
+print &quot;&lt;script&gt;\n&quot;;
+print &quot;var randomNumber = &quot; . rand() . &quot;;\n&quot;;
+?&gt;
+
+opener.postMessage(randomNumber, '*');
+
+// Our opener will tell us to perform various loads.
+window.addEventListener('message', function(event) {
+
+    // Go forward and back.
+    if (event.data === 'go-forward-and-back') {
+        window.location = 'history-back.html';
+        return;
+    }
+
+    // Reload.
+    if (event.data === 'reload') {
+        window.location.reload();
+        return;
+    }
+
+    // Normal navigation, next.
+    if (event.data === 'next') {
+        window.location = 'no-cache-main-resource-next.php';
+        return;
+    }
+
+}, false);
+&lt;/script&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestshttptestscacheresourcesnostoreresourceforwardhtml"></a>
<div class="delfile"><h4>Deleted: trunk/LayoutTests/http/tests/cache/resources/no-store-resource-forward.html (178011 => 178012)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/cache/resources/no-store-resource-forward.html        2015-01-07 01:57:00 UTC (rev 178011)
+++ trunk/LayoutTests/http/tests/cache/resources/no-store-resource-forward.html        2015-01-07 01:59:10 UTC (rev 178012)
</span><span class="lines">@@ -1,4 +0,0 @@
</span><del>-&lt;p&gt;Now go back&lt;/p&gt;
-&lt;script&gt;
-window.history.back();
-&lt;/script&gt;
</del></span></pre></div>
<a id="trunkLayoutTestshttptestscacheresourcesnostoreresourcehtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/http/tests/cache/resources/no-store-resource.html (178011 => 178012)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/cache/resources/no-store-resource.html        2015-01-07 01:57:00 UTC (rev 178011)
+++ trunk/LayoutTests/http/tests/cache/resources/no-store-resource.html        2015-01-07 01:59:10 UTC (rev 178012)
</span><span class="lines">@@ -10,7 +10,7 @@
</span><span class="cx"> 
</span><span class="cx">     // Go forward and back.
</span><span class="cx">     if (event.data === 'go-forward-and-back') {
</span><del>-        window.location = 'no-store-resource-forward.html';
</del><ins>+        window.location = 'history-back.html';
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (178011 => 178012)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-01-07 01:57:00 UTC (rev 178011)
+++ trunk/Source/WebCore/ChangeLog        2015-01-07 01:59:10 UTC (rev 178012)
</span><span class="lines">@@ -1,3 +1,65 @@
</span><ins>+2015-01-06  Chris Dumez  &lt;cdumez@apple.com&gt;
+
+        Do not attempt to revalidate cached main resource on back/forward navigation
+        https://bugs.webkit.org/show_bug.cgi?id=139263
+
+        Reviewed by Darin Adler.
+
+        Do not attempt to revalidate cached main resource on back/forward
+        navigation, as allowed by RFC2616 &amp; newer RFC7234 which distinguish
+        history mechanisms and caches, stating:
+
+           The freshness model (Section 4.2) does not necessarily apply to
+           history mechanisms.  That is, a history mechanism can display a
+           previous representation even if it has expired.
+
+        Previously, we would bypass revalidation on back/forward navigation
+        only for sub-resources. This patch extends this policy to the main
+        resource as well.
+
+        This behavior is also consistent with IE10+ and Chrome. It makes it more
+        likely we return cached content to the user on back/forward navigation
+        and avoids making network requests in this case.
+
+        Test: http/tests/cache/history-navigation-no-resource-revalidation.html
+
+        * loader/cache/CacheValidation.cpp:
+        (WebCore::redirectChainAllowsReuse):
+        * loader/cache/CacheValidation.h:
+        * loader/cache/CachedResource.cpp:
+        (WebCore::CachedResource::redirectChainAllowsReuse):
+        Add a &quot;ReuseExpiredRedirectionOrNot&quot; flag argument because in the case
+        of an HistoryBuffer navigation, we don't mind reuse an expired
+        redirection. However, we still need to make sure that the redirection
+        is actually cached before reusing it.
+
+        * loader/cache/CachedResource.h:
+        * loader/cache/CachedResourceLoader.cpp:
+        (WebCore::CachedResourceLoader::determineRevalidationPolicy):
+        - Do the redirectChainAllowsReuse() check *before* checking if the cache
+          policy is CachePolicyHistoryBuffer. This is needed because
+          redirectChainAllowsReuse() will return false if the redirection is not
+          cached. Loading from the cache in this case will cause us to load the
+          wrong resource (the one before the redirection). This case is covered
+          by http/tests/navigation/redirect-on-reload-updates-history-item.html.
+        - Do not use the cached main resource if it has &quot;cache-control: no-store&quot;,
+          even if it is a history navigation (cachePolicy is
+          CachePolicyHistoryBuffer). This maintains the previous behavior, and
+          some layout tests rely on this. We now have to be explicit about it
+          because cachePolicy() can now return CachePolicyHistoryBuffer for the
+          main resource (not just sub-resources). This difference in behavior
+          on history navigation for the main resource and sub-resources is not
+          great. However, I chose to maintain this pre-existing behavior in this
+          patch to do one behavior change at a time. We can harmonize this later.
+
+        Previously, the order was not an issue because the main resource was
+        always revalidated on back/forward navigation.
+
+        (WebCore::CachedResourceLoader::cachePolicy):
+        Return CachePolicyHistoryBuffer for the main resource in case of
+        history navigation, instead of CachePolicyVerify so that we don't
+        attempt to revalidate.
+
</ins><span class="cx"> 2015-01-06  Commit Queue  &lt;commit-queue@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, rolling out r177988.
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCoreexpin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.exp.in (178011 => 178012)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.exp.in        2015-01-07 01:57:00 UTC (rev 178011)
+++ trunk/Source/WebCore/WebCore.exp.in        2015-01-07 01:59:10 UTC (rev 178012)
</span><span class="lines">@@ -1058,7 +1058,7 @@
</span><span class="cx"> __ZN7WebCore24fileSystemRepresentationERKN3WTF6StringE
</span><span class="cx"> __ZN7WebCore24notifyHistoryItemChangedE
</span><span class="cx"> __ZN7WebCore24pathByAppendingComponentERKN3WTF6StringES3_
</span><del>-__ZN7WebCore24redirectChainAllowsReuseENS_24RedirectChainCacheStatusE
</del><ins>+__ZN7WebCore24redirectChainAllowsReuseENS_24RedirectChainCacheStatusENS_28ReuseExpiredRedirectionOrNotE
</ins><span class="cx"> __ZN7WebCore25addLanguageChangeObserverEPvPFvS0_E
</span><span class="cx"> __ZN7WebCore25computeViewportAttributesENS_17ViewportArgumentsEiiifNS_7IntSizeE
</span><span class="cx"> __ZN7WebCore25createCanonicalUUIDStringEv
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCacheValidationcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CacheValidation.cpp (178011 => 178012)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/cache/CacheValidation.cpp        2015-01-07 01:57:00 UTC (rev 178011)
+++ trunk/Source/WebCore/loader/cache/CacheValidation.cpp        2015-01-07 01:59:10 UTC (rev 178012)
</span><span class="lines">@@ -135,7 +135,7 @@
</span><span class="cx">     redirectChainCacheStatus.endOfValidity = std::min(redirectChainCacheStatus.endOfValidity, endOfValidity);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool redirectChainAllowsReuse(RedirectChainCacheStatus redirectChainCacheStatus)
</del><ins>+bool redirectChainAllowsReuse(RedirectChainCacheStatus redirectChainCacheStatus, ReuseExpiredRedirectionOrNot reuseExpiredRedirection)
</ins><span class="cx"> {
</span><span class="cx">     switch (redirectChainCacheStatus.status) {
</span><span class="cx">     case RedirectChainCacheStatus::NoRedirection:
</span><span class="lines">@@ -143,7 +143,7 @@
</span><span class="cx">     case RedirectChainCacheStatus::NotCachedRedirection:
</span><span class="cx">         return false;
</span><span class="cx">     case RedirectChainCacheStatus::CachedRedirection:
</span><del>-        return currentTime() &lt;= redirectChainCacheStatus.endOfValidity;
</del><ins>+        return reuseExpiredRedirection || currentTime() &lt;= redirectChainCacheStatus.endOfValidity;
</ins><span class="cx">     }
</span><span class="cx">     ASSERT_NOT_REACHED();
</span><span class="cx">     return false;
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCacheValidationh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CacheValidation.h (178011 => 178012)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/cache/CacheValidation.h        2015-01-07 01:57:00 UTC (rev 178011)
+++ trunk/Source/WebCore/loader/cache/CacheValidation.h        2015-01-07 01:59:10 UTC (rev 178012)
</span><span class="lines">@@ -48,8 +48,10 @@
</span><span class="cx"> double computeFreshnessLifetimeForHTTPFamily(const ResourceResponse&amp;, double responseTimestamp);
</span><span class="cx"> void updateResponseHeadersAfterRevalidation(ResourceResponse&amp;, const ResourceResponse&amp; validatingResponse);
</span><span class="cx"> void updateRedirectChainStatus(RedirectChainCacheStatus&amp;, const ResourceResponse&amp;);
</span><del>-bool redirectChainAllowsReuse(RedirectChainCacheStatus);
</del><span class="cx"> 
</span><ins>+enum ReuseExpiredRedirectionOrNot { DoNotReuseExpiredRedirection, ReuseExpiredRedirection };
+bool redirectChainAllowsReuse(RedirectChainCacheStatus, ReuseExpiredRedirectionOrNot);
+
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCachedResourcecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CachedResource.cpp (178011 => 178012)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/cache/CachedResource.cpp        2015-01-07 01:57:00 UTC (rev 178011)
+++ trunk/Source/WebCore/loader/cache/CachedResource.cpp        2015-01-07 01:59:10 UTC (rev 178012)
</span><span class="lines">@@ -715,9 +715,9 @@
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool CachedResource::redirectChainAllowsReuse() const
</del><ins>+bool CachedResource::redirectChainAllowsReuse(ReuseExpiredRedirectionOrNot reuseExpiredRedirection) const
</ins><span class="cx"> {
</span><del>-    return WebCore::redirectChainAllowsReuse(m_redirectChainCacheStatus);
</del><ins>+    return WebCore::redirectChainAllowsReuse(m_redirectChainCacheStatus, reuseExpiredRedirection);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> unsigned CachedResource::overheadSize() const
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCachedResourceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CachedResource.h (178011 => 178012)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/cache/CachedResource.h        2015-01-07 01:57:00 UTC (rev 178011)
+++ trunk/Source/WebCore/loader/cache/CachedResource.h        2015-01-07 01:59:10 UTC (rev 178012)
</span><span class="lines">@@ -230,7 +230,7 @@
</span><span class="cx">     bool canUseCacheValidator() const;
</span><span class="cx"> 
</span><span class="cx">     virtual bool mustRevalidateDueToCacheHeaders(const CachedResourceLoader&amp;, CachePolicy) const;
</span><del>-    bool redirectChainAllowsReuse() const;
</del><ins>+    bool redirectChainAllowsReuse(ReuseExpiredRedirectionOrNot) const;
</ins><span class="cx"> 
</span><span class="cx">     bool isCacheValidator() const { return m_resourceToRevalidate; }
</span><span class="cx">     CachedResource* resourceToRevalidate() const { return m_resourceToRevalidate; }
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCachedResourceLoadercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CachedResourceLoader.cpp (178011 => 178012)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/cache/CachedResourceLoader.cpp        2015-01-07 01:57:00 UTC (rev 178011)
+++ trunk/Source/WebCore/loader/cache/CachedResourceLoader.cpp        2015-01-07 01:59:10 UTC (rev 178012)
</span><span class="lines">@@ -620,11 +620,23 @@
</span><span class="cx">     // Alwaus use preloads.
</span><span class="cx">     if (existingResource-&gt;isPreloaded())
</span><span class="cx">         return Use;
</span><del>-    
-    // CachePolicyHistoryBuffer uses the cache no matter what.
-    if (cachePolicy(type) == CachePolicyHistoryBuffer)
-        return Use;
</del><span class="cx"> 
</span><ins>+    // Validate the redirect chain.
+    bool cachePolicyIsHistoryBuffer = cachePolicy(type) == CachePolicyHistoryBuffer;
+    if (!existingResource-&gt;redirectChainAllowsReuse(cachePolicyIsHistoryBuffer ? ReuseExpiredRedirection : DoNotReuseExpiredRedirection)) {
+        LOG(ResourceLoading, &quot;CachedResourceLoader::determineRevalidationPolicy reloading due to not cached or expired redirections.&quot;);
+        FEATURE_COUNTER_INCREMENT_KEY(page, FeatureCounterResourceRequestInMemoryCacheUnusedReasonRedirectChainKey);
+        return Reload;
+    }
+
+    // CachePolicyHistoryBuffer uses the cache except if this is a main resource with &quot;cache-control: no-store&quot;.
+    if (cachePolicyIsHistoryBuffer) {
+        // FIXME: Ignoring &quot;cache-control: no-cache&quot; for sub-resources on history navigation but not the main
+        // resource is inconsistent. We should probably harmonize this.
+        if (!existingResource-&gt;response().cacheControlContainsNoStore() || type != CachedResource::MainResource)
+            return Use;
+    }
+
</ins><span class="cx">     // Don't reuse resources with Cache-control: no-store.
</span><span class="cx">     if (existingResource-&gt;response().cacheControlContainsNoStore()) {
</span><span class="cx">         LOG(ResourceLoading, &quot;CachedResourceLoader::determineRevalidationPolicy reloading due to Cache-control: no-store.&quot;);
</span><span class="lines">@@ -632,13 +644,6 @@
</span><span class="cx">         return Reload;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // Validate the redirect chain
-    if (!existingResource-&gt;redirectChainAllowsReuse()) {
-        LOG(ResourceLoading, &quot;CachedResourceLoader::determineRevalidationPolicy reloading due to not cached or expired redirections.&quot;);
-        FEATURE_COUNTER_INCREMENT_KEY(page, FeatureCounterResourceRequestInMemoryCacheUnusedReasonRedirectChainKey);
-        return Reload;
-    }
-
</del><span class="cx">     // If credentials were sent with the previous request and won't be
</span><span class="cx">     // with this one, or vice versa, re-fetch the resource.
</span><span class="cx">     //
</span><span class="lines">@@ -759,9 +764,18 @@
</span><span class="cx">     if (type != CachedResource::MainResource)
</span><span class="cx">         return frame()-&gt;loader().subresourceCachePolicy();
</span><span class="cx">     
</span><del>-    if (frame()-&gt;loader().loadType() == FrameLoadType::ReloadFromOrigin || frame()-&gt;loader().loadType() == FrameLoadType::Reload)
</del><ins>+    switch (frame()-&gt;loader().loadType()) {
+    case FrameLoadType::ReloadFromOrigin:
+    case FrameLoadType::Reload:
</ins><span class="cx">         return CachePolicyReload;
</span><del>-    return CachePolicyVerify;
</del><ins>+    case FrameLoadType::Back:
+    case FrameLoadType::Forward:
+    case FrameLoadType::IndexedBackForward:
+        // Do not revalidate cached main resource on back/forward navigation.
+        return CachePolicyHistoryBuffer;
+    default:
+        return CachePolicyVerify;
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void CachedResourceLoader::removeCachedResource(CachedResource* resource) const
</span></span></pre>
</div>
</div>

</body>
</html>