| 45 | |
| 46 | |
| 47 | def _read_json(handler: BaseHTTPRequestHandler) -> Dict[str, Any]: |
| 48 | length = int(handler.headers.get("Content-Length") or 0) |
| 49 | if length <= 0: |
| 50 | return {} |
| 51 | raw = handler.rfile.read(length) |
| 52 | if not raw: |
| 53 | return {} |
| 54 | try: |
| 55 | parsed = json.loads(raw.decode("utf-8")) |
| 56 | except json.JSONDecodeError as exc: |
| 57 | raise ValueError(f"Invalid JSON body: {exc}") from exc |
| 58 | if not isinstance(parsed, dict): |
| 59 | raise ValueError("JSON body must be an object") |
| 60 | return parsed |
| 61 | |
| 62 | |
| 63 | def _query(path: str) -> Tuple[str, Dict[str, Any]]: |