Commit 31303062 authored by lars's avatar lars
Browse files

Reviewed by Zack.

        Add an API layer for network downloads. Basically QWebnetworkInterface
        is an interface class for downloading resources. QWebnetworkJob describes
        the actual object to download.

        QWebNetworkInterface has a default implementation that replaces the
        old ResourceHandleManager class in the Qt port.

        Remove the ResourceHandleManager class, it is now part of 
        QWebNetworkInterface. Adapt ResourceHandle to the new way 
        of things.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@21619 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 05011d70
2007-05-21 Lars Knoll <lars@trolltech.com>
Reviewed by Zack.
Remove the ResourceHandleManager class, it is now part of
QWebNetworkInterface. Adapt ResourceHandle to the new way
of things.
* WebCore.pro:
* platform/network/ResourceHandleInternal.h:
(WebCore::ResourceHandleInternal::ResourceHandleInternal):
* platform/network/qt/ResourceHandleManagerKDE.cpp: Removed.
* platform/network/qt/ResourceHandleManagerKDE.h: Removed.
* platform/network/qt/ResourceHandleManagerQt.cpp: Removed.
* platform/network/qt/ResourceHandleManagerQt.h: Removed.
* platform/network/qt/ResourceHandleQt.cpp:
(WebCore::ResourceHandle::~ResourceHandle):
(WebCore::ResourceHandle::start):
(WebCore::ResourceHandle::cancel):
2007-05-21 David Hyatt <hyatt@apple.com>
 
