Merge pull request #23414 from joereyna/fix/pass-through-server-root-path

fix: strip SERVER_ROOT_PATH prefix before checking mapped pass-through routes
This commit is contained in:
Joe Reyna
2026-03-12 11:57:13 -07:00
committed by GitHub
4 changed files with 24 additions and 9 deletions
+7 -4
View File
@@ -50,7 +50,7 @@ from litellm.proxy.common_utils.http_parsing_utils import (
_read_request_body, _safe_get_request_headers,
populate_request_with_path_params)
from litellm.proxy.common_utils.realtime_utils import _realtime_request_body
from litellm.proxy.utils import PrismaClient, ProxyLogging
from litellm.proxy.utils import PrismaClient, ProxyLogging, normalize_route_for_root_path
from litellm.secret_managers.main import get_secret_bool
from litellm.types.services import ServiceTypes
@@ -386,9 +386,12 @@ async def check_api_key_for_custom_headers_or_pass_through_endpoints(
api_key: str,
) -> Union[UserAPIKeyAuth, str]:
is_mapped_pass_through_route: bool = False
for mapped_route in LiteLLMRoutes.mapped_pass_through_routes.value: # type: ignore
if route.startswith(mapped_route):
is_mapped_pass_through_route = True
normalized_route = normalize_route_for_root_path(route)
if normalized_route is not None:
for mapped_route in LiteLLMRoutes.mapped_pass_through_routes.value: # type: ignore
if normalized_route.startswith(mapped_route):
is_mapped_pass_through_route = True
break
if is_mapped_pass_through_route:
if request.headers.get("litellm_user_api_key") is not None:
api_key = request.headers.get("litellm_user_api_key") or ""
@@ -54,7 +54,7 @@ from litellm.proxy.common_utils.http_parsing_utils import (
_read_request_body,
_safe_get_request_headers,
)
from litellm.proxy.utils import get_server_root_path
from litellm.proxy.utils import get_server_root_path, normalize_route_for_root_path
from litellm.secret_managers.main import get_secret_str
from litellm.types.llms.custom_http import httpxSpecialProvider
from litellm.types.passthrough_endpoints.pass_through_endpoints import (
@@ -2061,9 +2061,11 @@ class InitPassThroughEndpointHelpers:
bool: True if route is a registered pass-through endpoint, False otherwise
"""
## CHECK IF MAPPED PASS THROUGH ENDPOINT
for mapped_route in LiteLLMRoutes.mapped_pass_through_routes.value:
if route.startswith(mapped_route):
return True
normalized_route = normalize_route_for_root_path(route)
if normalized_route is not None:
for mapped_route in LiteLLMRoutes.mapped_pass_through_routes.value:
if normalized_route.startswith(mapped_route):
return True
# Fast path: check if any registered route key contains this path
# Keys are in format: "{endpoint_id}:exact:{path}:{methods}" or "{endpoint_id}:subpath:{path}:{methods}"
+10
View File
@@ -5196,6 +5196,16 @@ def get_server_root_path() -> str:
return os.getenv("SERVER_ROOT_PATH", "")
def normalize_route_for_root_path(route: str) -> Optional[str]:
"""Strip SERVER_ROOT_PATH prefix. Returns de-prefixed route, or None if route is not under root path."""
root_path = get_server_root_path()
if root_path and root_path != "/":
if route.startswith(root_path + "/"):
return route[len(root_path):]
return None
return route
def get_prisma_client_or_throw(message: str):
from litellm.proxy.proxy_server import prisma_client
@@ -2383,7 +2383,7 @@ def test_mapped_pass_through_routes_with_server_root_path():
)
with patch(
"litellm.proxy.pass_through_endpoints.pass_through_endpoints.get_server_root_path"
"litellm.proxy.utils.get_server_root_path"
) as mock_get_root:
mock_get_root.return_value = "/litellm"