gohttp/changes.md

3.5 KiB
Raw Blame History

代码审查修改记录

修改概述

本次代码审查发现了若干问题并进行了修复,主要涉及安全性、并发安全和代码质量方面的改进。


1. 安全性修复

1.1 修复 FileExists 函数错误处理 (handler/file.go)

问题FileExists 函数在文件不存在时错误地返回 os.IsExist(err),导致调用方无法正确区分"文件不存在"和其他错误。

修复

// 修改前
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)

问题:原有代码仅检查 ../ 前缀,无法防止符号链接导致的路径遍历攻击。

修复:添加了符号链接解析和真实路径验证逻辑:

// 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,确保计数器操作的原子性:

// 修改前
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 调用效率较低。

修复

// 修改前
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.Containsstrings.Cut 简化代码:

// 修改前
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. 构建验证

所有修改已通过 go build ./... 编译验证。