| 12 | }; |
| 13 | |
| 14 | static common_http_url common_http_parse_url(const std::string & url) { |
| 15 | common_http_url parts; |
| 16 | auto scheme_end = url.find("://"); |
| 17 | |
| 18 | if (scheme_end == std::string::npos) { |
| 19 | throw std::runtime_error("invalid URL: no scheme"); |
| 20 | } |
| 21 | parts.scheme = url.substr(0, scheme_end); |
| 22 | |
| 23 | if (parts.scheme != "http" && parts.scheme != "https") { |
| 24 | throw std::runtime_error("unsupported URL scheme: " + parts.scheme); |
| 25 | } |
| 26 | |
| 27 | auto rest = url.substr(scheme_end + 3); |
| 28 | auto at_pos = rest.find('@'); |
| 29 | |
| 30 | if (at_pos != std::string::npos) { |
| 31 | auto auth = rest.substr(0, at_pos); |
| 32 | auto colon_pos = auth.find(':'); |
| 33 | if (colon_pos != std::string::npos) { |
| 34 | parts.user = auth.substr(0, colon_pos); |
| 35 | parts.password = auth.substr(colon_pos + 1); |
| 36 | } else { |
| 37 | parts.user = auth; |
| 38 | } |
| 39 | rest = rest.substr(at_pos + 1); |
| 40 | } |
| 41 | |
| 42 | auto slash_pos = rest.find('/'); |
| 43 | |
| 44 | if (slash_pos != std::string::npos) { |
| 45 | parts.host = rest.substr(0, slash_pos); |
| 46 | parts.path = rest.substr(slash_pos); |
| 47 | } else { |
| 48 | parts.host = rest; |
| 49 | parts.path = "/"; |
| 50 | } |
| 51 | |
| 52 | auto colon_pos = parts.host.find(':'); |
| 53 | |
| 54 | if (colon_pos != std::string::npos) { |
| 55 | parts.port = std::stoi(parts.host.substr(colon_pos + 1)); |
| 56 | parts.host = parts.host.substr(0, colon_pos); |
| 57 | } else if (parts.scheme == "http") { |
| 58 | parts.port = 80; |
| 59 | } else if (parts.scheme == "https") { |
| 60 | parts.port = 443; |
| 61 | } else { |
| 62 | throw std::runtime_error("unsupported URL scheme: " + parts.scheme); |
| 63 | } |
| 64 | |
| 65 | return parts; |
| 66 | } |
| 67 | |
| 68 | static std::pair<httplib::Client, common_http_url> common_http_client(const std::string & url) { |
| 69 | common_http_url parts = common_http_parse_url(url); |
no test coverage detected