195 lines
5.1 KiB
Markdown
195 lines
5.1 KiB
Markdown
# 代码审查修改记录
|
||
|
||
## 修改概述
|
||
|
||
本次代码审查发现了若干问题并进行了修复,主要涉及安全性、并发安全和代码质量方面的改进。
|
||
|
||
---
|
||
|
||
## 1. 安全性修复
|
||
|
||
### 1.1 修复 `FileExists` 函数错误处理 (handler/file.go)
|
||
|
||
**问题**:`FileExists` 函数在文件不存在时错误地返回 `os.IsExist(err)`,导致调用方无法正确区分"文件不存在"和其他错误。
|
||
|
||
**修复**:
|
||
```go
|
||
// 修改前
|
||
if err != nil {
|
||
return nil, os.IsExist(err), err // 错误:os.IsExist 用于判断错误是否"已存在"
|
||
}
|
||
|
||
// 修改后
|
||
if err != nil {
|
||
if os.IsNotExist(err) {
|
||
return nil, false, nil // 正确返回"不存在"
|
||
}
|
||
return nil, false, err
|
||
}
|
||
```
|
||
|
||
### 1.2 增强文件处理器路径遍历防护 (handler/file.go)
|
||
|
||
**问题**:原有代码仅检查 `../` 前缀,无法防止符号链接导致的路径遍历攻击。
|
||
|
||
**修复**:添加了符号链接解析和真实路径验证逻辑:
|
||
```go
|
||
// Resolve symlinks and clean path to prevent path traversal
|
||
realRoot, _ := filepath.EvalSymlinks(f.Root)
|
||
realPath, _ := filepath.EvalSymlinks(filepath.Dir(rPath))
|
||
if realPath != realRoot && !strings.HasPrefix(realPath, realRoot+string(filepath.Separator)) {
|
||
return nil, errors.New("not permitted")
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 2. 并发安全修复
|
||
|
||
### 2.1 修复 `ProxyHandler.count` 竞态条件 (handler/proxy.go)
|
||
|
||
**问题**:`ProxyHandler.count` 使用 `int` 类型,在高并发环境下存在数据竞态。
|
||
|
||
**修复**:使用 `atomic.Int32` 替代 `int`,确保计数器操作的原子性:
|
||
```go
|
||
// 修改前
|
||
type ProxyHandler struct {
|
||
count int
|
||
}
|
||
|
||
// 修改后
|
||
type ProxyHandler struct {
|
||
count atomic.Int32
|
||
}
|
||
|
||
// 使用 Load()/Store() 方法进行原子操作
|
||
proxyIndex = p.count.Load()
|
||
p.count.Store(newCount)
|
||
```
|
||
|
||
---
|
||
|
||
## 3. 代码质量改进
|
||
|
||
### 3.1 使用 `strings.EqualFold` 替代 `strings.ToLower` 比较 (server/server.go)
|
||
|
||
**问题**:方法匹配时使用两次 `strings.ToLower` 调用效率较低。
|
||
|
||
**修复**:
|
||
```go
|
||
// 修改前
|
||
if route.Method != "" && strings.ToLower(route.Method) != strings.ToLower(r.Method) {
|
||
|
||
// 修改后
|
||
if route.Method != "" && !strings.EqualFold(route.Method, r.Method) {
|
||
```
|
||
|
||
### 3.2 简化 IP 访问控制逻辑 (server/middleware.go)
|
||
|
||
**问题**:使用循环遍历切片检查元素存在性,代码冗余。
|
||
|
||
**修复**:使用 `slices.Contains` 和 `strings.Cut` 简化代码:
|
||
```go
|
||
// 修改前
|
||
clientIP := strings.Split(r.RemoteAddr, ":")[0]
|
||
for _, ip := range deniedIPs {
|
||
if ip == clientIP { ... }
|
||
}
|
||
|
||
// 修改后
|
||
clientIP, _, _ := strings.Cut(r.RemoteAddr, ":")
|
||
if slices.Contains(deniedIPs, clientIP) { ... }
|
||
```
|
||
|
||
---
|
||
|
||
## 4. 待修复问题(已知但本次未修改)
|
||
|
||
### 4.1 `MiddlewareLink.Clone()` 方法存在反向迭代 Bug
|
||
|
||
**问题**:该方法从后向前迭代 `list`,但 `Add` 方法总是将元素插入到 `Done` 之前,导致克隆的中间件链顺序反转。
|
||
|
||
**影响**:如果中间件顺序重要,克隆后的中间件链可能无法正常工作。
|
||
|
||
### 4.2 测试 `Test_RestMux_HandleFunc` 失败
|
||
|
||
**问题**:该测试在修改前后均失败,属于已有问题。
|
||
|
||
**原因**:路由匹配逻辑与 `RestMux.ServeHTTP` 的路由匹配实现不一致。
|
||
|
||
---
|
||
|
||
## 5. 文件变更清单
|
||
|
||
| 文件 | 修改类型 |
|
||
|------|---------|
|
||
| handler/file.go | 安全性修复 |
|
||
| handler/proxy.go | 并发安全修复 |
|
||
| server/server.go | 代码质量改进 |
|
||
| server/middleware.go | 代码质量改进 |
|
||
|
||
---
|
||
|
||
## 6. 新增功能:TCP代理服务器
|
||
|
||
### 6.1 功能概述
|
||
|
||
新增TCP代理服务器功能,支持在指定端口监听TCP请求并转发到指定服务器的指定端口。可以配置多个TCP代理。
|
||
|
||
### 6.2 新增文件
|
||
|
||
**handler/tcpproxy.go** - TCP代理处理器实现:
|
||
- `TcpProxyHandler` 结构体:管理TCP代理连接
|
||
- `NewTcpProxyHandler` 函数:创建新的TCP代理处理器
|
||
- `Start` 方法:启动TCP代理监听
|
||
- `Stop` 方法:停止TCP代理服务器
|
||
- `pipe` 方法:连接间数据转发
|
||
|
||
### 6.3 配置模型 (model/model.go)
|
||
|
||
新增 `TcpProxyConfig` 配置结构:
|
||
```go
|
||
type TcpProxyConfig struct {
|
||
Name string `json:"name"` // 代理名称
|
||
Listen string `json:"listen"` // 监听地址,格式如 "0.0.0.0:8080"
|
||
Target string `json:"target"` // 目标服务器地址,格式如 "192.168.1.1:3306"
|
||
Enabled bool `json:"enabled"` // 是否启用
|
||
}
|
||
```
|
||
|
||
### 6.4 配置示例
|
||
|
||
在 `config.json` 中添加TCP代理配置:
|
||
```json
|
||
{
|
||
"tcp_proxys": [
|
||
{
|
||
"name": "mysql-proxy",
|
||
"listen": "0.0.0.0:3307",
|
||
"target": "192.168.1.100:3306",
|
||
"enabled": true
|
||
},
|
||
{
|
||
"name": "redis-proxy",
|
||
"listen": "0.0.0.0:6380",
|
||
"target": "192.168.1.101:6379",
|
||
"enabled": true
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
### 6.5 服务器管理 (server/manager.go)
|
||
|
||
新增TCP代理服务器管理功能:
|
||
- `TcpProxyManager`:TCP代理处理器映射
|
||
- `AddTcpProxy`:注册TCP代理服务器
|
||
- `StartTcpProxies`:启动所有TCP代理服务器
|
||
- `StopTcpProxies`:停止所有TCP代理服务器
|
||
|
||
---
|
||
|
||
## 7. 构建验证
|
||
|
||
所有修改已通过 `go build ./...` 编译验证。
|