@tduncan / Nvidia-Optimization-Stack-VLLM Mirror · read-only / commits / f77a0802b7
Fork 0

A high-throughput and memory-efficient inference and serving engine for LLMs

Mirrored from https://github.com/tduncan-lum/Nvidia-Optimization-Stack---VLLM.git

Synced Nov 14, 05:30 UTC

Limit HTTP header count and size (#23267)

Signed-off-by: Taneem Ibrahim <taneem.ibrahim@gmail.com> Signed-off-by: Russell Bryant <rbryant@redhat.com> Co-authored-by: Taneem Ibrahim <taneem.ibrahim@gmail.com>

Russell Bryant committed Aug 20, 2025 at 13:57 UTC f77a0802b758a32c5b9f7bc04e9498d77e8d99e0
4 files changed +41
vllm/entrypoints/constants.py new
+10
@@ -0,0 +1,10 @@
1 +# SPDX-License-Identifier: Apache-2.0
2 +# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 +"""
4 +Shared constants for vLLM entrypoints.
5 +"""
6 +
7 +# HTTP header limits for h11 parser
8 +# These constants help mitigate header abuse attacks
9 +H11_MAX_INCOMPLETE_EVENT_SIZE_DEFAULT = 4194304 # 4 MB
10 +H11_MAX_HEADER_COUNT_DEFAULT = 256
vllm/entrypoints/launcher.py
+21
@@ -14,6 +14,8 @@ from vllm import envs
14 from vllm.engine.async_llm_engine import AsyncEngineDeadError
15 from vllm.engine.multiprocessing import MQEngineDeadError
16 from vllm.engine.protocol import EngineClient
17 +from vllm.entrypoints.constants import (H11_MAX_HEADER_COUNT_DEFAULT,
18 + H11_MAX_INCOMPLETE_EVENT_SIZE_DEFAULT)
19 from vllm.entrypoints.ssl import SSLCertRefresher
20 from vllm.logger import init_logger
21 from vllm.utils import find_process_using_port
@@ -26,6 +28,11 @@ async def serve_http(app: FastAPI,
28 sock: Optional[socket.socket],
29 enable_ssl_refresh: bool = False,
30 **uvicorn_kwargs: Any):
31 + """
32 + Start a FastAPI app using Uvicorn, with support for custom Uvicorn config
33 + options. Supports http header limits via h11_max_incomplete_event_size and
34 + h11_max_header_count.
35 + """
36 logger.info("Available routes are:")
37 for route in app.routes:
38 methods = getattr(route, "methods", None)
@@ -36,7 +43,21 @@ async def serve_http(app: FastAPI,
43
44 logger.info("Route: %s, Methods: %s", path, ', '.join(methods))
45
46 + # Extract header limit options if present
47 + h11_max_incomplete_event_size = uvicorn_kwargs.pop(
48 + "h11_max_incomplete_event_size", None)
49 + h11_max_header_count = uvicorn_kwargs.pop("h11_max_header_count", None)
50 +
51 + # Set safe defaults if not provided
52 + if h11_max_incomplete_event_size is None:
53 + h11_max_incomplete_event_size = H11_MAX_INCOMPLETE_EVENT_SIZE_DEFAULT
54 + if h11_max_header_count is None:
55 + h11_max_header_count = H11_MAX_HEADER_COUNT_DEFAULT
56 +
57 config = uvicorn.Config(app, **uvicorn_kwargs)
58 + # Set header limits
59 + config.h11_max_incomplete_event_size = h11_max_incomplete_event_size
60 + config.h11_max_header_count = h11_max_header_count
61 config.load()
62 server = uvicorn.Server(config)
63 _add_shutdown_handlers(app, server)
vllm/entrypoints/openai/api_server.py
+2
@@ -1922,6 +1922,8 @@ async def run_server_worker(listen_address,
1922 ssl_certfile=args.ssl_certfile,
1923 ssl_ca_certs=args.ssl_ca_certs,
1924 ssl_cert_reqs=args.ssl_cert_reqs,
1925 + h11_max_incomplete_event_size=args.h11_max_incomplete_event_size,
1926 + h11_max_header_count=args.h11_max_header_count,
1927 **uvicorn_kwargs,
1928 )
1929
vllm/entrypoints/openai/cli_args.py
+8
@@ -20,6 +20,8 @@ from vllm.config import config
20 from vllm.engine.arg_utils import AsyncEngineArgs, optional_type
21 from vllm.entrypoints.chat_utils import (ChatTemplateContentFormatOption,
22 validate_chat_template)
23 +from vllm.entrypoints.constants import (H11_MAX_HEADER_COUNT_DEFAULT,
24 + H11_MAX_INCOMPLETE_EVENT_SIZE_DEFAULT)
25 from vllm.entrypoints.openai.serving_models import LoRAModulePath
26 from vllm.entrypoints.openai.tool_parsers import ToolParserManager
27 from vllm.logger import init_logger
@@ -172,6 +174,12 @@ schema. Example: `[{"type": "text", "text": "Hello world!"}]`"""
174 enable_log_outputs: bool = False
175 """If set to True, enable logging of model outputs (generations)
176 in addition to the input logging that is enabled by default."""
177 + h11_max_incomplete_event_size: int = H11_MAX_INCOMPLETE_EVENT_SIZE_DEFAULT
178 + """Maximum size (bytes) of an incomplete HTTP event (header or body) for
179 + h11 parser. Helps mitigate header abuse. Default: 4194304 (4 MB)."""
180 + h11_max_header_count: int = H11_MAX_HEADER_COUNT_DEFAULT
181 + """Maximum number of HTTP headers allowed in a request for h11 parser.
182 + Helps mitigate header abuse. Default: 256."""
183
184 @staticmethod
185 def add_cli_args(parser: FlexibleArgumentParser) -> FlexibleArgumentParser: