mirror of
https://github.com/nextcloud/desktop.git
synced 2024-10-27 23:17:13 +03:00
Update server url in case of permanent redirection #5972
This is the first time the account url may update outside of account setup. Summary of redirection handling: 1. During account setup (wizard) - status.php gets permanently redirected -> adjust url - authed PROPFIND gets *any* redirection -> adjust url 2. During connectivity ping (ConnectionValidator) - status.php gets permanently redirected -> adjust url (new!) All other redirections should be followed transparently and don't update the account url in the settings.
This commit is contained in:
parent
1c0d80c20d
commit
b810ce7768
6 changed files with 65 additions and 8 deletions
|
@ -196,13 +196,10 @@ void OwncloudSetupWizard::slotOwnCloudFoundAuth(const QUrl &url, const QJsonObje
|
||||||
// https://github.com/owncloud/core/pull/27473/files
|
// https://github.com/owncloud/core/pull/27473/files
|
||||||
_ocWizard->account()->setServerVersion(serverVersion);
|
_ocWizard->account()->setServerVersion(serverVersion);
|
||||||
|
|
||||||
QString p = url.path();
|
if (url != _ocWizard->account()->url()) {
|
||||||
if (p.endsWith("/status.php")) {
|
|
||||||
// We might be redirected, update the account
|
// We might be redirected, update the account
|
||||||
QUrl redirectedUrl = url;
|
_ocWizard->account()->setUrl(url);
|
||||||
redirectedUrl.setPath(url.path().left(url.path().length() - 11));
|
qCInfo(lcWizard) << " was redirected to" << url.toString();
|
||||||
_ocWizard->account()->setUrl(redirectedUrl);
|
|
||||||
qCInfo(lcWizard) << " was redirected to" << redirectedUrl.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DetermineAuthTypeJob *job = new DetermineAuthTypeJob(_ocWizard->account(), this);
|
DetermineAuthTypeJob *job = new DetermineAuthTypeJob(_ocWizard->account(), this);
|
||||||
|
|
|
@ -182,6 +182,8 @@ void AbstractNetworkJob::slotFinished()
|
||||||
} else if (verb.isEmpty()) {
|
} else if (verb.isEmpty()) {
|
||||||
qCWarning(lcNetworkJob) << this << "cannot redirect request: could not detect original verb";
|
qCWarning(lcNetworkJob) << this << "cannot redirect request: could not detect original verb";
|
||||||
} else {
|
} else {
|
||||||
|
emit redirected(_reply, redirectUrl, _redirectCount - 1);
|
||||||
|
|
||||||
// Create the redirected request and send it
|
// Create the redirected request and send it
|
||||||
qCInfo(lcNetworkJob) << "Redirecting" << verb << requestedUrl << redirectUrl;
|
qCInfo(lcNetworkJob) << "Redirecting" << verb << requestedUrl << redirectUrl;
|
||||||
resetTimeout();
|
resetTimeout();
|
||||||
|
|
|
@ -98,6 +98,14 @@ signals:
|
||||||
void networkError(QNetworkReply *reply);
|
void networkError(QNetworkReply *reply);
|
||||||
void networkActivity();
|
void networkActivity();
|
||||||
|
|
||||||
|
/** Emitted when a redirect is followed.
|
||||||
|
*
|
||||||
|
* \a reply The "please redirect" reply
|
||||||
|
* \a targetUrl Where to redirect to
|
||||||
|
* \a redirectCount Counts redirect hops, first is 0.
|
||||||
|
*/
|
||||||
|
void redirected(QNetworkReply *reply, const QUrl &targetUrl, int redirectCount);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void setupConnections(QNetworkReply *reply);
|
void setupConnections(QNetworkReply *reply);
|
||||||
|
|
||||||
|
|
|
@ -135,6 +135,13 @@ void ConnectionValidator::slotStatusFound(const QUrl &url, const QJsonObject &in
|
||||||
<< CheckServerJob::versionString(info)
|
<< CheckServerJob::versionString(info)
|
||||||
<< "(" << serverVersion << ")";
|
<< "(" << serverVersion << ")";
|
||||||
|
|
||||||
|
// Update server url in case of redirection
|
||||||
|
if (_account->url() != url) {
|
||||||
|
qCInfo(lcConnectionValidator()) << "status.php was redirected to" << url.toString();
|
||||||
|
_account->setUrl(url);
|
||||||
|
_account->wantsAccountSaved(_account.data());
|
||||||
|
}
|
||||||
|
|
||||||
if (!serverVersion.isEmpty() && !setAndCheckServerVersion(serverVersion)) {
|
if (!serverVersion.isEmpty() && !setAndCheckServerVersion(serverVersion)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -397,13 +397,17 @@ namespace {
|
||||||
CheckServerJob::CheckServerJob(AccountPtr account, QObject *parent)
|
CheckServerJob::CheckServerJob(AccountPtr account, QObject *parent)
|
||||||
: AbstractNetworkJob(account, QLatin1String(statusphpC), parent)
|
: AbstractNetworkJob(account, QLatin1String(statusphpC), parent)
|
||||||
, _subdirFallback(false)
|
, _subdirFallback(false)
|
||||||
|
, _permanentRedirects(0)
|
||||||
{
|
{
|
||||||
setIgnoreCredentialFailure(true);
|
setIgnoreCredentialFailure(true);
|
||||||
|
connect(this, SIGNAL(redirected(QNetworkReply *, QUrl, int)),
|
||||||
|
SLOT(slotRedirected(QNetworkReply *, QUrl, int)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckServerJob::start()
|
void CheckServerJob::start()
|
||||||
{
|
{
|
||||||
sendRequest("GET", makeAccountUrl(path()));
|
_serverUrl = account()->url();
|
||||||
|
sendRequest("GET", Utility::concatUrlPath(_serverUrl, path()));
|
||||||
connect(reply(), SIGNAL(metaDataChanged()), this, SLOT(metaDataChangedSlot()));
|
connect(reply(), SIGNAL(metaDataChanged()), this, SLOT(metaDataChangedSlot()));
|
||||||
connect(reply(), SIGNAL(encrypted()), this, SLOT(encryptedSlot()));
|
connect(reply(), SIGNAL(encrypted()), this, SLOT(encryptedSlot()));
|
||||||
AbstractNetworkJob::start();
|
AbstractNetworkJob::start();
|
||||||
|
@ -455,6 +459,24 @@ void CheckServerJob::encryptedSlot()
|
||||||
mergeSslConfigurationForSslButton(reply()->sslConfiguration(), account());
|
mergeSslConfigurationForSslButton(reply()->sslConfiguration(), account());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CheckServerJob::slotRedirected(QNetworkReply *reply, const QUrl &targetUrl, int redirectCount)
|
||||||
|
{
|
||||||
|
QByteArray slashStatusPhp("/");
|
||||||
|
slashStatusPhp.append(statusphpC);
|
||||||
|
|
||||||
|
int httpCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||||
|
QString path = targetUrl.path();
|
||||||
|
if ((httpCode == 301 || httpCode == 308) // permanent redirection
|
||||||
|
&& redirectCount == _permanentRedirects // don't apply permanent redirects after a temporary one
|
||||||
|
&& path.endsWith(slashStatusPhp)) {
|
||||||
|
_serverUrl = targetUrl;
|
||||||
|
_serverUrl.setPath(path.left(path.size() - slashStatusPhp.size()));
|
||||||
|
qCInfo(lcCheckServerJob) << "status.php was permanently redirected to"
|
||||||
|
<< targetUrl << "new server url is" << _serverUrl;
|
||||||
|
++_permanentRedirects;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CheckServerJob::metaDataChangedSlot()
|
void CheckServerJob::metaDataChangedSlot()
|
||||||
{
|
{
|
||||||
account()->setSslConfiguration(reply()->sslConfiguration());
|
account()->setSslConfiguration(reply()->sslConfiguration());
|
||||||
|
@ -499,7 +521,7 @@ bool CheckServerJob::finished()
|
||||||
|
|
||||||
qCInfo(lcCheckServerJob) << "status.php returns: " << status << " " << reply()->error() << " Reply: " << reply();
|
qCInfo(lcCheckServerJob) << "status.php returns: " << status << " " << reply()->error() << " Reply: " << reply();
|
||||||
if (status.object().contains("installed")) {
|
if (status.object().contains("installed")) {
|
||||||
emit instanceFound(reply()->url(), status.object());
|
emit instanceFound(_serverUrl, status.object());
|
||||||
} else {
|
} else {
|
||||||
qCWarning(lcCheckServerJob) << "No proper answer on " << reply()->url();
|
qCWarning(lcCheckServerJob) << "No proper answer on " << reply()->url();
|
||||||
emit instanceNotFound(reply());
|
emit instanceNotFound(reply());
|
||||||
|
|
|
@ -241,6 +241,11 @@ public:
|
||||||
static bool installed(const QJsonObject &info);
|
static bool installed(const QJsonObject &info);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
/** Emitted when a status.php was successfully read.
|
||||||
|
*
|
||||||
|
* \a url see _serverStatusUrl (does not include "/status.php")
|
||||||
|
* \a info The status.php reply information
|
||||||
|
*/
|
||||||
void instanceFound(const QUrl &url, const QJsonObject &info);
|
void instanceFound(const QUrl &url, const QJsonObject &info);
|
||||||
|
|
||||||
/** Emitted on invalid status.php reply.
|
/** Emitted on invalid status.php reply.
|
||||||
|
@ -248,6 +253,11 @@ signals:
|
||||||
* \a reply is never null
|
* \a reply is never null
|
||||||
*/
|
*/
|
||||||
void instanceNotFound(QNetworkReply *reply);
|
void instanceNotFound(QNetworkReply *reply);
|
||||||
|
|
||||||
|
/** A timeout occurred.
|
||||||
|
*
|
||||||
|
* \a url The specific url where the timeout happened.
|
||||||
|
*/
|
||||||
void timeout(const QUrl &url);
|
void timeout(const QUrl &url);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -256,9 +266,20 @@ private:
|
||||||
private slots:
|
private slots:
|
||||||
virtual void metaDataChangedSlot();
|
virtual void metaDataChangedSlot();
|
||||||
virtual void encryptedSlot();
|
virtual void encryptedSlot();
|
||||||
|
void slotRedirected(QNetworkReply *reply, const QUrl &targetUrl, int redirectCount);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _subdirFallback;
|
bool _subdirFallback;
|
||||||
|
|
||||||
|
/** The permanent-redirect adjusted account url.
|
||||||
|
*
|
||||||
|
* Note that temporary redirects or a permanent redirect behind a temporary
|
||||||
|
* one do not affect this url.
|
||||||
|
*/
|
||||||
|
QUrl _serverUrl;
|
||||||
|
|
||||||
|
/** Keep track of how many permanent redirect were applied. */
|
||||||
|
int _permanentRedirects;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue