Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F16568799
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
37 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/kio/kio/accessmanager.cpp b/kio/kio/accessmanager.cpp
index 4666247184..6e57bbbd46 100644
--- a/kio/kio/accessmanager.cpp
+++ b/kio/kio/accessmanager.cpp
@@ -1,543 +1,545 @@
/*
* This file is part of the KDE project.
*
* Copyright (C) 2009,2010 Dawit Alemayehu <adawit @ kde.org>
* Copyright (C) 2008 - 2009 Urs Wolfer <uwolfer @ kde.org>
* Copyright (C) 2007 Trolltech ASA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*
*/
#include "accessmanager.h"
#include "accessmanagerreply_p.h"
#include "job.h"
#include "scheduler.h"
#include "jobuidelegate.h"
#include <kdebug.h>
#include <kconfiggroup.h>
#include <ksharedconfig.h>
#include <kprotocolinfo.h>
#include <klocalizedstring.h>
#include <QtCore/QUrl>
#include <QtGui/QWidget>
#include <QtCore/QEventLoop>
#include <QtCore/QWeakPointer>
#include <QtDBus/QDBusInterface>
#include <QtDBus/QDBusConnection>
#include <QtDBus/QDBusReply>
#include <QtNetwork/QNetworkReply>
#include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QSslCipher>
#include <QtNetwork/QSslCertificate>
#include <QtNetwork/QSslConfiguration>
#define QL1S(x) QLatin1String(x)
#define QL1C(x) QLatin1Char(x)
#if QT_VERSION >= 0x040800
static QNetworkRequest::Attribute gSynchronousNetworkRequestAttribute = QNetworkRequest::SynchronousRequestAttribute;
#else // QtWebkit hack to use the internal attribute
static QNetworkRequest::Attribute gSynchronousNetworkRequestAttribute = static_cast<QNetworkRequest::Attribute>(QNetworkRequest::HttpPipeliningWasUsedAttribute + 7);
#endif
static qint64 sizeFromRequest(const QNetworkRequest& req)
{
const QVariant size = req.header(QNetworkRequest::ContentLengthHeader);
if (!size.isValid())
return -1;
bool ok = false;
const qlonglong value = size.toLongLong(&ok);
return (ok ? value : -1);
}
namespace KIO {
class AccessManager::AccessManagerPrivate
{
public:
AccessManagerPrivate()
: externalContentAllowed(true),
emitReadReadOnMetaDataChange(false),
window(0)
{}
void setMetaDataForRequest(QNetworkRequest request, KIO::MetaData& metaData);
bool externalContentAllowed;
bool emitReadReadOnMetaDataChange;
KIO::MetaData requestMetaData;
KIO::MetaData sessionMetaData;
QWidget* window;
};
namespace Integration {
class CookieJar::CookieJarPrivate
{
public:
CookieJarPrivate()
: windowId((WId)-1),
isEnabled(true),
isStorageDisabled(false)
{}
WId windowId;
bool isEnabled;
bool isStorageDisabled;
};
}
}
using namespace KIO;
AccessManager::AccessManager(QObject *parent)
:QNetworkAccessManager(parent), d(new AccessManager::AccessManagerPrivate())
{
// KDE Cookiejar (KCookieJar) integration...
setCookieJar(new KIO::Integration::CookieJar);
}
AccessManager::~AccessManager()
{
delete d;
}
void AccessManager::setExternalContentAllowed(bool allowed)
{
d->externalContentAllowed = allowed;
}
bool AccessManager::isExternalContentAllowed() const
{
return d->externalContentAllowed;
}
#ifndef KDE_NO_DEPRECATED
void AccessManager::setCookieJarWindowId(WId id)
{
QWidget* window = QWidget::find(id);
if (!window) {
return;
}
KIO::Integration::CookieJar *jar = qobject_cast<KIO::Integration::CookieJar *> (cookieJar());
if (jar) {
jar->setWindowId(id);
}
d->window = window->isWindow() ? window : window->window();
}
#endif
void AccessManager::setWindow(QWidget* widget)
{
if (!widget) {
return;
}
d->window = widget->isWindow() ? widget : widget->window();
if (!d->window) {
return;
}
KIO::Integration::CookieJar *jar = qobject_cast<KIO::Integration::CookieJar *> (cookieJar());
if (jar) {
jar->setWindowId(d->window->winId());
}
}
#ifndef KDE_NO_DEPRECATED
WId AccessManager::cookieJarWindowid() const
{
KIO::Integration::CookieJar *jar = qobject_cast<KIO::Integration::CookieJar *> (cookieJar());
if (jar)
return jar->windowId();
return 0;
}
#endif
QWidget* AccessManager::window() const
{
return d->window;
}
KIO::MetaData& AccessManager::requestMetaData()
{
return d->requestMetaData;
}
KIO::MetaData& AccessManager::sessionMetaData()
{
return d->sessionMetaData;
}
void AccessManager::putReplyOnHold(QNetworkReply* reply)
{
KDEPrivate::AccessManagerReply* r = qobject_cast<KDEPrivate::AccessManagerReply*>(reply);
if (!r) {
return;
}
r->putOnHold();
}
void AccessManager::setEmitReadyReadOnMetaDataChange(bool enable)
{
d->emitReadReadOnMetaDataChange = enable;
}
QNetworkReply *AccessManager::createRequest(Operation op, const QNetworkRequest &req, QIODevice *outgoingData)
{
KIO::SimpleJob *kioJob = 0;
const KUrl reqUrl (req.url());
- if (!d->externalContentAllowed && !KDEPrivate::AccessManager_isLocalRequest(reqUrl) && reqUrl.scheme() != QL1S("data")) {
+ if (!d->externalContentAllowed &&
+ !KDEPrivate::AccessManagerReply::isLocalRequest(reqUrl) &&
+ reqUrl.scheme() != QL1S("data")) {
kDebug( 7044 ) << "Blocked: " << reqUrl;
KDEPrivate::AccessManagerReply* reply = new KDEPrivate::AccessManagerReply(op, req, kioJob, d->emitReadReadOnMetaDataChange, this);
reply->setStatus(i18n("Blocked request."),QNetworkReply::ContentAccessDenied);
return reply;
}
// Check if the internal ignore content disposition header is set.
const bool ignoreContentDisposition = req.hasRawHeader("x-kdewebkit-ignore-disposition");
// Retrieve the KIO meta data...
KIO::MetaData metaData;
d->setMetaDataForRequest(req, metaData);
switch (op) {
case HeadOperation: {
//kDebug( 7044 ) << "HeadOperation:" << reqUrl;
kioJob = KIO::mimetype(reqUrl, KIO::HideProgressInfo);
break;
}
case GetOperation: {
//kDebug( 7044 ) << "GetOperation:" << reqUrl;
if (!reqUrl.path().isEmpty() || reqUrl.host().isEmpty())
kioJob = KIO::get(reqUrl, KIO::NoReload, KIO::HideProgressInfo);
else
kioJob = KIO::stat(reqUrl, KIO::HideProgressInfo);
// WORKAROUND: Avoid the brain damaged stuff QtWebKit does when a POST
// operation is redirected! See BR# 268694.
metaData.remove(QL1S("content-type")); // Remove the content-type from a GET/HEAD request!
break;
}
case PutOperation: {
//kDebug( 7044 ) << "PutOperation:" << reqUrl;
if (outgoingData)
kioJob = KIO::storedPut(outgoingData->readAll(), reqUrl, -1, KIO::HideProgressInfo);
else
kioJob = KIO::put(reqUrl, -1, KIO::HideProgressInfo);
break;
}
case PostOperation: {
kioJob = KIO::http_post(reqUrl, outgoingData, sizeFromRequest(req), KIO::HideProgressInfo);
if (!metaData.contains(QL1S("content-type"))) {
const QVariant header = req.header(QNetworkRequest::ContentTypeHeader);
if (header.isValid()) {
metaData.insert(QL1S("content-type"),
(QL1S("Content-Type: ") + header.toString()));
} else {
metaData.insert(QL1S("content-type"),
QL1S("Content-Type: application/x-www-form-urlencoded"));
}
}
break;
}
case DeleteOperation: {
//kDebug(7044) << "DeleteOperation:" << reqUrl;
kioJob = KIO::http_delete(reqUrl, KIO::HideProgressInfo);
break;
}
case CustomOperation: {
const QByteArray& method = req.attribute(QNetworkRequest::CustomVerbAttribute).toByteArray();
//kDebug(7044) << "CustomOperation:" << reqUrl << "method:" << method << "outgoing data:" << outgoingData;
if (method.isEmpty()) {
KDEPrivate::AccessManagerReply* reply = new KDEPrivate::AccessManagerReply(op, req, kioJob, d->emitReadReadOnMetaDataChange, this);
reply->setStatus(i18n("Unknown HTTP verb."), QNetworkReply::ProtocolUnknownError);
return reply;
}
if (outgoingData)
kioJob = KIO::http_post(reqUrl, outgoingData, sizeFromRequest(req), KIO::HideProgressInfo);
else
kioJob = KIO::get(reqUrl, KIO::NoReload, KIO::HideProgressInfo);
metaData.insert(QL1S("CustomHTTPMethod"), method);
break;
}
default: {
kWarning(7044) << "Unsupported KIO operation requested! Defering to QNetworkAccessManager...";
return QNetworkAccessManager::createRequest(op, req, outgoingData);
}
}
// Set the window on the the KIO ui delegate
if (d->window) {
kioJob->ui()->setWindow(d->window);
}
// Disable internal automatic redirection handling
kioJob->setRedirectionHandlingEnabled(false);
// Set the job priority
switch (req.priority()) {
case QNetworkRequest::HighPriority:
KIO::Scheduler::setJobPriority(kioJob, -5);
break;
case QNetworkRequest::LowPriority:
KIO::Scheduler::setJobPriority(kioJob, 5);
break;
default:
break;
}
// Set the meta data for this job...
kioJob->setMetaData(metaData);
// Create the reply...
KDEPrivate::AccessManagerReply *reply = new KDEPrivate::AccessManagerReply(op, req, kioJob, d->emitReadReadOnMetaDataChange, this);
/*
* NOTE: Since QtWebkit >= v2.2 no longer spins in its own even loop, we
* are forced to create our own local event loop here to handle the very
* rare but still in use synchronous XHR calls, e.g. http://webchat.freenode.net/
*/
if (req.attribute(gSynchronousNetworkRequestAttribute).toBool()) {
QEventLoop eventLoop;
connect (reply, SIGNAL(finished()), &eventLoop, SLOT(quit()));
eventLoop.exec();
}
if (ignoreContentDisposition) {
kDebug(7044) << "Content-Disposition WILL BE IGNORED!";
reply->setIgnoreContentDisposition(ignoreContentDisposition);
}
return reply;
}
void AccessManager::AccessManagerPrivate::setMetaDataForRequest(QNetworkRequest request, KIO::MetaData& metaData)
{
// Add any meta data specified within request...
QVariant userMetaData = request.attribute (static_cast<QNetworkRequest::Attribute>(MetaData));
if (userMetaData.isValid() && userMetaData.type() == QVariant::Map)
metaData += userMetaData.toMap();
metaData.insert(QL1S("PropagateHttpHeader"), QL1S("true"));
if (request.hasRawHeader("User-Agent")) {
metaData.insert(QL1S("UserAgent"), request.rawHeader("User-Agent"));
request.setRawHeader("User-Agent", QByteArray());
}
if (request.hasRawHeader("Accept")) {
metaData.insert(QL1S("accept"), request.rawHeader("Accept"));
request.setRawHeader("Accept", QByteArray());
}
if (request.hasRawHeader("Accept-Charset")) {
metaData.insert(QL1S("Charsets"), request.rawHeader("Accept-Charset"));
request.setRawHeader("Accept-Charset", QByteArray());
}
if (request.hasRawHeader("Accept-Language")) {
metaData.insert(QL1S("Languages"), request.rawHeader("Accept-Language"));
request.setRawHeader("Accept-Language", QByteArray());
}
if (request.hasRawHeader("Referer")) {
metaData.insert(QL1S("referrer"), request.rawHeader("Referer"));
request.setRawHeader("Referer", QByteArray());
}
if (request.hasRawHeader("Content-Type")) {
metaData.insert(QL1S("content-type"), request.rawHeader("Content-Type"));
request.setRawHeader("Content-Type", QByteArray());
}
if (request.attribute(QNetworkRequest::AuthenticationReuseAttribute) == QNetworkRequest::Manual) {
metaData.insert(QL1S("no-preemptive-auth-reuse"), QL1S("true"));
}
request.setRawHeader("Content-Length", QByteArray());
request.setRawHeader("Connection", QByteArray());
request.setRawHeader("If-None-Match", QByteArray());
request.setRawHeader("If-Modified-Since", QByteArray());
request.setRawHeader("x-kdewebkit-ignore-disposition", QByteArray());
QStringList customHeaders;
Q_FOREACH(const QByteArray &key, request.rawHeaderList()) {
const QByteArray value = request.rawHeader(key);
if (value.length())
customHeaders << (key + QL1S(": ") + value);
}
if (!customHeaders.isEmpty()) {
metaData.insert(QL1S("customHTTPHeader"), customHeaders.join("\r\n"));
}
// Append per request meta data, if any...
if (!requestMetaData.isEmpty()) {
metaData += requestMetaData;
// Clear per request meta data...
requestMetaData.clear();
}
// Append per session meta data, if any...
if (!sessionMetaData.isEmpty()) {
metaData += sessionMetaData;
}
}
using namespace KIO::Integration;
static QSsl::SslProtocol qSslProtocolFromString(const QString& str)
{
if (str.compare(QLatin1String("SSLv3"), Qt::CaseInsensitive) == 0) {
return QSsl::SslV3;
}
if (str.compare(QLatin1String("SSLv2"), Qt::CaseInsensitive) == 0) {
return QSsl::SslV2;
}
if (str.compare(QLatin1String("TLSv1"), Qt::CaseInsensitive) == 0) {
return QSsl::TlsV1;
}
return QSsl::AnyProtocol;
}
bool KIO::Integration::sslConfigFromMetaData(const KIO::MetaData& metadata, QSslConfiguration& sslconfig)
{
bool success = false;
if (metadata.contains(QL1S("ssl_in_use"))) {
const QSsl::SslProtocol sslProto = qSslProtocolFromString(metadata.value(QL1S("ssl_protocol_version")));
QList<QSslCipher> cipherList;
cipherList << QSslCipher(metadata.value(QL1S("ssl_cipher_name")), sslProto);
sslconfig.setCaCertificates(QSslCertificate::fromData(metadata.value(QL1S("ssl_peer_chain")).toUtf8()));
sslconfig.setCiphers(cipherList);
sslconfig.setProtocol(sslProto);
success = sslconfig.isNull();
}
return success;
}
CookieJar::CookieJar(QObject* parent)
:QNetworkCookieJar(parent), d(new CookieJar::CookieJarPrivate)
{
reparseConfiguration();
}
CookieJar::~CookieJar()
{
delete d;
}
WId CookieJar::windowId() const
{
return d->windowId;
}
bool CookieJar::isCookieStorageDisabled() const
{
return d->isStorageDisabled;
}
QList<QNetworkCookie> CookieJar::cookiesForUrl(const QUrl &url) const
{
QList<QNetworkCookie> cookieList;
if (!d->isEnabled) {
return cookieList;
}
QDBusInterface kcookiejar("org.kde.kded", "/modules/kcookiejar", "org.kde.KCookieServer");
QDBusReply<QString> reply = kcookiejar.call("findDOMCookies", url.toString(QUrl::RemoveUserInfo), (qlonglong)d->windowId);
if (!reply.isValid()) {
kWarning(7044) << "Unable to communicate with the cookiejar!";
return cookieList;
}
const QString cookieStr = reply.value();
const QStringList cookies = cookieStr.split(QL1S("; "), QString::SkipEmptyParts);
Q_FOREACH(const QString& cookie, cookies) {
const int index = cookie.indexOf(QL1C('='));
const QString name = cookie.left(index);
const QString value = cookie.right((cookie.length() - index - 1));
cookieList << QNetworkCookie(name.toUtf8(), value.toUtf8());
//kDebug(7044) << "cookie: name=" << name << ", value=" << value;
}
return cookieList;
}
bool CookieJar::setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, const QUrl &url)
{
if (!d->isEnabled) {
return false;
}
QDBusInterface kcookiejar("org.kde.kded", "/modules/kcookiejar", "org.kde.KCookieServer");
Q_FOREACH(const QNetworkCookie &cookie, cookieList) {
QByteArray cookieHeader ("Set-Cookie: ");
if (d->isStorageDisabled && !cookie.isSessionCookie()) {
QNetworkCookie sessionCookie(cookie);
sessionCookie.setExpirationDate(QDateTime());
cookieHeader += sessionCookie.toRawForm();
} else {
cookieHeader += cookie.toRawForm();
}
kcookiejar.call("addCookies", url.toString(QUrl::RemoveUserInfo), cookieHeader, (qlonglong)d->windowId);
//kDebug(7044) << "[" << d->windowId << "]" << cookieHeader << " from " << url;
}
return !kcookiejar.lastError().isValid();
}
void CookieJar::setDisableCookieStorage(bool disable)
{
d->isStorageDisabled = disable;
}
void CookieJar::setWindowId(WId id)
{
d->windowId = id;
}
void CookieJar::reparseConfiguration()
{
KConfigGroup cfg = KSharedConfig::openConfig("kcookiejarrc", KConfig::NoGlobals)->group("Cookie Policy");
d->isEnabled = cfg.readEntry("Cookies", true);
}
#include "accessmanager.moc"
diff --git a/kio/kio/accessmanagerreply_p.cpp b/kio/kio/accessmanagerreply_p.cpp
index 6bc9bbd258..aeb3295a96 100644
--- a/kio/kio/accessmanagerreply_p.cpp
+++ b/kio/kio/accessmanagerreply_p.cpp
@@ -1,416 +1,417 @@
/*
* This file is part of the KDE project.
*
* Copyright (C) 2008 Alex Merry <alex.merry @ kdemail.net>
* Copyright (C) 2008 - 2009 Urs Wolfer <uwolfer @ kde.org>
* Copyright (C) 2009 - 2010 Dawit Alemayehu <adawit @ kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*
*/
#include "accessmanagerreply_p.h"
#include "accessmanager.h"
#include "job.h"
#include "scheduler.h"
#include <kdebug.h>
#include <kauthorized.h>
#include <kprotocolinfo.h>
#include <QtNetwork/QSslConfiguration>
#define QL1S(x) QLatin1String(x)
#define QL1C(x) QLatin1Char(x)
namespace KDEPrivate {
-bool AccessManager_isLocalRequest(const KUrl& url)
-{
- const QString scheme (url.protocol());
- return (KProtocolInfo::isKnownProtocol(scheme) &&
- KProtocolInfo::protocolClass(scheme).compare(QL1S(":local"), Qt::CaseInsensitive) == 0);
-}
-
AccessManagerReply::AccessManagerReply(const QNetworkAccessManager::Operation &op,
const QNetworkRequest &request,
KIO::SimpleJob *kioJob,
- bool emitReadReadOnMetaDataChange,
+ bool emitReadyReadOnMetaDataChange,
QObject *parent)
:QNetworkReply(parent),
m_metaDataRead(false),
m_ignoreContentDisposition(false),
- m_emitReadReadOnMetaDataChange(emitReadReadOnMetaDataChange),
+ m_emitReadyReadOnMetaDataChange(emitReadyReadOnMetaDataChange),
m_kioJob(kioJob)
{
setRequest(request);
setOpenMode(QIODevice::ReadOnly);
setUrl(request.url());
setOperation(op);
setError(NoError, QString());
if (!request.sslConfiguration().isNull())
setSslConfiguration(request.sslConfiguration());
if (kioJob) {
connect(kioJob, SIGNAL(redirection(KIO::Job*, const KUrl&)), SLOT(slotRedirection(KIO::Job*, const KUrl&)));
connect(kioJob, SIGNAL(percent(KJob*, unsigned long)), SLOT(slotPercent(KJob*, unsigned long)));
if (qobject_cast<KIO::StatJob*>(kioJob)) {
connect(kioJob, SIGNAL(result(KJob *)), SLOT(slotStatResult(KJob *)));
} else {
connect(kioJob, SIGNAL(result(KJob *)), SLOT(slotResult(KJob *)));
connect(kioJob, SIGNAL(data(KIO::Job *, const QByteArray &)),
SLOT(slotData(KIO::Job *, const QByteArray &)));
connect(kioJob, SIGNAL(mimetype(KIO::Job *, const QString&)),
SLOT(slotMimeType(KIO::Job *, const QString&)));
}
}
}
AccessManagerReply::~AccessManagerReply()
{
}
void AccessManagerReply::abort()
{
if (m_kioJob)
m_kioJob->kill();
m_data.clear();
m_metaDataRead = false;
}
qint64 AccessManagerReply::bytesAvailable() const
{
return (QNetworkReply::bytesAvailable() + m_data.length());
}
qint64 AccessManagerReply::readData(char *data, qint64 maxSize)
{
const qint64 length = qMin(qint64(m_data.length()), maxSize);
if (length) {
qMemCopy(data, m_data.constData(), length);
m_data.remove(0, length);
}
return length;
}
bool AccessManagerReply::ignoreContentDisposition (KIO::Job* job)
{
if (m_ignoreContentDisposition) {
return true;
}
if (job->queryMetaData(QL1S("content-disposition-type")).isEmpty()) {
return true;
}
bool ok = false;
const int statusCode = attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(&ok);
if (!ok || statusCode < 200 || statusCode > 299) {
return true;
}
return false;
}
void AccessManagerReply::setIgnoreContentDisposition(bool on)
{
// kDebug(7044) << on;
m_ignoreContentDisposition = on;
}
void AccessManagerReply::setStatus(const QString& message, QNetworkReply::NetworkError code)
{
setError(code, message);
if (code != QNetworkReply::NoError) {
QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, Q_ARG(QNetworkReply::NetworkError, code));
}
QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
}
void AccessManagerReply::putOnHold()
{
if (!m_kioJob || isFinished())
return;
// kDebug(7044) << m_kioJob << m_data;
m_kioJob->disconnect(this);
m_kioJob->putOnHold();
m_kioJob = 0;
KIO::Scheduler::publishSlaveOnHold();
}
+bool AccessManagerReply::isLocalRequest (const KUrl& url)
+{
+ const QString scheme (url.protocol());
+ return (KProtocolInfo::isKnownProtocol(scheme) &&
+ KProtocolInfo::protocolClass(scheme).compare(QL1S(":local"), Qt::CaseInsensitive) == 0);
+}
+
void AccessManagerReply::readHttpResponseHeaders(KIO::Job *job)
{
if (!job || m_metaDataRead)
return;
const KIO::MetaData& metaData = job->metaData();
if (metaData.isEmpty()) {
// Allow handling of local resources such as man pages and file url...
- if (AccessManager_isLocalRequest(url())) {
+ if (isLocalRequest(url())) {
setHeader(QNetworkRequest::ContentLengthHeader, job->totalAmount(KJob::Bytes));
setAttribute(QNetworkRequest::HttpStatusCodeAttribute, "200");
emit metaDataChanged();
}
return;
}
// Set the encryption attribute and values...
QSslConfiguration sslConfig;
const bool isEncrypted = KIO::Integration::sslConfigFromMetaData(metaData, sslConfig);
setAttribute(QNetworkRequest::ConnectionEncryptedAttribute, isEncrypted);
if (isEncrypted)
setSslConfiguration(sslConfig);
// Set the returned meta data as attribute...
setAttribute(static_cast<QNetworkRequest::Attribute>(KIO::AccessManager::MetaData),
metaData.toVariant());
// Set the raw header information...
const QStringList httpHeaders (metaData.value(QL1S("HTTP-Headers")).split(QL1C('\n'), QString::SkipEmptyParts));
if (httpHeaders.isEmpty()) {
if (metaData.contains(QL1S("charset"))) {
QString mimeType = header(QNetworkRequest::ContentTypeHeader).toString();
mimeType += QL1S(" ; charset=");
mimeType += metaData.value(QL1S("charset"));
kDebug(7044) << "changed content-type to" << mimeType;
setHeader(QNetworkRequest::ContentTypeHeader, mimeType.toUtf8());
}
} else {
Q_FOREACH(const QString& httpHeader, httpHeaders) {
int index = httpHeader.indexOf(QL1C(':'));
// Handle HTTP status line...
if (index == -1) {
// Except for the status line, all HTTP header must be an nvpair of
// type "<name>:<value>"
if (!httpHeader.startsWith(QL1S("HTTP/"), Qt::CaseInsensitive)) {
continue;
}
QStringList statusLineAttrs (httpHeader.split(QL1C(' '), QString::SkipEmptyParts));
if (statusLineAttrs.count() > 1) {
setAttribute(QNetworkRequest::HttpStatusCodeAttribute, statusLineAttrs.at(1));
}
if (statusLineAttrs.count() > 2) {
setAttribute(QNetworkRequest::HttpReasonPhraseAttribute, statusLineAttrs.at(2));
}
continue;
}
const QString headerName = httpHeader.left(index);
QString headerValue = httpHeader.mid(index+1);
// Ignore cookie header since it is handled by the http ioslave.
if (headerName.startsWith(QL1S("set-cookie"), Qt::CaseInsensitive)) {
continue;
}
if (headerName.startsWith(QL1S("content-disposition"), Qt::CaseInsensitive) &&
ignoreContentDisposition(job)) {
continue;
}
// Without overridding the corrected mime-type sent by kio_http, add
// back the "charset=" portion of the content-type header if present.
if (headerName.startsWith(QL1S("content-type"), Qt::CaseInsensitive)) {
const QString mimeType = header(QNetworkRequest::ContentTypeHeader).toString();
if (!headerValue.contains(mimeType, Qt::CaseInsensitive)) {
index = headerValue.indexOf(QL1C(';'));
if (index == -1) {
headerValue = mimeType;
} else {
headerValue.replace(0, index, mimeType);
}
kDebug(7044) << "Changed mime-type from" << mimeType << "to" << headerValue;
}
}
setRawHeader(headerName.trimmed().toUtf8(), headerValue.trimmed().toUtf8());
}
}
m_metaDataRead = true;
emit metaDataChanged();
}
int AccessManagerReply::jobError(KJob* kJob)
{
const int errCode = kJob->error();
switch (errCode)
{
case 0:
break; // No error;
case KIO::ERR_NO_CONTENT: // Sent by a 204 response is not an error condition.
setError(QNetworkReply::NoError, kJob->errorText());
//kDebug(7044) << "0 -> QNetworkReply::NoError";
break;
case KIO::ERR_IS_DIRECTORY:
// This error condition can happen if you click on an ftp link that points
// to a directory instead of a file, e.g. ftp://ftp.kde.org/pub
setHeader(QNetworkRequest::ContentTypeHeader, "inode/directory");
setError(QNetworkReply::NoError, kJob->errorText());
break;
case KIO::ERR_COULD_NOT_CONNECT:
setError(QNetworkReply::ConnectionRefusedError, kJob->errorText());
kDebug(7044) << "KIO::ERR_COULD_NOT_CONNECT -> QNetworkReply::ConnectionRefusedError";
break;
case KIO::ERR_UNKNOWN_HOST:
setError(QNetworkReply::HostNotFoundError, kJob->errorText());
kDebug(7044) << "KIO::ERR_UNKNOWN_HOST -> QNetworkReply::HostNotFoundError";
break;
case KIO::ERR_SERVER_TIMEOUT:
setError(QNetworkReply::TimeoutError, kJob->errorText());
kDebug(7044) << "KIO::ERR_SERVER_TIMEOUT -> QNetworkReply::TimeoutError";
break;
case KIO::ERR_USER_CANCELED:
case KIO::ERR_ABORTED:
setError(QNetworkReply::OperationCanceledError, kJob->errorText());
kDebug(7044) << "KIO::ERR_ABORTED -> QNetworkReply::OperationCanceledError";
break;
case KIO::ERR_UNKNOWN_PROXY_HOST:
setError(QNetworkReply::ProxyNotFoundError, kJob->errorText());
kDebug(7044) << "KIO::UNKNOWN_PROXY_HOST -> QNetworkReply::ProxyNotFoundError";
break;
case KIO::ERR_ACCESS_DENIED:
setError(QNetworkReply::ContentAccessDenied, kJob->errorText());
kDebug(7044) << "KIO::ERR_ACCESS_DENIED -> QNetworkReply::ContentAccessDenied";
break;
case KIO::ERR_WRITE_ACCESS_DENIED:
setError(QNetworkReply::ContentOperationNotPermittedError, kJob->errorText());
kDebug(7044) << "KIO::ERR_WRITE_ACCESS_DENIED -> QNetworkReply::ContentOperationNotPermittedError";
break;
case KIO::ERR_DOES_NOT_EXIST:
setError(QNetworkReply::ContentNotFoundError, kJob->errorText());
kDebug(7044) << "KIO::ERR_DOES_NOT_EXIST -> QNetworkReply::ContentNotFoundError";
break;
case KIO::ERR_COULD_NOT_AUTHENTICATE:
setError(QNetworkReply::AuthenticationRequiredError, kJob->errorText());
kDebug(7044) << "KIO::ERR_COULD_NOT_AUTHENTICATE -> QNetworkReply::AuthenticationRequiredError";
break;
case KIO::ERR_UNSUPPORTED_PROTOCOL:
case KIO::ERR_NO_SOURCE_PROTOCOL:
setError(QNetworkReply::ProtocolUnknownError, kJob->errorText());
kDebug(7044) << "KIO::ERR_UNSUPPORTED_PROTOCOL -> QNetworkReply::ProtocolUnknownError";
break;
case KIO::ERR_CONNECTION_BROKEN:
setError(QNetworkReply::RemoteHostClosedError, kJob->errorText());
kDebug(7044) << "KIO::ERR_CONNECTION_BROKEN -> QNetworkReply::RemoteHostClosedError";
break;
case KIO::ERR_UNSUPPORTED_ACTION:
setError(QNetworkReply::ProtocolInvalidOperationError, kJob->errorText());
kDebug(7044) << "KIO::ERR_UNSUPPORTED_ACTION -> QNetworkReply::ProtocolInvalidOperationError";
break;
default:
setError(QNetworkReply::UnknownNetworkError, kJob->errorText());
kDebug(7044) << KIO::rawErrorDetail(errCode, QString()) << "-> QNetworkReply::UnknownNetworkError";
}
return errCode;
}
void AccessManagerReply::slotData(KIO::Job *kioJob, const QByteArray &data)
{
Q_UNUSED (kioJob);
m_data += data;
emit readyRead();
}
void AccessManagerReply::slotMimeType(KIO::Job *kioJob, const QString &mimeType)
{
//kDebug(7044) << kioJob << mimeType;
setHeader(QNetworkRequest::ContentTypeHeader, mimeType.toUtf8());
readHttpResponseHeaders(kioJob);
- if (m_emitReadReadOnMetaDataChange) {
+ if (m_emitReadyReadOnMetaDataChange) {
emit readyRead();
}
}
void AccessManagerReply::slotResult(KJob *kJob)
{
const int errcode = jobError(kJob);
const QUrl redirectUrl = attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
if (!redirectUrl.isValid()) {
setAttribute(static_cast<QNetworkRequest::Attribute>(KIO::AccessManager::KioError), errcode);
if (errcode && errcode != KIO::ERR_NO_CONTENT)
emit error(error());
}
// Make sure HTTP response headers are always set.
if (!m_metaDataRead) {
readHttpResponseHeaders(qobject_cast<KIO::Job*>(kJob));
}
emit finished();
}
void AccessManagerReply::slotStatResult(KJob* kJob)
{
if (jobError(kJob)) {
emit error (error());
emit finished();
+ return;
}
KIO::StatJob* statJob = qobject_cast<KIO::StatJob*>(kJob);
Q_ASSERT(statJob);
KIO::UDSEntry entry = statJob->statResult();
QString mimeType = entry.stringValue(KIO::UDSEntry::UDS_MIME_TYPE);
if (mimeType.isEmpty() && entry.isDir())
mimeType = QL1S("inode/directory");
if (!mimeType.isEmpty())
setHeader(QNetworkRequest::ContentTypeHeader, mimeType.toUtf8());
emit finished();
}
void AccessManagerReply::slotRedirection(KIO::Job* job, const KUrl& u)
{
Q_UNUSED(job);
if (!KAuthorized::authorizeUrlAction(QLatin1String("redirect"), url(), u)) {
kWarning(7007) << "Redirection from" << url() << "to" << u << "REJECTED by policy!";
setError(QNetworkReply::ContentAccessDenied, u.url());
emit error(error());
return;
}
setAttribute(QNetworkRequest::RedirectionTargetAttribute, QUrl(u));
}
void AccessManagerReply::slotPercent(KJob *job, unsigned long percent)
{
qulonglong bytesTotal = job->totalAmount(KJob::Bytes);
qulonglong bytesProcessed = bytesTotal * (percent / 100);
if (operation() == QNetworkAccessManager::PutOperation ||
operation() == QNetworkAccessManager::PostOperation) {
emit uploadProgress(bytesProcessed, bytesTotal);
return;
}
emit downloadProgress(bytesProcessed, bytesTotal);
}
}
#include "accessmanagerreply_p.moc"
diff --git a/kio/kio/accessmanagerreply_p.h b/kio/kio/accessmanagerreply_p.h
index 374de6ceb2..0dc8ea83c1 100644
--- a/kio/kio/accessmanagerreply_p.h
+++ b/kio/kio/accessmanagerreply_p.h
@@ -1,93 +1,95 @@
/*
* This file is part of the KDE project.
*
* Copyright (C) 2008 - 2009 Urs Wolfer <uwolfer @ kde.org>
* Copyright (C) 2009 - 2010 Dawit Alemayehu <adawit @ kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*
*/
#ifndef KIO_ACCESSMANAGERREPLY_P_H
#define KIO_ACCESSMANAGERREPLY_P_H
#include <QtCore/QPointer>
#include <QtNetwork/QNetworkReply>
namespace KIO
{
class Job;
class SimpleJob;
}
class KJob;
class KUrl;
namespace KDEPrivate {
/**
* Used for KIO::AccessManager; KDE implementation of QNetworkReply.
*
* @since 4.3
* @author Urs Wolfer \<uwolfer @ kde.org\>
*/
class AccessManagerReply : public QNetworkReply
{
Q_OBJECT
public:
AccessManagerReply(const QNetworkAccessManager::Operation &op,
const QNetworkRequest &request,
KIO::SimpleJob *kioJob,
- bool emitReadReadOnMetaDataChange = false,
+ bool emitReadyReadOnMetaDataChange = false,
QObject *parent = 0);
virtual ~AccessManagerReply();
virtual qint64 bytesAvailable() const;
virtual void abort();
void setIgnoreContentDisposition(bool on);
void setStatus(const QString& message, QNetworkReply::NetworkError);
void putOnHold();
+ static bool isLocalRequest(const KUrl& url);
+
protected:
virtual qint64 readData(char *data, qint64 maxSize);
void readHttpResponseHeaders(KIO::Job *);
int jobError(KJob *kJob);
bool ignoreContentDisposition(KIO::Job* job);
private Q_SLOTS:
void slotData(KIO::Job *kioJob, const QByteArray &data);
void slotMimeType(KIO::Job *kioJob, const QString &mimeType);
void slotResult(KJob *kJob);
void slotStatResult(KJob *kJob);
void slotRedirection(KIO::Job *job, const KUrl &url);
void slotPercent(KJob *job, unsigned long percent);
private:
QByteArray m_data;
bool m_metaDataRead;
bool m_ignoreContentDisposition;
- bool m_emitReadReadOnMetaDataChange;
+ bool m_emitReadyReadOnMetaDataChange;
QPointer<KIO::SimpleJob> m_kioJob;
};
bool AccessManager_isLocalRequest(const KUrl&);
}
#endif // KIO_ACCESSMANAGERREPLY_P_H
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Fri, Nov 1, 7:57 AM (1 d, 3 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
10074615
Default Alt Text
(37 KB)
Attached To
Mode
rKL kdelibs
Attached
Detach File
Event Timeline
Log In to Comment