496 Commits

Author SHA1 Message Date
xfy
294ff73a7a test(variable): 添加变量系统覆盖测试(覆盖率 74.5% → 预计 >85%)
新建 internal/variable/builtin_coverage_test.go,覆盖低覆盖率函数:

formatRequestTime 测试(原 0%):
- 8 个子测试覆盖零值、毫秒、秒、大值等各种时间格式

SetGlobalVariables 测试(原 0%):
- 正常设置、空配置、覆盖、变量展开

EphemeralGet 测试(原 49.3%):
- 全局变量、回退、server_name、upstream_connect_time
- upstream_header_time、body_bytes_sent、request_time
- UserValue 响应信息、并发安全

GetSSLClientVerify 测试(原 40%):
- TLS UserValue 设置、对端证书存在、无效类型

init 注册验证测试(原 49.3%):
- 验证 16 个内置变量注册
- 验证 5 个 upstream 变量
- 验证 9 个 SSL 变量
- 验证 host/uri/request_uri/args/method 的 GetterBytes 注册
2026-06-04 08:21:48 +08:00
xfy
b0e795bc9a test(stream): 添加 Stream 服务器覆盖测试(覆盖率 57% → 预计 >75%)
新建 internal/stream/server_coverage_test.go,覆盖之前 0% 的函数:

TCP 监听测试:
- TestListenTCP_Success: 成功监听随机端口
- TestListenTCP_InvalidAddress: 无效地址返回错误

服务器启动测试:
- TestStart_NoListeners: 无监听器时启动
- TestStart_WithTCPListeners: 有 TCP 监听器时启动
- TestStart_AcceptConnections: 实际接受 TCP 连接

UDP 服务器测试:
- TestNewUDPServer_DefaultTimeout: 默认 60 秒超时
- TestNewUDPServer_CustomTimeout: 自定义超时

会话管理测试:
- TestSessionKey: 会话键生成正确性
- TestGetSession_NotExist/Existing: 会话查找
- TestRemoveSession/NotExist: 会话移除
- TestCleanupExpiredSessions_RemovesExpired/AllExpired: 过期清理

会话创建测试:
- TestGetOrCreateSession_NoHealthyTargets: 无健康目标
- TestGetOrCreateSession_ExistingSession: 复用现有会话
- TestGetOrCreateSession_NewSession: 创建新会话

响应处理测试:
- TestHandleBackendResponse_Timeout: 后端超时处理
- TestServe_ReceivesAndForwards: UDP 数据转发
- TestStartCleanupTicker_StopsOnSignal: 定时清理停止
2026-06-04 08:21:41 +08:00
xfy
8bb88e8898 test(http3): 完善 HTTP/3 服务器测试(覆盖率 46% → 93.1%)
补充 server_test.go 中未实现的测试用例:

新增测试:
- TestNewServer_TableDriven: 表驱动验证所有 NewServer 错误/成功路径
- TestNewServer_VerifyInternalFields: 验证服务器内部字段初始化
- TestStart_AlreadyRunning: 重复启动返回 "server already running"
- TestStart_InvalidListenAddress: 无效监听地址返回错误
- TestStart_Success: 绑定随机端口并验证运行状态
- TestStart_EmptyListenAddress: 空地址回退到 :443(无权限时 skip)
- TestStart_QUICConfigDefaults: 零值/自定义 MaxStreams、IdleTimeout、0RTT
- TestStart_MultipleStartsAndStops: start → stop → start 生命周期循环
- TestStop_NotRunning: 空闲服务器 stop 为空操作
- TestStop_Running: stop 正确设置 running = false
- TestStop_CalledMultipleTimes: 重复 stop 安全
- TestStartStop_Lifecycle: 完整生命周期状态断言
2026-06-04 08:21:32 +08:00
xfy
f26a4a7949 test(sslutil): 为 tlsconfig.go 添加全面单元测试(覆盖率 29.2% → 预计 >85%)
添加 internal/sslutil/tlsconfig_test.go,覆盖所有 TLS 配置函数:

- TestParseTLSVersions (16 子测试): 空/nil、仅 TLS1.2、仅 TLS1.3、
  混合、大小写不敏感、TLS1.0/1.1 拒绝、未知版本错误、重复项
- TestParseMinTLSVersion (9 子测试): TLS1.2/1.3、默认值、
  大小写、首次匹配优先、未知版本回退
