#pragma once #include struct common_http_url { std::string scheme; std::string user; std::string password; std::string host; std::string path; }; static common_http_url common_http_parse_url(const std::string & url) { common_http_url parts; auto scheme_end = url.find("://"); if (scheme_end == std::string::npos) { throw std::runtime_error("invalid URL: no scheme"); } parts.scheme = url.substr(0, scheme_end); if (parts.scheme != "http" && parts.scheme != "https") { throw std::runtime_error("unsupported URL scheme: " + parts.scheme); } auto rest = url.substr(scheme_end + 3); auto at_pos = rest.find('@'); if (at_pos != std::string::npos) { auto auth = rest.substr(0, at_pos); auto colon_pos = auth.find(':'); if (colon_pos != std::string::npos) { parts.user = auth.substr(0, colon_pos); parts.password = auth.substr(colon_pos + 1); } else { parts.user = auth; } rest = rest.substr(at_pos + 1); } auto slash_pos = rest.find('/'); if (slash_pos != std::string::npos) { parts.host = rest.substr(0, slash_pos); parts.path = rest.substr(slash_pos); } else { parts.host = rest; parts.path = "/"; } return parts; } static std::pair common_http_client(const std::string & url) { common_http_url parts = common_http_parse_url(url); if (parts.host.empty()) { throw std::runtime_error("error: invalid URL format"); } httplib::Client cli(parts.scheme + "://" + parts.host); if (!parts.user.empty()) { cli.set_basic_auth(parts.user, parts.password); } cli.set_follow_location(true); return { std::move(cli), std::move(parts) }; } static std::string common_http_show_masked_url(const common_http_url & parts) { return parts.scheme + "://" + (parts.user.empty() ? "" : "****:****@") + parts.host + parts.path; }