CachedResourceLoader is not taking into account fetch options to use or not cached resources
https://bugs.webkit.org/show_bug.cgi?id=161389

Patch by Youenn Fablet <youenn@apple.com> on 2016-09-06
Reviewed by Darin Adler.

LayoutTests/imported/w3c:

Updated as new console log messages appear now that cors checks are done at SubresourceLoader level.

* web-platform-tests/XMLHttpRequest/security-consideration.sub-expected.txt:
* web-platform-tests/fetch/api/cors/cors-basic-expected.txt:
* web-platform-tests/fetch/api/cors/cors-basic-worker-expected.txt:
* web-platform-tests/fetch/api/cors/cors-basic.js: Fixing a typo in the test making the test always passing, since the fetch promise was not taken into account.
* web-platform-tests/fetch/api/cors/cors-multiple-origins-expected.txt:
* web-platform-tests/fetch/api/cors/cors-multiple-origins-worker-expected.txt:
* web-platform-tests/fetch/api/cors/cors-origin-expected.txt:
* web-platform-tests/fetch/api/cors/cors-origin-worker-expected.txt:
* web-platform-tests/fetch/api/cors/cors-origin.js:
(corsOrigin): Fixing a typo in the test making the tests always passing, since the fetch promise was not taken into account.
* web-platform-tests/fetch/api/cors/cors-redirect-credentials-expected.txt:
* web-platform-tests/fetch/api/cors/cors-redirect-credentials-worker-expected.txt:

Source/WebCore:

Tests: http/tests/fetch/fetching-same-resource-with-diffferent-options.html
       http/tests/security/cross-origin-cached-resource-parallel.html
       http/tests/security/cross-origin-cached-resource.html
       http/tests/security/load-image-after-redirection-2.html
       http/tests/security/shape-outside-and-cached-resources.html

Adding CORS checks for the response in case of CORS fetch mode, in SubresourceLoader.
Removing the CORS checks in Image and DocumentThreadableLoader.

The direction of this patch is to make CachedResource origin-specific/fetch mode specific.

This will remove the need for CachedResource clients to do CORS checks when receiving the notifyFinished call.
This will also make the computation of whether a resource is clean or not much easier since the CachedResource knowd its origin and its response tainting.

Removing the CORS checks at ImageLoader creates the risk of using some cached resources loaded from previously no-cors mode without doing the actual CORS check.
Note that the risk was already there in case of a resource loaded through redirections.
Reusing a cached resource for a load with different options also leads to bad computation of the resource tainting.

As a first step, improvements are done but only for CachedImage resources.

This patch limits the direct reuse of cached resources as follow:
- If the request and existing resources have different origins.
- If the fetch mode is different between request and existing resource.

In those cases, a new CachedResource is created with the correct options and origin.
The data and response of the CachedResource found in the cache are copied efficiently in the new CachedResource, if the matching CachedResource finished loading (CachedImage specific).

If the matching CachedResource is still loading, we trigger a reload (with caching=false to not disturb the being loaded resource).
This should be made more efficient at some point, especially if the matching CachedResource already has its response set.

This triggers a change of behavior: previously, the CORS checks were done by the ImageLoader when the resource was finished loading.
The CORS checks were controlled by the crossOrigin attribute, which may be set or unset between the load start and the load end.

Now the crossOrigin attribute is checked at load start. If it is set, the CORS checks will happen even if the attribute is unset before the end of the load.
This is more consistent as the actual request was built with CORS enabled.

* loader/CrossOriginPreflightChecker.cpp:
(WebCore::CrossOriginPreflightChecker::startPreflight): Setting correctly the preflight options as per fetch spec.
* loader/DocumentThreadableLoader.cpp:
(WebCore::DocumentThreadableLoader::didReceiveResponse): Removing CORS check.
(WebCore::DocumentThreadableLoader::loadRequest): Adding CORS check in sync mode.
* loader/ImageLoader.cpp:
(WebCore::ImageLoader::updateFromElement):
(WebCore::ImageLoader::notifyFinished):
* loader/SubresourceLoader.cpp:
(WebCore::SubresourceLoader::didReceiveResponse): Adding CORS checks to the response
(WebCore::SubresourceLoader::checkResponseCrossOriginAccessControl): Helper routine to do CORS checks
* loader/SubresourceLoader.h:
* loader/cache/CachedImage.cpp:
(WebCore::CachedImage::cloneData): Responsible to set image content from another CachedImage.
* loader/cache/CachedImage.h:
* loader/cache/CachedResource.cpp:
(WebCore::CachedResource::computeOrigin): Helper routine to set the origin and whether the resource is cross-origin or not.
(WebCore::CachedResource::load): Using computeOrigin.
(WebCore::CachedResource::loadFrom): Loading from a CachedResource from the same type and which finished loading.
* loader/cache/CachedResource.h:
(WebCore::CachedResource::cloneData):
* loader/cache/CachedResourceLoader.cpp:
(WebCore::CachedResourceLoader::updateCachedResourceWithCurrentRequest): Helper routine responsible to adapt the CachedResource
that can be reused to the origin and options of a new request.
(WebCore::CachedResourceLoader::requestResource): Calling updateCachedResourceWithCurrentRequest before actually returning the resource.
(WebCore::CachedResourceLoader::determineRevalidationPolicy): Space clean-up.
* loader/cache/CachedResourceLoader.h:
* loader/cache/CachedResourceRequest.h:
(WebCore::CachedResourceRequest::setCachingPolicy):
* style/StylePendingResources.cpp:
(WebCore::Style::loadPendingImage): Allowing data URLs for ShapeOutside data.

