refactor: improve NetworkRequestHelper

This commit is contained in:
parhelia512 2025-09-27 19:00:12 +08:00
parent e615045a92
commit 3cdf027dd6
7 changed files with 139 additions and 113 deletions

View File

@ -89,12 +89,14 @@ namespace Configs {
QString simple_dl_url = "http://cachefly.cachefly.net/1mb.test"; QString simple_dl_url = "http://cachefly.cachefly.net/1mb.test";
bool allow_beta_update = false; bool allow_beta_update = false;
// Network
bool net_use_proxy = false;
bool net_insecure = false;
// Subscription // Subscription
QString user_agent = ""; // set at main.cpp QString user_agent = ""; // set at main.cpp
bool sub_use_proxy = false;
bool sub_clear = false;
bool sub_insecure = false;
int sub_auto_update = -30; int sub_auto_update = -30;
bool sub_clear = false;
bool sub_send_hwid = false; bool sub_send_hwid = false;
// Security // Security

View File

@ -26,7 +26,7 @@ namespace Configs_network {
; ;
public: public:
static HTTPResponse HttpGet(const QString &url); static HTTPResponse HttpGet(const QString &url, bool sendHwid = false);
static QString GetHeader(const QList<QPair<QByteArray, QByteArray>> &header, const QString &name); static QString GetHeader(const QList<QPair<QByteArray, QByteArray>> &header, const QString &name);

View File

@ -490,95 +490,125 @@
</widget> </widget>
<widget class="QWidget" name="tab_3"> <widget class="QWidget" name="tab_3">
<attribute name="title"> <attribute name="title">
<string>Subscription</string> <string>Network</string>
</attribute> </attribute>
<layout class="QGridLayout" name="gridLayout_3"> <layout class="QVBoxLayout" name="verticalLayout_6">
<item row="0" column="1"> <item>
<layout class="QHBoxLayout" name="horizontalLayout_5"> <widget class="QGroupBox" name="groupBox_3">
<item>
<widget class="QCheckBox" name="sub_auto_update_enable">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Enable</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_21">
<property name="text">
<string>Interval (minute, invalid if less than 30)</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="sub_auto_update">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="1">
<widget class="MyLineEdit" name="user_agent"/>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="sub_use_proxy">
<property name="text">
<string>Use proxy when updating subscription</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="sub_insecure">
<property name="text">
<string>Ignore TLS errors when updating subscription</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="sub_clear">
<property name="text">
<string>Clear servers before updating subscription</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QCheckBox" name="sub_send_hwid">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;HWID=%1&lt;/p&gt;&lt;p&gt;OS=%2&lt;/p&gt;&lt;p&gt;OS Version=%3&lt;/p&gt;&lt;p&gt;Model=%4&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Enable sending HWID, device model, and OS version when updating subscription</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_20">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum"> <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="text"> <property name="title">
<string>Automatic update</string> <string>Network</string>
</property> </property>
<layout class="QHBoxLayout" name="horizontalLayout_11">
<item>
<widget class="QCheckBox" name="net_use_proxy">
<property name="text">
<string>Use proxy</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="net_insecure">
<property name="text">
<string>Ignore TLS errors</string>
</property>
</widget>
</item>
</layout>
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item>
<widget class="QLabel" name="label_4"> <widget class="QGroupBox" name="groupBox_4">
<property name="text"> <property name="sizePolicy">
<string>User Agent</string> <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property> </property>
<property name="title">
<string>Subscription</string>
</property>
<layout class="QGridLayout" name="gridLayout_10">
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QCheckBox" name="sub_auto_update_enable">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Enable</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_21">
<property name="text">
<string>Interval (minute, invalid if less than 30)</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="sub_auto_update">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="1">
<widget class="MyLineEdit" name="user_agent"/>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="sub_clear">
<property name="text">
<string>Clear servers before updating subscription</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="sub_send_hwid">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;HWID=%1&lt;/p&gt;&lt;p&gt;OS=%2&lt;/p&gt;&lt;p&gt;OS Version=%3&lt;/p&gt;&lt;p&gt;Model=%4&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Enable sending HWID, device model, and OS version when updating subscription</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_20">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Automatic update</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>User Agent</string>
</property>
</widget>
</item>
</layout>
</widget> </widget>
</item> </item>
</layout> </layout>

View File

@ -807,7 +807,7 @@ namespace Subscription {
auto groupName = group == nullptr ? content : group->name; auto groupName = group == nullptr ? content : group->name;
MW_show_log(">>>>>>>> " + QObject::tr("Requesting subscription: %1").arg(groupName)); MW_show_log(">>>>>>>> " + QObject::tr("Requesting subscription: %1").arg(groupName));
auto resp = NetworkRequestHelper::HttpGet(content); auto resp = NetworkRequestHelper::HttpGet(content, Configs::dataStore->sub_send_hwid);
if (!resp.error.isEmpty()) { if (!resp.error.isEmpty()) {
MW_show_log("<<<<<<<< " + QObject::tr("Requesting subscription %1 error: %2").arg(groupName, resp.error + "\n" + resp.data)); MW_show_log("<<<<<<<< " + QObject::tr("Requesting subscription %1 error: %2").arg(groupName, resp.error + "\n" + resp.data));
return; return;

View File

@ -255,7 +255,7 @@ namespace Configs {
_add(new configItem("theme", &theme, itemType::string)); _add(new configItem("theme", &theme, itemType::string));
_add(new configItem("custom_inbound", &custom_inbound, itemType::string)); _add(new configItem("custom_inbound", &custom_inbound, itemType::string));
_add(new configItem("custom_route", &custom_route_global, itemType::string)); _add(new configItem("custom_route", &custom_route_global, itemType::string));
_add(new configItem("sub_use_proxy", &sub_use_proxy, itemType::boolean)); _add(new configItem("net_use_proxy", &net_use_proxy, itemType::boolean));
_add(new configItem("remember_id", &remember_id, itemType::integer)); _add(new configItem("remember_id", &remember_id, itemType::integer));
_add(new configItem("remember_enable", &remember_enable, itemType::boolean)); _add(new configItem("remember_enable", &remember_enable, itemType::boolean));
_add(new configItem("language", &language, itemType::integer)); _add(new configItem("language", &language, itemType::integer));
@ -277,7 +277,7 @@ namespace Configs {
_add(new configItem("vpn_ipv6", &vpn_ipv6, itemType::boolean)); _add(new configItem("vpn_ipv6", &vpn_ipv6, itemType::boolean));
_add(new configItem("vpn_strict_route", &vpn_strict_route, itemType::boolean)); _add(new configItem("vpn_strict_route", &vpn_strict_route, itemType::boolean));
_add(new configItem("sub_clear", &sub_clear, itemType::boolean)); _add(new configItem("sub_clear", &sub_clear, itemType::boolean));
_add(new configItem("sub_insecure", &sub_insecure, itemType::boolean)); _add(new configItem("net_insecure", &net_insecure, itemType::boolean));
_add(new configItem("sub_auto_update", &sub_auto_update, itemType::integer)); _add(new configItem("sub_auto_update", &sub_auto_update, itemType::integer));
_add(new configItem("sub_send_hwid", &sub_send_hwid, itemType::boolean)); _add(new configItem("sub_send_hwid", &sub_send_hwid, itemType::boolean));
_add(new configItem("start_minimal", &start_minimal, itemType::boolean)); _add(new configItem("start_minimal", &start_minimal, itemType::boolean));

View File

@ -14,11 +14,12 @@
namespace Configs_network { namespace Configs_network {
HTTPResponse NetworkRequestHelper::HttpGet(const QString &url) { HTTPResponse NetworkRequestHelper::HttpGet(const QString &url, bool sendHwid) {
QNetworkRequest request; QNetworkRequest request;
QNetworkAccessManager accessManager; QNetworkAccessManager accessManager;
accessManager.setTransferTimeout(10000);
request.setUrl(url); request.setUrl(url);
if (Configs::dataStore->sub_use_proxy || Configs::dataStore->spmode_system_proxy) { if (Configs::dataStore->net_use_proxy || Configs::dataStore->spmode_system_proxy) {
if (Configs::dataStore->started_id < 0) { if (Configs::dataStore->started_id < 0) {
return HTTPResponse{QObject::tr("Request with proxy but no profile started.")}; return HTTPResponse{QObject::tr("Request with proxy but no profile started.")};
} }
@ -31,13 +32,13 @@ namespace Configs_network {
// Set attribute // Set attribute
request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy); request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);
request.setHeader(QNetworkRequest::KnownHeaders::UserAgentHeader, Configs::dataStore->GetUserAgent()); request.setHeader(QNetworkRequest::KnownHeaders::UserAgentHeader, Configs::dataStore->GetUserAgent());
if (Configs::dataStore->sub_insecure) { if (Configs::dataStore->net_insecure) {
QSslConfiguration c; QSslConfiguration c;
c.setPeerVerifyMode(QSslSocket::PeerVerifyMode::VerifyNone); c.setPeerVerifyMode(QSslSocket::PeerVerifyMode::VerifyNone);
request.setSslConfiguration(c); request.setSslConfiguration(c);
} }
//Attach HWID and device info headers if enabled in settings //Attach HWID and device info headers if enabled in settings
if (Configs::dataStore->sub_send_hwid && !request.url().toString().contains("/throneproj/")) { if (sendHwid) {
auto details = GetDeviceDetails(); auto details = GetDeviceDetails();
if (!details.hwid.isEmpty()) request.setRawHeader("x-hwid", details.hwid.toUtf8()); if (!details.hwid.isEmpty()) request.setRawHeader("x-hwid", details.hwid.toUtf8());
@ -52,23 +53,13 @@ namespace Configs_network {
for (const auto &err: errors) { for (const auto &err: errors) {
error_str << err.errorString(); error_str << err.errorString();
} }
MW_show_log(QString("SSL Errors: %1 %2").arg(error_str.join(","), Configs::dataStore->sub_insecure ? "(Ignored)" : "")); MW_show_log(QString("SSL Errors: %1 %2").arg(error_str.join(","), Configs::dataStore->net_insecure ? "(Ignored)" : ""));
}); });
// Wait for response // Wait for response
auto abortTimer = new QTimer; QEventLoop loop;
abortTimer->setSingleShot(true); connect(_reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
abortTimer->setInterval(10000); loop.exec();
connect(abortTimer, &QTimer::timeout, _reply, &QNetworkReply::abort);
abortTimer->start();
{
QEventLoop loop;
connect(_reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
loop.exec();
}
if (abortTimer != nullptr) {
abortTimer->stop();
abortTimer->deleteLater();
}
// //
auto result = HTTPResponse{_reply->error() == QNetworkReply::NetworkError::NoError ? "" : _reply->errorString(), auto result = HTTPResponse{_reply->error() == QNetworkReply::NetworkError::NoError ? "" : _reply->errorString(),
_reply->readAll(), _reply->rawHeaderPairs()}; _reply->readAll(), _reply->rawHeaderPairs()};
@ -87,7 +78,7 @@ namespace Configs_network {
QNetworkRequest request; QNetworkRequest request;
QNetworkAccessManager accessManager; QNetworkAccessManager accessManager;
request.setUrl(url); request.setUrl(url);
if (Configs::dataStore->spmode_system_proxy) { if (Configs::dataStore->net_use_proxy || Configs::dataStore->spmode_system_proxy) {
if (Configs::dataStore->started_id < 0) { if (Configs::dataStore->started_id < 0) {
return QObject::tr("Request with proxy but no profile started."); return QObject::tr("Request with proxy but no profile started.");
} }
@ -97,8 +88,11 @@ namespace Configs_network {
p.setPort(Configs::dataStore->inbound_socks_port); p.setPort(Configs::dataStore->inbound_socks_port);
accessManager.setProxy(p); accessManager.setProxy(p);
} }
request.setHeader(QNetworkRequest::KnownHeaders::UserAgentHeader, Configs::dataStore->GetUserAgent()); if (Configs::dataStore->net_insecure) {
request.setRawHeader("Accept", "application/octet-stream"); QSslConfiguration c;
c.setPeerVerifyMode(QSslSocket::PeerVerifyMode::VerifyNone);
request.setSslConfiguration(c);
}
auto _reply = accessManager.get(request); auto _reply = accessManager.get(request);
connect(_reply, &QNetworkReply::sslErrors, _reply, [](const QList<QSslError> &errors) { connect(_reply, &QNetworkReply::sslErrors, _reply, [](const QList<QSslError> &errors) {
@ -106,7 +100,7 @@ namespace Configs_network {
for (const auto &err: errors) { for (const auto &err: errors) {
error_str << err.errorString(); error_str << err.errorString();
} }
MW_show_log(QString("SSL Errors: %1").arg(error_str.join(","))); MW_show_log(QString("SSL Errors: %1 %2").arg(error_str.join(","), Configs::dataStore->net_insecure ? "(Ignored)" : ""));
}); });
connect(_reply, &QNetworkReply::downloadProgress, _reply, [&](qint64 bytesReceived, qint64 bytesTotal) connect(_reply, &QNetworkReply::downloadProgress, _reply, [&](qint64 bytesReceived, qint64 bytesTotal)
{ {
@ -123,6 +117,7 @@ namespace Configs_network {
GetMainWindow()->setDownloadReport({}, false); GetMainWindow()->setDownloadReport({}, false);
GetMainWindow()->UpdateDataView(true); GetMainWindow()->UpdateDataView(true);
}); });
_reply->deleteLater();
if(_reply->error() != QNetworkReply::NetworkError::NoError) { if(_reply->error() != QNetworkReply::NetworkError::NoError) {
return _reply->errorString(); return _reply->errorString();
} }
@ -137,7 +132,6 @@ namespace Configs_network {
} }
file.write(_reply->readAll()); file.write(_reply->readAll());
file.close(); file.close();
_reply->deleteLater();
return ""; return "";
} }

View File

@ -114,9 +114,9 @@ DialogBasicSettings::DialogBasicSettings(QWidget *parent)
ui->user_agent->setText(Configs::dataStore->user_agent); ui->user_agent->setText(Configs::dataStore->user_agent);
ui->user_agent->setPlaceholderText(Configs::dataStore->GetUserAgent(true)); ui->user_agent->setPlaceholderText(Configs::dataStore->GetUserAgent(true));
D_LOAD_BOOL(sub_use_proxy) D_LOAD_BOOL(net_use_proxy)
D_LOAD_BOOL(sub_clear) D_LOAD_BOOL(sub_clear)
D_LOAD_BOOL(sub_insecure) D_LOAD_BOOL(net_insecure)
D_LOAD_BOOL(sub_send_hwid) D_LOAD_BOOL(sub_send_hwid)
D_LOAD_INT_ENABLE(sub_auto_update, sub_auto_update_enable) D_LOAD_INT_ENABLE(sub_auto_update, sub_auto_update_enable)
auto details = GetDeviceDetails(); auto details = GetDeviceDetails();
@ -206,9 +206,9 @@ void DialogBasicSettings::accept() {
} }
Configs::dataStore->user_agent = ui->user_agent->text(); Configs::dataStore->user_agent = ui->user_agent->text();
D_SAVE_BOOL(sub_use_proxy) D_SAVE_BOOL(net_use_proxy)
D_SAVE_BOOL(sub_clear) D_SAVE_BOOL(sub_clear)
D_SAVE_BOOL(sub_insecure) D_SAVE_BOOL(net_insecure)
D_SAVE_BOOL(sub_send_hwid) D_SAVE_BOOL(sub_send_hwid)
D_SAVE_INT_ENABLE(sub_auto_update, sub_auto_update_enable) D_SAVE_INT_ENABLE(sub_auto_update, sub_auto_update_enable)