42 Commits

Author SHA1 Message Date
xfy
3b2360162c refactor(utils): add unified ETag generation function
Extract duplicate generateETag function from handler/static.go and
cache/file_cache.go into internal/utils/etag.go. Both functions were
identical, using strconv.AppendInt for zero-allocation ETag generation.

- Create utils.GenerateETag(modTime, size) as the unified implementation
- Update handler/static.go to call utils.GenerateETag
- Update cache/file_cache.go to call utils.GenerateETag
- Remove unused strconv import from static.go

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-08 18:06:13 +08:00
xfy
3c96f12f74 feat(cache): store ContentType in FileEntry for cache hits
- Add ContentType field to FileEntry struct
- Update Set method signature to accept contentType parameter
- Use cached ContentType in static.go cache hit branches
- Update all test files to use new Set signature

This avoids redundant MIME type detection on cache hits,
reducing lock contention in mimeutil.DetectContentType.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 16:13:42 +08:00
xfy
b62a3f12da feat(handler): add autoindex module for directory listing
Add nginx-like autoindex functionality with three output formats:
- HTML: styled directory listing with sortable columns
- JSON: structured API-friendly output
- XML: machine-readable format

Configuration options:
- auto_index: enable/disable directory listing
- auto_index_format: output format (html/json/xml)
- auto_index_localtime: use local time instead of GMT
- auto_index_exact_size: show exact bytes vs human-readable

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 15:11:34 +08:00
xfy
8cc3fdef6f perf(handler): optimize static file serving performance
- Add pathPrefixLen for zero-allocation path stripping
- Precompute ETag in FileCache.Set, reuse on cache hits
- Add MIME LRU cache with O(1) operations using container/list
- Remove sharded cache (eager LRU was slower than single-lock)
- Add FileInfo cache to reduce os.Stat calls (TTL-only strategy)
- Adjust test expectations for normalized root path format

Benchmark results: Lookup 12.7µs → 10.6µs (16% improvement)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 14:17:56 +08:00
xfy
b1e1547e36 fix(lint): resolve errcheck and goconst issues
- Add nolint comments for sync.Pool.Get() type assertions (pool always returns valid pointers)
- Extract TLS version strings to constants in sslutil/tlsconfig.go
- Extract expires directive strings to constants in handler/static.go

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 13:41:15 +08:00
xfy
f145a8770e refactor: modernize code with Go 1.22+ features
Apply modern Go patterns across the codebase:
- Replace `interface{}` with `any` (Go 1.18+)
- Use `for range n` instead of `for i := 0; i < n; i++` (Go 1.22+)
- Replace `sort.Slice` with `slices.Sort` from slices package
- Simplify sync.WaitGroup patterns with errgroup where appropriate
- Add Makefile targets for modernize analyzer

Total: 84 files updated, net reduction of 79 lines

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 10:37:45 +08:00
xfy
41288a560f test(cache): FileCache Set 分配热点专项测试
追踪 Set 新建/更新/淘汰三种路径的分配来源:
- SetNew: 3 allocs/op (目标 ≤1,待优化)
- SetUpdate: 1 allocs/op (已达标)
- Eviction: 3 allocs/op (待优化)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 10:36:22 +08:00
xfy
9895fb4158 test(cache): 分片缓存原型与扩展性对比测试
- 新增 ShardedFileCache 实现(16 分片,独立锁)
- 添加 BenchmarkFileCacheSharded 对比测试
- Benchmark 结论:当前竞争轻微,单锁扩展性更好
  - 单锁 8核: 45 ns/op
  - 分片 8核: 201 ns/op(hash 计算开销)

分片缓存保留为原型,暂不替换主实现。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 09:48:08 +08:00
xfy
58ed02ceac perf(cache): FileEntry 池化减少 GC 压力
- 添加 entryPool sync.Pool 复用 FileEntry 结构体
- Set 新建路径使用 pool.Get() 获取条目
- removeEntry 重置条目后 pool.Put() 回池
- 添加 BenchmarkFileCacheSet_Pooled 对比测试