- TestParseCipherSuites (16 子测试): OpenSSL 名称、Go 标准名称、
  TLS1.3 密码套件、未知/不安全错误、混合有效无效
- TestParseCipherSuitesLenient (10 子测试): 有效/跳过未知/跳过不安全/
  全无效返回 nil/混合
- TestIsInsecureCipher (4 子测试): 8 个不安全 ID 全部识别、
  安全 ID 正确排除
- TestDefaultCipherSuites (4 子测试): 非空、全部安全、
  包含预期套件、每次返回新切片
- TestTLSVersionMap (3 子测试): 键/值/条目数验证
- TestCipherNameToID_Consistency: OpenSSL↔Go 名称映射一致性
2026-06-04 08:13:42 +08:00
xfy
a836152836 test(utils): 为 utils 包添加全面单元测试(覆盖率 4.6% → 预计 >70%)
添加三个新测试文件:

bytes_test.go - 字节/字符串零拷贝转换测试:
- TestB2s: nil 切片、空切片、ASCII、UTF-8、特殊字符
- TestB2s_ZeroAlloc: 验证内存共享(指针比较)
- TestS2b: 空字符串返回 nil、正常转换
- TestS2b_ZeroAlloc: 验证内存共享
- TestB2s_S2b_RoundTrip: 往返转换正确性,包括二进制数据

etag_test.go - ETag 生成测试:
- TestGenerateETag: 表驱动测试,零时间、大尺寸、负值
- TestGenerateETag_Format: 验证引号包裹的 hex-hex 格式
- TestGenerateETag_Deterministic: 相同输入产生相同输出
- TestGenerateETag_DifferentInputs: 不同输入产生不同输出

ipallowlist_test.go - IP 白名单测试:
- TestParseIPAllowList: nil、空、CIDR、单 IP、localhost、无效输入
- TestParseIPAllowList_Localhost: 验证 127.0.0.1/32 + ::1/128 展开
- TestParseIPAllowList_SingleIPv4/IPv6: /32 和 /128 自动转换
- TestParseCIDR/TestParseCIDR_Invalid: 有效/无效 CIDR 和单 IP
- TestIPInAllowList: 匹配/不匹配及边界情况
- TestParseIPAllowList_Integration: 端到端解析+检查
2026-06-04 08:13:34 +08:00
xfy
d6ee721bc8 test(adapter): 为 adapter 包添加完整单元测试(覆盖率 0% → 预计 >80%)
添加 internal/adapter/common_test.go,覆盖 CommonAdapter 的所有公开方法:

- TestDefaultBodyThreshold: 验证 DefaultBodyThreshold 常量值
- TestNewCommonAdapter: 验证构造函数返回非空实例及 CtxPool 初始化
- TestResetContext: 验证请求/响应/用户值状态重置
- TestResetContext_DisableNormalizing: 验证头部规范化禁用
- TestStreamRequestBody: 表驱动测试覆盖 nil body、NoBody、空体、
  小体(≤64KB)、阈值体、大体(>64KB)、未知长度
- TestStreamRequestBody_ReadError: 读取错误不 panic
- TestStreamRequestBody_PartialReadError: 部分读取错误时保留已读数据
- TestGetContext/PutContext: Pool 获取/归还正确性
- TestGetContext_PutAndGet: 完整的 get-put-get 循环
- TestConcurrentPoolAccess: 100 goroutine 并发安全
- TestConcurrentStreamRequestBody: 50 goroutine 并发流式读取
2026-06-04 08:13:25 +08:00
xfy
8e00e63972 chore: fix lint issues from performance optimization
- errcheck: check type assertions from sync.Pool.Get() in
  loadbalance/balancer.go and matcher/radix.go
- errcheck: check type assertion from list.Element.Value in
  resolver/resolver.go evictLRULocked
- revive: add doc comment for exported ReleaseMatchResult function
2026-06-04 00:22:45 +08:00
xfy
7fe1ca6bec perf(loadbalance): eliminate double-lock in ConsistentHash with atomic.Bool rebuild guard
SelectByKey and SelectExcludingByKey previously had a RLock→RUnlock→
rebuildCircle(Lock)→RLock pattern when the hash ring was empty. Under
cold-start concurrency, multiple goroutines could trigger simultaneous
rebuild attempts.

Add atomic.Bool 'rebuilt' flag with ensureRebuilt() check before any
RLock acquisition:
- Fast path: atomic load returns true → skip rebuild, proceed to RLock
- Cold start: first caller rebuilds and sets flag, subsequent callers
  see the flag and skip rebuild
