<!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>[203899] 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/203899">203899</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2016-07-29 04:08:04 -0700 (Fri, 29 Jul 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>CrossOrigin preflight checker should compute the right Access-Control-Request-Headers value
https://bugs.webkit.org/show_bug.cgi?id=160028

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

LayoutTests/imported/w3c:

* web-platform-tests/fetch/api/cors/cors-no-preflight-expected.txt:
* web-platform-tests/fetch/api/cors/cors-no-preflight-worker-expected.txt:
* web-platform-tests/fetch/api/cors/cors-no-preflight.js:
(corsNoPreflight): fixing bugs in that test and adding new test to cover mime type checking that should ignore case.
* web-platform-tests/fetch/api/cors/cors-preflight-worker.html:
* web-platform-tests/fetch/api/cors/cors-preflight.html:
* web-platform-tests/fetch/api/cors/cors-preflight.js:
(corsPreflight): Adding safe headers to the request and checking more precisely sent Access-Control-Request-Headers header value.

Source/WebCore:

Covered by updated test.

Computing Access-Control-Request-Headers value according https://fetch.spec.whatwg.org/#cors-preflight-fetch:
- Remove safe headers
- lowercase header names
- sort lexicographically header names
The only difference is that we keep separating headers with ', ' instead of ',' as per the spec.
Also, some headers that might be safe are still marked as unsafe (DPR, Downlink...).

Moved setting of Origin header after preflighting, consistently with fetch spec.

* loader/CrossOriginAccessControl.cpp:
(WebCore::createAccessControlPreflightRequest): Implementing new computation of Access-Control-Request-Headers.
* loader/DocumentThreadableLoader.cpp:
(WebCore::DocumentThreadableLoader::makeCrossOriginAccessRequest): Removing call to updateRequestForAccessControl (which sets Origin header value).
(WebCore::DocumentThreadableLoader::makeSimpleCrossOriginAccessRequest): Adding call to updateRequestForAccessControl.
(WebCore::DocumentThreadableLoader::preflightSuccess): Ditto.
* platform/network/HTTPParsers.cpp:
(WebCore::isCrossOriginSafeRequestHeader): Helper routine to implement https://fetch.spec.whatwg.org/#cors-safelisted-request-header.
* platform/network/HTTPParsers.h:

LayoutTests:

Rebasing regular tests. Also updating skipped worker tests.

