643 Commits

Author SHA1 Message Date
xfy
f12ffd180f chore: release v0.4.0
- Update CHANGELOG.md for v0.4.0
- Update Makefile FALLBACK_VERSION to 0.4.0
- Fix lint warnings (godoc comments, goconst)
- Clean up code formatting
v0.4.0
2026-06-09 15:59:36 +08:00
xfy
503daf65d3 perf(loadbalance): add benchmarks for Least Time and Sticky
- Benchmark Select and Record operations
- Concurrent benchmark for realistic load testing
- Baseline performance:
  - LeastTime.Select: ~33ns/op, 0 allocs
  - LeastTime.Record: ~5.6ns/op, 0 allocs
  - StickySession.Select: ~205ns/op (with cookie lookup)
2026-06-08 18:21:03 +08:00
xfy
ef871f1d39 test(loadbalance): add integration tests for Least Time and Sticky
- Verify Least Time picks faster target consistently
- Verify Sticky fallback when target becomes unhealthy
- Test cookie encoding and session persistence
2026-06-08 18:19:20 +08:00
xfy
e5885ce888 fix(proxy): correct response time recording for Least Time
- Record headerTime when header is received
- Record lastByteTime when response is complete
- Use correct timing calculations (headerReceived/connectEnd/responseEnd)
2026-06-08 18:17:08 +08:00
xfy
72f189bba8 feat(proxy): integrate Least Time and Sticky balancers
- Add least_time and sticky to createBalancerByName
- Implement response time recording for Least Time
- Support StickySession in target selector with request context
- StickySession auto-starts when created
2026-06-08 18:11:47 +08:00
xfy
3b6b70a491 fix(config): validate least_time default_time is not negative 2026-06-08 18:03:52 +08:00
xfy
cb1f86298e fix: add missing test coverage for Task 4 config integration
- Add validation tests for least_time and sticky configs
- Add algorithm tests for least_time and sticky
- Add SameSite validation in validateProxy
2026-06-08 18:01:21 +08:00
xfy
88a2c1fc1b feat(config): add Least Time and Sticky configuration support
- Add least_time and sticky to valid algorithms list
- Add LeastTimeConfig and StickyConfig structures
- Update default config generation with new options
- Add configuration validation for new fields
2026-06-08 17:57:06 +08:00
xfy
a73da4e14a fix(sticky): recreate stopCh on Start to support restart 2026-06-08 17:52:20 +08:00
xfy
0a5443f6cf fix(sticky): guard against double Stop, nil fallback, and multiple Start calls
- Add sync.Once to prevent double close of stopCh in Stop()
- Add nil fallback guard in NewStickySession (defaults to RoundRobin)
- Add atomic.Bool to make Start() idempotent
- Add tests for double Stop() and nil fallback scenarios
2026-06-08 17:47:37 +08:00
xfy
360fd0da9d fix(sticky): check cookie expiration in Select method
- Fix Select to check if cookie is expired before routing
- Add TestStickySession_ExpiredCookie test
- Expired cookies now trigger fallback + new cookie set
2026-06-08 17:40:54 +08:00
xfy
66752a47f0 fix(sticky): fix cookie format, shard keying, and tests
- Encode cookie as base64(target_url + | + timestamp) per spec
- Use cookie value (not targetURL) for shard key and session map keys
- Add missing sticky.Start() calls in tests
- Fix time precision in cookie encode/decode tests
2026-06-08 17:36:41 +08:00
xfy
f69a11ea05 feat(loadbalance): implement Session Sticky balancer
- Add 256-shard lock map for concurrent session routing
- Cookie-based session persistence with base64 encoding
- TTL expiration with background cleanup goroutine
- Support Secure, HttpOnly, SameSite cookie attributes
- Fallback to configured balancer when session target unavailable
2026-06-08 17:30:06 +08:00
xfy
fa95b2a76e feat(loadbalance): implement Least Time balancer
- Add atomic EWMA Stats field to Target
- Implement LeastTime balancer with header_time and last_byte metrics
- Support Select and SelectExcluding with zero-lock design
- Add ResponseTimeRecorder interface for proxy integration
2026-06-08 17:21:20 +08:00
xfy
c6bb75cffe feat(loadbalance): add atomic EWMA statistics core
- Zero-lock atomic EWMA implementation using fixed-point arithmetic
- Supports header_time and last_byte_time tracking
- Concurrent-safe with CAS retry loop
2026-06-08 17:13:08 +08:00
xfy
a04dadbe16 feat(examples): add FreeBSD deployment examples 2026-06-05 17:21:26 +08:00
xfy
c847f6036d chore: release v0.3.0 v0.3.0 2026-06-05 14:24:39 +08:00
xfy
85ae7747b8 fix(integration): remove calls to removed proxy.Start/Stop methods 2026-06-05 14:24:34 +08:00
xfy
989a572467 docs(skills): add release workflow skill 2026-06-05 14:02:20 +08:00
xfy
93c0c151d0 fix(lua): wait for SchedulerLoop exit before closing LState; lock cleanupResources 2026-06-05 13:48:04 +08:00
xfy
4789265ca8 fix: add synchronization for concurrent access in server/app/http3/stream 2026-06-05 12:31:41 +08:00
xfy
5e3196c37e fix: resolve race conditions in handler sendfile and lua cosocket tests 2026-06-05 12:31:39 +08:00
xfy
f73a761632 fix(server): protect accessLogMiddleware and accessControl from concurrent writes 2026-06-05 11:49:19 +08:00
xfy
76257a7859 fix(lua): add schedulerMu to protect scheduler LState and callback queue 2026-06-05 11:38:52 +08:00
xfy
2be04f3fb9 fix(lua): add mutex protection for TCPSocket.currentOp in async methods 2026-06-05 11:35:20 +08:00
xfy
170e0f1942 feat(Makefile): add freebsd and openbsd build targets 2026-06-05 10:17:58 +08:00
xfy
0db14c239c chore(Makefile): optimize targets and fix inconsistencies
- Auto-detect VERSION from git tags with fallback
- Extract mkdir as order-only prerequisite to eliminate duplication
- Add PERF_GCFLAGS/PERF_ASMFLAGS to cross-platform builds and install
- Merge bench-regression into bench-check, unify file naming
- Fix bench scope and sampling consistency (internal/ only, -run=^$)
- Fix test-cover scope to avoid un-tagged integration/e2e code
- Fix deprecated go get -u ./... to go get -u
- Add clean-mod target, clean benchmark artifacts in clean
- Remove phantom build-prod/build-perf from help
- Split docker long line for readability
- Add .PHONY declarations for all targets
2026-06-05 10:15:21 +08:00
xfy
d82afa3233 Update readme 2026-06-04 13:29:45 +08:00
xfy
8757f0d5cb chore: add docs/plans/ to .gitignore 2026-06-04 11:31:44 +08:00
xfy
31faf77fcc style: add doc comments for exported hash and utils functions
Fix revive lint warnings for FNV64a, FNV64aBytes, BytesContainsFold.
2026-06-04 11:17:08 +08:00
xfy
2be6b67d0b fix(server): release MatchResult back to pool after use
Add matcher.ReleaseMatchResult(result) in the base handler to prevent
sync.Pool object leak. Every Match() call acquires from pool but the
caller never returned objects, causing unbounded pool growth.
2026-06-04 11:14:32 +08:00
xfy
10f16bfda9 test(ssl): update extractPEMBlock tests for DER output
Verify returned bytes are parseable by x509.ParseCertificate instead
of checking raw PEM text markers.
2026-06-04 11:14:23 +08:00
xfy
434ac0b114 fix(ssl): use encoding/pem for DER extraction in extractPEMBlock
Replace manual PEM text scanning with pem.Decode(). Returns proper
DER-encoded bytes instead of raw PEM text, fixing potential TLS
handshake failures with certificate chains.

