Add (entirely incorrect) fetching of ServiceWorker scripts.
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 6 Oct 2017 16:20:04 +0000 (16:20 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 6 Oct 2017 16:20:04 +0000 (16:20 +0000)
https://bugs.webkit.org/show_bug.cgi?id=176179

Reviewed by Andy Estes.

Source/WebCore:

No new tests (Covered by changes to existing tests).

When the Storage process is running the "Update" algorithm and a ServiceWorker script file needs to be fetched, this patch:
  - Messages back to the WebContent process that started the register/update job
  - Executes a FetchLoad in that script context for the script
  - Sends the results back to the Storage process

We don't do anything with the results yet.

Soon.

* WebCore.xcodeproj/project.pbxproj:

* workers/WorkerScriptLoader.cpp:
(WebCore::WorkerScriptLoader::didFail):
* workers/WorkerScriptLoader.h:
(WebCore::WorkerScriptLoader::error const):

* workers/WorkerScriptLoaderClient.h:
(WebCore::WorkerScriptLoaderClient::~WorkerScriptLoaderClient):
(WebCore::WorkerScriptLoaderClient::didReceiveResponse): Deleted.
(WebCore::WorkerScriptLoaderClient::notifyFinished): Deleted.

* workers/service/ServiceWorkerContainer.cpp:
(WebCore::ServiceWorkerContainer::startScriptFetchForJob):
(WebCore::ServiceWorkerContainer::jobFinishedLoadingScript):
(WebCore::ServiceWorkerContainer::jobFailedLoadingScript):
* workers/service/ServiceWorkerContainer.h:

* workers/service/ServiceWorkerFetchResult.h: Copied from Source/WebCore/workers/service/server/SWClientConnection.h.
(WebCore::ServiceWorkerFetchResult::encode const):
(WebCore::ServiceWorkerFetchResult::decode):

* workers/service/ServiceWorkerJob.cpp:
(WebCore::ServiceWorkerJob::startScriptFetch):
(WebCore::ServiceWorkerJob::fetchScriptWithContext):
(WebCore::ServiceWorkerJob::didReceiveResponse):
(WebCore::ServiceWorkerJob::notifyFinished):
* workers/service/ServiceWorkerJob.h:
* workers/service/ServiceWorkerJobClient.h:

* workers/service/server/SWClientConnection.cpp:
(WebCore::SWClientConnection::finishedFetchingScript):
(WebCore::SWClientConnection::failedFetchingScript):
(WebCore::SWClientConnection::startScriptFetchForServer):
* workers/service/server/SWClientConnection.h:

* workers/service/server/SWServer.cpp:
(WebCore::SWServer::Connection::finishFetchingScriptInServer):
(WebCore::SWServer::startScriptFetch):
(WebCore::SWServer::scriptFetchFinished):
* workers/service/server/SWServer.h:

* workers/service/server/SWServerRegistration.cpp:
(WebCore::SWServerRegistration::scriptFetchFinished):
(WebCore::SWServerRegistration::runUpdateJob):
(WebCore::SWServerRegistration::startScriptFetchFromMainThread):
(WebCore::SWServerRegistration::startScriptFetchForCurrentJob):
* workers/service/server/SWServerRegistration.h:

Source/WebKit:

* StorageProcess/ServiceWorker/WebSWServerConnection.cpp:
(WebKit::WebSWServerConnection::startScriptFetchInClient):
* StorageProcess/ServiceWorker/WebSWServerConnection.h:
* StorageProcess/ServiceWorker/WebSWServerConnection.messages.in:

* WebProcess/Storage/WebSWClientConnection.cpp:
(WebKit::WebSWClientConnection::finishFetchingScriptInServer):
* WebProcess/Storage/WebSWClientConnection.h:
* WebProcess/Storage/WebSWClientConnection.messages.in:

LayoutTests:

* http/tests/workers/service/basic-register-exceptions-expected.txt:
* http/tests/workers/service/basic-register-expected.txt:
* http/tests/workers/service/resources/basic-register-exceptions.js:
* http/tests/workers/service/resources/basic-register.js:
* http/tests/workers/service/resources/registration-task-queue-scheduling-1.js:

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

30 files changed:
LayoutTests/ChangeLog
LayoutTests/http/tests/workers/service/basic-register-exceptions-expected.txt
LayoutTests/http/tests/workers/service/basic-register-expected.txt
LayoutTests/http/tests/workers/service/resources/basic-register-exceptions.js
LayoutTests/http/tests/workers/service/resources/basic-register.js
LayoutTests/http/tests/workers/service/resources/registration-task-queue-scheduling-1.js
Source/WebCore/ChangeLog
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/workers/WorkerScriptLoader.cpp
Source/WebCore/workers/WorkerScriptLoader.h
Source/WebCore/workers/WorkerScriptLoaderClient.h
Source/WebCore/workers/service/ServiceWorkerContainer.cpp
Source/WebCore/workers/service/ServiceWorkerContainer.h
Source/WebCore/workers/service/ServiceWorkerFetchResult.h [new file with mode: 0644]
Source/WebCore/workers/service/ServiceWorkerJob.cpp
Source/WebCore/workers/service/ServiceWorkerJob.h
Source/WebCore/workers/service/ServiceWorkerJobClient.h
Source/WebCore/workers/service/server/SWClientConnection.cpp
Source/WebCore/workers/service/server/SWClientConnection.h
Source/WebCore/workers/service/server/SWServer.cpp
Source/WebCore/workers/service/server/SWServer.h
Source/WebCore/workers/service/server/SWServerRegistration.cpp
Source/WebCore/workers/service/server/SWServerRegistration.h
Source/WebKit/ChangeLog
Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.cpp
Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.h
Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.messages.in
Source/WebKit/WebProcess/Storage/WebSWClientConnection.cpp
Source/WebKit/WebProcess/Storage/WebSWClientConnection.h
Source/WebKit/WebProcess/Storage/WebSWClientConnection.messages.in

index 63d1bf3..786f44d 100644 (file)
@@ -1,3 +1,16 @@
+2017-10-06  Brady Eidson  <beidson@apple.com>
+
+        Add (entirely incorrect) fetching of ServiceWorker scripts.
+        https://bugs.webkit.org/show_bug.cgi?id=176179
+
+        Reviewed by Andy Estes.
+
+        * http/tests/workers/service/basic-register-exceptions-expected.txt:
+        * http/tests/workers/service/basic-register-expected.txt:
+        * http/tests/workers/service/resources/basic-register-exceptions.js:
+        * http/tests/workers/service/resources/basic-register.js:
+        * http/tests/workers/service/resources/registration-task-queue-scheduling-1.js:
+
 2017-10-06  Ryan Haddad  <ryanhaddad@apple.com>
 
         Rebaseline js/dom/global-constructors-attributes.html
index df29d25..34f6496 100644 (file)
@@ -1,9 +1,10 @@
-CONSOLE MESSAGE: line 10: Registration failed with error: TypeError: serviceWorker.register() cannot be called with an empty script URL
-CONSOLE MESSAGE: line 20: Registration failed with error: TypeError: serviceWorker.register() must be called with a valid relative script URL
-CONSOLE MESSAGE: line 30: Registration failed with error: TypeError: serviceWorker.register() must be called with a script URL whose protocol is either HTTP or HTTPS
-CONSOLE MESSAGE: line 40: Registration failed with error: TypeError: serviceWorker.register() must be called with a script URL whose path does not contain '%2f' or '%5c'
-CONSOLE MESSAGE: line 50: Registration failed with error: TypeError: Scope URL provided to serviceWorker.register() must be either HTTP or HTTPS
-CONSOLE MESSAGE: line 60: Registration failed with error: TypeError: Scope URL provided to serviceWorker.register() cannot have a path that contains '%2f' or '%5c'
-CONSOLE MESSAGE: line 70: Registration failed with error: SecurityError: Script origin does not match the registering client's origin
-CONSOLE MESSAGE: line 81: Registration failed with error: SecurityError: Scope origin does not match the registering client's origin
+CONSOLE MESSAGE: line 20: Registration failed with error: TypeError: serviceWorker.register() cannot be called with an empty script URL
+CONSOLE MESSAGE: line 30: Registration failed with error: TypeError: serviceWorker.register() must be called with a valid relative script URL
+CONSOLE MESSAGE: line 40: Registration failed with error: TypeError: serviceWorker.register() must be called with a script URL whose protocol is either HTTP or HTTPS
+CONSOLE MESSAGE: line 50: Registration failed with error: TypeError: serviceWorker.register() must be called with a script URL whose path does not contain '%2f' or '%5c'
+CONSOLE MESSAGE: line 60: Registration failed with error: TypeError: Scope URL provided to serviceWorker.register() must be either HTTP or HTTPS
+CONSOLE MESSAGE: line 70: Registration failed with error: TypeError: Scope URL provided to serviceWorker.register() cannot have a path that contains '%2f' or '%5c'
+CONSOLE MESSAGE: line 10: Registration failed with error: UnknownError: Script URL http://127.0.0.1:8000/workers/service/image-mime-type.php fetched with 0 characters, but we're not using the result yet
+CONSOLE MESSAGE: line 80: Registration failed with error: SecurityError: Script origin does not match the registering client's origin
+CONSOLE MESSAGE: line 91: Registration failed with error: SecurityError: Scope origin does not match the registering client's origin
 
index c018e45..4940778 100644 (file)
@@ -1,2 +1,3 @@
-CONSOLE MESSAGE: line 11: Registration failed with error: UnknownError: serviceWorker job scheduling is not yet implemented
+CONSOLE MESSAGE: line 10: Registration failed with error: UnknownError: Script URL http://127.0.0.1:8000/workers/service/resources/empty-worker.js fetched with 41 characters, but we're not using the result yet
+CONSOLE MESSAGE: line 21: Registration failed with error: UnknownError: Script URL http://127.0.0.1:8000/workers/service/resources/empty-worker-doesnt-exist.js fetched with 0 characters, but we're not using the result yet
 
index 8a0306f..78d1d8a 100644 (file)
@@ -3,6 +3,16 @@ function done()
     finishSWTest();
 }
 