- Rebuild() explicitly resets the flag for explicit ring invalidation

Eliminates the RLock→Unlock→Lock→RLock transition entirely. The ring
is guaranteed ready before RLock is acquired.
2026-06-04 00:20:43 +08:00
xfy
c6e7091089 perf(loadbalance): eliminate per-request allocations in filterHealthy with sync.Pool
filterHealthy() allocated 2 slices (available + backups) per call.
filterHealthyAndExclude() allocated 3 (adds excludeSet map).
IPHash allocated fnv.New64a() object per call.
All triggered on every request's LB selection.

Changes:
- Add filterContext struct holding reusable buffers, managed by sync.Pool
- Replace filterHealthy → filterInto (writes into pooled buffers)
- Replace filterHealthyAndExclude → filterIntoExcluding (pooled buffers)
- Add inline fnvHash64a() to avoid fnv.New64a() heap allocation
- Update all 6 balancer algorithms (RoundRobin, WeightedRoundRobin,
  LeastConnections, IPHash, Random, ConsistentHash) to use pooled
  filterContext via acquire/release pattern
- ConsistentHash.SelectExcludingByKey also uses pool for targetSet
- Remove buildExcludeSet (merged into filterIntoExcluding)

Result: allocs/op reduced from 2-3 to 0-1 on all LB Select paths.
2026-06-04 00:19:04 +08:00
xfy
e44cfc7128 perf(handler): eliminate read-lock upgrade in FileInfoCache.Get with approximate LRU
FileInfoCache.Get previously acquired TWO locks on every cache hit:
1. RLock → check existence + TTL
2. Release RLock → Lock → MoveToFront (LRU update) → Unlock

The MoveToFront on every hit forced a read-to-write lock upgrade,
creating contention under concurrent reads.

Apply approximate LRU: skip MoveToFront on Get (read) path entirely.
LRU position is only updated in Set (write) path. This is the same
pattern already used by internal/cache/file_cache.go.

Result: Get fast path reduced from 2 lock acquisitions to 1 RLock.
TTL-expired entries still use double-check locking for safe removal.
2026-06-04 00:13:29 +08:00
xfy
12caed5d4e perf(resolver): replace slice-based LRU with container/list for O(1) operations
DNS resolver LRU cache used []string slice for access ordering:
- moveToFrontLocked: O(n) linear scan + slice重组 per cache update
- storeCache held exclusive write lock during entire O(n) operation,
  blocking all concurrent reads

Replace with container/list + map[string]*list.Element:
- storeCache: O(1) MoveToFront via list.Element pointer
- evictLRULocked: O(1) Back() + Remove()
- DeleteCacheEntry: O(1) instead of O(n) scan

This matches the LRU pattern already used by FileCache and
FileInfoCache. Write lock duration reduced from O(n) to O(1),
significantly reducing read contention under mixed workloads.
2026-06-04 00:13:10 +08:00
xfy
ba8c746a2e perf(matcher): eliminate heap allocations in RadixTree search with sync.Pool
RadixTree.searchLongest previously allocated &MatchResult{} on the
heap every time it encountered a handler-bearing node during tree
traversal — potentially N allocations per lookup with only 1 surviving.

Changes:
- searchLongest now tracks best *RadixNode (stack pointer) instead of
  allocating MatchResult at every handler node
- FindLongestPrefix allocates a single pooled MatchResult via sync.Pool
  only when returning a match
- Add ReleaseMatchResult() for callers to return MatchResult to pool
- LocationEngine.Match releases pooled results after use

Result: 0 B/op, 0 allocs/op on tree traversal benchmarks (sequential
and parallel).
2026-06-04 00:12:52 +08:00
xfy
d03c180f62 perf(loadbalance): replace failMu mutex with atomic operations in Target
Remove sync.Mutex from Target's failure tracking hot path:
- failCount int64 → atomic.Int64
- failedUntil int64 → atomic.Int64
- IsAvailable(): Load() instead of Lock/Unlock, eliminating mutex
  from every per-target check in every LB Select() call
- RecordFailure(): Add(1) + Store() instead of Lock/Unlock
- RecordSuccess(): Store(0) instead of Lock/Unlock

