diff options
author | Steve Block <steveblock@google.com> | 2011-05-25 19:08:45 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2011-06-08 13:51:31 +0100 |
commit | 2bde8e466a4451c7319e3a072d118917957d6554 (patch) | |
tree | 28f4a1b869a513e565c7760d0e6a06e7cf1fe95a /Source/WebKit2/WebProcess/Downloads/cfnet/DownloadCFNet.cpp | |
parent | 6939c99b71d9372d14a0c74a772108052e8c48c8 (diff) | |
download | external_webkit-2bde8e466a4451c7319e3a072d118917957d6554.zip external_webkit-2bde8e466a4451c7319e3a072d118917957d6554.tar.gz external_webkit-2bde8e466a4451c7319e3a072d118917957d6554.tar.bz2 |
Merge WebKit at r82507: Initial merge by git
Change-Id: I60ce9d780725b58b45e54165733a8ffee23b683e
Diffstat (limited to 'Source/WebKit2/WebProcess/Downloads/cfnet/DownloadCFNet.cpp')
-rw-r--r-- | Source/WebKit2/WebProcess/Downloads/cfnet/DownloadCFNet.cpp | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/Source/WebKit2/WebProcess/Downloads/cfnet/DownloadCFNet.cpp b/Source/WebKit2/WebProcess/Downloads/cfnet/DownloadCFNet.cpp new file mode 100644 index 0000000..170c6aa --- /dev/null +++ b/Source/WebKit2/WebProcess/Downloads/cfnet/DownloadCFNet.cpp @@ -0,0 +1,226 @@ +/* + * Copyright (C) 2010, 2011 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 "DataReference.h" + +#pragma warning(push, 0) +#include <WebCore/DownloadBundle.h> +#include <WebCore/LoaderRunLoopCF.h> +#include <WebCore/NotImplemented.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*) +{ + 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); + + CFURLDownloadStart(m_download.get()); +} + +void Download::startWithHandle(WebPage*, 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() +{ + ASSERT(m_download); + if (!m_download) + return; + + CFURLDownloadSetDeletesUponFailure(m_download.get(), false); + CFURLDownloadCancel(m_download.get()); + + RetainPtr<CFDataRef> resumeData(AdoptCF, CFURLDownloadCopyResumeData(m_download.get())); + if (resumeData) + DownloadBundle::appendResumeData(resumeData.get(), m_bundlePath); + + didCancel(CoreIPC::DataReference()); +} + +void Download::platformInvalidate() +{ + m_download = nullptr; +} + +void Download::didDecideDestination(const String& destination, bool allowOverwrite) +{ + ASSERT(!destination.isEmpty()); + if (destination.isEmpty()) + return; + + m_allowOverwrite = allowOverwrite; + m_destination = destination; + m_bundlePath = destination + DownloadBundle::fileExtension(); + + RetainPtr<CFStringRef> bundlePath(AdoptCF, CFStringCreateWithCharactersNoCopy(0, reinterpret_cast<const UniChar*>(m_bundlePath.characters()), m_bundlePath.length(), kCFAllocatorNull)); + RetainPtr<CFURLRef> bundlePathURL(AdoptCF, CFURLCreateWithFileSystemPath(0, bundlePath.get(), kCFURLWindowsPathStyle, false)); + CFURLDownloadSetDestination(m_download.get(), bundlePathURL.get(), allowOverwrite); +} + +// 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, CFStringRef objectName, const void* clientInfo) +{ + Download* download = downloadFromClientInfo(clientInfo); + bool allowOverwrite; + download->decideDestinationWithSuggestedFilename(objectName, allowOverwrite); +} + +void didCreateDestinationCallback(CFURLDownloadRef, CFURLRef, const void* clientInfo) +{ + // The concept of the ".download bundle" is internal to the Download, so we try to hide its + // existence by reporting the final destination was created, when in reality the bundle was created. + + Download* download = downloadFromClientInfo(clientInfo); + download->didCreateDestination(download->destination()); +} + +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); +} + +void Download::receivedCredential(const AuthenticationChallenge& authenticationChallenge, const Credential& credential) +{ + notImplemented(); +} + +void Download::receivedRequestToContinueWithoutCredential(const AuthenticationChallenge& authenticationChallenge) +{ + notImplemented(); +} + +void Download::receivedCancellation(const AuthenticationChallenge& authenticationChallenge) +{ + notImplemented(); +} + +} // namespace WebKit |