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 "MessageReceiver.h"
31#include "MessageSender.h"
32#include "ServiceWorkerFetchTask.h"
33#include <WebCore/FetchIdentifier.h>
34#include <WebCore/SWServer.h>
35#include <pal/SessionID.h>
36#include <wtf/HashMap.h>
37
38namespace IPC {
39class FormDataReference;
40}
41
42namespace WebCore {
43class ServiceWorkerRegistrationKey;
44struct ClientOrigin;
45struct ExceptionData;
46struct MessageWithMessagePorts;
47struct ServiceWorkerClientData;
48}
49
50namespace WebKit {
51
52class NetworkProcess;
53
54class WebSWServerConnection : public WebCore::SWServer::Connection, public IPC::MessageSender, public IPC::MessageReceiver {
55public:
56 WebSWServerConnection(NetworkProcess&, WebCore::SWServer&, IPC::Connection&, PAL::SessionID);
57 WebSWServerConnection(const WebSWServerConnection&) = delete;
58 ~WebSWServerConnection() final;
59
60 IPC::Connection& ipcConnection() const { return m_contentConnection.get(); }
61
62 void didReceiveMessage(IPC::Connection&, IPC::Decoder&) final;
63 void didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&);
64
65 PAL::SessionID sessionID() const { return m_sessionID; }
66
67 void postMessageToServiceWorkerClient(WebCore::DocumentIdentifier destinationContextIdentifier, WebCore::MessageWithMessagePorts&&, WebCore::ServiceWorkerIdentifier sourceServiceWorkerIdentifier, const String& sourceOrigin);
68 void postMessageToServiceWorker(WebCore::ServiceWorkerIdentifier destination, WebCore::MessageWithMessagePorts&&, const WebCore::ServiceWorkerOrClientIdentifier& source);
69
70private:
71 // Implement SWServer::Connection (Messages to the client WebProcess)
72 void rejectJobInClient(WebCore::ServiceWorkerJobIdentifier, const WebCore::ExceptionData&) final;
73 void resolveRegistrationJobInClient(WebCore::ServiceWorkerJobIdentifier, const WebCore::ServiceWorkerRegistrationData&, WebCore::ShouldNotifyWhenResolved) final;
74 void resolveUnregistrationJobInClient(WebCore::ServiceWorkerJobIdentifier, const WebCore::ServiceWorkerRegistrationKey&, bool unregistrationResult) final;
75 void startScriptFetchInClient(WebCore::ServiceWorkerJobIdentifier, const WebCore::ServiceWorkerRegistrationKey&, WebCore::FetchOptions::Cache) final;
76 void updateRegistrationStateInClient(WebCore::ServiceWorkerRegistrationIdentifier, WebCore::ServiceWorkerRegistrationState, const Optional<WebCore::ServiceWorkerData>&) final;
77 void updateWorkerStateInClient(WebCore::ServiceWorkerIdentifier, WebCore::ServiceWorkerState) final;
78 void fireUpdateFoundEvent(WebCore::ServiceWorkerRegistrationIdentifier) final;
79 void setRegistrationLastUpdateTime(WebCore::ServiceWorkerRegistrationIdentifier, WallTime) final;
80 void setRegistrationUpdateViaCache(WebCore::ServiceWorkerRegistrationIdentifier, WebCore::ServiceWorkerUpdateViaCache) final;
81 void notifyClientsOfControllerChange(const HashSet<WebCore::DocumentIdentifier>& contextIdentifiers, const WebCore::ServiceWorkerData& newController);
82 void registrationReady(uint64_t registrationReadyRequestIdentifier, WebCore::ServiceWorkerRegistrationData&&) final;
83
84 void scheduleJobInServer(WebCore::ServiceWorkerJobData&&);
85
86 void startFetch(WebCore::ServiceWorkerRegistrationIdentifier, WebCore::FetchIdentifier, WebCore::ResourceRequest&&, WebCore::FetchOptions&&, IPC::FormDataReference&&, String&& referrer);
87 void cancelFetch(WebCore::ServiceWorkerRegistrationIdentifier, WebCore::FetchIdentifier);
88 void continueDidReceiveFetchResponse(WebCore::ServiceWorkerRegistrationIdentifier, WebCore::FetchIdentifier);
89
90 void matchRegistration(uint64_t registrationMatchRequestIdentifier, const WebCore::SecurityOriginData& topOrigin, const URL& clientURL);
91 void getRegistrations(uint64_t registrationMatchRequestIdentifier, const WebCore::SecurityOriginData& topOrigin, const URL& clientURL);
92
93 void registerServiceWorkerClient(WebCore::SecurityOriginData&& topOrigin, WebCore::ServiceWorkerClientData&&, const Optional<WebCore::ServiceWorkerRegistrationIdentifier>&, String&& userAgent);
94 void unregisterServiceWorkerClient(const WebCore::ServiceWorkerClientIdentifier&);
95 void syncTerminateWorkerFromClient(WebCore::ServiceWorkerIdentifier&&, CompletionHandler<void()>&&);
96
97 void serverToContextConnectionCreated(WebCore::SWServerToContextConnection&) final;
98
99 bool isThrottleable() const { return m_isThrottleable; }
100 bool hasMatchingClient(const WebCore::RegistrableDomain&) const;
101 bool computeThrottleState(const WebCore::RegistrableDomain&) const;
102 void setThrottleState(bool isThrottleable);
103 void updateThrottleState();
104
105 IPC::Connection* messageSenderConnection() const final { return m_contentConnection.ptr(); }
106 uint64_t messageSenderDestinationID() const final { return identifier().toUInt64(); }
107
108 template<typename U> static void sendToContextProcess(WebCore::SWServerToContextConnection&, U&& message);
109
110 PAL::SessionID m_sessionID;
111 Ref<IPC::Connection> m_contentConnection;
112 Ref<NetworkProcess> m_networkProcess;
113 HashMap<WebCore::ServiceWorkerClientIdentifier, WebCore::ClientOrigin> m_clientOrigins;
114 bool m_isThrottleable { true };
115};
116
117} // namespace WebKit
118
119#endif // ENABLE(SERVICE_WORKER)
120