Benchmark 结果: steady-state 4 allocs/op
(entry 复用生效,time.Now/list.Element/map 分配不可避免)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 09:39:18 +08:00
xfy
11e22c80b8 perf: 零分配优化与 Dial timeout 支持
- 添加 b2s/s2b 零分配字节-字符串转换工具函数
- WebSocket 数据转发使用 sync.Pool 复用 32KB buffer
- 条件化 Debug 日志避免非 Debug 级别的字符串分配
- 缓存键哈希计算直接写入 []byte 避免 string 转换
- 使用 bytes.EqualFold 替代 strings.ToLower 进行大小写不敏感比较
- generateETag 使用 strconv.AppendInt 避免 fmt.Sprintf
- 支持 Dial timeout 配置,区分 TCP 连接建立和总连接超时
- MaxConnsPerHost 默认值改为 512(fasthttp 推荐)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-28 20:11:20 +08:00
xfy
cf2fcca7e8 refactor: 提取公共逻辑、消除重复代码、加强错误处理
- 提取 App 公共逻辑到 app_common.go,消除 app.go/app_windows.go 重复定义
- 提取 Server 生命周期/中间件/路由逻辑到独立文件(lifecycle.go/middleware_builder.go/router.go)
- 提取 Proxy 缓存处理/头部修改/目标选择到独立模块
- 提取 CheckIPAccess/CheckTokenAuth 到 utils/httperror.go,消除 status/purge 重复实现
- 修复 stream 双向转发:任一方向完成立即关闭双端,避免连接泄漏
- 修复 SSL/TLS 中静默忽略错误的问题,添加日志记录
- 统一日志消息为英文

💘 Generated with Crush

Assisted-by: GLM 5.1 via Crush <crush@charm.land>
2026-04-28 18:00:48 +08:00
xfy
179090fa34 fix(security): 修复 2 个 CRITICAL + 6 个 HIGH 安全与代码质量问题
安全修复:
- ConnLimiter Acquire() TOCTOU 竞态: atomic.AddInt64 替代 loadInt64+addInt64
- Cache Purge token 时序侧信道: 改用 subtle.ConstantTimeCompare
- Lua Cosocket SSRF: 新增 ip_guard 两层 IP 检查(字面量+解析后),拒绝私有/回环地址
- X-Accel-Redirect 路径遍历: urlpath.Clean + 前缀拒绝(/internal/ /admin/)
- CRLF 注入: containsCRLF 校验变量展开后的 header 值,logging.Warn 可观测
- Proxy URI 注入: bytes.ContainsAny 检查 path 中的 @\r\n 危险字符

代码质量:
- disk_cache.go Set() 7 处静默 return 改为 logging.Error 日志记录
- config.go 从 2392 行拆分为 9 个按域文件(config/server/proxy/security/ssl/cache/performance/monitoring/variable)

验证: go build + vet + golangci-lint(0 issues) + test(83.2% 无回归) + race detector 全部通过

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-28 10:13:47 +08:00
xfy
5574339d28 test: 完善测试覆盖率和 E2E 测试场景
Phase 1: 单元测试补充
- 新增 config/loader_test.go,覆盖配置加载、include 合并、循环检测
- 补充 cache/cache_test.go,测试 RefreshCachedAt、DeleteByPatternWithMethod
- 补充 handler/static_test.go,测试 SetExpires、setCacheHeaders、parseExpires

Phase 2: E2E 测试扩展
- 新增 ratelimit_e2e_test.go,测试请求限流功能
- 新增 compression_e2e_test.go,测试 Gzip 压缩功能
- 新增 access_e2e_test.go,测试 IP 访问控制
- 新增 rewrite_e2e_test.go,测试 URL 重写和重定向

