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