Move WKProcessPool._registerURLSchemeServiceWorkersCanHandle to _WKWebsiteDataStoreCo...
[WebKit-https.git] / Source / WebCore / workers / service / server / SWServer.h
1 /*
2  * Copyright (C) 2017 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #pragma once
27
28 #if ENABLE(SERVICE_WORKER)
29
30 #include "ClientOrigin.h"
31 #include "DocumentIdentifier.h"
32 #include "SWServerWorker.h"
33 #include "SecurityOriginData.h"
34 #include "ServiceWorkerClientData.h"
35 #include "ServiceWorkerIdentifier.h"
36 #include "ServiceWorkerJob.h"
37 #include "ServiceWorkerRegistrationData.h"
38 #include "ServiceWorkerRegistrationKey.h"
39 #include "ServiceWorkerTypes.h"
40 #include <pal/SessionID.h>
41 #include <wtf/HashMap.h>
42 #include <wtf/HashSet.h>
43 #include <wtf/ObjectIdentifier.h>
44 #include <wtf/RunLoop.h>
45 #include <wtf/ThreadSafeRefCounted.h>
46 #include <wtf/Threading.h>
47 #include <wtf/UniqueRef.h>
48 #include <wtf/WeakPtr.h>
49
50 namespace WebCore {
51
52 class RegistrationStore;
53 class SWOriginStore;
54 class SWServerJobQueue;
55 class SWServerRegistration;
56 class SWServerToContextConnection;
57 enum class ServiceWorkerRegistrationState : uint8_t;
58 enum class ServiceWorkerState : uint8_t;
59 struct ExceptionData;
60 struct MessageWithMessagePorts;
61 struct ServiceWorkerClientQueryOptions;
62 struct ServiceWorkerContextData;
63 struct ServiceWorkerFetchResult;
64 struct ServiceWorkerRegistrationData;
65 class Timer;
66
67 class SWServer : public CanMakeWeakPtr<SWServer> {
68     WTF_MAKE_FAST_ALLOCATED;
69 public:
70     class Connection : public CanMakeWeakPtr<Connection> {
71         WTF_MAKE_FAST_ALLOCATED;
72         friend class SWServer;
73     public:
74         virtual ~Connection() = default;
75
76         using Identifier = SWServerConnectionIdentifier;
77         Identifier identifier() const { return m_identifier; }
78
79         WEBCORE_EXPORT void didResolveRegistrationPromise(const ServiceWorkerRegistrationKey&);
80         SWServerRegistration* doRegistrationMatching(const SecurityOriginData& topOrigin, const URL& clientURL) { return m_server.doRegistrationMatching(topOrigin, clientURL); }
81         void resolveRegistrationReadyRequests(SWServerRegistration&);
82
83         // Messages to the client WebProcess
84         virtual void updateRegistrationStateInClient(ServiceWorkerRegistrationIdentifier, ServiceWorkerRegistrationState, const Optional<ServiceWorkerData>&) = 0;
85         virtual void updateWorkerStateInClient(ServiceWorkerIdentifier, ServiceWorkerState) = 0;
86         virtual void fireUpdateFoundEvent(ServiceWorkerRegistrationIdentifier) = 0;
87         virtual void setRegistrationLastUpdateTime(ServiceWorkerRegistrationIdentifier, WallTime) = 0;
88         virtual void setRegistrationUpdateViaCache(ServiceWorkerRegistrationIdentifier, ServiceWorkerUpdateViaCache) = 0;
89         virtual void notifyClientsOfControllerChange(const HashSet<DocumentIdentifier>& contextIdentifiers, const ServiceWorkerData& newController) = 0;
90         virtual void registrationReady(uint64_t registrationReadyRequestIdentifier, ServiceWorkerRegistrationData&&) = 0;
91         virtual void postMessageToServiceWorkerClient(DocumentIdentifier, const MessageWithMessagePorts&, ServiceWorkerIdentifier, const String& sourceOrigin) = 0;
92
93         virtual void contextConnectionCreated(SWServerToContextConnection&) = 0;
94
95         SWServer& server() { return m_server; }
96         const SWServer& server() const { return m_server; }
97
98     protected:
99         WEBCORE_EXPORT Connection(SWServer&, Identifier);
100
101         WEBCORE_EXPORT void finishFetchingScriptInServer(const ServiceWorkerFetchResult&);
102         WEBCORE_EXPORT void addServiceWorkerRegistrationInServer(ServiceWorkerRegistrationIdentifier);
103         WEBCORE_EXPORT void removeServiceWorkerRegistrationInServer(ServiceWorkerRegistrationIdentifier);
104         WEBCORE_EXPORT void syncTerminateWorker(ServiceWorkerIdentifier);
105         WEBCORE_EXPORT void whenRegistrationReady(uint64_t registrationReadyRequestIdentifier, const SecurityOriginData& topOrigin, const URL& clientURL);
106
107         WEBCORE_EXPORT void storeRegistrationsOnDisk(CompletionHandler<void()>&&);
108
109     private:
110         // Messages to the client WebProcess
111         virtual void rejectJobInClient(ServiceWorkerJobIdentifier, const ExceptionData&) = 0;
112         virtual void resolveRegistrationJobInClient(ServiceWorkerJobIdentifier, const ServiceWorkerRegistrationData&, ShouldNotifyWhenResolved) = 0;
113         virtual void resolveUnregistrationJobInClient(ServiceWorkerJobIdentifier, const ServiceWorkerRegistrationKey&, bool registrationResult) = 0;
114         virtual void startScriptFetchInClient(ServiceWorkerJobIdentifier, const ServiceWorkerRegistrationKey&, FetchOptions::Cache) = 0;
115
116         struct RegistrationReadyRequest {
117             SecurityOriginData topOrigin;
118             URL clientURL;
119             uint64_t identifier;
120         };
121
122         SWServer& m_server;
123         Identifier m_identifier;
124         Vector<RegistrationReadyRequest> m_registrationReadyRequests;
125     };
126
127     using CreateContextConnectionCallback = Function<void(const WebCore::RegistrableDomain&)>;
128     WEBCORE_EXPORT SWServer(UniqueRef<SWOriginStore>&&, HashSet<String>&& registeredSchemes, bool processTerminationDelayEnabled, String&& registrationDatabaseDirectory, PAL::SessionID, CreateContextConnectionCallback&&);
129
130     WEBCORE_EXPORT ~SWServer();
131
132     WEBCORE_EXPORT void clearAll(WTF::CompletionHandler<void()>&&);
133     WEBCORE_EXPORT void clear(const SecurityOriginData&, WTF::CompletionHandler<void()>&&);
134
135     WEBCORE_EXPORT void startSuspension(CompletionHandler<void()>&&);
136     WEBCORE_EXPORT void endSuspension();
137
138     WEBCORE_EXPORT SWServerRegistration* getRegistration(const ServiceWorkerRegistrationKey&);
139     void addRegistration(std::unique_ptr<SWServerRegistration>&&);
140     void removeRegistration(ServiceWorkerRegistrationIdentifier);
141     WEBCORE_EXPORT Vector<ServiceWorkerRegistrationData> getRegistrations(const SecurityOriginData& topOrigin, const URL& clientURL);
142
143     WEBCORE_EXPORT void scheduleJob(ServiceWorkerJobData&&);
144     void rejectJob(const ServiceWorkerJobData&, const ExceptionData&);
145     void resolveRegistrationJob(const ServiceWorkerJobData&, const ServiceWorkerRegistrationData&, ShouldNotifyWhenResolved);
146     void resolveUnregistrationJob(const ServiceWorkerJobData&, const ServiceWorkerRegistrationKey&, bool unregistrationResult);
147     void startScriptFetch(const ServiceWorkerJobData&, FetchOptions::Cache);
148
149     void updateWorker(Connection&, const ServiceWorkerJobDataIdentifier&, SWServerRegistration&, const URL&, const String& script, const ContentSecurityPolicyResponseHeaders&, const String& referrerPolicy, WorkerType, HashMap<URL, ServiceWorkerContextData::ImportedScript>&&);
150     void terminateWorker(SWServerWorker&);
151     void syncTerminateWorker(SWServerWorker&);
152     void fireInstallEvent(SWServerWorker&);
153     void fireActivateEvent(SWServerWorker&);
154
155     WEBCORE_EXPORT SWServerWorker* workerByID(ServiceWorkerIdentifier) const;
156     Optional<ServiceWorkerClientData> serviceWorkerClientWithOriginByID(const ClientOrigin&, const ServiceWorkerClientIdentifier&) const;
157     String serviceWorkerClientUserAgent(const ClientOrigin&) const;
158     WEBCORE_EXPORT SWServerWorker* activeWorkerFromRegistrationID(ServiceWorkerRegistrationIdentifier);
159
160     WEBCORE_EXPORT void markAllWorkersForRegistrableDomainAsTerminated(const RegistrableDomain&);
161     
162     WEBCORE_EXPORT void addConnection(std::unique_ptr<Connection>&&);
163     WEBCORE_EXPORT void removeConnection(SWServerConnectionIdentifier);
164     Connection* connection(SWServerConnectionIdentifier identifier) const { return m_connections.get(identifier); }
165
166     const HashMap<SWServerConnectionIdentifier, std::unique_ptr<Connection>>& connections() const { return m_connections; }
167     const HashSet<String> registeredSchemes() const { return m_registeredSchemes; }
168
169     SWOriginStore& originStore() { return m_originStore; }
170
171     void scriptContextFailedToStart(const Optional<ServiceWorkerJobDataIdentifier>&, SWServerWorker&, const String& message);
172     void scriptContextStarted(const Optional<ServiceWorkerJobDataIdentifier>&, SWServerWorker&);
173     void didFinishInstall(const Optional<ServiceWorkerJobDataIdentifier>&, SWServerWorker&, bool wasSuccessful);
174     void didFinishActivation(SWServerWorker&);
175     void workerContextTerminated(SWServerWorker&);
176     void matchAll(SWServerWorker&, const ServiceWorkerClientQueryOptions&, ServiceWorkerClientsMatchAllCallback&&);
177     void claim(SWServerWorker&);
178
179     WEBCORE_EXPORT static HashSet<SWServer*>& allServers();
180
181     WEBCORE_EXPORT void registerServiceWorkerClient(ClientOrigin&&, ServiceWorkerClientData&&, const Optional<ServiceWorkerRegistrationIdentifier>&, String&& userAgent);
182     WEBCORE_EXPORT void unregisterServiceWorkerClient(const ClientOrigin&, ServiceWorkerClientIdentifier);
183
184     using RunServiceWorkerCallback = WTF::Function<void(SWServerToContextConnection*)>;
185     WEBCORE_EXPORT void runServiceWorkerIfNecessary(ServiceWorkerIdentifier, RunServiceWorkerCallback&&);
186
187     void resolveRegistrationReadyRequests(SWServerRegistration&);
188
189     void addRegistrationFromStore(ServiceWorkerContextData&&);
190     void registrationStoreImportComplete();
191     void registrationStoreDatabaseFailedToOpen();
192
193     WEBCORE_EXPORT void getOriginsWithRegistrations(Function<void(const HashSet<SecurityOriginData>&)>&&);
194
195     PAL::SessionID sessionID() const { return m_sessionID; }
196     WEBCORE_EXPORT bool needsContextConnectionForRegistrableDomain(const RegistrableDomain&) const;
197
198     void removeFromScopeToRegistrationMap(const ServiceWorkerRegistrationKey&);
199
200     WEBCORE_EXPORT void addContextConnection(SWServerToContextConnection&);
201     WEBCORE_EXPORT void removeContextConnection(SWServerToContextConnection&);
202
203     SWServerToContextConnection* contextConnectionForRegistrableDomain(const RegistrableDomain& domain) { return m_contextConnections.get(domain); }
204     WEBCORE_EXPORT void createContextConnection(const RegistrableDomain&);
205
206 private:
207     void scriptFetchFinished(Connection&, const ServiceWorkerFetchResult&);
208
209     void didResolveRegistrationPromise(Connection&, const ServiceWorkerRegistrationKey&);
210
211     void addClientServiceWorkerRegistration(Connection&, ServiceWorkerRegistrationIdentifier);
212     void removeClientServiceWorkerRegistration(Connection&, ServiceWorkerRegistrationIdentifier);
213
214     void terminatePreinstallationWorker(SWServerWorker&);
215
216     WEBCORE_EXPORT SWServerRegistration* doRegistrationMatching(const SecurityOriginData& topOrigin, const URL& clientURL);
217     bool runServiceWorker(ServiceWorkerIdentifier);
218
219     void tryInstallContextData(ServiceWorkerContextData&&);
220     void installContextData(const ServiceWorkerContextData&);
221
222     SWServerRegistration* registrationFromServiceWorkerIdentifier(ServiceWorkerIdentifier);
223     void forEachClientForOrigin(const ClientOrigin&, const WTF::Function<void(ServiceWorkerClientData&)>&);
224
225     void performGetOriginsWithRegistrationsCallbacks();
226
227     enum TerminationMode {
228         Synchronous,
229         Asynchronous,
230     };
231     void terminateWorkerInternal(SWServerWorker&, TerminationMode);
232
233     void contextConnectionCreated(SWServerToContextConnection&);
234
235     HashMap<SWServerConnectionIdentifier, std::unique_ptr<Connection>> m_connections;
236     HashMap<ServiceWorkerRegistrationKey, WeakPtr<SWServerRegistration>> m_scopeToRegistrationMap;
237     HashMap<ServiceWorkerRegistrationIdentifier, std::unique_ptr<SWServerRegistration>> m_registrations;
238     HashMap<ServiceWorkerRegistrationKey, std::unique_ptr<SWServerJobQueue>> m_jobQueues;
239
240     HashMap<ServiceWorkerIdentifier, Ref<SWServerWorker>> m_runningOrTerminatingWorkers;
241
242     HashMap<RegistrableDomain, HashSet<ServiceWorkerClientIdentifier>> m_clientsByRegistrableDomain;
243     struct Clients {
244         Vector<ServiceWorkerClientIdentifier> identifiers;
245         std::unique_ptr<Timer> terminateServiceWorkersTimer;
246         String userAgent;
247     };
248     HashMap<ClientOrigin, Clients> m_clientIdentifiersPerOrigin;
249     HashMap<ServiceWorkerClientIdentifier, ServiceWorkerClientData> m_clientsById;
250     HashMap<ServiceWorkerClientIdentifier, ServiceWorkerRegistrationIdentifier> m_clientToControllingRegistration;
251
252     UniqueRef<SWOriginStore> m_originStore;
253     std::unique_ptr<RegistrationStore> m_registrationStore;
254     HashMap<RegistrableDomain, Vector<ServiceWorkerContextData>> m_pendingContextDatas;
255     HashMap<RegistrableDomain, HashMap<ServiceWorkerIdentifier, Vector<RunServiceWorkerCallback>>> m_serviceWorkerRunRequests;
256     PAL::SessionID m_sessionID;
257     bool m_importCompleted { false };
258     bool m_isProcessTerminationDelayEnabled { true };
259     HashSet<String> m_registeredSchemes;
260     Vector<CompletionHandler<void()>> m_clearCompletionCallbacks;
261     Vector<Function<void(const HashSet<SecurityOriginData>&)>> m_getOriginsWithRegistrationsCallbacks;
262     HashMap<RegistrableDomain, SWServerToContextConnection*> m_contextConnections;
263
264     CreateContextConnectionCallback m_createContextConnectionCallback;
265     HashSet<WebCore::RegistrableDomain> m_pendingConnectionDomains;
266 };
267
268 } // namespace WebCore
269
270 #endif // ENABLE(SERVICE_WORKER)