Remove unused findMarker and matchMarker helpers.
2026-06-04 11:14:13 +08:00
xfy
197d0d2344 perf(security): reduce GeoIP lookups and deduplicate trusted proxy check
- Check(): single GeoIP LookupCountry call, result reused for both
  deny and allow checks. Removed goto label for structured flow.
- getClientIP(): single trusted proxy CIDR scan gates both
  X-Forwarded-For and X-Real-IP processing.
2026-06-04 11:09:29 +08:00
xfy
e535b9062c perf(gzip_static): pre-build extension set, use BytesContainsFold
- Pre-build extSet map for O(1) extension lookup instead of linear scan
- Replace bytes.ToLower allocation in supportsEncoding with
  utils.BytesContainsFold for case-insensitive encoding detection
2026-06-04 11:09:20 +08:00
xfy
e5fa9fe9de perf(compression): pre-compute MIME type byte slices for isCompressible
Add typesBytes and typesWildcardPrefix fields to Middleware, built once
at construction. isCompressible now uses pre-converted byte slices
instead of allocating []byte(t) per comparison per request.
2026-06-04 11:09:08 +08:00
xfy
bd97c05d0d test(matcher): update test callers for []byte Match/FindLongestPrefix 2026-06-04 11:06:09 +08:00
xfy
1eeab88c98 perf(server): pass ctx.Path() directly to Match, eliminate string alloc
Removes the string(ctx.Path()) conversion that caused one heap
allocation per request in the routing hot path.
2026-06-04 11:06:00 +08:00
xfy
aef0d8357b perf(matcher): change Match/FindLongestPrefix to accept []byte
Accept []byte directly instead of string, allowing callers to pass
fasthttp's ctx.Path() without string conversion. Internally uses
bytes.HasPrefix instead of strings.HasPrefix in radix tree search.
2026-06-04 11:05:49 +08:00
xfy
0a53622351 perf(proxy): pre-build cacheIgnoreSet, single-pass cache key, pool UpstreamTiming
Three optimizations in the proxy cache hot path:

- Pre-build cacheIgnoreSet map once at Proxy creation instead of
  per-response. Eliminates map allocation + linear scan per cached
  response.

- Compute cache key once per request via computeCacheKey() closure.
  Previously buildCacheKeyHash was called up to 5 times per request;
  now computed on first access and reused.

