Skip to content

Commit fd3c754

Browse files
fix: handle middleware rewrite bodies and loops (#193)
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
1 parent 5e88d33 commit fd3c754

File tree

1 file changed

+33
-10
lines changed

1 file changed

+33
-10
lines changed

edge-runtime/lib/response.ts

+33-10
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export const buildResponse = async ({
2626
request,
2727
result,
2828
nextConfig,
29-
}: BuildResponseOptions) => {
29+
}: BuildResponseOptions): Promise<Response | void> => {
3030
logger
3131
.withFields({ is_nextresponse_next: result.response.headers.has('x-middleware-next') })
3232
.debug('Building Next.js response')
@@ -118,27 +118,50 @@ export const buildResponse = async ({
118118

119119
const rewriteUrl = new URL(rewrite, request.url)
120120
const baseUrl = new URL(request.url)
121+
if (rewriteUrl.toString() === baseUrl.toString()) {
122+
logger.withFields({ rewrite_url: rewrite }).debug('Rewrite url is same as original url')
123+
return
124+
}
125+
121126
const relativeUrl = relativizeURL(rewrite, request.url)
122127
const originalPath = new URL(request.url, `http://n`).pathname
123128

124-
// Data requests might be rewritten to an external URL
125-
// This header tells the client router the redirect target, and if it's external then it will do a full navigation
126-
if (isDataReq) {
129+
if (rewriteUrl.origin !== baseUrl.origin) {
130+
// Netlify Edge Functions don't support proxying to external domains, but Next middleware does
131+
logger.withFields({ rewrite_url: rewrite }).debug('Rewriting to external url')
132+
let proxyRequest: Request
133+
134+
// Remove Netlify internal headers
135+
const headers = new Headers(
136+
[...request.headers.entries()].filter(([key]) => !key.startsWith('x-nf-')),
137+
)
138+
if (request.body && !request.bodyUsed) {
139+
// This is not ideal, but streaming to an external URL doesn't work
140+
const body = await request.arrayBuffer()
141+
proxyRequest = new Request(rewriteUrl, {
142+
headers,
143+
method: request.method,
144+
body,
145+
})
146+
} else {
147+
proxyRequest = new Request(rewriteUrl, {
148+
headers,
149+
method: request.method,
150+
})
151+
}
152+
return addMiddlewareHeaders(fetch(proxyRequest), res)
153+
} else if (isDataReq) {
154+
// Data requests might be rewritten to an external URL
155+
// This header tells the client router the redirect target, and if it's external then it will do a full navigation
127156
res.headers.set('x-nextjs-rewrite', relativeUrl)
128157
rewriteUrl.pathname = rewriteDataPath({
129158
dataUrl: originalPath,
130159
newRoute: relativeUrl,
131160
basePath: nextConfig?.basePath,
132161
})
133162
}
134-
if (rewriteUrl.origin !== baseUrl.origin) {
135-
// Netlify Edge Functions don't support proxying to external domains, but Next middleware does
136-
const proxied = fetch(new Request(rewriteUrl, request))
137-
return addMiddlewareHeaders(proxied, res)
138-
}
139163
res.headers.set('x-middleware-rewrite', relativeUrl)
140164
request.headers.set('x-middleware-rewrite', rewrite)
141-
142165
return addMiddlewareHeaders(fetch(new Request(rewriteUrl, request)), res)
143166
}
144167

0 commit comments

Comments
 (0)