Use the Qt image loading framework instead of the Mozilla
[WebKit-https.git] / WebCore / platform / network / qt / ResourceHandleManager.cpp
1 /*
2  * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
3  *
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
16  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
19  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #include "config.h"
29
30 #if PLATFORM(KDE)
31 #include <kio/job.h>
32 #endif
33
34 #include <QEvent>
35 #include <QFile>
36
37 #include "FrameQt.h"
38 #include "ResourceHandleManager.h"
39 #include "ResourceResponse.h"
40 #include "ResourceHandleInternal.h"
41
42 namespace WebCore {
43
44 static ResourceHandleManager* s_self = 0;
45
46
47 ResourceHandleManager* ResourceHandleManager::self()
48 {
49     if (!s_self)
50         s_self = new ResourceHandleManager();
51
52     return s_self;
53 }
54
55 QtJob::QtJob(const QString& path)
56     : m_path(path)
57 {
58     startTimer(0);
59 }
60
61 void QtJob::timerEvent(QTimerEvent* e)
62 {
63     killTimer(e->timerId());
64
65     QFile f(m_path);
66     QByteArray data;
67     if (f.open(QIODevice::ReadOnly)) {
68         data = f.readAll();
69         f.close();
70     };
71
72     emit finished(this, data);
73
74     deleteLater();
75 }
76 #if PLATFORM(KDE)
77
78 ResourceHandleManager::ResourceHandleManager()
79     : m_jobToKioMap()
80     , m_kioToJobMap()
81     , m_frameClient(0)
82 {
83 }
84
85 ResourceHandleManager::~ResourceHandleManager()
86 {
87 }
88
89
90 void ResourceHandleManager::deliverJobData(QtJob*, const QByteArray&)
91 {
92
93 }
94 void ResourceHandleManager::slotData(KIO::Job* kioJob, const QByteArray& data)
95 {
96     ResourceHandle* job = 0;
97
98     // Check if we know about 'kioJob'...
99     QMap<KIO::Job*, ResourceHandle*>::const_iterator it = m_kioToJobMap.find(kioJob);
100     if (it != m_kioToJobMap.end())
101         job = it.value();
102
103     if (!job)
104         return;
105
106     ResourceHandleInternal* d = job->getInternal();
107     if (!d || !d->m_client)
108         return;
109
110     d->m_client->didReceiveData(job, data.data(), data.size(), data.size());
111 }
112
113 void ResourceHandleManager::slotMimetype(KIO::Job* kioJob, const QString& type)
114 {
115     ResourceHandle* job = 0;
116
117     // Check if we know about 'kioJob'...
118     QMap<KIO::Job*, ResourceHandle*>::const_iterator it = m_kioToJobMap.find(kioJob);
119     if (it != m_kioToJobMap.end())
120         job = it.value();
121
122     if (!job)
123         return;
124
125     ResourceHandleInternal* d = job->getInternal();
126     if (!d || !d->m_client)
127         return;
128
129     d->m_mimetype = type;
130 }
131
132 void ResourceHandleManager::slotResult(KJob* kjob)
133 {
134     KIO::Job* kioJob = qobject_cast<KIO::Job*>(kjob);
135     if (!kioJob)
136         return;
137
138     ResourceHandle* job = 0;
139
140     // Check if we know about 'kioJob'...
141     QMap<KIO::Job*, ResourceHandle*>::const_iterator it = m_kioToJobMap.find(kioJob);
142     if (it != m_kioToJobMap.end())
143         job = it.value();
144
145     if (!job)
146         return;
147
148     //FIXME: should report an error
149     //job->setError(kjob->error());
150     remove(job);
151
152     ASSERT(m_frameClient);
153     m_frameClient->checkLoaded();
154 }
155
156 void ResourceHandleManager::remove(ResourceHandle* job)
157 {
158     ResourceHandleInternal* d = job->getInternal();
159     if (!d || !d->m_client)
160         return;
161
162     KIO::Job* kioJob = 0;
163
164     // Check if we know about 'job'...
165     QMap<ResourceHandle*, KIO::Job*>::const_iterator it = m_jobToKioMap.find(job);
166     if (it != m_jobToKioMap.end())
167         kioJob = it.value();
168
169     if (!kioJob)
170         return;
171
172     QString headers = kioJob->queryMetaData("HTTP-Headers");
173     if (job->method() == "GET")
174         d->m_charset = job->extractCharsetFromHeaders(headers);
175     else if (job->method() == "POST") {
176         // Will take care of informing our client...
177         // This must be called before didFinishLoading(),
178         // otherwhise assembleResponseHeaders() is called too early...
179         ResourceResponse response(job->url(), String(), 0, String(), String());
180         d->m_client->didReceiveResponse(job, response);
181     }
182
183     d->m_client->didFinishLoading(job);
184
185     m_jobToKioMap.remove(job);
186     m_kioToJobMap.remove(kioJob);
187 }
188
189 void ResourceHandleManager::add(ResourceHandle* job, FrameQtClient* frameClient)
190 {
191     ResourceHandleInternal* d = job->getInternal();
192     DeprecatedString url = d->m_request.url().url();
193
194     KIO::Job* kioJob = 0;
195
196     if (job->method() == "POST") {
197         ASSERT(job->postData());
198         DeprecatedString postData = job->postData()->flattenToString().deprecatedString();
199         QByteArray postDataArray(postData.ascii(), postData.length());
200
201         kioJob = KIO::http_post(KUrl(url), postDataArray, false);
202         kioJob->addMetaData("PropagateHttpHeader", "true");
203         kioJob->addMetaData("content-type", "Content-Type: application/x-www-form-urlencoded");
204     } else
205         kioJob = KIO::get(KUrl(url), false, false);
206
207     Q_ASSERT(kioJob != 0);
208
209     QObject::connect(kioJob, SIGNAL(data(KIO::Job*, const QByteArray&)), this, SLOT(slotData(KIO::Job*, const QByteArray&)));
210     QObject::connect(kioJob, SIGNAL(mimetype(KIO::Job*, const QString&)), this, SLOT(slotMimetype(KIO::Job*, const QString&)));
211     QObject::connect(kioJob, SIGNAL(result(KJob*)), this, SLOT(slotResult(KJob*)));
212
213     m_jobToKioMap.insert(job, kioJob);
214     m_kioToJobMap.insert(kioJob, job);
215
216     if (!m_frameClient)
217         m_frameClient = frameClient;
218     else
219         ASSERT(m_frameClient == frameClient);
220 }
221
222 void ResourceHandleManager::cancel(ResourceHandle* job)
223 {
224     remove(job);
225     //FIXME set an error state
226     //job->setError(1);
227 }
228
229 // Qt Resource Handle Manager
230 #else
231 ResourceHandleManager::ResourceHandleManager()
232     : m_frameClient(0)
233 {
234 }
235
236 ResourceHandleManager::~ResourceHandleManager()
237 {
238 }
239
240
241 void ResourceHandleManager::remove(ResourceHandle* job)
242 {
243     ResourceHandleInternal* d = job->getInternal();
244     if (!d || !d->m_client)
245         return;
246
247     // Check if we know about 'job'...
248     QtJob *qtJob = m_resourceToJob.value(job);
249     if (!qtJob)
250         return;
251
252     d->m_client->receivedAllData(job, 0);
253     d->m_client->didFinishLoading(job);
254
255     m_resourceToJob.remove(job);
256     m_jobToResource.remove(qtJob);
257 }
258
259 void ResourceHandleManager::add(ResourceHandle* resource, FrameQtClient* frameClient)
260 {
261     ResourceHandleInternal* d = resource->getInternal();
262
263     if (resource->method() == "POST"
264         || !d->m_request.url().isLocalFile()) {
265         // ### not supported for the local filesystem
266         return;
267     }
268     QtJob* qtJob =  new QtJob(d->m_request.url().path());
269     connect(qtJob, SIGNAL(finished(QtJob *, const QByteArray &)),
270             this, SLOT(deliverJobData(QtJob *, const QByteArray &)));
271
272     m_resourceToJob.insert(resource, qtJob);
273     m_jobToResource.insert(qtJob, resource);
274
275     if (!m_frameClient)
276         m_frameClient = frameClient;
277     else
278         ASSERT(m_frameClient == frameClient);
279 }
280
281 void ResourceHandleManager::cancel(ResourceHandle* job)
282 {
283     remove(job);
284     //FIXME set an error state
285     //job->setError(1);
286 }
287
288 void ResourceHandleManager::slotData(KIO::Job*, const QByteArray& data)
289 {
290     // dummy, never called in a Qt-only build
291 }
292
293 void ResourceHandleManager::slotMimetype(KIO::Job*, const QString& type)
294 {
295     // dummy, never called in a Qt-only build
296 }
297
298 void ResourceHandleManager::slotResult(KJob*)
299 {
300     // dummy, never called in a Qt-only build
301 }
302
303 void ResourceHandleManager::deliverJobData(QtJob* job, const QByteArray& data)
304 {
305     ResourceHandle* handle = m_jobToResource.value(job);
306     if (!handle)
307         return;
308
309     ResourceHandleInternal* d = handle->getInternal();
310     if (!d || !d->m_client)
311         return;
312
313     d->m_client->didReceiveData(handle, data.data(), data.size());
314
315     //FIXME: should report an error
316     //handle->setError(0);
317     remove(handle);
318
319     ASSERT(m_frameClient);
320     m_frameClient->checkLoaded();
321 }
322
323 #endif
324
325 } // namespace WebCore
326
327 #include "ResourceHandleManager.moc"