12#include <boost/asio.hpp>
13#include <boost/asio/ssl.hpp>
14#include <boost/beast.hpp>
16#include <nlohmann/json.hpp>
19namespace net = boost::asio;
20namespace ssl = net::ssl;
21namespace beast = boost::beast;
22namespace http = beast::http;
23using tcp = net::ip::tcp;
35User::User(std::string login, std::string
name, std::string company,
38 company(
std::move(company)), location(
std::move(location)) {}
45void User::print()
const {
46 std::cout <<
"Login: " <<
login <<
"\n"
47 <<
"Name: " <<
name <<
"\n"
48 <<
"Company: " <<
company <<
"\n"
69User User::fetch_github_user(
const std::string &username) {
70 const std::string host =
"api.github.com";
71 const std::string target =
"/users/" + username;
74 ssl::context ctx(ssl::context::sslv23_client);
75 ctx.set_default_verify_paths();
77 ssl::stream<tcp::socket> stream(ioc, ctx);
78 tcp::resolver resolver(ioc);
80 beast::get_lowest_layer(stream).connect(
81 *resolver.resolve(host,
"443").begin());
82 stream.handshake(ssl::stream_base::client);
84 http::request<http::string_body> req{http::verb::get, target, 11};
85 req.set(http::field::host, host);
86 req.set(http::field::user_agent,
"github_user_fetcher");
87 http::write(stream, req);
89 beast::flat_buffer buffer;
90 http::response<http::string_body> res;
91 http::read(stream, buffer, res);
93 if (res.result() != http::status::ok) {
94 throw std::runtime_error(
"GitHub request failed: HTTP " +
95 std::to_string(res.result_int()));
98 const auto json = nlohmann::json::parse(res.body(),
nullptr,
false);
99 if (json.is_discarded()) {
100 throw std::runtime_error(
"Failed to parse JSON");
103 beast::error_code error_code;
104 if (stream.shutdown(error_code)) {
105 throw beast::system_error{error_code};
108 return User{json.value(
"login",
""), json.value(
"name",
""),
109 json.value(
"company",
""), json.value(
"location",
"")};
Structure representing a GitHub user.
const char * name
Full name.
const char * login
GitHub username.
const char * location
User's location.
const char * company
Company name.