Enforce a TCP/TLS HTTP timeout on Qt 6.3+

Timeouts for long requests like launch or resume timed the entire
HTTP operation. If the host was no longer reachable, we could
spend 2 minutes sitting there, even though we hadn't even made
successful contact with the host to give it our request yet.

Now we will time out a request if we can't send it in 5 seconds,
regardless of how long we want to wait for the server to respond.
This commit is contained in:
Cameron Gutman committed 2026-10-22 22:54:32 -05:00
1 parent b709bf5402
commit 74173b26eb
1 file changed
+34 -3
+34 -3
View File
@@ -516,14 +516,35 @@ NvHTTP::openConnection(QUrl baseUrl,
auto sslErrorsConnection = connect(m_Nam, &QNetworkAccessManager::sslErrors, this, &NvHTTP::handleSslErrors);
QNetworkReply* reply = m_Nam->get(request);
// Run the request with a timeout if requested
QEventLoop loop;
// Connect the quit signals
connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, &loop, &QEventLoop::quit);
// Enforce a transfer timeout if requested
if (timeoutMs) {
QTimer::singleShot(timeoutMs, &loop, &QEventLoop::quit);
}
#if QT_VERSION >= QT_VERSION_CHECK(6, 3, 0)
// Time the request to distinguish a slow response from an unreachable host
auto* connectTimer = new QTimer(reply);
connectTimer->setSingleShot(true);
connect(connectTimer, &QTimer::timeout, reply, [reply, logLevel, url]() {
if (!reply->isFinished()) {
if (logLevel >= NvLogLevel::NVLL_ERROR) {
qWarning() << "Aborting timed out connection for" << url.toString();
}
reply->setProperty("timeout_reason", "connection_timeout");
reply->abort();
}
});
connect(reply, &QNetworkReply::requestSent, connectTimer, &QTimer::stop);
connectTimer->start(REQUEST_TIMEOUT_MS);
#endif
if (logLevel >= NvLogLevel::NVLL_VERBOSE) {
qInfo() << "Executing request:" << url.toString();
}
@@ -559,7 +580,11 @@ NvHTTP::openConnection(QUrl baseUrl,
throw exception;
}
else if (reply->error() == QNetworkReply::OperationCanceledError) {
QtNetworkReplyException exception(QNetworkReply::TimeoutError, "Request timed out");
QString reason = reply->property("timeout_reason").toString();
QtNetworkReplyException exception(QNetworkReply::TimeoutError,
reason == "connection_timeout" ?
"Connection timed out" :
"Request timed out");
delete reply;
throw exception;
}
@@ -570,5 +595,11 @@ NvHTTP::openConnection(QUrl baseUrl,
}
}
#if QT_VERSION >= QT_VERSION_CHECK(6, 3, 0)
// The requestSent signal must have stopped the timer for any successful request,
// otherwise we could falsely time out a slow response when we connected fine.
Q_ASSERT(!connectTimer->isActive());
#endif
return reply;
}