LayoutTests:

Added specific expectations for fetch cors-origin* tests for mac-wk2 and ios-simulator-wk2 as these tests use
HTTPS, and the connection is refused.

* TestExpectations: Marking http/tests/security/contentSecurityPolicy/worker-csp-blocks-xhr-redirect-cross-origin.html as flaky.
* http/tests/eventsource/eventsource-cors-basic-expected.txt:
* http/tests/eventsource/eventsource-cors-with-credentials-expected.txt:
* http/tests/fetch/fetching-same-resource-with-diffferent-options-expected.txt: Added.
* http/tests/fetch/fetching-same-resource-with-diffferent-options.html: Added.
* http/tests/loading/cross-origin-XHR-willLoadRequest-expected.txt:
* http/tests/resources/download-json-with-delay.php:
* http/tests/resources/redirect.php:
* http/tests/security/cross-origin-cached-resource-expected.txt: Added.
* http/tests/security/cross-origin-cached-resource-parallel-expected.txt: Added.
* http/tests/security/cross-origin-cached-resource-parallel.html: Added.
* http/tests/security/cross-origin-cached-resource.html: Added.
* http/tests/security/img-with-failed-cors-check-fails-to-load-expected.txt:
* http/tests/security/load-image-after-redirection-2-expected.txt: Added.
* http/tests/security/load-image-after-redirection-2.html: Added.
* http/tests/security/resources/abe-allow-star.php:
* http/tests/security/resources/allow-if-origin.php: Added.
* http/tests/security/resources/cross-origin-cached-resource-iframe.html: Added.
* http/tests/security/resources/rgbalpha.png: Added.
* http/tests/security/shape-outside-and-cached-resources-expected.html: Added.
* http/tests/security/shape-outside-and-cached-resources.html: Added.
* http/tests/security/video-poster-cross-origin-crash-expected.txt:
* http/tests/security/video-poster-cross-origin-crash2-expected.txt:
* http/tests/xmlhttprequest/access-control-and-redirects-async-same-origin-expected.txt:
* http/tests/xmlhttprequest/access-control-repeated-failed-preflight-crash-expected.txt:
* http/tests/xmlhttprequest/cross-origin-no-authorization-expected.txt:
* http/tests/xmlhttprequest/cross-origin-no-credential-prompt-expected.txt:
* http/tests/xmlhttprequest/cross-site-denied-response-expected.txt:
* http/tests/xmlhttprequest/onerror-event-expected.txt:
* http/tests/xmlhttprequest/origin-whitelisting-https-expected.txt:
* http/tests/xmlhttprequest/origin-whitelisting-ip-addresses-with-subdomains-expected.txt:
* http/tests/xmlhttprequest/post-blob-content-type-async-expected.txt:
* http/tests/xmlhttprequest/redirect-cross-origin-2-expected.txt:
* http/tests/xmlhttprequest/redirect-cross-origin-expected.txt:
* http/tests/xmlhttprequest/simple-cross-origin-denied-events-expected.txt:
* http/tests/xmlhttprequest/simple-cross-origin-progress-events-expected.txt:
* http/tests/xmlhttprequest/xmlhttprequest-unsafe-redirect-expected.txt:
* platform/ios-simulator-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-basic-expected.txt:
* platform/ios-simulator-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-basic-worker-expected.txt:
* platform/ios-simulator-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-origin-expected.txt: Added.
* platform/ios-simulator-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-origin-worker-expected.txt: Added.
* platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-basic-expected.txt:
* platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-basic-worker-expected.txt:
* platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-origin-expected.txt: Added.
* platform/mac-wk2/imported/w3c/web-platform-tests/fetch/api/cors/cors-origin-worker-expected.txt: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@205473 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/loader/CrossOriginPreflightChecker.cpp b/Source/WebCore/loader/CrossOriginPreflightChecker.cpp
index 3447239..c2945a2 100644
--- a/Source/WebCore/loader/CrossOriginPreflightChecker.cpp
+++ b/Source/WebCore/loader/CrossOriginPreflightChecker.cpp
@@ -100,8 +100,8 @@
 
 void CrossOriginPreflightChecker::startPreflight()
 {
-    ResourceLoaderOptions options = static_cast<FetchOptions>(m_loader.options());
-    options.credentials = FetchOptions::Credentials::Omit;
+    ResourceLoaderOptions options;
+    options.referrerPolicy = m_loader.options().referrerPolicy;
     options.redirect = FetchOptions::Redirect::Manual;
 
     CachedResourceRequest preflightRequest(createAccessControlPreflightRequest(m_request, m_loader.securityOrigin()), options);