<!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 &lt;youenn@apple.com&gt; 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 &quot;default&quot;.
* 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  &lt;youenn@apple.com&gt;
+
+        [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  &lt;cdumez@apple.com&gt;
</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  &lt;youenn@apple.com&gt;
+
+        [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  &lt;cdumez@apple.com&gt;
</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 &quot;default&quot; 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 &quot;no-cache&quot; mode revalidates stale responses found in the cache with Etag and stale response 
</span><span class="cx"> PASS RequestCache &quot;no-cache&quot; mode revalidates stale responses found in the cache with date and stale response 
</span><del>-FAIL RequestCache &quot;no-cache&quot; mode revalidates fresh responses found in the cache with Etag and fresh response assert_equals: expected 2 but got 1
-FAIL RequestCache &quot;no-cache&quot; mode revalidates fresh responses found in the cache with date and fresh response assert_equals: expected 2 but got 1
-FAIL RequestCache &quot;force-cache&quot; 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 &quot;force-cache&quot; 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 &quot;no-cache&quot; mode revalidates fresh responses found in the cache with Etag and fresh response 
+PASS RequestCache &quot;no-cache&quot; mode revalidates fresh responses found in the cache with date and fresh response 
+PASS RequestCache &quot;force-cache&quot; mode checks the cache for previously cached content and avoid revalidation for stale responses with Etag and stale response 
+PASS RequestCache &quot;force-cache&quot; 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 &quot;force-cache&quot; 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 &quot;force-cache&quot; 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 &quot;force-cache&quot; 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 &quot;force-cache&quot; stores the response in the cache if it goes to the network with date and stale response 
</span><span class="cx"> PASS RequestCache &quot;force-cache&quot; stores the response in the cache if it goes to the network with Etag and fresh response 
</span><span class="cx"> PASS RequestCache &quot;force-cache&quot; stores the response in the cache if it goes to the network with date and fresh response 
</span><del>-FAIL RequestCache &quot;only-if-cached&quot; 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 &quot;TypeError: Type error&quot;
-FAIL RequestCache &quot;only-if-cached&quot; 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 &quot;TypeError: Type error&quot;
-FAIL RequestCache &quot;only-if-cached&quot; 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 &quot;TypeError: Type error&quot;
-FAIL RequestCache &quot;only-if-cached&quot; 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 &quot;TypeError: Type error&quot;
</del><ins>+PASS RequestCache &quot;only-if-cached&quot; mode checks the cache for previously cached content and avoids revalidation for stale responses with Etag and stale response 
+PASS RequestCache &quot;only-if-cached&quot; mode checks the cache for previously cached content and avoids revalidation for stale responses with date and stale response 
+PASS RequestCache &quot;only-if-cached&quot; mode checks the cache for previously cached content and avoids revalidation for fresh responses with Etag and fresh response 
+PASS RequestCache &quot;only-if-cached&quot; 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 &quot;only-if-cached&quot; 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 &quot;only-if-cached&quot; 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 &quot;only-if-cached&quot; (with &quot;same-origin&quot;) uses cached same-origin redirects to same-origin content with Etag and fresh response promise_test: Unhandled rejection with value: object &quot;TypeError: Type error&quot;
</span><span class="lines">@@ -37,14 +37,14 @@
</span><span class="cx"> PASS RequestCache &quot;only-if-cached&quot; (with &quot;same-origin&quot;) does not follow redirects across origins and rejects with date and fresh response 
</span><span class="cx"> PASS RequestCache &quot;only-if-cached&quot; (with &quot;same-origin&quot;) does not follow redirects across origins and rejects with Etag and stale response 
</span><span class="cx"> PASS RequestCache &quot;only-if-cached&quot; (with &quot;same-origin&quot;) does not follow redirects across origins and rejects with date and stale response 
</span><del>-FAIL RequestCache &quot;no-store&quot; 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) &quot;\&quot;0.04196530864700354\&quot;&quot;
-FAIL RequestCache &quot;no-store&quot; 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) &quot;Fri, 09 Sep 2016 08:49:10 GMT&quot;
-FAIL RequestCache &quot;no-store&quot; 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 &quot;no-store&quot; 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 &quot;no-store&quot; mode does not store the response in the cache with Etag and stale response assert_equals: expected (undefined) undefined but got (string) &quot;\&quot;0.12846053184726147\&quot;&quot;
-FAIL RequestCache &quot;no-store&quot; mode does not store the response in the cache with date and stale response assert_equals: expected (undefined) undefined but got (string) &quot;Fri, 09 Sep 2016 08:49:10 GMT&quot;
-FAIL RequestCache &quot;no-store&quot; mode does not store the response in the cache with Etag and fresh response assert_equals: expected 2 but got 1
-FAIL RequestCache &quot;no-store&quot; 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 &quot;no-store&quot; mode does not check the cache for previously cached content and goes to the network regardless with Etag and stale response 
+PASS RequestCache &quot;no-store&quot; mode does not check the cache for previously cached content and goes to the network regardless with date and stale response 
+PASS RequestCache &quot;no-store&quot; mode does not check the cache for previously cached content and goes to the network regardless with Etag and fresh response 
+PASS RequestCache &quot;no-store&quot; mode does not check the cache for previously cached content and goes to the network regardless with date and fresh response 
+PASS RequestCache &quot;no-store&quot; mode does not store the response in the cache with Etag and stale response 
+PASS RequestCache &quot;no-store&quot; mode does not store the response in the cache with date and stale response 
+PASS RequestCache &quot;no-store&quot; mode does not store the response in the cache with Etag and fresh response 
+PASS RequestCache &quot;no-store&quot; mode does not store the response in the cache with date and fresh response 
</ins><span class="cx"> PASS RequestCache &quot;default&quot; mode with an If-Modified-Since header is treated similarly to &quot;no-store&quot; with Etag and stale response 
</span><span class="cx"> PASS RequestCache &quot;default&quot; mode with an If-Modified-Since header is treated similarly to &quot;no-store&quot; with date and stale response 
</span><span class="cx"> PASS RequestCache &quot;default&quot; mode with an If-Modified-Since header is treated similarly to &quot;no-store&quot; with Etag and fresh response 
</span><span class="lines">@@ -51,7 +51,7 @@
</span><span class="cx"> PASS RequestCache &quot;default&quot; mode with an If-Modified-Since header is treated similarly to &quot;no-store&quot; with date and fresh response 
</span><span class="cx"> PASS RequestCache &quot;default&quot; mode with an If-Modified-Since header is treated similarly to &quot;no-store&quot; with Etag and stale response 
</span><span class="cx"> PASS RequestCache &quot;default&quot; mode with an If-Modified-Since header is treated similarly to &quot;no-store&quot; with date and stale response 
</span><del>-FAIL RequestCache &quot;default&quot; mode with an If-Modified-Since header is treated similarly to &quot;no-store&quot; with Etag and fresh response assert_equals: expected 2 but got 1
</del><ins>+PASS RequestCache &quot;default&quot; mode with an If-Modified-Since header is treated similarly to &quot;no-store&quot; with Etag and fresh response 
</ins><span class="cx"> PASS RequestCache &quot;default&quot; mode with an If-Modified-Since header is treated similarly to &quot;no-store&quot; with date and fresh response 
</span><span class="cx"> PASS RequestCache &quot;default&quot; mode with an If-None-Match header is treated similarly to &quot;no-store&quot; with Etag and stale response 
</span><span class="cx"> PASS RequestCache &quot;default&quot; mode with an If-None-Match header is treated similarly to &quot;no-store&quot; with date and stale response 
</span><span class="lines">@@ -59,8 +59,8 @@
</span><span class="cx"> PASS RequestCache &quot;default&quot; mode with an If-None-Match header is treated similarly to &quot;no-store&quot; with date and fresh response 
</span><span class="cx"> PASS RequestCache &quot;default&quot; mode with an If-None-Match header is treated similarly to &quot;no-store&quot; with Etag and stale response 
</span><span class="cx"> PASS RequestCache &quot;default&quot; mode with an If-None-Match header is treated similarly to &quot;no-store&quot; with date and stale response 
</span><del>-FAIL RequestCache &quot;default&quot; mode with an If-None-Match header is treated similarly to &quot;no-store&quot; with Etag and fresh response assert_equals: expected 2 but got 1
-FAIL RequestCache &quot;default&quot; mode with an If-None-Match header is treated similarly to &quot;no-store&quot; with date and fresh response assert_equals: expected 2 but got 1
</del><ins>+PASS RequestCache &quot;default&quot; mode with an If-None-Match header is treated similarly to &quot;no-store&quot; with Etag and fresh response 
+PASS RequestCache &quot;default&quot; mode with an If-None-Match header is treated similarly to &quot;no-store&quot; with date and fresh response 
</ins><span class="cx"> PASS RequestCache &quot;default&quot; mode with an If-Unmodified-Since header is treated similarly to &quot;no-store&quot; with Etag and stale response 
</span><span class="cx"> PASS RequestCache &quot;default&quot; mode with an If-Unmodified-Since header is treated similarly to &quot;no-store&quot; with date and stale response 
</span><span class="cx"> PASS RequestCache &quot;default&quot; mode with an If-Unmodified-Since header is treated similarly to &quot;no-store&quot; with Etag and fresh response 
</span><span class="lines">@@ -67,8 +67,8 @@
</span><span class="cx"> PASS RequestCache &quot;default&quot; mode with an If-Unmodified-Since header is treated similarly to &quot;no-store&quot; with date and fresh response 
</span><span class="cx"> PASS RequestCache &quot;default&quot; mode with an If-Unmodified-Since header is treated similarly to &quot;no-store&quot; with Etag and stale response 
</span><span class="cx"> PASS RequestCache &quot;default&quot; mode with an If-Unmodified-Since header is treated similarly to &quot;no-store&quot; with date and stale response 
</span><del>-FAIL RequestCache &quot;default&quot; mode with an If-Unmodified-Since header is treated similarly to &quot;no-store&quot; with Etag and fresh response assert_equals: expected 2 but got 1
-FAIL RequestCache &quot;default&quot; mode with an If-Unmodified-Since header is treated similarly to &quot;no-store&quot; with date and fresh response assert_equals: expected 2 but got 1
</del><ins>+PASS RequestCache &quot;default&quot; mode with an If-Unmodified-Since header is treated similarly to &quot;no-store&quot; with Etag and fresh response 
+PASS RequestCache &quot;default&quot; mode with an If-Unmodified-Since header is treated similarly to &quot;no-store&quot; with date and fresh response 
</ins><span class="cx"> PASS RequestCache &quot;default&quot; mode with an If-Match header is treated similarly to &quot;no-store&quot; with Etag and stale response 
</span><span class="cx"> PASS RequestCache &quot;default&quot; mode with an If-Match header is treated similarly to &quot;no-store&quot; with date and stale response 
</span><span class="cx"> PASS RequestCache &quot;default&quot; mode with an If-Match header is treated similarly to &quot;no-store&quot; with Etag and fresh response 
</span><span class="lines">@@ -75,8 +75,8 @@
</span><span class="cx"> PASS RequestCache &quot;default&quot; mode with an If-Match header is treated similarly to &quot;no-store&quot; with date and fresh response 
</span><span class="cx"> PASS RequestCache &quot;default&quot; mode with an If-Match header is treated similarly to &quot;no-store&quot; with Etag and stale response 
</span><span class="cx"> PASS RequestCache &quot;default&quot; mode with an If-Match header is treated similarly to &quot;no-store&quot; with date and stale response 
</span><del>-FAIL RequestCache &quot;default&quot; mode with an If-Match header is treated similarly to &quot;no-store&quot; with Etag and fresh response assert_equals: expected 2 but got 1
-FAIL RequestCache &quot;default&quot; mode with an If-Match header is treated similarly to &quot;no-store&quot; with date and fresh response assert_equals: expected 2 but got 1
</del><ins>+PASS RequestCache &quot;default&quot; mode with an If-Match header is treated similarly to &quot;no-store&quot; with Etag and fresh response 
+PASS RequestCache &quot;default&quot; mode with an If-Match header is treated similarly to &quot;no-store&quot; with date and fresh response 
</ins><span class="cx"> PASS RequestCache &quot;default&quot; mode with an If-Range header is treated similarly to &quot;no-store&quot; with Etag and stale response 
</span><span class="cx"> PASS RequestCache &quot;default&quot; mode with an If-Range header is treated similarly to &quot;no-store&quot; with date and stale response 
</span><span class="cx"> PASS RequestCache &quot;default&quot; mode with an If-Range header is treated similarly to &quot;no-store&quot; with Etag and fresh response 
</span><span class="lines">@@ -83,22 +83,22 @@
</span><span class="cx"> PASS RequestCache &quot;default&quot; mode with an If-Range header is treated similarly to &quot;no-store&quot; with date and fresh response 
</span><span class="cx"> PASS RequestCache &quot;default&quot; mode with an If-Range header is treated similarly to &quot;no-store&quot; with Etag and stale response 
</span><span class="cx"> PASS RequestCache &quot;default&quot; mode with an If-Range header is treated similarly to &quot;no-store&quot; with date and stale response 
</span><del>-FAIL RequestCache &quot;default&quot; mode with an If-Range header is treated similarly to &quot;no-store&quot; with Etag and fresh response assert_equals: expected 2 but got 1
-FAIL RequestCache &quot;default&quot; mode with an If-Range header is treated similarly to &quot;no-store&quot; with date and fresh response assert_equals: expected 2 but got 1
</del><ins>+PASS RequestCache &quot;default&quot; mode with an If-Range header is treated similarly to &quot;no-store&quot; with Etag and fresh response 
+PASS RequestCache &quot;default&quot; mode with an If-Range header is treated similarly to &quot;no-store&quot; with date and fresh response 
</ins><span class="cx"> PASS Responses with the &quot;Cache-Control: no-store&quot; header are not stored in the cache with Etag and stale response 
</span><span class="cx"> PASS Responses with the &quot;Cache-Control: no-store&quot; header are not stored in the cache with date and stale response 
</span><span class="cx"> PASS Responses with the &quot;Cache-Control: no-store&quot; header are not stored in the cache with Etag and fresh response 
</span><span class="cx"> PASS Responses with the &quot;Cache-Control: no-store&quot; header are not stored in the cache with date and fresh response 
</span><del>-FAIL RequestCache &quot;reload&quot; 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) &quot;\&quot;0.7894894845056666\&quot;&quot;
-FAIL RequestCache &quot;reload&quot; 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) &quot;Fri, 09 Sep 2016 08:49:10 GMT&quot;
-FAIL RequestCache &quot;reload&quot; 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 &quot;reload&quot; 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 &quot;reload&quot; mode does not check the cache for previously cached content and goes to the network regardless with Etag and stale response 
+PASS RequestCache &quot;reload&quot; mode does not check the cache for previously cached content and goes to the network regardless with date and stale response 
+PASS RequestCache &quot;reload&quot; mode does not check the cache for previously cached content and goes to the network regardless with Etag and fresh response 
+PASS RequestCache &quot;reload&quot; 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 &quot;reload&quot; mode does store the response in the cache with Etag and stale response 
</span><span class="cx"> PASS RequestCache &quot;reload&quot; mode does store the response in the cache with date and stale response 
</span><del>-PASS RequestCache &quot;reload&quot; mode does store the response in the cache with Etag and fresh response 
-PASS RequestCache &quot;reload&quot; mode does store the response in the cache with date and fresh response 
-FAIL RequestCache &quot;reload&quot; 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) &quot;\&quot;0.49509960167414313\&quot;&quot;
-FAIL RequestCache &quot;reload&quot; 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) &quot;Fri, 09 Sep 2016 08:49:10 GMT&quot;
-FAIL RequestCache &quot;reload&quot; 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 &quot;reload&quot; 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 &quot;reload&quot; mode does store the response in the cache with Etag and fresh response assert_equals: expected 1 but got 2
+FAIL RequestCache &quot;reload&quot; mode does store the response in the cache with date and fresh response assert_equals: expected 1 but got 2
+PASS RequestCache &quot;reload&quot; mode does store the response in the cache even if a previous response is already stored with Etag and stale response 
+PASS RequestCache &quot;reload&quot; mode does store the response in the cache even if a previous response is already stored with date and stale response 
+PASS RequestCache &quot;reload&quot; mode does store the response in the cache even if a previous response is already stored with Etag and fresh response 
+PASS RequestCache &quot;reload&quot; 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(&quot;&quot;, options); });
</span><span class="cx">         },&quot;Bad &quot; + parameter +&quot; init parameter value&quot;);
</span><span class="cx">       });
</span><ins>+
+      function testOnlyIfCachedMode(fetchMode, ok) {
+        test(function() {
+          var options = {&quot;cache&quot;: &quot;only-if-cached&quot;, &quot;mode&quot;: fetchMode};
+          if (ok)
+            new Request(&quot;test&quot;, options);
+          else
+            assert_throws(new TypeError(), function() { new Request(&quot;test&quot;, options); });
+        }, &quot;Request with cache mode: only-if-cached and fetch mode: &quot; + fetchMode);
+      }
+      testOnlyIfCachedMode(&quot;same-origin&quot;, true);
+      testOnlyIfCachedMode(&quot;cors&quot;, false);
+      testOnlyIfCachedMode(&quot;no-cors&quot;, false);
+
+      test(function() {
+        var initialHeaders = new Headers([[&quot;Content-Type&quot;, &quot;potato&quot;]]);
+        var initialRequest = new Request(&quot;&quot;, {&quot;headers&quot; : initialHeaders});
+        var headers = new Headers([]);
+        var request = new Request(initialRequest, {&quot;headers&quot; : headers});
+        assert_false(request.headers.has(&quot;Content-Type&quot;));
+      }, &quot;Request should not get its content-type from the init request if init headers are provided&quot;);
+
</ins><span class="cx">     &lt;/script&gt;
</span><span class="cx">   &lt;/body&gt;
</span><span class="cx"> &lt;/html&gt;
</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  &lt;youenn@apple.com&gt;
+
+        [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 &quot;default&quot;.
+        * 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  &lt;antti@apple.com&gt;
</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 == &quot;force-cache&quot;)
</span><span class="cx">         options.cache = FetchOptions::Cache::ForceCache;
</span><ins>+    else if (cache == &quot;only-if-cached&quot;)
+        options.cache = FetchOptions::Cache::OnlyIfCached;
</ins><span class="cx">     else
</span><span class="cx">         return Exception { TypeError, ASCIILiteral(&quot;Bad cache mode value.&quot;) };
</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 &amp;&amp; request.options.mode != FetchOptions::Mode::SameOrigin)
+        return Exception { TypeError, ASCIILiteral(&quot;only-if-cached cache option requires fetch mode to be same-origin.&quot;)  };
+
</ins><span class="cx">     if (init.get(&quot;redirect&quot;, 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&amp; request, FrameLoadType loadType, bool mainResource)
</del><ins>+ResourceRequestCachePolicy FrameLoader::defaultRequestCachingPolicy(const ResourceRequest&amp; request, FrameLoadType loadType, bool isMainResource)
</ins><span class="cx"> {
</span><del>-    Page* page = frame().page();
-    bool cachingDisabled = page &amp;&amp; page-&gt;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 (&lt;rdar://problem/6616664&gt;).
-    if (request.firstPartyForCookies().isEmpty()) {
-        if (mainResource &amp;&amp; m_frame.isMainFrame())
-            request.setFirstPartyForCookies(request.url());
-        else if (Document* document = m_frame.document())
-            request.setFirstPartyForCookies(document-&gt;firstPartyForCookies());
-    }
-
-    // The remaining modifications are only necessary for HTTP and HTTPS.
-    if (!request.url().isEmpty() &amp;&amp; !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()-&gt;isLoadingInAPISense()) {
</del><ins>+            return ReloadIgnoringCacheData;
+        if (documentLoader()-&gt;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()-&gt;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&amp; 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 (&lt;rdar://problem/6616664&gt;).
+    if (request.firstPartyForCookies().isEmpty()) {
+        if (isMainResource &amp;&amp; m_frame.isMainFrame())
+            request.setFirstPartyForCookies(request.url());
+        else if (Document* document = m_frame.document())
+            request.setFirstPartyForCookies(document-&gt;firstPartyForCookies());
+    }
+
+    Page* page = frame().page();
+    bool hasSpecificCachePolicy = request.cachePolicy() != UseProtocolCachePolicy;
+
+    if (page &amp;&amp; page-&gt;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() &amp;&amp; !request.url().protocolIsInHTTPFamily())
+        return;
</ins><span class="cx"> 
</span><del>-    if (request.cachePolicy() == ReloadIgnoringCacheData) {
</del><ins>+    if (!hasSpecificCachePolicy &amp;&amp; request.cachePolicy() == ReloadIgnoringCacheData) {
</ins><span class="cx">         if (loadType == FrameLoadType::Reload)
</span><span class="cx">             request.setHTTPHeaderField(HTTPHeaderName::CacheControl, &quot;max-age=0&quot;);
</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&amp;);
</span><span class="cx">     void loadDifferentDocumentItem(HistoryItem&amp;, 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&amp;);
</span><del>-    
</del><ins>+
</ins><span class="cx">     void addExtraFieldsToRequest(ResourceRequest&amp;, FrameLoadType, bool isMainResource);
</span><ins>+    ResourceRequestCachePolicy defaultRequestCachingPolicy(const ResourceRequest&amp;, 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 &quot;FrameLoaderClient.h&quot;
</span><span class="cx"> #include &quot;HTMLElement.h&quot;
</span><span class="cx"> #include &quot;HTMLFrameOwnerElement.h&quot;
</span><ins>+#include &quot;HTTPHeaderValues.h&quot;
</ins><span class="cx"> #include &quot;LoaderStrategy.h&quot;
</span><span class="cx"> #include &quot;LocalizedStrings.h&quot;
</span><span class="cx"> #include &quot;Logging.h&quot;
</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&amp; request)
+{
+    if (request.options().cache == FetchOptions::Cache::Default
+            &amp;&amp; (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&amp; resourceRequest)
+{
+    // Implementing steps 10 to 12 of https://fetch.spec.whatwg.org/#http-network-or-cache-fetch
+    updateRequestAccordingCacheMode(resourceRequest);
+}
+
</ins><span class="cx"> CachedResourceHandle&lt;CachedResource&gt; CachedResourceLoader::requestResource(CachedResource::Type type, CachedResourceRequest&amp;&amp; request, ForPreload forPreload, DeferOption defer)
</span><span class="cx"> {
</span><span class="cx">     if (Document* document = this-&gt;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&amp; memoryCache = MemoryCache::singleton();
</span><span class="cx">     if (request.allowsCaching() &amp;&amp; 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&lt;CachedResource&gt; CachedResourceLoader::loadResource(CachedResource::Type type, CachedResourceRequest&amp;&amp; request)
</span><span class="cx"> {
</span><span class="cx">     auto&amp; 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, &quot;Loading CachedResource for '%s'.&quot;, 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 &amp;&amp; existingResource-&gt;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-&gt;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&amp;);
</ins><span class="cx">     CachedResourceHandle&lt;CachedResource&gt; requestResource(CachedResource::Type, CachedResourceRequest&amp;&amp;, ForPreload = ForPreload::No, DeferOption = DeferOption::NoDefer);
</span><span class="cx">     void prepareFetch(CachedResource::Type, CachedResourceRequest&amp;);
</span><span class="cx">     CachedResourceHandle&lt;CachedResource&gt; revalidateResource(CachedResourceRequest&amp;&amp;, CachedResource&amp;);
</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&lt;SecurityOrigin&gt; 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()-&gt;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&amp; value)
+{
+    return m_commonHeaders.add(headerName, value).isNewEntry;
+}
+
</ins><span class="cx"> bool HTTPHeaderMap::contains(const String&amp; 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&amp; value);
</span><span class="cx">     void add(HTTPHeaderName, const String&amp; value);
</span><ins>+    bool addIfNotPresent(HTTPHeaderName, const String&amp;);
</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&amp; noCache()
+{
+    static NeverDestroyed&lt;const String&gt; value(ASCIILiteral(&quot;no-cache&quot;));
+    return value;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+const String&amp; maxAge0()
+{
+    static NeverDestroyed&lt;const String&gt; value(ASCIILiteral(&quot;max-age=0&quot;));
+    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&amp; textPlainContentType();
</span><span class="cx"> const String&amp; formURLEncodedContentType();
</span><del>-
</del><ins>+const String&amp; noCache();
+const String&amp; 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&amp; 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&amp; 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&amp; name, const String&amp; 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&amp; value);
</span><span class="cx">     void addHTTPHeaderField(HTTPHeaderName, const String&amp; value);
</span><span class="cx">     void addHTTPHeaderField(const String&amp; name, const String&amp; value);
</span><ins>+    void addHTTPHeaderFieldIfNotPresent(HTTPHeaderName, const String&amp;);
</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&lt;size_t length&gt; String httpHeaderField(const char (&amp;)[length]) const = delete;
</span><span class="cx">     template&lt;size_t length&gt; void setHTTPHeaderField(const char (&amp;)[length], const String&amp;) = delete;
</span></span></pre>
</div>
</div>

</body>
</html>