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#include "config.h"
27#include "NetworkConnectionToWebProcess.h"
28
29#include "BlobDataFileReferenceWithSandboxExtension.h"
30#include "CacheStorageEngineConnectionMessages.h"
31#include "DataReference.h"
32#include "NetworkCache.h"
33#include "NetworkMDNSRegisterMessages.h"
34#include "NetworkProcess.h"
35#include "NetworkProcessConnectionMessages.h"
36#include "NetworkProcessMessages.h"
37#include "NetworkRTCMonitorMessages.h"
38#include "NetworkRTCProviderMessages.h"
39#include "NetworkRTCSocketMessages.h"
40#include "NetworkResourceLoadParameters.h"
41#include "NetworkResourceLoader.h"
42#include "NetworkResourceLoaderMessages.h"
43#include "NetworkSession.h"
44#include "NetworkSocketChannel.h"
45#include "NetworkSocketChannelMessages.h"
46#include "NetworkSocketStream.h"
47#include "NetworkSocketStreamMessages.h"
48#include "PingLoad.h"
49#include "PreconnectTask.h"
50#include "ServiceWorkerFetchTaskMessages.h"
51#include "StorageManager.h"
52#include "StorageManagerMessages.h"
53#include "WebCoreArgumentCoders.h"
54#include "WebErrors.h"
55#include "WebIDBConnectionToClient.h"
56#include "WebIDBConnectionToClientMessages.h"
57#include "WebProcessPoolMessages.h"
58#include "WebResourceLoadStatisticsStore.h"
59#include "WebSWServerConnection.h"
60#include "WebSWServerConnectionMessages.h"
61#include "WebSWServerToContextConnection.h"
62#include "WebSWServerToContextConnectionMessages.h"
63#include "WebsiteDataStoreParameters.h"
64#include <WebCore/DocumentStorageAccess.h>
65#include <WebCore/NetworkStorageSession.h>
66#include <WebCore/ResourceLoadStatistics.h>
67#include <WebCore/ResourceRequest.h>
68#include <WebCore/SameSiteInfo.h>
69#include <WebCore/SecurityPolicy.h>
70
71#if ENABLE(APPLE_PAY_REMOTE_UI)
72#include "WebPaymentCoordinatorProxyMessages.h"
73#endif
74
75namespace WebKit {
76using namespace WebCore;
77
78Ref<NetworkConnectionToWebProcess> NetworkConnectionToWebProcess::create(NetworkProcess& networkProcess, IPC::Connection::Identifier connectionIdentifier)
79{
80 return adoptRef(*new NetworkConnectionToWebProcess(networkProcess, connectionIdentifier));
81}
82
83NetworkConnectionToWebProcess::NetworkConnectionToWebProcess(NetworkProcess& networkProcess, IPC::Connection::Identifier connectionIdentifier)
84 : m_connection(IPC::Connection::createServerConnection(connectionIdentifier, *this))
85 , m_networkProcess(networkProcess)
86#if ENABLE(WEB_RTC)
87 , m_mdnsRegister(*this)
88#endif
89{
90 RELEASE_ASSERT(RunLoop::isMain());
91
92 // Use this flag to force synchronous messages to be treated as asynchronous messages in the WebProcess.
93 // Otherwise, the WebProcess would process incoming synchronous IPC while waiting for a synchronous IPC
94 // reply from the Network process, which would be unsafe.
95 m_connection->setOnlySendMessagesAsDispatchWhenWaitingForSyncReplyWhenProcessingSuchAMessage(true);
96 m_connection->open();
97}
98
99NetworkConnectionToWebProcess::~NetworkConnectionToWebProcess()
100{
101 RELEASE_ASSERT(RunLoop::isMain());
102
103 m_connection->invalidate();
104#if USE(LIBWEBRTC)
105 if (m_rtcProvider)
106 m_rtcProvider->close();
107#endif
108
109#if ENABLE(SERVICE_WORKER)
110 unregisterSWConnections();
111#endif
112}
113
114void NetworkConnectionToWebProcess::didCleanupResourceLoader(NetworkResourceLoader& loader)
115{
116 RELEASE_ASSERT(loader.identifier());
117 RELEASE_ASSERT(RunLoop::isMain());
118
119 if (loader.isKeptAlive()) {
120 networkProcess().removeKeptAliveLoad(loader);
121 return;
122 }
123
124 ASSERT(m_networkResourceLoaders.get(loader.identifier()) == &loader);
125 m_networkResourceLoaders.remove(loader.identifier());
126}
127
128void NetworkConnectionToWebProcess::transferKeptAliveLoad(NetworkResourceLoader& loader)
129{
130 RELEASE_ASSERT(RunLoop::isMain());
131 ASSERT(loader.isKeptAlive());
132 ASSERT(m_networkResourceLoaders.get(loader.identifier()) == &loader);
133 if (auto takenLoader = m_networkResourceLoaders.take(loader.identifier()))
134 m_networkProcess->addKeptAliveLoad(takenLoader.releaseNonNull());
135}
136
137void NetworkConnectionToWebProcess::didReceiveMessage(IPC::Connection& connection, IPC::Decoder& decoder)
138{
139 if (decoder.messageReceiverName() == Messages::NetworkConnectionToWebProcess::messageReceiverName()) {
140 didReceiveNetworkConnectionToWebProcessMessage(connection, decoder);
141 return;
142 }
143
144 if (decoder.messageReceiverName() == Messages::NetworkResourceLoader::messageReceiverName()) {
145 RELEASE_ASSERT(RunLoop::isMain());
146 RELEASE_ASSERT(decoder.destinationID());
147 if (auto* loader = m_networkResourceLoaders.get(decoder.destinationID()))
148 loader->didReceiveNetworkResourceLoaderMessage(connection, decoder);
149 return;
150 }
151
152 if (decoder.messageReceiverName() == Messages::NetworkSocketStream::messageReceiverName()) {
153 if (auto* socketStream = m_networkSocketStreams.get(decoder.destinationID())) {
154 socketStream->didReceiveMessage(connection, decoder);
155 if (decoder.messageName() == Messages::NetworkSocketStream::Close::name())
156 m_networkSocketStreams.remove(decoder.destinationID());
157 }
158 return;
159 }
160
161 if (decoder.messageReceiverName() == Messages::NetworkSocketChannel::messageReceiverName()) {
162 if (auto* channel = m_networkSocketChannels.get(decoder.destinationID()))
163 channel->didReceiveMessage(connection, decoder);
164 return;
165 }
166
167 if (decoder.messageReceiverName() == Messages::NetworkProcess::messageReceiverName()) {
168 m_networkProcess->didReceiveNetworkProcessMessage(connection, decoder);
169 return;
170 }
171
172
173#if USE(LIBWEBRTC)
174 if (decoder.messageReceiverName() == Messages::NetworkRTCSocket::messageReceiverName()) {
175 rtcProvider().didReceiveNetworkRTCSocketMessage(connection, decoder);
176 return;
177 }
178 if (decoder.messageReceiverName() == Messages::NetworkRTCMonitor::messageReceiverName()) {
179 rtcProvider().didReceiveNetworkRTCMonitorMessage(connection, decoder);
180 return;
181 }
182 if (decoder.messageReceiverName() == Messages::NetworkRTCProvider::messageReceiverName()) {
183 rtcProvider().didReceiveMessage(connection, decoder);
184 return;
185 }
186#endif
187#if ENABLE(WEB_RTC)
188 if (decoder.messageReceiverName() == Messages::NetworkMDNSRegister::messageReceiverName()) {
189 mdnsRegister().didReceiveMessage(connection, decoder);
190 return;
191 }
192#endif
193
194 if (decoder.messageReceiverName() == Messages::CacheStorageEngineConnection::messageReceiverName()) {
195 cacheStorageConnection().didReceiveMessage(connection, decoder);
196 return;
197 }
198
199#if ENABLE(INDEXED_DATABASE)
200 if (decoder.messageReceiverName() == Messages::WebIDBConnectionToClient::messageReceiverName()) {
201 auto iterator = m_webIDBConnections.find(decoder.destinationID());
202 if (iterator != m_webIDBConnections.end())
203 iterator->value->didReceiveMessage(connection, decoder);
204 return;
205 }
206#endif
207
208#if ENABLE(SERVICE_WORKER)
209 if (decoder.messageReceiverName() == Messages::WebSWServerConnection::messageReceiverName()) {
210 if (auto swConnection = m_swConnections.get(makeObjectIdentifier<SWServerConnectionIdentifierType>(decoder.destinationID())))
211 swConnection->didReceiveMessage(connection, decoder);
212 return;
213 }
214
215 if (decoder.messageReceiverName() == Messages::WebSWServerToContextConnection::messageReceiverName()) {
216 if (auto* contextConnection = m_networkProcess->connectionToContextProcessFromIPCConnection(connection)) {
217 contextConnection->didReceiveMessage(connection, decoder);
218 return;
219 }
220 }
221
222 if (decoder.messageReceiverName() == Messages::ServiceWorkerFetchTask::messageReceiverName()) {
223 if (auto* contextConnection = m_networkProcess->connectionToContextProcessFromIPCConnection(connection)) {
224 contextConnection->didReceiveFetchTaskMessage(connection, decoder);
225 return;
226 }
227 }
228#endif
229
230#if ENABLE(APPLE_PAY_REMOTE_UI)
231 if (decoder.messageReceiverName() == Messages::WebPaymentCoordinatorProxy::messageReceiverName())
232 return paymentCoordinator().didReceiveMessage(connection, decoder);
233#endif
234
235 if (decoder.messageReceiverName() == Messages::StorageManager::messageReceiverName()) {
236 if (auto* session = m_networkProcess->networkSessionByConnection(connection)) {
237 session->storageManager().didReceiveMessage(connection, decoder);
238 return;
239 }
240 }
241
242 ASSERT_NOT_REACHED();
243}
244
245#if USE(LIBWEBRTC)
246NetworkRTCProvider& NetworkConnectionToWebProcess::rtcProvider()
247{
248 if (!m_rtcProvider)
249 m_rtcProvider = NetworkRTCProvider::create(*this);
250 return *m_rtcProvider;
251}
252#endif
253
254CacheStorageEngineConnection& NetworkConnectionToWebProcess::cacheStorageConnection()
255{
256 if (!m_cacheStorageConnection)
257 m_cacheStorageConnection = CacheStorageEngineConnection::create(*this);
258 return *m_cacheStorageConnection;
259}
260
261void NetworkConnectionToWebProcess::didReceiveSyncMessage(IPC::Connection& connection, IPC::Decoder& decoder, std::unique_ptr<IPC::Encoder>& reply)
262{
263 if (decoder.messageReceiverName() == Messages::NetworkConnectionToWebProcess::messageReceiverName()) {
264 didReceiveSyncNetworkConnectionToWebProcessMessage(connection, decoder, reply);
265 return;
266 }
267
268#if ENABLE(SERVICE_WORKER)
269 if (decoder.messageReceiverName() == Messages::WebSWServerConnection::messageReceiverName()) {
270 if (auto swConnection = m_swConnections.get(makeObjectIdentifier<SWServerConnectionIdentifierType>(decoder.destinationID())))
271 swConnection->didReceiveSyncMessage(connection, decoder, reply);
272 return;
273 }
274#endif
275
276#if ENABLE(APPLE_PAY_REMOTE_UI)
277 if (decoder.messageReceiverName() == Messages::WebPaymentCoordinatorProxy::messageReceiverName())
278 return paymentCoordinator().didReceiveSyncMessage(connection, decoder, reply);
279#endif
280
281 if (decoder.messageReceiverName() == Messages::StorageManager::messageReceiverName()) {
282 if (auto* session = m_networkProcess->networkSessionByConnection(connection)) {
283 session->storageManager().didReceiveSyncMessage(connection, decoder, reply);
284 return;
285 }
286 }
287
288 ASSERT_NOT_REACHED();
289}
290
291void NetworkConnectionToWebProcess::didClose(IPC::Connection& connection)
292{
293#if ENABLE(SERVICE_WORKER)
294 if (RefPtr<WebSWServerToContextConnection> serverToContextConnection = m_networkProcess->connectionToContextProcessFromIPCConnection(connection)) {
295 // Service Worker process exited.
296 m_networkProcess->connectionToContextProcessWasClosed(serverToContextConnection.releaseNonNull());
297 return;
298 }
299#else
300 UNUSED_PARAM(connection);
301#endif
302
303 // Protect ourself as we might be otherwise be deleted during this function.
304 Ref<NetworkConnectionToWebProcess> protector(*this);
305
306 while (!m_networkResourceLoaders.isEmpty())
307 m_networkResourceLoaders.begin()->value->abort();
308
309 // All trackers of resources that were in the middle of being loaded were
310 // stopped with the abort() calls above, but we still need to sweep up the
311 // root activity trackers.
312 stopAllNetworkActivityTracking();
313
314 m_networkProcess->webProcessWasDisconnected(connection);
315
316 m_networkProcess->networkBlobRegistry().connectionToWebProcessDidClose(*this);
317 m_networkProcess->removeNetworkConnectionToWebProcess(*this);
318
319#if USE(LIBWEBRTC)
320 if (m_rtcProvider) {
321 m_rtcProvider->close();
322 m_rtcProvider = nullptr;
323 }
324#endif
325
326#if ENABLE(INDEXED_DATABASE)
327 auto idbConnections = m_webIDBConnections;
328 for (auto& connection : idbConnections.values())
329 connection->disconnectedFromWebProcess();
330
331 m_webIDBConnections.clear();
332#endif
333
334#if ENABLE(SERVICE_WORKER)
335 unregisterSWConnections();
336#endif
337
338#if ENABLE(APPLE_PAY_REMOTE_UI)
339 m_paymentCoordinator = nullptr;
340#endif
341}
342
343void NetworkConnectionToWebProcess::didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference, IPC::StringReference)
344{
345}
346
347void NetworkConnectionToWebProcess::createSocketStream(URL&& url, PAL::SessionID sessionID, String cachePartition, uint64_t identifier)
348{
349 ASSERT(!m_networkSocketStreams.contains(identifier));
350 WebCore::SourceApplicationAuditToken token = { };
351#if PLATFORM(COCOA)
352 token = { m_networkProcess->sourceApplicationAuditData() };
353#endif
354 m_networkSocketStreams.set(identifier, NetworkSocketStream::create(m_networkProcess.get(), WTFMove(url), sessionID, cachePartition, identifier, m_connection, WTFMove(token)));
355}
356
357void NetworkConnectionToWebProcess::createSocketChannel(PAL::SessionID sessionID, const ResourceRequest& request, const String& protocol, uint64_t identifier)
358{
359 ASSERT(!m_networkSocketChannels.contains(identifier));
360 if (auto channel = NetworkSocketChannel::create(*this, sessionID, request, protocol, identifier))
361 m_networkSocketChannels.add(identifier, WTFMove(channel));
362}
363
364void NetworkConnectionToWebProcess::removeSocketChannel(uint64_t identifier)
365{
366 ASSERT(m_networkSocketChannels.contains(identifier));
367 m_networkSocketChannels.remove(identifier);
368}
369
370void NetworkConnectionToWebProcess::cleanupForSuspension(Function<void()>&& completionHandler)
371{
372#if USE(LIBWEBRTC)
373 if (m_rtcProvider) {
374 m_rtcProvider->closeListeningSockets(WTFMove(completionHandler));
375 return;
376 }
377#endif
378 completionHandler();
379}
380
381void NetworkConnectionToWebProcess::endSuspension()
382{
383#if USE(LIBWEBRTC)
384 if (m_rtcProvider)
385 m_rtcProvider->authorizeListeningSockets();
386#endif
387}
388
389Vector<RefPtr<WebCore::BlobDataFileReference>> NetworkConnectionToWebProcess::resolveBlobReferences(const NetworkResourceLoadParameters& parameters)
390{
391 Vector<RefPtr<WebCore::BlobDataFileReference>> files;
392 if (auto* body = parameters.request.httpBody()) {
393 for (auto& element : body->elements()) {
394 if (auto* blobData = WTF::get_if<FormDataElement::EncodedBlobData>(element.data))
395 files.appendVector(m_networkProcess->networkBlobRegistry().filesInBlob(*this, blobData->url));
396 }
397 const_cast<WebCore::ResourceRequest&>(parameters.request).setHTTPBody(body->resolveBlobReferences(m_networkProcess->networkBlobRegistry().blobRegistry()));
398 }
399
400 return files;
401}
402
403void NetworkConnectionToWebProcess::scheduleResourceLoad(NetworkResourceLoadParameters&& loadParameters)
404{
405 auto identifier = loadParameters.identifier;
406 RELEASE_ASSERT(identifier);
407 RELEASE_ASSERT(RunLoop::isMain());
408 ASSERT(!m_networkResourceLoaders.contains(identifier));
409
410 auto loader = NetworkResourceLoader::create(WTFMove(loadParameters), *this);
411 m_networkResourceLoaders.add(identifier, loader.copyRef());
412 loader->start();
413}
414
415void NetworkConnectionToWebProcess::performSynchronousLoad(NetworkResourceLoadParameters&& loadParameters, Messages::NetworkConnectionToWebProcess::PerformSynchronousLoad::DelayedReply&& reply)
416{
417 auto identifier = loadParameters.identifier;
418 RELEASE_ASSERT(identifier);
419 RELEASE_ASSERT(RunLoop::isMain());
420 ASSERT(!m_networkResourceLoaders.contains(identifier));
421
422 auto loader = NetworkResourceLoader::create(WTFMove(loadParameters), *this, WTFMove(reply));
423 m_networkResourceLoaders.add(identifier, loader.copyRef());
424 loader->start();
425}
426
427void NetworkConnectionToWebProcess::loadPing(NetworkResourceLoadParameters&& loadParameters)
428{
429 auto completionHandler = [connection = m_connection.copyRef(), identifier = loadParameters.identifier] (const ResourceError& error, const ResourceResponse& response) {
430 connection->send(Messages::NetworkProcessConnection::DidFinishPingLoad(identifier, error, response), 0);
431 };
432
433 // PingLoad manages its own lifetime, deleting itself when its purpose has been fulfilled.
434 new PingLoad(*this, networkProcess(), WTFMove(loadParameters), WTFMove(completionHandler));
435}
436
437void NetworkConnectionToWebProcess::setOnLineState(bool isOnLine)
438{
439 m_connection->send(Messages::NetworkProcessConnection::SetOnLineState(isOnLine), 0);
440}
441
442void NetworkConnectionToWebProcess::removeLoadIdentifier(ResourceLoadIdentifier identifier)
443{
444 RELEASE_ASSERT(identifier);
445 RELEASE_ASSERT(RunLoop::isMain());
446
447 RefPtr<NetworkResourceLoader> loader = m_networkResourceLoaders.get(identifier);
448
449 // It's possible we have no loader for this identifier if the NetworkProcess crashed and this was a respawned NetworkProcess.
450 if (!loader)
451 return;
452
453 // Abort the load now, as the WebProcess won't be able to respond to messages any more which might lead
454 // to leaked loader resources (connections, threads, etc).
455 loader->abort();
456 ASSERT(!m_networkResourceLoaders.contains(identifier));
457}
458
459void NetworkConnectionToWebProcess::pageLoadCompleted(PageIdentifier webPageID)
460{
461 stopAllNetworkActivityTrackingForPage(webPageID);
462}
463
464void NetworkConnectionToWebProcess::prefetchDNS(const String& hostname)
465{
466 m_networkProcess->prefetchDNS(hostname);
467}
468
469void NetworkConnectionToWebProcess::preconnectTo(uint64_t preconnectionIdentifier, NetworkResourceLoadParameters&& parameters)
470{
471 ASSERT(!parameters.request.httpBody());
472
473#if ENABLE(SERVER_PRECONNECT)
474 new PreconnectTask(networkProcess(), WTFMove(parameters), [this, protectedThis = makeRef(*this), identifier = preconnectionIdentifier] (const ResourceError& error) {
475 didFinishPreconnection(identifier, error);
476 });
477#else
478 UNUSED_PARAM(parameters);
479 didFinishPreconnection(preconnectionIdentifier, internalError(parameters.request.url()));
480#endif
481}
482
483void NetworkConnectionToWebProcess::didFinishPreconnection(uint64_t preconnectionIdentifier, const ResourceError& error)
484{
485 if (!m_connection->isValid())
486 return;
487
488 m_connection->send(Messages::NetworkProcessConnection::DidFinishPreconnection(preconnectionIdentifier, error), 0);
489}
490
491static NetworkStorageSession& storageSession(const NetworkProcess& networkProcess, PAL::SessionID sessionID)
492{
493 ASSERT(sessionID.isValid());
494 if (sessionID != PAL::SessionID::defaultSessionID()) {
495 if (auto* storageSession = networkProcess.storageSession(sessionID))
496 return *storageSession;
497
498 // Some requests with private browsing mode requested may still be coming shortly after NetworkProcess was told to destroy its session.
499 // FIXME: Find a way to track private browsing sessions more rigorously.
500 LOG_ERROR("Non-default storage session was requested, but there was no session for it. Please file a bug unless you just disabled private browsing, in which case it's an expected race.");
501 }
502 return networkProcess.defaultStorageSession();
503}
504
505void NetworkConnectionToWebProcess::startDownload(PAL::SessionID sessionID, DownloadID downloadID, const ResourceRequest& request, const String& suggestedName)
506{
507 m_networkProcess->downloadManager().startDownload(sessionID, downloadID, request, suggestedName);
508}
509
510void NetworkConnectionToWebProcess::convertMainResourceLoadToDownload(PAL::SessionID sessionID, uint64_t mainResourceLoadIdentifier, DownloadID downloadID, const ResourceRequest& request, const ResourceResponse& response)
511{
512 RELEASE_ASSERT(RunLoop::isMain());
513
514 // In case a response is served from service worker, we do not have yet the ability to convert the load.
515 if (!mainResourceLoadIdentifier || response.source() == ResourceResponse::Source::ServiceWorker) {
516 m_networkProcess->downloadManager().startDownload(sessionID, downloadID, request);
517 return;
518 }
519
520 NetworkResourceLoader* loader = m_networkResourceLoaders.get(mainResourceLoadIdentifier);
521 if (!loader) {
522 // If we're trying to download a blob here loader can be null.
523 return;
524 }
525
526 loader->convertToDownload(downloadID, request, response);
527}
528
529void NetworkConnectionToWebProcess::cookiesForDOM(PAL::SessionID sessionID, const URL& firstParty, const SameSiteInfo& sameSiteInfo, const URL& url, Optional<uint64_t> frameID, Optional<PageIdentifier> pageID, IncludeSecureCookies includeSecureCookies, CompletionHandler<void(String cookieString, bool secureCookiesAccessed)>&& completionHandler)
530{
531 auto& networkStorageSession = storageSession(networkProcess(), sessionID);
532 auto result = networkStorageSession.cookiesForDOM(firstParty, sameSiteInfo, url, frameID, pageID, includeSecureCookies);
533#if ENABLE(RESOURCE_LOAD_STATISTICS) && !RELEASE_LOG_DISABLED
534 if (auto session = networkProcess().networkSession(sessionID)) {
535 if (session->shouldLogCookieInformation())
536 NetworkResourceLoader::logCookieInformation(*this, "NetworkConnectionToWebProcess::cookiesForDOM", reinterpret_cast<const void*>(this), networkStorageSession, firstParty, sameSiteInfo, url, emptyString(), frameID, pageID, WTF::nullopt);
537 }
538#endif
539 completionHandler(WTFMove(result.first), result.second);
540}
541
542void NetworkConnectionToWebProcess::setCookiesFromDOM(PAL::SessionID sessionID, const URL& firstParty, const SameSiteInfo& sameSiteInfo, const URL& url, Optional<uint64_t> frameID, Optional<PageIdentifier> pageID, const String& cookieString)
543{
544 auto& networkStorageSession = storageSession(networkProcess(), sessionID);
545 networkStorageSession.setCookiesFromDOM(firstParty, sameSiteInfo, url, frameID, pageID, cookieString);
546#if ENABLE(RESOURCE_LOAD_STATISTICS) && !RELEASE_LOG_DISABLED
547 if (auto session = networkProcess().networkSession(sessionID)) {
548 if (session->shouldLogCookieInformation())
549 NetworkResourceLoader::logCookieInformation(*this, "NetworkConnectionToWebProcess::setCookiesFromDOM", reinterpret_cast<const void*>(this), networkStorageSession, firstParty, sameSiteInfo, url, emptyString(), frameID, pageID, WTF::nullopt);
550 }
551#endif
552}
553
554void NetworkConnectionToWebProcess::cookiesEnabled(PAL::SessionID sessionID, CompletionHandler<void(bool)>&& completionHandler)
555{
556 completionHandler(storageSession(networkProcess(), sessionID).cookiesEnabled());
557}
558
559void NetworkConnectionToWebProcess::cookieRequestHeaderFieldValue(PAL::SessionID sessionID, const URL& firstParty, const SameSiteInfo& sameSiteInfo, const URL& url, Optional<uint64_t> frameID, Optional<PageIdentifier> pageID, IncludeSecureCookies includeSecureCookies, CompletionHandler<void(String, bool)>&& completionHandler)
560{
561 auto result = storageSession(networkProcess(), sessionID).cookieRequestHeaderFieldValue(firstParty, sameSiteInfo, url, frameID, pageID, includeSecureCookies);
562 completionHandler(WTFMove(result.first), result.second);
563}
564
565void NetworkConnectionToWebProcess::getRawCookies(PAL::SessionID sessionID, const URL& firstParty, const SameSiteInfo& sameSiteInfo, const URL& url, Optional<uint64_t> frameID, Optional<PageIdentifier> pageID, CompletionHandler<void(Vector<WebCore::Cookie>&&)>&& completionHandler)
566{
567 Vector<WebCore::Cookie> result;
568 storageSession(networkProcess(), sessionID).getRawCookies(firstParty, sameSiteInfo, url, frameID, pageID, result);
569 completionHandler(WTFMove(result));
570}
571
572void NetworkConnectionToWebProcess::deleteCookie(PAL::SessionID sessionID, const URL& url, const String& cookieName)
573{
574 storageSession(networkProcess(), sessionID).deleteCookie(url, cookieName);
575}
576
577void NetworkConnectionToWebProcess::registerFileBlobURL(const URL& url, const String& path, SandboxExtension::Handle&& extensionHandle, const String& contentType)
578{
579 m_networkProcess->networkBlobRegistry().registerFileBlobURL(*this, url, path, SandboxExtension::create(WTFMove(extensionHandle)), contentType);
580}
581
582void NetworkConnectionToWebProcess::registerBlobURL(const URL& url, Vector<BlobPart>&& blobParts, const String& contentType)
583{
584 m_networkProcess->networkBlobRegistry().registerBlobURL(*this, url, WTFMove(blobParts), contentType);
585}
586
587void NetworkConnectionToWebProcess::registerBlobURLFromURL(const URL& url, const URL& srcURL, bool shouldBypassConnectionCheck)
588{
589 m_networkProcess->networkBlobRegistry().registerBlobURL(*this, url, srcURL, shouldBypassConnectionCheck);
590}
591
592void NetworkConnectionToWebProcess::registerBlobURLOptionallyFileBacked(const URL& url, const URL& srcURL, const String& fileBackedPath, const String& contentType)
593{
594 m_networkProcess->networkBlobRegistry().registerBlobURLOptionallyFileBacked(*this, url, srcURL, fileBackedPath, contentType);
595}
596
597void NetworkConnectionToWebProcess::registerBlobURLForSlice(const URL& url, const URL& srcURL, int64_t start, int64_t end)
598{
599 m_networkProcess->networkBlobRegistry().registerBlobURLForSlice(*this, url, srcURL, start, end);
600}
601
602void NetworkConnectionToWebProcess::unregisterBlobURL(const URL& url)
603{
604 m_networkProcess->networkBlobRegistry().unregisterBlobURL(*this, url);
605}
606
607void NetworkConnectionToWebProcess::blobSize(const URL& url, CompletionHandler<void(uint64_t)>&& completionHandler)
608{
609 completionHandler(m_networkProcess->networkBlobRegistry().blobSize(*this, url));
610}
611
612void NetworkConnectionToWebProcess::writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, CompletionHandler<void(Vector<String>&&)>&& completionHandler)
613{
614 Vector<RefPtr<BlobDataFileReference>> fileReferences;
615 for (auto& url : blobURLs)
616 fileReferences.appendVector(m_networkProcess->networkBlobRegistry().filesInBlob(*this, { { }, url }));
617
618 for (auto& file : fileReferences)
619 file->prepareForFileAccess();
620
621 m_networkProcess->networkBlobRegistry().writeBlobsToTemporaryFiles(blobURLs, [fileReferences = WTFMove(fileReferences), completionHandler = WTFMove(completionHandler)](auto&& fileNames) mutable {
622 for (auto& file : fileReferences)
623 file->revokeFileAccess();
624 completionHandler(WTFMove(fileNames));
625 });
626}
627
628Vector<RefPtr<WebCore::BlobDataFileReference>> NetworkConnectionToWebProcess::filesInBlob(const URL& url)
629{
630 return m_networkProcess->networkBlobRegistry().filesInBlob(*this, url);
631}
632
633WebCore::BlobRegistryImpl& NetworkConnectionToWebProcess::blobRegistry()
634{
635 return m_networkProcess->networkBlobRegistry().blobRegistry();
636}
637
638void NetworkConnectionToWebProcess::setCaptureExtraNetworkLoadMetricsEnabled(bool enabled)
639{
640 m_captureExtraNetworkLoadMetricsEnabled = enabled;
641 if (m_captureExtraNetworkLoadMetricsEnabled)
642 return;
643
644 m_networkLoadInformationByID.clear();
645 for (auto& loader : m_networkResourceLoaders.values())
646 loader->disableExtraNetworkLoadMetricsCapture();
647}
648
649void NetworkConnectionToWebProcess::ensureLegacyPrivateBrowsingSession()
650{
651 m_networkProcess->addWebsiteDataStore(WebsiteDataStoreParameters::legacyPrivateSessionParameters());
652}
653
654#if ENABLE(RESOURCE_LOAD_STATISTICS)
655void NetworkConnectionToWebProcess::removeStorageAccessForFrame(PAL::SessionID sessionID, uint64_t frameID, PageIdentifier pageID)
656{
657 if (auto* storageSession = networkProcess().storageSession(sessionID))
658 storageSession->removeStorageAccessForFrame(frameID, pageID);
659}
660
661void NetworkConnectionToWebProcess::clearPageSpecificDataForResourceLoadStatistics(PAL::SessionID sessionID, PageIdentifier pageID)
662{
663 if (auto* storageSession = networkProcess().storageSession(sessionID))
664 storageSession->clearPageSpecificDataForResourceLoadStatistics(pageID);
665}
666
667void NetworkConnectionToWebProcess::logUserInteraction(PAL::SessionID sessionID, const RegistrableDomain& domain)
668{
669 ASSERT(sessionID.isValid());
670 if (!sessionID.isValid())
671 return;
672
673 if (auto networkSession = networkProcess().networkSession(sessionID)) {
674 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
675 resourceLoadStatistics->logUserInteraction(domain, [] { });
676 }
677}
678
679void NetworkConnectionToWebProcess::logWebSocketLoading(PAL::SessionID sessionID, const RegistrableDomain& targetDomain, const RegistrableDomain& topFrameDomain, WallTime lastSeen)
680{
681 if (auto networkSession = networkProcess().networkSession(sessionID)) {
682 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
683 resourceLoadStatistics->logWebSocketLoading(targetDomain, topFrameDomain, lastSeen, [] { });
684 }
685}
686
687void NetworkConnectionToWebProcess::logSubresourceLoading(PAL::SessionID sessionID, const RegistrableDomain& targetDomain, const RegistrableDomain& topFrameDomain, WallTime lastSeen)
688{
689 if (auto networkSession = networkProcess().networkSession(sessionID)) {
690 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
691 resourceLoadStatistics->logSubresourceLoading(targetDomain, topFrameDomain, lastSeen, [] { });
692 }
693}
694
695void NetworkConnectionToWebProcess::logSubresourceRedirect(PAL::SessionID sessionID, const RegistrableDomain& sourceDomain, const RegistrableDomain& targetDomain)
696{
697 if (auto networkSession = networkProcess().networkSession(sessionID)) {
698 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
699 resourceLoadStatistics->logSubresourceRedirect(sourceDomain, targetDomain, [] { });
700 }
701}
702
703void NetworkConnectionToWebProcess::resourceLoadStatisticsUpdated(Vector<WebCore::ResourceLoadStatistics>&& statistics)
704{
705 for (auto& networkSession : networkProcess().networkSessions().values()) {
706 if (networkSession->sessionID().isEphemeral())
707 continue;
708
709 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
710 resourceLoadStatistics->resourceLoadStatisticsUpdated(WTFMove(statistics));
711 }
712}
713
714void NetworkConnectionToWebProcess::hasStorageAccess(PAL::SessionID sessionID, const RegistrableDomain& subFrameDomain, const RegistrableDomain& topFrameDomain, uint64_t frameID, PageIdentifier pageID, CompletionHandler<void(bool)>&& completionHandler)
715{
716 if (auto networkSession = networkProcess().networkSession(sessionID)) {
717 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics()) {
718 resourceLoadStatistics->hasStorageAccess(subFrameDomain, topFrameDomain, frameID, pageID, WTFMove(completionHandler));
719 return;
720 }
721 }
722
723 completionHandler(true);
724}
725
726void NetworkConnectionToWebProcess::requestStorageAccess(PAL::SessionID sessionID, const RegistrableDomain& subFrameDomain, const RegistrableDomain& topFrameDomain, uint64_t frameID, PageIdentifier pageID, CompletionHandler<void(WebCore::StorageAccessWasGranted wasGranted, WebCore::StorageAccessPromptWasShown promptWasShown)>&& completionHandler)
727{
728 if (auto networkSession = networkProcess().networkSession(sessionID)) {
729 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics()) {
730 resourceLoadStatistics->requestStorageAccess(subFrameDomain, topFrameDomain, frameID, pageID, WTFMove(completionHandler));
731 return;
732 }
733 }
734
735 completionHandler(WebCore::StorageAccessWasGranted::Yes, WebCore::StorageAccessPromptWasShown::No);
736}
737
738void NetworkConnectionToWebProcess::requestStorageAccessUnderOpener(PAL::SessionID sessionID, WebCore::RegistrableDomain&& domainInNeedOfStorageAccess, PageIdentifier openerPageID, WebCore::RegistrableDomain&& openerDomain)
739{
740 if (auto networkSession = networkProcess().networkSession(sessionID)) {
741 if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
742 resourceLoadStatistics->requestStorageAccessUnderOpener(WTFMove(domainInNeedOfStorageAccess), openerPageID, WTFMove(openerDomain));
743 }
744}
745#endif
746
747void NetworkConnectionToWebProcess::addOriginAccessWhitelistEntry(const String& sourceOrigin, const String& destinationProtocol, const String& destinationHost, bool allowDestinationSubdomains)
748{
749 SecurityPolicy::addOriginAccessWhitelistEntry(SecurityOrigin::createFromString(sourceOrigin).get(), destinationProtocol, destinationHost, allowDestinationSubdomains);
750}
751
752void NetworkConnectionToWebProcess::removeOriginAccessWhitelistEntry(const String& sourceOrigin, const String& destinationProtocol, const String& destinationHost, bool allowDestinationSubdomains)
753{
754 SecurityPolicy::removeOriginAccessWhitelistEntry(SecurityOrigin::createFromString(sourceOrigin).get(), destinationProtocol, destinationHost, allowDestinationSubdomains);
755}
756
757void NetworkConnectionToWebProcess::resetOriginAccessWhitelists()
758{
759 SecurityPolicy::resetOriginAccessWhitelists();
760}
761
762Optional<NetworkActivityTracker> NetworkConnectionToWebProcess::startTrackingResourceLoad(PageIdentifier pageID, ResourceLoadIdentifier resourceID, bool isMainResource, const PAL::SessionID& sessionID)
763{
764 if (sessionID.isEphemeral())
765 return WTF::nullopt;
766
767 // Either get the existing root activity tracker for this page or create a
768 // new one if this is the main resource.
769
770 size_t rootActivityIndex;
771 if (isMainResource) {
772 // If we're loading a page from the top, make sure any tracking of
773 // previous activity for this page is stopped.
774
775 stopAllNetworkActivityTrackingForPage(pageID);
776
777 rootActivityIndex = m_networkActivityTrackers.size();
778 m_networkActivityTrackers.constructAndAppend(pageID);
779 m_networkActivityTrackers[rootActivityIndex].networkActivity.start();
780
781#if HAVE(NW_ACTIVITY)
782 ASSERT(m_networkActivityTrackers[rootActivityIndex].networkActivity.getPlatformObject());
783#endif
784 } else {
785 rootActivityIndex = findRootNetworkActivity(pageID);
786
787 // This could happen if the Networking process crashes, taking its
788 // previous state with it.
789 if (rootActivityIndex == notFound)
790 return WTF::nullopt;
791
792#if HAVE(NW_ACTIVITY)
793 ASSERT(m_networkActivityTrackers[rootActivityIndex].networkActivity.getPlatformObject());
794#endif
795 }
796
797 // Create a tracker for the loading of the new resource, setting the root
798 // activity tracker as its parent.
799
800 size_t newActivityIndex = m_networkActivityTrackers.size();
801 m_networkActivityTrackers.constructAndAppend(pageID, resourceID);
802#if HAVE(NW_ACTIVITY)
803 ASSERT(m_networkActivityTrackers[newActivityIndex].networkActivity.getPlatformObject());
804#endif
805
806 auto& newActivityTracker = m_networkActivityTrackers[newActivityIndex];
807 newActivityTracker.networkActivity.setParent(m_networkActivityTrackers[rootActivityIndex].networkActivity);
808 newActivityTracker.networkActivity.start();
809
810 return newActivityTracker.networkActivity;
811}
812
813void NetworkConnectionToWebProcess::stopTrackingResourceLoad(ResourceLoadIdentifier resourceID, NetworkActivityTracker::CompletionCode code)
814{
815 auto itemIndex = findNetworkActivityTracker(resourceID);
816 if (itemIndex == notFound)
817 return;
818
819 m_networkActivityTrackers[itemIndex].networkActivity.complete(code);
820 m_networkActivityTrackers.remove(itemIndex);
821}
822
823void NetworkConnectionToWebProcess::stopAllNetworkActivityTracking()
824{
825 for (auto& activityTracker : m_networkActivityTrackers)
826 activityTracker.networkActivity.complete(NetworkActivityTracker::CompletionCode::None);
827
828 m_networkActivityTrackers.clear();
829}
830
831void NetworkConnectionToWebProcess::stopAllNetworkActivityTrackingForPage(PageIdentifier pageID)
832{
833 for (auto& activityTracker : m_networkActivityTrackers) {
834 if (activityTracker.pageID == pageID)
835 activityTracker.networkActivity.complete(NetworkActivityTracker::CompletionCode::None);
836 }
837
838 m_networkActivityTrackers.removeAllMatching([&](const auto& activityTracker) {
839 return activityTracker.pageID == pageID;
840 });
841}
842
843size_t NetworkConnectionToWebProcess::findRootNetworkActivity(PageIdentifier pageID)
844{
845 return m_networkActivityTrackers.findMatching([&](const auto& item) {
846 return item.isRootActivity && item.pageID == pageID;
847 });
848}
849
850size_t NetworkConnectionToWebProcess::findNetworkActivityTracker(ResourceLoadIdentifier resourceID)
851{
852 return m_networkActivityTrackers.findMatching([&](const auto& item) {
853 return item.resourceID == resourceID;
854 });
855}
856
857#if ENABLE(INDEXED_DATABASE)
858static uint64_t generateIDBConnectionToServerIdentifier()
859{
860 ASSERT(RunLoop::isMain());
861 static uint64_t identifier = 0;
862 return ++identifier;
863}
864
865void NetworkConnectionToWebProcess::establishIDBConnectionToServer(PAL::SessionID sessionID, CompletionHandler<void(uint64_t)>&& completionHandler)
866{
867 uint64_t serverConnectionIdentifier = generateIDBConnectionToServerIdentifier();
868 LOG(IndexedDB, "NetworkConnectionToWebProcess::establishIDBConnectionToServer - %" PRIu64, serverConnectionIdentifier);
869 ASSERT(!m_webIDBConnections.contains(serverConnectionIdentifier));
870
871 m_webIDBConnections.set(serverConnectionIdentifier, WebIDBConnectionToClient::create(m_networkProcess, m_connection.get(), serverConnectionIdentifier, sessionID));
872 completionHandler(serverConnectionIdentifier);
873}
874#endif
875
876#if ENABLE(SERVICE_WORKER)
877void NetworkConnectionToWebProcess::unregisterSWConnections()
878{
879 auto swConnections = WTFMove(m_swConnections);
880 for (auto& swConnection : swConnections.values()) {
881 if (swConnection)
882 swConnection->server().removeConnection(swConnection->identifier());
883 }
884}
885
886void NetworkConnectionToWebProcess::establishSWServerConnection(PAL::SessionID sessionID, CompletionHandler<void(WebCore::SWServerConnectionIdentifier&&)>&& completionHandler)
887{
888 auto& server = m_networkProcess->swServerForSession(sessionID);
889 auto connection = std::make_unique<WebSWServerConnection>(m_networkProcess, server, m_connection.get(), sessionID);
890
891 SWServerConnectionIdentifier serverConnectionIdentifier = connection->identifier();
892 LOG(ServiceWorker, "NetworkConnectionToWebProcess::establishSWServerConnection - %s", serverConnectionIdentifier.loggingString().utf8().data());
893
894 ASSERT(!m_swConnections.contains(serverConnectionIdentifier));
895 m_swConnections.add(serverConnectionIdentifier, makeWeakPtr(*connection));
896 server.addConnection(WTFMove(connection));
897 completionHandler(WTFMove(serverConnectionIdentifier));
898}
899#endif
900
901void NetworkConnectionToWebProcess::webPageWasAdded(PAL::SessionID sessionID, PageIdentifier pageID, WebCore::PageIdentifier oldPageID)
902{
903 m_networkProcess->webPageWasAdded(m_connection.get(), sessionID, pageID, oldPageID);
904}
905
906void NetworkConnectionToWebProcess::webPageWasRemoved(PAL::SessionID sessionID, PageIdentifier pageID)
907{
908 m_networkProcess->webPageWasRemoved(m_connection.get(), sessionID, pageID);
909}
910
911void NetworkConnectionToWebProcess::webProcessSessionChanged(PAL::SessionID newSessionID, const Vector<PageIdentifier>& pages)
912{
913 m_networkProcess->webProcessSessionChanged(m_connection.get(), newSessionID, pages);
914}
915
916} // namespace WebKit
917