Tolerate trailing slash in cluster publicUrl · Entire
Tolerate trailing slash in cluster publicUrl
8fc7b1c→main·
toothbrush·3w ago·2 files·+8 added/-3 removed
hostFromPublicURL rejected any non-empty path, so a catalog entry like https://aws-us-east-2.entire.io/ (Path == "/") was dropped in clustersToRegions — silently removing clusters and risking "no regions available to mirror into" if the control plane emits trailing slashes. publicUrl is a trusted catalog field, so accept a bare "/" path; real paths/queries/fragments/userinfo are still refused. (Trail review)
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com
Sessions
32af87a69f30View transcript
?\ Interactive Repo Mirror Onboarding WizardClaude Code·1 step
Changes
2
cmd/entire/cli
Mrepo_mirror_create_wizard.go+6/-3
- Mrepo_mirror_create_wizard_test.go+2
102 unmodified lines
103
104
105
106
107
108
106
107
108
109
110
111
112
113
114
102 unmodified lines
// Reject anything beyond scheme://host[:port]. url.Parse demotes the
// `host@evil.com` userinfo trick into u.User (leaving u.Host=evil.com) and
// stashes a trailing path in u.Path, neither of which validateClusterHost
// would otherwise see. Same belt-and-suspenders the positional <cluster-host>
// arg gets — the host flows into clone URLs and the STS audience.
if u.User != nil || u.Path != "" || u.RawQuery != "" || u.Fragment != "" {
// would otherwise see. A bare "/" path is tolerated: publicUrl is a trusted
// catalog field, and a trailing slash (https://host/) is benign — rejecting
// it would silently drop the cluster and could leave the wizard with no
// regions. Anything richer (a real path, query, fragment, userinfo) is still
// refused, since the host flows into clone URLs and the STS audience.
if u.User != nil || (u.Path != "" && u.Path != "/") || u.RawQuery != "" || u.Fragment != "" {
return "", fmt.Errorf("public_url %q must be scheme://host[:port] only", raw)
}
if err := validateClusterHost(u.Host); err != nil {
Mcmd/entire/cli/repo_mirror_create_wizard.go+6/-3
66 unmodified lines
67
68
69
70
71
72
73
74
66 unmodified lines
{name: "bare host", in: "eu-west-1.entire.io", want: "eu-west-1.entire.io"},
{name: "host with port", in: "https://localhost:8080", want: "localhost:8080"},
{name: "trims space", in: " https://aws-us-east-2.entire.io ", want: "aws-us-east-2.entire.io"},
// A trailing slash is a benign catalog shape, not a path injection.
{name: "trailing slash", in: "https://aws-us-east-2.entire.io/", want: "aws-us-east-2.entire.io"},
{name: "empty", in: "", wantErr: true},
// userinfo trick rejected by validateClusterHost
{name: "userinfo injection", in: "https://aws-us-east-2.entire.io@evil.com", wantErr: true},
Mcmd/entire/cli/repo_mirror_create_wizard_test.go+2