Bring back SWContextManager abstraction in WebCore
[WebKit-https.git] / Source / WebKit / WebProcess / Storage / WebSWContextManagerConnection.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 "WebSWContextManagerConnection.h"
28
29 #if ENABLE(SERVICE_WORKER)
30
31 #include "DataReference.h"
32 #include "Logging.h"
33 #include "StorageProcessMessages.h"
34 #include "WebCacheStorageProvider.h"
35 #include "WebCoreArgumentCoders.h"
36 #include "WebDocumentLoader.h"
37 #include "WebPreferencesKeys.h"
38 #include "WebPreferencesStore.h"
39 #include "WebProcess.h"
40 #include "WebServiceWorkerFetchTaskClient.h"
41 #include "WebSocketProvider.h"
42 #include <WebCore/EditorClient.h>
43 #include <WebCore/EmptyClients.h>
44 #include <WebCore/EmptyFrameLoaderClient.h>
45 #include <WebCore/LibWebRTCProvider.h>
46 #include <WebCore/PageConfiguration.h>
47 #include <WebCore/RuntimeEnabledFeatures.h>
48 #include <WebCore/SerializedScriptValue.h>
49 #include <pal/SessionID.h>
50
51 #if USE(QUICK_LOOK)
52 #include <WebCore/PreviewLoaderClient.h>
53 #endif
54
55 using namespace PAL;
56 using namespace WebCore;
57
58 namespace WebKit {
59
60 class ServiceWorkerFrameLoaderClient final : public EmptyFrameLoaderClient {
61 public:
62     ServiceWorkerFrameLoaderClient(PAL::SessionID sessionID, uint64_t pageID, uint64_t frameID)
63         : m_sessionID(sessionID)
64         , m_pageID(pageID)
65         , m_frameID(frameID)
66     {
67     }
68
69 private:
70     Ref<DocumentLoader> createDocumentLoader(const ResourceRequest& request, const SubstituteData& substituteData) final
71     {
72         return WebDocumentLoader::create(request, substituteData);
73     }
74
75     PAL::SessionID sessionID() const final { return m_sessionID; }
76     uint64_t pageID() const final { return m_pageID; }
77     uint64_t frameID() const final { return m_frameID; }
78
79     PAL::SessionID m_sessionID;
80     uint64_t m_pageID { 0 };
81     uint64_t m_frameID { 0 };
82 };
83
84 WebSWContextManagerConnection::WebSWContextManagerConnection(Ref<IPC::Connection>&& connection, uint64_t pageID, const WebPreferencesStore& store)
85     : m_connectionToStorageProcess(WTFMove(connection))
86     , m_pageID(pageID)
87 {
88     updatePreferences(store);
89 }
90
91 void WebSWContextManagerConnection::updatePreferences(const WebPreferencesStore& store)
92 {
93     RuntimeEnabledFeatures::sharedFeatures().setCacheAPIEnabled(store.getBoolValueForKey(WebPreferencesKey::cacheAPIEnabledKey()));
94     RuntimeEnabledFeatures::sharedFeatures().setFetchAPIEnabled(store.getBoolValueForKey(WebPreferencesKey::fetchAPIEnabledKey()));
95 }
96
97 void WebSWContextManagerConnection::startServiceWorker(uint64_t serverConnectionIdentifier, const ServiceWorkerContextData& data)
98 {
99     // FIXME: Provide a sensical session ID.
100     auto sessionID = PAL::SessionID::defaultSessionID();
101
102     PageConfiguration pageConfiguration {
103         createEmptyEditorClient(),
104         WebSocketProvider::create(),
105         WebCore::LibWebRTCProvider::create(),
106         WebProcess::singleton().cacheStorageProvider()
107     };
108     fillWithEmptyClients(pageConfiguration);
109     auto frameLoaderClient = std::make_unique<ServiceWorkerFrameLoaderClient>(sessionID, m_pageID, ++m_previousServiceWorkerID);
110     pageConfiguration.loaderClientForMainFrame = frameLoaderClient.release();
111
112     auto serviceWorkerThreadProxy = ServiceWorkerThreadProxy::create(WTFMove(pageConfiguration), serverConnectionIdentifier, data, sessionID, WebProcess::singleton().cacheStorageProvider());
113     auto serviceWorkerIdentifier = serviceWorkerThreadProxy->identifier();
114     SWContextManager::singleton().registerServiceWorkerThread(WTFMove(serviceWorkerThreadProxy));
115
116     LOG(ServiceWorker, "Context process PID: %i started worker thread %s\n", getpid(), data.workerID.utf8().data());
117
118     m_connectionToStorageProcess->send(Messages::StorageProcess::ServiceWorkerContextStarted(serverConnectionIdentifier, data.registrationKey, serviceWorkerIdentifier, data.workerID), 0);
119 }
120
121 void WebSWContextManagerConnection::startFetch(uint64_t serverConnectionIdentifier, uint64_t fetchIdentifier, uint64_t serviceWorkerIdentifier, ResourceRequest&& request, FetchOptions&& options)
122 {
123     auto* serviceWorkerThreadProxy = SWContextManager::singleton().serviceWorkerThreadProxy(serviceWorkerIdentifier);
124     if (!serviceWorkerThreadProxy) {
125         m_connectionToStorageProcess->send(Messages::StorageProcess::DidNotHandleFetch(serverConnectionIdentifier, fetchIdentifier), 0);
126         return;
127     }
128
129     auto client = WebServiceWorkerFetchTaskClient::create(m_connectionToStorageProcess.copyRef(), serverConnectionIdentifier, fetchIdentifier);
130     serviceWorkerThreadProxy->thread().postFetchTask(WTFMove(client), WTFMove(request), WTFMove(options));
131 }
132
133 void WebSWContextManagerConnection::postMessageToServiceWorkerGlobalScope(uint64_t serviceWorkerIdentifier, const IPC::DataReference& message, const String& sourceOrigin)
134 {
135     SWContextManager::singleton().postMessageToServiceWorkerGlobalScope(serviceWorkerIdentifier, SerializedScriptValue::adopt(message.vector()), sourceOrigin);
136 }
137
138 } // namespace WebCore
139
140 #endif // ENABLE(SERVICE_WORKER)