[WebKit-devel] KDE/kdelibs/kdewebkit
Dawit Alemayehu
adawit at kde.org
Wed May 19 02:08:45 CEST 2010
SVN commit 1128338 by adawit:
- Added a slot that properly handles the downloading of replies that might contain
"content-disposition" headers.
Note this new API was added this late in anticipation of fixing a critical
issue that is awaiting a pending patch upstream in QtWebKit. See
https://bugs.webkit.org/show_bug.cgi?id=37880
CCMAIL:kde-bindings at kde.org
CCMAIL:rekonq at kde.org
CCMAIL:webkit-devel at kde.org
M +88 -35 kwebpage.cpp
M +16 -5 kwebpage.h
--- trunk/KDE/kdelibs/kdewebkit/kwebpage.cpp #1128337:1128338
@@ -4,7 +4,7 @@
* Copyright (C) 2008 Dirk Mueller <mueller at kde.org>
* Copyright (C) 2008 Urs Wolfer <uwolfer @ kde.org>
* Copyright (C) 2008 Michael Howell <mhowell123 at gmail.com>
- * Copyright (C) 2009 Dawit Alemayehu <adawit at kde.org>
+ * Copyright (C) 2009,2010 Dawit Alemayehu <adawit at kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -49,18 +49,63 @@
#include <QtCore/QPointer>
#include <QtCore/QFileInfo>
#include <QtWebKit/QWebFrame>
+#include <QtNetwork/QNetworkReply>
-#define QL1(x) QLatin1String(x)
+#define QL1S(x) QLatin1String(x)
+#define QL1C(x) QLatin1Char(x)
+static KUrl promptUser (QWidget *parent, const KUrl& url, const QString& suggestedName)
+{
+ KUrl destUrl;
+ int result = KIO::R_OVERWRITE;
+ const QUrl fileName ((suggestedName.isEmpty() ? url.fileName() : suggestedName));
+ do {
+ destUrl = KFileDialog::getSaveFileName(fileName, QString(), parent);
+
+ if (destUrl.isLocalFile()) {
+ QFileInfo finfo (destUrl.toLocalFile());
+ if (finfo.exists()) {
+ QDateTime now = QDateTime::currentDateTime();
+ KIO::RenameDialog dlg (parent, i18n("Overwrite File?"), url, destUrl,
+ KIO::RenameDialog_Mode(KIO::M_OVERWRITE | KIO::M_SKIP),
+ -1, finfo.size(),
+ now.toTime_t(), finfo.created().toTime_t(),
+ now.toTime_t(), finfo.lastModified().toTime_t());
+ result = dlg.exec();
+ }
+ }
+ } while (result == KIO::R_CANCEL && destUrl.isValid());
+
+ return destUrl;
+}
+
+static bool downloadResource (const KUrl& srcUrl, const KIO::MetaData& metaData = KIO::MetaData(),
+ QWidget* parent = 0, const QString& suggestedName = QString())
+{
+ const KUrl& destUrl = promptUser(parent, srcUrl, suggestedName);
+
+ if (destUrl.isValid()) {
+ KIO::Job *job = KIO::file_copy(srcUrl, destUrl, -1, KIO::Overwrite);
+
+ if (!metaData.isEmpty())
+ job->setMetaData(metaData);
+
+ job->addMetaData(QL1S("MaxCacheSize"), QL1S("0")); // Don't store in http cache.
+ job->addMetaData(QL1S("cache"), QL1S("cache")); // Use entry from cache if available.
+ job->uiDelegate()->setAutoErrorHandlingEnabled(true);
+ return true;
+ }
+ return false;
+}
+
class KWebPage::KWebPagePrivate
{
public:
QPointer<KWebWallet> wallet;
};
-
KWebPage::KWebPage(QObject *parent, Integration flags)
:QWebPage(parent), d(new KWebPagePrivate)
{
@@ -162,43 +207,51 @@
void KWebPage::downloadRequest(const QNetworkRequest &request)
{
- KUrl destUrl;
- KUrl srcUrl (request.url());
- int result = KIO::R_OVERWRITE;
+ downloadResource(request.url(),
+ request.attribute(static_cast<QNetworkRequest::Attribute>(KIO::AccessManager::MetaData)).toMap(),
+ view());
+}
- do {
- destUrl = KFileDialog::getSaveFileName(srcUrl.fileName(), QString(), view());
-
- if (destUrl.isLocalFile()) {
- QFileInfo finfo (destUrl.toLocalFile());
- if (finfo.exists()) {
- QDateTime now = QDateTime::currentDateTime();
- KIO::RenameDialog dlg (view(), i18n("Overwrite File?"), srcUrl, destUrl,
- KIO::RenameDialog_Mode(KIO::M_OVERWRITE | KIO::M_SKIP),
- -1, finfo.size(),
- now.toTime_t(), finfo.created().toTime_t(),
- now.toTime_t(), finfo.lastModified().toTime_t());
- result = dlg.exec();
+void KWebPage::downloadUrl(const KUrl &url)
+{
+ downloadResource(url, KIO::MetaData(), view());
}
- }
- } while (result == KIO::R_CANCEL && destUrl.isValid());
- if (result == KIO::R_OVERWRITE && destUrl.isValid()) {
- KIO::Job *job = KIO::file_copy(srcUrl, destUrl, -1, KIO::Overwrite);
- QVariant attr = request.attribute(static_cast<QNetworkRequest::Attribute>(KIO::AccessManager::MetaData));
- if (attr.isValid() && attr.type() == QVariant::Map)
- job->setMetaData(KIO::MetaData(attr.toMap()));
+void KWebPage::downloadResponse(QNetworkReply *reply)
+{
+ // FIXME: Remove the next line of code once support for putting an ioslave is
+ // implemented in KIO::AccessManager which is waiting for an upstream fix.
+ // See https://bugs.webkit.org/show_bug.cgi?id=37880.
+ reply->abort();
- job->addMetaData(QL1("MaxCacheSize"), QL1("0")); // Don't store in http cache.
- job->addMetaData(QL1("cache"), QL1("cache")); // Use entry from cache if available.
- job->uiDelegate()->setAutoErrorHandlingEnabled(true);
+ QString suggestedFileName;
+ if (reply && reply->hasRawHeader("Content-Disposition")) {
+ KIO::MetaData metaData = reply->attribute(static_cast<QNetworkRequest::Attribute>(KIO::AccessManager::MetaData)).toMap();
+ if (metaData.value(QL1S("content-disposition-type")).compare(QL1S("attachment"), Qt::CaseInsensitive) == 0) {
+ suggestedFileName = metaData.value(QL1S("content-disposition-filename"));
+ } else {
+ const QString value = QL1S(reply->rawHeader("Content-Disposition").simplified());
+ if (value.startsWith(QL1S("attachment"), Qt::CaseInsensitive)) {
+ const int length = value.size();
+ int pos = value.indexOf(QL1S("filename"), 0, Qt::CaseInsensitive);
+ if (pos > -1) {
+ pos += 9;
+ while (pos < length && (value.at(pos) == QL1C(' ') || value.at(pos) == QL1C('=') || value.at(pos) == QL1C('"')))
+ pos++;
+
+ int endPos = pos;
+ while (endPos < length && value.at(endPos) != QL1C('"') && value.at(endPos) != QL1C(';'))
+ endPos++;
+
+ if (endPos > pos) {
+ suggestedFileName = value.mid(pos, (endPos-pos)).trimmed();
}
}
+ }
+ }
+ }
-void KWebPage::downloadUrl(const KUrl &url)
-{
- QNetworkRequest request (url);
- downloadRequest(request);
+ downloadResource(reply->url(), KIO::MetaData(), this->view(), suggestedFileName);
}
QString KWebPage::sessionMetaData(const QString &key) const
@@ -254,7 +307,7 @@
QString KWebPage::userAgentForUrl(const QUrl& _url) const
{
const KUrl url(_url);
- QString userAgent = KProtocolManager::userAgentForHost((url.isLocalFile() ? "localhost" : url.host()));
+ const QString userAgent = KProtocolManager::userAgentForHost((url.isLocalFile() ? QL1S("localhost") : url.host()));
if (userAgent == KProtocolManager::defaultUserAgent())
return QWebPage::userAgentForUrl(_url);
@@ -275,7 +328,7 @@
meta-data value to the current url for proper integration with KCookieJar...
*/
if (frame == mainFrame() && type != QWebPage::NavigationTypeReload) {
- setSessionMetaData(QL1("cross-domain"), request.url().toString());
+ setSessionMetaData(QL1S("cross-domain"), request.url().toString());
}
return QWebPage::acceptNavigationRequest(frame, request, type);
--- trunk/KDE/kdelibs/kdewebkit/kwebpage.h #1128337:1128338
@@ -4,7 +4,7 @@
* Copyright (C) 2008 Dirk Mueller <mueller at kde.org>
* Copyright (C) 2008 Urs Wolfer <uwolfer @ kde.org>
* Copyright (C) 2008 Michael Howell <mhowell123 at gmail.com>
- * Copyright (C) 2009 Dawit Alemayehu <adawit @ 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
@@ -126,7 +126,7 @@
* Downloads @p request using KIO.
*
* This slot first prompts the user where to put/save the requested
- * resource and then downloads using KIO::file_copy.
+ * resource and then downloads it using KIO.
*/
virtual void downloadRequest(const QNetworkRequest &request);
@@ -134,10 +134,20 @@
* Downloads @p url using KIO.
*
* This slot first prompts the user where to put/save the requested
- * resource and then downloads using KIO::file_copy.
+ * resource and then downloads it using KIO.
*/
virtual void downloadUrl(const KUrl &url);
+ /**
+ * Downloads the resource specified by @p reply using KIO.
+ *
+ * This slot first prompts the user where to save the requested resource
+ * and then downloads it using KIO.
+ *
+ * @since 4.5
+ */
+ void downloadResponse(QNetworkReply *reply);
+
protected:
/**
* Returns the value of the permanent (per session) meta data for the given @p key.
@@ -184,10 +194,11 @@
void removeRequestMetaData(const QString &key);
/**
- * Reimplemented for internal reasons, the API is not affected.
+ * This function is re-implemented to provide KDE user-agent management
+ * integration through KProtocolManager.
*
+ * @see KProtocolManager::userAgentForUrl.
* @see QWebPage::userAgentForUrl.
- * @internal
*/
virtual QString userAgentForUrl(const QUrl& url) const;
More information about the WebKit-devel
mailing list