diff --git a/README.md b/README.md
index 5b3b544..43dbf26 100644
--- a/README.md
+++ b/README.md
@@ -1,47 +1,46 @@
# V-Hono
-一个用 V 语言编写的轻量级 Web 框架,灵感来自 Hono.js。
+一个用 V 语言编写的高性能 Web 框架,灵感来自 [Hono.js](https://hono.dev/)。
## 特性
-- 🚀 高性能路由系统(混合路由算法)
+- 🚀 高性能路由系统(FastRouter + LRU 缓存 + 预编译正则)
- 🎯 类似 Hono.js 的 Context API
- 🔧 洋葱模型中间件支持
- 📦 内置 LRU 缓存系统
-- 🛠️ 支持动态路由参数(`:param`)
-- ⚡ 支持通配符路由(`*` 和 `**`)
+- 🛠️ 动态路由参数(`:param`)和通配符路由(`*`、`**`)
- 🔄 支持所有 HTTP 方法(GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS)
-- 🏗️ 构造函数风格的 API 设计
-- 📁 静态文件服务中间件(类似 Hono.js 的 serveStatic)
+- 🏗️ 路由分组与子应用中间件继承
+- 📁 静态文件服务中间件
- 🛡️ 内置安全防护(路径遍历攻击防护、点文件访问控制)
- 💾 智能缓存支持(ETag、Last-Modified、Cache-Control)
-- 🎯 自动 Content-Type 检测
-- 📤 **大文件分片上传**:支持大文件分片上传、断点续传、秒传、自动合并
-- 🔄 **断点续传**:支持上传中断后继续上传
-- ⚡ **秒传功能**:基于文件哈希的秒传检测
-- 🗂️ **文件去重**:基于文件哈希的去重机制
-- 💾 **数据库存储**:使用 SQLite 存储文件元数据
-- 🚀 **双请求池系统**:活跃请求池 + 待请求池,支持并发控制和智能调度
-- ⚡ **并发优化**:可配置最大并发数,自动管理请求队列
-- 📊 **实时状态监控**:实时显示活跃请求数和等待请求数
-- ⚡ **性能优化**:分片大小记录文件,避免遍历文件计算总大小
+- 📤 大文件分片上传(断点续传、秒传、自动合并)
+- 🔐 用户认证系统(JWT、角色权限、菜单管理)
+- 📊 配置管理系统
+- 🗄️ SQLite 数据库集成
+
+## 性能测试
+
+基于 100,000 次迭代的路由匹配性能测试:
+
+| 框架 | 平均延迟 | 吞吐量 |
+|------|---------|--------|
+| v-hono | 5,621 ns/op | **177,904 ops/sec** |
+| 简单路由器 | 9,265 ns/op | 107,933 ops/sec |
+
+v-hono 在动态路由场景下优势明显,得益于 LRU 缓存和预编译正则表达式。
## 安装
```bash
-# 克隆仓库
git clone https://github.com/meiseayoung/v-hono.git
cd v-hono
-
-# 运行示例
v run example.v
```
## 快速开始
```v
-module main
-
import hono
import net.http
@@ -53,14 +52,10 @@ fn main() {
return c.html('
Hello V-Hono!
')
})
- app.get('/api/users/:id', fn (mut c hono.Context) http.Response {
+ // 动态路由
+ app.get('/users/:id', fn (mut c hono.Context) http.Response {
user_id := c.params['id']
- return c.json('{"id": "${user_id}", "name": "John Doe"}')
- })
-
- app.post('/api/users', fn (mut c hono.Context) http.Response {
- c.status(201)
- return c.json('{"message": "User created", "data": "${c.body}"}')
+ return c.json('{"id": "${user_id}"}')
})
// 中间件
@@ -73,124 +68,76 @@ fn main() {
}
```
-## API 参考
+## 路由分组
-### Context
-
-Context 是请求的核心对象,包含所有请求和响应信息:
+支持子应用路由分组,中间件自动继承:
```v
-pub struct Context {
-pub:
- req http.Request // 原始 HTTP 请求
- params map[string]string // 路径参数
- query map[string]string // 查询参数
- url string // 请求 URL
-pub mut:
- status_code int = 200 // 响应状态码
- headers map[string]string // 响应头
- body string // 响应体
+// 创建子应用
+mut api := hono.Hono.new()
+
+// 子应用中间件(只对 /api/* 生效)
+api.use(fn (mut c hono.Context, next fn (mut hono.Context) http.Response) http.Response {
+ c.headers['X-API-Version'] = '1.0'
+ return next(mut c)
+})
+
+api.get('/users', fn (mut c hono.Context) http.Response {
+ return c.json('{"users": []}')
+})
+
+// 挂载到主应用
+app.route('/api', mut api)
+```
+
+## all() 方法
+
+一次性为所有 HTTP 方法注册处理器:
+
+```v
+app.all('/echo', fn (mut c hono.Context) http.Response {
+ return c.json('{"method": "${c.req.method}"}')
+})
+```
+
+## 自定义错误处理
+
+```v
+// 自定义 404 处理器
+app.not_found(fn (mut c hono.Context) http.Response {
+ c.status(404)
+ return c.json('{"error": "Not Found", "path": "${c.path}"}')
+})
+
+// 自定义错误处理器
+app.on_error(fn (error_msg string, status_code int, mut c hono.Context) http.Response {
+ c.status(status_code)
+ return c.json('{"error": "${error_msg}"}')
+})
+```
+
+## 静态文件服务
+
+```v
+// 默认配置(./public 目录)
+app.use(hono.serve_static_default())
+
+// 指定路径前缀和根目录
+app.use(hono.serve_static_path('/assets', './static'))
+
+// 自定义配置
+options := hono.StaticOptions{
+ root: './public'
+ path: '/static'
+ index: 'index.html'
+ etag: true
+ last_modified: true
+ max_age: 3600
}
+app.use(hono.serve_static(options))
```
-### 构造函数
-
-所有对象都使用构造函数风格创建:
-
-```v
-// 创建 Context
-ctx := hono.Context.new(req, params, query, body)
-
-// 创建路由器
-router := hono.ContextHybridRouter.new()
-trie_router := hono.ContextTrieRouter.new()
-
-// 创建缓存
-cache := hono.ContextLRUCache.new(1000)
-```
-
-### 路由方法
-
-支持所有 HTTP 方法:
-
-```v
-// GET 请求
-app.get('/path', fn (mut c hono.Context) http.Response {
- return c.json('{"message": "GET response"}')
-})
-
-// POST 请求
-app.post('/path', fn (mut c hono.Context) http.Response {
- return c.json('{"message": "POST response"}')
-})
-
-// PUT 请求
-app.put('/path', fn (mut c hono.Context) http.Response {
- return c.json('{"message": "PUT response"}')
-})
-
-// DELETE 请求
-app.delete('/path', fn (mut c hono.Context) http.Response {
- c.status(204)
- return c.text('')
-})
-
-// PATCH 请求
-app.patch('/path', fn (mut c hono.Context) http.Response {
- return c.json('{"message": "PATCH response"}')
-})
-
-// HEAD 请求
-app.head('/path', fn (mut c hono.Context) http.Response {
- return c.text('')
-})
-
-// OPTIONS 请求
-app.options('/path', fn (mut c hono.Context) http.Response {
- return c.text('')
-})
-```
-
-### 动态路由
-
-支持路径参数和通配符:
-
-```v
-// 单参数
-app.get('/users/:id', fn (mut c hono.Context) http.Response {
- user_id := c.params['id']
- return c.json('{"id": "${user_id}"}')
-})
-
-// 多参数
-app.get('/posts/:id/comments/:comment_id', fn (mut c hono.Context) http.Response {
- post_id := c.params['id']
- comment_id := c.params['comment_id']
- return c.json('{"post_id": "${post_id}", "comment_id": "${comment_id}"}')
-})
-
-// 嵌套参数
-app.get('/api/users/:user_id/posts/:post_id', fn (mut c hono.Context) http.Response {
- user_id := c.params['user_id']
- post_id := c.params['post_id']
- return c.json('{"user_id": "${user_id}", "post_id": "${post_id}"}')
-})
-
-// 通配符
-app.get('/files/*', fn (mut c hono.Context) http.Response {
- file_path := c.params['*']
- return c.text('File: ${file_path}')
-})
-
-// 多级通配符
-app.get('/api/**/search', fn (mut c hono.Context) http.Response {
- return c.json('{"search": "wildcard"}')
-})
-```
-
-### 响应方法
-
-所有响应方法直接返回 `http.Response`:
+## 响应方法
```v
// JSON 响应
@@ -202,723 +149,231 @@ return c.text('Hello World')
// HTML 响应
return c.html('Hello
')
+// 文件响应
+return c.file('path/to/file.pdf')
+
// 设置状态码
-c.status(404)
-return c.json('{"error": "Not Found"}')
+c.status(201)
+return c.json('{"created": true}')
+
+// 错误响应
+return c.not_found('Resource not found')
+return c.unauthorized('Token required')
+return c.forbidden('Access denied')
```
-### 中间件
-支持洋葱模型中间件:
+## 大文件分片上传
+
+支持大文件分片上传、断点续传、秒传功能:
```v
-// 日志中间件
-app.use(fn (mut c hono.Context, next fn (mut hono.Context) http.Response) http.Response {
- println('[${time.now()}] ${c.req.method} ${c.path}')
- return next(mut c)
+mut upload_manager := hono.new_chunk_upload_manager(hono.ChunkUploadConfig{
+ chunk_size: 1024 * 1024 // 1MB 分片
+ max_file_size: 1024 * 1024 * 1024 // 最大 1GB
+ temp_dir: './uploads/chunks'
+ upload_dir: './uploads/files'
})
-// 认证中间件
-app.use(fn (mut c hono.Context, next fn (mut hono.Context) http.Response) http.Response {
- token := c.query['token']
- if token == '' {
- c.status(401)
- return c.json('{"error": "Unauthorized"}')
- }
- return next(mut c)
+// 分片上传接口
+app.post('/upload/chunk', fn [mut upload_manager] (mut c hono.Context) http.Response {
+ return upload_manager.handle_chunk_upload(mut c)
})
-// 性能监控中间件
-app.use(fn (mut c hono.Context, next fn (mut hono.Context) http.Response) http.Response {
- start := time.now()
- response := next(mut c)
- duration := time.now() - start
- println('请求处理时间: ${duration.milliseconds()}ms')
- return response
+// 上传状态查询
+app.get('/upload/status', fn [mut upload_manager] (mut c hono.Context) http.Response {
+ return upload_manager.get_upload_status(mut c)
})
```
-### 静态文件服务
-
-提供类似 Hono.js 的 `serveStatic` 中间件:
-
-```v
-// 使用默认配置(./public 目录)
-app.use(hono.serve_static_default())
-
-// 指定根目录
-app.use(hono.serve_static_root('./static'))
-
-// 指定路径前缀和根目录
-app.use(hono.serve_static_path('/assets', './static'))
-
-// 使用自定义配置
-options := hono.StaticOptions{
- root: './public'
- path: '/static'
- index: 'index.html'
- dotfiles: false
- etag: true
- last_modified: true
- max_age: 3600 // 1小时缓存
- headers: {
- 'X-Custom-Header': 'value'
- }
-}
-app.use(hono.serve_static(options))
-```
-
-**特性:**
-- 🛡️ 路径遍历攻击防护
-- 📁 自动索引文件支持(index.html)
-- 🔒 点文件访问控制
-- 🏷️ ETag 和 Last-Modified 支持
-- 💾 可配置缓存策略
-- 📋 自定义响应头
-- 🎯 智能 Content-Type 检测
-
-### 查询参数和请求体
-
-```v
-// 获取查询参数
-app.get('/search', fn (mut c hono.Context) http.Response {
- query := c.query['q']
- page := c.query['page']
- return c.json('{"query": "${query}", "page": "${page}"}')
-})
-
-// 获取请求体
-app.post('/api/data', fn (mut c hono.Context) http.Response {
- println('请求体: ${c.body}')
- return c.json('{"received": "${c.body}"}')
-})
-```
-
-### 路由统计和缓存
-
-```v
-// 获取路由统计信息
-static_count, dynamic_count, cache_size, cache_capacity := app.get_router_stats()
-println('静态路由: ${static_count}, 动态路由: ${dynamic_count}')
-println('缓存: ${cache_size}/${cache_capacity}')
-
-// 清理缓存
-app.clear_cache()
-```
-
-## 示例
-
-### 基础示例
-
-运行完整示例:
-
-```bash
-v run example.v
-```
-
-示例包含:
-- 静态路由
-- 动态路由(单参数、多参数、嵌套参数)
-- 所有 HTTP 方法
-- 中间件功能
-- 参数提取和查询参数处理
-
-### 静态文件服务示例
-
-运行静态文件服务示例:
-
-```bash
-v run static_example.v
-```
-
-这个示例演示了:
-- 多个静态文件目录配置
-- 自定义缓存策略
-- 安全特性演示
-- 完整的HTML界面
-
-**重要提示**: 静态文件路径映射
-- `./public` 目录 → 访问路径 `/`
-- `./static` 目录 → 访问路径 `/assets`
-- `./uploads` 目录 → 访问路径 `/files`
-
-例如:
-- `./public/test.txt` → `http://localhost:8080/test.txt`
-- `./static/style.css` → `http://localhost:8080/assets/style.css`
-- `./uploads/sample.json` → `http://localhost:8080/files/sample.json`
-
-### 快速测试
-
-运行简单的静态文件测试:
-
-```bash
-v run test_static.v
-```
-
-测试文件结构:
-```
-v-hono/
-├── public/
-│ ├── index.html # 默认索引文件
-│ └── test.txt # 测试文本文件
-├── static/
-│ ├── style.css # 样式文件
-│ └── app.js # JavaScript文件
-└── uploads/
- └── sample.json # JSON文件
-```
-
-## 大文件分片上传系统
-
-### 概述
-
-V-Hono 大文件分片上传系统是一个基于 V 语言和 Hono 框架构建的高性能文件上传解决方案。支持大文件分片上传、断点续传、秒传、自动合并等功能。
-
-**相关文档:**
-- [分片上传系统详解](README_CHUNK_UPLOAD.md) - 完整的分片上传功能文档
-- [双请求池系统详解](README_REQUEST_POOL.md) - 请求池系统的设计和实现
-
-### 主要特性
-
-- ✅ **分片上传**:支持大文件分片上传,默认分片大小 1MB
-- ✅ **断点续传**:支持上传中断后继续上传
-- ✅ **秒传功能**:基于文件哈希的秒传检测
-- ✅ **自动合并**:所有分片上传完成后自动合并文件
-- ✅ **文件去重**:基于文件哈希的去重机制
-- ✅ **数据库存储**:使用 SQLite 存储文件元数据
-- ✅ **RESTful API**:完整的 REST API 接口
-- ✅ **Web 界面**:提供友好的 Web 上传界面
-- ✅ **双请求池系统**:活跃请求池 + 待请求池,智能并发控制
-- ✅ **实时状态监控**:实时显示上传进度和请求池状态
-
-### 系统架构
-
-```
-前端 (Web/移动端)
- ↓
-V-Hono 服务器
- ↓
-分片存储 (./uploads/chunks/)
- ↓
-文件合并 (./uploads/files/)
- ↓
-数据库 (SQLite)
-```
-
-### 安装和运行
-
-#### 1. 环境要求
-
-- V 语言 0.4.x 或更高版本
-- Windows/Linux/macOS
-
-#### 2. 启动服务器
-
-```bash
-# 克隆项目
-git clone https://github.com/meiseayoung/v-hono.git
-cd v-hono
-
-# 启动分片上传服务器
-v run chunk_upload_example.v
-```
-
-服务器将在 `http://localhost:8080` 启动。
-
-#### 3. 访问 Web 界面
-
-打开浏览器访问 `http://localhost:8080` 即可使用 Web 上传界面。
-
-### API 接口文档
-
-#### 1. 分片上传接口
-
-**接口地址:** `POST /upload/chunk`
-
-**请求参数:**
-- `file_hash` (string): 文件哈希值
-- `chunk_index` (int): 分片索引,从 0 开始
-- `filename` (string): 原始文件名
-- `file_size` (int): 文件总大小(字节)
-- `chunk_size` (int): 分片大小(字节)
-- `chunk_hash` (string): 分片哈希值
-- `chunk` (file): 分片文件数据
-
-**响应格式:**
-
-上传完成(自动合并):
-```json
-{
- "success": true,
- "all_chunk_uploaded": true,
- "file_path": ".\\uploads\\files\\xxx.zip",
- "file_uuid": "xxx-xxx-xxx",
- "message": "File merged successfully"
-}
-```
-
-上传中:
-```json
-{
- "success": true,
- "chunk_index": 1,
- "all_chunk_uploaded": false,
- "message": "Chunk uploaded successfully"
-}
-```
-
-#### 2. 分片存在检查接口
-
-**接口地址:** `GET /upload/chunk_exists`
-
-**请求参数:**
-- `file_hash` (string): 文件哈希值
-- `chunk_index` (int): 分片索引
-- `chunk_hash` (string): 分片哈希值
-- `file_size` (int): 文件总大小
-- `trunk_size` (int): 分片大小
-
-**响应格式:**
-```json
-{
- "exists": true,
- "all_chunk_uploaded": false
-}
-```
-
-#### 3. 上传状态查询接口
-
-**接口地址:** `GET /upload/status`
-
-**请求参数:**
-- `file_hash` (string): 文件哈希值
-
-**响应格式:**
-```json
-{
- "file_hash": "xxx",
- "filename": "example.zip",
- "total_chunks": 0,
- "file_size": 1048576,
- "chunk_size": 2097152,
- "uploaded_chunks": [0, 1, 2],
- "status": "uploading",
- "created_at": 1640995200,
- "updated_at": 1640995300
-}
-```
-
-#### 4. 已上传分片查询接口
-
-**接口地址:** `GET /upload/chunks`
-
-**请求参数:**
-- `file_hash` (string): 文件哈希值
-
-**响应格式:**
-```json
-{
- "uploaded_chunks": [0, 1, 2],
- "total_chunks": 5,
- "completed": false
-}
-```
-
-#### 5. 文件管理接口
-
-##### 获取所有文件
-**接口地址:** `GET /api/files`
-
-##### 根据 UUID 获取文件
-**接口地址:** `GET /api/files/{uuid}`
-
-##### 根据哈希获取文件
-**接口地址:** `GET /api/files/hash/{hash}`
-
-##### 删除文件
-**接口地址:** `DELETE /api/files/{uuid}`
-
-### 配置说明
-
-#### ChunkUploadConfig 配置项
-
-```v
-pub struct ChunkUploadConfig {
- chunk_size: int = 1024 * 1024 // 默认分片大小 1MB
- max_file_size: int = 1024 * 1024 * 1024 // 最大文件大小 1GB
- temp_dir: string = './uploads/chunks' // 临时分片目录
- upload_dir: string = './uploads/files' // 最终文件目录
- cleanup_delay: int = 3600 // 清理延迟时间(秒)
- clear_chunks_on_complete: bool = false // 完成后是否清理分片
- db_path: string = './uploads/files.db' // 数据库文件路径
-}
-```
-
-### 文件存储结构
-
-```
-uploads/
-├── chunks/ # 分片文件目录
-│ └── {file_hash}/ # 按文件哈希分组
-│ └── {chunk_size}/ # 按分片大小分组
-│ ├── chunk_0.part # 分片文件
-│ ├── chunk_1.part
-│ └── ...
-├── files/ # 最终文件目录
-│ ├── {file_hash}.{ext} # 合并后的文件
-│ └── ...
-└── files.db # SQLite 数据库文件
-```
-
-### 使用示例
-
-#### 1. 前端 JavaScript 示例
+### 前端示例
```javascript
-// 请求池管理类
-class RequestPool {
- constructor(maxConcurrent = 6) {
- this.maxConcurrent = maxConcurrent;
- this.activePool = new Map(); // 活跃请求池 {requestId: Promise}
- this.pendingPool = []; // 待请求池 [{requestId, task, resolve, reject}]
- this.requestIdCounter = 0;
- }
+// 请求池管理(控制并发)
+const requestPool = new RequestPool(6);
- // 生成请求ID
- generateRequestId() {
- return ++this.requestIdCounter;
- }
-
- // 添加请求到池中
- async addRequest(task) {
- const requestId = this.generateRequestId();
-
- return new Promise((resolve, reject) => {
- const request = {
- requestId,
- task,
- resolve,
- reject
- };
-
- // 如果活跃池未满,直接执行
- if (this.activePool.size < this.maxConcurrent) {
- this.executeRequest(request);
- } else {
- // 否则加入待请求池
- this.pendingPool.push(request);
- console.log(`请求 ${requestId} 加入待请求池,当前待请求数: ${this.pendingPool.length}`);
- }
- });
- }
-
- // 执行请求
- async executeRequest(request) {
- const { requestId, task, resolve, reject } = request;
-
- console.log(`开始执行请求 ${requestId},当前活跃请求数: ${this.activePool.size + 1}`);
-
- // 将请求添加到活跃池
- const promise = task()
- .then(result => {
- console.log(`请求 ${requestId} 执行成功`);
- resolve(result);
- return result;
- })
- .catch(error => {
- console.log(`请求 ${requestId} 执行失败:`, error);
- reject(error);
- throw error;
- })
- .finally(() => {
- // 请求完成后从活跃池移除
- this.activePool.delete(requestId);
- console.log(`请求 ${requestId} 完成,从活跃池移除,当前活跃请求数: ${this.activePool.size}`);
-
- // 检查待请求池,如果有待请求则执行
- this.processPendingRequests();
- });
-
- this.activePool.set(requestId, promise);
- }
-
- // 处理待请求池中的请求
- processPendingRequests() {
- while (this.pendingPool.length > 0 && this.activePool.size < this.maxConcurrent) {
- const request = this.pendingPool.shift();
- this.executeRequest(request);
- console.log(`从待请求池取出请求 ${request.requestId} 执行,剩余待请求数: ${this.pendingPool.length}`);
- }
- }
-
- // 获取池状态
- getStatus() {
- return {
- activeCount: this.activePool.size,
- pendingCount: this.pendingPool.length,
- maxConcurrent: this.maxConcurrent
- };
- }
-
- // 清空所有池
- clear() {
- this.activePool.clear();
- this.pendingPool = [];
- console.log('请求池已清空');
- }
-}
-
-// 计算文件哈希
-async function calculateFileHash(file) {
- return new Promise(resolve => {
- const spark = new SparkMD5.ArrayBuffer();
- const reader = new FileReader();
- reader.onload = e => {
- spark.append(e.target.result);
- resolve(spark.end());
- };
- reader.readAsArrayBuffer(file);
- });
-}
-
-// 上传分片
+// 分片上传
async function uploadChunk(file, chunk, { fileHash, chunkIndex, chunkHash }) {
const form = new FormData();
form.append('file_hash', fileHash);
form.append('chunk_index', chunkIndex);
- form.append('filename', file.name);
- form.append('file_size', file.size);
- form.append('chunk_size', CHUNK_SIZE);
- form.append('chunk_hash', chunkHash);
form.append('chunk', chunk);
-
- const response = await fetch('/upload/chunk', {
- method: 'POST',
- body: form
- });
- const result = await response.json();
-
- if (result.all_chunk_uploaded) {
- console.log('上传完成,文件已合并:', result.file_path);
- return true; // 上传完成
- }
-
- return false; // 继续上传
-}
-
-// 使用请求池的分片上传主函数
-async function uploadFileWithPool(file) {
- const fileHash = await calculateFileHash(file);
- const chunkSize = 2 * 1024 * 1024; // 2MB
- const totalChunks = Math.ceil(file.size / chunkSize);
-
- // 创建请求池实例
- const requestPool = new RequestPool(6);
-
- // 创建所有分片的上传任务并添加到请求池
- const uploadPromises = [];
- for (let i = 0; i < totalChunks; i++) {
- const chunkIndex = i;
- const promise = requestPool.addRequest(async () => {
- const chunk = file.slice(chunkIndex * chunkSize, (chunkIndex + 1) * chunkSize);
- const chunkHash = await calculateFileHash(chunk);
-
- return await uploadChunk(file, chunk, {
- fileHash,
- chunkIndex,
- chunkHash
- });
- });
-
- uploadPromises.push(promise);
- }
-
- // 等待所有上传任务完成
- const results = await Promise.all(uploadPromises);
-
- // 清空请求池
- requestPool.clear();
-
- return results;
+ const response = await fetch('/upload/chunk', { method: 'POST', body: form });
+ return response.json();
}
```
-#### 2. cURL 示例
+详细文档:[README_CHUNK_UPLOAD.md](README_CHUNK_UPLOAD.md)
+
+## 用户认证系统
+
+内置完整的用户认证和权限管理:
+
+```v
+// 初始化认证管理器
+mut db := hono.new_database_manager('./auth.db')
+mut auth := hono.new_auth_manager(db)
+auth.init_tables()!
+
+// 创建用户
+user := auth.create_user('admin', 'admin@example.com', 'password', .admin)!
+
+// 用户登录
+session := auth.login('admin', 'password')!
+
+// 验证令牌
+user := auth.verify_token(session.token)!
+
+// 权限检查
+if auth.check_permission(user, 'write') {
+ // 允许操作
+}
+```
+
+### 用户角色
+
+- `admin` - 管理员(所有权限)
+- `manager` - 管理者(read、write、manage)
+- `user` - 普通用户(read、write)
+- `guest` - 访客(read)
+
+详细文档:[README_AUTH_SYSTEM.md](README_AUTH_SYSTEM.md)
+
+## 配置管理
+
+```v
+// 加载配置
+config := hono.load_config('config.json')!
+
+// 获取配置值
+db_path := config.get_string('database.path')
+port := config.get_int('server.port')
+debug := config.get_bool('debug')
+```
+
+## 项目结构
+
+```
+v-hono/
+├── hono/ # 核心模块
+│ ├── app.v # 主应用
+│ ├── fast_router.v # 快速路由器
+│ ├── cache.v # LRU 缓存
+│ ├── auth.v # 认证系统
+│ ├── database.v # 数据库管理
+│ ├── upload.v # 分片上传
+│ ├── static.v # 静态文件服务
+│ ├── response.v # 响应方法
+│ ├── error_handler.v # 错误处理
+│ ├── security.v # 安全模块
+│ └── ...
+├── public/ # 静态文件目录
+├── uploads/ # 上传文件目录
+├── example.v # 完整示例
+├── route_grouping_example_v2.v # 路由分组示例
+└── benchmark_vweb_vs_hono.v # 性能测试
+```
+
+## API 参考
+
+### Context
+
+```v
+pub struct Context {
+pub:
+ req http.Request // 原始请求
+ params map[string]string // 路径参数
+ query map[string]string // 查询参数
+ url string // 请求 URL
+ path string // 请求路径
+pub mut:
+ status_code int = 200 // 响应状态码
+ headers map[string]string // 响应头
+ body string // 请求体
+}
+```
+
+### 路由方法
+
+```v
+app.get(path, handler) // GET 请求
+app.post(path, handler) // POST 请求
+app.put(path, handler) // PUT 请求
+app.delete(path, handler) // DELETE 请求
+app.patch(path, handler) // PATCH 请求
+app.head(path, handler) // HEAD 请求
+app.options(path, handler) // OPTIONS 请求
+app.all(path, handler) // 所有方法
+```
+
+### 动态路由
+
+```v
+// 单参数
+app.get('/users/:id', handler)
+
+// 多参数
+app.get('/users/:id/posts/:post_id', handler)
+
+// 通配符
+app.get('/files/*path', handler)
+```
+
+### 中间件
+
+```v
+// 全局中间件
+app.use(middleware)
+
+// 子应用中间件(只对特定前缀生效)
+mut api := hono.Hono.new()
+api.use(api_middleware)
+app.route('/api', mut api)
+```
+
+## 运行示例
```bash
-# 上传分片
+# 完整示例
+v run example.v
+
+# 路由分组示例
+v run route_grouping_example_v2.v
+
+# 性能测试
+v run benchmark_vweb_vs_hono.v
+```
+
+## 测试命令
+
+```bash
+# 基本测试
+curl http://localhost:8080/
+curl http://localhost:8080/api/health
+curl http://localhost:8080/users/123
+
+# POST 请求
+curl -X POST http://localhost:8080/api/users -d '{"name":"John"}'
+
+# 静态文件
+curl http://localhost:8080/test.txt
+
+# 分片上传
curl -X POST http://localhost:8080/upload/chunk \
-F "file_hash=abc123" \
-F "chunk_index=0" \
- -F "filename=large_file.zip" \
- -F "file_size=10485760" \
- -F "chunk_size=2097152" \
- -F "chunk_hash=def456" \
- -F "chunk=@chunk_0.part"
-
-# 检查分片是否存在
-curl "http://localhost:8080/upload/chunk_exists?file_hash=abc123&chunk_index=0&chunk_hash=def456&file_size=10485760&trunk_size=2097152"
+ -F "chunk=@file.part"
```
-### 核心算法
+## 相关文档
-#### 1. 分片合并判断
-
-系统使用以下逻辑判断是否所有分片都已上传:
-
-```v
-// 计算理论上需要的分片数量
-expected_chunks := (expected_file_size + u64(chunk_size) - 1) / u64(chunk_size)
-
-// 只有当分片数量达到预期且总大小 >= 文件大小时,才认为上传完成
-if chunk_count >= int(expected_chunks) && total_chunk_size >= expected_file_size {
- all_chunk_uploaded = true
-}
-```
-
-#### 2. 文件去重机制
-
-- 基于文件哈希进行去重
-- 相同哈希的文件只存储一份
-- 支持同一文件的不同文件名
-
-#### 3. 秒传检测
-
-- 前端计算文件哈希
-- 后端检查文件是否已存在
-- 如果存在则直接返回文件信息,无需上传
-
-### 性能优化
-
-#### 1. 内存管理
-
-- 分片文件存储在磁盘,不占用大量内存
-- 上传状态使用内存缓存,提高查询速度
-- 支持配置清理策略,自动清理临时文件
-
-#### 2. 双请求池系统
-
-**架构设计:**
-- **活跃请求池**:存储正在执行的请求,使用 Map 结构 `{requestId: Promise}`
-- **待请求池**:存储等待执行的请求,使用数组结构 `[{requestId, task, resolve, reject}]`
-- **智能调度**:当活跃池未满时直接执行,满时加入待请求池
-- **自动管理**:请求完成后自动从活跃池移除,并处理待请求池中的请求
-
-**核心特性:**
-- **可配置并发数**:默认最大并发数为 6,可根据服务器性能调整
-- **请求ID管理**:每个请求都有唯一ID,便于追踪和调试
-- **状态实时更新**:实时显示活跃请求数和等待请求数
-- **自动清理**:上传完成后自动清空请求池
-
-**使用示例:**
-```javascript
-// 创建请求池实例(最大并发6个)
-const requestPool = new RequestPool(6);
-
-// 添加请求到池中
-const promise = requestPool.addRequest(async () => {
- // 上传分片的逻辑
- return await uploadChunk(chunk);
-});
-
-// 获取池状态
-const status = requestPool.getStatus();
-console.log(`活跃: ${status.activeCount}/${status.maxConcurrent}, 等待: ${status.pendingCount}`);
-```
-
-#### 3. 并发处理
-
-- 支持多用户同时上传
-- 分片级别的并发控制
-- 文件级别的锁机制
-- 基于请求池的智能并发管理
-
-#### 4. 错误处理
-
-- 网络异常自动重试
-- 分片损坏自动重新上传
-- 完整的错误日志记录
-- 请求池级别的错误隔离
-
-### 监控和日志
-
-#### 1. 调试日志
-
-系统提供详细的调试日志,包括:
-- 分片上传状态
-- 文件合并过程
-- 错误信息追踪
-
-#### 2. 性能监控
-
-- 上传速度统计
-- 分片成功率
-- 系统资源使用情况
-
-### 故障排除
-
-#### 1. 常见问题
-
-**Q: 上传大文件时出现内存不足**
-A: 检查分片大小配置,建议设置为 1-5MB
-
-**Q: 分片上传后文件合并失败**
-A: 检查磁盘空间和文件权限
-
-**Q: 秒传功能不工作**
-A: 确认前端哈希算法与后端一致
-
-#### 2. 日志分析
-
-查看服务器日志获取详细错误信息:
-```bash
-# 启动时查看详细日志
-v run chunk_upload_example.v
-```
-
-### 扩展功能
-
-#### 1. 云存储集成
-
-可以扩展支持:
-- AWS S3
-- 阿里云 OSS
-- 腾讯云 COS
-
-#### 2. 文件处理
-
-可以添加:
-- 图片压缩
-- 视频转码
-- 文档预览
-
-#### 3. 权限控制
-
-可以集成:
-- 用户认证
-- 文件权限
-- 访问控制
-
-#### 4. 双请求池系统
-
-详细文档请参考:
-- [双请求池系统详解](README_REQUEST_POOL.md) - 完整的系统设计和实现指南
-- [分片上传系统](README_CHUNK_UPLOAD.md) - 包含请求池的分片上传完整方案
-
-## 性能特性
-
-- **混合路由算法**:静态路由 O(1) 查找,动态路由正则匹配
-- **LRU 缓存**:自动缓存路由匹配结果
-- **Trie 路由树**:支持复杂路径匹配
-- **内存优化**:使用指针和堆分配优化性能
-- **分片上传优化**:分片大小记录文件,避免遍历文件计算总大小(O(1) vs O(n))
-
-## 贡献
-
-欢迎提交 Issue 和 Pull Request!
+- [分片上传系统](README_CHUNK_UPLOAD.md)
+- [请求池系统](README_REQUEST_POOL.md)
+- [认证系统](README_AUTH_SYSTEM.md)
+- [数据库模块](README_DATABASE.md)
+- [性能测试](README_BENCHMARK.md)
## 许可证
MIT License
-