summaryrefslogtreecommitdiff
path: root/Source/WebKit2/UIProcess/Downloads
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebKit2/UIProcess/Downloads
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/WebKit2/UIProcess/Downloads')
-rw-r--r--Source/WebKit2/UIProcess/Downloads/DownloadProxy.cpp159
-rw-r--r--Source/WebKit2/UIProcess/Downloads/DownloadProxy.h44
-rw-r--r--Source/WebKit2/UIProcess/Downloads/DownloadProxy.messages.in13
-rw-r--r--Source/WebKit2/UIProcess/Downloads/DownloadProxyMap.cpp20
-rw-r--r--Source/WebKit2/UIProcess/Downloads/DownloadProxyMap.h12
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