refactor(handler,middleware,server): 增强预压缩配置灵活性
- NewGzipStatic 增加 precompressedExtensions 参数,支持自定义预压缩扩展名 - SetGzipStatic 分离源文件扩展名和预压缩扩展名参数 - 更新相关测试用例 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
91d67ad384
commit
2bdc8f3b3b
@ -164,18 +164,19 @@ func (h *StaticHandler) SetFileCache(fc *cache.FileCache) {
|
|||||||
|
|
||||||
// SetGzipStatic 设置预压缩文件支持。
|
// SetGzipStatic 设置预压缩文件支持。
|
||||||
//
|
//
|
||||||
// 启用后,对于匹配扩展名的请求,优先发送 .gz 预压缩文件。
|
// 启用后,对于匹配扩展名的请求,优先发送预压缩文件。
|
||||||
//
|
//
|
||||||
// 参数:
|
// 参数:
|
||||||
// - enabled: 是否启用预压缩支持
|
// - enabled: 是否启用预压缩支持
|
||||||
// - extensions: 需要支持预压缩的文件扩展名列表(如 [".html", ".css", ".js"])
|
// - extensions: 支持预压缩的源文件扩展名列表(如 [".html", ".css", ".js"]),为空使用默认值
|
||||||
|
// - precompressedExtensions: 预压缩文件扩展名列表(如 [".br", ".gz"]),为空使用默认值
|
||||||
//
|
//
|
||||||
// 使用示例:
|
// 使用示例:
|
||||||
//
|
//
|
||||||
// handler.SetGzipStatic(true, []string{".html", ".css", ".js"})
|
// handler.SetGzipStatic(true, nil, []string{".gz", ".br"})
|
||||||
func (h *StaticHandler) SetGzipStatic(enabled bool, extensions []string) {
|
func (h *StaticHandler) SetGzipStatic(enabled bool, extensions, precompressedExtensions []string) {
|
||||||
if enabled {
|
if enabled {
|
||||||
h.gzipStatic = compression.NewGzipStatic(true, h.root, extensions)
|
h.gzipStatic = compression.NewGzipStatic(true, h.root, extensions, precompressedExtensions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -449,13 +449,13 @@ func TestStaticHandler_SetGzipStatic(t *testing.T) {
|
|||||||
handler := NewStaticHandler("/var/www", "/", nil, false)
|
handler := NewStaticHandler("/var/www", "/", nil, false)
|
||||||
|
|
||||||
// 启用 gzip
|
// 启用 gzip
|
||||||
handler.SetGzipStatic(true, []string{".gz", ".gzip"})
|
handler.SetGzipStatic(true, nil, []string{".gz", ".gzip"})
|
||||||
if handler.gzipStatic == nil {
|
if handler.gzipStatic == nil {
|
||||||
t.Error("Expected gzipStatic to be non-nil")
|
t.Error("Expected gzipStatic to be non-nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 禁用 gzip
|
// 禁用 gzip
|
||||||
handler.SetGzipStatic(false, nil)
|
handler.SetGzipStatic(false, nil, nil)
|
||||||
// gzipStatic 保持不变(SetGzipStatic 只在 enabled=true 时设置)
|
// gzipStatic 保持不变(SetGzipStatic 只在 enabled=true 时设置)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -525,7 +525,7 @@ func TestStaticHandler_Handle_Precompressed(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handler := NewStaticHandler(tmpDir, "/", nil, false)
|
handler := NewStaticHandler(tmpDir, "/", nil, false)
|
||||||
handler.SetGzipStatic(true, []string{".gz"})
|
handler.SetGzipStatic(true, nil, []string{".gz"})
|
||||||
|
|
||||||
ctx := &fasthttp.RequestCtx{}
|
ctx := &fasthttp.RequestCtx{}
|
||||||
ctx.Request.SetRequestURI("/test.txt")
|
ctx.Request.SetRequestURI("/test.txt")
|
||||||
|
|||||||
@ -55,19 +55,23 @@ type GzipStatic struct {
|
|||||||
// 参数:
|
// 参数:
|
||||||
// - enabled: 是否启用预压缩支持
|
// - enabled: 是否启用预压缩支持
|
||||||
// - root: 静态文件根目录路径
|
// - root: 静态文件根目录路径
|
||||||
// - extensions: 支持预压缩的文件扩展名列表,为空则使用默认值
|
// - extensions: 支持预压缩的源文件扩展名列表(如 .html, .css),为空则使用默认值
|
||||||
|
// - precompressedExtensions: 预压缩文件扩展名列表(如 .br, .gz),为空则使用默认值
|
||||||
//
|
//
|
||||||
// 返回值:
|
// 返回值:
|
||||||
// - *GzipStatic: 创建的预压缩文件处理器
|
// - *GzipStatic: 创建的预压缩文件处理器
|
||||||
func NewGzipStatic(enabled bool, root string, extensions []string) *GzipStatic {
|
func NewGzipStatic(enabled bool, root string, extensions, precompressedExtensions []string) *GzipStatic {
|
||||||
if len(extensions) == 0 {
|
if len(extensions) == 0 {
|
||||||
extensions = []string{".html", ".css", ".js", ".json", ".xml", ".svg", ".txt"}
|
extensions = []string{".html", ".css", ".js", ".json", ".xml", ".svg", ".txt"}
|
||||||
}
|
}
|
||||||
|
if len(precompressedExtensions) == 0 {
|
||||||
|
precompressedExtensions = []string{".br", ".gz"}
|
||||||
|
}
|
||||||
return &GzipStatic{
|
return &GzipStatic{
|
||||||
enabled: enabled,
|
enabled: enabled,
|
||||||
root: root,
|
root: root,
|
||||||
extensions: extensions,
|
extensions: extensions,
|
||||||
precompressedExtensions: []string{".br", ".gz"},
|
precompressedExtensions: precompressedExtensions,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -35,7 +35,7 @@ func TestGzipStaticServeFile_BrotliPriority(t *testing.T) {
|
|||||||
t.Fatalf("创建 .gz 文件失败: %v", err)
|
t.Fatalf("创建 .gz 文件失败: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
g := NewGzipStatic(true, tmpDir, nil)
|
g := NewGzipStatic(true, tmpDir, nil, nil)
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
acceptEncoding string
|
acceptEncoding string
|
||||||
@ -119,7 +119,7 @@ func TestGzipStaticServeFile_GzipFallback(t *testing.T) {
|
|||||||
t.Fatalf("创建 .gz 文件失败: %v", err)
|
t.Fatalf("创建 .gz 文件失败: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
g := NewGzipStatic(true, tmpDir, nil)
|
g := NewGzipStatic(true, tmpDir, nil, nil)
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
acceptEncoding string
|
acceptEncoding string
|
||||||
@ -177,7 +177,7 @@ func TestGzipStaticServeFile_AcceptEncodingParsing(t *testing.T) {
|
|||||||
t.Fatalf("创建 .br 文件失败: %v", err)
|
t.Fatalf("创建 .br 文件失败: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
g := NewGzipStatic(true, tmpDir, nil)
|
g := NewGzipStatic(true, tmpDir, nil, nil)
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
@ -241,7 +241,7 @@ func TestGzipStaticServeFile_Disabled(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 禁用的 GzipStatic
|
// 禁用的 GzipStatic
|
||||||
g := NewGzipStatic(false, tmpDir, nil)
|
g := NewGzipStatic(false, tmpDir, nil, nil)
|
||||||
|
|
||||||
ctx := &fasthttp.RequestCtx{}
|
ctx := &fasthttp.RequestCtx{}
|
||||||
ctx.Request.Header.Set("Accept-Encoding", "br")
|
ctx.Request.Header.Set("Accept-Encoding", "br")
|
||||||
@ -263,7 +263,7 @@ func TestGzipStaticServeFile_InvalidExtension(t *testing.T) {
|
|||||||
t.Fatalf("创建 .br 文件失败: %v", err)
|
t.Fatalf("创建 .br 文件失败: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
g := NewGzipStatic(true, tmpDir, nil)
|
g := NewGzipStatic(true, tmpDir, nil, nil)
|
||||||
|
|
||||||
ctx := &fasthttp.RequestCtx{}
|
ctx := &fasthttp.RequestCtx{}
|
||||||
ctx.Request.Header.Set("Accept-Encoding", "br")
|
ctx.Request.Header.Set("Accept-Encoding", "br")
|
||||||
@ -285,7 +285,7 @@ func TestGzipStaticServeFile_PathTraversal(t *testing.T) {
|
|||||||
t.Fatalf("创建 .br 文件失败: %v", err)
|
t.Fatalf("创建 .br 文件失败: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
g := NewGzipStatic(true, tmpDir, nil)
|
g := NewGzipStatic(true, tmpDir, nil, nil)
|
||||||
|
|
||||||
ctx := &fasthttp.RequestCtx{}
|
ctx := &fasthttp.RequestCtx{}
|
||||||
ctx.Request.Header.Set("Accept-Encoding", "br")
|
ctx.Request.Header.Set("Accept-Encoding", "br")
|
||||||
@ -308,7 +308,7 @@ func TestGzipStaticServeFile_VaryHeader(t *testing.T) {
|
|||||||
t.Fatalf("创建 .br 文件失败: %v", err)
|
t.Fatalf("创建 .br 文件失败: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
g := NewGzipStatic(true, tmpDir, nil)
|
g := NewGzipStatic(true, tmpDir, nil, nil)
|
||||||
|
|
||||||
ctx := &fasthttp.RequestCtx{}
|
ctx := &fasthttp.RequestCtx{}
|
||||||
ctx.Request.Header.Set("Accept-Encoding", "br")
|
ctx.Request.Header.Set("Accept-Encoding", "br")
|
||||||
@ -323,7 +323,7 @@ func TestGzipStaticServeFile_VaryHeader(t *testing.T) {
|
|||||||
|
|
||||||
// TestNewGzipStatic_DefaultExtensions 测试默认扩展名
|
// TestNewGzipStatic_DefaultExtensions 测试默认扩展名
|
||||||
func TestNewGzipStatic_DefaultExtensions(t *testing.T) {
|
func TestNewGzipStatic_DefaultExtensions(t *testing.T) {
|
||||||
g := NewGzipStatic(true, "/tmp", nil)
|
g := NewGzipStatic(true, "/tmp", nil, nil)
|
||||||
|
|
||||||
expected := []string{".html", ".css", ".js", ".json", ".xml", ".svg", ".txt"}
|
expected := []string{".html", ".css", ".js", ".json", ".xml", ".svg", ".txt"}
|
||||||
got := g.Extensions()
|
got := g.Extensions()
|
||||||
@ -342,7 +342,7 @@ func TestNewGzipStatic_DefaultExtensions(t *testing.T) {
|
|||||||
// TestNewGzipStatic_CustomExtensions 测试自定义扩展名
|
// TestNewGzipStatic_CustomExtensions 测试自定义扩展名
|
||||||
func TestNewGzipStatic_CustomExtensions(t *testing.T) {
|
func TestNewGzipStatic_CustomExtensions(t *testing.T) {
|
||||||
custom := []string{".custom", ".ext"}
|
custom := []string{".custom", ".ext"}
|
||||||
g := NewGzipStatic(true, "/tmp", custom)
|
g := NewGzipStatic(true, "/tmp", custom, nil)
|
||||||
|
|
||||||
got := g.Extensions()
|
got := g.Extensions()
|
||||||
if len(got) != 2 || got[0] != ".custom" || got[1] != ".ext" {
|
if len(got) != 2 || got[0] != ".custom" || got[1] != ".ext" {
|
||||||
@ -352,12 +352,12 @@ func TestNewGzipStatic_CustomExtensions(t *testing.T) {
|
|||||||
|
|
||||||
// TestGzipStatic_Enabled 测试 Enabled 方法
|
// TestGzipStatic_Enabled 测试 Enabled 方法
|
||||||
func TestGzipStatic_Enabled(t *testing.T) {
|
func TestGzipStatic_Enabled(t *testing.T) {
|
||||||
g1 := NewGzipStatic(true, "/tmp", nil)
|
g1 := NewGzipStatic(true, "/tmp", nil, nil)
|
||||||
if !g1.Enabled() {
|
if !g1.Enabled() {
|
||||||
t.Error("Enabled() = false, want true")
|
t.Error("Enabled() = false, want true")
|
||||||
}
|
}
|
||||||
|
|
||||||
g2 := NewGzipStatic(false, "/tmp", nil)
|
g2 := NewGzipStatic(false, "/tmp", nil, nil)
|
||||||
if g2.Enabled() {
|
if g2.Enabled() {
|
||||||
t.Error("Enabled() = true, want false")
|
t.Error("Enabled() = true, want false")
|
||||||
}
|
}
|
||||||
@ -366,7 +366,7 @@ func TestGzipStatic_Enabled(t *testing.T) {
|
|||||||
// TestDefaultExtensions 测试默认扩展名(通过 NewGzipStatic 间接测试)
|
// TestDefaultExtensions 测试默认扩展名(通过 NewGzipStatic 间接测试)
|
||||||
func TestDefaultExtensions(t *testing.T) {
|
func TestDefaultExtensions(t *testing.T) {
|
||||||
expected := []string{".html", ".css", ".js", ".json", ".xml", ".svg", ".txt"}
|
expected := []string{".html", ".css", ".js", ".json", ".xml", ".svg", ".txt"}
|
||||||
g := NewGzipStatic(true, "/tmp", nil)
|
g := NewGzipStatic(true, "/tmp", nil, nil)
|
||||||
got := g.Extensions()
|
got := g.Extensions()
|
||||||
|
|
||||||
if len(got) != len(expected) {
|
if len(got) != len(expected) {
|
||||||
@ -462,7 +462,7 @@ func TestTryServeFile(t *testing.T) {
|
|||||||
ctx := &fasthttp.RequestCtx{}
|
ctx := &fasthttp.RequestCtx{}
|
||||||
ctx.Request.Header.Set("Accept-Encoding", "br")
|
ctx.Request.Header.Set("Accept-Encoding", "br")
|
||||||
|
|
||||||
g := NewGzipStatic(true, tmpDir, nil)
|
g := NewGzipStatic(true, tmpDir, nil, nil)
|
||||||
served := g.ServeFile(ctx, "test.js")
|
served := g.ServeFile(ctx, "test.js")
|
||||||
|
|
||||||
if !served {
|
if !served {
|
||||||
@ -477,7 +477,7 @@ func TestTryServeFile(t *testing.T) {
|
|||||||
|
|
||||||
// TestGzipStatic_PrecompressedExtensions 测试预压缩扩展名优先级
|
// TestGzipStatic_PrecompressedExtensions 测试预压缩扩展名优先级
|
||||||
func TestGzipStatic_PrecompressedExtensions(t *testing.T) {
|
func TestGzipStatic_PrecompressedExtensions(t *testing.T) {
|
||||||
g := NewGzipStatic(true, "/tmp", nil)
|
g := NewGzipStatic(true, "/tmp", nil, nil)
|
||||||
|
|
||||||
// 验证默认预压缩扩展名顺序
|
// 验证默认预压缩扩展名顺序
|
||||||
expected := []string{".br", ".gz"}
|
expected := []string{".br", ".gz"}
|
||||||
|
|||||||
@ -1083,7 +1083,9 @@ func (s *Server) registerStaticHandlersWithLocationEngine(cfg *config.ServerConf
|
|||||||
staticHandler.SetCacheTTL(5 * time.Second)
|
staticHandler.SetCacheTTL(5 * time.Second)
|
||||||
}
|
}
|
||||||
if cfg.Compression.GzipStatic {
|
if cfg.Compression.GzipStatic {
|
||||||
staticHandler.SetGzipStatic(true, cfg.Compression.GzipStaticExtensions)
|
// extensions: 源文件类型,为空使用默认值
|
||||||
|
// GzipStaticExtensions: 预压缩文件扩展名(如 .br, .gz)
|
||||||
|
staticHandler.SetGzipStatic(true, nil, cfg.Compression.GzipStaticExtensions)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置符号链接安全检查
|
// 设置符号链接安全检查
|
||||||
@ -1446,7 +1448,9 @@ func (s *Server) registerStaticHandlers(router *handler.Router, cfg *config.Serv
|
|||||||
staticHandler.SetCacheTTL(5 * time.Second)
|
staticHandler.SetCacheTTL(5 * time.Second)
|
||||||
}
|
}
|
||||||
if cfg.Compression.GzipStatic {
|
if cfg.Compression.GzipStatic {
|
||||||
staticHandler.SetGzipStatic(true, cfg.Compression.GzipStaticExtensions)
|
// extensions: 源文件类型,为空使用默认值
|
||||||
|
// GzipStaticExtensions: 预压缩文件扩展名(如 .br, .gz)
|
||||||
|
staticHandler.SetGzipStatic(true, nil, cfg.Compression.GzipStaticExtensions)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置符号链接安全检查
|
// 设置符号链接安全检查
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user