diff --git a/pkg/agent/endpoint/front.go b/pkg/agent/endpoint/front.go index ca0dc51a8..7a2741dfa 100644 --- a/pkg/agent/endpoint/front.go +++ b/pkg/agent/endpoint/front.go @@ -415,10 +415,13 @@ func splitEndpointPath(u *url.URL) (endpointPath, error) { return endpointPath{}, errMalformedPath } // "_" and "%5F" both land here; neither is a registrable name - // (IsReservedAgentName) - if agentName == UnnamedAgentSegment { + // (IsReservedAgentName, ValidateDeployment) + if agentName == UnnamedSegment { agentName = "" } + if deployment == UnnamedSegment { + deployment = "" + } return endpointPath{agentName: agentName, deployment: deployment, path: path, escPath: escPath}, nil } diff --git a/pkg/agent/endpoint/front_test.go b/pkg/agent/endpoint/front_test.go index 089c692b5..0a98e65fb 100644 --- a/pkg/agent/endpoint/front_test.go +++ b/pkg/agent/endpoint/front_test.go @@ -287,6 +287,10 @@ func TestSplitEndpointPath(t *testing.T) { {name: "bare underscore is unnamed", target: "/agents/_/d/x", agentName: "", deployment: "d", path: "/x", escPath: "/x"}, {name: "encoded underscore is unnamed", target: "/agents/%5F/d/x", agentName: "", deployment: "d", path: "/x", escPath: "/x"}, {name: "double encoded underscore is a name", target: "/agents/%255F/d/x", agentName: "%5F", deployment: "d", path: "/x", escPath: "/x"}, + {name: "bare underscore deployment is unnamed", target: "/agents/a/_/x", agentName: "a", deployment: "", path: "/x", escPath: "/x"}, + {name: "encoded underscore deployment is unnamed", target: "/agents/a/%5F/x", agentName: "a", deployment: "", path: "/x", escPath: "/x"}, + {name: "unnamed agent and deployment", target: "/agents/_/_/x", agentName: "", deployment: "", path: "/x", escPath: "/x"}, + {name: "default is a deployment name", target: "/agents/a/default/x", agentName: "a", deployment: "default", path: "/x", escPath: "/x"}, {name: "not an endpoint path", target: "/other/x", err: errNotEndpointPath}, {name: "no deployment segment", target: "/agents/a", err: errNotEndpointPath}, diff --git a/pkg/agent/endpoint/registry.go b/pkg/agent/endpoint/registry.go index 7fbc036ae..7b61d680d 100644 --- a/pkg/agent/endpoint/registry.go +++ b/pkg/agent/endpoint/registry.go @@ -21,29 +21,15 @@ import ( "sync/atomic" ) -// DefaultDeployment is the URL segment that addresses workers registered with an -// empty deployment name (self-hosted workers typically set none). -const DefaultDeployment = "default" - -// UnnamedAgentSegment is the URL segment that addresses workers registered with -// an empty agent name. -const UnnamedAgentSegment = "_" +// UnnamedSegment is the URL segment that addresses workers registered with an +// empty agent name or deployment. +const UnnamedSegment = "_" // IsReservedAgentName reports whether a name cannot address a worker. These are // unreserved characters (RFC 3986 ยง2.3), so percent-encoding them yields no // distinct form to address them by. func IsReservedAgentName(agentName string) bool { - return agentName == UnnamedAgentSegment || agentName == "." || agentName == ".." -} - -// NormalizeDeployment maps an empty deployment to the segment that addresses it -// in a URL. Every embedder must key its scopes through this, or a worker that -// registered without a deployment is unreachable from any node but its own. -func NormalizeDeployment(d string) string { - if d == "" { - return DefaultDeployment - } - return d + return agentName == UnnamedSegment || agentName == "." || agentName == ".." } // DefaultMaxStreams is the soft per-session concurrency cap used only for diff --git a/pkg/service/agentendpointscope.go b/pkg/service/agentendpointscope.go index ee4dac12e..1a6ab251f 100644 --- a/pkg/service/agentendpointscope.go +++ b/pkg/service/agentendpointscope.go @@ -32,7 +32,7 @@ type endpointScopeKey struct { } func newEndpointScopeKey(apiKey, agentName, deployment string) endpointScopeKey { - return endpointScopeKey{apiKey, agentName, endpoint.NormalizeDeployment(deployment)} + return endpointScopeKey{apiKey, agentName, deployment} } // EndpointScopes maps that tenancy onto the endpoint package's scopes, one per