1635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project/* 2635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * Copyright (C) 2007 Apple Inc. All rights reserved. 3635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * 4635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * Redistribution and use in source and binary forms, with or without 5635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * modification, are permitted provided that the following conditions 6635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * are met: 7635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 8635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * notice, this list of conditions and the following disclaimer. 9635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 10635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 11635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * documentation and/or other materials provided with the distribution. 12635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * 13635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 14635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 17635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project */ 25635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 26635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "config.h" 27635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "WebKitDLL.h" 28635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "WebDownload.h" 29635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 30635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "DefaultDownloadDelegate.h" 31635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "MarshallingHelpers.h" 32635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "WebError.h" 33635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "WebKit.h" 34635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "WebKitLogging.h" 35635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "WebMutableURLRequest.h" 36635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "WebURLAuthenticationChallenge.h" 37635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "WebURLCredential.h" 38635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "WebURLResponse.h" 39635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 40635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include <wtf/platform.h> 41dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include <wtf/text/CString.h> 42635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 43635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include <io.h> 44635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include <sys/stat.h> 45635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include <sys/types.h> 46635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 47635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include <WebCore/AuthenticationCF.h> 48635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include <WebCore/BString.h> 49231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include <WebCore/CredentialStorage.h> 502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include <WebCore/DownloadBundle.h> 51643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include <WebCore/LoaderRunLoopCF.h> 52635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include <WebCore/ResourceError.h> 53635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include <WebCore/ResourceHandle.h> 54635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include <WebCore/ResourceRequest.h> 55635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include <WebCore/ResourceResponse.h> 56635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include <wtf/CurrentTime.h> 57635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 58635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectusing namespace WebCore; 59635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 60635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project// CFURLDownload Callbacks ---------------------------------------------------------------- 61635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic void didStartCallback(CFURLDownloadRef download, const void *clientInfo); 62635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic CFURLRequestRef willSendRequestCallback(CFURLDownloadRef download, CFURLRequestRef request, CFURLResponseRef redirectionResponse, const void *clientInfo); 63635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic void didReceiveAuthenticationChallengeCallback(CFURLDownloadRef download, CFURLAuthChallengeRef challenge, const void *clientInfo); 64635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic void didReceiveResponseCallback(CFURLDownloadRef download, CFURLResponseRef response, const void *clientInfo); 65635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic void willResumeWithResponseCallback(CFURLDownloadRef download, CFURLResponseRef response, UInt64 startingByte, const void *clientInfo); 66635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic void didReceiveDataCallback(CFURLDownloadRef download, CFIndex length, const void *clientInfo); 67635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic Boolean shouldDecodeDataOfMIMETypeCallback(CFURLDownloadRef download, CFStringRef encodingType, const void *clientInfo); 68635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic void decideDestinationWithSuggestedObjectNameCallback(CFURLDownloadRef download, CFStringRef objectName, const void *clientInfo); 69635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic void didCreateDestinationCallback(CFURLDownloadRef download, CFURLRef path, const void *clientInfo); 70635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic void didFinishCallback(CFURLDownloadRef download, const void *clientInfo); 71635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic void didFailCallback(CFURLDownloadRef download, CFErrorRef error, const void *clientInfo); 72635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 73635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid WebDownload::init(ResourceHandle* handle, const ResourceRequest& request, const ResourceResponse& response, IWebDownloadDelegate* delegate) 74635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 75635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_delegate = delegate ? delegate : DefaultDownloadDelegate::sharedInstance(); 76635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CFURLConnectionRef connection = handle->connection(); 77635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!connection) { 78635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project LOG_ERROR("WebDownload::WebDownload(ResourceHandle*,...) called with an inactive ResourceHandle"); 79635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return; 80635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 81635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 82635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CFURLDownloadClient client = {0, this, 0, 0, 0, didStartCallback, willSendRequestCallback, didReceiveAuthenticationChallengeCallback, 83635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project didReceiveResponseCallback, willResumeWithResponseCallback, didReceiveDataCallback, shouldDecodeDataOfMIMETypeCallback, 84635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project decideDestinationWithSuggestedObjectNameCallback, didCreateDestinationCallback, didFinishCallback, didFailCallback}; 85635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 86635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_request.adoptRef(WebMutableURLRequest::createInstance(request)); 87635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_download.adoptCF(CFURLDownloadCreateAndStartWithLoadingConnection(0, connection, request.cfURLRequest(), response.cfURLResponse(), &client)); 88635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 89635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // It is possible for CFURLDownloadCreateAndStartWithLoadingConnection() to fail if the passed in CFURLConnection is not in a "downloadable state" 90635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // However, we should never hit that case 91635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!m_download) { 92635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT_NOT_REACHED(); 93635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project LOG_ERROR("WebDownload - Failed to create WebDownload from existing connection (%s)", request.url().string().utf8().data()); 94635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } else 95635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project LOG(Download, "WebDownload - Created WebDownload %p from existing connection (%s)", this, request.url().string().utf8().data()); 96635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 97635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // The CFURLDownload either starts successfully and retains the CFURLConnection, 98635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // or it fails to creating and we have a now-useless connection with a dangling ref. 99635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Either way, we need to release the connection to balance out ref counts 100635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project handle->releaseConnectionForDownload(); 101635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CFRelease(connection); 102635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 103635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 104635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid WebDownload::init(const KURL& url, IWebDownloadDelegate* delegate) 105635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 106635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_delegate = delegate ? delegate : DefaultDownloadDelegate::sharedInstance(); 107635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project LOG_ERROR("Delegate is %p", m_delegate.get()); 108635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 109635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ResourceRequest request(url); 110635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CFURLRequestRef cfRequest = request.cfURLRequest(); 111635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 112635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CFURLDownloadClient client = {0, this, 0, 0, 0, didStartCallback, willSendRequestCallback, didReceiveAuthenticationChallengeCallback, 113635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project didReceiveResponseCallback, willResumeWithResponseCallback, didReceiveDataCallback, shouldDecodeDataOfMIMETypeCallback, 114635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project decideDestinationWithSuggestedObjectNameCallback, didCreateDestinationCallback, didFinishCallback, didFailCallback}; 115635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_request.adoptRef(WebMutableURLRequest::createInstance(request)); 116635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_download.adoptCF(CFURLDownloadCreate(0, cfRequest, &client)); 117635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 118635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CFURLDownloadScheduleWithCurrentMessageQueue(m_download.get()); 119643ca7872b450ea4efacab6188849e5aac2ba161Steve Block CFURLDownloadScheduleDownloadWithRunLoop(m_download.get(), loaderRunLoop(), kCFRunLoopDefaultMode); 120635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 121635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project LOG(Download, "WebDownload - Initialized download of url %s in WebDownload %p", url.string().utf8().data(), this); 122635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 123635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 124635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project// IWebDownload ------------------------------------------------------------------- 125635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 126635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectHRESULT STDMETHODCALLTYPE WebDownload::initWithRequest( 127635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project /* [in] */ IWebURLRequest* request, 128635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project /* [in] */ IWebDownloadDelegate* delegate) 129635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 130635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project COMPtr<WebMutableURLRequest> webRequest; 131635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!request || FAILED(request->QueryInterface(&webRequest))) { 132635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project LOG(Download, "WebDownload - initWithRequest failed - not a WebMutableURLRequest"); 133635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return E_FAIL; 134635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 135635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 136635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!delegate) 137635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return E_FAIL; 138635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_delegate = delegate; 139635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project LOG(Download, "Delegate is %p", m_delegate.get()); 140635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 141635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project RetainPtr<CFURLRequestRef> cfRequest = webRequest->resourceRequest().cfURLRequest(); 142635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 143635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CFURLDownloadClient client = {0, this, 0, 0, 0, didStartCallback, willSendRequestCallback, didReceiveAuthenticationChallengeCallback, 144635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project didReceiveResponseCallback, willResumeWithResponseCallback, didReceiveDataCallback, shouldDecodeDataOfMIMETypeCallback, 145635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project decideDestinationWithSuggestedObjectNameCallback, didCreateDestinationCallback, didFinishCallback, didFailCallback}; 146635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_request.adoptRef(WebMutableURLRequest::createInstance(webRequest.get())); 147635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_download.adoptCF(CFURLDownloadCreate(0, cfRequest.get(), &client)); 148635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 149635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // If for some reason the download failed to create, 150635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // we have particular cleanup to do 151635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!m_download) { 152635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_request = 0; 153635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return E_FAIL; 154635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 155635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 156635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CFURLDownloadScheduleWithCurrentMessageQueue(m_download.get()); 157643ca7872b450ea4efacab6188849e5aac2ba161Steve Block CFURLDownloadScheduleDownloadWithRunLoop(m_download.get(), loaderRunLoop(), kCFRunLoopDefaultMode); 158635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 159635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project LOG(Download, "WebDownload - initWithRequest complete, started download of url %s", webRequest->resourceRequest().url().string().utf8().data()); 160635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return S_OK; 161635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 162635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 163635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectHRESULT STDMETHODCALLTYPE WebDownload::initToResumeWithBundle( 164635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project /* [in] */ BSTR bundlePath, 165635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project /* [in] */ IWebDownloadDelegate* delegate) 166635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 167635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project LOG(Download, "Attempting resume of download bundle %s", String(bundlePath, SysStringLen(bundlePath)).ascii().data()); 168635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 1692fc2651226baac27029e38c9d6ef883fa32084dbSteve Block RetainPtr<CFDataRef> resumeData(AdoptCF, DownloadBundle::extractResumeData(String(bundlePath, SysStringLen(bundlePath)))); 1702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 171635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!resumeData) 172635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return E_FAIL; 173635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 174635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!delegate) 175635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return E_FAIL; 176635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_delegate = delegate; 177635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project LOG(Download, "Delegate is %p", m_delegate.get()); 178635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 179635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CFURLDownloadClient client = {0, this, 0, 0, 0, didStartCallback, willSendRequestCallback, didReceiveAuthenticationChallengeCallback, 180635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project didReceiveResponseCallback, willResumeWithResponseCallback, didReceiveDataCallback, shouldDecodeDataOfMIMETypeCallback, 181635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project decideDestinationWithSuggestedObjectNameCallback, didCreateDestinationCallback, didFinishCallback, didFailCallback}; 182635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 183635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project RetainPtr<CFURLRef> pathURL(AdoptCF, MarshallingHelpers::PathStringToFileCFURLRef(String(bundlePath, SysStringLen(bundlePath)))); 184635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(pathURL); 185635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 186635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_download.adoptCF(CFURLDownloadCreateWithResumeData(0, resumeData.get(), pathURL.get(), &client)); 187635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 188635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!m_download) { 189635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project LOG(Download, "Failed to create CFURLDownloadRef for resume"); 190635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return E_FAIL; 191635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 192635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 193635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_bundlePath = String(bundlePath, SysStringLen(bundlePath)); 194635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Attempt to remove the ".download" extension from the bundle for the final file destination 195635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Failing that, we clear m_destination and will ask the delegate later once the download starts 1962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (m_bundlePath.endsWith(DownloadBundle::fileExtension(), false)) { 197231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_destination = m_bundlePath.threadsafeCopy(); 1982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block m_destination.truncate(m_destination.length() - DownloadBundle::fileExtension().length()); 199635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } else 200635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_destination = String(); 201635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 202635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CFURLDownloadScheduleWithCurrentMessageQueue(m_download.get()); 203643ca7872b450ea4efacab6188849e5aac2ba161Steve Block CFURLDownloadScheduleDownloadWithRunLoop(m_download.get(), loaderRunLoop(), kCFRunLoopDefaultMode); 204635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 205635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project LOG(Download, "WebDownload - initWithRequest complete, resumed download of bundle %s", String(bundlePath, SysStringLen(bundlePath)).ascii().data()); 206635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return S_OK; 207635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 208635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 209635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectHRESULT STDMETHODCALLTYPE WebDownload::start() 210635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 211635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project LOG(Download, "WebDownload - Starting download (%p)", this); 212635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!m_download) 213635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return E_FAIL; 214635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 215635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CFURLDownloadStart(m_download.get()); 216635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // FIXME: 4950477 - CFURLDownload neglects to make the didStart() client call upon starting the download. 217635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // This is a somewhat critical call, so we'll fake it for now! 218635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project didStart(); 219635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 220635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return S_OK; 221635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 222635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 223635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectHRESULT STDMETHODCALLTYPE WebDownload::cancel() 224635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 225635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project LOG(Download, "WebDownload - Cancelling download (%p)", this); 226635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!m_download) 227635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return E_FAIL; 228635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 229635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CFURLDownloadCancel(m_download.get()); 230635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_download = 0; 231635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return S_OK; 232635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 233635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 234635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectHRESULT STDMETHODCALLTYPE WebDownload::cancelForResume() 235635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 236635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project LOG(Download, "WebDownload - Cancelling download (%p), writing resume information to file if possible", this); 237635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(m_download); 238635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!m_download) 239635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return E_FAIL; 240635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 241635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project HRESULT hr = S_OK; 242635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project RetainPtr<CFDataRef> resumeData; 243635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (m_destination.isEmpty()) { 244635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CFURLDownloadCancel(m_download.get()); 245635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project goto exit; 246635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 247635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 248635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CFURLDownloadSetDeletesUponFailure(m_download.get(), false); 249635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CFURLDownloadCancel(m_download.get()); 250635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 2512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block resumeData.adoptCF(CFURLDownloadCopyResumeData(m_download.get())); 252635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!resumeData) { 253635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project LOG(Download, "WebDownload - Unable to create resume data for download (%p)", this); 254635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project goto exit; 255635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 256635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 2572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block DownloadBundle::appendResumeData(resumeData.get(), m_bundlePath); 2582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 259635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectexit: 260635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_download = 0; 261635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return hr; 262635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 263635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 264635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectHRESULT STDMETHODCALLTYPE WebDownload::deletesFileUponFailure( 265635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project /* [out, retval] */ BOOL* result) 266635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 267635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!m_download) 268635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return E_FAIL; 269635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *result = CFURLDownloadDeletesUponFailure(m_download.get()); 270635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return S_OK; 271635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 272635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 273635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectHRESULT STDMETHODCALLTYPE WebDownload::setDeletesFileUponFailure( 274635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project /* [in] */ BOOL deletesFileUponFailure) 275635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 276635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!m_download) 277635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return E_FAIL; 278635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CFURLDownloadSetDeletesUponFailure(m_download.get(), !!deletesFileUponFailure); 279635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return S_OK; 280635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 281635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 282635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectHRESULT STDMETHODCALLTYPE WebDownload::setDestination( 283635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project /* [in] */ BSTR path, 284635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project /* [in] */ BOOL allowOverwrite) 285635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 286635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!m_download) 287635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return E_FAIL; 288635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 289635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_destination = String(path, SysStringLen(path)); 2902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block m_bundlePath = m_destination + DownloadBundle::fileExtension(); 291635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 292635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CFURLRef pathURL = MarshallingHelpers::PathStringToFileCFURLRef(m_bundlePath); 293635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CFURLDownloadSetDestination(m_download.get(), pathURL, !!allowOverwrite); 294635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CFRelease(pathURL); 295635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 296635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project LOG(Download, "WebDownload - Set destination to %s", m_bundlePath.ascii().data()); 297635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 298635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return S_OK; 299635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 300635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 301635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project// IWebURLAuthenticationChallengeSender ------------------------------------------------------------------- 302635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 303635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectHRESULT STDMETHODCALLTYPE WebDownload::cancelAuthenticationChallenge( 304635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project /* [in] */ IWebURLAuthenticationChallenge*) 305635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 306635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (m_download) { 307635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CFURLDownloadCancel(m_download.get()); 308635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_download = 0; 309635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 310635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 311635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // FIXME: Do we need a URL or description for this error code? 312635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ResourceError error(String(WebURLErrorDomain), WebURLErrorUserCancelledAuthentication, "", ""); 313635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project COMPtr<WebError> webError(AdoptCOM, WebError::createInstance(error)); 314635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_delegate->didFailWithError(this, webError.get()); 315635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 316635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return S_OK; 317635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 318635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 319635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectHRESULT STDMETHODCALLTYPE WebDownload::continueWithoutCredentialForAuthenticationChallenge( 320635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project /* [in] */ IWebURLAuthenticationChallenge* challenge) 321635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 322635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project COMPtr<WebURLAuthenticationChallenge> webChallenge(Query, challenge); 323635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!webChallenge) 324635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return E_NOINTERFACE; 325635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 326635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (m_download) 327635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CFURLDownloadUseCredential(m_download.get(), 0, webChallenge->authenticationChallenge().cfURLAuthChallengeRef()); 328635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return S_OK; 329635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 330635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 331635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectHRESULT STDMETHODCALLTYPE WebDownload::useCredential( 332635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project /* [in] */ IWebURLCredential* credential, 333635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project /* [in] */ IWebURLAuthenticationChallenge* challenge) 334635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 335635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project COMPtr<WebURLAuthenticationChallenge> webChallenge(Query, challenge); 336635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!webChallenge) 337635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return E_NOINTERFACE; 338635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 339635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project COMPtr<WebURLCredential> webCredential(Query, credential); 340635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!webCredential) 341635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return E_NOINTERFACE; 342635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 343635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project RetainPtr<CFURLCredentialRef> cfCredential(AdoptCF, createCF(webCredential->credential())); 344635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 345635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (m_download) 346635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CFURLDownloadUseCredential(m_download.get(), cfCredential.get(), webChallenge->authenticationChallenge().cfURLAuthChallengeRef()); 347635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return S_OK; 348635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 349635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 350635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project// CFURLDownload Callbacks ------------------------------------------------------------------- 351635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid WebDownload::didStart() 352635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 353635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#ifndef NDEBUG 354635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_startTime = m_dataTime = currentTime(); 355635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_received = 0; 356635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project LOG(Download, "DOWNLOAD - Started %p at %.3f seconds", this, m_startTime); 357635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif 358635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (FAILED(m_delegate->didBegin(this))) 359635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project LOG_ERROR("DownloadDelegate->didBegin failed"); 360635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 361635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 362635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectCFURLRequestRef WebDownload::willSendRequest(CFURLRequestRef request, CFURLResponseRef response) 363635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 364635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project COMPtr<WebMutableURLRequest> webRequest(AdoptCOM, WebMutableURLRequest::createInstance(ResourceRequest(request))); 365635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project COMPtr<WebURLResponse> webResponse(AdoptCOM, WebURLResponse::createInstance(ResourceResponse(response))); 366635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project COMPtr<IWebMutableURLRequest> finalRequest; 367635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 368635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (FAILED(m_delegate->willSendRequest(this, webRequest.get(), webResponse.get(), &finalRequest))) 369635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project LOG_ERROR("DownloadDelegate->willSendRequest failed"); 370635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 371635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!finalRequest) 372635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return 0; 373635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 374635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project COMPtr<WebMutableURLRequest> finalWebRequest(AdoptCOM, WebMutableURLRequest::createInstance(finalRequest.get())); 375635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_request = finalWebRequest.get(); 376635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CFURLRequestRef result = finalWebRequest->resourceRequest().cfURLRequest(); 377635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CFRetain(result); 378635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return result; 379635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 380635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 381635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid WebDownload::didReceiveAuthenticationChallenge(CFURLAuthChallengeRef challenge) 382635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 3830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // Try previously stored credential first. 3840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!CFURLAuthChallengeGetPreviousFailureCount(challenge)) { 385231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block Credential credential = CredentialStorage::get(core(CFURLAuthChallengeGetProtectionSpace(challenge))); 386231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!credential.isEmpty()) { 387231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block RetainPtr<CFURLCredentialRef> cfCredential(AdoptCF, createCF(credential)); 388231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block CFURLDownloadUseCredential(m_download.get(), cfCredential.get(), challenge); 3890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return; 3900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 3910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 3920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 393635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project COMPtr<IWebURLAuthenticationChallenge> webChallenge(AdoptCOM, 394635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project WebURLAuthenticationChallenge::createInstance(AuthenticationChallenge(challenge, 0), this)); 395635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 396635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (SUCCEEDED(m_delegate->didReceiveAuthenticationChallenge(this, webChallenge.get()))) 397635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return; 398635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 399635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project cancelAuthenticationChallenge(webChallenge.get()); 400635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 401635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 402635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid WebDownload::didReceiveResponse(CFURLResponseRef response) 403635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 404635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project COMPtr<WebURLResponse> webResponse(AdoptCOM, WebURLResponse::createInstance(ResourceResponse(response))); 405635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (FAILED(m_delegate->didReceiveResponse(this, webResponse.get()))) 406635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project LOG_ERROR("DownloadDelegate->didReceiveResponse failed"); 407635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 408635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 409635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid WebDownload::willResumeWithResponse(CFURLResponseRef response, UInt64 fromByte) 410635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 411635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project COMPtr<WebURLResponse> webResponse(AdoptCOM, WebURLResponse::createInstance(ResourceResponse(response))); 412635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (FAILED(m_delegate->willResumeWithResponse(this, webResponse.get(), fromByte))) 413635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project LOG_ERROR("DownloadDelegate->willResumeWithResponse failed"); 414635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 415635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 416635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid WebDownload::didReceiveData(CFIndex length) 417635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 418635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#ifndef NDEBUG 419635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_received += length; 420635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project double current = currentTime(); 421635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (current - m_dataTime > 2.0) 422635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project LOG(Download, "DOWNLOAD - %p hanged for %.3f seconds - Received %i bytes for a total of %i", this, current - m_dataTime, length, m_received); 423635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_dataTime = current; 424635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif 425635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (FAILED(m_delegate->didReceiveDataOfLength(this, length))) 426635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project LOG_ERROR("DownloadDelegate->didReceiveData failed"); 427635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 428635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 429635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool WebDownload::shouldDecodeDataOfMIMEType(CFStringRef mimeType) 430635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 431635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project BOOL result; 432635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (FAILED(m_delegate->shouldDecodeSourceDataOfMIMEType(this, BString(mimeType), &result))) { 433635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project LOG_ERROR("DownloadDelegate->shouldDecodeSourceDataOfMIMEType failed"); 434635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return false; 435635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 436635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return !!result; 437635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 438635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 439635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid WebDownload::decideDestinationWithSuggestedObjectName(CFStringRef name) 440635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 441635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (FAILED(m_delegate->decideDestinationWithSuggestedFilename(this, BString(name)))) 442635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project LOG_ERROR("DownloadDelegate->decideDestinationWithSuggestedObjectName failed"); 443635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 444635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 445635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid WebDownload::didCreateDestination(CFURLRef destination) 446635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 447635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // The concept of the ".download bundle" is internal to the WebDownload, so therefore 448635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // we try to mask the delegate from its existence as much as possible by telling it the final 449635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // destination was created, when in reality the bundle was created 450635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 451635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project String createdDestination = MarshallingHelpers::FileCFURLRefToPathString(destination); 452635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 453635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // At this point in receiving CFURLDownload callbacks, we should definitely have the bundle path stored locally 454635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // and it should match with the file that CFURLDownload created 455635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(createdDestination == m_bundlePath); 456635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // And we should also always have the final-destination stored 457635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(!m_destination.isEmpty()); 458635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 459635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project BString path(m_destination); 460635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (FAILED(m_delegate->didCreateDestination(this, path))) 461635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project LOG_ERROR("DownloadDelegate->didCreateDestination failed"); 462635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 463635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 464635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid WebDownload::didFinish() 465635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 466635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#ifndef NDEBUG 467635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project LOG(Download, "DOWNLOAD - Finished %p after %i bytes and %.3f seconds", this, m_received, currentTime() - m_startTime); 468635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif 469635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 470635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(!m_bundlePath.isEmpty() && !m_destination.isEmpty()); 471635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project LOG(Download, "WebDownload - Moving file from bundle %s to destination %s", m_bundlePath.ascii().data(), m_destination.ascii().data()); 472635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 473635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // We try to rename the bundle to the final file name. If that fails, we give the delegate one more chance to chose 474635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // the final file name, then we just leave it 475635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!MoveFileEx(m_bundlePath.charactersWithNullTermination(), m_destination.charactersWithNullTermination(), 0)) { 476635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project LOG_ERROR("Failed to move bundle %s to %s on completion\nError - %i", m_bundlePath.ascii().data(), m_destination.ascii().data(), GetLastError()); 477635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 478635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project bool reportBundlePathAsFinalPath = true; 479635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 480635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project BString destinationBSTR(m_destination.characters(), m_destination.length()); 481635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (FAILED(m_delegate->decideDestinationWithSuggestedFilename(this, destinationBSTR))) 482635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project LOG_ERROR("delegate->decideDestinationWithSuggestedFilename() failed"); 483635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 484635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // The call to m_delegate->decideDestinationWithSuggestedFilename() should have changed our destination, so we'll try the move 485635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // one last time. 486635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!m_destination.isEmpty()) 487635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (MoveFileEx(m_bundlePath.charactersWithNullTermination(), m_destination.charactersWithNullTermination(), 0)) 488635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project reportBundlePathAsFinalPath = false; 489635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 490635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // We either need to tell the delegate our final filename is the bundle filename, or is the file name they just told us to use 491635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (reportBundlePathAsFinalPath) { 492635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project BString bundleBSTR(m_bundlePath); 493635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_delegate->didCreateDestination(this, bundleBSTR); 494635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } else { 495635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project BString finalDestinationBSTR = BString(m_destination); 496635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_delegate->didCreateDestination(this, finalDestinationBSTR); 497635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 498635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 499635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 500635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // It's extremely likely the call to delegate->didFinish() will deref this, so lets not let that cause our destruction just yet 501635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project COMPtr<WebDownload> protect = this; 502635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (FAILED(m_delegate->didFinish(this))) 503635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project LOG_ERROR("DownloadDelegate->didFinish failed"); 504635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 505635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_download = 0; 506635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 507635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 508635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid WebDownload::didFail(CFErrorRef error) 509635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 510635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project COMPtr<WebError> webError(AdoptCOM, WebError::createInstance(ResourceError(error))); 511635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (FAILED(m_delegate->didFailWithError(this, webError.get()))) 512635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project LOG_ERROR("DownloadDelegate->didFailWithError failed"); 513635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 514635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 515635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project// CFURLDownload Callbacks ---------------------------------------------------------------- 516635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid didStartCallback(CFURLDownloadRef, const void *clientInfo) 517635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ ((WebDownload*)clientInfo)->didStart(); } 518635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 519635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectCFURLRequestRef willSendRequestCallback(CFURLDownloadRef, CFURLRequestRef request, CFURLResponseRef redirectionResponse, const void *clientInfo) 520635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ return ((WebDownload*)clientInfo)->willSendRequest(request, redirectionResponse); } 521635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 522635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid didReceiveAuthenticationChallengeCallback(CFURLDownloadRef, CFURLAuthChallengeRef challenge, const void *clientInfo) 523635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ ((WebDownload*)clientInfo)->didReceiveAuthenticationChallenge(challenge); } 524635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 525635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid didReceiveResponseCallback(CFURLDownloadRef, CFURLResponseRef response, const void *clientInfo) 526635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ ((WebDownload*)clientInfo)->didReceiveResponse(response); } 527635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 528635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid willResumeWithResponseCallback(CFURLDownloadRef, CFURLResponseRef response, UInt64 startingByte, const void *clientInfo) 529635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ ((WebDownload*)clientInfo)->willResumeWithResponse(response, startingByte); } 530635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 531635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid didReceiveDataCallback(CFURLDownloadRef, CFIndex length, const void *clientInfo) 532635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ ((WebDownload*)clientInfo)->didReceiveData(length); } 533635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 534635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectBoolean shouldDecodeDataOfMIMETypeCallback(CFURLDownloadRef, CFStringRef encodingType, const void *clientInfo) 535635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ return ((WebDownload*)clientInfo)->shouldDecodeDataOfMIMEType(encodingType); } 536635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 537635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid decideDestinationWithSuggestedObjectNameCallback(CFURLDownloadRef, CFStringRef objectName, const void *clientInfo) 538635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ ((WebDownload*)clientInfo)->decideDestinationWithSuggestedObjectName(objectName); } 539635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 540635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid didCreateDestinationCallback(CFURLDownloadRef, CFURLRef path, const void *clientInfo) 541635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ ((WebDownload*)clientInfo)->didCreateDestination(path); } 542635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 543635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid didFinishCallback(CFURLDownloadRef, const void *clientInfo) 544635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ ((WebDownload*)clientInfo)->didFinish(); } 545635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 546635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid didFailCallback(CFURLDownloadRef, CFErrorRef error, const void *clientInfo) 547635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ ((WebDownload*)clientInfo)->didFail(error); } 548