From e8b61bb3cac6c9c3ef3fa33e43440cc646473696 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BF=A0=20/=20green?= Date: Thu, 11 Aug 2022 04:51:52 +0900 Subject: [PATCH] feat: show warning on 431 response (#9324) Co-authored-by: Bjorn Lu --- docs/guide/troubleshooting.md | 10 ++++++++++ packages/vite/src/node/http.ts | 17 +++++++++++++++++ packages/vite/src/node/preview.ts | 8 +++++++- packages/vite/src/node/server/index.ts | 11 ++++++++++- 4 files changed, 44 insertions(+), 2 deletions(-) diff --git a/docs/guide/troubleshooting.md b/docs/guide/troubleshooting.md index d3587c375411b0..1665a982a91119 100644 --- a/docs/guide/troubleshooting.md +++ b/docs/guide/troubleshooting.md @@ -44,6 +44,16 @@ To solve this: $ sudo sysctl fs.inotify.max_user_watches=524288 ``` +### 431 Request Header Fields Too Large + +When the server / WebSocket server receives a large HTTP header, the request will be dropped and the following warning will be shown. + +> Server responded with status code 431. See https://vitejs.dev/guide/troubleshooting.html#_431-request-header-fields-too-large. + +This is because Node.js limits request header size to mitigate [CVE-2018-12121](https://www.cve.org/CVERecord?id=CVE-2018-12121). + +To avoid this, try to reduce your request header size. For example, if the cookie is long, delete it. Or you can use [`--max-http-header-size`](https://nodejs.org/api/cli.html#--max-http-header-sizesize) to change max header size. + ## HMR ### Vite detects a file change but the HMR is not working diff --git a/packages/vite/src/node/http.ts b/packages/vite/src/node/http.ts index f0f53f1d686fd6..3317814252018b 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,19 @@ 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') { + logger.warn( + colors.yellow( + 'Server responded with status code 431. ' + + 'See https://vitejs.dev/guide/troubleshooting.html#_431-request-header-fields-too-large.' + ) + ) + } + }) +} diff --git a/packages/vite/src/node/preview.ts b/packages/vite/src/node/preview.ts index c223c4debd3baf..2a563575c69ce1 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: [