Requests handled by Service Worker should not go through preflighting
https://bugs.webkit.org/show_bug.cgi?id=179250

Patch by Youenn Fablet <youenn@apple.com> on 2017-11-03
Reviewed by Alex Christensen.

Source/WebCore:

Test: http/tests/workers/service/service-worker-crossorigin-fetch.html
In case of cross origin requests needed preflighting that may be served through SW, the following is done:
- Bypass preflight
- Put service workers mode as Only so that if SW is not handling the request, the load will fail
- If load fails, restart DocumentThreadableLoader load with preflight.

Additional testing should be added when we properly handle the case where no fetch event handler is registered in the service worker.

* loader/DocumentThreadableLoader.cpp:
(WebCore::DocumentThreadableLoader::makeCrossOriginAccessRequest):
(WebCore::DocumentThreadableLoader::didFail):
* loader/DocumentThreadableLoader.h:
* loader/ResourceLoaderOptions.h:
* loader/cache/CachedResourceRequest.cpp:
(WebCore::CachedResourceRequest::setSelectedServiceWorkerIdentifierIfNeeded):
* platform/network/ResourceErrorBase.h:

Source/WebKit:

* WebProcess/Network/WebLoaderStrategy.cpp:
(WebKit::WebLoaderStrategy::scheduleLoad):
* WebProcess/Storage/WebSWClientConnection.cpp:
(WebKit::WebSWClientConnection::startFetch):
* WebProcess/Storage/WebServiceWorkerProvider.cpp:
(WebKit::shouldHandleFetch):

LayoutTests:

* http/tests/workers/service/resources/service-worker-crossorigin-fetch-worker.js: Added.
(event.event.request.url.indexOf):
(event.event.request.url.endsWith):
* http/tests/workers/service/resources/service-worker-crossorigin-fetch.js: Added.
(done):
(async.logStatus):
(async.test):
* http/tests/workers/service/service-worker-crossorigin-fetch-expected.txt: Added.
* http/tests/workers/service/service-worker-crossorigin-fetch.html: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@224439 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/loader/DocumentThreadableLoader.cpp b/Source/WebCore/loader/DocumentThreadableLoader.cpp
index 902c89e..65b7ae9 100644
--- a/Source/WebCore/loader/DocumentThreadableLoader.cpp
+++ b/Source/WebCore/loader/DocumentThreadableLoader.cpp
@@ -148,6 +148,17 @@
     if ((m_options.preflightPolicy == ConsiderPreflight && isSimpleCrossOriginAccessRequest(request.httpMethod(), request.httpHeaderFields())) || m_options.preflightPolicy == PreventPreflight)
         makeSimpleCrossOriginAccessRequest(WTFMove(request));
     else {
+#if ENABLE(SERVICE_WORKER)
+        if (m_options.serviceWorkersMode == ServiceWorkersMode::All && m_async) {
+            if (m_options.serviceWorkerIdentifier || document().activeServiceWorker()) {
+                ASSERT(!m_bypassingPreflightForServiceWorkerRequest);
+                m_bypassingPreflightForServiceWorkerRequest = WTFMove(request);
+                m_options.serviceWorkersMode = ServiceWorkersMode::Only;
+                loadRequest(ResourceRequest { m_bypassingPreflightForServiceWorkerRequest.value() }, SkipSecurityCheck);
+                return;
+            }
+        }
+#endif
         m_simpleRequest = false;
         if (CrossOriginPreflightResultCache::singleton().canSkipPreflight(securityOrigin().toString(), request.url(), m_options.storedCredentialsPolicy, request.httpMethod(), request.httpHeaderFields()))
             preflightSuccess(WTFMove(request));
@@ -392,6 +403,13 @@
 void DocumentThreadableLoader::didFail(unsigned long, const ResourceError& error)
 {
     ASSERT(m_client);
+#if ENABLE(SERVICE_WORKER)
+    if (m_bypassingPreflightForServiceWorkerRequest) {
+        m_options.serviceWorkersMode = ServiceWorkersMode::None;
+        makeCrossOriginAccessRequest(WTFMove(m_bypassingPreflightForServiceWorkerRequest.value()));
+        return;
+    }
+#endif
     logErrorAndFail(error);
 }