# data_send_service 基于 Go 标准库的轻量文件传输服务,仅认领运行目录下的 `share/` 文件夹及其所有子文件夹,零第三方依赖。 所有接口均为 **GET**,URL 中只传一个加密的 `key`,不暴露任何文件路径,且 key 由 base64url 字符(`A-Za-z0-9-_`)构成,**链接永远不需要做 URL 转义**,方便一键分享。 ## 运行 ```bash go run . # 默认监听 :8080 go run . -addr :9000 # 自定义端口 go run . -root D:/path/to/share # 自定义共享目录 go run . -secret ./my.key # 自定义密钥文件位置 ``` 启动时若 `share/` 不存在会自动创建;密钥文件 `.secret.key` 不存在时会自动生成随机 AES-256 密钥。 ## 分享 key 机制 - 每个文件/目录的相对路径经 **AES-256-GCM** 加密后生成 key,后端收到后解密回路径。 - GCM 自带完整性校验:key 被篡改或不是本服务签发的,一律拒绝。 - 随机 nonce:同一文件每次列目录得到的 key 字面不同,但全部有效。 - 密钥持久化在服务端 `.secret.key`(已加入 .gitignore),**密钥不变则所有历史链接永久有效,服务重启不影响**;删除或更换该文件,旧链接立即全部失效(等价于全局吊销)。 - key 只解决“定位文件”,下载时的文件名仍取自真实文件。 ## API ### 1. GET /api/get_dict_detail 获取目录下的文件和子目录列表。不传 `key` 表示根目录;进入子目录时传该目录条目的 `key`。若目录下存在 `reademe.md`(兼容 `readme.md`,大小写不敏感),其内容会放入 `readme` 字段。 ``` GET /api/get_dict_detail GET /api/get_dict_detail?key=<目录key> ``` 响应: ```json { "key": "", "name": "share", "readme": "# 共享根目录\n……", "entries": [ { "name": "文档资料", "key": "KrL-2DN0fcoyrWQM4taObwQjXOWDx4S724XQIQQfBR_Nan8H0qCQ1A", "type": "dir", "size": 0, "mod_time": "2026-10-10T18:39:16Z" } ] } ``` `type` 为 `file` 或 `dir`;目录在前、文件在后,各自按名称排序。 ### 2. GET /api/download 下载单个文件,支持 Range/断点续传: ``` GET /api/download?key=<文件key> ``` 不支持下载目录。 ### 3. GET /api/preview - **文本/代码类**(txt、md、json、go、py、js、yml 等,统一以 `text/plain; charset=utf-8` 返回,防止同源 XSS):大小上限 10 MiB。 - **浏览器原生支持的类型**(png、jpg、gif、webp、svg、pdf 等):返回对应 MIME,可直接内联展示。 - 其他类型返回 `415`,提示走下载。 ``` GET /api/preview?key=<文件key> ``` ## 安全说明 - 路径经 key 加密对外不可见;解密后仍会做路径清洗和符号链接解析,拒绝 `..` 穿越、绝对路径,任何请求都无法逃逸出 `share/`。 - HTML/SVG 等预览强制按纯文本返回,避免在服务同源下执行脚本。 - `.secret.key` 是安全核心:持有它即可伪造任意文件链接,勿提交到代码仓库或外泄。 - 错误统一返回 `{"code": , "message": "..."}`,不泄露解密细节。