feat(chv): 架构与代码质量 9.5+ 提升——长函数清零、WarmPool facade、#215 对齐、审计计数、只读 VM 字段、ADR-8~11

This commit is contained in:
host committed 2026-10-31 06:20:12 +00:00
1 parent c908a0147a
commit 42de20da68
15 files changed
+840 -345

No files matched your search

+93 -72
View File
@@ -9,12 +9,100 @@ import os
import socket
def _read_header(sock):
"""读满响应头:返回 (header_text, 已收体部前缀)。
超时或提前关流即 RuntimeError,绝不把半截头当结束
(feat-chv-fix P1-6 的语义,纯移动)。"""
buf = b""
header_end = None
timed_out = False
while header_end is None:
try:
data = sock.recv(65536)
except socket.timeout:
timed_out = True
break
if not data:
break
buf += data
header_end = buf.find(b"\r\n\r\n")
if timed_out or header_end is None:
raise RuntimeError("CHV API 响应头不完整(超时或提前关流)")
header = buf[:header_end].decode("utf-8", errors="replace")
return header, buf[header_end + 4:]
def _parse_content_length(header):
"""从响应头取 Content-Length:chunked 或无长度即拒绝。
chunked 明确拒绝(CHV REST 不应发 chunked);无长度则
无法证完整性,同样拒绝。"""
content_length = None
is_chunked = False
for line in header.split("\r\n")[1:]:
if ":" not in line:
continue
name, value = line.split(":", 1)
name = name.strip().lower()
value = value.strip()
if name == "content-length":
try:
content_length = int(value)
except ValueError:
raise RuntimeError("CHV API Content-Length 非法")
elif name == "transfer-encoding" \
and "chunked" in value.lower():
is_chunked = True
if is_chunked:
raise RuntimeError("CHV API 响应为 chunked,拒绝解析")
if content_length is None:
raise RuntimeError("CHV API 响应无 Content-Length,拒绝解析")
return content_length
def _read_body(sock, body, content_length):
"""按 Content-Length 读满体部:超时或提前关流即截断错误。"""
while len(body) < content_length:
try:
data = sock.recv(65536)
except socket.timeout:
raise RuntimeError(
"CHV API 响应体截断:已收 %d / 需 %d 字节"
% (len(body), content_length))
if not data:
raise RuntimeError(
"CHV API 响应体截断:已收 %d / 需 %d 字节"
% (len(body), content_length))
body += data
return body[:content_length]
def _parse_response(header, body):
"""从已读满的头与体部解析 (status, body):能解析 JSON
时为 dict,否则为原文本;状态行解析失败时 status 为 0。"""
text = header + "\r\n\r\n" + body.decode("utf-8", errors="replace")
status = 0
if text.startswith("HTTP/"):
try:
status = int(text.split()[1])
except (IndexError, ValueError):
status = 0
body_text = body.decode("utf-8", errors="replace")
try:
parsed = json.loads(body_text) if body_text.strip() else {}
except ValueError:
parsed = body_text
return status, parsed
def _unix_socket_api(socket_path, method, path, payload=None):
"""Cloud Hypervisor REST API 的默认传输:标准库 raw HTTP
over Unix socket(无第三方依赖)。返回 (status, body),
body 能解析 JSON 时为 dict,否则为原文本。socket 不存在
或连接失败时 raise RuntimeError(调用方据此判 api 超时
/失败,不编造 200)。"""
/失败,不编造 200)。读满语义见 _read_header /
_parse_content_length / _read_body(P1-6,纯移动)。"""
if not os.path.exists(socket_path):
raise RuntimeError("api socket 不存在:%s" % socket_path)
body = b""
@@ -32,79 +120,12 @@ def _unix_socket_api(socket_path, method, path, payload=None):
try:
sock.connect(socket_path)
sock.sendall(raw)
chunks = []
# feat-chv-fix(P1-6):读超时不再当“响应结束”。
# 先读满响应头,再按 Content-Length 读满体部;超时、
# 提前关流、体部短于 Content-Length 一律 RuntimeError
# (调用方判 api_timeout / 传输失败),绝不解析半截
# 响应。chunked 与无 Content-Length 响应明确拒绝
# (Cloud Hypervisor REST 不应发 chunked;无长度则
# 无法证完整性)。
buf = b""
header_end = None
timed_out = False
while header_end is None:
try:
data = sock.recv(65536)
except socket.timeout:
timed_out = True
break
if not data:
break
buf += data
header_end = buf.find(b"\r\n\r\n")
if timed_out or header_end is None:
raise RuntimeError("CHV API 响应头不完整(超时或提前关流)")
header = buf[:header_end].decode("utf-8", errors="replace")
body = buf[header_end + 4:]
content_length = None
is_chunked = False
for line in header.split("\r\n")[1:]:
if ":" not in line:
continue
name, value = line.split(":", 1)
name = name.strip().lower()
value = value.strip()
if name == "content-length":
try:
content_length = int(value)
except ValueError:
raise RuntimeError("CHV API Content-Length 非法")
elif name == "transfer-encoding" \
and "chunked" in value.lower():
is_chunked = True
if is_chunked:
raise RuntimeError("CHV API 响应为 chunked,拒绝解析")
if content_length is None:
raise RuntimeError("CHV API 响应无 Content-Length,拒绝解析")
while len(body) < content_length:
try:
data = sock.recv(65536)
except socket.timeout:
raise RuntimeError(
"CHV API 响应体截断:已收 %d / 需 %d 字节"
% (len(body), content_length))
if not data:
raise RuntimeError(
"CHV API 响应体截断:已收 %d / 需 %d 字节"
% (len(body), content_length))
body += data
body = body[:content_length]
header, body = _read_header(sock)
content_length = _parse_content_length(header)
body = _read_body(sock, body, content_length)
finally:
sock.close()
text = header + "\r\n\r\n" + body.decode("utf-8", errors="replace")
status = 0
if text.startswith("HTTP/"):
try:
status = int(text.split()[1])
except (IndexError, ValueError):
status = 0
body_text = body.decode("utf-8", errors="replace")
try:
parsed = json.loads(body_text) if body_text.strip() else {}
except ValueError:
parsed = body_text
return status, parsed
return _parse_response(header, body)
def normalize_api_result(result) -> tuple: