Repository navigation
feat(driver): add CtFile (城通网盘) storage driver - #123
Conversation
基于城通网盘官方 OpenAPI (https://openapi.ctfile.com/, rest.ctfile.com/v1) 实现存储驱动,响应 OpenList#1217 的城通网盘接入需求: - 支持公有云/私有云挂载(public/private 命名空间) - 目录浏览(folder/list + file/list 自动翻页与防死循环保护) - 下载直链(file/fetch_url;非 VIP 限速取决于账号等级) - 建目录、重命名(文件/文件夹)、删除(入回收站)、移动 - 上传(file/upload 预签名地址 + multipart 直传,md5-size 校验和可秒传) - Session 失效(401)转换为「开放接口登录密钥管理」重新生成的明确提示 - folder_id / file_id 前缀(d/f)在文档与社区实现间要求不一致, 调用层内置 raw/stripped 双形态自动回退;批量 ids 内置字符串/数组双形态回退 - /task/refresh 定时巡检复用 checkCookieValid,Session 过期在后台标记 - 驱动别名:ctfile / ctfilepan / 400gb / 城通网盘 说明:城通网盘已关闭服务器端密码登录(/v1/user/auth/login 恒返回 410, 网页密码登录要求扫码验证),因此驱动仅支持开放接口 Session 方式。 验证: - tsc --strict 全量类型检查通过(ctfile 目录及其依赖图) - node:test 单测 10/10 通过(鉴权、ID 形态回退、翻页、秒传校验和等) - 对 rest.ctfile.com 真实 API 冒烟:未配置/失效 Session 均返回可操作提示 - prettier 格式检查通过 Co-Authored-By: MiMo (OpenCode) <noreply@opencode.ai>
补充:Session 获取入口实测与免费账号可用性调研PR 描述里只写了 Session 来自「开放接口登录密钥管理」,这里补充确切入口、实测约束和一条免费账号的替代方案(均为 2026-10 实测,中国大陆移动网络出口、非代理)。 一、官方入口的确切位置
二、程序化获取 Session 的各条路径实测(均已不可用)
补充参考:2025-08 的社区文章(博客园《城通网盘API的链接研究》)与社区 Go 实现 Icy2010/ctFile 的 三、免费账号的替代方案(浏览器会话复用,待更多验证)网页端与 v1 API 同属
四、免费账号已知限制(账号侧,非驱动可控)
如果后续确认网页端 session 不被 v1 接受、且密钥页确实锁定会员,剩余路径只有官方 App 登录签名逆向或开通会员,届时再在本 PR 同步结论。 |
pikachuren
left a comment
There was a problem hiding this comment.
🙏 感谢 @wumingzhinu 提交!
🤖 AI 自动审核声明:本评审报告由 AI 自动生成,当前使用 Claude Sonnet 5 模型进行分析。
🎯 结论
✅ Approve — 功能完整、设计合理、测试覆盖到位,CI 全绿,符合生产合并标准
📖 概要
feat(driver): add CtFile (城通网盘) storage driver · 关联 #1217 · 基于官方 OpenAPI (openapi.ctfile.com) 新增 CtFile 存储驱动
核心改动:新增 drivers/ctfile/{driver,util,types,util.test}.ts(1101 行),集成到 op/storage.ts、admin.ts、task.ts,补充 README 驱动列表
🧭 整体方案
基于城通网盘官方 OpenAPI v1(rest.ctfile.com/v1,统一 POST JSON + Session 鉴权),纯 Web API 实现(无 Node 独占模块,兼容 Workers / Vercel / Node),支持公有云/私有云挂载、目录浏览(自动翻页+防死循环)、下载直链、建目录/重命名/删除/移动、上传(md5-size 秒传+multipart 直传)、Session 失效自动提示(401→可操作引导)。技术路线清晰,API 封装与故障回退(ID 前缀 raw/stripped、ids 字符串/数组、翻页终止)处理完备。
📊 变更统计
8 个文件(+1239 / -3 行) | 功能 ⭐⭐⭐⭐⭐ | 最小改动 ⭐⭐⭐⭐ | 前向兼容 ⭐⭐⭐⭐⭐ | 方案设计 ⭐⭐⭐⭐⭐
🚨 关键问题
无重大问题(P0/P1 均不存在)
P2(可选优化):
- 💡
util.ts:28MAX_LIST_PAGES = 500按 500 页 × 单页默认 100 条 = 最多支持 5 万文件,超限时静默截断 → 建议日志记录或给出"文件过多,可能未列全"提示 - 💡
driver.ts:289move()声明接收_names: string[]但未使用(直接移整个srcPhysical条目),与其他驱动的批量移动语义不同 → 可在注释标注"本驱动暂不支持批量移动,仅移动单个条目"避免误用 - 💡
admin.ts:2007新增驱动配置中user_agent默认值是写死的 Chrome 142 UA,若需在现代浏览器安全策略下假装"最新版 Chrome"可能需定期更新 UA 版本号 → 可文档注明或改用生成逻辑(当前写死 142.0.0.0 可短期使用)
📂 逐文件分析
drivers/ctfile/util.ts(API 客户端核心,474 行)
改动意图:封装城通网盘 v1 API 调用层,处理 Session 鉴权、401 自动转化、网络重试、ID 形态双向回退(raw/stripped)、翻页防死循环
代码逻辑:三层架构清晰 —— post() 处理传输层(网络重试、429/5xx、401 直接抛)+ call() 处理业务层(code !== 200 抛错)+ callWithId/callWithIds() 处理 ID 形态回退(400/404 时自动换形态重试)
实现质量:✅ 无注入风险(全 JSON POST);✅ 网络故障 300ms×retry 退避;✅ 401 统一转 SESSION_EXPIRED_MSG 可操作提示;✅ listFiles() 双重终止条件(空页 + 重复首项)防死循环,MAX_LIST_PAGES 兜底保护;✅ uploadTicket() 生成 md5-size 校验和触发秒传
drivers/ctfile/driver.ts(驱动主实现,327 行)
改动意图:实现 StorageDriver 接口,封装路径解析、缓存、文件夹/文件操作(list/get/mkdir/rename/remove/move/put)
代码逻辑:resolveFolderKey() 逐级递归解析路径(名称或ID匹配,写缓存);resolveEntry() 先找文件夹再找文件;list() 合并文件夹+文件并按配置排序;get() 调用 fetchDownloadUrl 并附 UA 头;put() 先 uploadTicket 判秒传,未秒传再 upload()
实现质量:✅ init() 启动即校验 Session(await this.client.profile());✅ checkCookieValid() 对接 /task/refresh 巡检;✅ pathKeyCache 缓存减少重复解析,文件夹改名/移动后 clear() 保持一致性;✅ 上传双重判断避免不必要的大文件传输;copy() 直接抛异常说明不支持(符合城通 API 约束)
drivers/ctfile/util.test.ts(单元测试,228 行)
改动意图:覆盖关键边界:Session 缺失提示、401 转失效提示、ID 形态回退(folder/meta、fetch_url)、翻页终止(空页+重复首项)、ids 形态回退(字符串/数组)、private 命名空间、md5 校验和、默认值归一化
实现质量:✅ 用 stubFetch 脚本化 mock,捕获请求体断言;✅ 10 个测试覆盖核心分支;✅ 按官方文档/社区实现双重验证 ID 前缀处理;✅ 防死循环场景实测(服务端忽略 start 时检测重复首项)
遗漏:无端到端测试(列表/下载/上传/移动真实账号验证)—— PR 描述已标注"提交人可在合并前用自有账号验证",合理
op/storage.ts、admin.ts、task.ts(集成点)
改动意图:注册驱动别名(ctfile / ctfilepan / 400gb / 城通网盘)、添加表单元数据(session / cloud_type / base_url / order_by / order_direction / user_agent)、扩展 /task/refresh 巡检正则(/(lanzou|ctfile|400gb)/i)
实现质量:✅ normalizeDriver() 支持中文别名(提前检测 includes("城通")),避免归一化丢失;✅ driverConfigs 字段齐全(required / help / default),新手可用;✅ task.ts 巡检扩展无侵入
兼容性:✅ 仅新增配置项,不影响既有存储
README.md
改动意图:「国内网盘」列表补充"城通网盘"
实现质量:✅ 位置合理(蓝奏云后)
types.ts(类型定义,131 行)
改动意图:TypeScript 类型映射官方 API 响应结构(CtFileProfile / CtFileFolder / CtFileFile / CtFileUploadTicket 等)
实现质量:✅ 字段覆盖完整(含可选字段,适配官方文档与社区实现差异);✅ CtFileAddition 支持 cloud_type: "public" | "private" 多实例
🔐 依赖安全审查
不适用 — 本 PR 无依赖声明变更,仅新增业务代码
✅ 补充亮点(评审中发现)
- ID 形态自适应回退:官方文档与社区实现对
folder_id/file_id是否携带d/f前缀的要求不一致,callWithId()内置prefer: "raw" | "stripped"策略,失败自动换形态重试,完美解决接口不统一问题 - 翻页防死循环设计:
listFiles()检测「空页」与「重复首项」双重终止,防服务端异常导致无限循环,辅以MAX_LIST_PAGES兜底 - Session 失效统一提示:401 直接转换为含"开放接口登录密钥管理"操作路径的错误,用户可按提示自助修复,体验比裸 401 好
- 秒传优化:
uploadTicket()计算md5-size校验和,put()检测ticket.exists > 0直接跳过真正上传,节省带宽 - PR 描述与补充 comment 质量极高:完整 commit 归属(
Co-Authored-By: MiMo)、已知限制明确、补充 comment 做了 Session 获取入口的完整实测调研(含免费账号替代方案),可直接作为驱动文档素材
✅ 待处理清单
- [P2]
util.ts:28MAX_LIST_PAGES 超限时补日志或提示 - [P2]
driver.ts:289move() 注释标注"暂不支持批量移动" - [P2]
admin.ts:2007user_agent 默认值版本号策略(文档注明或生成逻辑)
🎯 结论:✅ Approve — 功能完整、防御式编程到位、测试覆盖合理、注释充分、实测调研翔实,完全达到生产合并标准。3 条 P2 可选优化,不阻塞合并。
feat(driver): add CtFile (城通网盘) storage driver
Summary / 摘要
基于城通网盘官方 OpenAPI(openapi.ctfile.com,
rest.ctfile.com/v1)新增CtFile存储驱动,响应 OpenList#1217 的接入需求。功能覆盖
cloud_type: public / private)folder/list+file/list,自动翻页 + 防死循环保护)file/fetch_url;非 VIP 限速取决于账号等级)file/upload预签名地址 + multipart 直传,md5-大小校验和,支持秒传命中跳过/task/refresh定时巡检复用checkCookieValid,Session 过期在管理后台标记cookie_expiredctfile/ctfilepan/400gb/城通网盘实现要点
folder_id/file_id是否携带d/f前缀的要求在官方文档与社区实现间不一致,调用层内置 raw / stripped 双形态自动回退;批量ids内置字符串 / 数组双形态回退file/list翻页以空页与重复首项双重终止,防服务端异常导致死循环fetch+FormData),无 Node 独占模块,兼容 Workers / Vercel / Node 容器变更文件
src/backend/drivers/ctfile/{types,util,driver,util.test}.tsinternal/op/storage.ts:驱动实例化分支server/admin.ts:驱动表单元数据 +normalizeDriver别名(含中文名)server/task.ts:巡检扩展/(lanzou|ctfile|400gb)/iREADME.md:国内网盘列表补充已知限制
城通网盘已关闭服务器端密码登录(
/v1/user/auth/login恒返回 410,网页密码登录要求扫码),驱动仅支持开放接口 Session(管理后台「开放接口登录密钥管理」生成)非 VIP 账号下载直链受官方限速(约 30KB/s),属账号侧限制
This PR has breaking changes. / 此 PR 包含破坏性变更。
This PR changes public API, config, storage format, or migration behavior. / 此 PR 修改了公开 API、配置、存储格式或迁移行为。
(新增驱动配置项:
session/cloud_type/base_url/order_by/order_direction/user_agent,均为新增,不影响既有存储)This PR requires corresponding changes in related repositories. / 此 PR 需要关联仓库同步修改。
Related repository PRs / 关联仓库 PR :
Related Issues / 关联 Issue
Relates to OpenListTeam/OpenList#1217
Testing / 测试
tsc --strict类型检查(ctfile 驱动目录及其依赖图全量通过)tsx --test src/backend/drivers/ctfile/util.test.ts— 10/10 通过:鉴权缺失提示、401→Session 失效、ID 前缀回退(folder/meta、fetch_url)、
翻页终止、防死循环、ids 形态回退、private 命名空间、md5 校验和、默认值归一化
rest.ctfile.comAPI 冒烟:未配置 / 失效 Session 均返回可操作错误提示prettier --check格式检查通过Checklist / 检查清单
prettier. / 我已使用 prettier 格式化变更代码。AI Disclosure / AI 使用声明
Tools used / 使用工具:
Usage scope / 使用范围:
Code generation / 代码生成
Tests / 测试
Documentation / 文档
I have reviewed and validated all AI-assisted content included in this PR. / 我已审核并验证此 PR 中的所有 AI 辅助内容。
I have ensured that all AI-assisted commits include
Co-Authored-Byattribution. / 我已确保所有 AI 辅助提交都包含Co-Authored-By归属信息。(commit 已带Co-Authored-By: MiMo (OpenCode) <noreply@opencode.ai>)I can reproduce all AI-assisted content included in this PR without any AI tools. / 我可以在没有任何 AI 工具的情况下重现此 PR 中包含的所有 AI 辅助内容。(请提交人确认后勾选)