package parser import ( "fmt" "net/url" "strconv" "strings" "github.com/subconverter-go/internal/logging" ) // TrojanParser Trojan协议解析器 // 实现Trojan代理配置的解析功能 type TrojanParser struct { logger *logging.Logger } // NewTrojanParser 创建新的Trojan解析器 // 返回初始化好的TrojanParser实例 func NewTrojanParser(logger *logging.Logger) *TrojanParser { return &TrojanParser{ logger: logger, } } // Parse 解析Trojan配置 // 支持标准URL格式 func (p *TrojanParser) Parse(input string) (*ProxyConfig, error) { p.logger.Debugf("Parsing Trojan configuration") // 去除前缀 input = strings.TrimPrefix(input, "trojan://") // 解析URL parsedURL, err := url.Parse("trojan://" + input) if err != nil { return nil, fmt.Errorf("failed to parse Trojan URL: %v", err) } // 获取密码 password := parsedURL.User.String() if password == "" { return nil, fmt.Errorf("password is required") } config := &ProxyConfig{ Type: "trojan", Protocol: "trojan", Server: parsedURL.Hostname(), } // 解析端口 port, err := strconv.Atoi(parsedURL.Port()) if err != nil { return nil, fmt.Errorf("invalid port number: %v", err) } config.Port = port // 解析备注 if parsedURL.Fragment != "" { config.Name = parsedURL.Fragment } else { config.Name = fmt.Sprintf("trojan-%s:%d", config.Server, config.Port) } // 创建设置映射 settings := map[string]interface{}{ "password": password, "udp": true, } // 解析查询参数 query := parsedURL.Query() // 解析allowInsecure if allowInsecure := query.Get("allowInsecure"); allowInsecure != "" { settings["allowInsecure"] = p.parseBool(allowInsecure) } // 解析sni if sni := query.Get("sni"); sni != "" { settings["sni"] = sni } // 解析peer if peer := query.Get("peer"); peer != "" { settings["peer"] = peer } // 解析network类型 network := query.Get("type") if network == "" { network = "tcp" } // 添加网络特定配置 switch network { case "ws": settings["network"] = "ws" wsSettings := map[string]interface{}{ "path": "/", } if host := query.Get("host"); host != "" { wsSettings["headers"] = map[string]string{ "Host": host, } } if path := query.Get("path"); path != "" { wsSettings["path"] = path } settings["wsSettings"] = wsSettings case "grpc": settings["network"] = "grpc" grpcSettings := map[string]interface{}{ "serviceName": query.Get("serviceName"), "multiMode": false, } if service := query.Get("serviceName"); service != "" { grpcSettings["serviceName"] = service } settings["grpcSettings"] = grpcSettings case "kcp": settings["network"] = "kcp" kcpSettings := map[string]interface{}{ "header": map[string]string{ "type": query.Get("headerType"), }, } if headerType := query.Get("headerType"); headerType != "" { kcpSettings["header"].(map[string]string)["type"] = headerType } settings["kcpSettings"] = kcpSettings default: settings["network"] = "tcp" } // 解析TLS配置 if network != "tcp" || query.Get("security") == "tls" { settings["security"] = "tls" } config.Settings = settings config.UDP = true p.logger.Infof("Successfully parsed Trojan configuration for server: %s:%d", config.Server, config.Port) return config, nil } // parseBool 解析布尔值 func (p *TrojanParser) parseBool(value string) bool { switch strings.ToLower(value) { case "1", "true", "yes", "on": return true default: return false } } // Validate 验证Trojan配置 func (p *TrojanParser) Validate(config *ProxyConfig) error { p.logger.Debugf("Validating Trojan configuration") // 检查必要字段 if config.Server == "" { return fmt.Errorf("server address is required") } if config.Port <= 0 || config.Port > 65535 { return fmt.Errorf("invalid port number: %d", config.Port) } password := p.getPassword(config) if password == "" { return fmt.Errorf("password is required") } // 验证密码格式(应该是一个44字符的Base64编码字符串) if len(password) != 44 { p.logger.Warnf("Trojan password length is not 44 characters: %d", len(password)) } // 验证网络协议 network := p.getNetwork(config) if err := p.validateNetwork(network); err != nil { return err } // 验证SNI(如果启用TLS) if p.getSecurity(config) == "tls" { sni := p.getSNI(config) if sni == "" { p.logger.Debug("SNI not specified, using server address") } } p.logger.Debug("Trojan configuration validation passed") return nil } // validateNetwork 验证网络协议 func (p *TrojanParser) validateNetwork(network string) error { supportedNetworks := []string{"tcp", "ws", "grpc", "kcp"} for _, supported := range supportedNetworks { if network == supported { return nil } } return fmt.Errorf("unsupported network type: %s", network) } // getPassword 从配置中获取密码 func (p *TrojanParser) getPassword(config *ProxyConfig) string { if password, exists := config.Settings["password"]; exists { if passwordStr, ok := password.(string); ok { return passwordStr } } return "" } // getNetwork 从配置中获取网络协议 func (p *TrojanParser) getNetwork(config *ProxyConfig) string { if network, exists := config.Settings["network"]; exists { if networkStr, ok := network.(string); ok { return networkStr } } return "tcp" } // getSecurity 从配置中获取安全设置 func (p *TrojanParser) getSecurity(config *ProxyConfig) string { if security, exists := config.Settings["security"]; exists { if securityStr, ok := security.(string); ok { return securityStr } } return "none" } // getSNI 从配置中获取SNI func (p *TrojanParser) getSNI(config *ProxyConfig) string { if sni, exists := config.Settings["sni"]; exists { if sniStr, ok := sni.(string); ok { return sniStr } } return "" } // GetSupportedProtocols 获取支持的协议 func (p *TrojanParser) GetSupportedProtocols() []string { return []string{"trojan"} }