+navigator.serviceWorker.register("image-mime-type.php", { })
+.then(function(r) {
+       console.log("Registered! (unexpectedly)");
+}, function(e) {
+       console.log("Registration failed with error: " + e);
+})
+.catch(function(e) {
+       console.log("Exception registering: " + e);
+});
+
 navigator.serviceWorker.register("", { })
 .then(function(r) {
        console.log("Registered! (unexpectedly)");
index e7516fe..3a1e63b 100644 (file)
@@ -6,6 +6,16 @@ function done()
 navigator.serviceWorker.register("resources/empty-worker.js", { })
 .then(function(r) {
        console.log("Registered!");
+}, function(e) {
+       console.log("Registration failed with error: " + e);
+})
+.catch(function(e) {
+       console.log("Exception registering: " + e);
+});
+
+navigator.serviceWorker.register("resources/empty-worker-doesnt-exist.js", { })
+.then(function(r) {
+       console.log("Registered!");
        done();
 }, function(e) {
        console.log("Registration failed with error: " + e);
index 127a3db..00fec93 100644 (file)
@@ -48,8 +48,8 @@ for (var i = 0; i < 1000; ++i) {
                console.log("Original window resolved successfully (unexpected)")
                done();
        }, function(e) {
-               if (e+"" != "UnknownError: serviceWorker job scheduling is not yet implemented") {
-                       alert("Unexpected error received from server");
+               if (e+"" != "UnknownError: Script URL http://127.0.0.1:8000/workers/service/resources/empty-worker.js fetched with 41 characters, but we're not using the result yet") {
+                       alert("Unexpected error received from server: " + e);
                        finishSWTest();
                }
                
index 5058eaa..ca48220 100644 (file)
@@ -1,3 +1,70 @@
+2017-10-06  Brady Eidson  <beidson@apple.com>
+
+        Add (entirely incorrect) fetching of ServiceWorker scripts.
+        https://bugs.webkit.org/show_bug.cgi?id=176179
+
+        Reviewed by Andy Estes.
+
+        No new tests (Covered by changes to existing tests).
+
+        When the Storage process is running the "Update" algorithm and a ServiceWorker script file needs to be fetched, this patch:
+          - Messages back to the WebContent process that started the register/update job
+          - Executes a FetchLoad in that script context for the script
+          - Sends the results back to the Storage process
+
+        We don't do anything with the results yet.
+
+        Soon.
+
+        * WebCore.xcodeproj/project.pbxproj:
+
+        * workers/WorkerScriptLoader.cpp:
+        (WebCore::WorkerScriptLoader::didFail):
+        * workers/WorkerScriptLoader.h:
+        (WebCore::WorkerScriptLoader::error const):
+
+        * workers/WorkerScriptLoaderClient.h:
+        (WebCore::WorkerScriptLoaderClient::~WorkerScriptLoaderClient):
+        (WebCore::WorkerScriptLoaderClient::didReceiveResponse): Deleted.
+        (WebCore::WorkerScriptLoaderClient::notifyFinished): Deleted.
+
+        * workers/service/ServiceWorkerContainer.cpp:
+        (WebCore::ServiceWorkerContainer::startScriptFetchForJob):
+        (WebCore::ServiceWorkerContainer::jobFinishedLoadingScript):
+        (WebCore::ServiceWorkerContainer::jobFailedLoadingScript):
+        * workers/service/ServiceWorkerContainer.h:
+
+        * workers/service/ServiceWorkerFetchResult.h: Copied from Source/WebCore/workers/service/server/SWClientConnection.h.
+        (WebCore::ServiceWorkerFetchResult::encode const):
+        (WebCore::ServiceWorkerFetchResult::decode):
+
+        * workers/service/ServiceWorkerJob.cpp:
+        (WebCore::ServiceWorkerJob::startScriptFetch):
+        (WebCore::ServiceWorkerJob::fetchScriptWithContext):
+        (WebCore::ServiceWorkerJob::didReceiveResponse):
+        (WebCore::ServiceWorkerJob::notifyFinished):
+        * workers/service/ServiceWorkerJob.h:
+        * workers/service/ServiceWorkerJobClient.h:
+
+        * workers/service/server/SWClientConnection.cpp:
+        (WebCore::SWClientConnection::finishedFetchingScript):
+        (WebCore::SWClientConnection::failedFetchingScript):
+        (WebCore::SWClientConnection::startScriptFetchForServer):
+        * workers/service/server/SWClientConnection.h:
+
+        * workers/service/server/SWServer.cpp:
+        (WebCore::SWServer::Connection::finishFetchingScriptInServer):
+        (WebCore::SWServer::startScriptFetch):
+        (WebCore::SWServer::scriptFetchFinished):
+        * workers/service/server/SWServer.h:
+
+        * workers/service/server/SWServerRegistration.cpp:
+        (WebCore::SWServerRegistration::scriptFetchFinished):
+        (WebCore::SWServerRegistration::runUpdateJob):
+        (WebCore::SWServerRegistration::startScriptFetchFromMainThread):
+        (WebCore::SWServerRegistration::startScriptFetchForCurrentJob):
+        * workers/service/server/SWServerRegistration.h:
+
 2017-10-06  Zan Dobersek  <zdobersek@igalia.com>
 
         [Cairo] Create Cairo patterns from Gradient objects on-the-fly
index e02992e..5c14562 100644 (file)
                2E94F43B119207DA00B7F75D /* JSFileReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2E94F439119207DA00B7F75D /* JSFileReader.cpp */; };
                2E94F43C119207DA00B7F75D /* JSFileReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 2E94F43A119207DA00B7F75D /* JSFileReader.h */; };
                2E9B5D8F1B66A94E008C6A24 /* WheelEventDeltaFilterMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 2E9B5D8E1B66A94E008C6A24 /* WheelEventDeltaFilterMac.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               2EA768040FE7126400AB9C8A /* WorkerScriptLoaderClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 2EA768030FE7126400AB9C8A /* WorkerScriptLoaderClient.h */; };
+               2EA768040FE7126400AB9C8A /* WorkerScriptLoaderClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 2EA768030FE7126400AB9C8A /* WorkerScriptLoaderClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
                2EB4BCD2121F03E300EC4885 /* BlobResourceHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2EB4BCD0121F03E300EC4885 /* BlobResourceHandle.cpp */; };
                2EB4BCD3121F03E300EC4885 /* BlobResourceHandle.h in Headers */ = {isa = PBXBuildFile; fileRef = 2EB4BCD1121F03E300EC4885 /* BlobResourceHandle.h */; };
                2EB767561DA19B99003E23B5 /* InputEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2EB767551DA19B99003E23B5 /* InputEvent.cpp */; };
                517A53461F50C17F00DCDC0A /* SWServerWorker.h in Headers */ = {isa = PBXBuildFile; fileRef = 517A53421F50C16100DCDC0A /* SWServerWorker.h */; settings = {ATTRIBUTES = (Private, ); }; };
                517A534E1F54A8BA00DCDC0A /* ServiceWorkerRegistrationData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 517A534B1F549D4A00DCDC0A /* ServiceWorkerRegistrationData.cpp */; };
                517A534F1F54A8BA00DCDC0A /* ServiceWorkerRegistrationData.h in Headers */ = {isa = PBXBuildFile; fileRef = 517A534C1F549D4A00DCDC0A /* ServiceWorkerRegistrationData.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               517A53581F5889E800DCDC0A /* FetchLoaderClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4147E2B61C89912600A7E715 /* FetchLoaderClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               517A535A1F5889EF00DCDC0A /* FetchLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 4147E2B51C89912600A7E715 /* FetchLoader.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               517A535B1F588A4C00DCDC0A /* FetchBodyConsumer.h in Headers */ = {isa = PBXBuildFile; fileRef = 41CF8BE51D46222000707DC9 /* FetchBodyConsumer.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               517A535D1F5899FE00DCDC0A /* ServiceWorkerFetchResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 517A535C1F5899F200DCDC0A /* ServiceWorkerFetchResult.h */; settings = {ATTRIBUTES = (Private, ); }; };
                517A63C31B74318700E7DCDC /* KeyedDecoderCF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 517A63BF1B74317E00E7DCDC /* KeyedDecoderCF.cpp */; };
                517A63C41B74318B00E7DCDC /* KeyedEncoderCF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 517A63C11B74317E00E7DCDC /* KeyedEncoderCF.cpp */; };
                517A63C51B74318F00E7DCDC /* KeyedDecoderCF.h in Headers */ = {isa = PBXBuildFile; fileRef = 517A63C01B74317E00E7DCDC /* KeyedDecoderCF.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A7D20F62107F406900A80392 /* JSWebGLActiveInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7D20F60107F406900A80392 /* JSWebGLActiveInfo.cpp */; };
                A7D20F63107F406900A80392 /* JSWebGLActiveInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D20F61107F406900A80392 /* JSWebGLActiveInfo.h */; };
                A7D20F6D107F438B00A80392 /* WebGLActiveInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D20F6B107F438B00A80392 /* WebGLActiveInfo.h */; };
