tidy
Some checks failed
dropshell-build / build (push) Failing after 6s

This commit is contained in:
j842 2025-06-09 18:14:46 +12:00
parent 10e26e8a6c
commit ede75f5565
6 changed files with 91 additions and 44 deletions

3
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"cmake.sourceDirectory": "/home/j/code/dropshell-build/ipdemo"
}

View File

@ -114,4 +114,20 @@ Applications can use:
- MariaDB via connector at `/usr/local/mariadb-connector-c/`
- SQLite3 at `/usr/local/sqlite3/`
All database libraries are statically linked into the final binary.
All database libraries are statically linked into the final binary.
### HTTP Client Utilities
The ipdemo includes a blocking HTTP client utility (`src/http_utils.hpp`) that wraps Drogon's asynchronous HttpClient:
```cpp
#include "http_utils.hpp"
// Make a blocking HTTP GET request
auto response = http_get("example.com", "/api/endpoint", true, 10.0); // HTTPS with 10s timeout
if (response.success && response.status_code == 200) {
std::cout << response.body << std::endl;
}
```
This utility handles the threading complexity and provides a simple synchronous interface for HTTP requests.

View File

@ -112,15 +112,9 @@ set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH}
set(JSONCPP_INCLUDE_DIRS /usr/local/jsoncpp/include)
set(JSONCPP_LIBRARIES /usr/local/jsoncpp/lib/libjsoncpp.a)
##########
# If you include the drogon source code locally in your project, use this method to add drogon
# add_subdirectory(external/drogon)
# target_link_libraries(${PROJECT_NAME} PRIVATE drogon)
##########
find_package(Drogon CONFIG REQUIRED)
target_link_libraries(${PROJECT_NAME} PRIVATE Drogon::Drogon)
# Additional PostgreSQL libraries needed for static linking
set(POSTGRESQL_EXTRA_LIBS
/usr/local/pgsql/lib/libpgcommon.a

48
ipdemo/src/http_utils.cpp Normal file
View File

@ -0,0 +1,48 @@
#include "http_utils.hpp"
HttpResponse http_get(const std::string& url, const std::string& path, bool use_https, double timeout_seconds) {
HttpResponse result{0, "", false};
bool done = false;
std::mutex mtx;
std::condition_variable cv;
std::thread worker([&]() {
trantor::EventLoop loop;
auto client = drogon::HttpClient::newHttpClient(
(use_https ? "https://" : "http://") + url,
&loop
);
auto req = drogon::HttpRequest::newHttpRequest();
req->setMethod(drogon::Get);
req->setPath(path);
client->sendRequest(req, [&](drogon::ReqResult res, const drogon::HttpResponsePtr &resp) {
std::lock_guard<std::mutex> lock(mtx);
if (res == drogon::ReqResult::Ok && resp) {
result.status_code = resp->statusCode();
result.body = resp->body();
result.success = true;
} else {
result.status_code = 0;
result.body = "";
result.success = false;
}
done = true;
cv.notify_one();
loop.quit();
}, timeout_seconds);
loop.loop();
});
// Wait for completion
{
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [&] { return done; });
}
worker.join();
return result;
}

17
ipdemo/src/http_utils.hpp Normal file
View File

@ -0,0 +1,17 @@
#pragma once
#include <string>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <drogon/HttpClient.h>
#include <trantor/net/EventLoop.h>
struct HttpResponse {
int status_code;
std::string body;
bool success;
};
// Utility function for blocking HTTP GET requests
HttpResponse http_get(const std::string& url, const std::string& path, bool use_https = false, double timeout_seconds = 10.0);

View File

@ -1,12 +1,9 @@
#include <iostream>
#include <memory>
#include <thread>
#include <chrono>
#include <nlohmann/json.hpp>
#include <drogon/drogon.h>
#include "version.hpp"
#include "assert.hpp"
#include "http_utils.hpp"
void crashy() {
ASSERT(false, "SUCCESS!");
@ -17,42 +14,14 @@ int main() {
std::cout << std::endl;
std::cout << "Retrieving IP address..." << std::endl;
// Initialize drogon app but don't run it
drogon::app().setLogLevel(trantor::Logger::kError);
std::string ip_body;
int status = 0;
bool done = false;
// Run in a separate thread to avoid event loop conflicts
std::thread worker([&]() {
trantor::EventLoop loop;
auto client = drogon::HttpClient::newHttpClient("http://ipinfo.io", &loop);
auto req = drogon::HttpRequest::newHttpRequest();
req->setMethod(drogon::Get);
req->setPath("/ip");
client->sendRequest(req, [&](drogon::ReqResult result, const drogon::HttpResponsePtr &resp) {
if (result == drogon::ReqResult::Ok && resp) {
ip_body = resp->body();
status = resp->statusCode();
} else {
status = 0;
}
done = true;
loop.quit();
});
loop.loop();
});
worker.join();
// Use the utility function for HTTP GET
auto response = http_get("ipinfo.io", "/ip", false, 10.0);
ASSERT(status == 200, "Failed to get IP");
ASSERT(response.success && response.status_code == 200, "Failed to get IP");
nlohmann::json j;
j["ip"] = ip_body;
j["status"] = status;
j["ip"] = response.body;
j["status"] = response.status_code;
std::cout << j.dump(4) << std::endl;