Home | History | Annotate | Download | only in Downloads
      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 "WebContext.h"
     32 #include "WebData.h"
     33 #include "WebProcessMessages.h"
     34 #include <wtf/text/CString.h>
     35 #include <wtf/text/WTFString.h>
     36 
     37 using namespace WebCore;
     38 
     39 namespace WebKit {
     40 
     41 static uint64_t generateDownloadID()
     42 {
     43     static uint64_t uniqueDownloadID = 0;
     44     return ++uniqueDownloadID;
     45 }
     46 
     47 PassRefPtr<DownloadProxy> DownloadProxy::create(WebContext* webContext)
     48 {
     49     return adoptRef(new DownloadProxy(webContext));
     50 }
     51 
     52 DownloadProxy::DownloadProxy(WebContext* webContext)
     53     : m_webContext(webContext)
     54     , m_downloadID(generateDownloadID())
     55 {
     56 }
     57 
     58 DownloadProxy::~DownloadProxy()
     59 {
     60     ASSERT(!m_webContext);
     61 }
     62 
     63 void DownloadProxy::cancel()
     64 {
     65     if (!m_webContext)
     66         return;
     67 
     68     // FIXME (Multi-WebProcess): Downloads shouldn't be handled in the web process.
     69     m_webContext->sendToAllProcesses(Messages::WebProcess::CancelDownload(m_downloadID));
     70 }
     71 
     72 void DownloadProxy::invalidate()
     73 {
     74     ASSERT(m_webContext);
     75     m_webContext = 0;
     76 }
     77 
     78 void DownloadProxy::processDidClose()
     79 {
     80     if (!m_webContext)
     81         return;
     82 
     83     m_webContext->downloadClient().processDidCrash(m_webContext, this);
     84 }
     85 
     86 void DownloadProxy::didStart(const ResourceRequest& request)
     87 {
     88     m_request = request;
     89 
     90     if (!m_webContext)
     91         return;
     92 
     93     m_webContext->downloadClient().didStart(m_webContext, this);
     94 }
     95 
     96 void DownloadProxy::didReceiveAuthenticationChallenge(const AuthenticationChallenge& authenticationChallenge, uint64_t challengeID)
     97 {
     98     if (!m_webContext)
     99         return;
    100 
    101     RefPtr<AuthenticationChallengeProxy> authenticationChallengeProxy = AuthenticationChallengeProxy::create(authenticationChallenge, challengeID, m_webContext->process());
    102     m_webContext->downloadClient().didReceiveAuthenticationChallenge(m_webContext, this, authenticationChallengeProxy.get());
    103 }
    104 
    105 void DownloadProxy::didReceiveResponse(const ResourceResponse& response)
    106 {
    107     if (!m_webContext)
    108         return;
    109 
    110     m_webContext->downloadClient().didReceiveResponse(m_webContext, this, response);
    111 }
    112 
    113 void DownloadProxy::didReceiveData(uint64_t length)
    114 {
    115     if (!m_webContext)
    116         return;
    117 
    118     m_webContext->downloadClient().didReceiveData(m_webContext, this, length);
    119 }
    120 
    121 void DownloadProxy::shouldDecodeSourceDataOfMIMEType(const String& mimeType, bool& result)
    122 {
    123     if (!m_webContext)
    124         return;
    125 
    126     result = m_webContext->downloadClient().shouldDecodeSourceDataOfMIMEType(m_webContext, this, mimeType);
    127 }
    128 
    129 void DownloadProxy::decideDestinationWithSuggestedFilename(const String& filename, String& destination, bool& allowOverwrite, SandboxExtension::Handle& sandboxExtensionHandle)
    130 {
    131     if (!m_webContext)
    132         return;
    133 
    134     destination = m_webContext->downloadClient().decideDestinationWithSuggestedFilename(m_webContext, this, filename, allowOverwrite);
    135 
    136     if (!destination.isNull())
    137         SandboxExtension::createHandle(destination, SandboxExtension::WriteOnly, sandboxExtensionHandle);
    138 }
    139 
    140 void DownloadProxy::didCreateDestination(const String& path)
    141 {
    142     if (!m_webContext)
    143         return;
    144 
    145     m_webContext->downloadClient().didCreateDestination(m_webContext, this, path);
    146 }
    147 
    148 void DownloadProxy::didFinish()
    149 {
    150     if (!m_webContext)
    151         return;
    152 
    153     m_webContext->downloadClient().didFinish(m_webContext, this);
    154 
    155     // This can cause the DownloadProxy object to be deleted.
    156     m_webContext->downloadFinished(this);
    157 }
    158 
    159 static PassRefPtr<WebData> createWebData(const CoreIPC::DataReference& data)
    160 {
    161     if (data.isEmpty())
    162         return 0;
    163 
    164     return WebData::create(data.data(), data.size());
    165 }
    166 
    167 void DownloadProxy::didFail(const ResourceError& error, const CoreIPC::DataReference& resumeData)
    168 {
    169     if (!m_webContext)
    170         return;
    171 
    172     m_resumeData = createWebData(resumeData);
    173 
    174     m_webContext->downloadClient().didFail(m_webContext, this, error);
    175 
    176     // This can cause the DownloadProxy object to be deleted.
    177     m_webContext->downloadFinished(this);
    178 }
    179 
    180 void DownloadProxy::didCancel(const CoreIPC::DataReference& resumeData)
    181 {
    182     m_resumeData = createWebData(resumeData);
    183 
    184     m_webContext->downloadClient().didCancel(m_webContext, this);
    185 
    186     // This can cause the DownloadProxy object to be deleted.
    187     m_webContext->downloadFinished(this);
    188 }
    189 
    190 } // namespace WebKit
    191 
    192