1/*
2 * Copyright (C) 2012-2019 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#include "CacheStorageEngineConnection.h"
29#include "Connection.h"
30#include "DownloadID.h"
31#include "NetworkActivityTracker.h"
32#include "NetworkConnectionToWebProcessMessages.h"
33#include "NetworkMDNSRegister.h"
34#include "NetworkRTCProvider.h"
35#include "NetworkResourceLoadMap.h"
36#include "WebPaymentCoordinatorProxy.h"
37#include <WebCore/NetworkLoadInformation.h>
38#include <WebCore/PageIdentifier.h>
39#include <WebCore/ProcessIdentifier.h>
40#include <WebCore/RegistrableDomain.h>
41#include <wtf/RefCounted.h>
42
43namespace PAL {
44class SessionID;
45}
46
47namespace WebCore {
48class BlobDataFileReference;
49class BlobRegistryImpl;
50class ResourceError;
51class ResourceRequest;
52enum class StorageAccessPromptWasShown : bool;
53enum class StorageAccessWasGranted : bool;
54struct SameSiteInfo;
55
56enum class IncludeSecureCookies : bool;
57}
58
59namespace WebKit {
60
61class NetworkProcess;
62class NetworkResourceLoader;
63class NetworkSocketChannel;
64class NetworkSocketStream;
65class WebIDBConnectionToClient;
66class WebSWServerConnection;
67typedef uint64_t ResourceLoadIdentifier;
68
69namespace NetworkCache {
70struct DataKey;
71}
72
73class NetworkConnectionToWebProcess
74 : public RefCounted<NetworkConnectionToWebProcess>
75#if ENABLE(APPLE_PAY_REMOTE_UI)
76 , public WebPaymentCoordinatorProxy::Client
77#endif
78 , IPC::Connection::Client {
79public:
80 using RegistrableDomain = WebCore::RegistrableDomain;
81
82 static Ref<NetworkConnectionToWebProcess> create(NetworkProcess&, IPC::Connection::Identifier);
83 virtual ~NetworkConnectionToWebProcess();
84
85 IPC::Connection& connection() { return m_connection.get(); }
86 NetworkProcess& networkProcess() { return m_networkProcess.get(); }
87
88 void didCleanupResourceLoader(NetworkResourceLoader&);
89 void transferKeptAliveLoad(NetworkResourceLoader&);
90 void setOnLineState(bool);
91
92 bool captureExtraNetworkLoadMetricsEnabled() const { return m_captureExtraNetworkLoadMetricsEnabled; }
93
94 RefPtr<WebCore::BlobDataFileReference> getBlobDataFileReferenceForPath(const String& path);
95
96 void cleanupForSuspension(Function<void()>&&);
97 void endSuspension();
98
99 void getNetworkLoadInformationRequest(ResourceLoadIdentifier identifier, CompletionHandler<void(const WebCore::ResourceRequest&)>&& completionHandler)
100 {
101 completionHandler(m_networkLoadInformationByID.get(identifier).request);
102 }
103
104 void getNetworkLoadInformationResponse(ResourceLoadIdentifier identifier, CompletionHandler<void(const WebCore::ResourceResponse&)>&& completionHandler)
105 {
106 completionHandler(m_networkLoadInformationByID.get(identifier).response);
107 }
108
109 void getNetworkLoadIntermediateInformation(ResourceLoadIdentifier identifier, CompletionHandler<void(const Vector<WebCore::NetworkTransactionInformation>&)>&& completionHandler)
110 {
111 completionHandler(m_networkLoadInformationByID.get(identifier).transactions);
112 }
113
114 void takeNetworkLoadInformationMetrics(ResourceLoadIdentifier identifier, CompletionHandler<void(const WebCore::NetworkLoadMetrics&)>&& completionHandler)
115 {
116 completionHandler(m_networkLoadInformationByID.take(identifier).metrics);
117 }
118
119 void addNetworkLoadInformation(ResourceLoadIdentifier identifier, WebCore::NetworkLoadInformation&& information)
120 {
121 ASSERT(!m_networkLoadInformationByID.contains(identifier));
122 m_networkLoadInformationByID.add(identifier, WTFMove(information));
123 }
124
125 void addNetworkLoadInformationMetrics(ResourceLoadIdentifier identifier, const WebCore::NetworkLoadMetrics& metrics)
126 {
127 ASSERT(m_networkLoadInformationByID.contains(identifier));
128 m_networkLoadInformationByID.ensure(identifier, [] {
129 return WebCore::NetworkLoadInformation { };
130 }).iterator->value.metrics = metrics;
131 }
132
133 void removeNetworkLoadInformation(ResourceLoadIdentifier identifier)
134 {
135 m_networkLoadInformationByID.remove(identifier);
136 }
137
138 Optional<NetworkActivityTracker> startTrackingResourceLoad(WebCore::PageIdentifier, ResourceLoadIdentifier resourceID, bool isMainResource, const PAL::SessionID&);
139 void stopTrackingResourceLoad(ResourceLoadIdentifier resourceID, NetworkActivityTracker::CompletionCode);
140
141 WebCore::BlobRegistryImpl& blobRegistry();
142 Vector<RefPtr<WebCore::BlobDataFileReference>> filesInBlob(const URL&);
143 Vector<RefPtr<WebCore::BlobDataFileReference>> resolveBlobReferences(const NetworkResourceLoadParameters&);
144
145 void webPageWasAdded(PAL::SessionID, WebCore::PageIdentifier, WebCore::PageIdentifier oldPageID);
146 void webPageWasRemoved(PAL::SessionID, WebCore::PageIdentifier);
147 void webProcessSessionChanged(PAL::SessionID newSessionID, const Vector<WebCore::PageIdentifier>& pages);
148
149 void removeSocketChannel(uint64_t identifier);
150
151private:
152 NetworkConnectionToWebProcess(NetworkProcess&, IPC::Connection::Identifier);
153
154 void didFinishPreconnection(uint64_t preconnectionIdentifier, const WebCore::ResourceError&);
155
156 // IPC::Connection::Client
157 void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override;
158 void didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&) override;
159 void didClose(IPC::Connection&) override;
160 void didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference messageReceiverName, IPC::StringReference messageName) override;
161
162 // Message handlers.
163 void didReceiveNetworkConnectionToWebProcessMessage(IPC::Connection&, IPC::Decoder&);
164 void didReceiveSyncNetworkConnectionToWebProcessMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&);
165
166 void scheduleResourceLoad(NetworkResourceLoadParameters&&);
167 void performSynchronousLoad(NetworkResourceLoadParameters&&, Messages::NetworkConnectionToWebProcess::PerformSynchronousLoad::DelayedReply&&);
168 void loadPing(NetworkResourceLoadParameters&&);
169 void prefetchDNS(const String&);
170 void preconnectTo(uint64_t preconnectionIdentifier, NetworkResourceLoadParameters&&);
171
172 void removeLoadIdentifier(ResourceLoadIdentifier);
173 void pageLoadCompleted(WebCore::PageIdentifier);
174 void crossOriginRedirectReceived(ResourceLoadIdentifier, const URL& redirectURL);
175 void startDownload(PAL::SessionID, DownloadID, const WebCore::ResourceRequest&, const String& suggestedName = { });
176 void convertMainResourceLoadToDownload(PAL::SessionID, uint64_t mainResourceLoadIdentifier, DownloadID, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&);
177
178 void cookiesForDOM(PAL::SessionID, const URL& firstParty, const WebCore::SameSiteInfo&, const URL&, Optional<uint64_t> frameID, Optional<WebCore::PageIdentifier>, WebCore::IncludeSecureCookies, CompletionHandler<void(String cookieString, bool secureCookiesAccessed)>&&);
179 void setCookiesFromDOM(PAL::SessionID, const URL& firstParty, const WebCore::SameSiteInfo&, const URL&, Optional<uint64_t> frameID, Optional<WebCore::PageIdentifier>, const String&);
180 void cookiesEnabled(PAL::SessionID, CompletionHandler<void(bool)>&&);
181 void cookieRequestHeaderFieldValue(PAL::SessionID, const URL& firstParty, const WebCore::SameSiteInfo&, const URL&, Optional<uint64_t> frameID, Optional<WebCore::PageIdentifier>, WebCore::IncludeSecureCookies, CompletionHandler<void(String cookieString, bool secureCookiesAccessed)>&&);
182 void getRawCookies(PAL::SessionID, const URL& firstParty, const WebCore::SameSiteInfo&, const URL&, Optional<uint64_t> frameID, Optional<WebCore::PageIdentifier>, CompletionHandler<void(Vector<WebCore::Cookie>&&)>&&);
183 void deleteCookie(PAL::SessionID, const URL&, const String& cookieName);
184
185 void registerFileBlobURL(const URL&, const String& path, SandboxExtension::Handle&&, const String& contentType);
186 void registerBlobURL(const URL&, Vector<WebCore::BlobPart>&&, const String& contentType);
187 void registerBlobURLFromURL(const URL&, const URL& srcURL, bool shouldBypassConnectionCheck);
188 void registerBlobURLOptionallyFileBacked(const URL&, const URL& srcURL, const String& fileBackedPath, const String& contentType);
189 void registerBlobURLForSlice(const URL&, const URL& srcURL, int64_t start, int64_t end);
190 void blobSize(const URL&, CompletionHandler<void(uint64_t)>&&);
191 void unregisterBlobURL(const URL&);
192 void writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, CompletionHandler<void(Vector<String>&&)>&&);
193
194 void setCaptureExtraNetworkLoadMetricsEnabled(bool);
195
196 void createSocketStream(URL&&, PAL::SessionID, String cachePartition, uint64_t);
197
198 void createSocketChannel(PAL::SessionID, const WebCore::ResourceRequest&, const String& protocol, uint64_t identifier);
199
200 void ensureLegacyPrivateBrowsingSession();
201
202#if ENABLE(INDEXED_DATABASE)
203 // Messages handlers (Modern IDB).
204 void establishIDBConnectionToServer(PAL::SessionID, CompletionHandler<void(uint64_t serverConnectionIdentifier)>&&);
205#endif
206
207#if ENABLE(SERVICE_WORKER)
208 void establishSWServerConnection(PAL::SessionID, CompletionHandler<void(WebCore::SWServerConnectionIdentifier&&)>&&);
209 void unregisterSWConnections();
210#endif
211
212#if USE(LIBWEBRTC)
213 NetworkRTCProvider& rtcProvider();
214#endif
215#if ENABLE(WEB_RTC)
216 NetworkMDNSRegister& mdnsRegister() { return m_mdnsRegister; }
217#endif
218
219 CacheStorageEngineConnection& cacheStorageConnection();
220
221#if ENABLE(RESOURCE_LOAD_STATISTICS)
222 void removeStorageAccessForFrame(PAL::SessionID, uint64_t frameID, WebCore::PageIdentifier);
223 void clearPageSpecificDataForResourceLoadStatistics(PAL::SessionID, WebCore::PageIdentifier);
224
225 void logUserInteraction(PAL::SessionID, const RegistrableDomain&);
226 void logWebSocketLoading(PAL::SessionID, const RegistrableDomain& targetDomain, const RegistrableDomain& topFrameDomain, WallTime lastSeen);
227 void logSubresourceLoading(PAL::SessionID, const RegistrableDomain& targetDomain, const RegistrableDomain& topFrameDomain, WallTime lastSeen);
228 void logSubresourceRedirect(PAL::SessionID, const RegistrableDomain& sourceDomain, const RegistrableDomain& targetDomain);
229 void resourceLoadStatisticsUpdated(Vector<WebCore::ResourceLoadStatistics>&&);
230 void hasStorageAccess(PAL::SessionID, const RegistrableDomain& subFrameDomain, const RegistrableDomain& topFrameDomain, uint64_t frameID, WebCore::PageIdentifier, CompletionHandler<void(bool)>&&);
231 void requestStorageAccess(PAL::SessionID, const RegistrableDomain& subFrameDomain, const RegistrableDomain& topFrameDomain, uint64_t frameID, WebCore::PageIdentifier, CompletionHandler<void(WebCore::StorageAccessWasGranted, WebCore::StorageAccessPromptWasShown)>&&);
232 void requestStorageAccessUnderOpener(PAL::SessionID, WebCore::RegistrableDomain&& domainInNeedOfStorageAccess, WebCore::PageIdentifier openerPageID, WebCore::RegistrableDomain&& openerDomain);
233#endif
234
235 void addOriginAccessWhitelistEntry(const String& sourceOrigin, const String& destinationProtocol, const String& destinationHost, bool allowDestinationSubdomains);
236 void removeOriginAccessWhitelistEntry(const String& sourceOrigin, const String& destinationProtocol, const String& destinationHost, bool allowDestinationSubdomains);
237 void resetOriginAccessWhitelists();
238
239 struct ResourceNetworkActivityTracker {
240 ResourceNetworkActivityTracker() = default;
241 ResourceNetworkActivityTracker(const ResourceNetworkActivityTracker&) = default;
242 ResourceNetworkActivityTracker(ResourceNetworkActivityTracker&&) = default;
243 ResourceNetworkActivityTracker(WebCore::PageIdentifier pageID)
244 : pageID { pageID }
245 , isRootActivity { true }
246 , networkActivity { NetworkActivityTracker::Label::LoadPage }
247 {
248 }
249
250 ResourceNetworkActivityTracker(WebCore::PageIdentifier pageID, ResourceLoadIdentifier resourceID)
251 : pageID { pageID }
252 , resourceID { resourceID }
253 , networkActivity { NetworkActivityTracker::Label::LoadResource }
254 {
255 }
256
257 WebCore::PageIdentifier pageID;
258 ResourceLoadIdentifier resourceID { 0 };
259 bool isRootActivity { false };
260 NetworkActivityTracker networkActivity;
261 };
262
263 void stopAllNetworkActivityTracking();
264 void stopAllNetworkActivityTrackingForPage(WebCore::PageIdentifier);
265 size_t findRootNetworkActivity(WebCore::PageIdentifier);
266 size_t findNetworkActivityTracker(ResourceLoadIdentifier resourceID);
267
268#if ENABLE(APPLE_PAY_REMOTE_UI)
269 WebPaymentCoordinatorProxy& paymentCoordinator();
270
271 // WebPaymentCoordinatorProxy::Client
272 IPC::Connection* paymentCoordinatorConnection(const WebPaymentCoordinatorProxy&) final;
273 UIViewController *paymentCoordinatorPresentingViewController(const WebPaymentCoordinatorProxy&) final;
274 const String& paymentCoordinatorBoundInterfaceIdentifier(const WebPaymentCoordinatorProxy&, PAL::SessionID) final;
275 const String& paymentCoordinatorCTDataConnectionServiceType(const WebPaymentCoordinatorProxy&, PAL::SessionID) final;
276 const String& paymentCoordinatorSourceApplicationBundleIdentifier(const WebPaymentCoordinatorProxy&, PAL::SessionID) final;
277 const String& paymentCoordinatorSourceApplicationSecondaryIdentifier(const WebPaymentCoordinatorProxy&, PAL::SessionID) final;
278 std::unique_ptr<PaymentAuthorizationPresenter> paymentCoordinatorAuthorizationPresenter(WebPaymentCoordinatorProxy&, PKPaymentRequest *) final;
279 void paymentCoordinatorAddMessageReceiver(WebPaymentCoordinatorProxy&, const IPC::StringReference&, IPC::MessageReceiver&) final;
280 void paymentCoordinatorRemoveMessageReceiver(WebPaymentCoordinatorProxy&, const IPC::StringReference&) final;
281#endif
282
283 Ref<IPC::Connection> m_connection;
284 Ref<NetworkProcess> m_networkProcess;
285
286 HashMap<uint64_t, RefPtr<NetworkSocketStream>> m_networkSocketStreams;
287 HashMap<uint64_t, std::unique_ptr<NetworkSocketChannel>> m_networkSocketChannels;
288 NetworkResourceLoadMap m_networkResourceLoaders;
289 HashMap<String, RefPtr<WebCore::BlobDataFileReference>> m_blobDataFileReferences;
290 Vector<ResourceNetworkActivityTracker> m_networkActivityTrackers;
291
292 HashMap<ResourceLoadIdentifier, WebCore::NetworkLoadInformation> m_networkLoadInformationByID;
293
294
295#if USE(LIBWEBRTC)
296 RefPtr<NetworkRTCProvider> m_rtcProvider;
297#endif
298#if ENABLE(WEB_RTC)
299 NetworkMDNSRegister m_mdnsRegister;
300#endif
301
302 bool m_captureExtraNetworkLoadMetricsEnabled { false };
303
304 RefPtr<CacheStorageEngineConnection> m_cacheStorageConnection;
305
306#if ENABLE(INDEXED_DATABASE)
307 HashMap<uint64_t, RefPtr<WebIDBConnectionToClient>> m_webIDBConnections;
308#endif
309
310#if ENABLE(SERVICE_WORKER)
311 HashMap<WebCore::SWServerConnectionIdentifier, WeakPtr<WebSWServerConnection>> m_swConnections;
312#endif
313
314#if ENABLE(APPLE_PAY_REMOTE_UI)
315 std::unique_ptr<WebPaymentCoordinatorProxy> m_paymentCoordinator;
316#endif
317};
318
319} // namespace WebKit
320