video_monitor/scripts/verify-local-http.py

64 lines
2.6 KiB
Python
Raw Normal View History

2026-08-30 22:22:11 +08:00
"""Read-only HTTP smoke checks against the locally recorded server (no login)."""
import io
import json
import time
import psutil
import requests
from PIL import Image
from local_server import RUNTIME, recorded_process
def main():
proc = recorded_process()
if not proc:
raise RuntimeError('Start the local server first')
client = requests.Session()
client.trust_env = False
results = []
cases = [
('/', 302, None),
('/login', 200, None),
('/user/openCaptcha', 200, None),
('/static/lib/css/style.css', 200, None),
('/static/images/logo.png', 200, None),
('/system/openConfig', 302, None),
('/system/openConfig', 302, {'Safe': 'legacy-bypass'}),
('/inner/on_publish', 403, None),
]
for path, expected, headers in cases:
response = client.get('http://127.0.0.1:10001' + path, headers=headers,
allow_redirects=False, timeout=15)
assert response.status_code == expected, (path, response.status_code)
if expected == 302:
assert response.headers['Location'] == '/login'
if path == '/user/openCaptcha':
image = Image.open(io.BytesIO(response.content))
image.verify()
assert response.headers['Content-Type'].startswith('image/')
results.append({'path': path, 'safe_header': bool(headers), 'status': response.status_code})
client.close()
processes = [proc, *proc.children(recursive=True)]
sockets = []
for process in processes:
for conn in process.connections(kind='inet'):
if conn.status == psutil.CONN_LISTEN:
assert conn.laddr.ip == '127.0.0.1' and conn.laddr.port == 10001, conn
assert conn.type.name != 'SOCK_DGRAM', conn
if conn.raddr:
assert conn.raddr.ip in ('127.0.0.1', '::1'), conn
sockets.append({'pid': process.pid, 'local': list(conn.laddr),
'remote': list(conn.raddr), 'status': conn.status})
assert 'ffmpeg' not in process.name().lower() and 'zlm' not in process.name().lower()
assert any(item['status'] == psutil.CONN_LISTEN for item in sockets)
report = {'checked_at': time.strftime('%Y-%m-%d %H:%M:%S'), 'http': results,
'process_ids': [process.pid for process in processes], 'sockets': sockets,
'scope': 'Anonymous HTTP and current process/socket snapshot only; no real camera/model/login tested'}
(RUNTIME / 'local-verification.json').write_text(json.dumps(report, indent=2), encoding='utf-8')
print(json.dumps(report, indent=2))
if __name__ == '__main__':
main()