diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebKit2/UIProcess/Downloads | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebKit2/UIProcess/Downloads')
5 files changed, 167 insertions, 81 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); diff --git a/Source/WebKit2/UIProcess/Downloads/DownloadProxy.h b/Source/WebKit2/UIProcess/Downloads/DownloadProxy.h index 6f8536146..1cada8e2a 100644 --- a/Source/WebKit2/UIProcess/Downloads/DownloadProxy.h +++ b/Source/WebKit2/UIProcess/Downloads/DownloadProxy.h @@ -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 @@ -28,6 +28,7 @@ #include "APIObject.h" #include "Connection.h" +#include "DownloadID.h" #include "SandboxExtension.h" #include <WebCore/ResourceRequest.h> #include <wtf/Forward.h> @@ -38,23 +39,25 @@ class Data; } namespace WebCore { - class AuthenticationChallenge; - class ResourceError; - class ResourceResponse; +class AuthenticationChallenge; +class ProtectionSpace; +class ResourceError; +class ResourceResponse; } namespace WebKit { +class DownloadID; class DownloadProxyMap; -class WebContext; class WebPageProxy; +class WebProcessPool; class DownloadProxy : public API::ObjectImpl<API::Object::Type::Download>, public IPC::MessageReceiver { public: - static PassRefPtr<DownloadProxy> create(DownloadProxyMap&, WebContext&); + static PassRefPtr<DownloadProxy> create(DownloadProxyMap&, WebProcessPool&, const WebCore::ResourceRequest&); ~DownloadProxy(); - uint64_t downloadID() const { return m_downloadID; } + DownloadID downloadID() const { return m_downloadID; } const WebCore::ResourceRequest& request() const { return m_request; } API::Data* resumeData() const { return m_resumeData.get(); } @@ -63,34 +66,43 @@ public: void invalidate(); void processDidClose(); - void didReceiveDownloadProxyMessage(IPC::Connection*, IPC::MessageDecoder&); - void didReceiveSyncDownloadProxyMessage(IPC::Connection*, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&); + void didReceiveDownloadProxyMessage(IPC::Connection&, IPC::Decoder&); + void didReceiveSyncDownloadProxyMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&); private: - explicit DownloadProxy(DownloadProxyMap&, WebContext&); + explicit DownloadProxy(DownloadProxyMap&, WebProcessPool&, const WebCore::ResourceRequest&); // IPC::MessageReceiver - virtual void didReceiveMessage(IPC::Connection*, IPC::MessageDecoder&) override; - virtual void didReceiveSyncMessage(IPC::Connection*, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&) override; + void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override; + void didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&) override; // Message handlers. - void didStart(const WebCore::ResourceRequest&); + void didStart(const WebCore::ResourceRequest&, const String& suggestedFilename); void didReceiveAuthenticationChallenge(const WebCore::AuthenticationChallenge&, uint64_t challengeID); void didReceiveResponse(const WebCore::ResourceResponse&); void didReceiveData(uint64_t length); void shouldDecodeSourceDataOfMIMEType(const String& mimeType, bool& result); - void decideDestinationWithSuggestedFilename(const String& filename, String& destination, bool& allowOverwrite, SandboxExtension::Handle& sandboxExtensionHandle); void didCreateDestination(const String& path); void didFinish(); void didFail(const WebCore::ResourceError&, const IPC::DataReference& resumeData); void didCancel(const IPC::DataReference& resumeData); +#if USE(NETWORK_SESSION) +#if USE(PROTECTION_SPACE_AUTH_CALLBACK) + void canAuthenticateAgainstProtectionSpace(const WebCore::ProtectionSpace&); +#endif + void willSendRequest(const WebCore::ResourceRequest& redirectRequest, const WebCore::ResourceResponse& redirectResponse); +#else + void decideDestinationWithSuggestedFilename(const String& filename, const String& mimeType, String& destination, bool& allowOverwrite, SandboxExtension::Handle& sandboxExtensionHandle); +#endif + void decideDestinationWithSuggestedFilenameAsync(DownloadID, const String& suggestedFilename); DownloadProxyMap& m_downloadProxyMap; - RefPtr<WebContext> m_webContext; - uint64_t m_downloadID; + RefPtr<WebProcessPool> m_processPool; + DownloadID m_downloadID; RefPtr<API::Data> m_resumeData; WebCore::ResourceRequest m_request; + String m_suggestedFilename; }; } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/Downloads/DownloadProxy.messages.in b/Source/WebKit2/UIProcess/Downloads/DownloadProxy.messages.in index 37ef52fd7..c22d099ba 100644 --- a/Source/WebKit2/UIProcess/Downloads/DownloadProxy.messages.in +++ b/Source/WebKit2/UIProcess/Downloads/DownloadProxy.messages.in @@ -21,13 +21,22 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. messages -> DownloadProxy { - DidStart(WebCore::ResourceRequest request) + DidStart(WebCore::ResourceRequest request, AtomicString suggestedFilename) DidReceiveAuthenticationChallenge(WebCore::AuthenticationChallenge challenge, uint64_t challengeID) +#if USE(NETWORK_SESSION) + WillSendRequest(WebCore::ResourceRequest redirectRequest, WebCore::ResourceResponse redirectResponse)) +#if USE(PROTECTION_SPACE_AUTH_CALLBACK) + CanAuthenticateAgainstProtectionSpace(WebCore::ProtectionSpace protectionSpace) +#endif +#endif + DecideDestinationWithSuggestedFilenameAsync(WebKit::DownloadID downloadID, String suggestedFilename) DidReceiveResponse(WebCore::ResourceResponse response) DidReceiveData(uint64_t length) ShouldDecodeSourceDataOfMIMEType(String mimeType) -> (bool result) - DecideDestinationWithSuggestedFilename(String filename) -> (String destination, bool allowOverwrite, WebKit::SandboxExtension::Handle sandboxExtensionHandle) +#if !USE(NETWORK_SESSION) + DecideDestinationWithSuggestedFilename(String filename, String mimeType) -> (String destination, bool allowOverwrite, WebKit::SandboxExtension::Handle sandboxExtensionHandle) +#endif DidCreateDestination(String path) DidFinish() DidFail(WebCore::ResourceError error, IPC::DataReference resumeData) diff --git a/Source/WebKit2/UIProcess/Downloads/DownloadProxyMap.cpp b/Source/WebKit2/UIProcess/Downloads/DownloadProxyMap.cpp index e6246b2a3..7509ddedb 100644 --- a/Source/WebKit2/UIProcess/Downloads/DownloadProxyMap.cpp +++ b/Source/WebKit2/UIProcess/Downloads/DownloadProxyMap.cpp @@ -44,38 +44,38 @@ DownloadProxyMap::~DownloadProxyMap() ASSERT(m_downloads.isEmpty()); } -DownloadProxy* DownloadProxyMap::createDownloadProxy(WebContext& webContext) +DownloadProxy* DownloadProxyMap::createDownloadProxy(WebProcessPool& processPool, const WebCore::ResourceRequest& resourceRequest) { - RefPtr<DownloadProxy> downloadProxy = DownloadProxy::create(*this, webContext); + RefPtr<DownloadProxy> downloadProxy = DownloadProxy::create(*this, processPool, resourceRequest); m_downloads.set(downloadProxy->downloadID(), downloadProxy); - m_process->addMessageReceiver(Messages::DownloadProxy::messageReceiverName(), downloadProxy->downloadID(), *downloadProxy); + m_process->addMessageReceiver(Messages::DownloadProxy::messageReceiverName(), downloadProxy->downloadID().downloadID(), *downloadProxy); return downloadProxy.get(); } void DownloadProxyMap::downloadFinished(DownloadProxy* downloadProxy) { - uint64_t downloadID = downloadProxy->downloadID(); + auto downloadID = downloadProxy->downloadID(); ASSERT(m_downloads.contains(downloadID)); + m_process->removeMessageReceiver(Messages::DownloadProxy::messageReceiverName(), downloadID.downloadID()); downloadProxy->invalidate(); m_downloads.remove(downloadID); - - m_process->removeMessageReceiver(Messages::DownloadProxy::messageReceiverName(), downloadID); } void DownloadProxyMap::processDidClose() { // Invalidate all outstanding downloads. - for (HashMap<uint64_t, RefPtr<DownloadProxy>>::iterator::Values it = m_downloads.begin().values(), end = m_downloads.end().values(); it != end; ++it) { - (*it)->processDidClose(); - (*it)->invalidate(); + for (const auto& download : m_downloads.values()) { + download->processDidClose(); + download->invalidate(); + m_process->removeMessageReceiver(Messages::DownloadProxy::messageReceiverName(), download->downloadID().downloadID()); } m_downloads.clear(); - m_process = 0; + m_process = nullptr; } } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/Downloads/DownloadProxyMap.h b/Source/WebKit2/UIProcess/Downloads/DownloadProxyMap.h index 66f5f41d8..8f89cd6ab 100644 --- a/Source/WebKit2/UIProcess/Downloads/DownloadProxyMap.h +++ b/Source/WebKit2/UIProcess/Downloads/DownloadProxyMap.h @@ -26,15 +26,19 @@ #ifndef DownloadProxyMap_h #define DownloadProxyMap_h +#include "DownloadID.h" #include <wtf/HashMap.h> #include <wtf/Noncopyable.h> -#include <wtf/PassRefPtr.h> + +namespace WebCore { +class ResourceRequest; +} namespace WebKit { class ChildProcessProxy; class DownloadProxy; -class WebContext; +class WebProcessPool; class DownloadProxyMap { WTF_MAKE_NONCOPYABLE(DownloadProxyMap); @@ -43,7 +47,7 @@ public: explicit DownloadProxyMap(ChildProcessProxy*); ~DownloadProxyMap(); - DownloadProxy* createDownloadProxy(WebContext&); + DownloadProxy* createDownloadProxy(WebProcessPool&, const WebCore::ResourceRequest&); void downloadFinished(DownloadProxy*); bool isEmpty() const { return m_downloads.isEmpty(); } @@ -52,7 +56,7 @@ public: private: ChildProcessProxy* m_process; - HashMap<uint64_t, RefPtr<DownloadProxy>> m_downloads; + HashMap<DownloadID, RefPtr<DownloadProxy>> m_downloads; }; } // namespace WebKit |