Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lib http client #697

Open
wants to merge 14 commits into
base: develop
Choose a base branch
from
Prev Previous commit
Next Next commit
move to local test server
  • Loading branch information
weyrick committed Nov 13, 2023
commit 2cd6cb48b5a2f61d3290b1068325562e1c35af41
1 change: 1 addition & 0 deletions libs/visor_http_client/httpssession.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ struct Target {
http_parser_url *parsed;
std::string address;
std::string uri;
std::string port;
};

enum class HTTPMethod {
Expand Down
64 changes: 48 additions & 16 deletions libs/visor_http_client/test_driver.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#include <catch2/catch_test_macros.hpp>

#include <iostream>
#define CPPHTTPLIB_OPENSSL_SUPPORT
#include <httplib.h>

#ifdef __GNUC__
#pragma GCC diagnostic push
Expand All @@ -25,36 +27,36 @@ void connect_tcp_events(std::shared_ptr<uvw::tcp_handle> tcp_handle, std::shared

// SOCKET: socket error
tcp_handle->on<uvw::error_event>([](uvw::error_event &event, uvw::tcp_handle &handle) {
std::cout << "error_event: " << handle.sock().ip << ":" << handle.sock().port << " - " << event.what() << std::endl;
std::cerr << "error_event: " << handle.sock().ip << ":" << handle.sock().port << " - " << event.what() << std::endl;
handle.close();
});

// INCOMING: remote peer closed connection, EOF
tcp_handle->on<uvw::end_event>([tcp_session](uvw::end_event &, uvw::tcp_handle &) {
std::cout << "end_event" << std::endl;
std::cerr << "end_event" << std::endl;
tcp_session->on_end_event();
});

// OUTGOING: we've finished writing all our data and are shutting down
tcp_handle->on<uvw::shutdown_event>([tcp_session](uvw::shutdown_event &, uvw::tcp_handle &) {
std::cout << "shutdown_event" << std::endl;
std::cerr << "shutdown_event" << std::endl;
tcp_session->on_shutdown_event();
});

// INCOMING: remote peer sends data, pass to session
tcp_handle->on<uvw::data_event>([tcp_session](uvw::data_event &event, uvw::tcp_handle &) {
std::cout << "data_event" << std::endl;
std::cerr << "data_event" << std::endl;
tcp_session->receive_data(event.data.get(), event.length);
});

// OUTGOING: write operation has finished
tcp_handle->on<uvw::write_event>([](uvw::write_event &, uvw::tcp_handle &) {
std::cout << "WriteEvent" << std::endl;
std::cerr << "WriteEvent" << std::endl;
});

// SOCKET: on connect
tcp_handle->on<uvw::connect_event>([tcp_session](uvw::connect_event &, uvw::tcp_handle &handle) {
std::cout << "ConnectEvent" << std::endl;
std::cerr << "ConnectEvent" << std::endl;
tcp_session->on_connect_event();

// start reading from incoming stream, fires data_event when receiving
Expand All @@ -68,9 +70,28 @@ TEST_CASE("HTTP Client", "[http]")

auto family = AF_INET;

auto svr = std::make_unique<httplib::SSLServer>(
"/tmp/cacert.pem",
"/tmp/cakey.pem");
if (!svr->is_valid()) {
std::cerr << "could not create test server" << std::endl;
return;
}
auto svr_port = svr->bind_to_any_port("127.0.0.1");
if (svr_port <= 0) {
std::cerr << "could not bind test server" << std::endl;
return;
} else {
std::cerr << "tls test server started on 127.0.0.1:" << svr_port << std::endl;
}

auto svr_thread = std::make_unique<std::thread>([&svr] {
svr->listen_after_bind();
});

std::vector<Target> target_list;
std::vector<std::string> raw_target_list;
raw_target_list.emplace_back("https://google.com");
raw_target_list.emplace_back("https://127.0.0.1:" + std::to_string(svr_port));
auto request = loop->resource<uvw::get_addr_info_req>();
for (const auto &i : raw_target_list) {
uvw::socket_address addr;
Expand All @@ -84,8 +105,12 @@ TEST_CASE("HTTP Client", "[http]")
std::cerr << "could not parse url: " << url << std::endl;
}
std::string authority(&url[parsed.field_data[UF_HOST].off], parsed.field_data[UF_HOST].len);
std::string port;
if (parsed.field_data[UF_PORT].len) {
port = std::string(&url[parsed.field_data[UF_PORT].off], parsed.field_data[UF_PORT].len);
}

auto target_resolved = request->addr_info_sync(authority, "443");
auto target_resolved = request->addr_info_sync(authority, port);
if (!target_resolved.first) {
std::cerr << "unable to resolve target address: " << authority << std::endl;
if (i == "file") {
Expand All @@ -99,6 +124,7 @@ TEST_CASE("HTTP Client", "[http]")
if (!node) {
std::cerr << "name did not resolve to valid IP address for this inet family: " << i
<< std::endl;
continue;
}

if (family == AF_INET) {
Expand All @@ -110,7 +136,12 @@ TEST_CASE("HTTP Client", "[http]")
inet_ntop(AF_INET6, &reinterpret_cast<struct sockaddr_in6 *>(node->ai_addr)->sin6_addr, buffer, INET6_ADDRSTRLEN);
addr.ip = buffer;
}
target_list.push_back({&parsed, addr.ip, url});
target_list.push_back({&parsed, addr.ip, url, port});
}

if (!target_list.size()) {
std::cerr << "no targets resolved" << std::endl;
return;
}

// ---
Expand All @@ -119,17 +150,17 @@ TEST_CASE("HTTP Client", "[http]")
auto tcp_handle = loop->resource<uvw::tcp_handle>(family);

auto malformed_data = [tcp_handle]() {
std::cout << "malformed_data or handshake error" << std::endl;
std::cerr << "malformed_data or handshake error" << std::endl;
tcp_handle->close();
};
auto got_dns_message = []([[maybe_unused]] std::unique_ptr<const char[]> data,
[[maybe_unused]] size_t size) {
std::cout << "got_dns_message" << std::endl;
std::cerr << "got_dns_message" << std::endl;
// process_wire(data.get(), size);
};
auto connection_ready = [tcp_session]() {
/** SEND DATA **/
std::cout << "connection_ready" << std::endl;
std::cerr << "connection_ready" << std::endl;
// tcp_session->write(std::move(std::get<0>(qt)), std::get<1>(qt));
};

Expand All @@ -144,14 +175,15 @@ TEST_CASE("HTTP Client", "[http]")
target_list[0],
HTTPMethod::GET);
if (!tcp_session->setup()) {
std::cout << "setup failed" << std::endl;
std::cerr << "setup failed" << std::endl;
}
std::cout << "connecting to " << target_list[0].address << ":" << 443 << std::endl;
tcp_handle->connect(target_list[0].address, 443);
std::cerr << "connecting to " << target_list[0].address << ":" << target_list[0].port << std::endl;
tcp_handle->connect(target_list[0].address, std::stoul(target_list[0].port));

// ----
CHECK(loop->run() == 0);
loop = nullptr;
svr->stop();
svr_thread->join();

std::cout << "Hello, World!" << std::endl;
}