[next@15] Undocumented `reactMaxHeadersLength` next config option is not respected
Opened this issue · 0 comments
next@v15.0.0-canary.99 added a new reactMaxHeadersLength
option to next.config.js
.
It was introduced in this PR: vercel/next.js#67715. This gets passed to react-dom's renderToReadableStream
here: https://github.com/vercel/next.js/blob/4837a67fb9bc7199e48cd8bd2cc42659b17dfacc/packages/next/src/server/app-render/app-render.tsx#L1490.
This was added in facebook/react#27641.
It ultimately gets used here via remainingCapacity
.
One theory is that this functionality doesn't play nicely with our use of a TransformStream
: https://github.com/netlify/next-runtime/blob/f10d6611921fe355f33804f394eb25678cbedd85/src/run/handlers/server.ts#L135.
FAIL test/e2e/app-dir/react-max-headers-length/react-max-headers-length.test.ts (296.858 s)
react-max-headers-length
reactMaxHeadersLength = 0
✕ should respect reactMaxHeadersLength (288 ms)
reactMaxHeadersLength = 400
✕ should respect reactMaxHeadersLength (277 ms)
reactMaxHeadersLength = undefined
✓ should respect reactMaxHeadersLength (247 ms)
reactMaxHeadersLength = 10000
✕ should respect reactMaxHeadersLength (278 ms)
● react-max-headers-length › reactMaxHeadersLength = 0 › should respect reactMaxHeadersLength
expect(received).toBeNull()
Received: "</?q=some+string+that+spans+lots+of+characters&i=00>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=01>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=02>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=03>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=04>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=05>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=06>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=07>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=08>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=09>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=10>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=11>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=12>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=13>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=14>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=15>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=16>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=17>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=18>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=19>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=20>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=21>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=22>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=23>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=24>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=25>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=26>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=27>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=28>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=29>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=30>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=31>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=32>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=33>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=34>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=35>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=36>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=37>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=38>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=39>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=40>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=41>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=42>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=43>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=44>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=45>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=46>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=47>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=48>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=49>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=50>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=51>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\", </?q=some+string+that+spans+lots+of+characters&i=52>; rel=preload; as=\"font\"; crossorigin=\"\"; type=\"font/woff2\""
46 | } else if (reactMaxHeadersLength === 0) {
47 | // This is the case where the header is not emitted.
> 48 | expect(header).toBeNull()
| ^
49 | } else if (typeof reactMaxHeadersLength === 'number') {
50 | // This is the case where the header is emitted and the length is
51 | // respected.
at Object.toBeNull (e2e/app-dir/react-max-headers-length/react-max-headers-length.test.ts:48:26)
● react-max-headers-length › reactMaxHeadersLength = 400 › should respect reactMaxHeadersLength
expect(received).toBeLessThanOrEqual(expected)
Expected: <= 400
Received: 5987
56 | calculateMinHeaderLength(reactMaxHeadersLength)
57 | )
> 58 | expect(header.length).toBeLessThanOrEqual(reactMaxHeadersLength)
| ^
59 | }
60 | })
61 | }
at Object.toBeLessThanOrEqual (e2e/app-dir/react-max-headers-length/react-max-headers-length.test.ts:58:33)
● react-max-headers-length › reactMaxHeadersLength = 10000 › should respect reactMaxHeadersLength
expect(received).toBeGreaterThanOrEqual(expected)
Expected: >= 9942
Received: 5987
53 | expect(header).toBeString()
54 |
> 55 | expect(header.length).toBeGreaterThanOrEqual(
| ^
56 | calculateMinHeaderLength(reactMaxHeadersLength)
57 | )
58 | expect(header.length).toBeLessThanOrEqual(reactMaxHeadersLength)
at Object.toBeGreaterThanOrEqual (e2e/app-dir/react-max-headers-length/react-max-headers-length.test.ts:55:33)
Test Suites: 1 failed, 1 total
Tests: 3 failed, 1 passed, 4 total
Data
The following is parsed automatically by the Next.js repo e2e test report generator.
test: test/e2e/app-dir/react-max-headers-length/react-max-headers-length.test.ts
reason: Undocumented next@15-canary reactMaxHeadersLength config option is not respected; cannot debug due to React 19 RC being closed source