|
1 | 1 | # Bug scan progress |
2 | 2 |
|
3 | | -Last scanned: app.py — 2026-07-15 |
| 3 | +Last scanned: lrtmp2_client.py — 2026-08-12 |
4 | 4 |
|
5 | 5 | ## Module checklist |
6 | 6 |
|
7 | 7 | - [x] `app.py` — Flask routes, auth, session handling, stream CRUD |
8 | | -- [ ] `lrtmp2_client.py` — librtmp2-server REST API client |
| 8 | +- [x] `lrtmp2_client.py` — librtmp2-server REST API client |
9 | 9 | - [ ] `config.py` — startup validation and environment configuration |
10 | 10 | - [ ] `templates/` — Jinja2 templates (XSS, CSRF forms) |
11 | 11 | - [ ] `static/js/` — frontend JavaScript (DOM injection, fetch logic) |
12 | 12 |
|
13 | 13 | (`templates/`/`static/js/` were actually scanned 2026-07-05/06, see findings |
14 | 14 | below — checkboxes just hadn't been ticked.) |
15 | 15 |
|
| 16 | +## Findings (2026-08-12 lrtmp2_client.py pass) |
| 17 | + |
| 18 | +- **Bug (fixed):** `delete_stream()` default `wait_timeout=35` was sized for an |
| 19 | + obsolete 30s librtmp2-server RTMP drain window. Current server |
| 20 | + `DELETE_DRAIN_TIMEOUT` is **300s** (`librtmp2-server` `src/http.rs`): during |
| 21 | + drain the stream stays in `GET /api/v1/streams` with `enabled=false` until |
| 22 | + finalize. Scenario: operator deletes a live stream with long-lived RTMP |
| 23 | + sessions; server returns HTTP 202 and keeps draining; after 35s the panel |
| 24 | + raises `Lrtmp2ApiError` ("stream is still present…") even though the delete |
| 25 | + is still progressing normally on the server for up to five more minutes. |
| 26 | + Impact: false failure during incident response — operator believes the revoke |
| 27 | + failed and may stop monitoring while publish/play keys remain valid until |
| 28 | + drain completes. Fixed by defaulting `wait_timeout` to 305s |
| 29 | + (`DELETE_STREAM_DRAIN_WAIT_SECONDS`) and raising the Docker Gunicorn |
| 30 | + `--timeout` to 330s so the synchronous delete route can outlast the server |
| 31 | + drain. |
| 32 | +- Reviewed but not a bug: network/JSON errors wrapped as `Lrtmp2ApiError`; |
| 33 | + path segments URL-encoded; Bearer token only in Authorization header; |
| 34 | + `delete_stream` 202 polling until stream disappears; `cluster_remove_node` |
| 35 | + surfaces 404; per-call timeouts; no shared mutable request state. |
| 36 | + |
16 | 37 | ## Findings (2026-07-15 app.py pass) |
17 | 38 |
|
18 | 39 | - **Bug (fixed):** `delete_stream()` moved deletes into a daemon background |
|
0 commit comments