Skip to content

Commit 85bdb29

Browse files
authored
Merge pull request #9352 from nextcloud/backport/9350/stable-4.0
[stable-4.0] fix(accessmanager): only handle manual redirects unless specified otherwise
2 parents 55c02fc + a12008e commit 85bdb29

3 files changed

Lines changed: 87 additions & 6 deletions

File tree

src/libsync/accessmanager.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,12 @@ QNetworkReply *AccessManager::createRequest(QNetworkAccessManager::Operation op,
8282
}
8383
#endif
8484

85-
// We handle redirects ourselves in AbstractNetworkJob::slotFinished
86-
// Qt's automatic handling of redirects will transmit all set headers from the original
87-
// request again, including e.g. `Authorization`.
88-
newRequest.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::ManualRedirectPolicy);
85+
if (!newRequest.attribute(QNetworkRequest::RedirectPolicyAttribute).isValid()) {
86+
// We handle redirects ourselves in AbstractNetworkJob::slotFinished
87+
// Qt's automatic handling of redirects will transmit all set headers from the original
88+
// request again, including e.g. `Authorization`.
89+
newRequest.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::ManualRedirectPolicy);
90+
}
8991

9092
const auto reply = QNetworkAccessManager::createRequest(op, newRequest, outgoingData);
9193
HttpLogger::logRequest(reply, op, outgoingData);

test/CMakeLists.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,16 @@ set_target_properties(testutils PROPERTIES FOLDER Tests)
3030
nextcloud_add_test(NextcloudPropagator)
3131
if(Qt${QT_VERSION_MAJOR}HttpServer_FOUND)
3232
target_compile_definitions(NextcloudPropagatorTest PRIVATE HAVE_QHTTPSERVER=1)
33-
target_link_libraries(NextcloudPropagatorTest PRIVATE Qt6::HttpServer)
33+
target_link_libraries(NextcloudPropagatorTest PRIVATE Qt::HttpServer)
3434
endif()
3535

3636
IF(BUILD_UPDATER)
3737
nextcloud_add_test(Updater)
38+
39+
if(Qt${QT_VERSION_MAJOR}HttpServer_FOUND)
40+
target_compile_definitions(UpdaterTest PRIVATE HAVE_QHTTPSERVER=1)
41+
target_link_libraries(UpdaterTest PRIVATE Qt::HttpServer)
42+
endif()
3843
endif()
3944

4045
nextcloud_add_test(NetrcParser)

test/testupdater.cpp

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,19 @@
1010

1111
#include <QtTest>
1212

13+
#include "common/filesystembase.h"
1314
#include "updater/updater.h"
1415
#include "updater/ocupdater.h"
16+
#include "configfile.h"
1517
#include "logger.h"
18+
#include "filesystem.h"
19+
20+
using namespace Qt::StringLiterals;
21+
22+
#ifdef HAVE_QHTTPSERVER
23+
#include <QHttpServer>
24+
#include <QTcpServer>
25+
#endif
1626

1727
using namespace OCC;
1828

@@ -41,7 +51,71 @@ private slots:
4151
QVERIFY(currVersion < highVersion);
4252
}
4353

54+
#ifdef HAVE_QHTTPSERVER
55+
void testUpdaterDownloadRedirect()
56+
{
57+
QTemporaryDir tempDir;
58+
ConfigFile::setConfDir(tempDir.path()); // we don't want to pollute the user's config file
59+
QVERIFY(tempDir.isValid());
60+
QDir dir(tempDir.path());
61+
62+
// set up a download server that provides the version info and redirects the download request to e.g. some object storage
63+
QHttpServer httpServer;
64+
httpServer.route("/updateinfo.xml", [](const QHttpServerRequest &request, QHttpServerResponder &responder) -> void {
65+
auto downloadTarget = request.url();
66+
downloadTarget.setPath("/Nextcloud.msi");
67+
qInfo() << "redirecting to" << downloadTarget;
68+
69+
QHttpHeaders headers;
70+
headers.append(QHttpHeaders::WellKnownHeader::ContentType, "application/xml"_ba);
71+
72+
auto xmlResponse = "<?xml version=\"1.0\"?>\n<owncloudclient><version>600.0.0</version><versionstring>Nextcloud Client 600.0.0</versionstring><downloadurl>"_ba;
73+
xmlResponse.append(downloadTarget.toEncoded());
74+
xmlResponse.append("</downloadurl><web>https://nextcloud.com/install</web></owncloudclient>"_ba);
75+
76+
responder.write(xmlResponse, headers);
77+
});
78+
httpServer.route("/Nextcloud.msi", [](QHttpServerResponder &responder) -> void {
79+
QHttpHeaders headers;
80+
headers.append(QHttpHeaders::WellKnownHeader::Location, "/storage/blob/42?signature=1234abcd&signatureVersion=2026-01-21"_ba);
81+
responder.write(""_ba, headers, QHttpServerResponder::StatusCode::Found);
82+
});
83+
84+
bool redirectHit = false;
85+
httpServer.route("/storage/blob/42", [&redirectHit](QHttpServerResponder &responder) -> void {
86+
QHttpHeaders headers;
87+
headers.append(QHttpHeaders::WellKnownHeader::ContentType, "application/octet-stream"_ba);
88+
redirectHit = true;
89+
90+
responder.write("This would be the installer"_ba, headers);
91+
});
92+
93+
QTcpServer tcpServer;
94+
QVERIFY(tcpServer.listen(QHostAddress::LocalHost));
95+
QVERIFY(httpServer.bind(&tcpServer));
96+
const QString baseUrl = "http://%1:%2"_L1.arg(tcpServer.serverAddress().toString(), QString::number(tcpServer.serverPort()));
97+
qInfo() << "Listening on" << baseUrl;
98+
99+
NSISUpdater updater(QUrl("%1/updateinfo.xml"_L1.arg(baseUrl)));
100+
QSignalSpy downloadAvailableSpy(&updater, &OCUpdater::newUpdateAvailable);
101+
updater.checkForUpdate();
102+
downloadAvailableSpy.wait();
103+
QCOMPARE(downloadAvailableSpy.size(), 1);
104+
QVERIFY(redirectHit);
105+
106+
ConfigFile cfg;
107+
QSettings settings(cfg.configFile(), QSettings::IniFormat);
108+
const auto downloadedUpdateFilePath = settings.value("Updater/updateAvailable"_L1).toString(); // anonymous const in ocupdater.cpp
109+
const auto expectedUpdateFilePath = FileSystem::joinPath(cfg.configPath(), "Nextcloud.msi");
110+
QCOMPARE(downloadedUpdateFilePath, expectedUpdateFilePath);
111+
QFile updateFile(expectedUpdateFilePath);
112+
QVERIFY(updateFile.open(QIODevice::ReadOnly));
113+
const auto updateContents = updateFile.readAll();
114+
updateFile.close();
115+
QCOMPARE(updateContents, "This would be the installer"_ba);
116+
}
117+
#endif
44118
};
45119

46-
QTEST_APPLESS_MAIN(TestUpdater)
120+
QTEST_GUILESS_MAIN(TestUpdater)
47121
#include "testupdater.moc"

0 commit comments

Comments
 (0)