summaryrefslogtreecommitdiff
path: root/Source/WebKit2/UIProcess/Downloads/DownloadProxy.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebKit2/UIProcess/Downloads/DownloadProxy.cpp')
-rw-r--r--Source/WebKit2/UIProcess/Downloads/DownloadProxy.cpp159
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);