fix: refuse a Redis URL whose port cannot be used

urlsplit accepts an authority such as localhost:notaport or localhost:65536 and
urlunsplit rebuilds it verbatim; only parts.port raises, and nothing read it. The
unusable value reached .env, where the worker picked it up and failed to start
its broker, while `up` reported success because it waits only on the API health
endpoint.
This commit is contained in:
Alex committed 2026-09-17 00:34:42 +01:00
1 parent 147bb352ec
commit 51b2fa38de
2 files changed
+16

No files matched your search

+7
View File
@@ -215,6 +215,13 @@ def _redis_urls(base: str) -> dict[str, str]:
except ValueError as exc:
# urlsplit raises on things like redis://[::1 ; that is a typo, not a crash.
raise DeployError(f"the Redis URL {base!r} could not be read: {exc}") from exc
try:
_ = parts.port # a non-numeric or out-of-range port raises here, not when the URL is split
except ValueError as exc:
raise DeployError(
f"the Redis URL {base!r} has an unusable port: {exc}. Pass a URL like "
"redis://host:6379 or redis://host:6379/5."
) from exc
if parts.scheme not in ("redis", "rediss"):
raise DeployError(
f"the Redis URL {base!r} should start with redis:// or rediss://, with any options as "
+9
View File
@@ -231,6 +231,15 @@ class TestNativeUp:
with pytest.raises(DeployError, match="too long to read"):
_run(argv, _native_context())
@pytest.mark.parametrize("url", ["redis://localhost:notaport/0", "redis://localhost:65536/0"])
def test_a_redis_url_with_an_unusable_port_is_refused(self, tmp_path, url):
"""urlsplit accepts it and rebuilds it verbatim; only .port notices, and the worker dies later."""
argv = ["up", "--native", "--dir", str(tmp_path), "--yes",
"--postgres-uri", "postgresql://localhost/d", "--redis-url", url]
with pytest.raises(DeployError, match="unusable port"):
_run(argv, _native_context())
assert not (tmp_path / ".env").exists(), "it refuses before writing settings the worker would read"
@pytest.mark.parametrize("url", ["localhost:6379", "redis+socket:///var/run/redis.sock",
"redis://localhost:6379/queue"])
def test_a_redis_url_that_cannot_be_numbered_is_refused(self, tmp_path, url):