<!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>[203815] 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/203815">203815</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2016-07-28 01:30:14 -0700 (Thu, 28 Jul 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Compute fetch response type in case of cross-origin requests
https://bugs.webkit.org/show_bug.cgi?id=158565

Patch by Youenn Fablet &lt;youenn@apple.com&gt; on 2016-07-28
Reviewed by Alex Christensen.

LayoutTests/imported/w3c:

Rebasing fetch API tests as filtering is now done.
Rebasing XHR tests as console messages are no longer available when trying to access non-exposed headers.

* web-platform-tests/XMLHttpRequest/getresponseheader-cookies-and-more-expected.txt:
* web-platform-tests/fetch/api/basic/mode-no-cors-expected.txt:
* web-platform-tests/fetch/api/basic/mode-no-cors-worker-expected.txt:
* web-platform-tests/fetch/api/cors/cors-basic-expected.txt:
* web-platform-tests/fetch/api/cors/cors-filtering-expected.txt:
* web-platform-tests/fetch/api/request/request-cache-expected.txt:

Source/WebCore:

Covered by rebased tests.

Implementing Response filtering based on Response tainting in ResourceResponse.
Refactoring code in FetchHeaders and CrossOriginAccessControl.cpp accordingly.

Computing response tainting in SubresourceLoader for all resources.
This is used by DocumentThreadableLoader which now filters responses accordingly for all its clients including fetch and XHR.

Response tainting notably allows computing the response type and filtering out headers in case of cross origin responses.

Removing the filtering implemented in XMLHttpRequest as this is done before it gets access to the headers.
This is triggering some rebasing in the XHR tests as error messages triggered by trying to access unsafe headers no longer happen.

This filtering currently requires creating a new ResourceResponse object from the one sent from CachedResource.
This is done so as the same ResourceResponse may be reused accross loads and may be filtered differently by given to two different DocumentThreadableLoader
This can be mitigated in the future by changing ThreadableLoaderClient API to pass a ResourceResponse&amp;&amp;.

* Modules/fetch/FetchHeaders.cpp: Moving header checking in HTTParsers.h/.cpp
(WebCore::isForbiddenHeaderName): Deleted.
(WebCore::isForbiddenResponseHeaderName): Deleted.
(WebCore::isSimpleHeader): Deleted.
* loader/CrossOriginAccessControl.cpp:
(WebCore::parseAccessControlExposeHeadersAllowList): Deleted.
* loader/CrossOriginAccessControl.h: Moving header checking in HTTParsers.h/.cpp
* loader/DocumentThreadableLoader.cpp:
(WebCore::DocumentThreadableLoader::responseReceived):
(WebCore::DocumentThreadableLoader::didReceiveResponse): Doing response filtering. Since underlying loaders are
not yet aware that fetch mode may be cors (it is always no-cors currently), the tainting needs to be updated.
(WebCore::DocumentThreadableLoader::loadRequest): Computing response tainting in case of synchronous calls to ensure headers are filtered for synchronous XHR.
* loader/DocumentThreadableLoader.h:
* loader/SubresourceLoader.cpp:
(WebCore::SubresourceLoader::init): Getting origin from its resource and setting response tainting accordingly
(WebCore::SubresourceLoader::willSendRequestInternal): Always calling checkRedirectionCrossOriginAccessControl
to ensure response tainting is computed, even for no-cors resources.
(WebCore::SubresourceLoader::didReceiveResponse):
(WebCore::SubresourceLoader::checkRedirectionCrossOriginAccessControl): Computing response tainting in case of redirection.
* loader/SubresourceLoader.h:
* loader/cache/CachedResource.cpp:
(WebCore::CachedResource::load): Computing resource origin from the HTTP headers or from the document if none is
set in the HTTP headers.
(WebCore::CachedResource::setCrossOrigin): Helper routine to set response tainting.
(WebCore::CachedResource::isCrossOrigin): Helper routine to know whether resource is cross origin
(WebCore::CachedResource::isClean):
(WebCore::CachedResource::setResponse): Removing m_responseType
* loader/cache/CachedResource.h:
(WebCore::CachedResource::responseTainting):
(WebCore::CachedResource::origin):
(WebCore::CachedResource::setOpaqueRedirect): Deleted.
* platform/network/HTTPParsers.cpp: Implementing safe response header checking
(WebCore::parseAccessControlExposeHeadersAllowList):
(WebCore::isForbiddenHeaderName):
(WebCore::isForbiddenResponseHeaderName):
(WebCore::isSimpleHeader):
(WebCore::isCrossOriginSafeHeader):
* platform/network/HTTPParsers.h:
* platform/network/ResourceRequestBase.cpp:
(WebCore::ResourceRequestBase::hasHTTPOrigin): Added.
(WebCore::ResourceRequestBase::clearHTTPOrigin):
* platform/network/ResourceRequestBase.h:
* platform/network/ResourceResponseBase.cpp: Implementation of response filtering.
(WebCore::ResourceResponseBase::filterResponse):
* platform/network/ResourceResponseBase.h:
* xml/XMLHttpRequest.cpp:
(WebCore::isSetCookieHeader): Deleted.
(WebCore::XMLHttpRequest::getAllResponseHeaders): Removing header filtering since DocumentThreadableLoader does it.
(WebCore::XMLHttpRequest::getResponseHeader): Ditto.

LayoutTests:

Rebasing fetch API tests as filtering is now done.
Rebasing XHR tests as console messages are no longer available when trying to access non-exposed headers.

