# -*- coding: utf-8 -*- r'''给静态资源加缓存头,让 Cloudflare 在边缘直接发。 == 为什么这是最大的一招 == 基线实测(下载 15 MB 安装包走隧道回 4G 源站): ykxmz-watch-1.8.1.apk 201523 字节 / 66.8 秒 = 3 KB/s ykxmz-server-1.8.1.zip 214900 字节 / 3.1 秒 = 67 KB/s ykxmz-setup-1.8.1.exe 只下到 237568/15067199 字节就停了 原因:relay 给所有响应都发 `Cache-Control: no-store`, **Cloudflare 完全不缓存** —— 每一次下载、每一张图、每个 favicon 都要穿隧道回 4G 源站。而回源吞吐只有几 KB/s。 改成可缓存后,Cloudflare 会在用户附近的边缘节点直接发, 速度是"边缘到用户",跟 4G 那条腿无关。 == 各路径的策略 == /download/* public, max-age=604800, immutable 文件名带版本号(ykxmz-setup-1.8.1.exe), 同一名字的内容永不改变,所以可以放心长缓存。 /shot/* 已经是 public, max-age=86400(保持不变) /favicon.ico public, max-age=604800(147 KB,之前每次 3.2 秒) / public, max-age=60 首页会列出当前版本,缓存久了下新版本会看不到按钮。 60 秒足够挡住刷新的重复回源,又不会让版本信息过期太久。 /v1/* no-store(接口,必须实时) 注意:Cloudflare 默认只缓存一部分扩展名,.exe/.zip/.apk 可能不在 默认列表里。所以改完必须**实测 cf-cache-status 是不是 HIT**, 不 HIT 就要在 Cloudflare 后台加一条 Cache Rule(我会告诉用户怎么加)。 ''' from __future__ import annotations import sys from pathlib import Path SRC = Path(r"C:\Users\shu\Desktop\deepseekagent\LanRemote\relay\relay.py") OLD_DL = """ self.send_header( "Content-Disposition", f"attachment; filename*=UTF-8''{quoted}") self.send_header("Cache-Control", "no-store")""" NEW_DL = """ self.send_header( "Content-Disposition", f"attachment; filename*=UTF-8''{quoted}") # ★ 让 Cloudflare 在边缘缓存。 # 原来这里是 no-store,于是每次下载都要穿隧道回 4G 源站, # 实测吞吐只有 3~67 KB/s(15 MB 的安装包根本下不动)。 # 文件名带版本号,同一名字内容永不改变,可以长缓存。 self.send_header( "Cache-Control", "public, max-age=604800, immutable")""" # favicon 那块 OLD_ICON = """ self._send(200, icon, "image/x-icon")""" NEW_ICON = """ self._send(200, icon, "image/x-icon", {"Cache-Control": "public, max-age=604800"})""" # 首页那块 OLD_SITE = """ self._send(200, _site_page().encode("utf-8"), "text/html; charset=utf-8") return""" NEW_SITE = """ # 首页缓存 60 秒:挡住刷新的重复回源, # 又不会让"当前版本/下载按钮"过期太久。 self._send(200, _site_page().encode("utf-8"), "text/html; charset=utf-8", {"Cache-Control": "public, max-age=60"}) return""" def patch(text: str, old: str, new: str, label: str) -> tuple: if old not in text: print(" ✗ 没找到:%s" % label) return text, False if text.count(old) != 1: print(" ! 出现 %d 次:%s" % (text.count(old), label)) return text, False print(" ✓ %s" % label) return text.replace(old, new, 1), True def main() -> int: text = SRC.read_text(encoding="utf-8") before = text.count("\n") + 1 ok_all = True print(" 加缓存头:") for old, new, label in ( (OLD_DL, NEW_DL, "下载:no-store -> public,max-age=604800,immutable"), (OLD_ICON, NEW_ICON, "favicon:加 7 天缓存"), (OLD_SITE, NEW_SITE, "首页:加 60 秒缓存"), ): text, ok = patch(text, old, new, label) ok_all = ok_all and ok if not ok_all: print() print(" 有锚点没匹配,没有写回") return 1 SRC.write_text(text, encoding="utf-8", newline="\n") print() print(" 已写回:%d -> %d 行" % (before, text.count("\n") + 1)) return 0 if __name__ == "__main__": sys.exit(main())