Skip to content

Commit 79462ea

Browse files
committed
Fix GitHub API endpoint selection based on host parsing
Previously, any provided GitHub URL was treated as a GitHub Enterprise Server (GHES) instance when selecting the API endpoint. This assumption was incorrect because the URL can also be for GitHub.com (e.g., https://github.com), which led to using the wrong API endpoint. This commit adds a function to extract the host from a URL. This is used to differentiate between GitHub.com and GHES instances to select the correct API endpoint.
1 parent 602278b commit 79462ea

File tree

1 file changed

+50
-2
lines changed

1 file changed

+50
-2
lines changed

src/vcpkg/base/downloads.cpp

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,46 @@ namespace
3434
cmd.string_arg("-H").string_arg(header);
3535
}
3636
}
37+
38+
// Extracts the host part from a URL string.
39+
std::string extract_host(StringView url)
40+
{
41+
// Remove scheme if present
42+
StringView http_scheme = "http://";
43+
StringView https_scheme = "https://";
44+
if (url.starts_with(http_scheme))
45+
{
46+
url = url.substr(http_scheme.size());
47+
}
48+
else if (url.starts_with(https_scheme))
49+
{
50+
url = url.substr(https_scheme.size());
51+
}
52+
53+
// Remove userinfo if present (e.g., user:pass@host)
54+
const char* at_sign = Strings::find_first_of(url, "@");
55+
size_t at_pos = at_sign[0] == '\0' ? std::string::npos : static_cast<size_t>(at_sign - url.data());
56+
if (at_pos != std::string::npos && at_pos + 1 < url.size())
57+
{
58+
// Move past the '@'
59+
url = url.substr(at_pos + 1);
60+
}
61+
62+
// Find the start of the path (first '/')
63+
const char* first_slash = Strings::find_first_of(url, "/");
64+
size_t slash_pos = first_slash[0] == '\0' ? std::string::npos : static_cast<size_t>(first_slash - url.data());
65+
StringView host_part = slash_pos != std::string::npos ? url.substr(0, slash_pos) : url;
66+
67+
// Remove port if present (e.g., host:port)
68+
const char* colon = Strings::find_first_of(host_part, ":");
69+
size_t colon_pos = colon[0] == '\0' ? std::string::npos : static_cast<size_t>(colon - host_part.data());
70+
if (colon_pos != std::string::npos)
71+
{
72+
host_part = host_part.substr(0, colon_pos);
73+
}
74+
75+
return std::string(host_part);
76+
}
3777
}
3878

3979
namespace vcpkg
@@ -786,8 +826,16 @@ namespace vcpkg
786826
std::string uri;
787827
if (auto github_server_url = maybe_github_server_url.get())
788828
{
789-
uri = *github_server_url;
790-
uri.append("/api/v3");
829+
const auto host = extract_host(*github_server_url);
830+
if (host != "github.com")
831+
{
832+
uri = *github_server_url;
833+
uri.append("/api/v3");
834+
}
835+
else
836+
{
837+
uri = "https://api.github.com";
838+
}
791839
}
792840
else
793841
{

0 commit comments

Comments
 (0)