Skip to content

Commit ab8e61e

Browse files
heskewclaude
authored andcommitted
Strip all trailing slashes in normalizeUrlPath (review)
Gemini review: '/api//' normalized to '/api/', which then failed both the exact and boundary match for '/api/...' requests; '///' likewise survived as '//'. Strip the full trailing-slash run instead of one. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 6dfd5eb commit ab8e61e

2 files changed

Lines changed: 5 additions & 3 deletions

File tree

server/middlewareChain.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ export function resolveDeps(entries: HttpEntry[], nameToEntry: Map<string, HttpE
125125
}
126126

127127
/**
128-
* Normalizes a urlPath by ensuring a leading slash and stripping a single trailing slash.
128+
* Normalizes a urlPath by ensuring a leading slash and stripping trailing slashes.
129129
* '/api', 'api', and '/api/' are treated equivalently for routing/matching — pathnames
130130
* always begin with '/', so a slash-less urlPath could otherwise never match anything (#1583).
131131
* A urlPath that constrains nothing — the root mount ('/'), empty, or undefined — normalizes
@@ -135,7 +135,7 @@ export function resolveDeps(entries: HttpEntry[], nameToEntry: Map<string, HttpE
135135
export function normalizeUrlPath(urlPath: string | undefined): string | undefined {
136136
if (!urlPath) return undefined;
137137
if (!urlPath.startsWith('/')) urlPath = '/' + urlPath;
138-
if (urlPath.endsWith('/')) urlPath = urlPath.slice(0, -1);
138+
urlPath = urlPath.replace(/\/+$/, '');
139139
return urlPath.length <= 1 ? undefined : urlPath;
140140
}
141141

unitTests/server/middlewareChain.test.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -683,10 +683,12 @@ describe('normalizeUrlPath', () => {
683683
it('normalizes the root mount to undefined — no path constraint (#1766)', () => {
684684
assert.strictEqual(normalizeUrlPath('/'), undefined);
685685
assert.strictEqual(normalizeUrlPath('//'), undefined);
686+
assert.strictEqual(normalizeUrlPath('///'), undefined);
686687
});
687688

688-
it('strips a single trailing slash', () => {
689+
it('strips trailing slashes', () => {
689690
assert.strictEqual(normalizeUrlPath('/api/'), '/api');
691+
assert.strictEqual(normalizeUrlPath('/api//'), '/api');
690692
});
691693

692694
it('leaves paths without trailing slash unchanged', () => {

0 commit comments

Comments
 (0)