refactor(config,app): 默认配置迁移到 servers 格式

- DefaultConfig() 使用 Servers[0] 替代 Server
- GenerateConfigYAML() 生成 servers 列表格式
- App.Run() 支持多服务器监听地址日志输出

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
xfy 2026-04-15 10:34:04 +08:00
parent 1f170b1951
commit 168d34d58d
2 changed files with 197 additions and 183 deletions

View File

@ -166,7 +166,20 @@ func (a *App) Run() int {
} }
a.logger.LogStartup("配置加载成功", map[string]string{"config_path": a.cfgPath}) a.logger.LogStartup("配置加载成功", map[string]string{"config_path": a.cfgPath})
// 记录监听地址(支持多服务器模式)
mode := a.cfg.GetMode()
if mode == config.ServerModeMultiServer {
for i, srv := range a.cfg.Servers {
a.logger.LogStartup("监听地址", map[string]string{
"index": fmt.Sprintf("[%d]", i),
"listen": srv.Listen,
"name": srv.Name,
})
}
} else {
a.logger.LogStartup("监听地址", map[string]string{"listen": a.cfg.Server.Listen}) a.logger.LogStartup("监听地址", map[string]string{"listen": a.cfg.Server.Listen})
}
// 创建 DNS 解析器(如果启用) // 创建 DNS 解析器(如果启用)
if a.cfg.Resolver.Enabled { if a.cfg.Resolver.Enabled {

View File

@ -37,7 +37,7 @@ import (
// - 压缩: gzip级别 6最小 1024 字节 // - 压缩: gzip级别 6最小 1024 字节
func DefaultConfig() *Config { func DefaultConfig() *Config {
return &Config{ return &Config{
Server: ServerConfig{ Servers: []ServerConfig{{
Listen: ":8080", Listen: ":8080",
Name: "localhost", Name: "localhost",
ReadTimeout: 30 * time.Second, ReadTimeout: 30 * time.Second,
@ -142,7 +142,7 @@ func DefaultConfig() *Config {
"application/javascript", "application/javascript",
}, },
}, },
}, }},
Logging: LoggingConfig{ Logging: LoggingConfig{
Format: "text", Format: "text",
Access: AccessLogConfig{ Access: AccessLogConfig{
@ -234,37 +234,38 @@ func GenerateConfigYAML(cfg *Config) ([]byte, error) {
// buf.WriteString("# 文档: https://github.com/xfy/lolly\n") // buf.WriteString("# 文档: https://github.com/xfy/lolly\n")
buf.WriteString("\n") buf.WriteString("\n")
// server 配置 // servers 配置
buf.WriteString("# 服务器配置(单服务器模式)\n") buf.WriteString("# 服务器配置(多服务器模式)\n")
buf.WriteString("server:\n") buf.WriteString("servers:\n")
fmt.Fprintf(&buf, " listen: \"%s\" # 监听地址\n", cfg.Server.Listen) buf.WriteString(" - # 服务器配置\n")
fmt.Fprintf(&buf, " name: \"%s\" # 服务器名称(虚拟主机匹配)\n", cfg.Server.Name) fmt.Fprintf(&buf, " listen: \"%s\" # 监听地址\n", cfg.Servers[0].Listen)
fmt.Fprintf(&buf, " read_timeout: %ds # 读取超时0 表示不限制)\n", int(cfg.Server.ReadTimeout.Seconds())) fmt.Fprintf(&buf, " name: \"%s\" # 服务器名称(虚拟主机匹配)\n", cfg.Servers[0].Name)
fmt.Fprintf(&buf, " write_timeout: %ds # 写入超时0 表示不限制)\n", int(cfg.Server.WriteTimeout.Seconds())) fmt.Fprintf(&buf, " read_timeout: %ds # 读取超时0 表示不限制)\n", int(cfg.Servers[0].ReadTimeout.Seconds()))
fmt.Fprintf(&buf, " idle_timeout: %ds # 空闲超时0 表示不限制)\n", int(cfg.Server.IdleTimeout.Seconds())) fmt.Fprintf(&buf, " write_timeout: %ds # 写入超时0 表示不限制)\n", int(cfg.Servers[0].WriteTimeout.Seconds()))
fmt.Fprintf(&buf, " max_conns_per_ip: %d # 每 IP 最大连接数0 表示不限制)\n", cfg.Server.MaxConnsPerIP) fmt.Fprintf(&buf, " idle_timeout: %ds # 空闲超时0 表示不限制)\n", int(cfg.Servers[0].IdleTimeout.Seconds()))
fmt.Fprintf(&buf, " max_requests_per_conn: %d # 每连接最大请求数0 表示不限制)\n", cfg.Server.MaxRequestsPerConn) fmt.Fprintf(&buf, " max_conns_per_ip: %d # 每 IP 最大连接数0 表示不限制)\n", cfg.Servers[0].MaxConnsPerIP)
fmt.Fprintf(&buf, " max_requests_per_conn: %d # 每连接最大请求数0 表示不限制)\n", cfg.Servers[0].MaxRequestsPerConn)
fmt.Fprintf(&buf, " client_max_body_size: \"1MB\" # 请求体大小限制(支持单位: b, kb, mb, gb\n") fmt.Fprintf(&buf, " client_max_body_size: \"1MB\" # 请求体大小限制(支持单位: b, kb, mb, gb\n")
buf.WriteString("\n") buf.WriteString("\n")
// cache_api 配置 // cache_api 配置
buf.WriteString(" # 缓存清理 API 配置(用于主动清理代理缓存)\n") buf.WriteString(" # 缓存清理 API 配置(用于主动清理代理缓存)\n")
buf.WriteString(" # cache_api:\n") buf.WriteString(" # cache_api:\n")
fmt.Fprintf(&buf, " # enabled: %v # 是否启用缓存清理 API\n", cfg.Server.CacheAPI.Enabled) fmt.Fprintf(&buf, " # enabled: %v # 是否启用缓存清理 API\n", cfg.Servers[0].CacheAPI.Enabled)
fmt.Fprintf(&buf, " # path: \"%s\" # API 端点路径\n", cfg.Server.CacheAPI.Path) fmt.Fprintf(&buf, " # path: \"%s\" # API 端点路径\n", cfg.Servers[0].CacheAPI.Path)
buf.WriteString(" # allow: # 允许访问的 IP\n") buf.WriteString(" # allow: # 允许访问的 IP\n")
for _, ip := range cfg.Server.CacheAPI.Allow { for _, ip := range cfg.Servers[0].CacheAPI.Allow {
fmt.Fprintf(&buf, " # - \"%s\"\n", ip) fmt.Fprintf(&buf, " # - \"%s\"\n", ip)
} }
buf.WriteString(" # auth: # 认证配置\n") buf.WriteString(" # auth: # 认证配置\n")
fmt.Fprintf(&buf, " # type: \"%s\" # 认证类型(有效值: none, token\n", cfg.Server.CacheAPI.Auth.Type) fmt.Fprintf(&buf, " # type: \"%s\" # 认证类型(有效值: none, token\n", cfg.Servers[0].CacheAPI.Auth.Type)
buf.WriteString(" # token: \"\" # 认证令牌(支持环境变量 ${CACHE_API_TOKEN}\n") buf.WriteString(" # token: \"\" # 认证令牌(支持环境变量 ${CACHE_API_TOKEN}\n")
buf.WriteString("\n") buf.WriteString("\n")
// lua 配置 // lua 配置
buf.WriteString(" # Lua 中间件配置(在请求处理流程中嵌入 Lua 脚本)\n") buf.WriteString(" # Lua 中间件配置(在请求处理流程中嵌入 Lua 脚本)\n")
buf.WriteString(" # lua:\n") buf.WriteString(" # lua:\n")
fmt.Fprintf(&buf, " # enabled: %v # 是否启用 Lua 中间件\n", cfg.Server.Lua.Enabled) fmt.Fprintf(&buf, " # enabled: %v # 是否启用 Lua 中间件\n", cfg.Servers[0].Lua.Enabled)
buf.WriteString(" # scripts: # Lua 脚本列表\n") buf.WriteString(" # scripts: # Lua 脚本列表\n")
buf.WriteString(" # - path: \"/scripts/auth.lua\" # 脚本路径\n") buf.WriteString(" # - path: \"/scripts/auth.lua\" # 脚本路径\n")
buf.WriteString(" # phase: \"access\" # 执行阶段(有效值: rewrite, access, content, log, header_filter, body_filter\n") buf.WriteString(" # phase: \"access\" # 执行阶段(有效值: rewrite, access, content, log, header_filter, body_filter\n")
@ -281,7 +282,7 @@ func GenerateConfigYAML(cfg *Config) ([]byte, error) {
// static 配置 // static 配置
buf.WriteString(" # 静态文件服务配置(支持多个目录)\n") buf.WriteString(" # 静态文件服务配置(支持多个目录)\n")
buf.WriteString(" static:\n") buf.WriteString(" static:\n")
for _, st := range cfg.Server.Static { for _, st := range cfg.Servers[0].Static {
buf.WriteString(" - path: \"/\" # 匹配路径前缀\n") buf.WriteString(" - path: \"/\" # 匹配路径前缀\n")
fmt.Fprintf(&buf, " root: \"%s\" # 静态文件根目录\n", st.Root) fmt.Fprintf(&buf, " root: \"%s\" # 静态文件根目录\n", st.Root)
buf.WriteString(" index: # 索引文件\n") buf.WriteString(" index: # 索引文件\n")
@ -339,7 +340,7 @@ func GenerateConfigYAML(cfg *Config) ([]byte, error) {
buf.WriteString(" # key: /path/to/key.pem # 私钥文件\n") buf.WriteString(" # key: /path/to/key.pem # 私钥文件\n")
buf.WriteString(" # cert_chain: /path/to/chain.pem # 证书链文件\n") buf.WriteString(" # cert_chain: /path/to/chain.pem # 证书链文件\n")
buf.WriteString(" # protocols: # TLS 版本(有效值: TLSv1.2, TLSv1.3\n") buf.WriteString(" # protocols: # TLS 版本(有效值: TLSv1.2, TLSv1.3\n")
for _, proto := range cfg.Server.SSL.Protocols { for _, proto := range cfg.Servers[0].SSL.Protocols {
fmt.Fprintf(&buf, " # - \"%s\"\n", proto) fmt.Fprintf(&buf, " # - \"%s\"\n", proto)
} }
buf.WriteString(" # ciphers: # 加密套件(仅 TLS 1.2 有效TLS 1.3 使用内置套件)\n") buf.WriteString(" # ciphers: # 加密套件(仅 TLS 1.2 有效TLS 1.3 使用内置套件)\n")
@ -348,16 +349,16 @@ func GenerateConfigYAML(cfg *Config) ([]byte, error) {
buf.WriteString(" # - ECDHE-ECDSA-CHACHA20-POLY1305\n") buf.WriteString(" # - ECDHE-ECDSA-CHACHA20-POLY1305\n")
buf.WriteString(" # - ECDHE-RSA-CHACHA20-POLY1305\n") buf.WriteString(" # - ECDHE-RSA-CHACHA20-POLY1305\n")
buf.WriteString(" # # 拒绝不安全套件:含 RC4、DES、3DES、CBC 的配置将报错\n") buf.WriteString(" # # 拒绝不安全套件:含 RC4、DES、3DES、CBC 的配置将报错\n")
fmt.Fprintf(&buf, " # ocsp_stapling: %v # OCSP Stapling\n", cfg.Server.SSL.OCSPStapling) fmt.Fprintf(&buf, " # ocsp_stapling: %v # OCSP Stapling\n", cfg.Servers[0].SSL.OCSPStapling)
buf.WriteString(" # hsts: # HTTP Strict Transport Security\n") buf.WriteString(" # hsts: # HTTP Strict Transport Security\n")
fmt.Fprintf(&buf, " # max_age: %d # 过期时间(秒)\n", cfg.Server.SSL.HSTS.MaxAge) fmt.Fprintf(&buf, " # max_age: %d # 过期时间(秒)\n", cfg.Servers[0].SSL.HSTS.MaxAge)
fmt.Fprintf(&buf, " # include_sub_domains: %v # 包含子域名\n", cfg.Server.SSL.HSTS.IncludeSubDomains) fmt.Fprintf(&buf, " # include_sub_domains: %v # 包含子域名\n", cfg.Servers[0].SSL.HSTS.IncludeSubDomains)
fmt.Fprintf(&buf, " # preload: %v # 加入 HSTS 预加载列表\n", cfg.Server.SSL.HSTS.Preload) fmt.Fprintf(&buf, " # preload: %v # 加入 HSTS 预加载列表\n", cfg.Servers[0].SSL.HSTS.Preload)
buf.WriteString(" # session_tickets: # TLS Session Tickets 配置TLS 1.3 会话恢复)\n") buf.WriteString(" # session_tickets: # TLS Session Tickets 配置TLS 1.3 会话恢复)\n")
fmt.Fprintf(&buf, " # enabled: %v # 是否启用 Session Tickets\n", cfg.Server.SSL.SessionTickets.Enabled) fmt.Fprintf(&buf, " # enabled: %v # 是否启用 Session Tickets\n", cfg.Servers[0].SSL.SessionTickets.Enabled)
buf.WriteString(" # key_file: \"\" # 密钥存储文件路径(用于持久化密钥)\n") buf.WriteString(" # key_file: \"\" # 密钥存储文件路径(用于持久化密钥)\n")
fmt.Fprintf(&buf, " # rotate_interval: %d # 密钥轮换间隔(秒),建议 1-24 小时\n", int(cfg.Server.SSL.SessionTickets.RotateInterval.Seconds())) fmt.Fprintf(&buf, " # rotate_interval: %d # 密钥轮换间隔(秒),建议 1-24 小时\n", int(cfg.Servers[0].SSL.SessionTickets.RotateInterval.Seconds()))
fmt.Fprintf(&buf, " # retain_keys: %d # 保留的历史密钥数量,建议 3-5 个\n", cfg.Server.SSL.SessionTickets.RetainKeys) fmt.Fprintf(&buf, " # retain_keys: %d # 保留的历史密钥数量,建议 3-5 个\n", cfg.Servers[0].SSL.SessionTickets.RetainKeys)
buf.WriteString(" # client_verify: # mTLS 客户端证书验证配置\n") buf.WriteString(" # client_verify: # mTLS 客户端证书验证配置\n")
buf.WriteString(" # enabled: false # 是否启用客户端证书验证\n") buf.WriteString(" # enabled: false # 是否启用客户端证书验证\n")
buf.WriteString(" # mode: \"none\" # 验证模式(有效值: none, request, require, optional_no_ca\n") buf.WriteString(" # mode: \"none\" # 验证模式(有效值: none, request, require, optional_no_ca\n")
@ -365,13 +366,13 @@ func GenerateConfigYAML(cfg *Config) ([]byte, error) {
buf.WriteString(" # verify_depth: 1 # 证书链验证深度\n") buf.WriteString(" # verify_depth: 1 # 证书链验证深度\n")
buf.WriteString(" # crl: \"\" # 证书撤销列表文件路径(可选)\n") buf.WriteString(" # crl: \"\" # 证书撤销列表文件路径(可选)\n")
buf.WriteString(" # http2: # HTTP/2 配置(需 SSL 证书)\n") buf.WriteString(" # http2: # HTTP/2 配置(需 SSL 证书)\n")
fmt.Fprintf(&buf, " # enabled: %v # 是否启用 HTTP/2\n", cfg.Server.SSL.HTTP2.Enabled) fmt.Fprintf(&buf, " # enabled: %v # 是否启用 HTTP/2\n", cfg.Servers[0].SSL.HTTP2.Enabled)
fmt.Fprintf(&buf, " # max_concurrent_streams: %d # 最大并发流数\n", cfg.Server.SSL.HTTP2.MaxConcurrentStreams) fmt.Fprintf(&buf, " # max_concurrent_streams: %d # 最大并发流数\n", cfg.Servers[0].SSL.HTTP2.MaxConcurrentStreams)
fmt.Fprintf(&buf, " # max_header_list_size: %d # 最大头部列表大小(字节)\n", cfg.Server.SSL.HTTP2.MaxHeaderListSize) fmt.Fprintf(&buf, " # max_header_list_size: %d # 最大头部列表大小(字节)\n", cfg.Servers[0].SSL.HTTP2.MaxHeaderListSize)
fmt.Fprintf(&buf, " # idle_timeout: %ds # 空闲超时\n", int(cfg.Server.SSL.HTTP2.IdleTimeout.Seconds())) fmt.Fprintf(&buf, " # idle_timeout: %ds # 空闲超时\n", int(cfg.Servers[0].SSL.HTTP2.IdleTimeout.Seconds()))
fmt.Fprintf(&buf, " # push_enabled: %v # 是否启用 Server Push\n", cfg.Server.SSL.HTTP2.PushEnabled) fmt.Fprintf(&buf, " # push_enabled: %v # 是否启用 Server Push\n", cfg.Servers[0].SSL.HTTP2.PushEnabled)
fmt.Fprintf(&buf, " # h2c_enabled: %v # 是否启用 H2C明文 HTTP/2\n", cfg.Server.SSL.HTTP2.H2CEnabled) fmt.Fprintf(&buf, " # h2c_enabled: %v # 是否启用 H2C明文 HTTP/2\n", cfg.Servers[0].SSL.HTTP2.H2CEnabled)
fmt.Fprintf(&buf, " # graceful_shutdown_timeout: %ds # HTTP/2 优雅关闭超时\n", int(cfg.Server.SSL.HTTP2.GracefulShutdownTimeout.Seconds())) fmt.Fprintf(&buf, " # graceful_shutdown_timeout: %ds # HTTP/2 优雅关闭超时\n", int(cfg.Servers[0].SSL.HTTP2.GracefulShutdownTimeout.Seconds()))
buf.WriteString("\n") buf.WriteString("\n")
// security 配置 // security 配置
@ -381,33 +382,33 @@ func GenerateConfigYAML(cfg *Config) ([]byte, error) {
buf.WriteString(" access:\n") buf.WriteString(" access:\n")
buf.WriteString(" allow: [] # 允许的 IP/CIDR 列表\n") buf.WriteString(" allow: [] # 允许的 IP/CIDR 列表\n")
buf.WriteString(" deny: [] # 拒绝的 IP/CIDR 列表\n") buf.WriteString(" deny: [] # 拒绝的 IP/CIDR 列表\n")
fmt.Fprintf(&buf, " default: \"%s\" # 默认动作(有效值: allow, deny\n", cfg.Server.Security.Access.Default) fmt.Fprintf(&buf, " default: \"%s\" # 默认动作(有效值: allow, deny\n", cfg.Servers[0].Security.Access.Default)
buf.WriteString(" trusted_proxies: [] # 可信代理 CIDR 列表,用于 X-Forwarded-For 解析\n") buf.WriteString(" trusted_proxies: [] # 可信代理 CIDR 列表,用于 X-Forwarded-For 解析\n")
buf.WriteString("\n") buf.WriteString("\n")
buf.WriteString(" # 速率限制\n") buf.WriteString(" # 速率限制\n")
buf.WriteString(" rate_limit:\n") buf.WriteString(" rate_limit:\n")
fmt.Fprintf(&buf, " request_rate: %d # 每秒请求数0 表示不限制)\n", cfg.Server.Security.RateLimit.RequestRate) fmt.Fprintf(&buf, " request_rate: %d # 每秒请求数0 表示不限制)\n", cfg.Servers[0].Security.RateLimit.RequestRate)
fmt.Fprintf(&buf, " burst: %d # 突发上限\n", cfg.Server.Security.RateLimit.Burst) fmt.Fprintf(&buf, " burst: %d # 突发上限\n", cfg.Servers[0].Security.RateLimit.Burst)
fmt.Fprintf(&buf, " conn_limit: %d # 连接数限制\n", cfg.Server.Security.RateLimit.ConnLimit) fmt.Fprintf(&buf, " conn_limit: %d # 连接数限制\n", cfg.Servers[0].Security.RateLimit.ConnLimit)
fmt.Fprintf(&buf, " key: \"%s\" # 限流 key 来源(有效值: ip, header\n", cfg.Server.Security.RateLimit.Key) fmt.Fprintf(&buf, " key: \"%s\" # 限流 key 来源(有效值: ip, header\n", cfg.Servers[0].Security.RateLimit.Key)
fmt.Fprintf(&buf, " algorithm: \"%s\" # 限流算法(有效值: token_bucket, sliding_window\n", cfg.Server.Security.RateLimit.Algorithm) fmt.Fprintf(&buf, " algorithm: \"%s\" # 限流算法(有效值: token_bucket, sliding_window\n", cfg.Servers[0].Security.RateLimit.Algorithm)
fmt.Fprintf(&buf, " sliding_window_mode: \"%s\" # 滑动窗口模式(有效值: approximate, precise仅 algorithm=sliding_window 时有效)\n", cfg.Server.Security.RateLimit.SlidingWindowMode) fmt.Fprintf(&buf, " sliding_window_mode: \"%s\" # 滑动窗口模式(有效值: approximate, precise仅 algorithm=sliding_window 时有效)\n", cfg.Servers[0].Security.RateLimit.SlidingWindowMode)
fmt.Fprintf(&buf, " sliding_window: %d # 滑动窗口大小(秒,仅 algorithm=sliding_window 时有效)\n", cfg.Server.Security.RateLimit.SlidingWindow) fmt.Fprintf(&buf, " sliding_window: %d # 滑动窗口大小(秒,仅 algorithm=sliding_window 时有效)\n", cfg.Servers[0].Security.RateLimit.SlidingWindow)
buf.WriteString("\n") buf.WriteString("\n")
buf.WriteString(" # 认证配置type 为空时禁用)\n") buf.WriteString(" # 认证配置type 为空时禁用)\n")
buf.WriteString(" auth:\n") buf.WriteString(" auth:\n")
buf.WriteString(" type: \"\" # 认证类型(有效值: basic空表示禁用\n") buf.WriteString(" type: \"\" # 认证类型(有效值: basic空表示禁用\n")
fmt.Fprintf(&buf, " require_tls: %v # 启用时强制 HTTPS\n", cfg.Server.Security.Auth.RequireTLS) fmt.Fprintf(&buf, " require_tls: %v # 启用时强制 HTTPS\n", cfg.Servers[0].Security.Auth.RequireTLS)
fmt.Fprintf(&buf, " algorithm: \"%s\" # 密码哈希算法(有效值: bcrypt, argon2id\n", cfg.Server.Security.Auth.Algorithm) fmt.Fprintf(&buf, " algorithm: \"%s\" # 密码哈希算法(有效值: bcrypt, argon2id\n", cfg.Servers[0].Security.Auth.Algorithm)
buf.WriteString(" users: [] # 用户列表\n") buf.WriteString(" users: [] # 用户列表\n")
fmt.Fprintf(&buf, " realm: \"%s\" # 认证域\n", cfg.Server.Security.Auth.Realm) fmt.Fprintf(&buf, " realm: \"%s\" # 认证域\n", cfg.Servers[0].Security.Auth.Realm)
fmt.Fprintf(&buf, " min_password_length: %d # 密码最小长度\n", cfg.Server.Security.Auth.MinPasswordLength) fmt.Fprintf(&buf, " min_password_length: %d # 密码最小长度\n", cfg.Servers[0].Security.Auth.MinPasswordLength)
buf.WriteString("\n") buf.WriteString("\n")
buf.WriteString(" # 安全头部\n") buf.WriteString(" # 安全头部\n")
buf.WriteString(" headers:\n") buf.WriteString(" headers:\n")
fmt.Fprintf(&buf, " x_frame_options: \"%s\" # 防止点击劫持(有效值: DENY, SAMEORIGIN, 空表示禁用)\n", cfg.Server.Security.Headers.XFrameOptions) fmt.Fprintf(&buf, " x_frame_options: \"%s\" # 防止点击劫持(有效值: DENY, SAMEORIGIN, 空表示禁用)\n", cfg.Servers[0].Security.Headers.XFrameOptions)
fmt.Fprintf(&buf, " x_content_type_options: \"%s\" # 防止 MIME 嗅探有效值nosniff空表示禁用\n", cfg.Server.Security.Headers.XContentTypeOptions) fmt.Fprintf(&buf, " x_content_type_options: \"%s\" # 防止 MIME 嗅探有效值nosniff空表示禁用\n", cfg.Servers[0].Security.Headers.XContentTypeOptions)
fmt.Fprintf(&buf, " referrer_policy: \"%s\" # 引用策略(有效值: no-referrer, no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url\n", cfg.Server.Security.Headers.ReferrerPolicy) fmt.Fprintf(&buf, " referrer_policy: \"%s\" # 引用策略(有效值: no-referrer, no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url\n", cfg.Servers[0].Security.Headers.ReferrerPolicy)
buf.WriteString(" content_security_policy: \"\" # 内容安全策略 CSP空表示禁用\n") buf.WriteString(" content_security_policy: \"\" # 内容安全策略 CSP空表示禁用\n")
buf.WriteString(" permissions_policy: \"\" # 权限策略(空表示禁用)\n") buf.WriteString(" permissions_policy: \"\" # 权限策略(空表示禁用)\n")
buf.WriteString("\n") buf.WriteString("\n")
@ -438,16 +439,16 @@ func GenerateConfigYAML(cfg *Config) ([]byte, error) {
// compression 配置 // compression 配置
buf.WriteString(" # 响应压缩配置\n") buf.WriteString(" # 响应压缩配置\n")
buf.WriteString(" compression:\n") buf.WriteString(" compression:\n")
fmt.Fprintf(&buf, " type: \"%s\" # 压缩类型(有效值: gzip, brotli, both空表示禁用\n", cfg.Server.Compression.Type) fmt.Fprintf(&buf, " type: \"%s\" # 压缩类型(有效值: gzip, brotli, both空表示禁用\n", cfg.Servers[0].Compression.Type)
fmt.Fprintf(&buf, " level: %d # 压缩级别(范围 0-90=不压缩1=最快9=最高压缩率)\n", cfg.Server.Compression.Level) fmt.Fprintf(&buf, " level: %d # 压缩级别(范围 0-90=不压缩1=最快9=最高压缩率)\n", cfg.Servers[0].Compression.Level)
fmt.Fprintf(&buf, " min_size: %d # 最小压缩大小(字节,小于此值不压缩)\n", cfg.Server.Compression.MinSize) fmt.Fprintf(&buf, " min_size: %d # 最小压缩大小(字节,小于此值不压缩)\n", cfg.Servers[0].Compression.MinSize)
fmt.Fprintf(&buf, " gzip_static: %v # 启用预压缩文件支持(自动查找 .gz/.br 文件)\n", cfg.Server.Compression.GzipStatic) fmt.Fprintf(&buf, " gzip_static: %v # 启用预压缩文件支持(自动查找 .gz/.br 文件)\n", cfg.Servers[0].Compression.GzipStatic)
buf.WriteString(" gzip_static_extensions: # 预压缩文件扩展名\n") buf.WriteString(" gzip_static_extensions: # 预压缩文件扩展名\n")
for _, ext := range cfg.Server.Compression.GzipStaticExtensions { for _, ext := range cfg.Servers[0].Compression.GzipStaticExtensions {
fmt.Fprintf(&buf, " - \"%s\"\n", ext) fmt.Fprintf(&buf, " - \"%s\"\n", ext)
} }
buf.WriteString(" types: # 可压缩的 MIME 类型\n") buf.WriteString(" types: # 可压缩的 MIME 类型\n")
for _, t := range cfg.Server.Compression.Types { for _, t := range cfg.Servers[0].Compression.Types {
fmt.Fprintf(&buf, " - \"%s\"\n", t) fmt.Fprintf(&buf, " - \"%s\"\n", t)
} }
buf.WriteString("\n") buf.WriteString("\n")