fix(config): 添加缺失的 Lua 配置默认值

- 补充 LuaMiddlewareConfig 默认配置
- 添加 Status.Format 字段默认值
- 简化验证逻辑

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
xfy 2026-04-13 13:15:31 +08:00
parent 742e261fdc
commit 75b0d0758b
2 changed files with 54 additions and 38 deletions

View File

@ -54,6 +54,17 @@ func DefaultConfig() *Config {
Token: "",
},
},
Lua: &LuaMiddlewareConfig{
Enabled: false,
Scripts: []LuaScriptConfig{},
GlobalSettings: LuaGlobalSettings{
MaxConcurrentCoroutines: 1000,
CoroutineTimeout: 30 * time.Second,
CodeCacheSize: 1000,
EnableFileWatch: true,
MaxExecutionTime: 30 * time.Second,
},
},
Static: []StaticConfig{{
Path: "/",
Root: "/var/www/html",
@ -164,8 +175,9 @@ func DefaultConfig() *Config {
},
Monitoring: MonitoringConfig{
Status: StatusConfig{
Path: "/_status",
Allow: []string{"127.0.0.1"},
Path: "/_status",
Format: "text",
Allow: []string{"127.0.0.1"},
},
Pprof: PprofConfig{
Enabled: false,
@ -235,6 +247,37 @@ func GenerateConfigYAML(cfg *Config) ([]byte, error) {
fmt.Fprintf(&buf, " client_max_body_size: \"1MB\" # 请求体大小限制(支持单位: b, kb, mb, gb\n")
buf.WriteString("\n")
// cache_api 配置
buf.WriteString(" # 缓存清理 API 配置(用于主动清理代理缓存)\n")
buf.WriteString(" # cache_api:\n")
fmt.Fprintf(&buf, " # enabled: %v # 是否启用缓存清理 API\n", cfg.Server.CacheAPI.Enabled)
fmt.Fprintf(&buf, " # path: \"%s\" # API 端点路径\n", cfg.Server.CacheAPI.Path)
buf.WriteString(" # allow: # 允许访问的 IP\n")
for _, ip := range cfg.Server.CacheAPI.Allow {
fmt.Fprintf(&buf, " # - \"%s\"\n", ip)
}
buf.WriteString(" # auth: # 认证配置\n")
fmt.Fprintf(&buf, " # type: \"%s\" # 认证类型(有效值: none, token\n", cfg.Server.CacheAPI.Auth.Type)
buf.WriteString(" # token: \"\" # 认证令牌(支持环境变量 ${CACHE_API_TOKEN}\n")
buf.WriteString("\n")
// lua 配置
buf.WriteString(" # Lua 中间件配置(在请求处理流程中嵌入 Lua 脚本)\n")
buf.WriteString(" # lua:\n")
fmt.Fprintf(&buf, " # enabled: %v # 是否启用 Lua 中间件\n", cfg.Server.Lua.Enabled)
buf.WriteString(" # scripts: # Lua 脚本列表\n")
buf.WriteString(" # - path: \"/scripts/auth.lua\" # 脚本路径\n")
buf.WriteString(" # phase: \"access\" # 执行阶段(有效值: rewrite, access, content, log, header_filter, body_filter\n")
buf.WriteString(" # timeout: 10s # 执行超时\n")
buf.WriteString(" # enabled: true # 是否启用此脚本\n")
buf.WriteString(" # global_settings: # 全局设置\n")
buf.WriteString(" # max_concurrent_coroutines: 1000 # 最大并发协程数\n")
buf.WriteString(" # coroutine_timeout: 30s # 协程执行超时\n")
buf.WriteString(" # code_cache_size: 1000 # 字节码缓存条目数\n")
buf.WriteString(" # enable_file_watch: true # 启用文件变更检测\n")
buf.WriteString(" # max_execution_time: 30s # 最大执行时间\n")
buf.WriteString("\n")
// static 配置
buf.WriteString(" # 静态文件服务配置(支持多个目录)\n")
buf.WriteString(" static:\n")
@ -328,6 +371,7 @@ func GenerateConfigYAML(cfg *Config) ([]byte, error) {
fmt.Fprintf(&buf, " # idle_timeout: %ds # 空闲超时\n", int(cfg.Server.SSL.HTTP2.IdleTimeout.Seconds()))
fmt.Fprintf(&buf, " # push_enabled: %v # 是否启用 Server Push\n", cfg.Server.SSL.HTTP2.PushEnabled)
fmt.Fprintf(&buf, " # h2c_enabled: %v # 是否启用 H2C明文 HTTP/2\n", cfg.Server.SSL.HTTP2.H2CEnabled)
fmt.Fprintf(&buf, " # graceful_shutdown_timeout: %ds # HTTP/2 优雅关闭超时\n", int(cfg.Server.SSL.HTTP2.GracefulShutdownTimeout.Seconds()))
buf.WriteString("\n")
// security 配置
@ -548,6 +592,7 @@ func GenerateConfigYAML(cfg *Config) ([]byte, error) {
buf.WriteString("monitoring:\n")
buf.WriteString(" status:\n")
fmt.Fprintf(&buf, " path: \"%s\" # 状态端点路径\n", cfg.Monitoring.Status.Path)
fmt.Fprintf(&buf, " format: \"%s\" # 输出格式(有效值: text, json, html\n", cfg.Monitoring.Status.Format)
buf.WriteString(" allow: # 允许访问的 IP\n")
for _, ip := range cfg.Monitoring.Status.Allow {
fmt.Fprintf(&buf, " - \"%s\"\n", ip)

View File

@ -21,6 +21,7 @@ import (
"errors"
"fmt"
"net"
"slices"
"strings"
"rua.plus/lolly/internal/loadbalance"
@ -29,10 +30,8 @@ import (
// ValidateEnum 验证值是否在有效枚举列表中
func ValidateEnum(value string, validValues []string, fieldName string) error {
for _, v := range validValues {
if value == v {
return nil
}
if slices.Contains(validValues, value) {
return nil
}
return fmt.Errorf("无效的 %s: %s仅支持 %v", fieldName, value, validValues)
}
@ -760,14 +759,7 @@ func validateRewrite(r *RewriteRule) error {
// 验证标志
validFlags := []string{"", "last", "redirect", "permanent", "break"}
valid := false
for _, f := range validFlags {
if r.Flag == f {
valid = true
break
}
}
if !valid {
if !slices.Contains(validFlags, r.Flag) {
return fmt.Errorf("无效的 flag: %s仅支持 last, redirect, permanent, break", r.Flag)
}
@ -819,14 +811,7 @@ func validateLogging(l *LoggingConfig) error {
func validateSecurityHeaders(h *SecurityHeaders) error {
// 验证 X-Frame-Options
validFrameOptions := []string{"", "DENY", "SAMEORIGIN"}
valid := false
for _, opt := range validFrameOptions {
if h.XFrameOptions == opt {
valid = true
break
}
}
if !valid {
if !slices.Contains(validFrameOptions, h.XFrameOptions) {
return fmt.Errorf("无效的 x_frame_options: %s仅支持 DENY, SAMEORIGIN 或空)", h.XFrameOptions)
}
@ -836,14 +821,7 @@ func validateSecurityHeaders(h *SecurityHeaders) error {
"origin-when-cross-origin", "same-origin", "strict-origin",
"strict-origin-when-cross-origin", "unsafe-url",
}
valid = false
for _, policy := range validReferrerPolicies {
if h.ReferrerPolicy == policy {
valid = true
break
}
}
if !valid {
if !slices.Contains(validReferrerPolicies, h.ReferrerPolicy) {
return fmt.Errorf("无效的 referrer_policy: %s", h.ReferrerPolicy)
}
@ -1023,14 +1001,7 @@ func validateLua(l *LuaMiddlewareConfig) error {
// 验证阶段值
validPhases := []string{"rewrite", "access", "content", "log", "header_filter", "body_filter"}
valid := false
for _, phase := range validPhases {
if script.Phase == phase {
valid = true
break
}
}
if !valid {
if !slices.Contains(validPhases, script.Phase) {
return fmt.Errorf("scripts[%d].phase 无效: %s仅支持 rewrite, access, content, log, header_filter, body_filter", i, script.Phase)
}