Title: [226126] trunk
Revision
226126
Author
[email protected]
Date
2017-12-19 10:37:44 -0800 (Tue, 19 Dec 2017)

Log Message

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

Patch by Youenn Fablet <[email protected]> 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:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (226125 => 226126)


--- trunk/LayoutTests/ChangeLog	2017-12-19 18:25:54 UTC (rev 226125)
+++ trunk/LayoutTests/ChangeLog	2017-12-19 18:37:44 UTC (rev 226126)
@@ -1,3 +1,12 @@
+2017-12-19  Youenn Fablet  <[email protected]>
+
+        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  <[email protected]>
 
         Unreviewed, rebaseline service workers flaky tests.

Modified: trunk/LayoutTests/TestExpectations (226125 => 226126)


--- trunk/LayoutTests/TestExpectations	2017-12-19 18:25:54 UTC (rev 226125)
+++ trunk/LayoutTests/TestExpectations	2017-12-19 18:37:44 UTC (rev 226126)
@@ -175,7 +175,6 @@
 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 ]

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (226125 => 226126)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2017-12-19 18:25:54 UTC (rev 226125)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2017-12-19 18:37:44 UTC (rev 226126)
@@ -1,3 +1,14 @@
+2017-12-19  Youenn Fablet  <[email protected]>
+
+        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  <[email protected]>
 
         Unreviewed, rebaseline service workers flaky tests.

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-header-visibility.https-expected.txt (226125 => 226126)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-header-visibility.https-expected.txt	2017-12-19 18:25:54 UTC (rev 226125)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-header-visibility.https-expected.txt	2017-12-19 18:37:44 UTC (rev 226126)
@@ -1,4 +1,3 @@
 
+PASS Visibility of defaulted headers during interception 
 
-FAIL Visibility of defaulted headers during interception assert_unreached: unexpected rejection: withUA FAIL - expected "custom_ua", got "NO_UA" Reached unreachable code
-

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-xhr.https-expected.txt (226125 => 226126)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-xhr.https-expected.txt	2017-12-19 18:25:54 UTC (rev 226125)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-xhr.https-expected.txt	2017-12-19 18:37:44 UTC (rev 226126)
@@ -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 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-xhr-iframe.https.html (226125 => 226126)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-xhr-iframe.https.html	2017-12-19 18:25:54 UTC (rev 226125)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-xhr-iframe.https.html	2017-12-19 18:37:44 UTC (rev 226126)
@@ -179,7 +179,7 @@
           '\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");
       });
 }
 

Modified: trunk/Source/WebCore/ChangeLog (226125 => 226126)


--- trunk/Source/WebCore/ChangeLog	2017-12-19 18:25:54 UTC (rev 226125)
+++ trunk/Source/WebCore/ChangeLog	2017-12-19 18:37:44 UTC (rev 226126)
@@ -1,3 +1,33 @@
+2017-12-19  Youenn Fablet  <[email protected]>
+
+        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  <[email protected]>
 
         [Apple Pay] Stop maintaining a list of payment networks

Modified: trunk/Source/WebCore/loader/CrossOriginAccessControl.cpp (226125 => 226126)


--- trunk/Source/WebCore/loader/CrossOriginAccessControl.cpp	2017-12-19 18:25:54 UTC (rev 226125)
+++ trunk/Source/WebCore/loader/CrossOriginAccessControl.cpp	2017-12-19 18:37:44 UTC (rev 226126)
@@ -116,14 +116,35 @@
         && 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)

Modified: trunk/Source/WebCore/loader/CrossOriginAccessControl.h (226125 => 226126)


--- trunk/Source/WebCore/loader/CrossOriginAccessControl.h	2017-12-19 18:25:54 UTC (rev 226125)
+++ trunk/Source/WebCore/loader/CrossOriginAccessControl.h	2017-12-19 18:37:44 UTC (rev 226126)
@@ -26,8 +26,10 @@
 
 #pragma once
 
+#include "HTTPHeaderNames.h"
 #include "StoredCredentialsPolicy.h"
 #include <wtf/Forward.h>
+#include <wtf/HashSet.h>
 
 namespace WebCore {
 
@@ -44,8 +46,11 @@
 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);
 

Modified: trunk/Source/WebCore/loader/DocumentThreadableLoader.cpp (226125 => 226126)


--- trunk/Source/WebCore/loader/DocumentThreadableLoader.cpp	2017-12-19 18:25:54 UTC (rev 226125)
+++ trunk/Source/WebCore/loader/DocumentThreadableLoader.cpp	2017-12-19 18:37:44 UTC (rev 226126)
@@ -119,6 +119,11 @@
     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;

Modified: trunk/Source/WebCore/loader/ResourceLoaderOptions.h (226125 => 226126)


--- trunk/Source/WebCore/loader/ResourceLoaderOptions.h	2017-12-19 18:25:54 UTC (rev 226125)
+++ trunk/Source/WebCore/loader/ResourceLoaderOptions.h	2017-12-19 18:37:44 UTC (rev 226126)
@@ -31,8 +31,10 @@
 #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 @@
     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 };

Modified: trunk/Source/WebCore/loader/SubresourceLoader.cpp (226125 => 226126)