This removes the only mutex acquisition in the load balancing
selection path. Every Select() call iterates targets and calls
IsAvailable() on each — previously acquiring failMu per target
when MaxFails > 0. Now fully lock-free.
2026-06-04 00:12:29 +08:00
xfy
2ad056d0ca fix(config): supplement missing fields and fix comments in -g template
Add missing fields to GenerateConfigYAML output:
- proxy.timeout.dial (TCP dial timeout)
- health_check.slow_start and health_check.match (status/body/headers)
- proxy.buffering.buffers (multi-buffer config)
- lua.scripts[].route and route_type (routing mode)

Fix coroutine_stack_size comment to show actual default (64).
2026-06-04 00:04:13 +08:00
xfy
6612819f3a chore: remove stale AGENTS.md files, rewrite root AGENTS.md 2026-06-03 23:47:29 +08:00
xfy
29752f62bd fix: resolve golangci-lint issues across multiple packages
- stream: fix atomic.Int64 usage in tests and benchmarks
- server: fix errcheck, goconst ("tcp" -> constant), and govet shadow
- app: add missing ServerModeAuto case in requiresFullRestart
- lua: fix nolintlint unused directive warnings
- proxy: use `any` instead of `interface{}`
2026-06-03 18:17:07 +08:00
xfy
6f17bbad7e chore: remove trailing blank lines and clean up whitespace 2026-06-03 18:08:34 +08:00
xfy
5ee83f6a69 refactor: extract common functions from server startup modes 2026-06-03 18:03:23 +08:00
xfy
c1796dadc5 refactor: eliminate redundant switch blocks in router.go LocationEngine functions 2026-06-03 17:54:51 +08:00
xfy
6e481c36c5 refactor: simplify CheckIPAccess by reusing IPInAllowList 2026-06-03 17:53:00 +08:00
xfy
66f608f25b refactor: remove redundant generateETag wrappers, use utils.GenerateETag directly 2026-06-03 17:51:50 +08:00
xfy
ae3c167cd6 refactor: remove extractHostFromURL, use netutil.ParseTargetURL 2026-06-03 17:50:06 +08:00
xfy
041bc97578 refactor: remove unused code identified by staticcheck 2026-06-03 17:46:58 +08:00
xfy
13547ec63e fix: use defaultMIME fallback in DetectContentType 2026-06-03 17:44:16 +08:00
xfy
a3b4507be0 refactor: remove unused variable pool statistics dead code 2026-06-03 17:42:48 +08:00
xfy
a3bc453fbf refactor: remove unused stream SSL dead code 2026-06-03 17:41:14 +08:00
xfy
a919369ca4 refactor: remove dead code package internal/middleware/limitrate 2026-06-03 17:39:03 +08:00
xfy
5066a1a64c feat(utils): add GetInternalRedirectPath function 2026-06-03 16:39:36 +08:00
xfy
1a6b5f9166 Merge origin/master into master 2026-06-03 16:36:23 +08:00
xfy
856b46fd6d refactor: remove unused ParseTLSVersion and app setter tests
- Remove sslutil.ParseTLSVersion (singular): unused, ParseTLSVersions (plural) is used
- Remove TestSetPidFile and TestSetLogFile: trivial setter tests
2026-06-03 16:32:15 +08:00
xfy
d0867bfe3e refactor(lua): remove unused mock engine and filter writer subsystem
- Delete mock_engine.go (331 lines): unused MockLuaEngine/MockCoroutine
- Delete filter_writer.go (811 lines): DelayedResponseWriter not integrated
- Delete filter_phase_test.go (1466 lines): tests for removed filter code
- Total: 2608 lines of dead code removed
2026-06-03 16:31:18 +08:00
xfy
2734b04d8f refactor: remove 16.8k lines of dead code across all internal packages
- Delete unused files: tempfile subsystem, matcher variants, server/internal
- Remove 200+ unused functions across proxy, ssl, lua, http2/3, stream, variable
- Fix proxy test type errors (backgroundRefresh ctx→Request)
- Move bench/tools mock backend into internal/testutil
- Remove corresponding test functions for all deleted code
2026-06-03 16:15:43 +08:00
5dec128510
Merge pull request #3 from xfy911/improve-comments
docs: add comprehensive documentation comments
2026-06-03 15:41:36 +08:00
xfy911
a6152d4dc1 docs: add documentation comments for method implementations and test utilities
- Add GoDoc for Warning.String, ParseError.Error
- Add GoDoc for ngxReqAPILayer.String, Phase.String, SocketState.String
- Add GoDoc for ConflictError.Error
- Add GoDoc for noopResolver methods (LookupHost, LookupHostWithCache, Refresh, Start, Stop, Stats)
- Add GoDoc for load balancer Select methods (roundRobin, weightedRoundRobin, ipHash)
- Add GoDoc for WithWSHeaders test utility
- Include author attribution (xfy)
2026-06-03 15:28:53 +08:00
xfy911
a136b07bb9 docs: add documentation comments for exported constants and variables
- Fix gjson/gjson.go package comments and constant documentation
- Fix internal/config/config.go constant documentation
- Fix internal/utils/httperror.go variable documentation
- Fix internal/matcher/matcher.go constant documentation
- Fix internal/middleware/compression/compression.go constant documentation
- Fix internal/middleware/limitrate/limitrate.go constant documentation
- Fix internal/middleware/rewrite/rewrite.go constant documentation
- Fix internal/middleware/security/access.go and auth.go constant documentation
- Fix internal/ssl/client_verify.go constant documentation
- Fix internal/variable/builtin.go and ssl.go constant documentation
- Fix internal/lua/api_log.go HTTP and log level constant documentation
- Fix internal/benchmark/tools/tools.go constant documentation
- Include author attribution (xfy)
2026-06-03 15:28:53 +08:00
xfy911
fc1de2d445 docs: add documentation comments for more exported constants and variables
- Add comments for ssl/client_verify.go verification modes
- Add comments for security/auth.go hash algorithms
- Add comments for rewrite/rewrite.go flags
- Add comments for compression/compression.go algorithms
- Add comments for limitrate/limitrate.go strategies
- Include author attribution (xfy)
2026-06-03 15:28:53 +08:00
xfy911
396a466de1 docs: add documentation comments for exported constants and variables
- Add comments for lua/api_log.go HTTP status codes and log levels
- Add comments for variable/builtin.go and ssl.go constants
- Add comments for utils/httperror.go error variables
- Add comments for matcher/matcher.go location types
- Add comments for compression/compression.go algorithms
- Include author attribution (xfy)
2026-06-03 15:28:53 +08:00
xfy911
0b5b0eb747 docs(loadbalance): add package comments for loadbalance module
- Add package documentation for random load balancing file
- Include author attribution (xfy)
2026-06-03 15:28:53 +08:00
xfy911
57d4d3ba3c docs(app): add package comments for app module
- Add package documentation for app, app_common, import, app_windows, and testutil files
- Include author attribution (xfy)
2026-06-03 15:28:53 +08:00
xfy911
63ce8ecd2a docs(lua): add package comments for lua module
- Add package documentation for ip_guard file
- Include author attribution (xfy)
2026-06-03 15:28:53 +08:00
xfy911
4a53d3032a docs(utils): add package comments for utils module
- Add package documentation for internal, etag, and bytes files
- Include author attribution (xfy)
2026-06-03 15:28:53 +08:00
xfy911
c33adeb296 docs(middleware/limitrate): add package comments for rate limiter
- Add package documentation for limitrate and writer files
- Include author attribution (xfy)
2026-06-03 15:28:53 +08:00
xfy911
05f434d5e5 docs(server): add package comments for server module
- Add package documentation for router, internal, lifecycle, and middleware_builder files
- Include author attribution (xfy)
2026-06-03 15:28:53 +08:00
xfy911
dc54d3822f docs(proxy): add package comments for proxy module
- Add package documentation for target_selector, utils, validate,
  cache_handler, and header_modifier files
- Include author attribution (xfy)
2026-06-03 15:28:53 +08:00
xfy911
65aaba4e59 docs(config): add package comments for config module
- Add package documentation for cache, monitoring, performance, proxy,
  security, server, ssl, and variable config files
- Include author attribution (xfy)
2026-06-03 15:28:53 +08:00
xfy
8ae4add922 fix: address code review feedback
- proxyDebugLog: move Enabled() guard to call sites to avoid allocations
- proxyDebugLog: add default case for unsupported types
- static routes: remove unintended regex support to match original behavior
2026-06-03 14:29:30 +08:00
xfy
4678cb5483 refactor: use testutil helpers in server tests 2026-06-03 14:19:22 +08:00
xfy
8681472c4b refactor: use testutil helpers in proxy tests 2026-06-03 14:10:07 +08:00
xfy
094976df2b feat: add testutil package for proxy config helpers 2026-06-03 14:00:07 +08:00
xfy
1ce42c039b refactor: extract proxyDebugLog helper for repeated debug logging 2026-06-03 13:57:55 +08:00