diff --git a/bun.lockb b/bun.lockb index cbaee6d06..78894db9b 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/deno_dist/middleware/timing/index.ts b/deno_dist/middleware/timing/index.ts index d4dc022f1..429929c32 100644 --- a/deno_dist/middleware/timing/index.ts +++ b/deno_dist/middleware/timing/index.ts @@ -21,7 +21,7 @@ interface TimingOptions { enabled: boolean | ((c: Context) => boolean) totalDescription: string autoEnd: boolean - crossOrigin: boolean | string + crossOrigin: boolean | string | ((c: Context) => boolean | string) } const getTime = () => { @@ -64,10 +64,14 @@ export const timing = (config?: Partial): MiddlewareHandler => { if (enabled) { c.res.headers.append('Server-Timing', headers.join(',')) - if (options.crossOrigin) { + + const crossOrigin = + typeof options.crossOrigin === 'function' ? options.crossOrigin(c) : options.crossOrigin + + if (crossOrigin) { c.res.headers.append( 'Timing-Allow-Origin', - typeof options.crossOrigin === 'string' ? options.crossOrigin : '*' + typeof crossOrigin === 'string' ? crossOrigin : '*' ) } } diff --git a/src/middleware/timing/index.test.ts b/src/middleware/timing/index.test.ts index 079c7a18d..ae5eed34f 100644 --- a/src/middleware/timing/index.test.ts +++ b/src/middleware/timing/index.test.ts @@ -55,4 +55,89 @@ describe('Server-Timing API', () => { expect(res.headers.get('server-timing')?.includes(region)).toBeTruthy() expect(res.headers.get('server-timing')?.includes(regionDesc)).toBeTruthy() }) + + describe('Should handle crossOrigin setting', async () => { + it('Should do nothing when crossOrigin is falsy', async () => { + const crossOriginApp = new Hono() + + crossOriginApp.use( + '*', + timing({ + crossOrigin: false, + }) + ) + + crossOriginApp.get('/', (c) => c.text('/')) + + const res = await crossOriginApp.request('http://localhost/') + + expect(res).not.toBeNull() + expect(res.headers.has('server-timing')).toBeTruthy() + expect(res.headers.has('timing-allow-origin')).toBeFalsy() + }) + + it('Should set Timing-Allow-Origin to * when crossOrigin is true', async () => { + const crossOriginApp = new Hono() + + crossOriginApp.use( + '*', + timing({ + crossOrigin: true, + }) + ) + + crossOriginApp.get('/', (c) => c.text('/')) + + const res = await crossOriginApp.request('http://localhost/') + + expect(res).not.toBeNull() + expect(res.headers.has('server-timing')).toBeTruthy() + expect(res.headers.has('timing-allow-origin')).toBeTruthy() + expect(res.headers.get('timing-allow-origin')).toBe('*') + }) + + it('Should set Timing-Allow-Origin to the value of crossOrigin when it is a string', async () => { + const crossOriginApp = new Hono() + + crossOriginApp.use( + '*', + timing({ + crossOrigin: 'https://example.com', + }) + ) + + crossOriginApp.get('/', (c) => c.text('/')) + + const res = await crossOriginApp.request('http://localhost/') + + expect(res).not.toBeNull() + expect(res.headers.has('server-timing')).toBeTruthy() + expect(res.headers.has('timing-allow-origin')).toBeTruthy() + expect(res.headers.get('timing-allow-origin')).toBe('https://example.com') + }) + + it('Should set Timing-Allow-Origin to the return value of crossOrigin when it is a function', async () => { + const crossOriginApp = new Hono() + + crossOriginApp.use( + '*', + timing({ + crossOrigin: (c) => c.req.header('origin') ?? '*', + }) + ) + + crossOriginApp.get('/', (c) => c.text('/')) + + const res = await crossOriginApp.request('http://localhost/', { + headers: { + origin: 'https://example.com', + }, + }) + + expect(res).not.toBeNull() + expect(res.headers.has('server-timing')).toBeTruthy() + expect(res.headers.has('timing-allow-origin')).toBeTruthy() + expect(res.headers.get('timing-allow-origin')).toBe('https://example.com') + }) + }) }) diff --git a/src/middleware/timing/index.ts b/src/middleware/timing/index.ts index 356d7e9c1..504331b15 100644 --- a/src/middleware/timing/index.ts +++ b/src/middleware/timing/index.ts @@ -21,7 +21,7 @@ interface TimingOptions { enabled: boolean | ((c: Context) => boolean) totalDescription: string autoEnd: boolean - crossOrigin: boolean | string + crossOrigin: boolean | string | ((c: Context) => boolean | string) } const getTime = () => { @@ -64,10 +64,14 @@ export const timing = (config?: Partial): MiddlewareHandler => { if (enabled) { c.res.headers.append('Server-Timing', headers.join(',')) - if (options.crossOrigin) { + + const crossOrigin = + typeof options.crossOrigin === 'function' ? options.crossOrigin(c) : options.crossOrigin + + if (crossOrigin) { c.res.headers.append( 'Timing-Allow-Origin', - typeof options.crossOrigin === 'string' ? options.crossOrigin : '*' + typeof crossOrigin === 'string' ? crossOrigin : '*' ) } }