Implement "UpdateWorkerState" and use it
[WebKit-https.git] / Source / WebKit / StorageProcess / ServiceWorker / WebSWServerConnection.cpp
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 #include "config.h"
27 #include "WebSWServerConnection.h"
28
29 #if ENABLE(SERVICE_WORKER)
30
31 #include "DataReference.h"
32 #include "Logging.h"
33 #include "ServiceWorkerClientFetchMessages.h"
34 #include "StorageProcess.h"
35 #include "StorageToWebProcessConnectionMessages.h"
36 #include "WebCoreArgumentCoders.h"
37 #include "WebProcess.h"
38 #include "WebProcessMessages.h"
39 #include "WebSWClientConnectionMessages.h"
40 #include "WebSWContextManagerConnectionMessages.h"
41 #include "WebSWOriginStore.h"
42 #include "WebSWServerConnectionMessages.h"
43 #include "WebToStorageProcessConnection.h"
44 #include <WebCore/ExceptionData.h>
45 #include <WebCore/NotImplemented.h>
46 #include <WebCore/SWServerRegistration.h>
47 #include <WebCore/SecurityOrigin.h>
48 #include <WebCore/ServiceWorkerClientIdentifier.h>
49 #include <WebCore/ServiceWorkerContextData.h>
50 #include <WebCore/ServiceWorkerJobData.h>
51 #include <wtf/MainThread.h>
52
53 using namespace PAL;
54 using namespace WebCore;
55
56 namespace WebKit {
57
58 WebSWServerConnection::WebSWServerConnection(SWServer& server, IPC::Connection& connection, uint64_t connectionIdentifier, SessionID sessionID)
59     : SWServer::Connection(server, connectionIdentifier)
60     , m_sessionID(sessionID)
61     , m_contentConnection(connection)
62 {
63 }
64
65 WebSWServerConnection::~WebSWServerConnection()
66 {
67 }
68
69 void WebSWServerConnection::disconnectedFromWebProcess()
70 {
71     notImplemented();
72 }
73
74 void WebSWServerConnection::rejectJobInClient(uint64_t jobIdentifier, const ExceptionData& exceptionData)
75 {
76     send(Messages::WebSWClientConnection::JobRejectedInServer(jobIdentifier, exceptionData));
77 }
78
79 void WebSWServerConnection::resolveRegistrationJobInClient(uint64_t jobIdentifier, const ServiceWorkerRegistrationData& registrationData)
80 {
81     auto origin = registrationData.key.topOrigin().securityOrigin();
82     StorageProcess::singleton().ensureSWOriginStoreForSession(m_sessionID).add(origin);
83     send(Messages::WebSWClientConnection::RegistrationJobResolvedInServer(jobIdentifier, registrationData));
84 }
85
86 void WebSWServerConnection::resolveUnregistrationJobInClient(uint64_t jobIdentifier, const ServiceWorkerRegistrationKey& registrationKey, bool unregistrationResult)
87 {
88     auto origin = registrationKey.topOrigin().securityOrigin();
89     if (auto* store = StorageProcess::singleton().swOriginStoreForSession(m_sessionID))
90         store->remove(origin);
91     send(Messages::WebSWClientConnection::UnregistrationJobResolvedInServer(jobIdentifier, unregistrationResult));
92 }
93
94 void WebSWServerConnection::startScriptFetchInClient(uint64_t jobIdentifier)
95 {
96     send(Messages::WebSWClientConnection::StartScriptFetchForServer(jobIdentifier));
97 }
98
99 void WebSWServerConnection::updateRegistrationStateInClient(const ServiceWorkerRegistrationKey& key, ServiceWorkerRegistrationState state, std::optional<ServiceWorkerIdentifier> serviceWorkerIdentifier)
100 {
101     send(Messages::WebSWClientConnection::UpdateRegistrationState(key, state, serviceWorkerIdentifier));
102 }
103
104 void WebSWServerConnection::fireUpdateFoundEvent(const ServiceWorkerRegistrationKey& key)
105 {
106     send(Messages::WebSWClientConnection::FireUpdateFoundEvent(key));
107 }
108
109 void WebSWServerConnection::firePostInstallEvents(const ServiceWorkerRegistrationKey& key)
110 {
111     send(Messages::WebSWClientConnection::FirePostInstallEvents(key));
112 }
113
114 void WebSWServerConnection::updateWorkerStateInClient(ServiceWorkerIdentifier worker, ServiceWorkerState state)
115 {
116     send(Messages::WebSWClientConnection::UpdateWorkerState(worker, state));
117 }
118
119 void WebSWServerConnection::installServiceWorkerContext(const ServiceWorkerContextData& data)
120 {
121     if (sendToContextProcess(Messages::WebSWContextManagerConnection::InstallServiceWorker(identifier(), data)))
122         return;
123
124     m_pendingContextDatas.append(data);
125 }
126
127 void WebSWServerConnection::fireInstallEvent(ServiceWorkerIdentifier serviceWorkerIdentifier)
128 {
129     sendToContextProcess(Messages::WebSWContextManagerConnection::FireInstallEvent(identifier(), serviceWorkerIdentifier));
130 }
131
132 void WebSWServerConnection::startFetch(uint64_t fetchIdentifier, std::optional<ServiceWorkerIdentifier> serviceWorkerIdentifier, const ResourceRequest& request, const FetchOptions& options)
133 {
134     sendToContextProcess(Messages::WebSWContextManagerConnection::StartFetch(identifier(), fetchIdentifier, serviceWorkerIdentifier, request, options));
135 }
136
137 void WebSWServerConnection::postMessageToServiceWorkerGlobalScope(ServiceWorkerIdentifier destinationServiceWorkerIdentifier, const IPC::DataReference& message, uint64_t sourceScriptExecutionContextIdentifier, const String& sourceOrigin)
138 {
139     ServiceWorkerClientIdentifier sourceIdentifier { identifier(), sourceScriptExecutionContextIdentifier };
140     sendToContextProcess(Messages::WebSWContextManagerConnection::PostMessageToServiceWorkerGlobalScope { destinationServiceWorkerIdentifier, message, sourceIdentifier, sourceOrigin });
141 }
142
143 void WebSWServerConnection::didReceiveFetchResponse(uint64_t fetchIdentifier, const ResourceResponse& response)
144 {
145     m_contentConnection->send(Messages::ServiceWorkerClientFetch::DidReceiveResponse { response }, fetchIdentifier);
146 }
147
148 void WebSWServerConnection::didReceiveFetchData(uint64_t fetchIdentifier, const IPC::DataReference& data, int64_t encodedDataLength)
149 {
150     m_contentConnection->send(Messages::ServiceWorkerClientFetch::DidReceiveData { data, encodedDataLength }, fetchIdentifier);
151 }
152
153 void WebSWServerConnection::didFinishFetch(uint64_t fetchIdentifier)
154 {
155     m_contentConnection->send(Messages::ServiceWorkerClientFetch::DidFinish { }, fetchIdentifier);
156 }
157
158 void WebSWServerConnection::didFailFetch(uint64_t fetchIdentifier)
159 {
160     m_contentConnection->send(Messages::ServiceWorkerClientFetch::DidFail { }, fetchIdentifier);
161 }
162
163 void WebSWServerConnection::didNotHandleFetch(uint64_t fetchIdentifier)
164 {
165     m_contentConnection->send(Messages::ServiceWorkerClientFetch::DidNotHandle { }, fetchIdentifier);
166 }
167
168 void WebSWServerConnection::postMessageToServiceWorkerClient(uint64_t destinationScriptExecutionContextIdentifier, const IPC::DataReference& message, ServiceWorkerIdentifier sourceServiceWorkerIdentifier, const String& sourceOrigin)
169 {
170     send(Messages::WebSWClientConnection::PostMessageToServiceWorkerClient { destinationScriptExecutionContextIdentifier, message, sourceServiceWorkerIdentifier, sourceOrigin });
171 }
172
173 void WebSWServerConnection::matchRegistration(uint64_t registrationMatchRequestIdentifier, const SecurityOriginData& topOrigin, const URL& clientURL)
174 {
175     if (auto* registration = doRegistrationMatching(topOrigin, clientURL)) {
176         send(Messages::WebSWClientConnection::DidMatchRegistration { registrationMatchRequestIdentifier, registration->data() });
177         return;
178     }
179     send(Messages::WebSWClientConnection::DidMatchRegistration { registrationMatchRequestIdentifier, std::nullopt });
180 }
181
182 template<typename U> bool WebSWServerConnection::sendToContextProcess(U&& message)
183 {
184     if (!m_contextConnection)
185         return false;
186
187     return m_contextConnection->send<U>(WTFMove(message), 0);
188 }
189
190 void WebSWServerConnection::setContextConnection(IPC::Connection* connection)
191 {
192     m_contextConnection = connection;
193
194     // We can now start any pending service worker updates.
195     for (auto& pendingContextData : m_pendingContextDatas)
196         installServiceWorkerContext(pendingContextData);
197     
198     m_pendingContextDatas.clear();
199 }
200     
201 } // namespace WebKit
202
203 #endif // ENABLE(SERVICE_WORKER)