Three defects made the panel look broken to the operator:
- POST /api/proxies with a Chinese name slugged the id down to its ASCII
digits ("香港01" -> "01"), collided with an existing node and returned
HTTP 500 "proxy id already exists". Non-ASCII names now get sequential
node-N ids; ASCII names keep a readable slug. Both paths de-duplicate.
- A host pasted as a URL ("http://192.168.3.71") went straight to DNS, so
every check failed with "[Errno -2] Name does not resolve". normalize_host
accepts host, host:port, scheme://user:pass@host:port and [IPv6]:port, and
existing configs are healed at startup.
- str(asyncio.TimeoutError()) is empty, so a black-holed proxy showed a blank
error in the UI and looked like an internal bug. describe_exc always
produces a reason.
Also:
- Expected validation failures return 400 with an error message instead of
500 + traceback; the frontend surfaces every API error as a toast.
- PUT/DELETE on an unknown proxy id return 404 instead of silently creating
or reporting ok=false with 200.
- POST /api/check/<id> forces a check on disabled nodes instead of returning
ok=true without doing anything.
- Port range is validated (1..65535).
- Store.close() lets tests release SQLite handles.
- 33 unittest cases cover id generation, host normalization, error text,
startup migration and manual checks.
15 lines
584 B
Diff
15 lines
584 B
Diff
# Incremental rebuild on top of the previously published image.
|
|
# Used when the upstream python:3.11-alpine base cannot be pulled
|
|
# (mirror rate limits). Only ships the updated app source.
|
|
#
|
|
# docker build -f Dockerfile.patch -t 192.168.2.66:80/hermes/socks5-monitor:latest .
|
|
#
|
|
# This is an escape hatch, not the canonical build. Prefer the plain
|
|
# `Dockerfile` whenever the base image is reachable, otherwise layers keep
|
|
# stacking on top of each other with every patch.
|
|
FROM 192.168.2.66:80/hermes/socks5-monitor:latest
|
|
|
|
WORKDIR /app
|
|
COPY app.py README.md ./
|
|
COPY static ./static
|