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