feat: 实现文件上传功能并完善测试覆盖

- 新增 upload.rs 模块,支持 multipart/form-data 文件上传
- 文件按日期存储在 storage/YYYY-MM-DD/ 目录下
- 使用 UUID 生成唯一文件名,保留原始扩展名
- 添加 axum-extra, uuid, chrono 依赖

新增测试用例:
- config_test.rs: 6 个测试 (配置结构验证)
- router_test.rs: 11 个测试 (路由匹配逻辑)
- handler_test.rs: 8 个测试 (请求处理)
- upload_test.rs: 13 个测试 (文件上传功能)

其他改进:
- 优化 handler.rs 代码注释
- 更新 .gitignore 忽略 storage/ 和 .claude/
- 添加 CLAUDE.md 项目指南文档

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-19 22:11:42 +08:00
parent 5f3269bad5
commit ab368ead1b
14 changed files with 2113 additions and 15 deletions

228
CLAUDE.md Normal file
View File

@@ -0,0 +1,228 @@
# Mock Server 项目指南
## 项目概述
基于 Rust + Axum 的配置驱动型 Mock 服务,支持 YAML 配置、请求匹配、延迟响应、大文件流式返回和文件上传等特性。
## 技术栈
- **语言**: Rust (Edition 2024)
- **Web 框架**: Axum 0.8.8 + axum-extra (multipart 支持)
- **异步运行时**: Tokio
- **序列化**: serde + serde_yaml + serde_json
- **工具库**: walkdir, uuid, chrono, tokio-util
## 项目结构
```
mock-server/
├── src/
│ ├── main.rs # 程序入口,路由配置,服务启动
│ ├── lib.rs # 库模块导出
│ ├── config.rs # 配置结构定义 (MockRule, MockResponse, MockSettings)
│ ├── loader.rs # YAML 配置加载器,递归扫描 mocks 目录
│ ├── router.rs # 路由匹配引擎,基于路径首段索引
│ ├── handler.rs # 请求处理器,统一处理所有 Mock 请求
│ └── upload.rs # 文件上传处理模块
├── tests/ # 集成测试
│ ├── config_test.rs # 配置模块测试
│ ├── handler_test.rs # 请求处理测试
│ ├── integration_test.rs # 集成测试
│ ├── loader_test.rs # 加载器测试
│ ├── router_test.rs # 路由匹配测试
│ └── upload_test.rs # 文件上传测试
├── mocks/ # YAML Mock 配置文件目录
├── storage/ # 上传文件存储目录 (按日期分类: YYYY-MM-DD)
└── Cargo.toml
```
## 核心模块说明
### config.rs - 配置结构
定义 Mock 规则的数据结构:
- `MockRule`: 完整的 Mock 规则id, request, response, settings
- `MockRequest`: 请求匹配条件method, path, query_params, headers, body
- `MockResponse`: 响应配置status, headers, body
- `MockSettings`: 额外设置delay_ms 延迟)
- `MockSource`: 支持单接口和多接口 YAML 格式
**文件协议**: body 以 `file://` 开头时,从磁盘流式读取文件
### loader.rs - 配置加载器
- `MockLoader::load_all_from_dir()`: 递归扫描目录下的 .yaml/.yml 文件
- 按路径首段建立索引(如 `/api/users` -> key: `api`
- 支持单接口和多接口两种 YAML 格式
### router.rs - 路由匹配引擎
- 基于路径首段的 HashMap 快速索引
- 线性深度匹配method -> path -> query_params -> headers -> body
- 支持大小写不敏感的方法匹配
- 支持尾部斜杠忽略
### handler.rs - 请求处理器
- 统一处理所有 HTTP 方法和路径
- 支持延迟响应settings.delay_ms
- 支持文件流式响应(低内存占用)
- 匹配失败返回 404
### upload.rs - 文件上传
- 路由: `POST /api/upload`
- 支持 multipart/form-data 格式
- 文件存储: `storage/YYYY-MM-DD/uuid.extension`
- 返回 JSON 格式的文件信息
## 常用命令
```bash
# 构建项目
cargo build
# 运行项目
cargo run
# 运行所有测试
cargo test
# 运行特定测试
cargo test test_name
# 检查代码
cargo check
# 格式化代码
cargo fmt
# 代码检查
cargo clippy
```
## YAML 配置示例
### 单接口模式
```yaml
id: "user-login"
request:
method: "POST"
path: "/api/v1/login"
query_params:
redirect: "/dashboard"
headers:
Content-Type: "application/json"
body:
username: "test"
password: "123456"
response:
status: 200
headers:
Content-Type: "application/json"
body: '{"code": 0, "message": "success", "data": {"token": "xxx"}}'
settings:
delay_ms: 100
```
### 多接口模式
```yaml
- id: "get-users"
request:
method: "GET"
path: "/api/users"
response:
status: 200
body: '{"users": []}'
- id: "create-user"
request:
method: "POST"
path: "/api/users"
response:
status: 201
body: '{"id": 1}'
```
### 文件响应模式
```yaml
id: "download-file"
request:
method: "GET"
path: "/api/download"
response:
status: 200
headers:
Content-Type: "application/pdf"
body: "file://./data/document.pdf"
```
## 开发规范
### 代码风格
- 使用 Rust 标准命名约定snake_case for functions/variables, PascalCase for types
- 公开函数添加文档注释 `///`
- 错误处理使用 `Result``Option`
- 异步函数使用 `async/await`
### 测试规范
- 每个模块对应一个测试文件
- 测试函数命名:`test_<模块>_<场景>`
- 使用 `tempfile` crate 处理临时文件
- 测试应该独立运行,不依赖执行顺序
### Git 提交规范
```
feat: 新功能
fix: 修复 bug
docs: 文档更新
test: 测试相关
refactor: 代码重构
chore: 构建/工具变更
```
## API 端点
| 端点 | 方法 | 说明 |
|------|------|------|
| `/api/upload` | POST | 文件上传 |
| `/*` | ANY | Mock 请求处理(由 YAML 配置定义) |
## 文件上传响应格式
```json
{
"success": true,
"files": [
{
"original_name": "document.pdf",
"stored_name": "550e8400-e29b-41d4-a716-446655440000.pdf",
"path": "storage/2026-03-19/550e8400-e29b-41d4-a716-446655440000.pdf",
"size": 1024,
"content_type": "application/pdf"
}
],
"message": "Files uploaded successfully"
}
```
## 扩展功能规划
- [ ] 热加载:配置文件变更自动重载
- [ ] 动态占位符:支持 `{{timestamp}}`, `{{uuid}}`
- [ ] 管理界面Web UI 管理 Mock 规则
- [ ] 请求录制:自动生成 Mock 配置
- [ ] 条件匹配:基于请求体的复杂匹配规则
## 注意事项
1. **文件协议**: 使用 `file://` 时确保文件路径正确
2. **延迟响应**: 仅用于测试,生产环境请移除
3. **上传目录**: 确保 `storage/` 目录有写入权限
4. **内存限制**: 请求体限制为 10MB