next.js icon indicating copy to clipboard operation
next.js copied to clipboard

fix: prevent middleware fetches from mutating init param

Open HW13 opened this issue 3 years ago • 0 comments

Summary

Middleware using fetch with a RequestInit parameter defined outside the scope of the middleware will have every request append the x-middleware-subrequest header to its value from the previous request. This eventually results in a 431 response from the upstream API.

For example, given an app with the following middleware:

// middleware.js
import { NextResponse } from 'next/server'

const reqInit = { headers: { foo: 'bar' } }

export default async function middleware (req) {
  await fetch('https://my-api.com/ping', reqInit)

  return NextResponse.next()
}

The 2nd request to the app will trigger a fetch to the upstream API containing an x-middleware-subrequest header equal to 'middleware:middleware' and every subsequent request will append another ':middleware' to that header.

This is due to the init parameter being mutated in packages/next/server/web/sandbox/context.ts and can be resolved by using a shallow clone of the parameter instead.

Test Plan

Without this PR's changes to context.ts, the added test will fail with the following output:

Screen Shot 2022-11-09 at 5 28 39 PM

Bug

  • [ ] Related issues linked using fixes #number
  • [x] Integration tests added
  • [ ] Errors have a helpful link attached, see contributing.md

HW13 avatar Nov 10 '22 02:11 HW13