* platform/ios-simulator-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-no-preflight-expected.txt: Added.
* platform/ios-simulator-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-no-preflight-worker-expected.txt: Added.
* platform/ios-simulator-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight-redirect-worker-expected.txt: Added.
* platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-no-preflight-expected.txt: Added.
* platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-no-preflight-worker-expected.txt: Added.
* platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight-redirect-worker-expected.txt: Added.
* platform/mac/TestExpectations:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsimportedw3cChangeLog">trunk/LayoutTests/imported/w3c/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestsfetchapicorscorsbasicworkerexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-basic-worker-expected.txt</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestsfetchapicorscorsfilteringworkerexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-filtering-worker-expected.txt</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestsfetchapicorscorsnopreflightexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-no-preflight-expected.txt</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestsfetchapicorscorsnopreflightworkerexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-no-preflight-worker-expected.txt</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestsfetchapicorscorsnopreflightjs">trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-no-preflight.js</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestsfetchapicorscorspreflightworkerexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight-worker-expected.txt</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestsfetchapicorscorspreflightworkerhtml">trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight-worker.html</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestsfetchapicorscorspreflighthtml">trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight.html</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestsfetchapicorscorspreflightjs">trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight.js</a></li>
<li><a href="#trunkLayoutTestsplatformmacTestExpectations">trunk/LayoutTests/platform/mac/TestExpectations</a></li>
<li><a href="#trunkLayoutTestsplatformmacwk2importedw3cwebplatformtestsfetchapicorscorsbasicworkerexpectedtxt">trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-basic-worker-expected.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreloaderCrossOriginAccessControlcpp">trunk/Source/WebCore/loader/CrossOriginAccessControl.cpp</a></li>
<li><a href="#trunkSourceWebCoreloaderDocumentThreadableLoadercpp">trunk/Source/WebCore/loader/DocumentThreadableLoader.cpp</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>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsplatformiossimulatorwk2importedw3cwebplatformtestsfetchapicorscorsnopreflightexpectedtxt">trunk/LayoutTests/platform/ios-simulator-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-no-preflight-expected.txt</a></li>
<li><a href="#trunkLayoutTestsplatformiossimulatorwk2importedw3cwebplatformtestsfetchapicorscorsnopreflightworkerexpectedtxt">trunk/LayoutTests/platform/ios-simulator-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-no-preflight-worker-expected.txt</a></li>
<li><a href="#trunkLayoutTestsplatformmacwk2importedw3cwebplatformtestsfetchapicorscorsnopreflightexpectedtxt">trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-no-preflight-expected.txt</a></li>
<li><a href="#trunkLayoutTestsplatformmacwk2importedw3cwebplatformtestsfetchapicorscorsnopreflightworkerexpectedtxt">trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-no-preflight-worker-expected.txt</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestsfetchapicorscorspreflightredirectworkerexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight-redirect-worker-expected.txt</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (203898 => 203899)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-07-29 09:58:41 UTC (rev 203898)
+++ trunk/LayoutTests/ChangeLog        2016-07-29 11:08:04 UTC (rev 203899)
</span><span class="lines">@@ -1,3 +1,20 @@
</span><ins>+2016-07-29  Youenn Fablet  &lt;youenn@apple.com&gt;
+
+        CrossOrigin preflight checker should compute the right Access-Control-Request-Headers value
+        https://bugs.webkit.org/show_bug.cgi?id=160028
+
+        Reviewed by Alex Christensen.
+
+        Rebasing regular tests. Also updating skipped worker tests.
+
+        * platform/ios-simulator-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-no-preflight-expected.txt: Added.
+        * platform/ios-simulator-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-no-preflight-worker-expected.txt: Added.
+        * platform/ios-simulator-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight-redirect-worker-expected.txt: Added.
+        * platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-no-preflight-expected.txt: Added.
+        * platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-no-preflight-worker-expected.txt: Added.
+        * platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight-redirect-worker-expected.txt: Added.
+        * platform/mac/TestExpectations:
+
</ins><span class="cx"> 2016-07-28  Youenn Fablet  &lt;youennf@gmail.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Binding generator should expose the visible interface name in error messages
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/ChangeLog (203898 => 203899)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/ChangeLog        2016-07-29 09:58:41 UTC (rev 203898)
+++ trunk/LayoutTests/imported/w3c/ChangeLog        2016-07-29 11:08:04 UTC (rev 203899)
</span><span class="lines">@@ -1,3 +1,19 @@
</span><ins>+2016-07-29  Youenn Fablet  &lt;youenn@apple.com&gt;
+
+        CrossOrigin preflight checker should compute the right Access-Control-Request-Headers value
+        https://bugs.webkit.org/show_bug.cgi?id=160028
+
+        Reviewed by Alex Christensen.
+
+        * web-platform-tests/fetch/api/cors/cors-no-preflight-expected.txt:
+        * web-platform-tests/fetch/api/cors/cors-no-preflight-worker-expected.txt:
+        * web-platform-tests/fetch/api/cors/cors-no-preflight.js:
+        (corsNoPreflight): fixing bugs in that test and adding new test to cover mime type checking that should ignore case.
+        * web-platform-tests/fetch/api/cors/cors-preflight-worker.html:
+        * web-platform-tests/fetch/api/cors/cors-preflight.html:
+        * web-platform-tests/fetch/api/cors/cors-preflight.js:
+        (corsPreflight): Adding safe headers to the request and checking more precisely sent Access-Control-Request-Headers header value.
+
</ins><span class="cx"> 2016-07-28  Chris Dumez  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Add support for Element.getAttributeNames()
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestsfetchapicorscorsbasicworkerexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-basic-worker-expected.txt (203898 => 203899)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-basic-worker-expected.txt        2016-07-29 09:58:41 UTC (rev 203898)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-basic-worker-expected.txt        2016-07-29 11:08:04 UTC (rev 203899)
</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] promise_test: Unhandled rejection with value: object &quot;TypeError: Type error&quot;
</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] promise_test: Unhandled rejection with value: object &quot;TypeError: Type error&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] promise_test: Unhandled rejection with value: object &quot;TypeError: Type error&quot;
</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] promise_test: Unhandled rejection with value: object &quot;TypeError: Type error&quot;
</del><ins>+PASS Cross domain different protocol [cors mode] 
</ins><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestsfetchapicorscorsfilteringworkerexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-filtering-worker-expected.txt (203898 => 203899)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-filtering-worker-expected.txt        2016-07-29 09:58:41 UTC (rev 203898)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-filtering-worker-expected.txt        2016-07-29 11:08:04 UTC (rev 203899)
</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="trunkLayoutTestsimportedw3cwebplatformtestsfetchapicorscorsnopreflightexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-no-preflight-expected.txt (203898 => 203899)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-no-preflight-expected.txt        2016-07-29 09:58:41 UTC (rev 203898)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-no-preflight-expected.txt        2016-07-29 11:08:04 UTC (rev 203899)
</span><span class="lines">@@ -13,4 +13,5 @@
</span><span class="cx"> PASS Cross domain [GET] [Content-Type: multipart/form-data] 
</span><span class="cx"> PASS Cross domain [GET] [Content-Type: text/plain] 
</span><span class="cx"> PASS Cross domain [GET] [Content-Type: text/plain;charset=utf-8] 
</span><ins>+PASS Cross domain [GET] [Content-Type: Text/Plain;charset=utf-8] 
</ins><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestsfetchapicorscorsnopreflightworkerexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-no-preflight-worker-expected.txt (203898 => 203899)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-no-preflight-worker-expected.txt        2016-07-29 09:58:41 UTC (rev 203898)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-no-preflight-worker-expected.txt        2016-07-29 11:08:04 UTC (rev 203899)
</span><span class="lines">@@ -13,4 +13,5 @@
</span><span class="cx"> PASS Cross domain [GET] [Content-Type: multipart/form-data] 
</span><span class="cx"> PASS Cross domain [GET] [Content-Type: text/plain] 
</span><span class="cx"> PASS Cross domain [GET] [Content-Type: text/plain;charset=utf-8] 
</span><ins>+PASS Cross domain [GET] [Content-Type: Text/Plain;charset=utf-8] 
</ins><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestsfetchapicorscorsnopreflightjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-no-preflight.js (203898 => 203899)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-no-preflight.js        2016-07-29 09:58:41 UTC (rev 203898)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-no-preflight.js        2016-07-29 11:08:04 UTC (rev 203899)
</span><span class="lines">@@ -15,7 +15,7 @@
</span><span class="cx">     requestInit[&quot;headers&quot;][headerName] = headerValue;
</span><span class="cx"> 
</span><span class="cx">   promise_test(function(test) {
</span><del>-    fetch(RESOURCES_DIR + &quot;clean-stash.py?token=&quot; + uuid_token).then(function(resp) {
</del><ins>+    return fetch(RESOURCES_DIR + &quot;clean-stash.py?token=&quot; + uuid_token).then(function(resp) {
</ins><span class="cx">       assert_equals(resp.status, 200, &quot;Clean stash response's status is 200&quot;);
</span><span class="cx">       return fetch(url + urlParameters, requestInit).then(function(resp) {
</span><span class="cx">         assert_equals(resp.status, 200, &quot;Response's status is 200&quot;);
</span><span class="lines">@@ -28,8 +28,8 @@
</span><span class="cx"> var host_info = get_host_info();
</span><span class="cx"> 
</span><span class="cx"> corsNoPreflight(&quot;Cross domain basic usage [GET]&quot;, host_info.HTTP_REMOTE_ORIGIN, &quot;GET&quot;);
</span><del>-corsNoPreflight(&quot;Same domain different port [GET]&quot;, host_info.HTTP_ORIGIN_WITH_DIFFERENT_ORIGIN, &quot;GET&quot;);
-corsNoPreflight(&quot;Cross domain different port [GET]&quot;, host_info.HTTP_REMOTE_ORIGIN_WITH_DIFFERENT_ORIGIN, &quot;GET&quot;);
</del><ins>+corsNoPreflight(&quot;Same domain different port [GET]&quot;, host_info.HTTP_ORIGIN_WITH_DIFFERENT_PORT, &quot;GET&quot;);
+corsNoPreflight(&quot;Cross domain different port [GET]&quot;, host_info.HTTP_REMOTE_ORIGIN_WITH_DIFFERENT_PORT, &quot;GET&quot;);
</ins><span class="cx"> corsNoPreflight(&quot;Cross domain different protocol [GET]&quot;, host_info.HTTPS_REMOTE_ORIGIN, &quot;GET&quot;);
</span><span class="cx"> corsNoPreflight(&quot;Same domain different protocol different port [GET]&quot;, host_info.HTTPS_ORIGIN, &quot;GET&quot;);
</span><span class="cx"> corsNoPreflight(&quot;Cross domain [POST]&quot;, host_info.HTTP_REMOTE_ORIGIN, &quot;POST&quot;);
</span><span class="lines">@@ -41,5 +41,6 @@
</span><span class="cx"> corsNoPreflight(&quot;Cross domain [GET] [Content-Type: multipart/form-data]&quot;, host_info.HTTP_REMOTE_ORIGIN, &quot;GET&quot; , &quot;Content-Type&quot;, &quot;multipart/form-data&quot;);
</span><span class="cx"> corsNoPreflight(&quot;Cross domain [GET] [Content-Type: text/plain]&quot;, host_info.HTTP_REMOTE_ORIGIN, &quot;GET&quot; , &quot;Content-Type&quot;, &quot;text/plain&quot;);
</span><span class="cx"> corsNoPreflight(&quot;Cross domain [GET] [Content-Type: text/plain;charset=utf-8]&quot;, host_info.HTTP_REMOTE_ORIGIN, &quot;GET&quot; , &quot;Content-Type&quot;, &quot;text/plain;charset=utf-8&quot;);
</span><ins>+corsNoPreflight(&quot;Cross domain [GET] [Content-Type: Text/Plain;charset=utf-8]&quot;, host_info.HTTP_REMOTE_ORIGIN, &quot;GET&quot; , &quot;Content-Type&quot;, &quot;Text/Plain;charset=utf-8&quot;);
</ins><span class="cx"> 
</span><span class="cx"> done();
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestsfetchapicorscorspreflightredirectworkerexpectedtxt"></a>
<div class="delfile"><h4>Deleted: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight-redirect-worker-expected.txt (203898 => 203899)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight-redirect-worker-expected.txt        2016-07-29 09:58:41 UTC (rev 203898)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight-redirect-worker-expected.txt        2016-07-29 11:08:04 UTC (rev 203899)
</span><span class="lines">@@ -1,12 +0,0 @@
</span><del>-
-PASS Redirection 301 on preflight failed 
-PASS Redirection 301 after preflight failed 
-PASS Redirection 302 on preflight failed 
-PASS Redirection 302 after preflight failed 
-PASS Redirection 303 on preflight failed 
-PASS Redirection 303 after preflight failed 
-PASS Redirection 307 on preflight failed 
-PASS Redirection 307 after preflight failed 
-PASS Redirection 308 on preflight failed 
-PASS Redirection 308 after preflight failed 
-
</del></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestsfetchapicorscorspreflightworkerexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight-worker-expected.txt (203898 => 203899)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight-worker-expected.txt        2016-07-29 09:58:41 UTC (rev 203898)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight-worker-expected.txt        2016-07-29 11:08:04 UTC (rev 203899)
</span><span class="lines">@@ -7,10 +7,10 @@
</span><span class="cx"> PASS CORS [PATCH], server refuses 
</span><span class="cx"> PASS CORS [NEW], server allows 
</span><span class="cx"> PASS CORS [NEW], server refuses 
</span><del>-PASS CORS [GET] [x-test-header: allowed], server allows 
</del><ins>+FAIL CORS [GET] [x-test-header: allowed], server allows assert_equals: Access-Control-Allow-Headers value expected &quot;x-test-header1&quot; but got &quot;referer,x-test-header1&quot;
</ins><span class="cx"> PASS CORS [GET] [x-test-header: refused], server refuses 
</span><del>-PASS CORS [GET] [several headers], server allows 
</del><ins>+FAIL CORS [GET] [several headers], server allows assert_equals: Access-Control-Allow-Headers value expected &quot;content-type,x-test-header-a,x-test-header-b,x-test-header-c,x-test-header-d,x-test-header1,x-test-header2,x-test-header3&quot; but got &quot;content-type,referer,x-test-header-a,x-test-header-b,x-test-header-c,x-test-header-d,x-test-header1,x-test-header2,x-test-header3&quot;
</ins><span class="cx"> PASS CORS [GET] [several headers], server refuses 
</span><del>-PASS CORS [PUT] [several headers], server allows 
</del><ins>+FAIL CORS [PUT] [several headers], server allows assert_equals: Access-Control-Allow-Headers value expected &quot;content-type,x-test-header-a,x-test-header-b,x-test-header-c,x-test-header-d,x-test-header1,x-test-header2,x-test-header3&quot; but got &quot;content-type,referer,x-test-header-a,x-test-header-b,x-test-header-c,x-test-header-d,x-test-header1,x-test-header2,x-test-header3&quot;
</ins><span class="cx"> PASS CORS [PUT] [several headers], server refuses 
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestsfetchapicorscorspreflightworkerhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight-worker.html (203898 => 203899)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight-worker.html        2016-07-29 09:58:41 UTC (rev 203898)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight-worker.html        2016-07-29 11:08:04 UTC (rev 203899)
</span><span class="lines">@@ -14,7 +14,7 @@
</span><span class="cx">   &lt;/head&gt;
</span><span class="cx">   &lt;body&gt;
</span><span class="cx">     &lt;script&gt;
</span><del>-      fetch_tests_from_worker(new Worker(&quot;cors-preflight.js?pipe=sub&quot;));
</del><ins>+      fetch_tests_from_worker(new Worker(&quot;cors-preflight.js&quot;));
</ins><span class="cx">     &lt;/script&gt;
</span><span class="cx">   &lt;/body&gt;
</span><del>-&lt;/html&gt;
</del><span class="cx">\ No newline at end of file
</span><ins>+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestsfetchapicorscorspreflighthtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight.html (203898 => 203899)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight.html        2016-07-29 09:58:41 UTC (rev 203898)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight.html        2016-07-29 11:08:04 UTC (rev 203899)
</span><span class="lines">@@ -14,7 +14,8 @@
</span><span class="cx">   &lt;/head&gt;
</span><span class="cx">   &lt;body&gt;
</span><span class="cx">     &lt;script src=&quot;../resources/utils.js&quot;&gt;&lt;/script&gt;
</span><ins>+    &lt;script src=&quot;../resources/get-host-info.sub.js&quot;&gt;&lt;/script&gt;
</ins><span class="cx">     &lt;script src=&quot;/common/utils.js&quot;&gt;&lt;/script&gt;
</span><del>-    &lt;script src=&quot;cors-preflight.js?pipe=sub&quot;&gt;&lt;/script&gt;
</del><ins>+    &lt;script src=&quot;cors-preflight.js&quot;&gt;&lt;/script&gt;
</ins><span class="cx">   &lt;/body&gt;
</span><del>-&lt;/html&gt;
</del><span class="cx">\ No newline at end of file
</span><ins>+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestsfetchapicorscorspreflightjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight.js (203898 => 203899)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight.js        2016-07-29 09:58:41 UTC (rev 203898)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight.js        2016-07-29 11:08:04 UTC (rev 203899)
</span><span class="lines">@@ -1,15 +1,24 @@
</span><span class="cx"> if (this.document === undefined) {
</span><span class="cx">   importScripts(&quot;/resources/testharness.js&quot;);
</span><ins>+  importScripts(&quot;/common/utils.js&quot;);
</ins><span class="cx">   importScripts(&quot;../resources/utils.js&quot;);
</span><del>-  importScripts(&quot;/common/utils.js&quot;);
</del><ins>+  importScripts(&quot;../resources/get-host-info.sub.js&quot;);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+function headerNames(headers)
+{
+    let names = [];
+    for (let header of headers)
+        names.push(header[0].toLowerCase());
+    return names
+}
+
</ins><span class="cx"> /*
</span><span class="cx">   Check preflight is done
</span><span class="cx">   Control if server allows method and headers and check accordingly
</span><span class="cx">   Check control access headers added by UA (for method and headers)
</span><span class="cx"> */
</span><del>-function corsPreflight(desc, corsUrl, method, allowed, headers) {
</del><ins>+function corsPreflight(desc, corsUrl, method, allowed, headers, safeHeaders) {
</ins><span class="cx">   return promise_test(function(test) {
</span><span class="cx">     var uuid_token = token();
</span><span class="cx">     return fetch(RESOURCES_DIR + &quot;clean-stash.py?token=&quot; + uuid_token).then(function(response) {
</span><span class="lines">@@ -16,8 +25,12 @@
</span><span class="cx">       var url = corsUrl;
</span><span class="cx">       var urlParameters = &quot;?token=&quot; + uuid_token + &quot;&amp;max_age=0&quot;;
</span><span class="cx">       var requestInit = {&quot;mode&quot;: &quot;cors&quot;, &quot;method&quot;: method};
</span><ins>+      var requestHeaders = [];
</ins><span class="cx">       if (headers)
</span><del>-        requestInit[&quot;headers&quot;] = headers;
</del><ins>+        requestHeaders.push.apply(requestHeaders, headers);
+      if (safeHeaders)
+        requestHeaders.push.apply(requestHeaders, safeHeaders);
+      requestInit[&quot;headers&quot;] = requestHeaders;
</ins><span class="cx"> 
</span><span class="cx">       if (allowed) {
</span><span class="cx">         urlParameters += &quot;&amp;allow_methods=&quot; + method;
</span><span class="lines">@@ -26,20 +39,22 @@
</span><span class="cx">           //Server will send back headers from Access-Control-Request-Headers in x-control-request-headers
</span><span class="cx">           urlParameters += &quot;&amp;control_request_headers&quot;
</span><span class="cx">           //Make the server allow the headers
</span><del>-          urlParameters += &quot;&amp;allow_headers=&quot;
-          urlParameters += headers.map(function (x) { return x[0]; }).join(&quot;%2C%20&quot;);
</del><ins>+          urlParameters += &quot;&amp;allow_headers=&quot; + headerNames(headers).join(&quot;%20%2C&quot;);
</ins><span class="cx">         }
</span><span class="cx">         return fetch(url + urlParameters, requestInit).then(function(resp) {
</span><span class="cx">           assert_equals(resp.status, 200, &quot;Response's status is 200&quot;);
</span><span class="cx">           assert_equals(resp.headers.get(&quot;x-did-preflight&quot;), &quot;1&quot;, &quot;Preflight request has been made&quot;);
</span><span class="cx">           if (headers) {
</span><del>-            var actualHeaders = resp.headers.get(&quot;x-control-request-headers&quot;).split(&quot;,&quot;);
</del><ins>+            var actualHeaders = resp.headers.get(&quot;x-control-request-headers&quot;).toLowerCase().split(&quot;,&quot;);
</ins><span class="cx">             for (var i in actualHeaders)
</span><span class="cx">               actualHeaders[i] = actualHeaders[i].trim();
</span><span class="cx">             for (var header of headers)
</span><del>-              assert_in_array(header[0], actualHeaders, &quot;Preflight asked permission for header: &quot; + header);
</del><ins>+              assert_in_array(header[0].toLowerCase(), actualHeaders, &quot;Preflight asked permission for header: &quot; + header);
+
+            let accessControlAllowHeaders = headerNames(headers).sort().join(&quot;,&quot;);
+            assert_equals(resp.headers.get(&quot;x-control-request-headers&quot;).replace(new RegExp(&quot; &quot;, &quot;g&quot;), &quot;&quot;), accessControlAllowHeaders, &quot;Access-Control-Allow-Headers value&quot;);
+            return fetch(RESOURCES_DIR + &quot;clean-stash.py?token=&quot; + uuid_token);
</ins><span class="cx">           }
</span><del>-          return fetch(RESOURCES_DIR + &quot;clean-stash.py?token=&quot; + uuid_token);
</del><span class="cx">         });
</span><span class="cx">       } else {
</span><span class="cx">         return promise_rejects(test, new TypeError(), fetch(url + urlParameters, requestInit)).then(function(){
</span><span class="lines">@@ -50,7 +65,7 @@
</span><span class="cx">   }, desc);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-var corsUrl = &quot;http://{{host}}:{{ports[http][1]}}&quot; + dirname(location.pathname) + RESOURCES_DIR + &quot;preflight.py&quot;;
</del><ins>+var corsUrl = get_host_info().HTTP_REMOTE_ORIGIN + dirname(location.pathname) + RESOURCES_DIR + &quot;preflight.py&quot;;
</ins><span class="cx"> 
</span><span class="cx"> corsPreflight(&quot;CORS [DELETE], server allows&quot;, corsUrl, &quot;DELETE&quot;, true);
</span><span class="cx"> corsPreflight(&quot;CORS [DELETE], server refuses&quot;, corsUrl, &quot;DELETE&quot;, false);
</span><span class="lines">@@ -64,12 +79,25 @@
</span><span class="cx"> corsPreflight(&quot;CORS [GET] [x-test-header: allowed], server allows&quot;, corsUrl, &quot;GET&quot;, true, [[&quot;x-test-header1&quot;, &quot;allowed&quot;]]);
</span><span class="cx"> corsPreflight(&quot;CORS [GET] [x-test-header: refused], server refuses&quot;, corsUrl, &quot;GET&quot;, false, [[&quot;x-test-header1&quot;, &quot;refused&quot;]]);
</span><span class="cx"> 
</span><del>-var headers = [[&quot;x-test-header1&quot;, &quot;allowedOrRefused&quot;],
-               [&quot;x-test-header2&quot;, &quot;allowedOrRefused&quot;],
-               [&quot;x-test-header3&quot;, &quot;allowedOrRefused&quot;]];
-corsPreflight(&quot;CORS [GET] [several headers], server allows&quot;, corsUrl, &quot;GET&quot;, true, headers);
-corsPreflight(&quot;CORS [GET] [several headers], server refuses&quot;, corsUrl, &quot;GET&quot;, false, headers);
-corsPreflight(&quot;CORS [PUT] [several headers], server allows&quot;, corsUrl, &quot;PUT&quot;, true, headers);
-corsPreflight(&quot;CORS [PUT] [several headers], server refuses&quot;, corsUrl, &quot;PUT&quot;, false, headers);
</del><ins>+var headers = [
+    [&quot;x-test-header1&quot;, &quot;allowedOrRefused&quot;],
+    [&quot;x-test-header2&quot;, &quot;allowedOrRefused&quot;],
+    [&quot;X-test-header3&quot;, &quot;allowedOrRefused&quot;],
+    [&quot;x-test-header-b&quot;, &quot;allowedOrRefused&quot;],
+    [&quot;x-test-header-D&quot;, &quot;allowedOrRefused&quot;],
+    [&quot;x-test-header-C&quot;, &quot;allowedOrRefused&quot;],
+    [&quot;x-test-header-a&quot;, &quot;allowedOrRefused&quot;],
+    [&quot;Content-Type&quot;, &quot;allowedOrRefused&quot;],
+];
+var safeHeaders= [
+    [&quot;Accept&quot;, &quot;*&quot;],
+    [&quot;Accept-Language&quot;, &quot;bzh&quot;],
+    [&quot;Content-Language&quot;, &quot;eu&quot;],
+];
</ins><span class="cx"> 
</span><ins>+corsPreflight(&quot;CORS [GET] [several headers], server allows&quot;, corsUrl, &quot;GET&quot;, true, headers, safeHeaders);
+corsPreflight(&quot;CORS [GET] [several headers], server refuses&quot;, corsUrl, &quot;GET&quot;, false, headers, safeHeaders);
+corsPreflight(&quot;CORS [PUT] [several headers], server allows&quot;, corsUrl, &quot;PUT&quot;, true, headers, safeHeaders);
+corsPreflight(&quot;CORS [PUT] [several headers], server refuses&quot;, corsUrl, &quot;PUT&quot;, false, headers, safeHeaders);
+
</ins><span class="cx"> done();
</span></span></pre></div>
<a id="trunkLayoutTestsplatformiossimulatorwk2importedw3cwebplatformtestsfetchapicorscorsnopreflightexpectedtxtfromrev203898trunkLayoutTestsimportedw3cwebplatformtestsfetchapicorscorsnopreflightexpectedtxt"></a>
<div class="copfile"><h4>Copied: trunk/LayoutTests/platform/ios-simulator-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-no-preflight-expected.txt (from rev 203898, trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-no-preflight-expected.txt) (0 => 203899)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/ios-simulator-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-no-preflight-expected.txt                                (rev 0)
+++ trunk/LayoutTests/platform/ios-simulator-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-no-preflight-expected.txt        2016-07-29 11:08:04 UTC (rev 203899)
</span><span class="lines">@@ -0,0 +1,17 @@
</span><ins>+
+PASS Cross domain basic usage [GET] 
+PASS Same domain different port [GET] 
+PASS Cross domain different port [GET] 
+FAIL Cross domain different protocol [GET] promise_test: Unhandled rejection with value: object &quot;TypeError: Type error&quot;
+FAIL Same domain different protocol different port [GET] promise_test: Unhandled rejection with value: object &quot;TypeError: Type error&quot;
+PASS Cross domain [POST] 
+PASS Cross domain [HEAD] 
+PASS Cross domain [GET] [Accept: */*] 
+PASS Cross domain [GET] [Accept-Language: fr] 
+PASS Cross domain [GET] [Content-Language: fr] 
+PASS Cross domain [GET] [Content-Type: application/x-www-form-urlencoded] 
+PASS Cross domain [GET] [Content-Type: multipart/form-data] 
+PASS Cross domain [GET] [Content-Type: text/plain] 
+PASS Cross domain [GET] [Content-Type: text/plain;charset=utf-8] 
+PASS Cross domain [GET] [Content-Type: Text/Plain;charset=utf-8] 
+
</ins></span></pre></div>
<a id="trunkLayoutTestsplatformiossimulatorwk2importedw3cwebplatformtestsfetchapicorscorsnopreflightworkerexpectedtxtfromrev203898trunkLayoutTestsimportedw3cwebplatformtestsfetchapicorscorsnopreflightworkerexpectedtxt"></a>
<div class="copfile"><h4>Copied: trunk/LayoutTests/platform/ios-simulator-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-no-preflight-worker-expected.txt (from rev 203898, trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-no-preflight-worker-expected.txt) (0 => 203899)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/ios-simulator-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-no-preflight-worker-expected.txt                                (rev 0)
+++ trunk/LayoutTests/platform/ios-simulator-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-no-preflight-worker-expected.txt        2016-07-29 11:08:04 UTC (rev 203899)
</span><span class="lines">@@ -0,0 +1,17 @@
</span><ins>+
+PASS Cross domain basic usage [GET] 
+PASS Same domain different port [GET] 
+PASS Cross domain different port [GET] 
+FAIL Cross domain different protocol [GET] promise_test: Unhandled rejection with value: object &quot;TypeError: Type error&quot;
+FAIL Same domain different protocol different port [GET] promise_test: Unhandled rejection with value: object &quot;TypeError: Type error&quot;
+PASS Cross domain [POST] 
+PASS Cross domain [HEAD] 
+PASS Cross domain [GET] [Accept: */*] 
+PASS Cross domain [GET] [Accept-Language: fr] 
+PASS Cross domain [GET] [Content-Language: fr] 
+PASS Cross domain [GET] [Content-Type: application/x-www-form-urlencoded] 
+PASS Cross domain [GET] [Content-Type: multipart/form-data] 
+PASS Cross domain [GET] [Content-Type: text/plain] 
+PASS Cross domain [GET] [Content-Type: text/plain;charset=utf-8] 
+PASS Cross domain [GET] [Content-Type: Text/Plain;charset=utf-8] 
+
</ins></span></pre></div>
<a id="trunkLayoutTestsplatformmacTestExpectations"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/mac/TestExpectations (203898 => 203899)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac/TestExpectations        2016-07-29 09:58:41 UTC (rev 203898)
+++ trunk/LayoutTests/platform/mac/TestExpectations        2016-07-29 11:08:04 UTC (rev 203899)
</span><span class="lines">@@ -1425,5 +1425,3 @@
</span><span class="cx"> 
</span><span class="cx"> # rdar://problem/27475162
</span><span class="cx"> [ Sierra+ ] compositing/video/poster.html [ Pass ImageOnlyFailure ]
</span><del>-
-webkit.org/b/160056 imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight.html [ Pass Failure ]
</del></span></pre></div>
<a id="trunkLayoutTestsplatformmacwk2importedw3cwebplatformtestsfetchapicorscorsbasicworkerexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-basic-worker-expected.txt (203898 => 203899)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-basic-worker-expected.txt        2016-07-29 09:58:41 UTC (rev 203898)
+++ trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-basic-worker-expected.txt        2016-07-29 11:08:04 UTC (rev 203899)
</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="trunkLayoutTestsplatformmacwk2importedw3cwebplatformtestsfetchapicorscorsnopreflightexpectedtxtfromrev203898trunkLayoutTestsimportedw3cwebplatformtestsfetchapicorscorsnopreflightexpectedtxt"></a>
<div class="copfile"><h4>Copied: trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-no-preflight-expected.txt (from rev 203898, trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-no-preflight-expected.txt) (0 => 203899)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-no-preflight-expected.txt                                (rev 0)
+++ trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-no-preflight-expected.txt        2016-07-29 11:08:04 UTC (rev 203899)
</span><span class="lines">@@ -0,0 +1,17 @@
</span><ins>+
+PASS Cross domain basic usage [GET] 
+PASS Same domain different port [GET] 
+PASS Cross domain different port [GET] 
+FAIL Cross domain different protocol [GET] promise_test: Unhandled rejection with value: object &quot;TypeError: Type error&quot;
+FAIL Same domain different protocol different port [GET] promise_test: Unhandled rejection with value: object &quot;TypeError: Type error&quot;
+PASS Cross domain [POST] 
+PASS Cross domain [HEAD] 
+PASS Cross domain [GET] [Accept: */*] 
+PASS Cross domain [GET] [Accept-Language: fr] 
+PASS Cross domain [GET] [Content-Language: fr] 
+PASS Cross domain [GET] [Content-Type: application/x-www-form-urlencoded] 
+PASS Cross domain [GET] [Content-Type: multipart/form-data] 
+PASS Cross domain [GET] [Content-Type: text/plain] 
+PASS Cross domain [GET] [Content-Type: text/plain;charset=utf-8] 
+PASS Cross domain [GET] [Content-Type: Text/Plain;charset=utf-8] 
+
</ins></span></pre></div>
<a id="trunkLayoutTestsplatformmacwk2importedw3cwebplatformtestsfetchapicorscorsnopreflightworkerexpectedtxtfromrev203898trunkLayoutTestsimportedw3cwebplatformtestsfetchapicorscorsnopreflightworkerexpectedtxt"></a>
<div class="copfile"><h4>Copied: trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-no-preflight-worker-expected.txt (from rev 203898, trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-no-preflight-worker-expected.txt) (0 => 203899)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-no-preflight-worker-expected.txt                                (rev 0)
+++ trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-no-preflight-worker-expected.txt        2016-07-29 11:08:04 UTC (rev 203899)
</span><span class="lines">@@ -0,0 +1,17 @@
</span><ins>+
+PASS Cross domain basic usage [GET] 
+PASS Same domain different port [GET] 
+PASS Cross domain different port [GET] 
+FAIL Cross domain different protocol [GET] promise_test: Unhandled rejection with value: object &quot;TypeError: Type error&quot;
+FAIL Same domain different protocol different port [GET] promise_test: Unhandled rejection with value: object &quot;TypeError: Type error&quot;
+PASS Cross domain [POST] 
+PASS Cross domain [HEAD] 
+PASS Cross domain [GET] [Accept: */*] 
+PASS Cross domain [GET] [Accept-Language: fr] 
+PASS Cross domain [GET] [Content-Language: fr] 
+PASS Cross domain [GET] [Content-Type: application/x-www-form-urlencoded] 
+PASS Cross domain [GET] [Content-Type: multipart/form-data] 
+PASS Cross domain [GET] [Content-Type: text/plain] 
+PASS Cross domain [GET] [Content-Type: text/plain;charset=utf-8] 
+PASS Cross domain [GET] [Content-Type: Text/Plain;charset=utf-8] 
+
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (203898 => 203899)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-07-29 09:58:41 UTC (rev 203898)
+++ trunk/Source/WebCore/ChangeLog        2016-07-29 11:08:04 UTC (rev 203899)
</span><span class="lines">@@ -1,3 +1,31 @@
</span><ins>+2016-07-29  Youenn Fablet  &lt;youenn@apple.com&gt;
+
+        CrossOrigin preflight checker should compute the right Access-Control-Request-Headers value
+        https://bugs.webkit.org/show_bug.cgi?id=160028
+
+        Reviewed by Alex Christensen.
+
+        Covered by updated test.
+
+        Computing Access-Control-Request-Headers value according https://fetch.spec.whatwg.org/#cors-preflight-fetch:
+        - Remove safe headers
+        - lowercase header names
+        - sort lexicographically header names
+        The only difference is that we keep separating headers with ', ' instead of ',' as per the spec.
+        Also, some headers that might be safe are still marked as unsafe (DPR, Downlink...).
+
+        Moved setting of Origin header after preflighting, consistently with fetch spec.
+
+        * loader/CrossOriginAccessControl.cpp:
+        (WebCore::createAccessControlPreflightRequest): Implementing new computation of Access-Control-Request-Headers.
+        * loader/DocumentThreadableLoader.cpp:
+        (WebCore::DocumentThreadableLoader::makeCrossOriginAccessRequest): Removing call to updateRequestForAccessControl (which sets Origin header value).
+        (WebCore::DocumentThreadableLoader::makeSimpleCrossOriginAccessRequest): Adding call to updateRequestForAccessControl.
+        (WebCore::DocumentThreadableLoader::preflightSuccess): Ditto.
+        * platform/network/HTTPParsers.cpp:
+        (WebCore::isCrossOriginSafeRequestHeader): Helper routine to implement https://fetch.spec.whatwg.org/#cors-safelisted-request-header.
+        * platform/network/HTTPParsers.h:
+
</ins><span class="cx"> 2016-07-29  Frederic Wang  &lt;fwang@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Parse the operator text on the MathMLOperatorElement class.
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderCrossOriginAccessControlcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/CrossOriginAccessControl.cpp (203898 => 203899)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/CrossOriginAccessControl.cpp        2016-07-29 09:58:41 UTC (rev 203898)
+++ trunk/Source/WebCore/loader/CrossOriginAccessControl.cpp        2016-07-29 11:08:04 UTC (rev 203899)
</span><span class="lines">@@ -116,19 +116,29 @@
</span><span class="cx">     const HTTPHeaderMap&amp; requestHeaderFields = request.httpHeaderFields();
</span><span class="cx"> 
</span><span class="cx">     if (!requestHeaderFields.isEmpty()) {
</span><ins>+        Vector&lt;String&gt; unsafeHeaders;
+        for (const auto&amp; headerField : requestHeaderFields.commonHeaders()) {
+            if (!isCrossOriginSafeRequestHeader(headerField.key, headerField.value))
+                unsafeHeaders.append(httpHeaderNameString(headerField.key).toStringWithoutCopying().convertToASCIILowercase());
+        }
+        for (const auto&amp; headerField : requestHeaderFields.uncommonHeaders())
+            unsafeHeaders.append(headerField.key.convertToASCIILowercase());
+
+        std::sort(unsafeHeaders.begin(), unsafeHeaders.end(), WTF::codePointCompareLessThan);
+
</ins><span class="cx">         StringBuilder headerBuffer;
</span><del>-        
</del><ins>+
</ins><span class="cx">         bool appendComma = false;
</span><del>-        for (const auto&amp; headerField : requestHeaderFields) {
</del><ins>+        for (const auto&amp; headerField : unsafeHeaders) {
+            // FIXME: header names should be separated by 0x2C, without space.
</ins><span class="cx">             if (appendComma)
</span><span class="cx">                 headerBuffer.appendLiteral(&quot;, &quot;);
</span><span class="cx">             else
</span><span class="cx">                 appendComma = true;
</span><del>-            
-            headerBuffer.append(headerField.key);
</del><ins>+
+            headerBuffer.append(headerField);
</ins><span class="cx">         }
</span><del>-
-        preflightRequest.setHTTPHeaderField(HTTPHeaderName::AccessControlRequestHeaders, headerBuffer.toString().convertToASCIILowercase());
</del><ins>+        preflightRequest.setHTTPHeaderField(HTTPHeaderName::AccessControlRequestHeaders, headerBuffer.toString());
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     return preflightRequest;
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderDocumentThreadableLoadercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/DocumentThreadableLoader.cpp (203898 => 203899)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/DocumentThreadableLoader.cpp        2016-07-29 09:58:41 UTC (rev 203898)
+++ trunk/Source/WebCore/loader/DocumentThreadableLoader.cpp        2016-07-29 11:08:04 UTC (rev 203899)
</span><span class="lines">@@ -113,17 +113,14 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(m_options.mode == FetchOptions::Mode::Cors);
</span><span class="cx"> 
</span><del>-    auto crossOriginRequest = request;
-    updateRequestForAccessControl(crossOriginRequest, securityOrigin(), m_options.allowCredentials());
-
-    if ((m_options.preflightPolicy == ConsiderPreflight &amp;&amp; isSimpleCrossOriginAccessRequest(crossOriginRequest.httpMethod(), crossOriginRequest.httpHeaderFields())) || m_options.preflightPolicy == PreventPreflight)
-        makeSimpleCrossOriginAccessRequest(crossOriginRequest);
</del><ins>+    if ((m_options.preflightPolicy == ConsiderPreflight &amp;&amp; isSimpleCrossOriginAccessRequest(request.httpMethod(), request.httpHeaderFields())) || m_options.preflightPolicy == PreventPreflight)
+        makeSimpleCrossOriginAccessRequest(request);
</ins><span class="cx">     else {
</span><span class="cx">         m_simpleRequest = false;
</span><del>-        if (CrossOriginPreflightResultCache::singleton().canSkipPreflight(securityOrigin().toString(), crossOriginRequest.url(), m_options.allowCredentials(), crossOriginRequest.httpMethod(), crossOriginRequest.httpHeaderFields()))
-            preflightSuccess(WTFMove(crossOriginRequest));
</del><ins>+        if (CrossOriginPreflightResultCache::singleton().canSkipPreflight(securityOrigin().toString(), request.url(), m_options.allowCredentials(), request.httpMethod(), request.httpHeaderFields()))
+            preflightSuccess(ResourceRequest(request));
</ins><span class="cx">         else
</span><del>-            makeCrossOriginAccessRequestWithPreflight(WTFMove(crossOriginRequest));
</del><ins>+            makeCrossOriginAccessRequestWithPreflight(ResourceRequest(request));
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -138,7 +135,9 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    loadRequest(request, DoSecurityCheck);
</del><ins>+    auto crossOriginRequest = request;
+    updateRequestForAccessControl(crossOriginRequest, securityOrigin(), m_options.allowCredentials());
+    loadRequest(crossOriginRequest, DoSecurityCheck);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void DocumentThreadableLoader::makeCrossOriginAccessRequestWithPreflight(ResourceRequest&amp;&amp; request)
</span><span class="lines">@@ -334,7 +333,7 @@
</span><span class="cx"> void DocumentThreadableLoader::preflightSuccess(ResourceRequest&amp;&amp; request)
</span><span class="cx"> {
</span><span class="cx">     ResourceRequest actualRequest(WTFMove(request));
</span><del>-    actualRequest.setHTTPOrigin(securityOrigin().toString());
</del><ins>+    updateRequestForAccessControl(actualRequest, securityOrigin(), m_options.allowCredentials());
</ins><span class="cx"> 
</span><span class="cx">     m_preflightChecker = Nullopt;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkHTTPParserscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/HTTPParsers.cpp (203898 => 203899)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/HTTPParsers.cpp        2016-07-29 09:58:41 UTC (rev 203898)
+++ trunk/Source/WebCore/platform/network/HTTPParsers.cpp        2016-07-29 11:08:04 UTC (rev 203899)
</span><span class="lines">@@ -854,4 +854,22 @@
</span><span class="cx">     return accessControlExposeHeaderSet.contains(name);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+// Implements https://fetch.spec.whatwg.org/#cors-safelisted-request-header
+bool isCrossOriginSafeRequestHeader(HTTPHeaderName name, const String&amp; value)
+{
+    switch (name) {
+    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:
+        // FIXME: Should we also make safe other headers (DPR, Downlink, Save-Data...)? That would require validating their values.
+        return false;
+    }
</ins><span class="cx"> }
</span><ins>+
+}
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkHTTPParsersh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/HTTPParsers.h (203898 => 203899)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/HTTPParsers.h        2016-07-29 09:58:41 UTC (rev 203898)
+++ trunk/Source/WebCore/platform/network/HTTPParsers.h        2016-07-29 11:08:04 UTC (rev 203899)
</span><span class="lines">@@ -109,6 +109,7 @@
</span><span class="cx"> bool isSimpleHeader(const String&amp; name, const String&amp; value);
</span><span class="cx"> bool isCrossOriginSafeHeader(HTTPHeaderName, const HTTPHeaderSet&amp;);
</span><span class="cx"> bool isCrossOriginSafeHeader(const String&amp;, const HTTPHeaderSet&amp;);
</span><ins>+bool isCrossOriginSafeRequestHeader(HTTPHeaderName, const String&amp;);
</ins><span class="cx"> 
</span><span class="cx"> inline bool isHTTPSpace(UChar character)
</span><span class="cx"> {
</span></span></pre>
</div>
</div>

</body>
</html>