mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2026-10-26 14:00:08 +00:00
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:
1 parent
b709bf5402
commit
74173b26eb
1 file changed
+34
-3
+34
-3
@@ -516,14 +516,35 @@ NvHTTP::openConnection(QUrl baseUrl,
|
|||||||
|
|
||||||
auto sslErrorsConnection = connect(m_Nam, &QNetworkAccessManager::sslErrors, this, &NvHTTP::handleSslErrors);
|
auto sslErrorsConnection = connect(m_Nam, &QNetworkAccessManager::sslErrors, this, &NvHTTP::handleSslErrors);
|
||||||
QNetworkReply* reply = m_Nam->get(request);
|
QNetworkReply* reply = m_Nam->get(request);
|
||||||
|
|
||||||
// Run the request with a timeout if requested
|
|
||||||
QEventLoop loop;
|
QEventLoop loop;
|
||||||
|
|
||||||
|
// Connect the quit signals
|
||||||
connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
|
connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
|
||||||
connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, &loop, &QEventLoop::quit);
|
connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, &loop, &QEventLoop::quit);
|
||||||
|
|
||||||
|
// Enforce a transfer timeout if requested
|
||||||
if (timeoutMs) {
|
if (timeoutMs) {
|
||||||
QTimer::singleShot(timeoutMs, &loop, &QEventLoop::quit);
|
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) {
|
if (logLevel >= NvLogLevel::NVLL_VERBOSE) {
|
||||||
qInfo() << "Executing request:" << url.toString();
|
qInfo() << "Executing request:" << url.toString();
|
||||||
}
|
}
|
||||||
@@ -559,7 +580,11 @@ NvHTTP::openConnection(QUrl baseUrl,
|
|||||||
throw exception;
|
throw exception;
|
||||||
}
|
}
|
||||||
else if (reply->error() == QNetworkReply::OperationCanceledError) {
|
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;
|
delete reply;
|
||||||
throw exception;
|
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;
|
return reply;
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user