Skip to content

Commit 655ea3c

Browse files
authored
fix(server): handle prefix problem (#326)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Bug Fixes** - Enhanced URL prefix handling for more precise matching of requests based on the expected structure. - **Tests** - Introduced new test cases to validate URL prefix matching behavior, ensuring only correctly formatted paths are recognized. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent 4038fb9 commit 655ea3c

File tree

2 files changed

+100
-15
lines changed

2 files changed

+100
-15
lines changed

packages/server/src/adapters/standard/handler.test.ts

+96-13
Original file line numberDiff line numberDiff line change
@@ -340,20 +340,103 @@ describe('standardHandler', () => {
340340
expect(init).toHaveBeenCalledWith(options)
341341
})
342342

343-
it('should check prefix first', async () => {
344-
const result = await handler.handle({
345-
method: 'GET',
346-
headers: {
347-
Accept: 'application/json',
348-
},
349-
url: new URL('http://localhost/users/1'),
350-
body: vi.fn(),
351-
signal,
352-
}, {
353-
context: { db: 'postgres' },
354-
prefix: '/invalid',
343+
describe('prefix', () => {
344+
it('require match prefix', async () => {
345+
matcher.match.mockResolvedValue({
346+
path: ['ping'],
347+
procedure: ping,
348+
params: { id: '__id__' },
349+
})
350+
351+
const result = await handler.handle({
352+
method: 'GET',
353+
headers: {
354+
Accept: 'application/json',
355+
},
356+
url: new URL('http://localhost/users/1'),
357+
body: vi.fn(),
358+
signal,
359+
}, {
360+
context: { db: 'postgres' },
361+
prefix: '/prefix',
362+
})
363+
364+
expect(result).toEqual({ matched: false, response: undefined })
365+
expect(matcher.match).not.toHaveBeenCalled()
366+
})
367+
368+
it('must be separate with slash', async () => {
369+
matcher.match.mockResolvedValue({
370+
path: ['ping'],
371+
procedure: ping,
372+
params: { id: '__id__' },
373+
})
374+
375+
const result = await handler.handle({
376+
method: 'GET',
377+
headers: {
378+
Accept: 'application/json',
379+
},
380+
url: new URL('http://localhost/prefixusers/1'),
381+
body: vi.fn(),
382+
signal,
383+
}, {
384+
context: { db: 'postgres' },
385+
prefix: '/prefix',
386+
})
387+
388+
expect(result).toEqual({ matched: false, response: undefined })
389+
expect(matcher.match).not.toHaveBeenCalled()
390+
})
391+
392+
it('support prefix exact match', async () => {
393+
matcher.match.mockResolvedValue({
394+
path: ['ping'],
395+
procedure: ping,
396+
params: { id: '__id__' },
397+
})
398+
399+
const result = await handler.handle({
400+
method: 'GET',
401+
headers: {
402+
Accept: 'application/json',
403+
},
404+
url: new URL('http://localhost/prefix'),
405+
body: vi.fn(),
406+
signal,
407+
}, {
408+
context: { db: 'postgres' },
409+
prefix: '/prefix',
410+
})
411+
412+
expect(result.matched).toEqual(true)
413+
expect(matcher.match).toHaveBeenCalledOnce()
414+
expect(matcher.match).toHaveBeenCalledWith('GET', '/')
355415
})
356416

357-
expect(result).toEqual({ matched: false, response: undefined })
417+
it('support prefix ending with slash', async () => {
418+
matcher.match.mockResolvedValue({
419+
path: ['ping'],
420+
procedure: ping,
421+
params: { id: '__id__' },
422+
})
423+
424+
const result = await handler.handle({
425+
method: 'GET',
426+
headers: {
427+
Accept: 'application/json',
428+
},
429+
url: new URL('http://localhost/prefix/something'),
430+
body: vi.fn(),
431+
signal,
432+
}, {
433+
context: { db: 'postgres' },
434+
prefix: '/prefix/',
435+
})
436+
437+
expect(result.matched).toEqual(true)
438+
expect(matcher.match).toHaveBeenCalledOnce()
439+
expect(matcher.match).toHaveBeenCalledWith('GET', '/something')
440+
})
358441
})
359442
})

packages/server/src/adapters/standard/handler.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,15 @@ export class StandardHandler<T extends Context> {
7272
}
7373

7474
async handle(request: StandardLazyRequest, options: StandardHandleOptions<T>): Promise<StandardHandleResult> {
75-
if (options.prefix && !request.url.pathname.startsWith(options.prefix)) {
75+
const prefix = (options.prefix?.replace(/\/$/, '') || undefined) as HTTPPath | undefined
76+
77+
if (prefix && !request.url.pathname.startsWith(`${prefix}/`) && request.url.pathname !== prefix) {
7678
return { matched: false, response: undefined }
7779
}
7880

7981
return intercept(
8082
this.rootInterceptors,
81-
{ ...options, request },
83+
{ ...options, request, prefix },
8284
async (interceptorOptions) => {
8385
let isDecoding = false
8486

0 commit comments

Comments
 (0)