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