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'
2
4
import { SpanStatusCode , trace } from '@opentelemetry/api'
3
5
import type { NextConfigComplete } from 'next/dist/server/config-shared.js'
4
6
import type { WorkerRequestHandler } from 'next/dist/server/lib/types.js'
@@ -18,6 +20,29 @@ import { createRequestContext, runWithRequestContext } from './request-context.c
18
20
19
21
let nextHandler : WorkerRequestHandler , nextConfig : NextConfigComplete , tagsManifest : TagsManifest
20
22
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
+
21
46
export default async ( request : Request ) => {
22
47
const tracer = trace . getTracer ( 'Next.js Runtime' )
23
48
@@ -53,6 +78,8 @@ export default async (request: Request) => {
53
78
54
79
const requestContext = createRequestContext ( )
55
80
81
+ disableFaultyTransferEncodingHandling ( res as unknown as ComputeJsOutgoingMessage )
82
+
56
83
const resProxy = nextResponseProxy ( res , requestContext )
57
84
58
85
// We don't await this here, because it won't resolve until the response is finished.
0 commit comments