diff --git a/_build/fix_duplicate_cache_header.py b/_build/fix_duplicate_cache_header.py new file mode 100644 index 0000000..200e3f6 --- /dev/null +++ b/_build/fix_duplicate_cache_header.py @@ -0,0 +1,96 @@ +# -*- coding: utf-8 -*- +r'''修掉下载响应的**重复 Cache-Control 头**。 + +== 问题 == + +实测 curl -I /download/ykxmz-setup-2.1.3.exe 返回: + + Cache-Control: public, max-age=604800, immutable + Cache-Control: public, max-age=604800, immutable <- 两条! + +一条是 relay 自己发的(它 /download/ 那段本来就带了正确的头), +另一条是 nginx 配置里那句 add_header 加的。 + +**为什么必须修**:HTTP 规范里 Cache-Control 是**可合并**的头, +但重复出现时很多 CDN 会保守处理 —— Cloudflare 遇到重复的 +Cache-Control 有可能判定"缓存指令有歧义"而**跳过缓存**。 +那就等于我们白配了这一层。 + +== 改法 == + +**只留 relay 发的那条**,nginx 不再自己加。 + +为什么留 relay 的而不是 nginx 的: + * relay 知道每个文件的情况,是"单一事实来源" + * 万一以后某个文件要不同的缓存策略,改 relay 就行, + 不用在 nginx 里再维护一套按路径匹配的规则 + * 少一处配置就少一处不一致 +''' +from __future__ import annotations + +import sys +from pathlib import Path + +ROOT = Path(__file__).resolve().parent.parent +sys.path.insert(0, str(ROOT / "_build")) +from lssh import run # noqa: E402 + +DOMAIN = "yk.xxmxxs.top" + + +def main() -> int: + print(" ── 1. 从 nginx 配置里去掉重复的 add_header ──") + # 用 sed 精确删掉那一行(它前面有 8 个空格缩进) + out = run( + "sudo sed -i '/add_header Cache-Control \"public, max-age=604800, " + "immutable\" always;/d' /etc/nginx/sites-available/ykxmz && " + "echo ' 已删'; " + "echo ' --- 现在 /download/ 那段 ---'; " + "sudo sed -n '/location \\/download\\//,/^ }/p' " + "/etc/nginx/sites-available/ykxmz | sed 's/^/ /'", + timeout=120, quiet=True) + for ln in out[1].strip().splitlines(): + print(ln) + + print() + print(" ── 2. 加一句注释说明为什么这里不设 Cache-Control ──") + out = run( + "sudo sed -i 's| proxy_buffering on;|" + " proxy_buffering on;\\n\\n" + " # 这里**故意不设** Cache-Control —— relay 自己已经发了\\n" + " # 正确的(public, max-age=604800, immutable)。\\n" + " # 两边都设的话响应里会出现**两条** Cache-Control,\\n" + " # Cloudflare 遇到重复的缓存指令有可能直接跳过缓存,\\n" + " # 那就白配这一层了。|' " + "/etc/nginx/sites-available/ykxmz && echo ' 已加注释'", + timeout=120, quiet=True) + for ln in out[1].strip().splitlines(): + print(" " + ln) + + print() + print(" ── 3. 语法检查 + 重载 ──") + out = run("sudo nginx -t 2>&1 | tail -2 && sudo systemctl reload nginx && " + "sleep 2 && systemctl is-active nginx", timeout=180, quiet=True) + for ln in out[1].strip().splitlines(): + print(" " + ln) + + print() + print(" ── 4. 复查:现在应该只有一条 Cache-Control ──") + out = run( + 'echo "--- 安装包 ---"; ' + 'curl -sI --max-time 10 http://127.0.0.1:80/download/' + 'ykxmz-setup-2.1.3.exe | grep -ci "cache-control" | ' + 'sed "s/^/ Cache-Control 条数: /"; ' + 'curl -sI --max-time 10 http://127.0.0.1:80/download/' + 'ykxmz-setup-2.1.3.exe | grep -i "cache-control" | sed "s/^/ /"; ' + 'echo "--- 长轮询(应该 no-store)---"; ' + 'curl -sI --max-time 10 http://127.0.0.1:80/v1/health | ' + 'grep -i "cache-control" | sed "s/^/ /"', + timeout=120, quiet=True) + for ln in out[1].strip().splitlines(): + print(ln) + return 0 + + +if __name__ == "__main__": + sys.exit(main())