Files
ykxmz/_build/test_public_clean.py
T
xmz7891 bf15a2ee61 静态资源交给 Cloudflare 边缘缓存(下载提速 41 倍)
实测基线:
  ykxmz-setup-1.8.1.exe   只下到 237568/15067199 字节就停(17 KB/s)
  ykxmz-watch-1.8.1.apk   201523 字节 / 66.8 秒 = 3 KB/s
  ykxmz-server-1.8.1.zip  214900 字节 / 3.1 秒  = 67 KB/s

原因:relay 给所有响应都发 Cache-Control: no-store,
Cloudflare 完全不缓存 —— 每次下载/每张图都要穿隧道回 4G 源站。

改动:
  /download/*   no-store -> public, max-age=604800, immutable
                文件名带版本号,同一名字内容永不改变,可以长缓存
  /             -> public, max-age=60(挡住刷新重复回源)
  /favicon.ico  已是 max-age=86400,保持不变
  /shot/*       已是 max-age=86400,保持不变
  /v1/*         保持 no-store(接口必须实时)

顺带修两个自己踩的坑:

1. _send() 无条件先发 no-store,再追加 extra 里的 Cache-Control,
   结果是**两个 Cache-Control 头**,客户端只认第一个 ——
   调用方传的缓存策略被吃掉。改成 extra 里有就不再发默认值。

2. do_HEAD 和 do_GET 的缓存头不一致:HEAD 对非 /shot/ 一律报 no-store。
   下载器/代理用 HEAD 探测时会误判文件不可缓存。
   现在 _head_info 给每个路由带上和 GET 完全相同的缓存头,
   do_HEAD 也不再盲目覆盖。

结果(同一个测试口径):
  setup.exe  17 KB/s(截断) -> 695 KB/s 完整 15 MB   41 倍
  watch.apk   3 KB/s         -> 101 KB/s              33 倍
  server.zip 67 KB/s         ->  87 KB/s
  三个文件全部 cf-cache-status=HIT(不再穿隧道回源)

排查过程记一笔:我一开始用 curl -I 验证,
看到的全是 no-store —— 因为 **-I 发的是 HEAD**,
而 HEAD 走的是另一个分支。查了半天才发现是验证方法错了。
2026-10-07 15:44:48 +08:00

174 lines
5.8 KiB
Python

# -*- coding: utf-8 -*-
r'''守卫:对外公开的材料里不许出现「中转管理后台」。
用户定的规矩(原话):
「你对外公开的数据里不要包含那个中转站管理的页面,你就只能提官网」
范围(用户已确认):
✅ 必须干净:发布说明、CHANGELOG、官网页面、README、我对外的汇报
❌ 不用管:服务端 zip 里的运维文档(给装机的人看)、
源码实现(路径是功能本身)、_build/_tests 内部材料
为什么写成测试而不是写进文档:
文档没人看。这一天里我因为"以为记住了"翻了三次车,
所以把规矩变成会红的断言 —— 违反了立刻报错。
顺便也守住另外两条用户明确说过的:
* 官网里不能出现管理入口
* 发布说明只能是更新内容
'''
from __future__ import annotations
import re
import sys
from pathlib import Path
ROOT = Path(r"C:\Users\shu\Desktop\deepseekagent\LanRemote")
# 这些词一律不许出现在对外材料里
FORBIDDEN = [
"zhongzhuanzhan",
"/admin",
"管理后台",
"管理页",
"管理入口",
"管理面板",
"admin_password",
]
# 对外公开的文件(相对路径)
PUBLIC_FILES = [
"_build/CHANGELOG.md",
"README.md",
]
# 对外公开的目录:里面所有 .md 都要干净
PUBLIC_DIRS = [
"docs",
]
# docs 里这些是**运维文档**,是给装服务器的人看的,允许提到管理页
DOCS_ALLOWLIST = {
"AFTER-INSTALL.txt",
"BEFORE-INSTALL.txt",
"LICENSE.txt",
"项目规矩.md", # 这份文件本身就是在讲这条规矩
"免费托管方案.md", # 讲托管方案,不涉及
# 开发流程文档:里面要写"发布脚本会检查更新说明里有没有管理页字眼",
# 属于描述规则本身,不是对外宣传材料。
"双平台发布.md",
"EzHub-SSH诊断报告.md", # 给服务端运维看的排查报告
}
# 官网源码里这些词也不许有(landing.py 渲染出来的页面)
SITE_FILES = [
"relay/landing.py",
"relay/showcase.py",
]
passed = 0
failed = 0
def check(name: str, ok: bool, detail: str = "") -> None:
global passed, failed
if ok:
passed += 1
print(" [PASS] " + name)
else:
failed += 1
print(" [FAIL] " + name + " " + str(detail))
def scan(path: Path) -> list:
"""返回 [(行号, 关键词, 那一行)]"""
hits = []
try:
text = path.read_text(encoding="utf-8", errors="replace")
except OSError:
return hits
for index, line in enumerate(text.splitlines(), 1):
for word in FORBIDDEN:
if word in line:
hits.append((index, word, line.strip()[:70]))
return hits
def main() -> int:
print(" 一、对外公开的单文件")
for rel in PUBLIC_FILES:
path = ROOT / rel
if not path.is_file():
check("%s 存在" % rel, False, "文件不存在")
continue
hits = scan(path)
check("%s 干净" % rel, not hits,
"第 %d 行含「%s」" % (hits[0][0], hits[0][1]) if hits else "")
print()
print(" 二、docs 目录(运维文档除外)")
for rel in PUBLIC_DIRS:
directory = ROOT / rel
if not directory.is_dir():
continue
for path in sorted(directory.iterdir()):
if not path.is_file():
continue
if path.name in DOCS_ALLOWLIST:
print(" [跳过] %s(运维文档,允许提及)" % path.name)
continue
hits = scan(path)
check("docs/%s 干净" % path.name, not hits,
"第 %d 行含「%s」" % (hits[0][0], hits[0][1]) if hits else "")
print()
print(" 三、官网页面(渲染出来给所有人看的)")
sys.path.insert(0, str(ROOT / "relay"))
try:
import landing
html = landing.render_site([
{"name": "ykxmz-setup-1.8.0.exe", "size": 15066550},
{"name": "ykxmz-server-1.8.0.zip", "size": 214661},
{"name": "ykxmz-watch-1.8.0.apk", "size": 201523},
])
except Exception as exc: # noqa: BLE001
check("官网能渲染", False, exc)
html = ""
if html:
check("官网能渲染", len(html) > 5000, "%d 字符" % len(html))
for word in FORBIDDEN:
check("官网里没有「%s」" % word, word not in html.lower()
if word.isascii() else word not in html)
# 只允许链接到下载 / 截图 / 首页 / 图标 / 页内锚点。
# 出现别的站内路径就说明可能把管理入口又加回去了。
allowed = ("/download/", "/shot/", "/", "/favicon.ico", "#")
hrefs = set(re.findall(r'href="([^"]+)"', html))
bad = [h for h in hrefs
if h.startswith("/") and not h.startswith(allowed)]
check("官网里的站内链接只指向下载/首页/锚点", not bad, bad)
print()
print(" 四、发布说明只能是「更新内容」")
rel_notes = ROOT / "_build" / "RELEASE-1.8.0.md"
if rel_notes.is_file():
text = rel_notes.read_text(encoding="utf-8")
# 不该出现安装教程这种内容(用户要求"只放更新内容")
for bad_title in ("安装教程", "安装步骤", "怎么安装"):
check("发布说明里没有「%s」" % bad_title, bad_title not in text)
# 也不该提管理页
hits = scan(rel_notes)
check("RELEASE-1.8.0.md 干净", not hits,
"第 %d 行含「%s」" % (hits[0][0], hits[0][1]) if hits else "")
else:
print(" [跳过] 没有 RELEASE-1.8.0.md")
print()
print("=" * 54)
print(" 通过 %d 项,失败 %d 项" % (passed, failed))
return 0 if failed == 0 else 1
if __name__ == "__main__":
sys.exit(main())