Source/WebCore:
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 23 Oct 2017 17:25:32 +0000 (17:25 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 23 Oct 2017 17:25:32 +0000 (17:25 +0000)
Create a Fetch event when ServiceWorker has to handle a fetch
https://bugs.webkit.org/show_bug.cgi?id=178491

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

Covered by existing test.

Updating FetchEvent to pass a FetchResponse* within its onResponse callback.
Making it a CompletionHandler.
Fixing a check on respondWith to ensure that event is dispatched when respondWith is called.

Adding ServiceWorkerFetch class to handle the creation of the fetch event, waiting for the fetch event to be responded
and processing when fetch event is responded.
ServiceWorkerFetchTask takes a client to which will be sent the response body or the error.
WebKit implementation of it will be to send the related IPC message back to the WebProcess that made the fetch request.

Adding a method to ServiceWorkerThread to create the fetch event on worker thread and dispatch on the global scope.

* WebCore.xcodeproj/project.pbxproj:
* platform/network/ResourceResponseBase.h:
* testing/Internals.cpp:
(WebCore::Internals::waitForFetchEventToFinish):
* workers/service/FetchEvent.cpp:
(WebCore::FetchEvent::~FetchEvent):
(WebCore::FetchEvent::respondWith):
(WebCore::FetchEvent::onResponse):
(WebCore::FetchEvent::respondWithError):
(WebCore::FetchEvent::processResponse):
(WebCore::FetchEvent::promiseIsSettled):
* workers/service/FetchEvent.h:
* workers/service/context/ServiceWorkerFetch.cpp: Added.
(WebCore::ServiceWorkerFetch::dispatchFetchTask):
(WebCore::ServiceWorkerFetch::processResponse):
* workers/service/context/ServiceWorkerFetch.h: Added.
* workers/service/context/ServiceWorkerThread.cpp:
(WebCore::m_workerObjectProxy):
(WebCore::ServiceWorkerThread::dispatchFetchEvent):
* workers/service/context/ServiceWorkerThread.h:

Source/WebKit:
TestController should clear all fetch caches when resetting its state
https://bugs.webkit.org/show_bug.cgi?id=178486
<rdar://problem/35066305>

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

Adding a new DidNotHandle message to disambiguate with the DidFail fetch case.
With DidNotHandle, the loading should go the network process.
With DidFail, the loading should return a network error.

On receiving an order to start a fetch, ServiceWorkerThread will dispatch a fetch event.
The client of this event will retrieve the response and return it to the WebProcess through IPC.

* StorageProcess/ServiceWorker/WebSWServerConnection.cpp:
(WebKit::WebSWServerConnection::didNotHandleFetch):
* StorageProcess/ServiceWorker/WebSWServerConnection.h:
* StorageProcess/StorageProcess.cpp:
(WebKit::StorageProcess::didNotHandleFetch):
* StorageProcess/StorageProcess.h:
* StorageProcess/StorageProcess.messages.in:
* WebKit.xcodeproj/project.pbxproj:
* WebProcess/Storage/ServiceWorkerClientFetch.cpp:
(WebKit::ServiceWorkerClientFetch::didFail):
(WebKit::ServiceWorkerClientFetch::didNotHandle):
* WebProcess/Storage/ServiceWorkerClientFetch.h:
* WebProcess/Storage/ServiceWorkerClientFetch.messages.in:
* WebProcess/Storage/ServiceWorkerContextManager.cpp:
(WebKit::ServiceWorkerContextManager::startFetch):
* WebProcess/Storage/ServiceWorkerContextManager.h:
* WebProcess/Storage/WebServiceWorkerFetchTaskClient.cpp: Added.
(WebKit::WebServiceWorkerFetchTaskClient::~WebServiceWorkerFetchTaskClient):
(WebKit::WebServiceWorkerFetchTaskClient::WebServiceWorkerFetchTaskClient):
(WebKit::WebServiceWorkerFetchTaskClient::didReceiveResponse):
(WebKit::WebServiceWorkerFetchTaskClient::didReceiveData):
(WebKit::WebServiceWorkerFetchTaskClient::didFail):
(WebKit::WebServiceWorkerFetchTaskClient::didFinish):
* WebProcess/Storage/WebServiceWorkerFetchTaskClient.h: Added.
* WebProcess/WebProcess.cpp:
(WebKit::WebProcess::startFetchInServiceWorker):
* WebProcess/WebProcess.h:

LayoutTests:
TestController should clear all fetch caches when resetting its state
https://bugs.webkit.org/show_bug.cgi?id=178486
<rdar://problem/35066305>

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

Beefing up the test by using fetch event handler to return responses
previously hard coded in ServiceWorkerContextManager.

* http/tests/workers/service/basic-fetch.https-expected.txt:
* http/tests/workers/service/resources/basic-fetch-worker.js:
(event.event.request.url.indexOf):
* http/tests/workers/service/resources/basic-fetch.js:

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

31 files changed:
LayoutTests/ChangeLog
LayoutTests/http/tests/workers/service/resources/basic-fetch-worker.js
LayoutTests/http/tests/workers/service/resources/sw-test-pre.js
LayoutTests/http/wpt/service-workers/fetchEvent.https.html
Source/WebCore/ChangeLog
Source/WebCore/Modules/fetch/FetchRequest.h
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/testing/Internals.cpp
Source/WebCore/testing/Internals.h
Source/WebCore/testing/Internals.idl
Source/WebCore/workers/service/FetchEvent.cpp
Source/WebCore/workers/service/FetchEvent.h
Source/WebCore/workers/service/FetchEvent.idl
Source/WebCore/workers/service/context/ServiceWorkerFetch.cpp [new file with mode: 0644]
Source/WebCore/workers/service/context/ServiceWorkerFetch.h [new file with mode: 0644]
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/StorageProcess.cpp
Source/WebKit/StorageProcess/StorageProcess.h
Source/WebKit/StorageProcess/StorageProcess.messages.in
Source/WebKit/WebKit.xcodeproj/project.pbxproj
Source/WebKit/WebProcess/Storage/ServiceWorkerClientFetch.cpp
Source/WebKit/WebProcess/Storage/ServiceWorkerClientFetch.h
Source/WebKit/WebProcess/Storage/ServiceWorkerClientFetch.messages.in
Source/WebKit/WebProcess/Storage/ServiceWorkerContextManager.cpp
Source/WebKit/WebProcess/Storage/ServiceWorkerContextManager.h
Source/WebKit/WebProcess/Storage/WebServiceWorkerFetchTaskClient.cpp [new file with mode: 0644]
Source/WebKit/WebProcess/Storage/WebServiceWorkerFetchTaskClient.h [new file with mode: 0644]

index d7c13e3..aa0c304 100644 (file)
@@ -1,3 +1,19 @@
+2017-10-23  Youenn Fablet  <youenn@apple.com>
+
+        TestController should clear all fetch caches when resetting its state
+        https://bugs.webkit.org/show_bug.cgi?id=178486
+        <rdar://problem/35066305>
+
+        Reviewed by Chris Dumez.
+
+        Beefing up the test by using fetch event handler to return responses
+        previously hard coded in ServiceWorkerContextManager.
+
+        * http/tests/workers/service/basic-fetch.https-expected.txt:
+        * http/tests/workers/service/resources/basic-fetch-worker.js:
+        (event.event.request.url.indexOf):
+        * http/tests/workers/service/resources/basic-fetch.js:
+
 2017-10-23  Ryan Haddad  <ryanhaddad@apple.com>
 
         Mark compositing/visible-rect/iframe-no-layers.html as a flaky failure.
 2017-10-23  Ryan Haddad  <ryanhaddad@apple.com>
 
         Mark compositing/visible-rect/iframe-no-layers.html as a flaky failure.
index 29d8a2b..c1ab5d5 100644 (file)
@@ -1 +1,15 @@
-// FIXME: register an onfetch event handler and handle "test1", "test2" and "test3" URLs
+self.addEventListener("fetch", (event) => {
+    if (event.request.url.indexOf("test1") !== -1) {
+        event.respondWith(new Response(null, { status: 200, statusText: "Hello from service worker" }));
+        return;
+    }
+    if (event.request.url.indexOf("test2") !== -1) {
+        event.respondWith(new Response(null, { status: 500, statusText: "Error from service worker" }));
+        return;
+    }
+    if (event.request.url.indexOf("test3") !== -1) {
+        event.respondWith(Response.error());
+        return;
+    }
+    event.respondWith(Response.error());
+});
index 34223f5..d8201de 100644 (file)
@@ -4,6 +4,19 @@ if (window.testRunner) {
        testRunner.waitUntilDone();
 }
 
        testRunner.waitUntilDone();
 }
 
