Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/keepassxreboot/keepassxc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/EditWidgetIcons.cpp')
-rw-r--r--src/gui/EditWidgetIcons.cpp189
1 files changed, 75 insertions, 114 deletions
diff --git a/src/gui/EditWidgetIcons.cpp b/src/gui/EditWidgetIcons.cpp
index 7c01b31f1..1c33150b5 100644
--- a/src/gui/EditWidgetIcons.cpp
+++ b/src/gui/EditWidgetIcons.cpp
@@ -30,11 +30,10 @@
#include "gui/IconModels.h"
#include "gui/MessageBox.h"
-#ifdef WITH_XC_HTTP
-#include "http/qhttp/qhttpclient.hpp"
-#include "http/qhttp/qhttpclientresponse.hpp"
-
-using namespace qhttp::client;
+#ifdef WITH_XC_NETWORKING
+#include <curl/curl.h>
+#include "core/AsyncTask.h"
+#undef MessageBox
#endif
IconStruct::IconStruct()
@@ -49,11 +48,6 @@ EditWidgetIcons::EditWidgetIcons(QWidget* parent)
, m_database(nullptr)
, m_defaultIconModel(new DefaultIconModel(this))
, m_customIconModel(new CustomIconModel(this))
- #ifdef WITH_XC_HTTP
- , m_fallbackToGoogle(true)
- , m_redirectCount(0)
- , m_httpClient(nullptr)
- #endif
{
m_ui->setupUi(this);
@@ -89,17 +83,14 @@ IconStruct EditWidgetIcons::state()
QModelIndex index = m_ui->defaultIconsView->currentIndex();
if (index.isValid()) {
iconStruct.number = index.row();
- }
- else {
+ } else {
Q_ASSERT(false);
}
- }
- else {
+ } else {
QModelIndex index = m_ui->customIconsView->currentIndex();
if (index.isValid()) {
iconStruct.uuid = m_customIconModel->uuidFromIndex(m_ui->customIconsView->currentIndex());
- }
- else {
+ } else {
iconStruct.number = -1;
}
}
@@ -130,14 +121,12 @@ void EditWidgetIcons::load(const Uuid& currentUuid, Database* database, const Ic
int iconNumber = iconStruct.number;
m_ui->defaultIconsView->setCurrentIndex(m_defaultIconModel->index(iconNumber, 0));
m_ui->defaultIconsRadio->setChecked(true);
- }
- else {
+ } else {
QModelIndex index = m_customIconModel->indexFromUuid(iconUuid);
if (index.isValid()) {
m_ui->customIconsView->setCurrentIndex(index);
m_ui->customIconsRadio->setChecked(true);
- }
- else {
+ } else {
m_ui->defaultIconsView->setCurrentIndex(m_defaultIconModel->index(0, 0));
m_ui->defaultIconsRadio->setChecked(true);
}
@@ -146,10 +135,9 @@ void EditWidgetIcons::load(const Uuid& currentUuid, Database* database, const Ic
void EditWidgetIcons::setUrl(const QString& url)
{
-#ifdef WITH_XC_HTTP
+#ifdef WITH_XC_NETWORKING
m_url = url;
m_ui->faviconButton->setVisible(!url.isEmpty());
- resetFaviconDownload();
#else
Q_UNUSED(url);
m_ui->faviconButton->setVisible(false);
@@ -158,108 +146,83 @@ void EditWidgetIcons::setUrl(const QString& url)
void EditWidgetIcons::downloadFavicon()
{
-#ifdef WITH_XC_HTTP
+#ifdef WITH_XC_NETWORKING
+ m_ui->faviconButton->setDisabled(true);
+
QUrl url = QUrl(m_url);
url.setPath("/favicon.ico");
- fetchFavicon(url);
+ // Attempt to simply load the favicon.ico file
+ QImage image = fetchFavicon(url);
+ if (!image.isNull()) {
+ addCustomIcon(image);
+ } else if (config()->get("security/IconDownloadFallbackToGoogle", false).toBool()) {
+ QUrl faviconUrl = QUrl("https://www.google.com/s2/favicons");
+ faviconUrl.setQuery("domain=" + QUrl::toPercentEncoding(url.host()));
+ // Attempt to load favicon from Google
+ image = fetchFavicon(faviconUrl);
+ if (!image.isNull()) {
+ addCustomIcon(image);
+ } else {
+ emit messageEditEntry(tr("Unable to fetch favicon."), MessageWidget::Error);
+ }
+ } else {
+ emit messageEditEntry(tr("Unable to fetch favicon.") + "\n" +
+ tr("Hint: You can enable Google as a fallback under Tools>Settings>Security"),
+ MessageWidget::Error);
+ }
+
+ m_ui->faviconButton->setDisabled(false);
#endif
}
-#ifdef WITH_XC_HTTP
-void EditWidgetIcons::fetchFavicon(const QUrl& url)
+#ifdef WITH_XC_NETWORKING
+namespace {
+std::size_t writeCurlResponse(char* ptr, std::size_t size, std::size_t nmemb, void* data)
{
- if (nullptr == m_httpClient) {
- m_httpClient = new QHttpClient(this);
- }
+ QByteArray* response = static_cast<QByteArray*>(data);
+ std::size_t realsize = size * nmemb;
+ response->append(ptr, realsize);
+ return realsize;
+}
+}
- bool requestMade = m_httpClient->request(qhttp::EHTTP_GET, url, [this, url](QHttpResponse* response) {
- if (m_database == nullptr) {
- return;
+QImage EditWidgetIcons::fetchFavicon(const QUrl& url)
+{
+ QImage image;
+ CURL* curl = curl_easy_init();
+ if (curl) {
+ QByteArray imagedata;
+ QByteArray baUrl = url.url().toLatin1();
+
+ curl_easy_setopt(curl, CURLOPT_URL, baUrl.data());
+ curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 5L);
+ curl_easy_setopt(curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
+ curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
+ curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 5L);
+ curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, &imagedata);
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &writeCurlResponse);
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
+#ifdef Q_OS_WIN
+ const QDir appDir = QFileInfo(QCoreApplication::applicationFilePath()).absoluteDir();
+ if (appDir.exists("ssl\\certs")) {
+ curl_easy_setopt(curl, CURLOPT_CAINFO, (appDir.absolutePath() + "\\ssl\\certs\\ca-bundle.crt").toLatin1().data());
}
+#endif
- response->collectData();
- response->onEnd([this, response, &url]() {
- int status = response->status();
- if (200 == status) {
- QImage image;
- image.loadFromData(response->collectedData());
-
- if (!image.isNull()) {
- addCustomIcon(image);
- resetFaviconDownload();
- } else {
- fetchFaviconFromGoogle(url.host());
- }
- } else if (301 == status || 302 == status) {
- // Check if server has sent a redirect
- QUrl possibleRedirectUrl(response->headers().value("location", ""));
- if (!possibleRedirectUrl.isEmpty() && possibleRedirectUrl != m_redirectUrl && m_redirectCount < 3) {
- resetFaviconDownload(false);
- m_redirectUrl = possibleRedirectUrl;
- ++m_redirectCount;
- fetchFavicon(m_redirectUrl);
- } else {
- // website is trying to redirect to itself or
- // maximum number of redirects has been reached, fall back to Google
- fetchFaviconFromGoogle(url.host());
- }
- } else {
- fetchFaviconFromGoogle(url.host());
- }
+ // Perform the request in another thread
+ CURLcode result = AsyncTask::runAndWaitForFuture([curl]() {
+ return curl_easy_perform(curl);
});
- });
- if (!requestMade) {
- resetFaviconDownload();
- return;
- }
-
- m_httpClient->setConnectingTimeOut(5000, [this]() {
- QUrl tempurl = QUrl(m_url);
- if (tempurl.scheme() == "http") {
- resetFaviconDownload();
- emit messageEditEntry(tr("Unable to fetch favicon.") + "\n" +
- tr("Hint: You can enable Google as a fallback under Tools>Settings>Security"),
- MessageWidget::Error);
- } else {
- tempurl.setScheme("http");
- m_url = tempurl.url();
- tempurl.setPath("/favicon.ico");
- fetchFavicon(tempurl);
+ if (result == CURLE_OK) {
+ image.loadFromData(imagedata);
}
- });
-
- m_ui->faviconButton->setDisabled(true);
-}
-
-void EditWidgetIcons::fetchFaviconFromGoogle(const QString& domain)
-{
- if (config()->get("security/IconDownloadFallbackToGoogle", false).toBool() && m_fallbackToGoogle) {
- resetFaviconDownload();
- m_fallbackToGoogle = false;
- QUrl faviconUrl = QUrl("https://www.google.com/s2/favicons");
- faviconUrl.setQuery("domain=" + QUrl::toPercentEncoding(domain));
- fetchFavicon(faviconUrl);
- } else {
- resetFaviconDownload();
- emit messageEditEntry(tr("Unable to fetch favicon."), MessageWidget::Error);
- }
-}
-void EditWidgetIcons::resetFaviconDownload(bool clearRedirect)
-{
- if (clearRedirect) {
- m_redirectUrl.clear();
- m_redirectCount = 0;
+ curl_easy_cleanup(curl);
}
- if (nullptr != m_httpClient) {
- m_httpClient->deleteLater();
- m_httpClient = nullptr;
- }
-
- m_fallbackToGoogle = true;
- m_ui->faviconButton->setDisabled(false);
+ return image;
}
#endif
@@ -282,7 +245,7 @@ void EditWidgetIcons::addCustomIconFromFile()
}
}
-void EditWidgetIcons::addCustomIcon(const QImage &icon)
+void EditWidgetIcons::addCustomIcon(const QImage& icon)
{
if (m_database) {
Uuid uuid = m_database->metadata()->findCustomIcon(icon);
@@ -393,8 +356,7 @@ void EditWidgetIcons::updateWidgetsDefaultIcons(bool check)
QModelIndex index = m_ui->defaultIconsView->currentIndex();
if (!index.isValid()) {
m_ui->defaultIconsView->setCurrentIndex(m_defaultIconModel->index(0, 0));
- }
- else {
+ } else {
m_ui->defaultIconsView->setCurrentIndex(index);
}
m_ui->customIconsView->selectionModel()->clearSelection();
@@ -409,8 +371,7 @@ void EditWidgetIcons::updateWidgetsCustomIcons(bool check)
QModelIndex index = m_ui->customIconsView->currentIndex();
if (!index.isValid()) {
m_ui->customIconsView->setCurrentIndex(m_customIconModel->index(0, 0));
- }
- else {
+ } else {
m_ui->customIconsView->setCurrentIndex(index);
}
m_ui->defaultIconsView->selectionModel()->clearSelection();