diff --git a/Makefile b/Makefile index 989583c..4a02855 100644 --- a/Makefile +++ b/Makefile @@ -212,11 +212,11 @@ bench-check: # 格式化代码(使用 goimports 替代 go fmt) fmt: - @echo "Formatting code with goimports..." - @if command -v goimports >/dev/null 2>&1; then \ - goimports -w .; \ + @echo "Formatting code with gofumpt..." + @if command -v gofumpt >/dev/null 2>&1; then \ + gofumpt -w .; \ else \ - echo "goimports not installed. Run: go install golang.org/x/tools/cmd/goimports@latest"; \ + echo "gofumpt not installed. Run: go install mvdan.cc/gofumpt@latest"; \ exit 1; \ fi diff --git a/internal/app/app_windows.go b/internal/app/app_windows.go index 421dd5e..740a924 100644 --- a/internal/app/app_windows.go +++ b/internal/app/app_windows.go @@ -91,7 +91,7 @@ func generateConfig(outputPath string) int { if outputPath == "" { fmt.Print(string(yamlData)) } else { - if err := os.WriteFile(outputPath, yamlData, 0644); err != nil { + if err := os.WriteFile(outputPath, yamlData, 0o644); err != nil { fmt.Fprintf(os.Stderr, "写入文件失败: %v\n", err) return 1 } diff --git a/internal/handler/sendfile_other_test.go b/internal/handler/sendfile_other_test.go index 68a622e..c8a8c9f 100644 --- a/internal/handler/sendfile_other_test.go +++ b/internal/handler/sendfile_other_test.go @@ -29,7 +29,7 @@ func TestPlatformSendfile_NonLinux(t *testing.T) { tmpDir := t.TempDir() tmpFile := filepath.Join(tmpDir, "test.txt") content := []byte("test content") - if err := os.WriteFile(tmpFile, content, 0644); err != nil { + if err := os.WriteFile(tmpFile, content, 0o644); err != nil { t.Fatalf("Failed to create temp file: %v", err) } @@ -51,7 +51,7 @@ func TestCopyFile(t *testing.T) { tmpFile := filepath.Join(tmpDir, "test.txt") content := []byte("Hello, World! This is test content for copyFile.") - if err := os.WriteFile(tmpFile, content, 0644); err != nil { + if err := os.WriteFile(tmpFile, content, 0o644); err != nil { t.Fatalf("Failed to create temp file: %v", err) } @@ -132,7 +132,7 @@ func TestSendFile_SmallFile(t *testing.T) { tmpFile := filepath.Join(tmpDir, "small.txt") content := []byte("small file content") - if err := os.WriteFile(tmpFile, content, 0644); err != nil { + if err := os.WriteFile(tmpFile, content, 0o644); err != nil { t.Fatalf("Failed to create temp file: %v", err) } @@ -161,7 +161,7 @@ func TestSendFile_WithOffset(t *testing.T) { tmpFile := filepath.Join(tmpDir, "test.txt") content := []byte("0123456789ABCDEF") - if err := os.WriteFile(tmpFile, content, 0644); err != nil { + if err := os.WriteFile(tmpFile, content, 0o644); err != nil { t.Fatalf("Failed to create temp file: %v", err) } @@ -190,7 +190,7 @@ func TestSendFile_ZeroLength(t *testing.T) { tmpDir := t.TempDir() tmpFile := filepath.Join(tmpDir, "empty.txt") - if err := os.WriteFile(tmpFile, []byte{}, 0644); err != nil { + if err := os.WriteFile(tmpFile, []byte{}, 0o644); err != nil { t.Fatalf("Failed to create temp file: %v", err) } @@ -228,7 +228,7 @@ func TestCopyFile_Error(t *testing.T) { tmpFile := filepath.Join(tmpDir, "test.txt") content := []byte("test content") - if err := os.WriteFile(tmpFile, content, 0644); err != nil { + if err := os.WriteFile(tmpFile, content, 0o644); err != nil { t.Fatalf("Failed to create temp file: %v", err) } diff --git a/internal/handler/static_bench_test.go b/internal/handler/static_bench_test.go index 8c3a601..e9af0f8 100644 --- a/internal/handler/static_bench_test.go +++ b/internal/handler/static_bench_test.go @@ -31,10 +31,10 @@ func setupStaticTestDir() (string, func()) { for path, content := range testFiles { fullPath := filepath.Join(dir, path) - if err := os.MkdirAll(filepath.Dir(fullPath), 0755); err != nil { + if err := os.MkdirAll(filepath.Dir(fullPath), 0o755); err != nil { panic(err) } - if err := os.WriteFile(fullPath, content, 0644); err != nil { + if err := os.WriteFile(fullPath, content, 0o644); err != nil { panic(err) } } diff --git a/internal/handler/static_test.go b/internal/handler/static_test.go index cde3d6e..247cd3e 100644 --- a/internal/handler/static_test.go +++ b/internal/handler/static_test.go @@ -53,7 +53,7 @@ func TestStaticHandlerHandle(t *testing.T) { setup: func(t *testing.T, root string) { t.Helper() content := "hello world" - if err := os.WriteFile(filepath.Join(root, "test.txt"), []byte(content), 0644); err != nil { + if err := os.WriteFile(filepath.Join(root, "test.txt"), []byte(content), 0o644); err != nil { t.Fatalf("创建测试文件失败: %v", err) } }, @@ -66,11 +66,11 @@ func TestStaticHandlerHandle(t *testing.T) { setup: func(t *testing.T, root string) { t.Helper() subDir := filepath.Join(root, "sub", "dir") - if err := os.MkdirAll(subDir, 0755); err != nil { + if err := os.MkdirAll(subDir, 0o755); err != nil { t.Fatalf("创建子目录失败: %v", err) } content := "nested file content" - if err := os.WriteFile(filepath.Join(subDir, "nested.txt"), []byte(content), 0644); err != nil { + if err := os.WriteFile(filepath.Join(subDir, "nested.txt"), []byte(content), 0o644); err != nil { t.Fatalf("创建嵌套文件失败: %v", err) } }, @@ -83,11 +83,11 @@ func TestStaticHandlerHandle(t *testing.T) { setup: func(t *testing.T, root string) { t.Helper() dir := filepath.Join(root, "withindex") - if err := os.MkdirAll(dir, 0755); err != nil { + if err := os.MkdirAll(dir, 0o755); err != nil { t.Fatalf("创建目录失败: %v", err) } content := "index page" - if err := os.WriteFile(filepath.Join(dir, "index.html"), []byte(content), 0644); err != nil { + if err := os.WriteFile(filepath.Join(dir, "index.html"), []byte(content), 0o644); err != nil { t.Fatalf("创建索引文件失败: %v", err) } }, @@ -100,7 +100,7 @@ func TestStaticHandlerHandle(t *testing.T) { setup: func(t *testing.T, root string) { t.Helper() dir := filepath.Join(root, "noindex") - if err := os.MkdirAll(dir, 0755); err != nil { + if err := os.MkdirAll(dir, 0o755); err != nil { t.Fatalf("创建目录失败: %v", err) } }, @@ -133,7 +133,7 @@ func TestStaticHandlerHandle(t *testing.T) { setup: func(t *testing.T, root string) { t.Helper() content := "root index" - if err := os.WriteFile(filepath.Join(root, "index.html"), []byte(content), 0644); err != nil { + if err := os.WriteFile(filepath.Join(root, "index.html"), []byte(content), 0o644); err != nil { t.Fatalf("创建根索引文件失败: %v", err) } }, @@ -256,7 +256,7 @@ func TestStaticHandlerHandle_PathTraversalSecurity(t *testing.T) { setup: func(t *testing.T, root string) { t.Helper() // 创建目标文件供测试 - if err := os.WriteFile(filepath.Join(root, "bar.txt"), []byte("bar"), 0644); err != nil { + if err := os.WriteFile(filepath.Join(root, "bar.txt"), []byte("bar"), 0o644); err != nil { t.Fatalf("创建文件失败: %v", err) } }, @@ -288,15 +288,15 @@ func TestStaticHandlerHandle_IndexFallback(t *testing.T) { t.Run("优先 index.html", func(t *testing.T) { tmpDir := t.TempDir() dir := filepath.Join(tmpDir, "testdir") - if err := os.MkdirAll(dir, 0755); err != nil { + if err := os.MkdirAll(dir, 0o755); err != nil { t.Fatalf("创建目录失败: %v", err) } // 创建两个索引文件 - if err := os.WriteFile(filepath.Join(dir, "index.html"), []byte("html content"), 0644); err != nil { + if err := os.WriteFile(filepath.Join(dir, "index.html"), []byte("html content"), 0o644); err != nil { t.Fatalf("创建 index.html 失败: %v", err) } - if err := os.WriteFile(filepath.Join(dir, "index.htm"), []byte("htm content"), 0644); err != nil { + if err := os.WriteFile(filepath.Join(dir, "index.htm"), []byte("htm content"), 0o644); err != nil { t.Fatalf("创建 index.htm 失败: %v", err) } @@ -318,12 +318,12 @@ func TestStaticHandlerHandle_IndexFallback(t *testing.T) { t.Run("无 index.html 时使用 index.htm", func(t *testing.T) { tmpDir := t.TempDir() dir := filepath.Join(tmpDir, "testdir") - if err := os.MkdirAll(dir, 0755); err != nil { + if err := os.MkdirAll(dir, 0o755); err != nil { t.Fatalf("创建目录失败: %v", err) } // 仅创建 index.htm - if err := os.WriteFile(filepath.Join(dir, "index.htm"), []byte("htm content"), 0644); err != nil { + if err := os.WriteFile(filepath.Join(dir, "index.htm"), []byte("htm content"), 0o644); err != nil { t.Fatalf("创建 index.htm 失败: %v", err) } @@ -344,12 +344,12 @@ func TestStaticHandlerHandle_IndexFallback(t *testing.T) { t.Run("无索引文件时返回 403", func(t *testing.T) { tmpDir := t.TempDir() dir := filepath.Join(tmpDir, "testdir") - if err := os.MkdirAll(dir, 0755); err != nil { + if err := os.MkdirAll(dir, 0o755); err != nil { t.Fatalf("创建目录失败: %v", err) } // 创建一个非索引文件 - if err := os.WriteFile(filepath.Join(dir, "other.txt"), []byte("other content"), 0644); err != nil { + if err := os.WriteFile(filepath.Join(dir, "other.txt"), []byte("other content"), 0o644); err != nil { t.Fatalf("创建 other.txt 失败: %v", err) } @@ -365,12 +365,12 @@ func TestStaticHandlerHandle_IndexFallback(t *testing.T) { t.Run("目录不带斜杠结尾", func(t *testing.T) { tmpDir := t.TempDir() dir := filepath.Join(tmpDir, "testdir") - if err := os.MkdirAll(dir, 0755); err != nil { + if err := os.MkdirAll(dir, 0o755); err != nil { t.Fatalf("创建目录失败: %v", err) } // 创建索引文件 - if err := os.WriteFile(filepath.Join(dir, "index.html"), []byte("index"), 0644); err != nil { + if err := os.WriteFile(filepath.Join(dir, "index.html"), []byte("index"), 0o644); err != nil { t.Fatalf("创建 index.html 失败: %v", err) } @@ -447,7 +447,7 @@ func TestStaticHandler_SetGzipStatic(t *testing.T) { func TestStaticHandler_Handle_HeadRequest(t *testing.T) { tmpDir := t.TempDir() content := "head request test" - if err := os.WriteFile(filepath.Join(tmpDir, "test.txt"), []byte(content), 0644); err != nil { + if err := os.WriteFile(filepath.Join(tmpDir, "test.txt"), []byte(content), 0o644); err != nil { t.Fatalf("创建测试文件失败: %v", err) } @@ -474,7 +474,7 @@ func TestStaticHandler_Handle_HeadRequest(t *testing.T) { func TestStaticHandler_Handle_WithCache(t *testing.T) { tmpDir := t.TempDir() content := "cached content test" - if err := os.WriteFile(filepath.Join(tmpDir, "test.txt"), []byte(content), 0644); err != nil { + if err := os.WriteFile(filepath.Join(tmpDir, "test.txt"), []byte(content), 0o644); err != nil { t.Fatalf("创建测试文件失败: %v", err) } @@ -498,13 +498,13 @@ func TestStaticHandler_Handle_Precompressed(t *testing.T) { // 创建原始文件和 gzip 压缩版本 content := "test content for gzip" - if err := os.WriteFile(filepath.Join(tmpDir, "test.txt"), []byte(content), 0644); err != nil { + if err := os.WriteFile(filepath.Join(tmpDir, "test.txt"), []byte(content), 0o644); err != nil { t.Fatalf("创建测试文件失败: %v", err) } // 创建 .gz 文件(模拟预压缩) gzContent := []byte("gzipped content") - if err := os.WriteFile(filepath.Join(tmpDir, "test.txt.gz"), gzContent, 0644); err != nil { + if err := os.WriteFile(filepath.Join(tmpDir, "test.txt.gz"), gzContent, 0o644); err != nil { t.Fatalf("创建 gzip 文件失败: %v", err) } @@ -534,7 +534,7 @@ func TestStaticHandler_Handle_LargeFile(t *testing.T) { } tmpFile := filepath.Join(tmpDir, "large.bin") - if err := os.WriteFile(tmpFile, largeContent, 0644); err != nil { + if err := os.WriteFile(tmpFile, largeContent, 0o644); err != nil { t.Fatalf("创建大文件失败: %v", err) } @@ -558,7 +558,7 @@ func TestStaticHandler_Handle_Symlink(t *testing.T) { // 创建目标文件 targetContent := "symlink target" targetFile := filepath.Join(tmpDir, "target.txt") - if err := os.WriteFile(targetFile, []byte(targetContent), 0644); err != nil { + if err := os.WriteFile(targetFile, []byte(targetContent), 0o644); err != nil { t.Fatalf("创建目标文件失败: %v", err) } @@ -724,7 +724,7 @@ func TestStaticHandler_handleTryFiles(t *testing.T) { { name: "$uri 找到文件", setup: func(t *testing.T, root string) { - if err := os.WriteFile(filepath.Join(root, "app.js"), []byte("app content"), 0644); err != nil { + if err := os.WriteFile(filepath.Join(root, "app.js"), []byte("app content"), 0o644); err != nil { t.Fatalf("创建文件失败: %v", err) } }, @@ -737,10 +737,10 @@ func TestStaticHandler_handleTryFiles(t *testing.T) { name: "$uri 未找到回退到 $uri/", setup: func(t *testing.T, root string) { dir := filepath.Join(root, "assets") - if err := os.MkdirAll(dir, 0755); err != nil { + if err := os.MkdirAll(dir, 0o755); err != nil { t.Fatalf("创建目录失败: %v", err) } - if err := os.WriteFile(filepath.Join(dir, "index.html"), []byte("assets index"), 0644); err != nil { + if err := os.WriteFile(filepath.Join(dir, "index.html"), []byte("assets index"), 0o644); err != nil { t.Fatalf("创建索引文件失败: %v", err) } }, @@ -752,7 +752,7 @@ func TestStaticHandler_handleTryFiles(t *testing.T) { { name: "回退到 fallback 文件", setup: func(t *testing.T, root string) { - if err := os.WriteFile(filepath.Join(root, "index.html"), []byte("spa fallback"), 0644); err != nil { + if err := os.WriteFile(filepath.Join(root, "index.html"), []byte("spa fallback"), 0o644); err != nil { t.Fatalf("创建 fallback 文件失败: %v", err) } }, @@ -774,7 +774,7 @@ func TestStaticHandler_handleTryFiles(t *testing.T) { { name: "嵌套目录回退", setup: func(t *testing.T, root string) { - if err := os.WriteFile(filepath.Join(root, "app.html"), []byte("app shell"), 0644); err != nil { + if err := os.WriteFile(filepath.Join(root, "app.html"), []byte("app shell"), 0o644); err != nil { t.Fatalf("创建 fallback 文件失败: %v", err) } }, @@ -787,10 +787,10 @@ func TestStaticHandler_handleTryFiles(t *testing.T) { name: "路径前缀剥离", setup: func(t *testing.T, root string) { apiDir := filepath.Join(root, "api") - if err := os.MkdirAll(apiDir, 0755); err != nil { + if err := os.MkdirAll(apiDir, 0o755); err != nil { t.Fatalf("创建目录失败: %v", err) } - if err := os.WriteFile(filepath.Join(apiDir, "data.json"), []byte("json data"), 0644); err != nil { + if err := os.WriteFile(filepath.Join(apiDir, "data.json"), []byte("json data"), 0o644); err != nil { t.Fatalf("创建文件失败: %v", err) } }, @@ -802,7 +802,7 @@ func TestStaticHandler_handleTryFiles(t *testing.T) { { name: "空 try_files 数组", setup: func(t *testing.T, root string) { - if err := os.WriteFile(filepath.Join(root, "test.txt"), []byte("test"), 0644); err != nil { + if err := os.WriteFile(filepath.Join(root, "test.txt"), []byte("test"), 0o644); err != nil { t.Fatalf("创建文件失败: %v", err) } }, @@ -853,7 +853,7 @@ func TestStaticHandler_handleInternalRedirect(t *testing.T) { { name: "tryFilesPass false 直接服务文件", setup: func(t *testing.T, root string) { - if err := os.WriteFile(filepath.Join(root, "index.html"), []byte("index content"), 0644); err != nil { + if err := os.WriteFile(filepath.Join(root, "index.html"), []byte("index content"), 0o644); err != nil { t.Fatalf("创建文件失败: %v", err) } }, @@ -866,7 +866,7 @@ func TestStaticHandler_handleInternalRedirect(t *testing.T) { { name: "tryFilesPass true 触发重定向", setup: func(t *testing.T, root string) { - if err := os.WriteFile(filepath.Join(root, "fallback.txt"), []byte("fallback content"), 0644); err != nil { + if err := os.WriteFile(filepath.Join(root, "fallback.txt"), []byte("fallback content"), 0o644); err != nil { t.Fatalf("创建文件失败: %v", err) } }, @@ -891,11 +891,11 @@ func TestStaticHandler_handleInternalRedirect(t *testing.T) { name: "内部重定向目标是目录", setup: func(t *testing.T, root string) { dir := filepath.Join(root, "fallback") - if err := os.MkdirAll(dir, 0755); err != nil { + if err := os.MkdirAll(dir, 0o755); err != nil { t.Fatalf("创建目录失败: %v", err) } // 在 fallback 目录中创建一个 index.html - if err := os.WriteFile(filepath.Join(dir, "index.html"), []byte("fallback index"), 0644); err != nil { + if err := os.WriteFile(filepath.Join(dir, "index.html"), []byte("fallback index"), 0o644); err != nil { t.Fatalf("创建 index.html 失败: %v", err) } }, @@ -957,19 +957,19 @@ func TestStaticHandler_TryFilesSPA(t *testing.T) { // 创建 SPA 文件结构 // index.html - 主应用入口 - if err := os.WriteFile(filepath.Join(tmpDir, "index.html"), []byte("SPA App"), 0644); err != nil { + if err := os.WriteFile(filepath.Join(tmpDir, "index.html"), []byte("SPA App"), 0o644); err != nil { t.Fatalf("创建 index.html 失败: %v", err) } // 静态资源文件 assetsDir := filepath.Join(tmpDir, "assets") - if err := os.MkdirAll(assetsDir, 0755); err != nil { + if err := os.MkdirAll(assetsDir, 0o755); err != nil { t.Fatalf("创建 assets 目录失败: %v", err) } - if err := os.WriteFile(filepath.Join(assetsDir, "app.js"), []byte("console.log('app')"), 0644); err != nil { + if err := os.WriteFile(filepath.Join(assetsDir, "app.js"), []byte("console.log('app')"), 0o644); err != nil { t.Fatalf("创建 app.js 失败: %v", err) } - if err := os.WriteFile(filepath.Join(assetsDir, "style.css"), []byte("body { margin: 0 }"), 0644); err != nil { + if err := os.WriteFile(filepath.Join(assetsDir, "style.css"), []byte("body { margin: 0 }"), 0o644); err != nil { t.Fatalf("创建 style.css 失败: %v", err) } @@ -1037,15 +1037,15 @@ func TestStaticHandler_TryFilesWithPathPrefix(t *testing.T) { // 创建 API 模拟文件 apiDir := filepath.Join(tmpDir, "api") - if err := os.MkdirAll(apiDir, 0755); err != nil { + if err := os.MkdirAll(apiDir, 0o755); err != nil { t.Fatalf("创建 api 目录失败: %v", err) } - if err := os.WriteFile(filepath.Join(apiDir, "users.json"), []byte("[]"), 0644); err != nil { + if err := os.WriteFile(filepath.Join(apiDir, "users.json"), []byte("[]"), 0o644); err != nil { t.Fatalf("创建 users.json 失败: %v", err) } // 创建静态文件 - if err := os.WriteFile(filepath.Join(tmpDir, "index.html"), []byte("static index"), 0644); err != nil { + if err := os.WriteFile(filepath.Join(tmpDir, "index.html"), []byte("static index"), 0o644); err != nil { t.Fatalf("创建 index.html 失败: %v", err) } @@ -1113,7 +1113,7 @@ func TestStaticHandler_Alias(t *testing.T) { { name: "alias 基础替换", setup: func(t *testing.T, aliasDir string) { - if err := os.WriteFile(filepath.Join(aliasDir, "logo.png"), []byte("png content"), 0644); err != nil { + if err := os.WriteFile(filepath.Join(aliasDir, "logo.png"), []byte("png content"), 0o644); err != nil { t.Fatalf("创建文件失败: %v", err) } }, @@ -1127,10 +1127,10 @@ func TestStaticHandler_Alias(t *testing.T) { name: "alias 嵌套路径", setup: func(t *testing.T, aliasDir string) { subDir := filepath.Join(aliasDir, "icons") - if err := os.MkdirAll(subDir, 0755); err != nil { + if err := os.MkdirAll(subDir, 0o755); err != nil { t.Fatalf("创建目录失败: %v", err) } - if err := os.WriteFile(filepath.Join(subDir, "app.png"), []byte("app icon"), 0644); err != nil { + if err := os.WriteFile(filepath.Join(subDir, "app.png"), []byte("app icon"), 0o644); err != nil { t.Fatalf("创建文件失败: %v", err) } }, @@ -1143,7 +1143,7 @@ func TestStaticHandler_Alias(t *testing.T) { { name: "alias 目录索引", setup: func(t *testing.T, aliasDir string) { - if err := os.WriteFile(filepath.Join(aliasDir, "index.html"), []byte("alias index"), 0644); err != nil { + if err := os.WriteFile(filepath.Join(aliasDir, "index.html"), []byte("alias index"), 0o644); err != nil { t.Fatalf("创建文件失败: %v", err) } }, @@ -1167,7 +1167,7 @@ func TestStaticHandler_Alias(t *testing.T) { { name: "root 与 alias 互斥 - 使用 alias", setup: func(t *testing.T, aliasDir string) { - if err := os.WriteFile(filepath.Join(aliasDir, "file.txt"), []byte("from alias"), 0644); err != nil { + if err := os.WriteFile(filepath.Join(aliasDir, "file.txt"), []byte("from alias"), 0o644); err != nil { t.Fatalf("创建文件失败: %v", err) } }, @@ -1214,13 +1214,13 @@ func TestStaticHandler_AliasVsRoot(t *testing.T) { // 在 root 创建子目录和文件 imagesDir := filepath.Join(rootDir, "images") - if err := os.MkdirAll(imagesDir, 0755); err != nil { + if err := os.MkdirAll(imagesDir, 0o755); err != nil { t.Fatalf("创建 images 目录失败: %v", err) } - if err := os.WriteFile(filepath.Join(imagesDir, "logo.png"), []byte("from root"), 0644); err != nil { + if err := os.WriteFile(filepath.Join(imagesDir, "logo.png"), []byte("from root"), 0o644); err != nil { t.Fatalf("创建 root 文件失败: %v", err) } - if err := os.WriteFile(filepath.Join(aliasDir, "logo.png"), []byte("from alias"), 0644); err != nil { + if err := os.WriteFile(filepath.Join(aliasDir, "logo.png"), []byte("from alias"), 0o644); err != nil { t.Fatalf("创建 alias 文件失败: %v", err) } @@ -1299,10 +1299,10 @@ func TestStaticHandler_AliasWithTryFiles(t *testing.T) { aliasDir := t.TempDir() // 创建测试文件 - if err := os.WriteFile(filepath.Join(aliasDir, "app.js"), []byte("app content"), 0644); err != nil { + if err := os.WriteFile(filepath.Join(aliasDir, "app.js"), []byte("app content"), 0o644); err != nil { t.Fatalf("创建文件失败: %v", err) } - if err := os.WriteFile(filepath.Join(aliasDir, "index.html"), []byte("fallback"), 0644); err != nil { + if err := os.WriteFile(filepath.Join(aliasDir, "index.html"), []byte("fallback"), 0o644); err != nil { t.Fatalf("创建文件失败: %v", err) } @@ -1366,7 +1366,7 @@ func TestStaticHandler_TryFilesEdgeCases(t *testing.T) { tmpDir := t.TempDir() // 创建测试文件 - if err := os.WriteFile(filepath.Join(tmpDir, "file with spaces.txt"), []byte("spaces"), 0644); err != nil { + if err := os.WriteFile(filepath.Join(tmpDir, "file with spaces.txt"), []byte("spaces"), 0o644); err != nil { t.Fatalf("创建带空格文件失败: %v", err) } @@ -1426,7 +1426,7 @@ func TestStaticHandler_LargeFileContentType(t *testing.T) { for _, tc := range tests { t.Run(tc.ext, func(t *testing.T) { filePath := filepath.Join(tmpDir, "large"+tc.ext) - if err := os.WriteFile(filePath, largeContent, 0644); err != nil { + if err := os.WriteFile(filePath, largeContent, 0o644); err != nil { t.Fatalf("创建文件失败: %v", err) } @@ -1500,16 +1500,16 @@ func TestStaticHandler_TryFilesWithDynamicSuffix(t *testing.T) { tmpDir := t.TempDir() // 创建测试文件 - if err := os.WriteFile(filepath.Join(tmpDir, "about.html"), []byte("about page"), 0644); err != nil { + if err := os.WriteFile(filepath.Join(tmpDir, "about.html"), []byte("about page"), 0o644); err != nil { t.Fatalf("创建文件失败: %v", err) } - if err := os.MkdirAll(filepath.Join(tmpDir, "api"), 0755); err != nil { + if err := os.MkdirAll(filepath.Join(tmpDir, "api"), 0o755); err != nil { t.Fatalf("创建目录失败: %v", err) } - if err := os.WriteFile(filepath.Join(tmpDir, "api", "data.json"), []byte("{\"data\":true}"), 0644); err != nil { + if err := os.WriteFile(filepath.Join(tmpDir, "api", "data.json"), []byte("{\"data\":true}"), 0o644); err != nil { t.Fatalf("创建文件失败: %v", err) } - if err := os.WriteFile(filepath.Join(tmpDir, "index.html"), []byte("fallback"), 0644); err != nil { + if err := os.WriteFile(filepath.Join(tmpDir, "index.html"), []byte("fallback"), 0o644); err != nil { t.Fatalf("创建文件失败: %v", err) } @@ -1563,7 +1563,7 @@ func TestStaticHandler_TryFilesRootPathFallback(t *testing.T) { tmpDir := t.TempDir() // 创建 index.html 作为根路径回退 - if err := os.WriteFile(filepath.Join(tmpDir, "index.html"), []byte("root fallback"), 0644); err != nil { + if err := os.WriteFile(filepath.Join(tmpDir, "index.html"), []byte("root fallback"), 0o644); err != nil { t.Fatalf("创建文件失败: %v", err) } diff --git a/internal/loadbalance/balancer.go b/internal/loadbalance/balancer.go index 17a9fd0..00fa867 100644 --- a/internal/loadbalance/balancer.go +++ b/internal/loadbalance/balancer.go @@ -40,10 +40,10 @@ import ( // // 所有字段都设计为使用原子操作进行并发访问(如适用)。 type Target struct { + resolvedIPs atomic.Pointer[[]string] URL string hostname string VirtualHashes []uint64 - resolvedIPs atomic.Pointer[[]string] Weight int Connections int64 lastResolved atomic.Int64 diff --git a/internal/lua/lua_test.go b/internal/lua/lua_test.go index 6c39b2b..1769dcf 100644 --- a/internal/lua/lua_test.go +++ b/internal/lua/lua_test.go @@ -122,7 +122,7 @@ func TestLuaContextExecuteFile(t *testing.T) { // 创建临时 Lua 文件 tmpDir := t.TempDir() scriptPath := filepath.Join(tmpDir, "test.lua") - err = os.WriteFile(scriptPath, []byte("return 42"), 0644) + err = os.WriteFile(scriptPath, []byte("return 42"), 0o644) require.NoError(t, err) // 执行文件 @@ -185,7 +185,7 @@ func TestLuaCoroutineExecuteFile(t *testing.T) { // 创建临时文件 tmpDir := t.TempDir() scriptPath := filepath.Join(tmpDir, "test.lua") - err = os.WriteFile(scriptPath, []byte("return 42"), 0644) + err = os.WriteFile(scriptPath, []byte("return 42"), 0o644) require.NoError(t, err) err = coro.ExecuteFile(scriptPath) @@ -279,7 +279,7 @@ func TestCodeCacheFile(t *testing.T) { scriptPath := filepath.Join(tmpDir, "test.lua") scriptContent := "return 42" - err := os.WriteFile(scriptPath, []byte(scriptContent), 0644) + err := os.WriteFile(scriptPath, []byte(scriptContent), 0o644) require.NoError(t, err) cache := NewCodeCache(100, time.Hour, true) diff --git a/internal/lua/middleware_bench_test.go b/internal/lua/middleware_bench_test.go index 1e6e9f2..58be33b 100644 --- a/internal/lua/middleware_bench_test.go +++ b/internal/lua/middleware_bench_test.go @@ -22,7 +22,7 @@ func BenchmarkLuaMiddlewareOverhead(b *testing.B) { // 创建简单的 Lua 脚本 tmpDir := b.TempDir() scriptPath := filepath.Join(tmpDir, "simple.lua") - err = os.WriteFile(scriptPath, []byte(`ngx.say("ok")`), 0644) + err = os.WriteFile(scriptPath, []byte(`ngx.say("ok")`), 0o644) if err != nil { b.Fatal(err) } @@ -65,7 +65,7 @@ func BenchmarkLuaMiddlewareMultiPhase(b *testing.B) { // rewrite phase rewriteScript := filepath.Join(tmpDir, "rewrite.lua") - err = os.WriteFile(rewriteScript, []byte(`-- simple rewrite`), 0644) + err = os.WriteFile(rewriteScript, []byte(`-- simple rewrite`), 0o644) if err != nil { b.Fatal(err) } @@ -76,7 +76,7 @@ func BenchmarkLuaMiddlewareMultiPhase(b *testing.B) { // content phase contentScript := filepath.Join(tmpDir, "content.lua") - err = os.WriteFile(contentScript, []byte(`ngx.say("content")`), 0644) + err = os.WriteFile(contentScript, []byte(`ngx.say("content")`), 0o644) if err != nil { b.Fatal(err) } @@ -108,7 +108,7 @@ func BenchmarkLuaMiddlewareNgxExit(b *testing.B) { tmpDir := b.TempDir() scriptPath := filepath.Join(tmpDir, "exit.lua") - err = os.WriteFile(scriptPath, []byte(`ngx.exit(200)`), 0644) + err = os.WriteFile(scriptPath, []byte(`ngx.exit(200)`), 0o644) if err != nil { b.Fatal(err) } @@ -150,7 +150,7 @@ func TestLuaMiddlewarePerformanceOverhead(t *testing.T) { tmpDir := t.TempDir() scriptPath := filepath.Join(tmpDir, "perf.lua") - err = os.WriteFile(scriptPath, []byte(`ngx.say("performance test")`), 0644) + err = os.WriteFile(scriptPath, []byte(`ngx.say("performance test")`), 0o644) if err != nil { t.Fatal(err) } diff --git a/internal/lua/middleware_test.go b/internal/lua/middleware_test.go index 57367fe..4f62263 100644 --- a/internal/lua/middleware_test.go +++ b/internal/lua/middleware_test.go @@ -21,7 +21,7 @@ func TestLuaMiddlewareCreation(t *testing.T) { // 创建临时脚本文件 tmpDir := t.TempDir() scriptPath := filepath.Join(tmpDir, "test.lua") - err = os.WriteFile(scriptPath, []byte("ngx.say('hello')"), 0644) + err = os.WriteFile(scriptPath, []byte("ngx.say('hello')"), 0o644) require.NoError(t, err) config := LuaMiddlewareConfig{ @@ -52,7 +52,7 @@ func TestLuaMiddlewareDefaultConfig(t *testing.T) { // 创建临时脚本文件 tmpDir := t.TempDir() scriptPath := filepath.Join(tmpDir, "test.lua") - err = os.WriteFile(scriptPath, []byte("return 1"), 0644) + err = os.WriteFile(scriptPath, []byte("return 1"), 0o644) require.NoError(t, err) // 使用默认配置 @@ -98,7 +98,7 @@ func TestLuaMiddlewareProcess(t *testing.T) { // 创建脚本文件 tmpDir := t.TempDir() scriptPath := filepath.Join(tmpDir, "test.lua") - err = os.WriteFile(scriptPath, []byte(`ngx.say("hello from lua")`), 0644) + err = os.WriteFile(scriptPath, []byte(`ngx.say("hello from lua")`), 0o644) require.NoError(t, err) config := LuaMiddlewareConfig{ @@ -139,7 +139,7 @@ func TestLuaMiddlewareDisabled(t *testing.T) { // 创建脚本文件 tmpDir := t.TempDir() scriptPath := filepath.Join(tmpDir, "test.lua") - err = os.WriteFile(scriptPath, []byte(`ngx.say("lua output")`), 0644) + err = os.WriteFile(scriptPath, []byte(`ngx.say("lua output")`), 0o644) require.NoError(t, err) config := LuaMiddlewareConfig{ @@ -180,7 +180,7 @@ func TestLuaMiddlewareSetters(t *testing.T) { tmpDir := t.TempDir() scriptPath := filepath.Join(tmpDir, "test.lua") - err = os.WriteFile(scriptPath, []byte("return 1"), 0644) + err = os.WriteFile(scriptPath, []byte("return 1"), 0o644) require.NoError(t, err) config := DefaultLuaMiddlewareConfig() @@ -232,7 +232,7 @@ func TestMultiPhaseLuaMiddlewareAddPhase(t *testing.T) { // 添加 rewrite 阶段 rewriteScript := filepath.Join(tmpDir, "rewrite.lua") - err = os.WriteFile(rewriteScript, []byte("ngx.var.uri = '/rewritten'"), 0644) + err = os.WriteFile(rewriteScript, []byte("ngx.var.uri = '/rewritten'"), 0o644) require.NoError(t, err) err = multi.AddPhase(PhaseRewrite, rewriteScript, 10*time.Second) @@ -243,7 +243,7 @@ func TestMultiPhaseLuaMiddlewareAddPhase(t *testing.T) { // 添加 access 阶段 accessScript := filepath.Join(tmpDir, "access.lua") - err = os.WriteFile(accessScript, []byte("ngx.exit(403)"), 0644) + err = os.WriteFile(accessScript, []byte("ngx.exit(403)"), 0o644) require.NoError(t, err) err = multi.AddPhase(PhaseAccess, accessScript, 10*time.Second) @@ -264,7 +264,7 @@ func TestMultiPhaseLuaMiddlewareRemovePhase(t *testing.T) { multi := NewMultiPhaseLuaMiddleware(engine, "multi-test") scriptPath := filepath.Join(tmpDir, "test.lua") - err = os.WriteFile(scriptPath, []byte("return 1"), 0644) + err = os.WriteFile(scriptPath, []byte("return 1"), 0o644) require.NoError(t, err) err = multi.AddPhase(PhaseRewrite, scriptPath, 10*time.Second) @@ -289,7 +289,7 @@ func TestMultiPhaseLuaMiddlewareProcess(t *testing.T) { // rewrite 阎段脚本 rewriteScript := filepath.Join(tmpDir, "rewrite.lua") - err = os.WriteFile(rewriteScript, []byte(`ngx.say("rewrite")`), 0644) + err = os.WriteFile(rewriteScript, []byte(`ngx.say("rewrite")`), 0o644) require.NoError(t, err) err = multi.AddPhase(PhaseRewrite, rewriteScript, 10*time.Second) @@ -297,7 +297,7 @@ func TestMultiPhaseLuaMiddlewareProcess(t *testing.T) { // content 阎段脚本 contentScript := filepath.Join(tmpDir, "content.lua") - err = os.WriteFile(contentScript, []byte(`ngx.say("content")`), 0644) + err = os.WriteFile(contentScript, []byte(`ngx.say("content")`), 0o644) require.NoError(t, err) err = multi.AddPhase(PhaseContent, contentScript, 10*time.Second) @@ -335,7 +335,7 @@ func TestMultiPhaseLuaMiddlewareGetPhaseMiddleware(t *testing.T) { multi := NewMultiPhaseLuaMiddleware(engine, "multi-test") scriptPath := filepath.Join(tmpDir, "test.lua") - err = os.WriteFile(scriptPath, []byte("return 1"), 0644) + err = os.WriteFile(scriptPath, []byte("return 1"), 0o644) require.NoError(t, err) err = multi.AddPhase(PhaseRewrite, scriptPath, 10*time.Second) @@ -360,7 +360,7 @@ func TestLuaMiddlewareIntegrationWithChain(t *testing.T) { tmpDir := t.TempDir() scriptPath := filepath.Join(tmpDir, "test.lua") - err = os.WriteFile(scriptPath, []byte(`ngx.say("lua middleware")`), 0644) + err = os.WriteFile(scriptPath, []byte(`ngx.say("lua middleware")`), 0o644) require.NoError(t, err) config := LuaMiddlewareConfig{ @@ -401,7 +401,7 @@ func TestLuaMiddlewareExecutionError(t *testing.T) { // 创建有语法错误的脚本 tmpDir := t.TempDir() scriptPath := filepath.Join(tmpDir, "error.lua") - err = os.WriteFile(scriptPath, []byte("invalid lua syntax !!!"), 0644) + err = os.WriteFile(scriptPath, []byte("invalid lua syntax !!!"), 0o644) require.NoError(t, err) config := LuaMiddlewareConfig{ @@ -432,7 +432,7 @@ func TestLuaMiddlewareExit(t *testing.T) { tmpDir := t.TempDir() scriptPath := filepath.Join(tmpDir, "exit.lua") - err = os.WriteFile(scriptPath, []byte(`ngx.say("before exit"); ngx.exit(200)`), 0644) + err = os.WriteFile(scriptPath, []byte(`ngx.say("before exit"); ngx.exit(200)`), 0o644) require.NoError(t, err) config := LuaMiddlewareConfig{ diff --git a/internal/proxy/tempfile_cleaner.go b/internal/proxy/tempfile_cleaner.go index 09cdafc..dc398d3 100644 --- a/internal/proxy/tempfile_cleaner.go +++ b/internal/proxy/tempfile_cleaner.go @@ -225,8 +225,10 @@ func (c *TempFileCleaner) CountOrphanFiles() int { } // globalCleaner 全局清理器实例。 -var globalCleaner *TempFileCleaner -var globalCleanerMu sync.RWMutex +var ( + globalCleaner *TempFileCleaner + globalCleanerMu sync.RWMutex +) // StartGlobalTempFileCleaner 启动全局临时文件清理器。 // diff --git a/internal/proxy/tempfile_test.go b/internal/proxy/tempfile_test.go index 55a0fd1..bfe5968 100644 --- a/internal/proxy/tempfile_test.go +++ b/internal/proxy/tempfile_test.go @@ -427,7 +427,7 @@ func TestTempFileCleaner(t *testing.T) { // 创建一个过期的临时文件 oldFile := filepath.Join(tempDir, TempFilePrefix+"old") - if err := os.WriteFile(oldFile, []byte("old"), 0644); err != nil { + if err := os.WriteFile(oldFile, []byte("old"), 0o644); err != nil { t.Fatalf("创建测试文件失败: %v", err) } @@ -439,7 +439,7 @@ func TestTempFileCleaner(t *testing.T) { // 创建一个非过期的临时文件 newFile := filepath.Join(tempDir, TempFilePrefix+"new") - if err := os.WriteFile(newFile, []byte("new"), 0644); err != nil { + if err := os.WriteFile(newFile, []byte("new"), 0o644); err != nil { t.Fatalf("创建测试文件失败: %v", err) } @@ -463,7 +463,7 @@ func TestTempFileCleaner(t *testing.T) { // 创建一个非 lolly 前缀的文件 otherFile := filepath.Join(tempDir, "other-file") - if err := os.WriteFile(otherFile, []byte("other"), 0644); err != nil { + if err := os.WriteFile(otherFile, []byte("other"), 0o644); err != nil { t.Fatalf("创建测试文件失败: %v", err) } @@ -488,7 +488,7 @@ func TestTempFileCleaner(t *testing.T) { // 创建孤儿文件 orphanFile := filepath.Join(tempDir, TempFilePrefix+"orphan") - if err := os.WriteFile(orphanFile, []byte("orphan"), 0644); err != nil { + if err := os.WriteFile(orphanFile, []byte("orphan"), 0o644); err != nil { t.Fatalf("创建测试文件失败: %v", err) } diff --git a/internal/server/status.go b/internal/server/status.go index 22fa63d..4dec6e4 100644 --- a/internal/server/status.go +++ b/internal/server/status.go @@ -145,10 +145,8 @@ func NewStatusHandler(server *Server, cfg *config.StatusConfig) (*StatusHandler, } // 转换为 CIDR 格式 if ip.To4() != nil { - _, network, _ = net.ParseCIDR(cidr + "/32") } else { - _, network, _ = net.ParseCIDR(cidr + "/128") } } diff --git a/internal/server/upgrade.go b/internal/server/upgrade.go index 46a3afe..d65e679 100644 --- a/internal/server/upgrade.go +++ b/internal/server/upgrade.go @@ -223,21 +223,18 @@ func (u *UpgradeManager) GracefulUpgrade(newBinary string) error { // 写入新 PID 到文件 if u.pidFile != "" { - _ = os.WriteFile(u.pidFile, []byte(fmt.Sprintf("%d", newPid)), 0o644) } // 启动 goroutine 等待子进程结束,避免产生僵尸进程 // cmd.Wait() 会回收子进程资源,确保不会产生 defunct 进程 go func() { - _ = cmd.Wait() }() // 关闭父进程中的文件描述符副本(子进程已继承) // 避免文件描述符泄漏 for _, file := range files { - _ = file.Close() } @@ -334,7 +331,6 @@ func (u *UpgradeManager) SetupSignalHandlers(newBinary string) { go func() { for sig := range sigCh { if sig == syscall.SIGUSR2 { - _ = u.GracefulUpgrade(newBinary) } }