Diff
Modified: trunk/LayoutTests/ChangeLog (203814 => 203815)
--- trunk/LayoutTests/ChangeLog 2016-07-28 06:37:45 UTC (rev 203814)
+++ trunk/LayoutTests/ChangeLog 2016-07-28 08:30:14 UTC (rev 203815)
@@ -1,3 +1,24 @@
+2016-07-28 Youenn Fablet <[email protected]>
+
+ 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:
+
2016-07-27 Ryan Haddad <[email protected]>
Marking http/tests/loading/basic-credentials-sent-automatically.html as flaky on mac and ios-sim wk2
Modified: trunk/LayoutTests/http/tests/xmlhttprequest/access-control-basic-whitelist-response-headers-expected.txt (203814 => 203815)
--- 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)
@@ -1,4 +1,3 @@
-CONSOLE MESSAGE: line 25: Refused to get unsafe header "x-webkit"
PASS: Response header cache-control allowed.
PASS: Response header content-language allowed.
PASS: Response header content-type allowed.
Modified: trunk/LayoutTests/http/tests/xmlhttprequest/access-control-response-with-expose-headers-expected.txt (203814 => 203815)
--- 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)
@@ -1,4 +1,3 @@
-CONSOLE MESSAGE: line 1: Refused to get unsafe header "X-TEST"
Test for bug 41210: Cross Origin XMLHttpRequest can not expose headers indicated in Access-Control-Expose-Headers HTTP Response Header.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
Modified: trunk/LayoutTests/http/tests/xmlhttprequest/get-dangerous-headers-expected.txt (203814 => 203815)
--- 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)
@@ -1,7 +1,3 @@
-CONSOLE MESSAGE: line 15: Refused to get unsafe header "Set-Cookie"
-CONSOLE MESSAGE: line 17: Refused to get unsafe header "set-cookie"
-CONSOLE MESSAGE: line 19: Refused to get unsafe header "Set-Cookie2"
-CONSOLE MESSAGE: line 21: Refused to get unsafe header "set-cookie2"
Test that getResponseHeader and getAllResponseHeaders cannot be used to get the cookie header fields.
PASS
Modified: trunk/LayoutTests/http/tests/xmlhttprequest/getResponseHeader-expected.txt (203814 => 203815)
--- 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)
@@ -1,9 +1,3 @@
-CONSOLE MESSAGE: line 1: Refused to get unsafe header "SeT-COoKie"
-CONSOLE MESSAGE: line 1: Refused to get unsafe header "sEt-coOkIE2"
-CONSOLE MESSAGE: line 1: Refused to get unsafe header "SeT-COoKie"
-CONSOLE MESSAGE: line 1: Refused to get unsafe header "sEt-coOkIE2"
-CONSOLE MESSAGE: line 1: Refused to get unsafe header "SeT-COoKie"
-CONSOLE MESSAGE: line 1: Refused to get unsafe header "sEt-coOkIE2"
Test the required behavior of XMLHttpRequest.getResponseHeader()
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
Modified: trunk/LayoutTests/imported/w3c/ChangeLog (203814 => 203815)
--- 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)
@@ -1,3 +1,20 @@
+2016-07-28 Youenn Fablet <[email protected]>
+
+ 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:
+
2016-07-27 Chris Dumez <[email protected]>
First parameter to HTMLMediaElement.canPlayType() should be mandatory
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/XMLHttpRequest/getresponseheader-cookies-and-more-expected.txt (203814 => 203815)
--- 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)
@@ -1,9 +1,3 @@
-CONSOLE MESSAGE: line 23: Refused to get unsafe header "set-cookie"
-CONSOLE MESSAGE: line 24: Refused to get unsafe header "set-cookie2"
-CONSOLE MESSAGE: line 23: Refused to get unsafe header "set-cookie"
-CONSOLE MESSAGE: line 24: Refused to get unsafe header "set-cookie2"
-CONSOLE MESSAGE: line 23: Refused to get unsafe header "set-cookie"
-CONSOLE MESSAGE: line 24: Refused to get unsafe header "set-cookie2"
PASS XMLHttpRequest: getResponseHeader() custom/non-existent headers and cookies
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors-expected.txt (203814 => 203815)
--- 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)
@@ -1,6 +1,6 @@
PASS Fetch ../resources/top.txt with no-cors mode
PASS Fetch http://localhost:8800/fetch/api/resources/top.txt with no-cors mode
-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
+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
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors-worker-expected.txt (203814 => 203815)
--- 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)
@@ -1,6 +1,6 @@
PASS Fetch ../resources/top.txt with no-cors mode
PASS Fetch http://localhost:8800/fetch/api/resources/top.txt with no-cors mode
-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
+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
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-basic-expected.txt (203814 => 203815)
--- 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)
@@ -1,17 +1,17 @@
-FAIL Same domain different port [no-cors mode] assert_equals: Opaque filter: status is 0 expected 0 but got 200
+PASS Same domain different port [no-cors mode]
PASS Same domain different port [server forbid CORS]
-FAIL Same domain different port [cors mode] assert_equals: CORS response's type is cors expected "cors" but got "basic"
-FAIL Same domain different protocol different port [no-cors mode] assert_equals: Opaque filter: status is 0 expected 0 but got 200
+PASS Same domain different port [cors mode]
+PASS Same domain different protocol different port [no-cors mode]
PASS Same domain different protocol different port [server forbid CORS]
-FAIL Same domain different protocol different port [cors mode] assert_equals: CORS response's type is cors expected "cors" but got "basic"
-FAIL Cross domain basic usage [no-cors mode] assert_equals: Opaque filter: status is 0 expected 0 but got 200
+PASS Same domain different protocol different port [cors mode]
+PASS Cross domain basic usage [no-cors mode]
PASS Cross domain basic usage [server forbid CORS]
-FAIL Cross domain basic usage [cors mode] assert_equals: CORS response's type is cors expected "cors" but got "basic"
-FAIL Cross domain different port [no-cors mode] assert_equals: Opaque filter: status is 0 expected 0 but got 200
+PASS Cross domain basic usage [cors mode]
+PASS Cross domain different port [no-cors mode]
PASS Cross domain different port [server forbid CORS]
-FAIL Cross domain different port [cors mode] assert_equals: CORS response's type is cors expected "cors" but got "basic"
-FAIL Cross domain different protocol [no-cors mode] assert_equals: Opaque filter: status is 0 expected 0 but got 200
+PASS Cross domain different port [cors mode]
+PASS Cross domain different protocol [no-cors mode]
PASS Cross domain different protocol [server forbid CORS]
-FAIL Cross domain different protocol [cors mode] assert_equals: CORS response's type is cors expected "cors" but got "basic"
+PASS Cross domain different protocol [cors mode]
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-filtering-expected.txt (203814 => 203815)
--- 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)
@@ -1,20 +1,20 @@
-FAIL CORS filter on Cache-Control header assert_equals: CORS fetch's response has cors type expected "cors" but got "basic"
-FAIL CORS filter on Content-Language header assert_equals: CORS fetch's response has cors type expected "cors" but got "basic"
-FAIL CORS filter on Content-Type header assert_equals: CORS fetch's response has cors type expected "cors" but got "basic"
-FAIL CORS filter on Expires header assert_equals: CORS fetch's response has cors type expected "cors" but got "basic"
-FAIL CORS filter on Last-Modified header assert_equals: CORS fetch's response has cors type expected "cors" but got "basic"
-FAIL CORS filter on Pragma header assert_equals: CORS fetch's response has cors type expected "cors" but got "basic"
-FAIL CORS filter on Age header assert_equals: CORS fetch's response has cors type expected "cors" but got "basic"
-FAIL CORS filter on Server header assert_equals: CORS fetch's response has cors type expected "cors" but got "basic"
-FAIL CORS filter on Warning header assert_equals: CORS fetch's response has cors type expected "cors" but got "basic"
-FAIL CORS filter on Content-Length header assert_equals: CORS fetch's response has cors type expected "cors" but got "basic"
-FAIL CORS filter on Set-Cookie header assert_equals: CORS fetch's response has cors type expected "cors" but got "basic"
-FAIL CORS filter on Set-Cookie2 header assert_equals: CORS fetch's response has cors type expected "cors" but got "basic"
-FAIL CORS filter on Age header, header is exposed assert_equals: CORS fetch's response has cors type expected "cors" but got "basic"
-FAIL CORS filter on Server header, header is exposed assert_equals: CORS fetch's response has cors type expected "cors" but got "basic"
-FAIL CORS filter on Warning header, header is exposed assert_equals: CORS fetch's response has cors type expected "cors" but got "basic"
-FAIL CORS filter on Content-Length header, header is exposed assert_equals: CORS fetch's response has cors type expected "cors" but got "basic"
-FAIL CORS filter on Set-Cookie header, header is exposed assert_equals: CORS fetch's response has cors type expected "cors" but got "basic"
-FAIL CORS filter on Set-Cookie2 header, header is exposed assert_equals: CORS fetch's response has cors type expected "cors" but got "basic"
+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
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-cache-expected.txt (203814 => 203815)
--- 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)
@@ -37,12 +37,12 @@
PASS RequestCache "only-if-cached" (with "same-origin") does not follow redirects across origins and rejects with date and fresh response
PASS RequestCache "only-if-cached" (with "same-origin") does not follow redirects across origins and rejects with Etag and stale response
PASS RequestCache "only-if-cached" (with "same-origin") does not follow redirects across origins and rejects with date and stale response
-FAIL RequestCache "no-store" mode does not check the cache for previously cached content and goes to the network regardless with Etag and stale response assert_equals: expected (undefined) undefined but got (string) "\"0.5708867760543104\""
-FAIL RequestCache "no-store" mode does not check the cache for previously cached content and goes to the network regardless with date and stale response assert_equals: expected (undefined) undefined but got (string) "Tue, 26 Jul 2016 18:03:51 GMT"
+FAIL RequestCache "no-store" mode does not check the cache for previously cached content and goes to the network regardless with Etag and stale response assert_equals: expected (undefined) undefined but got (string) "\"0.5142751701087829\""
+FAIL RequestCache "no-store" mode does not check the cache for previously cached content and goes to the network regardless with date and stale response assert_equals: expected (undefined) undefined but got (string) "Wed, 27 Jul 2016 15:14:16 GMT"
FAIL RequestCache "no-store" mode does not check the cache for previously cached content and goes to the network regardless with Etag and fresh response assert_equals: expected 2 but got 1
FAIL RequestCache "no-store" mode does not check the cache for previously cached content and goes to the network regardless with date and fresh response assert_equals: expected 2 but got 1
-FAIL RequestCache "no-store" mode does not store the response in the cache with Etag and stale response assert_equals: expected (undefined) undefined but got (string) "\"0.03236160265570209\""
-FAIL RequestCache "no-store" mode does not store the response in the cache with date and stale response assert_equals: expected (undefined) undefined but got (string) "Tue, 26 Jul 2016 18:03:51 GMT"
+FAIL RequestCache "no-store" mode does not store the response in the cache with Etag and stale response assert_equals: expected (undefined) undefined but got (string) "\"0.8439838765231941\""
+FAIL RequestCache "no-store" mode does not store the response in the cache with date and stale response assert_equals: expected (undefined) undefined but got (string) "Wed, 27 Jul 2016 15:14:16 GMT"
FAIL RequestCache "no-store" mode does not store the response in the cache with Etag and fresh response assert_equals: expected 2 but got 1
FAIL RequestCache "no-store" mode does not store the response in the cache with date and fresh response assert_equals: expected 2 but got 1
PASS RequestCache "default" mode with an If-Modified-Since header is treated similarly to "no-store" with Etag and stale response
@@ -89,8 +89,8 @@
PASS Responses with the "Cache-Control: no-store" header are not stored in the cache with date and stale response
PASS Responses with the "Cache-Control: no-store" header are not stored in the cache with Etag and fresh response
PASS Responses with the "Cache-Control: no-store" header are not stored in the cache with date and fresh response
-FAIL RequestCache "reload" mode does not check the cache for previously cached content and goes to the network regardless with Etag and stale response assert_equals: expected (undefined) undefined but got (string) "\"0.32037580965802115\""
-FAIL RequestCache "reload" mode does not check the cache for previously cached content and goes to the network regardless with date and stale response assert_equals: expected (undefined) undefined but got (string) "Tue, 26 Jul 2016 18:03:51 GMT"
+FAIL RequestCache "reload" mode does not check the cache for previously cached content and goes to the network regardless with Etag and stale response assert_equals: expected (undefined) undefined but got (string) "\"0.7100561973865757\""
+FAIL RequestCache "reload" mode does not check the cache for previously cached content and goes to the network regardless with date and stale response assert_equals: expected (undefined) undefined but got (string) "Wed, 27 Jul 2016 15:14:16 GMT"
FAIL RequestCache "reload" mode does not check the cache for previously cached content and goes to the network regardless with Etag and fresh response assert_equals: expected 2 but got 1
FAIL RequestCache "reload" mode does not check the cache for previously cached content and goes to the network regardless with date and fresh response assert_equals: expected 2 but got 1
PASS RequestCache "reload" mode does store the response in the cache with Etag and stale response
@@ -97,8 +97,8 @@
PASS RequestCache "reload" mode does store the response in the cache with date and stale response
PASS RequestCache "reload" mode does store the response in the cache with Etag and fresh response
PASS RequestCache "reload" mode does store the response in the cache with date and fresh response
-FAIL RequestCache "reload" mode does store the response in the cache even if a previous response is already stored with Etag and stale response assert_equals: expected (undefined) undefined but got (string) "\"0.702774010433134\""
-FAIL RequestCache "reload" mode does store the response in the cache even if a previous response is already stored with date and stale response assert_equals: expected (undefined) undefined but got (string) "Tue, 26 Jul 2016 18:03:51 GMT"
+FAIL RequestCache "reload" mode does store the response in the cache even if a previous response is already stored with Etag and stale response assert_equals: expected (undefined) undefined but got (string) "\"0.45824924441966697\""
+FAIL RequestCache "reload" mode does store the response in the cache even if a previous response is already stored with date and stale response assert_equals: expected (undefined) undefined but got (string) "Wed, 27 Jul 2016 15:14:16 GMT"
FAIL RequestCache "reload" mode does store the response in the cache even if a previous response is already stored with Etag and fresh response assert_equals: expected 2 but got 1
FAIL RequestCache "reload" mode does store the response in the cache even if a previous response is already stored with date and fresh response assert_equals: expected 2 but got 1
Modified: trunk/LayoutTests/platform/ios-simulator-wk2/imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors-expected.txt (203814 => 203815)
--- 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)
@@ -2,5 +2,5 @@
PASS Fetch ../resources/top.txt with no-cors mode
PASS Fetch http://localhost:8800/fetch/api/resources/top.txt with no-cors mode
FAIL Fetch https://localhost:9443/fetch/api/resources/top.txt with no-cors mode promise_test: Unhandled rejection with value: object "TypeError: Type error"
-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
+PASS Fetch http://localhost:8801/fetch/api/resources/top.txt with no-cors mode
Modified: trunk/LayoutTests/platform/ios-simulator-wk2/imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors-worker-expected.txt (203814 => 203815)
--- 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)
@@ -2,5 +2,5 @@
PASS Fetch ../resources/top.txt with no-cors mode
PASS Fetch http://localhost:8800/fetch/api/resources/top.txt with no-cors mode
FAIL Fetch https://localhost:9443/fetch/api/resources/top.txt with no-cors mode promise_test: Unhandled rejection with value: object "TypeError: Type error"
-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
+PASS Fetch http://localhost:8801/fetch/api/resources/top.txt with no-cors mode
Modified: trunk/LayoutTests/platform/ios-simulator-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-basic-expected.txt (203814 => 203815)
--- 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)
@@ -1,16 +1,16 @@
-FAIL Same domain different port [no-cors mode] assert_equals: Opaque filter: status is 0 expected 0 but got 200
+PASS Same domain different port [no-cors mode]
PASS Same domain different port [server forbid CORS]
-FAIL Same domain different port [cors mode] assert_equals: CORS response's type is cors expected "cors" but got "basic"
+PASS Same domain different port [cors mode]
FAIL Same domain different protocol different port [no-cors mode] promise_test: Unhandled rejection with value: object "TypeError: Type error"
PASS Same domain different protocol different port [server forbid CORS]
FAIL Same domain different protocol different port [cors mode] promise_test: Unhandled rejection with value: object "TypeError: Type error"
-FAIL Cross domain basic usage [no-cors mode] assert_equals: Opaque filter: status is 0 expected 0 but got 200
+PASS Cross domain basic usage [no-cors mode]
PASS Cross domain basic usage [server forbid CORS]
-FAIL Cross domain basic usage [cors mode] assert_equals: CORS response's type is cors expected "cors" but got "basic"
-FAIL Cross domain different port [no-cors mode] assert_equals: Opaque filter: status is 0 expected 0 but got 200
+PASS Cross domain basic usage [cors mode]
+PASS Cross domain different port [no-cors mode]
PASS Cross domain different port [server forbid CORS]
-FAIL Cross domain different port [cors mode] assert_equals: CORS response's type is cors expected "cors" but got "basic"
+PASS Cross domain different port [cors mode]
FAIL Cross domain different protocol [no-cors mode] promise_test: Unhandled rejection with value: object "TypeError: Type error"
PASS Cross domain different protocol [server forbid CORS]
FAIL Cross domain different protocol [cors mode] promise_test: Unhandled rejection with value: object "TypeError: Type error"
Modified: trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors-expected.txt (203814 => 203815)
--- 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)
@@ -2,5 +2,5 @@
PASS Fetch ../resources/top.txt with no-cors mode
PASS Fetch http://localhost:8800/fetch/api/resources/top.txt with no-cors mode
FAIL Fetch https://localhost:9443/fetch/api/resources/top.txt with no-cors mode promise_test: Unhandled rejection with value: object "TypeError: Type error"
-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
+PASS Fetch http://localhost:8801/fetch/api/resources/top.txt with no-cors mode
Modified: trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/basic/mode-no-cors-worker-expected.txt (203814 => 203815)
--- 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)
@@ -2,5 +2,5 @@
PASS Fetch ../resources/top.txt with no-cors mode
PASS Fetch http://localhost:8800/fetch/api/resources/top.txt with no-cors mode
FAIL Fetch https://localhost:9443/fetch/api/resources/top.txt with no-cors mode promise_test: Unhandled rejection with value: object "TypeError: Type error"
-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
+PASS Fetch http://localhost:8801/fetch/api/resources/top.txt with no-cors mode
Modified: trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-basic-expected.txt (203814 => 203815)
--- 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)
@@ -1,16 +1,16 @@
-FAIL Same domain different port [no-cors mode] assert_equals: Opaque filter: status is 0 expected 0 but got 200
+PASS Same domain different port [no-cors mode]
PASS Same domain different port [server forbid CORS]
-FAIL Same domain different port [cors mode] assert_equals: CORS response's type is cors expected "cors" but got "basic"
+PASS Same domain different port [cors mode]
FAIL Same domain different protocol different port [no-cors mode] promise_test: Unhandled rejection with value: object "TypeError: Type error"
PASS Same domain different protocol different port [server forbid CORS]
FAIL Same domain different protocol different port [cors mode] promise_test: Unhandled rejection with value: object "TypeError: Type error"
-FAIL Cross domain basic usage [no-cors mode] assert_equals: Opaque filter: status is 0 expected 0 but got 200
+PASS Cross domain basic usage [no-cors mode]
PASS Cross domain basic usage [server forbid CORS]
-FAIL Cross domain basic usage [cors mode] assert_equals: CORS response's type is cors expected "cors" but got "basic"
-FAIL Cross domain different port [no-cors mode] assert_equals: Opaque filter: status is 0 expected 0 but got 200
+PASS Cross domain basic usage [cors mode]
+PASS Cross domain different port [no-cors mode]
PASS Cross domain different port [server forbid CORS]
-FAIL Cross domain different port [cors mode] assert_equals: CORS response's type is cors expected "cors" but got "basic"
+PASS Cross domain different port [cors mode]
FAIL Cross domain different protocol [no-cors mode] promise_test: Unhandled rejection with value: object "TypeError: Type error"
PASS Cross domain different protocol [server forbid CORS]
FAIL Cross domain different protocol [cors mode] promise_test: Unhandled rejection with value: object "TypeError: Type error"
Modified: trunk/Source/WebCore/ChangeLog (203814 => 203815)
--- 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)
@@ -1,3 +1,77 @@
+2016-07-28 Youenn Fablet <[email protected]>
+
+ 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&&.
+
+ * 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.
+
2016-07-27 Romain Bellessort <[email protected]>
[Streams API] Use makeThisTypeError in ReadableStreamDefaultReader.js
Modified: trunk/Source/WebCore/Modules/fetch/FetchHeaders.cpp (203814 => 203815)
--- 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)
@@ -36,64 +36,6 @@
namespace WebCore {
-// FIXME: Optimize these routines for HTTPHeaderMap keys and/or refactor them with XMLHttpRequest code.
-static bool isForbiddenHeaderName(const String& 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, "sec-") || startsWithLettersIgnoringASCIICase(name, "proxy-");
-}
-
-static bool isForbiddenResponseHeaderName(const String& name)
-{
- return equalLettersIgnoringASCIICase(name, "set-cookie") || equalLettersIgnoringASCIICase(name, "set-cookie2");
-}
-
-static bool isSimpleHeader(const String& name, const String& 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, "application/x-www-form-urlencoded") || equalLettersIgnoringASCIICase(mimeType, "multipart/form-data") || equalLettersIgnoringASCIICase(mimeType, "text/plain");
- }
- default:
- return false;
- }
-}
-
static bool canWriteHeader(const String& name, const String& value, FetchHeaders::Guard guard, ExceptionCode& ec)
{
if (!isValidHTTPToken(name) || !isValidHTTPHeaderValue(value)) {
Modified: trunk/Source/WebCore/loader/CrossOriginAccessControl.cpp (203814 => 203815)
--- 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)
@@ -180,15 +180,4 @@
return true;
}
-void parseAccessControlExposeHeadersAllowList(const String& headerValue, HTTPHeaderSet& headerSet)
-{
- Vector<String> headers;
- headerValue.split(',', false, headers);
- for (auto& header : headers) {
- String strippedHeader = header.stripWhiteSpace();
- if (!strippedHeader.isEmpty())
- headerSet.add(strippedHeader);
- }
-}
-
} // namespace WebCore
Modified: trunk/Source/WebCore/loader/CrossOriginAccessControl.h (203814 => 203815)
--- 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)
@@ -29,13 +29,9 @@
#include "ResourceHandleTypes.h"
#include <wtf/Forward.h>
-#include <wtf/HashSet.h>
-#include <wtf/text/StringHash.h>
namespace WebCore {
-typedef HashSet<String, ASCIICaseInsensitiveHash> HTTPHeaderSet;
-
class HTTPHeaderMap;
enum class HTTPHeaderName;
class ResourceRequest;
@@ -55,7 +51,6 @@
void cleanRedirectedRequestForAccessControl(ResourceRequest&);
bool passesAccessControlCheck(const ResourceResponse&, StoredCredentials, SecurityOrigin&, String& errorDescription);
-void parseAccessControlExposeHeadersAllowList(const String& headerValue, HTTPHeaderSet&);
} // namespace WebCore
Modified: trunk/Source/WebCore/loader/DocumentThreadableLoader.cpp (203814 => 203815)
--- 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)
@@ -268,10 +268,10 @@
void DocumentThreadableLoader::responseReceived(CachedResource* resource, const ResourceResponse& response)
{
ASSERT_UNUSED(resource, resource == m_resource);
- didReceiveResponse(m_resource->identifier(), response);
+ didReceiveResponse(m_resource->identifier(), response, m_resource->responseTainting());
}
-void DocumentThreadableLoader::didReceiveResponse(unsigned long identifier, const ResourceResponse& response)
+void DocumentThreadableLoader::didReceiveResponse(unsigned long identifier, const ResourceResponse& response, ResourceResponse::Tainting tainting)
{
ASSERT(m_client);
@@ -283,7 +283,16 @@
}
}
- m_client->didReceiveResponse(identifier, response);
+ 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 && tainting == ResourceResponse::Tainting::Opaque)
+ tainting = ResourceResponse::Tainting::Cors;
+ m_client->didReceiveResponse(identifier, ResourceResponse::filterResponse(response, tainting));
+ } else {
+ ASSERT(response.isNull() && response.type() == ResourceResponse::Type::Opaqueredirect);
+ m_client->didReceiveResponse(identifier, response);
+ }
}
void DocumentThreadableLoader::dataReceived(CachedResource* resource, const char* data, int dataLength)
@@ -386,7 +395,7 @@
if (requestURL.isLocalFile()) {
// We don't want XMLHttpRequest to raise an exception for file:// resources, see <rdar://problem/4962298>.
// FIXME: XMLHttpRequest quirks should be in XMLHttpRequest code, not in DocumentThreadableLoader.cpp.
- didReceiveResponse(identifier, response);
+ didReceiveResponse(identifier, response, ResourceResponse::Tainting::Basic);
didFinishLoading(identifier, 0.0);
return;
}
@@ -409,7 +418,10 @@
}
}
- didReceiveResponse(identifier, response);
+ 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);
if (data)
didReceiveData(identifier, data->data(), data->size());
Modified: trunk/Source/WebCore/loader/DocumentThreadableLoader.h (203814 => 203815)
--- 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)
@@ -32,6 +32,7 @@
#define DocumentThreadableLoader_h
#include "CrossOriginPreflightChecker.h"
+#include "ResourceResponse.h"
#include "SecurityOrigin.h"
#include "ThreadableLoader.h"
@@ -81,7 +82,7 @@
void redirectReceived(CachedResource*, ResourceRequest&, const ResourceResponse&) override;
void notifyFinished(CachedResource*) override;
- void didReceiveResponse(unsigned long identifier, const ResourceResponse&);
+ void didReceiveResponse(unsigned long identifier, const ResourceResponse&, ResourceResponse::Tainting);
void didReceiveData(unsigned long identifier, const char* data, int dataLength);
void didFinishLoading(unsigned long identifier, double finishTime);
void didFail(unsigned long identifier, const ResourceError&);
Modified: trunk/Source/WebCore/loader/SubresourceLoader.cpp (203814 => 203815)
--- 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)
@@ -6,13 +6,13 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
+ * documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
+ * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@@ -151,8 +151,10 @@
// FIXME: https://bugs.webkit.org/show_bug.cgi?id=155633.
// SubresourceLoader could use the document origin as a default and set PotentiallyCrossOriginEnabled requests accordingly.
// This would simplify resource loader users as they would only need to set fetch mode to Cors.
- if (options().mode == FetchOptions::Mode::Cors)
- m_origin = SecurityOrigin::createFromString(request.httpOrigin());
+ m_origin = m_resource->origin();
+ // https://fetch.spec.whatwg.org/#main-fetch, step 11, data URL here is considered not cross origin.
+ if (!request.url().protocolIsData() && m_origin && !m_origin->canRequest(request.url()))
+ m_resource->setCrossOrigin();
return true;
}
@@ -180,8 +182,10 @@
cancel();
return;
}
- m_resource->setOpaqueRedirect();
- m_resource->responseReceived({ });
+
+ ResourceResponse opaqueRedirectedResponse;
+ opaqueRedirectedResponse.setType(ResourceResponse::Type::Opaqueredirect);
+ m_resource->responseReceived(opaqueRedirectedResponse);
didFinishLoading(currentTime());
return;
}
@@ -202,7 +206,7 @@
return;
}
- if (options().mode == FetchOptions::Mode::Cors && !checkCrossOriginAccessControl(request(), redirectResponse, newRequest)) {
+ if (!checkRedirectionCrossOriginAccessControl(request(), redirectResponse, newRequest)) {
cancel();
return;
}
@@ -295,8 +299,8 @@
// The resource data will change as the next part is loaded, so we need to make a copy.
m_resource->finishLoading(buffer->copy().ptr());
clearResourceData();
- // 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 "finished"
+ // 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 "finished"
m_documentLoader->subresourceLoaderFinishedLoadingOnePart(this);
didFinishLoadingOnePart(0);
}
@@ -396,11 +400,19 @@
frame->page()->diagnosticLoggingClient().logDiagnosticMessageWithValue(DiagnosticLoggingKeys::resourceKey(), DiagnosticLoggingKeys::loadedKey(), resourceType, ShouldSample::Yes);
}
-bool SubresourceLoader::checkCrossOriginAccessControl(const ResourceRequest& previousRequest, const ResourceResponse& redirectResponse, ResourceRequest& newRequest)
+bool SubresourceLoader::checkRedirectionCrossOriginAccessControl(const ResourceRequest& previousRequest, const ResourceResponse& redirectResponse, ResourceRequest& newRequest)
{
- if (m_origin->canRequest(newRequest.url()))
+ ASSERT(options().mode != FetchOptions::Mode::SameOrigin);
+
+ bool shouldCheckCrossOrigin = options().mode == FetchOptions::Mode::Cors && m_resource->isCrossOrigin();
+
+ if (!(m_origin && m_origin->canRequest(newRequest.url())))
+ m_resource->setCrossOrigin();
+
+ if (!shouldCheckCrossOrigin)
return true;
+ ASSERT(m_origin);
String errorDescription;
bool responsePassesCORS = m_origin->canRequest(previousRequest.url())
|| passesAccessControlCheck(redirectResponse, options().allowCredentials(), *m_origin, errorDescription);
Modified: trunk/Source/WebCore/loader/SubresourceLoader.h (203814 => 203815)
--- 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)
@@ -6,13 +6,13 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
+ * documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
+ * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@@ -91,7 +91,7 @@
#endif
bool checkForHTTPStatusCodeError();
- bool checkCrossOriginAccessControl(const ResourceRequest&, const ResourceResponse&, ResourceRequest& newRequest);
+ bool checkRedirectionCrossOriginAccessControl(const ResourceRequest&, const ResourceResponse&, ResourceRequest& newRequest);
void didReceiveDataOrBuffer(const char*, int, RefPtr<SharedBuffer>&&, long long encodedDataLength, DataPayloadType);
Modified: trunk/Source/WebCore/loader/cache/CachedResource.cpp (203814 => 203815)
--- 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)
@@ -281,7 +281,14 @@
#endif
m_resourceRequest.setPriority(loadPriority());
- addAdditionalRequestHeaders(cachedResourceLoader);
+ if (type() != MainResource) {
+ if (m_resourceRequest.hasHTTPOrigin())
+ m_origin = SecurityOrigin::createFromString(m_resourceRequest.httpOrigin());
+ else
+ m_origin = cachedResourceLoader.document()->securityOrigin();
+ ASSERT(m_origin);
+ addAdditionalRequestHeaders(cachedResourceLoader);
+ }
// FIXME: It's unfortunate that the cache layer and below get to know anything about fragment identifiers.
// We should look into removing the expectation of that knowledge from the platform network stacks.
@@ -367,6 +374,23 @@
return passesAccessControlCheck(securityOrigin);
}
+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() && m_responseTainting != ResourceResponse::Tainting::Opaque;
+}
+
bool CachedResource::isExpired() const
{
if (m_response.isNull())
@@ -426,8 +450,8 @@
void CachedResource::setResponse(const ResourceResponse& response)
{
+ ASSERT(m_response.type() == ResourceResponse::Type::Default);
m_response = response;
- m_response.setType(m_responseType);
m_response.setRedirected(m_redirectChainCacheStatus.status != RedirectChainCacheStatus::NoRedirection);
m_varyingHeaderValues = collectVaryingRequestHeaders(m_resourceRequest, m_response, m_sessionID);
Modified: trunk/Source/WebCore/loader/cache/CachedResource.h (203814 => 203815)
--- 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)
@@ -200,11 +200,17 @@
virtual void responseReceived(const ResourceResponse&);
virtual bool shouldCacheResponse(const ResourceResponse&) { return true; }
void setResponse(const ResourceResponse&);
- void setOpaqueRedirect() { m_responseType = ResourceResponseBase::Type::Opaqueredirect; }
const ResourceResponse& response() const { return m_response; }
// This is the same as response() except after HTTP redirect to data: URL.
const ResourceResponse& responseForSameOriginPolicyChecks() const;
+ void setCrossOrigin();
+ bool isCrossOrigin() const;
+ bool isClean() const;
+ ResourceResponse::Tainting responseTainting() const { return m_responseTainting; }
+
+ SecurityOrigin* origin() const { return m_origin.get(); }
+
bool canDelete() const { return !hasClients() && !m_loader && !m_preloadCount && !m_handleCount && !m_resourceToRevalidate && !m_proxyResource; }
bool hasOneHandle() const { return m_handleCount == 1; }
@@ -224,7 +230,7 @@
DataBufferingPolicy dataBufferingPolicy() const { return m_options.dataBufferingPolicy(); }
bool allowsCaching() const { return m_options.cachingPolicy() == CachingPolicy::AllowCaching; }
-
+
virtual void destroyDecodedData() { }
void setOwningCachedResourceLoader(CachedResourceLoader* cachedResourceLoader) { m_owningCachedResourceLoader = cachedResourceLoader; }
@@ -284,7 +290,7 @@
RefPtr<SubresourceLoader> m_loader;
ResourceLoaderOptions m_options;
ResourceResponse m_response;
- ResourceResponseBase::Type m_responseType { ResourceResponseBase::Type::Basic };
+ ResourceResponse::Tainting m_responseTainting { ResourceResponse::Tainting::Basic };
ResourceResponse m_redirectResponseForSameOriginPolicyChecks;
RefPtr<SharedBuffer> m_data;
DeferrableOneShotTimer m_decodedDataDeletionTimer;
@@ -313,6 +319,7 @@
String m_fragmentIdentifierForRequest;
ResourceError m_error;
+ RefPtr<SecurityOrigin> m_origin;
double m_lastDecodedAccessTime; // Used as a "thrash guard" in the cache
double m_loadFinishTime;
Modified: trunk/Source/WebCore/platform/network/HTTPParsers.cpp (203814 => 203815)
--- 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)
@@ -33,6 +33,7 @@
#include "config.h"
#include "HTTPParsers.h"
+#include "HTTPHeaderNames.h"
#include <wtf/DateMath.h>
#include <wtf/NeverDestroyed.h>
#include <wtf/text/CString.h>
@@ -755,4 +756,102 @@
return length;
}
+void parseAccessControlExposeHeadersAllowList(const String& headerValue, HTTPHeaderSet& headerSet)
+{
+ Vector<String> headers;
+ headerValue.split(',', false, headers);
+ for (auto& header : headers) {
+ String strippedHeader = header.stripWhiteSpace();
+ if (!strippedHeader.isEmpty())
+ headerSet.add(strippedHeader);
+ }
}
+
+// Implememtnation of https://fetch.spec.whatwg.org/#cors-safelisted-response-header-name
+bool isForbiddenHeaderName(const String& 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, "sec-") || startsWithLettersIgnoringASCIICase(name, "proxy-");
+}
+
+bool isForbiddenResponseHeaderName(const String& name)
+{
+ return equalLettersIgnoringASCIICase(name, "set-cookie") || equalLettersIgnoringASCIICase(name, "set-cookie2");
+}
+
+bool isSimpleHeader(const String& name, const String& 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, "application/x-www-form-urlencoded") || equalLettersIgnoringASCIICase(mimeType, "multipart/form-data") || equalLettersIgnoringASCIICase(mimeType, "text/plain");
+ }
+ default:
+ return false;
+ }
+}
+
+bool isCrossOriginSafeHeader(HTTPHeaderName name, const HTTPHeaderSet& 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& name, const HTTPHeaderSet& accessControlExposeHeaderSet)
+{
+#ifndef ASSERT_DISABLED
+ HTTPHeaderName headerName;
+ ASSERT(!findHTTPHeaderName(name, headerName));
+#endif
+ return accessControlExposeHeaderSet.contains(name);
+}
+
+}
Modified: trunk/Source/WebCore/platform/network/HTTPParsers.h (203814 => 203815)
--- 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)
@@ -32,12 +32,18 @@
#define HTTPParsers_h
#include <wtf/Forward.h>
+#include <wtf/HashSet.h>
#include <wtf/Optional.h>
#include <wtf/Vector.h>
+#include <wtf/text/StringHash.h>
#include <wtf/text/WTFString.h>
namespace WebCore {
+typedef HashSet<String, ASCIICaseInsensitiveHash> HTTPHeaderSet;
+
+enum class HTTPHeaderName;
+
enum class XSSProtectionDisposition {
Invalid,
Disabled,
@@ -95,6 +101,15 @@
size_t parseHTTPHeader(const char* data, size_t length, String& failureReason, StringView& nameStr, String& valueStr, bool strict = true);
size_t parseHTTPRequestBody(const char* data, size_t length, Vector<unsigned char>& body);
+void parseAccessControlExposeHeadersAllowList(const String& headerValue, HTTPHeaderSet&);
+
+// HTTP Header routine as per https://fetch.spec.whatwg.org/#terminology-headers
+bool isForbiddenHeaderName(const String&);
+bool isForbiddenResponseHeaderName(const String&);
+bool isSimpleHeader(const String& name, const String& value);
+bool isCrossOriginSafeHeader(HTTPHeaderName, const HTTPHeaderSet&);
+bool isCrossOriginSafeHeader(const String&, const HTTPHeaderSet&);
+
inline bool isHTTPSpace(UChar character)
{
return character <= ' ' && (character == ' ' || character == '\n' || character == '\t' || character == '\r');
Modified: trunk/Source/WebCore/platform/network/ResourceRequestBase.cpp (203814 => 203815)
--- 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)
@@ -313,9 +313,14 @@
setHTTPHeaderField(HTTPHeaderName::Origin, httpOrigin);
}
+bool ResourceRequestBase::hasHTTPOrigin() const
+{
+ return m_httpHeaderFields.contains(HTTPHeaderName::Origin);
+}
+
void ResourceRequestBase::clearHTTPOrigin()
{
- updateResourceRequest();
+ updateResourceRequest();
m_httpHeaderFields.remove(HTTPHeaderName::Origin);
Modified: trunk/Source/WebCore/platform/network/ResourceRequestBase.h (203814 => 203815)
--- 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)
@@ -22,7 +22,7 @@
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ResourceRequestBase_h
@@ -100,8 +100,9 @@
WEBCORE_EXPORT String httpReferrer() const;
WEBCORE_EXPORT void setHTTPReferrer(const String&);
WEBCORE_EXPORT void clearHTTPReferrer();
-
+
String httpOrigin() const;
+ bool hasHTTPOrigin() const;
void setHTTPOrigin(const String&);
WEBCORE_EXPORT void clearHTTPOrigin();
Modified: trunk/Source/WebCore/platform/network/ResourceResponseBase.cpp (203814 => 203815)
--- 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)
@@ -99,6 +99,40 @@
return response;
}
+ResourceResponse ResourceResponseBase::filterResponse(const ResourceResponse& 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([&](auto& entry) {
+ return !isCrossOriginSafeHeader(entry.key, accessControlExposeHeaderSet);
+ });
+ filteredResponse.m_httpHeaderFields.commonHeaders().removeIf([&](auto& entry) {
+ return !isCrossOriginSafeHeader(entry.key, accessControlExposeHeaderSet);
+ });
+
+ return filteredResponse;
+}
+
// FIXME: Name does not make it clear this is true for HTTPS!
bool ResourceResponseBase::isHTTP() const
{
@@ -111,7 +145,7 @@
{
lazyInit(CommonFieldsOnly);
- return m_url;
+ return m_url;
}
void ResourceResponseBase::setURL(const URL& url)
Modified: trunk/Source/WebCore/platform/network/ResourceResponseBase.h (203814 => 203815)
--- 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)
@@ -65,6 +65,9 @@
CrossThreadData crossThreadData() const;
static ResourceResponse fromCrossThreadData(CrossThreadData&&);
+ enum class Tainting { Basic, Cors, Opaque };
+ static ResourceResponse filterResponse(const ResourceResponse&, Tainting);
+
bool isNull() const { return m_isNull; }
WEBCORE_EXPORT bool isHTTP() const;
bool isSuccessful() const;
Modified: trunk/Source/WebCore/xml/XMLHttpRequest.cpp (203814 => 203815)
--- 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)
@@ -75,11 +75,6 @@
XMLHttpRequestSendArrayBufferOrViewMax,
};
-static bool isSetCookieHeader(const String& name)
-{
- return equalLettersIgnoringASCIICase(name, "set-cookie") || equalLettersIgnoringASCIICase(name, "set-cookie2");
-}
-
static void replaceCharsetInMediaType(String& mediaType, const String& charsetValue)
{
unsigned pos = 0, len = 0;
@@ -906,22 +901,7 @@
StringBuilder stringBuilder;
- HTTPHeaderSet accessControlExposeHeaderSet;
- parseAccessControlExposeHeadersAllowList(m_response.httpHeaderField(HTTPHeaderName::AccessControlExposeHeaders), accessControlExposeHeaderSet);
-
for (const auto& header : m_response.httpHeaderFields()) {
- // 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) && !securityOrigin()->canLoadLocalResources())
- continue;
-
- if (!m_sameOriginRequest && !isOnAccessControlResponseHeaderWhitelist(header.key) && !accessControlExposeHeaderSet.contains(header.key))
- continue;
-
stringBuilder.append(header.key);
stringBuilder.append(':');
stringBuilder.append(' ');
@@ -938,19 +918,6 @@
if (m_state < HEADERS_RECEIVED || m_error)
return String();
- // See comment in getAllResponseHeaders above.
- if (isSetCookieHeader(name) && !securityOrigin()->canLoadLocalResources()) {
- logConsoleError(scriptExecutionContext(), "Refused to get unsafe header \"" + name + "\"");
- return String();
- }
-
- HTTPHeaderSet accessControlExposeHeaderSet;
- parseAccessControlExposeHeadersAllowList(m_response.httpHeaderField(HTTPHeaderName::AccessControlExposeHeaders), accessControlExposeHeaderSet);
-
- if (!m_sameOriginRequest && !isOnAccessControlResponseHeaderWhitelist(name) && !accessControlExposeHeaderSet.contains(name)) {
- logConsoleError(scriptExecutionContext(), "Refused to get unsafe header \"" + name + "\"");
- return String();
- }
return m_response.httpHeaderField(name);
}