<!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>[207086] 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/207086">207086</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2016-10-11 03:53:22 -0700 (Tue, 11 Oct 2016)</dd>
</dl>
<h3>Log Message</h3>
<pre>[Fetch API] Support Request cache mode
https://bugs.webkit.org/show_bug.cgi?id=162281
Patch by Youenn Fablet <youenn@apple.com> on 2016-10-11
Reviewed by Alex Christensen.
LayoutTests/imported/w3c:
* web-platform-tests/fetch/api/request/request-cache-expected.txt: Rebasing test now that more tests are passing.
* web-platform-tests/fetch/api/request/request-error-expected.txt:
* web-platform-tests/fetch/api/request/request-error.html: Adding test to ensure only-if-cached is used with same-origin fetch mode.
Source/WebCore:
Covered by updated test.
Added support for only-if-cached mode at Request level.
Added support for cache mode at CachedResourceLoader, by setting HTTP headers and ResourceRequest cache policy
based on https://fetch.spec.whatwg.org/#concept-request-cache-mode and https://fetch.spec.whatwg.org/#http-network-or-cache-fetch.
Disabled default cache policy computation (done in FrameLoader) when cache mode is different from the default.
Activated no-store cache mode for EventSource as per https://html.spec.whatwg.org/#the-eventsource-interface.
* Modules/fetch/FetchRequest.cpp:
(WebCore::setCache): Adding support for only-if-cached.
(WebCore::buildOptions): Throw if only-if-cached and fetch mode is not same-origin.
* loader/FetchOptions.h: Adding support for only-if-cached.
* loader/FrameLoader.cpp:
(WebCore::FrameLoader::defaultRequestCachingPolicy): Introduced to ease readability.
(WebCore::FrameLoader::addExtraFieldsToRequest): Updating cache policy only if request has the default cache policy.
This allows bypassing the default behavior for fetch cache mode different from "default".
* loader/FrameLoader.h:
* loader/cache/CachedResourceLoader.cpp:
(WebCore::updateRequestAccordingCacheMode): Introduced to set headers and request cache policy according fetch cache mode.
(WebCore::CachedResourceLoader::requestResource):
(WebCore::CachedResourceLoader::loadResource):
(WebCore::CachedResourceLoader::determineRevalidationPolicy): Ensure bypassing the memory cache in no-store and reload cases.
We reload in case of cache mode=reload to refresh the meory cache entry.
* loader/cache/CachedResourceRequest.h:
(WebCore::CachedResourceRequest::setCacheModeToNoStore):
* page/EventSource.cpp:
(WebCore::EventSource::connect): Use no-store cache mode as per https://html.spec.whatwg.org/#the-eventsource-interface.
* platform/network/HTTPHeaderMap.cpp:
(WebCore::HTTPHeaderMap::addIfNotPresent): Helper routine.
* platform/network/HTTPHeaderMap.h:
* platform/network/HTTPHeaderValues.cpp:
* platform/network/HTTPHeaderValues.h:
* platform/network/ResourceRequestBase.cpp:
(WebCore::ResourceRequestBase::addHTTPHeaderFieldIfNotPresent):
(WebCore::ResourceRequestBase::addHTTPHeaderField):
(WebCore::ResourceRequestBase::hasHTTPHeaderField):
* platform/network/ResourceRequestBase.h:
LayoutTests:
Activating request-cache.html tests for WK1, but not yet for WK2.
* TestExpectations:
* platform/mac/TestExpectations:
* platform/wk2/TestExpectations:</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsTestExpectations">trunk/LayoutTests/TestExpectations</a></li>
<li><a href="#trunkLayoutTestsimportedw3cChangeLog">trunk/LayoutTests/imported/w3c/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestsfetchapirequestrequestcacheexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-cache-expected.txt</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestsfetchapirequestrequesterrorexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-error-expected.txt</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestsfetchapirequestrequesterrorhtml">trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-error.html</a></li>
<li><a href="#trunkLayoutTestsplatformmacTestExpectations">trunk/LayoutTests/platform/mac/TestExpectations</a></li>
<li><a href="#trunkLayoutTestsplatformwk2TestExpectations">trunk/LayoutTests/platform/wk2/TestExpectations</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreModulesfetchFetchRequestcpp">trunk/Source/WebCore/Modules/fetch/FetchRequest.cpp</a></li>
<li><a href="#trunkSourceWebCoreloaderFetchOptionsh">trunk/Source/WebCore/loader/FetchOptions.h</a></li>
<li><a href="#trunkSourceWebCoreloaderFrameLoadercpp">trunk/Source/WebCore/loader/FrameLoader.cpp</a></li>
<li><a href="#trunkSourceWebCoreloaderFrameLoaderh">trunk/Source/WebCore/loader/FrameLoader.h</a></li>
<li><a href="#trunkSourceWebCoreloadercacheCachedResourceLoadercpp">trunk/Source/WebCore/loader/cache/CachedResourceLoader.cpp</a></li>
<li><a href="#trunkSourceWebCoreloadercacheCachedResourceLoaderh">trunk/Source/WebCore/loader/cache/CachedResourceLoader.h</a></li>
<li><a href="#trunkSourceWebCoreloadercacheCachedResourceRequesth">trunk/Source/WebCore/loader/cache/CachedResourceRequest.h</a></li>
<li><a href="#trunkSourceWebCorepageEventSourcecpp">trunk/Source/WebCore/page/EventSource.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkHTTPHeaderMapcpp">trunk/Source/WebCore/platform/network/HTTPHeaderMap.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkHTTPHeaderMaph">trunk/Source/WebCore/platform/network/HTTPHeaderMap.h</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkHTTPHeaderValuescpp">trunk/Source/WebCore/platform/network/HTTPHeaderValues.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkHTTPHeaderValuesh">trunk/Source/WebCore/platform/network/HTTPHeaderValues.h</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkResourceRequestBasecpp">trunk/Source/WebCore/platform/network/ResourceRequestBase.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkResourceRequestBaseh">trunk/Source/WebCore/platform/network/ResourceRequestBase.h</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (207085 => 207086)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/LayoutTests/ChangeLog        2016-10-11 10:53:22 UTC (rev 207086)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2016-10-11 Youenn Fablet <youenn@apple.com>
+
+ [Fetch API] Support Request cache mode
+ https://bugs.webkit.org/show_bug.cgi?id=162281
+
+ Reviewed by Alex Christensen.
+
+ Activating request-cache.html tests for WK1, but not yet for WK2.
+
+ * TestExpectations:
+ * platform/mac/TestExpectations:
+ * platform/wk2/TestExpectations:
+
</ins><span class="cx"> 2016-10-11 Chris Dumez <cdumez@apple.com>
</span><span class="cx">
</span><span class="cx"> Update IDBVersionChangeEvent to stop using legacy [ConstructorTemplate=Event]
</span></span></pre></div>
<a id="trunkLayoutTestsTestExpectations"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/TestExpectations (207085 => 207086)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/TestExpectations        2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/LayoutTests/TestExpectations        2016-10-11 10:53:22 UTC (rev 207086)
</span><span class="lines">@@ -282,8 +282,6 @@
</span><span class="cx"> # Failing assertion with dynamic message
</span><span class="cx"> imported/w3c/web-platform-tests/XMLHttpRequest/responsexml-document-properties.htm [ Failure ]
</span><span class="cx">
</span><del>-imported/w3c/web-platform-tests/fetch/api/request/request-cache.html [ Skip ]
-
</del><span class="cx"> webkit.org/b/161176 [ Debug ] imported/w3c/web-platform-tests/url/url-setters.html [ Skip ]
</span><span class="cx">
</span><span class="cx"> webkit.org/b/157068 imported/w3c/web-platform-tests/fetch/nosniff/importscripts.html [ Skip ]
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/ChangeLog (207085 => 207086)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/ChangeLog        2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/LayoutTests/imported/w3c/ChangeLog        2016-10-11 10:53:22 UTC (rev 207086)
</span><span class="lines">@@ -1,3 +1,14 @@
</span><ins>+2016-10-11 Youenn Fablet <youenn@apple.com>
+
+ [Fetch API] Support Request cache mode
+ https://bugs.webkit.org/show_bug.cgi?id=162281
+
+ Reviewed by Alex Christensen.
+
+ * web-platform-tests/fetch/api/request/request-cache-expected.txt: Rebasing test now that more tests are passing.
+ * web-platform-tests/fetch/api/request/request-error-expected.txt:
+ * web-platform-tests/fetch/api/request/request-error.html: Adding test to ensure only-if-cached is used with same-origin fetch mode.
+
</ins><span class="cx"> 2016-10-10 Chris Dumez <cdumez@apple.com>
</span><span class="cx">
</span><span class="cx"> Add support for languagechange event
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestsfetchapirequestrequestcacheexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-cache-expected.txt (207085 => 207086)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-cache-expected.txt        2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-cache-expected.txt        2016-10-11 10:53:22 UTC (rev 207086)
</span><span class="lines">@@ -5,10 +5,10 @@
</span><span class="cx"> PASS RequestCache "default" mode checks the cache for previously cached content and avoids going to the network if a fresh response exists with date and fresh response
</span><span class="cx"> PASS RequestCache "no-cache" mode revalidates stale responses found in the cache with Etag and stale response
</span><span class="cx"> PASS RequestCache "no-cache" mode revalidates stale responses found in the cache with date and stale response
</span><del>-FAIL RequestCache "no-cache" mode revalidates fresh responses found in the cache with Etag and fresh response assert_equals: expected 2 but got 1
-FAIL RequestCache "no-cache" mode revalidates fresh responses found in the cache with date and fresh response assert_equals: expected 2 but got 1
-FAIL RequestCache "force-cache" mode checks the cache for previously cached content and avoid revalidation for stale responses with Etag and stale response assert_equals: expected 1 but got 2
-FAIL RequestCache "force-cache" mode checks the cache for previously cached content and avoid revalidation for stale responses with date and stale response assert_equals: expected 1 but got 2
</del><ins>+PASS RequestCache "no-cache" mode revalidates fresh responses found in the cache with Etag and fresh response
+PASS RequestCache "no-cache" mode revalidates fresh responses found in the cache with date and fresh response
+PASS RequestCache "force-cache" mode checks the cache for previously cached content and avoid revalidation for stale responses with Etag and stale response
+PASS RequestCache "force-cache" mode checks the cache for previously cached content and avoid revalidation for stale responses with date and stale response
</ins><span class="cx"> PASS RequestCache "force-cache" mode checks the cache for previously cached content and avoid revalidation for fresh responses with Etag and fresh response
</span><span class="cx"> PASS RequestCache "force-cache" mode checks the cache for previously cached content and avoid revalidation for fresh responses with date and fresh response
</span><span class="cx"> PASS RequestCache "force-cache" mode checks the cache for previously cached content and goes to the network if a cached response is not found with Etag and stale response
</span><span class="lines">@@ -23,10 +23,10 @@
</span><span class="cx"> PASS RequestCache "force-cache" stores the response in the cache if it goes to the network with date and stale response
</span><span class="cx"> PASS RequestCache "force-cache" stores the response in the cache if it goes to the network with Etag and fresh response
</span><span class="cx"> PASS RequestCache "force-cache" stores the response in the cache if it goes to the network with date and fresh response
</span><del>-FAIL RequestCache "only-if-cached" mode checks the cache for previously cached content and avoids revalidation for stale responses with Etag and stale response promise_test: Unhandled rejection with value: object "TypeError: Type error"
-FAIL RequestCache "only-if-cached" mode checks the cache for previously cached content and avoids revalidation for stale responses with date and stale response promise_test: Unhandled rejection with value: object "TypeError: Type error"
-FAIL RequestCache "only-if-cached" mode checks the cache for previously cached content and avoids revalidation for fresh responses with Etag and fresh response promise_test: Unhandled rejection with value: object "TypeError: Type error"
-FAIL RequestCache "only-if-cached" mode checks the cache for previously cached content and avoids revalidation for fresh responses with date and fresh response promise_test: Unhandled rejection with value: object "TypeError: Type error"
</del><ins>+PASS RequestCache "only-if-cached" mode checks the cache for previously cached content and avoids revalidation for stale responses with Etag and stale response
+PASS RequestCache "only-if-cached" mode checks the cache for previously cached content and avoids revalidation for stale responses with date and stale response
+PASS RequestCache "only-if-cached" mode checks the cache for previously cached content and avoids revalidation for fresh responses with Etag and fresh response
+PASS RequestCache "only-if-cached" mode checks the cache for previously cached content and avoids revalidation for fresh responses with date and fresh response
</ins><span class="cx"> PASS RequestCache "only-if-cached" mode checks the cache for previously cached content and does not go to the network if a cached response is not found with Etag and fresh response
</span><span class="cx"> PASS RequestCache "only-if-cached" mode checks the cache for previously cached content and does not go to the network if a cached response is not found with date and fresh response
</span><span class="cx"> FAIL RequestCache "only-if-cached" (with "same-origin") uses cached same-origin redirects to same-origin content with Etag and fresh response promise_test: Unhandled rejection with value: object "TypeError: Type error"
</span><span class="lines">@@ -37,14 +37,14 @@
</span><span class="cx"> PASS RequestCache "only-if-cached" (with "same-origin") does not follow redirects across origins and rejects with date and fresh response
</span><span class="cx"> PASS RequestCache "only-if-cached" (with "same-origin") does not follow redirects across origins and rejects with Etag and stale response
</span><span class="cx"> PASS RequestCache "only-if-cached" (with "same-origin") does not follow redirects across origins and rejects with date and stale response
</span><del>-FAIL RequestCache "no-store" mode does not check the cache for previously cached content and goes to the network regardless with Etag and stale response assert_equals: expected (undefined) undefined but got (string) "\"0.04196530864700354\""
-FAIL RequestCache "no-store" mode does not check the cache for previously cached content and goes to the network regardless with date and stale response assert_equals: expected (undefined) undefined but got (string) "Fri, 09 Sep 2016 08:49:10 GMT"
-FAIL RequestCache "no-store" mode does not check the cache for previously cached content and goes to the network regardless with Etag and fresh response assert_equals: expected 2 but got 1
-FAIL RequestCache "no-store" mode does not check the cache for previously cached content and goes to the network regardless with date and fresh response assert_equals: expected 2 but got 1
-FAIL RequestCache "no-store" mode does not store the response in the cache with Etag and stale response assert_equals: expected (undefined) undefined but got (string) "\"0.12846053184726147\""
-FAIL RequestCache "no-store" mode does not store the response in the cache with date and stale response assert_equals: expected (undefined) undefined but got (string) "Fri, 09 Sep 2016 08:49:10 GMT"
-FAIL RequestCache "no-store" mode does not store the response in the cache with Etag and fresh response assert_equals: expected 2 but got 1
-FAIL RequestCache "no-store" mode does not store the response in the cache with date and fresh response assert_equals: expected 2 but got 1
</del><ins>+PASS RequestCache "no-store" mode does not check the cache for previously cached content and goes to the network regardless with Etag and stale response
+PASS RequestCache "no-store" mode does not check the cache for previously cached content and goes to the network regardless with date and stale response
+PASS RequestCache "no-store" mode does not check the cache for previously cached content and goes to the network regardless with Etag and fresh response
+PASS RequestCache "no-store" mode does not check the cache for previously cached content and goes to the network regardless with date and fresh response
+PASS RequestCache "no-store" mode does not store the response in the cache with Etag and stale response
+PASS RequestCache "no-store" mode does not store the response in the cache with date and stale response
+PASS RequestCache "no-store" mode does not store the response in the cache with Etag and fresh response
+PASS RequestCache "no-store" mode does not store the response in the cache with date and fresh response
</ins><span class="cx"> PASS RequestCache "default" mode with an If-Modified-Since header is treated similarly to "no-store" with Etag and stale response
</span><span class="cx"> PASS RequestCache "default" mode with an If-Modified-Since header is treated similarly to "no-store" with date and stale response
</span><span class="cx"> PASS RequestCache "default" mode with an If-Modified-Since header is treated similarly to "no-store" with Etag and fresh response
</span><span class="lines">@@ -51,7 +51,7 @@
</span><span class="cx"> PASS RequestCache "default" mode with an If-Modified-Since header is treated similarly to "no-store" with date and fresh response
</span><span class="cx"> PASS RequestCache "default" mode with an If-Modified-Since header is treated similarly to "no-store" with Etag and stale response
</span><span class="cx"> PASS RequestCache "default" mode with an If-Modified-Since header is treated similarly to "no-store" with date and stale response
</span><del>-FAIL RequestCache "default" mode with an If-Modified-Since header is treated similarly to "no-store" with Etag and fresh response assert_equals: expected 2 but got 1
</del><ins>+PASS RequestCache "default" mode with an If-Modified-Since header is treated similarly to "no-store" with Etag and fresh response
</ins><span class="cx"> PASS RequestCache "default" mode with an If-Modified-Since header is treated similarly to "no-store" with date and fresh response
</span><span class="cx"> PASS RequestCache "default" mode with an If-None-Match header is treated similarly to "no-store" with Etag and stale response
</span><span class="cx"> PASS RequestCache "default" mode with an If-None-Match header is treated similarly to "no-store" with date and stale response
</span><span class="lines">@@ -59,8 +59,8 @@
</span><span class="cx"> PASS RequestCache "default" mode with an If-None-Match header is treated similarly to "no-store" with date and fresh response
</span><span class="cx"> PASS RequestCache "default" mode with an If-None-Match header is treated similarly to "no-store" with Etag and stale response
</span><span class="cx"> PASS RequestCache "default" mode with an If-None-Match header is treated similarly to "no-store" with date and stale response
</span><del>-FAIL RequestCache "default" mode with an If-None-Match header is treated similarly to "no-store" with Etag and fresh response assert_equals: expected 2 but got 1
-FAIL RequestCache "default" mode with an If-None-Match header is treated similarly to "no-store" with date and fresh response assert_equals: expected 2 but got 1
</del><ins>+PASS RequestCache "default" mode with an If-None-Match header is treated similarly to "no-store" with Etag and fresh response
+PASS RequestCache "default" mode with an If-None-Match header is treated similarly to "no-store" with date and fresh response
</ins><span class="cx"> PASS RequestCache "default" mode with an If-Unmodified-Since header is treated similarly to "no-store" with Etag and stale response
</span><span class="cx"> PASS RequestCache "default" mode with an If-Unmodified-Since header is treated similarly to "no-store" with date and stale response
</span><span class="cx"> PASS RequestCache "default" mode with an If-Unmodified-Since header is treated similarly to "no-store" with Etag and fresh response
</span><span class="lines">@@ -67,8 +67,8 @@
</span><span class="cx"> PASS RequestCache "default" mode with an If-Unmodified-Since header is treated similarly to "no-store" with date and fresh response
</span><span class="cx"> PASS RequestCache "default" mode with an If-Unmodified-Since header is treated similarly to "no-store" with Etag and stale response
</span><span class="cx"> PASS RequestCache "default" mode with an If-Unmodified-Since header is treated similarly to "no-store" with date and stale response
</span><del>-FAIL RequestCache "default" mode with an If-Unmodified-Since header is treated similarly to "no-store" with Etag and fresh response assert_equals: expected 2 but got 1
-FAIL RequestCache "default" mode with an If-Unmodified-Since header is treated similarly to "no-store" with date and fresh response assert_equals: expected 2 but got 1
</del><ins>+PASS RequestCache "default" mode with an If-Unmodified-Since header is treated similarly to "no-store" with Etag and fresh response
+PASS RequestCache "default" mode with an If-Unmodified-Since header is treated similarly to "no-store" with date and fresh response
</ins><span class="cx"> PASS RequestCache "default" mode with an If-Match header is treated similarly to "no-store" with Etag and stale response
</span><span class="cx"> PASS RequestCache "default" mode with an If-Match header is treated similarly to "no-store" with date and stale response
</span><span class="cx"> PASS RequestCache "default" mode with an If-Match header is treated similarly to "no-store" with Etag and fresh response
</span><span class="lines">@@ -75,8 +75,8 @@
</span><span class="cx"> PASS RequestCache "default" mode with an If-Match header is treated similarly to "no-store" with date and fresh response
</span><span class="cx"> PASS RequestCache "default" mode with an If-Match header is treated similarly to "no-store" with Etag and stale response
</span><span class="cx"> PASS RequestCache "default" mode with an If-Match header is treated similarly to "no-store" with date and stale response
</span><del>-FAIL RequestCache "default" mode with an If-Match header is treated similarly to "no-store" with Etag and fresh response assert_equals: expected 2 but got 1
-FAIL RequestCache "default" mode with an If-Match header is treated similarly to "no-store" with date and fresh response assert_equals: expected 2 but got 1
</del><ins>+PASS RequestCache "default" mode with an If-Match header is treated similarly to "no-store" with Etag and fresh response
+PASS RequestCache "default" mode with an If-Match header is treated similarly to "no-store" with date and fresh response
</ins><span class="cx"> PASS RequestCache "default" mode with an If-Range header is treated similarly to "no-store" with Etag and stale response
</span><span class="cx"> PASS RequestCache "default" mode with an If-Range header is treated similarly to "no-store" with date and stale response
</span><span class="cx"> PASS RequestCache "default" mode with an If-Range header is treated similarly to "no-store" with Etag and fresh response
</span><span class="lines">@@ -83,22 +83,22 @@
</span><span class="cx"> PASS RequestCache "default" mode with an If-Range header is treated similarly to "no-store" with date and fresh response
</span><span class="cx"> PASS RequestCache "default" mode with an If-Range header is treated similarly to "no-store" with Etag and stale response
</span><span class="cx"> PASS RequestCache "default" mode with an If-Range header is treated similarly to "no-store" with date and stale response
</span><del>-FAIL RequestCache "default" mode with an If-Range header is treated similarly to "no-store" with Etag and fresh response assert_equals: expected 2 but got 1
-FAIL RequestCache "default" mode with an If-Range header is treated similarly to "no-store" with date and fresh response assert_equals: expected 2 but got 1
</del><ins>+PASS RequestCache "default" mode with an If-Range header is treated similarly to "no-store" with Etag and fresh response
+PASS RequestCache "default" mode with an If-Range header is treated similarly to "no-store" with date and fresh response
</ins><span class="cx"> PASS Responses with the "Cache-Control: no-store" header are not stored in the cache with Etag and stale response
</span><span class="cx"> PASS Responses with the "Cache-Control: no-store" header are not stored in the cache with date and stale response
</span><span class="cx"> PASS Responses with the "Cache-Control: no-store" header are not stored in the cache with Etag and fresh response
</span><span class="cx"> PASS Responses with the "Cache-Control: no-store" header are not stored in the cache with date and fresh response
</span><del>-FAIL RequestCache "reload" mode does not check the cache for previously cached content and goes to the network regardless with Etag and stale response assert_equals: expected (undefined) undefined but got (string) "\"0.7894894845056666\""
-FAIL RequestCache "reload" mode does not check the cache for previously cached content and goes to the network regardless with date and stale response assert_equals: expected (undefined) undefined but got (string) "Fri, 09 Sep 2016 08:49:10 GMT"
-FAIL RequestCache "reload" mode does not check the cache for previously cached content and goes to the network regardless with Etag and fresh response assert_equals: expected 2 but got 1
-FAIL RequestCache "reload" mode does not check the cache for previously cached content and goes to the network regardless with date and fresh response assert_equals: expected 2 but got 1
</del><ins>+PASS RequestCache "reload" mode does not check the cache for previously cached content and goes to the network regardless with Etag and stale response
+PASS RequestCache "reload" mode does not check the cache for previously cached content and goes to the network regardless with date and stale response
+PASS RequestCache "reload" mode does not check the cache for previously cached content and goes to the network regardless with Etag and fresh response
+PASS RequestCache "reload" mode does not check the cache for previously cached content and goes to the network regardless with date and fresh response
</ins><span class="cx"> PASS RequestCache "reload" mode does store the response in the cache with Etag and stale response
</span><span class="cx"> PASS RequestCache "reload" mode does store the response in the cache with date and stale response
</span><del>-PASS RequestCache "reload" mode does store the response in the cache with Etag and fresh response
-PASS RequestCache "reload" mode does store the response in the cache with date and fresh response
-FAIL RequestCache "reload" mode does store the response in the cache even if a previous response is already stored with Etag and stale response assert_equals: expected (undefined) undefined but got (string) "\"0.49509960167414313\""
-FAIL RequestCache "reload" mode does store the response in the cache even if a previous response is already stored with date and stale response assert_equals: expected (undefined) undefined but got (string) "Fri, 09 Sep 2016 08:49:10 GMT"
-FAIL RequestCache "reload" mode does store the response in the cache even if a previous response is already stored with Etag and fresh response assert_equals: expected 2 but got 1
-FAIL RequestCache "reload" mode does store the response in the cache even if a previous response is already stored with date and fresh response assert_equals: expected 2 but got 1
</del><ins>+FAIL RequestCache "reload" mode does store the response in the cache with Etag and fresh response assert_equals: expected 1 but got 2
+FAIL RequestCache "reload" mode does store the response in the cache with date and fresh response assert_equals: expected 1 but got 2
+PASS RequestCache "reload" mode does store the response in the cache even if a previous response is already stored with Etag and stale response
+PASS RequestCache "reload" mode does store the response in the cache even if a previous response is already stored with date and stale response
+PASS RequestCache "reload" mode does store the response in the cache even if a previous response is already stored with Etag and fresh response
+PASS RequestCache "reload" mode does store the response in the cache even if a previous response is already stored with date and fresh response
</ins><span class="cx">
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestsfetchapirequestrequesterrorexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-error-expected.txt (207085 => 207086)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-error-expected.txt        2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-error-expected.txt        2016-10-11 10:53:22 UTC (rev 207086)
</span><span class="lines">@@ -19,4 +19,8 @@
</span><span class="cx"> PASS Bad credentials init parameter value
</span><span class="cx"> PASS Bad cache init parameter value
</span><span class="cx"> PASS Bad redirect init parameter value
</span><ins>+PASS Request with cache mode: only-if-cached and fetch mode: same-origin
+PASS Request with cache mode: only-if-cached and fetch mode: cors
+PASS Request with cache mode: only-if-cached and fetch mode: no-cors
+PASS Request should not get its content-type from the init request if init headers are provided
</ins><span class="cx">
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestsfetchapirequestrequesterrorhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-error.html (207085 => 207086)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-error.html        2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-error.html        2016-10-11 10:53:22 UTC (rev 207086)
</span><span class="lines">@@ -105,6 +105,28 @@
</span><span class="cx"> assert_throws(new TypeError(), function() { new Request("", options); });
</span><span class="cx"> },"Bad " + parameter +" init parameter value");
</span><span class="cx"> });
</span><ins>+
+ function testOnlyIfCachedMode(fetchMode, ok) {
+ test(function() {
+ var options = {"cache": "only-if-cached", "mode": fetchMode};
+ if (ok)
+ new Request("test", options);
+ else
+ assert_throws(new TypeError(), function() { new Request("test", options); });
+ }, "Request with cache mode: only-if-cached and fetch mode: " + fetchMode);
+ }
+ testOnlyIfCachedMode("same-origin", true);
+ testOnlyIfCachedMode("cors", false);
+ testOnlyIfCachedMode("no-cors", false);
+
+ test(function() {
+ var initialHeaders = new Headers([["Content-Type", "potato"]]);
+ var initialRequest = new Request("", {"headers" : initialHeaders});
+ var headers = new Headers([]);
+ var request = new Request(initialRequest, {"headers" : headers});
+ assert_false(request.headers.has("Content-Type"));
+ }, "Request should not get its content-type from the init request if init headers are provided");
+
</ins><span class="cx"> </script>
</span><span class="cx"> </body>
</span><span class="cx"> </html>
</span></span></pre></div>
<a id="trunkLayoutTestsplatformmacTestExpectations"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/mac/TestExpectations (207085 => 207086)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac/TestExpectations        2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/LayoutTests/platform/mac/TestExpectations        2016-10-11 10:53:22 UTC (rev 207086)
</span><span class="lines">@@ -1403,8 +1403,6 @@
</span><span class="cx"> # See also https://bugs.webkit.org/show_bug.cgi?id=162494
</span><span class="cx"> webkit.org/b/151287 [ ElCapitan+ ] media/controls/inline-elements-dropoff-order.html [ Failure ]
</span><span class="cx">
</span><del>-webkit.org/b/159683 imported/w3c/web-platform-tests/fetch/api/request/request-cache.html [ Pass Failure ]
-
</del><span class="cx"> webkit.org/b/158500 storage/indexeddb/database-close-private.html [ Pass Failure ]
</span><span class="cx">
</span><span class="cx"> webkit.org/b/163122 imported/blink/storage/indexeddb/blob-valid-after-deletion.html [ Pass Timeout ]
</span></span></pre></div>
<a id="trunkLayoutTestsplatformwk2TestExpectations"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/wk2/TestExpectations (207085 => 207086)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/wk2/TestExpectations        2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/LayoutTests/platform/wk2/TestExpectations        2016-10-11 10:53:22 UTC (rev 207086)
</span><span class="lines">@@ -684,6 +684,9 @@
</span><span class="cx"> # DumpRenderTree does not implement setWillSendRequestHTTPBody
</span><span class="cx"> http/tests/misc/will-send-request-with-client-provided-http-body.html [ Pass ]
</span><span class="cx">
</span><ins>+# bug 162281
+imported/w3c/web-platform-tests/fetch/api/request/request-cache.html [ Skip ]
+
</ins><span class="cx"> ### END OF (5) Progressions, expected successes that are expected failures in WebKit1.
</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 (207085 => 207086)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/Source/WebCore/ChangeLog        2016-10-11 10:53:22 UTC (rev 207086)
</span><span class="lines">@@ -1,3 +1,50 @@
</span><ins>+2016-10-11 Youenn Fablet <youenn@apple.com>
+
+ [Fetch API] Support Request cache mode
+ https://bugs.webkit.org/show_bug.cgi?id=162281
+
+ Reviewed by Alex Christensen.
+
+ Covered by updated test.
+
+ Added support for only-if-cached mode at Request level.
+
+ Added support for cache mode at CachedResourceLoader, by setting HTTP headers and ResourceRequest cache policy
+ based on https://fetch.spec.whatwg.org/#concept-request-cache-mode and https://fetch.spec.whatwg.org/#http-network-or-cache-fetch.
+
+ Disabled default cache policy computation (done in FrameLoader) when cache mode is different from the default.
+ Activated no-store cache mode for EventSource as per https://html.spec.whatwg.org/#the-eventsource-interface.
+
+ * Modules/fetch/FetchRequest.cpp:
+ (WebCore::setCache): Adding support for only-if-cached.
+ (WebCore::buildOptions): Throw if only-if-cached and fetch mode is not same-origin.
+ * loader/FetchOptions.h: Adding support for only-if-cached.
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::defaultRequestCachingPolicy): Introduced to ease readability.
+ (WebCore::FrameLoader::addExtraFieldsToRequest): Updating cache policy only if request has the default cache policy.
+ This allows bypassing the default behavior for fetch cache mode different from "default".
+ * loader/FrameLoader.h:
+ * loader/cache/CachedResourceLoader.cpp:
+ (WebCore::updateRequestAccordingCacheMode): Introduced to set headers and request cache policy according fetch cache mode.
+ (WebCore::CachedResourceLoader::requestResource):
+ (WebCore::CachedResourceLoader::loadResource):
+ (WebCore::CachedResourceLoader::determineRevalidationPolicy): Ensure bypassing the memory cache in no-store and reload cases.
+ We reload in case of cache mode=reload to refresh the meory cache entry.
+ * loader/cache/CachedResourceRequest.h:
+ (WebCore::CachedResourceRequest::setCacheModeToNoStore):
+ * page/EventSource.cpp:
+ (WebCore::EventSource::connect): Use no-store cache mode as per https://html.spec.whatwg.org/#the-eventsource-interface.
+ * platform/network/HTTPHeaderMap.cpp:
+ (WebCore::HTTPHeaderMap::addIfNotPresent): Helper routine.
+ * platform/network/HTTPHeaderMap.h:
+ * platform/network/HTTPHeaderValues.cpp:
+ * platform/network/HTTPHeaderValues.h:
+ * platform/network/ResourceRequestBase.cpp:
+ (WebCore::ResourceRequestBase::addHTTPHeaderFieldIfNotPresent):
+ (WebCore::ResourceRequestBase::addHTTPHeaderField):
+ (WebCore::ResourceRequestBase::hasHTTPHeaderField):
+ * platform/network/ResourceRequestBase.h:
+
</ins><span class="cx"> 2016-10-10 Antti Koivisto <antti@apple.com>
</span><span class="cx">
</span><span class="cx"> Stop copying author shadow pseudo rules into shadow tree style resolver
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesfetchFetchRequestcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/fetch/FetchRequest.cpp (207085 => 207086)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/fetch/FetchRequest.cpp        2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/Source/WebCore/Modules/fetch/FetchRequest.cpp        2016-10-11 10:53:22 UTC (rev 207086)
</span><span class="lines">@@ -98,6 +98,8 @@
</span><span class="cx"> options.cache = FetchOptions::Cache::NoCache;
</span><span class="cx"> else if (cache == "force-cache")
</span><span class="cx"> options.cache = FetchOptions::Cache::ForceCache;
</span><ins>+ else if (cache == "only-if-cached")
+ options.cache = FetchOptions::Cache::OnlyIfCached;
</ins><span class="cx"> else
</span><span class="cx"> return Exception { TypeError, ASCIILiteral("Bad cache mode value.") };
</span><span class="cx"> return Nullopt;
</span><span class="lines">@@ -195,6 +197,9 @@
</span><span class="cx"> return exception;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ if (request.options.cache == FetchOptions::Cache::OnlyIfCached && request.options.mode != FetchOptions::Mode::SameOrigin)
+ return Exception { TypeError, ASCIILiteral("only-if-cached cache option requires fetch mode to be same-origin.") };
+
</ins><span class="cx"> if (init.get("redirect", value)) {
</span><span class="cx"> exception = setRedirect(request.options, value);
</span><span class="cx"> if (exception)
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderFetchOptionsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/FetchOptions.h (207085 => 207086)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/FetchOptions.h        2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/Source/WebCore/loader/FetchOptions.h        2016-10-11 10:53:22 UTC (rev 207086)
</span><span class="lines">@@ -43,7 +43,7 @@
</span><span class="cx"> enum class Credentials { Omit, SameOrigin, Include };
</span><span class="cx"> Credentials credentials { Credentials::Omit };
</span><span class="cx">
</span><del>- enum class Cache { Default, NoStore, Reload, NoCache, ForceCache };
</del><ins>+ enum class Cache { Default, NoStore, Reload, NoCache, ForceCache, OnlyIfCached };
</ins><span class="cx"> Cache cache { Cache::Default };
</span><span class="cx">
</span><span class="cx"> enum class Redirect { Follow, Error, Manual };
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderFrameLoadercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/FrameLoader.cpp (207085 => 207086)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/FrameLoader.cpp        2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/Source/WebCore/loader/FrameLoader.cpp        2016-10-11 10:53:22 UTC (rev 207086)
</span><span class="lines">@@ -2562,36 +2562,14 @@
</span><span class="cx"> addHTTPUpgradeInsecureRequestsIfNeeded(request);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void FrameLoader::addExtraFieldsToRequest(ResourceRequest& request, FrameLoadType loadType, bool mainResource)
</del><ins>+ResourceRequestCachePolicy FrameLoader::defaultRequestCachingPolicy(const ResourceRequest& request, FrameLoadType loadType, bool isMainResource)
</ins><span class="cx"> {
</span><del>- Page* page = frame().page();
- bool cachingDisabled = page && page->isResourceCachingDisabled();
-
- if (cachingDisabled)
- request.setCachePolicy(ReloadIgnoringCacheData);
-
- // Don't set the cookie policy URL if it's already been set.
- // But make sure to set it on all requests regardless of protocol, as it has significance beyond the cookie policy (<rdar://problem/6616664>).
- if (request.firstPartyForCookies().isEmpty()) {
- if (mainResource && m_frame.isMainFrame())
- request.setFirstPartyForCookies(request.url());
- else if (Document* document = m_frame.document())
- request.setFirstPartyForCookies(document->firstPartyForCookies());
- }
-
- // The remaining modifications are only necessary for HTTP and HTTPS.
- if (!request.url().isEmpty() && !request.url().protocolIsInHTTPFamily())
- return;
-
- applyUserAgent(request);
-
- if (cachingDisabled) {
- // Cache policy was already set above in the non-HTTP-specific code.
- loadType = FrameLoadType::ReloadFromOrigin;
- } else if (!mainResource) {
</del><ins>+ if (m_overrideCachePolicyForTesting)
+ return m_overrideCachePolicyForTesting.value();
+ if (!isMainResource) {
</ins><span class="cx"> if (request.isConditional())
</span><del>- request.setCachePolicy(ReloadIgnoringCacheData);
- else if (documentLoader()->isLoadingInAPISense()) {
</del><ins>+ return ReloadIgnoringCacheData;
+ if (documentLoader()->isLoadingInAPISense()) {
</ins><span class="cx"> // If we inherit cache policy from a main resource, we use the DocumentLoader's
</span><span class="cx"> // original request cache policy for two reasons:
</span><span class="cx"> // 1. For POST requests, we mutate the cache policy for the main resource,
</span><span class="lines">@@ -2602,22 +2580,41 @@
</span><span class="cx"> ResourceRequestCachePolicy mainDocumentOriginalCachePolicy = documentLoader()->originalRequest().cachePolicy();
</span><span class="cx"> // Back-forward navigations try to load main resource from cache only to avoid re-submitting form data, and start over (with a warning dialog) if that fails.
</span><span class="cx"> // This policy is set on initial request too, but should not be inherited.
</span><del>- ResourceRequestCachePolicy subresourceCachePolicy = (mainDocumentOriginalCachePolicy == ReturnCacheDataDontLoad) ? ReturnCacheDataElseLoad : mainDocumentOriginalCachePolicy;
- request.setCachePolicy(subresourceCachePolicy);
- } else
- request.setCachePolicy(UseProtocolCachePolicy);
-
</del><ins>+ return (mainDocumentOriginalCachePolicy == ReturnCacheDataDontLoad) ? ReturnCacheDataElseLoad : mainDocumentOriginalCachePolicy;
+ }
</ins><span class="cx"> // FIXME: Other FrameLoader functions have duplicated code for setting cache policy of main request when reloading.
</span><span class="cx"> // It seems better to manage it explicitly than to hide the logic inside addExtraFieldsToRequest().
</span><span class="cx"> } else if (loadType == FrameLoadType::Reload || loadType == FrameLoadType::ReloadFromOrigin || request.isConditional())
</span><ins>+ return ReloadIgnoringCacheData;
+
+ return UseProtocolCachePolicy;
+}
+
+void FrameLoader::addExtraFieldsToRequest(ResourceRequest& request, FrameLoadType loadType, bool isMainResource)
+{
+ // Don't set the cookie policy URL if it's already been set.
+ // But make sure to set it on all requests regardless of protocol, as it has significance beyond the cookie policy (<rdar://problem/6616664>).
+ if (request.firstPartyForCookies().isEmpty()) {
+ if (isMainResource && m_frame.isMainFrame())
+ request.setFirstPartyForCookies(request.url());
+ else if (Document* document = m_frame.document())
+ request.setFirstPartyForCookies(document->firstPartyForCookies());
+ }
+
+ Page* page = frame().page();
+ bool hasSpecificCachePolicy = request.cachePolicy() != UseProtocolCachePolicy;
+
+ if (page && page->isResourceCachingDisabled()) {
</ins><span class="cx"> request.setCachePolicy(ReloadIgnoringCacheData);
</span><ins>+ loadType = FrameLoadType::ReloadFromOrigin;
+ } else if (!hasSpecificCachePolicy)
+ request.setCachePolicy(defaultRequestCachingPolicy(request, loadType, isMainResource));
</ins><span class="cx">
</span><del>- if (m_overrideCachePolicyForTesting)
- request.setCachePolicy(m_overrideCachePolicyForTesting.value());
- if (m_overrideResourceLoadPriorityForTesting)
- request.setPriority(m_overrideResourceLoadPriorityForTesting.value());
</del><ins>+ // The remaining modifications are only necessary for HTTP and HTTPS.
+ if (!request.url().isEmpty() && !request.url().protocolIsInHTTPFamily())
+ return;
</ins><span class="cx">
</span><del>- if (request.cachePolicy() == ReloadIgnoringCacheData) {
</del><ins>+ if (!hasSpecificCachePolicy && request.cachePolicy() == ReloadIgnoringCacheData) {
</ins><span class="cx"> if (loadType == FrameLoadType::Reload)
</span><span class="cx"> request.setHTTPHeaderField(HTTPHeaderName::CacheControl, "max-age=0");
</span><span class="cx"> else if (loadType == FrameLoadType::ReloadFromOrigin) {
</span><span class="lines">@@ -2626,7 +2623,12 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><del>- if (mainResource)
</del><ins>+ if (m_overrideResourceLoadPriorityForTesting)
+ request.setPriority(m_overrideResourceLoadPriorityForTesting.value());
+
+ applyUserAgent(request);
+
+ if (isMainResource)
</ins><span class="cx"> request.setHTTPAccept(defaultAcceptHeader);
</span><span class="cx">
</span><span class="cx"> // Make sure we send the Origin header.
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderFrameLoaderh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/FrameLoader.h (207085 => 207086)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/FrameLoader.h        2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/Source/WebCore/loader/FrameLoader.h        2016-10-11 10:53:22 UTC (rev 207086)
</span><span class="lines">@@ -311,16 +311,17 @@
</span><span class="cx"> bool allChildrenAreComplete() const; // immediate children, not all descendants
</span><span class="cx">
</span><span class="cx"> void checkTimerFired();
</span><del>-
</del><ins>+
</ins><span class="cx"> void loadSameDocumentItem(HistoryItem&);
</span><span class="cx"> void loadDifferentDocumentItem(HistoryItem&, FrameLoadType, FormSubmissionCacheLoadPolicy);
</span><del>-
</del><ins>+
</ins><span class="cx"> void loadProvisionalItemFromCachedPage();
</span><span class="cx">
</span><span class="cx"> void updateFirstPartyForCookies();
</span><span class="cx"> void setFirstPartyForCookies(const URL&);
</span><del>-
</del><ins>+
</ins><span class="cx"> void addExtraFieldsToRequest(ResourceRequest&, FrameLoadType, bool isMainResource);
</span><ins>+ ResourceRequestCachePolicy defaultRequestCachingPolicy(const ResourceRequest&, FrameLoadType, bool isMainResource);
</ins><span class="cx">
</span><span class="cx"> void clearProvisionalLoad();
</span><span class="cx"> void transitionToCommitted(CachedPage*);
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCachedResourceLoadercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CachedResourceLoader.cpp (207085 => 207086)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/cache/CachedResourceLoader.cpp        2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/Source/WebCore/loader/cache/CachedResourceLoader.cpp        2016-10-11 10:53:22 UTC (rev 207086)
</span><span class="lines">@@ -51,6 +51,7 @@
</span><span class="cx"> #include "FrameLoaderClient.h"
</span><span class="cx"> #include "HTMLElement.h"
</span><span class="cx"> #include "HTMLFrameOwnerElement.h"
</span><ins>+#include "HTTPHeaderValues.h"
</ins><span class="cx"> #include "LoaderStrategy.h"
</span><span class="cx"> #include "LocalizedStrings.h"
</span><span class="cx"> #include "Logging.h"
</span><span class="lines">@@ -663,6 +664,49 @@
</span><span class="cx"> // FIXME: Decide whether to support client hints
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+static inline void updateRequestAccordingCacheMode(CachedResourceRequest& request)
+{
+ if (request.options().cache == FetchOptions::Cache::Default
+ && (request.resourceRequest().hasHTTPHeaderField(HTTPHeaderName::IfModifiedSince)
+ || request.resourceRequest().hasHTTPHeaderField(HTTPHeaderName::IfNoneMatch)
+ || request.resourceRequest().hasHTTPHeaderField(HTTPHeaderName::IfUnmodifiedSince)
+ || request.resourceRequest().hasHTTPHeaderField(HTTPHeaderName::IfMatch)
+ || request.resourceRequest().hasHTTPHeaderField(HTTPHeaderName::IfRange)))
+ request.setCacheModeToNoStore();
+
+ switch (request.options().cache) {
+ case FetchOptions::Cache::NoCache:
+ request.mutableResourceRequest().setCachePolicy(ReloadIgnoringCacheData);
+ request.mutableResourceRequest().addHTTPHeaderFieldIfNotPresent(HTTPHeaderName::CacheControl, HTTPHeaderValues::maxAge0());
+ break;
+ case FetchOptions::Cache::NoStore:
+ request.setCachingPolicy(CachingPolicy::DisallowCaching);
+ request.mutableResourceRequest().setCachePolicy(ReloadIgnoringCacheData);
+ request.mutableResourceRequest().addHTTPHeaderFieldIfNotPresent(HTTPHeaderName::Pragma, HTTPHeaderValues::noCache());
+ request.mutableResourceRequest().addHTTPHeaderFieldIfNotPresent(HTTPHeaderName::CacheControl, HTTPHeaderValues::noCache());
+ break;
+ case FetchOptions::Cache::Reload:
+ request.mutableResourceRequest().setCachePolicy(ReloadIgnoringCacheData);
+ request.mutableResourceRequest().addHTTPHeaderFieldIfNotPresent(HTTPHeaderName::Pragma, HTTPHeaderValues::noCache());
+ request.mutableResourceRequest().addHTTPHeaderFieldIfNotPresent(HTTPHeaderName::CacheControl, HTTPHeaderValues::noCache());
+ break;
+ case FetchOptions::Cache::Default:
+ break;
+ case FetchOptions::Cache::ForceCache:
+ request.mutableResourceRequest().setCachePolicy(ReturnCacheDataElseLoad);
+ break;
+ case FetchOptions::Cache::OnlyIfCached:
+ request.mutableResourceRequest().setCachePolicy(ReturnCacheDataDontLoad);
+ break;
+ }
+}
+
+void CachedResourceLoader::updateHTTPRequestHeaders(CachedResourceRequest& resourceRequest)
+{
+ // Implementing steps 10 to 12 of https://fetch.spec.whatwg.org/#http-network-or-cache-fetch
+ updateRequestAccordingCacheMode(resourceRequest);
+}
+
</ins><span class="cx"> CachedResourceHandle<CachedResource> CachedResourceLoader::requestResource(CachedResource::Type type, CachedResourceRequest&& request, ForPreload forPreload, DeferOption defer)
</span><span class="cx"> {
</span><span class="cx"> if (Document* document = this->document())
</span><span class="lines">@@ -720,6 +764,9 @@
</span><span class="cx"> loadTiming.markStartTimeAndFetchStart();
</span><span class="cx"> #endif
</span><span class="cx">
</span><ins>+ if (request.resourceRequest().url().protocolIsInHTTPFamily())
+ updateHTTPRequestHeaders(request);
+
</ins><span class="cx"> auto& memoryCache = MemoryCache::singleton();
</span><span class="cx"> if (request.allowsCaching() && memoryCache.disabled()) {
</span><span class="cx"> DocumentResourceMap::iterator it = m_documentResources.find(url.string());
</span><span class="lines">@@ -844,7 +891,8 @@
</span><span class="cx"> CachedResourceHandle<CachedResource> CachedResourceLoader::loadResource(CachedResource::Type type, CachedResourceRequest&& request)
</span><span class="cx"> {
</span><span class="cx"> auto& memoryCache = MemoryCache::singleton();
</span><del>- ASSERT(!request.allowsCaching() || !memoryCache.resourceForRequest(request.resourceRequest(), sessionID()));
</del><ins>+ ASSERT(!request.allowsCaching() || !memoryCache.resourceForRequest(request.resourceRequest(), sessionID())
+ || request.options().cache == FetchOptions::Cache::NoCache || request.options().cache == FetchOptions::Cache::NoStore || request.options().cache == FetchOptions::Cache::Reload);
</ins><span class="cx">
</span><span class="cx"> LOG(ResourceLoading, "Loading CachedResource for '%s'.", request.resourceRequest().url().stringCenterEllipsizedToLength().latin1().data());
</span><span class="cx">
</span><span class="lines">@@ -897,6 +945,12 @@
</span><span class="cx"> if (!existingResource)
</span><span class="cx"> return Load;
</span><span class="cx">
</span><ins>+ if (cachedResourceRequest.options().cache == FetchOptions::Cache::NoStore)
+ return Load;
+
+ if (cachedResourceRequest.options().cache == FetchOptions::Cache::Reload)
+ return Reload;
+
</ins><span class="cx"> // We already have a preload going for this URL.
</span><span class="cx"> if (forPreload == ForPreload::Yes && existingResource->isPreloaded())
</span><span class="cx"> return Use;
</span><span class="lines">@@ -931,10 +985,12 @@
</span><span class="cx"> if (defer == DeferOption::DeferredByClient)
</span><span class="cx"> return Reload;
</span><span class="cx">
</span><del>- // Don't reload resources while pasting.
- if (m_allowStaleResources)
</del><ins>+ // Don't reload resources while pasting or if cache mode allows stale resources.
+ if (m_allowStaleResources || cachedResourceRequest.options().cache == FetchOptions::Cache::ForceCache || cachedResourceRequest.options().cache == FetchOptions::Cache::OnlyIfCached)
</ins><span class="cx"> return Use;
</span><span class="cx">
</span><ins>+ ASSERT(cachedResourceRequest.options().cache == FetchOptions::Cache::Default || cachedResourceRequest.options().cache == FetchOptions::Cache::NoCache);
+
</ins><span class="cx"> // Always use preloads.
</span><span class="cx"> if (existingResource->isPreloaded())
</span><span class="cx"> return Use;
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCachedResourceLoaderh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CachedResourceLoader.h (207085 => 207086)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/cache/CachedResourceLoader.h        2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/Source/WebCore/loader/cache/CachedResourceLoader.h        2016-10-11 10:53:22 UTC (rev 207086)
</span><span class="lines">@@ -154,6 +154,7 @@
</span><span class="cx"> enum class ForPreload { Yes, No };
</span><span class="cx"> enum class DeferOption { NoDefer, DeferredByClient };
</span><span class="cx">
</span><ins>+ void updateHTTPRequestHeaders(CachedResourceRequest&);
</ins><span class="cx"> CachedResourceHandle<CachedResource> requestResource(CachedResource::Type, CachedResourceRequest&&, ForPreload = ForPreload::No, DeferOption = DeferOption::NoDefer);
</span><span class="cx"> void prepareFetch(CachedResource::Type, CachedResourceRequest&);
</span><span class="cx"> CachedResourceHandle<CachedResource> revalidateResource(CachedResourceRequest&&, CachedResource&);
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCachedResourceRequesth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CachedResourceRequest.h (207085 => 207086)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/cache/CachedResourceRequest.h        2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/Source/WebCore/loader/cache/CachedResourceRequest.h        2016-10-11 10:53:22 UTC (rev 207086)
</span><span class="lines">@@ -60,6 +60,8 @@
</span><span class="cx"> RefPtr<SecurityOrigin> releaseOrigin() { return WTFMove(m_origin); }
</span><span class="cx"> SecurityOrigin* origin() const { return m_origin.get(); }
</span><span class="cx">
</span><ins>+ void setCacheModeToNoStore() { m_options.cache = FetchOptions::Cache::NoStore; }
+
</ins><span class="cx"> private:
</span><span class="cx"> ResourceRequest m_resourceRequest;
</span><span class="cx"> String m_charset;
</span></span></pre></div>
<a id="trunkSourceWebCorepageEventSourcecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/EventSource.cpp (207085 => 207086)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/EventSource.cpp        2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/Source/WebCore/page/EventSource.cpp        2016-10-11 10:53:22 UTC (rev 207086)
</span><span class="lines">@@ -108,6 +108,7 @@
</span><span class="cx"> options.credentials = m_withCredentials ? FetchOptions::Credentials::Include : FetchOptions::Credentials::SameOrigin;
</span><span class="cx"> options.preflightPolicy = PreventPreflight;
</span><span class="cx"> options.mode = FetchOptions::Mode::Cors;
</span><ins>+ options.cache = FetchOptions::Cache::NoStore;
</ins><span class="cx"> options.dataBufferingPolicy = DoNotBufferData;
</span><span class="cx"> options.contentSecurityPolicyEnforcement = scriptExecutionContext()->shouldBypassMainWorldContentSecurityPolicy() ? ContentSecurityPolicyEnforcement::DoNotEnforce : ContentSecurityPolicyEnforcement::EnforceConnectSrcDirective;
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkHTTPHeaderMapcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/HTTPHeaderMap.cpp (207085 => 207086)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/HTTPHeaderMap.cpp        2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/Source/WebCore/platform/network/HTTPHeaderMap.cpp        2016-10-11 10:53:22 UTC (rev 207086)
</span><span class="lines">@@ -103,6 +103,11 @@
</span><span class="cx"> add(headerName, value);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+bool HTTPHeaderMap::addIfNotPresent(HTTPHeaderName headerName, const String& value)
+{
+ return m_commonHeaders.add(headerName, value).isNewEntry;
+}
+
</ins><span class="cx"> bool HTTPHeaderMap::contains(const String& name) const
</span><span class="cx"> {
</span><span class="cx"> HTTPHeaderName headerName;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkHTTPHeaderMaph"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/HTTPHeaderMap.h (207085 => 207086)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/HTTPHeaderMap.h        2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/Source/WebCore/platform/network/HTTPHeaderMap.h        2016-10-11 10:53:22 UTC (rev 207086)
</span><span class="lines">@@ -141,6 +141,7 @@
</span><span class="cx"> WEBCORE_EXPORT String get(HTTPHeaderName) const;
</span><span class="cx"> void set(HTTPHeaderName, const String& value);
</span><span class="cx"> void add(HTTPHeaderName, const String& value);
</span><ins>+ bool addIfNotPresent(HTTPHeaderName, const String&);
</ins><span class="cx"> bool contains(HTTPHeaderName) const;
</span><span class="cx"> WEBCORE_EXPORT bool remove(HTTPHeaderName);
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkHTTPHeaderValuescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/HTTPHeaderValues.cpp (207085 => 207086)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/HTTPHeaderValues.cpp        2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/Source/WebCore/platform/network/HTTPHeaderValues.cpp        2016-10-11 10:53:22 UTC (rev 207086)
</span><span class="lines">@@ -44,6 +44,18 @@
</span><span class="cx"> return contentType;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+const String& noCache()
+{
+ static NeverDestroyed<const String> value(ASCIILiteral("no-cache"));
+ return value;
</ins><span class="cx"> }
</span><span class="cx">
</span><ins>+const String& maxAge0()
+{
+ static NeverDestroyed<const String> value(ASCIILiteral("max-age=0"));
+ return value;
</ins><span class="cx"> }
</span><ins>+
+}
+
+}
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkHTTPHeaderValuesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/HTTPHeaderValues.h (207085 => 207086)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/HTTPHeaderValues.h        2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/Source/WebCore/platform/network/HTTPHeaderValues.h        2016-10-11 10:53:22 UTC (rev 207086)
</span><span class="lines">@@ -32,7 +32,8 @@
</span><span class="cx">
</span><span class="cx"> const String& textPlainContentType();
</span><span class="cx"> const String& formURLEncodedContentType();
</span><del>-
</del><ins>+const String& noCache();
+const String& maxAge0();
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkResourceRequestBasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/ResourceRequestBase.cpp (207085 => 207086)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/ResourceRequestBase.cpp        2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/Source/WebCore/platform/network/ResourceRequestBase.cpp        2016-10-11 10:53:22 UTC (rev 207086)
</span><span class="lines">@@ -464,6 +464,17 @@
</span><span class="cx"> m_platformRequestUpdated = false;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void ResourceRequestBase::addHTTPHeaderFieldIfNotPresent(HTTPHeaderName name, const String& value)
+{
+ updateResourceRequest();
+
+ if (!m_httpHeaderFields.addIfNotPresent(name, value))
+ return;
+
+ if (url().protocolIsInHTTPFamily())
+ m_platformRequestUpdated = false;
+}
+
</ins><span class="cx"> void ResourceRequestBase::addHTTPHeaderField(HTTPHeaderName name, const String& value)
</span><span class="cx"> {
</span><span class="cx"> updateResourceRequest();
</span><span class="lines">@@ -477,13 +488,18 @@
</span><span class="cx"> void ResourceRequestBase::addHTTPHeaderField(const String& name, const String& value)
</span><span class="cx"> {
</span><span class="cx"> updateResourceRequest();
</span><del>-
</del><ins>+
</ins><span class="cx"> m_httpHeaderFields.add(name, value);
</span><del>-
</del><ins>+
</ins><span class="cx"> if (url().protocolIsInHTTPFamily())
</span><span class="cx"> m_platformRequestUpdated = false;
</span><span class="cx"> }
</span><del>-
</del><ins>+
+bool ResourceRequestBase::hasHTTPHeaderField(HTTPHeaderName headerName) const
+{
+ return m_httpHeaderFields.contains(headerName);
+}
+
</ins><span class="cx"> void ResourceRequestBase::setHTTPHeaderFields(HTTPHeaderMap headerFields)
</span><span class="cx"> {
</span><span class="cx"> updateResourceRequest();
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkResourceRequestBaseh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/ResourceRequestBase.h (207085 => 207086)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/ResourceRequestBase.h        2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/Source/WebCore/platform/network/ResourceRequestBase.h        2016-10-11 10:53:22 UTC (rev 207086)
</span><span class="lines">@@ -85,7 +85,10 @@
</span><span class="cx"> WEBCORE_EXPORT void setHTTPHeaderField(HTTPHeaderName, const String& value);
</span><span class="cx"> void addHTTPHeaderField(HTTPHeaderName, const String& value);
</span><span class="cx"> void addHTTPHeaderField(const String& name, const String& value);
</span><ins>+ void addHTTPHeaderFieldIfNotPresent(HTTPHeaderName, const String&);
</ins><span class="cx">
</span><ins>+ bool hasHTTPHeaderField(HTTPHeaderName) const;
+
</ins><span class="cx"> // Instead of passing a string literal to any of these functions, just use a HTTPHeaderName instead.
</span><span class="cx"> template<size_t length> String httpHeaderField(const char (&)[length]) const = delete;
</span><span class="cx"> template<size_t length> void setHTTPHeaderField(const char (&)[length], const String&) = delete;
</span></span></pre>
</div>
</div>
</body>
</html>