package handler import ( "fmt" "net/http" "runtime" "strings" "time" "github.com/gofiber/fiber/v2" "github.com/subconverter-go/internal/config" "github.com/subconverter-go/internal/logging" ) // VersionHandler 版本信息处理器 // 提供应用程序版本和构建信息 type VersionHandler struct { logger *logging.Logger configMgr *config.ConfigManager buildTime time.Time gitCommit string gitVersion string } // NewVersionHandler 创建新的版本信息处理器 // 返回初始化好的VersionHandler实例 func NewVersionHandler(logger *logging.Logger, configMgr *config.ConfigManager) *VersionHandler { return &VersionHandler{ logger: logger, configMgr: configMgr, buildTime: getBuildTime(), gitCommit: getGitCommit(), gitVersion: getGitVersion(), } } // HandleVersion 处理版本信息请求 // 返回详细的版本和构建信息 func (h *VersionHandler) HandleVersion(c *fiber.Ctx) error { h.logger.Debug("Version info request received") // 获取配置信息 config := h.configMgr.GetConfig() // 创建版本信息响应 version := map[string]interface{}{ "service": "subconverter-go", "version": "1.0.0", "description": "Proxy subscription converter service", "author": "subconverter-go team", "license": "MIT", "homepage": "https://github.com/subconverter-go/subconverter-go", "repository": "https://github.com/subconverter-go/subconverter-go.git", } // 添加构建信息 version["build"] = map[string]interface{}{ "build_time": h.buildTime.Format(time.RFC3339), "git_commit": h.gitCommit, "git_version": h.gitVersion, "go_version": runtime.Version(), "compiler": runtime.Compiler, "platform": fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH), } // 添加运行时信息 version["runtime"] = map[string]interface{}{ "goroutines": runtime.NumGoroutine(), "cgocalls": runtime.NumCgoCall(), "memory": "N/A", // 可以添加内存使用情况 } // 添加功能特性信息 version["features"] = map[string]interface{}{ "supported_formats": config.Conversion.SupportedTargets, "security": map[string]interface{}{ "rate_limiting": config.Security.RateLimit > 0, "cors_enabled": len(config.Security.CorsOrigins) > 0, "auth_enabled": len(config.Security.AccessTokens) > 0, }, "logging": map[string]interface{}{ "level": config.Logging.Level, "format": config.Logging.Format, "output": config.Logging.Output, }, "server": map[string]interface{}{ "host": config.Server.Host, "port": config.Server.Port, "framework": "fiber/v2", }, } // 添加API信息 version["api"] = map[string]interface{}{ "version": "v1", "endpoints": []string{ "GET /health - Health check", "GET /version - Version information", "GET /ready - Readiness check", "GET /live - Liveness check", "GET /metrics - Runtime metrics", "GET /ping - Connectivity test", "GET /sub - Subscription conversion", "POST /sub - Subscription conversion", "GET /api/targets - Supported targets", "POST /api/convert - Convert subscription", "GET /api/validate - Validate URL", }, } // 添加依赖信息 version["dependencies"] = map[string]interface{}{ "fiber": map[string]interface{}{ "version": "v2.52.9", "website": "https://gofiber.io", }, "viper": map[string]interface{}{ "version": "v1.21.0", "website": "https://github.com/spf13/viper", }, "cobra": map[string]interface{}{ "version": "v1.10.1", "website": "https://github.com/spf13/cobra", }, "logrus": map[string]interface{}{ "version": "v1.8.1", "website": "https://github.com/sirupsen/logrus", }, } // 设置响应头 c.Set("Cache-Control", "public, max-age=3600") // 缓存1小时 c.Set("X-API-Version", "v1") c.Set("X-Service-Version", "1.0.0") format := c.Query("format") accept := c.Get("Accept") if strings.EqualFold(format, "plain") || strings.Contains(accept, "text/plain") { plain := fmt.Sprintf("%s %s backend\n", version["service"], version["version"]) c.Set("Content-Type", "text/plain; charset=utf-8") return c.Status(http.StatusOK).SendString(plain) } return c.JSON(version) } // HandleCompatibility 处理兼容性信息请求 // 返回与原C++版本的兼容性信息 func (h *VersionHandler) HandleCompatibility(c *fiber.Ctx) error { h.logger.Debug("Compatibility info request received") // 创建兼容性信息响应 compatibility := map[string]interface{}{ "original_version": "subconverter (C++)", "go_version": "subconverter-go", "compatibility": "1:1 functional compatibility", "status": "in development", } // 添加支持的格式兼容性 compatibility["format_compatibility"] = map[string]interface{}{ "input_formats": []string{ "Shadowsocks (SS)", "ShadowsocksR (SSR)", "VMess", "Trojan", "HTTP/Socks5", "Telegram links", }, "output_formats": []string{ "Clash", "ClashR", "Quantumult", "Quantumult X", "Loon", "Surfboard", "Surge (v2, v3, v4)", "V2Ray", }, "parameter_compatibility": "100%", } // 添加API兼容性 compatibility["api_compatibility"] = map[string]interface{}{ "endpoints": []string{ "/sub", "/config", "/health", "/version", }, "parameters": []string{ "target", "url", "emoji", "udp", "include", "exclude", "group", "config", }, } // 添加配置文件兼容性 compatibility["config_compatibility"] = map[string]interface{}{ "supported": "INI format", "structure": "Compatible with original", "sections": []string{ "common", "node_pref", "userinfo", "managed_config", "server", "ruleset", }, } return c.JSON(compatibility) } // HandleChangelog 处理变更日志请求 // 返回版本变更历史 func (h *VersionHandler) HandleChangelog(c *fiber.Ctx) error { h.logger.Debug("Changelog request received") // 创建变更日志响应 changelog := map[string]interface{}{ "current_version": "1.0.0", "latest_release": "2024-01-01", "changes": []map[string]interface{}{ { "version": "1.0.0", "date": "2024-01-01", "type": "initial", "description": "Initial Go release with 1:1 compatibility to C++ version", "features": []string{ "Complete conversion functionality", "HTTP API server", "CLI interface", "Configuration management", "Health checks and metrics", }, "changes": []string{ "Rewritten in Go language", "Improved error handling", "Better logging system", "Enhanced configuration management", }, }, }, "upcoming": []map[string]interface{}{ { "version": "1.1.0", "status": "planned", "features": []string{ "Performance optimizations", "Enhanced caching", "Additional proxy format support", "Web interface", }, }, }, } return c.JSON(changelog) } // getBuildTime 获取构建时间 // 从编译时变量或当前时间获取 func getBuildTime() time.Time { // 在实际项目中,这里应该从编译时变量获取 // 例如: return time.Unix(buildTime, 0) return time.Now() } // getGitCommit 获取Git提交信息 // 从编译时变量获取 func getGitCommit() string { // 在实际项目中,这里应该从编译时变量获取 // 例如: return gitCommit return "development" } // getGitVersion 获取Git版本信息 // 从编译时变量获取 func getGitVersion() string { // 在实际项目中,这里应该从编译时变量获取 // 例如: return gitVersion return "v1.0.0-dev" }