Second half of fix for 13793, make sure rules=groups works properly with
......@@ -136,11 +136,12 @@ STYLESHEETS_EMBED = $$PWD/css/html4.css
MANUALMOC =
qt-port:MANUALMOC += \
$$PWD/platform/network/qt/ResourceHandleManagerQt.h \
$$PWD/platform/qt/QWebPopup.h \
$$PWD/platform/qt/SharedTimerQt.h \
$$PWD/../WebKitQt/Api/qwebframe.h \
$$PWD/../WebKitQt/Api/qwebpage.h \
$$PWD/../WebKitQt/Api/qwebnetworkinterface.h \
$$PWD/../WebKitQt/Api/qwebnetworkinterface_p.h \
$$PWD/../WebKitQt/Api/qcookiejar.h \
$$PWD/../WebKitQt/WebCoreSupport/FrameLoaderClientQt.h
......@@ -709,7 +710,6 @@ qt-port:SOURCES += \
platform/graphics/qt/IntRectQt.cpp \
platform/graphics/qt/IntSizeQt.cpp \
platform/graphics/qt/PathQt.cpp \
platform/network/qt/ResourceHandleManagerQt.cpp \
platform/network/qt/ResourceHandleQt.cpp \
editing/qt/EditorQt.cpp \
history/qt/CachedPageQt.cpp \
......@@ -754,6 +754,7 @@ qt-port:SOURCES += \
../WebKitQt/WebCoreSupport/EditCommandQt.cpp \
../WebKitQt/WebCoreSupport/FrameLoaderClientQt.cpp \
../WebKitQt/Api/qwebframe.cpp \
../WebKitQt/Api/qwebnetworkinterface.cpp \
../WebKitQt/Api/qcookiejar.cpp \
../WebKitQt/Api/qwebpage.cpp \
../WebKitQt/Api/qwebpagehistory.cpp
......
......@@ -45,7 +45,7 @@
#endif
#if PLATFORM(QT)
#include <QString>
class QWebNetworkJob;
#endif
#if PLATFORM(MAC)
......@@ -93,6 +93,9 @@ namespace WebCore {
, m_url(0)
, m_customHeaders(0)
#endif
#if PLATFORM(QT)
, m_job(0)
#endif
#if PLATFORM(MAC)
, m_currentMacChallenge(nil)
#elif USE(CFNETWORK)
......@@ -139,6 +142,9 @@ namespace WebCore {
char* m_url;
struct curl_slist* m_customHeaders;
#endif
#if PLATFORM(QT)
QWebNetworkJob *m_job;
#endif
#if PLATFORM(MAC)
NSURLAuthenticationChallenge *m_currentMacChallenge;
#endif
......
/*
* Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include <kio/job.h>
#include <QEvent>
#include <QFile>
#include "FrameQt.h"
#include "ResourceHandleManager.h"
#include "ResourceHandleInternal.h"
namespace WebCore {
static ResourceHandleManager* s_self = 0;
ResourceHandleManager* ResourceHandleManager::self()
{
if (!s_self)
s_self = new ResourceHandleManager();
return s_self;
}
ResourceHandleManager::ResourceHandleManager()
: m_jobToKioMap()
, m_kioToJobMap()
, m_frameClient(0)
{
}
ResourceHandleManager::~ResourceHandleManager()
{
}
void ResourceHandleManager::slotData(KIO::Job* kioJob, const QByteArray& data)
{
ResourceHandle* job = 0;
// Check if we know about 'kioJob'...
QMap<KIO::Job*, ResourceHandle*>::const_iterator it = m_kioToJobMap.find(kioJob);
if (it != m_kioToJobMap.end())
job = it.value();
if (!job)
return;
ResourceHandleInternal* d = job->getInternal();
if (!d || !d->m_client)
return;
d->m_client->didReceiveData(job, data.data(), data.size());
}
void ResourceHandleManager::slotMimetype(KIO::Job* kioJob, const QString& type)
{
ResourceHandle* job = 0;
// Check if we know about 'kioJob'...
QMap<KIO::Job*, ResourceHandle*>::const_iterator it = m_kioToJobMap.find(kioJob);
if (it != m_kioToJobMap.end())
job = it.value();
if (!job)
return;
ResourceHandleInternal* d = job->getInternal();
if (!d || !d->m_client)
return;
d->m_mimetype = type;
}
void ResourceHandleManager::slotResult(KJob* kjob)
{
KIO::Job* kioJob = qobject_cast<KIO::Job*>(kjob);
if (!kioJob)
return;
ResourceHandle* job = 0;
// Check if we know about 'kioJob'...
QMap<KIO::Job*, ResourceHandle*>::const_iterator it = m_kioToJobMap.find(kioJob);
if (it != m_kioToJobMap.end())
job = it.value();
if (!job)
return;
job->setError(kjob->error());
remove(job);
ASSERT(m_frameClient);
m_frameClient->checkLoaded();
}
void ResourceHandleManager::remove(ResourceHandle* job)
{
ResourceHandleInternal* d = job->getInternal();
if (!d || !d->m_client)
return;
KIO::Job* kioJob = 0;
// Check if we know about 'job'...
QMap<ResourceHandle*, KIO::Job*>::const_iterator it = m_jobToKioMap.find(job);
if (it != m_jobToKioMap.end())
kioJob = it.value();
if (!kioJob)
return;
QString headers = kioJob->queryMetaData("HTTP-Headers");
if (job->method() == "GET")
d->m_charset = job->extractCharsetFromHeaders(headers);
else if (job->method() == "POST") {
// Will take care of informing our client...
// This must be called before didFinishLoading(),
// otherwhise assembleResponseHeaders() is called too early...
RefPtr<PlatformResponseQt> response(new PlatformResponseQt());
response->data = headers;
response->url = job->url().url();
job->receivedResponse(response);
}
d->m_client->receivedAllData(job, 0);
d->m_client->didFinishLoading(job);
m_jobToKioMap.remove(job);
m_kioToJobMap.remove(kioJob);
}
void ResourceHandleManager::add(ResourceHandle* job, FrameQtClient* frameClient)
{
ResourceHandleInternal* d = job->getInternal();
DeprecatedString url = d->m_request.url().url();
KIO::Job* kioJob = 0;
if (job->method() == "POST") {
DeprecatedString postData = job->postData().flattenToString().deprecatedString();
QByteArray postDataArray(postData.ascii(), postData.length());
kioJob = KIO::http_post(KUrl(url), postDataArray, false);
kioJob->addMetaData("PropagateHttpHeader", "true");
kioJob->addMetaData("content-type", "Content-Type: application/x-www-form-urlencoded");
} else
kioJob = KIO::get(KUrl(url), false, false);
Q_ASSERT(kioJob != 0);
QObject::connect(kioJob, SIGNAL(data(KIO::Job*, const QByteArray&)), this, SLOT(slotData(KIO::Job*, const QByteArray&)));
QObject::connect(kioJob, SIGNAL(mimetype(KIO::Job*, const QString&)), this, SLOT(slotMimetype(KIO::Job*, const QString&)));
QObject::connect(kioJob, SIGNAL(result(KJob*)), this, SLOT(slotResult(KJob*)));
m_jobToKioMap.insert(job, kioJob);
m_kioToJobMap.insert(kioJob, job);
if (!m_frameClient)
m_frameClient = frameClient;
else
ASSERT(m_frameClient == frameClient);
}
void ResourceHandleManager::cancel(ResourceHandle* job)
{
remove(job);
job->setError(1);
}
} // namespace WebCore
#include "ResourceHandleManager.moc"
/*
* Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ResourceHandleManagerKDE_h
#define ResourceHandleManagerKDE_h
#include <QMap>
#include <QObject>
#include "ResourceHandle.h"
namespace KIO {
class Job;
}
class KJob;
namespace WebCore {
class FrameQtClient;
class ResourceHandleManager : public QObject
{
Q_OBJECT
public:
static ResourceHandleManager* self();
void add(ResourceHandle*, FrameQtClient*);
void cancel(ResourceHandle*);
public Q_SLOTS:
void slotData(KIO::Job*, const QByteArray& data);
void slotMimetype(KIO::Job*, const QString& type);
void slotResult(KJob*);
void deliverJobData(QtJob* , const QByteArray&);
private:
ResourceHandleManager();
~ResourceHandleManager();
void remove(ResourceHandle*);
// KIO Job <-> WebKit Job mapping
QMap<ResourceHandle*, KIO::Job*> m_jobToKioMap;
QMap<KIO::Job*, ResourceHandle*> m_kioToJobMap;
FrameQtClient* m_frameClient;
};
}
#endif
/*
* Copyright (C) 2006 Enrico Ros <enrico.ros@m31engineering.it>
* Copyright (C) 2006 Trolltech ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ResourceHandleManagerQt_H
#define ResourceHandleManagerQt_H
#include <QHash>
#include <QHttp>
#include <QBuffer>
#include <QObject>
#include <QThread>
#include <QString>
#include <QEvent>
#include <QUrl>
namespace WebCore {
class LoaderThread;
class ResourceHandle;
class NetworkLoader;
struct HostInfo {
HostInfo() {}
HostInfo(const KURL& url);
QString protocol;
QString host;
int port;
bool isLocalFile() { return protocol.isEmpty() || protocol == QLatin1String("file"); }
};
class RequestQt
{
public:
RequestQt(ResourceHandle*);
void setURL(const KURL &url);
// not thread safe, don't use in other threads
KURL url;
QUrl qurl;
ResourceHandle* resource;
// to be used by other threads
HostInfo hostInfo;
QByteArray postData;
QHttpRequestHeader request;
QHttpResponseHeader response;
bool redirected;
bool cancelled;
};
/**
* @class ResourceHandleManager
* @short Download Controller: handle ResourceHandles using a pool of threads
*/
class ResourceHandleManager : public QObject {
Q_OBJECT
public:
static ResourceHandleManager* self();
void add(ResourceHandle*);
void add(RequestQt* request);
void cancel(ResourceHandle*);
public slots:
void receivedResponse(RequestQt*);
void receivedData(RequestQt*, const QByteArray& data);
void receivedFinished(RequestQt*, int errorCode);
signals:
void networkRequest(RequestQt*);
void networkCancel(RequestQt*);
void fileRequest(RequestQt*);
private:
ResourceHandleManager();
~ResourceHandleManager();
LoaderThread *m_networkLoader;
LoaderThread *m_fileLoader;
QHash<ResourceHandle *, RequestQt *> pendingRequests;
};
class LoaderThread : public QThread {
Q_OBJECT
public:
enum Type {
Network,
File
};
LoaderThread(ResourceHandleManager *manager, Type type);
void waitForSetup() { while (!m_setup); }
protected:
void run();
private:
Type m_type;
QObject* m_loader;
ResourceHandleManager* m_manager;
volatile bool m_setup;
};
class FileLoader : public QObject {
Q_OBJECT
public:
FileLoader();
public slots:
void request(RequestQt*);
signals:
void receivedResponse(RequestQt* resource);
void receivedData(RequestQt* resource, const QByteArray &data);
void receivedFinished(RequestQt* resource, int errorCode);
private:
void parseDataUrl(RequestQt* request);
void sendData(RequestQt* request, int statusCode, const QByteArray &data);
};
class WebCoreHttp : public QObject
{
Q_OBJECT
public:
WebCoreHttp(NetworkLoader* parent, const HostInfo&);
~WebCoreHttp();
void request(RequestQt* resource);
void cancel(RequestQt*);
signals:
void connectionClosed(const HostInfo &);
private slots:
void onResponseHeaderReceived(const QHttpResponseHeader& resp);
void onReadyRead();
void onRequestFinished(int, bool);
void onStateChanged(int);
void scheduleNextRequest();
int getConnection();
public:
HostInfo info;
private:
NetworkLoader* m_loader;
QList<RequestQt*> m_pendingRequests;
struct HttpConnection {
QHttp *http;
RequestQt *current;
};
HttpConnection connection[2];
bool m_inCancel;
};
class NetworkLoader : public QObject {
Q_OBJECT
public:
NetworkLoader();
~NetworkLoader();
public slots:
void request(RequestQt*);
void cancel(RequestQt*);
void connectionClosed(const HostInfo &);
signals:
void receivedResponse(RequestQt* resource);
void receivedData(RequestQt* resource, const QByteArray &data);
void receivedFinished(RequestQt* resource, int errorCode);
private:
friend class WebCoreHttp;
QHash<HostInfo, WebCoreHttp *> m_hostMapping;
};
}
#endif
/*
* Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
* Copyright (C) 2007 Trolltech AS
*
* All rights reserved.
*
......@@ -27,18 +28,15 @@
#include "config.h"
#if PLATFORM(KDE)
#include <kio/job.h>
#endif
#include <QRegExp>
#include "Frame.h"
#include "DocLoader.h"
#include "ResourceHandle.h"
#include "DeprecatedString.h"
#include "ResourceHandleManagerQt.h"
#include "ResourceHandleInternal.h"
#include "qwebnetworkinterface_p.h"
#define notImplemented() qDebug("FIXME: UNIMPLEMENTED: %s:%d (%s)", __FILE__, __LINE__, __FUNCTION__)
......@@ -50,20 +48,32 @@ ResourceHandleInternal::~ResourceHandleInternal()
ResourceHandle::~ResourceHandle()
{
cancel();
if (d->m_job)
cancel();
}