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 ab19472

Browse filesBrowse files
committed
fix: allow cookies in middleware to be accessible during the same request
1 parent f9a5a34 commit ab19472
Copy full SHA for ab19472

File tree

Expand file treeCollapse file tree

2 files changed

+46
-18
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+46
-18
lines changed

‎edge-runtime/lib/middleware.ts

Copy file name to clipboardExpand all lines: edge-runtime/lib/middleware.ts
+17Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { Context } from '@netlify/edge-functions'
22

33
import type { ElementHandlers } from '../vendor/deno.land/x/htmlrewriter@v1.0.0/src/index.ts'
4+
import { getCookies } from '../vendor/deno.land/std@0.175.0/http/cookie.ts'
45

56
type NextDataTransform = <T>(data: T) => T
67

@@ -58,3 +59,19 @@ export const addMiddlewareHeaders = async (
5859
})
5960
return response
6061
}
62+
63+
export function mergeMiddlewareCookies(middlewareResponse: Response, request: Request) {
64+
let mergedCookies = getCookies(request.headers)
65+
const middlewareCookies = middlewareResponse.headers.get('x-middleware-set-cookie') || ''
66+
const regex = new RegExp(/,(?!\s)/) // commas that are not followed by whitespace
67+
68+
middlewareCookies.split(regex).forEach((entry) => {
69+
const [cookie] = entry.split(';')
70+
const [name, value] = cookie.split('=')
71+
mergedCookies[name] = value
72+
})
73+
74+
return Object.entries(mergedCookies)
75+
.map(kv => kv.join('='))
76+
.join('; ')
77+
}

‎edge-runtime/lib/response.ts

Copy file name to clipboardExpand all lines: edge-runtime/lib/response.ts
+29-18Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,12 @@ import {
66

77
import { updateModifiedHeaders } from './headers.ts'
88
import type { StructuredLogger } from './logging.ts'
9-
import { addMiddlewareHeaders, isMiddlewareRequest, isMiddlewareResponse } from './middleware.ts'
9+
import {
10+
addMiddlewareHeaders,
11+
isMiddlewareRequest,
12+
isMiddlewareResponse,
13+
mergeMiddlewareCookies,
14+
} from './middleware.ts'
1015
import { RequestData } from './next-request.ts'
1116
import {
1217
addBasePath,
@@ -116,12 +121,13 @@ export const buildResponse = async ({
116121
}
117122
return rewriter.transform(response.originResponse)
118123
}
119-
const res = new Response(result.response.body, result.response)
124+
125+
const edgeResponse = new Response(result.response.body, result.response)
120126
request.headers.set('x-nf-next-middleware', 'skip')
121127

122-
let rewrite = res.headers.get('x-middleware-rewrite')
123-
let redirect = res.headers.get('location')
124-
let nextRedirect = res.headers.get('x-nextjs-redirect')
128+
let rewrite = edgeResponse.headers.get('x-middleware-rewrite')
129+
let redirect = edgeResponse.headers.get('location')
130+
let nextRedirect = edgeResponse.headers.get('x-nextjs-redirect')
125131

126132
// Data requests (i.e. requests for /_next/data ) need special handling
127133
const isDataReq = request.headers.has('x-nextjs-data')
@@ -152,7 +158,7 @@ export const buildResponse = async ({
152158
// Data requests might be rewritten to an external URL
153159
// This header tells the client router the redirect target, and if it's external then it will do a full navigation
154160

155-
res.headers.set('x-nextjs-rewrite', relativeUrl)
161+
edgeResponse.headers.set('x-nextjs-rewrite', relativeUrl)
156162
}
157163

158164
if (rewriteUrl.origin !== baseUrl.origin) {
@@ -178,7 +184,7 @@ export const buildResponse = async ({
178184
})
179185
}
180186

181-
return addMiddlewareHeaders(fetch(proxyRequest, { redirect: 'manual' }), res)
187+
return addMiddlewareHeaders(fetch(proxyRequest, { redirect: 'manual' }), edgeResponse)
182188
}
183189

184190
if (isDataReq) {
@@ -197,9 +203,9 @@ export const buildResponse = async ({
197203
logger.withFields({ rewrite_url: rewrite }).debug('Rewrite url is same as original url')
198204
return
199205
}
200-
res.headers.set('x-middleware-rewrite', relativeUrl)
206+
edgeResponse.headers.set('x-middleware-rewrite', relativeUrl)
201207
request.headers.set('x-middleware-rewrite', target)
202-
return addMiddlewareHeaders(context.rewrite(target), res)
208+
return addMiddlewareHeaders(context.rewrite(target), edgeResponse)
203209
}
204210

205211
if (redirect) {
@@ -208,27 +214,32 @@ export const buildResponse = async ({
208214
logger.withFields({ redirect_url: redirect }).debug('Redirect url is same as original url')
209215
return
210216
}
211-
res.headers.set('location', redirect)
217+
edgeResponse.headers.set('location', redirect)
212218
}
213219

214220
// Data requests shouldn't automatically redirect in the browser (they might be HTML pages): they're handled by the router
215221
if (redirect && isDataReq) {
216-
res.headers.delete('location')
217-
res.headers.set('x-nextjs-redirect', relativizeURL(redirect, request.url))
222+
edgeResponse.headers.delete('location')
223+
edgeResponse.headers.set('x-nextjs-redirect', relativizeURL(redirect, request.url))
218224
}
219225

220-
nextRedirect = res.headers.get('x-nextjs-redirect')
226+
nextRedirect = edgeResponse.headers.get('x-nextjs-redirect')
221227

222228
if (nextRedirect && isDataReq) {
223-
res.headers.set('x-nextjs-redirect', normalizeDataUrl(nextRedirect))
229+
edgeResponse.headers.set('x-nextjs-redirect', normalizeDataUrl(nextRedirect))
224230
}
225231

226-
if (res.headers.get('x-middleware-next') === '1') {
227-
res.headers.delete('x-middleware-next')
228-
return addMiddlewareHeaders(context.next(), res)
232+
if (edgeResponse.headers.get('x-middleware-next') === '1') {
233+
edgeResponse.headers.delete('x-middleware-next')
234+
235+
// coookies set in middleware need to be available during the lambda request
236+
const newRequest = new Request(request)
237+
newRequest.headers.set('Cookie', mergeMiddlewareCookies(edgeResponse, newRequest))
238+
239+
return addMiddlewareHeaders(context.next(newRequest), edgeResponse)
229240
}
230241

231-
return res
242+
return edgeResponse
232243
}
233244

234245
/**

0 commit comments

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