summaryrefslogtreecommitdiff
path: root/src/webpage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/webpage.cpp')
-rw-r--r--src/webpage.cpp380
1 files changed, 212 insertions, 168 deletions
diff --git a/src/webpage.cpp b/src/webpage.cpp
index 507263cc..00745445 100644
--- a/src/webpage.cpp
+++ b/src/webpage.cpp
@@ -97,6 +97,72 @@ static bool domainSchemeMatch(const QUrl& u1, const QUrl& u2)
}
+// NOTE
+// This is heavily based on the one from KdeWebKit and
+// extended to provide the extra functionality we need:
+// 1. KGet Integration
+// 2. Save downloads history
+static bool downloadResource (const KUrl& srcUrl, const KIO::MetaData& metaData = KIO::MetaData(),
+ QWidget* parent = 0, const QString& suggestedName = QString())
+{
+ KUrl destUrl;
+
+ int result = KIO::R_OVERWRITE;
+ const QUrl fileName ((suggestedName.isEmpty() ? srcUrl.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?"), 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();
+ }
+ }
+ }
+ while (result == KIO::R_CANCEL && destUrl.isValid());
+
+ // Save download on history manager
+ Application::historyManager()->addDownload(srcUrl.pathOrUrl() , destUrl.pathOrUrl());
+
+ if (ReKonfig::kgetDownload())
+ {
+ //KGet integration:
+ if (!QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.kget"))
+ {
+ KToolInvocation::kdeinitExecWait("kget");
+ }
+ QDBusInterface kget("org.kde.kget", "/KGet", "org.kde.kget.main");
+ if (kget.isValid())
+ {
+ kget.call("addTransfer", srcUrl.prettyUrl(), destUrl.prettyUrl(), true);
+ return true;
+ }
+ return false;
+ }
+
+ 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;
+
+}
+
+
// ---------------------------------------------------------------------------------
@@ -246,111 +312,151 @@ void WebPage::handleUnsupportedContent(QNetworkReply *reply)
if (_protHandler.postHandling(reply->request(), mainFrame()))
return;
- if (reply->error() == QNetworkReply::NoError)
- {
- KUrl replyUrl = reply->url();
+ if (reply->error() != QNetworkReply::NoError)
+ return;
+
+ KUrl replyUrl = reply->url();
- // HACK -------------------------------------------
- QString mimeType;
- QString suggestedFileName;
-
- QString app = reply->header(QNetworkRequest::ContentTypeHeader).toString();
- QStringList headerList = app.split( ';' );
-
- if(headerList.count() > 0)
+ // HACK -------------------------------------------
+ // This is done to fix #231204 && #212808
+
+ QString mimeType;
+ QString suggestedFileName;
+
+ QString app = reply->header(QNetworkRequest::ContentTypeHeader).toString();
+ QStringList headerList = app.split( ';' );
+
+ if(headerList.count() > 0)
+ {
+ mimeType = headerList.takeFirst().trimmed();
+ Q_FOREACH(const QString &head, headerList)
{
- mimeType = headerList.takeFirst().trimmed();
- Q_FOREACH(const QString &head, headerList)
+ if( head.contains( QL1S("name") ) )
{
- if( head.contains( QL1S("name") ) )
- {
- // this is not so sure.. :)
- suggestedFileName = head;
- suggestedFileName = suggestedFileName.remove( QL1S("name=") );
- suggestedFileName = suggestedFileName.remove( '"' );
- suggestedFileName = suggestedFileName.trimmed();
- break;
- }
+ // this is not so sure.. :)
+ suggestedFileName = head;
+ suggestedFileName = suggestedFileName.remove( QL1S("name=") );
+ suggestedFileName = suggestedFileName.remove( '"' );
+ suggestedFileName = suggestedFileName.trimmed();
+ break;
}
}
- else
+ }
+ else
+ {
+ mimeType = reply->header(QNetworkRequest::ContentTypeHeader).toString();
+ }
+
+ // NOTE
+ // This part has been copied from KWebPage::downloadResponse code
+ if (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
{
- mimeType = reply->header(QNetworkRequest::ContentTypeHeader).toString();
+ 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();
+ }
+ }
+ }
}
- // ------------------------------------------------
-
- KService::Ptr appService = KMimeTypeTrader::self()->preferredService(mimeType);
-
- bool isLocal = replyUrl.isLocalFile();
+ }
+
+ kDebug() << "Detected MimeType = " << mimeType;
+ kDebug() << "Suggested File Name = " << suggestedFileName;
+ // ------------------------------------------------
+
+ KService::Ptr appService = KMimeTypeTrader::self()->preferredService(mimeType);
- if (appService.isNull()) // no service can handle this. We can just download it..
- {
- kDebug() << "no service can handle this. We can just download it..";
+ bool isLocal = replyUrl.isLocalFile();
- isLocal
- ? KMessageBox::sorry(view(), i18n("No service can handle this :("))
- : downloadThings(reply->request(), suggestedFileName);
+ if (appService.isNull()) // no service can handle this. We can just download it..
+ {
+ kDebug() << "no service can handle this. We can just download it..";
- return;
- }
+ isLocal
+ ? KMessageBox::sorry(view(), i18n("No service can handle this :("))
+ : downloadReply(reply, suggestedFileName);
- if (!isLocal)
- {
+ return;
+ }
- KParts::BrowserOpenOrSaveQuestion dlg(Application::instance()->mainWindow(), replyUrl, mimeType);
- if(!suggestedFileName.isEmpty())
- dlg.setSuggestedFileName(suggestedFileName);
-
- switch (dlg.askEmbedOrSave())
- {
- case KParts::BrowserOpenOrSaveQuestion::Save:
- kDebug() << "user choice: no services, just download!";
- downloadThings(reply->request(), suggestedFileName);
- return;
+ if (!isLocal)
+ {
- case KParts::BrowserOpenOrSaveQuestion::Cancel:
- return;
+ KParts::BrowserOpenOrSaveQuestion dlg(Application::instance()->mainWindow(), replyUrl, mimeType);
+ if(!suggestedFileName.isEmpty())
+ dlg.setSuggestedFileName(suggestedFileName);
+
+ switch (dlg.askEmbedOrSave())
+ {
+ case KParts::BrowserOpenOrSaveQuestion::Save:
+ kDebug() << "user choice: no services, just download!";
+ downloadReply(reply, suggestedFileName);
+ return;
- default: // non extant case
- break;
- }
- }
+ case KParts::BrowserOpenOrSaveQuestion::Cancel:
+ return;
- // case KParts::BrowserRun::Embed
- KService::List partServices = KMimeTypeTrader::self()->query(mimeType, QL1S("KParts/ReadOnlyPart"));
- if (partServices.count() > 0)
- {
- QString p = replyUrl.pathOrUrl();
-
- // A part can handle this. Embed it!
- QString html;
- html += "<html>";
- html += "<head>";
- html += "<title>";
- html += p;
- html += "</title>";
- html += "<style type=\"text/css\">";
- html += "* { border: 0; padding: 0; margin: 0; }";
- html += "</style>";
- html += "</head>";
- html += "<body>";
- html += "<object type=\"" + mimeType + "\" data=\"" + p + "\" width=\"100%\" height=\"100%\" />";
- html += "</body>";
- html += "</html>";
-
- mainFrame()->setHtml(html);
- _isOnRekonqPage = true;
- Application::instance()->mainWindow()->mainView()->urlBar()->setQUrl(replyUrl);
- Application::instance()->mainWindow()->updateActions();
- }
- else
- {
- // No parts, just app services. Load it!
- KRun::run(*appService, replyUrl, 0);
+ default: // non extant case
+ break;
}
+ }
- return;
+ // case KParts::BrowserRun::Embed
+ KService::List partServices = KMimeTypeTrader::self()->query(mimeType, QL1S("KParts/ReadOnlyPart"));
+ if (partServices.count() > 0)
+ {
+ QString p = replyUrl.pathOrUrl();
+
+ // A part can handle this. Embed it!
+ QString html;
+ html += "<html>";
+ html += "<head>";
+ html += "<title>";
+ html += p;
+ html += "</title>";
+ html += "<style type=\"text/css\">";
+ html += "* { border: 0; padding: 0; margin: 0; }";
+ html += "</style>";
+ html += "</head>";
+ html += "<body>";
+ html += "<object type=\"" + mimeType + "\" data=\"" + p + "\" width=\"100%\" height=\"100%\" />";
+ html += "</body>";
+ html += "</html>";
+
+ mainFrame()->setHtml(html);
+ _isOnRekonqPage = true;
+ Application::instance()->mainWindow()->mainView()->urlBar()->setQUrl(replyUrl);
+ Application::instance()->mainWindow()->updateActions();
}
+ else
+ {
+ // No parts, just app services. Load it!
+ KRun::run(*appService, replyUrl, 0);
+ }
+
+ return;
}
@@ -402,24 +508,28 @@ void WebPage::manageNetworkErrors(QNetworkReply *reply)
}
break;
+ case QNetworkReply::OperationCanceledError: // operation canceled via abort() or close() calls
+ // ignore this..
+ return;
+
case QNetworkReply::ContentAccessDenied: // access to remote content denied (similar to HTTP error 401)
kDebug() << "We (hopefully) are managing this through the adblock :)";
break;
case QNetworkReply::UnknownNetworkError: // unknown network-related error detected
- if (_protHandler.postHandling(reply->request(), mainFrame()))
- break;
+ _protHandler.postHandling(reply->request(), mainFrame());
+ return;
case QNetworkReply::ConnectionRefusedError: // remote server refused connection
case QNetworkReply::HostNotFoundError: // invalid hostname
case QNetworkReply::TimeoutError: // connection time out
- case QNetworkReply::OperationCanceledError: // operation canceled via abort() or close() calls
case QNetworkReply::ProxyNotFoundError: // invalid proxy hostname
case QNetworkReply::ContentOperationNotPermittedError: // operation requested on remote content not permitted
case QNetworkReply::ContentNotFoundError: // remote content not found on server (similar to HTTP error 404)
case QNetworkReply::ProtocolUnknownError: // Unknown protocol
case QNetworkReply::ProtocolInvalidOperationError: // requested operation is invalid for this protocol
+ kDebug() << "ERROR " << reply->error() << ": " << reply->errorString();
if (reply->url() == _loadingUrl)
{
mainFrame()->setHtml(errorPage(reply));
@@ -478,89 +588,23 @@ QString WebPage::errorPage(QNetworkReply *reply)
}
-// WARNING
-// this code is actually copied from KWebPage::downloadRequest to save
-// downloads data before. If you have some better ideas about,
-// feel free to let us know about :)
-void WebPage::downloadThings(const QNetworkRequest &request, const QString &suggestedFileName)
+void WebPage::downloadReply(const QNetworkReply *reply, const QString &suggestedFileName)
{
- KUrl destUrl;
- KUrl srcUrl(request.url());
-
- if( !ReKonfig::kgetDownload() && suggestedFileName.isEmpty() )
- {
- kDebug() << "Using KWebPage downloadRequest..";
- Application::historyManager()->addDownload(srcUrl.pathOrUrl() , destUrl.pathOrUrl());
- KWebPage::downloadRequest(request);
- return;
- }
-
- int result = KIO::R_OVERWRITE;
-
- do
- {
- QString fName = suggestedFileName.isEmpty()
- ? srcUrl.fileName()
- : suggestedFileName;
-
- destUrl = KFileDialog::getSaveFileName(fName, QString(), view());
-
- if (destUrl.isLocalFile())
- {
- QFileInfo finfo(destUrl.toLocalFile());
- if (finfo.exists())
- {
- QDateTime now = QDateTime::currentDateTime();
- QPointer<KIO::RenameDialog> dlg = new KIO::RenameDialog(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();
- delete dlg;
- }
- }
- }
- while (result == KIO::R_CANCEL && destUrl.isValid());
+ downloadResource( reply->url(), KIO::MetaData(), view(), suggestedFileName);
+}
- if (result == KIO::R_OVERWRITE && destUrl.isValid())
- {
- // now store data
- // now, destUrl, srcUrl
- Application::historyManager()->addDownload(srcUrl.pathOrUrl() , destUrl.pathOrUrl());
- if (ReKonfig::kgetDownload())
- {
- //KGet integration:
- if (!QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.kget"))
- {
- KToolInvocation::kdeinitExecWait("kget");
- }
- QDBusInterface kget("org.kde.kget", "/KGet", "org.kde.kget.main");
- if (kget.isValid())
- {
- kget.call("addTransfer", srcUrl.prettyUrl(), destUrl.prettyUrl(), true);
- return;
- }
- }
+void WebPage::downloadRequest(const QNetworkRequest &request)
+{
+ downloadResource(request.url(),
+ request.attribute(static_cast<QNetworkRequest::Attribute>(KIO::AccessManager::MetaData)).toMap(),
+ view());
+}
- // else, use KIO or fallback to it
- 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()));
- 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);
- }
+void WebPage::downloadUrl(const KUrl &url)
+{
+ downloadResource( url, KIO::MetaData(), view() );
}