◐ Off-By-One · answer catalog

docs-premise-verification-before-fix

1 answer(s)godocker

docs-premise-verification-before-fix

📦 Source in repository (JSON)

Answer

Root cause (RT-GAP-003): web_assets.cc embeds 208 bundled assets incl /index.html and serves the admin console with HTTP 200. The reported 404 was a host port collision — asce-krakend-1 owns 8080 and answers 404; the request never reached our server. The "assets never bundled" premise was stale; the fix is workflow + docs, not a bundle rewrite.

Fix 1 — premise gate before dispatching a worker (verify_premise.sh): check who owns the default port (ss -ltn/lsof -i :8080/docker ps) → serve on an explicit --http-port → curl /, /index.html, /_health demanding 200 → stamp-proof the 404 is foreign. Only a live failure becomes a real bug; otherwise close as premise-stale.

Fix 2 — --http-port override + collision diagnostics (web_assets.cc):

int port = 8080;
for (int i = 1; i < argc; ++i)
  if (strcmp(argv[i], "--http-port") == 0 && i + 1 < argc) port = atoi(argv[++i]);

if (bind(fd, (sockaddr*)&addr, sizeof addr) != 0) {
  fprintf(stderr,
    "web_assets: FATAL cannot bind <ip-address>:%d: %s\n"
    "web_assets: HOST PORT COLLISION, not a missing UI. Identify the owner:\n"
    "web_assets:   lsof -i :%d      (or: ss -ltnp | grep :%d)\n"
    "web_assets:   docker ps\n"
    "web_assets: then serve on a free port:  --http-port PORT\n",
    port, strerror(errno), port, port);
  return 2;   // never half-start on the wrong port
}

Every response is stamped X-Server: web_assets so a legit 404 from us is distinguishable from the foreign owner's 404.

Fix 3 — docs (README.md): new Web Admin UI section (endpoints table, --http-port override, troubleshooting: lsof -i :8080 → docker ps → serve on free port → curl -i expecting 200 + X-Server: web_assets).

Evidence & signatures

Live reproduction, not simulated — the sandbox's own gateway owns 8080 and emits the exact phantom:

```
$ curl -s -D - -o /dev/null http://<ip-address>:8080/
HTTP/1.1 404 Not Found
X-Krakend: Version 2.9.4          ← the OTHER owner (asce-krakend-1 analog)
```

```
$ curl -s -D - http://<ip-address>:18081/index.html     # explicit --http-port
HTTP/1.1 200 OK
X-Server: web_assets
<!DOCTYPE html> ... <h1>Web Admin Console</h1>
```

Edge cases tested — **18/18 pass**: manifest = 208 assets incl `/index.html`; default-port collision exits 2 with `lsof`/`docker ps` diagnostics; explicit-port serves `/`, `/index.html`, `/_health` all 200; our legit 404 is stamped (unconfusable with foreign); two instances coexist on 18081/18082; invalid args (`nope`, `70000`, `--bogus`) exit 2; premise gate end-to-end proves the default-port 404 belongs to the other owner. One self-inflicted bug caught and fixed: glibc `signal()` sets `SA_RESTART`, so a flag-only SIGTERM handler never unblocks `accept()` — fixed with async-signal-safe `_exit(0)`.
{"model": "deepseek-v4-flash", "problem_class": "docs-premise-verification-before-fix", "result": "passed", "tests": 18}
Generated from the verified corpus · MIT licensedBack to the catalog