added httplib(header only lib) client as simple client to fixing crash when using qnetworkaccessmanager

This commit is contained in:
SC-One 2025-01-15 21:32:37 +03:30
parent adef6cd4af
commit 98dd048c60
No known key found for this signature in database
GPG Key ID: 1B9AE3605708E8DD
6 changed files with 124 additions and 0 deletions

3
.gitmodules vendored
View File

@ -1,3 +1,6 @@
[submodule "3rdparty/QHotkey"] [submodule "3rdparty/QHotkey"]
path = 3rdparty/QHotkey path = 3rdparty/QHotkey
url = https://github.com/Skycoder42/QHotkey.git url = https://github.com/Skycoder42/QHotkey.git
[submodule "3rdparty/cpp-httplib"]
path = 3rdparty/cpp-httplib
url = https://github.com/yhirose/cpp-httplib.git

1
3rdparty/cpp-httplib vendored Submodule

@ -0,0 +1 @@
Subproject commit 9b5f76f8337d54c8f6a0920df2232ac74eff613b

View File

@ -107,6 +107,10 @@ else ()
list(APPEND NKR_EXTERNAL_TARGETS qhotkey) list(APPEND NKR_EXTERNAL_TARGETS qhotkey)
endif () endif ()
# if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
# include_directories(3rdparty/cpp-httplib)
# endif()
#### debug print #### #### debug print ####
if (DBG_CMAKE) if (DBG_CMAKE)
@ -126,6 +130,7 @@ set(PROJECT_SOURCES
main/NekoGui.cpp main/NekoGui.cpp
main/NekoGui_Utils.cpp main/NekoGui_Utils.cpp
main/HTTPRequestHelper.cpp main/HTTPRequestHelper.cpp
main/SimpleHttpClient.cpp
3rdparty/base64.cpp 3rdparty/base64.cpp
3rdparty/qrcodegen.cpp 3rdparty/qrcodegen.cpp

View File

@ -7,6 +7,7 @@
#include <QTimer> #include <QTimer>
#include "main/NekoGui.hpp" #include "main/NekoGui.hpp"
#include "main/SimpleHttpClient.h"
namespace NekoGui_network { namespace NekoGui_network {
@ -44,6 +45,15 @@ namespace NekoGui_network {
c.setPeerVerifyMode(QSslSocket::PeerVerifyMode::VerifyNone); c.setPeerVerifyMode(QSslSocket::PeerVerifyMode::VerifyNone);
request.setSslConfiguration(c); request.setSslConfiguration(c);
} }
#ifdef __GNUC__
{
QNetworkAccessManagerAlternative::HttpClient syncClient;
auto res = syncClient.executeGetRequest(request, accessManager);
return NekoHTTPResponse{res.success ? "" : res.error,
res.body.toLocal8Bit(), res.headers};
}
#else
// //
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) {
@ -73,6 +83,7 @@ namespace NekoGui_network {
_reply->readAll(), _reply->rawHeaderPairs()}; _reply->readAll(), _reply->rawHeaderPairs()};
_reply->deleteLater(); _reply->deleteLater();
return result; return result;
#endif
} }
QString NetworkRequestHelper::GetHeader(const QList<QPair<QByteArray, QByteArray>> &header, const QString &name) { QString NetworkRequestHelper::GetHeader(const QList<QPair<QByteArray, QByteArray>> &header, const QString &name) {

73
main/SimpleHttpClient.cpp Normal file
View File

@ -0,0 +1,73 @@
#include "SimpleHttpClient.h"
#include "3rdparty/cpp-httplib/httplib.h"
#include <QNetworkProxy>
#ifdef __GNUC__
QNetworkAccessManagerAlternative::HttpResult QNetworkAccessManagerAlternative::HttpClient::executeGetRequest(const QNetworkRequest &request, QNetworkAccessManager &manager) {
HttpResult result;
result.success = false;
result.statusCode = -1;
QUrl url = request.url();
if (!url.isValid() || (url.scheme() != "http" && url.scheme() != "https")) {
result.error = "Unsupported or invalid URL scheme";
return result;
}
// bool isHttps = (url.scheme() == "https");
QString host = url.host();
// int port = (url.port() == -1) ? (isHttps ? 443 : 80) : url.port();
// httplib::Client client(host.toStdString(), port);
httplib::Client client(host.toStdString());
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
if (isHttps) {
client.enable_server_certificate_verification(false); // Skip SSL verification for demo
}
#endif
QNetworkProxy proxy = manager.proxy();
if (proxy.type() != QNetworkProxy::NoProxy) {
client.set_proxy(
proxy.hostName().toStdString(),
static_cast<int>(proxy.port())
);
if(!proxy.user().isEmpty())
client.set_proxy_basic_auth(
proxy.user().toStdString(),
proxy.password().toStdString()
);
}
httplib::Headers headers;
QList<QByteArray> headerList = request.rawHeaderList();
for (const QByteArray &header : headerList) {
headers.insert(std::pair{header.toStdString(), request.rawHeader(header).toStdString()});
}
auto const pathURL = url.path();
auto res = client.Get(pathURL.toStdString());
if (res) {
result.statusCode = res->status;
for (const auto &header : res->headers) {
result.headers.append(qMakePair(QByteArray(header.first.c_str()),
QByteArray(header.second.c_str())));
}
if (res->status == 200) {
result.success = true;
result.body = QString::fromStdString(res->body);
} else {
result.error = QString("HTTP Error: %1").arg(res->status);
}
} else {
result.error = QString::fromStdString(httplib::to_string(res.error()));
}
return result;
}
#endif

31
main/SimpleHttpClient.h Normal file
View File

@ -0,0 +1,31 @@
#ifndef SIMPLEHTTPCLIENT_H
#define SIMPLEHTTPCLIENT_H
#include <QNetworkRequest>
#include <QUrl>
#include <QByteArray>
#include <QList>
#include <QPair>
#include <QString>
#include <QNetworkAccessManager>
#ifdef __GNUC__
namespace QNetworkAccessManagerAlternative{
struct HttpResult {
bool success; // Success flag
QString body; // Response body
QList<QPair<QByteArray, QByteArray>> headers; // Raw headers as key-value pairs
QString error; // Error message if not successful
int statusCode; // HTTP status code
};
class HttpClient {
public:
static HttpResult executeGetRequest(const QNetworkRequest &request, QNetworkAccessManager &manager);
};
}
#endif
#endif // SIMPLEHTTPCLIENT_H