mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-12 23:01:41 +00:00
fix(mcp): preserve IPv6 hosts when comparing preview origins
This commit is contained in:
parent
493c98f9bf
commit
3169c80252
2 changed files with 32 additions and 12 deletions
|
|
@ -1243,6 +1243,17 @@ if MCP_AVAILABLE:
|
|||
mcp_auth_header: str | None
|
||||
oauth2_headers: dict[str, str] | None
|
||||
|
||||
def _preview_origin(url: str | None) -> tuple[str, str, int | None] | None:
|
||||
if not url:
|
||||
return None
|
||||
try:
|
||||
parsed: Final = httpx.URL(url)
|
||||
except httpx.InvalidURL:
|
||||
return None
|
||||
if parsed.scheme not in ("http", "https") or not parsed.host:
|
||||
return None
|
||||
return parsed.scheme, parsed.host, parsed.port
|
||||
|
||||
def _stage_server_test(new_mcp_server_request: NewMCPServerRequest, headers: Headers) -> _StagedServerTest:
|
||||
"""
|
||||
Resolve the credentials a not-yet-saved server config carries for a preview call.
|
||||
|
|
@ -1260,12 +1271,10 @@ if MCP_AVAILABLE:
|
|||
if new_mcp_server_request.server_id
|
||||
else None
|
||||
)
|
||||
saved_origin: Final = _redact_mcp_resource_url(saved_server.url) if saved_server else None
|
||||
preview_origin: Final = _redact_mcp_resource_url(new_mcp_server_request.url)
|
||||
saved_origin: Final = _preview_origin(saved_server.url) if saved_server else None
|
||||
preview_origin: Final = _preview_origin(new_mcp_server_request.url)
|
||||
may_inherit: Final = new_mcp_server_request.auth_type not in _STAGED_AUTH_VALUE_AUTH_TYPES or (
|
||||
saved_origin is not None
|
||||
and preview_origin is not None
|
||||
and httpx.URL(saved_origin) == httpx.URL(preview_origin)
|
||||
saved_origin is not None and saved_origin == preview_origin
|
||||
)
|
||||
request: Final = (
|
||||
_inherit_credentials_from_existing_server(new_mcp_server_request) if may_inherit else new_mcp_server_request
|
||||
|
|
|
|||
|
|
@ -154,17 +154,28 @@ class TestExecuteWithMcpClient:
|
|||
assert saved.url == "https://stored.example/mcp"
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("url", "same_origin"),
|
||||
("saved_url", "url", "same_origin"),
|
||||
(
|
||||
("https://other.example/mcp", False),
|
||||
("http://stored.example/mcp", False),
|
||||
("https://stored.example:8443/mcp", False),
|
||||
("https://stored.example:443/mcp", True),
|
||||
("https://stored.example/mcp", "https://other.example/mcp", False),
|
||||
("https://stored.example/mcp", "http://stored.example/mcp", False),
|
||||
("https://stored.example/mcp", "https://stored.example:8443/mcp", False),
|
||||
("https://stored.example/mcp", "https://stored.example:443/mcp", True),
|
||||
("http://stored.example/mcp", "http://stored.example:80/edited", True),
|
||||
("https://stored.example/mcp", "HTTPS://STORED.EXAMPLE/edited", True),
|
||||
("https://[::1]/mcp", "https://[::1]/edited", True),
|
||||
("https://[::1]/mcp", "https://[::1]:443/edited", True),
|
||||
("https://[::1]/mcp", "https://[::2]/edited", False),
|
||||
("https://stored.example/mcp", "https://stored.example:invalid/mcp", False),
|
||||
),
|
||||
)
|
||||
@pytest.mark.parametrize("explicit_credential", (None, "preview:explicit"))
|
||||
def test_static_preview_respects_origin_when_inheriting_credentials(
|
||||
self, monkeypatch: pytest.MonkeyPatch, url: str, same_origin: bool, explicit_credential: str | None
|
||||
self,
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
saved_url: str,
|
||||
url: str,
|
||||
same_origin: bool,
|
||||
explicit_credential: str | None,
|
||||
) -> None:
|
||||
from starlette.datastructures import Headers
|
||||
|
||||
|
|
@ -174,7 +185,7 @@ class TestExecuteWithMcpClient:
|
|||
saved: Final = MCPServer(
|
||||
server_id="saved-preview-server",
|
||||
name="saved",
|
||||
url="https://stored.example/mcp",
|
||||
url=saved_url,
|
||||
transport=MCPTransport.http,
|
||||
auth_type=MCPAuth.basic,
|
||||
authentication_token="preview:stored",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue