diff --git a/packages/vite/src/node/http.ts b/packages/vite/src/node/http.ts index 18ce37f6a327e1..621c93d196492e 100644 --- a/packages/vite/src/node/http.ts +++ b/packages/vite/src/node/http.ts @@ -6,6 +6,7 @@ import type { } from 'node:http' import type { ServerOptions as HttpsServerOptions } from 'node:https' import type { Connect } from 'types/connect' +import colors from 'picocolors' import { isObject } from './utils' import type { ProxyOptions } from './server/middlewares/proxy' import type { Logger } from './logger' @@ -183,3 +184,27 @@ export async function httpServerStart( }) }) } + +export function setClientErrorHandler( + server: HttpServer, + logger: Logger +): void { + server.on('clientError', (err, socket) => { + if ((err as any).code === 'HPE_HEADER_OVERFLOW') { + if (!socket.writableEnded) { + socket.end( + 'HTTP/1.1 431 Request Header Fields Too Large\r\n\r\n' + + 'Request Header was too large. Node.js limits request header size. ' + + 'Use https://nodejs.org/api/cli.html#--max-http-header-sizesize to change max header size.' + ) + } + logger.warn( + colors.yellow( + 'Server / WS server responded with "431 Request Header Fields Too Large." ' + + 'Node.js limits request header size and the request was dropped. ' + + 'Use https://nodejs.org/api/cli.html#--max-http-header-sizesize to change max header size.' + ) + ) + } + }) +} diff --git a/packages/vite/src/node/preview.ts b/packages/vite/src/node/preview.ts index 7b2cc4bb1729b4..e870fb4bd0bb8e 100644 --- a/packages/vite/src/node/preview.ts +++ b/packages/vite/src/node/preview.ts @@ -6,7 +6,12 @@ import type { Connect } from 'types/connect' import corsMiddleware from 'cors' import type { ResolvedServerOptions, ResolvedServerUrls } from './server' import type { CommonServerOptions } from './http' -import { httpServerStart, resolveHttpServer, resolveHttpsConfig } from './http' +import { + httpServerStart, + resolveHttpServer, + resolveHttpsConfig, + setClientErrorHandler +} from './http' import { openBrowser } from './server/openBrowser' import compression from './server/middlewares/compression' import { proxyMiddleware } from './server/middlewares/proxy' @@ -78,6 +83,7 @@ export async function preview( app, await resolveHttpsConfig(config.preview?.https, config.cacheDir) ) + setClientErrorHandler(httpServer, config.logger) // apply server hooks from plugins const postHooks: ((() => void) | void)[] = [] diff --git a/packages/vite/src/node/server/index.ts b/packages/vite/src/node/server/index.ts index a8222be65ae7b2..98d7814e587751 100644 --- a/packages/vite/src/node/server/index.ts +++ b/packages/vite/src/node/server/index.ts @@ -12,7 +12,12 @@ import type { Connect } from 'types/connect' import launchEditorMiddleware from 'launch-editor-middleware' import type { SourceMap } from 'rollup' import type { CommonServerOptions } from '../http' -import { httpServerStart, resolveHttpServer, resolveHttpsConfig } from '../http' +import { + httpServerStart, + resolveHttpServer, + resolveHttpsConfig, + setClientErrorHandler +} from '../http' import type { InlineConfig, ResolvedConfig } from '../config' import { isDepsOptimizerEnabled, resolveConfig } from '../config' import { @@ -301,6 +306,10 @@ export async function createServer( : await resolveHttpServer(serverConfig, middlewares, httpsOptions) const ws = createWebSocketServer(httpServer, config, httpsOptions) + if (httpServer) { + setClientErrorHandler(httpServer, config.logger) + } + const { ignored = [], ...watchOptions } = serverConfig.watch || {} const watcher = chokidar.watch(path.resolve(root), { ignored: [