覆盖率提升: 82.3% -> 83.1%
E2E 测试用例: ~84 -> ~104 (+20)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-27 17:06:55 +08:00
xfy
308529d568 perf(cache): Get 方法读锁优先,double-check 升级写锁
将 FileCache.Get 的全局写锁改为读锁优先,仅在需要修改状态
(过期删除、CachedAt 迁移)时升级为写锁并 double-check,
减少读路径的锁竞争。近似 LRU 场景下 Get 不再更新访问时间。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-24 13:13:18 +08:00
xfy
1e38fe9e90 fix: 显式忽略不需要处理的错误返回值
对 os.Remove、conn.Close 等清理操作的返回值使用 _ 忽略,
避免 errcheck 静态检查告警。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-24 10:41:35 +08:00
xfy
0de153bb24 test(cache): 添加 stale_if_error 和 stale_if_timeout 测试
覆盖 ProxyCache、DiskCache、TieredCache 的 GetStale 方法,
测试场景包括:错误时可用、超时时可用、窗口过期不可用、未过期直接返回。
同步更新 NewProxyCache 调用签名。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-24 10:07:27 +08:00
xfy
8deda73b24 feat(cache): 添加 stale_if_error 和 stale_if_timeout 缓存接口和实现
在 CacheBackend 接口新增 GetStale 方法,支持上游错误时按错误类型
(超时 vs 其他错误)检查对应的 stale 窗口返回过期缓存。
ProxyCache、DiskCache、TieredCache 均实现该方法。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-24 10:05:39 +08:00
xfy
91d67ad384 refactor(cache,config): 代码清理和优化
- disk_cache: 忽略 filepath.Walk 和 Delete 返回值
- tiered_cache: 忽略 l1.Delete 返回值,删除未使用的 revalidate 函数
- config: 简化 multiplier 变量声明

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 13:34:51 +08:00
xfy
aae378433e feat(cache): 实现分层缓存架构
- 添加 CacheBackend 接口统一内存/磁盘缓存访问
- 实现 DiskCache 磁盘缓存后端,支持目录层级和原子写入
- 实现 TieredCache 分层缓存(L1 内存 + L2 磁盘)
- 修改 ProxyCache.Delete 返回 error 以符合接口
- 添加 CacheStats() 方法实现接口

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 13:15:02 +08:00
xfy
d933c1bd98 refactor(cache): 提取 MatchRule 辅助函数并扩展测试
将 MatchRule 拆分为 matchPath/matchMethod/matchStatus 三个辅助函数,
提升代码可读性和可测试性。新增测试覆盖:
- AcquireLockWithTimeout 锁超时机制
- RefreshTTL TTL 刷新功能
- SetValidationHeaders 验证头设置
- MatchRule 路径匹配变体(前缀/通配符/精确)
- min_uses 计数阈值

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 08:08:37 +08:00
xfy
0a7f7170d5 feat(cache,proxy): 增强代理缓存功能
- 添加 min_uses 阈值支持,请求次数达标才缓存
- 添加 cache_lock_timeout 配置,防止缓存锁无限等待
- 添加条件请求支持 (If-Modified-Since/If-None-Match),处理 304 响应
- 添加 background_update_disable 配置,允许禁用后台更新
- 添加 cache_ignore_headers 配置,缓存时忽略指定响应头
- 添加 methods 配置,指定可缓存的 HTTP 方法
- 改进路径匹配逻辑,支持精确匹配和通配符匹配

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-21 18:23:20 +08:00
xfy
2458ac1ed1 docs: 为其余模块添加标准化 godoc 注释
为剩余模块添加完整文档注释:
- app: 应用生命周期管理
- cache: 文件缓存
- config: 配置加载器
- handler: 静态文件处理和错误页面
- http2/http3: HTTP/2 和 HTTP/3 适配器
- loadbalance: 负载均衡算法和均衡器
- middleware: bodylimit、compression、rewrite、security
- mimeutil: MIME 类型检测
- netutil: URL 处理工具
- resolver: DNS 解析器
- server: 服务器升级处理
- ssl: SSL/TLS 和 OCSP
- stream: 流处理
- testutil: 测试工具
- variable: 变量池和 SSL 变量

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-20 10:59:53 +08:00
xfy
05a414d1bb feat(server): 添加 Purge 测试导出方法和安全检查
- purgeByPath/purgeByPattern 添加 nil server 检查
- 导出 PurgeByPathForTest/PurgeByPatternForTest 用于测试
- 添加 purge.go 全面单元测试覆盖
- 添加 cache purge 测试验证缓存清理功能

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 18:12:16 +08:00
xfy
bec8932561 feat(server): 添加缓存清理 API 支持
新增 PurgeHandler 处理器,支持:
- 按精确路径和通配符模式清理缓存
- HTTP 方法过滤(默认 GET)
- IP 白名单访问控制(CIDR/单 IP/localhost)
- Token 认证保护
- 三种启动模式路由注册

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 16:47:10 +08:00
xfy
8ed800271d test: 迁移基准测试循环到 Go 1.24 b.Loop() API
- 所有 *_bench_test.go 文件从 for i := 0; i < b.N; i++ 改为 for b.Loop()
- 部分测试文件从 for i := 0; i < N; ... 改为 for range N 或 for i := range N
- 涵盖模块: cache, handler, http2, http3, loadbalance, logging, lua,
  middleware/accesslog, middleware/bodylimit, middleware/rewrite,
  middleware/security, netutil, resolver, server, ssl, stream

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 13:50:15 +08:00
xfy
fa55bfd497 feat(cache): 添加缓存 TTL 新鲜度验证优化
在 FileEntry 中新增 CachedAt 字段记录缓存时间,实现 TTL 窗口内的缓存新鲜度验证:
- TTL 内跳过 ModTime 验证,减少 os.Stat 调用
- TTL 过期后验证 ModTime,文件未修改时刷新 CachedAt
- 默认 TTL 设置为 5 秒

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 17:53:51 +08:00
xfy
9f04b92a75 perf(cache): 优化 FileCache.Get() 锁粒度
移除 defer c.mu.Unlock(),在每个 early return 路径添加显式解锁,
在操作完成后立即释放锁,减少锁持有时间,提高并发性能。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-14 14:12:52 +08:00
xfy
d21e27fbac fix(lint): 修复 golangci-lint 错误 (119 -> 0 issues)
主要修复:
- errcheck: defer Close 使用 //nolint:errcheck,类型断言改为 ok 检查
- govet fieldalignment: 调整结构体字段顺序优化内存布局
- revive unused-parameter: 将未使用参数改为 _
- exhaustive: 添加缺失的 switch case 或 default
- goconst: 提取重复字符串为常量 (accessAllow, accessDeny 等)
- staticcheck SA9003: 修复空分支逻辑
- gofmt: 运行 gofmt -w 格式化
- nolintlint: 修复 nolint 注释格式

