diff options
Diffstat (limited to 'Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.cpp')
-rw-r--r-- | Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.cpp | 276 |
1 files changed, 206 insertions, 70 deletions
diff --git a/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.cpp b/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.cpp index 1fee498a9..1416242f1 100644 --- a/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.cpp +++ b/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Apple Inc. All rights reserved. + * Copyright (C) 2012-2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,46 +26,65 @@ #include "config.h" #include "NetworkConnectionToWebProcess.h" -#if ENABLE(NETWORK_PROCESS) - -#include "BlobRegistrationData.h" -#include "ConnectionStack.h" +#include "BlobDataFileReferenceWithSandboxExtension.h" +#include "DataReference.h" #include "NetworkBlobRegistry.h" +#include "NetworkCache.h" #include "NetworkConnectionToWebProcessMessages.h" +#include "NetworkLoad.h" #include "NetworkProcess.h" +#include "NetworkProcessConnectionMessages.h" +#include "NetworkRTCMonitorMessages.h" +#include "NetworkRTCProviderMessages.h" +#include "NetworkRTCSocketMessages.h" #include "NetworkResourceLoadParameters.h" #include "NetworkResourceLoader.h" #include "NetworkResourceLoaderMessages.h" #include "RemoteNetworkingContext.h" #include "SessionTracker.h" -#include <WebCore/BlobData.h> +#include "WebCoreArgumentCoders.h" +#include <WebCore/NetworkStorageSession.h> +#include <WebCore/PingHandle.h> #include <WebCore/PlatformCookieJar.h> #include <WebCore/ResourceLoaderOptions.h> #include <WebCore/ResourceRequest.h> -#include <wtf/RunLoop.h> +#include <WebCore/SessionID.h> + +#if USE(NETWORK_SESSION) +#include "PingLoad.h" +#endif using namespace WebCore; namespace WebKit { -PassRefPtr<NetworkConnectionToWebProcess> NetworkConnectionToWebProcess::create(IPC::Connection::Identifier connectionIdentifier) +Ref<NetworkConnectionToWebProcess> NetworkConnectionToWebProcess::create(IPC::Connection::Identifier connectionIdentifier) { - return adoptRef(new NetworkConnectionToWebProcess(connectionIdentifier)); + return adoptRef(*new NetworkConnectionToWebProcess(connectionIdentifier)); } NetworkConnectionToWebProcess::NetworkConnectionToWebProcess(IPC::Connection::Identifier connectionIdentifier) - : m_serialLoadingEnabled(false) + : m_connection(IPC::Connection::createServerConnection(connectionIdentifier, *this)) { - m_connection = IPC::Connection::createServerConnection(connectionIdentifier, this, RunLoop::main()); - m_connection->setOnlySendMessagesAsDispatchWhenWaitingForSyncReplyWhenProcessingSuchAMessage(true); m_connection->open(); } NetworkConnectionToWebProcess::~NetworkConnectionToWebProcess() { +#if USE(LIBWEBRTC) + if (m_rtcProvider) + m_rtcProvider->close(); +#endif +} + +void NetworkConnectionToWebProcess::didCleanupResourceLoader(NetworkResourceLoader& loader) +{ + ASSERT(m_networkResourceLoaders.get(loader.identifier()) == &loader); + + m_networkResourceLoaders.remove(loader.identifier()); } - -void NetworkConnectionToWebProcess::didReceiveMessage(IPC::Connection* connection, IPC::MessageDecoder& decoder) + +void NetworkConnectionToWebProcess::didReceiveMessage(IPC::Connection& connection, IPC::Decoder& decoder) { if (decoder.messageReceiverName() == Messages::NetworkConnectionToWebProcess::messageReceiverName()) { didReceiveNetworkConnectionToWebProcessMessage(connection, decoder); @@ -73,16 +92,40 @@ void NetworkConnectionToWebProcess::didReceiveMessage(IPC::Connection* connectio } if (decoder.messageReceiverName() == Messages::NetworkResourceLoader::messageReceiverName()) { - HashMap<ResourceLoadIdentifier, RefPtr<NetworkResourceLoader>>::iterator loaderIterator = m_networkResourceLoaders.find(decoder.destinationID()); + auto loaderIterator = m_networkResourceLoaders.find(decoder.destinationID()); if (loaderIterator != m_networkResourceLoaders.end()) loaderIterator->value->didReceiveNetworkResourceLoaderMessage(connection, decoder); return; } - + +#if USE(LIBWEBRTC) + if (decoder.messageReceiverName() == Messages::NetworkRTCSocket::messageReceiverName()) { + rtcProvider().didReceiveNetworkRTCSocketMessage(connection, decoder); + return; + } + if (decoder.messageReceiverName() == Messages::NetworkRTCMonitor::messageReceiverName()) { + rtcProvider().didReceiveNetworkRTCMonitorMessage(connection, decoder); + return; + } + if (decoder.messageReceiverName() == Messages::NetworkRTCProvider::messageReceiverName()) { + rtcProvider().didReceiveMessage(connection, decoder); + return; + } +#endif + ASSERT_NOT_REACHED(); } -void NetworkConnectionToWebProcess::didReceiveSyncMessage(IPC::Connection* connection, IPC::MessageDecoder& decoder, std::unique_ptr<IPC::MessageEncoder>& reply) +#if USE(LIBWEBRTC) +NetworkRTCProvider& NetworkConnectionToWebProcess::rtcProvider() +{ + if (!m_rtcProvider) + m_rtcProvider = NetworkRTCProvider::create(*this); + return *m_rtcProvider; +} +#endif + +void NetworkConnectionToWebProcess::didReceiveSyncMessage(IPC::Connection& connection, IPC::Decoder& decoder, std::unique_ptr<IPC::Encoder>& reply) { if (decoder.messageReceiverName() == Messages::NetworkConnectionToWebProcess::messageReceiverName()) { didReceiveSyncNetworkConnectionToWebProcessMessage(connection, decoder, reply); @@ -91,43 +134,62 @@ void NetworkConnectionToWebProcess::didReceiveSyncMessage(IPC::Connection* conne ASSERT_NOT_REACHED(); } -void NetworkConnectionToWebProcess::didClose(IPC::Connection*) +void NetworkConnectionToWebProcess::didClose(IPC::Connection&) { // Protect ourself as we might be otherwise be deleted during this function. Ref<NetworkConnectionToWebProcess> protector(*this); - HashMap<ResourceLoadIdentifier, RefPtr<NetworkResourceLoader>>::iterator end = m_networkResourceLoaders.end(); - for (HashMap<ResourceLoadIdentifier, RefPtr<NetworkResourceLoader>>::iterator i = m_networkResourceLoaders.begin(); i != end; ++i) - i->value->abort(); + Vector<RefPtr<NetworkResourceLoader>> loaders; + copyValuesToVector(m_networkResourceLoaders, loaders); + for (auto& loader : loaders) + loader->abort(); + ASSERT(m_networkResourceLoaders.isEmpty()); - NetworkBlobRegistry::shared().connectionToWebProcessDidClose(this); + NetworkBlobRegistry::singleton().connectionToWebProcessDidClose(this); + NetworkProcess::singleton().removeNetworkConnectionToWebProcess(this); - m_networkResourceLoaders.clear(); - - NetworkProcess::shared().removeNetworkConnectionToWebProcess(this); +#if USE(LIBWEBRTC) + if (m_rtcProvider) { + m_rtcProvider->close(); + m_rtcProvider = nullptr; + } +#endif } -void NetworkConnectionToWebProcess::didReceiveInvalidMessage(IPC::Connection*, IPC::StringReference, IPC::StringReference) +void NetworkConnectionToWebProcess::didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference, IPC::StringReference) { } void NetworkConnectionToWebProcess::scheduleResourceLoad(const NetworkResourceLoadParameters& loadParameters) { - RefPtr<NetworkResourceLoader> loader = NetworkResourceLoader::create(loadParameters, this); - m_networkResourceLoaders.add(loadParameters.identifier, loader); - NetworkProcess::shared().networkResourceLoadScheduler().scheduleLoader(loader.get()); + auto loader = NetworkResourceLoader::create(loadParameters, *this); + m_networkResourceLoaders.add(loadParameters.identifier, loader.ptr()); + loader->start(); +} + +void NetworkConnectionToWebProcess::performSynchronousLoad(const NetworkResourceLoadParameters& loadParameters, Ref<Messages::NetworkConnectionToWebProcess::PerformSynchronousLoad::DelayedReply>&& reply) +{ + auto loader = NetworkResourceLoader::create(loadParameters, *this, WTFMove(reply)); + m_networkResourceLoaders.add(loadParameters.identifier, loader.ptr()); + loader->start(); } -void NetworkConnectionToWebProcess::performSynchronousLoad(const NetworkResourceLoadParameters& loadParameters, PassRefPtr<Messages::NetworkConnectionToWebProcess::PerformSynchronousLoad::DelayedReply> reply) +void NetworkConnectionToWebProcess::loadPing(const NetworkResourceLoadParameters& loadParameters) { - RefPtr<NetworkResourceLoader> loader = NetworkResourceLoader::create(loadParameters, this, reply); - m_networkResourceLoaders.add(loadParameters.identifier, loader); - NetworkProcess::shared().networkResourceLoadScheduler().scheduleLoader(loader.get()); +#if USE(NETWORK_SESSION) + // PingLoad manages its own lifetime, deleting itself when its purpose has been fulfilled. + new PingLoad(loadParameters); +#else + RefPtr<NetworkingContext> context = RemoteNetworkingContext::create(loadParameters.sessionID, loadParameters.shouldClearReferrerOnHTTPSToHTTPRedirect); + + // PingHandle manages its own lifetime, deleting itself when its purpose has been fulfilled. + new PingHandle(context.get(), loadParameters.request, loadParameters.allowStoredCredentials == AllowStoredCredentials, PingHandle::UsesAsyncCallbacks::Yes, loadParameters.shouldFollowRedirects); +#endif } void NetworkConnectionToWebProcess::removeLoadIdentifier(ResourceLoadIdentifier identifier) { - RefPtr<NetworkResourceLoader> loader = m_networkResourceLoaders.take(identifier); + RefPtr<NetworkResourceLoader> loader = m_networkResourceLoaders.get(identifier); // It's possible we have no loader for this identifier if the NetworkProcess crashed and this was a respawned NetworkProcess. if (!loader) @@ -136,24 +198,28 @@ void NetworkConnectionToWebProcess::removeLoadIdentifier(ResourceLoadIdentifier // Abort the load now, as the WebProcess won't be able to respond to messages any more which might lead // to leaked loader resources (connections, threads, etc). loader->abort(); + ASSERT(!m_networkResourceLoaders.contains(identifier)); } -void NetworkConnectionToWebProcess::servePendingRequests(uint32_t resourceLoadPriority) +void NetworkConnectionToWebProcess::setDefersLoading(ResourceLoadIdentifier identifier, bool defers) { - NetworkProcess::shared().networkResourceLoadScheduler().servePendingRequests(static_cast<ResourceLoadPriority>(resourceLoadPriority)); + RefPtr<NetworkResourceLoader> loader = m_networkResourceLoaders.get(identifier); + if (!loader) + return; + + loader->setDefersLoading(defers); } -void NetworkConnectionToWebProcess::setSerialLoadingEnabled(bool enabled) +void NetworkConnectionToWebProcess::prefetchDNS(const String& hostname) { - m_serialLoadingEnabled = enabled; + NetworkProcess::singleton().prefetchDNS(hostname); } -static NetworkStorageSession& storageSession(uint64_t sessionID) +static NetworkStorageSession& storageSession(SessionID sessionID) { - if (SessionTracker::isEphemeralID(sessionID)) { - NetworkStorageSession* privateSession = SessionTracker::session(sessionID); - if (privateSession) - return *privateSession; + if (sessionID.isEphemeral()) { + if (auto* privateStorageSession = NetworkStorageSession::storageSession(sessionID)) + return *privateStorageSession; // Some requests with private browsing mode requested may still be coming shortly after NetworkProcess was told to destroy its session. // FIXME: Find a way to track private browsing sessions more rigorously. LOG_ERROR("Private browsing 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."); @@ -161,79 +227,149 @@ static NetworkStorageSession& storageSession(uint64_t sessionID) return NetworkStorageSession::defaultStorageSession(); } -void NetworkConnectionToWebProcess::startDownload(uint64_t sessionID, uint64_t downloadID, const ResourceRequest& request) +void NetworkConnectionToWebProcess::startDownload(SessionID sessionID, DownloadID downloadID, const ResourceRequest& request, const String& suggestedName) { - // FIXME: Do something with the session ID. - NetworkProcess::shared().downloadManager().startDownload(downloadID, request); + NetworkProcess::singleton().downloadManager().startDownload(this, sessionID, downloadID, request, suggestedName); } -void NetworkConnectionToWebProcess::convertMainResourceLoadToDownload(uint64_t mainResourceLoadIdentifier, uint64_t downloadID, const ResourceRequest& request, const ResourceResponse& response) +void NetworkConnectionToWebProcess::convertMainResourceLoadToDownload(SessionID sessionID, uint64_t mainResourceLoadIdentifier, DownloadID downloadID, const ResourceRequest& request, const ResourceResponse& response) { + auto& networkProcess = NetworkProcess::singleton(); if (!mainResourceLoadIdentifier) { - NetworkProcess::shared().downloadManager().startDownload(downloadID, request); + networkProcess.downloadManager().startDownload(this, sessionID, downloadID, request); return; } NetworkResourceLoader* loader = m_networkResourceLoaders.get(mainResourceLoadIdentifier); - NetworkProcess::shared().downloadManager().convertHandleToDownload(downloadID, loader->handle(), request, response); + if (!loader) { + // If we're trying to download a blob here loader can be null. + return; + } - // Unblock the URL connection operation queue. - loader->handle()->continueDidReceiveResponse(); - - loader->didConvertHandleToDownload(); + loader->convertToDownload(downloadID, request, response); } -void NetworkConnectionToWebProcess::cookiesForDOM(uint64_t sessionID, const URL& firstParty, const URL& url, String& result) +void NetworkConnectionToWebProcess::cookiesForDOM(SessionID sessionID, const URL& firstParty, const URL& url, String& result) { result = WebCore::cookiesForDOM(storageSession(sessionID), firstParty, url); } -void NetworkConnectionToWebProcess::setCookiesFromDOM(uint64_t sessionID, const URL& firstParty, const URL& url, const String& cookieString) +void NetworkConnectionToWebProcess::setCookiesFromDOM(SessionID sessionID, const URL& firstParty, const URL& url, const String& cookieString) { WebCore::setCookiesFromDOM(storageSession(sessionID), firstParty, url, cookieString); } -void NetworkConnectionToWebProcess::cookiesEnabled(uint64_t sessionID, const URL& firstParty, const URL& url, bool& result) +void NetworkConnectionToWebProcess::cookiesEnabled(SessionID sessionID, const URL& firstParty, const URL& url, bool& result) { result = WebCore::cookiesEnabled(storageSession(sessionID), firstParty, url); } -void NetworkConnectionToWebProcess::cookieRequestHeaderFieldValue(uint64_t sessionID, const URL& firstParty, const URL& url, String& result) +void NetworkConnectionToWebProcess::cookieRequestHeaderFieldValue(SessionID sessionID, const URL& firstParty, const URL& url, String& result) { result = WebCore::cookieRequestHeaderFieldValue(storageSession(sessionID), firstParty, url); } -void NetworkConnectionToWebProcess::getRawCookies(uint64_t sessionID, const URL& firstParty, const URL& url, Vector<Cookie>& result) +void NetworkConnectionToWebProcess::getRawCookies(SessionID sessionID, const URL& firstParty, const URL& url, Vector<Cookie>& result) { WebCore::getRawCookies(storageSession(sessionID), firstParty, url, result); } -void NetworkConnectionToWebProcess::deleteCookie(uint64_t sessionID, const URL& url, const String& cookieName) +void NetworkConnectionToWebProcess::deleteCookie(SessionID sessionID, const URL& url, const String& cookieName) { WebCore::deleteCookie(storageSession(sessionID), url, cookieName); } -void NetworkConnectionToWebProcess::registerBlobURL(const URL& url, const BlobRegistrationData& data) +void NetworkConnectionToWebProcess::addCookie(SessionID sessionID, const URL& url, const Cookie& cookie) { - Vector<RefPtr<SandboxExtension>> extensions; - for (size_t i = 0, count = data.sandboxExtensions().size(); i < count; ++i) { - if (RefPtr<SandboxExtension> extension = SandboxExtension::create(data.sandboxExtensions()[i])) - extensions.append(extension); - } + WebCore::addCookie(storageSession(sessionID), url, cookie); +} + +void NetworkConnectionToWebProcess::registerFileBlobURL(const URL& url, const String& path, const SandboxExtension::Handle& extensionHandle, const String& contentType) +{ + RefPtr<SandboxExtension> extension = SandboxExtension::create(extensionHandle); - NetworkBlobRegistry::shared().registerBlobURL(this, url, data.releaseData(), extensions); + NetworkBlobRegistry::singleton().registerFileBlobURL(this, url, path, WTFMove(extension), contentType); +} + +void NetworkConnectionToWebProcess::registerBlobURL(const URL& url, Vector<BlobPart>&& blobParts, const String& contentType) +{ + NetworkBlobRegistry::singleton().registerBlobURL(this, url, WTFMove(blobParts), contentType); } void NetworkConnectionToWebProcess::registerBlobURLFromURL(const URL& url, const URL& srcURL) { - NetworkBlobRegistry::shared().registerBlobURL(this, url, srcURL); + NetworkBlobRegistry::singleton().registerBlobURL(this, url, srcURL); +} + +void NetworkConnectionToWebProcess::preregisterSandboxExtensionsForOptionallyFileBackedBlob(const Vector<String>& filePaths, const SandboxExtension::HandleArray& handles) +{ +#if ENABLE(SANDBOX_EXTENSIONS) + ASSERT(filePaths.size() == handles.size()); + + for (size_t i = 0; i < filePaths.size(); ++i) + m_blobDataFileReferences.add(filePaths[i], BlobDataFileReferenceWithSandboxExtension::create(filePaths[i], SandboxExtension::create(handles[i]))); +#else + for (size_t i = 0; i < filePaths.size(); ++i) + m_blobDataFileReferences.add(filePaths[i], BlobDataFileReferenceWithSandboxExtension::create(filePaths[i], nullptr)); +#endif +} + +RefPtr<WebCore::BlobDataFileReference> NetworkConnectionToWebProcess::getBlobDataFileReferenceForPath(const String& path) +{ + ASSERT(m_blobDataFileReferences.contains(path)); + return m_blobDataFileReferences.get(path); +} + +void NetworkConnectionToWebProcess::registerBlobURLOptionallyFileBacked(const URL& url, const URL& srcURL, const String& fileBackedPath, const String& contentType) +{ + NetworkBlobRegistry::singleton().registerBlobURLOptionallyFileBacked(this, url, srcURL, fileBackedPath, contentType); +} + +void NetworkConnectionToWebProcess::registerBlobURLForSlice(const URL& url, const URL& srcURL, int64_t start, int64_t end) +{ + NetworkBlobRegistry::singleton().registerBlobURLForSlice(this, url, srcURL, start, end); } void NetworkConnectionToWebProcess::unregisterBlobURL(const URL& url) { - NetworkBlobRegistry::shared().unregisterBlobURL(this, url); + NetworkBlobRegistry::singleton().unregisterBlobURL(this, url); } -} // namespace WebKit +void NetworkConnectionToWebProcess::blobSize(const URL& url, uint64_t& resultSize) +{ + resultSize = NetworkBlobRegistry::singleton().blobSize(this, url); +} + +void NetworkConnectionToWebProcess::writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, uint64_t requestIdentifier) +{ + Vector<RefPtr<BlobDataFileReference>> fileReferences; + for (auto& url : blobURLs) + fileReferences.appendVector(NetworkBlobRegistry::singleton().filesInBlob(*this, { ParsedURLString, url })); + + for (auto& file : fileReferences) + file->prepareForFileAccess(); + + NetworkBlobRegistry::singleton().writeBlobsToTemporaryFiles(blobURLs, [this, protectedThis = makeRef(*this), requestIdentifier, fileReferences = WTFMove(fileReferences)](auto& fileNames) mutable { + for (auto& file : fileReferences) + file->revokeFileAccess(); + + NetworkProcess::singleton().grantSandboxExtensionsToDatabaseProcessForBlobs(fileNames, [this, protectedThis = WTFMove(protectedThis), requestIdentifier, fileNames]() { + if (!m_connection->isValid()) + return; + + m_connection->send(Messages::NetworkProcessConnection::DidWriteBlobsToTemporaryFiles(requestIdentifier, fileNames), 0); + }); + }); +} -#endif // ENABLE(NETWORK_PROCESS) +void NetworkConnectionToWebProcess::storeDerivedDataToCache(const WebKit::NetworkCache::DataKey& dataKey, const IPC::DataReference& data) +{ + NetworkCache::singleton().storeData(dataKey, data.data(), data.size()); +} + +void NetworkConnectionToWebProcess::ensureLegacyPrivateBrowsingSession() +{ + NetworkProcess::singleton().ensurePrivateBrowsingSession(SessionID::legacyPrivateSessionID()); +} + +} // namespace WebKit |