-               A7D6B3490F61104500B79FD1 /* WorkerScriptLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D6B3470F61104500B79FD1 /* WorkerScriptLoader.h */; };
+               A7D6B3490F61104500B79FD1 /* WorkerScriptLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D6B3470F61104500B79FD1 /* WorkerScriptLoader.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A7D6B34A0F61104500B79FD1 /* WorkerScriptLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7D6B3480F61104500B79FD1 /* WorkerScriptLoader.cpp */; };
                A7DBF8DD1276919C006B6008 /* TextCheckingHelper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7DBF8DB1276919C006B6008 /* TextCheckingHelper.cpp */; };
                A7DBF8DE1276919C006B6008 /* TextCheckingHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = A7DBF8DC1276919C006B6008 /* TextCheckingHelper.h */; };
                517A53431F50C16100DCDC0A /* SWServerWorker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SWServerWorker.cpp; sourceTree = "<group>"; };
                517A534B1F549D4A00DCDC0A /* ServiceWorkerRegistrationData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ServiceWorkerRegistrationData.cpp; sourceTree = "<group>"; };
                517A534C1F549D4A00DCDC0A /* ServiceWorkerRegistrationData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ServiceWorkerRegistrationData.h; sourceTree = "<group>"; };
+               517A535C1F5899F200DCDC0A /* ServiceWorkerFetchResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ServiceWorkerFetchResult.h; sourceTree = "<group>"; };
                517A63BF1B74317E00E7DCDC /* KeyedDecoderCF.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KeyedDecoderCF.cpp; sourceTree = "<group>"; };
                517A63C01B74317E00E7DCDC /* KeyedDecoderCF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KeyedDecoderCF.h; sourceTree = "<group>"; };
                517A63C11B74317E00E7DCDC /* KeyedEncoderCF.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KeyedEncoderCF.cpp; sourceTree = "<group>"; };
                                51F175581F3EBC0C00C74950 /* ServiceWorkerContainer.cpp */,
                                51F175571F3EBC0C00C74950 /* ServiceWorkerContainer.h */,
                                51F175561F3EBC0C00C74950 /* ServiceWorkerContainer.idl */,
