diff options
Diffstat (limited to 'Source/WebKit2/UIProcess/Downloads/DownloadProxy.cpp')
-rw-r--r-- | Source/WebKit2/UIProcess/Downloads/DownloadProxy.cpp | 159 |
1 files changed, 110 insertions, 49 deletions
diff --git a/Source/WebKit2/UIProcess/Downloads/DownloadProxy.cpp b/Source/WebKit2/UIProcess/Downloads/DownloadProxy.cpp index 01f53bbe8..e2641d7c2 100644 --- a/Source/WebKit2/UIProcess/Downloads/DownloadProxy.cpp +++ b/Source/WebKit2/UIProcess/Downloads/DownloadProxy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010-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 @@ -27,19 +27,20 @@ #include "DownloadProxy.h" #include "APIData.h" +#include "APIDownloadClient.h" #include "AuthenticationChallengeProxy.h" #include "DataReference.h" #include "DownloadProxyMap.h" -#include "WebContext.h" +#include "NetworkProcessMessages.h" +#include "NetworkProcessProxy.h" #include "WebProcessMessages.h" +#include "WebProcessPool.h" +#include "WebProtectionSpace.h" +#include <WebCore/FileSystem.h> +#include <WebCore/MIMETypeRegistry.h> #include <wtf/text/CString.h> #include <wtf/text/WTFString.h> -#if ENABLE(NETWORK_PROCESS) -#include "NetworkProcessMessages.h" -#include "NetworkProcessProxy.h" -#endif - using namespace WebCore; namespace WebKit { @@ -50,132 +51,192 @@ static uint64_t generateDownloadID() return ++uniqueDownloadID; } -PassRefPtr<DownloadProxy> DownloadProxy::create(DownloadProxyMap& downloadProxyMap, WebContext& webContext) +PassRefPtr<DownloadProxy> DownloadProxy::create(DownloadProxyMap& downloadProxyMap, WebProcessPool& processPool, const ResourceRequest& resourceRequest) { - return adoptRef(new DownloadProxy(downloadProxyMap, webContext)); + return adoptRef(new DownloadProxy(downloadProxyMap, processPool, resourceRequest)); } -DownloadProxy::DownloadProxy(DownloadProxyMap& downloadProxyMap, WebContext& webContext) +DownloadProxy::DownloadProxy(DownloadProxyMap& downloadProxyMap, WebProcessPool& processPool, const ResourceRequest& resourceRequest) : m_downloadProxyMap(downloadProxyMap) - , m_webContext(&webContext) + , m_processPool(&processPool) , m_downloadID(generateDownloadID()) + , m_request(resourceRequest) { } DownloadProxy::~DownloadProxy() { - ASSERT(!m_webContext); + ASSERT(!m_processPool); } void DownloadProxy::cancel() { - if (!m_webContext) + if (!m_processPool) return; -#if ENABLE(NETWORK_PROCESS) - if (m_webContext->usesNetworkProcess()) { - if (NetworkProcessProxy* networkProcess = m_webContext->networkProcess()) - networkProcess->connection()->send(Messages::NetworkProcess::CancelDownload(m_downloadID), 0); - return; - } -#endif - - m_webContext->sendToAllProcesses(Messages::WebProcess::CancelDownload(m_downloadID)); + if (NetworkProcessProxy* networkProcess = m_processPool->networkProcess()) + networkProcess->connection()->send(Messages::NetworkProcess::CancelDownload(m_downloadID), 0); } void DownloadProxy::invalidate() { - ASSERT(m_webContext); - m_webContext = 0; + ASSERT(m_processPool); + m_processPool = nullptr; } void DownloadProxy::processDidClose() { - if (!m_webContext) + if (!m_processPool) return; - m_webContext->downloadClient().processDidCrash(m_webContext.get(), this); + m_processPool->downloadClient().processDidCrash(m_processPool.get(), this); } -void DownloadProxy::didStart(const ResourceRequest& request) +void DownloadProxy::didStart(const ResourceRequest& request, const String& suggestedFilename) { m_request = request; + m_suggestedFilename = suggestedFilename; - if (!m_webContext) + if (!m_processPool) return; - m_webContext->downloadClient().didStart(m_webContext.get(), this); + m_processPool->downloadClient().didStart(m_processPool.get(), this); } void DownloadProxy::didReceiveAuthenticationChallenge(const AuthenticationChallenge& authenticationChallenge, uint64_t challengeID) { - if (!m_webContext) + if (!m_processPool) return; - RefPtr<AuthenticationChallengeProxy> authenticationChallengeProxy = AuthenticationChallengeProxy::create(authenticationChallenge, challengeID, m_webContext->networkingProcessConnection()); + RefPtr<AuthenticationChallengeProxy> authenticationChallengeProxy = AuthenticationChallengeProxy::create(authenticationChallenge, challengeID, m_processPool->networkingProcessConnection()); + + m_processPool->downloadClient().didReceiveAuthenticationChallenge(m_processPool.get(), this, authenticationChallengeProxy.get()); +} + +#if USE(NETWORK_SESSION) +#if USE(PROTECTION_SPACE_AUTH_CALLBACK) +void DownloadProxy::canAuthenticateAgainstProtectionSpace(const ProtectionSpace& protectionSpace) +{ + if (!m_processPool) + return; + + auto* networkProcessProxy = m_processPool->networkProcess(); + if (!networkProcessProxy) + return; - m_webContext->downloadClient().didReceiveAuthenticationChallenge(m_webContext.get(), this, authenticationChallengeProxy.get()); + bool result = m_processPool->downloadClient().canAuthenticateAgainstProtectionSpace(getPtr(WebProtectionSpace::create(protectionSpace))); + + networkProcessProxy->connection()->send(Messages::NetworkProcess::ContinueCanAuthenticateAgainstProtectionSpaceDownload(m_downloadID, result), 0); } +#endif + +void DownloadProxy::willSendRequest(const ResourceRequest& proposedRequest, const ResourceResponse& redirectResponse) +{ + if (!m_processPool) + return; + + RefPtr<DownloadProxy> protectedThis(this); + m_processPool->downloadClient().willSendRequest(proposedRequest, redirectResponse, [protectedThis](const ResourceRequest& newRequest) { + if (!protectedThis->m_processPool) + return; + + auto* networkProcessProxy = protectedThis->m_processPool->networkProcess(); + if (!networkProcessProxy) + return; + + networkProcessProxy->connection()->send(Messages::NetworkProcess::ContinueWillSendRequest(protectedThis->m_downloadID, newRequest), 0); + }); +} +#endif void DownloadProxy::didReceiveResponse(const ResourceResponse& response) { - if (!m_webContext) + if (!m_processPool) return; - m_webContext->downloadClient().didReceiveResponse(m_webContext.get(), this, response); +#if !USE(NETWORK_SESSION) + // As per https://html.spec.whatwg.org/#as-a-download (step 2), the filename from the Content-Disposition header + // should override the suggested filename from the download attribute. + if (!m_suggestedFilename.isNull() && response.isAttachmentWithFilename()) + m_suggestedFilename = String(); +#endif + + m_processPool->downloadClient().didReceiveResponse(m_processPool.get(), this, response); } void DownloadProxy::didReceiveData(uint64_t length) { - if (!m_webContext) + if (!m_processPool) return; - m_webContext->downloadClient().didReceiveData(m_webContext.get(), this, length); + m_processPool->downloadClient().didReceiveData(m_processPool.get(), this, length); } void DownloadProxy::shouldDecodeSourceDataOfMIMEType(const String& mimeType, bool& result) { result = false; - if (!m_webContext) + if (!m_processPool) return; - result = m_webContext->downloadClient().shouldDecodeSourceDataOfMIMEType(m_webContext.get(), this, mimeType); + result = m_processPool->downloadClient().shouldDecodeSourceDataOfMIMEType(m_processPool.get(), this, mimeType); } -void DownloadProxy::decideDestinationWithSuggestedFilename(const String& filename, String& destination, bool& allowOverwrite, SandboxExtension::Handle& sandboxExtensionHandle) +void DownloadProxy::decideDestinationWithSuggestedFilenameAsync(DownloadID downloadID, const String& suggestedFilename) +{ + bool allowOverwrite = false; + + if (!m_processPool) + return; + + String destination = m_processPool->downloadClient().decideDestinationWithSuggestedFilename(m_processPool.get(), this, suggestedFilename, allowOverwrite); + + SandboxExtension::Handle sandboxExtensionHandle; + if (!destination.isNull()) + SandboxExtension::createHandle(destination, SandboxExtension::ReadWrite, sandboxExtensionHandle); + + if (NetworkProcessProxy* networkProcess = m_processPool->networkProcess()) + networkProcess->connection()->send(Messages::NetworkProcess::ContinueDecidePendingDownloadDestination(downloadID, destination, sandboxExtensionHandle, allowOverwrite), 0); +} + +#if !USE(NETWORK_SESSION) + +void DownloadProxy::decideDestinationWithSuggestedFilename(const String& filename, const String& mimeType, String& destination, bool& allowOverwrite, SandboxExtension::Handle& sandboxExtensionHandle) { allowOverwrite = false; - if (!m_webContext) + if (!m_processPool) return; - destination = m_webContext->downloadClient().decideDestinationWithSuggestedFilename(m_webContext.get(), this, filename, allowOverwrite); + String suggestedFilename = MIMETypeRegistry::appendFileExtensionIfNecessary(m_suggestedFilename.isNull() ? filename : m_suggestedFilename, mimeType); + destination = m_processPool->downloadClient().decideDestinationWithSuggestedFilename(m_processPool.get(), this, suggestedFilename, allowOverwrite); if (!destination.isNull()) SandboxExtension::createHandle(destination, SandboxExtension::ReadWrite, sandboxExtensionHandle); } +#endif + void DownloadProxy::didCreateDestination(const String& path) { - if (!m_webContext) + if (!m_processPool) return; - m_webContext->downloadClient().didCreateDestination(m_webContext.get(), this, path); + m_processPool->downloadClient().didCreateDestination(m_processPool.get(), this, path); } void DownloadProxy::didFinish() { - if (!m_webContext) + if (!m_processPool) return; - m_webContext->downloadClient().didFinish(m_webContext.get(), this); + m_processPool->downloadClient().didFinish(m_processPool.get(), this); // This can cause the DownloadProxy object to be deleted. m_downloadProxyMap.downloadFinished(this); } -static PassRefPtr<API::Data> createData(const IPC::DataReference& data) +static RefPtr<API::Data> createData(const IPC::DataReference& data) { if (data.isEmpty()) return 0; @@ -185,12 +246,12 @@ static PassRefPtr<API::Data> createData(const IPC::DataReference& data) void DownloadProxy::didFail(const ResourceError& error, const IPC::DataReference& resumeData) { - if (!m_webContext) + if (!m_processPool) return; m_resumeData = createData(resumeData); - m_webContext->downloadClient().didFail(m_webContext.get(), this, error); + m_processPool->downloadClient().didFail(m_processPool.get(), this, error); // This can cause the DownloadProxy object to be deleted. m_downloadProxyMap.downloadFinished(this); @@ -200,7 +261,7 @@ void DownloadProxy::didCancel(const IPC::DataReference& resumeData) { m_resumeData = createData(resumeData); - m_webContext->downloadClient().didCancel(m_webContext.get(), this); + m_processPool->downloadClient().didCancel(m_processPool.get(), this); // This can cause the DownloadProxy object to be deleted. m_downloadProxyMap.downloadFinished(this); |