+function log(msg)
+{
+    let console = document.getElementById("console");
+    if (!console) {
+        console = document.createElement("div");
+        console.id = "console";
+        document.body.appendChild(console);
+    }
+    let span = document.createElement("span");
+    span.innerHTML = msg + "<br>";
+    console.appendChild(span);
+}
+
 function finishSWTest()
 {
        if (window.testRunner)
 function finishSWTest()
 {
        if (window.testRunner)
index 8a39458..3a64a75 100644 (file)
@@ -6,7 +6,7 @@
 <script>
 // FIXME: Should be run on a service worker.
 test(() => {
 <script>
 // FIXME: Should be run on a service worker.
 test(() => {
-    var event = new FetchEvent('FetchEvent', { request : new Request('') });
+    var event = internals.createBeingDispatchedFetchEvent();
     event.respondWith(undefined);
     assert_throws('InvalidStateError', () => event.respondWith(undefined));
 }, "FetchEvent respondWith should throw if called twice");
     event.respondWith(undefined);
     assert_throws('InvalidStateError', () => event.respondWith(undefined));
 }, "FetchEvent respondWith should throw if called twice");
@@ -21,7 +21,7 @@ test(() => {
 promise_test(async t => {
     if (!window.internals)
           return Promise.reject("test require internals");
 promise_test(async t => {
     if (!window.internals)
           return Promise.reject("test require internals");
-    var event = new FetchEvent('FetchEvent', { request : new Request('') });
+    var event = internals.createBeingDispatchedFetchEvent();
     var promise = internals.waitForFetchEventToFinish(event);
     event.respondWith(undefined);
     return promise_rejects(t, new TypeError, promise);
     var promise = internals.waitForFetchEventToFinish(event);
     event.respondWith(undefined);
     return promise_rejects(t, new TypeError, promise);
@@ -30,7 +30,7 @@ promise_test(async t => {
 promise_test(async t => {
     if (!window.internals)
         return Promise.reject("test require internals");
 promise_test(async t => {
     if (!window.internals)
         return Promise.reject("test require internals");
-    var event = new FetchEvent('FetchEvent', { request : new Request('') });
+    var event = internals.createBeingDispatchedFetchEvent();
     var promise = internals.waitForFetchEventToFinish(event);
     event.respondWith(new Request(''));
     return promise_rejects(t, new TypeError, promise);
     var promise = internals.waitForFetchEventToFinish(event);
     event.respondWith(new Request(''));
     return promise_rejects(t, new TypeError, promise);
@@ -39,7 +39,7 @@ promise_test(async t => {
 promise_test(async t => {
     if (!window.internals)
         return Promise.reject("test require internals");
 promise_test(async t => {
     if (!window.internals)
         return Promise.reject("test require internals");
-    var event = new FetchEvent('FetchEvent', { request : new Request('') });
+    var event = internals.createBeingDispatchedFetchEvent();
     var promise = internals.waitForFetchEventToFinish(event);
     event.respondWith(new Promise((resolve, reject) => {
         resolve(new Request(''));
     var promise = internals.waitForFetchEventToFinish(event);
     event.respondWith(new Promise((resolve, reject) => {
         resolve(new Request(''));
@@ -50,7 +50,7 @@ promise_test(async t => {
 promise_test(async t => {
     if (!window.internals)
         return Promise.reject("test require internals");
 promise_test(async t => {
     if (!window.internals)
         return Promise.reject("test require internals");
-    var event = new FetchEvent('FetchEvent', { request : new Request('') });
+    var event = internals.createBeingDispatchedFetchEvent();
     var promise = internals.waitForFetchEventToFinish(event);
     event.respondWith(new Promise((resolve, reject) => {
         reject('not good');
     var promise = internals.waitForFetchEventToFinish(event);
     event.respondWith(new Promise((resolve, reject) => {
         reject('not good');
@@ -61,7 +61,7 @@ promise_test(async t => {
 promise_test(async t => {
     if (!window.internals)
          return Promise.reject("test require internals");
 promise_test(async t => {
     if (!window.internals)
          return Promise.reject("test require internals");
-    var event = new FetchEvent('FetchEvent', { request : new Request('') });
+    var event = internals.createBeingDispatchedFetchEvent();
     var response = new Response;
     event.respondWith(response);
     assert_true(response === await internals.waitForFetchEventToFinish(event));
     var response = new Response;
     event.respondWith(response);
     assert_true(response === await internals.waitForFetchEventToFinish(event));
index d70247b..d314892 100644 (file)
@@ -1,3 +1,44 @@
+2017-10-23  Youenn Fablet  <youenn@apple.com>
+
+        Create a Fetch event when ServiceWorker has to handle a fetch
+        https://bugs.webkit.org/show_bug.cgi?id=178491
+
+        Reviewed by Chris Dumez.
+
+        Covered by existing test.
+
+        Updating FetchEvent to pass a FetchResponse* within its onResponse callback.
+        Making it a CompletionHandler.
+        Fixing a check on respondWith to ensure that event is dispatched when respondWith is called.
+
+        Adding ServiceWorkerFetch class to handle the creation of the fetch event, waiting for the fetch event to be responded
+        and processing when fetch event is responded.
+        ServiceWorkerFetchTask takes a client to which will be sent the response body or the error.
+        WebKit implementation of it will be to send the related IPC message back to the WebProcess that made the fetch request.
+
+        Adding a method to ServiceWorkerThread to create the fetch event on worker thread and dispatch on the global scope.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * platform/network/ResourceResponseBase.h:
+        * testing/Internals.cpp:
+        (WebCore::Internals::waitForFetchEventToFinish):
+        * workers/service/FetchEvent.cpp:
+        (WebCore::FetchEvent::~FetchEvent):
+        (WebCore::FetchEvent::respondWith):
+        (WebCore::FetchEvent::onResponse):
+        (WebCore::FetchEvent::respondWithError):
+        (WebCore::FetchEvent::processResponse):
+        (WebCore::FetchEvent::promiseIsSettled):
+        * workers/service/FetchEvent.h:
+        * workers/service/context/ServiceWorkerFetch.cpp: Added.
+        (WebCore::ServiceWorkerFetch::dispatchFetchTask):
+        (WebCore::ServiceWorkerFetch::processResponse):
+        * workers/service/context/ServiceWorkerFetch.h: Added.
+        * workers/service/context/ServiceWorkerThread.cpp:
+        (WebCore::m_workerObjectProxy):
+        (WebCore::ServiceWorkerThread::dispatchFetchEvent):
+        * workers/service/context/ServiceWorkerThread.h:
+
 2017-10-23  Basuke Suzuki  <Basuke.Suzuki@sony.com>
 
         [Curl] Fix authentication related bugs
 2017-10-23  Basuke Suzuki  <Basuke.Suzuki@sony.com>
 
         [Curl] Fix authentication related bugs
index bab756e..a0423ce 100644 (file)
@@ -52,7 +52,6 @@ public:
     using Mode = FetchOptions::Mode;
     using Redirect = FetchOptions::Redirect;
 
     using Mode = FetchOptions::Mode;
     using Redirect = FetchOptions::Redirect;
 
-
     static ExceptionOr<Ref<FetchRequest>> create(ScriptExecutionContext&, Info&&, Init&&);
     static Ref<FetchRequest> create(ScriptExecutionContext& context, std::optional<FetchBody>&& body, Ref<FetchHeaders>&& headers, ResourceRequest&& request, FetchOptions&& options, String&& referrer) { return adoptRef(*new FetchRequest(context, WTFMove(body), WTFMove(headers), WTFMove(request), WTFMove(options), WTFMove(referrer))); }
 
     static ExceptionOr<Ref<FetchRequest>> create(ScriptExecutionContext&, Info&&, Init&&);
     static Ref<FetchRequest> create(ScriptExecutionContext& context, std::optional<FetchBody>&& body, Ref<FetchHeaders>&& headers, ResourceRequest&& request, FetchOptions&& options, String&& referrer) { return adoptRef(*new FetchRequest(context, WTFMove(body), WTFMove(headers), WTFMove(request), WTFMove(options), WTFMove(referrer))); }
 
@@ -93,7 +92,6 @@ private:
     const char* activeDOMObjectName() const final;
     bool canSuspendForDocumentSuspension() const final;
 
     const char* activeDOMObjectName() const final;
     bool canSuspendForDocumentSuspension() const final;
 
-
     ResourceRequest m_request;
     FetchOptions m_options;
     String m_referrer;
     ResourceRequest m_request;
     FetchOptions m_options;
     String m_referrer;
index 6f81212..9360ede 100644 (file)
                413015D91C7B571400091C6E /* FetchResponse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 413015D51C7B570400091C6E /* FetchResponse.cpp */; };
                413015D91C7B571400091C6F /* FetchBodySource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 413015D51C7B570400091C6F /* FetchBodySource.cpp */; };
                4131F3B31F9552860059995A /* JSFetchEventCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4131F3B11F9552810059995A /* JSFetchEventCustom.cpp */; };
                413015D91C7B571400091C6E /* FetchResponse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 413015D51C7B570400091C6E /* FetchResponse.cpp */; };
                413015D91C7B571400091C6F /* FetchBodySource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 413015D51C7B570400091C6F /* FetchBodySource.cpp */; };
                4131F3B31F9552860059995A /* JSFetchEventCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4131F3B11F9552810059995A /* JSFetchEventCustom.cpp */; };
+               4131F3E11F987CC00059995A /* ServiceWorkerFetch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 419ACF901F97E7D6009F1A83 /* ServiceWorkerFetch.cpp */; };
                41380C261F3436A600155FDA /* DOMCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41380C201F34368A00155FDA /* DOMCache.cpp */; };
                41380C271F3436AC00155FDA /* DOMCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 41380C251F34369A00155FDA /* DOMCache.h */; };
                41380C281F3436AC00155FDA /* DOMCacheStorage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41380C211F34368D00155FDA /* DOMCacheStorage.cpp */; };
                41380C261F3436A600155FDA /* DOMCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41380C201F34368A00155FDA /* DOMCache.cpp */; };
                41380C271F3436AC00155FDA /* DOMCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 41380C251F34369A00155FDA /* DOMCache.h */; };
                41380C281F3436AC00155FDA /* DOMCacheStorage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41380C211F34368D00155FDA /* DOMCacheStorage.cpp */; };
                418C39561C8DAC7F0051C8A3 /* DOMWindowFetch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 418C39521C8DAC7B0051C8A3 /* DOMWindowFetch.cpp */; };
                418C395A1C8DD6990051C8A3 /* WorkerGlobalScopeFetch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 418C39571C8DD6960051C8A3 /* WorkerGlobalScopeFetch.cpp */; };
                418F88050FF957AF0080F045 /* JSAbstractWorker.h in Headers */ = {isa = PBXBuildFile; fileRef = 418F88030FF957AE0080F045 /* JSAbstractWorker.h */; };
                418C39561C8DAC7F0051C8A3 /* DOMWindowFetch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 418C39521C8DAC7B0051C8A3 /* DOMWindowFetch.cpp */; };
                418C395A1C8DD6990051C8A3 /* WorkerGlobalScopeFetch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 418C39571C8DD6960051C8A3 /* WorkerGlobalScopeFetch.cpp */; };
                418F88050FF957AF0080F045 /* JSAbstractWorker.h in Headers */ = {isa = PBXBuildFile; fileRef = 418F88030FF957AE0080F045 /* JSAbstractWorker.h */; };
+               419ACF921F97E7DA009F1A83 /* ServiceWorkerFetch.h in Headers */ = {isa = PBXBuildFile; fileRef = 419ACF8E1F97E7D5009F1A83 /* ServiceWorkerFetch.h */; settings = {ATTRIBUTES = (Private, ); }; };
                419BC2DE1685329900D64D6D /* VisitedLinkState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 419BC2DC1685329900D64D6D /* VisitedLinkState.cpp */; };
                419BC2DF1685329900D64D6D /* VisitedLinkState.h in Headers */ = {isa = PBXBuildFile; fileRef = 419BC2DD1685329900D64D6D /* VisitedLinkState.h */; };
                419BE7591BC7F42B00E1C85B /* WebCoreBuiltinNames.h in Headers */ = {isa = PBXBuildFile; fileRef = 419BE7521BC7F3DB00E1C85B /* WebCoreBuiltinNames.h */; };
                419BC2DE1685329900D64D6D /* VisitedLinkState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 419BC2DC1685329900D64D6D /* VisitedLinkState.cpp */; };
                419BC2DF1685329900D64D6D /* VisitedLinkState.h in Headers */ = {isa = PBXBuildFile; fileRef = 419BC2DD1685329900D64D6D /* VisitedLinkState.h */; };
                419BE7591BC7F42B00E1C85B /* WebCoreBuiltinNames.h in Headers */ = {isa = PBXBuildFile; fileRef = 419BE7521BC7F3DB00E1C85B /* WebCoreBuiltinNames.h */; };
                418C395F1C8F0AAB0051C8A3 /* ReadableStreamDefaultController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReadableStreamDefaultController.h; sourceTree = "<group>"; };
                418F88020FF957AE0080F045 /* JSAbstractWorker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSAbstractWorker.cpp; sourceTree = "<group>"; };
                418F88030FF957AE0080F045 /* JSAbstractWorker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSAbstractWorker.h; sourceTree = "<group>"; };
                418C395F1C8F0AAB0051C8A3 /* ReadableStreamDefaultController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReadableStreamDefaultController.h; sourceTree = "<group>"; };
                418F88020FF957AE0080F045 /* JSAbstractWorker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSAbstractWorker.cpp; sourceTree = "<group>"; };
                418F88030FF957AE0080F045 /* JSAbstractWorker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSAbstractWorker.h; sourceTree = "<group>"; };
+               419ACF8E1F97E7D5009F1A83 /* ServiceWorkerFetch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ServiceWorkerFetch.h; sourceTree = "<group>"; };
+               419ACF901F97E7D6009F1A83 /* ServiceWorkerFetch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ServiceWorkerFetch.cpp; sourceTree = "<group>"; };
                419BC2DC1685329900D64D6D /* VisitedLinkState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VisitedLinkState.cpp; sourceTree = "<group>"; };
                419BC2DD1685329900D64D6D /* VisitedLinkState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VisitedLinkState.h; sourceTree = "<group>"; };
                419BE7521BC7F3DB00E1C85B /* WebCoreBuiltinNames.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebCoreBuiltinNames.h; sourceTree = "<group>"; };
                419BC2DC1685329900D64D6D /* VisitedLinkState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VisitedLinkState.cpp; sourceTree = "<group>"; };
                419BC2DD1685329900D64D6D /* VisitedLinkState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VisitedLinkState.h; sourceTree = "<group>"; };
                419BE7521BC7F3DB00E1C85B /* WebCoreBuiltinNames.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebCoreBuiltinNames.h; sourceTree = "<group>"; };
                517C87071F8E8FF200EB8076 /* context */ = {
                        isa = PBXGroup;
                        children = (
                517C87071F8E8FF200EB8076 /* context */ = {
                        isa = PBXGroup;
                        children = (
+                               419ACF901F97E7D6009F1A83 /* ServiceWorkerFetch.cpp */,
+                               419ACF8E1F97E7D5009F1A83 /* ServiceWorkerFetch.h */,
                                517C87111F8EE72F00EB8076 /* ServiceWorkerThread.cpp */,
                                517C87101F8EE72E00EB8076 /* ServiceWorkerThread.h */,
                        );
                                517C87111F8EE72F00EB8076 /* ServiceWorkerThread.cpp */,
                                517C87101F8EE72E00EB8076 /* ServiceWorkerThread.h */,
                        );
                                46EF142C1F97B7D800C2A524 /* ServiceWorkerClients.h in Headers */,
                                51F1755F1F3EBC8300C74950 /* ServiceWorkerContainer.h in Headers */,
                                51CA7EE91F883390003D3131 /* ServiceWorkerContextData.h in Headers */,
                                46EF142C1F97B7D800C2A524 /* ServiceWorkerClients.h in Headers */,
                                51F1755F1F3EBC8300C74950 /* ServiceWorkerContainer.h in Headers */,
                                51CA7EE91F883390003D3131 /* ServiceWorkerContextData.h in Headers */,
+                               419ACF921F97E7DA009F1A83 /* ServiceWorkerFetch.h in Headers */,
                                517A535D1F5899FE00DCDC0A /* ServiceWorkerFetchResult.h in Headers */,
                                51F175611F3EBC8300C74950 /* ServiceWorkerGlobalScope.h in Headers */,
                                51F175631F3EBC8300C74950 /* ServiceWorkerJob.h in Headers */,
                                517A535D1F5899FE00DCDC0A /* ServiceWorkerFetchResult.h in Headers */,
                                51F175611F3EBC8300C74950 /* ServiceWorkerGlobalScope.h in Headers */,
                                51F175631F3EBC8300C74950 /* ServiceWorkerJob.h in Headers */,
                                46EF142B1F97B7D800C2A524 /* ServiceWorkerClients.cpp in Sources */,
                                51F1755E1F3EBC8300C74950 /* ServiceWorkerContainer.cpp in Sources */,
                                517C87181F8FD4D900EB8076 /* ServiceWorkerContextData.cpp in Sources */,
                                46EF142B1F97B7D800C2A524 /* ServiceWorkerClients.cpp in Sources */,
                                51F1755E1F3EBC8300C74950 /* ServiceWorkerContainer.cpp in Sources */,
                                517C87181F8FD4D900EB8076 /* ServiceWorkerContextData.cpp in Sources */,
+                               4131F3E11F987CC00059995A /* ServiceWorkerFetch.cpp in Sources */,
                                51F175601F3EBC8300C74950 /* ServiceWorkerGlobalScope.cpp in Sources */,
                                51F175621F3EBC8300C74950 /* ServiceWorkerJob.cpp in Sources */,
                                517A53251F4B905500DCDC0A /* ServiceWorkerJobData.cpp in Sources */,
                                51F175601F3EBC8300C74950 /* ServiceWorkerGlobalScope.cpp in Sources */,
                                51F175621F3EBC8300C74950 /* ServiceWorkerJob.cpp in Sources */,
                                517A53251F4B905500DCDC0A /* ServiceWorkerJobData.cpp in Sources */,
index 39929b8..9eb7b38 100644 (file)
@@ -4224,8 +4224,8 @@ uint64_t Internals::responseSizeWithPadding(FetchResponse& response) const
 #if ENABLE(SERVICE_WORKER)
 void Internals::waitForFetchEventToFinish(FetchEvent& event, DOMPromiseDeferred<IDLInterface<FetchResponse>>&& promise)
 {
 #if ENABLE(SERVICE_WORKER)
 void Internals::waitForFetchEventToFinish(FetchEvent& event, DOMPromiseDeferred<IDLInterface<FetchResponse>>&& promise)
 {
-    event.onResponse([promise = WTFMove(promise), event = makeRef(event)] () mutable {
-        if (auto* response = event->response())
+    event.onResponse([promise = WTFMove(promise), event = makeRef(event)] (FetchResponse* response) mutable {
+        if (response)
             promise.resolve(*response);
         else
             promise.reject(TypeError, ASCIILiteral("fetch event responded with error"));
             promise.resolve(*response);
         else
             promise.reject(TypeError, ASCIILiteral("fetch event responded with error"));
@@ -4243,6 +4243,14 @@ Ref<ExtendableEvent> Internals::createTrustedExtendableEvent()
 {
     return ExtendableEvent::create("ExtendableEvent", { }, Event::IsTrusted::Yes);
 }
 {
     return ExtendableEvent::create("ExtendableEvent", { }, Event::IsTrusted::Yes);
 }
+
+Ref<FetchEvent> Internals::createBeingDispatchedFetchEvent(ScriptExecutionContext& context)
+{
+    auto event = FetchEvent::createForTesting(context);
+    event->setEventPhase(Event::CAPTURING_PHASE);
+    return event;
+}
+
 #endif
 
 String Internals::timelineDescription(AnimationTimeline& timeline)
 #endif
 
 String Internals::timelineDescription(AnimationTimeline& timeline)
index f05e6e5..782a2bf 100644 (file)
@@ -613,6 +613,7 @@ public:
 #if ENABLE(SERVICE_WORKER)
     void waitForFetchEventToFinish(FetchEvent&, DOMPromiseDeferred<IDLInterface<FetchResponse>>&&);
     void waitForExtendableEventToFinish(ExtendableEvent&, DOMPromiseDeferred<void>&&);
 #if ENABLE(SERVICE_WORKER)
     void waitForFetchEventToFinish(FetchEvent&, DOMPromiseDeferred<IDLInterface<FetchResponse>>&&);
     void waitForExtendableEventToFinish(ExtendableEvent&, DOMPromiseDeferred<void>&&);
+    Ref<FetchEvent> createBeingDispatchedFetchEvent(ScriptExecutionContext&);
     Ref<ExtendableEvent> createTrustedExtendableEvent();
 #endif
 
     Ref<ExtendableEvent> createTrustedExtendableEvent();
 #endif
 
index 52aaf0f..bb72dc5 100644 (file)
@@ -557,6 +557,7 @@ enum EventThrottlingBehavior {
 
     [Conditional=SERVICE_WORKER] Promise<Response> waitForFetchEventToFinish(FetchEvent event);
     [Conditional=SERVICE_WORKER] Promise<void> waitForExtendableEventToFinish(ExtendableEvent event);
 
     [Conditional=SERVICE_WORKER] Promise<Response> waitForFetchEventToFinish(FetchEvent event);
     [Conditional=SERVICE_WORKER] Promise<void> waitForExtendableEventToFinish(ExtendableEvent event);
+    [Conditional=SERVICE_WORKER, CallWith=ScriptExecutionContext] FetchEvent createBeingDispatchedFetchEvent();
     [Conditional=SERVICE_WORKER] ExtendableEvent createTrustedExtendableEvent();
 
     boolean hasServiceWorkerRegisteredForOrigin(DOMString origin);
     [Conditional=SERVICE_WORKER] ExtendableEvent createTrustedExtendableEvent();
 
     boolean hasServiceWorkerRegisteredForOrigin(DOMString origin);
index 38bf016..7eda32a 100644 (file)
 
 namespace WebCore {
 
 
 namespace WebCore {
 
+Ref<FetchEvent> FetchEvent::createForTesting(ScriptExecutionContext& context)
+{
+    FetchEvent::Init init;
+    init.request = FetchRequest::create(context, { }, FetchHeaders::create(FetchHeaders::Guard::Immutable, { }), { }, { }, { });
+    return FetchEvent::create("fetch", WTFMove(init), Event::IsTrusted::Yes);
+}
+
 FetchEvent::FetchEvent(const AtomicString& type, Init&& initializer, IsTrusted isTrusted)
     : ExtendableEvent(type, initializer, isTrusted)
     , m_request(initializer.request.releaseNonNull())
 FetchEvent::FetchEvent(const AtomicString& type, Init&& initializer, IsTrusted isTrusted)
     : ExtendableEvent(type, initializer, isTrusted)
     , m_request(initializer.request.releaseNonNull())
@@ -42,10 +49,16 @@ FetchEvent::FetchEvent(const AtomicString& type, Init&& initializer, IsTrusted i
 {
 }
 
 {
 }
 
+FetchEvent::~FetchEvent()
+{
+    if (auto callback = WTFMove(m_onResponse))
+        callback(nullptr);
+}
+
 ExceptionOr<void> FetchEvent::respondWith(Ref<DOMPromise>&& promise)
 {
 ExceptionOr<void> FetchEvent::respondWith(Ref<DOMPromise>&& promise)
 {
-    if (isBeingDispatched())
-        return Exception { InvalidStateError, ASCIILiteral("Event is being dispatched") };
+    if (!isBeingDispatched())
+        return Exception { InvalidStateError, ASCIILiteral("Event is not being dispatched") };
 
     if (m_respondWithEntered)
         return Exception { InvalidStateError, ASCIILiteral("Event respondWith flag is set") };
 
     if (m_respondWithEntered)
         return Exception { InvalidStateError, ASCIILiteral("Event respondWith flag is set") };
@@ -68,7 +81,7 @@ ExceptionOr<void> FetchEvent::respondWith(Ref<DOMPromise>&& promise)
     return { };
 }
 
     return { };
 }
 
-void FetchEvent::onResponse(WTF::Function<void()>&& callback)
+void FetchEvent::onResponse(CompletionHandler<void(FetchResponse*)>&& callback)
 {
     ASSERT(!m_onResponse);
     m_onResponse = WTFMove(callback);
 {
     ASSERT(!m_onResponse);
     m_onResponse = WTFMove(callback);
@@ -77,15 +90,15 @@ void FetchEvent::onResponse(WTF::Function<void()>&& callback)
 void FetchEvent::respondWithError()
 {
     m_respondWithError = true;
 void FetchEvent::respondWithError()
 {
     m_respondWithError = true;
-    processResponse();
+    processResponse(nullptr);
 }
 
 }
 
-void FetchEvent::processResponse()
+void FetchEvent::processResponse(FetchResponse* response)
 {
     m_respondPromise = nullptr;
     m_waitToRespond = false;
     if (auto callback = WTFMove(m_onResponse))
 {
     m_respondPromise = nullptr;
     m_waitToRespond = false;
     if (auto callback = WTFMove(m_onResponse))
-        callback();
+        callback(response);
 }
 
 void FetchEvent::promiseIsSettled()
 }
 
 void FetchEvent::promiseIsSettled()
@@ -107,45 +120,7 @@ void FetchEvent::promiseIsSettled()
         return;
     }
 
         return;
     }
 
-    m_response = WTFMove(response);
-
-    // FIXME: We should process the response and send the body in streaming.
-    if (m_response->hasReadableStreamBody()) {
-        m_response->consumeBodyFromReadableStream([this, protectedThis = makeRef(*this)] (ExceptionOr<RefPtr<SharedBuffer>>&& result) mutable {
-            if (result.hasException()) {
-                respondWithError();
-                return;
-            }
-            m_responseBody = result.releaseReturnValue();
-            processResponse();
-        });
-        return;
-    }
-    if (m_response->isLoading()) {
-        m_response->consumeBodyWhenLoaded([this, protectedThis = makeRef(*this)] (ExceptionOr<RefPtr<SharedBuffer>>&& result) mutable {
-            if (result.hasException()) {
-                respondWithError();
-                return;
-            }
-            m_responseBody = result.releaseReturnValue();
-            processResponse();
-        });
-        return;
-    }
-
-    auto body = m_response->consumeBody();
-    WTF::switchOn(body, 
-        [] (Ref<FormData>&) {
-            // FIXME: Support FormData response bodies.
-        },
-        [this] (Ref<SharedBuffer>& buffer) {
-            m_responseBody = WTFMove(buffer);
-        }, 
-        [] (std::nullptr_t&) {
-        }
-    );
-
-    processResponse();
+    processResponse(response);
 }
 
 } // namespace WebCore
 }
 
 } // namespace WebCore
index c231b5b..feacd04 100644 (file)
 
 #include "ExtendableEvent.h"
 #include "FetchRequest.h"
 
 #include "ExtendableEvent.h"
 #include "FetchRequest.h"
-#include "FetchResponse.h"
+#include <wtf/CompletionHandler.h>
 
 namespace WebCore {
 
 
 namespace WebCore {
 
+class FetchResponse;
+
 class FetchEvent final : public ExtendableEvent {
 public:
     struct Init : ExtendableEventInit {
 class FetchEvent final : public ExtendableEvent {
 public:
     struct Init : ExtendableEventInit {
@@ -42,29 +44,30 @@ public:
         String targetClientId;
     };
 
         String targetClientId;
     };
 
+    WEBCORE_EXPORT static Ref<FetchEvent> createForTesting(ScriptExecutionContext&);
+
     static Ref<FetchEvent> create(const AtomicString& type, Init&& initializer, IsTrusted isTrusted = IsTrusted::No)
     {
         return adoptRef(*new FetchEvent(type, WTFMove(initializer), isTrusted));
     }
     static Ref<FetchEvent> create(const AtomicString& type, Init&& initializer, IsTrusted isTrusted = IsTrusted::No)
     {
         return adoptRef(*new FetchEvent(type, WTFMove(initializer), isTrusted));
     }
+    ~FetchEvent();
 
     EventInterface eventInterface() const final { return FetchEventInterfaceType; }
 
     ExceptionOr<void> respondWith(Ref<DOMPromise>&&);
 
 
     EventInterface eventInterface() const final { return FetchEventInterfaceType; }
 
     ExceptionOr<void> respondWith(Ref<DOMPromise>&&);
 
-    WEBCORE_EXPORT void onResponse(WTF::Function<void()>&&);
+    WEBCORE_EXPORT void onResponse(CompletionHandler<void(FetchResponse*)>&&);
 
     FetchRequest& request() { return m_request.get(); }
     const String& clientId() const { return m_clientId; }
     const String& reservedClientId() const { return m_reservedClientId; }
     const String& targetClientId() const { return m_targetClientId; }
 
 
     FetchRequest& request() { return m_request.get(); }
     const String& clientId() const { return m_clientId; }
     const String& reservedClientId() const { return m_reservedClientId; }
     const String& targetClientId() const { return m_targetClientId; }
 
-    FetchResponse* response() { return m_response.get(); }
-
 private:
 private:
-    FetchEvent(const AtomicString&, Init&&, IsTrusted);
+    WEBCORE_EXPORT FetchEvent(const AtomicString&, Init&&, IsTrusted);
 
     void promiseIsSettled();
 
     void promiseIsSettled();
-    void processResponse();
+    void processResponse(FetchResponse*);
     void respondWithError();
 
     Ref<FetchRequest> m_request;
     void respondWithError();
 
     Ref<FetchRequest> m_request;
@@ -77,9 +80,7 @@ private:
     bool m_respondWithError { false };
     RefPtr<DOMPromise> m_respondPromise;
 
     bool m_respondWithError { false };
     RefPtr<DOMPromise> m_respondPromise;
 
-    WTF::Function<void()> m_onResponse;
-    RefPtr<FetchResponse> m_response;
-    RefPtr<SharedBuffer> m_responseBody;
+    CompletionHandler<void(FetchResponse*)> m_onResponse;
 };
 
 } // namespace WebCore
 };
 
 } // namespace WebCore
index c90ceff..a0b9aa3 100644 (file)
@@ -29,8 +29,8 @@
     Conditional=SERVICE_WORKER,
     JSCustomMarkFunction,
     EnabledAtRuntime=ServiceWorker,
     Conditional=SERVICE_WORKER,
     JSCustomMarkFunction,
     EnabledAtRuntime=ServiceWorker,
+    ExportMacro=WEBCORE_EXPORT,
     Exposed=(ServiceWorker,Worker,Window),
     Exposed=(ServiceWorker,Worker,Window),
-    ExportToWrappedFunction,
     JSGenerateToNativeObject
 ] interface FetchEvent : ExtendableEvent {
     [SameObject] readonly attribute FetchRequest request;
     JSGenerateToNativeObject
 ] interface FetchEvent : ExtendableEvent {
     [SameObject] readonly attribute FetchRequest request;
diff --git a/Source/WebCore/workers/service/context/ServiceWorkerFetch.cpp b/Source/WebCore/workers/service/context/ServiceWorkerFetch.cpp
new file mode 100644 (file)
index 0000000..e517f59
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 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.
+ */
+
+#include "config.h"
+#include "ServiceWorkerFetch.h"
+
+#if ENABLE(SERVICE_WORKER)
+
+#include "EventNames.h"
+#include "FetchEvent.h"
+#include "FetchRequest.h"
+#include "FetchResponse.h"
+#include "ResourceRequest.h"
+#include "WorkerGlobalScope.h"
+
+namespace WebCore {
+
+namespace ServiceWorkerFetch {
+
+static void processResponse(Ref<Client>&& client, FetchResponse* response)
+{
+    if (!response) {
+        client->didFail();
+        return;
+    }
+    auto protectedResponse = makeRef(*response);
+
+    client->didReceiveResponse(response->resourceResponse());
+
+    if (response->hasReadableStreamBody()) {
+        // FIXME: We should send the body as chunks.
+        response->consumeBodyFromReadableStream([client = WTFMove(client)] (ExceptionOr<RefPtr<SharedBuffer>>&& result) mutable {
+            if (result.hasException()) {
+                client->didFail();
+                return;
+            }
+            client->didReceiveData(result.releaseReturnValue().releaseNonNull());
+            client->didFinish();
+        });
+        return;
+    }
+    if (response->isLoading()) {
+        // FIXME: We should send the body as chunks.
+        response->consumeBodyWhenLoaded([client = WTFMove(client)] (ExceptionOr<RefPtr<SharedBuffer>>&& result) mutable {
+            if (result.hasException()) {
+                client->didFail();
+                return;
+            }
+            client->didReceiveData(result.releaseReturnValue().releaseNonNull());
+            client->didFail();
+        });
+        return;
+    }
+
+    auto body = response->consumeBody();
+    WTF::switchOn(body, [] (Ref<FormData>&) {
+        // FIXME: Support FormData response bodies.
+    }, [&] (Ref<SharedBuffer>& buffer) {
+        client->didReceiveData(WTFMove(buffer));
+    }, [] (std::nullptr_t&) {
+    });
+
+    client->didFinish();
+}
+
+void dispatchFetchEvent(Ref<Client>&& client, WorkerGlobalScope& globalScope, ResourceRequest&& request, FetchOptions&& options)
+{
+    ASSERT(globalScope.isServiceWorkerGlobalScope());
+
+    // FIXME: Set request body and referrer.
+    auto requestHeaders = FetchHeaders::create(FetchHeaders::Guard::Immutable, HTTPHeaderMap { request.httpHeaderFields() });
+    auto fetchRequest = FetchRequest::create(globalScope, std::nullopt, WTFMove(requestHeaders),  WTFMove(request), WTFMove(options), { });
+
+    // FIXME: Initialize other FetchEvent::Init fields.
+    FetchEvent::Init init;
+    init.request = WTFMove(fetchRequest);
+    auto event = FetchEvent::create(eventNames().fetchEvent, WTFMove(init), Event::IsTrusted::Yes);
+
+    event->onResponse([client = WTFMove(client)] (FetchResponse* response) mutable {
+        processResponse(WTFMove(client), response);
+    });
+
+    globalScope.dispatchEvent(event);
+}
+
+} // namespace ServiceWorkerFetch
+
+} // namespace WebCore
+
+#endif // ENABLE(SERVICE_WORKER)
diff --git a/Source/WebCore/workers/service/context/ServiceWorkerFetch.h b/Source/WebCore/workers/service/context/ServiceWorkerFetch.h
new file mode 100644 (file)
index 0000000..105d143
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 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.
+ */
+
+#pragma once
+
+#if ENABLE(SERVICE_WORKER)
+
+#include <wtf/Ref.h>
+#include <wtf/ThreadSafeRefCounted.h>
+
+namespace WebCore {
+struct FetchOptions;
+class FetchResponse;
+class ResourceRequest;
+class ResourceResponse;
+class SharedBuffer;
+class WorkerGlobalScope;
+
+namespace ServiceWorkerFetch {
+class Client : public ThreadSafeRefCounted<Client> {
+public:
+    virtual ~Client() = default;
+
+    virtual void didReceiveResponse(const ResourceResponse&) = 0;
+    virtual void didReceiveData(Ref<SharedBuffer>&&) = 0;
+    virtual void didFail() = 0;
+    virtual void didFinish() = 0;
+};
+
+void dispatchFetchEvent(Ref<Client>&&, WorkerGlobalScope&, ResourceRequest&&, FetchOptions&&);
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(SERVICE_WORKER)
index 3c46b27..3818e99 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "ContentSecurityPolicyResponseHeaders.h"
 #include "SecurityOrigin.h"
 
 #include "ContentSecurityPolicyResponseHeaders.h"
 #include "SecurityOrigin.h"
+#include "ServiceWorkerFetch.h"
 #include "ServiceWorkerGlobalScope.h"
 #include "WorkerLoaderProxy.h"
 #include "WorkerObjectProxy.h"
 #include "ServiceWorkerGlobalScope.h"
 #include "WorkerLoaderProxy.h"
 #include "WorkerObjectProxy.h"
@@ -74,6 +75,7 @@ ServiceWorkerThread::ServiceWorkerThread(uint64_t serverConnectionIdentifier, co
     , m_data(data.isolatedCopy())
     , m_workerObjectProxy(ServiceWorkerThreadProxy::sharedDummyProxy())
 {
     , m_data(data.isolatedCopy())
     , m_workerObjectProxy(ServiceWorkerThreadProxy::sharedDummyProxy())
 {
+    AtomicString::init();
 }
 
 ServiceWorkerThread::~ServiceWorkerThread() = default;
 }
 
 ServiceWorkerThread::~ServiceWorkerThread() = default;
@@ -89,6 +91,15 @@ void ServiceWorkerThread::runEventLoop()
     WorkerThread::runEventLoop();
 }
 
     WorkerThread::runEventLoop();
 }
 
+void ServiceWorkerThread::postFetchTask(Ref<ServiceWorkerFetch::Client>&& client, ResourceRequest&& request, 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), request = request.isolatedCopy(), options = options.isolatedCopy()] (ScriptExecutionContext& context) mutable {
+        ServiceWorkerFetch::dispatchFetchEvent(WTFMove(client), downcast<WorkerGlobalScope>(context), WTFMove(request), WTFMove(options));
+    }, WorkerRunLoop::defaultMode());
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(SERVICE_WORKER)
 } // namespace WebCore
 
 #endif // ENABLE(SERVICE_WORKER)
index 8dba489..954daf6 100644 (file)
@@ -28,6 +28,7 @@
 #if ENABLE(SERVICE_WORKER)
 
 #include "ServiceWorkerContextData.h"
 #if ENABLE(SERVICE_WORKER)
 
 #include "ServiceWorkerContextData.h"
+#include "ServiceWorkerFetch.h"
 #include "WorkerThread.h"
 #include <wtf/Identified.h>
 
 #include "WorkerThread.h"
 #include <wtf/Identified.h>
 
@@ -47,6 +48,8 @@ public:
 
     WorkerObjectProxy& workerObjectProxy() const { return m_workerObjectProxy; }
 
 
     WorkerObjectProxy& workerObjectProxy() const { return m_workerObjectProxy; }
 
+    WEBCORE_EXPORT void postFetchTask(Ref<ServiceWorkerFetch::Client>&&, ResourceRequest&&, FetchOptions&&);
+
 protected:
     Ref<WorkerGlobalScope> createWorkerGlobalScope(const URL&, const String& identifier, const String& userAgent, const ContentSecurityPolicyResponseHeaders&, bool shouldBypassMainWorldContentSecurityPolicy, Ref<SecurityOrigin>&& topOrigin, MonotonicTime timeOrigin, PAL::SessionID) final;
     void runEventLoop() override;
 protected:
     Ref<WorkerGlobalScope> createWorkerGlobalScope(const URL&, const String& identifier, const String& userAgent, const ContentSecurityPolicyResponseHeaders&, bool shouldBypassMainWorldContentSecurityPolicy, Ref<SecurityOrigin>&& topOrigin, MonotonicTime timeOrigin, PAL::SessionID) final;
     void runEventLoop() override;
index 61354a3..90eedf1 100644 (file)
@@ -1,3 +1,46 @@
+2017-10-23  Youenn Fablet  <youenn@apple.com>
+
+        TestController should clear all fetch caches when resetting its state
+        https://bugs.webkit.org/show_bug.cgi?id=178486
+        <rdar://problem/35066305>
+
+        Reviewed by Chris Dumez.
+
+        Adding a new DidNotHandle message to disambiguate with the DidFail fetch case.
+        With DidNotHandle, the loading should go the network process.
+        With DidFail, the loading should return a network error.
+
+        On receiving an order to start a fetch, ServiceWorkerThread will dispatch a fetch event.
+        The client of this event will retrieve the response and return it to the WebProcess through IPC.
+
+        * StorageProcess/ServiceWorker/WebSWServerConnection.cpp:
+        (WebKit::WebSWServerConnection::didNotHandleFetch):
+        * StorageProcess/ServiceWorker/WebSWServerConnection.h:
+        * StorageProcess/StorageProcess.cpp:
+        (WebKit::StorageProcess::didNotHandleFetch):
+        * StorageProcess/StorageProcess.h:
+        * StorageProcess/StorageProcess.messages.in:
+        * WebKit.xcodeproj/project.pbxproj:
+        * WebProcess/Storage/ServiceWorkerClientFetch.cpp:
+        (WebKit::ServiceWorkerClientFetch::didFail):
+        (WebKit::ServiceWorkerClientFetch::didNotHandle):
+        * WebProcess/Storage/ServiceWorkerClientFetch.h:
+        * WebProcess/Storage/ServiceWorkerClientFetch.messages.in:
+        * WebProcess/Storage/ServiceWorkerContextManager.cpp:
+        (WebKit::ServiceWorkerContextManager::startFetch):
+        * WebProcess/Storage/ServiceWorkerContextManager.h:
+        * WebProcess/Storage/WebServiceWorkerFetchTaskClient.cpp: Added.
+        (WebKit::WebServiceWorkerFetchTaskClient::~WebServiceWorkerFetchTaskClient):
+        (WebKit::WebServiceWorkerFetchTaskClient::WebServiceWorkerFetchTaskClient):
+        (WebKit::WebServiceWorkerFetchTaskClient::didReceiveResponse):
+        (WebKit::WebServiceWorkerFetchTaskClient::didReceiveData):
+        (WebKit::WebServiceWorkerFetchTaskClient::didFail):
+        (WebKit::WebServiceWorkerFetchTaskClient::didFinish):
+        * WebProcess/Storage/WebServiceWorkerFetchTaskClient.h: Added.
+        * WebProcess/WebProcess.cpp:
+        (WebKit::WebProcess::startFetchInServiceWorker):
+        * WebProcess/WebProcess.h:
+
 2017-10-22  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         [iOS] WebProcess::initializeWebProcess spends ~150ms spinning up AVSystemController on some devices
 2017-10-22  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         [iOS] WebProcess::initializeWebProcess spends ~150ms spinning up AVSystemController on some devices
index 00a7596..f58c175 100644 (file)
@@ -120,6 +120,11 @@ void WebSWServerConnection::didFailFetch(uint64_t fetchIdentifier)
     m_contentConnection->send(Messages::ServiceWorkerClientFetch::DidFail { }, fetchIdentifier);
 }
 
     m_contentConnection->send(Messages::ServiceWorkerClientFetch::DidFail { }, fetchIdentifier);
 }
 
+void WebSWServerConnection::didNotHandleFetch(uint64_t fetchIdentifier)
+{
+    m_contentConnection->send(Messages::ServiceWorkerClientFetch::DidNotHandle { }, fetchIdentifier);
+}
+
 template<typename U> bool WebSWServerConnection::sendToContextProcess(U&& message)
 {
     if (!m_contextConnection)
 template<typename U> bool WebSWServerConnection::sendToContextProcess(U&& message)
 {
     if (!m_contextConnection)
index ae3a25d..7cc76bd 100644 (file)
@@ -55,6 +55,7 @@ public:
     void didReceiveFetchData(uint64_t fetchIdentifier, const IPC::DataReference&, int64_t encodedDataLength);
     void didFinishFetch(uint64_t fetchIdentifier);
     void didFailFetch(uint64_t fetchIdentifier);
     void didReceiveFetchData(uint64_t fetchIdentifier, const IPC::DataReference&, int64_t encodedDataLength);
     void didFinishFetch(uint64_t fetchIdentifier);
     void didFailFetch(uint64_t fetchIdentifier);
+    void didNotHandleFetch(uint64_t fetchIdentifier);
 
 private:
     // Implement SWServer::Connection (Messages to the client WebProcess)
 
 private:
     // Implement SWServer::Connection (Messages to the client WebProcess)
index 2c97acc..a8968b0 100644 (file)
@@ -411,6 +411,12 @@ void StorageProcess::didFailFetch(uint64_t serverConnectionIdentifier, uint64_t
         connection->didFailFetch(fetchIdentifier);
 }
 
         connection->didFailFetch(fetchIdentifier);
 }
 
+void StorageProcess::didNotHandleFetch(uint64_t serverConnectionIdentifier, uint64_t fetchIdentifier)
+{
+    if (auto* connection = m_swServerConnections.get(serverConnectionIdentifier))
+        connection->didNotHandleFetch(fetchIdentifier);
+}
+
 void StorageProcess::didReceiveFetchResponse(uint64_t serverConnectionIdentifier, uint64_t fetchIdentifier, const WebCore::ResourceResponse& response)
 {
     if (auto* connection = m_swServerConnections.get(serverConnectionIdentifier))
 void StorageProcess::didReceiveFetchResponse(uint64_t serverConnectionIdentifier, uint64_t fetchIdentifier, const WebCore::ResourceResponse& response)
 {
     if (auto* connection = m_swServerConnections.get(serverConnectionIdentifier))
index cfd4bc1..c83f74a 100644 (file)
@@ -124,6 +124,7 @@ private:
     void didReceiveFetchData(uint64_t serverConnectionIdentifier, uint64_t fetchIdentifier, const IPC::DataReference&, int64_t encodedDataLength);
     void didFinishFetch(uint64_t serverConnectionIdentifier, uint64_t fetchIdentifier);
     void didFailFetch(uint64_t serverConnectionIdentifier, uint64_t fetchIdentifier);
     void didReceiveFetchData(uint64_t serverConnectionIdentifier, uint64_t fetchIdentifier, const IPC::DataReference&, int64_t encodedDataLength);
     void didFinishFetch(uint64_t serverConnectionIdentifier, uint64_t fetchIdentifier);
     void didFailFetch(uint64_t serverConnectionIdentifier, uint64_t fetchIdentifier);
+    void didNotHandleFetch(uint64_t serverConnectionIdentifier, uint64_t fetchIdentifier);
 #endif
 #if ENABLE(INDEXED_DATABASE)
     Vector<WebCore::SecurityOriginData> indexedDatabaseOrigins(const String& path);
 #endif
 #if ENABLE(INDEXED_DATABASE)
     Vector<WebCore::SecurityOriginData> indexedDatabaseOrigins(const String& path);
index 2064d69..3392af7 100644 (file)
@@ -41,6 +41,7 @@ messages -> StorageProcess LegacyReceiver {
     ServiceWorkerContextFailedToStart(uint64_t serverConnectionIdentifier, struct WebCore::ServiceWorkerRegistrationKey registrationKey, String workerID, String message)
     ServiceWorkerContextStarted(uint64_t serverConnectionIdentifier, struct WebCore::ServiceWorkerRegistrationKey registrationKey, uint64_t identifier, String workerID)
 
     ServiceWorkerContextFailedToStart(uint64_t serverConnectionIdentifier, struct WebCore::ServiceWorkerRegistrationKey registrationKey, String workerID, String message)
     ServiceWorkerContextStarted(uint64_t serverConnectionIdentifier, struct WebCore::ServiceWorkerRegistrationKey registrationKey, uint64_t identifier, String workerID)
 
+    DidNotHandleFetch(uint64_t serverConnectionIdentifier, uint64_t fetchIdentifier)
     DidFailFetch(uint64_t serverConnectionIdentifier, uint64_t fetchIdentifier)
     DidReceiveFetchResponse(uint64_t serverConnectionIdentifier, uint64_t fetchIdentifier, WebCore::ResourceResponse response)
     DidReceiveFetchData(uint64_t serverConnectionIdentifier, uint64_t fetchIdentifier, IPC::DataReference data, int64_t encodedDataLength)
     DidFailFetch(uint64_t serverConnectionIdentifier, uint64_t fetchIdentifier)
     DidReceiveFetchResponse(uint64_t serverConnectionIdentifier, uint64_t fetchIdentifier, WebCore::ResourceResponse response)
     DidReceiveFetchData(uint64_t serverConnectionIdentifier, uint64_t fetchIdentifier, IPC::DataReference data, int64_t encodedDataLength)
index 594b433..57f7d65 100644 (file)
                4131F3D11F96BCCC0059995A /* ServiceWorkerClientFetch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4131F3D01F96BCC80059995A /* ServiceWorkerClientFetch.cpp */; };
                4131F3D41F96E9350059995A /* ServiceWorkerContextManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4131F3D31F96E9310059995A /* ServiceWorkerContextManager.cpp */; };
                4131F3D51F96E9350059995A /* ServiceWorkerContextManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 4131F3D21F96E9300059995A /* ServiceWorkerContextManager.h */; };
                4131F3D11F96BCCC0059995A /* ServiceWorkerClientFetch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4131F3D01F96BCC80059995A /* ServiceWorkerClientFetch.cpp */; };
                4131F3D41F96E9350059995A /* ServiceWorkerContextManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4131F3D31F96E9310059995A /* ServiceWorkerContextManager.cpp */; };
                4131F3D51F96E9350059995A /* ServiceWorkerContextManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 4131F3D21F96E9300059995A /* ServiceWorkerContextManager.h */; };
+               4131F3E21F9880840059995A /* WebServiceWorkerFetchTaskClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4131F3E01F98712C0059995A /* WebServiceWorkerFetchTaskClient.cpp */; };
                4135FBD11F4FB8090074C47B /* CacheStorageEngineCaches.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4135FBCF1F4FB7F20074C47B /* CacheStorageEngineCaches.cpp */; };
                41897ECF1F415D620016FA42 /* WebCacheStorageConnection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41897ECE1F415D5C0016FA42 /* WebCacheStorageConnection.cpp */; };
                41897ED01F415D650016FA42 /* WebCacheStorageProvider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41897ECC1F415D5C0016FA42 /* WebCacheStorageProvider.cpp */; };
                4135FBD11F4FB8090074C47B /* CacheStorageEngineCaches.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4135FBCF1F4FB7F20074C47B /* CacheStorageEngineCaches.cpp */; };
                41897ECF1F415D620016FA42 /* WebCacheStorageConnection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41897ECE1F415D5C0016FA42 /* WebCacheStorageConnection.cpp */; };
                41897ED01F415D650016FA42 /* WebCacheStorageProvider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41897ECC1F415D5C0016FA42 /* WebCacheStorageProvider.cpp */; };
                4131F3D01F96BCC80059995A /* ServiceWorkerClientFetch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ServiceWorkerClientFetch.cpp; sourceTree = "<group>"; };
                4131F3D21F96E9300059995A /* ServiceWorkerContextManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ServiceWorkerContextManager.h; sourceTree = "<group>"; };
                4131F3D31F96E9310059995A /* ServiceWorkerContextManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ServiceWorkerContextManager.cpp; sourceTree = "<group>"; };
                4131F3D01F96BCC80059995A /* ServiceWorkerClientFetch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ServiceWorkerClientFetch.cpp; sourceTree = "<group>"; };
                4131F3D21F96E9300059995A /* ServiceWorkerContextManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ServiceWorkerContextManager.h; sourceTree = "<group>"; };
                4131F3D31F96E9310059995A /* ServiceWorkerContextManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ServiceWorkerContextManager.cpp; sourceTree = "<group>"; };
+               4131F3E01F98712C0059995A /* WebServiceWorkerFetchTaskClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebServiceWorkerFetchTaskClient.cpp; sourceTree = "<group>"; };
                4135FBCF1F4FB7F20074C47B /* CacheStorageEngineCaches.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CacheStorageEngineCaches.cpp; sourceTree = "<group>"; };
                4135FBD01F4FB7F20074C47B /* CacheStorageEngineCaches.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CacheStorageEngineCaches.h; sourceTree = "<group>"; };
                41897ECB1F415D5C0016FA42 /* WebCacheStorageConnection.messages.in */ = {isa = PBXFileReference; lastKnownFileType = text; path = WebCacheStorageConnection.messages.in; sourceTree = "<group>"; };
                4135FBCF1F4FB7F20074C47B /* CacheStorageEngineCaches.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CacheStorageEngineCaches.cpp; sourceTree = "<group>"; };
                4135FBD01F4FB7F20074C47B /* CacheStorageEngineCaches.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CacheStorageEngineCaches.h; sourceTree = "<group>"; };
                41897ECB1F415D5C0016FA42 /* WebCacheStorageConnection.messages.in */ = {isa = PBXFileReference; lastKnownFileType = text; path = WebCacheStorageConnection.messages.in; sourceTree = "<group>"; };
                41897ED41F415D850016FA42 /* CacheStorageEngineConnection.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CacheStorageEngineConnection.h; sourceTree = "<group>"; };
                41897ED51F415D850016FA42 /* CacheStorageEngineConnection.messages.in */ = {isa = PBXFileReference; lastKnownFileType = text; path = CacheStorageEngineConnection.messages.in; sourceTree = "<group>"; };
                41897ED61F415D860016FA42 /* CacheStorageEngine.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CacheStorageEngine.cpp; sourceTree = "<group>"; };
                41897ED41F415D850016FA42 /* CacheStorageEngineConnection.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CacheStorageEngineConnection.h; sourceTree = "<group>"; };
                41897ED51F415D850016FA42 /* CacheStorageEngineConnection.messages.in */ = {isa = PBXFileReference; lastKnownFileType = text; path = CacheStorageEngineConnection.messages.in; sourceTree = "<group>"; };
                41897ED61F415D860016FA42 /* CacheStorageEngine.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CacheStorageEngine.cpp; sourceTree = "<group>"; };
+               419ACF9B1F981D26009F1A83 /* WebServiceWorkerFetchTaskClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebServiceWorkerFetchTaskClient.h; sourceTree = "<group>"; };
                41AC86811E042E5300303074 /* WebRTCResolver.messages.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; lineEnding = 0; name = WebRTCResolver.messages.in; path = Network/webrtc/WebRTCResolver.messages.in; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = "<none>"; };
                41B28B081F83AD3E00FB52AC /* RTCPacketOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTCPacketOptions.h; sourceTree = "<group>"; };
                41B28B091F83AD3E00FB52AC /* RTCPacketOptions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RTCPacketOptions.cpp; sourceTree = "<group>"; };
                41AC86811E042E5300303074 /* WebRTCResolver.messages.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; lineEnding = 0; name = WebRTCResolver.messages.in; path = Network/webrtc/WebRTCResolver.messages.in; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = "<none>"; };
                41B28B081F83AD3E00FB52AC /* RTCPacketOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTCPacketOptions.h; sourceTree = "<group>"; };
                41B28B091F83AD3E00FB52AC /* RTCPacketOptions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RTCPacketOptions.cpp; sourceTree = "<group>"; };
                                4131F3CF1F96A9360059995A /* ServiceWorkerClientFetch.messages.in */,
                                4131F3D31F96E9310059995A /* ServiceWorkerContextManager.cpp */,
                                4131F3D21F96E9300059995A /* ServiceWorkerContextManager.h */,
                                4131F3CF1F96A9360059995A /* ServiceWorkerClientFetch.messages.in */,
                                4131F3D31F96E9310059995A /* ServiceWorkerContextManager.cpp */,
                                4131F3D21F96E9300059995A /* ServiceWorkerContextManager.h */,
+                               4131F3E01F98712C0059995A /* WebServiceWorkerFetchTaskClient.cpp */,
+                               419ACF9B1F981D26009F1A83 /* WebServiceWorkerFetchTaskClient.h */,
                                51BEB6291F3A5ACD005029B9 /* WebServiceWorkerProvider.cpp */,
                                51BEB62A1F3A5ACD005029B9 /* WebServiceWorkerProvider.h */,
                                517A53031F4793B200DCDC0A /* WebSWClientConnection.cpp */,
                                51BEB6291F3A5ACD005029B9 /* WebServiceWorkerProvider.cpp */,
                                51BEB62A1F3A5ACD005029B9 /* WebServiceWorkerProvider.h */,
                                517A53031F4793B200DCDC0A /* WebSWClientConnection.cpp */,
                                51F060E11654318500F3281C /* WebRTCSocketMessageReceiver.cpp in Sources */,
                                7C361D721927FA360036A59D /* WebScriptMessageHandler.cpp in Sources */,
                                D3B9484811FF4B6500032B39 /* WebSearchPopupMenu.cpp in Sources */,
                                51F060E11654318500F3281C /* WebRTCSocketMessageReceiver.cpp in Sources */,
                                7C361D721927FA360036A59D /* WebScriptMessageHandler.cpp in Sources */,
                                D3B9484811FF4B6500032B39 /* WebSearchPopupMenu.cpp in Sources */,
+                               4131F3E21F9880840059995A /* WebServiceWorkerFetchTaskClient.cpp in Sources */,
                                51BEB62B1F3A5AD7005029B9 /* WebServiceWorkerProvider.cpp in Sources */,
                                1A4832D61A9CDF96008B4DFE /* WebsiteData.cpp in Sources */,
                                1A4832D91A9D1FD2008B4DFE /* WebsiteDataRecord.cpp in Sources */,
                                51BEB62B1F3A5AD7005029B9 /* WebServiceWorkerProvider.cpp in Sources */,
                                1A4832D61A9CDF96008B4DFE /* WebsiteData.cpp in Sources */,
                                1A4832D91A9D1FD2008B4DFE /* WebsiteDataRecord.cpp in Sources */,
index 6139e5f..f23b35e 100644 (file)
@@ -88,6 +88,17 @@ void ServiceWorkerClientFetch::didFinish()
 
 void ServiceWorkerClientFetch::didFail()
 {
 
 void ServiceWorkerClientFetch::didFail()
 {
+    auto protectedThis = makeRef(*this);
+    m_loader->didFail({ });
+
+    if (auto callback = WTFMove(m_callback))
+        callback(Result::Succeeded);
+
+    m_serviceWorkerProvider.fetchFinished(m_identifier);
+}
+
+void ServiceWorkerClientFetch::didNotHandle()
+{
     if (auto callback = WTFMove(m_callback))
         callback(Result::Unhandled);
 
     if (auto callback = WTFMove(m_callback))
         callback(Result::Unhandled);
 
index 10bb60e..68de12b 100644 (file)
@@ -58,6 +58,7 @@ private:
     void didReceiveData(const IPC::DataReference&, int64_t encodedDataLength);
     void didFinish();
     void didFail();
     void didReceiveData(const IPC::DataReference&, int64_t encodedDataLength);
     void didFinish();
     void didFail();
+    void didNotHandle();
 
     IPC::Connection* messageSenderConnection() final { return m_connection.ptr(); }
     uint64_t messageSenderDestinationID() final { return m_identifier; }
 
     IPC::Connection* messageSenderConnection() final { return m_connection.ptr(); }
     uint64_t messageSenderDestinationID() final { return m_identifier; }
index a1081b4..40dda87 100644 (file)
@@ -27,6 +27,7 @@ messages -> ServiceWorkerClientFetch {
     DidReceiveData(IPC::DataReference data, int64_t encodedDataLength)
     DidFinish()
     DidFail()
     DidReceiveData(IPC::DataReference data, int64_t encodedDataLength)
     DidFinish()
     DidFail()
+    DidNotHandle()
 }
 
 #endif // ENABLE(SERVICE_WORKER)
 }
 
 #endif // ENABLE(SERVICE_WORKER)
index 47831a8..0def354 100644 (file)
@@ -31,6 +31,7 @@
 #include "Logging.h"
 #include "StorageProcessMessages.h"
 #include "WebCoreArgumentCoders.h"
 #include "Logging.h"
 #include "StorageProcessMessages.h"
 #include "WebCoreArgumentCoders.h"
+#include "WebServiceWorkerFetchTaskClient.h"
 #include <WebCore/ResourceRequest.h>
 #include <WebCore/ResourceResponse.h>
 #include <pal/SessionID.h>
 #include <WebCore/ResourceRequest.h>
 #include <WebCore/ResourceResponse.h>
 #include <pal/SessionID.h>
@@ -55,41 +56,16 @@ void ServiceWorkerContextManager::startServiceWorker(uint64_t serverConnectionId
     m_connectionToStorageProcess->send(Messages::StorageProcess::ServiceWorkerContextStarted(serverConnectionIdentifier, data.registrationKey, threadIdentifier, data.workerID), 0);
 }
 
     m_connectionToStorageProcess->send(Messages::StorageProcess::ServiceWorkerContextStarted(serverConnectionIdentifier, data.registrationKey, threadIdentifier, data.workerID), 0);
 }
 
-void ServiceWorkerContextManager::startFetch(uint64_t serverConnectionIdentifier, uint64_t fetchIdentifier, uint64_t serviceWorkerIdentifier, const ResourceRequest& request, const FetchOptions& options)
+void ServiceWorkerContextManager::startFetch(uint64_t serverConnectionIdentifier, uint64_t fetchIdentifier, uint64_t serviceWorkerIdentifier, ResourceRequest&& request, FetchOptions&& options)
 {
 {
-    UNUSED_PARAM(serviceWorkerIdentifier);
-
-    // FIXME: Hard coding some fetches for testing purpose until we implement the creation of fetch event.
-    if (request.url().string().contains("test1")) {
-        ResourceResponse response;
-        response.setURL(request.url());
-        response.setHTTPStatusCode(200);
-        response.setHTTPStatusText(ASCIILiteral("Hello from service worker"));
-        m_connectionToStorageProcess->send(Messages::StorageProcess::DidReceiveFetchResponse(serverConnectionIdentifier, fetchIdentifier, response), 0);
-        m_connectionToStorageProcess->send(Messages::StorageProcess::DidFinishFetch(serverConnectionIdentifier, fetchIdentifier), 0);
-        return;
-    }
-    if (request.url().string().contains("test2")) {
-        ResourceResponse response;
-        response.setURL(request.url());
-        response.setHTTPStatusCode(500);
-        response.setHTTPStatusText(ASCIILiteral("Error from service worker"));
-        m_connectionToStorageProcess->send(Messages::StorageProcess::DidReceiveFetchResponse(serverConnectionIdentifier, fetchIdentifier, response), 0);
-        m_connectionToStorageProcess->send(Messages::StorageProcess::DidFinishFetch(serverConnectionIdentifier, fetchIdentifier), 0);
-        return;
-    }
-    if (request.url().string().contains("test3")) {
-        ResourceResponse response;
-        response.setURL(request.url());
-        response.setHTTPStatusCode(500);
-        response.setHTTPStatusText(ASCIILiteral("Error from service worker"));
-        response.setType(ResourceResponse::Type::Error);
-        m_connectionToStorageProcess->send(Messages::StorageProcess::DidReceiveFetchResponse(serverConnectionIdentifier, fetchIdentifier, response), 0);
-        m_connectionToStorageProcess->send(Messages::StorageProcess::DidFinishFetch(serverConnectionIdentifier, fetchIdentifier), 0);
+    auto serviceWorkerThread = m_workerThreadMap.get(serviceWorkerIdentifier);
+    if (!serviceWorkerThread) {
+        m_connectionToStorageProcess->send(Messages::StorageProcess::DidNotHandleFetch(serverConnectionIdentifier, fetchIdentifier), 0);
         return;
     }
 
         return;
     }
 
-    m_connectionToStorageProcess->send(Messages::StorageProcess::DidFailFetch(serverConnectionIdentifier, fetchIdentifier), 0);
+    auto client = WebServiceWorkerFetchTaskClient::create(m_connectionToStorageProcess.copyRef(), serverConnectionIdentifier, fetchIdentifier);
+    serviceWorkerThread->postFetchTask(WTFMove(client), WTFMove(request), WTFMove(options));
 }
 
 } // namespace WebCore
 }
 
 } // namespace WebCore
index 2d7fd8d..8d200c0 100644 (file)
@@ -51,7 +51,7 @@ public:
 
 private:
     void startServiceWorker(uint64_t serverConnectionIdentifier, const WebCore::ServiceWorkerContextData&);
 
 private:
     void startServiceWorker(uint64_t serverConnectionIdentifier, const WebCore::ServiceWorkerContextData&);
-    void startFetch(uint64_t serverConnectionIdentifier, uint64_t fetchIdentifier, uint64_t serviceWorkerIdentifier, const WebCore::ResourceRequest&, const WebCore::FetchOptions&);
+    void startFetch(uint64_t serverConnectionIdentifier, uint64_t fetchIdentifier, uint64_t serviceWorkerIdentifier, WebCore::ResourceRequest&&, WebCore::FetchOptions&&);
 
     Ref<IPC::Connection> m_connectionToStorageProcess;
     HashMap<uint64_t, RefPtr<WebCore::ServiceWorkerThread>> m_workerThreadMap;
 
     Ref<IPC::Connection> m_connectionToStorageProcess;
     HashMap<uint64_t, RefPtr<WebCore::ServiceWorkerThread>> m_workerThreadMap;
diff --git a/Source/WebKit/WebProcess/Storage/WebServiceWorkerFetchTaskClient.cpp b/Source/WebKit/WebProcess/Storage/WebServiceWorkerFetchTaskClient.cpp
new file mode 100644 (file)
index 0000000..1fc6a8f
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 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.
+ */
+
+#include "config.h"
+#include "WebServiceWorkerFetchTaskClient.h"
+
+#if ENABLE(SERVICE_WORKER)
+
+#include "DataReference.h"
+#include "StorageProcessMessages.h"
+#include "WebCoreArgumentCoders.h"
+#include <WebCore/ResourceResponse.h>
+#include <wtf/RunLoop.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+WebServiceWorkerFetchTaskClient::~WebServiceWorkerFetchTaskClient()
+{
+    if (m_connection)
+        RunLoop::main().dispatch([connection = WTFMove(m_connection)] { });
+}
+
+WebServiceWorkerFetchTaskClient::WebServiceWorkerFetchTaskClient(Ref<IPC::Connection>&& connection, uint64_t serverConnectionIdentifier, uint64_t fetchTaskIdentifier)
+    : m_connection(WTFMove(connection))
+    , m_serverConnectionIdentifier(serverConnectionIdentifier)
+    , m_fetchTaskIdentifier(fetchTaskIdentifier)
+{
+}
+
+void WebServiceWorkerFetchTaskClient::didReceiveResponse(const ResourceResponse& response)
+{
+    if (!m_connection)
+        return;
+    m_connection->send(Messages::StorageProcess::DidReceiveFetchResponse { m_serverConnectionIdentifier, m_fetchTaskIdentifier, response }, 0);
+}
+
+void WebServiceWorkerFetchTaskClient::didReceiveData(Ref<SharedBuffer>&& buffer)
+{
+    if (!m_connection)
+        return;
+    IPC::SharedBufferDataReference dataReference { buffer.ptr() };
+    m_connection->send(Messages::StorageProcess::DidReceiveFetchData { m_serverConnectionIdentifier, m_fetchTaskIdentifier, dataReference, static_cast<int64_t>(buffer->size()) }, 0);
+}
+
+void WebServiceWorkerFetchTaskClient::didFail()
+{
+    if (!m_connection)
+        return;
+    m_connection->send(Messages::StorageProcess::DidFailFetch { m_serverConnectionIdentifier, m_fetchTaskIdentifier }, 0);
+    m_connection = nullptr;
+}
+
+void WebServiceWorkerFetchTaskClient::didFinish()
+{
+    if (!m_connection)
+        return;
+    m_connection->send(Messages::StorageProcess::DidFinishFetch { m_serverConnectionIdentifier, m_fetchTaskIdentifier }, 0);
+    m_connection = nullptr;
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(SERVICE_WORKER)
diff --git a/Source/WebKit/WebProcess/Storage/WebServiceWorkerFetchTaskClient.h b/Source/WebKit/WebProcess/Storage/WebServiceWorkerFetchTaskClient.h
new file mode 100644 (file)
index 0000000..4025ce2
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 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.
+ */
+
+#pragma once
+
+#if ENABLE(SERVICE_WORKER)
+
+#include "Connection.h"
+#include <WebCore/ServiceWorkerFetch.h>
+
+namespace WebKit {
+
+class WebServiceWorkerFetchTaskClient final : public WebCore::ServiceWorkerFetch::Client {
+public:
+    static Ref<WebServiceWorkerFetchTaskClient> create(Ref<IPC::Connection>&& connection, uint64_t serverConnectionIdentifier, uint64_t fetchTaskIdentifier)
+    {
+        return adoptRef(*new WebServiceWorkerFetchTaskClient(WTFMove(connection), serverConnectionIdentifier, fetchTaskIdentifier));
+    }
+
+    ~WebServiceWorkerFetchTaskClient();
+
+private:
+    WebServiceWorkerFetchTaskClient(Ref<IPC::Connection>&&, uint64_t serverConnectionIdentifier, uint64_t fetchTaskIdentifier);
+
+    void didReceiveResponse(const WebCore::ResourceResponse&) final;
+    void didReceiveData(Ref<WebCore::SharedBuffer>&&) final;
+    void didFail() final;
+    void didFinish() final;
+
+    RefPtr<IPC::Connection> m_connection;
+    uint64_t m_serverConnectionIdentifier { 0 };
+    uint64_t m_fetchTaskIdentifier { 0 };
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(SERVICE_WORKER)