@@ -0,0 +1,111 @@
# 2026-10-20
- **修复 Docker 构建拉取依赖失败**:`docker compose up -d` 在 `RUN go mod download` 报连接 proxy.golang.org (142.250.198.145) 被拒。根因=构建环境无法直连 Google Go 模块代理(国内/受限网络)。
- 主 `Dockerfile` 加 `ENV GOPROXY=https://goproxy.cn,https://goproxy.io,https://mirrors.aliyun.com/goproxy/,direct` 。
- 新增 `Dockerfile.offline` :用 `go mod vendor` 打包的 `vendor/` , `-mod=vendor` 编译,完全离线可用;本机已 `go mod vendor` 生成 vendor/ 并验证 `-mod=vendor` 编译通过(产出 10MB 静态二进制)。
- `docs/DEPLOY.md` 新增 3.3 小节说明方案 A/B; `.dockerignore` 确认未排除 vendor/。
- **修复 UI 主页 `(index):28` 报错的根因(与之前的桩修复是不同 bug)**:`static/index.html` 内联脚本第 28 行 `String.fromCharCode(b[i)` 漏写 `]` → 整个 UI `<script>` 语法错误、`go()` 失效。已改为 `b[i]` 。之前 10-19 误判为代理桩破坏目标站脚本(桩修复本身有效,但非本次报错源)。
- **用 headless Chrome (CDP) 真实浏览器验证通过**:页面 JS 异常数=0,`go()` 生成的 `/p/<base64url>` 与后端期望一致。验证脚本 `tests/verify_browser.js` 。
- **关键约束**: main.go 用 `os.ReadFile("static/index.html")` 运行时读取(非 embed),本地直接跑立即生效;但用户用 Docker 启动,容器内是 build 时旧文件,改 UI 后必须 `docker compose up -d --build` / `./deploy.sh` 重建镜像。
- **新功能:新标签顶层导航自动带外框**(用户反馈 `target="_blank"` 链接在新标签打开 `/p/xxx` 时 UI 外框丢失)。
- `proxy.go` :顶层导航(`Sec-Fetch-Dest: document` ,老浏览器兜底 `Accept: text/html` 前缀)且 GET 且无 `?_wpframe=1` 时,302 改道到 `/?url=<enc>` ; iframe/AJAX/POST 不受影响。
- `static/index.html` : iframe src 带 `?_wpframe=1` 标记防循环;支持 `?url=` 参数自动回填输入框并加载(`dec()` 解码)。
- 验证:curl 7 场景 + headless Chrome( `tests/verify_newtab.js` )确认 302 落地外框、输入框回填、iframe 加载出内容,全部通过。
- 已知取舍:POST 顶层导航(表单 target=_blank)不改道(保表单语义),此类新标签无外框。
- 文档同步:README 特性表/局限表、API.md 3.3 节+路由表、ARCHITECTURE.md 设计决策表、tests/README.md。
- **诊断:访问 192.168.0.107:5666(飞牛 fnOS NAS 登录页)白屏,非 SSRF/网络问题**。
- 实测:本机直连 200、代理 `_wpframe=1` 抓 HTML 200、ssrf.mode=off 内网本就放行;`curl` 直连与代理均通 → 排除 SSRF 与网络。
- 真因:fnOS 是 React/Vite 重 SPA,主 JS 2.8MB 含 **102 处动态 `import('/xxx.js')`(绝对路径) ** 。浏览器把这些绝对路径解析到代理根 `http://localhost:8765/jsencrypt-CTgvjfLn.js` → 代理只认 `/p/` ,返回 **404 ** ,分包加载失败 → 整页白屏(headless Chrome 渲染 #root 为空)。
- 这是 URL 重写型代理的**架构性局限**: JS 桩只拦截 fetch/XHR/WebSocket/window.open/submit,无法拦截 JS 内部的 `import()` (不是函数,无法重写);绝对路径 import 在代理根下 404。
- 修复方向(待用户拍板):① 路径前缀反代 `/_p/<host>/<path>` 保留绝对/相对路径(正解,改动大);② 代理对 JS 内容做 import() 字面量路径改写(快速但有局限);③ 仅记为已知局限。
- **实施:子域名反代(用户选"路径前缀反代(推荐)",实际落地为更稳的子域名方案)**。
- 根因复核:`import('/x')` 是语言关键字无法被 JS 桩拦截;纯路径前缀仍会让绝对路径 import 打到代理根 404。子域名方案让文档"源"变成目标自身——`http://<编码origin>.localhost:8765/<path>` ,浏览器把 `*.localhost` 原生解析到 127.0.0.1,绝对路径 import/fetch 自然落回代理并映射回目标,**完全无需改写 JS 内部 import**。
- 编码坑:浏览器会把 Host 小写化 → base64url(含大小写)被破,改用 **hex ** (0-9a-f 小写无损)。子域名标签=`hex(scheme://host:port)` ; `?url=` 仍用 base64url(在 query 里不被小写)。
- 改文件:`main.go` (路由统一进 `rootHandler` :子域名→proxySubdomain / `/p/` →proxyHandler / 其他→uiHandler)、`proxy.go` (抽出 `doProxy` 公共核心;新增 `isSubdomain` /`decodeSubdomainOrigin` /`proxySubdomain` ;顶层导航 302 显式指向 `http://localhost:<port>/?url=` 防止新标签丢外框)、`static/index.html` (`subURL()` 用 hex 标签拼子域名 iframe src)。保留 `/p/` 传统路径兼容。
- 验证(curl): 子域名文档 200;子域名绝对路径 JS → 200 + `application/javascript` (证明 import 映射正确);顶层导航 302 → `http://localhost:8765/?url=...` (外框保住)。无头 Chrome 渲染 fnOS 时 `#root` 仍空——但定位到是 **fnOS 侧 ** :直连 `/assets/index-DhUqaTaa.js` 即 404(HTML 引了已删除的旧哈希包),且 fnOS 按 UA 返回不同 HTML( Go UA 给完整页、Chrome/curl UA 给 4543 回退壳)。属 fnOS 自身缓存/版本/鉴权问题,代理无法修。代理架构层面 SPA 支持已就绪。
- 约束:子域名反代**仅 localhost 访问可用**(依赖 `*.localhost` →127.0.0.1);经 LAN IP 访问的 SPA 仍走旧 `/p/` 路径,绝对路径 import 可能 404。已写进 README 已知局限。
- **修复:子域名模式下飞牛 SPA 控制台报 `Failed to load module script: Expected ... text/html` (同源资源 MIME 错误)**。
- 真因(与"白屏"是同一架构的延续 bug,非无解):子域名模式重写时把同源绝对地址 `http://192.168.0.107:5666/assets/x.js` 错写成 * * `/p/<base64>` **(绝对代理路径)。浏览器在子域名源下解析成 `http://<hex>.localhost:8765/p/<base64>` , `rootHandler` 见 host 是子域名 → `proxySubdomain` 把 `/p/<base64>` 当成**目标路径**去飞牛取 → 飞牛无此路径 → 回登录页 HTML → 浏览器当模块解析失败报 MIME 错误。
- 验证事实:经代理取 `polyfills.js` 返回 `application/javascript` (资源本身没问题);直连飞牛任意 UA 也是 `application/javascript` → 坐实是代理映射错误,不是 fnOS 资源缺失。
- 修复三处:① `rewriter.go` 的 `rewriteHTML` /`rewriteCSS` 增加 `subdomainMode` 参数——子域名模式下**同源绝对地址改为根相对** `/assets/x.js` (让子域名处理器自行映射回目标),跨域才走 `/p/<base64>` ;② `buildProxyJS` 增加 `subdomainMode` /BASE_HOST——子域名模式下 JS 桩只对**跨域**请求加 `/p/` 前缀,同源 fetch/XHR/WebSocket/表单保持相对(import() 本就靠浏览器在子域名源解析,无需桩干预);③ `proxy.go` `rootHandler` 改为**先判 `/p/` 前缀再判子域名**,使子域名下的跨域资源也能走 `/p/` 代理路径。
- 验证:子域名文档重写后 script src 全部为根相对(`/assets/polyfills-Bk1OHpAC.js` 等),仅跨域 busuanzi 保留 `/p/<base64>` ;子域名取 `/assets/...` 返回 `application/javascript` ; **无头 Chrome 渲染 fnOS `#root` 被填充 2632 字符(含 form/飞牛/svg/img 登录页结构)**, MIME 报错消失。
- 结论:飞牛经代理可正常加载,之前的报错是代理映射 bug 已修复,非目标站/网络/SSRF 问题,也非"不能解决"。
- **修复:子域名模式下不蒜子(busuanzi)同源 POST `/api.php` 报 400 "禁止请求代理自身"(用户问"是不是被限制了") **。
- 真因(同源 API 调用被 JS 桩错误劫持,非访问受限):不蒜子脚本发起 `fetch('http://<hex>.localhost:8765/api.php')` ——这是**子域名同源请求**。但 `buildProxyJS` 的同源判断基准 `BASE_HOST` 传的是飞牛真实域名 `192.168.0.107:5666` ,不蒜子请求 host=`687474...localhost:8765` 与 `BASE_HOST` 不符 → 桩误判成跨域 → 改写成 `/p/<base64>` 转走 → 解码后目标仍是子域名自身 → 触发 `proxyHandler` 的"禁止请求代理自身"自保护 400。页面加载正常,仅该统计 POST 失败。
- 修复(一行):`buildProxyJS` 模板中 `if(SUBMODE){BASE=location.origin;BASE_HOST=location.host;}` ——子域名模式下把同源基准切成**页面自身源(子域名)**,于是同源 fetch/XHR/表单保持相对(交给子域名处理器映射回 fnOS),仅真正跨域才走 `/p/` 。`/p/` 传统模式不受影响(SUBMODE=false 走原逻辑)。
- 验证:子域名文档注入的 stub 含该分支;服务端模拟 `POST /api.php` (子域名同源)返回 **200(不再 400) ** ;跨域 CDN 仍走 `/p/` 。无头 Chrome 渲染 fnOS `#root` 仍正常 2632 字符。
- 给用户的定性:不是被限制,是代理桩的同源判断错配,已修复;剩余 `/api.php` 若 fnOS 本身无此端点会返回 fnOS 自己的 404,但绝不再是代理 400。
- **诊断:飞牛页面控制台仍残留 busuanzi(不蒜子) `SyntaxError: Unexpected token '<'` + favicon 404,二者均无害**。
- favicon.ico 404:浏览器每次自动请求图标,代理未提供 favicon,无害。
- busuanzi 报错真因(第三方计数器脆弱性,非代理 bug):`busuanzi.min.js` 逻辑为 `u=new URL(document.currentScript.src); fetch(u.protocol+'//'+u.host+'/api.php')` 。经代理后脚本 src host 变成子域名 `687474...localhost:8765` ,于是 `/api.php` 打到飞牛 `192.168.0.107:5666/api.php` ;实测飞牛**无此端点**(直连返回 `404 + text/html` , body 是飞牛 SPA 首页 HTML)。busuanzi 对 HTML 做 `r.json()` 解析失败 → 报错。HTML 来自飞牛上游(我们代理自身错误页是 text/plain,已排除掺假)。且此脚本在真实局域网直连飞牛时同样会因同源 `/api.php` 缺失而失败——属第三方脚本固有脆弱性,**不影响飞牛登录/文件管理功能**。
- 顺带修复一个真实代理 bug: `doProxy` 在透传上游 **404/5xx 的 HTML/CSS ** 时只 `Write` 未 `WriteHeader` ,导致状态码被吞成 200( busuanzi 因此收到 200+HTML 而非 404+HTML)。已在 html 成功/失败回退、css 三个分支补 `w.WriteHeader(resp.StatusCode)` 透传原始状态码。验证:子域名 POST `/api.php` 现正确回 404(之前 200),正常页/UI 仍 200。
- 给用户结论:功能性 bug 已全部修复;剩余两条纯属无害噪声。若想要零控制台的干净效果,可加一个 HTML 重写规则**剥离 busuanzi `<script>` **(它只是访客计数,剥离不影响飞牛);待用户拍板是否做。
- **实施:用户要求控制台零报错 → 剥离 busuanzi `<script>` + favicon 返回 204 + 验证方式说明**。
- `rewriter.go` `rewriteHTML` 的 `walk` 在元素处理最前增加:若 `<script>` 的 src 解析后(resolveURL(base,...))含 `busuanzi` (大小写不敏感),则 `n.Parent.RemoveChild(n)` 并 return(在属性改写前拦截,故即使跨域被编码成 `/p/<base64>` 也能在解码后命中)。剥离后飞牛页面不再发起 `/api.php` POST、不再有 `r.json()` 解析报错。
- 残余 `busuanzi` 字样仅为飞牛页面里的**死 DOM 占位 span**( `<span id="busuanzi_container_site_pv">` 、`本站总访问量:` ),非脚本、不执行 JS,零影响。
- `main.go` `uiHandler` 增加 `/favicon.ico` → `204 No Content` ,消除浏览器自动请求图标产生的 404 噪声。
- 验证方法(向用户说明):① `curl` 模拟不蒜子 POST `/api.php` 从 400→404,证明新二进制已生效(旧版必报 400);② `curl` 抓取子域名文档 `grep -iE '<script[^>]*busuanzi[^>]*>'` 为 0,证明脚本已剥离;③ 无头 Chrome `--dump-dom` 渲染飞牛 `#root` 2525 字符、含 form/飞牛,证明主功能正常;④ `curl /favicon.ico` 返回 204。
- 重要提示用户:若其用 **Docker ** 跑代理,本地 `go build` 不影响容器内镜像,改 Go 代码后须 `docker compose up -d --build` ( main.go 用 os.ReadFile 读 static,但 Go 二进制本身需重建镜像);其日志 400→404 的演变已证明其当前访问的是本地重建后的服务。
- **修复:WebSocket 连接不上(用户报"socket连接连接不上") **。
- 真因:此前代理只把 `ws://` 也交给 `doProxy` 当普通 HTTP 抓取/透传,未做 WS 隧道升级;`doProxy` 发的是普通 request( `http.NewRequest` )→ 收到 101 也无后续双向字节拷贝 → 浏览器 WS 握手失败、连不上。JS 桩本身已把跨域 `ws://` 改写成 `/p/<base64>` (子域名模式)或相对路径(同源),但服务端没对应隧道。
- 修复:`proxy.go` 在 `doProxy` 入口检测 `Upgrade: websocket` (且 Connection 含 upgrade)→ 归一化 `ws→http` /`wss→https` (便于 SSRF 校验与拨号,避免白名单模式把 ws 协议拦掉)→ SSRF 校验 → 命中则走新增 `proxyWebSocket()` ,复用 `httputil.ReverseProxy` (自动转发 Upgrade 请求、收到后端 101 后劫持双向连接并 `io.Copy` 字节)→ 真正的 WS 隧道。`makeTransport` 加 `ForceAttemptHTTP2:false` ( WS 升级需 HTTP/1.1)。Director 额外把 `Origin` 改为目标 origin 提升后端兼容性。
- 验证(本地起 echo 服务器 + 原生实现握手/帧的 WS 客户端经代理 `/p/<base64>` ):客户端收到 `HTTP/1.1 101 Switching Protocols` + 正确 `Sec-WebSocket-Accept` ,随后发出 masked `ping` 、经隧道原样回显 `ping` → **双向隧道 PASS ** 。fnOS 子域名文档/JS 资源仍 200+正确 MIME( headless dump-dom 偶发 #root 空是 Chrome 计时假象,curl 取资源确认无误)。
- 提示用户:仅 localhost 访问走子域名隧道可用;Docker 部署改 Go 后需 `docker compose up -d --build` 。
- **修复:飞牛登录态无法保持 / `GET /app/token 401 (Unauthorized)` 反复出现(用户报"请求登陆token校验失败") **。
- 先定性:fnOS 未登录时 `/app/token` 返回 401 是其**正常的"未登录"响应**,app 据此跳登录页——这一步不是代理 bug。但真正的坑在后续:登录后每次请求仍 401,登录态根本存不住。
- 真因(代理服务端 cookie 存储缺陷):代理此前用 `client.Jar = s.jar` ( `net/http/cookiejar` )。Go 默认 cookiejar 按 publicsuffix 规则**拒绝为 IP 地址主机(如 192.168.0.107)保存 cookie** → 飞牛下发的会话 cookie(带 `Domain=192.168.0.107` )被静默丢弃 → 服务端 jar 永远是空的 → 每次 `/app/token` 都无会话 → 永久 401。已写最小复现程序 `tests/cjprobe` 坐实。
- 修复(让浏览器持有 cookie,而非服务端 jar):① `doProxy` 中 `client.Jar = nil` ,不再依赖服务端 jar;② 响应头转发时**特殊改写 `Set-Cookie` **:去掉 `Domain` (让浏览器按代理主机 `*.localhost:8765` 作用域存储)、代理链路为 http 时去 `Secure` 、`Path` 规整为 `/` ( `rewriteSetCookie` /`stripDomainSecure` );③ 浏览器 `Cookie` 请求头原样透传给上游(本就非 hop header)。这样同一份飞牛会话 cookie 既能用于普通 HTTP,也会随浏览器自动带入 **WebSocket 握手 ** ,登录态在反代后真正生效。
- 验证:`tests/cookietest` 起 mock fnOS( /login 下发 IP-Domain cookie、/app/token 校验、/websocket 回显 cookie) + 真代理二进制。结果:子域名 `POST /login` 上游 Set-Cookie=`fnos_sid=SECRET; Path=/; HttpOnly` (已无 Domain)→ 浏览器存于代理主机 → `GET /app/token` 回 **200 ** (cookie 成功 replay); WS 握手带 `fnos_sid=SECRET` 经代理 → 上游收到 `cookie=SECRET` 。
- 已杀掉旧代理进程并用修复后二进制重启于 `:8765` (后台任务 DxiPvF)。提示用户:Docker 部署改 Go 后仍需 `docker compose up -d --build` 。
- **修复:飞牛登录页后台请求报 `errno:65534 errmsg:'验签失败'` ( E_REQ_SIGN)导致反复 `location.reload()` 登录死循环**。
- 取证:从 fnOS 主 JS bundle( `/assets/index-*.js` , 2.8MB)确认 `65534` =`E_REQ_SIGN` ,属**逐请求签名校验**;客户端收到 `result:'fail',code:65534` 时执行 `location.reload()` (这正是用户看到的"一直 401→登录页→重连"循环)。`/app/token` 在未登录时返回 `401 invalid token` 本身是"未登录"正常响应,不是根因。
- 客户端鉴权头构造:`Authorization: \` trim ${token}\``(模板字符串)——未登录时 token 为 undefined,于是发出 ` Authorization: trim undefined`(无害,仅说明未登录)。fnOS 真正拒绝的是**请求签名**校验。
- 真因(高概率):fnOS 在逐请求签名校验时按**源站(Origin/Host/Referer)绑定**校验;浏览器经子域名反代后,发出的 `Origin` /`Referer` 是代理子域名(`687474...localhost:8765` ),飞牛收到的是自身源(`192.168.0.107:5666` ),源不一致 → 验签失败。WS 通道此前已把 Origin 改写为上游(生效),但普通 HTTP 请求未改写。
- 修复:`doProxy` 在转发普通 HTTP 请求前,把 `Origin` /`Referer` 头部**改写为上游自身源**( `rewriteOriginInURL` 仅替换源站部分、保留 path/query),与 WS 通道的 Origin 改写保持一致。浏览器侧同源判断不受影响(它看到的是子域名文档源,仍按同源处理,不会触发 CORS 预检)。
- 新增**调试日志**(非侵入,默认关闭):环境变量 `WEBPROXY_DEBUG=1` 开启;可选 `WEBPROXY_DEBUG_FILE=路径` 落盘。记录每个代理请求的 `[REQ][REQ.h][OUT.h][RESP][RESP.body]` (仅对 ≥400 且非 html/css 的响应读 body 避免消费流),便于定位仍报错的真实请求。
- 验证:`--noproxy` 直连代理子域名,debug 日志确认 `[REQ.h] Origin=子域名` → `[OUT.h] Origin=192.168.0.107:5666` (改写已生效);资源/HTML 仍 200+正确 MIME。
- 当前状态:修复后二进制已带调试日志重启于 `:8765` (后台任务 4mSMjT,debug.log 落盘于项目目录)。请用户在浏览器重新登录验证;若仍报 `验签失败` ,把 Network 面板里失败请求的 curl 或贴出 debug.log,即可定位是否还有别的签名因子(如签名含 host 而非仅 Origin)。
- 约束:本环境走 `--noproxy` 才通;浏览器直连 localhost:8765 不经过沙箱 HTTP_PROXY(127.0.0.1:7890),不受影响。Docker 部署改 Go 后仍需 `docker compose up -d --build` 。
## fnOS 登录态真正根因(19:50 定案,debug.log 实锤)
- debug.log 显示:`POST /app/ticket → 200` (登录成功,fnOS 下发 `ost=...; Path=/; HttpOnly; SameSite=Lax` , **无 Domain 属性**),但之后浏览器所有请求 `Cookie=""` → `/app/token` 仍 401 → E_REQ_SIGN(65534) 验签失败连环 reload。
- 根因:页面是 `localhost:8765` 顶层 + `<hex>.localhost` iframe, Chrome 判定**跨站(第三方)上下文**(日志中 Sec-Fetch-Site: cross-site),SameSite=Lax Cookie 在跨站 iframe 的 fetch/XHR/WS 里被浏览器扣发。改 Set-Cookie 属性绕不开 Chrome 155 第三方 Cookie 策略。
- 修复(proxy.go):会话 Cookie 改回**服务端全局 jar**( `jarFor(origin)` , sync.Map 按 origin 存,多目标互不干扰);响应不再下发 Set-Cookie;`proxyWebSocket` 在服务端把 jar 里同一份 Cookie 注入 WS 握手。之前的"Go cookiejar 拒 IP Cookie"结论有误——host-only(无 Domain) Cookie 对 IP 主机存储正常,当时探测用的是非法的 Domain=IP。
- 回归(tests/cookietest/):mock 改为 host-only+SameSite=Lax;① login 200 且 Set-Cookie 不下发浏览器 ② 浏览器零 Cookie 下 /app/token→200( jar 注入)③ WS 握手 echo cookie=SECRET。真实 fnOS 冒烟 GET / 200。
- 运维注意:jar 在内存里,代理重启需重新登录 fnOS。WS 截图答疑:两条 websocket?type=main(一条 101 健康+一条旧连接/重连),非代理复制连接。
## runoob 公网站点"第三方直连"定性(20:02)
- 用户访问 runoob(子域名反代 68747470733a2f2f7777772e72756e6f6f622e636f6d.localhost:8765),抓包见大量直连外站请求(gtag/hm.baidu/doubleclick ads/recaptcha/adtrafficquality)。用户问"是不是新情况"。
- 结论:**不是 bug/不是回归**。debug.log 证实:① runoob 主页及静态资源 200;② 不少第三方 SDK 调用(如 ep1.adtrafficquality.google/getconfig/sodar,走 fetch/XHR)已被 JS 桩捕获经 /p/ 代理 200;③ 代理全程零 SSRF/502/403。直连外站的仅是运行时由第三方脚本 `createElement('script'/'iframe').src` /`new Image().src` 注入的资源,JS 桩只 hook fetch/XHR/WS/open/form,拦不到这类,故浏览器直连真实域名。这是内容改写型代理固有行为。对"访问内网站点"的核心目标无影响(内网站点无此类跟踪器)。唯一代价:第三方跟踪器看到真实 IP 与代理页 URL(隐私)。
- 已将此定性写入 MEMORY.md「URL 拦截范围与第三方直连」条目。若要全封装需 Service Worker 网络层拦截,属较大改动,当前目标下非必需。
## 开源化准备(发布到 git 前)
- 创建 `.gitignore` :排除 debug.log/chrome_err*.log、*.exe 二进制、调试散文件(dom*.html/doc*.html/rewritten*.html/bsz.js/js_via_proxy.js 等)、本地 config.json。从暂存区撤出此前误暂存的垃圾/敏感文件(debug.log 含内网 IP 192.168.0.107;此前全是 A 状态、尚未 commit)。
- 新增 `config.example.json` ( ssrf.mode=blacklist 安全默认),取代原 `config.json` (mode=off)——避免开源示例把 SSRF 防护关掉。
- 新增 LICENSE( MIT)、根 SECURITY.md( GitHub 安全页引用)、CONTRIBUTING.md、CHANGELOG.md、Makefile、.github/workflows/ci.yml( gofmt/vet/build/test)。
- 新增 `proxy_test.go` 单元测试(URL base64url 编解码、子域名反代解析、SSRF IP 分类、Origin 改写、truncate),`go test ./...` 通过;`tests/cookietest/{mock,wsclient}.go` 加 `//go:build cookietest` 标签避免与 `go test ./...` 冲突。
- README 加徽章、§11 测试章节、License 章节、文档导航补 CONTRIBUTING/CHANGELOG/根SECURITY; tests/README.md 补 cookietest 带 tag 构建说明。
- 待办(依赖用户):把 `go.mod` 的 `module webproxy` 改成规范路径 `github.com/<用户名>/webproxy` (仅改一行,无内部子包依赖);README 徽章里的 YOUR_USERNAME 同步替换。
- 状态:105 文件已暂存(未 commit),gofmt/vet/build/test 全绿,垃圾/敏感项确认被忽略。
## 开源化收尾 + 全量注释补齐(当日续)
- 用户确认 GitHub 用户名:`yexuejc` 。go.mod 的 `module webproxy` → `module github.com/yexuejc/webproxy` (仅改一行,无内部子包依赖);README 徽章、CONTRIBUTING clone 地址中的 YOUR_USERNAME 全部替换为 yexuejc; README 删掉"发布前替换用户名"提示行。
- 按用户要求补齐全量中文注释(函数作用/场景/入参/出参 + 分支说明 + 变量说明):session.go、ssrf.go、main.go、rewriter.go、proxy.go、proxy_test.go、tests/cjprobe/main.go、tests/cookietest/{mock.go,wsclient}。proxy.go 里旧方案死代码 rewriteSetCookie/stripDomainSecure/reCookie* 保留但注释标明"已弃用(2026-10-20 起改服务端 jar),可连同正则一起删除"。
- 顺手修了两个构建问题:① 我写 cjprobe 注释版时漏了 httptest.NewServer 的一个右括号(`}))` →`})` ,已修);② cookietest 下 mock.go 与 wsclient.go 同 package main 双 main,加 `-tags cookietest` 整包编译即冲突(历史遗留地雷)——把 wsclient.go 移到 `tests/cookietest/wsclient/main.go` 独立子包,tests/README.md 与文件头用法同步更新。修后 `go build -tags cookietest ./tests/...` 全过。
- 终态校验全绿:gofmt(含 -w 修 proxy_test/mock 的对齐)、go vet ./...、go build ./...、go test ./...、cjprobe 实跑(login 200 / app/token 401,按设计复现 Domain=IP Cookie 被拒)。105 文件已暂存,等用户 commit & push。
## 删除 proxy.go 已弃用 Cookie 死代码(当日续)
- 用户拍板删掉旧"浏览器持有 Cookie"方案残留:`rewriteSetCookie` / `stripDomainSecure` 两个函数 + `reCookieDomain` / `reCookieSecure` 两个正则(proxy.go 613– 671 行,约 60 行)+ import 中的 `regexp` 。该方案 2026-10-20 已被服务端 jar 取代,注释里早已标明"可连同正则一起删除"。
- 删除前已 grep 全仓确认零引用;删除后全量校验全绿:gofmt / go vet ./... / go build ./... / go test ./...( ok 1.646s) / go build -tags cookietest ./tests/... / mock、wsclient、cjprobe 单编全过。proxy.go 746→685 行。
- 中间有个小插曲:一次性跑满 7 步校验时第 6 步偶发 SIGTERM(go test 缓存进程干扰),单独重跑即过,非代码问题。
- 删死代码后用新二进制重启(PID 29620,:8765 监听,debug 落盘),冒烟验证:/p/ 代理 runoob 首页 200( 526KB),debug.log 请求闭环正常;用户实测确认无问题。jar 在内存,重启后 fnOS 需重登一次。
- 已提交(未 push,等用户操作):root commit a9ebb5e, 105 files / 178210 insertions,工作区干净。
## git push 代理故障排除(22:0x 续)
- 用户 `git push github` 报 `fatal: unable to access 'https://github.com/yexuejc/webproxy/': Failed to connect to 127.0.0.1 port 7890` 。
- 根因:git **全局配置**残留 `http.https://github.com.proxy = http://127.0.0.1:7890`(指向常不开的本地代理客户端);端口 7890 与报错完全一致。另,当前 shell 还有 `https_proxy/http_proxy=http://127.0.0.1:2683` 等**死代理环境变量 ** (不同端口),git 会回退读取。
- 处理(仅动 git 全局配置,**未碰任何项目文件、未改 remote**,符合用户"和项目没关系"的定性):`git config --global --unset http.https://github.com.proxy` ;复查 `git config --show-scope --get-regexp proxy` 为空(git 配置已无任何 proxy)。
- 验证:`unset https_proxy HTTPS_PROXY http_proxy HTTP_PROXY all_proxy` 清掉会话内 env 后,`git push --dry-run github HEAD:master` 成功到达 GitHub( `[new branch] HEAD -> master` , exit 0),证明直连通路通畅。
- 提醒用户:其自身终端仍有死代理 env(7890/2683),推送前需先 `unset https_proxy HTTPS_PROXY http_proxy HTTP_PROXY` 再 `git push github master` ,否则回退到 env 代理仍失败;若要永久生效,去 `~/.bashrc` /`~/.zshrc` 删 `export https_proxy=...` 那行。
- remote 现状核实:`github` = `https://github.com/yexuejc/webproxy` ( HTTPS,正确);`origin` = 内网 Gitea 192.168.0.107:3001。此前那次 SSH over 443 改动经实测未真正落地,当前即是正确状态,无需回退。
- 教训(同时记入个人记忆):push 失败先去代理,不要擅自改 remote 通道绕行;该代理属用户全局环境项,与本项目无关。