513566c89e
A tiny stdlib HTTP server that logs every request (source IP, method, path, full body, JPEG part stripped) to verify whether a Hikvision camera actually POSTs its Alarm Server events — independent of our app's parsing/acceptance. It cracked the 2026-06-27 "auto-exit" investigation: proved the exit camera was sending NOTHING (corrupt config DB), then later that it sent plain VMD without targetType=vehicle. python3 test-post-camera-events.py [port] # default 8099 Point a camera's Alarm Server at this host:port; drive a car. A line from the camera IP = it sends (debug downstream); silence = the camera isn't POSTing. Claude-Session: https://claude.ai/code/session_01Xcm6ikLgGoCxxHrxtjkk5V
45 lines
1.4 KiB
Python
45 lines
1.4 KiB
Python
#!/usr/bin/env python3
|
|
import sys
|
|
from datetime import datetime
|
|
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
|
|
|
|
PORT = int(sys.argv[1]) if len(sys.argv) > 1 else 8099
|
|
|
|
|
|
class Sink(BaseHTTPRequestHandler):
|
|
def _log(self, method: str) -> None:
|
|
ts = datetime.now().strftime("%H:%M:%S")
|
|
src = self.client_address[0]
|
|
clen = int(self.headers.get("Content-Length", 0) or 0)
|
|
body = self.rfile.read(clen) if clen else b""
|
|
ctype = self.headers.get("Content-Type", "-")
|
|
print(f"\n=== {ts} {method} {self.path} from {src} ===", flush=True)
|
|
print(f" Content-Type: {ctype} ({clen} bytes)", flush=True)
|
|
text = body.decode("utf-8", "replace")
|
|
cut = text.find('Content-Type: image/jpeg')
|
|
if cut != -1:
|
|
text = text[:cut] + "\n [...JPEG image part omitted...]"
|
|
print(" body:\n" + text, flush=True)
|
|
self.send_response(200)
|
|
self.send_header("Content-Length", "2")
|
|
self.end_headers()
|
|
self.wfile.write(b"OK")
|
|
|
|
def do_POST(self):
|
|
self._log("POST")
|
|
|
|
def do_GET(self):
|
|
self._log("GET")
|
|
|
|
def do_PUT(self):
|
|
self._log("PUT")
|
|
|
|
def log_message(self, *args):
|
|
pass
|
|
|
|
|
|
if __name__ == "__main__":
|
|
print(f"camera-event post test listening on 0.0.0.0:{PORT}", flush=True)
|
|
print("Ctrl-C to stop.\n", flush=True)
|
|
ThreadingHTTPServer(("0.0.0.0", PORT), Sink).serve_forever()
|