+ issue #0001705: Download manager does not follow redirect (HTTP status 302)

This commit is contained in:
wmayer 2015-01-04 18:15:20 +01:00
parent 0d1fc35b20
commit c3102b69bc
4 changed files with 65 additions and 13 deletions

View File

@ -464,16 +464,16 @@ void DownloadItem::metaDataChanged()
header.chop(1); header.chop(1);
m_fileName = QUrl::fromPercentEncoding(header); m_fileName = QUrl::fromPercentEncoding(header);
} }
else { // Sometimes "filename=" and "filename*=UTF-8''" is set.
index = header.indexOf("filename*=UTF-8''"); // So, search for this too.
if (index >= 0) { index = header.indexOf("filename*=UTF-8''");
header = header.mid(index+17); if (index >= 0) {
if (header.startsWith("\"") || header.startsWith("'")) header = header.mid(index+17);
header = header.mid(1); if (header.startsWith("\"") || header.startsWith("'"))
if (header.endsWith("\"") || header.endsWith("'")) header = header.mid(1);
header.chop(1); if (header.endsWith("\"") || header.endsWith("'"))
m_fileName = QUrl::fromPercentEncoding(header); header.chop(1);
} m_fileName = QUrl::fromPercentEncoding(header);
} }
} }

View File

@ -71,6 +71,8 @@ DownloadManager::DownloadManager(QWidget *parent)
m_model = new DownloadModel(this); m_model = new DownloadModel(this);
ui->downloadsView->setModel(m_model); ui->downloadsView->setModel(m_model);
connect(ui->cleanupButton, SIGNAL(clicked()), this, SLOT(cleanup())); connect(ui->cleanupButton, SIGNAL(clicked()), this, SLOT(cleanup()));
connect(m_manager, SIGNAL(finished(QNetworkReply*)),
this, SLOT(replyFinished(QNetworkReply*)));
load(); load();
Gui::DockWindowManager* pDockMgr = Gui::DockWindowManager::instance(); Gui::DockWindowManager* pDockMgr = Gui::DockWindowManager::instance();
@ -108,11 +110,57 @@ int DownloadManager::activeDownloads() const
return count; return count;
} }
QUrl DownloadManager::redirectUrl(const QUrl& url) const
{
QUrl redirectUrl = url;
if (url.host() == QLatin1String("www.dropbox.com")) {
QList< QPair<QString, QString> > query = url.queryItems();
for (QList< QPair<QString, QString> >::iterator it = query.begin(); it != query.end(); ++it) {
if (it->first == QLatin1String("dl") && it->second == QLatin1String("0\r\n")) {
redirectUrl.removeQueryItem(QLatin1String("dl"));
redirectUrl.addQueryItem(QLatin1String("dl"), QLatin1String("1\r\n"));
break;
}
}
}
return redirectUrl;
}
void DownloadManager::replyFinished(QNetworkReply* reply)
{
// The 'requestFileName' is used to store the argument passed by 'download()'
// and to also distinguish between replies created by 'download()' and
// this method.
// Replies from this method shouldn't be further examined because it's not
// assumed to get re-directed urls over several steps.
QVariant var = reply->property("requestFileName");
if (var.isValid()) {
bool requestFileName = reply->property("requestFileName").toBool();
QUrl url = reply->url();
// If this is a redirected url use this instead
QUrl redirectUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
if (!redirectUrl.isEmpty()) {
url = redirectUrl;
}
// start the actual download now
handleUnsupportedContent(m_manager->get(QNetworkRequest(url)), requestFileName);
}
reply->deleteLater();
}
void DownloadManager::download(const QNetworkRequest &request, bool requestFileName) void DownloadManager::download(const QNetworkRequest &request, bool requestFileName)
{ {
if (request.url().isEmpty()) if (request.url().isEmpty())
return; return;
handleUnsupportedContent(m_manager->get(request), requestFileName);
// postpone this reply until we can examine it in replyFinished
QNetworkReply* reply = m_manager->get(request);
reply->setProperty("requestFileName", QVariant(requestFileName));
} }
void DownloadManager::handleUnsupportedContent(QNetworkReply *reply, bool requestFileName) void DownloadManager::handleUnsupportedContent(QNetworkReply *reply, bool requestFileName)

View File

@ -65,6 +65,7 @@ public:
RemovePolicy removePolicy() const; RemovePolicy removePolicy() const;
void setRemovePolicy(RemovePolicy policy); void setRemovePolicy(RemovePolicy policy);
void closeEvent(QCloseEvent* e); void closeEvent(QCloseEvent* e);
QUrl redirectUrl(const QUrl&) const;
public Q_SLOTS: public Q_SLOTS:
void download(const QNetworkRequest &request, bool requestFileName = false); void download(const QNetworkRequest &request, bool requestFileName = false);
@ -76,6 +77,7 @@ public Q_SLOTS:
private Q_SLOTS: private Q_SLOTS:
void save() const; void save() const;
void updateRow(); void updateRow();
void replyFinished(QNetworkReply* reply);
private: private:
void addItem(DownloadItem *item); void addItem(DownloadItem *item);

View File

@ -1585,7 +1585,8 @@ void MainWindow::loadUrls(App::Document* doc, const QList<QUrl>& url)
} }
} }
else if (it->scheme().toLower() == QLatin1String("http")) { else if (it->scheme().toLower() == QLatin1String("http")) {
Gui::Dialog::DownloadManager::getInstance()->download(*it); Gui::Dialog::DownloadManager* dm = Gui::Dialog::DownloadManager::getInstance();
dm->download(dm->redirectUrl(*it));
} }
//#ifndef QT_NO_OPENSSL //#ifndef QT_NO_OPENSSL
else if (it->scheme().toLower() == QLatin1String("https")) { else if (it->scheme().toLower() == QLatin1String("https")) {
@ -1594,7 +1595,8 @@ void MainWindow::loadUrls(App::Document* doc, const QList<QUrl>& url)
url.removeEncodedQueryItem(QByteArray("sid")); url.removeEncodedQueryItem(QByteArray("sid"));
url.setScheme(QLatin1String("http")); url.setScheme(QLatin1String("http"));
} }
Gui::Dialog::DownloadManager::getInstance()->download(url); Gui::Dialog::DownloadManager* dm = Gui::Dialog::DownloadManager::getInstance();
dm->download(dm->redirectUrl(url));
} }
//#endif //#endif
else if (it->scheme().toLower() == QLatin1String("ftp")) { else if (it->scheme().toLower() == QLatin1String("ftp")) {