summaryrefslogtreecommitdiffstats
path: root/Source/WebKit2/WebProcess/Downloads
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebKit2/WebProcess/Downloads')
-rw-r--r--Source/WebKit2/WebProcess/Downloads/Download.cpp132
-rw-r--r--Source/WebKit2/WebProcess/Downloads/Download.h112
-rw-r--r--Source/WebKit2/WebProcess/Downloads/DownloadManager.cpp83
-rw-r--r--Source/WebKit2/WebProcess/Downloads/DownloadManager.h65
-rw-r--r--Source/WebKit2/WebProcess/Downloads/cf/DownloadCFNet.cpp185
-rw-r--r--Source/WebKit2/WebProcess/Downloads/curl/DownloadCurl.cpp55
-rw-r--r--Source/WebKit2/WebProcess/Downloads/mac/DownloadMac.mm287
-rw-r--r--Source/WebKit2/WebProcess/Downloads/qt/DownloadQt.cpp54
8 files changed, 973 insertions, 0 deletions
diff --git a/Source/WebKit2/WebProcess/Downloads/Download.cpp b/Source/WebKit2/WebProcess/Downloads/Download.cpp
new file mode 100644
index 0000000..3cb5588
--- /dev/null
+++ b/Source/WebKit2/WebProcess/Downloads/Download.cpp
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2010 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 "Download.h"
+
+#include "Connection.h"
+#include "DataReference.h"
+#include "DownloadProxyMessages.h"
+#include "DownloadManager.h"
+#include "SandboxExtension.h"
+#include "WebCoreArgumentCoders.h"
+#include "WebProcess.h"
+
+using namespace WebCore;
+
+namespace WebKit {
+
+PassOwnPtr<Download> Download::create(uint64_t downloadID, const ResourceRequest& request)
+{
+ return adoptPtr(new Download(downloadID, request));
+}
+
+Download::Download(uint64_t downloadID, const ResourceRequest& request)
+ : m_downloadID(downloadID)
+ , m_request(request)
+{
+ ASSERT(m_downloadID);
+}
+
+Download::~Download()
+{
+ platformInvalidate();
+}
+
+CoreIPC::Connection* Download::connection() const
+{
+ return WebProcess::shared().connection();
+}
+
+void Download::didStart()
+{
+ send(Messages::DownloadProxy::DidStart(m_request));
+}
+
+void Download::didReceiveResponse(const ResourceResponse& response)
+{
+ send(Messages::DownloadProxy::DidReceiveResponse(response));
+}
+
+void Download::didReceiveData(uint64_t length)
+{
+ send(Messages::DownloadProxy::DidReceiveData(length));
+}
+
+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), Messages::DownloadProxy::DecideDestinationWithSuggestedFilename::Reply(destination, allowOverwrite, sandboxExtensionHandle)))
+ return String();
+
+ m_sandboxExtension = SandboxExtension::create(sandboxExtensionHandle);
+ if (m_sandboxExtension)
+ m_sandboxExtension->consume();
+
+ return destination;
+}
+
+void Download::didCreateDestination(const String& path)
+{
+ send(Messages::DownloadProxy::DidCreateDestination(path));
+}
+
+void Download::didFinish()
+{
+ send(Messages::DownloadProxy::DidFinish());
+
+ if (m_sandboxExtension)
+ m_sandboxExtension->invalidate();
+ DownloadManager::shared().downloadFinished(this);
+}
+
+void Download::didFail(const ResourceError& error, const CoreIPC::DataReference& resumeData)
+{
+ send(Messages::DownloadProxy::DidFail(error, resumeData));
+
+ if (m_sandboxExtension)
+ m_sandboxExtension->invalidate();
+ DownloadManager::shared().downloadFinished(this);
+}
+
+void Download::didCancel(const CoreIPC::DataReference& resumeData)
+{
+ send(Messages::DownloadProxy::DidCancel(resumeData));
+
+ if (m_sandboxExtension)
+ m_sandboxExtension->invalidate();
+ DownloadManager::shared().downloadFinished(this);
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/Downloads/Download.h b/Source/WebKit2/WebProcess/Downloads/Download.h
new file mode 100644
index 0000000..2319ec7
--- /dev/null
+++ b/Source/WebKit2/WebProcess/Downloads/Download.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2010 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 "MessageSender.h"
+#include <WebCore/ResourceRequest.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/PassOwnPtr.h>
+
+#if PLATFORM(MAC)
+#include <wtf/RetainPtr.h>
+#ifdef __OBJC__
+@class NSURLDownload;
+@class WKDownloadAsDelegate;
+#else
+class NSURLDownload;
+class WKDownloadAsDelegate;
+#endif
+#endif
+
+#if USE(CFNETWORK)
+#include <CFNetwork/CFURLDownloadPriv.h>
+#endif
+
+namespace CoreIPC {
+ class DataReference;
+}
+
+namespace WebCore {
+ class ResourceError;
+ class ResourceHandle;
+ class ResourceResponse;
+}
+
+namespace WebKit {
+
+class SandboxExtension;
+class WebPage;
+
+class Download : public CoreIPC::MessageSender<Download> {
+ WTF_MAKE_NONCOPYABLE(Download);
+
+public:
+ static PassOwnPtr<Download> create(uint64_t downloadID, const WebCore::ResourceRequest&);
+ ~Download();
+
+ // Used by MessageSender.
+ CoreIPC::Connection* connection() const;
+ uint64_t destinationID() const { return downloadID(); }
+
+ void start(WebPage* initiatingWebPage);
+ void startWithHandle(WebPage* initiatingPage, WebCore::ResourceHandle*, const WebCore::ResourceRequest& initialRequest, const WebCore::ResourceResponse&);
+ void cancel();
+
+ uint64_t downloadID() const { return m_downloadID; }
+
+ void didStart();
+ void didReceiveResponse(const WebCore::ResourceResponse&);
+ void didReceiveData(uint64_t length);
+ bool shouldDecodeSourceDataOfMIMEType(const String& mimeType);
+ String decideDestinationWithSuggestedFilename(const String& filename, bool& allowOverwrite);
+ void didCreateDestination(const String& path);
+ void didFinish();
+ void didFail(const WebCore::ResourceError&, const CoreIPC::DataReference& resumeData);
+ void didCancel(const CoreIPC::DataReference& resumeData);
+
+private:
+ Download(uint64_t downloadID, const WebCore::ResourceRequest&);
+
+ void platformInvalidate();
+
+ uint64_t m_downloadID;
+ WebCore::ResourceRequest m_request;
+
+ RefPtr<SandboxExtension> m_sandboxExtension;
+
+#if PLATFORM(MAC)
+ RetainPtr<NSURLDownload> m_nsURLDownload;
+ RetainPtr<WKDownloadAsDelegate> m_delegate;
+#endif
+#if USE(CFNETWORK)
+ RetainPtr<CFURLDownloadRef> m_download;
+#endif
+};
+
+} // namespace WebKit
+
+#endif // Download_h
diff --git a/Source/WebKit2/WebProcess/Downloads/DownloadManager.cpp b/Source/WebKit2/WebProcess/Downloads/DownloadManager.cpp
new file mode 100644
index 0000000..e65883a
--- /dev/null
+++ b/Source/WebKit2/WebProcess/Downloads/DownloadManager.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2010 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 "DownloadManager.h"
+
+#include "Download.h"
+#include "WebProcess.h"
+#include <wtf/StdLibExtras.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+DownloadManager& DownloadManager::shared()
+{
+ DEFINE_STATIC_LOCAL(DownloadManager, downloadManager, ());
+ return downloadManager;
+}
+
+DownloadManager::DownloadManager()
+{
+}
+
+void DownloadManager::startDownload(uint64_t downloadID, WebPage* initiatingPage, const ResourceRequest& request)
+{
+ OwnPtr<Download> download = Download::create(downloadID, request);
+ download->start(initiatingPage);
+
+ ASSERT(!m_downloads.contains(downloadID));
+ m_downloads.set(downloadID, download.leakPtr());
+}
+
+void DownloadManager::convertHandleToDownload(uint64_t downloadID, WebPage* initiatingPage, ResourceHandle* handle, const ResourceRequest& request, const ResourceRequest& initialRequest, const ResourceResponse& response)
+{
+ OwnPtr<Download> download = Download::create(downloadID, request);
+
+ download->startWithHandle(initiatingPage, handle, initialRequest, response);
+ ASSERT(!m_downloads.contains(downloadID));
+ m_downloads.set(downloadID, download.leakPtr());
+}
+
+void DownloadManager::cancelDownload(uint64_t downloadID)
+{
+ Download* download = m_downloads.get(downloadID);
+ if (!download)
+ return;
+
+ download->cancel();
+}
+
+void DownloadManager::downloadFinished(Download* download)
+{
+ ASSERT(m_downloads.contains(download->downloadID()));
+ m_downloads.remove(download->downloadID());
+
+ delete download;
+
+ WebProcess::shared().shutdownIfPossible();
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/Downloads/DownloadManager.h b/Source/WebKit2/WebProcess/Downloads/DownloadManager.h
new file mode 100644
index 0000000..1f27b86
--- /dev/null
+++ b/Source/WebKit2/WebProcess/Downloads/DownloadManager.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2010 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 <wtf/HashMap.h>
+#include <wtf/Noncopyable.h>
+
+namespace WebCore {
+ class ResourceHandle;
+ class ResourceRequest;
+ class ResourceResponse;
+}
+
+namespace WebKit {
+
+class Download;
+class WebPage;
+
+class DownloadManager {
+ WTF_MAKE_NONCOPYABLE(DownloadManager);
+
+public:
+ static DownloadManager& shared();
+
+ void startDownload(uint64_t downloadID, WebPage* initiatingPage, const WebCore::ResourceRequest&);
+ void convertHandleToDownload(uint64_t downloadID, WebPage* initiatingPage, WebCore::ResourceHandle*, const WebCore::ResourceRequest&, const WebCore::ResourceRequest& initialRequest, const WebCore::ResourceResponse&);
+
+ void cancelDownload(uint64_t downloadID);
+
+ void downloadFinished(Download*);
+ bool isDownloading() const { return !m_downloads.isEmpty(); }
+
+private:
+ DownloadManager();
+
+ HashMap<uint64_t, Download*> m_downloads;
+};
+
+} // namespace WebKit
+
+#endif // DownloadManager_h
diff --git a/Source/WebKit2/WebProcess/Downloads/cf/DownloadCFNet.cpp b/Source/WebKit2/WebProcess/Downloads/cf/DownloadCFNet.cpp
new file mode 100644
index 0000000..08c381f
--- /dev/null
+++ b/Source/WebKit2/WebProcess/Downloads/cf/DownloadCFNet.cpp
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2010 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 "Download.h"
+
+#include "DataReference.h"
+#include "NotImplemented.h"
+
+#pragma warning(push, 0)
+#include <WebCore/LoaderRunLoopCF.h>
+#include <WebCore/ResourceError.h>
+#include <WebCore/ResourceHandle.h>
+#include <WebCore/ResourceResponse.h>
+#pragma warning(pop)
+
+using namespace WebCore;
+
+namespace WebKit {
+
+// CFURLDownload Callbacks ----------------------------------------------------------------
+static void didStartCallback(CFURLDownloadRef download, const void* clientInfo);
+static CFURLRequestRef willSendRequestCallback(CFURLDownloadRef download, CFURLRequestRef request, CFURLResponseRef redirectionResponse, const void* clientInfo);
+static void didReceiveAuthenticationChallengeCallback(CFURLDownloadRef download, CFURLAuthChallengeRef challenge, const void* clientInfo);
+static void didReceiveResponseCallback(CFURLDownloadRef download, CFURLResponseRef response, const void* clientInfo);
+static void willResumeWithResponseCallback(CFURLDownloadRef download, CFURLResponseRef response, UInt64 startingByte, const void* clientInfo);
+static void didReceiveDataCallback(CFURLDownloadRef download, CFIndex length, const void* clientInfo);
+static Boolean shouldDecodeDataOfMIMETypeCallback(CFURLDownloadRef download, CFStringRef encodingType, const void* clientInfo);
+static void decideDestinationWithSuggestedObjectNameCallback(CFURLDownloadRef download, CFStringRef objectName, const void* clientInfo);
+static void didCreateDestinationCallback(CFURLDownloadRef download, CFURLRef path, const void* clientInfo);
+static void didFinishCallback(CFURLDownloadRef download, const void* clientInfo);
+static void didFailCallback(CFURLDownloadRef download, CFErrorRef error, const void* clientInfo);
+
+void Download::start(WebPage* initiatingWebPage)
+{
+ ASSERT(!m_download);
+
+ CFURLRequestRef cfRequest = m_request.cfURLRequest();
+
+ CFURLDownloadClient client = {0, this, 0, 0, 0, didStartCallback, willSendRequestCallback, didReceiveAuthenticationChallengeCallback,
+ didReceiveResponseCallback, willResumeWithResponseCallback, didReceiveDataCallback, shouldDecodeDataOfMIMETypeCallback,
+ decideDestinationWithSuggestedObjectNameCallback, didCreateDestinationCallback, didFinishCallback, didFailCallback};
+ m_download.adoptCF(CFURLDownloadCreate(0, cfRequest, &client));
+
+ // FIXME: Allow this to be changed by the client.
+ CFURLDownloadSetDeletesUponFailure(m_download.get(), false);
+
+ CFURLDownloadScheduleWithCurrentMessageQueue(m_download.get());
+ CFURLDownloadScheduleDownloadWithRunLoop(m_download.get(), loaderRunLoop(), kCFRunLoopDefaultMode);
+}
+
+void Download::startWithHandle(WebPage* initiatingPage, ResourceHandle* handle, const ResourceRequest& initialRequest, const ResourceResponse& response)
+{
+ ASSERT(!m_download);
+
+ CFURLConnectionRef connection = handle->connection();
+ if (!connection)
+ return;
+
+ CFURLDownloadClient client = {0, this, 0, 0, 0, didStartCallback, willSendRequestCallback, didReceiveAuthenticationChallengeCallback,
+ didReceiveResponseCallback, willResumeWithResponseCallback, didReceiveDataCallback, shouldDecodeDataOfMIMETypeCallback,
+ decideDestinationWithSuggestedObjectNameCallback, didCreateDestinationCallback, didFinishCallback, didFailCallback};
+
+ m_download.adoptCF(CFURLDownloadCreateAndStartWithLoadingConnection(0, connection, initialRequest.cfURLRequest(), response.cfURLResponse(), &client));
+
+ // It is possible for CFURLDownloadCreateAndStartWithLoadingConnection() to fail if the passed in CFURLConnection is not in a "downloadable state"
+ // However, we should never hit that case
+ if (!m_download)
+ ASSERT_NOT_REACHED();
+
+ // The CFURLDownload either starts successfully and retains the CFURLConnection,
+ // or it fails to creating and we have a now-useless connection with a dangling ref.
+ // Either way, we need to release the connection to balance out ref counts
+ handle->releaseConnectionForDownload();
+ CFRelease(connection);
+}
+
+void Download::cancel()
+{
+ notImplemented();
+}
+
+void Download::platformInvalidate()
+{
+ m_download = nullptr;
+}
+
+// CFURLDownload Callbacks ----------------------------------------------------------------
+static Download* downloadFromClientInfo(const void* clientInfo)
+{
+ return reinterpret_cast<Download*>(const_cast<void*>(clientInfo));
+}
+
+void didStartCallback(CFURLDownloadRef, const void* clientInfo)
+{
+ downloadFromClientInfo(clientInfo)->didStart();
+}
+
+CFURLRequestRef willSendRequestCallback(CFURLDownloadRef, CFURLRequestRef request, CFURLResponseRef redirectionResponse, const void* clientInfo)
+{
+ // CFNetwork requires us to return a retained request.
+ CFRetain(request);
+ return request;
+}
+
+void didReceiveAuthenticationChallengeCallback(CFURLDownloadRef, CFURLAuthChallengeRef challenge, const void* clientInfo)
+{
+ // FIXME: implement.
+ notImplemented();
+}
+
+void didReceiveResponseCallback(CFURLDownloadRef, CFURLResponseRef response, const void* clientInfo)
+{
+ downloadFromClientInfo(clientInfo)->didReceiveResponse(ResourceResponse(response));
+}
+
+void willResumeWithResponseCallback(CFURLDownloadRef, CFURLResponseRef response, UInt64 startingByte, const void* clientInfo)
+{
+ // FIXME: implement.
+ notImplemented();
+}
+
+void didReceiveDataCallback(CFURLDownloadRef, CFIndex length, const void* clientInfo)
+{
+ downloadFromClientInfo(clientInfo)->didReceiveData(length);
+}
+
+Boolean shouldDecodeDataOfMIMETypeCallback(CFURLDownloadRef, CFStringRef encodingType, const void* clientInfo)
+{
+ return downloadFromClientInfo(clientInfo)->shouldDecodeSourceDataOfMIMEType(encodingType);
+}
+
+void decideDestinationWithSuggestedObjectNameCallback(CFURLDownloadRef cfURLDownloadRef, CFStringRef objectName, const void* clientInfo)
+{
+ Download* download = downloadFromClientInfo(clientInfo);
+ bool allowOverwrite;
+ String destination = download->decideDestinationWithSuggestedFilename(objectName, allowOverwrite);
+ if (destination.isNull())
+ return;
+
+ RetainPtr<CFStringRef> cfPath(AdoptCF, CFStringCreateWithCharactersNoCopy(0, reinterpret_cast<const UniChar*>(destination.characters()), destination.length(), kCFAllocatorNull));
+ RetainPtr<CFURLRef> pathURL(AdoptCF, CFURLCreateWithFileSystemPath(0, cfPath.get(), kCFURLWindowsPathStyle, false));
+ CFURLDownloadSetDestination(cfURLDownloadRef, pathURL.get(), allowOverwrite);
+}
+
+void didCreateDestinationCallback(CFURLDownloadRef, CFURLRef url, const void* clientInfo)
+{
+ RetainPtr<CFStringRef> path(AdoptCF, CFURLCopyFileSystemPath(url, kCFURLWindowsPathStyle));
+ String result(path.get());
+ downloadFromClientInfo(clientInfo)->didCreateDestination(result);
+}
+
+void didFinishCallback(CFURLDownloadRef, const void* clientInfo)
+{
+ downloadFromClientInfo(clientInfo)->didFinish();
+}
+
+void didFailCallback(CFURLDownloadRef, CFErrorRef error, const void* clientInfo)
+{
+ CoreIPC::DataReference dataReference(0, 0);
+ downloadFromClientInfo(clientInfo)->didFail(ResourceError(error), dataReference);
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/Downloads/curl/DownloadCurl.cpp b/Source/WebKit2/WebProcess/Downloads/curl/DownloadCurl.cpp
new file mode 100644
index 0000000..25ed351
--- /dev/null
+++ b/Source/WebKit2/WebProcess/Downloads/curl/DownloadCurl.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Brent Fulgham <bfulgham@webkit.org>
+ *
+ * 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 "Download.h"
+
+#include "NotImplemented.h"
+
+using namespace WebCore;
+
+namespace WebKit {
+
+void Download::start(WebPage* initiatingWebPage)
+{
+ notImplemented();
+}
+
+void Download::startWithHandle(WebPage* initiatingPage, ResourceHandle*, const ResourceRequest& initialRequest, const ResourceResponse&)
+{
+ notImplemented();
+}
+
+void Download::cancel()
+{
+ notImplemented();
+}
+
+void Download::platformInvalidate()
+{
+ notImplemented();
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/Downloads/mac/DownloadMac.mm b/Source/WebKit2/WebProcess/Downloads/mac/DownloadMac.mm
new file mode 100644
index 0000000..6839020
--- /dev/null
+++ b/Source/WebKit2/WebProcess/Downloads/mac/DownloadMac.mm
@@ -0,0 +1,287 @@
+/*
+ * Copyright (C) 2010 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 "Download.h"
+
+#include <WebCore/BackForwardController.h>
+#include <WebCore/HistoryItem.h>
+#include <WebCore/Page.h>
+#include <WebCore/ResourceHandle.h>
+#include <WebCore/ResourceResponse.h>
+#include "DataReference.h"
+#include "NotImplemented.h"
+#include "WebPage.h"
+
+@interface NSURLDownload (WebNSURLDownloadDetails)
++(id)_downloadWithLoadingConnection:(NSURLConnection *)connection
+ request:(NSURLRequest *)request
+ response:(NSURLResponse *)r
+ delegate:(id)delegate
+ proxy:(id)proxy;
+- (void)_setOriginatingURL:(NSURL *)originatingURL;
+@end
+
+@interface WKDownloadAsDelegate : NSObject <NSURLConnectionDelegate> {
+ WebKit::Download* _download;
+}
+- (id)initWithDownload:(WebKit::Download*)download;
+- (void)invalidate;
+@end
+
+using namespace WebCore;
+
+namespace WebKit {
+
+static KURL originatingURLFromBackForwardList(WebPage *webPage)
+{
+ if (!webPage)
+ return KURL();
+
+ Page* page = webPage->corePage();
+ if (!page)
+ return KURL();
+
+ KURL originalURL;
+ int backCount = page->backForward()->backCount();
+ for (int backIndex = 0; backIndex <= backCount; backIndex++) {
+ // FIXME: At one point we had code here to check a "was user gesture" flag.
+ // Do we need to restore that logic?
+ HistoryItem* historyItem = page->backForward()->itemAtIndex(-backIndex);
+ if (!historyItem)
+ continue;
+
+ originalURL = historyItem->originalURL();
+ if (!originalURL.isNull())
+ return originalURL;
+ }
+
+ return KURL();
+}
+
+static void setOriginalURLForDownload(WebPage *webPage, NSURLDownload *download, const ResourceRequest& initialRequest)
+{
+ KURL originalURL;
+
+ // If there was no referrer, don't traverse the back/forward history
+ // since this download was initiated directly. <rdar://problem/5294691>
+ if (!initialRequest.httpReferrer().isNull()) {
+ // find the first item in the history that was originated by the user
+ originalURL = originatingURLFromBackForwardList(webPage);
+ }
+
+ if (originalURL.isNull())
+ originalURL = initialRequest.url();
+
+ NSURL *originalNSURL = originalURL;
+
+ NSString *scheme = [originalNSURL scheme];
+ NSString *host = [originalNSURL host];
+ if (scheme && host && [scheme length] && [host length]) {
+ NSNumber *port = [originalNSURL port];
+ if (port && [port intValue] < 0)
+ port = nil;
+ RetainPtr<NSString> hostOnlyURLString;
+ if (port)
+ hostOnlyURLString.adoptNS([[NSString alloc] initWithFormat:@"%@://%@:%d", scheme, host, [port intValue]]);
+ else
+ hostOnlyURLString.adoptNS([[NSString alloc] initWithFormat:@"%@://%@", scheme, host]);
+
+ RetainPtr<NSURL> hostOnlyURL = [[NSURL alloc] initWithString:hostOnlyURLString.get()];
+
+ ASSERT([download respondsToSelector:@selector(_setOriginatingURL:)]);
+ [download _setOriginatingURL:hostOnlyURL.get()];
+ }
+}
+
+void Download::start(WebPage* initiatingPage)
+{
+ ASSERT(!m_nsURLDownload);
+ ASSERT(!m_delegate);
+
+ m_delegate.adoptNS([[WKDownloadAsDelegate alloc] initWithDownload:this]);
+ m_nsURLDownload.adoptNS([[NSURLDownload alloc] initWithRequest:m_request.nsURLRequest() delegate:m_delegate.get()]);
+
+ // FIXME: Allow this to be changed by the client.
+ [m_nsURLDownload.get() setDeletesFileUponFailure:NO];
+
+ setOriginalURLForDownload(initiatingPage, m_nsURLDownload.get(), m_request);
+}
+
+void Download::startWithHandle(WebPage* initiatingPage, ResourceHandle* handle, const ResourceRequest& initialRequest, const ResourceResponse& response)
+{
+ ASSERT(!m_nsURLDownload);
+ ASSERT(!m_delegate);
+
+ id proxy = handle->releaseProxy();
+ ASSERT(proxy);
+
+ m_delegate.adoptNS([[WKDownloadAsDelegate alloc] initWithDownload:this]);
+ m_nsURLDownload = [NSURLDownload _downloadWithLoadingConnection:handle->connection()
+ request:m_request.nsURLRequest()
+ response:response.nsURLResponse()
+ delegate:m_delegate.get()
+ proxy:proxy];
+
+ // FIXME: Allow this to be changed by the client.
+ [m_nsURLDownload.get() setDeletesFileUponFailure:NO];
+
+ setOriginalURLForDownload(initiatingPage, m_nsURLDownload.get(), initialRequest);
+}
+
+void Download::cancel()
+{
+ [m_nsURLDownload.get() cancel];
+
+ RetainPtr<NSData> resumeData = [m_nsURLDownload.get() resumeData];
+ didCancel(CoreIPC::DataReference(reinterpret_cast<const uint8_t*>([resumeData.get() bytes]), [resumeData.get() length]));
+}
+
+void Download::platformInvalidate()
+{
+ ASSERT(m_nsURLDownload);
+ ASSERT(m_delegate);
+
+ [m_delegate.get() invalidate];
+ m_delegate = nullptr;
+ m_nsURLDownload = nullptr;
+}
+
+} // namespace WebKit
+
+@implementation WKDownloadAsDelegate
+
+- (id)initWithDownload:(WebKit::Download*)download
+{
+ self = [super init];
+ if (!self)
+ return nil;
+
+ _download = download;
+ return self;
+}
+
+- (void)invalidate
+{
+ _download = 0;
+}
+
+- (void)downloadDidBegin:(NSURLDownload *)download
+{
+ if (_download)
+ _download->didStart();
+}
+
+- (NSURLRequest *)download:(NSURLDownload *)download willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse
+{
+ return request;
+}
+
+- (BOOL)download:(NSURLDownload *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
+{
+ // FIXME: Implement.
+ notImplemented();
+ return NO;
+}
+
+- (void)download:(NSURLDownload *)download didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
+{
+ // FIXME: Implement.
+ notImplemented();
+}
+
+- (void)download:(NSURLDownload *)download didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
+{
+ // FIXME: Implement.
+ notImplemented();
+}
+
+- (BOOL)downloadShouldUseCredentialStorage:(NSURLDownload *)download
+{
+ // FIXME: Implement.
+ notImplemented();
+ return YES;
+}
+
+- (void)download:(NSURLDownload *)download didReceiveResponse:(NSURLResponse *)response
+{
+ if (_download)
+ _download->didReceiveResponse(response);
+}
+
+- (void)download:(NSURLDownload *)download willResumeWithResponse:(NSURLResponse *)response fromByte:(long long)startingByte
+{
+ // FIXME: Implement.
+ notImplemented();
+}
+
+- (void)download:(NSURLDownload *)download didReceiveDataOfLength:(NSUInteger)length
+{
+ if (_download)
+ _download->didReceiveData(length);
+}
+
+- (BOOL)download:(NSURLDownload *)download shouldDecodeSourceDataOfMIMEType:(NSString *)encodingType
+{
+ if (_download)
+ return _download->shouldDecodeSourceDataOfMIMEType(encodingType);
+
+ return YES;
+}
+
+- (void)download:(NSURLDownload *)download decideDestinationWithSuggestedFilename:(NSString *)filename
+{
+ String destination;
+ bool allowOverwrite;
+ if (_download)
+ destination = _download->decideDestinationWithSuggestedFilename(filename, allowOverwrite);
+
+ if (!destination.isNull())
+ [download setDestination:destination allowOverwrite:allowOverwrite];
+}
+
+- (void)download:(NSURLDownload *)download didCreateDestination:(NSString *)path
+{
+ if (_download)
+ _download->didCreateDestination(path);
+}
+
+- (void)downloadDidFinish:(NSURLDownload *)download
+{
+ if (_download)
+ _download->didFinish();
+}
+
+- (void)download:(NSURLDownload *)download didFailWithError:(NSError *)error
+{
+ if (!_download)
+ return;
+
+ RetainPtr<NSData> resumeData = [download resumeData];
+ CoreIPC::DataReference dataReference(reinterpret_cast<const uint8_t*>([resumeData.get() bytes]), [resumeData.get() length]);
+
+ _download->didFail(error, dataReference);
+}
+
+@end
diff --git a/Source/WebKit2/WebProcess/Downloads/qt/DownloadQt.cpp b/Source/WebKit2/WebProcess/Downloads/qt/DownloadQt.cpp
new file mode 100644
index 0000000..34fd60e
--- /dev/null
+++ b/Source/WebKit2/WebProcess/Downloads/qt/DownloadQt.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2010 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 "Download.h"
+
+#include "NotImplemented.h"
+
+using namespace WebCore;
+
+namespace WebKit {
+
+void Download::start(WebPage* initiatingWebPage)
+{
+ notImplemented();
+}
+
+void Download::startWithHandle(WebPage* initiatingPage, ResourceHandle*, const ResourceRequest& initialRequest, const ResourceResponse&)
+{
+ notImplemented();
+}
+
+void Download::cancel()
+{
+ notImplemented();
+}
+
+void Download::platformInvalidate()
+{
+ notImplemented();
+}
+
+} // namespace WebKit