Add option to use new config route instead of deprecated one
For the sake of compatibility with older Syncthing versions, this option is not enabled by default.
This commit is contained in:
parent
c7f6da6a17
commit
46c2333230
|
@ -13,7 +13,7 @@ set(META_VERSION_MAJOR 1)
|
|||
set(META_VERSION_MINOR 3)
|
||||
set(META_VERSION_PATCH 3)
|
||||
set(META_RELEASE_DATE "2023-01-02")
|
||||
set(META_SOVERSION 4)
|
||||
set(META_SOVERSION 5)
|
||||
set(META_ADD_DEFAULT_CPP_UNIT_TEST_APPLICATION ON)
|
||||
|
||||
project(${META_PROJECT_NAME})
|
||||
|
|
|
@ -505,6 +505,8 @@ It is possible to turn on logging of the underlying library by setting environme
|
|||
* `SYNCTHING_PORT`: override the port of the Syncthing test instance spawned when running tests
|
||||
* `SYNCTHINGTRAY_SYSTEMD_USER_UNIT`: override the name of the systemd user-unit checked by the wizard's
|
||||
setup detection
|
||||
* `LIB_SYNCTHING_CONNECTOR_USE_DEPRECATED_ROUTES`: change whether to use deprecated routes (enabled by
|
||||
default for compatibility with older Syncthing versions, set to `0` to change the behavior)
|
||||
|
||||
## Known bugs and workarounds
|
||||
The following bugs are caused by dependencies or limitations of certain
|
||||
|
|
|
@ -103,6 +103,7 @@ SyncthingConnection::SyncthingConnection(
|
|||
, m_lastFileDeleted(false)
|
||||
, m_dirStatsAltered(false)
|
||||
, m_recordFileChanges(false)
|
||||
, m_useDeprecatedRoutes(true)
|
||||
{
|
||||
m_trafficPollTimer.setInterval(SyncthingConnectionSettings::defaultTrafficPollInterval);
|
||||
m_trafficPollTimer.setTimerType(Qt::VeryCoarseTimer);
|
||||
|
@ -125,6 +126,13 @@ SyncthingConnection::SyncthingConnection(
|
|||
#endif
|
||||
|
||||
setLoggingFlags(loggingFlags);
|
||||
|
||||
// allow initializing the default value for m_useDeprecatedRoutes via environment variable
|
||||
auto useDeprecatedRoutesIsInt = false;
|
||||
auto useDeprecatedRoutesInt = qEnvironmentVariableIntValue(PROJECT_VARNAME_UPPER "_USE_DEPRECATED_ROUTES", &useDeprecatedRoutesIsInt);
|
||||
if (useDeprecatedRoutesIsInt) {
|
||||
m_useDeprecatedRoutes = useDeprecatedRoutesInt;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
|
@ -109,6 +109,7 @@ class LIB_SYNCTHING_CONNECTOR_EXPORT SyncthingConnection : public QObject {
|
|||
Q_PROPERTY(QStringList directoryIds READ directoryIds)
|
||||
Q_PROPERTY(QStringList deviceIds READ deviceIds)
|
||||
Q_PROPERTY(QJsonObject rawConfig READ rawConfig NOTIFY newConfig)
|
||||
Q_PROPERTY(bool useDeprecatedRoutes READ isUsingDeprecatedRoutes WRITE setUseDeprecatedRoutes)
|
||||
|
||||
public:
|
||||
explicit SyncthingConnection(const QString &syncthingUrl = QStringLiteral("http://localhost:8080"), const QByteArray &apiKey = QByteArray(),
|
||||
|
@ -124,6 +125,8 @@ public:
|
|||
const QString &user() const;
|
||||
const QString &password() const;
|
||||
void setCredentials(const QString &user, const QString &password);
|
||||
bool isUsingDeprecatedRoutes() const;
|
||||
void setUseDeprecatedRoutes(bool useLegacyRoutes);
|
||||
|
||||
// getter for the status of the connection to Syncthing and of Syncthing itself
|
||||
SyncthingStatus status() const;
|
||||
|
@ -340,6 +343,8 @@ private Q_SLOTS:
|
|||
void handleAdditionalRequestCanceled();
|
||||
void handleSslErrors(const QList<QSslError> &errors);
|
||||
void recalculateStatus();
|
||||
QString configPath() const;
|
||||
QByteArray changeConfigVerb() const;
|
||||
|
||||
private:
|
||||
// internal helper methods
|
||||
|
@ -350,6 +355,7 @@ private:
|
|||
QNetworkRequest prepareRequest(const QString &path, const QUrlQuery &query, bool rest = true);
|
||||
QNetworkReply *requestData(const QString &path, const QUrlQuery &query, bool rest = true);
|
||||
QNetworkReply *postData(const QString &path, const QUrlQuery &query, const QByteArray &data = QByteArray());
|
||||
QNetworkReply *sendData(const QByteArray &verb, const QString &path, const QUrlQuery &query, const QByteArray &data = QByteArray());
|
||||
Reply prepareReply(bool readData = true, bool handleAborting = true);
|
||||
Reply prepareReply(QNetworkReply *&expectedReply, bool readData = true, bool handleAborting = true);
|
||||
Reply prepareReply(QList<QNetworkReply *> &expectedReplies, bool readData = true, bool handleAborting = true);
|
||||
|
@ -420,6 +426,7 @@ private:
|
|||
QJsonObject m_rawConfig;
|
||||
bool m_dirStatsAltered;
|
||||
bool m_recordFileChanges;
|
||||
bool m_useDeprecatedRoutes;
|
||||
};
|
||||
|
||||
/*!
|
||||
|
@ -479,6 +486,27 @@ inline void SyncthingConnection::setCredentials(const QString &user, const QStri
|
|||
m_password = password;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns whether deprecated routes should still be used in order to support older versions of Syncthing.
|
||||
* \remarks
|
||||
* - This is still enabled by default but may cease to work once those deprecated routes have been removed by
|
||||
* Syncthing itself.
|
||||
* - Disabling this will require Syncthing 1.12.0 or newer.
|
||||
*/
|
||||
inline bool SyncthingConnection::isUsingDeprecatedRoutes() const
|
||||
{
|
||||
return m_useDeprecatedRoutes;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns whether deprecated routes should still be used in order to support older versions of Syncthing.
|
||||
* \sa See isUsingLegacyRoutes() for details.
|
||||
*/
|
||||
inline void SyncthingConnection::setUseDeprecatedRoutes(bool useDeprecatedRoutes)
|
||||
{
|
||||
m_useDeprecatedRoutes = useDeprecatedRoutes;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the string representation of the current status().
|
||||
*/
|
||||
|
|
|
@ -75,6 +75,19 @@ QNetworkReply *SyncthingConnection::postData(const QString &path, const QUrlQuer
|
|||
return reply;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Invokes an asynchronous request using the rest API.
|
||||
*/
|
||||
QNetworkReply *SyncthingConnection::sendData(const QByteArray &verb, const QString &path, const QUrlQuery &query, const QByteArray &data)
|
||||
{
|
||||
auto *const reply = networkAccessManager().sendCustomRequest(prepareRequest(path, query), verb, data);
|
||||
QObject::connect(reply, &QNetworkReply::sslErrors, this, &SyncthingConnection::handleSslErrors);
|
||||
if (loggingFlags() & SyncthingConnectionLoggingFlags::ApiCalls) {
|
||||
cerr << Phrases::Info << "Querying API: " << verb.data() << ' ' << reply->url().toString().toStdString() << Phrases::EndFlush;
|
||||
}
|
||||
return reply;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Prepares the current reply.
|
||||
*/
|
||||
|
@ -195,6 +208,22 @@ SyncthingConnection::Reply SyncthingConnection::handleReply(QNetworkReply *reply
|
|||
return data;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the path to Syncthing's "config" route depending on whether deprecated routes should be used.
|
||||
*/
|
||||
QString SyncthingConnection::configPath() const
|
||||
{
|
||||
return isUsingDeprecatedRoutes() ? QStringLiteral("system/config") : QStringLiteral("config");
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the verb for posting the Syncthing config in accordance to the path returned by configPath().
|
||||
*/
|
||||
QByteArray SyncthingConnection::changeConfigVerb() const
|
||||
{
|
||||
return isUsingDeprecatedRoutes() ? QByteArray("POST") : QByteArray("PUT");
|
||||
}
|
||||
|
||||
// pause/resume devices
|
||||
|
||||
/*!
|
||||
|
@ -261,7 +290,7 @@ bool SyncthingConnection::pauseResumeDevice(const QStringList &devIds, bool paus
|
|||
|
||||
QJsonDocument doc;
|
||||
doc.setObject(config);
|
||||
QNetworkReply *const reply = postData(QStringLiteral("system/config"), QUrlQuery(), doc.toJson(QJsonDocument::Compact));
|
||||
QNetworkReply *const reply = sendData(changeConfigVerb(), configPath(), QUrlQuery(), doc.toJson(QJsonDocument::Compact));
|
||||
reply->setProperty("devIds", devIds);
|
||||
reply->setProperty("resume", !paused);
|
||||
QObject::connect(reply, &QNetworkReply::finished, this, &SyncthingConnection::readDevPauseResume);
|
||||
|
@ -366,7 +395,7 @@ bool SyncthingConnection::pauseResumeDirectory(const QStringList &dirIds, bool p
|
|||
if (setDirectoriesPaused(config, dirIds, paused)) {
|
||||
QJsonDocument doc;
|
||||
doc.setObject(config);
|
||||
QNetworkReply *const reply = postData(QStringLiteral("system/config"), QUrlQuery(), doc.toJson(QJsonDocument::Compact));
|
||||
QNetworkReply *const reply = sendData(changeConfigVerb(), configPath(), QUrlQuery(), doc.toJson(QJsonDocument::Compact));
|
||||
reply->setProperty("dirIds", dirIds);
|
||||
reply->setProperty("resume", !paused);
|
||||
QObject::connect(reply, &QNetworkReply::finished, this, &SyncthingConnection::readDirPauseResume);
|
||||
|
@ -563,8 +592,7 @@ void SyncthingConnection::requestConfig()
|
|||
if (m_configReply) {
|
||||
return;
|
||||
}
|
||||
QObject::connect(
|
||||
m_configReply = requestData(QStringLiteral("system/config"), QUrlQuery()), &QNetworkReply::finished, this, &SyncthingConnection::readConfig);
|
||||
QObject::connect(m_configReply = requestData(configPath(), QUrlQuery()), &QNetworkReply::finished, this, &SyncthingConnection::readConfig);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -1407,7 +1435,7 @@ void SyncthingConnection::readLog()
|
|||
*/
|
||||
void SyncthingConnection::postConfigFromJsonObject(const QJsonObject &rawConfig)
|
||||
{
|
||||
QObject::connect(postData(QStringLiteral("system/config"), QUrlQuery(), QJsonDocument(rawConfig).toJson(QJsonDocument::Compact)),
|
||||
QObject::connect(sendData(changeConfigVerb(), configPath(), QUrlQuery(), QJsonDocument(rawConfig).toJson(QJsonDocument::Compact)),
|
||||
&QNetworkReply::finished, this, &SyncthingConnection::readPostConfig);
|
||||
}
|
||||
|
||||
|
@ -1420,7 +1448,7 @@ void SyncthingConnection::postConfigFromJsonObject(const QJsonObject &rawConfig)
|
|||
void SyncthingConnection::postConfigFromByteArray(const QByteArray &rawConfig)
|
||||
{
|
||||
QObject::connect(
|
||||
postData(QStringLiteral("system/config"), QUrlQuery(), rawConfig), &QNetworkReply::finished, this, &SyncthingConnection::readPostConfig);
|
||||
sendData(changeConfigVerb(), configPath(), QUrlQuery(), rawConfig), &QNetworkReply::finished, this, &SyncthingConnection::readPostConfig);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
|
@ -372,7 +372,7 @@ void ConnectionTests::testErrorCases()
|
|||
return;
|
||||
}
|
||||
if ((errorMessage.startsWith(QStringLiteral("Unable to request Syncthing config: Error transferring "))
|
||||
&& errorMessage.endsWith(QStringLiteral("/rest/system/config - server replied: Forbidden")))) {
|
||||
&& errorMessage.endsWith(QStringLiteral("config - server replied: Forbidden")))) {
|
||||
apiKeyErrorConfig = true;
|
||||
return;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue