对话笔记直发:7.23 白嫖云盘cftc,tgState,tgNetDisc。分类:网络基建。

三个项目的源码级分析与对比

分析时间:2026-07-22
核查的是三个仓库默认分支当前版本:

我不仅看了 README,也检查了核心源码、部署文件、GitHub Actions、提交历史、开放 Issue,并做了基础构建验证。


一、先说结论

这三个项目实际上可以分为两类:

1. tgState 与 tgNetDisc:同一套核心程序

tgNetDisc 不是另一套独立架构,而是基于 tgState 修改、重新包装后的版本。

tgNetDisc 的 README 也明确写了原项目来自 tgState:

我对两个项目默认分支的全部 Go 源码做了字符级比对,相似度约 97%。两者的:

  • 上传接口
  • Telegram 存储方式
  • /d/<file_id> 下载协议
  • 大文件分片格式
  • Web 页面结构
  • 密码中间件
  • Telegram Bot 的 get 处理

基本都来自同一套代码。

它们的区别主要是:

  • tgNetDisc 的 Docker 打包更方便
  • 环境变量名称不同
  • 分片大小从 10 MiB 改成 20 MiB
  • UI 和域名/子路径适配做了少量调整
  • 多架构镜像支持更丰富

因此,这两个项目之间的选择,本质上是:

选原版、许可证更清晰的 tgState,还是选部署体验更好的 tgNetDisc。


2. cftc:完全不同的 Cloudflare 文件管理平台

cftc 不是简单的 Telegram 外链代理,而是一套:

  • Cloudflare Workers/Pages 运行时
  • D1 元数据数据库
  • R2 或 Telegram 双存储
  • Web 管理后台
  • Telegram Bot 菜单
  • 分类、搜索、删除、重命名
  • 自定义直链

组成的文件管理系统。

功能明显比前两个多,但代码复杂度、安全风险、状态管理成本也高很多。


二、核心架构差异

tgState / tgNetDisc 的数据流

浏览器 / API
      │
      ▼
Go 服务
      │ sendDocument
      ▼
Telegram Bot API
      │
      ▼
频道 / 群组 / 私聊
      │
      └── 返回 Telegram file_id
                 │
                 ▼
          /d/<file_id> 外链

下载时:

用户访问 /d/<file_id>
        │
        ▼
Go 服务调用 getFile
        │
        ▼
Telegram CDN 临时地址
        │
        ▼
Go 服务代理数据给用户

特点:

  • 不需要数据库
  • 文件链接中直接携带 Telegram file_id
  • 服务本身几乎无状态
  • Telegram 频道可充当人工文件列表
  • 所有下载流量都经过自己的 Go 服务

大文件上传时,由浏览器切成多个小文件,最后再上传一个 fileAll.txt 清单:

tgstate-blob
原始文件名
size原始大小
分片1的 file_id
分片2的 file_id
……

下载服务发现这个标记后,再依次从 Telegram 拉取各分片并拼接返回。


cftc 的数据流

浏览器上传 ───────────────┐
                         │
Telegram Webhook ────────┤
                         ▼
                Cloudflare Worker
                   │           │
                   │           ├── D1:文件元数据、分类、用户设置
                   │
                   ├── R2:对象存储
                   │
                   └── Telegram:频道/群组存储

访问文件时:

用户访问 /自定义文件名.ext
        │
        ▼
Worker 查询 R2 或 D1
        │
        ├── R2 对象
        └── Telegram file_id → Telegram CDN

它比前两个项目多了一层关键状态:

D1 数据库是 cftc 的核心资产。

如果 D1 丢失,即使 Telegram 或 R2 中的文件仍在,自定义链接、分类和后台文件记录也可能全部失效。


三、功能对比表

对比项tgStatetgNetDisccftc
项目定位极简 Telegram 外链/网盘tgState 的部署增强版Cloudflare 图床和文件管理平台
语言GoGoJavaScript
运行环境VPS、Docker、VercelVPS、Docker、VercelCloudflare Workers/Pages
文件存储TelegramTelegramTelegram 或 R2
元数据数据库无无D1,必需
Web 上传支持支持支持
上传 API/api,较明确/api,较明确有上传端点,但不是稳定、正式文档化 API
Telegram 上传发文件后回复 get发文件后回复 get完整 Bot 菜单和 Webhook
Bot 管理面板无无有
文件列表无,依赖 Telegram 历史无,依赖 Telegram 历史有
分类管理无无有
搜索无无有
批量删除无无有
自定义链接不支持,使用 file_id不支持,使用 file_id支持自定义路径名
大文件分片浏览器端 10 MiB 分片浏览器端 20 MiB 分片不支持分片
默认单文件限制网页分片绕过网页分片绕过默认 20 MiB,可配置
R2/CDN无无支持
下载 Range/断点续传不支持不支持实现中也没有完整支持
文件访问密码/d/ 文件链接仍是公开的/d/ 文件链接仍是公开的文件链接仍是公开的
部署难度中最低中到高
多架构镜像主要 amd64/arm648 种 Linux 架构无此问题
许可证MITCC0,但有继承 MIT 的疑问MIT
维护成熟度三者中最高,但已停滞中等,核心跟随 tgState最年轻、功能多但代码最脆弱

