mirror of
https://github.com/Mahdi-zarei/nekoray.git
synced 2025-12-19 05:30:06 +08:00
Migrate to QtNetwork for HTTP(s) requests (#344)
* Migrate to QtNetwork for HTTP(s) requests * Fix * Cleanup * Fix linux build
This commit is contained in:
parent
19cbfe0754
commit
c43d11cb7b
@ -37,7 +37,6 @@ list(APPEND CMAKE_PREFIX_PATH ${NKR_LIBS})
|
||||
if(WIN32)
|
||||
list(APPEND CMAKE_PREFIX_PATH "libs/deps/built/x64-windows-static")
|
||||
endif ()
|
||||
add_definitions(-DCURL_STATICLIB)
|
||||
|
||||
message("[CMAKE_PREFIX_PATH] ${CMAKE_PREFIX_PATH}")
|
||||
|
||||
@ -66,9 +65,6 @@ list(APPEND NKR_EXTERNAL_TARGETS yaml-cpp)
|
||||
find_package(ZXing CONFIG REQUIRED)
|
||||
list(APPEND NKR_EXTERNAL_TARGETS ZXing::ZXing)
|
||||
|
||||
find_package(cpr REQUIRED)
|
||||
list(APPEND NKR_EXTERNAL_TARGETS cpr::cpr)
|
||||
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
list(APPEND NKR_EXTERNAL_TARGETS qhotkey)
|
||||
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef NKR_NO_GRPC
|
||||
|
||||
#include "core/server/gen/libcore.pb.h"
|
||||
#include <QString>
|
||||
|
||||
@ -54,4 +52,3 @@ namespace NekoGui_rpc {
|
||||
|
||||
inline Client *defaultClient;
|
||||
} // namespace NekoGui_rpc
|
||||
#endif
|
||||
|
||||
@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
#include <QNetworkRequest>
|
||||
#include <QObject>
|
||||
#include <functional>
|
||||
|
||||
@ -26,7 +23,7 @@ namespace NekoGui_network {
|
||||
|
||||
static QString GetHeader(const QList<QPair<QByteArray, QByteArray>> &header, const QString &name);
|
||||
|
||||
static QString DownloadAsset(const QString &url, const QString &fileName, bool isTemp);
|
||||
static QString DownloadAsset(const QString &url, const QString &fileName);
|
||||
};
|
||||
} // namespace NekoGui_network
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ mkdir -p $INSTALL_PREFIX
|
||||
|
||||
#### clean ####
|
||||
clean() {
|
||||
rm -rf dl.zip yaml-* zxing-* protobuf curl cpr libpsl* zlib vcpkg
|
||||
rm -rf dl.zip yaml-* zxing-* protobuf
|
||||
}
|
||||
|
||||
#### ZXing v2.3.0 ####
|
||||
@ -69,46 +69,5 @@ ninja && ninja install
|
||||
|
||||
cd ../..
|
||||
|
||||
if [[ "$(uname -s)" == *"NT"* ]]; then
|
||||
git clone https://github.com/Microsoft/vcpkg.git
|
||||
cd vcpkg
|
||||
export VCPKG_BUILD_TYPE="release"
|
||||
export VCPKG_LIBRARY_LINKAGE="static"
|
||||
./bootstrap-vcpkg.sh
|
||||
./vcpkg integrate install
|
||||
./vcpkg install curl:x64-windows-static --x-install-root=$INSTALL_PREFIX
|
||||
|
||||
cd ..
|
||||
|
||||
git clone https://github.com/libcpr/cpr.git
|
||||
cd cpr
|
||||
git checkout bb01c8db702fb41e5497aee9c0559ddf4bf13749
|
||||
sed -i 's/find_package(CURL COMPONENTS HTTP HTTPS)/find_package(CURL REQUIRED)/g' CMakeLists.txt
|
||||
mkdir build && cd build
|
||||
cmake -GNinja .. -DCMAKE_BUILD_TYPE=Release -DCPR_USE_SYSTEM_CURL=ON -DBUILD_SHARED_LIBS=OFF -DCURL_STATICLIB=ON -DCMAKE_OSX_ARCHITECTURES=$1 -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 -DCURL_LIBRARY=../../built/x64-windows-static/lib -DCURL_INCLUDE_DIR=../../built/x64-windows-static/include -DCMAKE_INSTALL_PREFIX=$INSTALL_PREFIX
|
||||
ninja && ninja install
|
||||
|
||||
cd ../..
|
||||
|
||||
else
|
||||
git clone https://github.com/curl/curl.git
|
||||
cd curl
|
||||
git checkout 7eb8c048470ed2cc14dca75be9c1cdae7ac8498b
|
||||
mkdir build && cd build
|
||||
cmake -GNinja .. -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DCMAKE_OSX_ARCHITECTURES=$1 -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 -DCMAKE_INSTALL_PREFIX=$INSTALL_PREFIX -DCURL_STATICLIB=ON -DUSE_LIBIDN2=OFF
|
||||
ninja && ninja install
|
||||
|
||||
cd ../..
|
||||
|
||||
git clone https://github.com/libcpr/cpr.git
|
||||
cd cpr
|
||||
git checkout bb01c8db702fb41e5497aee9c0559ddf4bf13749
|
||||
mkdir build && cd build
|
||||
cmake -GNinja .. -DCMAKE_BUILD_TYPE=Release -DCPR_USE_SYSTEM_CURL=ON -DBUILD_SHARED_LIBS=OFF -DCURL_STATICLIB=ON -DCMAKE_OSX_ARCHITECTURES=$1 -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 -DCMAKE_INSTALL_PREFIX=$INSTALL_PREFIX
|
||||
ninja && ninja install
|
||||
|
||||
cd ../..
|
||||
fi
|
||||
|
||||
####
|
||||
clean
|
||||
|
||||
@ -53,7 +53,7 @@ patchelf --set-rpath '$ORIGIN/../../lib' ./usr/plugins/platformthemes/libqxdgdes
|
||||
# fix extra libs...
|
||||
mkdir ./usr/lib2
|
||||
ls ./usr/lib/
|
||||
cp ./usr/lib/libQt* ./usr/lib/libxcb-util* ./usr/lib/libicuuc* ./usr/lib/libicui18n* ./usr/lib/libicudata* ./usr/lib/libssl* ./usr/lib/libcrypto* ./usr/lib2
|
||||
cp ./usr/lib/libQt* ./usr/lib/libxcb-util* ./usr/lib/libicuuc* ./usr/lib/libicui18n* ./usr/lib/libicudata* ./usr/lib2
|
||||
rm -r ./usr/lib
|
||||
mv ./usr/lib2 ./usr/lib
|
||||
|
||||
|
||||
@ -1,42 +1,67 @@
|
||||
#include "include/global/HTTPRequestHelper.hpp"
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QMetaEnum>
|
||||
#include <QNetworkProxy>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
#include <QNetworkRequest>
|
||||
#include <QTimer>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
#include <QFile>
|
||||
#include <QDir>
|
||||
#include <QApplication>
|
||||
#include "cpr/cpr.h"
|
||||
|
||||
#include "include/global/NekoGui.hpp"
|
||||
|
||||
namespace NekoGui_network {
|
||||
|
||||
NekoHTTPResponse NetworkRequestHelper::HttpGet(const QString &url) {
|
||||
cpr::Session session;
|
||||
QNetworkRequest request;
|
||||
QNetworkAccessManager accessManager;
|
||||
request.setUrl(url);
|
||||
if (NekoGui::dataStore->sub_use_proxy || NekoGui::dataStore->spmode_system_proxy) {
|
||||
session.SetProxies({{"http", "127.0.0.1:" + QString(Int2String(NekoGui::dataStore->inbound_socks_port)).toStdString()},
|
||||
{"https", "127.0.0.1:" + QString(Int2String(NekoGui::dataStore->inbound_socks_port)).toStdString()}});
|
||||
if (NekoGui::dataStore->started_id < 0 && NekoGui::dataStore->sub_use_proxy) {
|
||||
QNetworkProxy p;
|
||||
p.setType(QNetworkProxy::HttpProxy);
|
||||
p.setHostName("127.0.0.1");
|
||||
p.setPort(NekoGui::dataStore->inbound_socks_port);
|
||||
accessManager.setProxy(p);
|
||||
if (NekoGui::dataStore->started_id < 0) {
|
||||
return NekoHTTPResponse{QObject::tr("Request with proxy but no profile started.")};
|
||||
}
|
||||
}
|
||||
// Set attribute
|
||||
request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);
|
||||
request.setHeader(QNetworkRequest::KnownHeaders::UserAgentHeader, NekoGui::dataStore->GetUserAgent());
|
||||
if (NekoGui::dataStore->sub_insecure) {
|
||||
session.SetVerifySsl(cpr::VerifySsl{false});
|
||||
QSslConfiguration c;
|
||||
c.setPeerVerifyMode(QSslSocket::PeerVerifyMode::VerifyNone);
|
||||
request.setSslConfiguration(c);
|
||||
}
|
||||
session.SetUserAgent(cpr::UserAgent{NekoGui::dataStore->GetUserAgent().toStdString()});
|
||||
session.SetTimeout(cpr::Timeout(10000));
|
||||
session.SetUrl(cpr::Url(url.toStdString()));
|
||||
auto resp = session.Get();
|
||||
auto headerPairs = QList<QPair<QByteArray, QByteArray>>();
|
||||
for (const auto &item: resp.header) {
|
||||
headerPairs.append(std::pair<QByteArray, QByteArray>(QByteArray(item.first.c_str()), QByteArray(item.second.c_str())));
|
||||
//
|
||||
auto _reply = accessManager.get(request);
|
||||
connect(_reply, &QNetworkReply::sslErrors, _reply, [](const QList<QSslError> &errors) {
|
||||
QStringList error_str;
|
||||
for (const auto &err: errors) {
|
||||
error_str << err.errorString();
|
||||
}
|
||||
MW_show_log(QString("SSL Errors: %1 %2").arg(error_str.join(","), NekoGui::dataStore->sub_insecure ? "(Ignored)" : ""));
|
||||
});
|
||||
// Wait for response
|
||||
auto abortTimer = new QTimer;
|
||||
abortTimer->setSingleShot(true);
|
||||
abortTimer->setInterval(10000);
|
||||
connect(abortTimer, &QTimer::timeout, _reply, &QNetworkReply::abort);
|
||||
abortTimer->start();
|
||||
{
|
||||
QEventLoop loop;
|
||||
connect(_reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
|
||||
loop.exec();
|
||||
}
|
||||
auto err = resp.error.message.empty() ? (resp.status_code == 200 ? "" : resp.status_line) : resp.error.message;
|
||||
auto result = NekoHTTPResponse{ err.c_str(),
|
||||
resp.text.c_str(), headerPairs};
|
||||
if (abortTimer != nullptr) {
|
||||
abortTimer->stop();
|
||||
abortTimer->deleteLater();
|
||||
}
|
||||
//
|
||||
auto result = NekoHTTPResponse{_reply->error() == QNetworkReply::NetworkError::NoError ? "" : _reply->errorString(),
|
||||
_reply->readAll(), _reply->rawHeaderPairs()};
|
||||
_reply->deleteLater();
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -47,38 +72,46 @@ namespace NekoGui_network {
|
||||
return "";
|
||||
}
|
||||
|
||||
QString NetworkRequestHelper::DownloadAsset(const QString &url, const QString &fileName, bool isTemp) {
|
||||
cpr::Session session;
|
||||
session.SetUrl(cpr::Url{url.toStdString()});
|
||||
QString NetworkRequestHelper::DownloadAsset(const QString &url, const QString &fileName) {
|
||||
QNetworkRequest request;
|
||||
QNetworkAccessManager accessManager;
|
||||
request.setUrl(url);
|
||||
if (NekoGui::dataStore->spmode_system_proxy) {
|
||||
session.SetProxies({{"http", "127.0.0.1:" + QString(Int2String(NekoGui::dataStore->inbound_socks_port)).toStdString()},
|
||||
{"https", "127.0.0.1:" + QString(Int2String(NekoGui::dataStore->inbound_socks_port)).toStdString()}});
|
||||
QNetworkProxy p;
|
||||
p.setType(QNetworkProxy::HttpProxy);
|
||||
p.setHostName("127.0.0.1");
|
||||
p.setPort(NekoGui::dataStore->inbound_socks_port);
|
||||
accessManager.setProxy(p);
|
||||
if (NekoGui::dataStore->started_id < 0) {
|
||||
return QObject::tr("Request with proxy but no profile started.");
|
||||
}
|
||||
}
|
||||
|
||||
auto _reply = accessManager.get(request);
|
||||
connect(_reply, &QNetworkReply::sslErrors, _reply, [](const QList<QSslError> &errors) {
|
||||
QStringList error_str;
|
||||
for (const auto &err: errors) {
|
||||
error_str << err.errorString();
|
||||
}
|
||||
MW_show_log(QString("SSL Errors: %1").arg(error_str.join(",")));
|
||||
});
|
||||
QEventLoop loop;
|
||||
connect(_reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
|
||||
loop.exec();
|
||||
if(_reply->error() != QNetworkReply::NetworkError::NoError) {
|
||||
return _reply->errorString();
|
||||
}
|
||||
|
||||
auto filePath = NekoGui::GetBasePath()+ "/" + fileName;
|
||||
auto tempFilePath = QString(filePath);
|
||||
if(isTemp) tempFilePath += ".1";
|
||||
QFile::remove(tempFilePath);
|
||||
|
||||
std::ofstream fout;
|
||||
fout.open(tempFilePath.toStdString(), std::ios::trunc | std::ios::out | std::ios::binary);
|
||||
auto r = session.Download(fout);
|
||||
fout.close();
|
||||
|
||||
auto tmpFile = QFile(tempFilePath);
|
||||
if (r.status_code != 200) {
|
||||
tmpFile.remove();
|
||||
if (r.status_code == 0) {
|
||||
return "Please check the URL and your network Connectivity";
|
||||
}
|
||||
return r.status_line.c_str();
|
||||
auto file = QFile(filePath);
|
||||
if (file.exists()) {
|
||||
file.remove();
|
||||
}
|
||||
if(isTemp) {
|
||||
QFile(filePath).remove();
|
||||
if (!tmpFile.rename(filePath)) {
|
||||
tmpFile.remove();
|
||||
return tmpFile.errorString();
|
||||
}
|
||||
if (!file.open(QIODevice::WriteOnly)) {
|
||||
return QObject::tr("Could not open file.");
|
||||
}
|
||||
file.write(_reply->readAll());
|
||||
file.close();
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
@ -19,11 +19,6 @@
|
||||
#include "include/sys/windows/MiniDump.h"
|
||||
#include "include/sys/windows/vcCheck.h"
|
||||
#include "include/sys/windows/eventHandler.h"
|
||||
#pragma comment (lib, "cpr.lib")
|
||||
#pragma comment (lib, "libcurl.lib")
|
||||
#pragma comment (lib, "Ws2_32.lib")
|
||||
#pragma comment (lib, "Wldap32.lib")
|
||||
#pragma comment (lib, "Crypt32.lib")
|
||||
#endif
|
||||
|
||||
void signal_handler(int signum) {
|
||||
|
||||
@ -2094,14 +2094,14 @@ void MainWindow::DownloadAssets(const QString &geoipUrl, const QString &geositeU
|
||||
MW_show_log("Start downloading...");
|
||||
QString errors;
|
||||
if (!geoipUrl.isEmpty()) {
|
||||
auto resp = NetworkRequestHelper::DownloadAsset(geoipUrl, "geoip.db", true);
|
||||
auto resp = NetworkRequestHelper::DownloadAsset(geoipUrl, "geoip.db");
|
||||
if (!resp.isEmpty()) {
|
||||
MW_show_log(QString(tr("Failed to download geoip: %1")).arg(resp));
|
||||
errors += "geoip: " + resp;
|
||||
}
|
||||
}
|
||||
if (!geositeUrl.isEmpty()) {
|
||||
auto resp = NetworkRequestHelper::DownloadAsset(geositeUrl, "geosite.db", true);
|
||||
auto resp = NetworkRequestHelper::DownloadAsset(geositeUrl, "geosite.db");
|
||||
if (!resp.isEmpty()) {
|
||||
MW_show_log(QString(tr("Failed to download geosite: %1")).arg(resp));
|
||||
errors += "\ngeosite: " + resp;
|
||||
@ -2193,7 +2193,7 @@ void MainWindow::CheckUpdate() {
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
auto resp = NetworkRequestHelper::HttpGet("https://api.github.com/repos/Mahdi-zarei/nekoray/releases");
|
||||
if (!resp.error.isEmpty()) {
|
||||
runOnUiThread([=] {
|
||||
@ -2201,7 +2201,7 @@ void MainWindow::CheckUpdate() {
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
QString assets_name, release_download_url, release_url, release_note, note_pre_release;
|
||||
bool exitFlag = false;
|
||||
QJsonArray array = QString2QJsonArray(resp.data);
|
||||
@ -2252,7 +2252,7 @@ void MainWindow::CheckUpdate() {
|
||||
}
|
||||
QString errors;
|
||||
if (!release_download_url.isEmpty()) {
|
||||
auto res = NetworkRequestHelper::DownloadAsset(release_download_url, "nekoray.zip", false);
|
||||
auto res = NetworkRequestHelper::DownloadAsset(release_download_url, "nekoray.zip");
|
||||
if (!res.isEmpty()) {
|
||||
errors += res;
|
||||
}
|
||||
@ -2275,4 +2275,4 @@ void MainWindow::CheckUpdate() {
|
||||
QDesktopServices::openUrl(QUrl(release_url));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user