1/*
2 * Copyright (C) 2012 Igalia S.L.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB.  If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20#include "config.h"
21#include "WebKitDownloadClient.h"
22
23#include "APIURLResponse.h"
24#include "WebContext.h"
25#include "WebKitDownloadPrivate.h"
26#include "WebKitURIResponsePrivate.h"
27#include "WebKitWebContextPrivate.h"
28#include <WebKit/WKString.h>
29#include <wtf/gobject/GRefPtr.h>
30#include <wtf/text/CString.h>
31
32using namespace WebCore;
33using namespace WebKit;
34
35static void didStart(WKContextRef, WKDownloadRef wkDownload, const void* clientInfo)
36{
37    GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(toImpl(wkDownload));
38    webkitWebContextDownloadStarted(WEBKIT_WEB_CONTEXT(clientInfo), download.get());
39}
40
41static void didReceiveResponse(WKContextRef, WKDownloadRef wkDownload, WKURLResponseRef wkResponse, const void* /* clientInfo */)
42{
43    GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(toImpl(wkDownload));
44    if (webkitDownloadIsCancelled(download.get()))
45        return;
46
47    GRefPtr<WebKitURIResponse> response = adoptGRef(webkitURIResponseCreateForResourceResponse(toImpl(wkResponse)->resourceResponse()));
48    webkitDownloadSetResponse(download.get(), response.get());
49}
50
51static void didReceiveData(WKContextRef, WKDownloadRef wkDownload, uint64_t length, const void* /* clientInfo */)
52{
53    GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(toImpl(wkDownload));
54    webkitDownloadNotifyProgress(download.get(), length);
55}
56
57static WKStringRef decideDestinationWithSuggestedFilename(WKContextRef, WKDownloadRef wkDownload, WKStringRef filename, bool* /* allowOverwrite */, const void* /* clientInfo */)
58{
59    GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(toImpl(wkDownload));
60    CString destinationURI = webkitDownloadDecideDestinationWithSuggestedFilename(download.get(),
61                                                                                  toImpl(filename)->string().utf8());
62    return WKStringCreateWithUTF8CString(destinationURI.data());
63}
64
65static void didCreateDestination(WKContextRef, WKDownloadRef wkDownload, WKStringRef path, const void* /* clientInfo */)
66{
67    GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(toImpl(wkDownload));
68    webkitDownloadDestinationCreated(download.get(), toImpl(path)->string().utf8());
69}
70
71static void didFail(WKContextRef, WKDownloadRef wkDownload, WKErrorRef error, const void* /* clientInfo */)
72{
73    GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(toImpl(wkDownload));
74    if (webkitDownloadIsCancelled(download.get())) {
75        // Cancellation takes precedence over other errors.
76        webkitDownloadCancelled(download.get());
77    } else
78        webkitDownloadFailed(download.get(), toImpl(error)->platformError());
79    webkitWebContextRemoveDownload(toImpl(wkDownload));
80}
81
82static void didCancel(WKContextRef, WKDownloadRef wkDownload, const void* /* clientInfo */)
83{
84    GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(toImpl(wkDownload));
85    webkitDownloadCancelled(download.get());
86    webkitWebContextRemoveDownload(toImpl(wkDownload));
87}
88
89static void didFinish(WKContextRef, WKDownloadRef wkDownload, const void* /* clientInfo */)
90{
91    GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(toImpl(wkDownload));
92    webkitDownloadFinished(download.get());
93    webkitWebContextRemoveDownload(toImpl(wkDownload));
94}
95
96void attachDownloadClientToContext(WebKitWebContext* webContext)
97{
98    WKContextDownloadClientV0 wkDownloadClient = {
99        {
100            0, // version
101            webContext, // ClientInfo
102        },
103        didStart,
104        0, // didReceiveAuthenticationChallenge
105        didReceiveResponse,
106        didReceiveData,
107        0, // shouldDecodeSourceDataOfMIMEType
108        decideDestinationWithSuggestedFilename,
109        didCreateDestination,
110        didFinish,
111        didFail,
112        didCancel,
113        0, // processDidCrash
114    };
115    WKContextSetDownloadClient(toAPI(webkitWebContextGetContext(webContext)), &wkDownloadClient.base);
116}
117
118