diff --git a/src/gui/EditWidgetIcons.cpp b/src/gui/EditWidgetIcons.cpp index 58117679e..e0ac5227b 100644 --- a/src/gui/EditWidgetIcons.cpp +++ b/src/gui/EditWidgetIcons.cpp @@ -143,28 +143,54 @@ void EditWidgetIcons::setUrl(const QString &url) void EditWidgetIcons::downloadFavicon() { - if (m_networkOperation == nullptr) { - QUrl url(m_url); - QString path = "http://www.google.com/s2/favicons?domain=" + url.host(); + QUrl url = QUrl(m_url); + url.setPath("/favicon.ico"); + fetchFavicon(url); +} - m_networkOperation = m_networkAccessMngr->get(QNetworkRequest(path)); +void EditWidgetIcons::fetchFavicon(QUrl url) +{ + if (m_networkOperation == nullptr) { + m_networkOperation = m_networkAccessMngr->get(QNetworkRequest(url)); m_ui->faviconButton->setDisabled(true); } } -void EditWidgetIcons::abortFaviconDownload() +void EditWidgetIcons::fetchFaviconFromGoogle(QString domain) +{ + if (m_fallbackToGoogle) { + abortFaviconDownload(); + m_fallbackToGoogle = false; + fetchFavicon(QUrl("http://www.google.com/s2/favicons?domain=" + domain)); + } + else { + abortFaviconDownload(); + MessageBox::warning(this, tr("Error"), tr("Unable to fetch favicon.")); + } +} + +void EditWidgetIcons::abortFaviconDownload(bool clearRedirect) { if (m_networkOperation != nullptr) { m_networkOperation->abort(); m_networkOperation->deleteLater(); m_networkOperation = nullptr; } + + if (clearRedirect) { + if (!m_redirectUrl.isEmpty()) { + m_redirectUrl.clear(); + } + m_redirectCount = 0; + } + + m_fallbackToGoogle = true; m_ui->faviconButton->setDisabled(false); } void EditWidgetIcons::onRequestFinished(QNetworkReply *reply) { - if (!reply->error()) { + if (!reply->error()) { QImage image; image.loadFromData(reply->readAll()); @@ -177,10 +203,26 @@ void EditWidgetIcons::onRequestFinished(QNetworkReply *reply) QModelIndex index = m_customIconModel->indexFromUuid(uuid); m_ui->customIconsView->setCurrentIndex(index); m_ui->customIconsRadio->setChecked(true); + + abortFaviconDownload(); + } + else { + // Check if server has sent a redirect + QUrl possibleRedirectUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl(); + if (!possibleRedirectUrl.isEmpty() && possibleRedirectUrl != m_redirectUrl && m_redirectCount < 3) { + abortFaviconDownload(false); + m_redirectUrl = possibleRedirectUrl; + ++m_redirectCount; + fetchFavicon(m_redirectUrl); + } + else { // Webpage is trying to redirect back to itself or the maximum number of redirects has been reached, fallback to Google + fetchFaviconFromGoogle(reply->url().host()); + } } } - - abortFaviconDownload(); + else { // Request Error e.g. 404, fallback to Google + fetchFaviconFromGoogle(reply->url().host()); + } } void EditWidgetIcons::addCustomIcon() diff --git a/src/gui/EditWidgetIcons.h b/src/gui/EditWidgetIcons.h index 9330a4b85..508c56864 100644 --- a/src/gui/EditWidgetIcons.h +++ b/src/gui/EditWidgetIcons.h @@ -60,7 +60,9 @@ public Q_SLOTS: private Q_SLOTS: void downloadFavicon(); - void abortFaviconDownload(); + void fetchFavicon(QUrl url); + void fetchFaviconFromGoogle(QString domain); + void abortFaviconDownload(bool clearRedirect = true); void onRequestFinished(QNetworkReply *reply); void addCustomIcon(); void removeCustomIcon(); @@ -74,6 +76,9 @@ private: Database* m_database; Uuid m_currentUuid; QString m_url; + QUrl m_redirectUrl; + bool m_fallbackToGoogle = true; + unsigned short m_redirectCount = 0; DefaultIconModel* const m_defaultIconModel; CustomIconModel* const m_customIconModel; QNetworkAccessManager* const m_networkAccessMngr;