Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 93c8766

Browse filesBrowse files
committed
test: validate functionality of mergeMiddlewareCookies
1 parent c8379d6 commit 93c8766
Copy full SHA for 93c8766

File tree

Expand file treeCollapse file tree

3 files changed

+111
-9
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+111
-9
lines changed

‎edge-runtime/lib/middleware.test.ts

Copy file name to clipboard
+95Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import { assertEquals } from 'https://deno.land/std@0.175.0/testing/asserts.ts'
2+
import { mergeMiddlewareCookies } from './middleware.ts'
3+
4+
const MIDDLEWARE_HEADER = 'x-middleware-set-cookie'
5+
6+
Deno.test('mergeMiddlewareCookies', async (t) => {
7+
await t.step('should handle empty cookies', async () => {
8+
const request = new Request('https://www.test-url.com')
9+
const response = new Response()
10+
11+
const result = mergeMiddlewareCookies(response, request)
12+
assertEquals(result, '')
13+
})
14+
15+
await t.step('should return request cookies when there are no middleware headers', async () => {
16+
const request = new Request('https://www.test-url.com')
17+
const response = new Response()
18+
19+
request.headers.set('Cookie', 'oatmeal=raisin')
20+
21+
const result = mergeMiddlewareCookies(response, request)
22+
assertEquals(result, 'oatmeal=raisin')
23+
})
24+
25+
await t.step('should not require cookies in request to be set', async () => {
26+
const request = new Request('https://www.test-url.com')
27+
const response = new Response()
28+
29+
response.headers.set(MIDDLEWARE_HEADER, 'peanut=butter; Path=/')
30+
31+
const result = mergeMiddlewareCookies(response, request)
32+
assertEquals(result, 'peanut=butter')
33+
})
34+
35+
await t.step('should merge request and middleware cookies', async () => {
36+
const request = new Request('https://www.test-url.com')
37+
const response = new Response()
38+
39+
request.headers.set('Cookie', 'oatmeal=raisin')
40+
response.headers.set(MIDDLEWARE_HEADER, 'peanut=butter; Path=/')
41+
42+
const result = mergeMiddlewareCookies(response, request)
43+
assertEquals(result, 'oatmeal=raisin; peanut=butter')
44+
})
45+
46+
await t.step('should overwrite request cookies with latest values', async () => {
47+
const request = new Request('https://www.test-url.com')
48+
const response = new Response()
49+
50+
request.headers.set('Cookie', 'oatmeal=chocolate')
51+
response.headers.set(MIDDLEWARE_HEADER, 'oatmeal=raisin; Path=/')
52+
53+
const result = mergeMiddlewareCookies(response, request)
54+
assertEquals(result, 'oatmeal=raisin')
55+
})
56+
57+
await t.step('should not decode middleware cookie values', async () => {
58+
const request = new Request('https://www.test-url.com')
59+
const response = new Response()
60+
61+
response.headers.set(
62+
MIDDLEWARE_HEADER,
63+
'greeting=Hello%20from%20the%20cookie; Path=/',
64+
)
65+
66+
const result = mergeMiddlewareCookies(response, request)
67+
assertEquals(result, 'greeting=Hello%20from%20the%20cookie')
68+
})
69+
70+
await t.step('should support multiple cookies being set in middleware', async () => {
71+
const request = new Request('https://www.test-url.com')
72+
const response = new Response()
73+
74+
response.headers.set(
75+
MIDDLEWARE_HEADER,
76+
'oatmeal=raisin; Path=/,peanut=butter; Path=/,chocolate=chip; Path=/',
77+
)
78+
79+
const result = mergeMiddlewareCookies(response, request)
80+
assertEquals(result, 'oatmeal=raisin; peanut=butter; chocolate=chip')
81+
})
82+
83+
await t.step('should ignore comma in middleware cookie expiry', async () => {
84+
const request = new Request('https://www.test-url.com')
85+
const response = new Response()
86+
87+
response.headers.set(
88+
MIDDLEWARE_HEADER,
89+
'oatmeal=raisin; Path=/; Expires=Wed, 23 Apr 2025 13:37:43 GMT; Max-Age=604800',
90+
)
91+
92+
const result = mergeMiddlewareCookies(response, request)
93+
assertEquals(result, 'oatmeal=raisin')
94+
})
95+
})

‎edge-runtime/lib/middleware.ts

Copy file name to clipboardExpand all lines: edge-runtime/lib/middleware.ts
+12-8Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,16 +60,20 @@ export const addMiddlewareHeaders = async (
6060
return response
6161
}
6262

63-
export function mergeMiddlewareCookies(middlewareResponse: Response, request: Request) {
64-
let mergedCookies = getCookies(request.headers)
65-
const middlewareCookies = middlewareResponse.headers.get('x-middleware-set-cookie') || ''
63+
// This serves the same purpose as the mergeMiddlewareCookies in Next.js but has been customized to our domain
64+
// See: https://github.com/vercel/next.js/blob/6e4495f8430eab33b12cd11dffdd8e27eee6e0cf/packages/next/src/server/async-storage/request-store.ts#L78-L105
65+
export function mergeMiddlewareCookies(middlewareResponse: Response, lambdaRequest: Request) {
66+
let mergedCookies = getCookies(lambdaRequest.headers)
67+
const middlewareCookies = middlewareResponse.headers.get('x-middleware-set-cookie')
6668
const regex = new RegExp(/,(?!\s)/) // commas that are not followed by whitespace
6769

68-
middlewareCookies.split(regex).forEach((entry) => {
69-
const [cookie] = entry.split(';')
70-
const [name, value] = cookie.split('=')
71-
mergedCookies[name] = value
72-
})
70+
if (middlewareCookies) {
71+
middlewareCookies.split(regex).forEach((entry) => {
72+
const [cookie] = entry.split(';')
73+
const [name, value] = cookie.split('=')
74+
mergedCookies[name] = value
75+
})
76+
}
7377

7478
return Object.entries(mergedCookies)
7579
.map((kv) => kv.join('='))

‎edge-runtime/lib/response.ts

Copy file name to clipboardExpand all lines: edge-runtime/lib/response.ts
+4-1Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,10 @@ export const buildResponse = async ({
234234

235235
// coookies set in middleware need to be available during the lambda request
236236
const newRequest = new Request(request)
237-
newRequest.headers.set('Cookie', mergeMiddlewareCookies(edgeResponse, newRequest))
237+
const newRequestCookies = mergeMiddlewareCookies(edgeResponse, newRequest)
238+
if (newRequestCookies) {
239+
newRequest.headers.set('Cookie', newRequestCookies)
240+
}
238241

239242
return addMiddlewareHeaders(context.next(newRequest), edgeResponse)
240243
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.