主题
文件系统 API
本文引用的源码文件
本文引用的文件
目录
简介
本文件是 Agent 本地代理中文件系统相关 HTTP API 的完整参考文档。Agent 作为独立 Node.js 进程,通过本地 HTTP 接口为 Chrome 扩展侧提供文件读取、写入、上传、下载、目录列表、删除到回收站、从回收站恢复等能力。所有路径访问均经过白名单与硬阻止清单校验;二进制内容支持 base64 传输;大文件优先使用流式处理以避免内存膨胀。
项目结构
文件系统 API 主要实现于 Agent 服务端入口文件中,安全校验逻辑位于独立的安全模块,回收站逻辑位于独立的回收站模块;扩展侧 side panel 通过工作区管理器封装部分调用。
graph TB Client["浏览器/扩展前端"] --> Server["Agent 服务器<br/>agent/src/server.js"] Server --> Security["路径安全检查<br/>agent/src/security.js"] Server --> Trash["回收站模块<br/>agent/src/trash.js"] Client --> WorkspaceManager["工作区管理器<br/>src/side_panel/workspace-manager.js"] WorkspaceManager --> Server
图表来源
- agent/src/server.js#L752-L862
- agent/src/security.js#L109-L229
- agent/src/trash.js#L141-L250
- src/side_panel/workspace-manager.js#L352-L370
章节来源
- agent/src/server.js#L132-L136
- agent/src/server.js#L752-L862
- agent/src/security.js#L109-L229
- agent/src/trash.js#L141-L250
- src/side_panel/workspace-manager.js#L352-L370
核心组件
- Agent 服务器:统一路由分发、请求体解析、JSON 响应封装、日志记录、MIME 类型检测、ZIP 打包、流式读写。
- 路径安全检查:基于
allowedPaths白名单、系统工作目录默认值、符号链接规范化、硬阻止敏感路径。 - 回收站模块:将删除目标移动到用户主目录下的回收站目录,支持跨设备移动、过期清理、恢复和条目列表。
- 扩展侧工作区管理器:封装写文件、下载文件、批量下载等常用调用。
章节来源
- agent/src/server.js#L193-L213
- agent/src/server.js#L752-L862
- agent/src/security.js#L109-L229
- agent/src/trash.js#L141-L250
- src/side_panel/workspace-manager.js#L352-L370
架构总览
下图展示典型文件操作请求在扩展侧与 Agent 侧之间的交互流程。
sequenceDiagram
participant Frontend as "扩展前端"
participant Manager as "工作区管理器"
participant Server as "Agent 服务器"
participant Security as "路径安全检查"
participant FS as "文件系统"
participant Trash as "回收站模块"
Frontend->>Manager : "调用 writeFileContent(path, content)"
Manager->>Server : "POST /api/fs/write"
Server->>Security : "checkPath(path)"
Security-->>Server : "{ allowed, resolved }"
Server->>FS : "写入文件或二进制 Buffer"
Server-->>Manager : "{ success, size, path }"
Manager-->>Frontend : "返回结果"
图表来源
- src/side_panel/workspace-manager.js#L352-L357
- agent/src/server.js#L1053-L1086
- agent/src/security.js#L109-L229
端点参考
通用约定
- 基础地址:由扩展配置或状态接口返回的 Agent 本地服务地址。
- 认证:文件系统类接口通常要求已认证的 Agent 会话;未认证时可能直接拒绝。
- 响应格式:大多数 JSON 端点返回
{ success, ... }结构;错误时success=false并包含error。 - 路径参数:除非特别说明,路径均为字符串;服务端会进行规范化、绝对路径检查与白名单校验。
- MIME 类型:服务端根据扩展名推断 MIME,用于下载响应头与预览场景。
章节来源
/api/fs/read:读取文件
| 项目 | 说明 |
|---|---|
| HTTP 方法 | POST |
| URL 模式 | /api/fs/read |
| 请求体 | path:要读取的文件路径 |
| 成功响应 | { success: true, content, size, path } |
| 失败响应 | { success: false, error } |
| 状态码 | 200 成功;400 路径是目录或内容过大;403 路径不在允许范围;404 文件不存在;500 内部错误 |
处理要点:
- 先执行路径安全检查。
- 判断是否为目录,若是则返回 400。
- 使用
DEFAULT_MAX_SIZE或配置的fileMaxSize限制读取大小。 - 以 UTF-8 文本读取并返回
content。
章节来源
- agent/src/server.js#L1036-L1050
- agent/src/server.js#L132-L136
- agent/test/integration/api.integration.test.js#L257-L277
/api/fs/write:写入文件
| 项目 | 说明 |
|---|---|
| HTTP 方法 | POST |
| URL 模式 | /api/fs/write |
| 请求体 | path:目标路径;content:文本或 base64 编码内容;encoding:可选,base64 表示二进制 |
| 成功响应 | { success: true, size, path } |
| 失败响应 | { success: false, error } |
| 状态码 | 200 成功;400 内容过大或缺少必要字段;403 路径不允许;404 父目录创建失败;500 写入失败 |
处理要点:
- 路径安全检查后确保父目录存在。
- 若
encoding=base64,先将 base64 解码为 Buffer 再写入,避免损坏二进制文件。 - 对脚本扩展名或 shebang 内容自动移除执行权限。
- 写入大小受
DEFAULT_MAX_SIZE或fileMaxSize限制。
章节来源
/api/fs/upload-stream:流式上传
| 项目 | 说明 |
|---|---|
| HTTP 方法 | POST |
| URL 模式 | /api/fs/upload-stream?path=目标路径 |
| 请求体 | 原始二进制 body;路径通过查询参数 path 传递 |
| 成功响应 | { success: true, size, path } |
| 失败响应 | { success: false, error } |
| 状态码 | 200 成功;400 缺少路径、声明大小超限、接收大小超限或写入失败;403 路径不允许;500 内部错误 |
处理要点:
- 路径必须通过查询参数传入,避免 JSON 体中的路径被普通解析器误处理。
- 使用
MAX_UPLOAD_SIZE限制流式上传大小。 - 同时校验
Content-Length与实际接收字节数,防止伪造或异常连接。 - 自动创建目标父目录。
- 对脚本扩展名自动移除执行权限。
- 失败时尝试清理半成品文件。
章节来源
/api/files/upload:multipart 上传
| 项目 | 说明 |
|---|---|
| HTTP 方法 | POST |
| URL 模式 | /api/files/upload |
| 请求体 | multipart/form-data,包含 file 字段 |
| 成功响应 | { success: true, path, name, size } |
| 失败响应 | { success: false, error } |
| 状态码 | 200 成功;400 上传失败;500 内部错误 |
处理要点:
- 文件名过滤危险字符并取 basename,防止路径穿越。
- 如果同名文件已存在,自动追加序号后缀。
- 写入工作目录,并记录 MIME 类型。
- 该接口会将整个文件读入内存,因此更适合中小文件;超大文件应使用流式上传。
章节来源
/api/fs/download:下载文件
| 项目 | 说明 |
|---|---|
| HTTP 方法 | POST |
| URL 模式 | /api/fs/download |
| 请求体 | path:文件路径;或 paths:多个路径(见批量行为) |
| 成功响应 | 单文件:{ success: true, type: 'file', name, size, content, mimeType }目录: { success: true, type: 'directory', name, size, content, mimeType: 'application/zip' } |
| 失败响应 | { success: false, error } |
| 状态码 | 200 成功;400 缺少路径或文件过大;403 路径不允许;404 路径不存在;500 打包或读取失败 |
处理要点:
- 单文件返回 base64 编码内容和 MIME 类型。
- 目录自动打包为 ZIP,返回 ZIP 的 base64 内容。
- 文件大小受
DEFAULT_MAX_SIZE或fileMaxSize限制。 - 对于大文件,建议使用
/api/fs/download-stream或/api/fs/download-multi。
章节来源
/api/fs/list:目录列表
| 项目 | 说明 |
|---|---|
| HTTP 方法 | POST |
| URL 模式 | /api/fs/list |
| 请求体 | path:目录路径;默认为当前工作目录 |
| 成功响应 | { success: true, entries, path } |
| 失败响应 | { success: false, error } |
| 状态码 | 200 成功;400 路径不是目录;403 路径不允许;404 目录不存在 |
entries 元素结构:
name:名称type:file、directory或unknownsize:字节数mtime:修改时间毫秒时间戳
章节来源
/api/fs/delete:删除到回收站
| 项目 | 说明 |
|---|---|
| HTTP 方法 | POST |
| URL 模式 | /api/fs/delete |
| 请求体 | path:要删除的文件或目录路径 |
| 成功响应 | { success: true, path, isDir, trashId, message } |
| 失败响应 | { success: false, error } |
| 状态码 | 200 成功;403 路径不允许;404 路径不存在;500 移动到回收站失败 |
处理要点:
- 删除不会立即物理删除,而是移动到回收站。
- 返回
trashId,可用于后续恢复。 - 回收站支持过期自动清理。
章节来源
/api/trash/restore:从回收站恢复
| 项目 | 说明 |
|---|---|
| HTTP 方法 | POST |
| URL 模式 | /api/trash/restore |
| 请求体 | trashId:回收站条目 ID |
| 成功响应 | { success: true, restoredPath } |
| 失败响应 | { success: false, error } |
| 状态码 | 200 成功;400 缺少 trashId、原路径被占用、恢复失败;500 内部错误 |
处理要点:
- 若原路径已被占用,恢复失败。
- 恢复成功后从回收站元数据中移除对应条目。
- 支持跨设备移动,失败时清理半成品目标。
章节来源
回收站管理端点说明
仓库中明确实现的回收站相关端点是:
/api/fs/delete:将文件/目录移动到回收站。/api/trash/restore:根据trashId恢复文件/目录。
回收站模块还提供:
- 回收站条目列表:
listTrash() - 回收站目录路径:
getTrashDir() - 定期清理过期条目:
startPeriodicCleanup()
目前代码中没有名为 /api/fs/trash 的路由;如需完整的回收站管理界面,可基于现有模块新增列出、清空、按时间筛选等端点。
章节来源
其他相关文件系统端点
虽然不在问题描述的核心列表中,但以下端点与文件系统 API 密切相关,建议一并了解:
| 端点 | 用途 | 关键行为 |
|---|---|---|
/api/fs/stat | 获取文件详细信息 | 返回类型、大小、时间戳、权限、MIME 类型等 |
/api/fs/mkdir | 创建目录 | 递归创建失败时返回冲突或错误 |
/api/fs/rename | 重命名文件/目录 | 仅改文件名,不跨目录;目标路径也需通过安全检查 |
/api/fs/move | 移动文件/目录 | 目标路径同样需要安全检查 |
/api/fs/download-multi | 批量下载 | 后端打包为 ZIP,返回 base64 |
/api/fs/download-stream | 流式下载 | 单文件或目录打包后流式返回,避免 base64 膨胀 |
/api/fs/search_files | 按文件名搜索 | 支持模式匹配和递归 |
/api/fs/search_content | 按内容搜索 | 支持正则、大小写、上下文行数 |
/api/fs/preview-xlsx | Excel 预览 | 服务端解析前若干行,返回结构化 JSON |
章节来源
- agent/src/server.js#L1112-L1142
- agent/src/server.js#L1222-L1385
- agent/src/server.js#L1387-L1442
- agent/src/server.js#L1444-L1515
依赖与安全分析
路径安全检查
所有涉及用户路径的文件系统操作都会调用路径安全检查函数。其核心规则包括:
- 空路径或非字符串路径直接拒绝。
- 解析为绝对路径并进行规范化。
- 检查是否命中硬阻止敏感路径。
- 检查是否在
allowedPaths白名单内。 - 使用真实路径再次校验,防止符号链接绕过。
- Windows 下路径比较大小写不敏感。
flowchart TD
Start["收到路径"] --> Validate["验证路径类型"]
Validate --> Valid{"路径有效?"}
Valid --> |否| DenyInvalid["拒绝:路径无效"]
Valid --> |是| Normalize["规范化并解析绝对路径"]
Normalize --> HardBlocked{"命中硬阻止清单?"}
HardBlocked --> |是| DenyHard["拒绝:敏感路径"]
HardBlocked --> |否| AllowedCheck["检查 allowedPaths 白名单"]
AllowedCheck --> Allowed{"在白名单内?"}
Allowed --> |否| DenyRange["拒绝:路径不在允许范围"]
Allowed --> |是| RealPath["解析真实路径"]
RealPath --> FinalCheck["再次前缀校验"]
FinalCheck --> Allow["允许:返回 resolved 路径"]
图表来源
章节来源
MIME 类型检测
服务端根据文件扩展名映射 MIME 类型,用于下载响应头和预览场景。未知扩展名通常回退到通用类型。
章节来源
批量操作支持
/api/fs/download-multi:接受paths数组,在后端打包为 ZIP。/api/fs/download-stream:同时支持path和paths,多文件时打包为 ZIP 流式返回。- 扩展侧提供
downloadFiles(paths)调用封装。
章节来源
性能与大小限制
大小限制常量
| 常量 | 值 | 适用场景 |
|---|---|---|
DEFAULT_MAX_SIZE | 50MB | 读取文件、stat、download 等读取类操作的默认上限 |
MAX_UPLOAD_SIZE | 200MB | 流式上传 /api/fs/upload-stream 的上限 |
MAX_BODY_SIZE | 200MB | JSON body 解析上限,影响旧版 base64 上传 |
config.fileMaxSize | 可配置 | 覆盖 DEFAULT_MAX_SIZE,用于 read/download 等读取限制 |
注意:
/api/fs/read和/api/fs/download使用config.fileMaxSize || DEFAULT_MAX_SIZE。/api/fs/upload-stream使用MAX_UPLOAD_SIZE,因为流式写入不会把整个文件加载到内存。/api/files/upload会把 multipart 文件整体读入内存,适合中小文件。
章节来源
- agent/src/server.js#L132-L136
- agent/src/server.js#L722-L749
- agent/src/server.js#L752-L790
- agent/src/server.js#L792-L862
- agent/src/server.js#L1036-L1050
- agent/src/server.js#L1163-L1220
流式处理优化
- 流式上传:边接收边写入磁盘,实时统计字节数并在超过上限时中断。
- 流式下载:单文件使用
createReadStream直接管道输出;目录打包后分块写入响应,避免一次性发送大 Buffer。 - 批量下载:后端打包 ZIP,前端可选择 base64 下载或流式下载。
章节来源
客户端调用示例
JavaScript 调用方式说明
由于文档规范禁止直接粘贴具体代码片段,下面给出调用步骤和数据结构说明,便于自行实现。
读取文件
- 向
/api/fs/read发送 POST 请求。 - 请求体包含
path。 - 成功响应包含
content、size、path。 - 错误时检查
success=false和error字段。
写入文件
- 向
/api/fs/write发送 POST 请求。 - 文本写入:
{ path, content }。 - 二进制写入:
{ path, content, encoding: 'base64' }。 - 成功响应包含
size、path。
流式上传
- 向
/api/fs/upload-stream?path=目标路径发送 POST 请求。 - 请求体为原始二进制数据。
- 成功响应包含
size、path。
multipart 上传
- 向
/api/files/upload发送 POST 请求。 - 使用
multipart/form-data,字段名为file。 - 成功响应包含
path、name、size。
下载文件
- 小文件:使用
/api/fs/download,处理返回的 base64content。 - 大文件:使用
/api/fs/download-stream,直接处理二进制流。 - 目录:两者都支持,目录会被打包为 ZIP。
目录列表
- 向
/api/fs/list发送 POST 请求。 - 请求体包含
path。 - 成功响应包含
entries数组。
删除到回收站
- 向
/api/fs/delete发送 POST 请求。 - 请求体包含
path。 - 成功响应包含
trashId。
从回收站恢复
- 向
/api/trash/restore发送 POST 请求。 - 请求体包含
trashId。 - 成功响应包含
restoredPath。
章节来源
- agent/src/server.js#L1036-L1050
- agent/src/server.js#L1053-L1086
- agent/src/server.js#L792-L862
- agent/src/server.js#L752-L790
- agent/src/server.js#L1163-L1385
- agent/src/server.js#L1144-L1161
- agent/src/server.js#L1693-L1703
故障排除指南
常见错误与原因
| 现象 | 可能原因 | 处理建议 |
|---|---|---|
| 读取文件返回 403 | 路径不在 allowedPaths 白名单或命中硬阻止清单 | 检查工作目录和允许路径配置 |
| 读取文件返回 404 | 文件不存在 | 确认路径是否正确 |
| 读取文件返回 400 | 目标是目录或文件大小超过限制 | 使用 list 查看目录;增大 fileMaxSize 或使用下载流 |
| 写入文件返回 403 | 目标路径不在允许范围 | 调整工作目录或允许路径 |
| 写入文件返回 400 | 内容超过限制或编码异常 | 检查 encoding=base64 的使用;减小内容体积 |
| 流式上传返回 400 | 缺少 path、声明大小超限、实际接收大小超限 | 检查查询参数和请求体大小 |
| 下载返回 400 | 文件过大或参数缺失 | 改用 /api/fs/download-stream |
| 删除返回 500 | 移动到回收站失败 | 检查回收站目录权限和磁盘空间 |
| 恢复返回 400 | 原路径被占用或回收站条目不存在 | 检查原路径是否被新文件占用 |
调试建议
- 先调用状态接口确认 Agent 版本、工作目录、允许路径、文件大小限制。
- 使用
/api/fs/stat检查目标路径的类型、大小、权限和时间戳。 - 使用
/api/fs/list确认目录内容。 - 查看 Agent 日志中的
fs_*和security_*分类日志。 - 对于路径安全问题,优先检查
allowedPaths和工作目录配置。
章节来源
- agent/src/server.js#L722-L749
- agent/src/server.js#L1112-L1142
- agent/src/server.js#L1144-L1161
- agent/src/server.js#L1693-L1703
- agent/test/integration/api.integration.test.js#L257-L277
结论
文件系统 API 围绕 Agent 本地服务构建,提供安全的文件读写、上传、下载、目录管理和回收站能力。核心安全机制是路径白名单与硬阻止清单;核心性能机制是流式上传与流式下载;核心用户体验机制是回收站和批量操作。客户端应根据文件大小选择合适的接口:小文件可用 base64 下载,大文件应使用流式下载;上传大文件时应使用流式上传而非 multipart。