🔧 fix: merge set.headers without duplicating Response

This commit is contained in:
truehazker
2025-12-04 10:57:02 +04:00
parent 708577623e
commit 2fce4b7f7d
2 changed files with 38 additions and 5 deletions
+13 -5
View File
@@ -338,6 +338,7 @@ export const createResponseHandler = (handler: CreateHandlerParameter) => {
return (response: Response, set: Context['set'], request?: Request) => {
let isCookieSet = false
// Merge headers: Response headers take precedence, set.headers fill in non-conflicting ones
if (set.headers instanceof Headers)
for (const key of set.headers.keys()) {
if (key === 'set-cookie') {
@@ -347,14 +348,21 @@ export const createResponseHandler = (handler: CreateHandlerParameter) => {
for (const cookie of set.headers.getSetCookie())
response.headers.append('set-cookie', cookie)
} else response.headers.append(key, set.headers?.get(key) ?? '')
} else if (!response.headers.has(key))
response.headers.set(key, set.headers?.get(key) ?? '')
}
else
for (const key in set.headers)
(response as Response).headers.append(
key,
set.headers[key] as any
)
if (key === 'set-cookie')
(response as Response).headers.append(
key,
set.headers[key] as any
)
else if (!response.headers.has(key))
(response as Response).headers.set(
key,
set.headers[key] as any
)
const status = set.status ?? 200
+25
View File
@@ -36,4 +36,29 @@ describe('Custom Response Type', () => {
expect(await response.text()).toBe('Shuba Shuba')
})
it('Response headers take precedence, set.headers merge non-conflicting', async () => {
const app = new Elysia()
.onRequest(({ set }) => {
set.headers['Content-Type'] = 'application/json'
set.headers['X-Framework'] = 'Elysia'
})
.get('/', () => {
return new Response('{"message":"hello"}', {
headers: {
'Content-Type': 'text/plain',
'X-Custom': 'custom-value'
}
})
})
const response = await app.handle(req('/'))
// Response's Content-Type takes precedence
expect(response.headers.get('Content-Type')).toBe('text/plain')
// set.headers adds non-conflicting headers
expect(response.headers.get('X-Framework')).toBe('Elysia')
// Response's own headers are preserved
expect(response.headers.get('X-Custom')).toBe('custom-value')
})
})