+                               517A535C1F5899F200DCDC0A /* ServiceWorkerFetchResult.h */,
                                51F175551F3EBC0C00C74950 /* ServiceWorkerGlobalScope.cpp */,
                                51F175541F3EBC0C00C74950 /* ServiceWorkerGlobalScope.h */,
                                51F175531F3EBC0C00C74950 /* ServiceWorkerGlobalScope.idl */,
                                93F198E508245E59001E9ABC /* HTMLDocument.h in Headers */,
                                977B3867122883E900B81FF8 /* HTMLDocumentParser.h in Headers */,
                                93F198E608245E59001E9ABC /* HTMLElement.h in Headers */,
+                               517A53581F5889E800DCDC0A /* FetchLoaderClient.h in Headers */,
                                A17C81230F2A5CF7005DAAEB /* HTMLElementFactory.h in Headers */,
                                977B37241228721700B81FF8 /* HTMLElementStack.h in Headers */,
                                B562DB6017D3CD630010AF96 /* HTMLElementTypeHelpers.h in Headers */,
                                FA654A6C1108ABED002626F1 /* MathMLUnderOverElement.h in Headers */,
                                37C738EF1EDBD71B003F2B0B /* MathMLUnknownElement.h in Headers */,
                                439046EA12DA25E812AF80AC /* MathOperator.h in Headers */,
+                               517A535B1F588A4C00DCDC0A /* FetchBodyConsumer.h in Headers */,
                                49D5DC2C0F423A73008F20FD /* Matrix3DTransformOperation.h in Headers */,
                                49E911C70EF86D47009D0CAF /* MatrixTransformOperation.h in Headers */,
                                5CBC8DAD1AAA302200E1C803 /* MediaAccessibilitySoftLink.h in Headers */,
                                656D37430ADBA5DE00A4554D /* NetscapePlugInStreamLoader.h in Headers */,
                                A19D934B1AA11B1E00B46C24 /* NetworkExtensionContentFilter.h in Headers */,
                                628D214C12131ED10055DCFC /* NetworkingContext.h in Headers */,
+                               517A535D1F5899FE00DCDC0A /* ServiceWorkerFetchResult.h in Headers */,
                                8A81BF8511DCFD9000DA2B98 /* NetworkLoadMetrics.h in Headers */,
                                59C27F07138D28CF0079B7E2 /* NetworkResourcesData.h in Headers */,
                                1A7FA6190DDA3B3A0028F8A5 /* NetworkStateNotifier.h in Headers */,
index 35bcb16..9720a97 100644 (file)
@@ -164,8 +164,9 @@ void WorkerScriptLoader::didFinishLoading(unsigned long identifier)
     notifyFinished();
 }
 
-void WorkerScriptLoader::didFail(const ResourceError&)
+void WorkerScriptLoader::didFail(const ResourceError& error)
 {
+    m_error = error;
     notifyError();
 }
 
index c80798a..a86c574 100644 (file)
 
 #pragma once
 
-#include "URL.h"
+#include "ResourceError.h"
 #include "ResourceRequest.h"
 #include "ThreadableLoader.h"
 #include "ThreadableLoaderClient.h"
+#include "URL.h"
 #include <memory>
 #include <wtf/FastMalloc.h>
 #include <wtf/RefCounted.h>
 
 namespace WebCore {
 
-    class ResourceResponse;
-    class ScriptExecutionContext;
-    class TextResourceDecoder;
-    class WorkerScriptLoaderClient;
+class ResourceResponse;
+class ScriptExecutionContext;
+class TextResourceDecoder;
+class WorkerScriptLoaderClient;
 
-    class WorkerScriptLoader : public RefCounted<WorkerScriptLoader>, public ThreadableLoaderClient {
-        WTF_MAKE_FAST_ALLOCATED;
-    public:
-        static Ref<WorkerScriptLoader> create()
-        {
-            return adoptRef(*new WorkerScriptLoader);
-        }
+class WorkerScriptLoader : public RefCounted<WorkerScriptLoader>, public ThreadableLoaderClient {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    static Ref<WorkerScriptLoader> create()
+    {
+        return adoptRef(*new WorkerScriptLoader);
+    }
 
-        void loadSynchronously(ScriptExecutionContext*, const URL&, FetchOptions::Mode, ContentSecurityPolicyEnforcement, const String& initiatorIdentifier);
-        void loadAsynchronously(ScriptExecutionContext*, const URL&, FetchOptions::Mode, ContentSecurityPolicyEnforcement, const String& initiatorIdentifier, WorkerScriptLoaderClient*);
+    void loadSynchronously(ScriptExecutionContext*, const URL&, FetchOptions::Mode, ContentSecurityPolicyEnforcement, const String& initiatorIdentifier);
+    void loadAsynchronously(ScriptExecutionContext*, const URL&, FetchOptions::Mode, ContentSecurityPolicyEnforcement, const String& initiatorIdentifier, WorkerScriptLoaderClient*);
 
-        void notifyError();
+    void notifyError();
 
-        String script();
-        const URL& url() const { return m_url; }
-        const URL& responseURL() const;
-        bool failed() const { return m_failed; }
-        unsigned long identifier() const { return m_identifier; }
+    String script();
+    const URL& url() const { return m_url; }
+    const URL& responseURL() const;
+    bool failed() const { return m_failed; }
+    unsigned long identifier() const { return m_identifier; }
+    const ResourceError& error() const { return m_error; }
 
-        void didReceiveResponse(unsigned long identifier, const ResourceResponse&) override;
-        void didReceiveData(const char* data, int dataLength) override;
-        void didFinishLoading(unsigned long identifier) override;
-        void didFail(const ResourceError&) override;
+    void didReceiveResponse(unsigned long identifier, const ResourceResponse&) override;
+    void didReceiveData(const char* data, int dataLength) override;
+    void didFinishLoading(unsigned long identifier) override;
+    void didFail(const ResourceError&) override;
 
-    private:
-        friend class WTF::RefCounted<WorkerScriptLoader>;
+private:
+    friend class WTF::RefCounted<WorkerScriptLoader>;
 
-        WorkerScriptLoader();
-        ~WorkerScriptLoader();
+    WorkerScriptLoader();
+    ~WorkerScriptLoader();
 
-        std::unique_ptr<ResourceRequest> createResourceRequest(const String& initiatorIdentifier);
-        void notifyFinished();
+    std::unique_ptr<ResourceRequest> createResourceRequest(const String& initiatorIdentifier);
+    void notifyFinished();
 
-        WorkerScriptLoaderClient* m_client { nullptr };
-        RefPtr<ThreadableLoader> m_threadableLoader;
-        String m_responseEncoding;        
-        RefPtr<TextResourceDecoder> m_decoder;
-        StringBuilder m_script;
-        URL m_url;
-        URL m_responseURL;
-        unsigned long m_identifier { 0 };
-        bool m_failed { false };
-        bool m_finishing { false };
-    };
+    WorkerScriptLoaderClient* m_client { nullptr };
+    RefPtr<ThreadableLoader> m_threadableLoader;
+    String m_responseEncoding;
+    RefPtr<TextResourceDecoder> m_decoder;
+    StringBuilder m_script;
+    URL m_url;
+    URL m_responseURL;
+    unsigned long m_identifier { 0 };
+    bool m_failed { false };
+    bool m_finishing { false };
+    ResourceError m_error;
+};
 
 } // namespace WebCore