* http/tests/xmlhttprequest/access-control-basic-whitelist-response-headers-expected.txt:
* http/tests/xmlhttprequest/access-control-response-with-expose-headers-expected.txt:
* http/tests/xmlhttprequest/get-dangerous-headers-expected.txt:
* http/tests/xmlhttprequest/getResponseHeader-expected.txt:
* platform/ios-simulator-wk2/imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors-expected.txt:
* platform/ios-simulator-wk2/imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors-worker-expected.txt:
* platform/ios-simulator-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-basic-expected.txt:
* platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors-expected.txt:
* platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors-worker-expected.txt:
* platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-basic-expected.txt:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestshttptestsxmlhttprequestaccesscontrolbasicwhitelistresponseheadersexpectedtxt">trunk/LayoutTests/http/tests/xmlhttprequest/access-control-basic-whitelist-response-headers-expected.txt</a></li>
<li><a href="#trunkLayoutTestshttptestsxmlhttprequestaccesscontrolresponsewithexposeheadersexpectedtxt">trunk/LayoutTests/http/tests/xmlhttprequest/access-control-response-with-expose-headers-expected.txt</a></li>
<li><a href="#trunkLayoutTestshttptestsxmlhttprequestgetdangerousheadersexpectedtxt">trunk/LayoutTests/http/tests/xmlhttprequest/get-dangerous-headers-expected.txt</a></li>
<li><a href="#trunkLayoutTestshttptestsxmlhttprequestgetResponseHeaderexpectedtxt">trunk/LayoutTests/http/tests/xmlhttprequest/getResponseHeader-expected.txt</a></li>
<li><a href="#trunkLayoutTestsimportedw3cChangeLog">trunk/LayoutTests/imported/w3c/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestsXMLHttpRequestgetresponseheadercookiesandmoreexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/XMLHttpRequest/getresponseheader-cookies-and-more-expected.txt</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestsfetchapibasicmodenocorsexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors-expected.txt</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestsfetchapibasicmodenocorsworkerexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors-worker-expected.txt</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestsfetchapicorscorsbasicexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-basic-expected.txt</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestsfetchapicorscorsfilteringexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-filtering-expected.txt</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="#trunkLayoutTestsplatformiossimulatorwk2importedw3cwebplatformtestsfetchapibasicmodenocorsexpectedtxt">trunk/LayoutTests/platform/ios-simulator-wk2/imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors-expected.txt</a></li>
<li><a href="#trunkLayoutTestsplatformiossimulatorwk2importedw3cwebplatformtestsfetchapibasicmodenocorsworkerexpectedtxt">trunk/LayoutTests/platform/ios-simulator-wk2/imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors-worker-expected.txt</a></li>
<li><a href="#trunkLayoutTestsplatformiossimulatorwk2importedw3cwebplatformtestsfetchapicorscorsbasicexpectedtxt">trunk/LayoutTests/platform/ios-simulator-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-basic-expected.txt</a></li>
<li><a href="#trunkLayoutTestsplatformmacwk2importedw3cwebplatformtestsfetchapibasicmodenocorsexpectedtxt">trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors-expected.txt</a></li>
<li><a href="#trunkLayoutTestsplatformmacwk2importedw3cwebplatformtestsfetchapibasicmodenocorsworkerexpectedtxt">trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors-worker-expected.txt</a></li>
<li><a href="#trunkLayoutTestsplatformmacwk2importedw3cwebplatformtestsfetchapicorscorsbasicexpectedtxt">trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-basic-expected.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreModulesfetchFetchHeaderscpp">trunk/Source/WebCore/Modules/fetch/FetchHeaders.cpp</a></li>
<li><a href="#trunkSourceWebCoreloaderCrossOriginAccessControlcpp">trunk/Source/WebCore/loader/CrossOriginAccessControl.cpp</a></li>
<li><a href="#trunkSourceWebCoreloaderCrossOriginAccessControlh">trunk/Source/WebCore/loader/CrossOriginAccessControl.h</a></li>
<li><a href="#trunkSourceWebCoreloaderDocumentThreadableLoadercpp">trunk/Source/WebCore/loader/DocumentThreadableLoader.cpp</a></li>
<li><a href="#trunkSourceWebCoreloaderDocumentThreadableLoaderh">trunk/Source/WebCore/loader/DocumentThreadableLoader.h</a></li>
<li><a href="#trunkSourceWebCoreloaderSubresourceLoadercpp">trunk/Source/WebCore/loader/SubresourceLoader.cpp</a></li>
<li><a href="#trunkSourceWebCoreloaderSubresourceLoaderh">trunk/Source/WebCore/loader/SubresourceLoader.h</a></li>
<li><a href="#trunkSourceWebCoreloadercacheCachedResourcecpp">trunk/Source/WebCore/loader/cache/CachedResource.cpp</a></li>
<li><a href="#trunkSourceWebCoreloadercacheCachedResourceh">trunk/Source/WebCore/loader/cache/CachedResource.h</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkHTTPParserscpp">trunk/Source/WebCore/platform/network/HTTPParsers.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkHTTPParsersh">trunk/Source/WebCore/platform/network/HTTPParsers.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>
<li><a href="#trunkSourceWebCoreplatformnetworkResourceResponseBasecpp">trunk/Source/WebCore/platform/network/ResourceResponseBase.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkResourceResponseBaseh">trunk/Source/WebCore/platform/network/ResourceResponseBase.h</a></li>
<li><a href="#trunkSourceWebCorexmlXMLHttpRequestcpp">trunk/Source/WebCore/xml/XMLHttpRequest.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (203814 => 203815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-07-28 06:37:45 UTC (rev 203814)
+++ trunk/LayoutTests/ChangeLog        2016-07-28 08:30:14 UTC (rev 203815)
</span><span class="lines">@@ -1,3 +1,24 @@
</span><ins>+2016-07-28  Youenn Fablet  &lt;youenn@apple.com&gt;
+
+        Compute fetch response type in case of cross-origin requests
+        https://bugs.webkit.org/show_bug.cgi?id=158565
+
+        Reviewed by Alex Christensen.
+
+        Rebasing fetch API tests as filtering is now done.
+        Rebasing XHR tests as console messages are no longer available when trying to access non-exposed headers.
+
+        * http/tests/xmlhttprequest/access-control-basic-whitelist-response-headers-expected.txt:
+        * http/tests/xmlhttprequest/access-control-response-with-expose-headers-expected.txt:
+        * http/tests/xmlhttprequest/get-dangerous-headers-expected.txt:
+        * http/tests/xmlhttprequest/getResponseHeader-expected.txt:
+        * platform/ios-simulator-wk2/imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors-expected.txt:
+        * platform/ios-simulator-wk2/imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors-worker-expected.txt:
+        * platform/ios-simulator-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-basic-expected.txt:
+        * platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors-expected.txt:
+        * platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors-worker-expected.txt:
+        * platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-basic-expected.txt:
+
</ins><span class="cx"> 2016-07-27  Ryan Haddad  &lt;ryanhaddad@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Marking http/tests/loading/basic-credentials-sent-automatically.html as flaky on mac and ios-sim wk2
</span></span></pre></div>
<a id="trunkLayoutTestshttptestsxmlhttprequestaccesscontrolbasicwhitelistresponseheadersexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/http/tests/xmlhttprequest/access-control-basic-whitelist-response-headers-expected.txt (203814 => 203815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/xmlhttprequest/access-control-basic-whitelist-response-headers-expected.txt        2016-07-28 06:37:45 UTC (rev 203814)
+++ trunk/LayoutTests/http/tests/xmlhttprequest/access-control-basic-whitelist-response-headers-expected.txt        2016-07-28 08:30:14 UTC (rev 203815)
</span><span class="lines">@@ -1,4 +1,3 @@
</span><del>-CONSOLE MESSAGE: line 25: Refused to get unsafe header &quot;x-webkit&quot;
</del><span class="cx"> PASS: Response header cache-control allowed.
</span><span class="cx"> PASS: Response header content-language allowed.
</span><span class="cx"> PASS: Response header content-type allowed.
</span></span></pre></div>
<a id="trunkLayoutTestshttptestsxmlhttprequestaccesscontrolresponsewithexposeheadersexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/http/tests/xmlhttprequest/access-control-response-with-expose-headers-expected.txt (203814 => 203815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/xmlhttprequest/access-control-response-with-expose-headers-expected.txt        2016-07-28 06:37:45 UTC (rev 203814)
+++ trunk/LayoutTests/http/tests/xmlhttprequest/access-control-response-with-expose-headers-expected.txt        2016-07-28 08:30:14 UTC (rev 203815)
</span><span class="lines">@@ -1,4 +1,3 @@
</span><del>-CONSOLE MESSAGE: line 1: Refused to get unsafe header &quot;X-TEST&quot;
</del><span class="cx"> Test for bug 41210: Cross Origin XMLHttpRequest can not expose headers indicated in Access-Control-Expose-Headers HTTP Response Header.
</span><span class="cx"> 
</span><span class="cx"> On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
</span></span></pre></div>
<a id="trunkLayoutTestshttptestsxmlhttprequestgetdangerousheadersexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/http/tests/xmlhttprequest/get-dangerous-headers-expected.txt (203814 => 203815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/xmlhttprequest/get-dangerous-headers-expected.txt        2016-07-28 06:37:45 UTC (rev 203814)
+++ trunk/LayoutTests/http/tests/xmlhttprequest/get-dangerous-headers-expected.txt        2016-07-28 08:30:14 UTC (rev 203815)
</span><span class="lines">@@ -1,7 +1,3 @@
</span><del>-CONSOLE MESSAGE: line 15: Refused to get unsafe header &quot;Set-Cookie&quot;
-CONSOLE MESSAGE: line 17: Refused to get unsafe header &quot;set-cookie&quot;
-CONSOLE MESSAGE: line 19: Refused to get unsafe header &quot;Set-Cookie2&quot;
-CONSOLE MESSAGE: line 21: Refused to get unsafe header &quot;set-cookie2&quot;
</del><span class="cx"> Test that getResponseHeader and getAllResponseHeaders cannot be used to get the cookie header fields.
</span><span class="cx"> 
</span><span class="cx"> PASS
</span></span></pre></div>
<a id="trunkLayoutTestshttptestsxmlhttprequestgetResponseHeaderexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/http/tests/xmlhttprequest/getResponseHeader-expected.txt (203814 => 203815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/xmlhttprequest/getResponseHeader-expected.txt        2016-07-28 06:37:45 UTC (rev 203814)
+++ trunk/LayoutTests/http/tests/xmlhttprequest/getResponseHeader-expected.txt        2016-07-28 08:30:14 UTC (rev 203815)
</span><span class="lines">@@ -1,9 +1,3 @@
</span><del>-CONSOLE MESSAGE: line 1: Refused to get unsafe header &quot;SeT-COoKie&quot;
-CONSOLE MESSAGE: line 1: Refused to get unsafe header &quot;sEt-coOkIE2&quot;
-CONSOLE MESSAGE: line 1: Refused to get unsafe header &quot;SeT-COoKie&quot;
-CONSOLE MESSAGE: line 1: Refused to get unsafe header &quot;sEt-coOkIE2&quot;
-CONSOLE MESSAGE: line 1: Refused to get unsafe header &quot;SeT-COoKie&quot;
-CONSOLE MESSAGE: line 1: Refused to get unsafe header &quot;sEt-coOkIE2&quot;
</del><span class="cx"> Test the required behavior of XMLHttpRequest.getResponseHeader()
</span><span class="cx"> 
</span><span class="cx"> On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/ChangeLog (203814 => 203815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/ChangeLog        2016-07-28 06:37:45 UTC (rev 203814)
+++ trunk/LayoutTests/imported/w3c/ChangeLog        2016-07-28 08:30:14 UTC (rev 203815)
</span><span class="lines">@@ -1,3 +1,20 @@
</span><ins>+2016-07-28  Youenn Fablet  &lt;youenn@apple.com&gt;
+
+        Compute fetch response type in case of cross-origin requests
+        https://bugs.webkit.org/show_bug.cgi?id=158565
+
+        Reviewed by Alex Christensen.
+
+        Rebasing fetch API tests as filtering is now done.
+        Rebasing XHR tests as console messages are no longer available when trying to access non-exposed headers.
+
+        * web-platform-tests/XMLHttpRequest/getresponseheader-cookies-and-more-expected.txt:
+        * web-platform-tests/fetch/api/basic/mode-no-cors-expected.txt:
+        * web-platform-tests/fetch/api/basic/mode-no-cors-worker-expected.txt:
+        * web-platform-tests/fetch/api/cors/cors-basic-expected.txt:
+        * web-platform-tests/fetch/api/cors/cors-filtering-expected.txt:
+        * web-platform-tests/fetch/api/request/request-cache-expected.txt:
+
</ins><span class="cx"> 2016-07-27  Chris Dumez  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         First parameter to HTMLMediaElement.canPlayType() should be mandatory
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestsXMLHttpRequestgetresponseheadercookiesandmoreexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/XMLHttpRequest/getresponseheader-cookies-and-more-expected.txt (203814 => 203815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/XMLHttpRequest/getresponseheader-cookies-and-more-expected.txt        2016-07-28 06:37:45 UTC (rev 203814)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/XMLHttpRequest/getresponseheader-cookies-and-more-expected.txt        2016-07-28 08:30:14 UTC (rev 203815)
</span><span class="lines">@@ -1,9 +1,3 @@
</span><del>-CONSOLE MESSAGE: line 23: Refused to get unsafe header &quot;set-cookie&quot;
-CONSOLE MESSAGE: line 24: Refused to get unsafe header &quot;set-cookie2&quot;
-CONSOLE MESSAGE: line 23: Refused to get unsafe header &quot;set-cookie&quot;
-CONSOLE MESSAGE: line 24: Refused to get unsafe header &quot;set-cookie2&quot;
-CONSOLE MESSAGE: line 23: Refused to get unsafe header &quot;set-cookie&quot;
-CONSOLE MESSAGE: line 24: Refused to get unsafe header &quot;set-cookie2&quot;
</del><span class="cx"> 
</span><span class="cx"> PASS XMLHttpRequest: getResponseHeader() custom/non-existent headers and cookies 
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestsfetchapibasicmodenocorsexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors-expected.txt (203814 => 203815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors-expected.txt        2016-07-28 06:37:45 UTC (rev 203814)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors-expected.txt        2016-07-28 08:30:14 UTC (rev 203815)
</span><span class="lines">@@ -1,6 +1,6 @@
</span><span class="cx"> 
</span><span class="cx"> PASS Fetch ../resources/top.txt with no-cors mode 
</span><span class="cx"> PASS Fetch http://localhost:8800/fetch/api/resources/top.txt with no-cors mode 
</span><del>-FAIL Fetch https://localhost:9443/fetch/api/resources/top.txt with no-cors mode assert_equals: Opaque filter: status is 0 expected 0 but got 200
-FAIL Fetch http://localhost:8801/fetch/api/resources/top.txt with no-cors mode assert_equals: Opaque filter: status is 0 expected 0 but got 200
</del><ins>+PASS Fetch https://localhost:9443/fetch/api/resources/top.txt with no-cors mode 
+PASS Fetch http://localhost:8801/fetch/api/resources/top.txt with no-cors mode 
</ins><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestsfetchapibasicmodenocorsworkerexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors-worker-expected.txt (203814 => 203815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors-worker-expected.txt        2016-07-28 06:37:45 UTC (rev 203814)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors-worker-expected.txt        2016-07-28 08:30:14 UTC (rev 203815)
</span><span class="lines">@@ -1,6 +1,6 @@
</span><span class="cx"> 
</span><span class="cx"> PASS Fetch ../resources/top.txt with no-cors mode 
</span><span class="cx"> PASS Fetch http://localhost:8800/fetch/api/resources/top.txt with no-cors mode 
</span><del>-FAIL Fetch https://localhost:9443/fetch/api/resources/top.txt with no-cors mode assert_equals: Opaque filter: status is 0 expected 0 but got 200
-FAIL Fetch http://localhost:8801/fetch/api/resources/top.txt with no-cors mode assert_equals: Opaque filter: status is 0 expected 0 but got 200
</del><ins>+PASS Fetch https://localhost:9443/fetch/api/resources/top.txt with no-cors mode 
+PASS Fetch http://localhost:8801/fetch/api/resources/top.txt with no-cors mode 
</ins><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestsfetchapicorscorsbasicexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-basic-expected.txt (203814 => 203815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-basic-expected.txt        2016-07-28 06:37:45 UTC (rev 203814)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-basic-expected.txt        2016-07-28 08:30:14 UTC (rev 203815)
</span><span class="lines">@@ -1,17 +1,17 @@
</span><span class="cx"> 
</span><del>-FAIL Same domain different port [no-cors mode] assert_equals: Opaque filter: status is 0 expected 0 but got 200
</del><ins>+PASS Same domain different port [no-cors mode] 
</ins><span class="cx"> PASS Same domain different port [server forbid CORS] 
</span><del>-FAIL Same domain different port [cors mode] assert_equals: CORS response's type is cors expected &quot;cors&quot; but got &quot;basic&quot;
-FAIL Same domain different protocol different port [no-cors mode] assert_equals: Opaque filter: status is 0 expected 0 but got 200
</del><ins>+PASS Same domain different port [cors mode] 
+PASS Same domain different protocol different port [no-cors mode] 
</ins><span class="cx"> PASS Same domain different protocol different port [server forbid CORS] 
</span><del>-FAIL Same domain different protocol different port [cors mode] assert_equals: CORS response's type is cors expected &quot;cors&quot; but got &quot;basic&quot;
-FAIL Cross domain basic usage [no-cors mode] assert_equals: Opaque filter: status is 0 expected 0 but got 200
</del><ins>+PASS Same domain different protocol different port [cors mode] 
+PASS Cross domain basic usage [no-cors mode] 
</ins><span class="cx"> PASS Cross domain basic usage [server forbid CORS] 
</span><del>-FAIL Cross domain basic usage [cors mode] assert_equals: CORS response's type is cors expected &quot;cors&quot; but got &quot;basic&quot;
-FAIL Cross domain different port [no-cors mode] assert_equals: Opaque filter: status is 0 expected 0 but got 200
</del><ins>+PASS Cross domain basic usage [cors mode] 
+PASS Cross domain different port [no-cors mode] 
</ins><span class="cx"> PASS Cross domain different port [server forbid CORS] 
</span><del>-FAIL Cross domain different port [cors mode] assert_equals: CORS response's type is cors expected &quot;cors&quot; but got &quot;basic&quot;
-FAIL Cross domain different protocol [no-cors mode] assert_equals: Opaque filter: status is 0 expected 0 but got 200
</del><ins>+PASS Cross domain different port [cors mode] 
+PASS Cross domain different protocol [no-cors mode] 
</ins><span class="cx"> PASS Cross domain different protocol [server forbid CORS] 
</span><del>-FAIL Cross domain different protocol [cors mode] assert_equals: CORS response's type is cors expected &quot;cors&quot; but got &quot;basic&quot;
</del><ins>+PASS Cross domain different protocol [cors mode] 
</ins><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestsfetchapicorscorsfilteringexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-filtering-expected.txt (203814 => 203815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-filtering-expected.txt        2016-07-28 06:37:45 UTC (rev 203814)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-filtering-expected.txt        2016-07-28 08:30:14 UTC (rev 203815)
</span><span class="lines">@@ -1,20 +1,20 @@
</span><span class="cx"> 
</span><del>-FAIL CORS filter on Cache-Control header assert_equals: CORS fetch's response has cors type expected &quot;cors&quot; but got &quot;basic&quot;
-FAIL CORS filter on Content-Language header assert_equals: CORS fetch's response has cors type expected &quot;cors&quot; but got &quot;basic&quot;
-FAIL CORS filter on Content-Type header assert_equals: CORS fetch's response has cors type expected &quot;cors&quot; but got &quot;basic&quot;
-FAIL CORS filter on Expires header assert_equals: CORS fetch's response has cors type expected &quot;cors&quot; but got &quot;basic&quot;
-FAIL CORS filter on Last-Modified header assert_equals: CORS fetch's response has cors type expected &quot;cors&quot; but got &quot;basic&quot;
-FAIL CORS filter on Pragma header assert_equals: CORS fetch's response has cors type expected &quot;cors&quot; but got &quot;basic&quot;
-FAIL CORS filter on Age header assert_equals: CORS fetch's response has cors type expected &quot;cors&quot; but got &quot;basic&quot;
-FAIL CORS filter on Server header assert_equals: CORS fetch's response has cors type expected &quot;cors&quot; but got &quot;basic&quot;
-FAIL CORS filter on Warning header assert_equals: CORS fetch's response has cors type expected &quot;cors&quot; but got &quot;basic&quot;
-FAIL CORS filter on Content-Length header assert_equals: CORS fetch's response has cors type expected &quot;cors&quot; but got &quot;basic&quot;
-FAIL CORS filter on Set-Cookie header assert_equals: CORS fetch's response has cors type expected &quot;cors&quot; but got &quot;basic&quot;
-FAIL CORS filter on Set-Cookie2 header assert_equals: CORS fetch's response has cors type expected &quot;cors&quot; but got &quot;basic&quot;
-FAIL CORS filter on Age header, header is exposed assert_equals: CORS fetch's response has cors type expected &quot;cors&quot; but got &quot;basic&quot;
-FAIL CORS filter on Server header, header is exposed assert_equals: CORS fetch's response has cors type expected &quot;cors&quot; but got &quot;basic&quot;
-FAIL CORS filter on Warning header, header is exposed assert_equals: CORS fetch's response has cors type expected &quot;cors&quot; but got &quot;basic&quot;
-FAIL CORS filter on Content-Length header, header is exposed assert_equals: CORS fetch's response has cors type expected &quot;cors&quot; but got &quot;basic&quot;
-FAIL CORS filter on Set-Cookie header, header is exposed assert_equals: CORS fetch's response has cors type expected &quot;cors&quot; but got &quot;basic&quot;
-FAIL CORS filter on Set-Cookie2 header, header is exposed assert_equals: CORS fetch's response has cors type expected &quot;cors&quot; but got &quot;basic&quot;
</del><ins>+PASS CORS filter on Cache-Control header 
+PASS CORS filter on Content-Language header 
+PASS CORS filter on Content-Type header 
+PASS CORS filter on Expires header 
+PASS CORS filter on Last-Modified header 
+PASS CORS filter on Pragma header 
+PASS CORS filter on Age header 
+PASS CORS filter on Server header 
+PASS CORS filter on Warning header 
+PASS CORS filter on Content-Length header 
+PASS CORS filter on Set-Cookie header 
+PASS CORS filter on Set-Cookie2 header 
+PASS CORS filter on Age header, header is exposed 
+PASS CORS filter on Server header, header is exposed 
+PASS CORS filter on Warning header, header is exposed 
+PASS CORS filter on Content-Length header, header is exposed 
+PASS CORS filter on Set-Cookie header, header is exposed 
+PASS CORS filter on Set-Cookie2 header, header is exposed 
</ins><span class="cx"> 
</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 (203814 => 203815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-cache-expected.txt        2016-07-28 06:37:45 UTC (rev 203814)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-cache-expected.txt        2016-07-28 08:30:14 UTC (rev 203815)
</span><span class="lines">@@ -37,12 +37,12 @@
</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.5708867760543104\&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;Tue, 26 Jul 2016 18:03:51 GMT&quot;
</del><ins>+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.5142751701087829\&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;Wed, 27 Jul 2016 15:14:16 GMT&quot;
</ins><span class="cx"> 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
</span><span class="cx"> 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
</span><del>-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.03236160265570209\&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;Tue, 26 Jul 2016 18:03:51 GMT&quot;
</del><ins>+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.8439838765231941\&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;Wed, 27 Jul 2016 15:14:16 GMT&quot;
</ins><span class="cx"> 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
</span><span class="cx"> 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
</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="lines">@@ -89,8 +89,8 @@
</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.32037580965802115\&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;Tue, 26 Jul 2016 18:03:51 GMT&quot;
</del><ins>+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.7100561973865757\&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;Wed, 27 Jul 2016 15:14:16 GMT&quot;
</ins><span class="cx"> 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
</span><span class="cx"> 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
</span><span class="cx"> PASS RequestCache &quot;reload&quot; mode does store the response in the cache with Etag and stale response 
</span><span class="lines">@@ -97,8 +97,8 @@
</span><span class="cx"> PASS RequestCache &quot;reload&quot; mode does store the response in the cache with date and stale response 
</span><span class="cx"> PASS RequestCache &quot;reload&quot; mode does store the response in the cache with Etag and fresh response 
</span><span class="cx"> PASS RequestCache &quot;reload&quot; mode does store the response in the cache with date and fresh response 
</span><del>-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.702774010433134\&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;Tue, 26 Jul 2016 18:03:51 GMT&quot;
</del><ins>+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.45824924441966697\&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;Wed, 27 Jul 2016 15:14:16 GMT&quot;
</ins><span class="cx"> 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
</span><span class="cx"> 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
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsplatformiossimulatorwk2importedw3cwebplatformtestsfetchapibasicmodenocorsexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/ios-simulator-wk2/imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors-expected.txt (203814 => 203815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/ios-simulator-wk2/imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors-expected.txt        2016-07-28 06:37:45 UTC (rev 203814)
+++ trunk/LayoutTests/platform/ios-simulator-wk2/imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors-expected.txt        2016-07-28 08:30:14 UTC (rev 203815)
</span><span class="lines">@@ -2,5 +2,5 @@
</span><span class="cx"> PASS Fetch ../resources/top.txt with no-cors mode 
</span><span class="cx"> PASS Fetch http://localhost:8800/fetch/api/resources/top.txt with no-cors mode 
</span><span class="cx"> FAIL Fetch https://localhost:9443/fetch/api/resources/top.txt with no-cors mode promise_test: Unhandled rejection with value: object &quot;TypeError: Type error&quot;
</span><del>-FAIL Fetch http://localhost:8801/fetch/api/resources/top.txt with no-cors mode assert_equals: Opaque filter: status is 0 expected 0 but got 200
</del><ins>+PASS Fetch http://localhost:8801/fetch/api/resources/top.txt with no-cors mode 
</ins><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsplatformiossimulatorwk2importedw3cwebplatformtestsfetchapibasicmodenocorsworkerexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/ios-simulator-wk2/imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors-worker-expected.txt (203814 => 203815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/ios-simulator-wk2/imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors-worker-expected.txt        2016-07-28 06:37:45 UTC (rev 203814)
+++ trunk/LayoutTests/platform/ios-simulator-wk2/imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors-worker-expected.txt        2016-07-28 08:30:14 UTC (rev 203815)
</span><span class="lines">@@ -2,5 +2,5 @@
</span><span class="cx"> PASS Fetch ../resources/top.txt with no-cors mode 
</span><span class="cx"> PASS Fetch http://localhost:8800/fetch/api/resources/top.txt with no-cors mode 
</span><span class="cx"> FAIL Fetch https://localhost:9443/fetch/api/resources/top.txt with no-cors mode promise_test: Unhandled rejection with value: object &quot;TypeError: Type error&quot;
</span><del>-FAIL Fetch http://localhost:8801/fetch/api/resources/top.txt with no-cors mode assert_equals: Opaque filter: status is 0 expected 0 but got 200
</del><ins>+PASS Fetch http://localhost:8801/fetch/api/resources/top.txt with no-cors mode 
</ins><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsplatformiossimulatorwk2importedw3cwebplatformtestsfetchapicorscorsbasicexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/ios-simulator-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-basic-expected.txt (203814 => 203815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/ios-simulator-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-basic-expected.txt        2016-07-28 06:37:45 UTC (rev 203814)
+++ trunk/LayoutTests/platform/ios-simulator-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-basic-expected.txt        2016-07-28 08:30:14 UTC (rev 203815)
</span><span class="lines">@@ -1,16 +1,16 @@
</span><span class="cx"> 
</span><del>-FAIL Same domain different port [no-cors mode] assert_equals: Opaque filter: status is 0 expected 0 but got 200
</del><ins>+PASS Same domain different port [no-cors mode] 
</ins><span class="cx"> PASS Same domain different port [server forbid CORS] 
</span><del>-FAIL Same domain different port [cors mode] assert_equals: CORS response's type is cors expected &quot;cors&quot; but got &quot;basic&quot;
</del><ins>+PASS Same domain different port [cors mode] 
</ins><span class="cx"> FAIL Same domain different protocol different port [no-cors mode] promise_test: Unhandled rejection with value: object &quot;TypeError: Type error&quot;
</span><span class="cx"> PASS Same domain different protocol different port [server forbid CORS] 
</span><span class="cx"> FAIL Same domain different protocol different port [cors mode] promise_test: Unhandled rejection with value: object &quot;TypeError: Type error&quot;
</span><del>-FAIL Cross domain basic usage [no-cors mode] assert_equals: Opaque filter: status is 0 expected 0 but got 200
</del><ins>+PASS Cross domain basic usage [no-cors mode] 
</ins><span class="cx"> PASS Cross domain basic usage [server forbid CORS] 
</span><del>-FAIL Cross domain basic usage [cors mode] assert_equals: CORS response's type is cors expected &quot;cors&quot; but got &quot;basic&quot;
-FAIL Cross domain different port [no-cors mode] assert_equals: Opaque filter: status is 0 expected 0 but got 200
</del><ins>+PASS Cross domain basic usage [cors mode] 
+PASS Cross domain different port [no-cors mode] 
</ins><span class="cx"> PASS Cross domain different port [server forbid CORS] 
</span><del>-FAIL Cross domain different port [cors mode] assert_equals: CORS response's type is cors expected &quot;cors&quot; but got &quot;basic&quot;
</del><ins>+PASS Cross domain different port [cors mode] 
</ins><span class="cx"> FAIL Cross domain different protocol [no-cors mode] promise_test: Unhandled rejection with value: object &quot;TypeError: Type error&quot;
</span><span class="cx"> PASS Cross domain different protocol [server forbid CORS] 
</span><span class="cx"> FAIL Cross domain different protocol [cors mode] promise_test: Unhandled rejection with value: object &quot;TypeError: Type error&quot;
</span></span></pre></div>
<a id="trunkLayoutTestsplatformmacwk2importedw3cwebplatformtestsfetchapibasicmodenocorsexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors-expected.txt (203814 => 203815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors-expected.txt        2016-07-28 06:37:45 UTC (rev 203814)
+++ trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors-expected.txt        2016-07-28 08:30:14 UTC (rev 203815)
</span><span class="lines">@@ -2,5 +2,5 @@
</span><span class="cx"> PASS Fetch ../resources/top.txt with no-cors mode 
</span><span class="cx"> PASS Fetch http://localhost:8800/fetch/api/resources/top.txt with no-cors mode 
</span><span class="cx"> FAIL Fetch https://localhost:9443/fetch/api/resources/top.txt with no-cors mode promise_test: Unhandled rejection with value: object &quot;TypeError: Type error&quot;
</span><del>-FAIL Fetch http://localhost:8801/fetch/api/resources/top.txt with no-cors mode assert_equals: Opaque filter: status is 0 expected 0 but got 200
</del><ins>+PASS Fetch http://localhost:8801/fetch/api/resources/top.txt with no-cors mode 
</ins><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsplatformmacwk2importedw3cwebplatformtestsfetchapibasicmodenocorsworkerexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors-worker-expected.txt (203814 => 203815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors-worker-expected.txt        2016-07-28 06:37:45 UTC (rev 203814)
+++ trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors-worker-expected.txt        2016-07-28 08:30:14 UTC (rev 203815)
</span><span class="lines">@@ -2,5 +2,5 @@
</span><span class="cx"> PASS Fetch ../resources/top.txt with no-cors mode 
</span><span class="cx"> PASS Fetch http://localhost:8800/fetch/api/resources/top.txt with no-cors mode 
</span><span class="cx"> FAIL Fetch https://localhost:9443/fetch/api/resources/top.txt with no-cors mode promise_test: Unhandled rejection with value: object &quot;TypeError: Type error&quot;
</span><del>-FAIL Fetch http://localhost:8801/fetch/api/resources/top.txt with no-cors mode assert_equals: Opaque filter: status is 0 expected 0 but got 200
</del><ins>+PASS Fetch http://localhost:8801/fetch/api/resources/top.txt with no-cors mode 
</ins><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsplatformmacwk2importedw3cwebplatformtestsfetchapicorscorsbasicexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-basic-expected.txt (203814 => 203815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-basic-expected.txt        2016-07-28 06:37:45 UTC (rev 203814)
+++ trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-basic-expected.txt        2016-07-28 08:30:14 UTC (rev 203815)
</span><span class="lines">@@ -1,16 +1,16 @@
</span><span class="cx"> 
</span><del>-FAIL Same domain different port [no-cors mode] assert_equals: Opaque filter: status is 0 expected 0 but got 200
</del><ins>+PASS Same domain different port [no-cors mode] 
</ins><span class="cx"> PASS Same domain different port [server forbid CORS] 
</span><del>-FAIL Same domain different port [cors mode] assert_equals: CORS response's type is cors expected &quot;cors&quot; but got &quot;basic&quot;
</del><ins>+PASS Same domain different port [cors mode] 
</ins><span class="cx"> FAIL Same domain different protocol different port [no-cors mode] promise_test: Unhandled rejection with value: object &quot;TypeError: Type error&quot;
</span><span class="cx"> PASS Same domain different protocol different port [server forbid CORS] 
</span><span class="cx"> FAIL Same domain different protocol different port [cors mode] promise_test: Unhandled rejection with value: object &quot;TypeError: Type error&quot;
</span><del>-FAIL Cross domain basic usage [no-cors mode] assert_equals: Opaque filter: status is 0 expected 0 but got 200
</del><ins>+PASS Cross domain basic usage [no-cors mode] 
</ins><span class="cx"> PASS Cross domain basic usage [server forbid CORS] 
</span><del>-FAIL Cross domain basic usage [cors mode] assert_equals: CORS response's type is cors expected &quot;cors&quot; but got &quot;basic&quot;
-FAIL Cross domain different port [no-cors mode] assert_equals: Opaque filter: status is 0 expected 0 but got 200
</del><ins>+PASS Cross domain basic usage [cors mode] 
+PASS Cross domain different port [no-cors mode] 
</ins><span class="cx"> PASS Cross domain different port [server forbid CORS] 
</span><del>-FAIL Cross domain different port [cors mode] assert_equals: CORS response's type is cors expected &quot;cors&quot; but got &quot;basic&quot;
</del><ins>+PASS Cross domain different port [cors mode] 
</ins><span class="cx"> FAIL Cross domain different protocol [no-cors mode] promise_test: Unhandled rejection with value: object &quot;TypeError: Type error&quot;
</span><span class="cx"> PASS Cross domain different protocol [server forbid CORS] 
</span><span class="cx"> FAIL Cross domain different protocol [cors mode] promise_test: Unhandled rejection with value: object &quot;TypeError: Type error&quot;
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (203814 => 203815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-07-28 06:37:45 UTC (rev 203814)
+++ trunk/Source/WebCore/ChangeLog        2016-07-28 08:30:14 UTC (rev 203815)
</span><span class="lines">@@ -1,3 +1,77 @@
</span><ins>+2016-07-28  Youenn Fablet  &lt;youenn@apple.com&gt;
+
+        Compute fetch response type in case of cross-origin requests
+        https://bugs.webkit.org/show_bug.cgi?id=158565
+
+        Reviewed by Alex Christensen.
+
+        Covered by rebased tests.
+
+        Implementing Response filtering based on Response tainting in ResourceResponse.
+        Refactoring code in FetchHeaders and CrossOriginAccessControl.cpp accordingly.
+
+        Computing response tainting in SubresourceLoader for all resources.
+        This is used by DocumentThreadableLoader which now filters responses accordingly for all its clients including fetch and XHR.
+
+        Response tainting notably allows computing the response type and filtering out headers in case of cross origin responses.
+
+        Removing the filtering implemented in XMLHttpRequest as this is done before it gets access to the headers.
+        This is triggering some rebasing in the XHR tests as error messages triggered by trying to access unsafe headers no longer happen.
+
+        This filtering currently requires creating a new ResourceResponse object from the one sent from CachedResource.
+        This is done so as the same ResourceResponse may be reused accross loads and may be filtered differently by given to two different DocumentThreadableLoader
+        This can be mitigated in the future by changing ThreadableLoaderClient API to pass a ResourceResponse&amp;&amp;.
+
+        * Modules/fetch/FetchHeaders.cpp: Moving header checking in HTTParsers.h/.cpp
+        (WebCore::isForbiddenHeaderName): Deleted.
+        (WebCore::isForbiddenResponseHeaderName): Deleted.
+        (WebCore::isSimpleHeader): Deleted.
+        * loader/CrossOriginAccessControl.cpp:
+        (WebCore::parseAccessControlExposeHeadersAllowList): Deleted.
+        * loader/CrossOriginAccessControl.h: Moving header checking in HTTParsers.h/.cpp
+        * loader/DocumentThreadableLoader.cpp:
+        (WebCore::DocumentThreadableLoader::responseReceived):
+        (WebCore::DocumentThreadableLoader::didReceiveResponse): Doing response filtering. Since underlying loaders are
+        not yet aware that fetch mode may be cors (it is always no-cors currently), the tainting needs to be updated.
+        (WebCore::DocumentThreadableLoader::loadRequest): Computing response tainting in case of synchronous calls to ensure headers are filtered for synchronous XHR.
+        * loader/DocumentThreadableLoader.h:
+        * loader/SubresourceLoader.cpp:
+        (WebCore::SubresourceLoader::init): Getting origin from its resource and setting response tainting accordingly
+        (WebCore::SubresourceLoader::willSendRequestInternal): Always calling checkRedirectionCrossOriginAccessControl
+        to ensure response tainting is computed, even for no-cors resources.
+        (WebCore::SubresourceLoader::didReceiveResponse):
+        (WebCore::SubresourceLoader::checkRedirectionCrossOriginAccessControl): Computing response tainting in case of redirection.
+        * loader/SubresourceLoader.h:
+        * loader/cache/CachedResource.cpp:
+        (WebCore::CachedResource::load): Computing resource origin from the HTTP headers or from the document if none is
+        set in the HTTP headers.
+        (WebCore::CachedResource::setCrossOrigin): Helper routine to set response tainting.
+        (WebCore::CachedResource::isCrossOrigin): Helper routine to know whether resource is cross origin
+        (WebCore::CachedResource::isClean):
+        (WebCore::CachedResource::setResponse): Removing m_responseType
+        * loader/cache/CachedResource.h:
+        (WebCore::CachedResource::responseTainting):
+        (WebCore::CachedResource::origin):
+        (WebCore::CachedResource::setOpaqueRedirect): Deleted.
+        * platform/network/HTTPParsers.cpp: Implementing safe response header checking
+        (WebCore::parseAccessControlExposeHeadersAllowList):
+        (WebCore::isForbiddenHeaderName):
+        (WebCore::isForbiddenResponseHeaderName):
+        (WebCore::isSimpleHeader):
+        (WebCore::isCrossOriginSafeHeader):
+        * platform/network/HTTPParsers.h:
+        * platform/network/ResourceRequestBase.cpp:
+        (WebCore::ResourceRequestBase::hasHTTPOrigin): Added.
+        (WebCore::ResourceRequestBase::clearHTTPOrigin):
+        * platform/network/ResourceRequestBase.h:
+        * platform/network/ResourceResponseBase.cpp: Implementation of response filtering.
+        (WebCore::ResourceResponseBase::filterResponse):
+        * platform/network/ResourceResponseBase.h:
+        * xml/XMLHttpRequest.cpp:
+        (WebCore::isSetCookieHeader): Deleted.
+        (WebCore::XMLHttpRequest::getAllResponseHeaders): Removing header filtering since DocumentThreadableLoader does it.
+        (WebCore::XMLHttpRequest::getResponseHeader): Ditto.
+
</ins><span class="cx"> 2016-07-27  Romain Bellessort  &lt;romain.bellessort@crf.canon.fr&gt;
</span><span class="cx"> 
</span><span class="cx">         [Streams API] Use makeThisTypeError in ReadableStreamDefaultReader.js
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesfetchFetchHeaderscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/fetch/FetchHeaders.cpp (203814 => 203815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/fetch/FetchHeaders.cpp        2016-07-28 06:37:45 UTC (rev 203814)
+++ trunk/Source/WebCore/Modules/fetch/FetchHeaders.cpp        2016-07-28 08:30:14 UTC (rev 203815)
</span><span class="lines">@@ -36,64 +36,6 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-// FIXME: Optimize these routines for HTTPHeaderMap keys and/or refactor them with XMLHttpRequest code.
-static bool isForbiddenHeaderName(const String&amp; name)
-{
-    HTTPHeaderName headerName;
-    if (findHTTPHeaderName(name, headerName)) {
-        switch (headerName) {
-        case HTTPHeaderName::AcceptCharset:
-        case HTTPHeaderName::AcceptEncoding:
-        case HTTPHeaderName::AccessControlRequestHeaders:
-        case HTTPHeaderName::AccessControlRequestMethod:
-        case HTTPHeaderName::Connection:
-        case HTTPHeaderName::ContentLength:
-        case HTTPHeaderName::Cookie:
-        case HTTPHeaderName::Cookie2:
-        case HTTPHeaderName::Date:
-        case HTTPHeaderName::DNT:
-        case HTTPHeaderName::Expect:
-        case HTTPHeaderName::Host:
-        case HTTPHeaderName::KeepAlive:
-        case HTTPHeaderName::Origin:
-        case HTTPHeaderName::Referer:
-        case HTTPHeaderName::TE:
-        case HTTPHeaderName::Trailer:
-        case HTTPHeaderName::TransferEncoding:
-        case HTTPHeaderName::Upgrade:
-        case HTTPHeaderName::Via:
-            return true;
-        default:
-            break;
-        }
-    }
-    return startsWithLettersIgnoringASCIICase(name, &quot;sec-&quot;) || startsWithLettersIgnoringASCIICase(name, &quot;proxy-&quot;);
-}
-
-static bool isForbiddenResponseHeaderName(const String&amp; name)
-{
-    return equalLettersIgnoringASCIICase(name, &quot;set-cookie&quot;) || equalLettersIgnoringASCIICase(name, &quot;set-cookie2&quot;);
-}
-
-static bool isSimpleHeader(const String&amp; name, const String&amp; value)
-{
-    HTTPHeaderName headerName;
-    if (!findHTTPHeaderName(name, headerName))
-        return false;
-    switch (headerName) {
-    case HTTPHeaderName::Accept:
-    case HTTPHeaderName::AcceptLanguage:
-    case HTTPHeaderName::ContentLanguage:
-        return true;
-    case HTTPHeaderName::ContentType: {
-        String mimeType = extractMIMETypeFromMediaType(value);
-        return equalLettersIgnoringASCIICase(mimeType, &quot;application/x-www-form-urlencoded&quot;) || equalLettersIgnoringASCIICase(mimeType, &quot;multipart/form-data&quot;) || equalLettersIgnoringASCIICase(mimeType, &quot;text/plain&quot;);
-    }
-    default:
-        return false;
-    }
-}
-
</del><span class="cx"> static bool canWriteHeader(const String&amp; name, const String&amp; value, FetchHeaders::Guard guard, ExceptionCode&amp; ec)
</span><span class="cx"> {
</span><span class="cx">     if (!isValidHTTPToken(name) || !isValidHTTPHeaderValue(value)) {
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderCrossOriginAccessControlcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/CrossOriginAccessControl.cpp (203814 => 203815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/CrossOriginAccessControl.cpp        2016-07-28 06:37:45 UTC (rev 203814)
+++ trunk/Source/WebCore/loader/CrossOriginAccessControl.cpp        2016-07-28 08:30:14 UTC (rev 203815)
</span><span class="lines">@@ -180,15 +180,4 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void parseAccessControlExposeHeadersAllowList(const String&amp; headerValue, HTTPHeaderSet&amp; headerSet)
-{
-    Vector&lt;String&gt; headers;
-    headerValue.split(',', false, headers);
-    for (auto&amp; header : headers) {
-        String strippedHeader = header.stripWhiteSpace();
-        if (!strippedHeader.isEmpty())
-            headerSet.add(strippedHeader);
-    }
-}
-
</del><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderCrossOriginAccessControlh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/CrossOriginAccessControl.h (203814 => 203815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/CrossOriginAccessControl.h        2016-07-28 06:37:45 UTC (rev 203814)
+++ trunk/Source/WebCore/loader/CrossOriginAccessControl.h        2016-07-28 08:30:14 UTC (rev 203815)
</span><span class="lines">@@ -29,13 +29,9 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;ResourceHandleTypes.h&quot;
</span><span class="cx"> #include &lt;wtf/Forward.h&gt;
</span><del>-#include &lt;wtf/HashSet.h&gt;
-#include &lt;wtf/text/StringHash.h&gt;
</del><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-typedef HashSet&lt;String, ASCIICaseInsensitiveHash&gt; HTTPHeaderSet;
-
</del><span class="cx"> class HTTPHeaderMap;
</span><span class="cx"> enum class HTTPHeaderName;
</span><span class="cx"> class ResourceRequest;
</span><span class="lines">@@ -55,7 +51,6 @@
</span><span class="cx"> void cleanRedirectedRequestForAccessControl(ResourceRequest&amp;);
</span><span class="cx"> 
</span><span class="cx"> bool passesAccessControlCheck(const ResourceResponse&amp;, StoredCredentials, SecurityOrigin&amp;, String&amp; errorDescription);
</span><del>-void parseAccessControlExposeHeadersAllowList(const String&amp; headerValue, HTTPHeaderSet&amp;);
</del><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderDocumentThreadableLoadercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/DocumentThreadableLoader.cpp (203814 => 203815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/DocumentThreadableLoader.cpp        2016-07-28 06:37:45 UTC (rev 203814)
+++ trunk/Source/WebCore/loader/DocumentThreadableLoader.cpp        2016-07-28 08:30:14 UTC (rev 203815)
</span><span class="lines">@@ -268,10 +268,10 @@
</span><span class="cx"> void DocumentThreadableLoader::responseReceived(CachedResource* resource, const ResourceResponse&amp; response)
</span><span class="cx"> {
</span><span class="cx">     ASSERT_UNUSED(resource, resource == m_resource);
</span><del>-    didReceiveResponse(m_resource-&gt;identifier(), response);
</del><ins>+    didReceiveResponse(m_resource-&gt;identifier(), response, m_resource-&gt;responseTainting());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void DocumentThreadableLoader::didReceiveResponse(unsigned long identifier, const ResourceResponse&amp; response)
</del><ins>+void DocumentThreadableLoader::didReceiveResponse(unsigned long identifier, const ResourceResponse&amp; response, ResourceResponse::Tainting tainting)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(m_client);
</span><span class="cx"> 
</span><span class="lines">@@ -283,7 +283,16 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    m_client-&gt;didReceiveResponse(identifier, response);
</del><ins>+    ASSERT(response.type() != ResourceResponse::Type::Error);
+    if (response.type() == ResourceResponse::Type::Default) {
+        // FIXME: To be removed once the real fetch mode is passed to underlying loaders.
+        if (options().mode == FetchOptions::Mode::Cors &amp;&amp; tainting == ResourceResponse::Tainting::Opaque)
+            tainting = ResourceResponse::Tainting::Cors;
+        m_client-&gt;didReceiveResponse(identifier, ResourceResponse::filterResponse(response, tainting));
+    } else {
+        ASSERT(response.isNull() &amp;&amp; response.type() == ResourceResponse::Type::Opaqueredirect);
+        m_client-&gt;didReceiveResponse(identifier, response);
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void DocumentThreadableLoader::dataReceived(CachedResource* resource, const char* data, int dataLength)
</span><span class="lines">@@ -386,7 +395,7 @@
</span><span class="cx">         if (requestURL.isLocalFile()) {
</span><span class="cx">             // We don't want XMLHttpRequest to raise an exception for file:// resources, see &lt;rdar://problem/4962298&gt;.
</span><span class="cx">             // FIXME: XMLHttpRequest quirks should be in XMLHttpRequest code, not in DocumentThreadableLoader.cpp.
</span><del>-            didReceiveResponse(identifier, response);
</del><ins>+            didReceiveResponse(identifier, response, ResourceResponse::Tainting::Basic);
</ins><span class="cx">             didFinishLoading(identifier, 0.0);
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="lines">@@ -409,7 +418,10 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    didReceiveResponse(identifier, response);
</del><ins>+    ResourceResponse::Tainting tainting = ResourceResponse::Tainting::Basic;
+    if (!m_sameOriginRequest)
+        tainting = m_options.mode == FetchOptions::Mode::Cors ? ResourceResponse::Tainting::Cors : ResourceResponse::Tainting::Opaque;
+    didReceiveResponse(identifier, response, tainting);
</ins><span class="cx"> 
</span><span class="cx">     if (data)
</span><span class="cx">         didReceiveData(identifier, data-&gt;data(), data-&gt;size());
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderDocumentThreadableLoaderh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/DocumentThreadableLoader.h (203814 => 203815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/DocumentThreadableLoader.h        2016-07-28 06:37:45 UTC (rev 203814)
+++ trunk/Source/WebCore/loader/DocumentThreadableLoader.h        2016-07-28 08:30:14 UTC (rev 203815)
</span><span class="lines">@@ -32,6 +32,7 @@
</span><span class="cx"> #define DocumentThreadableLoader_h
</span><span class="cx"> 
</span><span class="cx"> #include &quot;CrossOriginPreflightChecker.h&quot;
</span><ins>+#include &quot;ResourceResponse.h&quot;
</ins><span class="cx"> #include &quot;SecurityOrigin.h&quot;
</span><span class="cx"> #include &quot;ThreadableLoader.h&quot;
</span><span class="cx"> 
</span><span class="lines">@@ -81,7 +82,7 @@
</span><span class="cx">         void redirectReceived(CachedResource*, ResourceRequest&amp;, const ResourceResponse&amp;) override;
</span><span class="cx">         void notifyFinished(CachedResource*) override;
</span><span class="cx"> 
</span><del>-        void didReceiveResponse(unsigned long identifier, const ResourceResponse&amp;);
</del><ins>+        void didReceiveResponse(unsigned long identifier, const ResourceResponse&amp;, ResourceResponse::Tainting);
</ins><span class="cx">         void didReceiveData(unsigned long identifier, const char* data, int dataLength);
</span><span class="cx">         void didFinishLoading(unsigned long identifier, double finishTime);
</span><span class="cx">         void didFail(unsigned long identifier, const ResourceError&amp;);
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderSubresourceLoadercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/SubresourceLoader.cpp (203814 => 203815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/SubresourceLoader.cpp        2016-07-28 06:37:45 UTC (rev 203814)
+++ trunk/Source/WebCore/loader/SubresourceLoader.cpp        2016-07-28 08:30:14 UTC (rev 203815)
</span><span class="lines">@@ -6,13 +6,13 @@
</span><span class="cx">  * are met:
</span><span class="cx">  *
</span><span class="cx">  * 1.  Redistributions of source code must retain the above copyright
</span><del>- *     notice, this list of conditions and the following disclaimer. 
</del><ins>+ *     notice, this list of conditions and the following disclaimer.
</ins><span class="cx">  * 2.  Redistributions in binary form must reproduce the above copyright
</span><span class="cx">  *     notice, this list of conditions and the following disclaimer in the
</span><del>- *     documentation and/or other materials provided with the distribution. 
</del><ins>+ *     documentation and/or other materials provided with the distribution.
</ins><span class="cx">  * 3.  Neither the name of Apple Inc. (&quot;Apple&quot;) nor the names of
</span><span class="cx">  *     its contributors may be used to endorse or promote products derived
</span><del>- *     from this software without specific prior written permission. 
</del><ins>+ *     from this software without specific prior written permission.
</ins><span class="cx">  *
</span><span class="cx">  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS &quot;AS IS&quot; AND ANY
</span><span class="cx">  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
</span><span class="lines">@@ -151,8 +151,10 @@
</span><span class="cx">     // FIXME: https://bugs.webkit.org/show_bug.cgi?id=155633.
</span><span class="cx">     // SubresourceLoader could use the document origin as a default and set PotentiallyCrossOriginEnabled requests accordingly.
</span><span class="cx">     // This would simplify resource loader users as they would only need to set fetch mode to Cors.
</span><del>-    if (options().mode == FetchOptions::Mode::Cors)
-        m_origin = SecurityOrigin::createFromString(request.httpOrigin());
</del><ins>+    m_origin = m_resource-&gt;origin();
+    // https://fetch.spec.whatwg.org/#main-fetch, step 11, data URL here is considered not cross origin.
+    if (!request.url().protocolIsData() &amp;&amp; m_origin &amp;&amp; !m_origin-&gt;canRequest(request.url()))
+        m_resource-&gt;setCrossOrigin();
</ins><span class="cx"> 
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="lines">@@ -180,8 +182,10 @@
</span><span class="cx">                 cancel();
</span><span class="cx">                 return;
</span><span class="cx">             }
</span><del>-            m_resource-&gt;setOpaqueRedirect();
-            m_resource-&gt;responseReceived({ });
</del><ins>+
+            ResourceResponse opaqueRedirectedResponse;
+            opaqueRedirectedResponse.setType(ResourceResponse::Type::Opaqueredirect);
+            m_resource-&gt;responseReceived(opaqueRedirectedResponse);
</ins><span class="cx">             didFinishLoading(currentTime());
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="lines">@@ -202,7 +206,7 @@
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        if (options().mode == FetchOptions::Mode::Cors &amp;&amp; !checkCrossOriginAccessControl(request(), redirectResponse, newRequest)) {
</del><ins>+        if (!checkRedirectionCrossOriginAccessControl(request(), redirectResponse, newRequest)) {
</ins><span class="cx">             cancel();
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="lines">@@ -295,8 +299,8 @@
</span><span class="cx">         // The resource data will change as the next part is loaded, so we need to make a copy.
</span><span class="cx">         m_resource-&gt;finishLoading(buffer-&gt;copy().ptr());
</span><span class="cx">         clearResourceData();
</span><del>-        // Since a subresource loader does not load multipart sections progressively, data was delivered to the loader all at once.        
-        // After the first multipart section is complete, signal to delegates that this load is &quot;finished&quot; 
</del><ins>+        // Since a subresource loader does not load multipart sections progressively, data was delivered to the loader all at once.
+        // After the first multipart section is complete, signal to delegates that this load is &quot;finished&quot;
</ins><span class="cx">         m_documentLoader-&gt;subresourceLoaderFinishedLoadingOnePart(this);
</span><span class="cx">         didFinishLoadingOnePart(0);
</span><span class="cx">     }
</span><span class="lines">@@ -396,11 +400,19 @@
</span><span class="cx">     frame-&gt;page()-&gt;diagnosticLoggingClient().logDiagnosticMessageWithValue(DiagnosticLoggingKeys::resourceKey(), DiagnosticLoggingKeys::loadedKey(), resourceType, ShouldSample::Yes);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool SubresourceLoader::checkCrossOriginAccessControl(const ResourceRequest&amp; previousRequest, const ResourceResponse&amp; redirectResponse, ResourceRequest&amp; newRequest)
</del><ins>+bool SubresourceLoader::checkRedirectionCrossOriginAccessControl(const ResourceRequest&amp; previousRequest, const ResourceResponse&amp; redirectResponse, ResourceRequest&amp; newRequest)
</ins><span class="cx"> {
</span><del>-    if (m_origin-&gt;canRequest(newRequest.url()))
</del><ins>+    ASSERT(options().mode != FetchOptions::Mode::SameOrigin);
+
+    bool shouldCheckCrossOrigin = options().mode == FetchOptions::Mode::Cors &amp;&amp; m_resource-&gt;isCrossOrigin();
+
+    if (!(m_origin &amp;&amp; m_origin-&gt;canRequest(newRequest.url())))
+        m_resource-&gt;setCrossOrigin();
+
+    if (!shouldCheckCrossOrigin)
</ins><span class="cx">         return true;
</span><span class="cx"> 
</span><ins>+    ASSERT(m_origin);
</ins><span class="cx">     String errorDescription;
</span><span class="cx">     bool responsePassesCORS = m_origin-&gt;canRequest(previousRequest.url())
</span><span class="cx">         || passesAccessControlCheck(redirectResponse, options().allowCredentials(), *m_origin, errorDescription);
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderSubresourceLoaderh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/SubresourceLoader.h (203814 => 203815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/SubresourceLoader.h        2016-07-28 06:37:45 UTC (rev 203814)
+++ trunk/Source/WebCore/loader/SubresourceLoader.h        2016-07-28 08:30:14 UTC (rev 203815)
</span><span class="lines">@@ -6,13 +6,13 @@
</span><span class="cx">  * are met:
</span><span class="cx">  *
</span><span class="cx">  * 1.  Redistributions of source code must retain the above copyright
</span><del>- *     notice, this list of conditions and the following disclaimer. 
</del><ins>+ *     notice, this list of conditions and the following disclaimer.
</ins><span class="cx">  * 2.  Redistributions in binary form must reproduce the above copyright
</span><span class="cx">  *     notice, this list of conditions and the following disclaimer in the
</span><del>- *     documentation and/or other materials provided with the distribution. 
</del><ins>+ *     documentation and/or other materials provided with the distribution.
</ins><span class="cx">  * 3.  Neither the name of Apple Inc. (&quot;Apple&quot;) nor the names of
</span><span class="cx">  *     its contributors may be used to endorse or promote products derived
</span><del>- *     from this software without specific prior written permission. 
</del><ins>+ *     from this software without specific prior written permission.
</ins><span class="cx">  *
</span><span class="cx">  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS &quot;AS IS&quot; AND ANY
</span><span class="cx">  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
</span><span class="lines">@@ -91,7 +91,7 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     bool checkForHTTPStatusCodeError();
</span><del>-    bool checkCrossOriginAccessControl(const ResourceRequest&amp;, const ResourceResponse&amp;, ResourceRequest&amp; newRequest);
</del><ins>+    bool checkRedirectionCrossOriginAccessControl(const ResourceRequest&amp;, const ResourceResponse&amp;, ResourceRequest&amp; newRequest);
</ins><span class="cx"> 
</span><span class="cx">     void didReceiveDataOrBuffer(const char*, int, RefPtr&lt;SharedBuffer&gt;&amp;&amp;, long long encodedDataLength, DataPayloadType);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCachedResourcecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CachedResource.cpp (203814 => 203815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/cache/CachedResource.cpp        2016-07-28 06:37:45 UTC (rev 203814)
+++ trunk/Source/WebCore/loader/cache/CachedResource.cpp        2016-07-28 08:30:14 UTC (rev 203815)
</span><span class="lines">@@ -281,7 +281,14 @@
</span><span class="cx"> #endif
</span><span class="cx">     m_resourceRequest.setPriority(loadPriority());
</span><span class="cx"> 
</span><del>-    addAdditionalRequestHeaders(cachedResourceLoader);
</del><ins>+    if (type() != MainResource) {
+        if (m_resourceRequest.hasHTTPOrigin())
+            m_origin = SecurityOrigin::createFromString(m_resourceRequest.httpOrigin());
+        else
+            m_origin = cachedResourceLoader.document()-&gt;securityOrigin();
+        ASSERT(m_origin);
+        addAdditionalRequestHeaders(cachedResourceLoader);
+    }
</ins><span class="cx"> 
</span><span class="cx">     // FIXME: It's unfortunate that the cache layer and below get to know anything about fragment identifiers.
</span><span class="cx">     // We should look into removing the expectation of that knowledge from the platform network stacks.
</span><span class="lines">@@ -367,6 +374,23 @@
</span><span class="cx">     return passesAccessControlCheck(securityOrigin);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void CachedResource::setCrossOrigin()
+{
+    ASSERT(m_options.mode != FetchOptions::Mode::SameOrigin);
+    m_responseTainting = (m_options.mode == FetchOptions::Mode::Cors) ? ResourceResponse::Tainting::Cors : ResourceResponse::Tainting::Opaque;
+}
+
+bool CachedResource::isCrossOrigin() const
+{
+    return m_responseTainting != ResourceResponse::Tainting::Basic;
+}
+
+bool CachedResource::isClean() const
+{
+    // https://html.spec.whatwg.org/multipage/infrastructure.html#cors-same-origin
+    return !loadFailedOrCanceled() &amp;&amp; m_responseTainting != ResourceResponse::Tainting::Opaque;
+}
+
</ins><span class="cx"> bool CachedResource::isExpired() const
</span><span class="cx"> {
</span><span class="cx">     if (m_response.isNull())
</span><span class="lines">@@ -426,8 +450,8 @@
</span><span class="cx"> 
</span><span class="cx"> void CachedResource::setResponse(const ResourceResponse&amp; response)
</span><span class="cx"> {
</span><ins>+    ASSERT(m_response.type() == ResourceResponse::Type::Default);
</ins><span class="cx">     m_response = response;
</span><del>-    m_response.setType(m_responseType);
</del><span class="cx">     m_response.setRedirected(m_redirectChainCacheStatus.status != RedirectChainCacheStatus::NoRedirection);
</span><span class="cx"> 
</span><span class="cx">     m_varyingHeaderValues = collectVaryingRequestHeaders(m_resourceRequest, m_response, m_sessionID);
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCachedResourceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CachedResource.h (203814 => 203815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/cache/CachedResource.h        2016-07-28 06:37:45 UTC (rev 203814)
+++ trunk/Source/WebCore/loader/cache/CachedResource.h        2016-07-28 08:30:14 UTC (rev 203815)
</span><span class="lines">@@ -200,11 +200,17 @@
</span><span class="cx">     virtual void responseReceived(const ResourceResponse&amp;);
</span><span class="cx">     virtual bool shouldCacheResponse(const ResourceResponse&amp;) { return true; }
</span><span class="cx">     void setResponse(const ResourceResponse&amp;);
</span><del>-    void setOpaqueRedirect() { m_responseType = ResourceResponseBase::Type::Opaqueredirect; }
</del><span class="cx">     const ResourceResponse&amp; response() const { return m_response; }
</span><span class="cx">     // This is the same as response() except after HTTP redirect to data: URL.
</span><span class="cx">     const ResourceResponse&amp; responseForSameOriginPolicyChecks() const;
</span><span class="cx"> 
</span><ins>+    void setCrossOrigin();
+    bool isCrossOrigin() const;
+    bool isClean() const;
+    ResourceResponse::Tainting responseTainting() const { return m_responseTainting; }
+
+    SecurityOrigin* origin() const { return m_origin.get(); }
+
</ins><span class="cx">     bool canDelete() const { return !hasClients() &amp;&amp; !m_loader &amp;&amp; !m_preloadCount &amp;&amp; !m_handleCount &amp;&amp; !m_resourceToRevalidate &amp;&amp; !m_proxyResource; }
</span><span class="cx">     bool hasOneHandle() const { return m_handleCount == 1; }
</span><span class="cx"> 
</span><span class="lines">@@ -224,7 +230,7 @@
</span><span class="cx">     DataBufferingPolicy dataBufferingPolicy() const { return m_options.dataBufferingPolicy(); }
</span><span class="cx"> 
</span><span class="cx">     bool allowsCaching() const { return m_options.cachingPolicy() == CachingPolicy::AllowCaching; }
</span><del>-    
</del><ins>+
</ins><span class="cx">     virtual void destroyDecodedData() { }
</span><span class="cx"> 
</span><span class="cx">     void setOwningCachedResourceLoader(CachedResourceLoader* cachedResourceLoader) { m_owningCachedResourceLoader = cachedResourceLoader; }
</span><span class="lines">@@ -284,7 +290,7 @@
</span><span class="cx">     RefPtr&lt;SubresourceLoader&gt; m_loader;
</span><span class="cx">     ResourceLoaderOptions m_options;
</span><span class="cx">     ResourceResponse m_response;
</span><del>-    ResourceResponseBase::Type m_responseType { ResourceResponseBase::Type::Basic };
</del><ins>+    ResourceResponse::Tainting m_responseTainting { ResourceResponse::Tainting::Basic };
</ins><span class="cx">     ResourceResponse m_redirectResponseForSameOriginPolicyChecks;
</span><span class="cx">     RefPtr&lt;SharedBuffer&gt; m_data;
</span><span class="cx">     DeferrableOneShotTimer m_decodedDataDeletionTimer;
</span><span class="lines">@@ -313,6 +319,7 @@
</span><span class="cx">     String m_fragmentIdentifierForRequest;
</span><span class="cx"> 
</span><span class="cx">     ResourceError m_error;
</span><ins>+    RefPtr&lt;SecurityOrigin&gt; m_origin;
</ins><span class="cx"> 
</span><span class="cx">     double m_lastDecodedAccessTime; // Used as a &quot;thrash guard&quot; in the cache
</span><span class="cx">     double m_loadFinishTime;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkHTTPParserscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/HTTPParsers.cpp (203814 => 203815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/HTTPParsers.cpp        2016-07-28 06:37:45 UTC (rev 203814)
+++ trunk/Source/WebCore/platform/network/HTTPParsers.cpp        2016-07-28 08:30:14 UTC (rev 203815)
</span><span class="lines">@@ -33,6 +33,7 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;HTTPParsers.h&quot;
</span><span class="cx"> 
</span><ins>+#include &quot;HTTPHeaderNames.h&quot;
</ins><span class="cx"> #include &lt;wtf/DateMath.h&gt;
</span><span class="cx"> #include &lt;wtf/NeverDestroyed.h&gt;
</span><span class="cx"> #include &lt;wtf/text/CString.h&gt;
</span><span class="lines">@@ -755,4 +756,102 @@
</span><span class="cx">     return length;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void parseAccessControlExposeHeadersAllowList(const String&amp; headerValue, HTTPHeaderSet&amp; headerSet)
+{
+    Vector&lt;String&gt; headers;
+    headerValue.split(',', false, headers);
+    for (auto&amp; header : headers) {
+        String strippedHeader = header.stripWhiteSpace();
+        if (!strippedHeader.isEmpty())
+            headerSet.add(strippedHeader);
+    }
</ins><span class="cx"> }
</span><ins>+
+// Implememtnation of https://fetch.spec.whatwg.org/#cors-safelisted-response-header-name
+bool isForbiddenHeaderName(const String&amp; name)
+{
+    HTTPHeaderName headerName;
+    if (findHTTPHeaderName(name, headerName)) {
+        switch (headerName) {
+        case HTTPHeaderName::AcceptCharset:
+        case HTTPHeaderName::AcceptEncoding:
+        case HTTPHeaderName::AccessControlRequestHeaders:
+        case HTTPHeaderName::AccessControlRequestMethod:
+        case HTTPHeaderName::Connection:
+        case HTTPHeaderName::ContentLength:
+        case HTTPHeaderName::Cookie:
+        case HTTPHeaderName::Cookie2:
+        case HTTPHeaderName::Date:
+        case HTTPHeaderName::DNT:
+        case HTTPHeaderName::Expect:
+        case HTTPHeaderName::Host:
+        case HTTPHeaderName::KeepAlive:
+        case HTTPHeaderName::Origin:
+        case HTTPHeaderName::Referer:
+        case HTTPHeaderName::TE:
+        case HTTPHeaderName::Trailer:
+        case HTTPHeaderName::TransferEncoding:
+        case HTTPHeaderName::Upgrade:
+        case HTTPHeaderName::Via:
+            return true;
+        default:
+            break;
+        }
+    }
+    return startsWithLettersIgnoringASCIICase(name, &quot;sec-&quot;) || startsWithLettersIgnoringASCIICase(name, &quot;proxy-&quot;);
+}
+
+bool isForbiddenResponseHeaderName(const String&amp; name)
+{
+    return equalLettersIgnoringASCIICase(name, &quot;set-cookie&quot;) || equalLettersIgnoringASCIICase(name, &quot;set-cookie2&quot;);
+}
+
+bool isSimpleHeader(const String&amp; name, const String&amp; value)
+{
+    HTTPHeaderName headerName;
+    if (!findHTTPHeaderName(name, headerName))
+        return false;
+    switch (headerName) {
+    case HTTPHeaderName::Accept:
+    case HTTPHeaderName::AcceptLanguage:
+    case HTTPHeaderName::ContentLanguage:
+        return true;
+    case HTTPHeaderName::ContentType: {
+        String mimeType = extractMIMETypeFromMediaType(value);
+        return equalLettersIgnoringASCIICase(mimeType, &quot;application/x-www-form-urlencoded&quot;) || equalLettersIgnoringASCIICase(mimeType, &quot;multipart/form-data&quot;) || equalLettersIgnoringASCIICase(mimeType, &quot;text/plain&quot;);
+    }
+    default:
+        return false;
+    }
+}
+
+bool isCrossOriginSafeHeader(HTTPHeaderName name, const HTTPHeaderSet&amp; accessControlExposeHeaderSet)
+{
+    switch (name) {
+    case HTTPHeaderName::CacheControl:
+    case HTTPHeaderName::ContentLanguage:
+    case HTTPHeaderName::ContentType:
+    case HTTPHeaderName::Expires:
+    case HTTPHeaderName::LastModified:
+    case HTTPHeaderName::Pragma:
+    case HTTPHeaderName::Accept:
+        return true;
+    case HTTPHeaderName::SetCookie:
+    case HTTPHeaderName::SetCookie2:
+        return false;
+    default:
+        break;
+    }
+    return accessControlExposeHeaderSet.contains(httpHeaderNameString(name).toStringWithoutCopying());
+}
+
+bool isCrossOriginSafeHeader(const String&amp; name, const HTTPHeaderSet&amp; accessControlExposeHeaderSet)
+{
+#ifndef ASSERT_DISABLED
+    HTTPHeaderName headerName;
+    ASSERT(!findHTTPHeaderName(name, headerName));
+#endif
+    return accessControlExposeHeaderSet.contains(name);
+}
+
+}
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkHTTPParsersh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/HTTPParsers.h (203814 => 203815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/HTTPParsers.h        2016-07-28 06:37:45 UTC (rev 203814)
+++ trunk/Source/WebCore/platform/network/HTTPParsers.h        2016-07-28 08:30:14 UTC (rev 203815)
</span><span class="lines">@@ -32,12 +32,18 @@
</span><span class="cx"> #define HTTPParsers_h
</span><span class="cx"> 
</span><span class="cx"> #include &lt;wtf/Forward.h&gt;
</span><ins>+#include &lt;wtf/HashSet.h&gt;
</ins><span class="cx"> #include &lt;wtf/Optional.h&gt;
</span><span class="cx"> #include &lt;wtf/Vector.h&gt;
</span><ins>+#include &lt;wtf/text/StringHash.h&gt;
</ins><span class="cx"> #include &lt;wtf/text/WTFString.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><ins>+typedef HashSet&lt;String, ASCIICaseInsensitiveHash&gt; HTTPHeaderSet;
+
+enum class HTTPHeaderName;
+
</ins><span class="cx"> enum class XSSProtectionDisposition {
</span><span class="cx">     Invalid,
</span><span class="cx">     Disabled,
</span><span class="lines">@@ -95,6 +101,15 @@
</span><span class="cx"> size_t parseHTTPHeader(const char* data, size_t length, String&amp; failureReason, StringView&amp; nameStr, String&amp; valueStr, bool strict = true);
</span><span class="cx"> size_t parseHTTPRequestBody(const char* data, size_t length, Vector&lt;unsigned char&gt;&amp; body);
</span><span class="cx"> 
</span><ins>+void parseAccessControlExposeHeadersAllowList(const String&amp; headerValue, HTTPHeaderSet&amp;);
+
+// HTTP Header routine as per https://fetch.spec.whatwg.org/#terminology-headers
+bool isForbiddenHeaderName(const String&amp;);
+bool isForbiddenResponseHeaderName(const String&amp;);
+bool isSimpleHeader(const String&amp; name, const String&amp; value);
+bool isCrossOriginSafeHeader(HTTPHeaderName, const HTTPHeaderSet&amp;);
+bool isCrossOriginSafeHeader(const String&amp;, const HTTPHeaderSet&amp;);
+
</ins><span class="cx"> inline bool isHTTPSpace(UChar character)
</span><span class="cx"> {
</span><span class="cx">     return character &lt;= ' ' &amp;&amp; (character == ' ' || character == '\n' || character == '\t' || character == '\r');
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkResourceRequestBasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/ResourceRequestBase.cpp (203814 => 203815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/ResourceRequestBase.cpp        2016-07-28 06:37:45 UTC (rev 203814)
+++ trunk/Source/WebCore/platform/network/ResourceRequestBase.cpp        2016-07-28 08:30:14 UTC (rev 203815)
</span><span class="lines">@@ -313,9 +313,14 @@
</span><span class="cx">     setHTTPHeaderField(HTTPHeaderName::Origin, httpOrigin);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool ResourceRequestBase::hasHTTPOrigin() const
+{
+    return m_httpHeaderFields.contains(HTTPHeaderName::Origin);
+}
+
</ins><span class="cx"> void ResourceRequestBase::clearHTTPOrigin()
</span><span class="cx"> {
</span><del>-    updateResourceRequest(); 
</del><ins>+    updateResourceRequest();
</ins><span class="cx"> 
</span><span class="cx">     m_httpHeaderFields.remove(HTTPHeaderName::Origin);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkResourceRequestBaseh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/ResourceRequestBase.h (203814 => 203815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/ResourceRequestBase.h        2016-07-28 06:37:45 UTC (rev 203814)
+++ trunk/Source/WebCore/platform/network/ResourceRequestBase.h        2016-07-28 08:30:14 UTC (rev 203815)
</span><span class="lines">@@ -22,7 +22,7 @@
</span><span class="cx">  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
</span><span class="cx">  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
</span><span class="cx">  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
</span><del>- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
</del><ins>+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</ins><span class="cx">  */
</span><span class="cx"> 
</span><span class="cx"> #ifndef ResourceRequestBase_h
</span><span class="lines">@@ -100,8 +100,9 @@
</span><span class="cx">     WEBCORE_EXPORT String httpReferrer() const;
</span><span class="cx">     WEBCORE_EXPORT void setHTTPReferrer(const String&amp;);
</span><span class="cx">     WEBCORE_EXPORT void clearHTTPReferrer();
</span><del>-    
</del><ins>+
</ins><span class="cx">     String httpOrigin() const;
</span><ins>+    bool hasHTTPOrigin() const;
</ins><span class="cx">     void setHTTPOrigin(const String&amp;);
</span><span class="cx">     WEBCORE_EXPORT void clearHTTPOrigin();
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkResourceResponseBasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/ResourceResponseBase.cpp (203814 => 203815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/ResourceResponseBase.cpp        2016-07-28 06:37:45 UTC (rev 203814)
+++ trunk/Source/WebCore/platform/network/ResourceResponseBase.cpp        2016-07-28 08:30:14 UTC (rev 203815)
</span><span class="lines">@@ -99,6 +99,40 @@
</span><span class="cx">     return response;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+ResourceResponse ResourceResponseBase::filterResponse(const ResourceResponse&amp; response, ResourceResponse::Tainting tainting)
+{
+    if (tainting == ResourceResponse::Tainting::Opaque) {
+        ResourceResponse opaqueResponse;
+        opaqueResponse.setType(ResourceResponse::Type::Opaque);
+        return opaqueResponse;
+    }
+
+    ResourceResponse filteredResponse = response;
+    // Let's initialize filteredResponse to remove some header fields.
+    filteredResponse.lazyInit(AllFields);
+
+    if (tainting == ResourceResponse::Tainting::Basic) {
+        filteredResponse.setType(ResourceResponse::Type::Basic);
+        filteredResponse.m_httpHeaderFields.remove(HTTPHeaderName::SetCookie);
+        filteredResponse.m_httpHeaderFields.remove(HTTPHeaderName::SetCookie2);
+        return filteredResponse;
+    }
+
+    ASSERT(tainting == ResourceResponse::Tainting::Cors);
+    filteredResponse.setType(ResourceResponse::Type::Cors);
+
+    HTTPHeaderSet accessControlExposeHeaderSet;
+    parseAccessControlExposeHeadersAllowList(response.httpHeaderField(HTTPHeaderName::AccessControlExposeHeaders), accessControlExposeHeaderSet);
+    filteredResponse.m_httpHeaderFields.uncommonHeaders().removeIf([&amp;](auto&amp; entry) {
+        return !isCrossOriginSafeHeader(entry.key, accessControlExposeHeaderSet);
+    });
+    filteredResponse.m_httpHeaderFields.commonHeaders().removeIf([&amp;](auto&amp; entry) {
+        return !isCrossOriginSafeHeader(entry.key, accessControlExposeHeaderSet);
+    });
+
+    return filteredResponse;
+}
+
</ins><span class="cx"> // FIXME: Name does not make it clear this is true for HTTPS!
</span><span class="cx"> bool ResourceResponseBase::isHTTP() const
</span><span class="cx"> {
</span><span class="lines">@@ -111,7 +145,7 @@
</span><span class="cx"> {
</span><span class="cx">     lazyInit(CommonFieldsOnly);
</span><span class="cx"> 
</span><del>-    return m_url; 
</del><ins>+    return m_url;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ResourceResponseBase::setURL(const URL&amp; url)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkResourceResponseBaseh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/ResourceResponseBase.h (203814 => 203815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/ResourceResponseBase.h        2016-07-28 06:37:45 UTC (rev 203814)
+++ trunk/Source/WebCore/platform/network/ResourceResponseBase.h        2016-07-28 08:30:14 UTC (rev 203815)
</span><span class="lines">@@ -65,6 +65,9 @@
</span><span class="cx">     CrossThreadData crossThreadData() const;
</span><span class="cx">     static ResourceResponse fromCrossThreadData(CrossThreadData&amp;&amp;);
</span><span class="cx"> 
</span><ins>+    enum class Tainting { Basic, Cors, Opaque };
+    static ResourceResponse filterResponse(const ResourceResponse&amp;, Tainting);
+
</ins><span class="cx">     bool isNull() const { return m_isNull; }
</span><span class="cx">     WEBCORE_EXPORT bool isHTTP() const;
</span><span class="cx">     bool isSuccessful() const;
</span></span></pre></div>
<a id="trunkSourceWebCorexmlXMLHttpRequestcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/xml/XMLHttpRequest.cpp (203814 => 203815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/xml/XMLHttpRequest.cpp        2016-07-28 06:37:45 UTC (rev 203814)
+++ trunk/Source/WebCore/xml/XMLHttpRequest.cpp        2016-07-28 08:30:14 UTC (rev 203815)
</span><span class="lines">@@ -75,11 +75,6 @@
</span><span class="cx">     XMLHttpRequestSendArrayBufferOrViewMax,
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-static bool isSetCookieHeader(const String&amp; name)
-{
-    return equalLettersIgnoringASCIICase(name, &quot;set-cookie&quot;) || equalLettersIgnoringASCIICase(name, &quot;set-cookie2&quot;);
-}
-
</del><span class="cx"> static void replaceCharsetInMediaType(String&amp; mediaType, const String&amp; charsetValue)
</span><span class="cx"> {
</span><span class="cx">     unsigned pos = 0, len = 0;
</span><span class="lines">@@ -906,22 +901,7 @@
</span><span class="cx"> 
</span><span class="cx">     StringBuilder stringBuilder;
</span><span class="cx"> 
</span><del>-    HTTPHeaderSet accessControlExposeHeaderSet;
-    parseAccessControlExposeHeadersAllowList(m_response.httpHeaderField(HTTPHeaderName::AccessControlExposeHeaders), accessControlExposeHeaderSet);
-    
</del><span class="cx">     for (const auto&amp; header : m_response.httpHeaderFields()) {
</span><del>-        // Hide Set-Cookie header fields from the XMLHttpRequest client for these reasons:
-        //     1) If the client did have access to the fields, then it could read HTTP-only
-        //        cookies; those cookies are supposed to be hidden from scripts.
-        //     2) There's no known harm in hiding Set-Cookie header fields entirely; we don't
-        //        know any widely used technique that requires access to them.
-        //     3) Firefox has implemented this policy.
-        if (isSetCookieHeader(header.key) &amp;&amp; !securityOrigin()-&gt;canLoadLocalResources())
-            continue;
-
-        if (!m_sameOriginRequest &amp;&amp; !isOnAccessControlResponseHeaderWhitelist(header.key) &amp;&amp; !accessControlExposeHeaderSet.contains(header.key))
-            continue;
-
</del><span class="cx">         stringBuilder.append(header.key);
</span><span class="cx">         stringBuilder.append(':');
</span><span class="cx">         stringBuilder.append(' ');
</span><span class="lines">@@ -938,19 +918,6 @@
</span><span class="cx">     if (m_state &lt; HEADERS_RECEIVED || m_error)
</span><span class="cx">         return String();
</span><span class="cx"> 
</span><del>-    // See comment in getAllResponseHeaders above.
-    if (isSetCookieHeader(name) &amp;&amp; !securityOrigin()-&gt;canLoadLocalResources()) {
-        logConsoleError(scriptExecutionContext(), &quot;Refused to get unsafe header \&quot;&quot; + name + &quot;\&quot;&quot;);
-        return String();
-    }
-
-    HTTPHeaderSet accessControlExposeHeaderSet;
-    parseAccessControlExposeHeadersAllowList(m_response.httpHeaderField(HTTPHeaderName::AccessControlExposeHeaders), accessControlExposeHeaderSet);
-
-    if (!m_sameOriginRequest &amp;&amp; !isOnAccessControlResponseHeaderWhitelist(name) &amp;&amp; !accessControlExposeHeaderSet.contains(name)) {
-        logConsoleError(scriptExecutionContext(), &quot;Refused to get unsafe header \&quot;&quot; + name + &quot;\&quot;&quot;);
-        return String();
-    }
</del><span class="cx">     return m_response.httpHeaderField(name);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>