2 * Copyright (C) 2017 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
27 #include "WebSWContextManagerConnection.h"
29 #if ENABLE(SERVICE_WORKER)
31 #include "DataReference.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>
52 #include <WebCore/PreviewLoaderClient.h>
56 using namespace WebCore;
60 class ServiceWorkerFrameLoaderClient final : public EmptyFrameLoaderClient {
62 ServiceWorkerFrameLoaderClient(PAL::SessionID sessionID, uint64_t pageID, uint64_t frameID)
63 : m_sessionID(sessionID)
70 Ref<DocumentLoader> createDocumentLoader(const ResourceRequest& request, const SubstituteData& substituteData) final
72 return WebDocumentLoader::create(request, substituteData);
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; }
79 PAL::SessionID m_sessionID;
80 uint64_t m_pageID { 0 };
81 uint64_t m_frameID { 0 };
84 WebSWContextManagerConnection::WebSWContextManagerConnection(Ref<IPC::Connection>&& connection, uint64_t pageID, const WebPreferencesStore& store)
85 : m_connectionToStorageProcess(WTFMove(connection))
88 updatePreferences(store);
91 void WebSWContextManagerConnection::updatePreferences(const WebPreferencesStore& store)
93 RuntimeEnabledFeatures::sharedFeatures().setCacheAPIEnabled(store.getBoolValueForKey(WebPreferencesKey::cacheAPIEnabledKey()));
94 RuntimeEnabledFeatures::sharedFeatures().setFetchAPIEnabled(store.getBoolValueForKey(WebPreferencesKey::fetchAPIEnabledKey()));
97 void WebSWContextManagerConnection::startServiceWorker(uint64_t serverConnectionIdentifier, const ServiceWorkerContextData& data)
99 // FIXME: Provide a sensical session ID.
100 auto sessionID = PAL::SessionID::defaultSessionID();
102 PageConfiguration pageConfiguration {
103 createEmptyEditorClient(),
104 WebSocketProvider::create(),
105 WebCore::LibWebRTCProvider::create(),
106 WebProcess::singleton().cacheStorageProvider()
108 fillWithEmptyClients(pageConfiguration);
109 auto frameLoaderClient = std::make_unique<ServiceWorkerFrameLoaderClient>(sessionID, m_pageID, ++m_previousServiceWorkerID);
110 pageConfiguration.loaderClientForMainFrame = frameLoaderClient.release();
112 auto serviceWorkerThreadProxy = ServiceWorkerThreadProxy::create(WTFMove(pageConfiguration), serverConnectionIdentifier, data, sessionID, WebProcess::singleton().cacheStorageProvider());
113 auto serviceWorkerIdentifier = serviceWorkerThreadProxy->identifier();
114 SWContextManager::singleton().registerServiceWorkerThread(WTFMove(serviceWorkerThreadProxy));
116 LOG(ServiceWorker, "Context process PID: %i started worker thread %s\n", getpid(), data.workerID.utf8().data());
118 m_connectionToStorageProcess->send(Messages::StorageProcess::ServiceWorkerContextStarted(serverConnectionIdentifier, data.registrationKey, serviceWorkerIdentifier, data.workerID), 0);
121 void WebSWContextManagerConnection::startFetch(uint64_t serverConnectionIdentifier, uint64_t fetchIdentifier, uint64_t serviceWorkerIdentifier, ResourceRequest&& request, FetchOptions&& options)
123 auto* serviceWorkerThreadProxy = SWContextManager::singleton().serviceWorkerThreadProxy(serviceWorkerIdentifier);
124 if (!serviceWorkerThreadProxy) {
125 m_connectionToStorageProcess->send(Messages::StorageProcess::DidNotHandleFetch(serverConnectionIdentifier, fetchIdentifier), 0);
129 auto client = WebServiceWorkerFetchTaskClient::create(m_connectionToStorageProcess.copyRef(), serverConnectionIdentifier, fetchIdentifier);
130 serviceWorkerThreadProxy->thread().postFetchTask(WTFMove(client), WTFMove(request), WTFMove(options));
133 void WebSWContextManagerConnection::postMessageToServiceWorkerGlobalScope(uint64_t serviceWorkerIdentifier, const IPC::DataReference& message, const String& sourceOrigin)
135 SWContextManager::singleton().postMessageToServiceWorkerGlobalScope(serviceWorkerIdentifier, SerializedScriptValue::adopt(message.vector()), sourceOrigin);
138 } // namespace WebCore
140 #endif // ENABLE(SERVICE_WORKER)