diff --git a/.auto/log.jsonl b/.auto/log.jsonl index 098d17dc..aaa7f3c2 100644 --- a/.auto/log.jsonl +++ b/.auto/log.jsonl @@ -1,3 +1,4 @@ {"type":"config","name":"前后端代码质量优化(符合最佳实践)","metricName":"total_issues","metricUnit":"","bestDirection":"lower"} {"run":1,"commit":"305d609","metric":108,"metrics":{"golint_canonicalheader":8,"golint_errname":1,"golint_errorlint":12,"golint_forcetypeassert":3,"golint_gosec":2,"golint_intrange":3,"golint_modernize":37,"golint_nilnil":3,"golint_perfsprint":18,"golint_prealloc":3,"golint_recvcheck":7,"golint_usestdlibvars":3,"golint_wastedassign":7,"golint_total":107,"eslint_problems":1,"eslint_errors":0,"eslint_warnings":1,"tsc_errors":0,"measure_s":36},"status":"checks_failed","description":"基线:总问题 108(golangci 107 + eslint 1)。checks 失败的唯一原因:repo 自带 golangci gate 有 2 个既有 gosec G115 问题(预期内,首次修复后即绿)。","timestamp":1786871594292,"segment":0,"confidence":null,"asi":{"hypothesis":"baseline","next_action_hint":"修复 internal/apps/edge/observability/linux.go 的 2 个 G115 gosec 问题后 checks.sh 才能通过;之后每次迭代即可正常 keep/discard"}} {"run":2,"commit":"f1f6bb8","metric":106,"metrics":{"golint_canonicalheader":8,"golint_errname":1,"golint_errorlint":12,"golint_forcetypeassert":3,"golint_gosec":0,"golint_intrange":3,"golint_modernize":37,"golint_nilnil":3,"golint_perfsprint":18,"golint_prealloc":3,"golint_recvcheck":7,"golint_usestdlibvars":3,"golint_wastedassign":7,"golint_total":105,"eslint_problems":1,"eslint_errors":0,"eslint_warnings":1,"tsc_errors":0,"measure_s":38},"status":"keep","description":"修复 internal/apps/edge/observability/linux.go 的 2 个 gosec G115 整数溢出转换:helper 改为接收 int64 b,用 gosec 认可的饱和乘法模式(uint64 域乘积 + 上界比较),去掉原 //nolint:gosec,语义不变(Bsize 恒为正)。repo 自带 gate 首次全绿。","timestamp":1786872064145,"segment":0,"confidence":null,"asi":{"hypothesis":"修复 gosec G115:multiplyUint64ToInt64 改为 accept int64 b 并采用 gosec 认可的饱和乘法模式","insight":"gosec G115 不接受分支上界证明(a > MaxInt64/b),但接受先算 uint64 乘积再 if v > MaxInt64 饱和的模式,无需 nolint","next_action_hint":"下一步批量清理 modernize(37)/perfsprint(18) 等自动可修复类别,用 golangci-lint --fix 后人工核对 diff"}} +{"run":3,"commit":"b76f707","metric":74,"metrics":{"golint_canonicalheader":8,"golint_errname":1,"golint_errorlint":12,"golint_forcetypeassert":3,"golint_gosec":0,"golint_intrange":3,"golint_modernize":5,"golint_nilnil":3,"golint_perfsprint":18,"golint_prealloc":3,"golint_recvcheck":7,"golint_usestdlibvars":3,"golint_wastedassign":7,"golint_total":73,"eslint_problems":1,"eslint_errors":0,"eslint_warnings":1,"tsc_errors":0,"measure_s":38},"status":"keep","description":"modernize 37→5(-32):interface{}→any、内置 max/min、slices/maps 辅助、strings.Cut/SplitSeq、strings.Builder(修复 mail.go O(n²) 拼接)。逐 hunk 核对语义等价;omitzero 冲突修复被自动跳过(wire 格式不变);手动清 4 处遗留 sort import + 2 处 QF1012。","timestamp":1786872502383,"segment":0,"confidence":17,"asi":{"hypothesis":"批量应用 modernize 自动修复(interface{}→any、max/min、slices.Sort/Contains、strings.Cut/SplitSeq、maps.Copy、strings.Builder)","insight":"golangci-lint --fix 会把 omitempty→omitzero 的冲突修复跳过(2个文件保留原 tag,wire 格式不变,好);但 fixer 会遗留未使用的 sort import,需手动清 4 处;mail.go 的 Builder 迁移附带暴露 2 个 QF1012,顺手用 fmt.Fprintf 修复。全部修复语义等价,已逐项核对 diff","next_action_hint":"剩余 modernize=5 应为 omitzero 冲突文件;下轮先处理 perfsprint(18):先看 --fix 是否安全再决定"}} diff --git a/internal/apps/admin/status/routers.go b/internal/apps/admin/status/routers.go index c5ad700a..37ee1434 100644 --- a/internal/apps/admin/status/routers.go +++ b/internal/apps/admin/status/routers.go @@ -14,6 +14,7 @@ import ( "os" "os/exec" "runtime" + "strconv" "time" "github.com/Rain-kl/Wavelet/internal/infra/config" @@ -309,7 +310,7 @@ func exportSQLite(c *gin.Context) { c.Header("Content-Disposition", `attachment; filename="openflare.db"`) c.Header("Content-Type", "application/octet-stream") - c.Header("Content-Length", fmt.Sprintf("%d", fi.Size())) + c.Header("Content-Length", strconv.FormatInt(fi.Size(), 10)) c.Status(http.StatusOK) http.ServeContent(c.Writer, c.Request, "openflare.db", fi.ModTime(), f) } @@ -328,7 +329,7 @@ func exportPostgres(c *gin.Context) { args := []string{ "--no-password", "-h", dbCfg.Host, - "-p", fmt.Sprintf("%d", dbCfg.Port), + "-p", strconv.Itoa(dbCfg.Port), "-U", dbCfg.Username, dbCfg.Database, } diff --git a/internal/apps/agent/nginx/manager.go b/internal/apps/agent/nginx/manager.go index 8796530f..82c08d34 100644 --- a/internal/apps/agent/nginx/manager.go +++ b/internal/apps/agent/nginx/manager.go @@ -516,7 +516,7 @@ func (m *Manager) CurrentChecksum() (string, error) { normalizedMain = strings.ReplaceAll(normalizedMain, listen, openrestyrender.ObservabilityListenPlaceholder) } if m.OpenrestyObservabilityPort > 0 { - normalizedMain = strings.ReplaceAll(normalizedMain, fmt.Sprintf("%d", m.OpenrestyObservabilityPort), openrestyrender.ObservabilityPortPlaceholder) + normalizedMain = strings.ReplaceAll(normalizedMain, strconv.Itoa(m.OpenrestyObservabilityPort), openrestyrender.ObservabilityPortPlaceholder) } if resolverDirective := strings.TrimSpace(m.OpenrestyResolverDirective); resolverDirective != "" { normalizedMain = strings.ReplaceAll(normalizedMain, resolverDirective, ResolverDirectivePlaceholder) @@ -1463,7 +1463,7 @@ func (m *Manager) renderMainConfig(content string) string { rendered = strings.ReplaceAll(rendered, openrestyrender.ObservabilityListenPlaceholder, listen) } if m.OpenrestyObservabilityPort > 0 { - rendered = strings.ReplaceAll(rendered, openrestyrender.ObservabilityPortPlaceholder, fmt.Sprintf("%d", m.OpenrestyObservabilityPort)) + rendered = strings.ReplaceAll(rendered, openrestyrender.ObservabilityPortPlaceholder, strconv.Itoa(m.OpenrestyObservabilityPort)) } if resolverDirective := strings.TrimSpace(m.OpenrestyResolverDirective); resolverDirective != "" { rendered = strings.ReplaceAll(rendered, ResolverDirectivePlaceholder, resolverDirective) diff --git a/internal/apps/agent/sync/pages.go b/internal/apps/agent/sync/pages.go index f2c64fc1..840eee8c 100644 --- a/internal/apps/agent/sync/pages.go +++ b/internal/apps/agent/sync/pages.go @@ -15,6 +15,7 @@ import ( "log/slog" "os" "path/filepath" + "strconv" "strings" "github.com/Rain-kl/Wavelet/internal/apps/agent/protocol" @@ -392,7 +393,7 @@ func (s *Service) downloadPagesProjectPackage( metadata *protocol.PagesProjectLatestHashResponse, maxBytes int64, ) (packagePath string, hash string, err error) { - releasesRoot := filepath.Join(s.pagesDir, "projects", fmt.Sprintf("%d", projectID), "releases") + releasesRoot := filepath.Join(s.pagesDir, "projects", strconv.FormatUint(uint64(projectID), 10), "releases") if err := os.MkdirAll(releasesRoot, pagesDirPerm); err != nil { return "", "", err } @@ -441,7 +442,7 @@ func cleanupPagesProjectStaleReleases(baseDir string, projectID uint, keepHash s if projectID == 0 || keepHash == "" { return nil } - releasesRoot := filepath.Join(baseDir, "projects", fmt.Sprintf("%d", projectID), "releases") + releasesRoot := filepath.Join(baseDir, "projects", strconv.FormatUint(uint64(projectID), 10), "releases") entries, err := os.ReadDir(releasesRoot) //nolint:gosec // managed PagesDir if err != nil { if os.IsNotExist(err) { @@ -982,9 +983,9 @@ func writePagesMarker(dir string, project pagesProjectRef) error { } func pagesProjectCurrentDir(baseDir string, projectID uint) string { - return filepath.Join(baseDir, "projects", fmt.Sprintf("%d", projectID), "current") + return filepath.Join(baseDir, "projects", strconv.FormatUint(uint64(projectID), 10), "current") } func pagesProjectReleaseDir(baseDir string, projectID uint, checksum string) string { - return filepath.Join(baseDir, "projects", fmt.Sprintf("%d", projectID), "releases", checksum) + return filepath.Join(baseDir, "projects", strconv.FormatUint(uint64(projectID), 10), "releases", checksum) } diff --git a/internal/apps/edge/updater/restart_unix.go b/internal/apps/edge/updater/restart_unix.go index 403aac11..4855c309 100644 --- a/internal/apps/edge/updater/restart_unix.go +++ b/internal/apps/edge/updater/restart_unix.go @@ -4,6 +4,7 @@ package updater import ( + "errors" "fmt" "log/slog" "os" @@ -37,7 +38,7 @@ func replaceAndRestart(execPath string, tmpPath string) error { if err := syscall.Exec(execPath, os.Args, os.Environ()); err != nil { //nolint:gosec // execPath is the validated edge updater binary path return fmt.Errorf("exec restart: %w", err) } - return fmt.Errorf("unreachable after exec") + return errors.New("unreachable after exec") } func removeBackupBinary(path string) error { diff --git a/internal/apps/edge/updater/service.go b/internal/apps/edge/updater/service.go index cf38a824..a1f87fbb 100644 --- a/internal/apps/edge/updater/service.go +++ b/internal/apps/edge/updater/service.go @@ -6,6 +6,7 @@ import ( "crypto/sha256" "encoding/hex" "encoding/json" + "errors" "fmt" "io" "log/slog" @@ -295,7 +296,7 @@ func parseSHA256Checksum(content string, assetName string) (string, error) { } } if assetName == "" { - return "", fmt.Errorf("checksum asset does not contain a valid sha256 digest") + return "", errors.New("checksum asset does not contain a valid sha256 digest") } return "", fmt.Errorf("checksum asset does not contain a sha256 digest for %q", assetName) } @@ -340,7 +341,7 @@ func isSHA256Hex(value string) bool { func (s *Service) downloadAndRestart(ctx context.Context, url string, expectedChecksum string, targetPath string) error { expectedChecksum = strings.ToLower(strings.TrimSpace(expectedChecksum)) if !isSHA256Hex(expectedChecksum) { - return fmt.Errorf("invalid expected sha256 checksum") + return errors.New("invalid expected sha256 checksum") } req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) if err != nil { diff --git a/internal/apps/oauth/cache.go b/internal/apps/oauth/cache.go index 266f29e2..72a9eafd 100644 --- a/internal/apps/oauth/cache.go +++ b/internal/apps/oauth/cache.go @@ -5,6 +5,7 @@ package oauth import ( "context" + "errors" "fmt" "strconv" "sync" @@ -140,7 +141,7 @@ func GetCachedToken(ctx context.Context, tokenHash string) (*model.AccessToken, return &token, nil } } - return nil, fmt.Errorf("cache miss") + return nil, errors.New("cache miss") } // SetCachedToken 设置 AccessToken 缓存 @@ -183,7 +184,7 @@ func GetCachedUser(ctx context.Context, userID uint64) (*model.User, error) { return &u, nil } } - return nil, fmt.Errorf("cache miss") + return nil, errors.New("cache miss") } // SetCachedUser 设置 User 缓存 diff --git a/internal/apps/openflare/agent/waf_ip_group.go b/internal/apps/openflare/agent/waf_ip_group.go index 73167d23..a13886a7 100644 --- a/internal/apps/openflare/agent/waf_ip_group.go +++ b/internal/apps/openflare/agent/waf_ip_group.go @@ -46,7 +46,7 @@ func ChangedWAFIPGroupsForAgent(ctx context.Context, ids []uint, checksums map[s } changed := make([]WAFIPGroup, 0, len(groups)) for _, group := range groups { - if strings.TrimSpace(checksums[fmt.Sprintf("%d", group.ID)]) == group.Checksum { + if strings.TrimSpace(checksums[strconv.FormatUint(uint64(group.ID), 10)]) == group.Checksum { continue } changed = append(changed, group) diff --git a/internal/apps/openflare/config_version/helpers.go b/internal/apps/openflare/config_version/helpers.go index 49c8b3a2..1c776471 100644 --- a/internal/apps/openflare/config_version/helpers.go +++ b/internal/apps/openflare/config_version/helpers.go @@ -6,6 +6,7 @@ package config_version import ( "context" "encoding/json" + "errors" "fmt" "net" "strconv" @@ -27,7 +28,7 @@ func normalizeSnapshotDomains(domains []string) ([]string, error) { for _, raw := range domains { domain := strings.ToLower(strings.TrimSpace(raw)) if domain == "" || strings.Contains(domain, "://") || strings.Contains(domain, "/") { - return nil, fmt.Errorf("domains payload is invalid") + return nil, errors.New("domains payload is invalid") } if _, ok := seen[domain]; ok { continue @@ -36,7 +37,7 @@ func normalizeSnapshotDomains(domains []string) ([]string, error) { normalized = append(normalized, domain) } if len(normalized) == 0 { - return nil, fmt.Errorf("domain is required") + return nil, errors.New("domain is required") } return normalized, nil } @@ -55,7 +56,7 @@ func decodeStoredUpstreams(raw string, fallbackOriginURL string) ([]string, erro } var upstreams []string if err := json.Unmarshal([]byte(text), &upstreams); err != nil { - return nil, fmt.Errorf("upstreams payload is invalid") + return nil, errors.New("upstreams payload is invalid") } return normalizeUpstreams(fallbackOriginURL, upstreams) } @@ -79,7 +80,7 @@ func normalizeUpstreams(originURL string, upstreams []string) ([]string, error) normalized = append(normalized, value) } if len(normalized) == 0 { - return nil, fmt.Errorf("upstream is required") + return nil, errors.New("upstream is required") } return normalized, nil } @@ -91,7 +92,7 @@ func decodeStoredCustomHeaders(raw string) ([]customHeaderInput, error) { } var headers []customHeaderInput if err := json.Unmarshal([]byte(text), &headers); err != nil { - return nil, fmt.Errorf("custom_headers payload is invalid") + return nil, errors.New("custom_headers payload is invalid") } return headers, nil } @@ -103,7 +104,7 @@ func decodeStoredCacheRules(raw string) ([]string, error) { } var rules []string if err := json.Unmarshal([]byte(text), &rules); err != nil { - return nil, fmt.Errorf("cache_rules payload is invalid") + return nil, errors.New("cache_rules payload is invalid") } normalized := make([]string, 0, len(rules)) for _, rule := range rules { diff --git a/internal/apps/openflare/config_version/logics.go b/internal/apps/openflare/config_version/logics.go index 973608dc..e7828b14 100644 --- a/internal/apps/openflare/config_version/logics.go +++ b/internal/apps/openflare/config_version/logics.go @@ -494,51 +494,51 @@ func diffOpenRestyOptionDetails(left openRestyConfigSnapshot, right openRestyCon CurrentValue: current, }) } - appendIfChanged("OpenRestyDefaultServerReturnStatus", fmt.Sprintf("%d", left.DefaultServerReturnStatus), fmt.Sprintf("%d", right.DefaultServerReturnStatus)) + appendIfChanged("OpenRestyDefaultServerReturnStatus", strconv.Itoa(left.DefaultServerReturnStatus), strconv.Itoa(right.DefaultServerReturnStatus)) appendIfChanged("OpenRestyWorkerProcesses", left.WorkerProcesses, right.WorkerProcesses) - appendIfChanged("OpenRestyWorkerConnections", fmt.Sprintf("%d", left.WorkerConnections), fmt.Sprintf("%d", right.WorkerConnections)) - appendIfChanged("OpenRestyWorkerRlimitNofile", fmt.Sprintf("%d", left.WorkerRlimitNofile), fmt.Sprintf("%d", right.WorkerRlimitNofile)) + appendIfChanged("OpenRestyWorkerConnections", strconv.Itoa(left.WorkerConnections), strconv.Itoa(right.WorkerConnections)) + appendIfChanged("OpenRestyWorkerRlimitNofile", strconv.Itoa(left.WorkerRlimitNofile), strconv.Itoa(right.WorkerRlimitNofile)) appendIfChanged("OpenRestyEventsUse", left.EventsUse, right.EventsUse) - appendIfChanged("OpenRestyEventsMultiAcceptEnabled", fmt.Sprintf("%t", left.EventsMultiAcceptEnabled), fmt.Sprintf("%t", right.EventsMultiAcceptEnabled)) - appendIfChanged("OpenRestyKeepaliveTimeout", fmt.Sprintf("%d", left.KeepaliveTimeout), fmt.Sprintf("%d", right.KeepaliveTimeout)) - appendIfChanged("OpenRestyKeepaliveRequests", fmt.Sprintf("%d", left.KeepaliveRequests), fmt.Sprintf("%d", right.KeepaliveRequests)) - appendIfChanged("OpenRestyClientHeaderTimeout", fmt.Sprintf("%d", left.ClientHeaderTimeout), fmt.Sprintf("%d", right.ClientHeaderTimeout)) - appendIfChanged("OpenRestyClientBodyTimeout", fmt.Sprintf("%d", left.ClientBodyTimeout), fmt.Sprintf("%d", right.ClientBodyTimeout)) + appendIfChanged("OpenRestyEventsMultiAcceptEnabled", strconv.FormatBool(left.EventsMultiAcceptEnabled), strconv.FormatBool(right.EventsMultiAcceptEnabled)) + appendIfChanged("OpenRestyKeepaliveTimeout", strconv.Itoa(left.KeepaliveTimeout), strconv.Itoa(right.KeepaliveTimeout)) + appendIfChanged("OpenRestyKeepaliveRequests", strconv.Itoa(left.KeepaliveRequests), strconv.Itoa(right.KeepaliveRequests)) + appendIfChanged("OpenRestyClientHeaderTimeout", strconv.Itoa(left.ClientHeaderTimeout), strconv.Itoa(right.ClientHeaderTimeout)) + appendIfChanged("OpenRestyClientBodyTimeout", strconv.Itoa(left.ClientBodyTimeout), strconv.Itoa(right.ClientBodyTimeout)) appendIfChanged("OpenRestyClientMaxBodySize", left.ClientMaxBodySize, right.ClientMaxBodySize) appendIfChanged("OpenRestyLargeClientHeaderBuffers", left.LargeClientHeaderBuffers, right.LargeClientHeaderBuffers) - appendIfChanged("OpenRestySendTimeout", fmt.Sprintf("%d", left.SendTimeout), fmt.Sprintf("%d", right.SendTimeout)) - appendIfChanged("OpenRestyProxyConnectTimeout", fmt.Sprintf("%d", left.ProxyConnectTimeout), fmt.Sprintf("%d", right.ProxyConnectTimeout)) - appendIfChanged("OpenRestyProxySendTimeout", fmt.Sprintf("%d", left.ProxySendTimeout), fmt.Sprintf("%d", right.ProxySendTimeout)) - appendIfChanged("OpenRestyProxyReadTimeout", fmt.Sprintf("%d", left.ProxyReadTimeout), fmt.Sprintf("%d", right.ProxyReadTimeout)) - appendIfChanged("OpenRestyWebsocketEnabled", fmt.Sprintf("%t", left.WebsocketEnabled), fmt.Sprintf("%t", right.WebsocketEnabled)) - appendIfChanged("OpenRestyHTTP3Enabled", fmt.Sprintf("%t", left.HTTP3Enabled), fmt.Sprintf("%t", right.HTTP3Enabled)) - appendIfChanged("OpenRestyProxyRequestBufferingEnabled", fmt.Sprintf("%t", left.ProxyRequestBuffering), fmt.Sprintf("%t", right.ProxyRequestBuffering)) - appendIfChanged("OpenRestyProxyBufferingEnabled", fmt.Sprintf("%t", left.ProxyBufferingEnabled), fmt.Sprintf("%t", right.ProxyBufferingEnabled)) + appendIfChanged("OpenRestySendTimeout", strconv.Itoa(left.SendTimeout), strconv.Itoa(right.SendTimeout)) + appendIfChanged("OpenRestyProxyConnectTimeout", strconv.Itoa(left.ProxyConnectTimeout), strconv.Itoa(right.ProxyConnectTimeout)) + appendIfChanged("OpenRestyProxySendTimeout", strconv.Itoa(left.ProxySendTimeout), strconv.Itoa(right.ProxySendTimeout)) + appendIfChanged("OpenRestyProxyReadTimeout", strconv.Itoa(left.ProxyReadTimeout), strconv.Itoa(right.ProxyReadTimeout)) + appendIfChanged("OpenRestyWebsocketEnabled", strconv.FormatBool(left.WebsocketEnabled), strconv.FormatBool(right.WebsocketEnabled)) + appendIfChanged("OpenRestyHTTP3Enabled", strconv.FormatBool(left.HTTP3Enabled), strconv.FormatBool(right.HTTP3Enabled)) + appendIfChanged("OpenRestyProxyRequestBufferingEnabled", strconv.FormatBool(left.ProxyRequestBuffering), strconv.FormatBool(right.ProxyRequestBuffering)) + appendIfChanged("OpenRestyProxyBufferingEnabled", strconv.FormatBool(left.ProxyBufferingEnabled), strconv.FormatBool(right.ProxyBufferingEnabled)) appendIfChanged("OpenRestyProxyBuffers", left.ProxyBuffers, right.ProxyBuffers) appendIfChanged("OpenRestyProxyBufferSize", left.ProxyBufferSize, right.ProxyBufferSize) appendIfChanged("OpenRestyProxyBusyBuffersSize", left.ProxyBusyBuffersSize, right.ProxyBusyBuffersSize) - appendIfChanged("OpenRestyGzipEnabled", fmt.Sprintf("%t", left.GzipEnabled), fmt.Sprintf("%t", right.GzipEnabled)) - appendIfChanged("OpenRestyGzipMinLength", fmt.Sprintf("%d", left.GzipMinLength), fmt.Sprintf("%d", right.GzipMinLength)) - appendIfChanged("OpenRestyGzipCompLevel", fmt.Sprintf("%d", left.GzipCompLevel), fmt.Sprintf("%d", right.GzipCompLevel)) + appendIfChanged("OpenRestyGzipEnabled", strconv.FormatBool(left.GzipEnabled), strconv.FormatBool(right.GzipEnabled)) + appendIfChanged("OpenRestyGzipMinLength", strconv.Itoa(left.GzipMinLength), strconv.Itoa(right.GzipMinLength)) + appendIfChanged("OpenRestyGzipCompLevel", strconv.Itoa(left.GzipCompLevel), strconv.Itoa(right.GzipCompLevel)) appendIfChanged("OpenRestyResolvers", left.Resolvers, right.Resolvers) - appendIfChanged("OpenRestyCacheEnabled", fmt.Sprintf("%t", left.CacheEnabled), fmt.Sprintf("%t", right.CacheEnabled)) + appendIfChanged("OpenRestyCacheEnabled", strconv.FormatBool(left.CacheEnabled), strconv.FormatBool(right.CacheEnabled)) appendIfChanged("OpenRestyCachePath", left.CachePath, right.CachePath) appendIfChanged("OpenRestyCacheLevels", left.CacheLevels, right.CacheLevels) appendIfChanged("OpenRestyCacheInactive", left.CacheInactive, right.CacheInactive) appendIfChanged("OpenRestyCacheMaxSize", left.CacheMaxSize, right.CacheMaxSize) appendIfChanged("OpenRestyCacheKeyTemplate", left.CacheKeyTemplate, right.CacheKeyTemplate) - appendIfChanged("OpenRestyCacheLockEnabled", fmt.Sprintf("%t", left.CacheLockEnabled), fmt.Sprintf("%t", right.CacheLockEnabled)) + appendIfChanged("OpenRestyCacheLockEnabled", strconv.FormatBool(left.CacheLockEnabled), strconv.FormatBool(right.CacheLockEnabled)) appendIfChanged("OpenRestyCacheLockTimeout", left.CacheLockTimeout, right.CacheLockTimeout) appendIfChanged("OpenRestyCacheUseStale", left.CacheUseStale, right.CacheUseStale) - appendIfChanged("OpenRestyDefaultLimitConnPerServer", fmt.Sprintf("%d", left.DefaultLimitConnPerServer), fmt.Sprintf("%d", right.DefaultLimitConnPerServer)) - appendIfChanged("OpenRestyDefaultLimitConnPerIP", fmt.Sprintf("%d", left.DefaultLimitConnPerIP), fmt.Sprintf("%d", right.DefaultLimitConnPerIP)) + appendIfChanged("OpenRestyDefaultLimitConnPerServer", strconv.Itoa(left.DefaultLimitConnPerServer), strconv.Itoa(right.DefaultLimitConnPerServer)) + appendIfChanged("OpenRestyDefaultLimitConnPerIP", strconv.Itoa(left.DefaultLimitConnPerIP), strconv.Itoa(right.DefaultLimitConnPerIP)) appendIfChanged("OpenRestyDefaultLimitRate", left.DefaultLimitRate, right.DefaultLimitRate) appendIfChanged("OpenRestyDefaultLimitReqPerIP", left.DefaultLimitReqPerIP, right.DefaultLimitReqPerIP) - appendIfChanged("OriginErrorPageEnabled", fmt.Sprintf("%t", left.OriginErrorPageEnabled), fmt.Sprintf("%t", right.OriginErrorPageEnabled)) + appendIfChanged("OriginErrorPageEnabled", strconv.FormatBool(left.OriginErrorPageEnabled), strconv.FormatBool(right.OriginErrorPageEnabled)) appendIfChanged("OriginErrorPageStatusCodes", encodeOriginErrorPageStatusCodes(left.OriginErrorPageStatusCodes), encodeOriginErrorPageStatusCodes(right.OriginErrorPageStatusCodes)) appendIfChanged("OriginErrorPageHTML", left.OriginErrorPageHTML, right.OriginErrorPageHTML) - appendIfChanged("OriginErrorPageGetOnly", fmt.Sprintf("%t", left.OriginErrorPageGetOnly), fmt.Sprintf("%t", right.OriginErrorPageGetOnly)) - appendIfChanged("SWOfflineEnabled", fmt.Sprintf("%t", left.SWOfflineEnabled), fmt.Sprintf("%t", right.SWOfflineEnabled)) + appendIfChanged("OriginErrorPageGetOnly", strconv.FormatBool(left.OriginErrorPageGetOnly), strconv.FormatBool(right.OriginErrorPageGetOnly)) + appendIfChanged("SWOfflineEnabled", strconv.FormatBool(left.SWOfflineEnabled), strconv.FormatBool(right.SWOfflineEnabled)) appendIfChanged("SWOfflineHTML", left.SWOfflineHTML, right.SWOfflineHTML) appendIfChanged("SWOfflineDomains", encodeSWOfflineDomains(left.SWOfflineDomains), encodeSWOfflineDomains(right.SWOfflineDomains)) return changes diff --git a/internal/apps/openflare/config_version/snapshot.go b/internal/apps/openflare/config_version/snapshot.go index a72947b5..77c7f352 100644 --- a/internal/apps/openflare/config_version/snapshot.go +++ b/internal/apps/openflare/config_version/snapshot.go @@ -478,7 +478,7 @@ func decodeIPList(raw string) ([]string, error) { } var items []string if err := json.Unmarshal([]byte(text), &items); err != nil { - return nil, fmt.Errorf("ip_list payload is invalid") + return nil, errors.New("ip_list payload is invalid") } return items, nil } diff --git a/internal/apps/openflare/flared/logics.go b/internal/apps/openflare/flared/logics.go index c20ecf26..3e7c3a87 100644 --- a/internal/apps/openflare/flared/logics.go +++ b/internal/apps/openflare/flared/logics.go @@ -28,7 +28,7 @@ const ( // Heartbeat processes an OpenFlared heartbeat and returns runtime settings. func Heartbeat(ctx context.Context, node *model.OpenFlareNode, payload HeartbeatPayload) (*HeartbeatResponse, error) { if node == nil { - return nil, fmt.Errorf("tunnel client node is nil") + return nil, errors.New("tunnel client node is nil") } if node.NodeType != "tunnel_client" { return nil, fmt.Errorf("node %s is not a tunnel_client", node.NodeID) @@ -95,7 +95,7 @@ func Heartbeat(ctx context.Context, node *model.OpenFlareNode, payload Heartbeat // GetTunnelConfig builds the full tunnel routing config for an OpenFlared client. func GetTunnelConfig(ctx context.Context, node *model.OpenFlareNode) (*TunnelConfigResponse, error) { if node == nil { - return nil, fmt.Errorf("node is nil") + return nil, errors.New("node is nil") } activeVersion, err := getActiveConfigMeta(ctx) diff --git a/internal/apps/openflare/node/helpers.go b/internal/apps/openflare/node/helpers.go index ef4e3199..8c1b567e 100644 --- a/internal/apps/openflare/node/helpers.go +++ b/internal/apps/openflare/node/helpers.go @@ -8,6 +8,7 @@ import ( "crypto/rand" "encoding/hex" "encoding/json" + "errors" "fmt" "io" "net" @@ -317,7 +318,7 @@ func fetchLatestStableGitHubRelease(ctx context.Context, repo string) (*githubRe url := fmt.Sprintf(githubReleasesAPIBase+"/latest", strings.TrimSpace(repo)) req, err := newGitHubReleaseRequest(ctx, url) if err != nil { - return nil, fmt.Errorf("创建更新请求失败") + return nil, errors.New("创建更新请求失败") } resp, err := releaseHTTPClient.Do(req) if err != nil { @@ -334,7 +335,7 @@ func fetchLatestPreviewGitHubRelease(ctx context.Context, repo string) (*githubR url := fmt.Sprintf(githubReleasesAPIBase+"?per_page=20", strings.TrimSpace(repo)) req, err := newGitHubReleaseRequest(ctx, url) if err != nil { - return nil, fmt.Errorf("创建更新请求失败") + return nil, errors.New("创建更新请求失败") } resp, err := releaseHTTPClient.Do(req) if err != nil { @@ -346,7 +347,7 @@ func fetchLatestPreviewGitHubRelease(ctx context.Context, repo string) (*githubR } var releases []githubReleaseResponse if err = json.NewDecoder(resp.Body).Decode(&releases); err != nil { - return nil, fmt.Errorf("解析 preview 版本信息失败") + return nil, errors.New("解析 preview 版本信息失败") } for _, release := range releases { if release.Draft || !release.Prerelease { @@ -355,18 +356,18 @@ func fetchLatestPreviewGitHubRelease(ctx context.Context, repo string) (*githubR releaseCopy := release return &releaseCopy, nil } - return nil, fmt.Errorf("当前没有可用的 preview 发布") + return nil, errors.New("当前没有可用的 preview 发布") } func fetchGitHubReleaseByTag(ctx context.Context, repo string, tag string) (*githubReleaseResponse, error) { tag = strings.TrimSpace(tag) if tag == "" { - return nil, fmt.Errorf("缺少发布版本号") + return nil, errors.New("缺少发布版本号") } url := fmt.Sprintf(githubReleasesAPIBase+"/tags/%s", strings.TrimSpace(repo), tag) req, err := newGitHubReleaseRequest(ctx, url) if err != nil { - return nil, fmt.Errorf("创建更新请求失败") + return nil, errors.New("创建更新请求失败") } resp, err := releaseHTTPClient.Do(req) if err != nil { @@ -395,7 +396,7 @@ func newGitHubReleaseRequest(ctx context.Context, url string) (*http.Request, er func decodeGitHubRelease(reader io.Reader) (*githubReleaseResponse, error) { var release githubReleaseResponse if err := json.NewDecoder(reader).Decode(&release); err != nil { - return nil, fmt.Errorf("解析版本信息失败") + return nil, errors.New("解析版本信息失败") } return &release, nil } diff --git a/internal/apps/openflare/node/logics.go b/internal/apps/openflare/node/logics.go index b5b4468b..1d4edbf1 100644 --- a/internal/apps/openflare/node/logics.go +++ b/internal/apps/openflare/node/logics.go @@ -414,14 +414,14 @@ type forceSyncConfigPayload struct { func ValidateDiscoveryToken(ctx context.Context, token string) error { token = strings.TrimSpace(token) if token == "" { - return fmt.Errorf("缺少 Discovery Token") + return errors.New("缺少 Discovery Token") } discoveryToken, err := ensureGlobalDiscoveryToken(ctx) if err != nil { return err } if token != discoveryToken { - return fmt.Errorf("discovery Token 无效") // error 消息首字母小写 + return errors.New("discovery Token 无效") // error 消息首字母小写 } return nil } diff --git a/internal/apps/openflare/option/validate.go b/internal/apps/openflare/option/validate.go index 986a31e7..f48c2b15 100644 --- a/internal/apps/openflare/option/validate.go +++ b/internal/apps/openflare/option/validate.go @@ -176,16 +176,16 @@ func validateUptimeKumaEnabled(ctx context.Context, key, trimmed string, state m username := strings.TrimSpace(state[model.ConfigKeyUptimeKumaUsername]) password := strings.TrimSpace(state[model.ConfigKeyUptimeKumaPassword]) if url == "" { - return fmt.Errorf("启用 Uptime Kuma 时地址不能为空") + return errors.New("启用 Uptime Kuma 时地址不能为空") } if username == "" { - return fmt.Errorf("启用 Uptime Kuma 时用户名不能为空") + return errors.New("启用 Uptime Kuma 时用户名不能为空") } // 如果待验证的密码为空,且当前配置中也没有密码,则报错 if password == "" { existingPwd, _ := repository.GetSystemConfigByKey(ctx, model.ConfigKeyUptimeKumaPassword) if strings.TrimSpace(existingPwd.Value) == "" { - return fmt.Errorf("启用 Uptime Kuma 时密码不能为空") + return errors.New("启用 Uptime Kuma 时密码不能为空") } } return nil @@ -193,21 +193,21 @@ func validateUptimeKumaEnabled(ctx context.Context, key, trimmed string, state m func validateUptimeKumaUsername(trimmed string, state map[string]string) error { if trimmed == "" && state[model.ConfigKeyUptimeKumaEnabled] == optionValueTrue { - return fmt.Errorf("启用 Uptime Kuma 时用户名不能为空") + return errors.New("启用 Uptime Kuma 时用户名不能为空") } return nil } func validateUptimeKumaURL(trimmed string) error { if trimmed != "" && !strings.HasPrefix(trimmed, "http://") && !strings.HasPrefix(trimmed, "https://") { - return fmt.Errorf("uptime Kuma 地址必须以 http:// 或 https:// 开头") + return errors.New("uptime Kuma 地址必须以 http:// 或 https:// 开头") } return nil } func validateUptimeKumaMonitorScope(trimmed string) error { if trimmed != "all" && trimmed != "selected" { - return fmt.Errorf("监控范围必须为全部站点 (all) 或选择站点 (selected)") + return errors.New("监控范围必须为全部站点 (all) 或选择站点 (selected)") } return nil } diff --git a/internal/apps/openflare/pages/rebind.go b/internal/apps/openflare/pages/rebind.go index b55bb3d3..4c5d9306 100644 --- a/internal/apps/openflare/pages/rebind.go +++ b/internal/apps/openflare/pages/rebind.go @@ -6,6 +6,7 @@ package pages import ( "context" "encoding/json" + "errors" "fmt" "path" "strings" @@ -151,7 +152,7 @@ func resolveProjectIDFromRouteMap(route map[string]json.RawMessage) (uint, error return deployment.ProjectID, nil } } - return 0, fmt.Errorf("pages 配置无效: 缺少 pages_project_id") + return 0, errors.New("pages 配置无效: 缺少 pages_project_id") } func loadActivePagesProject(ctx context.Context, projectID uint, siteName string) (*model.PagesProject, *model.PagesDeployment, error) { diff --git a/internal/apps/openflare/relay/logics.go b/internal/apps/openflare/relay/logics.go index 5339c26f..12f1c462 100644 --- a/internal/apps/openflare/relay/logics.go +++ b/internal/apps/openflare/relay/logics.go @@ -5,6 +5,7 @@ package relay import ( "context" + "errors" "fmt" "strings" "time" @@ -20,7 +21,7 @@ const nodeStatusOnline = "online" // Heartbeat processes a relay heartbeat, updates node status, and returns config. func Heartbeat(ctx context.Context, node *model.OpenFlareNode, payload HeartbeatPayload) (*HeartbeatResponse, error) { if node == nil { - return nil, fmt.Errorf("relay node is nil") + return nil, errors.New("relay node is nil") } payload.Version = strings.TrimSpace(payload.Version) diff --git a/internal/apps/openflare/uptimekuma/client.go b/internal/apps/openflare/uptimekuma/client.go index 0d1bbdc0..5cfb3259 100644 --- a/internal/apps/openflare/uptimekuma/client.go +++ b/internal/apps/openflare/uptimekuma/client.go @@ -89,7 +89,7 @@ func NewSocketIOClient(baseURL string) *SocketIOClient { // Connect performs the Engine.IO handshake and starts the polling loop. func (c *SocketIOClient) Connect() error { slog.Debug("Uptime Kuma client starting handshake", "baseURL", c.baseURL) - u := fmt.Sprintf("%s/socket.io/?EIO=4&transport=polling", c.baseURL) + u := c.baseURL + "/socket.io/?EIO=4&transport=polling" reqHandshake, err := http.NewRequestWithContext(c.ctx, http.MethodGet, u, nil) if err != nil { return fmt.Errorf("create handshake request failed: %w", err) diff --git a/internal/apps/openflare/uptimekuma/sync.go b/internal/apps/openflare/uptimekuma/sync.go index 062b1fc2..e9b6e5fa 100644 --- a/internal/apps/openflare/uptimekuma/sync.go +++ b/internal/apps/openflare/uptimekuma/sync.go @@ -5,6 +5,7 @@ package uptimekuma import ( "context" + "errors" "fmt" "log/slog" "strings" @@ -75,11 +76,11 @@ func SyncToUptimeKuma(ctx context.Context) error { // 检查是否启用 enabled, _ := repository.GetBoolByKey(ctx, model.ConfigKeyUptimeKumaEnabled) if !enabled { - return fmt.Errorf("uptime Kuma integration is disabled") + return errors.New("uptime Kuma integration is disabled") } if !isSyncing.CompareAndSwap(false, true) { - return fmt.Errorf("sync task is already in progress, please try again later") + return errors.New("sync task is already in progress, please try again later") } defer isSyncing.Store(false) @@ -225,7 +226,7 @@ func filterOpenFlareMonitors(monitors map[string]Monitor, openFlareTagID int) ma func routeMonitorURL(ctx context.Context, route *model.ProxyRoute) (string, error) { if route == nil { - return "", fmt.Errorf("proxy route is nil") + return "", errors.New("proxy route is nil") } domains, err := repository.ListZoneDomainsByRouteID(ctx, route.ID) if err != nil { diff --git a/internal/apps/openflare/uptimekuma/sync_helpers.go b/internal/apps/openflare/uptimekuma/sync_helpers.go index 14f7d63f..2a184805 100644 --- a/internal/apps/openflare/uptimekuma/sync_helpers.go +++ b/internal/apps/openflare/uptimekuma/sync_helpers.go @@ -5,6 +5,7 @@ package uptimekuma import ( "context" + "errors" "fmt" "log/slog" "strings" @@ -18,13 +19,13 @@ const monitorListWaitTimeout = 5 * time.Second // validateKumaConfig 验证 kumaConfig 配置完整性 func validateKumaConfig(config *kumaConfig) error { if strings.TrimSpace(config.URL) == "" { - return fmt.Errorf("uptime Kuma URL is not configured") + return errors.New("uptime Kuma URL is not configured") } if strings.TrimSpace(config.Username) == "" { - return fmt.Errorf("uptime Kuma username is not configured") + return errors.New("uptime Kuma username is not configured") } if strings.TrimSpace(config.Password) == "" { - return fmt.Errorf("uptime Kuma password is not configured") + return errors.New("uptime Kuma password is not configured") } return nil } @@ -65,7 +66,7 @@ func connectAndLoginUptimeKuma(kumaURL, kumaUsername, kumaPassword string) (*Soc case <-time.After(monitorListWaitTimeout): client.Close() slog.Error("Timeout waiting for Uptime Kuma monitorList push event") - return nil, fmt.Errorf("timeout waiting for monitorList event from Uptime Kuma") + return nil, errors.New("timeout waiting for monitorList event from Uptime Kuma") } return client, nil } diff --git a/internal/apps/openflare/waf/graph_compile.go b/internal/apps/openflare/waf/graph_compile.go index 20b970f7..7a36b761 100644 --- a/internal/apps/openflare/waf/graph_compile.go +++ b/internal/apps/openflare/waf/graph_compile.go @@ -4,6 +4,7 @@ package waf import ( + "errors" "fmt" "slices" "sort" @@ -35,14 +36,14 @@ func CompileRuleGraph(graph RuleGraph) (RuntimeRuleGraph, error) { } if node.Type == RuleNodeStart { if runtime.Entry != "" { - return RuntimeRuleGraph{}, fmt.Errorf("规则图包含多个开始节点") + return RuntimeRuleGraph{}, errors.New("规则图包含多个开始节点") } runtime.Entry = node.ID } runtime.Nodes[node.ID] = RuntimeRuleNode{Type: node.Type, Config: config} } if runtime.Entry == "" { - return RuntimeRuleGraph{}, fmt.Errorf("规则图缺少开始节点") + return RuntimeRuleGraph{}, errors.New("规则图缺少开始节点") } for _, edge := range graph.Edges { node, ok := runtime.Nodes[edge.Source] diff --git a/internal/apps/openflare/waf/graph_validate.go b/internal/apps/openflare/waf/graph_validate.go index 1025f8ec..90b42e7b 100644 --- a/internal/apps/openflare/waf/graph_validate.go +++ b/internal/apps/openflare/waf/graph_validate.go @@ -68,7 +68,7 @@ func validateRuleGraphLimits(graph RuleGraph) error { if raw, err := json.Marshal(graph); err != nil { return fmt.Errorf("规则图无法序列化: %w", err) } else if len(raw) > maxRuleGraphBytes { - return fmt.Errorf("规则图大小不能超过 256 KiB") + return errors.New("规则图大小不能超过 256 KiB") } return nil } diff --git a/internal/apps/openflare/zone/legacy_import.go b/internal/apps/openflare/zone/legacy_import.go index 938d52a7..351f377e 100644 --- a/internal/apps/openflare/zone/legacy_import.go +++ b/internal/apps/openflare/zone/legacy_import.go @@ -103,7 +103,7 @@ func ImportLegacyTx(ctx context.Context, tx *sql.Tx, postgres bool) (report Impo `), domain).Scan(&existingID, &existingZoneDomain) if scanErr == nil { if existingZoneDomain != root { - report.Conflicts = append(report.Conflicts, fmt.Sprintf("%s: global domain conflict", domain)) + report.Conflicts = append(report.Conflicts, domain+": global domain conflict") } else if item.ProxyRouteID != nil { if _, bindErr := tx.ExecContext(ctx, q(` UPDATE of_zone_domains @@ -147,7 +147,7 @@ func ImportLegacyTx(ctx context.Context, tx *sql.Tx, postgres bool) (report Impo } if len(report.Conflicts) > 0 { - return report, fmt.Errorf("legacy data has conflicts") + return report, errors.New("legacy data has conflicts") } return report, nil } diff --git a/internal/apps/upload/handler/routers.go b/internal/apps/upload/handler/routers.go index 2667611f..72d503b2 100644 --- a/internal/apps/upload/handler/routers.go +++ b/internal/apps/upload/handler/routers.go @@ -204,7 +204,7 @@ func DownloadFile(c *gin.Context) { } } - c.Header("Content-Disposition", fmt.Sprintf("attachment; filename*=UTF-8''%s", url.PathEscape(fileName))) + c.Header("Content-Disposition", "attachment; filename*=UTF-8''"+url.PathEscape(fileName)) filesrv.ServeUpload(c, upload) } diff --git a/internal/apps/upload/task/storage_migration.go b/internal/apps/upload/task/storage_migration.go index dd5746f8..9e2ea119 100644 --- a/internal/apps/upload/task/storage_migration.go +++ b/internal/apps/upload/task/storage_migration.go @@ -69,7 +69,7 @@ func (h *MigrationHandler) ValidatePayload(payload []byte) ([]byte, error) { return payload, err } if active { - return payload, fmt.Errorf("storage migration task is already unresolved") + return payload, errors.New("storage migration task is already unresolved") } return normalized, nil } diff --git a/internal/apps/user/tasks.go b/internal/apps/user/tasks.go index 167854a6..0849f326 100644 --- a/internal/apps/user/tasks.go +++ b/internal/apps/user/tasks.go @@ -152,7 +152,7 @@ func (h *SendEmailHandler) Execute(ctx context.Context, payload []byte) (*task.T return nil, fmt.Errorf(errSendMailFailed, err) } - msg := fmt.Sprintf("邮件成功发送至: %s", req.To) + msg := "邮件成功发送至: " + req.To task.AppendLog(ctx, "%s", msg) return &task.TaskResult{ diff --git a/internal/cmd/banner.go b/internal/cmd/banner.go index f079be73..ae354361 100644 --- a/internal/cmd/banner.go +++ b/internal/cmd/banner.go @@ -34,18 +34,18 @@ func formatStartupBanner(state startupState) string { "/ /_/ / /_/ / __/ / / / __/ / / /_/ / / / __/", "\\____/ .___/\\___/_/ /_/_/ /_/\\__,_/_/ \\___/ ", " /_/ ", - fmt.Sprintf(" OpenFlare %s", buildinfo.Version), + " OpenFlare " + buildinfo.Version, "", - fmt.Sprintf(" Environment: %s", config.Config.App.Env), + " Environment: " + config.Config.App.Env, fmt.Sprintf(" Runtime: %s/%s (%s)", runtime.GOOS, runtime.GOARCH, runtime.Version()), - fmt.Sprintf(" Build time: %s", buildTime()), - fmt.Sprintf(" Database: %s", formatMigration(state.relationalDB)), - fmt.Sprintf(" Analytics: %s", formatMigration(state.clickHouseDB)), + " Build time: " + buildTime(), + " Database: " + formatMigration(state.relationalDB), + " Analytics: " + formatMigration(state.clickHouseDB), } if state.listensForHTTP { - lines = append(lines, fmt.Sprintf(" Listening: http://%s", config.Config.App.Addr)) + lines = append(lines, " Listening: http://"+config.Config.App.Addr) } - lines = append(lines, fmt.Sprintf(" Mode: %s", state.mode), "") + lines = append(lines, " Mode: "+state.mode, "") return strings.Join(lines, "\n") } diff --git a/internal/infra/objectstore/local.go b/internal/infra/objectstore/local.go index 3e172116..0f02e5c8 100644 --- a/internal/infra/objectstore/local.go +++ b/internal/infra/objectstore/local.go @@ -5,6 +5,7 @@ package objectstore import ( "context" + "errors" "fmt" "io" "mime" @@ -20,7 +21,7 @@ type localBackend struct { func newLocalBackend(cfg LocalConfig) (*localBackend, error) { root := filepath.Clean(cfg.Root) if root == "" { - return nil, fmt.Errorf("local root is required") + return nil, errors.New("local root is required") } return &localBackend{root: root}, nil } @@ -103,7 +104,7 @@ func (b *localBackend) path(key string) (string, error) { } rel, err := filepath.Rel(absRoot, absPath) if err != nil || strings.HasPrefix(rel, "..") { - return "", fmt.Errorf("storage key escapes local root") + return "", errors.New("storage key escapes local root") } return cleanPath, nil } @@ -114,7 +115,7 @@ func (b *localBackend) path(key string) (string, error) { path := filepath.Join(b.root, cleanKey) rel, err := filepath.Rel(b.root, path) if err != nil || strings.HasPrefix(rel, "..") { - return "", fmt.Errorf("storage key escapes local root") + return "", errors.New("storage key escapes local root") } return path, nil } diff --git a/internal/infra/persistence/batchwriter/config.go b/internal/infra/persistence/batchwriter/config.go index f2363d16..cf19d708 100644 --- a/internal/infra/persistence/batchwriter/config.go +++ b/internal/infra/persistence/batchwriter/config.go @@ -4,7 +4,7 @@ package batchwriter import ( - "fmt" + "errors" "time" ) @@ -51,19 +51,19 @@ func DefaultConfig() Config { func (c Config) validate() error { if c.QueueSize <= 0 { - return fmt.Errorf("batchwriter: queue size must be positive") + return errors.New("batchwriter: queue size must be positive") } if c.MaxBatchSize <= 0 { - return fmt.Errorf("batchwriter: max batch size must be positive") + return errors.New("batchwriter: max batch size must be positive") } if c.MinBatchSize < 0 { - return fmt.Errorf("batchwriter: min batch size must be non-negative") + return errors.New("batchwriter: min batch size must be non-negative") } if c.FlushInterval <= 0 { - return fmt.Errorf("batchwriter: flush interval must be positive") + return errors.New("batchwriter: flush interval must be positive") } if c.MaxFlushWait < 0 { - return fmt.Errorf("batchwriter: max flush wait must be non-negative") + return errors.New("batchwriter: max flush wait must be non-negative") } return nil } diff --git a/internal/infra/persistence/redis.go b/internal/infra/persistence/redis.go index 541ae165..78f3e28b 100644 --- a/internal/infra/persistence/redis.go +++ b/internal/infra/persistence/redis.go @@ -9,6 +9,7 @@ import ( "encoding/json" "fmt" "log" + "strconv" "strings" "time" @@ -83,7 +84,7 @@ func init() { if err := redisotel.InstrumentTracing( Redis, redisotel.WithAttributes( - attribute.String("db.instance", fmt.Sprintf("%v", cfg.DB)), + attribute.String("db.instance", strconv.Itoa(cfg.DB)), attribute.String("db.ip", strings.Join(cfg.Addrs, ",")), attribute.String("db.system", "Redis"), ), diff --git a/internal/model/access_token.go b/internal/model/access_token.go index 91993a25..7665f3ed 100644 --- a/internal/model/access_token.go +++ b/internal/model/access_token.go @@ -41,7 +41,7 @@ func GenerateTokenString() (string, error) { if _, err := rand.Read(bytes); err != nil { return "", err } - return fmt.Sprintf("at_%s", hex.EncodeToString(bytes)), nil + return "at_" + hex.EncodeToString(bytes), nil } // HashToken 计算 Token 的 SHA-256 哈希值用于数据库存储与查询 diff --git a/internal/repository/analytics/access_log.go b/internal/repository/analytics/access_log.go index 045f03a9..9be348ec 100644 --- a/internal/repository/analytics/access_log.go +++ b/internal/repository/analytics/access_log.go @@ -6,6 +6,7 @@ package analytics import ( "context" + "errors" "fmt" "time" @@ -15,7 +16,7 @@ import ( func userAccessLogConn() error { if db.ChConn == nil { - return fmt.Errorf("clickhouse native connection is not initialized") + return errors.New("clickhouse native connection is not initialized") } return nil } diff --git a/internal/repository/analytics/access_log_writer.go b/internal/repository/analytics/access_log_writer.go index 337ca966..d79627ee 100644 --- a/internal/repository/analytics/access_log_writer.go +++ b/internal/repository/analytics/access_log_writer.go @@ -5,6 +5,7 @@ package analytics import ( "context" + "errors" "fmt" db "github.com/Rain-kl/Wavelet/internal/infra/persistence" @@ -17,7 +18,7 @@ func BatchInsert(ctx context.Context, logs []analyticsmodel.UserAccessLog) error return nil } if db.ChConn == nil { - return fmt.Errorf("clickhouse connection is not initialized") + return errors.New("clickhouse connection is not initialized") } batch, err := db.ChConn.PrepareBatch(ctx, analyticsmodel.UserAccessLog{}.BatchInsertSQL()) diff --git a/internal/repository/analytics/clickhouse_stats.go b/internal/repository/analytics/clickhouse_stats.go index c6547902..7a4a71de 100644 --- a/internal/repository/analytics/clickhouse_stats.go +++ b/internal/repository/analytics/clickhouse_stats.go @@ -5,6 +5,7 @@ package analytics import ( "context" + "errors" "fmt" "github.com/Rain-kl/Wavelet/internal/infra/config" @@ -19,7 +20,7 @@ type ClickHouseOperationalStats = analyticsmodel.ClickHouseOperationalStats // GetClickHouseOperationalStats returns operational metrics for the configured database. func GetClickHouseOperationalStats(ctx context.Context) (*ClickHouseOperationalStats, error) { if db.ChConn == nil { - return nil, fmt.Errorf("clickhouse native connection is not initialized") + return nil, errors.New("clickhouse native connection is not initialized") } database := config.Config.ClickHouse.Database stats := &ClickHouseOperationalStats{Database: database} diff --git a/internal/repository/analytics/node_access_log.go b/internal/repository/analytics/node_access_log.go index 38b184db..a8e78f6c 100644 --- a/internal/repository/analytics/node_access_log.go +++ b/internal/repository/analytics/node_access_log.go @@ -5,6 +5,7 @@ package analytics import ( "context" + "errors" "fmt" "strings" "time" @@ -19,7 +20,7 @@ type NodeAccessLogRegionCount = analyticsmodel.NodeAccessLogRegionCount func nodeAccessLogConn() (driver.Conn, error) { if db.ChConn == nil { - return nil, fmt.Errorf("clickhouse connection is not initialized") + return nil, errors.New("clickhouse connection is not initialized") } return db.ChConn, nil } diff --git a/internal/repository/analytics/node_access_log_writer.go b/internal/repository/analytics/node_access_log_writer.go index 062de249..0558c109 100644 --- a/internal/repository/analytics/node_access_log_writer.go +++ b/internal/repository/analytics/node_access_log_writer.go @@ -5,6 +5,7 @@ package analytics import ( "context" + "errors" "fmt" "strings" "time" @@ -20,7 +21,7 @@ func BatchInsertNodeAccessLogs(ctx context.Context, logs []analyticsmodel.NodeAc return nil } if db.ChConn == nil { - return fmt.Errorf("clickhouse connection is not initialized") + return errors.New("clickhouse connection is not initialized") } batch, err := db.ChConn.PrepareBatch(ctx, analyticsmodel.NodeAccessLog{}.BatchInsertSQL()) diff --git a/internal/repository/analytics/node_observability.go b/internal/repository/analytics/node_observability.go index 3fba630b..42668976 100644 --- a/internal/repository/analytics/node_observability.go +++ b/internal/repository/analytics/node_observability.go @@ -5,6 +5,7 @@ package analytics import ( "context" + "errors" "fmt" "slices" "time" @@ -16,7 +17,7 @@ import ( func observabilityConn() (driver.Conn, error) { if db.ChConn == nil { - return nil, fmt.Errorf("clickhouse connection is not initialized") + return nil, errors.New("clickhouse connection is not initialized") } return db.ChConn, nil } diff --git a/internal/repository/analytics/node_observability_writer.go b/internal/repository/analytics/node_observability_writer.go index a45673d5..6deff8c4 100644 --- a/internal/repository/analytics/node_observability_writer.go +++ b/internal/repository/analytics/node_observability_writer.go @@ -5,6 +5,7 @@ package analytics import ( "context" + "errors" "fmt" "strings" "time" @@ -30,7 +31,7 @@ func BatchInsertNodeMetricSnapshots(ctx context.Context, snapshots []analyticsmo return nil } if db.ChConn == nil { - return fmt.Errorf("clickhouse connection is not initialized") + return errors.New("clickhouse connection is not initialized") } batch, err := db.ChConn.PrepareBatch(ctx, analyticsmodel.NodeMetricSnapshot{}.BatchInsertSQL()) @@ -102,7 +103,7 @@ func BatchInsertNodeEdgeHealth(ctx context.Context, rows []analyticsmodel.NodeEd return nil } if db.ChConn == nil { - return fmt.Errorf("clickhouse connection is not initialized") + return errors.New("clickhouse connection is not initialized") } batch, err := db.ChConn.PrepareBatch(ctx, analyticsmodel.NodeEdgeHealth{}.BatchInsertSQL()) if err != nil { @@ -160,7 +161,7 @@ func BatchInsertNodeObsFrps(ctx context.Context, observations []analyticsmodel.N return nil } if db.ChConn == nil { - return fmt.Errorf("clickhouse connection is not initialized") + return errors.New("clickhouse connection is not initialized") } batch, err := db.ChConn.PrepareBatch(ctx, analyticsmodel.NodeObsFrps{}.BatchInsertSQL()) @@ -223,7 +224,7 @@ func BatchInsertNodeObsFrpc(ctx context.Context, observations []analyticsmodel.N return nil } if db.ChConn == nil { - return fmt.Errorf("clickhouse connection is not initialized") + return errors.New("clickhouse connection is not initialized") } batch, err := db.ChConn.PrepareBatch(ctx, analyticsmodel.NodeObsFrpc{}.BatchInsertSQL()) diff --git a/internal/repository/openflare_zone.go b/internal/repository/openflare_zone.go index 9f99c877..a7a6ae8d 100644 --- a/internal/repository/openflare_zone.go +++ b/internal/repository/openflare_zone.go @@ -3,7 +3,6 @@ package repository import ( "context" "errors" - "fmt" "gorm.io/gorm" @@ -124,7 +123,7 @@ func ListZoneDomainsByIDs(ctx context.Context, domainIDs []uint) ([]model.ZoneDo for _, id := range domainIDs { domain, ok := byID[id] if !ok { - return nil, fmt.Errorf("one or more zone domains do not exist") + return nil, errors.New("one or more zone domains do not exist") } ordered = append(ordered, domain) } diff --git a/pkg/geoip/emptyProvider.go b/pkg/geoip/emptyProvider.go index 6d689a0d..82839ea4 100644 --- a/pkg/geoip/emptyProvider.go +++ b/pkg/geoip/emptyProvider.go @@ -1,7 +1,7 @@ package geoip import ( - "fmt" + "errors" "net" ) @@ -20,12 +20,12 @@ func (e *EmptyProvider) Initialize() error { // GetGeoInfo reports that no GeoIP provider has been configured. func (e *EmptyProvider) GetGeoInfo(_ net.IP) (*GeoInfo, error) { - return nil, fmt.Errorf("you are using an empty GeoIP provider, please set a valid provider") + return nil, errors.New("you are using an empty GeoIP provider, please set a valid provider") } // UpdateDatabase reports that no GeoIP provider has been configured. func (e *EmptyProvider) UpdateDatabase() error { - return fmt.Errorf("you are using an empty GeoIP provider, please set a valid provider") + return errors.New("you are using an empty GeoIP provider, please set a valid provider") } // Close releases resources held by the empty provider. diff --git a/pkg/geoip/geoip.go b/pkg/geoip/geoip.go index aab42ce6..08b50f92 100644 --- a/pkg/geoip/geoip.go +++ b/pkg/geoip/geoip.go @@ -2,6 +2,7 @@ package geoip import ( + "errors" "fmt" "log/slog" "net" @@ -138,7 +139,7 @@ func InitGeoIP(provider string) { // GetGeoInfo looks up geographic information for ip using the active provider. func GetGeoInfo(ip net.IP) (*GeoInfo, error) { if ip == nil { - return nil, fmt.Errorf("IP address cannot be nil") + return nil, errors.New("IP address cannot be nil") } provider := getProvider() cacheKey := provider.Name() + ":" + ip.String() @@ -157,7 +158,7 @@ func GetGeoInfo(ip net.IP) (*GeoInfo, error) { // LookupGeoInfoWithProvider looks up geographic information using a temporary provider. func LookupGeoInfoWithProvider(providerName string, ip net.IP) (*GeoInfo, error) { if ip == nil { - return nil, fmt.Errorf("IP address cannot be nil") + return nil, errors.New("IP address cannot be nil") } provider, err := providerFactory(normalizeProvider(providerName)) diff --git a/pkg/geoip/mmdb.go b/pkg/geoip/mmdb.go index 94d263c8..2e760447 100644 --- a/pkg/geoip/mmdb.go +++ b/pkg/geoip/mmdb.go @@ -2,6 +2,7 @@ package geoip import ( "context" + "errors" "fmt" "io" "net" @@ -96,10 +97,10 @@ func (s *MaxMindGeoIPService) GetGeoInfo(ip net.IP) (*GeoInfo, error) { defer s.mu.RUnlock() if s.maxMindDBReader == nil { - return nil, fmt.Errorf("MaxMind database is not initialized or failed to open") + return nil, errors.New("MaxMind database is not initialized or failed to open") } if ip == nil { - return nil, fmt.Errorf("IP address cannot be nil") + return nil, errors.New("IP address cannot be nil") } var record Record diff --git a/pkg/pagesarchive/entry.go b/pkg/pagesarchive/entry.go index ce19734b..a236a407 100644 --- a/pkg/pagesarchive/entry.go +++ b/pkg/pagesarchive/entry.go @@ -72,14 +72,14 @@ func copyLimited(dst io.Writer, src io.Reader, maxBytes int64) (int64, error) { return written, err } if written > maxBytes { - return written, fmt.Errorf("pages file size out of bounds") + return written, errors.New("pages file size out of bounds") } return written, nil } func copyAndVerifySize(dst io.Writer, src io.Reader, declaredSize uint64, maxBytes int64) (int64, error) { if declaredSize > uint64(math.MaxInt64) { - return 0, fmt.Errorf("pages file size out of bounds") + return 0, errors.New("pages file size out of bounds") } written, err := copyLimited(dst, src, maxBytes) if err != nil { diff --git a/pkg/pagesarchive/extract.go b/pkg/pagesarchive/extract.go index c8eb1426..d88f9963 100644 --- a/pkg/pagesarchive/extract.go +++ b/pkg/pagesarchive/extract.go @@ -124,7 +124,7 @@ func extractEntries(entries []Entry, destDir string, opts ExtractOptions) error appendMeasuredFile(measured, normalizedPath, actual) } if measured.fileCount == 0 { - return fmt.Errorf("pages package is empty") + return errors.New("pages package is empty") } return nil } @@ -139,7 +139,7 @@ func extractTarFamilyAt(ra io.ReaderAt, size int64, format Format, destDir strin return err } if firstPass.fileCount == 0 { - return fmt.Errorf("pages package is empty") + return errors.New("pages package is empty") } commonPrefix := "" if opts.StripCommonRoot { @@ -162,7 +162,7 @@ func extractTarFamilyAt(ra io.ReaderAt, size int64, format Format, destDir strin return extractErr } if secondPass.fileCount != firstPass.fileCount || secondPass.totalSize != firstPass.totalSize { - return fmt.Errorf("pages tar package changed between validation and extraction") + return errors.New("pages tar package changed between validation and extraction") } return nil } diff --git a/pkg/pagesarchive/format.go b/pkg/pagesarchive/format.go index 99fde833..279247ab 100644 --- a/pkg/pagesarchive/format.go +++ b/pkg/pagesarchive/format.go @@ -7,7 +7,7 @@ package pagesarchive import ( "bytes" - "fmt" + "errors" "path/filepath" "strings" ) @@ -87,7 +87,7 @@ func DetectFormat(fileName string, data []byte) (Format, error) { if format, ok := DetectFormatFromBytes(data); ok { return format, nil } - return "", fmt.Errorf("unsupported pages package format") + return "", errors.New("unsupported pages package format") } // Extension returns the canonical file extension for a format (without leading dot). diff --git a/pkg/pagesarchive/inspect.go b/pkg/pagesarchive/inspect.go index ae3a3125..ac9f442d 100644 --- a/pkg/pagesarchive/inspect.go +++ b/pkg/pagesarchive/inspect.go @@ -137,7 +137,7 @@ func scanTarFamilyAt( enforceLimits bool, ) (*measuredArchive, error) { if size < 0 { - return nil, fmt.Errorf("invalid pages package size") + return nil, errors.New("invalid pages package size") } tarReader, closeReader, err := openTarFamilyReader(io.NewSectionReader(ra, 0, size), format) if err != nil { @@ -183,7 +183,7 @@ func scanTarReader(tarReader *tar.Reader, limits Limits, enforceLimits bool) (*m func buildMeasuredManifest(measured *measuredArchive, opts InspectOptions) (*Manifest, error) { if measured == nil || measured.fileCount == 0 { - return nil, fmt.Errorf("pages package is empty") + return nil, errors.New("pages package is empty") } targetEntryPath, err := resolveTargetEntryPath(opts.RootDir, opts.EntryFile) if err != nil { @@ -231,7 +231,7 @@ func prepareMeasuredFile(measured *measuredArchive, normalizedPath string, decla } remaining := limits.MaxTotalBytes - measured.totalSize if remaining < 0 || declaredSize > uint64(remaining) { //nolint:gosec // remaining is checked non-negative - return fmt.Errorf("pages extracted size exceeds limit") + return errors.New("pages extracted size exceeds limit") } return nil } diff --git a/pkg/pagesarchive/list.go b/pkg/pagesarchive/list.go index e5781f08..1af579cf 100644 --- a/pkg/pagesarchive/list.go +++ b/pkg/pagesarchive/list.go @@ -8,6 +8,7 @@ import ( "archive/zip" "compress/bzip2" "compress/gzip" + "errors" "fmt" "io" "os" @@ -52,7 +53,7 @@ func (z sevenZipArchiveFile) Open() (io.ReadCloser, error) { // Tar-family archives use the sequential streaming paths in inspect.go/extract.go. func listRandomAccessEntriesAt(ra io.ReaderAt, size int64, format Format) ([]Entry, error) { if size < 0 { - return nil, fmt.Errorf("invalid pages package size") + return nil, errors.New("invalid pages package size") } switch format { case FormatZip: diff --git a/pkg/pagesarchive/path.go b/pkg/pagesarchive/path.go index 85d15375..8f7d2b38 100644 --- a/pkg/pagesarchive/path.go +++ b/pkg/pagesarchive/path.go @@ -4,6 +4,7 @@ package pagesarchive import ( + "errors" "fmt" "path" "strings" @@ -18,7 +19,7 @@ func NormalizeLogicalPath(raw string, allowEmpty bool) (string, error) { if allowEmpty { return "", nil } - return "", fmt.Errorf("pages path is required") + return "", errors.New("pages path is required") } if err := validateLogicalPathText(raw); err != nil { return "", err @@ -29,7 +30,7 @@ func NormalizeLogicalPath(raw string, allowEmpty bool) (string, error) { if allowEmpty { return "", nil } - return "", fmt.Errorf("pages path is required") + return "", errors.New("pages path is required") } if strings.HasPrefix(cleaned, "/") || cleaned == ".." || strings.HasPrefix(cleaned, "../") { return "", fmt.Errorf("pages path escapes directory: %s", raw) @@ -39,7 +40,7 @@ func NormalizeLogicalPath(raw string, allowEmpty bool) (string, error) { func validateLogicalPathText(raw string) error { if !utf8.ValidString(raw) { - return fmt.Errorf("pages path is not valid UTF-8") + return errors.New("pages path is not valid UTF-8") } if strings.Contains(raw, "\\") { return fmt.Errorf("pages path must use POSIX separators: %s", raw) @@ -56,7 +57,7 @@ func validateLogicalPathText(raw string) error { func validateLogicalPathRunes(raw string) error { for _, r := range raw { if r == 0 || unicode.IsControl(r) { - return fmt.Errorf("pages path contains a control character") + return errors.New("pages path contains a control character") } if r == '\'' || r == '"' || r == ';' { return fmt.Errorf("pages path contains an unsupported character: %s", raw) diff --git a/pkg/push/lark.go b/pkg/push/lark.go index e97a8b1a..d44e217e 100644 --- a/pkg/push/lark.go +++ b/pkg/push/lark.go @@ -265,7 +265,7 @@ func (p *LarkPusher) ValidateConfig(cfg Config) error { } func larkSign(secret string, timestamp int64) (string, error) { - stringToSign := fmt.Sprintf("%v", timestamp) + "\n" + secret + stringToSign := strconv.FormatInt(timestamp, 10) + "\n" + secret h := hmac.New(sha256.New, []byte(stringToSign)) _, err := h.Write(nil) if err != nil { diff --git a/pkg/render/openresty/render.go b/pkg/render/openresty/render.go index e11f8d45..a0f25406 100644 --- a/pkg/render/openresty/render.go +++ b/pkg/render/openresty/render.go @@ -14,6 +14,7 @@ import ( "path" "regexp" "sort" + "strconv" "strings" ) @@ -168,32 +169,32 @@ func DedupeSupportFiles(files []SupportFile) []SupportFile { func renderMainConfigTemplate(templateText string, cfg ConfigSnapshot, limitReqRates []string) string { replacer := strings.NewReplacer( "{{OpenRestyWorkerProcesses}}", cfg.WorkerProcesses, - "{{OpenRestyWorkerConnections}}", fmt.Sprintf("%d", cfg.WorkerConnections), - "{{OpenRestyWorkerRlimitNofile}}", fmt.Sprintf("%d", cfg.WorkerRlimitNofile), + "{{OpenRestyWorkerConnections}}", strconv.Itoa(cfg.WorkerConnections), + "{{OpenRestyWorkerRlimitNofile}}", strconv.Itoa(cfg.WorkerRlimitNofile), "{{OpenRestyConnectionUpgradeMap}}", renderConnectionUpgradeMap(), "{{OpenRestyDefaultServerBlock}}", renderDefaultServerBlock(cfg.DefaultServerReturnStatus, cfg.HTTP3Enabled), "{{OpenRestyAccessLogPath}}", AccessLogPlaceholder, "{{OpenRestyErrorLogPath}}", ErrorLogPlaceholder, "{{OpenRestyEventsUseDirective}}", renderTemplateDirective(cfg.EventsUse != "", fmt.Sprintf("use %s;", cfg.EventsUse)), "{{OpenRestyEventsMultiAcceptDirective}}", renderTemplateDirective(cfg.EventsMultiAcceptEnabled, "multi_accept on;"), - "{{OpenRestyKeepaliveTimeout}}", fmt.Sprintf("%d", cfg.KeepaliveTimeout), - "{{OpenRestyKeepaliveRequests}}", fmt.Sprintf("%d", cfg.KeepaliveRequests), - "{{OpenRestyClientHeaderTimeout}}", fmt.Sprintf("%d", cfg.ClientHeaderTimeout), - "{{OpenRestyClientBodyTimeout}}", fmt.Sprintf("%d", cfg.ClientBodyTimeout), + "{{OpenRestyKeepaliveTimeout}}", strconv.Itoa(cfg.KeepaliveTimeout), + "{{OpenRestyKeepaliveRequests}}", strconv.Itoa(cfg.KeepaliveRequests), + "{{OpenRestyClientHeaderTimeout}}", strconv.Itoa(cfg.ClientHeaderTimeout), + "{{OpenRestyClientBodyTimeout}}", strconv.Itoa(cfg.ClientBodyTimeout), "{{OpenRestyClientMaxBodySize}}", cfg.ClientMaxBodySize, "{{OpenRestyLargeClientHeaderBuffers}}", cfg.LargeClientHeaderBuffers, - "{{OpenRestySendTimeout}}", fmt.Sprintf("%d", cfg.SendTimeout), - "{{OpenRestyProxyConnectTimeout}}", fmt.Sprintf("%d", cfg.ProxyConnectTimeout), - "{{OpenRestyProxySendTimeout}}", fmt.Sprintf("%d", cfg.ProxySendTimeout), - "{{OpenRestyProxyReadTimeout}}", fmt.Sprintf("%d", cfg.ProxyReadTimeout), + "{{OpenRestySendTimeout}}", strconv.Itoa(cfg.SendTimeout), + "{{OpenRestyProxyConnectTimeout}}", strconv.Itoa(cfg.ProxyConnectTimeout), + "{{OpenRestyProxySendTimeout}}", strconv.Itoa(cfg.ProxySendTimeout), + "{{OpenRestyProxyReadTimeout}}", strconv.Itoa(cfg.ProxyReadTimeout), "{{OpenRestyProxyRequestBuffering}}", onOff(cfg.ProxyRequestBuffering), "{{OpenRestyProxyBuffering}}", onOff(cfg.ProxyBufferingEnabled), "{{OpenRestyProxyBuffers}}", cfg.ProxyBuffers, "{{OpenRestyProxyBufferSize}}", cfg.ProxyBufferSize, "{{OpenRestyProxyBusyBuffersSize}}", cfg.ProxyBusyBuffersSize, "{{OpenRestyGzip}}", onOff(cfg.GzipEnabled), - "{{OpenRestyGzipMinLength}}", fmt.Sprintf("%d", cfg.GzipMinLength), - "{{OpenRestyGzipCompLevel}}", fmt.Sprintf("%d", cfg.GzipCompLevel), + "{{OpenRestyGzipMinLength}}", strconv.Itoa(cfg.GzipMinLength), + "{{OpenRestyGzipCompLevel}}", strconv.Itoa(cfg.GzipCompLevel), "{{OpenRestyResolverDirective}}", renderTemplateDirective(cfg.Resolvers != "", fmt.Sprintf("resolver %s;", cfg.Resolvers)), "{{OpenRestyCacheBlock}}", renderOpenRestyCacheTemplateBlock(cfg, limitReqRates), "{{OpenRestyRouteConfigInclude}}", RouteConfigPlaceholder, @@ -765,7 +766,7 @@ func renderDefaultServerBlock(statusCode int, http3Enabled bool) string { " }", "", " server {", - fmt.Sprintf(" listen 443 ssl default_server;%s", h3Default), + " listen 443 ssl default_server;" + h3Default, " server_name _;", "", " ssl_reject_handshake on;", @@ -946,7 +947,7 @@ func buildPathPrefixMatchPattern(rules []string) string { parts = append(parts, "/") continue } - parts = append(parts, fmt.Sprintf("%s(?:/|$)", regexp.QuoteMeta(trimmed))) + parts = append(parts, regexp.QuoteMeta(trimmed)+"(?:/|$)") } return fmt.Sprintf("^(?:%s)", strings.Join(parts, "|")) } diff --git a/pkg/render/openresty/status_codes.go b/pkg/render/openresty/status_codes.go index 7eed8161..f97381aa 100644 --- a/pkg/render/openresty/status_codes.go +++ b/pkg/render/openresty/status_codes.go @@ -4,6 +4,7 @@ package openresty import ( + "errors" "fmt" "sort" "strconv" @@ -22,7 +23,7 @@ const ( func ParseStatusCodeTag(tag string) (lo, hi int, err error) { tag = strings.TrimSpace(tag) if tag == "" { - return 0, 0, fmt.Errorf("状态码标签不能为空") + return 0, 0, errors.New("状态码标签不能为空") } if before, after, ok := strings.Cut(tag, "-"); ok { lo, err = strconv.Atoi(before) diff --git a/pkg/util/format.go b/pkg/util/format.go index 2aa9f5a9..20fab153 100644 --- a/pkg/util/format.go +++ b/pkg/util/format.go @@ -29,13 +29,13 @@ func Bytes2Size(num int64) string { numStr = fmt.Sprintf("%.2f", float64(num)/float64(sizeGB)) unit = "GB" case num/int64(sizeMB) >= 1: - numStr = fmt.Sprintf("%d", int(float64(num)/float64(sizeMB))) + numStr = strconv.Itoa(int(float64(num) / float64(sizeMB))) unit = "MB" case num/int64(sizeKB) >= 1: - numStr = fmt.Sprintf("%d", int(float64(num)/float64(sizeKB))) + numStr = strconv.Itoa(int(float64(num) / float64(sizeKB))) unit = "KB" default: - numStr = fmt.Sprintf("%d", num) + numStr = strconv.FormatInt(num, 10) } return numStr + " " + unit } diff --git a/pkg/util/value.go b/pkg/util/value.go index 7c627d65..25776634 100644 --- a/pkg/util/value.go +++ b/pkg/util/value.go @@ -1,6 +1,9 @@ package util -import "fmt" +import ( + "fmt" + "strconv" +) // Interface2String converts a string, int, or float64 value to its string representation. func Interface2String(inter any) string { @@ -8,7 +11,7 @@ func Interface2String(inter any) string { case string: return v case int: - return fmt.Sprintf("%d", v) + return strconv.Itoa(v) case float64: return fmt.Sprintf("%f", v) } diff --git a/scripts/live_ch_smoke/main.go b/scripts/live_ch_smoke/main.go index e0ffa5a2..df9e46db 100644 --- a/scripts/live_ch_smoke/main.go +++ b/scripts/live_ch_smoke/main.go @@ -6,6 +6,7 @@ package main import ( "context" + "errors" "fmt" "os" "time" @@ -32,7 +33,7 @@ func main() { func run() error { if !db.ChConnReady() { - return fmt.Errorf("ChConn not ready — check config.yaml clickhouse.enabled") + return errors.New("ChConn not ready — check config.yaml clickhouse.enabled") } ctx := context.Background() chwriter.Init(ctx) @@ -76,7 +77,7 @@ func waitForSnapshot(ctx context.Context, nodeID string, now time.Time) error { } time.Sleep(pollInterval) } - return fmt.Errorf("not flushed within timeout") + return errors.New("not flushed within timeout") } func assertLatestIncludes(ctx context.Context, nodeID string, now time.Time) error {