refactor(variable): 重命名核心类型移除冗余前缀

VariableContext → Context
VariableStore → Store
ReleaseVariableContext → ReleaseContext (别名保留向后兼容)
提取硬编码字符串为命名常量 sslProtocolNone

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
xfy 2026-04-10 09:40:17 +08:00
parent 7a2b1d7e03
commit 0731dc46e4
7 changed files with 158 additions and 145 deletions

View File

@ -1,6 +1,7 @@
// builtin.go - 内置变量定义
// Package variable 提供 nginx 风格的内置变量支持,用于日志、代理和重写规则。
//
// 提供 18 个 nginx 风格的内置变量,用于日志、代理和重写规则。
// 包含 18 个内置变量常量、动态变量获取函数($arg_name、$http_name、$cookie_name
// 以及 Context 池管理。
//
// 作者xfy
package variable
@ -132,7 +133,7 @@ func init() {
})
// 9. $server_name - 服务器名称
// 注意:这个变量需要从 VariableContext 获取
// 注意:这个变量需要从 Context 获取
RegisterBuiltin(&BuiltinVariable{
Name: VarServerName,
Description: "服务器名称",
@ -167,7 +168,7 @@ func init() {
})
// 11. $status - HTTP 状态码
// 需要从 VariableContext 获取
// 需要从 Context 获取
RegisterBuiltin(&BuiltinVariable{
Name: VarStatus,
Description: "HTTP 响应状态码",
@ -182,7 +183,7 @@ func init() {
})
// 12. $body_bytes_sent - 响应体大小
// 需要从 VariableContext 获取
// 需要从 Context 获取
RegisterBuiltin(&BuiltinVariable{
Name: VarBodyBytesSent,
Description: "发送的响应体字节数",
@ -197,7 +198,7 @@ func init() {
})
// 13. $request_time - 请求处理时间
// 需要从 VariableContext 获取
// 需要从 Context 获取
RegisterBuiltin(&BuiltinVariable{
Name: VarRequestTime,
Description: "请求处理时间(秒)",
@ -215,7 +216,7 @@ func init() {
RegisterBuiltin(&BuiltinVariable{
Name: VarTimeLocal,
Description: "本地时间格式02/Jan/2024:15:04:05 +0800",
Getter: func(ctx *fasthttp.RequestCtx) string {
Getter: func(_ *fasthttp.RequestCtx) string {
return time.Now().Format("02/Jan/2006:15:04:05 +0800")
},
})
@ -224,7 +225,7 @@ func init() {
RegisterBuiltin(&BuiltinVariable{
Name: VarTimeISO8601,
Description: "ISO8601 格式时间",
Getter: func(ctx *fasthttp.RequestCtx) string {
Getter: func(_ *fasthttp.RequestCtx) string {
return time.Now().Format(time.RFC3339)
},
})

View File

@ -18,7 +18,7 @@ import (
)
// TestVariableInAccessLog 测试访问日志中的变量展开
func TestVariableInAccessLog(t *testing.T) {
func TestVariableInAccessLog(_ *testing.T) {
// 创建测试请求上下文
cfg := &config.LoggingConfig{
Access: config.AccessLogConfig{
@ -91,8 +91,8 @@ func TestVariableCompatibility(t *testing.T) {
// 设置响应信息(模拟日志场景)
variable.SetResponseInfoInContext(ctx, 201, 2048, 100000000) // 100ms
vc := variable.NewVariableContext(ctx)
defer variable.ReleaseVariableContext(vc)
vc := variable.NewContext(ctx)
defer variable.ReleaseContext(vc)
tests := []struct {
template string
@ -129,8 +129,8 @@ func TestVariableExpansionPerformance(t *testing.T) {
ctx.Request.Header.SetMethod("GET")
ctx.Request.Header.SetHost("api.example.com")
vc := variable.NewVariableContext(ctx)
defer variable.ReleaseVariableContext(vc)
vc := variable.NewContext(ctx)
defer variable.ReleaseContext(vc)
// 常见日志格式模板
template := "$remote_addr - $remote_user [$time_local] \"$request_method $request_uri $scheme\" $status $body_bytes_sent \"$http_user_agent\""
@ -160,8 +160,8 @@ func TestMixedVariableFormats(t *testing.T) {
ctx.Request.Header.SetMethod("GET")
ctx.Request.Header.SetHost("example.com")
vc := variable.NewVariableContext(ctx)
defer variable.ReleaseVariableContext(vc)
vc := variable.NewContext(ctx)
defer variable.ReleaseContext(vc)
tests := []struct {
template string
@ -188,8 +188,8 @@ func TestUndefinedVariableInIntegration(t *testing.T) {
ctx := &fasthttp.RequestCtx{}
ctx.Request.SetRequestURI("/test")
vc := variable.NewVariableContext(ctx)
defer variable.ReleaseVariableContext(vc)
vc := variable.NewContext(ctx)
defer variable.ReleaseContext(vc)
// 未定义变量应该保持原样
template := "$host $undefined_var $uri"
@ -213,14 +213,14 @@ func TestVariableContextReuse(t *testing.T) {
ctx2.Request.Header.SetHost("second.com")
// 使用第一个上下文
vc1 := variable.NewVariableContext(ctx1)
vc1 := variable.NewContext(ctx1)
result1 := vc1.Expand("$host$uri")
variable.ReleaseVariableContext(vc1)
variable.ReleaseContext(vc1)
// 复用(从池中获取)用于第二个上下文
vc2 := variable.NewVariableContext(ctx2)
vc2 := variable.NewContext(ctx2)
result2 := vc2.Expand("$host$uri")
variable.ReleaseVariableContext(vc2)
variable.ReleaseContext(vc2)
// 验证结果正确
if result1 != "first.com/first" {

View File

@ -1,6 +1,6 @@
// pool.go - VariableContext 池管理
// Package variable 提供 sync.Pool 用于复用 Context减少 GC 压力。
//
// 提供 sync.Pool 复用 VariableContext减少 GC 压力
// 包含池统计信息、Get/Put 包装方法和统计重置功能
//
// 作者xfy
package variable
@ -39,9 +39,9 @@ func GetPool() *sync.Pool {
return &pool
}
// PoolGet 从池中获取 VariableContext包装方法用于统计
func PoolGet(ctx *fasthttp.RequestCtx) *VariableContext {
vc := pool.Get().(*VariableContext)
// PoolGet 从池中获取 Context包装方法用于统计
func PoolGet(ctx *fasthttp.RequestCtx) *Context {
vc := pool.Get().(*Context)
// 初始化
vc.ctx = ctx
@ -67,8 +67,8 @@ func PoolGet(ctx *fasthttp.RequestCtx) *VariableContext {
return vc
}
// PoolPut 将 VariableContext 放回池中(包装方法,用于统计)
func PoolPut(vc *VariableContext) {
// PoolPut 将 Context 放回池中(包装方法,用于统计)
func PoolPut(vc *Context) {
if vc == nil {
return
}

View File

@ -31,6 +31,8 @@ const (
VarSSLClientNotAfter = "ssl_client_notafter"
VarSSLClientDNS = "ssl_client_s_dn"
VarSSLClientEmail = "ssl_client_email"
sslProtocolNone = "NONE"
)
// init 注册 SSL 变量
@ -125,12 +127,12 @@ func init() {
// - "NONE": 未提供证书
func GetSSLClientVerify(ctx *fasthttp.RequestCtx) string {
if ctx == nil {
return "NONE"
return sslProtocolNone
}
// 检查是否有 TLS 连接信息
if !ctx.IsTLS() {
return "NONE"
return sslProtocolNone
}
// 从 UserValue 获取验证状态(由连接处理器设置)
@ -145,7 +147,7 @@ func GetSSLClientVerify(ctx *fasthttp.RequestCtx) string {
return "SUCCESS"
}
return "NONE"
return sslProtocolNone
}
// GetSSLClientSerial 获取客户端证书序列号。
@ -283,7 +285,7 @@ func calculateFingerprint(raw []byte) string {
// - *pem.Block: 解析后的 PEM 块
// - []byte: 剩余数据
//
// nolint:unused // 保留用于未来 SSL 变量解析功能
//nolint:unused // 保留用于未来 SSL 变量解析功能
func parsePEMCertificate(pemData []byte) (*pem.Block, []byte) {
return pem.Decode(pemData)
}

View File

@ -25,8 +25,8 @@ import (
"github.com/valyala/fasthttp"
)
// VariableStore 变量存储接口
type VariableStore interface {
// Store 变量存储接口
type Store interface {
// Get 获取变量值
Get(name string) (string, bool)
// Set 设置变量值(用于自定义变量)
@ -40,8 +40,8 @@ type BuiltinVariable struct {
Getter func(ctx *fasthttp.RequestCtx) string
}
// VariableContext 变量上下文,绑定到请求
type VariableContext struct {
// Context 变量上下文,绑定到请求
type Context struct {
ctx *fasthttp.RequestCtx
store map[string]string // 自定义变量存储
cache map[string]string // 内置变量缓存
@ -57,10 +57,10 @@ type VariableContext struct {
upstreamHeaderTime float64 // 上游首字节时间(秒)
}
// pool 用于复用 VariableContext
// pool 用于复用 Context
var pool = sync.Pool{
New: func() interface{} {
return &VariableContext{
return &Context{
store: make(map[string]string),
cache: make(map[string]string),
}
@ -124,9 +124,9 @@ func GetBuiltin(name string) *BuiltinVariable {
return builtinVars[name]
}
// NewVariableContext 从池中获取 VariableContext并注入全局变量。
func NewVariableContext(ctx *fasthttp.RequestCtx) *VariableContext {
vc := pool.Get().(*VariableContext)
// NewContext 从池中获取 Context并注入全局变量。
func NewContext(ctx *fasthttp.RequestCtx) *Context {
vc := pool.Get().(*Context)
vc.ctx = ctx
vc.status = 0
vc.bodySize = 0
@ -153,8 +153,13 @@ func NewVariableContext(ctx *fasthttp.RequestCtx) *VariableContext {
return vc
}
// ReleaseVariableContext 释放 VariableContext 回池中
func ReleaseVariableContext(vc *VariableContext) {
// NewVariableContext 是 NewContext 的别名(向后兼容)
func NewVariableContext(ctx *fasthttp.RequestCtx) *Context {
return NewContext(ctx)
}
// ReleaseContext 释放 Context 回池中
func ReleaseContext(vc *Context) {
if vc == nil {
return
}
@ -171,20 +176,25 @@ func ReleaseVariableContext(vc *VariableContext) {
pool.Put(vc)
}
// ReleaseVariableContext 是 ReleaseContext 的别名(向后兼容)
func ReleaseVariableContext(vc *Context) {
ReleaseContext(vc)
}
// SetResponseInfo 设置响应信息(用于需要 status、body_bytes_sent、request_time 的场景)
func (vc *VariableContext) SetResponseInfo(status int, bodySize int64, durationNs int64) {
func (vc *Context) SetResponseInfo(status int, bodySize int64, durationNs int64) {
vc.status = status
vc.bodySize = bodySize
vc.duration = durationNs
}
// SetServerName 设置服务器名称
func (vc *VariableContext) SetServerName(name string) {
func (vc *Context) SetServerName(name string) {
vc.serverName = name
}
// SetUpstreamVars 设置上游变量
func (vc *VariableContext) SetUpstreamVars(addr string, status int, responseTime, connectTime, headerTime float64) {
func (vc *Context) SetUpstreamVars(addr string, status int, responseTime, connectTime, headerTime float64) {
vc.upstreamAddr = addr
vc.upstreamStatus = status
vc.upstreamResponseTime = responseTime
@ -193,7 +203,7 @@ func (vc *VariableContext) SetUpstreamVars(addr string, status int, responseTime
}
// Get 获取变量值(优先自定义变量,再查内置变量)
func (vc *VariableContext) Get(name string) (string, bool) {
func (vc *Context) Get(name string) (string, bool) {
// 1. 先查自定义变量
if v, ok := vc.store[name]; ok {
return v, true
@ -281,12 +291,12 @@ func (vc *VariableContext) Get(name string) (string, bool) {
}
// Set 设置自定义变量
func (vc *VariableContext) Set(name string, value string) {
func (vc *Context) Set(name string, value string) {
vc.store[name] = value
}
// evalBuiltin 求值内置变量
func (vc *VariableContext) evalBuiltin(name string) (string, bool) {
func (vc *Context) evalBuiltin(name string) (string, bool) {
builtin := builtinVars[name]
if builtin == nil || builtin.Getter == nil {
return "", false
@ -297,7 +307,7 @@ func (vc *VariableContext) evalBuiltin(name string) (string, bool) {
// Expand 展开模板字符串中的变量
// 支持 $var 和 ${var} 两种格式
// 对于未定义的变量,保持原样不变
func (vc *VariableContext) Expand(template string) string {
func (vc *Context) Expand(template string) string {
if template == "" {
return ""
}

View File

@ -30,8 +30,8 @@ func setupBenchmarkRequestCtx() *fasthttp.RequestCtx {
// 模板: "$remote_addr - $request_method"
func BenchmarkVariableExpandSimple(b *testing.B) {
ctx := setupBenchmarkRequestCtx()
vc := NewVariableContext(ctx)
defer ReleaseVariableContext(vc)
vc := NewContext(ctx)
defer ReleaseContext(vc)
template := "$remote_addr - $request_method"
@ -47,9 +47,9 @@ func BenchmarkVariableExpandSimple(b *testing.B) {
// "$remote_addr - [$time_local] \"$request_method $uri $args\" $status $body_bytes_sent"
func BenchmarkVariableExpandComplex(b *testing.B) {
ctx := setupBenchmarkRequestCtx()
vc := NewVariableContext(ctx)
vc := NewContext(ctx)
vc.SetResponseInfo(200, 1024, 1000000) // status, bodySize, durationNs
defer ReleaseVariableContext(vc)
defer ReleaseContext(vc)
template := "$remote_addr - [$time_local] \"$request_method $uri $args\" $status $body_bytes_sent"
@ -62,8 +62,8 @@ func BenchmarkVariableExpandComplex(b *testing.B) {
// BenchmarkVariableExpandMixed 测试混合 ${var} 和 $var 格式的展开性能。
func BenchmarkVariableExpandMixed(b *testing.B) {
ctx := setupBenchmarkRequestCtx()
vc := NewVariableContext(ctx)
defer ReleaseVariableContext(vc)
vc := NewContext(ctx)
defer ReleaseContext(vc)
template := "${remote_addr} - $request_method ${uri}?${args}"
@ -76,8 +76,8 @@ func BenchmarkVariableExpandMixed(b *testing.B) {
// BenchmarkVariableExpandNoVar 测试无变量模板的性能(快速路径)。
func BenchmarkVariableExpandNoVar(b *testing.B) {
ctx := setupBenchmarkRequestCtx()
vc := NewVariableContext(ctx)
defer ReleaseVariableContext(vc)
vc := NewContext(ctx)
defer ReleaseContext(vc)
template := "This is a plain string with no variables"
@ -93,8 +93,8 @@ func BenchmarkVariableContextPool(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
vc := NewVariableContext(ctx)
ReleaseVariableContext(vc)
vc := NewContext(ctx)
ReleaseContext(vc)
}
}
@ -104,8 +104,8 @@ func BenchmarkVariableContextPoolParallel(b *testing.B) {
b.RunParallel(func(pb *testing.PB) {
ctx := setupBenchmarkRequestCtx()
for pb.Next() {
vc := NewVariableContext(ctx)
ReleaseVariableContext(vc)
vc := NewContext(ctx)
ReleaseContext(vc)
}
})
}
@ -115,8 +115,8 @@ func BenchmarkVariableContextPoolParallel(b *testing.B) {
// 首次获取变量会求值并缓存,后续获取命中缓存。
func BenchmarkVariableGetCache(b *testing.B) {
ctx := setupBenchmarkRequestCtx()
vc := NewVariableContext(ctx)
defer ReleaseVariableContext(vc)
vc := NewContext(ctx)
defer ReleaseContext(vc)
// 预热缓存
_, _ = vc.Get("remote_addr")
@ -135,17 +135,17 @@ func BenchmarkVariableGetNoCache(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
vc := NewVariableContext(ctx)
vc := NewContext(ctx)
vc.Get("remote_addr")
ReleaseVariableContext(vc)
ReleaseContext(vc)
}
}
// BenchmarkVariableGetMultiple 测试获取多个内置变量的性能。
func BenchmarkVariableGetMultiple(b *testing.B) {
ctx := setupBenchmarkRequestCtx()
vc := NewVariableContext(ctx)
defer ReleaseVariableContext(vc)
vc := NewContext(ctx)
defer ReleaseContext(vc)
vars := []string{
"remote_addr", "request_method", "uri", "args",
@ -163,8 +163,8 @@ func BenchmarkVariableGetMultiple(b *testing.B) {
// BenchmarkVariableSetAndGet 测试设置和获取自定义变量的性能。
func BenchmarkVariableSetAndGet(b *testing.B) {
ctx := setupBenchmarkRequestCtx()
vc := NewVariableContext(ctx)
defer ReleaseVariableContext(vc)
vc := NewContext(ctx)
defer ReleaseContext(vc)
b.ResetTimer()
for i := 0; i < b.N; i++ {
@ -198,10 +198,10 @@ func BenchmarkExpandStringStaticWithLookup(b *testing.B) {
// 模拟完整访问日志格式,约 200 字符。
func BenchmarkVariableExpandLongTemplate(b *testing.B) {
ctx := setupBenchmarkRequestCtx()
vc := NewVariableContext(ctx)
vc := NewContext(ctx)
vc.SetResponseInfo(200, 4096, 15000000)
vc.SetServerName("api.example.com")
defer ReleaseVariableContext(vc)
defer ReleaseContext(vc)
template := "$remote_addr - [$time_local] \"$request_method $uri?$args\" $status $body_bytes_sent \"$http_referer\" \"$http_user_agent\" $request_time $server_name"

View File

@ -16,7 +16,7 @@ import (
)
// mockRequestCtx 创建测试用的 fasthttp.RequestCtx
func mockRequestCtx(t *testing.T) *fasthttp.RequestCtx {
func mockRequestCtx(_ *testing.T) *fasthttp.RequestCtx {
ctx := &fasthttp.RequestCtx{}
// 设置请求信息
@ -51,8 +51,8 @@ func TestBuiltinVariables(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ctx := mockRequestCtx(t)
vc := NewVariableContext(ctx)
defer ReleaseVariableContext(vc)
vc := NewContext(ctx)
defer ReleaseContext(vc)
value, ok := vc.Get(tt.varName)
if !ok && !tt.contains {
@ -76,8 +76,8 @@ func TestBuiltinVariables(t *testing.T) {
// TestExpandSimple 测试简单变量展开
func TestExpandSimple(t *testing.T) {
ctx := mockRequestCtx(t)
vc := NewVariableContext(ctx)
defer ReleaseVariableContext(vc)
vc := NewContext(ctx)
defer ReleaseContext(vc)
tests := []struct {
template string
@ -104,8 +104,8 @@ func TestExpandSimple(t *testing.T) {
// TestExpandBrace 测试花括号变量展开
func TestExpandBrace(t *testing.T) {
ctx := mockRequestCtx(t)
vc := NewVariableContext(ctx)
defer ReleaseVariableContext(vc)
vc := NewContext(ctx)
defer ReleaseContext(vc)
tests := []struct {
template string
@ -132,8 +132,8 @@ func TestExpandBrace(t *testing.T) {
// TestExpandMixed 测试混合格式展开
func TestExpandMixed(t *testing.T) {
ctx := mockRequestCtx(t)
vc := NewVariableContext(ctx)
defer ReleaseVariableContext(vc)
vc := NewContext(ctx)
defer ReleaseContext(vc)
tests := []struct {
template string
@ -157,8 +157,8 @@ func TestExpandMixed(t *testing.T) {
// TestExpandUndefined 测试未定义变量
func TestExpandUndefined(t *testing.T) {
ctx := mockRequestCtx(t)
vc := NewVariableContext(ctx)
defer ReleaseVariableContext(vc)
vc := NewContext(ctx)
defer ReleaseContext(vc)
tests := []struct {
template string
@ -183,8 +183,8 @@ func TestExpandUndefined(t *testing.T) {
// TestExpandEdgeCases 测试边界情况
func TestExpandEdgeCases(t *testing.T) {
ctx := mockRequestCtx(t)
vc := NewVariableContext(ctx)
defer ReleaseVariableContext(vc)
vc := NewContext(ctx)
defer ReleaseContext(vc)
tests := []struct {
template string
@ -212,8 +212,8 @@ func TestExpandEdgeCases(t *testing.T) {
// TestCustomVariable 测试自定义变量
func TestCustomVariable(t *testing.T) {
ctx := mockRequestCtx(t)
vc := NewVariableContext(ctx)
defer ReleaseVariableContext(vc)
vc := NewContext(ctx)
defer ReleaseContext(vc)
// 设置自定义变量
vc.Set("custom_var", "custom_value")
@ -234,8 +234,8 @@ func TestCustomVariable(t *testing.T) {
// TestCustomOverridesBuiltin 测试自定义变量覆盖内置变量
func TestCustomOverridesBuiltin(t *testing.T) {
ctx := mockRequestCtx(t)
vc := NewVariableContext(ctx)
defer ReleaseVariableContext(vc)
vc := NewContext(ctx)
defer ReleaseContext(vc)
// 设置同名自定义变量
vc.Set("host", "custom.host.com")
@ -250,8 +250,8 @@ func TestCustomOverridesBuiltin(t *testing.T) {
// TestResponseInfoVariables 测试响应相关变量
func TestResponseInfoVariables(t *testing.T) {
ctx := mockRequestCtx(t)
vc := NewVariableContext(ctx)
defer ReleaseVariableContext(vc)
vc := NewContext(ctx)
defer ReleaseContext(vc)
// 设置响应信息
vc.SetResponseInfo(200, 1024, 15000000) // 15ms
@ -345,8 +345,8 @@ func BenchmarkExpandSimple(b *testing.B) {
ctx.Request.Header.SetMethod("GET")
ctx.Request.Header.SetRequestURI("/test")
vc := NewVariableContext(ctx)
defer ReleaseVariableContext(vc)
vc := NewContext(ctx)
defer ReleaseContext(vc)
template := "$host $request_method $uri"
@ -365,8 +365,8 @@ func BenchmarkExpandComplex(b *testing.B) {
ctx.Request.Header.SetMethod("GET")
ctx.Request.Header.SetRequestURI("/api/v1/users?page=1&limit=10")
vc := NewVariableContext(ctx)
defer ReleaseVariableContext(vc)
vc := NewContext(ctx)
defer ReleaseContext(vc)
// 模拟日志格式
template := "$remote_addr - - [$time_local] \"$request_method $request_uri HTTP/1.1\" $status $body_bytes_sent"
@ -382,8 +382,8 @@ func BenchmarkExpandComplex(b *testing.B) {
// BenchmarkExpandNoVariable 基准测试:无变量字符串
func BenchmarkExpandNoVariable(b *testing.B) {
ctx := &fasthttp.RequestCtx{}
vc := NewVariableContext(ctx)
defer ReleaseVariableContext(vc)
vc := NewContext(ctx)
defer ReleaseContext(vc)
template := "This is a static string without any variables"
@ -401,8 +401,8 @@ func BenchmarkExpandBrace(b *testing.B) {
ctx.Request.Header.SetHost("example.com")
ctx.Request.Header.SetMethod("GET")
vc := NewVariableContext(ctx)
defer ReleaseVariableContext(vc)
vc := NewContext(ctx)
defer ReleaseContext(vc)
template := "${scheme}://${host}${uri}"
@ -422,8 +422,8 @@ func BenchmarkPoolGetPut(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
vc := NewVariableContext(ctx)
ReleaseVariableContext(vc)
vc := NewContext(ctx)
ReleaseContext(vc)
}
}
@ -456,20 +456,20 @@ func TestPoolReuse(t *testing.T) {
// 获取和释放多个 context确保没有 panic
for i := 0; i < 10; i++ {
vc := NewVariableContext(ctx)
vc := NewContext(ctx)
vc.Set("key", "value")
if v, ok := vc.Get("key"); !ok || v != "value" {
t.Errorf("iteration %d: expected key=value, got %s", i, v)
}
ReleaseVariableContext(vc)
ReleaseContext(vc)
}
// 验证池在复用(第二次获取应该清除之前的值)
vc2 := NewVariableContext(ctx)
vc2 := NewContext(ctx)
if v, ok := vc2.Get("key"); ok {
t.Errorf("expected key to be cleared after release, got %s", v)
}
ReleaseVariableContext(vc2)
ReleaseContext(vc2)
}
// TestMoreBuiltinVariables 测试更多内置变量
@ -483,21 +483,21 @@ func TestMoreBuiltinVariables(t *testing.T) {
}{
{
name: "server_port with local addr",
setupFunc: func(ctx *fasthttp.RequestCtx) {},
setupFunc: func(_ *fasthttp.RequestCtx) {},
varName: VarServerPort,
expected: "0", // 没有设置 local addr 时返回 "0"
shouldExist: true,
},
{
name: "remote_addr without addr",
setupFunc: func(ctx *fasthttp.RequestCtx) {},
setupFunc: func(_ *fasthttp.RequestCtx) {},
varName: VarRemoteAddr,
expected: "0.0.0.0:0", // mock ctx 返回默认值
shouldExist: true,
},
{
name: "remote_port without addr",
setupFunc: func(ctx *fasthttp.RequestCtx) {},
setupFunc: func(_ *fasthttp.RequestCtx) {},
varName: VarRemotePort,
expected: "0",
shouldExist: true,
@ -526,8 +526,8 @@ func TestMoreBuiltinVariables(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
ctx := mockRequestCtx(t)
tt.setupFunc(ctx)
vc := NewVariableContext(ctx)
defer ReleaseVariableContext(vc)
vc := NewContext(ctx)
defer ReleaseContext(vc)
value, ok := vc.Get(tt.varName)
if tt.shouldExist && !ok {
@ -542,9 +542,9 @@ func TestMoreBuiltinVariables(t *testing.T) {
}
// TestReleaseNilContext 测试释放 nil context
func TestReleaseNilContext(t *testing.T) {
func TestReleaseNilContext(_ *testing.T) {
// 不应该 panic
ReleaseVariableContext(nil)
ReleaseContext(nil)
}
// TestGetBuiltin 测试获取内置变量定义
@ -633,8 +633,8 @@ func TestGetCookieVariable(t *testing.T) {
// TestEmptyTemplate 测试空模板
func TestEmptyTemplate(t *testing.T) {
ctx := mockRequestCtx(t)
vc := NewVariableContext(ctx)
defer ReleaseVariableContext(vc)
vc := NewContext(ctx)
defer ReleaseContext(vc)
result := vc.Expand("")
if result != "" {
@ -642,17 +642,17 @@ func TestEmptyTemplate(t *testing.T) {
}
}
// TestReleaseVariableContextWithNil 测试释放 nil
func TestReleaseVariableContextWithNil(t *testing.T) {
// TestReleaseContextWithNil 测试释放 nil
func TestReleaseContextWithNil(_ *testing.T) {
// 不应该 panic
ReleaseVariableContext(nil)
ReleaseContext(nil)
}
// TestExpandOnlyDollar 测试只有 $ 的情况
func TestExpandOnlyDollar(t *testing.T) {
ctx := mockRequestCtx(t)
vc := NewVariableContext(ctx)
defer ReleaseVariableContext(vc)
vc := NewContext(ctx)
defer ReleaseContext(vc)
tests := []struct {
template string
@ -698,7 +698,7 @@ func TestPoolFunctions(t *testing.T) {
}
// TestPoolPutNil 测试 PoolPut nil
func TestPoolPutNil(t *testing.T) {
func TestPoolPutNil(_ *testing.T) {
// 不应该 panic
PoolPut(nil)
}
@ -724,8 +724,8 @@ func TestStatsFunctions(t *testing.T) {
// TestSetResponseInfo 测试 SetResponseInfo
func TestSetResponseInfo(t *testing.T) {
ctx := mockRequestCtx(t)
vc := NewVariableContext(ctx)
defer ReleaseVariableContext(vc)
vc := NewContext(ctx)
defer ReleaseContext(vc)
// 设置响应信息
vc.SetResponseInfo(404, 512, 25000000) // 25ms
@ -744,8 +744,8 @@ func TestSetResponseInfo(t *testing.T) {
// TestSetServerName 测试 SetServerName
func TestSetServerName(t *testing.T) {
ctx := mockRequestCtx(t)
vc := NewVariableContext(ctx)
defer ReleaseVariableContext(vc)
vc := NewContext(ctx)
defer ReleaseContext(vc)
vc.SetServerName("my-server")
if vc.serverName != "my-server" {
@ -755,7 +755,7 @@ func TestSetServerName(t *testing.T) {
// TestEmptyExpandString 测试空模板 ExpandString
func TestEmptyExpandString(t *testing.T) {
lookup := func(name string) string { return "" }
lookup := func(_ string) string { return "" }
result := ExpandString("", lookup)
if result != "" {
t.Errorf("ExpandString('') = %q, want empty", result)
@ -764,7 +764,7 @@ func TestEmptyExpandString(t *testing.T) {
// TestExpandStringNoVar 测试无变量模板
func TestExpandStringNoVar(t *testing.T) {
lookup := func(name string) string { return "" }
lookup := func(_ string) string { return "" }
result := ExpandString("hello world", lookup)
if result != "hello world" {
t.Errorf("ExpandString = %q, want 'hello world'", result)
@ -780,8 +780,8 @@ func TestTLSBuiltin(t *testing.T) {
// 由于无法直接设置 TLSscheme 变量会检查 ctx.IsTLS()
// 这里我们测试它返回 http默认值
vc := NewVariableContext(ctx)
defer ReleaseVariableContext(vc)
vc := NewContext(ctx)
defer ReleaseContext(vc)
scheme, ok := vc.Get("scheme")
if !ok {
@ -795,8 +795,8 @@ func TestTLSBuiltin(t *testing.T) {
// TestEmptyVarNameBrace 测试空变量名 ${}
func TestEmptyVarNameBrace(t *testing.T) {
ctx := mockRequestCtx(t)
vc := NewVariableContext(ctx)
defer ReleaseVariableContext(vc)
vc := NewContext(ctx)
defer ReleaseContext(vc)
// ${} 应该保持为 ${}
result := vc.Expand("${}")
@ -835,8 +835,8 @@ func TestBuiltinVarNames(t *testing.T) {
// TestUpstreamVariables 测试上游变量
func TestUpstreamVariables(t *testing.T) {
ctx := mockRequestCtx(t)
vc := NewVariableContext(ctx)
defer ReleaseVariableContext(vc)
vc := NewContext(ctx)
defer ReleaseContext(vc)
// 未设置时应该返回默认值 "-"
tests := []struct {
@ -895,8 +895,8 @@ func TestUpstreamVariables(t *testing.T) {
// TestUpstreamVariablesInExpand 测试在模板中展开上游变量
func TestUpstreamVariablesInExpand(t *testing.T) {
ctx := mockRequestCtx(t)
vc := NewVariableContext(ctx)
defer ReleaseVariableContext(vc)
vc := NewContext(ctx)
defer ReleaseContext(vc)
// 设置上游变量
vc.SetUpstreamVars("http://backend:8080", 200, 0.123, 0.001, 0.045)
@ -913,8 +913,8 @@ func TestUpstreamVariablesInExpand(t *testing.T) {
// TestUpstreamVariablesErrorCases 测试上游变量错误情况
func TestUpstreamVariablesErrorCases(t *testing.T) {
ctx := mockRequestCtx(t)
vc := NewVariableContext(ctx)
defer ReleaseVariableContext(vc)
vc := NewContext(ctx)
defer ReleaseContext(vc)
// 测试各种错误场景
tests := []struct {
@ -982,8 +982,8 @@ func TestUpstreamVariablesErrorCases(t *testing.T) {
// TestUpstreamVariablesZeroValues 测试上游变量零值处理
func TestUpstreamVariablesZeroValues(t *testing.T) {
ctx := mockRequestCtx(t)
vc := NewVariableContext(ctx)
defer ReleaseVariableContext(vc)
vc := NewContext(ctx)
defer ReleaseContext(vc)
// 测试零值应该返回 "-"
vc.SetUpstreamVars("", 0, 0, 0, 0)
@ -1020,8 +1020,8 @@ func BenchmarkUpstreamVariables(b *testing.B) {
ctx.Request.Header.SetMethod("GET")
ctx.Request.Header.SetRequestURI("/test")
vc := NewVariableContext(ctx)
defer ReleaseVariableContext(vc)
vc := NewContext(ctx)
defer ReleaseContext(vc)
// 设置上游变量
vc.SetUpstreamVars("http://backend:8080", 200, 0.123, 0.001, 0.045)
@ -1075,8 +1075,8 @@ func TestGlobalVariables(t *testing.T) {
SetGlobalVariables(nil)
}
// TestNewVariableContextWithGlobals 测试全局变量注入到请求上下文
func TestNewVariableContextWithGlobals(t *testing.T) {
// TestNewContextWithGlobals 测试全局变量注入到请求上下文
func TestNewContextWithGlobals(t *testing.T) {
// 设置全局变量
SetGlobalVariables(map[string]string{
"global_var": "global_value",
@ -1084,8 +1084,8 @@ func TestNewVariableContextWithGlobals(t *testing.T) {
defer SetGlobalVariables(nil)
ctx := mockRequestCtx(t)
vc := NewVariableContext(ctx)
defer ReleaseVariableContext(vc)
vc := NewContext(ctx)
defer ReleaseContext(vc)
// 全局变量应该被注入
if v, ok := vc.Get("global_var"); !ok || v != "global_value" {
@ -1100,7 +1100,7 @@ func TestNewVariableContextWithGlobals(t *testing.T) {
}
// TestGlobalVariablesConcurrent 测试全局变量并发访问
func TestGlobalVariablesConcurrent(t *testing.T) {
func TestGlobalVariablesConcurrent(_ *testing.T) {
SetGlobalVariables(map[string]string{
"counter": "0",
})