index 10d06c7..d60e19c 100644 (file)
 
 namespace WebCore {
 
-    class ResourceResponse;
+class ResourceResponse;
 
-    class WorkerScriptLoaderClient {
-    public:
-        virtual void didReceiveResponse(unsigned long /*identifier*/, const ResourceResponse&) { }
+class WorkerScriptLoaderClient {
+public:
+    virtual void didReceiveResponse(unsigned long identifier, const ResourceResponse&) = 0;
+    virtual void notifyFinished() = 0;
 
-        // FIXME: notifyFinished() is not currently guaranteed to be invoked if used from worker context and the worker shuts down in the middle of an operation.
-        // This will cause leaks when we support nested workers.
-        virtual void notifyFinished() { }
-
-    protected:
-        virtual ~WorkerScriptLoaderClient() { }
-    };
+protected:
+    virtual ~WorkerScriptLoaderClient() { }
+};
 
 } // namespace WebCore
index 5c1ecdf..d30dc57 100644 (file)
@@ -32,7 +32,9 @@
 #include "IDLTypes.h"
 #include "JSDOMPromiseDeferred.h"
 #include "JSServiceWorkerRegistration.h"
+#include "Logging.h"
 #include "NavigatorBase.h"
+#include "ResourceError.h"
 #include "ScopeGuard.h"
 #include "ScriptExecutionContext.h"
 #include "SecurityOrigin.h"
@@ -181,6 +183,35 @@ void ServiceWorkerContainer::jobResolvedWithRegistration(ServiceWorkerJob& job,
     job.promise().resolve<IDLInterface<ServiceWorkerRegistration>>(registration.get());
 }
 
