Page MenuHomePhorge

No OneTemporary

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

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)

Event Timeline