mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2025-07-02 15:55:39 +00:00
Introduce more granular HTTP timeouts
This commit is contained in:
parent
067f5e33aa
commit
89c342bb6f
@ -13,6 +13,9 @@
|
|||||||
#include <QNetworkProxy>
|
#include <QNetworkProxy>
|
||||||
|
|
||||||
#define REQUEST_TIMEOUT_MS 5000
|
#define REQUEST_TIMEOUT_MS 5000
|
||||||
|
#define LAUNCH_TIMEOUT_MS 120000
|
||||||
|
#define RESUME_TIMEOUT_MS 30000
|
||||||
|
#define QUIT_TIMEOUT_MS 30000
|
||||||
|
|
||||||
NvHTTP::NvHTTP(QString address, QSslCertificate serverCert) :
|
NvHTTP::NvHTTP(QString address, QSslCertificate serverCert) :
|
||||||
m_Address(address),
|
m_Address(address),
|
||||||
@ -89,7 +92,7 @@ NvHTTP::getServerInfo(NvLogLevel logLevel)
|
|||||||
serverInfo = openConnectionToString(m_BaseUrlHttps,
|
serverInfo = openConnectionToString(m_BaseUrlHttps,
|
||||||
"serverinfo",
|
"serverinfo",
|
||||||
nullptr,
|
nullptr,
|
||||||
true,
|
REQUEST_TIMEOUT_MS,
|
||||||
logLevel);
|
logLevel);
|
||||||
// Throws if the request failed
|
// Throws if the request failed
|
||||||
verifyResponseStatus(serverInfo);
|
verifyResponseStatus(serverInfo);
|
||||||
@ -102,7 +105,7 @@ NvHTTP::getServerInfo(NvLogLevel logLevel)
|
|||||||
serverInfo = openConnectionToString(m_BaseUrlHttp,
|
serverInfo = openConnectionToString(m_BaseUrlHttp,
|
||||||
"serverinfo",
|
"serverinfo",
|
||||||
nullptr,
|
nullptr,
|
||||||
true,
|
REQUEST_TIMEOUT_MS,
|
||||||
logLevel);
|
logLevel);
|
||||||
verifyResponseStatus(serverInfo);
|
verifyResponseStatus(serverInfo);
|
||||||
}
|
}
|
||||||
@ -119,7 +122,7 @@ NvHTTP::getServerInfo(NvLogLevel logLevel)
|
|||||||
serverInfo = openConnectionToString(m_BaseUrlHttp,
|
serverInfo = openConnectionToString(m_BaseUrlHttp,
|
||||||
"serverinfo",
|
"serverinfo",
|
||||||
nullptr,
|
nullptr,
|
||||||
true,
|
REQUEST_TIMEOUT_MS,
|
||||||
logLevel);
|
logLevel);
|
||||||
verifyResponseStatus(serverInfo);
|
verifyResponseStatus(serverInfo);
|
||||||
}
|
}
|
||||||
@ -180,7 +183,7 @@ NvHTTP::launchApp(int appId,
|
|||||||
"&surroundAudioInfo="+getSurroundAudioInfoString(streamConfig->audioConfiguration)+
|
"&surroundAudioInfo="+getSurroundAudioInfoString(streamConfig->audioConfiguration)+
|
||||||
"&remoteControllersBitmap="+QString::number(gamepadMask)+
|
"&remoteControllersBitmap="+QString::number(gamepadMask)+
|
||||||
"&gcmap="+QString::number(gamepadMask),
|
"&gcmap="+QString::number(gamepadMask),
|
||||||
false);
|
LAUNCH_TIMEOUT_MS);
|
||||||
|
|
||||||
// Throws if the request failed
|
// Throws if the request failed
|
||||||
verifyResponseStatus(response);
|
verifyResponseStatus(response);
|
||||||
@ -200,7 +203,7 @@ NvHTTP::resumeApp(PSTREAM_CONFIGURATION streamConfig)
|
|||||||
"rikey="+QString(QByteArray(streamConfig->remoteInputAesKey, sizeof(streamConfig->remoteInputAesKey)).toHex())+
|
"rikey="+QString(QByteArray(streamConfig->remoteInputAesKey, sizeof(streamConfig->remoteInputAesKey)).toHex())+
|
||||||
"&rikeyid="+QString::number(riKeyId)+
|
"&rikeyid="+QString::number(riKeyId)+
|
||||||
"&surroundAudioInfo="+getSurroundAudioInfoString(streamConfig->audioConfiguration),
|
"&surroundAudioInfo="+getSurroundAudioInfoString(streamConfig->audioConfiguration),
|
||||||
false);
|
RESUME_TIMEOUT_MS);
|
||||||
|
|
||||||
// Throws if the request failed
|
// Throws if the request failed
|
||||||
verifyResponseStatus(response);
|
verifyResponseStatus(response);
|
||||||
@ -213,7 +216,7 @@ NvHTTP::quitApp()
|
|||||||
openConnectionToString(m_BaseUrlHttps,
|
openConnectionToString(m_BaseUrlHttps,
|
||||||
"cancel",
|
"cancel",
|
||||||
nullptr,
|
nullptr,
|
||||||
false);
|
QUIT_TIMEOUT_MS);
|
||||||
|
|
||||||
// Throws if the request failed
|
// Throws if the request failed
|
||||||
verifyResponseStatus(response);
|
verifyResponseStatus(response);
|
||||||
@ -260,7 +263,7 @@ NvHTTP::getAppList()
|
|||||||
QString appxml = openConnectionToString(m_BaseUrlHttps,
|
QString appxml = openConnectionToString(m_BaseUrlHttps,
|
||||||
"applist",
|
"applist",
|
||||||
nullptr,
|
nullptr,
|
||||||
true,
|
REQUEST_TIMEOUT_MS,
|
||||||
NvLogLevel::ERROR);
|
NvLogLevel::ERROR);
|
||||||
verifyResponseStatus(appxml);
|
verifyResponseStatus(appxml);
|
||||||
|
|
||||||
@ -328,7 +331,7 @@ NvHTTP::getBoxArt(int appId)
|
|||||||
"appasset",
|
"appasset",
|
||||||
"appid="+QString::number(appId)+
|
"appid="+QString::number(appId)+
|
||||||
"&AssetType=2&AssetIdx=0",
|
"&AssetType=2&AssetIdx=0",
|
||||||
true,
|
REQUEST_TIMEOUT_MS,
|
||||||
NvLogLevel::VERBOSE);
|
NvLogLevel::VERBOSE);
|
||||||
QImage image = QImageReader(reply).read();
|
QImage image = QImageReader(reply).read();
|
||||||
delete reply;
|
delete reply;
|
||||||
@ -375,10 +378,10 @@ QString
|
|||||||
NvHTTP::openConnectionToString(QUrl baseUrl,
|
NvHTTP::openConnectionToString(QUrl baseUrl,
|
||||||
QString command,
|
QString command,
|
||||||
QString arguments,
|
QString arguments,
|
||||||
bool enableTimeout,
|
int timeoutMs,
|
||||||
NvLogLevel logLevel)
|
NvLogLevel logLevel)
|
||||||
{
|
{
|
||||||
QNetworkReply* reply = openConnection(baseUrl, command, arguments, enableTimeout, logLevel);
|
QNetworkReply* reply = openConnection(baseUrl, command, arguments, timeoutMs, logLevel);
|
||||||
QString ret;
|
QString ret;
|
||||||
|
|
||||||
QTextStream stream(reply);
|
QTextStream stream(reply);
|
||||||
@ -393,7 +396,7 @@ QNetworkReply*
|
|||||||
NvHTTP::openConnection(QUrl baseUrl,
|
NvHTTP::openConnection(QUrl baseUrl,
|
||||||
QString command,
|
QString command,
|
||||||
QString arguments,
|
QString arguments,
|
||||||
bool enableTimeout,
|
int timeoutMs,
|
||||||
NvLogLevel logLevel)
|
NvLogLevel logLevel)
|
||||||
{
|
{
|
||||||
// Build a URL for the request
|
// Build a URL for the request
|
||||||
@ -434,9 +437,8 @@ NvHTTP::openConnection(QUrl baseUrl,
|
|||||||
// Run the request with a timeout if requested
|
// Run the request with a timeout if requested
|
||||||
QEventLoop loop;
|
QEventLoop loop;
|
||||||
QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
|
QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
|
||||||
if (enableTimeout)
|
if (timeoutMs) {
|
||||||
{
|
QTimer::singleShot(timeoutMs, &loop, SLOT(quit()));
|
||||||
QTimer::singleShot(REQUEST_TIMEOUT_MS, &loop, SLOT(quit()));
|
|
||||||
}
|
}
|
||||||
if (logLevel >= NvLogLevel::VERBOSE) {
|
if (logLevel >= NvLogLevel::VERBOSE) {
|
||||||
qInfo() << "Executing request:" << url.toString();
|
qInfo() << "Executing request:" << url.toString();
|
||||||
@ -470,6 +472,11 @@ NvHTTP::openConnection(QUrl baseUrl,
|
|||||||
delete reply;
|
delete reply;
|
||||||
throw exception;
|
throw exception;
|
||||||
}
|
}
|
||||||
|
else if (reply->error() == QNetworkReply::OperationCanceledError) {
|
||||||
|
QtNetworkReplyException exception(QNetworkReply::TimeoutError, "Request timed out");
|
||||||
|
delete reply;
|
||||||
|
throw exception;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
QtNetworkReplyException exception(reply->error(), reply->errorString());
|
QtNetworkReplyException exception(reply->error(), reply->errorString());
|
||||||
delete reply;
|
delete reply;
|
||||||
|
@ -149,7 +149,7 @@ public:
|
|||||||
openConnectionToString(QUrl baseUrl,
|
openConnectionToString(QUrl baseUrl,
|
||||||
QString command,
|
QString command,
|
||||||
QString arguments,
|
QString arguments,
|
||||||
bool enableTimeout,
|
int timeoutMs,
|
||||||
NvLogLevel logLevel = NvLogLevel::VERBOSE);
|
NvLogLevel logLevel = NvLogLevel::VERBOSE);
|
||||||
|
|
||||||
void setServerCert(QSslCertificate serverCert);
|
void setServerCert(QSslCertificate serverCert);
|
||||||
@ -188,7 +188,7 @@ private:
|
|||||||
openConnection(QUrl baseUrl,
|
openConnection(QUrl baseUrl,
|
||||||
QString command,
|
QString command,
|
||||||
QString arguments,
|
QString arguments,
|
||||||
bool enableTimeout,
|
int timeoutMs,
|
||||||
NvLogLevel logLevel);
|
NvLogLevel logLevel);
|
||||||
|
|
||||||
QString m_Address;
|
QString m_Address;
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
#include <openssl/x509.h>
|
#include <openssl/x509.h>
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
|
|
||||||
|
#define REQUEST_TIMEOUT_MS 5000
|
||||||
|
|
||||||
NvPairingManager::NvPairingManager(QString address) :
|
NvPairingManager::NvPairingManager(QString address) :
|
||||||
m_Http(address, QSslCertificate())
|
m_Http(address, QSslCertificate())
|
||||||
{
|
{
|
||||||
@ -192,7 +194,7 @@ NvPairingManager::pair(QString appVersion, QString pin, QSslCertificate& serverC
|
|||||||
"pair",
|
"pair",
|
||||||
"devicename=roth&updateState=1&phrase=getservercert&salt=" +
|
"devicename=roth&updateState=1&phrase=getservercert&salt=" +
|
||||||
salt.toHex() + "&clientcert=" + IdentityManager::get()->getCertificate().toHex(),
|
salt.toHex() + "&clientcert=" + IdentityManager::get()->getCertificate().toHex(),
|
||||||
false);
|
0);
|
||||||
NvHTTP::verifyResponseStatus(getCert);
|
NvHTTP::verifyResponseStatus(getCert);
|
||||||
if (NvHTTP::getXmlString(getCert, "paired") != "1")
|
if (NvHTTP::getXmlString(getCert, "paired") != "1")
|
||||||
{
|
{
|
||||||
@ -204,7 +206,7 @@ NvPairingManager::pair(QString appVersion, QString pin, QSslCertificate& serverC
|
|||||||
if (serverCertStr == nullptr)
|
if (serverCertStr == nullptr)
|
||||||
{
|
{
|
||||||
qCritical() << "Server likely already pairing";
|
qCritical() << "Server likely already pairing";
|
||||||
m_Http.openConnectionToString(m_Http.m_BaseUrlHttp, "unpair", nullptr, true);
|
m_Http.openConnectionToString(m_Http.m_BaseUrlHttp, "unpair", nullptr, REQUEST_TIMEOUT_MS);
|
||||||
return PairState::ALREADY_IN_PROGRESS;
|
return PairState::ALREADY_IN_PROGRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,7 +215,7 @@ NvPairingManager::pair(QString appVersion, QString pin, QSslCertificate& serverC
|
|||||||
Q_ASSERT(!serverCert.isNull());
|
Q_ASSERT(!serverCert.isNull());
|
||||||
|
|
||||||
qCritical() << "Failed to parse plaincert";
|
qCritical() << "Failed to parse plaincert";
|
||||||
m_Http.openConnectionToString(m_Http.m_BaseUrlHttp, "unpair", nullptr, true);
|
m_Http.openConnectionToString(m_Http.m_BaseUrlHttp, "unpair", nullptr, REQUEST_TIMEOUT_MS);
|
||||||
return PairState::FAILED;
|
return PairState::FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,12 +228,12 @@ NvPairingManager::pair(QString appVersion, QString pin, QSslCertificate& serverC
|
|||||||
"pair",
|
"pair",
|
||||||
"devicename=roth&updateState=1&clientchallenge=" +
|
"devicename=roth&updateState=1&clientchallenge=" +
|
||||||
encryptedChallenge.toHex(),
|
encryptedChallenge.toHex(),
|
||||||
true);
|
REQUEST_TIMEOUT_MS);
|
||||||
NvHTTP::verifyResponseStatus(challengeXml);
|
NvHTTP::verifyResponseStatus(challengeXml);
|
||||||
if (NvHTTP::getXmlString(challengeXml, "paired") != "1")
|
if (NvHTTP::getXmlString(challengeXml, "paired") != "1")
|
||||||
{
|
{
|
||||||
qCritical() << "Failed pairing at stage #2";
|
qCritical() << "Failed pairing at stage #2";
|
||||||
m_Http.openConnectionToString(m_Http.m_BaseUrlHttp, "unpair", nullptr, true);
|
m_Http.openConnectionToString(m_Http.m_BaseUrlHttp, "unpair", nullptr, REQUEST_TIMEOUT_MS);
|
||||||
return PairState::FAILED;
|
return PairState::FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,12 +261,12 @@ NvPairingManager::pair(QString appVersion, QString pin, QSslCertificate& serverC
|
|||||||
"pair",
|
"pair",
|
||||||
"devicename=roth&updateState=1&serverchallengeresp=" +
|
"devicename=roth&updateState=1&serverchallengeresp=" +
|
||||||
encryptedChallengeResponseHash.toHex(),
|
encryptedChallengeResponseHash.toHex(),
|
||||||
true);
|
REQUEST_TIMEOUT_MS);
|
||||||
NvHTTP::verifyResponseStatus(respXml);
|
NvHTTP::verifyResponseStatus(respXml);
|
||||||
if (NvHTTP::getXmlString(respXml, "paired") != "1")
|
if (NvHTTP::getXmlString(respXml, "paired") != "1")
|
||||||
{
|
{
|
||||||
qCritical() << "Failed pairing at stage #3";
|
qCritical() << "Failed pairing at stage #3";
|
||||||
m_Http.openConnectionToString(m_Http.m_BaseUrlHttp, "unpair", nullptr, true);
|
m_Http.openConnectionToString(m_Http.m_BaseUrlHttp, "unpair", nullptr, REQUEST_TIMEOUT_MS);
|
||||||
return PairState::FAILED;
|
return PairState::FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,7 +279,7 @@ NvPairingManager::pair(QString appVersion, QString pin, QSslCertificate& serverC
|
|||||||
serverCertStr))
|
serverCertStr))
|
||||||
{
|
{
|
||||||
qCritical() << "MITM detected";
|
qCritical() << "MITM detected";
|
||||||
m_Http.openConnectionToString(m_Http.m_BaseUrlHttp, "unpair", nullptr, true);
|
m_Http.openConnectionToString(m_Http.m_BaseUrlHttp, "unpair", nullptr, REQUEST_TIMEOUT_MS);
|
||||||
return PairState::FAILED;
|
return PairState::FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -288,7 +290,7 @@ NvPairingManager::pair(QString appVersion, QString pin, QSslCertificate& serverC
|
|||||||
if (QCryptographicHash::hash(expectedResponseData, hashAlgo) != serverResponse)
|
if (QCryptographicHash::hash(expectedResponseData, hashAlgo) != serverResponse)
|
||||||
{
|
{
|
||||||
qCritical() << "Incorrect PIN";
|
qCritical() << "Incorrect PIN";
|
||||||
m_Http.openConnectionToString(m_Http.m_BaseUrlHttp, "unpair", nullptr, true);
|
m_Http.openConnectionToString(m_Http.m_BaseUrlHttp, "unpair", nullptr, REQUEST_TIMEOUT_MS);
|
||||||
return PairState::PIN_WRONG;
|
return PairState::PIN_WRONG;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,24 +302,24 @@ NvPairingManager::pair(QString appVersion, QString pin, QSslCertificate& serverC
|
|||||||
"pair",
|
"pair",
|
||||||
"devicename=roth&updateState=1&clientpairingsecret=" +
|
"devicename=roth&updateState=1&clientpairingsecret=" +
|
||||||
clientPairingSecret.toHex(),
|
clientPairingSecret.toHex(),
|
||||||
true);
|
REQUEST_TIMEOUT_MS);
|
||||||
NvHTTP::verifyResponseStatus(secretRespXml);
|
NvHTTP::verifyResponseStatus(secretRespXml);
|
||||||
if (NvHTTP::getXmlString(secretRespXml, "paired") != "1")
|
if (NvHTTP::getXmlString(secretRespXml, "paired") != "1")
|
||||||
{
|
{
|
||||||
qCritical() << "Failed pairing at stage #4";
|
qCritical() << "Failed pairing at stage #4";
|
||||||
m_Http.openConnectionToString(m_Http.m_BaseUrlHttp, "unpair", nullptr, true);
|
m_Http.openConnectionToString(m_Http.m_BaseUrlHttp, "unpair", nullptr, REQUEST_TIMEOUT_MS);
|
||||||
return PairState::FAILED;
|
return PairState::FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString pairChallengeXml = m_Http.openConnectionToString(m_Http.m_BaseUrlHttps,
|
QString pairChallengeXml = m_Http.openConnectionToString(m_Http.m_BaseUrlHttps,
|
||||||
"pair",
|
"pair",
|
||||||
"devicename=roth&updateState=1&phrase=pairchallenge",
|
"devicename=roth&updateState=1&phrase=pairchallenge",
|
||||||
true);
|
REQUEST_TIMEOUT_MS);
|
||||||
NvHTTP::verifyResponseStatus(pairChallengeXml);
|
NvHTTP::verifyResponseStatus(pairChallengeXml);
|
||||||
if (NvHTTP::getXmlString(pairChallengeXml, "paired") != "1")
|
if (NvHTTP::getXmlString(pairChallengeXml, "paired") != "1")
|
||||||
{
|
{
|
||||||
qCritical() << "Failed pairing at stage #5";
|
qCritical() << "Failed pairing at stage #5";
|
||||||
m_Http.openConnectionToString(m_Http.m_BaseUrlHttp, "unpair", nullptr, true);
|
m_Http.openConnectionToString(m_Http.m_BaseUrlHttp, "unpair", nullptr, REQUEST_TIMEOUT_MS);
|
||||||
return PairState::FAILED;
|
return PairState::FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user