- Pool UpstreamTiming objects with sync.Pool. Eliminates one heap
  allocation per proxied request.
2026-06-04 10:57:38 +08:00
xfy
02775de641 perf(proxy): eliminate string allocations in isWebSocketRequest
Replace string(connection)/strings.EqualFold/strings.ToLower with
bytes.EqualFold and utils.BytesContainsFold. Removes 2-4 heap
allocations per proxied request.
2026-06-04 10:48:57 +08:00
xfy
613c5f8ff0 perf(utils): add BytesContainsFold for zero-allocation case-insensitive search
Reports whether a byte slice contains a subslice, case-insensitively,
without allocating (unlike bytes.Contains(bytes.ToLower(b), sub)).
2026-06-04 10:48:51 +08:00
xfy
83d4e5e860 perf(proxy): inline FNV-1a in buildCacheKeyHash/buildCacheKeyHashValue
Replaces fnv.New64a() with direct inline hash computation over
fasthttp's []byte slices, eliminating 1 allocation per cache key
computation and 1 []byte(":") allocation.
2026-06-04 10:45:55 +08:00
xfy
f7997ab5c4 perf(security): eliminate fnv.New64a() allocation in SlidingWindowLimiter.getBucket
Same inline FNV-1a optimization as RateLimiter.
2026-06-04 10:45:41 +08:00
xfy
bc6bfb5ac3 perf(security): eliminate fnv.New64a() allocation in RateLimiter.getShard
Replaces hash/fnv.New64a() + Write() + Sum64() with inline FNV-1a.
Removes 2 allocations per rate-limited request.
2026-06-04 10:45:25 +08:00
xfy
71bfb895e5 perf(loadbalance): delegate fnvHash64a to internal/hash
Eliminates code duplication, uses shared inline FNV-1a implementation.
2026-06-04 10:45:11 +08:00
xfy
c59d387451 perf(hash): add inline FNV-1a hash functions to internal/hash package
Zero-allocation alternative to hash/fnv.New64a(). Computes FNV-1a
inline without heap-allocating a hash.Hash64 object per call.
2026-06-04 10:45:04 +08:00
xfy
7f08b1387d test(security): 添加安全中间件覆盖测试(覆盖率 75.9% → 88.5%)
新建 internal/middleware/security/coverage_test.go,覆盖:

headers.go 全部函数(原 0% → 100%):
- applySecurityHeaders: 安全头部应用
- 应各种安全头部配置

Argon2id 密码哈希测试(原 0% → 100%):
- authenticateArgon2id: Argon2id 认证
- parseArgon2idHash: 哈希解析(有效/无效格式)
- parseUint32/parseUint8: 参数解析

GeoIPLookup.Close 测试(原 0% → 80%):
- 关闭已初始化的 GeoIP 查找器
- 重复关闭安全性

注:GeoIP 数据库加载和网络认证等函数需要外部资源,
由 integration 测试覆盖。
2026-06-04 08:33:49 +08:00
xfy
9ae7a2b8ef test(server): 添加服务器模块覆盖测试(覆盖率 78.6% → 83.3%)
新建 internal/server/coverage_test.go,覆盖:

GetTLSConfig 测试(原 66.7% → 100%):
- 完整 TLS 配置生成
- HSTS 头部设置
- 自动 HTTP→HTTPS 重定向

registerLuaRoutesWithLocationEngine 测试(原 12.5% → 87.5%):
- Lua 路由注册到 location engine
- 多路由注册
- 无 Lua 路由时的处理

注:start* 系列函数(startSingleMode、startMultiServerMode、startServer)
由于涉及真实网络监听,更适合由 integration/e2e 测试覆盖。
2026-06-04 08:33:39 +08:00
xfy
164589a9cc test(proxy): 添加代理模块低覆盖率函数测试(覆盖率 71.1% → 预计 >80%)
新建 internal/proxy/proxy_low_coverage_test.go,覆盖:

proxyDebugLog 测试(原 0%):
- 字符串/整数/布尔/错误/nil 值的调试日志
- 空键值对处理

ServeHTTP 测试(原 47.3%):
- GET/POST/PUT 真实后端转发
- 连接拒绝、超时、故障转移
- X-Accel-Redirect 内部重定向
- 可疑路径拦截
- 缓存存储/命中/stale
- 重定向重写、空 URL、查询参数

selectTarget 测试(原 46.7%):
- random 算法选择
- Lua 选择成功/回退

selectByLua 测试(原 39.1%):
- 有效脚本执行、未选择、无 ngx 表

backgroundRefresh 测试(原 41.9%):
- 缓存条目重新验证、请求错误

WebSocket 测试(原 15.4%):
- Hijack 失败、读取响应、升级拒绝
- 拨号目标成功/超时

DNS 解析测试(原 0%):
- Start 幂等性、解析器启动失败
- 刷新成功/错误、TTL 获取
- 默认端口处理

WebSocket 辅助函数测试:
- 头部配置、升级响应错误、连接关闭错误
2026-06-04 08:33:29 +08:00