summaryrefslogtreecommitdiff
path: root/Source/WebKit2/NetworkProcess/Downloads
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebKit2/NetworkProcess/Downloads')
-rw-r--r--Source/WebKit2/NetworkProcess/Downloads/BlobDownloadClient.cpp106
-rw-r--r--Source/WebKit2/NetworkProcess/Downloads/BlobDownloadClient.h61
-rw-r--r--Source/WebKit2/NetworkProcess/Downloads/Download.cpp303
-rw-r--r--Source/WebKit2/NetworkProcess/Downloads/Download.h166
-rw-r--r--Source/WebKit2/NetworkProcess/Downloads/DownloadID.h96
-rw-r--r--Source/WebKit2/NetworkProcess/Downloads/DownloadManager.cpp235
-rw-r--r--Source/WebKit2/NetworkProcess/Downloads/DownloadManager.h118
-rw-r--r--Source/WebKit2/NetworkProcess/Downloads/PendingDownload.cpp106
-rw-r--r--Source/WebKit2/NetworkProcess/Downloads/PendingDownload.h82
-rw-r--r--Source/WebKit2/NetworkProcess/Downloads/gtk/DownloadSoupErrorsGtk.cpp46
-rw-r--r--Source/WebKit2/NetworkProcess/Downloads/soup/DownloadSoupErrors.h40
11 files changed, 1359 insertions, 0 deletions
diff --git a/Source/WebKit2/NetworkProcess/Downloads/BlobDownloadClient.cpp b/Source/WebKit2/NetworkProcess/Downloads/BlobDownloadClient.cpp
new file mode 100644
index 000000000..cf9acce9b
--- /dev/null
+++ b/Source/WebKit2/NetworkProcess/Downloads/BlobDownloadClient.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 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
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "BlobDownloadClient.h"
+
+#if !USE(NETWORK_SESSION)
+
+#include "DataReference.h"
+#include "Download.h"
+#include "WebErrors.h"
+#include <WebCore/MIMETypeRegistry.h>
+#include <WebCore/ResourceError.h>
+#include <WebCore/ResourceResponse.h>
+#include <WebCore/SharedBuffer.h>
+
+namespace WebKit {
+
+using namespace WebCore;
+
+BlobDownloadClient::BlobDownloadClient(Download& download)
+ : m_download(download)
+{
+}
+
+void BlobDownloadClient::didReceiveResponseAsync(ResourceHandle*, ResourceResponse&& response)
+{
+ m_download.didReceiveResponse(WTFMove(response));
+ String suggestedFilename = MIMETypeRegistry::appendFileExtensionIfNecessary(m_download.suggestedName().isEmpty() ? ASCIILiteral("unknown") : m_download.suggestedName(), response.mimeType());
+ m_download.decideDestinationWithSuggestedFilenameAsync(suggestedFilename);
+}
+
+void BlobDownloadClient::didDecideDownloadDestination(const String& destinationPath, bool allowOverwrite)
+{
+ ASSERT(!destinationPath.isEmpty());
+
+ if (fileExists(destinationPath)) {
+ if (!allowOverwrite) {
+ didFail(nullptr, cancelledError(m_download.request()));
+ return;
+ }
+ deleteFile(destinationPath);
+ }
+
+ m_destinationPath = destinationPath;
+ m_destinationFile = openFile(m_destinationPath, OpenForWrite);
+ m_download.didCreateDestination(m_destinationPath);
+
+ m_download.continueDidReceiveResponse();
+}
+
+void BlobDownloadClient::didReceiveBuffer(ResourceHandle*, Ref<SharedBuffer>&& buffer, int)
+{
+ writeToFile(m_destinationFile, buffer->data(), buffer->size());
+ m_download.didReceiveData(buffer->size());
+}
+
+void BlobDownloadClient::didFinishLoading(ResourceHandle*, double)
+{
+ closeFile(m_destinationFile);
+ m_download.didFinish();
+}
+
+void BlobDownloadClient::didCancel()
+{
+ closeFile(m_destinationFile);
+ if (!m_destinationPath.isEmpty())
+ deleteFile(m_destinationPath);
+
+ m_download.didCancel(IPC::DataReference());
+}
+
+void BlobDownloadClient::didFail(ResourceHandle*, const ResourceError& error)
+{
+ closeFile(m_destinationFile);
+ if (!m_destinationPath.isEmpty())
+ deleteFile(m_destinationPath);
+
+ m_download.didFail(error, IPC::DataReference());
+}
+
+}
+
+#endif // !USE(NETWORK_SESSION)
diff --git a/Source/WebKit2/NetworkProcess/Downloads/BlobDownloadClient.h b/Source/WebKit2/NetworkProcess/Downloads/BlobDownloadClient.h
new file mode 100644
index 000000000..4a3e63ee3
--- /dev/null
+++ b/Source/WebKit2/NetworkProcess/Downloads/BlobDownloadClient.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 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
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if !USE(NETWORK_SESSION)
+
+#include <WebCore/FileSystem.h>
+#include <WebCore/ResourceHandleClient.h>
+#include <wtf/RefPtr.h>
+
+namespace WebKit {
+
+class Download;
+class NetworkLoadParameters;
+
+class BlobDownloadClient final : public WebCore::ResourceHandleClient {
+public:
+ explicit BlobDownloadClient(Download&);
+
+ void didCancel();
+ void didDecideDownloadDestination(const String& destinationPath, bool allowOverwrite);
+
+private:
+ // ResourceHandleClient
+ void didReceiveResponseAsync(WebCore::ResourceHandle*, WebCore::ResourceResponse&&) final;
+ void didReceiveBuffer(WebCore::ResourceHandle*, Ref<WebCore::SharedBuffer>&&, int reportedEncodedDataLength) final;
+ void didFinishLoading(WebCore::ResourceHandle*, double finishTime) final;
+ void didFail(WebCore::ResourceHandle*, const WebCore::ResourceError&) final;
+ bool usesAsyncCallbacks() final { return true; }
+
+ Download& m_download;
+ String m_destinationPath;
+ WebCore::PlatformFileHandle m_destinationFile { WebCore::invalidPlatformFileHandle };
+};
+
+}
+
+#endif // !USE(NETWORK_SESSION)
diff --git a/Source/WebKit2/NetworkProcess/Downloads/Download.cpp b/Source/WebKit2/NetworkProcess/Downloads/Download.cpp
new file mode 100644
index 000000000..bf8443b57
--- /dev/null
+++ b/Source/WebKit2/NetworkProcess/Downloads/Download.cpp
@@ -0,0 +1,303 @@
+/*
+ * 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
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Download.h"
+
+#include "AuthenticationManager.h"
+#include "BlobDownloadClient.h"
+#include "Connection.h"
+#include "DataReference.h"
+#include "DownloadManager.h"
+#include "DownloadProxyMessages.h"
+#include "Logging.h"
+#include "NetworkDataTask.h"
+#include "SandboxExtension.h"
+#include "WebCoreArgumentCoders.h"
+#include <WebCore/NotImplemented.h>
+
+using namespace WebCore;
+
+#define RELEASE_LOG_IF_ALLOWED(fmt, ...) RELEASE_LOG_IF(isAlwaysOnLoggingAllowed(), Network, "%p - Download::" fmt, this, ##__VA_ARGS__)
+
+namespace WebKit {
+
+#if USE(NETWORK_SESSION)
+Download::Download(DownloadManager& downloadManager, DownloadID downloadID, NetworkDataTask& download, const SessionID& sessionID, const String& suggestedName)
+ : m_downloadManager(downloadManager)
+ , m_downloadID(downloadID)
+ , m_download(&download)
+ , m_sessionID(sessionID)
+ , m_suggestedName(suggestedName)
+{
+ ASSERT(m_downloadID.downloadID());
+
+ m_downloadManager.didCreateDownload();
+}
+#if PLATFORM(COCOA)
+Download::Download(DownloadManager& downloadManager, DownloadID downloadID, NSURLSessionDownloadTask* download, const SessionID& sessionID, const String& suggestedName)
+ : m_downloadManager(downloadManager)
+ , m_downloadID(downloadID)
+ , m_downloadTask(download)
+ , m_sessionID(sessionID)
+ , m_suggestedName(suggestedName)
+{
+ ASSERT(m_downloadID.downloadID());
+
+ m_downloadManager.didCreateDownload();
+}
+#endif
+#else
+Download::Download(DownloadManager& downloadManager, DownloadID downloadID, const ResourceRequest& request, const String& suggestedName)
+ : m_downloadManager(downloadManager)
+ , m_downloadID(downloadID)
+ , m_request(request)
+ , m_suggestedName(suggestedName)
+{
+ ASSERT(m_downloadID.downloadID());
+
+ m_downloadManager.didCreateDownload();
+}
+#endif // USE(NETWORK_SESSION)
+
+Download::~Download()
+{
+#if !USE(NETWORK_SESSION)
+ for (auto& fileReference : m_blobFileReferences)
+ fileReference->revokeFileAccess();
+
+ if (m_resourceHandle) {
+ m_resourceHandle->clearClient();
+ m_resourceHandle->cancel();
+ m_resourceHandle = nullptr;
+ }
+ m_downloadClient = nullptr;
+
+ platformInvalidate();
+#endif
+
+ m_downloadManager.didDestroyDownload();
+}
+
+#if !USE(NETWORK_SESSION)
+void Download::start()
+{
+ if (m_request.url().protocolIsBlob()) {
+ m_downloadClient = std::make_unique<BlobDownloadClient>(*this);
+ m_resourceHandle = ResourceHandle::create(nullptr, m_request, m_downloadClient.get(), false, false);
+ didStart();
+ return;
+ }
+
+ startNetworkLoad();
+}
+
+void Download::startWithHandle(ResourceHandle* handle, const ResourceResponse& response)
+{
+ if (m_request.url().protocolIsBlob()) {
+ m_downloadClient = std::make_unique<BlobDownloadClient>(*this);
+ m_resourceHandle = ResourceHandle::create(nullptr, m_request, m_downloadClient.get(), false, false);
+ didStart();
+ return;
+ }
+
+ startNetworkLoadWithHandle(handle, response);
+}
+#endif
+
+void Download::cancel()
+{
+#if USE(NETWORK_SESSION)
+ if (m_download) {
+ m_download->cancel();
+ didCancel({ });
+ return;
+ }
+#else
+ if (m_request.url().protocolIsBlob()) {
+ auto resourceHandle = WTFMove(m_resourceHandle);
+ resourceHandle->cancel();
+ static_cast<BlobDownloadClient*>(m_downloadClient.get())->didCancel();
+ return;
+ }
+#endif
+ platformCancelNetworkLoad();
+}
+
+#if !USE(NETWORK_SESSION)
+void Download::didStart()
+{
+ send(Messages::DownloadProxy::DidStart(m_request, m_suggestedName));
+}
+
+void Download::didReceiveAuthenticationChallenge(const AuthenticationChallenge& authenticationChallenge)
+{
+ m_downloadManager.downloadsAuthenticationManager().didReceiveAuthenticationChallenge(*this, authenticationChallenge);
+}
+
+void Download::didReceiveResponse(const ResourceResponse& response)
+{
+ RELEASE_LOG_IF_ALLOWED("didReceiveResponse: Created (id = %" PRIu64 ")", downloadID().downloadID());
+
+ m_responseMIMEType = response.mimeType();
+ send(Messages::DownloadProxy::DidReceiveResponse(response));
+}
+
+bool Download::shouldDecodeSourceDataOfMIMEType(const String& mimeType)
+{
+ bool result;
+ if (!sendSync(Messages::DownloadProxy::ShouldDecodeSourceDataOfMIMEType(mimeType), Messages::DownloadProxy::ShouldDecodeSourceDataOfMIMEType::Reply(result)))
+ return true;
+
+ return result;
+}
+
+String Download::decideDestinationWithSuggestedFilename(const String& filename, bool& allowOverwrite)
+{
+ String destination;
+ SandboxExtension::Handle sandboxExtensionHandle;
+ if (!sendSync(Messages::DownloadProxy::DecideDestinationWithSuggestedFilename(filename, m_responseMIMEType), Messages::DownloadProxy::DecideDestinationWithSuggestedFilename::Reply(destination, allowOverwrite, sandboxExtensionHandle)))
+ return String();
+
+ m_sandboxExtension = SandboxExtension::create(sandboxExtensionHandle);
+ if (m_sandboxExtension)
+ m_sandboxExtension->consume();
+
+ return destination;
+}
+
+void Download::decideDestinationWithSuggestedFilenameAsync(const String& suggestedFilename)
+{
+ send(Messages::DownloadProxy::DecideDestinationWithSuggestedFilenameAsync(downloadID(), suggestedFilename));
+}
+
+void Download::didDecideDownloadDestination(const String& destinationPath, const SandboxExtension::Handle& sandboxExtensionHandle, bool allowOverwrite)
+{
+ ASSERT(!m_sandboxExtension);
+ m_sandboxExtension = SandboxExtension::create(sandboxExtensionHandle);
+ if (m_sandboxExtension)
+ m_sandboxExtension->consume();
+
+ if (m_request.url().protocolIsBlob()) {
+ static_cast<BlobDownloadClient*>(m_downloadClient.get())->didDecideDownloadDestination(destinationPath, allowOverwrite);
+ return;
+ }
+
+ // For now, only Blob URL downloads go through this code path.
+ ASSERT_NOT_REACHED();
+}
+
+void Download::continueDidReceiveResponse()
+{
+ m_resourceHandle->continueDidReceiveResponse();
+}
+#endif
+
+void Download::didCreateDestination(const String& path)
+{
+ send(Messages::DownloadProxy::DidCreateDestination(path));
+}
+
+void Download::didReceiveData(uint64_t length)
+{
+ if (!m_hasReceivedData) {
+ RELEASE_LOG_IF_ALLOWED("didReceiveData: Started receiving data (id = %" PRIu64 ")", downloadID().downloadID());
+ m_hasReceivedData = true;
+ }
+
+ send(Messages::DownloadProxy::DidReceiveData(length));
+}
+
+void Download::didFinish()
+{
+ RELEASE_LOG_IF_ALLOWED("didFinish: (id = %" PRIu64 ")", downloadID().downloadID());
+
+#if !USE(NETWORK_SESSION)
+ platformDidFinish();
+#endif
+
+ send(Messages::DownloadProxy::DidFinish());
+
+ if (m_sandboxExtension) {
+ m_sandboxExtension->revoke();
+ m_sandboxExtension = nullptr;
+ }
+
+ m_downloadManager.downloadFinished(this);
+}
+
+void Download::didFail(const ResourceError& error, const IPC::DataReference& resumeData)
+{
+ RELEASE_LOG_IF_ALLOWED("didFail: (id = %" PRIu64 ", isTimeout = %d, isCancellation = %d, errCode = %d)",
+ downloadID().downloadID(), error.isTimeout(), error.isCancellation(), error.errorCode());
+
+ send(Messages::DownloadProxy::DidFail(error, resumeData));
+
+ if (m_sandboxExtension) {
+ m_sandboxExtension->revoke();
+ m_sandboxExtension = nullptr;
+ }
+ m_downloadManager.downloadFinished(this);
+}
+
+void Download::didCancel(const IPC::DataReference& resumeData)
+{
+ RELEASE_LOG_IF_ALLOWED("didCancel: (id = %" PRIu64 ")", downloadID().downloadID());
+
+ send(Messages::DownloadProxy::DidCancel(resumeData));
+
+ if (m_sandboxExtension) {
+ m_sandboxExtension->revoke();
+ m_sandboxExtension = nullptr;
+ }
+ m_downloadManager.downloadFinished(this);
+}
+
+IPC::Connection* Download::messageSenderConnection()
+{
+ return m_downloadManager.downloadProxyConnection();
+}
+
+uint64_t Download::messageSenderDestinationID()
+{
+ return m_downloadID.downloadID();
+}
+
+bool Download::isAlwaysOnLoggingAllowed() const
+{
+#if USE(NETWORK_SESSION) && PLATFORM(COCOA)
+ return m_sessionID.isAlwaysOnLoggingAllowed();
+#else
+ return false;
+#endif
+}
+
+#if !PLATFORM(COCOA)
+void Download::platformCancelNetworkLoad()
+{
+}
+#endif
+
+} // namespace WebKit
diff --git a/Source/WebKit2/NetworkProcess/Downloads/Download.h b/Source/WebKit2/NetworkProcess/Downloads/Download.h
new file mode 100644
index 000000000..ae4d7cff6
--- /dev/null
+++ b/Source/WebKit2/NetworkProcess/Downloads/Download.h
@@ -0,0 +1,166 @@
+/*
+ * 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
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef Download_h
+#define Download_h
+
+#include "DownloadID.h"
+#include "MessageSender.h"
+#include "SandboxExtension.h"
+#include <WebCore/ResourceHandle.h>
+#include <WebCore/ResourceHandleClient.h>
+#include <WebCore/ResourceRequest.h>
+#include <WebCore/SessionID.h>
+#include <memory>
+#include <wtf/Noncopyable.h>
+#include <wtf/RetainPtr.h>
+
+#if USE(NETWORK_SESSION)
+#if PLATFORM(COCOA)
+OBJC_CLASS NSURLSessionDownloadTask;
+#endif
+#else // USE(NETWORK_SESSION)
+#if PLATFORM(COCOA)
+OBJC_CLASS NSURLDownload;
+OBJC_CLASS WKDownloadAsDelegate;
+#endif
+#endif // USE(NETWORK_SESSION)
+
+#if USE(CFURLCONNECTION)
+#include <CFNetwork/CFURLDownloadPriv.h>
+#endif
+
+namespace IPC {
+class DataReference;
+}
+
+namespace WebCore {
+class AuthenticationChallenge;
+class BlobDataFileReference;
+class Credential;
+class ResourceError;
+class ResourceHandle;
+class ResourceResponse;
+}
+
+namespace WebKit {
+
+class DownloadManager;
+class NetworkDataTask;
+class NetworkSession;
+class WebPage;
+
+class Download : public IPC::MessageSender {
+ WTF_MAKE_NONCOPYABLE(Download); WTF_MAKE_FAST_ALLOCATED;
+public:
+#if USE(NETWORK_SESSION)
+ Download(DownloadManager&, DownloadID, NetworkDataTask&, const WebCore::SessionID& sessionID, const String& suggestedFilename = { });
+#if PLATFORM(COCOA)
+ Download(DownloadManager&, DownloadID, NSURLSessionDownloadTask*, const WebCore::SessionID& sessionID, const String& suggestedFilename = { });
+#endif
+#else
+ Download(DownloadManager&, DownloadID, const WebCore::ResourceRequest&, const String& suggestedFilename = { });
+#endif
+
+ ~Download();
+
+#if !USE(NETWORK_SESSION)
+ void setBlobFileReferences(Vector<RefPtr<WebCore::BlobDataFileReference>>&& fileReferences) { m_blobFileReferences = WTFMove(fileReferences); }
+
+ void start();
+ void startWithHandle(WebCore::ResourceHandle*, const WebCore::ResourceResponse&);
+#endif
+ void resume(const IPC::DataReference& resumeData, const String& path, const SandboxExtension::Handle&);
+ void cancel();
+
+ DownloadID downloadID() const { return m_downloadID; }
+ const String& suggestedName() const { return m_suggestedName; }
+
+#if USE(NETWORK_SESSION)
+ void setSandboxExtension(RefPtr<SandboxExtension>&& sandboxExtension) { m_sandboxExtension = WTFMove(sandboxExtension); }
+#else
+ const WebCore::ResourceRequest& request() const { return m_request; }
+ void didReceiveAuthenticationChallenge(const WebCore::AuthenticationChallenge&);
+ void didStart();
+ void didReceiveResponse(const WebCore::ResourceResponse&);
+ bool shouldDecodeSourceDataOfMIMEType(const String& mimeType);
+ String decideDestinationWithSuggestedFilename(const String& filename, bool& allowOverwrite);
+ void decideDestinationWithSuggestedFilenameAsync(const String&);
+ void didDecideDownloadDestination(const String& destinationPath, const SandboxExtension::Handle&, bool allowOverwrite);
+ void continueDidReceiveResponse();
+ void platformDidFinish();
+#endif
+ void didCreateDestination(const String& path);
+ void didReceiveData(uint64_t length);
+ void didFinish();
+ void didFail(const WebCore::ResourceError&, const IPC::DataReference& resumeData);
+ void didCancel(const IPC::DataReference& resumeData);
+
+private:
+ // IPC::MessageSender
+ IPC::Connection* messageSenderConnection() override;
+ uint64_t messageSenderDestinationID() override;
+
+#if !USE(NETWORK_SESSION)
+ void startNetworkLoad();
+ void startNetworkLoadWithHandle(WebCore::ResourceHandle*, const WebCore::ResourceResponse&);
+ void platformInvalidate();
+#endif
+ void platformCancelNetworkLoad();
+
+ bool isAlwaysOnLoggingAllowed() const;
+
+ DownloadManager& m_downloadManager;
+ DownloadID m_downloadID;
+
+ Vector<RefPtr<WebCore::BlobDataFileReference>> m_blobFileReferences;
+ RefPtr<SandboxExtension> m_sandboxExtension;
+
+#if USE(NETWORK_SESSION)
+ RefPtr<NetworkDataTask> m_download;
+#if PLATFORM(COCOA)
+ RetainPtr<NSURLSessionDownloadTask> m_downloadTask;
+#endif
+ WebCore::SessionID m_sessionID;
+#else // USE(NETWORK_SESSION)
+ WebCore::ResourceRequest m_request;
+ String m_responseMIMEType;
+#if PLATFORM(COCOA)
+ RetainPtr<NSURLDownload> m_nsURLDownload;
+ RetainPtr<WKDownloadAsDelegate> m_delegate;
+#endif
+#if USE(CFURLCONNECTION)
+ RetainPtr<CFURLDownloadRef> m_download;
+#endif
+ std::unique_ptr<WebCore::ResourceHandleClient> m_downloadClient;
+ RefPtr<WebCore::ResourceHandle> m_resourceHandle;
+#endif // USE(NETWORK_SESSION)
+ String m_suggestedName;
+ bool m_hasReceivedData { false };
+};
+
+} // namespace WebKit
+
+#endif // Download_h
diff --git a/Source/WebKit2/NetworkProcess/Downloads/DownloadID.h b/Source/WebKit2/NetworkProcess/Downloads/DownloadID.h
new file mode 100644
index 000000000..04df707f8
--- /dev/null
+++ b/Source/WebKit2/NetworkProcess/Downloads/DownloadID.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DownloadID_h
+#define DownloadID_h
+
+#include "ArgumentCoder.h"
+#include "Decoder.h"
+#include "Encoder.h"
+#include <wtf/HashTraits.h>
+
+namespace WebKit {
+
+class DownloadID {
+public:
+ DownloadID()
+ {
+ }
+
+ explicit DownloadID(uint64_t downloadID)
+ : m_downloadID(downloadID)
+ {
+ }
+
+ bool operator==(DownloadID other) const { return m_downloadID == other.m_downloadID; }
+ bool operator!=(DownloadID other) const { return m_downloadID != other.m_downloadID; }
+
+ uint64_t downloadID() const { return m_downloadID; }
+private:
+ uint64_t m_downloadID { 0 };
+};
+
+}
+
+namespace IPC {
+
+template<> struct ArgumentCoder<WebKit::DownloadID> {
+ static void encode(Encoder& encoder, const WebKit::DownloadID& downloadID)
+ {
+ encoder << downloadID.downloadID();
+ }
+ static bool decode(Decoder& decoder, WebKit::DownloadID& downloadID)
+ {
+ uint64_t id;
+ if (!decoder.decode(id))
+ return false;
+
+ downloadID = WebKit::DownloadID(id);
+
+ return true;
+ }
+};
+
+}
+
+namespace WTF {
+
+struct DownloadIDHash {
+ static unsigned hash(const WebKit::DownloadID& d) { return intHash(d.downloadID()); }
+ static bool equal(const WebKit::DownloadID& a, const WebKit::DownloadID& b) { return a.downloadID() == b.downloadID(); }
+ static const bool safeToCompareToEmptyOrDeleted = true;
+};
+template<> struct HashTraits<WebKit::DownloadID> : GenericHashTraits<WebKit::DownloadID> {
+ static WebKit::DownloadID emptyValue() { return { }; }
+
+ static void constructDeletedValue(WebKit::DownloadID& slot) { slot = WebKit::DownloadID(std::numeric_limits<uint64_t>::max()); }
+ static bool isDeletedValue(const WebKit::DownloadID& slot) { return slot.downloadID() == std::numeric_limits<uint64_t>::max(); }
+};
+template<> struct DefaultHash<WebKit::DownloadID> {
+ typedef DownloadIDHash Hash;
+};
+
+}
+#endif /* DownloadID_h */
diff --git a/Source/WebKit2/NetworkProcess/Downloads/DownloadManager.cpp b/Source/WebKit2/NetworkProcess/Downloads/DownloadManager.cpp
new file mode 100644
index 000000000..b76ba47bd
--- /dev/null
+++ b/Source/WebKit2/NetworkProcess/Downloads/DownloadManager.cpp
@@ -0,0 +1,235 @@
+/*
+ * 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
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DownloadManager.h"
+
+#include "Download.h"
+#include "NetworkBlobRegistry.h"
+#include "NetworkLoad.h"
+#include "NetworkSession.h"
+#include "PendingDownload.h"
+#include "SessionTracker.h"
+#include <WebCore/NotImplemented.h>
+#include <WebCore/SessionID.h>
+#include <wtf/StdLibExtras.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+DownloadManager::DownloadManager(Client& client)
+ : m_client(client)
+{
+}
+
+void DownloadManager::startDownload(NetworkConnectionToWebProcess* connection, SessionID sessionID, DownloadID downloadID, const ResourceRequest& request, const String& suggestedName)
+{
+#if USE(NETWORK_SESSION)
+ auto* networkSession = SessionTracker::networkSession(sessionID);
+ if (!networkSession)
+ return;
+
+ NetworkLoadParameters parameters;
+ parameters.sessionID = sessionID;
+ parameters.request = request;
+ parameters.clientCredentialPolicy = ClientCredentialPolicy::MayAskClientForCredentials;
+ if (request.url().protocolIsBlob() && connection)
+ parameters.blobFileReferences = NetworkBlobRegistry::singleton().filesInBlob(*connection, request.url());
+ parameters.allowStoredCredentials = sessionID.isEphemeral() ? DoNotAllowStoredCredentials : AllowStoredCredentials;
+
+ m_pendingDownloads.add(downloadID, std::make_unique<PendingDownload>(WTFMove(parameters), downloadID, *networkSession, suggestedName));
+#else
+ auto download = std::make_unique<Download>(*this, downloadID, request, suggestedName);
+ if (request.url().protocolIsBlob() && connection) {
+ auto blobFileReferences = NetworkBlobRegistry::singleton().filesInBlob(*connection, request.url());
+ for (auto& fileReference : blobFileReferences)
+ fileReference->prepareForFileAccess();
+ download->setBlobFileReferences(WTFMove(blobFileReferences));
+ }
+ download->start();
+
+ ASSERT(!m_downloads.contains(downloadID));
+ m_downloads.add(downloadID, WTFMove(download));
+#endif
+}
+
+#if USE(NETWORK_SESSION)
+void DownloadManager::dataTaskBecameDownloadTask(DownloadID downloadID, std::unique_ptr<Download>&& download)
+{
+ ASSERT(m_pendingDownloads.contains(downloadID));
+ m_pendingDownloads.remove(downloadID);
+ ASSERT(!m_downloads.contains(downloadID));
+ m_downloadsAfterDestinationDecided.remove(downloadID);
+ m_downloads.add(downloadID, WTFMove(download));
+}
+
+#if USE(PROTECTION_SPACE_AUTH_CALLBACK)
+void DownloadManager::continueCanAuthenticateAgainstProtectionSpace(DownloadID downloadID, bool canAuthenticate)
+{
+ auto* pendingDownload = m_pendingDownloads.get(downloadID);
+ ASSERT(pendingDownload);
+ if (pendingDownload)
+ pendingDownload->continueCanAuthenticateAgainstProtectionSpace(canAuthenticate);
+}
+#endif
+
+void DownloadManager::continueWillSendRequest(DownloadID downloadID, WebCore::ResourceRequest&& request)
+{
+ auto* pendingDownload = m_pendingDownloads.get(downloadID);
+ ASSERT(pendingDownload);
+ if (pendingDownload)
+ pendingDownload->continueWillSendRequest(WTFMove(request));
+}
+
+void DownloadManager::willDecidePendingDownloadDestination(NetworkDataTask& networkDataTask, ResponseCompletionHandler&& completionHandler)
+{
+ auto downloadID = networkDataTask.pendingDownloadID();
+ auto addResult = m_downloadsWaitingForDestination.set(downloadID, std::make_pair<RefPtr<NetworkDataTask>, ResponseCompletionHandler>(&networkDataTask, WTFMove(completionHandler)));
+ ASSERT_UNUSED(addResult, addResult.isNewEntry);
+}
+#endif // USE(NETWORK_SESSION)
+
+void DownloadManager::convertNetworkLoadToDownload(DownloadID downloadID, std::unique_ptr<NetworkLoad>&& networkLoad, Vector<RefPtr<WebCore::BlobDataFileReference>>&& blobFileReferences, const ResourceRequest& request, const ResourceResponse& response)
+{
+#if USE(NETWORK_SESSION)
+ ASSERT(!m_pendingDownloads.contains(downloadID));
+ m_pendingDownloads.add(downloadID, std::make_unique<PendingDownload>(WTFMove(networkLoad), downloadID, request, response));
+#else
+ auto download = std::make_unique<Download>(*this, downloadID, request);
+ download->setBlobFileReferences(WTFMove(blobFileReferences));
+
+ auto* handle = networkLoad->handle();
+ ASSERT(handle);
+ download->startWithHandle(handle, response);
+ ASSERT(!m_downloads.contains(downloadID));
+ m_downloads.add(downloadID, WTFMove(download));
+
+ // Unblock the URL connection operation queue.
+ handle->continueDidReceiveResponse();
+#endif
+}
+
+void DownloadManager::continueDecidePendingDownloadDestination(DownloadID downloadID, String destination, const SandboxExtension::Handle& sandboxExtensionHandle, bool allowOverwrite)
+{
+#if USE(NETWORK_SESSION)
+ if (m_downloadsWaitingForDestination.contains(downloadID)) {
+ auto pair = m_downloadsWaitingForDestination.take(downloadID);
+ auto networkDataTask = WTFMove(pair.first);
+ auto completionHandler = WTFMove(pair.second);
+ ASSERT(networkDataTask);
+ ASSERT(completionHandler);
+ ASSERT(m_pendingDownloads.contains(downloadID));
+
+ networkDataTask->setPendingDownloadLocation(destination, sandboxExtensionHandle, allowOverwrite);
+ completionHandler(PolicyDownload);
+ if (networkDataTask->state() == NetworkDataTask::State::Canceling || networkDataTask->state() == NetworkDataTask::State::Completed)
+ return;
+
+ if (m_downloads.contains(downloadID)) {
+ // The completion handler already called dataTaskBecameDownloadTask().
+ return;
+ }
+
+ ASSERT(!m_downloadsAfterDestinationDecided.contains(downloadID));
+ m_downloadsAfterDestinationDecided.set(downloadID, networkDataTask);
+ }
+#else
+ if (auto* waitingDownload = download(downloadID))
+ waitingDownload->didDecideDownloadDestination(destination, sandboxExtensionHandle, allowOverwrite);
+#endif
+}
+
+void DownloadManager::resumeDownload(SessionID, DownloadID downloadID, const IPC::DataReference& resumeData, const String& path, const SandboxExtension::Handle& sandboxExtensionHandle)
+{
+#if USE(NETWORK_SESSION)
+ notImplemented();
+#else
+ // Download::resume() is responsible for setting the Download's resource request.
+ auto download = std::make_unique<Download>(*this, downloadID, ResourceRequest());
+
+ download->resume(resumeData, path, sandboxExtensionHandle);
+ ASSERT(!m_downloads.contains(downloadID));
+ m_downloads.add(downloadID, WTFMove(download));
+#endif
+}
+
+void DownloadManager::cancelDownload(DownloadID downloadID)
+{
+ if (Download* download = m_downloads.get(downloadID)) {
+#if USE(NETWORK_SESSION)
+ ASSERT(!m_downloadsWaitingForDestination.contains(downloadID));
+ ASSERT(!m_pendingDownloads.contains(downloadID));
+#endif
+ download->cancel();
+ return;
+ }
+#if USE(NETWORK_SESSION)
+ auto pendingDownload = m_pendingDownloads.take(downloadID);
+ if (m_downloadsWaitingForDestination.contains(downloadID)) {
+ auto pair = m_downloadsWaitingForDestination.take(downloadID);
+ auto networkDataTask = WTFMove(pair.first);
+ auto completionHandler = WTFMove(pair.second);
+ ASSERT(networkDataTask);
+ ASSERT(completionHandler);
+
+ networkDataTask->cancel();
+ completionHandler(PolicyIgnore);
+ m_client.pendingDownloadCanceled(downloadID);
+ return;
+ }
+
+ if (pendingDownload)
+ pendingDownload->cancel();
+#endif
+}
+
+void DownloadManager::downloadFinished(Download* download)
+{
+ ASSERT(m_downloads.contains(download->downloadID()));
+ m_downloads.remove(download->downloadID());
+}
+
+void DownloadManager::didCreateDownload()
+{
+ m_client.didCreateDownload();
+}
+
+void DownloadManager::didDestroyDownload()
+{
+ m_client.didDestroyDownload();
+}
+
+IPC::Connection* DownloadManager::downloadProxyConnection()
+{
+ return m_client.downloadProxyConnection();
+}
+
+AuthenticationManager& DownloadManager::downloadsAuthenticationManager()
+{
+ return m_client.downloadsAuthenticationManager();
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/NetworkProcess/Downloads/DownloadManager.h b/Source/WebKit2/NetworkProcess/Downloads/DownloadManager.h
new file mode 100644
index 000000000..b4d525b72
--- /dev/null
+++ b/Source/WebKit2/NetworkProcess/Downloads/DownloadManager.h
@@ -0,0 +1,118 @@
+/*
+ * 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
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DownloadManager_h
+#define DownloadManager_h
+
+#include "DownloadID.h"
+#include "NetworkDataTask.h"
+#include "PendingDownload.h"
+#include "SandboxExtension.h"
+#include <WebCore/NotImplemented.h>
+#include <wtf/Forward.h>
+#include <wtf/HashMap.h>
+#include <wtf/Noncopyable.h>
+
+namespace WebCore {
+class BlobDataFileReference;
+class ResourceHandle;
+class ResourceRequest;
+class ResourceResponse;
+class SessionID;
+}
+
+namespace IPC {
+class Connection;
+class DataReference;
+}
+
+namespace WebKit {
+
+class AuthenticationManager;
+class Download;
+class NetworkConnectionToWebProcess;
+class NetworkLoad;
+class PendingDownload;
+
+class DownloadManager {
+ WTF_MAKE_NONCOPYABLE(DownloadManager);
+
+public:
+ class Client {
+ public:
+ virtual ~Client() { }
+
+ virtual void didCreateDownload() = 0;
+ virtual void didDestroyDownload() = 0;
+ virtual IPC::Connection* downloadProxyConnection() = 0;
+ virtual AuthenticationManager& downloadsAuthenticationManager() = 0;
+#if USE(NETWORK_SESSION)
+ virtual void pendingDownloadCanceled(DownloadID) = 0;
+#endif
+ };
+
+ explicit DownloadManager(Client&);
+
+ void startDownload(NetworkConnectionToWebProcess*, WebCore::SessionID, DownloadID, const WebCore::ResourceRequest&, const String& suggestedName = { });
+#if USE(NETWORK_SESSION)
+ void dataTaskBecameDownloadTask(DownloadID, std::unique_ptr<Download>&&);
+#if USE(PROTECTION_SPACE_AUTH_CALLBACK)
+ void continueCanAuthenticateAgainstProtectionSpace(DownloadID, bool canAuthenticate);
+#endif
+ void continueWillSendRequest(DownloadID, WebCore::ResourceRequest&&);
+ void willDecidePendingDownloadDestination(NetworkDataTask&, ResponseCompletionHandler&&);
+#endif
+ void convertNetworkLoadToDownload(DownloadID, std::unique_ptr<NetworkLoad>&&, Vector<RefPtr<WebCore::BlobDataFileReference>>&&, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&);
+ void continueDecidePendingDownloadDestination(DownloadID, String destination, const SandboxExtension::Handle&, bool allowOverwrite);
+
+ void resumeDownload(WebCore::SessionID, DownloadID, const IPC::DataReference& resumeData, const String& path, const SandboxExtension::Handle&);
+
+ void cancelDownload(DownloadID);
+
+ Download* download(DownloadID downloadID) { return m_downloads.get(downloadID); }
+
+ void downloadFinished(Download*);
+ bool isDownloading() const { return !m_downloads.isEmpty(); }
+ uint64_t activeDownloadCount() const { return m_downloads.size(); }
+
+ void didCreateDownload();
+ void didDestroyDownload();
+
+ IPC::Connection* downloadProxyConnection();
+ AuthenticationManager& downloadsAuthenticationManager();
+
+private:
+ Client& m_client;
+#if USE(NETWORK_SESSION)
+ HashMap<DownloadID, std::unique_ptr<PendingDownload>> m_pendingDownloads;
+ HashMap<DownloadID, std::pair<RefPtr<NetworkDataTask>, ResponseCompletionHandler>> m_downloadsWaitingForDestination;
+ HashMap<DownloadID, RefPtr<NetworkDataTask>> m_downloadsAfterDestinationDecided;
+#endif
+ HashMap<DownloadID, std::unique_ptr<Download>> m_downloads;
+};
+
+} // namespace WebKit
+
+#endif // DownloadManager_h
diff --git a/Source/WebKit2/NetworkProcess/Downloads/PendingDownload.cpp b/Source/WebKit2/NetworkProcess/Downloads/PendingDownload.cpp
new file mode 100644
index 000000000..876775b8f
--- /dev/null
+++ b/Source/WebKit2/NetworkProcess/Downloads/PendingDownload.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 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
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PendingDownload.h"
+
+#if USE(NETWORK_SESSION)
+
+#include "DataReference.h"
+#include "DownloadProxyMessages.h"
+#include "NetworkLoad.h"
+#include "NetworkProcess.h"
+#include "WebCoreArgumentCoders.h"
+
+using namespace WebCore;
+
+namespace WebKit {
+
+PendingDownload::PendingDownload(NetworkLoadParameters&& parameters, DownloadID downloadID, NetworkSession& networkSession, const String& suggestedName)
+ : m_networkLoad(std::make_unique<NetworkLoad>(*this, WTFMove(parameters), networkSession))
+{
+ m_networkLoad->setPendingDownloadID(downloadID);
+ m_networkLoad->setPendingDownload(*this);
+ m_networkLoad->setSuggestedFilename(suggestedName);
+
+ send(Messages::DownloadProxy::DidStart(m_networkLoad->currentRequest(), suggestedName));
+}
+
+PendingDownload::PendingDownload(std::unique_ptr<NetworkLoad>&& networkLoad, DownloadID downloadID, const ResourceRequest& request, const ResourceResponse& response)
+ : m_networkLoad(WTFMove(networkLoad))
+{
+ m_networkLoad->setPendingDownloadID(downloadID);
+ send(Messages::DownloadProxy::DidStart(request, String()));
+
+ m_networkLoad->convertTaskToDownload(*this, request, response);
+}
+
+void PendingDownload::willSendRedirectedRequest(WebCore::ResourceRequest&&, WebCore::ResourceRequest&& redirectRequest, WebCore::ResourceResponse&& redirectResponse)
+{
+ send(Messages::DownloadProxy::WillSendRequest(WTFMove(redirectRequest), WTFMove(redirectResponse)));
+};
+
+void PendingDownload::continueWillSendRequest(WebCore::ResourceRequest&& newRequest)
+{
+ m_networkLoad->continueWillSendRequest(WTFMove(newRequest));
+}
+
+void PendingDownload::cancel()
+{
+ ASSERT(m_networkLoad);
+ m_networkLoad->cancel();
+ send(Messages::DownloadProxy::DidCancel({ }));
+}
+
+#if USE(PROTECTION_SPACE_AUTH_CALLBACK)
+void PendingDownload::canAuthenticateAgainstProtectionSpaceAsync(const WebCore::ProtectionSpace& protectionSpace)
+{
+ send(Messages::DownloadProxy::CanAuthenticateAgainstProtectionSpace(protectionSpace));
+}
+
+void PendingDownload::continueCanAuthenticateAgainstProtectionSpace(bool canAuthenticate)
+{
+ m_networkLoad->continueCanAuthenticateAgainstProtectionSpace(canAuthenticate);
+}
+#endif
+
+void PendingDownload::didFailLoading(const WebCore::ResourceError& error)
+{
+ send(Messages::DownloadProxy::DidFail(error, { }));
+}
+
+IPC::Connection* PendingDownload::messageSenderConnection()
+{
+ return NetworkProcess::singleton().parentProcessConnection();
+}
+
+uint64_t PendingDownload::messageSenderDestinationID()
+{
+ return m_networkLoad->pendingDownloadID().downloadID();
+}
+
+}
+
+#endif
diff --git a/Source/WebKit2/NetworkProcess/Downloads/PendingDownload.h b/Source/WebKit2/NetworkProcess/Downloads/PendingDownload.h
new file mode 100644
index 000000000..208d73dae
--- /dev/null
+++ b/Source/WebKit2/NetworkProcess/Downloads/PendingDownload.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 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
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PendingDownload_h
+#define PendingDownload_h
+
+#if USE(NETWORK_SESSION)
+
+#include "MessageSender.h"
+#include "NetworkLoadClient.h"
+
+namespace WebCore {
+class ResourceResponse;
+}
+
+namespace WebKit {
+
+class DownloadID;
+class NetworkLoad;
+class NetworkLoadParameters;
+class NetworkSession;
+
+class PendingDownload : public NetworkLoadClient, public IPC::MessageSender {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ PendingDownload(NetworkLoadParameters&&, DownloadID, NetworkSession&, const String& suggestedName);
+ PendingDownload(std::unique_ptr<NetworkLoad>&&, DownloadID, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&);
+
+ void continueWillSendRequest(WebCore::ResourceRequest&&);
+#if USE(PROTECTION_SPACE_AUTH_CALLBACK)
+ void continueCanAuthenticateAgainstProtectionSpace(bool canAuthenticate);
+#endif
+ void cancel();
+
+private:
+ // NetworkLoadClient.
+ void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) override { }
+#if USE(PROTECTION_SPACE_AUTH_CALLBACK)
+ void canAuthenticateAgainstProtectionSpaceAsync(const WebCore::ProtectionSpace&) override;
+#endif
+ bool isSynchronous() const override { return false; }
+ void willSendRedirectedRequest(WebCore::ResourceRequest&&, WebCore::ResourceRequest&& redirectRequest, WebCore::ResourceResponse&& redirectResponse) override;
+ ShouldContinueDidReceiveResponse didReceiveResponse(WebCore::ResourceResponse&&) override { return ShouldContinueDidReceiveResponse::No; };
+ void didReceiveBuffer(Ref<WebCore::SharedBuffer>&&, int reportedEncodedDataLength) override { };
+ void didFinishLoading(double finishTime) override { };
+ void didFailLoading(const WebCore::ResourceError&) override;
+
+ // MessageSender.
+ IPC::Connection* messageSenderConnection() override;
+ uint64_t messageSenderDestinationID() override;
+
+private:
+ std::unique_ptr<NetworkLoad> m_networkLoad;
+};
+
+}
+
+#endif
+
+#endif
diff --git a/Source/WebKit2/NetworkProcess/Downloads/gtk/DownloadSoupErrorsGtk.cpp b/Source/WebKit2/NetworkProcess/Downloads/gtk/DownloadSoupErrorsGtk.cpp
new file mode 100644
index 000000000..ba2e7b456
--- /dev/null
+++ b/Source/WebKit2/NetworkProcess/Downloads/gtk/DownloadSoupErrorsGtk.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DownloadSoupErrors.h"
+
+#include <WebCore/ErrorsGtk.h>
+#include <WebCore/ResourceError.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+ResourceError platformDownloadNetworkError(int errorCode, const URL& failingURL, const String& localizedDescription)
+{
+ return downloadNetworkError(ResourceError(errorDomainDownload, errorCode, failingURL, localizedDescription));
+}
+
+ResourceError platformDownloadDestinationError(const ResourceResponse& response, const String& message)
+{
+ return downloadDestinationError(response, message);
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/NetworkProcess/Downloads/soup/DownloadSoupErrors.h b/Source/WebKit2/NetworkProcess/Downloads/soup/DownloadSoupErrors.h
new file mode 100644
index 000000000..ff397ec22
--- /dev/null
+++ b/Source/WebKit2/NetworkProcess/Downloads/soup/DownloadSoupErrors.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DownloadSoupErrors_h
+#define DownloadSoupErrors_h
+
+#include <WebCore/ResourceHandle.h>
+#include <WebCore/URL.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebKit {
+
+WebCore::ResourceError platformDownloadNetworkError(int errorCode, const WebCore::URL& failingURL, const String& localizedDescription);
+WebCore::ResourceError platformDownloadDestinationError(const WebCore::ResourceResponse&, const String& message);
+
+} // namespace WebKit
+
+#endif // DownloadSoupErrors_h