Service Worker should not clean HTTP headers added by the application or by fetch...
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 19 Dec 2017 18:37:44 +0000 (18:37 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 19 Dec 2017 18:37:44 +0000 (18:37 +0000)
https://bugs.webkit.org/show_bug.cgi?id=180939

Patch by Youenn Fablet <youenn@apple.com> on 2017-12-19
Reviewed by Chris Dumez.

LayoutTests/imported/w3c:

* web-platform-tests/service-workers/service-worker/fetch-request-xhr.https-expected.txt:
* web-platform-tests/service-workers/service-worker/resources/fetch-request-xhr-iframe.https.html:
* web-platform-tests/service-workers/service-worker/fetch-header-visibility.https-expected.txt:

Source/WebCore:

Covered by modified WPT test.

Add support to clean only specific headers in cleanHTTPRequestHeadersForAccessControl,
renamed from cleanRedirectedRequestForAccessControl.
Compute the list of headers to keep in DocumentThreadableLoader.
Add a specific rule for Accept header which is set prior service worker interception and for
HTTP headers set by DocumentThreadableLoader clients.

* loader/CrossOriginAccessControl.cpp:
(WebCore::httpHeadersToKeepFromCleaning):
(WebCore::cleanRedirectedRequestForAccessControl):
* loader/CrossOriginAccessControl.h:
(WebCore::cleanRedirectedRequestForAccessControl):
* loader/DocumentThreadableLoader.cpp:
(WebCore::DocumentThreadableLoader::DocumentThreadableLoader):
* loader/ResourceLoaderOptions.h:
* workers/service/context/ServiceWorkerFetch.cpp:
(WebCore::ServiceWorkerFetch::dispatchFetchEvent):
* workers/service/context/ServiceWorkerFetch.h:
* workers/service/context/ServiceWorkerThread.cpp:
(WebCore::ServiceWorkerThread::postFetchTask):
* workers/service/context/ServiceWorkerThread.h:

Source/WebKit:

Passing referrer as an explicit parameter of StartFetch.

Cleaning request headers based on ResourceLoaderOptions.httpHeadersToKeep.

* StorageProcess/ServiceWorker/WebSWServerConnection.cpp:
(WebKit::WebSWServerConnection::startFetch):
* StorageProcess/ServiceWorker/WebSWServerConnection.h:
* StorageProcess/ServiceWorker/WebSWServerConnection.messages.in:
* WebProcess/Storage/ServiceWorkerClientFetch.cpp:
(WebKit::ServiceWorkerClientFetch::start):
* WebProcess/Storage/WebSWClientConnection.cpp:
(WebKit::WebSWClientConnection::startFetch):
* WebProcess/Storage/WebSWClientConnection.h:
* WebProcess/Storage/WebSWContextManagerConnection.cpp:
(WebKit::WebSWContextManagerConnection::startFetch):
* WebProcess/Storage/WebSWContextManagerConnection.h:
* WebProcess/Storage/WebSWContextManagerConnection.messages.in:

LayoutTests:

* TestExpectations:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@226126 268f45cc-cd09-0410-ab3c-d52691b4dbfc

26 files changed:
LayoutTests/ChangeLog
LayoutTests/TestExpectations
LayoutTests/imported/w3c/ChangeLog
LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-header-visibility.https-expected.txt
LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-xhr.https-expected.txt
LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-xhr-iframe.https.html
Source/WebCore/ChangeLog
Source/WebCore/loader/CrossOriginAccessControl.cpp
Source/WebCore/loader/CrossOriginAccessControl.h
Source/WebCore/loader/DocumentThreadableLoader.cpp
Source/WebCore/loader/ResourceLoaderOptions.h
Source/WebCore/loader/SubresourceLoader.cpp
Source/WebCore/workers/service/context/ServiceWorkerFetch.cpp
Source/WebCore/workers/service/context/ServiceWorkerFetch.h
Source/WebCore/workers/service/context/ServiceWorkerThread.cpp
Source/WebCore/workers/service/context/ServiceWorkerThread.h
Source/WebKit/ChangeLog
Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.cpp
Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.h
Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.messages.in
Source/WebKit/WebProcess/Storage/ServiceWorkerClientFetch.cpp
Source/WebKit/WebProcess/Storage/WebSWClientConnection.cpp
Source/WebKit/WebProcess/Storage/WebSWClientConnection.h
Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp
Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h
Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.messages.in

index a4bf05a..89d91c6 100644 (file)
@@ -1,3 +1,12 @@
+2017-12-19  Youenn Fablet  <youenn@apple.com>
+
+        Service Worker should not clean HTTP headers added by the application or by fetch specification before service worker interception
+        https://bugs.webkit.org/show_bug.cgi?id=180939
+
+        Reviewed by Chris Dumez.
+
+        * TestExpectations:
+
 2017-12-19  Chris Dumez  <cdumez@apple.com>
 
         Unreviewed, rebaseline service workers flaky tests.
index a2ea032..719ffa7 100644 (file)
@@ -175,7 +175,6 @@ imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tain
 webkit.org/b/179248 imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-within-sw.https.html [ Pass Failure ]
 imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-respond-with-response-body-with-invalid-chunk.https.html [ Pass Failure ]
 imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-redirect.https.html [ Pass Failure Timeout ]
-imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-xhr.https.html [ Pass Failure ]
 imported/w3c/web-platform-tests/service-workers/service-worker/multiple-update.https.html [ Pass Failure ]
 imported/w3c/web-platform-tests/service-workers/service-worker/performance-timeline.https.html [ Pass Failure ]
 imported/w3c/web-platform-tests/service-workers/service-worker/registration-service-worker-attributes.https.html [ Pass Failure ]
index 9e3aefb..17290c4 100644 (file)
@@ -1,3 +1,14 @@
+2017-12-19  Youenn Fablet  <youenn@apple.com>
+
+        Service Worker should not clean HTTP headers added by the application or by fetch specification before service worker interception
+        https://bugs.webkit.org/show_bug.cgi?id=180939
+
+        Reviewed by Chris Dumez.
+
+        * web-platform-tests/service-workers/service-worker/fetch-request-xhr.https-expected.txt:
+        * web-platform-tests/service-workers/service-worker/resources/fetch-request-xhr-iframe.https.html:
+        * web-platform-tests/service-workers/service-worker/fetch-header-visibility.https-expected.txt:
+
 2017-12-19  Chris Dumez  <cdumez@apple.com>
 
         Unreviewed, rebaseline service workers flaky tests.
index fef5db6..a0667bb 100644 (file)
@@ -1,14 +1,14 @@
 
 PASS initialize global state 
 PASS event.request has the expected headers for same-origin GET. 
-FAIL event.request has the expected headers for same-origin POST. promise_test: Unhandled rejection with value: object "Error: assert_array_equals: event.request has the expected headers for same-origin POST. lengths differ, expected 2 got 1"
+PASS event.request has the expected headers for same-origin POST. 
 PASS event.request has the expected headers for cross-origin GET. 
-FAIL event.request has the expected headers for cross-origin POST. promise_test: Unhandled rejection with value: object "Error: assert_array_equals: event.request has the expected headers for cross-origin POST. lengths differ, expected 2 got 1"
+PASS event.request has the expected headers for cross-origin POST. 
 PASS FetchEvent#request.body contains XHR request data (string) 
 FAIL FetchEvent#request.body contains XHR request data (blob) promise_test: Unhandled rejection with value: object "Error: assert_equals: expected "test blob" but got """
 PASS FetchEvent#request.method is set to XHR method 
 PASS XHR using OPTIONS method 
-FAIL XHR with form data promise_test: Unhandled rejection with value: object "Error: assert_equals: expected "--\r\nContent-Disposition: form-data; name=\"sample string\"\r\n\r\n1234567890\r\n--\r\nContent-Disposition: form-data; name=\"sample blob\"; filename=\"blob\"\r\nContent-Type: application/octet-stream\r\n\r\nblob content\r\n--\r\nContent-Disposition: form-data; name=\"sample file\"; filename=\"file.dat\"\r\nContent-Type: application/octet-stream\r\n\r\nfile content\r\n----\r\n" but got """
+FAIL XHR with form data promise_test: Unhandled rejection with value: object "Error: assert_true: form data response content is as expected expected true got false"
 FAIL XHR with mode/credentials set promise_test: Unhandled rejection with value: object "Error: assert_equals: expected "include" but got "same-origin""
 PASS XHR to data URL 
 PASS restore global state 
index 867bf23..ab3e2a1 100644 (file)
@@ -179,7 +179,7 @@ function form_data_test() {
           '\r\n' +
           'file content\r\n' +
           '--' + boundary + '--\r\n';
-        assert_equals(response.body, expected_body);
+        assert_true(response.body === expected_body, "form data response content is as expected");
       });
 }
 
index 1dde104..48d5630 100644 (file)
@@ -1,3 +1,33 @@
+2017-12-19  Youenn Fablet  <youenn@apple.com>
+
+        Service Worker should not clean HTTP headers added by the application or by fetch specification before service worker interception
+        https://bugs.webkit.org/show_bug.cgi?id=180939
+
+        Reviewed by Chris Dumez.
+
+        Covered by modified WPT test.
+
+        Add support to clean only specific headers in cleanHTTPRequestHeadersForAccessControl,
+        renamed from cleanRedirectedRequestForAccessControl.
+        Compute the list of headers to keep in DocumentThreadableLoader.
+        Add a specific rule for Accept header which is set prior service worker interception and for
+        HTTP headers set by DocumentThreadableLoader clients.
+
+        * loader/CrossOriginAccessControl.cpp:
+        (WebCore::httpHeadersToKeepFromCleaning):
+        (WebCore::cleanRedirectedRequestForAccessControl):
+        * loader/CrossOriginAccessControl.h:
+        (WebCore::cleanRedirectedRequestForAccessControl):
+        * loader/DocumentThreadableLoader.cpp:
+        (WebCore::DocumentThreadableLoader::DocumentThreadableLoader):
+        * loader/ResourceLoaderOptions.h:
+        * workers/service/context/ServiceWorkerFetch.cpp:
+        (WebCore::ServiceWorkerFetch::dispatchFetchEvent):
+        * workers/service/context/ServiceWorkerFetch.h:
+        * workers/service/context/ServiceWorkerThread.cpp:
+        (WebCore::ServiceWorkerThread::postFetchTask):
+        * workers/service/context/ServiceWorkerThread.h:
+
 2017-12-19  Andy Estes  <aestes@apple.com>
 
         [Apple Pay] Stop maintaining a list of payment networks
index d7becee..c73ce0a 100644 (file)
@@ -116,14 +116,35 @@ bool isValidCrossOriginRedirectionURL(const URL& redirectURL)
         && redirectURL.pass().isEmpty();
 }
 
-void cleanRedirectedRequestForAccessControl(ResourceRequest& request)
+HTTPHeaderNameSet httpHeadersToKeepFromCleaning(const HTTPHeaderMap& headers)
+{
+    HTTPHeaderNameSet headersToKeep;
+    if (headers.contains(HTTPHeaderName::ContentType))
+        headersToKeep.add(HTTPHeaderName::ContentType);
+    if (headers.contains(HTTPHeaderName::Referer))
+        headersToKeep.add(HTTPHeaderName::Referer);
+    if (headers.contains(HTTPHeaderName::Origin))
+        headersToKeep.add(HTTPHeaderName::Origin);
+    if (headers.contains(HTTPHeaderName::UserAgent))
+        headersToKeep.add(HTTPHeaderName::UserAgent);
+    if (headers.contains(HTTPHeaderName::AcceptEncoding))
+        headersToKeep.add(HTTPHeaderName::AcceptEncoding);
+    return headersToKeep;
+}
+
+void cleanHTTPRequestHeadersForAccessControl(ResourceRequest& request, const HashSet<HTTPHeaderName, WTF::IntHash<HTTPHeaderName>, WTF::StrongEnumHashTraits<HTTPHeaderName>>& headersToKeep)
 {
     // Remove headers that may have been added by the network layer that cause access control to fail.
-    request.clearHTTPContentType();
-    request.clearHTTPReferrer();
-    request.clearHTTPOrigin();
-    request.clearHTTPUserAgent();
-    request.clearHTTPAcceptEncoding();
+    if (!headersToKeep.contains(HTTPHeaderName::ContentType))
+        request.clearHTTPContentType();
+    if (!headersToKeep.contains(HTTPHeaderName::Referer))
+        request.clearHTTPReferrer();
+    if (!headersToKeep.contains(HTTPHeaderName::Origin))
+        request.clearHTTPOrigin();
+    if (!headersToKeep.contains(HTTPHeaderName::UserAgent))
+        request.clearHTTPUserAgent();
+    if (!headersToKeep.contains(HTTPHeaderName::AcceptEncoding))
+        request.clearHTTPAcceptEncoding();
 }
 
 bool passesAccessControlCheck(const ResourceResponse& response, StoredCredentialsPolicy storedCredentialsPolicy, SecurityOrigin& securityOrigin, String& errorDescription)
index 68876e8..96832c6 100644 (file)
 
 #pragma once
 
+#include "HTTPHeaderNames.h"
 #include "StoredCredentialsPolicy.h"
 #include <wtf/Forward.h>
+#include <wtf/HashSet.h>
 
 namespace WebCore {
 
@@ -44,7 +46,10 @@ WEBCORE_EXPORT void updateRequestForAccessControl(ResourceRequest&, SecurityOrig
 WEBCORE_EXPORT ResourceRequest createAccessControlPreflightRequest(const ResourceRequest&, SecurityOrigin&, const String&);
 
 bool isValidCrossOriginRedirectionURL(const URL&);
-void cleanRedirectedRequestForAccessControl(ResourceRequest&);
+
+using HTTPHeaderNameSet = HashSet<HTTPHeaderName, WTF::IntHash<HTTPHeaderName>, WTF::StrongEnumHashTraits<HTTPHeaderName>>;
+HTTPHeaderNameSet httpHeadersToKeepFromCleaning(const HTTPHeaderMap&);
+WEBCORE_EXPORT void cleanHTTPRequestHeadersForAccessControl(ResourceRequest&, const HTTPHeaderNameSet& = { });
 
 WEBCORE_EXPORT bool passesAccessControlCheck(const ResourceResponse&, StoredCredentialsPolicy, SecurityOrigin&, String& errorDescription);
 WEBCORE_EXPORT bool validatePreflightResponse(const ResourceRequest&, const ResourceResponse&, StoredCredentialsPolicy, SecurityOrigin&, String& errorDescription);
index b70c864..345bdb5 100644 (file)
@@ -119,6 +119,11 @@ DocumentThreadableLoader::DocumentThreadableLoader(Document& document, Threadabl
     if (m_async && m_options.mode == FetchOptions::Mode::Cors)
         m_originalHeaders = request.httpHeaderFields();
 
+#if ENABLE(SERVICE_WORKER)
+    if (m_options.serviceWorkersMode == ServiceWorkersMode::All && m_async && (m_options.serviceWorkerIdentifier || document.activeServiceWorker()))
+        m_options.httpHeadersToKeep = httpHeadersToKeepFromCleaning(request.httpHeaderFields());
+#endif
+
     if (document.page() && document.page()->isRunningUserScripts() && SchemeRegistry::isUserExtensionScheme(request.url().protocol().toStringWithoutCopying())) {
         m_options.mode = FetchOptions::Mode::NoCors;
         m_options.filteringPolicy = ResponseFilteringPolicy::Disable;
index 676dbc7..a50439a 100644 (file)
 #pragma once
 
 #include "FetchOptions.h"
+#include "HTTPHeaderNames.h"
 #include "ServiceWorkerIdentifier.h"
 #include "StoredCredentialsPolicy.h"
+#include <wtf/HashSet.h>
 #include <wtf/Vector.h>
 #include <wtf/text/WTFString.h>
 
@@ -140,6 +142,10 @@ struct ResourceLoaderOptions : public FetchOptions {
     ServiceWorkersMode serviceWorkersMode { ServiceWorkersMode::All };
 #if ENABLE(SERVICE_WORKER)
     std::optional<ServiceWorkerIdentifier> serviceWorkerIdentifier;
+    // WebKit loading code is adding some HTTP headers between the application and the time service worker intercepts the fetch.
+    // We keep a list of these headers so that we only remove the ones that are set by the loading code and not by the application.
+    // FIXME: Remove this when service worker fetch interception happens before the setting of these headers in the loading code.
+    HashSet<HTTPHeaderName, WTF::IntHash<HTTPHeaderName>, WTF::StrongEnumHashTraits<HTTPHeaderName>> httpHeadersToKeep;
 #endif
 
     ClientCredentialPolicy clientCredentialPolicy { ClientCredentialPolicy::CannotAskClientForCredentials };
index 9958dfd..d5d4c2a 100644 (file)
@@ -542,7 +542,7 @@ bool SubresourceLoader::checkRedirectionCrossOriginAccessControl(const ResourceR
         m_origin = SecurityOrigin::createUnique();
 
     if (redirectingToNewOrigin) {
-        cleanRedirectedRequestForAccessControl(newRequest);
+        cleanHTTPRequestHeadersForAccessControl(newRequest);
         updateRequestForAccessControl(newRequest, *m_origin, options().storedCredentialsPolicy);
     }
 
index bc2743d..ec397b5 100644 (file)
@@ -91,18 +91,12 @@ static void processResponse(Ref<Client>&& client, FetchResponse* response)
     });
 }
 
-Ref<FetchEvent> dispatchFetchEvent(Ref<Client>&& client, WorkerGlobalScope& globalScope, std::optional<ServiceWorkerClientIdentifier> clientId, ResourceRequest&& request, FetchOptions&& options)
+Ref<FetchEvent> dispatchFetchEvent(Ref<Client>&& client, WorkerGlobalScope& globalScope, std::optional<ServiceWorkerClientIdentifier> clientId, ResourceRequest&& request, String&& referrer, FetchOptions&& options)
 {
     ASSERT(globalScope.isServiceWorkerGlobalScope());
 
-    auto httpReferrer = request.httpReferrer();
-    // We are intercepting fetch calls after going through the HTTP layer, which adds some specific headers.
-    // Let's clean them so that cross origin checks do not fail.
-    if (options.mode == FetchOptions::Mode::Cors)
-        cleanRedirectedRequestForAccessControl(request);
-
     auto requestHeaders = FetchHeaders::create(FetchHeaders::Guard::Immutable, HTTPHeaderMap { request.httpHeaderFields() });
-    auto fetchRequest = FetchRequest::create(globalScope, FetchBody::fromFormData(request.httpBody()), WTFMove(requestHeaders),  WTFMove(request), WTFMove(options), WTFMove(httpReferrer));
+    auto fetchRequest = FetchRequest::create(globalScope, FetchBody::fromFormData(request.httpBody()), WTFMove(requestHeaders),  WTFMove(request), WTFMove(options), WTFMove(referrer));
 
     FetchEvent::Init init;
     init.request = WTFMove(fetchRequest);
index 70670e7..7c94be7 100644 (file)
@@ -54,7 +54,7 @@ public:
     virtual void didNotHandle() = 0;
 };
 
-Ref<FetchEvent> dispatchFetchEvent(Ref<Client>&&, WorkerGlobalScope&, std::optional<ServiceWorkerClientIdentifier>, ResourceRequest&&, FetchOptions&&);
+Ref<FetchEvent> dispatchFetchEvent(Ref<Client>&&, WorkerGlobalScope&, std::optional<ServiceWorkerClientIdentifier>, ResourceRequest&&, String&& referrer, FetchOptions&&);
 };
 
 } // namespace WebCore
index d20ffc6..daa2096 100644 (file)
@@ -91,13 +91,13 @@ void ServiceWorkerThread::runEventLoop()
     WorkerThread::runEventLoop();
 }
 
-void ServiceWorkerThread::postFetchTask(Ref<ServiceWorkerFetch::Client>&& client, std::optional<ServiceWorkerClientIdentifier>&& clientId, ResourceRequest&& request, FetchOptions&& options)
+void ServiceWorkerThread::postFetchTask(Ref<ServiceWorkerFetch::Client>&& client, std::optional<ServiceWorkerClientIdentifier>&& clientId, ResourceRequest&& request, String&& referrer, FetchOptions&& options)
 {
     // FIXME: instead of directly using runLoop(), we should be using something like WorkerGlobalScopeProxy.
     // FIXME: request and options come straigth from IPC so are already isolated. We should be able to take benefit of that.
-    runLoop().postTaskForMode([client = WTFMove(client), clientId, request = request.isolatedCopy(), options = options.isolatedCopy()] (ScriptExecutionContext& context) mutable {
+    runLoop().postTaskForMode([client = WTFMove(client), clientId, request = request.isolatedCopy(), referrer = referrer.isolatedCopy(), options = options.isolatedCopy()] (ScriptExecutionContext& context) mutable {
         auto& serviceWorkerGlobalScope = downcast<ServiceWorkerGlobalScope>(context);
-        auto fetchEvent = ServiceWorkerFetch::dispatchFetchEvent(WTFMove(client), serviceWorkerGlobalScope, clientId, WTFMove(request), WTFMove(options));
+        auto fetchEvent = ServiceWorkerFetch::dispatchFetchEvent(WTFMove(client), serviceWorkerGlobalScope, clientId, WTFMove(request), WTFMove(referrer), WTFMove(options));
         serviceWorkerGlobalScope.updateExtendedEventsSet(fetchEvent.ptr());
     }, WorkerRunLoop::defaultMode());
 }
index e45cfbb..b55915f 100644 (file)
@@ -56,8 +56,7 @@ public:
 
     WorkerObjectProxy& workerObjectProxy() const { return m_workerObjectProxy; }
 
-    WEBCORE_EXPORT void postFetchTask(Ref<ServiceWorkerFetch::Client>&&, ResourceRequest&&, FetchOptions&&);
-    WEBCORE_EXPORT void postFetchTask(Ref<ServiceWorkerFetch::Client>&&, std::optional<ServiceWorkerClientIdentifier>&&, ResourceRequest&&, FetchOptions&&);
+    WEBCORE_EXPORT void postFetchTask(Ref<ServiceWorkerFetch::Client>&&, std::optional<ServiceWorkerClientIdentifier>&&, ResourceRequest&&, String&& referrer, FetchOptions&&);
     WEBCORE_EXPORT void postMessageToServiceWorker(Ref<SerializedScriptValue>&&, std::unique_ptr<MessagePortChannelArray>&&, ServiceWorkerOrClientData&& sourceData);
 
     void fireInstallEvent();
index 1079346..72acb71 100644 (file)
@@ -1,3 +1,28 @@
+2017-12-19  Youenn Fablet  <youenn@apple.com>
+
+        Service Worker should not clean HTTP headers added by the application or by fetch specification before service worker interception
+        https://bugs.webkit.org/show_bug.cgi?id=180939
+
+        Reviewed by Chris Dumez.
+
+        Passing referrer as an explicit parameter of StartFetch.
+
+        Cleaning request headers based on ResourceLoaderOptions.httpHeadersToKeep.
+
+        * StorageProcess/ServiceWorker/WebSWServerConnection.cpp:
+        (WebKit::WebSWServerConnection::startFetch):
+        * StorageProcess/ServiceWorker/WebSWServerConnection.h:
+        * StorageProcess/ServiceWorker/WebSWServerConnection.messages.in:
+        * WebProcess/Storage/ServiceWorkerClientFetch.cpp:
+        (WebKit::ServiceWorkerClientFetch::start):
+        * WebProcess/Storage/WebSWClientConnection.cpp:
+        (WebKit::WebSWClientConnection::startFetch):
+        * WebProcess/Storage/WebSWClientConnection.h:
+        * WebProcess/Storage/WebSWContextManagerConnection.cpp:
+        (WebKit::WebSWContextManagerConnection::startFetch):
+        * WebProcess/Storage/WebSWContextManagerConnection.h:
+        * WebProcess/Storage/WebSWContextManagerConnection.messages.in:
+
 2017-12-19  Andy Estes  <aestes@apple.com>
 
         [Apple Pay] Stop maintaining a list of payment networks
index b24bf07..6dde72d 100644 (file)
@@ -126,12 +126,12 @@ void WebSWServerConnection::updateWorkerStateInClient(ServiceWorkerIdentifier wo
     send(Messages::WebSWClientConnection::UpdateWorkerState(worker, state));
 }
 
-void WebSWServerConnection::startFetch(uint64_t fetchIdentifier, ServiceWorkerIdentifier serviceWorkerIdentifier, ResourceRequest&& request, FetchOptions&& options, IPC::FormDataReference&& formData)
+void WebSWServerConnection::startFetch(uint64_t fetchIdentifier, ServiceWorkerIdentifier serviceWorkerIdentifier, ResourceRequest&& request, FetchOptions&& options, IPC::FormDataReference&& formData, String&& referrer)
 {
     // It's possible this specific worker cannot be re-run (e.g. its registration has been removed)
-    server().runServiceWorkerIfNecessary(serviceWorkerIdentifier, [contentConnection = m_contentConnection.copyRef(), connectionIdentifier = identifier(), fetchIdentifier, serviceWorkerIdentifier = serviceWorkerIdentifier, request = WTFMove(request), options = WTFMove(options), formData = WTFMove(formData)](bool success, auto& contextConnection) {
+    server().runServiceWorkerIfNecessary(serviceWorkerIdentifier, [contentConnection = m_contentConnection.copyRef(), connectionIdentifier = identifier(), fetchIdentifier, serviceWorkerIdentifier = serviceWorkerIdentifier, request = WTFMove(request), options = WTFMove(options), formData = WTFMove(formData), referrer = WTFMove(referrer)](bool success, auto& contextConnection) {
         if (success)
-            sendToContextProcess(contextConnection, Messages::WebSWContextManagerConnection::StartFetch { connectionIdentifier, fetchIdentifier, serviceWorkerIdentifier, request, options, formData });
+            sendToContextProcess(contextConnection, Messages::WebSWContextManagerConnection::StartFetch { connectionIdentifier, fetchIdentifier, serviceWorkerIdentifier, request, options, formData, referrer });
         else
             contentConnection->send(Messages::ServiceWorkerClientFetch::DidNotHandle { }, fetchIdentifier);
     });
index 6b7a5d0..2092a77 100644 (file)
@@ -83,7 +83,7 @@ private:
     void notifyClientsOfControllerChange(const HashSet<WebCore::DocumentIdentifier>& contextIdentifiers, const WebCore::ServiceWorkerData& newController);
     void registrationReady(uint64_t registrationReadyRequestIdentifier, WebCore::ServiceWorkerRegistrationData&&) final;
 
-    void startFetch(uint64_t fetchIdentifier, WebCore::ServiceWorkerIdentifier, WebCore::ResourceRequest&&, WebCore::FetchOptions&&, IPC::FormDataReference&&);
+    void startFetch(uint64_t fetchIdentifier, WebCore::ServiceWorkerIdentifier, WebCore::ResourceRequest&&, WebCore::FetchOptions&&, IPC::FormDataReference&&, String&& referrer);
 
     void postMessageToServiceWorker(WebCore::ServiceWorkerIdentifier destination, IPC::DataReference&& message, const WebCore::ServiceWorkerOrClientIdentifier& source);
 
index 382a270..493a8f2 100644 (file)
@@ -29,7 +29,7 @@ messages -> WebSWServerConnection {
     AddServiceWorkerRegistrationInServer(WebCore::ServiceWorkerRegistrationIdentifier identifier)
     RemoveServiceWorkerRegistrationInServer(WebCore::ServiceWorkerRegistrationIdentifier identifier)
 
-    StartFetch(uint64_t identifier, WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, WebCore::ResourceRequest request, struct WebCore::FetchOptions options, IPC::FormDataReference requestBody)
+    StartFetch(uint64_t identifier, WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, WebCore::ResourceRequest request, struct WebCore::FetchOptions options, IPC::FormDataReference requestBody, String referrer)
 
     PostMessageToServiceWorker(WebCore::ServiceWorkerIdentifier destination, IPC::DataReference message, WebCore::ServiceWorkerOrClientIdentifier source)
 
index 9ea8e15..691e976 100644 (file)
@@ -31,6 +31,7 @@
 #include "DataReference.h"
 #include "WebSWClientConnection.h"
 #include "WebServiceWorkerProvider.h"
+#include <WebCore/CrossOriginAccessControl.h>
 #include <WebCore/MIMETypeRegistry.h>
 #include <WebCore/NotImplemented.h>
 #include <WebCore/ResourceError.h>
@@ -62,7 +63,17 @@ ServiceWorkerClientFetch::ServiceWorkerClientFetch(WebServiceWorkerProvider& ser
 
 void ServiceWorkerClientFetch::start()
 {
-    m_connection->startFetch(m_loader, m_loader->identifier());
+    auto request = m_loader->request();
+    auto& options = m_loader->options();
+
+    auto referrer = request.httpReferrer();
+
+    // We are intercepting fetch calls after going through the HTTP layer, which may add some specific headers.
+    if (options.mode == FetchOptions::Mode::Cors)
+        cleanHTTPRequestHeadersForAccessControl(request, options.httpHeadersToKeep);
+
+    ASSERT(options.serviceWorkersMode != ServiceWorkersMode::None);
+    m_connection->startFetch(m_loader->identifier(), options.serviceWorkerIdentifier.value(), request, options, referrer);
 }
 
 // https://fetch.spec.whatwg.org/#http-fetch step 3.3
index b16a862..a8b61b5 100644 (file)
@@ -192,10 +192,9 @@ void WebSWClientConnection::getRegistrations(const SecurityOrigin& topOrigin, co
     });
 }
 
-void WebSWClientConnection::startFetch(const ResourceLoader& loader, uint64_t identifier)
+void WebSWClientConnection::startFetch(uint64_t fetchIdentifier, WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, const WebCore::ResourceRequest& request, const WebCore::FetchOptions& options, const String& referrer)
 {
-    ASSERT(loader.options().serviceWorkersMode != ServiceWorkersMode::None && loader.options().serviceWorkerIdentifier);
-    send(Messages::WebSWServerConnection::StartFetch { identifier, loader.options().serviceWorkerIdentifier.value(), loader.request(), loader.options(), IPC::FormDataReference { loader.request().httpBody() } });
+    send(Messages::WebSWServerConnection::StartFetch { fetchIdentifier, serviceWorkerIdentifier, request, options, IPC::FormDataReference { request.httpBody() }, referrer });
 }
 
 void WebSWClientConnection::postMessageToServiceWorkerClient(DocumentIdentifier destinationContextIdentifier, const IPC::DataReference& message, ServiceWorkerData&& source, const String& sourceOrigin)
index 46556ba..8b6d98f 100644 (file)
@@ -60,7 +60,7 @@ public:
     void didReceiveMessage(IPC::Connection&, IPC::Decoder&) final;
 
     bool mayHaveServiceWorkerRegisteredForOrigin(const WebCore::SecurityOrigin&) const final;
-    void startFetch(const WebCore::ResourceLoader&, uint64_t identifier);
+    void startFetch(uint64_t fetchIdentifier, WebCore::ServiceWorkerIdentifier, const WebCore::ResourceRequest&, const WebCore::FetchOptions&, const String& referrer);
 
     void postMessageToServiceWorkerClient(WebCore::DocumentIdentifier destinationContextIdentifier, const IPC::DataReference& message, WebCore::ServiceWorkerData&& source, const String& sourceOrigin);
 
index 1917602..8c92709 100644 (file)
@@ -155,7 +155,7 @@ void WebSWContextManagerConnection::serviceWorkerStartedWithMessage(std::optiona
         m_connectionToStorageProcess->send(Messages::WebSWServerToContextConnection::ScriptContextFailedToStart(jobDataIdentifier, serviceWorkerIdentifier, exceptionMessage), 0);
 }
 
-void WebSWContextManagerConnection::startFetch(SWServerConnectionIdentifier serverConnectionIdentifier, uint64_t fetchIdentifier, ServiceWorkerIdentifier serviceWorkerIdentifier, ResourceRequest&& request, FetchOptions&& options, IPC::FormDataReference&& formData)
+void WebSWContextManagerConnection::startFetch(SWServerConnectionIdentifier serverConnectionIdentifier, uint64_t fetchIdentifier, ServiceWorkerIdentifier serviceWorkerIdentifier, ResourceRequest&& request, FetchOptions&& options, IPC::FormDataReference&& formData, String&& referrer)
 {
     auto* serviceWorkerThreadProxy = SWContextManager::singleton().serviceWorkerThreadProxy(serviceWorkerIdentifier);
     if (!serviceWorkerThreadProxy) {
@@ -169,7 +169,7 @@ void WebSWContextManagerConnection::startFetch(SWServerConnectionIdentifier serv
         clientId = ServiceWorkerClientIdentifier { serverConnectionIdentifier, options.clientIdentifier.value() };
 
     request.setHTTPBody(formData.takeData());
-    serviceWorkerThreadProxy->thread().postFetchTask(WTFMove(client), WTFMove(clientId), WTFMove(request), WTFMove(options));
+    serviceWorkerThreadProxy->thread().postFetchTask(WTFMove(client), WTFMove(clientId), WTFMove(request), WTFMove(referrer), WTFMove(options));
 }
 
 void WebSWContextManagerConnection::postMessageToServiceWorker(ServiceWorkerIdentifier destinationIdentifier, const IPC::DataReference& message, ServiceWorkerOrClientData&& sourceData)
index 980dad4..8dceb2e 100644 (file)
@@ -76,7 +76,7 @@ private:
     // IPC messages.
     void serviceWorkerStartedWithMessage(std::optional<WebCore::ServiceWorkerJobDataIdentifier>, WebCore::ServiceWorkerIdentifier, const String& exceptionMessage) final;
     void installServiceWorker(const WebCore::ServiceWorkerContextData&, PAL::SessionID);
-    void startFetch(WebCore::SWServerConnectionIdentifier, uint64_t fetchIdentifier, WebCore::ServiceWorkerIdentifier, WebCore::ResourceRequest&&, WebCore::FetchOptions&&, IPC::FormDataReference&&);
+    void startFetch(WebCore::SWServerConnectionIdentifier, uint64_t fetchIdentifier, WebCore::ServiceWorkerIdentifier, WebCore::ResourceRequest&&, WebCore::FetchOptions&&, IPC::FormDataReference&&, String&& referrer);
     void postMessageToServiceWorker(WebCore::ServiceWorkerIdentifier destinationIdentifier, const IPC::DataReference& message, WebCore::ServiceWorkerOrClientData&& sourceData);
     void fireInstallEvent(WebCore::ServiceWorkerIdentifier);
     void fireActivateEvent(WebCore::ServiceWorkerIdentifier);
index c1266b9..03295c4 100644 (file)
@@ -24,7 +24,7 @@
 
 messages -> WebSWContextManagerConnection {
     InstallServiceWorker(struct WebCore::ServiceWorkerContextData contextData, PAL::SessionID sessionID)
-    StartFetch(WebCore::SWServerConnectionIdentifier serverConnectionIdentifier, uint64_t fetchIdentifier, WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, WebCore::ResourceRequest request, struct WebCore::FetchOptions options, IPC::FormDataReference requestBody)
+    StartFetch(WebCore::SWServerConnectionIdentifier serverConnectionIdentifier, uint64_t fetchIdentifier, WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, WebCore::ResourceRequest request, struct WebCore::FetchOptions options, IPC::FormDataReference requestBody, String referrer)
     PostMessageToServiceWorker(WebCore::ServiceWorkerIdentifier destinationIdentifier, IPC::DataReference message, WebCore::ServiceWorkerOrClientData sourceData)
     FireInstallEvent(WebCore::ServiceWorkerIdentifier identifier)
     FireActivateEvent(WebCore::ServiceWorkerIdentifier identifier)