+void ServiceWorkerContainer::startScriptFetchForJob(ServiceWorkerJob& job)
+{
+    LOG(ServiceWorker, "SeviceWorkerContainer %p starting script fetch for job %" PRIu64, this, job.data().identifier());
+
+    auto* context = scriptExecutionContext();
+    if (!context) {
+        LOG_ERROR("ServiceWorkerContainer::jobResolvedWithRegistration called but the container's ScriptExecutionContext is gone");
+        m_swConnection->failedFetchingScript(job, { errorDomainWebKitInternal, 0, job.data().scriptURL, ASCIILiteral("Attempt to fetch service worker script with no ScriptExecutionContext") });
+        jobDidFinish(job);
+        return;
+    }
+
+    job.fetchScriptWithContext(*context);
+}
+
+void ServiceWorkerContainer::jobFinishedLoadingScript(ServiceWorkerJob& job, const String& script)
+{
+    LOG(ServiceWorker, "SeviceWorkerContainer %p finished fetching script for job %" PRIu64, this, job.data().identifier());
+
+    m_swConnection->finishedFetchingScript(job, script);
+}
+
+void ServiceWorkerContainer::jobFailedLoadingScript(ServiceWorkerJob& job, const ResourceError& error)
+{
+    LOG(ServiceWorker, "SeviceWorkerContainer %p failed fetching script for job %" PRIu64, this, job.data().identifier());
+
+    m_swConnection->failedFetchingScript(job, error);
+}
+
 void ServiceWorkerContainer::jobDidFinish(ServiceWorkerJob& job)
 {
     auto taken = m_jobMap.take(job.data().identifier());
index ecdfd14..ff4c78d 100644 (file)
@@ -73,6 +73,10 @@ private:
 
     void jobFailedWithException(ServiceWorkerJob&, const Exception&) final;
     void jobResolvedWithRegistration(ServiceWorkerJob&, const ServiceWorkerRegistrationData&) final;
+    void startScriptFetchForJob(ServiceWorkerJob&) final;
+    void jobFinishedLoadingScript(ServiceWorkerJob&, const String&) final;
+    void jobFailedLoadingScript(ServiceWorkerJob&, const ResourceError&) final;
+
     void jobDidFinish(ServiceWorkerJob&);
 
     uint64_t connectionIdentifier() final;
diff --git a/Source/WebCore/workers/service/ServiceWorkerFetchResult.h b/Source/WebCore/workers/service/ServiceWorkerFetchResult.h
new file mode 100644 (file)
index 0000000..ef7e72d
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * 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 "ResourceError.h"
+#include "ServiceWorkerRegistrationKey.h"
+
+namespace WebCore {
+
+struct ServiceWorkerFetchResult {
+    uint64_t jobIdentifier;
+    uint64_t connectionIdentifier;
+    ServiceWorkerRegistrationKey registrationKey;
+    String script;
+    ResourceError scriptError;
+
+    template<class Encoder> void encode(Encoder&) const;
+    template<class Decoder> static bool decode(Decoder&, ServiceWorkerFetchResult&);
+};
+
+template<class Encoder>
+void ServiceWorkerFetchResult::encode(Encoder& encoder) const
+{
+    encoder << jobIdentifier << connectionIdentifier << registrationKey << script << scriptError;
+}
+
+template<class Decoder>
+bool ServiceWorkerFetchResult::decode(Decoder& decoder, ServiceWorkerFetchResult& result)
+{
+    if (!decoder.decode(result.jobIdentifier))
+        return false;
+    if (!decoder.decode(result.connectionIdentifier))
+        return false;
+    
+    auto registrationKey = ServiceWorkerRegistrationKey::decode(decoder);
+    if (!registrationKey)
+        return false;
+    std::swap(*registrationKey, result.registrationKey);
+
+    if (!decoder.decode(result.script))
+        return false;
+    if (!decoder.decode(result.scriptError))
+        return false;
+
+    return true;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(SERVICE_WORKER)
index 49fb08e..231e041 100644 (file)
@@ -29,6 +29,8 @@
 #if ENABLE(SERVICE_WORKER)
 
 #include "JSDOMPromiseDeferred.h"
+#include "ResourceError.h"
+#include "ResourceResponse.h"
 #include "ServiceWorkerJobData.h"
 #include "ServiceWorkerRegistration.h"
 
@@ -64,6 +66,46 @@ void ServiceWorkerJob::resolvedWithRegistration(const ServiceWorkerRegistrationD
     m_client->jobResolvedWithRegistration(*this, data);
 }
 
+void ServiceWorkerJob::startScriptFetch()
+{
+    ASSERT(currentThread() == m_creationThread);
+    ASSERT(!m_completed);
+
+    m_client->startScriptFetchForJob(*this);
+}
+
+void ServiceWorkerJob::fetchScriptWithContext(ScriptExecutionContext& context)
+{
+    ASSERT(currentThread() == m_creationThread);
+    ASSERT(!m_completed);
+
+    // FIXME: WorkerScriptLoader is the wrong loader class to use here, but there's nothing else better right now.
+    m_scriptLoader = WorkerScriptLoader::create();
+    m_scriptLoader->loadAsynchronously(&context, m_jobData.scriptURL, FetchOptions::Mode::SameOrigin, ContentSecurityPolicyEnforcement::DoNotEnforce, "serviceWorkerScriptLoad:", this);
+}
+
+void ServiceWorkerJob::didReceiveResponse(unsigned long, const ResourceResponse& response)
+{
+    ASSERT(currentThread() == m_creationThread);
+    ASSERT(!m_completed);
+    ASSERT(m_scriptLoader);
+
+    m_lastResponse = response;
+}
+
+void ServiceWorkerJob::notifyFinished()
+{
+    ASSERT(currentThread() == m_creationThread);
+    ASSERT(m_scriptLoader);
+    
+    if (!m_scriptLoader->failed())
+        m_client->jobFinishedLoadingScript(*this, m_scriptLoader->script());
+    else
+        m_client->jobFailedLoadingScript(*this, m_scriptLoader->error());
+
+    m_scriptLoader = nullptr;
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(SERVICE_WORKER)
index d97ac1a..77d2183 100644 (file)
 
 #if ENABLE(SERVICE_WORKER)
 
+#include "ResourceResponse.h"
 #include "ServiceWorkerJobClient.h"
 #include "ServiceWorkerJobData.h"
+#include "WorkerScriptLoader.h"
+#include "WorkerScriptLoaderClient.h"
 #include <wtf/RefPtr.h>
 #include <wtf/RunLoop.h>
 #include <wtf/ThreadSafeRefCounted.h>
@@ -38,10 +41,11 @@ namespace WebCore {
 
 class DeferredPromise;
 class Exception;
+class ScriptExecutionContext;
 enum class ServiceWorkerJobType;
 struct ServiceWorkerRegistrationData;
 
-class ServiceWorkerJob : public ThreadSafeRefCounted<ServiceWorkerJob> {
+class ServiceWorkerJob : public ThreadSafeRefCounted<ServiceWorkerJob>, public WorkerScriptLoaderClient {
 public:
     static Ref<ServiceWorkerJob> create(ServiceWorkerJobClient& client, Ref<DeferredPromise>&& promise, ServiceWorkerJobData&& jobData)
     {
@@ -52,13 +56,20 @@ public:
 
     void failedWithException(const Exception&);
     void resolvedWithRegistration(const ServiceWorkerRegistrationData&);
+    void startScriptFetch();
 
     ServiceWorkerJobData data() const { return m_jobData; }
     DeferredPromise& promise() { return m_promise.get(); }
 
+    void fetchScriptWithContext(ScriptExecutionContext&);
+
 private:
     ServiceWorkerJob(ServiceWorkerJobClient&, Ref<DeferredPromise>&&, ServiceWorkerJobData&&);
 
+    // WorkerScriptLoaderClient
+    void didReceiveResponse(unsigned long identifier, const ResourceResponse&) final;
+    void notifyFinished() final;
+
     Ref<ServiceWorkerJobClient> m_client;
     ServiceWorkerJobData m_jobData;
     Ref<DeferredPromise> m_promise;
@@ -66,6 +77,8 @@ private:
     bool m_completed { false };
 
     Ref<RunLoop> m_runLoop { RunLoop::current() };
+    RefPtr<WorkerScriptLoader> m_scriptLoader;
+    ResourceResponse m_lastResponse;
 
 #if !ASSERT_DISABLED
     ThreadIdentifier m_creationThread { currentThread() };
index 6280f0c..f9cf226 100644 (file)
@@ -30,7 +30,9 @@
 namespace WebCore {
 
 class Exception;
+class ResourceError;
 class ServiceWorkerJob;
+class SharedBuffer;
 struct ServiceWorkerRegistrationData;
 
 class ServiceWorkerJobClient {
@@ -39,6 +41,9 @@ public:
 
     virtual void jobFailedWithException(ServiceWorkerJob&, const Exception&) = 0;
     virtual void jobResolvedWithRegistration(ServiceWorkerJob&, const ServiceWorkerRegistrationData&) = 0;
+    virtual void startScriptFetchForJob(ServiceWorkerJob&) = 0;
+    virtual void jobFinishedLoadingScript(ServiceWorkerJob&, const String&) = 0;
+    virtual void jobFailedLoadingScript(ServiceWorkerJob&, const ResourceError&) = 0;
 
     virtual uint64_t connectionIdentifier() = 0;
 
index 4702bbb..0bc4902 100644 (file)
@@ -29,6 +29,7 @@
 #if ENABLE(SERVICE_WORKER)
 
 #include "ExceptionData.h"
+#include "ServiceWorkerFetchResult.h"
 #include "ServiceWorkerJobData.h"
 
 namespace WebCore {
@@ -49,6 +50,20 @@ void SWClientConnection::scheduleJob(ServiceWorkerJob& job)
     scheduleJobInServer(job.data());
 }
 
+void SWClientConnection::finishedFetchingScript(ServiceWorkerJob& job, const String& script)
+{
+    ASSERT(m_scheduledJobs.get(job.data().identifier()) == &job);
+
+    finishFetchingScriptInServer({ job.data().identifier(), job.data().connectionIdentifier(), job.data().registrationKey(), script, { } });
+}
+
+void SWClientConnection::failedFetchingScript(ServiceWorkerJob& job, const ResourceError& error)
+{
+    ASSERT(m_scheduledJobs.get(job.data().identifier()) == &job);
+
+    finishFetchingScriptInServer({ job.data().identifier(), job.data().connectionIdentifier(), job.data().registrationKey(), { }, error });
+}
+
 void SWClientConnection::jobRejectedInServer(uint64_t jobIdentifier, const ExceptionData& exceptionData)
 {
     auto job = m_scheduledJobs.take(jobIdentifier);
@@ -71,6 +86,22 @@ void SWClientConnection::jobResolvedInServer(uint64_t jobIdentifier, const Servi
     job->resolvedWithRegistration(registrationData);
 }
 
+void SWClientConnection::startScriptFetchForServer(uint64_t jobIdentifier)
+{
+    auto job = m_scheduledJobs.get(jobIdentifier);
+    if (!job) {
+        LOG_ERROR("Job %" PRIu64 " instructed to start fetch from server, but job was not found", jobIdentifier);
+
+        // FIXME: Should message back to the server here to signal failure to fetch,
+        // but we currently need the registration key to do so, and don't have it here.
+        // In the future we'll refactor to have a global, cross-process job identifier that can be used to overcome this.
+
+        return;
+    }
+
+    job->startScriptFetch();
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(SERVICE_WORKER)
index b91e042..0bb85dd 100644 (file)
 
 namespace WebCore {
 
+class ResourceError;
+class SharedBuffer;
 struct ExceptionData;
+struct ServiceWorkerFetchResult;
 struct ServiceWorkerRegistrationData;
 
 class SWClientConnection : public ThreadSafeRefCounted<SWClientConnection> {
@@ -42,15 +45,19 @@ public:
     WEBCORE_EXPORT virtual ~SWClientConnection();
 
     void scheduleJob(ServiceWorkerJob&);
+    void finishedFetchingScript(ServiceWorkerJob&, const String&);
+    void failedFetchingScript(ServiceWorkerJob&, const ResourceError&);
 
     virtual uint64_t identifier() const = 0;
 
 protected:
     WEBCORE_EXPORT void jobRejectedInServer(uint64_t jobIdentifier, const ExceptionData&);
     WEBCORE_EXPORT void jobResolvedInServer(uint64_t jobIdentifier, const ServiceWorkerRegistrationData&);
+    WEBCORE_EXPORT void startScriptFetchForServer(uint64_t jobIdentifier);
 
 private:
     virtual void scheduleJobInServer(const ServiceWorkerJobData&) = 0;
+    virtual void finishFetchingScriptInServer(const ServiceWorkerFetchResult&) = 0;
 
     HashMap<uint64_t, RefPtr<ServiceWorkerJob>> m_scheduledJobs;
 };
index 4019340..6f81ab2 100644 (file)
@@ -32,6 +32,7 @@
 #include "ExceptionData.h"
 #include "Logging.h"
 #include "SWServerRegistration.h"
+#include "ServiceWorkerFetchResult.h"
 #include "ServiceWorkerJobData.h"
 #include <wtf/text/WTFString.h>
 
@@ -72,6 +73,11 @@ void SWServer::Connection::scheduleJobInServer(const ServiceWorkerJobData& jobDa
     m_server.scheduleJob(jobData);
 }
 
+void SWServer::Connection::finishFetchingScriptInServer(const ServiceWorkerFetchResult& result)
+{
+    m_server.scriptFetchFinished(result);
+}
+
 SWServer::SWServer()
 {
     m_taskThread = Thread::create(ASCIILiteral("ServiceWorker Task Thread"), [this] {
@@ -112,6 +118,29 @@ void SWServer::resolveJob(const ServiceWorkerJobData& jobData, const ServiceWork
     connection->resolveJobInClient(jobData.identifier(), registrationData);
 }
 
+void SWServer::startScriptFetch(const ServiceWorkerJobData& jobData)
+{
+    LOG(ServiceWorker, "Server issuing startScriptFetch for current job %" PRIu64 "-%" PRIu64 " in client", jobData.connectionIdentifier(), jobData.identifier());
+    auto* connection = m_connections.get(jobData.connectionIdentifier());
+    if (!connection)
+        return;
+
+    connection->startScriptFetchInClient(jobData.identifier());
+}
+
+void SWServer::scriptFetchFinished(const ServiceWorkerFetchResult& result)
+{
+    LOG(ServiceWorker, "Server handling scriptFetchFinished for current job %" PRIu64 "-%" PRIu64 " in client", result.connectionIdentifier, result.jobIdentifier);
+
+    ASSERT(m_connections.contains(result.connectionIdentifier));
+
+    auto registration = m_registrations.get(result.registrationKey);
+    if (!registration)
+        return;
+
+    registration->scriptFetchFinished(result);
+}
+
 void SWServer::taskThreadEntryPoint()
 {
     ASSERT(!isMainThread());
index 9bd40f7..a1fc5d3 100644 (file)
@@ -43,6 +43,7 @@ namespace WebCore {
 
 class SWServerRegistration;
 struct ExceptionData;
+struct ServiceWorkerFetchResult;
 struct ServiceWorkerRegistrationData;
 
 class SWServer {
@@ -57,10 +58,12 @@ public:
         SWServer& server() { return m_server; }
 
         WEBCORE_EXPORT void scheduleJobInServer(const ServiceWorkerJobData&);
+        WEBCORE_EXPORT void finishFetchingScriptInServer(const ServiceWorkerFetchResult&);
 
     private:
         virtual void rejectJobInClient(uint64_t jobIdentifier, const ExceptionData&) = 0;
         virtual void resolveJobInClient(uint64_t jobIdentifier, const ServiceWorkerRegistrationData&) = 0;
+        virtual void startScriptFetchInClient(uint64_t jobIdentifier) = 0;
 
         SWServer& m_server;
     };
@@ -71,6 +74,8 @@ public:
     void scheduleJob(const ServiceWorkerJobData&);
     void rejectJob(const ServiceWorkerJobData&, const ExceptionData&);
     void resolveJob(const ServiceWorkerJobData&, const ServiceWorkerRegistrationData&);
+    void startScriptFetch(const ServiceWorkerJobData&);
+
     void postTask(CrossThreadTask&&);
     void postTaskReply(CrossThreadTask&&);
 
@@ -81,6 +86,8 @@ private:
     void taskThreadEntryPoint();
     void handleTaskRepliesOnMainThread();
 
+    void scriptFetchFinished(const ServiceWorkerFetchResult&);
+
     HashMap<uint64_t, Connection*> m_connections;
     HashMap<ServiceWorkerRegistrationKey, std::unique_ptr<SWServerRegistration>> m_registrations;
 
index 1052b9b..d511ddd 100644 (file)
@@ -32,6 +32,7 @@
 #include "SWServer.h"
 #include "SWServerWorker.h"
 #include "SecurityOrigin.h"
+#include "ServiceWorkerFetchResult.h"
 #include "ServiceWorkerRegistrationData.h"
 #include "WorkerType.h"
 
@@ -63,6 +64,22 @@ void SWServerRegistration::enqueueJob(const ServiceWorkerJobData& jobData)
         m_jobTimer.startOneShot(0_s);
 }
 
+void SWServerRegistration::scriptFetchFinished(const ServiceWorkerFetchResult& result)
+{
+    ASSERT(m_currentJob && m_currentJob->identifier() == result.jobIdentifier);
+
+    // FIXME: We fetched the script contents but don't do anything with them yet.
+    // These errors are for testing the current state of the feature.
+
+    String message;
+    if (result.scriptError.isNull())
+        message = makeString("Script URL ", m_currentJob->scriptURL.string(), " fetched with ", String::number(result.script.length()), " characters, but we're not using the result yet");
+    else
+        message = makeString("Script URL ", m_currentJob->scriptURL.string(), " fetch resulted in error: ", result.scriptError.localizedDescription());
+
+    rejectCurrentJob(ExceptionData { UnknownError, message });
+}
+
 void SWServerRegistration::startNextJob()
 {
     ASSERT(isMainThread());
@@ -149,9 +166,7 @@ void SWServerRegistration::runUpdateJob(const ServiceWorkerJobData& job)
     if (newestWorker && !equalIgnoringFragmentIdentifier(job.scriptURL, newestWorker->scriptURL()))
         return rejectWithExceptionOnMainThread(ExceptionData { TypeError, ASCIILiteral("Cannot update a service worker with a requested script URL whose newest worker has a different script URL") });
 
-    // FIXME: At this point we are ready to actually fetch the script for the worker in the registering context.
-    // For now we're still hard coding the same rejection we have so far.
-    rejectWithExceptionOnMainThread(ExceptionData { UnknownError, ASCIILiteral("serviceWorker job scheduling is not yet implemented") });
+    startScriptFetchFromMainThread();
 }
 
 void SWServerRegistration::rejectWithExceptionOnMainThread(const ExceptionData& exception)
@@ -166,6 +181,12 @@ void SWServerRegistration::resolveWithRegistrationOnMainThread()
     m_server.postTaskReply(createCrossThreadTask(*this, &SWServerRegistration::resolveCurrentJob, data()));
 }
 
+void SWServerRegistration::startScriptFetchFromMainThread()
+{
+    ASSERT(!isMainThread());
+    m_server.postTaskReply(createCrossThreadTask(*this, &SWServerRegistration::startScriptFetchForCurrentJob));
+}
+
 void SWServerRegistration::rejectCurrentJob(const ExceptionData& exceptionData)
 {
     ASSERT(isMainThread());
@@ -186,6 +207,14 @@ void SWServerRegistration::resolveCurrentJob(const ServiceWorkerRegistrationData
     finishCurrentJob();
 }
 
+void SWServerRegistration::startScriptFetchForCurrentJob()
+{
+    ASSERT(isMainThread());
+    ASSERT(m_currentJob);
+
+    m_server.startScriptFetch(*m_currentJob);
+}
+
 void SWServerRegistration::finishCurrentJob()
 {
     ASSERT(m_currentJob);
index 9b6eabf..f768546 100644 (file)
@@ -38,6 +38,7 @@ namespace WebCore {
 class SWServer;
 class SWServerWorker;
 struct ExceptionData;
+struct ServiceWorkerFetchResult;
 
 class SWServerRegistration : public ThreadSafeIdentified<SWServerRegistration> {
 public:
@@ -46,6 +47,7 @@ public:
     ~SWServerRegistration();
 
     void enqueueJob(const ServiceWorkerJobData&);
+    void scriptFetchFinished(const ServiceWorkerFetchResult&);
 
     ServiceWorkerRegistrationData data() const;
 
@@ -54,6 +56,7 @@ private:
     void startNextJob();
     void rejectCurrentJob(const ExceptionData&);
     void resolveCurrentJob(const ServiceWorkerRegistrationData&);
+    void startScriptFetchForCurrentJob();
     void finishCurrentJob();
 
     void runRegisterJob(const ServiceWorkerJobData&);
@@ -61,6 +64,7 @@ private:
 
     void rejectWithExceptionOnMainThread(const ExceptionData&);
     void resolveWithRegistrationOnMainThread();
+    void startScriptFetchFromMainThread();
     bool isEmpty();
     SWServerWorker* getNewestWorker();
 
index b42ee27..d5e2d77 100644 (file)
@@ -1,3 +1,20 @@
+2017-10-06  Brady Eidson  <beidson@apple.com>
+
+        Add (entirely incorrect) fetching of ServiceWorker scripts.
+        https://bugs.webkit.org/show_bug.cgi?id=176179
+
+        Reviewed by Andy Estes.
+
+        * StorageProcess/ServiceWorker/WebSWServerConnection.cpp:
+        (WebKit::WebSWServerConnection::startScriptFetchInClient):
+        * StorageProcess/ServiceWorker/WebSWServerConnection.h:
+        * StorageProcess/ServiceWorker/WebSWServerConnection.messages.in:
+
+        * WebProcess/Storage/WebSWClientConnection.cpp:
+        (WebKit::WebSWClientConnection::finishFetchingScriptInServer):
+        * WebProcess/Storage/WebSWClientConnection.h:
+        * WebProcess/Storage/WebSWClientConnection.messages.in:
+
 2017-10-05  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         [GTK][WPE] Add API to configure and enable resource load statistics
index da215f1..d8e6c24 100644 (file)
@@ -28,6 +28,7 @@
 
 #if ENABLE(SERVICE_WORKER)
 
+#include "DataReference.h"
 #include "Logging.h"
 #include "StorageToWebProcessConnectionMessages.h"
 #include "WebProcess.h"
@@ -70,6 +71,11 @@ void WebSWServerConnection::resolveJobInClient(uint64_t jobIdentifier, const Ser
     send(Messages::WebSWClientConnection::JobResolvedInServer(jobIdentifier, registrationData));
 }
 
+void WebSWServerConnection::startScriptFetchInClient(uint64_t jobIdentifier)
+{
+    send(Messages::WebSWClientConnection::StartScriptFetchForServer(jobIdentifier));
+}
+
 } // namespace WebKit
 
 #endif // ENABLE(SERVICE_WORKER)
index c879251..b3ce76c 100644 (file)
@@ -51,6 +51,7 @@ private:
     // Implement SWServer::Connection
     void rejectJobInClient(uint64_t jobIdentifier, const WebCore::ExceptionData&) final;
     void resolveJobInClient(uint64_t jobIdentifier, const WebCore::ServiceWorkerRegistrationData&) final;
+    void startScriptFetchInClient(uint64_t jobIdentifier) final;
 
     IPC::Connection* messageSenderConnection() final { return m_connection.ptr(); }
     uint64_t messageSenderDestinationID() final { return identifier(); }
index 0571c4d..e4cfb96 100644 (file)
@@ -25,6 +25,7 @@
 messages -> WebSWServerConnection {
     # When possible, these messages can be implemented directly by WebCore::SWClientConnection
     ScheduleJobInServer(struct WebCore::ServiceWorkerJobData jobData)
+    FinishFetchingScriptInServer(struct WebCore::ServiceWorkerFetchResult result)
 }
 
 #endif // ENABLE(SERVICE_WORKER)
index 182649a..bb3db6b 100644 (file)
@@ -30,7 +30,9 @@
 
 #include "Logging.h"
 #include "StorageToWebProcessConnectionMessages.h"
+#include "WebCoreArgumentCoders.h"
 #include "WebSWServerConnectionMessages.h"
+#include <WebCore/ServiceWorkerFetchResult.h>
 #include <WebCore/ServiceWorkerJobData.h>
 
 using namespace PAL;
@@ -56,6 +58,11 @@ void WebSWClientConnection::scheduleJobInServer(const ServiceWorkerJobData& jobD
     send(Messages::WebSWServerConnection::ScheduleJobInServer(jobData));
 }
 
+void WebSWClientConnection::finishFetchingScriptInServer(const ServiceWorkerFetchResult& result)
+{
+    send(Messages::WebSWServerConnection::FinishFetchingScriptInServer(result));
+}
+
 } // namespace WebKit
 
 #endif // ENABLE(SERVICE_WORKER)
index 51de4bb..44af779 100644 (file)
@@ -48,6 +48,7 @@ public:
     uint64_t identifier() const final { return m_identifier; }
 
     void scheduleJobInServer(const WebCore::ServiceWorkerJobData&) final;
+    void finishFetchingScriptInServer(const WebCore::ServiceWorkerFetchResult&) final;
 
     void disconnectedFromWebProcess();
     void didReceiveMessage(IPC::Connection&, IPC::Decoder&) final;
index adef99a..40f7730 100644 (file)
@@ -26,6 +26,7 @@ messages -> WebSWClientConnection {
     # When possible, these messages can be implemented directly by WebCore::SWServer::Connection
     JobRejectedInServer(uint64_t identifier, struct WebCore::ExceptionData exception)
     JobResolvedInServer(uint64_t identifier, struct WebCore::ServiceWorkerRegistrationData registration)
+    StartScriptFetchForServer(uint64_t jobIdentifier)
 }
 
 #endif // ENABLE(SERVICE_WORKER)