Skip to content

Commit 98dd048

Browse files
committed
added httplib(header only lib) client as simple client to fixing crash when using qnetworkaccessmanager
1 parent adef6cd commit 98dd048

File tree

6 files changed

+124
-0
lines changed

6 files changed

+124
-0
lines changed

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
[submodule "3rdparty/QHotkey"]
22
path = 3rdparty/QHotkey
33
url = https://github.com/Skycoder42/QHotkey.git
4+
[submodule "3rdparty/cpp-httplib"]
5+
path = 3rdparty/cpp-httplib
6+
url = https://github.com/yhirose/cpp-httplib.git

3rdparty/cpp-httplib

Submodule cpp-httplib added at 9b5f76f

CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ else ()
107107
list(APPEND NKR_EXTERNAL_TARGETS qhotkey)
108108
endif ()
109109

110+
# if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
111+
# include_directories(3rdparty/cpp-httplib)
112+
# endif()
113+
110114
#### debug print ####
111115

112116
if (DBG_CMAKE)
@@ -126,6 +130,7 @@ set(PROJECT_SOURCES
126130
main/NekoGui.cpp
127131
main/NekoGui_Utils.cpp
128132
main/HTTPRequestHelper.cpp
133+
main/SimpleHttpClient.cpp
129134

130135
3rdparty/base64.cpp
131136
3rdparty/qrcodegen.cpp

main/HTTPRequestHelper.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <QTimer>
88

99
#include "main/NekoGui.hpp"
10+
#include "main/SimpleHttpClient.h"
1011

1112
namespace NekoGui_network {
1213

@@ -44,6 +45,15 @@ namespace NekoGui_network {
4445
c.setPeerVerifyMode(QSslSocket::PeerVerifyMode::VerifyNone);
4546
request.setSslConfiguration(c);
4647
}
48+
49+
#ifdef __GNUC__
50+
{
51+
QNetworkAccessManagerAlternative::HttpClient syncClient;
52+
auto res = syncClient.executeGetRequest(request, accessManager);
53+
return NekoHTTPResponse{res.success ? "" : res.error,
54+
res.body.toLocal8Bit(), res.headers};
55+
}
56+
#else
4757
//
4858
auto _reply = accessManager.get(request);
4959
connect(_reply, &QNetworkReply::sslErrors, _reply, [](const QList<QSslError> &errors) {
@@ -73,6 +83,7 @@ namespace NekoGui_network {
7383
_reply->readAll(), _reply->rawHeaderPairs()};
7484
_reply->deleteLater();
7585
return result;
86+
#endif
7687
}
7788

7889
QString NetworkRequestHelper::GetHeader(const QList<QPair<QByteArray, QByteArray>> &header, const QString &name) {

main/SimpleHttpClient.cpp

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#include "SimpleHttpClient.h"
2+
#include "3rdparty/cpp-httplib/httplib.h"
3+
#include <QNetworkProxy>
4+
5+
#ifdef __GNUC__
6+
7+
QNetworkAccessManagerAlternative::HttpResult QNetworkAccessManagerAlternative::HttpClient::executeGetRequest(const QNetworkRequest &request, QNetworkAccessManager &manager) {
8+
HttpResult result;
9+
result.success = false;
10+
result.statusCode = -1;
11+
12+
QUrl url = request.url();
13+
if (!url.isValid() || (url.scheme() != "http" && url.scheme() != "https")) {
14+
result.error = "Unsupported or invalid URL scheme";
15+
return result;
16+
}
17+
18+
// bool isHttps = (url.scheme() == "https");
19+
20+
QString host = url.host();
21+
// int port = (url.port() == -1) ? (isHttps ? 443 : 80) : url.port();
22+
23+
// httplib::Client client(host.toStdString(), port);
24+
httplib::Client client(host.toStdString());
25+
26+
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
27+
if (isHttps) {
28+
client.enable_server_certificate_verification(false); // Skip SSL verification for demo
29+
}
30+
#endif
31+
32+
QNetworkProxy proxy = manager.proxy();
33+
if (proxy.type() != QNetworkProxy::NoProxy) {
34+
client.set_proxy(
35+
proxy.hostName().toStdString(),
36+
static_cast<int>(proxy.port())
37+
);
38+
if(!proxy.user().isEmpty())
39+
client.set_proxy_basic_auth(
40+
proxy.user().toStdString(),
41+
proxy.password().toStdString()
42+
);
43+
}
44+
45+
httplib::Headers headers;
46+
QList<QByteArray> headerList = request.rawHeaderList();
47+
for (const QByteArray &header : headerList) {
48+
headers.insert(std::pair{header.toStdString(), request.rawHeader(header).toStdString()});
49+
}
50+
51+
auto const pathURL = url.path();
52+
auto res = client.Get(pathURL.toStdString());
53+
54+
if (res) {
55+
result.statusCode = res->status;
56+
for (const auto &header : res->headers) {
57+
result.headers.append(qMakePair(QByteArray(header.first.c_str()),
58+
QByteArray(header.second.c_str())));
59+
}
60+
if (res->status == 200) {
61+
result.success = true;
62+
result.body = QString::fromStdString(res->body);
63+
} else {
64+
result.error = QString("HTTP Error: %1").arg(res->status);
65+
}
66+
} else {
67+
result.error = QString::fromStdString(httplib::to_string(res.error()));
68+
}
69+
70+
return result;
71+
}
72+
73+
#endif

main/SimpleHttpClient.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#ifndef SIMPLEHTTPCLIENT_H
2+
#define SIMPLEHTTPCLIENT_H
3+
4+
#include <QNetworkRequest>
5+
#include <QUrl>
6+
#include <QByteArray>
7+
#include <QList>
8+
#include <QPair>
9+
#include <QString>
10+
#include <QNetworkAccessManager>
11+
12+
13+
#ifdef __GNUC__
14+
namespace QNetworkAccessManagerAlternative{
15+
struct HttpResult {
16+
bool success; // Success flag
17+
QString body; // Response body
18+
QList<QPair<QByteArray, QByteArray>> headers; // Raw headers as key-value pairs
19+
QString error; // Error message if not successful
20+
int statusCode; // HTTP status code
21+
};
22+
23+
class HttpClient {
24+
public:
25+
static HttpResult executeGetRequest(const QNetworkRequest &request, QNetworkAccessManager &manager);
26+
};
27+
28+
}
29+
#endif
30+
31+
#endif // SIMPLEHTTPCLIENT_H

0 commit comments

Comments
 (0)