1- import { toComputeResponse , toReqRes } from '@fastly/http-compute-js'
1+ import type { OutgoingHttpHeaders } from 'http'
2+
3+ import { toComputeResponse , toReqRes , ComputeJsOutgoingMessage } from '@fastly/http-compute-js'
24import { SpanStatusCode , trace } from '@opentelemetry/api'
35import type { NextConfigComplete } from 'next/dist/server/config-shared.js'
46import type { WorkerRequestHandler } from 'next/dist/server/lib/types.js'
@@ -18,6 +20,29 @@ import { createRequestContext, runWithRequestContext } from './request-context.c
1820
1921let nextHandler : WorkerRequestHandler , nextConfig : NextConfigComplete , tagsManifest : TagsManifest
2022
23+ /**
24+ * When Next.js proxies requests externally, it writes the response back as-is.
25+ * In some cases, this includes Transfer-Encoding: chunked.
26+ * This triggers behaviour in @fastly/http-compute-js to separate chunks with chunk delimiters, which is not what we want at this level.
27+ * We want Lambda to control the behaviour around chunking, not this.
28+ * This workaround removes the Transfer-Encoding header, which makes the library send the response as-is.
29+ */
30+ const disableFaultyTransferEncodingHandling = ( res : ComputeJsOutgoingMessage ) => {
31+ const originalStoreHeader = res . _storeHeader
32+ res . _storeHeader = function _storeHeader ( firstLine , headers ) {
33+ if ( headers ) {
34+ if ( Array . isArray ( headers ) ) {
35+ // eslint-disable-next-line no-param-reassign
36+ headers = headers . filter ( ( [ header ] ) => header . toLowerCase ( ) !== 'transfer-encoding' )
37+ } else {
38+ delete ( headers as OutgoingHttpHeaders ) [ 'transfer-encoding' ]
39+ }
40+ }
41+
42+ return originalStoreHeader . call ( this , firstLine , headers )
43+ }
44+ }
45+
2146export default async ( request : Request ) => {
2247 const tracer = trace . getTracer ( 'Next.js Runtime' )
2348
@@ -53,6 +78,8 @@ export default async (request: Request) => {
5378
5479 const requestContext = createRequestContext ( )
5580
81+ disableFaultyTransferEncodingHandling ( res as unknown as ComputeJsOutgoingMessage )
82+
5683 const resProxy = nextResponseProxy ( res , requestContext )
5784
5885 // We don't await this here, because it won't resolve until the response is finished.
0 commit comments