-
Notifications
You must be signed in to change notification settings - Fork 28k
/
Copy pathpatch-set-header.ts
53 lines (48 loc) · 1.44 KB
/
patch-set-header.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import { getRequestMeta, type NextIncomingMessage } from '../request-meta'
type PatchableResponse = {
setHeader(key: string, value: string | string[]): PatchableResponse
}
/**
* Ensure cookies set in middleware are merged and not overridden by API
* routes/getServerSideProps.
*
* @param req Incoming request
* @param res Outgoing response
*/
export function patchSetHeaderWithCookieSupport(
req: NextIncomingMessage,
res: PatchableResponse
) {
const setHeader = res.setHeader.bind(res)
res.setHeader = (
name: string,
value: string | string[]
): PatchableResponse => {
// When renders /_error after page is failed, it could attempt to set
// headers after headers.
if ('headersSent' in res && res.headersSent) {
return res
}
if (name.toLowerCase() === 'set-cookie') {
const middlewareValue = getRequestMeta(req, 'middlewareCookie')
if (
!middlewareValue ||
!Array.isArray(value) ||
!value.every((item, idx) => item === middlewareValue[idx])
) {
value = [
// TODO: (wyattjoh) find out why this is called multiple times resulting in duplicate cookies being added
...new Set([
...(middlewareValue || []),
...(typeof value === 'string'
? [value]
: Array.isArray(value)
? value
: []),
]),
]
}
}
return setHeader(name, value)
}
}