1/* 2 * Copyright (C) 2010 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include "config.h" 27#include "DownloadProxy.h" 28 29#include "AuthenticationChallengeProxy.h" 30#include "DataReference.h" 31#include "DownloadProxyMap.h" 32#include "WebContext.h" 33#include "WebData.h" 34#include "WebProcessMessages.h" 35#include <wtf/text/CString.h> 36#include <wtf/text/WTFString.h> 37 38#if ENABLE(NETWORK_PROCESS) 39#include "NetworkProcessMessages.h" 40#include "NetworkProcessProxy.h" 41#endif 42 43using namespace WebCore; 44 45namespace WebKit { 46 47static uint64_t generateDownloadID() 48{ 49 static uint64_t uniqueDownloadID = 0; 50 return ++uniqueDownloadID; 51} 52 53PassRefPtr<DownloadProxy> DownloadProxy::create(DownloadProxyMap& downloadProxyMap, WebContext* webContext) 54{ 55 return adoptRef(new DownloadProxy(downloadProxyMap, webContext)); 56} 57 58DownloadProxy::DownloadProxy(DownloadProxyMap& downloadProxyMap, WebContext* webContext) 59 : m_downloadProxyMap(downloadProxyMap) 60 , m_webContext(webContext) 61 , m_downloadID(generateDownloadID()) 62{ 63} 64 65DownloadProxy::~DownloadProxy() 66{ 67 ASSERT(!m_webContext); 68} 69 70void DownloadProxy::cancel() 71{ 72 if (!m_webContext) 73 return; 74 75#if ENABLE(NETWORK_PROCESS) 76 if (m_webContext->usesNetworkProcess()) { 77 if (NetworkProcessProxy* networkProcess = m_webContext->networkProcess()) 78 networkProcess->connection()->send(Messages::NetworkProcess::CancelDownload(m_downloadID), 0); 79 return; 80 } 81#endif 82 83 m_webContext->sendToAllProcesses(Messages::WebProcess::CancelDownload(m_downloadID)); 84} 85 86void DownloadProxy::invalidate() 87{ 88 ASSERT(m_webContext); 89 m_webContext = 0; 90} 91 92void DownloadProxy::processDidClose() 93{ 94 if (!m_webContext) 95 return; 96 97 m_webContext->downloadClient().processDidCrash(m_webContext.get(), this); 98} 99 100void DownloadProxy::didStart(const ResourceRequest& request) 101{ 102 m_request = request; 103 104 if (!m_webContext) 105 return; 106 107 m_webContext->downloadClient().didStart(m_webContext.get(), this); 108} 109 110void DownloadProxy::didReceiveAuthenticationChallenge(const AuthenticationChallenge& authenticationChallenge, uint64_t challengeID) 111{ 112 if (!m_webContext) 113 return; 114 115 RefPtr<AuthenticationChallengeProxy> authenticationChallengeProxy = AuthenticationChallengeProxy::create(authenticationChallenge, challengeID, m_webContext->networkingProcessConnection()); 116 117 m_webContext->downloadClient().didReceiveAuthenticationChallenge(m_webContext.get(), this, authenticationChallengeProxy.get()); 118} 119 120void DownloadProxy::didReceiveResponse(const ResourceResponse& response) 121{ 122 if (!m_webContext) 123 return; 124 125 m_webContext->downloadClient().didReceiveResponse(m_webContext.get(), this, response); 126} 127 128void DownloadProxy::didReceiveData(uint64_t length) 129{ 130 if (!m_webContext) 131 return; 132 133 m_webContext->downloadClient().didReceiveData(m_webContext.get(), this, length); 134} 135 136void DownloadProxy::shouldDecodeSourceDataOfMIMEType(const String& mimeType, bool& result) 137{ 138 if (!m_webContext) 139 return; 140 141 result = m_webContext->downloadClient().shouldDecodeSourceDataOfMIMEType(m_webContext.get(), this, mimeType); 142} 143 144void DownloadProxy::decideDestinationWithSuggestedFilename(const String& filename, String& destination, bool& allowOverwrite, SandboxExtension::Handle& sandboxExtensionHandle) 145{ 146 if (!m_webContext) 147 return; 148 149 destination = m_webContext->downloadClient().decideDestinationWithSuggestedFilename(m_webContext.get(), this, filename, allowOverwrite); 150 151 if (!destination.isNull()) 152 SandboxExtension::createHandle(destination, SandboxExtension::ReadWrite, sandboxExtensionHandle); 153} 154 155void DownloadProxy::didCreateDestination(const String& path) 156{ 157 if (!m_webContext) 158 return; 159 160 m_webContext->downloadClient().didCreateDestination(m_webContext.get(), this, path); 161} 162 163void DownloadProxy::didFinish() 164{ 165 if (!m_webContext) 166 return; 167 168 m_webContext->downloadClient().didFinish(m_webContext.get(), this); 169 170 // This can cause the DownloadProxy object to be deleted. 171 m_downloadProxyMap.downloadFinished(this); 172} 173 174static PassRefPtr<WebData> createWebData(const CoreIPC::DataReference& data) 175{ 176 if (data.isEmpty()) 177 return 0; 178 179 return WebData::create(data.data(), data.size()); 180} 181 182void DownloadProxy::didFail(const ResourceError& error, const CoreIPC::DataReference& resumeData) 183{ 184 if (!m_webContext) 185 return; 186 187 m_resumeData = createWebData(resumeData); 188 189 m_webContext->downloadClient().didFail(m_webContext.get(), this, error); 190 191 // This can cause the DownloadProxy object to be deleted. 192 m_downloadProxyMap.downloadFinished(this); 193} 194 195void DownloadProxy::didCancel(const CoreIPC::DataReference& resumeData) 196{ 197 m_resumeData = createWebData(resumeData); 198 199 m_webContext->downloadClient().didCancel(m_webContext.get(), this); 200 201 // This can cause the DownloadProxy object to be deleted. 202 m_downloadProxyMap.downloadFinished(this); 203} 204 205#if PLATFORM(QT) 206void DownloadProxy::startTransfer(const String& filename) 207{ 208 if (!m_webContext) 209 return; 210 211 // FIXME (Multi-WebProcess): <rdar://problem/12239483> Downloads shouldn't be handled in the web process. 212 m_webContext->sendToAllProcesses(Messages::WebProcess::StartTransfer(m_downloadID, filename)); 213} 214#endif 215 216} // namespace WebKit 217 218