- Shipped
- September 23, 2026 at 2:28 AM UTC
- Author
- Kamo
- Commit
- 4820f44
POST /convert-vector and WS /ws/pipeline take no auth (see this commit's companion report for why that is not fixed here) and, until now, read a caller's whole upload into memory before looking at its size at all — max_image_size_mb was defined in settings and never referenced anywhere. Either endpoint also ran background removal and vectorization (rembg, vtracer — both CPU-bound, via asyncio.to_thread) with no cap on how many could run at once. Together that is an open door to running this pod out of memory or CPU with a handful of concurrent requests, from anyone who can reach it — and per **************** that is any browser on the internet: Traefik routes /vector-ws/* straight to this service, bypassing apiservice's gateway entirely. - /convert-vector now reads the upload in bounded chunks and refuses (413) as soon as the running total crosses max_image_size_mb, rather than after buffering the whole thing. - The WebSocket pipeline has no equivalent of a chunked read — receive_text() already holds the full decoded frame by the time it's seen — so the same limit is checked immediately after base64-decoding an incoming image/mask, before it is ever handed to bg removal or vectorization. - A new conversion_semaphore (max_concurrent_conversions, default 4, in settings/configmap like max_image_size_mb already was) wraps every bg-removal and vectorization call in both endpoints. Excess callers wait; they are not refused. Tests: test_resource_limits.py (pytest + httpx only — the heavy ML/CV deps in requirements.txt are all imported lazily inside services/*.py function bodies, never at module load, so the two conversion entry points are mocked instead of installed). Not run by CI today; this build has none (build-and-deploy.yml goes straight from checkout to docker build/push/deploy). Each guard was verified red first: the size cap removed (an oversized upload reaches the mocked converter instead of being refused) and the WebSocket size check disabled, in a local worktree, restored after.
