Only reconnect when relevant settings changed
This commit is contained in:
parent
d66bedf988
commit
7755e97c5f
|
@ -138,6 +138,18 @@ void SyncthingConnection::connect()
|
|||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Applies the specified configuration and tries to reconnect via reconnect() if properties requiring reconnect
|
||||
* to take effect have changed.
|
||||
* \remarks The expected SSL errors of the specified configuration are updated accordingly.
|
||||
*/
|
||||
void SyncthingConnection::connect(SyncthingConnectionSettings &connectionSettings)
|
||||
{
|
||||
if(applySettings(connectionSettings)) {
|
||||
reconnect();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Disconnects. Does nothing if not connected.
|
||||
*/
|
||||
|
@ -620,8 +632,9 @@ QMetaObject::Connection SyncthingConnection::requestLog(std::function<void (cons
|
|||
* - Loading the certificate is only possible if the connection object is configured
|
||||
* to connect to the locally running Syncthing instance. Otherwise this method will
|
||||
* only do the cleanup of previous certificates but not emit any errors.
|
||||
* \returns Returns whether a certificate could be loaded.
|
||||
*/
|
||||
void SyncthingConnection::loadSelfSignedCertificate()
|
||||
bool SyncthingConnection::loadSelfSignedCertificate()
|
||||
{
|
||||
// ensure current exceptions for self-signed certificates are cleared
|
||||
m_expectedSslErrors.clear();
|
||||
|
@ -629,31 +642,33 @@ void SyncthingConnection::loadSelfSignedCertificate()
|
|||
// not required when not using secure connection
|
||||
const QUrl syncthingUrl(m_syncthingUrl);
|
||||
if(!syncthingUrl.scheme().endsWith(QChar('s'))) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// only possible if the Syncthing instance is running on the local machine
|
||||
if(!isLocal(syncthingUrl)) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// find cert
|
||||
const QString certPath = !m_configDir.isEmpty() ? (m_configDir + QStringLiteral("/https-cert.pem")) : SyncthingConfig::locateHttpsCertificate();
|
||||
if(certPath.isEmpty()) {
|
||||
emit error(tr("Unable to locate certificate used by Syncthing GUI."), SyncthingErrorCategory::OverallConnection);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
// add exception
|
||||
const QList<QSslCertificate> cert = QSslCertificate::fromPath(certPath);
|
||||
if(cert.isEmpty()) {
|
||||
const QList<QSslCertificate> certs = QSslCertificate::fromPath(certPath);
|
||||
if(certs.isEmpty()) {
|
||||
emit error(tr("Unable to load certificate used by Syncthing GUI."), SyncthingErrorCategory::OverallConnection);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
const QSslCertificate &cert = certs.at(0);
|
||||
m_expectedSslErrors.reserve(4);
|
||||
m_expectedSslErrors << QSslError(QSslError::UnableToGetLocalIssuerCertificate, cert.at(0));
|
||||
m_expectedSslErrors << QSslError(QSslError::UnableToVerifyFirstCertificate, cert.at(0));
|
||||
m_expectedSslErrors << QSslError(QSslError::SelfSignedCertificate, cert.at(0));
|
||||
m_expectedSslErrors << QSslError(QSslError::HostNameMismatch, cert.at(0));
|
||||
m_expectedSslErrors << QSslError(QSslError::UnableToGetLocalIssuerCertificate, cert)
|
||||
<< QSslError(QSslError::UnableToVerifyFirstCertificate, cert)
|
||||
<< QSslError(QSslError::SelfSignedCertificate, cert)
|
||||
<< QSslError(QSslError::HostNameMismatch, cert);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -661,26 +676,46 @@ void SyncthingConnection::loadSelfSignedCertificate()
|
|||
* \remarks
|
||||
* - The expected SSL errors of the specified configuration are updated accordingly.
|
||||
* - The configuration is not used instantly. It will be used on the next reconnect.
|
||||
* \returns Returns whether at least one property requiring a reconnect to take effect has changed.
|
||||
* \sa reconnect()
|
||||
*/
|
||||
void SyncthingConnection::applySettings(SyncthingConnectionSettings &connectionSettings)
|
||||
bool SyncthingConnection::applySettings(SyncthingConnectionSettings &connectionSettings)
|
||||
{
|
||||
setSyncthingUrl(connectionSettings.syncthingUrl);
|
||||
setApiKey(connectionSettings.apiKey);
|
||||
if(connectionSettings.authEnabled) {
|
||||
setCredentials(connectionSettings.userName, connectionSettings.password);
|
||||
} else {
|
||||
setCredentials(QString(), QString());
|
||||
bool reconnectRequired = false;
|
||||
if(syncthingUrl() != connectionSettings.syncthingUrl) {
|
||||
setSyncthingUrl(connectionSettings.syncthingUrl);
|
||||
reconnectRequired = true;
|
||||
}
|
||||
if(apiKey() != connectionSettings.apiKey) {
|
||||
setApiKey(connectionSettings.apiKey);
|
||||
reconnectRequired = true;
|
||||
}
|
||||
if((connectionSettings.authEnabled && (user() != connectionSettings.userName || password() != connectionSettings.password))
|
||||
|| (!connectionSettings.authEnabled && (!user().isEmpty() || !password().isEmpty()))) {
|
||||
if(connectionSettings.authEnabled) {
|
||||
setCredentials(connectionSettings.userName, connectionSettings.password);
|
||||
} else {
|
||||
setCredentials(QString(), QString());
|
||||
}
|
||||
reconnectRequired = true;
|
||||
}
|
||||
if(connectionSettings.expectedSslErrors.isEmpty()) {
|
||||
const bool previouslyHadExpectedSslErrors = !expectedSslErrors().isEmpty();
|
||||
const bool ok = loadSelfSignedCertificate();
|
||||
connectionSettings.expectedSslErrors = expectedSslErrors();
|
||||
if(ok || (previouslyHadExpectedSslErrors && !ok)) {
|
||||
reconnectRequired = true;
|
||||
}
|
||||
} else if(expectedSslErrors() != connectionSettings.expectedSslErrors) {
|
||||
m_expectedSslErrors = connectionSettings.expectedSslErrors;
|
||||
reconnectRequired = true;
|
||||
}
|
||||
|
||||
setTrafficPollInterval(connectionSettings.trafficPollInterval);
|
||||
setDevStatsPollInterval(connectionSettings.devStatsPollInterval);
|
||||
setAutoReconnectInterval(connectionSettings.reconnectInterval);
|
||||
if(connectionSettings.expectedSslErrors.isEmpty()) {
|
||||
loadSelfSignedCertificate();
|
||||
connectionSettings.expectedSslErrors = expectedSslErrors();
|
||||
} else {
|
||||
m_expectedSslErrors = connectionSettings.expectedSslErrors;
|
||||
}
|
||||
|
||||
return reconnectRequired;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
|
@ -111,9 +111,10 @@ public:
|
|||
const std::vector<SyncthingDir *> &completedDirs() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
void loadSelfSignedCertificate();
|
||||
void applySettings(SyncthingConnectionSettings &connectionSettings);
|
||||
bool loadSelfSignedCertificate();
|
||||
bool applySettings(SyncthingConnectionSettings &connectionSettings);
|
||||
void connect();
|
||||
void connect(SyncthingConnectionSettings &connectionSettings);
|
||||
void disconnect();
|
||||
void reconnect();
|
||||
void reconnect(SyncthingConnectionSettings &connectionSettings);
|
||||
|
|
|
@ -61,7 +61,7 @@ TrayIcon::TrayIcon(QObject *parent) :
|
|||
// setup notifications
|
||||
m_disconnectedNotification.setMessage(tr("Disconnected from Syncthing"));
|
||||
m_disconnectedNotification.setActions(QStringList(tr("Try to reconnect")));
|
||||
connect(&m_disconnectedNotification, &DBusNotification::actionInvoked, &(m_trayMenu.widget()->connection()), &SyncthingConnection::connect);
|
||||
connect(&m_disconnectedNotification, &DBusNotification::actionInvoked, &(m_trayMenu.widget()->connection()), static_cast<void(SyncthingConnection::*)(void)>(&SyncthingConnection::connect));
|
||||
m_syncthingNotification.setActions(QStringList({QStringLiteral("show"), tr("Show"), QStringLiteral("dismiss"), tr("Dismiss")}));
|
||||
connect(&m_syncthingNotification, &DBusNotification::actionInvoked, this, &TrayIcon::handleSyncthingNotificationAction);
|
||||
#endif
|
||||
|
|
|
@ -375,7 +375,7 @@ void TrayWidget::applySettings()
|
|||
instance->m_connectionsMenu->actions().at(0)->setChecked(true);
|
||||
}
|
||||
instance->m_ui->connectionsPushButton->setText(instance->m_selectedConnection->label);
|
||||
instance->m_connection.reconnect(*instance->m_selectedConnection);
|
||||
instance->m_connection.connect(*instance->m_selectedConnection);
|
||||
|
||||
// web view
|
||||
#ifndef SYNCTHINGTRAY_NO_WEBVIEW
|
||||
|
|
|
@ -57,6 +57,26 @@ WebPage::WebPage(WebViewDialog *dlg, WEB_VIEW_PROVIDER *view) :
|
|||
}
|
||||
}
|
||||
|
||||
bool WebPage::isSamePage(const QUrl &url1, const QUrl &url2)
|
||||
{
|
||||
if(url1.scheme() == url2.scheme()
|
||||
&& url1.host() == url2.host()
|
||||
&& url1.port() == url2.port()) {
|
||||
QString path1 = url1.path();
|
||||
while(path1.endsWith(QChar('/'))) {
|
||||
path1.resize(path1.size() - 1);
|
||||
}
|
||||
QString path2 = url2.path();
|
||||
while(path2.endsWith(QChar('/'))) {
|
||||
path2.resize(path2.size() - 1);
|
||||
}
|
||||
if(path1 == path2) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
WEB_PAGE_PROVIDER *WebPage::createWindow(WEB_PAGE_PROVIDER::WebWindowType type)
|
||||
{
|
||||
Q_UNUSED(type)
|
||||
|
@ -128,20 +148,8 @@ bool WebPage::handleNavigationRequest(const QUrl ¤tUrl, const QUrl &target
|
|||
return true;
|
||||
}
|
||||
// only allow navigation on the same page
|
||||
if(currentUrl.scheme() == targetUrl.scheme()
|
||||
&& currentUrl.host() == targetUrl.host()
|
||||
&& currentUrl.port() == targetUrl.port()) {
|
||||
QString currentPath = currentUrl.path();
|
||||
while(currentPath.endsWith(QChar('/'))) {
|
||||
currentPath.resize(currentPath.size() - 1);
|
||||
}
|
||||
QString targetPath = targetUrl.path();
|
||||
while(targetPath.endsWith(QChar('/'))) {
|
||||
targetPath.resize(targetPath.size() - 1);
|
||||
}
|
||||
if(currentPath == targetPath) {
|
||||
return true;
|
||||
}
|
||||
if(isSamePage(currentUrl, targetUrl)) {
|
||||
return true;
|
||||
}
|
||||
// otherwise open URL in external browser
|
||||
QDesktopServices::openUrl(targetUrl);
|
||||
|
|
|
@ -26,6 +26,8 @@ class WebPage : public WEB_PAGE_PROVIDER
|
|||
public:
|
||||
WebPage(WebViewDialog *dlg = nullptr, WEB_VIEW_PROVIDER *view = nullptr);
|
||||
|
||||
static bool isSamePage(const QUrl &url1, const QUrl &url2);
|
||||
|
||||
protected:
|
||||
WEB_PAGE_PROVIDER *createWindow(WebWindowType type);
|
||||
#ifdef SYNCTHINGTRAY_USE_WEBENGINE
|
||||
|
@ -45,7 +47,7 @@ private slots:
|
|||
#endif
|
||||
|
||||
private:
|
||||
bool handleNavigationRequest(const QUrl ¤tUrl, const QUrl &url);
|
||||
static bool handleNavigationRequest(const QUrl ¤tUrl, const QUrl &url);
|
||||
|
||||
WebViewDialog *m_dlg;
|
||||
WEB_VIEW_PROVIDER *m_view;
|
||||
|
|
|
@ -54,7 +54,9 @@ QtGui::WebViewDialog::~WebViewDialog()
|
|||
void QtGui::WebViewDialog::applySettings(const Data::SyncthingConnectionSettings &connectionSettings)
|
||||
{
|
||||
m_settings = connectionSettings;
|
||||
m_view->setUrl(connectionSettings.syncthingUrl);
|
||||
if(!WebPage::isSamePage(m_view->url(), connectionSettings.syncthingUrl)) {
|
||||
m_view->setUrl(connectionSettings.syncthingUrl);
|
||||
}
|
||||
m_view->setZoomFactor(Settings::values().webView.zoomFactor);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue