1/*
2 * Copyright (C) 2008 Brent Fulgham <bfulgham@gmail.com>. 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. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "WebKitDLL.h"
28#include "WebDownload.h"
29
30#include "DefaultDownloadDelegate.h"
31#include "MarshallingHelpers.h"
32#include "WebError.h"
33#include "WebKit.h"
34#include "WebKitLogging.h"
35#include "WebMutableURLRequest.h"
36#include "WebURLAuthenticationChallenge.h"
37#include "WebURLCredential.h"
38#include "WebURLResponse.h"
39
40#include <wtf/text/CString.h>
41
42#include <io.h>
43#include <sys/stat.h>
44#include <sys/types.h>
45
46#include <WebCore/BString.h>
47#include <WebCore/NotImplemented.h>
48#include <WebCore/ResourceError.h>
49#include <WebCore/ResourceHandle.h>
50#include <WebCore/ResourceRequest.h>
51#include <WebCore/ResourceResponse.h>
52
53using namespace WebCore;
54
55// WebDownload ----------------------------------------------------------------
56
57void WebDownload::init(ResourceHandle* handle, const ResourceRequest& request, const ResourceResponse& response, IWebDownloadDelegate* delegate)
58{
59    // Stop previous request
60    if (handle)
61        handle->setDefersLoading(true);
62
63    m_request.adoptRef(WebMutableURLRequest::createInstance(request));
64
65    m_delegate = delegate;
66
67    m_download.init(this, handle, request, response);
68
69    start();
70}
71
72void WebDownload::init(const URL& url, IWebDownloadDelegate* delegate)
73{
74    m_delegate = delegate;
75
76    m_download.init(this, url);
77}
78
79// IWebDownload -------------------------------------------------------------------
80
81HRESULT STDMETHODCALLTYPE WebDownload::initWithRequest(
82        /* [in] */ IWebURLRequest* request,
83        /* [in] */ IWebDownloadDelegate* delegate)
84{
85   notImplemented();
86   return E_FAIL;
87}
88
89HRESULT STDMETHODCALLTYPE WebDownload::initToResumeWithBundle(
90        /* [in] */ BSTR bundlePath,
91        /* [in] */ IWebDownloadDelegate* delegate)
92{
93   notImplemented();
94   return E_FAIL;
95}
96
97HRESULT STDMETHODCALLTYPE WebDownload::start()
98{
99    if (!m_download.start())
100        return E_FAIL;
101
102    if (m_delegate)
103        m_delegate->didBegin(this);
104
105    return S_OK;
106}
107
108HRESULT STDMETHODCALLTYPE WebDownload::cancel()
109{
110    if (!m_download.cancel())
111        return E_FAIL;
112
113    return S_OK;
114}
115
116HRESULT STDMETHODCALLTYPE WebDownload::cancelForResume()
117{
118   notImplemented();
119   return E_FAIL;
120}
121
122HRESULT STDMETHODCALLTYPE WebDownload::deletesFileUponFailure(
123        /* [out, retval] */ BOOL* result)
124{
125    *result = m_download.deletesFileUponFailure() ? TRUE : FALSE;
126    return S_OK;
127}
128
129HRESULT STDMETHODCALLTYPE WebDownload::setDeletesFileUponFailure(
130        /* [in] */ BOOL deletesFileUponFailure)
131{
132    m_download.setDeletesFileUponFailure(deletesFileUponFailure);
133    return S_OK;
134}
135
136HRESULT STDMETHODCALLTYPE WebDownload::setDestination(
137        /* [in] */ BSTR path,
138        /* [in] */ BOOL allowOverwrite)
139{
140    size_t len = wcslen(path);
141    m_destination = String(path, len);
142    m_download.setDestination(m_destination);
143    return S_OK;
144}
145
146// IWebURLAuthenticationChallengeSender -------------------------------------------------------------------
147
148HRESULT STDMETHODCALLTYPE WebDownload::cancelAuthenticationChallenge(
149        /* [in] */ IWebURLAuthenticationChallenge*)
150{
151   notImplemented();
152   return E_FAIL;
153}
154
155HRESULT STDMETHODCALLTYPE WebDownload::continueWithoutCredentialForAuthenticationChallenge(
156        /* [in] */ IWebURLAuthenticationChallenge* challenge)
157{
158   notImplemented();
159   return E_FAIL;
160}
161
162HRESULT STDMETHODCALLTYPE WebDownload::useCredential(
163        /* [in] */ IWebURLCredential* credential,
164        /* [in] */ IWebURLAuthenticationChallenge* challenge)
165{
166   notImplemented();
167   return E_FAIL;
168}
169
170void WebDownload::didReceiveResponse()
171{
172    COMPtr<WebDownload> protect = this;
173
174    if (m_delegate) {
175        ResourceResponse response = m_download.getResponse();
176        COMPtr<WebURLResponse> webResponse(AdoptCOM, WebURLResponse::createInstance(response));
177        m_delegate->didReceiveResponse(this, webResponse.get());
178
179        String suggestedFilename = response.suggestedFilename();
180        if (suggestedFilename.isEmpty())
181            suggestedFilename = pathGetFileName(response.url().string());
182        suggestedFilename = decodeURLEscapeSequences(suggestedFilename);
183        BString suggestedFilenameBSTR(suggestedFilename);
184        m_delegate->decideDestinationWithSuggestedFilename(this, suggestedFilenameBSTR);
185    }
186}
187
188void WebDownload::didReceiveDataOfLength(int size)
189{
190    COMPtr<WebDownload> protect = this;
191
192    if (m_delegate)
193        m_delegate->didReceiveDataOfLength(this, size);
194}
195
196void WebDownload::didFinish()
197{
198    COMPtr<WebDownload> protect = this;
199
200    if (m_delegate)
201        m_delegate->didFinish(this);
202}
203
204void WebDownload::didFail()
205{
206    COMPtr<WebDownload> protect = this;
207
208    if (m_delegate)
209        m_delegate->didFailWithError(this, 0);
210}
211