Now with HTTPS working!!
Some checks failed
dropshell-build / build (push) Failing after 6s

This commit is contained in:
j842 2025-06-10 09:47:48 +12:00
parent ede75f5565
commit 1fce6fc0b4
3 changed files with 141 additions and 2 deletions

View File

@ -1,4 +1,32 @@
#include "http_utils.hpp"
#include <fstream>
#include <vector>
#include <string>
static std::string find_ca_certificates() {
// Common CA certificate locations across different Linux distributions
const std::vector<std::string> ca_paths = {
"/etc/ssl/certs/ca-certificates.crt", // Debian/Ubuntu/Raspbian
"/etc/pki/tls/certs/ca-bundle.crt", // Fedora/RHEL/CentOS
"/etc/ssl/ca-bundle.pem", // OpenSUSE
"/etc/pki/tls/cert.pem", // Fedora/RHEL alternative
"/etc/ssl/certs/ca-bundle.crt", // Some distros
"/etc/ssl/cert.pem", // Alpine Linux
"/usr/local/share/certs/ca-root-nss.crt", // FreeBSD
"/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem", // CentOS/RHEL 7+
"/etc/ca-certificates/extracted/tls-ca-bundle.pem" // Arch Linux
};
for (const auto& path : ca_paths) {
std::ifstream file(path);
if (file.good()) {
file.close();
return path;
}
}
return "";
}
HttpResponse http_get(const std::string& url, const std::string& path, bool use_https, double timeout_seconds) {
HttpResponse result{0, "", false};
@ -14,6 +42,105 @@ HttpResponse http_get(const std::string& url, const std::string& path, bool use_
&loop
);
// Configure SSL certificates for HTTPS
if (use_https) {
std::string ca_path = find_ca_certificates();
if (!ca_path.empty()) {
std::cerr << "Debug: Found CA certificates at: " << ca_path << std::endl;
// Use addSSLConfigs with proper parameter names for OpenSSL
std::vector<std::pair<std::string, std::string>> sslConfigs;
sslConfigs.push_back({"VerifyCAFile", ca_path});
client->addSSLConfigs(sslConfigs);
} else {
// If no CA certificates found, print warning but continue
std::cerr << "Warning: No system CA certificates found. SSL verification may fail." << std::endl;
}
}
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;
}
HttpResponse http_get_with_ssl(const std::string& url, const std::string& path, const HttpClientSSLConfig& ssl_config, double timeout_seconds) {
HttpResponse result{0, "", false};
bool done = false;
std::mutex mtx;
std::condition_variable cv;
std::thread worker([&]() {
trantor::EventLoop loop;
// Create HTTPS client with SSL configuration options
auto client = drogon::HttpClient::newHttpClient(
"https://" + url,
&loop,
ssl_config.use_old_tls,
ssl_config.validate_cert
);
// Configure client certificate if provided
if (!ssl_config.cert_path.empty() && !ssl_config.key_path.empty()) {
client->setCertPath(ssl_config.cert_path, ssl_config.key_path);
}
// Configure SSL settings
std::vector<std::pair<std::string, std::string>> finalSslConfigs = ssl_config.ssl_configs;
// Set CA certificates path if not explicitly disabled
if (ssl_config.validate_cert) {
// Check if cafile is provided in ssl_configs
bool ca_path_set = false;
for (const auto& config : ssl_config.ssl_configs) {
if (config.first == "cafile" || config.first == "CAfile" ||
config.first == "VerifyCAFile") {
ca_path_set = true;
break;
}
}
// If no cafile provided, use system certificates
if (!ca_path_set) {
std::string ca_path = find_ca_certificates();
if (!ca_path.empty()) {
finalSslConfigs.push_back({"VerifyCAFile", ca_path});
}
}
}
// Add all SSL configurations at once
if (!finalSslConfigs.empty()) {
client->addSSLConfigs(finalSslConfigs);
}
auto req = drogon::HttpRequest::newHttpRequest();
req->setMethod(drogon::Get);
req->setPath(path);

View File

@ -13,5 +13,17 @@ struct HttpResponse {
bool success;
};
// SSL configuration options for HTTP client
struct HttpClientSSLConfig {
std::string cert_path; // Client certificate path
std::string key_path; // Client key path
bool validate_cert = true; // Whether to validate server certificate
bool use_old_tls = false; // Enable TLS 1.0/1.1
std::vector<std::pair<std::string, std::string>> ssl_configs; // Additional SSL_CONF_cmd options
};
// 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);
HttpResponse http_get(const std::string& url, const std::string& path, bool use_https = false, double timeout_seconds = 10.0);
// Utility function for blocking HTTP GET requests with SSL configuration
HttpResponse http_get_with_ssl(const std::string& url, const std::string& path, const HttpClientSSLConfig& ssl_config, double timeout_seconds = 10.0);

View File

@ -15,7 +15,7 @@ int main() {
std::cout << "Retrieving IP address..." << std::endl;
// Use the utility function for HTTP GET
auto response = http_get("ipinfo.io", "/ip", false, 10.0);
auto response = http_get("ipinfo.io", "/ip", true, 10.0);
ASSERT(response.success && response.status_code == 200, "Failed to get IP");