From 539d0f116d52a203c5db6d646e2679ffded556f5 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Wed, 31 Jan 2024 11:40:11 -0800 Subject: [PATCH 1/3] Replace image optimizer IPC call with request handler --- packages/next/src/server/lib/router-server.ts | 89 ++++++++++--------- packages/next/src/server/next-server.ts | 34 ++----- 2 files changed, 54 insertions(+), 69 deletions(-) diff --git a/packages/next/src/server/lib/router-server.ts b/packages/next/src/server/lib/router-server.ts index e0db090b35092..b9604793b5680 100644 --- a/packages/next/src/server/lib/router-server.ts +++ b/packages/next/src/server/lib/router-server.ts @@ -139,48 +139,6 @@ export async function initialize(opts: { renderServer.instance = require('./render-server') as typeof import('./render-server') - const renderServerOpts: Parameters[0] = { - port: opts.port, - dir: opts.dir, - hostname: opts.hostname, - minimalMode: opts.minimalMode, - dev: !!opts.dev, - server: opts.server, - isNodeDebugging: !!opts.isNodeDebugging, - serverFields: developmentBundler?.serverFields || {}, - experimentalTestProxy: !!opts.experimentalTestProxy, - experimentalHttpsServer: !!opts.experimentalHttpsServer, - bundlerService: devBundlerService, - startServerSpan: opts.startServerSpan, - } - - // pre-initialize workers - const handlers = await renderServer.instance.initialize(renderServerOpts) - - const logError = async ( - type: 'uncaughtException' | 'unhandledRejection', - err: Error | undefined - ) => { - if (isPostpone(err)) { - // React postpones that are unhandled might end up logged here but they're - // not really errors. They're just part of rendering. - return - } - await developmentBundler?.logErrorWithOriginalStack(err, type) - } - - process.on('uncaughtException', logError.bind(null, 'uncaughtException')) - process.on('unhandledRejection', logError.bind(null, 'unhandledRejection')) - - const resolveRoutes = getResolveRoutes( - fsChecker, - config, - opts, - renderServer.instance, - renderServerOpts, - developmentBundler?.ensureMiddleware - ) - const requestHandlerImpl: WorkerRequestHandler = async (req, res) => { if (compress) { // @ts-expect-error not express req/res @@ -574,6 +532,53 @@ export async function initialize(opts: { } requestHandlers[opts.dir] = requestHandler + const renderServerOpts: Parameters[0] = { + port: opts.port, + dir: opts.dir, + hostname: opts.hostname, + minimalMode: opts.minimalMode, + dev: !!opts.dev, + server: opts.server, + isNodeDebugging: !!opts.isNodeDebugging, + serverFields: developmentBundler?.serverFields || {}, + experimentalTestProxy: !!opts.experimentalTestProxy, + experimentalHttpsServer: !!opts.experimentalHttpsServer, + bundlerService: devBundlerService, + startServerSpan: opts.startServerSpan, + } + + if (!renderServerOpts.serverFields) { + renderServerOpts.serverFields = {} + } + renderServerOpts.serverFields.routerServerHandler = requestHandlerImpl + + // pre-initialize workers + const handlers = await renderServer.instance.initialize(renderServerOpts) + + const logError = async ( + type: 'uncaughtException' | 'unhandledRejection', + err: Error | undefined + ) => { + if (isPostpone(err)) { + // React postpones that are unhandled might end up logged here but they're + // not really errors. They're just part of rendering. + return + } + await developmentBundler?.logErrorWithOriginalStack(err, type) + } + + process.on('uncaughtException', logError.bind(null, 'uncaughtException')) + process.on('unhandledRejection', logError.bind(null, 'unhandledRejection')) + + const resolveRoutes = getResolveRoutes( + fsChecker, + config, + opts, + renderServer.instance, + renderServerOpts, + developmentBundler?.ensureMiddleware + ) + const upgradeHandler: WorkerUpgradeHandler = async (req, socket, head) => { try { req.on('error', (_err) => { diff --git a/packages/next/src/server/next-server.ts b/packages/next/src/server/next-server.ts index 799f3701333c0..a957e22c5cae3 100644 --- a/packages/next/src/server/next-server.ts +++ b/packages/next/src/server/next-server.ts @@ -171,6 +171,10 @@ export default class NextNodeServer extends BaseServer { page: string re: RegExp }[] + private routerServerHandler?: ( + req: IncomingMessage, + res: ServerResponse + ) => void constructor(options: Options) { // Initialize super class @@ -555,35 +559,11 @@ export default class NextNodeServer extends BaseServer { throw new Error(`Invariant attempted to optimize _next/image itself`) } - const protocol = this.serverOptions.experimentalHttpsServer - ? 'https' - : 'http' - - const invokeRes = await invokeRequest( - `${protocol}://${this.fetchHostname || 'localhost'}:${this.port}${ - newReq.url || '' - }`, - { - method: newReq.method || 'GET', - headers: newReq.headers, - signal: signalFromNodeResponse(res.originalResponse), - } - ) - const filteredResHeaders = filterReqHeaders( - toNodeOutgoingHttpHeaders(invokeRes.headers), - ipcForbiddenHeaders - ) - - for (const key of Object.keys(filteredResHeaders)) { - newRes.setHeader(key, filteredResHeaders[key] || '') + if (!this.routerServerHandler) { + throw new Error(`Invariant missing routerServerHandler`) } - newRes.statusCode = invokeRes.status || 200 - if (invokeRes.body) { - await pipeToNodeResponse(invokeRes.body, newRes) - } else { - res.send() - } + await this.routerServerHandler(newReq, newRes) return } From 8432e5019435f2983fffe028e3bfdd1c50cc5aa9 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Wed, 31 Jan 2024 11:47:02 -0800 Subject: [PATCH 2/3] fix lint --- packages/next/src/server/next-server.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/next/src/server/next-server.ts b/packages/next/src/server/next-server.ts index a957e22c5cae3..891ae15b9cc3e 100644 --- a/packages/next/src/server/next-server.ts +++ b/packages/next/src/server/next-server.ts @@ -90,8 +90,6 @@ import { getTracer } from './lib/trace/tracer' import { NextNodeServerSpan } from './lib/trace/constants' import { nodeFs } from './lib/node-fs-methods' import { getRouteRegex } from '../shared/lib/router/utils/route-regex' -import { invokeRequest } from './lib/server-ipc/invoke-request' -import { filterReqHeaders, ipcForbiddenHeaders } from './lib/server-ipc/utils' import { pipeToNodeResponse } from './pipe-readable' import { createRequestResponseMocks } from './lib/mock-request' import { NEXT_RSC_UNION_QUERY } from '../client/components/app-router-headers' From d83d2b7107936629e3be4b9575ca34da669196a3 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Wed, 31 Jan 2024 11:47:54 -0800 Subject: [PATCH 3/3] extra if --- packages/next/src/server/lib/router-server.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/next/src/server/lib/router-server.ts b/packages/next/src/server/lib/router-server.ts index b9604793b5680..e44cc2d40530d 100644 --- a/packages/next/src/server/lib/router-server.ts +++ b/packages/next/src/server/lib/router-server.ts @@ -546,10 +546,6 @@ export async function initialize(opts: { bundlerService: devBundlerService, startServerSpan: opts.startServerSpan, } - - if (!renderServerOpts.serverFields) { - renderServerOpts.serverFields = {} - } renderServerOpts.serverFields.routerServerHandler = requestHandlerImpl // pre-initialize workers