四、逐个项目分析

1. tgState

项目定位

tgState 是这条技术路线的原始项目,目标很明确:

用 Telegram Bot API 存储文件,用自己的域名提供外链。

它采用一个小型 Go 服务,没有数据库,没有复杂管理后台。

核心路由只有:

  • /:上传页面
  • /api:上传 API
  • /pwd:密码页面
  • /d/<file_id>:文件访问

核心代码可以看:

优点

1. 架构非常简单

不需要:

  • MySQL
  • SQLite
  • Redis
  • 本地数据目录
  • 定期备份应用状态

只要保留:

  • Bot Token
  • Telegram 频道/群组
  • 域名

就能恢复服务。

2. 迁移成本低

由于链接直接保存 Telegram file_id,迁移服务器时不需要搬数据库。

只要:

  • 继续使用同一个 Bot
  • 保持原域名或配置反向代理
  • /d/ 路由保持一致

原有链接大概率可以继续使用。

3. 原文件通常按 Document 上传

Web 上传统一使用 sendDocument,相比 Telegram 的 sendPhoto,更容易保持原始文件内容,不会主动压缩图片。

4. 社区数据最好

截至本次检查:

  • Star:约 1045
  • Fork:约 182
  • 最新 release:v1.4.1
  • 许可证:MIT

在三个项目中,它的用户基础最大。

缺点

1. 没有真正的文件管理后台

系统本身不保存:

  • 文件名
  • 上传时间
  • 分类
  • 所属用户
  • 删除状态

一旦丢失链接,只能回到 Telegram 频道或聊天记录中寻找文件,再回复 get 获取链接。

2. 下载服务实现不够稳健

下载处理存在几个明显问题:

  • 先按 Content-Length 分配整个文件大小的内存
  • 对普通文件执行一次 Read 后再继续复制
  • 对不足 12 字节的文件直接执行 buffer[:12],可能触发 panic
  • 不支持 HTTP Range
  • 没有整体请求超时
  • 分片获取失败时可能无限重试
  • 只接受 Telegram 返回的 application/octet-stream

相关实现见:

这会导致:

  • 视频不能正常拖动进度
  • 断点续传体验差
  • 大文件占用较多 VPS 内存和带宽
  • 部分 MP3、MP4、图片类型可能返回 404
  • 异常分片可能长期占用连接

开放 Issue 中也能看到“较多 500”“大文件下载”等类似反馈。

3. 密码认证比较薄弱

密码只是保护上传页面和上传接口,不保护 /d/ 文件链接。

另外:

  • Cookie 中直接保存明文密码
  • Cookie 没有 HttpOnly、Secure、SameSite
  • 没有会话签名
  • 没有 CSRF 保护
  • 没有内置限流
  • 密码页面使用普通文本输入框

更重要的是,/api?pass=密码 的逻辑有明显错误:

if strings.HasPrefix(r.URL.Path, "/api") &&
   r.URL.Query().Get("pass") == conf.Pass {
    return
}

密码正确时直接 return,没有调用实际上传处理函数,因此会返回一个空响应。

4. Telegram Bot 功能很少

Bot 只是监听长轮询,并识别回复消息中的 get。

支持识别的类型主要是:

  • Document
  • Video
  • Sticker

对普通 Telegram Photo、Audio 的处理并不完整。

5. 构建链已经很旧

go.mod 声明 Go 1.20,但 release 工作流中实际设置的是 Go 1.17.2,然后临时修改 go.mod:

Go 1.17 和 1.20 现在都已经不适合作为新生产构建基线,应当重新使用受支持版本构建。


2. tgNetDisc

项目定位

tgNetDisc 可以理解为:

tgState 核心代码 + 更方便的 Docke



相关: 00-索引-AI工程索引 N8N_DAILY_DIGEST_EXECUTION_SPEC_CN