--- trunk/Source/WebCore/loader/SubresourceLoader.cpp	2017-12-19 18:25:54 UTC (rev 226125)
+++ trunk/Source/WebCore/loader/SubresourceLoader.cpp	2017-12-19 18:37:44 UTC (rev 226126)
@@ -542,7 +542,7 @@
         m_origin = SecurityOrigin::createUnique();
 
     if (redirectingToNewOrigin) {
-        cleanRedirectedRequestForAccessControl(newRequest);
+        cleanHTTPRequestHeadersForAccessControl(newRequest);
         updateRequestForAccessControl(newRequest, *m_origin, options().storedCredentialsPolicy);
     }
 

Modified: trunk/Source/WebCore/workers/service/context/ServiceWorkerFetch.cpp (226125 => 226126)


--- trunk/Source/WebCore/workers/service/context/ServiceWorkerFetch.cpp	2017-12-19 18:25:54 UTC (rev 226125)
+++ trunk/Source/WebCore/workers/service/context/ServiceWorkerFetch.cpp	2017-12-19 18:37:44 UTC (rev 226126)
@@ -91,18 +91,12 @@
     });
 }
 
-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);

Modified: trunk/Source/WebCore/workers/service/context/ServiceWorkerFetch.h (226125 => 226126)


--- trunk/Source/WebCore/workers/service/context/ServiceWorkerFetch.h	2017-12-19 18:25:54 UTC (rev 226125)
+++ trunk/Source/WebCore/workers/service/context/ServiceWorkerFetch.h	2017-12-19 18:37:44 UTC (rev 226126)
@@ -54,7 +54,7 @@
     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

Modified: trunk/Source/WebCore/workers/service/context/ServiceWorkerThread.cpp (226125 => 226126)


--- trunk/Source/WebCore/workers/service/context/ServiceWorkerThread.cpp	2017-12-19 18:25:54 UTC (rev 226125)
+++ trunk/Source/WebCore/workers/service/context/ServiceWorkerThread.cpp	2017-12-19 18:37:44 UTC (rev 226126)
@@ -91,13 +91,13 @@
     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());
 }

Modified: trunk/Source/WebCore/workers/service/context/ServiceWorkerThread.h (226125 => 226126)


--- trunk/Source/WebCore/workers/service/context/ServiceWorkerThread.h	2017-12-19 18:25:54 UTC (rev 226125)
+++ trunk/Source/WebCore/workers/service/context/ServiceWorkerThread.h	2017-12-19 18:37:44 UTC (rev 226126)
@@ -56,8 +56,7 @@
 
     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();

Modified: trunk/Source/WebKit/ChangeLog (226125 => 226126)


--- trunk/Source/WebKit/ChangeLog	2017-12-19 18:25:54 UTC (rev 226125)
+++ trunk/Source/WebKit/ChangeLog	2017-12-19 18:37:44 UTC (rev 226126)
@@ -1,3 +1,28 @@
+2017-12-19  Youenn Fablet  <[email protected]>
+
+        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  <[email protected]>
 
         [Apple Pay] Stop maintaining a list of payment networks

Modified: trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.cpp (226125 => 226126)


--- trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.cpp	2017-12-19 18:25:54 UTC (rev 226125)
+++ trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.cpp	2017-12-19 18:37:44 UTC (rev 226126)
@@ -126,12 +126,12 @@
     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);
     });

Modified: trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.h (226125 => 226126)


--- trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.h	2017-12-19 18:25:54 UTC (rev 226125)
+++ trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.h	2017-12-19 18:37:44 UTC (rev 226126)
@@ -83,7 +83,7 @@
     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);
 

Modified: trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.messages.in (226125 => 226126)


--- trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.messages.in	2017-12-19 18:25:54 UTC (rev 226125)
+++ trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.messages.in	2017-12-19 18:37:44 UTC (rev 226126)
@@ -29,7 +29,7 @@
     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)
 

Modified: trunk/Source/WebKit/WebProcess/Storage/ServiceWorkerClientFetch.cpp (226125 => 226126)


--- trunk/Source/WebKit/WebProcess/Storage/ServiceWorkerClientFetch.cpp	2017-12-19 18:25:54 UTC (rev 226125)
+++ trunk/Source/WebKit/WebProcess/Storage/ServiceWorkerClientFetch.cpp	2017-12-19 18:37:44 UTC (rev 226126)
@@ -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 @@
 
 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

Modified: trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.cpp (226125 => 226126)


--- trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.cpp	2017-12-19 18:25:54 UTC (rev 226125)
+++ trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.cpp	2017-12-19 18:37:44 UTC (rev 226126)
@@ -192,10 +192,9 @@
     });
 }
 
-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)

Modified: trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.h (226125 => 226126)


--- trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.h	2017-12-19 18:25:54 UTC (rev 226125)
+++ trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.h	2017-12-19 18:37:44 UTC (rev 226126)
@@ -60,7 +60,7 @@
     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);
 

Modified: trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp (226125 => 226126)


--- trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp	2017-12-19 18:25:54 UTC (rev 226125)
+++ trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp	2017-12-19 18:37:44 UTC (rev 226126)
@@ -155,7 +155,7 @@
         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 @@
         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)

Modified: trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h (226125 => 226126)


--- trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h	2017-12-19 18:25:54 UTC (rev 226125)
+++ trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h	2017-12-19 18:37:44 UTC (rev 226126)
@@ -76,7 +76,7 @@
     // 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);

Modified: trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.messages.in (226125 => 226126)


--- trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.messages.in	2017-12-19 18:25:54 UTC (rev 226125)
+++ trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.messages.in	2017-12-19 18:37:44 UTC (rev 226126)
@@ -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)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to