其他改进:
- 更新 .golangci.yml 配置,启用更严格的检查
- 移除未使用的代码和导入
- 简化测试辅助函数调用

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 16:15:31 +08:00
xfy
742e261fdc fix(lint): 删除 cache_test.go 中未使用的测试函数
移除 TestContains 和 TestContainsInt,对应的辅助函数已删除

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 13:15:26 +08:00
xfy
95b6119e34 refactor: 使用标准库 slices/maps 替代自定义函数
- 使用 slices.Contains 替代 contains/containsInt 函数
- 使用 maps.Copy 替代手动遍历复制
- 删除 internal/cache 中不再需要的辅助函数

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 13:15:13 +08:00
xfy
8b382606df Merge branch 'lint-fix' - resolve sendfile.go conflict
Conflict: sendfile.go (!linux build tag) was incorrectly modified to
include linuxSendfile and getSocketFd functions which already exist
in sendfile_linux.go.

Resolution: Keep HEAD version (simple fallback returning ENOTSUP) as
Linux implementation is properly separated in sendfile_linux.go.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 09:26:48 +08:00
xfy
931144dd08 refactor(cache): 统一路径匹配函数并增强通配符支持
- 删除 file_cache.go 中的 pathMatch() 函数
- 导出 purge.go 中的 MatchPattern() 函数
- 增强 MatchPattern() 支持中间通配符(如 /api/*/users)
- 使用 netutil.ExtractClientIPNet() 替代内联 IP 提取逻辑
- 适配 status 模块使用新的工具函数

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-10 11:20:19 +08:00
xfy
ce43d5c1d6 feat(cache): 新增缓存清理 API
支持通过 HTTP API 主动清理代理缓存,提供精确路径和通配符模式清理。
包含 IP 白名单和 Token 认证支持。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 17:58:18 +08:00
xfy
214ea4e9a6 perf(cache,proxy): 使用 uint64 哈希键优化代理缓存性能
- ProxyCache 的 entries 和 pending map 从 string 改为 uint64 键
- 新增 buildCacheKeyHash 使用 FNV-64a 计算哈希(零分配)
- 增加原始键碰撞验证,防止哈希冲突误匹配
- 更新相关测试和基准测试

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 15:03:10 +08:00
xfy
0979b60ff2 test(cache,loadbalance,proxy,benchmark): 新增核心模块基准测试
- cache: LRU Get/Set 性能测试
- loadbalance: 负载均衡算法性能测试
- proxy: 代理处理性能测试
- benchmark/tools: 负载生成器和模拟后端工具

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-07 17:06:08 +08:00
xfy
f2352ab9cc docs(config,stream,logging,handler,proxy,cache,server,ssl,middleware): 为核心模块添加详细 GoDoc 文档注释
- config: 为 Config 和所有子配置结构添加完整文档,包含使用示例和注意事项
- stream: 为负载均衡器和服务器添加详细的参数、返回值和功能说明
- logging: 为日志格式化和输出函数添加文档,说明支持的变量替换
- handler: 为路由器、静态文件和 sendfile 处理器添加文档
- proxy: 为健康检查器和代理功能添加完整文档
- cache/server/ssl/middleware: 补充相关模块的文档注释
- config.example.yaml: 添加可信代理配置、加密套件示例,更新压缩级别说明

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-07 15:36:09 +08:00
xfy
fc71cf4835 refactor(test): 统一测试文件错误处理风格
使用空白标识符忽略测试辅助函数中 Close、ReadFrom、Set 等返回值,
与主代码风格保持一致。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-03 17:37:05 +08:00
xfy
ac9153f09d fix(proxy,stream,server): Phase 8 问题修复与功能完善
- WebSocket 代理集成:handleWebSocket 现调用 ProxyWebSocket 实现
- 删除 UDP Stream 冗余代码:移除 udpListener 类型及相关测试
- 热升级监听器继承:改用 net.Listen + Serve 模式支持监听器传递
- 代码格式修复:注释格式调整、字段对齐、文件末尾换行符

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-03 14:28:00 +08:00
xfy
95030cd68a docs: 更新 AGENTS.md 文档
添加各模块的 AGENTS.md 文档文件,记录模块职责和代码结构

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-03 14:07:42 +08:00
xfy
80936ae66b feat(server,proxy,ssl,docs): 完成 Phase 7 功能完善
主要变更:
- WebSocket 代理支持 (internal/proxy/websocket.go)
- OCSP stapling 实现 (internal/ssl/ocsp.go)
- 监控状态端点 (internal/server/status.go)
- 新增 nginx 模块文档 (19-24)
- UDP 代理超时配置支持
- 多模块代码注释完善和功能增强

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-03 13:13:12 +08:00
xfy
9d24263918 feat(stream,server,handler): 实现 Phase 6 性能优化和热升级
新增功能:
- stream 模块: 流式传输支持,优化大文件和实时数据传输
- Goroutine 池: 限制并发数量,减少调度开销
- 优雅升级: 零停机热升级,继承父进程监听器
- sendfile: 零拷贝文件传输,大文件直接从内核传输

重构改进:
- App 结构体封装,支持热升级和信号处理
- 配置结构字段对齐和代码清理
- 完善错误处理和日志记录

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-03 10:39:22 +08:00
xfy
8b2f2521f1 feat(cache): 实现文件缓存模块
- 基于内存的缓存存储,支持过期时间
- LRU 淘汰策略,控制最大条目数
- 支持文件元数据缓存(大小、修改时间)
- 线程安全的读写操作
- 完整单元测试覆盖

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-03 10:11:31 +08:00