diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebKit2/NetworkProcess/Downloads | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebKit2/NetworkProcess/Downloads')
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 |