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 f73ce83

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

File tree

Expand file treeCollapse file tree

2 files changed

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

2 files changed

+41
-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
+24-18Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ 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 { addMiddlewareHeaders, isMiddlewareRequest, isMiddlewareResponse, mergeMiddlewareCookies } from './middleware.ts'
1010
import { RequestData } from './next-request.ts'
1111
import {
1212
addBasePath,
@@ -116,12 +116,13 @@ export const buildResponse = async ({
116116
}
117117
return rewriter.transform(response.originResponse)
118118
}
119-
const res = new Response(result.response.body, result.response)
119+
120+
const edgeResponse = new Response(result.response.body, result.response)
120121
request.headers.set('x-nf-next-middleware', 'skip')
121122

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')
123+
let rewrite = edgeResponse.headers.get('x-middleware-rewrite')
124+
let redirect = edgeResponse.headers.get('location')
125+
let nextRedirect = edgeResponse.headers.get('x-nextjs-redirect')
125126

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

155-
res.headers.set('x-nextjs-rewrite', relativeUrl)
156+
edgeResponse.headers.set('x-nextjs-rewrite', relativeUrl)
156157
}
157158

158159
if (rewriteUrl.origin !== baseUrl.origin) {
@@ -178,7 +179,7 @@ export const buildResponse = async ({
178179
})
179180
}
180181

181-
return addMiddlewareHeaders(fetch(proxyRequest, { redirect: 'manual' }), res)
182+
return addMiddlewareHeaders(fetch(proxyRequest, { redirect: 'manual' }), edgeResponse)
182183
}
183184

184185
if (isDataReq) {
@@ -197,9 +198,9 @@ export const buildResponse = async ({
197198
logger.withFields({ rewrite_url: rewrite }).debug('Rewrite url is same as original url')
198199
return
199200
}
200-
res.headers.set('x-middleware-rewrite', relativeUrl)
201+
edgeResponse.headers.set('x-middleware-rewrite', relativeUrl)
201202
request.headers.set('x-middleware-rewrite', target)
202-
return addMiddlewareHeaders(context.rewrite(target), res)
203+
return addMiddlewareHeaders(context.rewrite(target), edgeResponse)
203204
}
204205

205206
if (redirect) {
@@ -208,27 +209,32 @@ export const buildResponse = async ({
208209
logger.withFields({ redirect_url: redirect }).debug('Redirect url is same as original url')
209210
return
210211
}
211-
res.headers.set('location', redirect)
212+
edgeResponse.headers.set('location', redirect)
212213
}
213214

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

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

222223
if (nextRedirect && isDataReq) {
223-
res.headers.set('x-nextjs-redirect', normalizeDataUrl(nextRedirect))
224+
edgeResponse.headers.set('x-nextjs-redirect', normalizeDataUrl(nextRedirect))
224225
}
225226

226-
if (res.headers.get('x-middleware-next') === '1') {
227-
res.headers.delete('x-middleware-next')
228-
return addMiddlewareHeaders(context.next(), res)
227+
if (edgeResponse.headers.get('x-middleware-next') === '1') {
228+
edgeResponse.headers.delete('x-middleware-next')
229+
230+
// coookies set in middleware need to be available during the lambda request
231+
const newRequest = new Request(request)
232+
newRequest.headers.set('Cookie', mergeMiddlewareCookies(edgeResponse, newRequest))
233+
234+
return addMiddlewareHeaders(context.next(newRequest), edgeResponse)
229235
}
230236

231-
return res
237+
return edgeResponse
232238
}
233239

234240
/**

0 commit comments

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