mirror of
https://github.com/Canner/WrenAI.git
synced 2026-10-28 03:08:09 +08:00
fix(clickhouse): default port-less clickhouse+https URLs to 8443, not 8123 (#2412)
This commit is contained in:
@@ -261,9 +261,15 @@ def _build_clickhouse_client_kwargs(connection_info: Any) -> dict:
|
||||
# urlparse leaves percent-encoded characters in userinfo, so decode
|
||||
# them before clickhouse-connect sees the credentials. Matches the
|
||||
# mssql / postgres URL handling elsewhere in this package.
|
||||
secure = parsed.scheme == "clickhouse+https"
|
||||
# Pick the port-less default from the scheme: ClickHouse listens for
|
||||
# HTTPS on 8443 and plaintext HTTP on 8123. Defaulting an https URL to
|
||||
# 8123 silently dialed the plaintext port with ``secure=True``, so the
|
||||
# TLS handshake hit a non-TLS listener and the connection failed.
|
||||
default_port = 8443 if secure else 8123
|
||||
out: dict = {
|
||||
"host": parsed.hostname,
|
||||
"port": int(parsed.port) if parsed.port else 8123,
|
||||
"port": int(parsed.port) if parsed.port else default_port,
|
||||
"username": (
|
||||
unquote_plus(parsed.username) if parsed.username else "default"
|
||||
),
|
||||
@@ -272,7 +278,7 @@ def _build_clickhouse_client_kwargs(connection_info: Any) -> dict:
|
||||
}
|
||||
if parsed.path and parsed.path != "/":
|
||||
out["database"] = parsed.path.lstrip("/")
|
||||
if parsed.scheme == "clickhouse+https":
|
||||
if secure:
|
||||
out["secure"] = True
|
||||
# ``settings`` already popped above, so ``out["settings"]`` survives.
|
||||
out.update(kwargs)
|
||||
|
||||
@@ -289,3 +289,45 @@ class TestClickHouseClientKwargs:
|
||||
info = _FakeChInfo(kwargs={"statement_timeout": 10})
|
||||
out = _build_clickhouse_client_kwargs(info)
|
||||
assert out["settings"] == {"max_execution_time": 10}
|
||||
|
||||
|
||||
class _FakeChUrl:
|
||||
"""Stand-in exposing a ``connection_url`` for the URL kwargs path."""
|
||||
|
||||
def __init__(self, url: str) -> None:
|
||||
from pydantic import SecretStr
|
||||
|
||||
self.connection_url = SecretStr(url)
|
||||
self.kwargs = None
|
||||
|
||||
|
||||
@pytest.mark.clickhouse
|
||||
class TestClickHouseUrlKwargs:
|
||||
"""Pure-Python tests for the ``connection_url`` branch of the kwargs builder."""
|
||||
|
||||
def test_https_url_without_port_uses_secure_default_port(self) -> None:
|
||||
"""A port-less clickhouse+https URL must dial 8443 (TLS), not 8123.
|
||||
|
||||
ClickHouse serves HTTPS on 8443 and plaintext HTTP on 8123. Defaulting
|
||||
an https URL to 8123 while also setting ``secure=True`` made the TLS
|
||||
client connect to the plaintext listener — the handshake fails.
|
||||
"""
|
||||
out = _build_clickhouse_client_kwargs(
|
||||
_FakeChUrl("clickhouse+https://user:pw@host/db")
|
||||
)
|
||||
assert out["secure"] is True
|
||||
assert out["port"] == 8443
|
||||
|
||||
def test_http_url_without_port_uses_plaintext_default_port(self) -> None:
|
||||
out = _build_clickhouse_client_kwargs(
|
||||
_FakeChUrl("clickhouse+http://user:pw@host/db")
|
||||
)
|
||||
assert "secure" not in out
|
||||
assert out["port"] == 8123
|
||||
|
||||
def test_explicit_port_is_respected_for_https(self) -> None:
|
||||
out = _build_clickhouse_client_kwargs(
|
||||
_FakeChUrl("clickhouse+https://user:pw@host:9440/db")
|
||||
)
|
||||
assert out["secure"] is True
|
||||
assert out["port"] == 9440
|
||||
|
||||
Reference in New Issue
Block a user