00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "accessmanager.h"
00025 #include "accessmanagerreply_p.h"
00026
00027 #include <kdebug.h>
00028 #include <kio/job.h>
00029 #include <kio/scheduler.h>
00030 #include <kconfiggroup.h>
00031 #include <ksharedconfig.h>
00032
00033 #include <QtCore/QUrl>
00034 #include <QtNetwork/QNetworkReply>
00035 #include <QtNetwork/QNetworkRequest>
00036 #include <QtDBus/QDBusInterface>
00037 #include <QtDBus/QDBusConnection>
00038 #include <QtDBus/QDBusReply>
00039
00040 #define QL1S(x) QLatin1String(x)
00041
00042
00043 namespace KIO {
00044
00045 class AccessManager::AccessManagerPrivate
00046 {
00047 public:
00048 AccessManagerPrivate():externalContentAllowed(true) {}
00049 KIO::MetaData metaDataForRequest(QNetworkRequest request);
00050 bool isRequestAllowed(const QUrl& url) const;
00051
00052 bool externalContentAllowed;
00053 KIO::MetaData requestMetaData;
00054 KIO::MetaData sessionMetaData;
00055 };
00056
00057 namespace Integration {
00058
00059 class CookieJar::CookieJarPrivate
00060 {
00061 public:
00062 CookieJarPrivate(): windowId((WId)-1), enabled(true) {}
00063
00064 WId windowId;
00065 bool enabled;
00066 };
00067
00068 }
00069
00070 }
00071
00072 using namespace KIO;
00073
00074 AccessManager::AccessManager(QObject *parent)
00075 :QNetworkAccessManager(parent), d(new AccessManager::AccessManagerPrivate())
00076 {
00077
00078 setCookieJar(new KIO::Integration::CookieJar);
00079 }
00080
00081 AccessManager::~AccessManager()
00082 {
00083 delete d;
00084 }
00085
00086 void AccessManager::setExternalContentAllowed(bool allowed)
00087 {
00088 d->externalContentAllowed = allowed;
00089 }
00090
00091 bool AccessManager::isExternalContentAllowed() const
00092 {
00093 return d->externalContentAllowed;
00094 }
00095
00096 void AccessManager::setCookieJarWindowId(WId id)
00097 {
00098 KIO::Integration::CookieJar *jar = qobject_cast<KIO::Integration::CookieJar *> (cookieJar());
00099 if (jar) {
00100 jar->setWindowId(id);
00101 d->sessionMetaData.insert(QL1S("window-id"), QString::number((qlonglong)id));
00102 }
00103 }
00104
00105 WId AccessManager::cookieJarWindowid() const
00106 {
00107 KIO::Integration::CookieJar *jar = qobject_cast<KIO::Integration::CookieJar *> (cookieJar());
00108 if (jar)
00109 return jar->windowId();
00110
00111 return 0;
00112 }
00113
00114 KIO::MetaData& AccessManager::requestMetaData()
00115 {
00116 return d->requestMetaData;
00117 }
00118
00119 KIO::MetaData& AccessManager::sessionMetaData()
00120 {
00121 return d->sessionMetaData;
00122 }
00123
00124 QNetworkReply *AccessManager::createRequest(Operation op, const QNetworkRequest &req, QIODevice *outgoingData)
00125 {
00126 KIO::SimpleJob *kioJob = 0;
00127 const QUrl reqUrl (req.url());
00128
00129 if ( !d->isRequestAllowed(reqUrl) ) {
00130 kDebug( 7044 ) << "Blocked: " << reqUrl;
00131
00132 return new KDEPrivate::AccessManagerReply(op, req, kioJob, this);
00133 }
00134
00135 switch (op) {
00136 case HeadOperation: {
00137 kDebug( 7044 ) << "HeadOperation:" << reqUrl;
00138 kioJob = KIO::mimetype(reqUrl, KIO::HideProgressInfo);
00139 break;
00140 }
00141 case GetOperation: {
00142 kDebug( 7044 ) << "GetOperation:" << reqUrl;
00143 if (!reqUrl.path().isEmpty() || reqUrl.host().isEmpty())
00144 kioJob = KIO::get(reqUrl, KIO::NoReload, KIO::HideProgressInfo);
00145 else
00146 kioJob = KIO::stat(reqUrl, KIO::HideProgressInfo);
00147 break;
00148 }
00149 case PutOperation: {
00150 kDebug( 7044 ) << "PutOperation:" << reqUrl;
00151 kioJob = KIO::put(reqUrl, -1, KIO::HideProgressInfo);
00152 break;
00153 }
00154 case PostOperation: {
00155 kDebug( 7044 ) << "PostOperation:" << reqUrl;
00156 kioJob = KIO::http_post(reqUrl, outgoingData->readAll(), KIO::HideProgressInfo);
00157 break;
00158 }
00159 default:
00160 kDebug( 7044 ) << "Unknown operation";
00161 return 0;
00162 }
00163
00164 kioJob->setRedirectionHandlingEnabled(false);
00165 KIO::Scheduler::scheduleJob(kioJob);
00166 KDEPrivate::AccessManagerReply *reply = new KDEPrivate::AccessManagerReply(op, req, kioJob, this);
00167
00168 kioJob->addMetaData(d->metaDataForRequest(req));
00169
00170 if ( op == PostOperation && !kioJob->metaData().contains("content-type")) {
00171 QVariant header = req.header(QNetworkRequest::ContentTypeHeader);
00172 if (header.isValid())
00173 kioJob->addMetaData(QL1S("content-type"),
00174 QString::fromLatin1("Content-Type: %1").arg(header.toString()));
00175 else
00176 kioJob->addMetaData(QL1S("content-type"),
00177 QL1S("Content-Type: application/x-www-form-urlencoded"));
00178 }
00179
00180 return reply;
00181 }
00182
00183 KIO::MetaData AccessManager::AccessManagerPrivate::metaDataForRequest(QNetworkRequest request)
00184 {
00185 KIO::MetaData metaData;
00186
00187
00188 QVariant userMetaData = request.attribute (static_cast<QNetworkRequest::Attribute>(MetaData));
00189 if (userMetaData.isValid() && userMetaData.type() == QVariant::Map) {
00190 metaData += userMetaData.toMap();
00191 }
00192
00193 metaData.insert("PropagateHttpHeader", "true");
00194
00195 if (request.hasRawHeader("User-Agent")) {
00196 metaData.insert("UserAgent", request.rawHeader("User-Agent"));
00197 request.setRawHeader("User-Agent", QByteArray());
00198 }
00199
00200 if (request.hasRawHeader("Accept")) {
00201 metaData.insert("accept", request.rawHeader("Accept"));
00202 request.setRawHeader("Accept", QByteArray());
00203 }
00204
00205 if (request.hasRawHeader("Referer")) {
00206 metaData.insert(QL1S("referrer"), request.rawHeader("Referer"));
00207 request.setRawHeader("Referer", QByteArray());
00208 }
00209
00210 if (request.hasRawHeader("Content-Type")) {
00211 metaData.insert(QL1S("content-type"), request.rawHeader("Content-Type"));
00212 request.setRawHeader("Content-Type", QByteArray());
00213 }
00214
00215 request.setRawHeader("content-length", QByteArray());
00216 request.setRawHeader("Connection", QByteArray());
00217 request.setRawHeader("If-None-Match", QByteArray());
00218 request.setRawHeader("If-Modified-Since", QByteArray());
00219
00220 QStringList customHeaders;
00221 Q_FOREACH(const QByteArray &key, request.rawHeaderList()) {
00222 const QByteArray value = request.rawHeader(key);
00223 if (value.length())
00224 customHeaders << (key + ": " + value);
00225 }
00226
00227 if (!customHeaders.isEmpty())
00228 metaData.insert("customHTTPHeader", customHeaders.join("\r\n"));
00229
00230
00231 if (!requestMetaData.isEmpty()) {
00232 metaData += requestMetaData;
00233
00234 requestMetaData.clear();
00235 }
00236
00237
00238 if (!sessionMetaData.isEmpty())
00239 metaData += sessionMetaData;
00240
00241 return metaData;
00242 }
00243
00244 bool AccessManager::AccessManagerPrivate::isRequestAllowed(const QUrl& url) const
00245 {
00246 const QString scheme (url.scheme());
00247
00248 return (externalContentAllowed || scheme == QL1S("file") || scheme == QL1S("data"));
00249 }
00250
00251
00252 using namespace KIO::Integration;
00253
00254 CookieJar::CookieJar(QObject* parent)
00255 :QNetworkCookieJar(parent), d(new CookieJar::CookieJarPrivate) {
00256 reparseConfiguration();
00257 }
00258
00259 CookieJar::~CookieJar() {
00260 delete d;
00261 }
00262
00263 WId CookieJar::windowId() const {
00264 return d->windowId;
00265 }
00266
00267 QList<QNetworkCookie> CookieJar::cookiesForUrl(const QUrl &url) const {
00268 QList<QNetworkCookie> cookieList;
00269
00270 if (d->enabled) {
00271 QDBusInterface kcookiejar("org.kde.kded", "/modules/kcookiejar", "org.kde.KCookieServer");
00272 QDBusReply<QString> reply = kcookiejar.call("findDOMCookies", url.toString(), (qlonglong)d->windowId);
00273
00274 if (reply.isValid()) {
00275 cookieList << reply.value().toUtf8();
00276
00277 } else {
00278 kWarning() << "Unable to communicate with the cookiejar!";
00279 }
00280 }
00281
00282 return cookieList;
00283 }
00284
00285 bool CookieJar::setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, const QUrl &url) {
00286 if (d->enabled) {
00287 QDBusInterface kcookiejar("org.kde.kded", "/modules/kcookiejar", "org.kde.KCookieServer");
00288
00289 QByteArray cookieHeader;
00290 Q_FOREACH(const QNetworkCookie &cookie, cookieList) {
00291 cookieHeader = "Set-Cookie: ";
00292 cookieHeader += cookie.toRawForm();
00293 kcookiejar.call("addCookies", url.toString(), cookieHeader, (qlonglong)d->windowId);
00294
00295 }
00296
00297 return !kcookiejar.lastError().isValid();
00298 }
00299
00300 return false;
00301 }
00302
00303 void CookieJar::setWindowId(WId id) {
00304 d->windowId = id;
00305 }
00306
00307 void CookieJar::reparseConfiguration() {
00308 KConfigGroup cfg = KSharedConfig::openConfig("kcookiejarrc", KConfig::NoGlobals)->group("Cookie Policy");
00309 d->enabled = cfg.readEntry("Cookies", true);
00310 }
00311
00312
00313 #include "accessmanager.moc"