mirror of
https://github.com/Mahdi-zarei/nekoray.git
synced 2025-12-19 13:50:12 +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)
|
if(WIN32)
|
||||||
list(APPEND CMAKE_PREFIX_PATH "libs/deps/built/x64-windows-static")
|
list(APPEND CMAKE_PREFIX_PATH "libs/deps/built/x64-windows-static")
|
||||||
endif ()
|
endif ()
|
||||||
add_definitions(-DCURL_STATICLIB)
|
|
||||||
|
|
||||||
message("[CMAKE_PREFIX_PATH] ${CMAKE_PREFIX_PATH}")
|
message("[CMAKE_PREFIX_PATH] ${CMAKE_PREFIX_PATH}")
|
||||||
|
|
||||||
@ -66,9 +65,6 @@ list(APPEND NKR_EXTERNAL_TARGETS yaml-cpp)
|
|||||||
find_package(ZXing CONFIG REQUIRED)
|
find_package(ZXing CONFIG REQUIRED)
|
||||||
list(APPEND NKR_EXTERNAL_TARGETS ZXing::ZXing)
|
list(APPEND NKR_EXTERNAL_TARGETS ZXing::ZXing)
|
||||||
|
|
||||||
find_package(cpr REQUIRED)
|
|
||||||
list(APPEND NKR_EXTERNAL_TARGETS cpr::cpr)
|
|
||||||
|
|
||||||
set(BUILD_SHARED_LIBS OFF)
|
set(BUILD_SHARED_LIBS OFF)
|
||||||
list(APPEND NKR_EXTERNAL_TARGETS qhotkey)
|
list(APPEND NKR_EXTERNAL_TARGETS qhotkey)
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifndef NKR_NO_GRPC
|
|
||||||
|
|
||||||
#include "core/server/gen/libcore.pb.h"
|
#include "core/server/gen/libcore.pb.h"
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
@ -54,4 +52,3 @@ namespace NekoGui_rpc {
|
|||||||
|
|
||||||
inline Client *defaultClient;
|
inline Client *defaultClient;
|
||||||
} // namespace NekoGui_rpc
|
} // namespace NekoGui_rpc
|
||||||
#endif
|
|
||||||
|
|||||||
@ -1,8 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QNetworkAccessManager>
|
|
||||||
#include <QNetworkReply>
|
|
||||||
#include <QNetworkRequest>
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
@ -26,7 +23,7 @@ namespace NekoGui_network {
|
|||||||
|
|
||||||
static QString GetHeader(const QList<QPair<QByteArray, QByteArray>> &header, const QString &name);
|
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
|
} // namespace NekoGui_network
|
||||||
|
|
||||||
|
|||||||
@ -19,7 +19,7 @@ mkdir -p $INSTALL_PREFIX
|
|||||||
|
|
||||||
#### clean ####
|
#### clean ####
|
||||||
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 ####
|
#### ZXing v2.3.0 ####
|
||||||
@ -69,46 +69,5 @@ ninja && ninja install
|
|||||||
|
|
||||||
cd ../..
|
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
|
clean
|
||||||
|
|||||||
@ -53,7 +53,7 @@ patchelf --set-rpath '$ORIGIN/../../lib' ./usr/plugins/platformthemes/libqxdgdes
|
|||||||
# fix extra libs...
|
# fix extra libs...
|
||||||
mkdir ./usr/lib2
|
mkdir ./usr/lib2
|
||||||
ls ./usr/lib/
|
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
|
rm -r ./usr/lib
|
||||||
mv ./usr/lib2 ./usr/lib
|
mv ./usr/lib2 ./usr/lib
|
||||||
|
|
||||||
|
|||||||
@ -1,42 +1,67 @@
|
|||||||
#include "include/global/HTTPRequestHelper.hpp"
|
#include "include/global/HTTPRequestHelper.hpp"
|
||||||
|
|
||||||
#include <QByteArray>
|
#include <QNetworkProxy>
|
||||||
#include <QMetaEnum>
|
#include <QNetworkAccessManager>
|
||||||
|
#include <QNetworkReply>
|
||||||
|
#include <QNetworkRequest>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QJsonObject>
|
|
||||||
#include <QJsonArray>
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QDir>
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include "cpr/cpr.h"
|
|
||||||
|
|
||||||
#include "include/global/NekoGui.hpp"
|
#include "include/global/NekoGui.hpp"
|
||||||
|
|
||||||
namespace NekoGui_network {
|
namespace NekoGui_network {
|
||||||
|
|
||||||
NekoHTTPResponse NetworkRequestHelper::HttpGet(const QString &url) {
|
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) {
|
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()},
|
QNetworkProxy p;
|
||||||
{"https", "127.0.0.1:" + QString(Int2String(NekoGui::dataStore->inbound_socks_port)).toStdString()}});
|
p.setType(QNetworkProxy::HttpProxy);
|
||||||
if (NekoGui::dataStore->started_id < 0 && NekoGui::dataStore->sub_use_proxy) {
|
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.")};
|
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) {
|
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));
|
auto _reply = accessManager.get(request);
|
||||||
session.SetUrl(cpr::Url(url.toStdString()));
|
connect(_reply, &QNetworkReply::sslErrors, _reply, [](const QList<QSslError> &errors) {
|
||||||
auto resp = session.Get();
|
QStringList error_str;
|
||||||
auto headerPairs = QList<QPair<QByteArray, QByteArray>>();
|
for (const auto &err: errors) {
|
||||||
for (const auto &item: resp.header) {
|
error_str << err.errorString();
|
||||||
headerPairs.append(std::pair<QByteArray, QByteArray>(QByteArray(item.first.c_str()), QByteArray(item.second.c_str())));
|
}
|
||||||
|
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;
|
if (abortTimer != nullptr) {
|
||||||
auto result = NekoHTTPResponse{ err.c_str(),
|
abortTimer->stop();
|
||||||
resp.text.c_str(), headerPairs};
|
abortTimer->deleteLater();
|
||||||
|
}
|
||||||
|
//
|
||||||
|
auto result = NekoHTTPResponse{_reply->error() == QNetworkReply::NetworkError::NoError ? "" : _reply->errorString(),
|
||||||
|
_reply->readAll(), _reply->rawHeaderPairs()};
|
||||||
|
_reply->deleteLater();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,38 +72,46 @@ namespace NekoGui_network {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
QString NetworkRequestHelper::DownloadAsset(const QString &url, const QString &fileName, bool isTemp) {
|
QString NetworkRequestHelper::DownloadAsset(const QString &url, const QString &fileName) {
|
||||||
cpr::Session session;
|
QNetworkRequest request;
|
||||||
session.SetUrl(cpr::Url{url.toStdString()});
|
QNetworkAccessManager accessManager;
|
||||||
|
request.setUrl(url);
|
||||||
if (NekoGui::dataStore->spmode_system_proxy) {
|
if (NekoGui::dataStore->spmode_system_proxy) {
|
||||||
session.SetProxies({{"http", "127.0.0.1:" + QString(Int2String(NekoGui::dataStore->inbound_socks_port)).toStdString()},
|
QNetworkProxy p;
|
||||||
{"https", "127.0.0.1:" + QString(Int2String(NekoGui::dataStore->inbound_socks_port)).toStdString()}});
|
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 filePath = NekoGui::GetBasePath()+ "/" + fileName;
|
||||||
auto tempFilePath = QString(filePath);
|
auto file = QFile(filePath);
|
||||||
if(isTemp) tempFilePath += ".1";
|
if (file.exists()) {
|
||||||
QFile::remove(tempFilePath);
|
file.remove();
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
if(isTemp) {
|
if (!file.open(QIODevice::WriteOnly)) {
|
||||||
QFile(filePath).remove();
|
return QObject::tr("Could not open file.");
|
||||||
if (!tmpFile.rename(filePath)) {
|
|
||||||
tmpFile.remove();
|
|
||||||
return tmpFile.errorString();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
file.write(_reply->readAll());
|
||||||
|
file.close();
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -19,11 +19,6 @@
|
|||||||
#include "include/sys/windows/MiniDump.h"
|
#include "include/sys/windows/MiniDump.h"
|
||||||
#include "include/sys/windows/vcCheck.h"
|
#include "include/sys/windows/vcCheck.h"
|
||||||
#include "include/sys/windows/eventHandler.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
|
#endif
|
||||||
|
|
||||||
void signal_handler(int signum) {
|
void signal_handler(int signum) {
|
||||||
|
|||||||
@ -2094,14 +2094,14 @@ void MainWindow::DownloadAssets(const QString &geoipUrl, const QString &geositeU
|
|||||||
MW_show_log("Start downloading...");
|
MW_show_log("Start downloading...");
|
||||||
QString errors;
|
QString errors;
|
||||||
if (!geoipUrl.isEmpty()) {
|
if (!geoipUrl.isEmpty()) {
|
||||||
auto resp = NetworkRequestHelper::DownloadAsset(geoipUrl, "geoip.db", true);
|
auto resp = NetworkRequestHelper::DownloadAsset(geoipUrl, "geoip.db");
|
||||||
if (!resp.isEmpty()) {
|
if (!resp.isEmpty()) {
|
||||||
MW_show_log(QString(tr("Failed to download geoip: %1")).arg(resp));
|
MW_show_log(QString(tr("Failed to download geoip: %1")).arg(resp));
|
||||||
errors += "geoip: " + resp;
|
errors += "geoip: " + resp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!geositeUrl.isEmpty()) {
|
if (!geositeUrl.isEmpty()) {
|
||||||
auto resp = NetworkRequestHelper::DownloadAsset(geositeUrl, "geosite.db", true);
|
auto resp = NetworkRequestHelper::DownloadAsset(geositeUrl, "geosite.db");
|
||||||
if (!resp.isEmpty()) {
|
if (!resp.isEmpty()) {
|
||||||
MW_show_log(QString(tr("Failed to download geosite: %1")).arg(resp));
|
MW_show_log(QString(tr("Failed to download geosite: %1")).arg(resp));
|
||||||
errors += "\ngeosite: " + resp;
|
errors += "\ngeosite: " + resp;
|
||||||
@ -2193,7 +2193,7 @@ void MainWindow::CheckUpdate() {
|
|||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto resp = NetworkRequestHelper::HttpGet("https://api.github.com/repos/Mahdi-zarei/nekoray/releases");
|
auto resp = NetworkRequestHelper::HttpGet("https://api.github.com/repos/Mahdi-zarei/nekoray/releases");
|
||||||
if (!resp.error.isEmpty()) {
|
if (!resp.error.isEmpty()) {
|
||||||
runOnUiThread([=] {
|
runOnUiThread([=] {
|
||||||
@ -2201,7 +2201,7 @@ void MainWindow::CheckUpdate() {
|
|||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString assets_name, release_download_url, release_url, release_note, note_pre_release;
|
QString assets_name, release_download_url, release_url, release_note, note_pre_release;
|
||||||
bool exitFlag = false;
|
bool exitFlag = false;
|
||||||
QJsonArray array = QString2QJsonArray(resp.data);
|
QJsonArray array = QString2QJsonArray(resp.data);
|
||||||
@ -2252,7 +2252,7 @@ void MainWindow::CheckUpdate() {
|
|||||||
}
|
}
|
||||||
QString errors;
|
QString errors;
|
||||||
if (!release_download_url.isEmpty()) {
|
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()) {
|
if (!res.isEmpty()) {
|
||||||
errors += res;
|
errors += res;
|
||||||
}
|
}
|
||||||
@ -2275,4 +2275,4 @@ void MainWindow::CheckUpdate() {
|
|||||||
QDesktopServices::openUrl(QUrl(release_url));
|
QDesktopServices::openUrl(QUrl(release_url));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user