Files
subconverter-go/internal/parser/manager.go
Rogee 7fcabe0225
Some checks failed
CI/CD Pipeline / Test (push) Failing after 22m19s
CI/CD Pipeline / Security Scan (push) Failing after 5m57s
CI/CD Pipeline / Build (amd64, darwin) (push) Has been skipped
CI/CD Pipeline / Build (amd64, linux) (push) Has been skipped
CI/CD Pipeline / Build (amd64, windows) (push) Has been skipped
CI/CD Pipeline / Build (arm64, darwin) (push) Has been skipped
CI/CD Pipeline / Build (arm64, linux) (push) Has been skipped
CI/CD Pipeline / Build Docker Image (push) Has been skipped
CI/CD Pipeline / Create Release (push) Has been skipped
first commit
2025-09-28 10:05:07 +08:00

255 lines
7.2 KiB
Go

package parser
import (
"fmt"
"sort"
"strings"
"github.com/subconverter-go/internal/config"
"github.com/subconverter-go/internal/logging"
)
// Parser 解析器接口
// 定义了所有代理协议解析器必须实现的方法
type Parser interface {
// Parse 解析代理配置
// input: 输入的代理配置字符串
// 返回解析后的代理配置和错误信息
Parse(input string) (*ProxyConfig, error)
// Validate 验证代理配置
// config: 需要验证的代理配置
// 返回验证结果和错误信息
Validate(config *ProxyConfig) error
// GetSupportedProtocols 获取支持的协议
// 返回该解析器支持的协议列表
GetSupportedProtocols() []string
}
// ProxyConfig 代理配置结构体
// 包含所有代理协议的通用配置信息
type ProxyConfig struct {
// 基本信息
Name string `json:"name"` // 代理名称
Server string `json:"server"` // 服务器地址
Port int `json:"port"` // 服务器端口
Type string `json:"type"` // 代理类型
// 协议特定配置
Protocol string `json:"protocol"` // 协议类型 (ss, ssr, vmess, trojan, http, socks5)
Settings map[string]interface{} `json:"settings"` // 协议特定设置
// 扩展信息
Remarks string `json:"remarks"` // 备注信息
Group string `json:"group"` // 分组名称
Location string `json:"location"` // 地理位置
UDP bool `json:"udp"` // 是否支持UDP
// 性能和质量指标
Latency int `json:"latency"` // 延迟 (ms)
Score int `json:"score"` // 质量评分
}
// ParserManager 解析器管理器
// 管理所有代理协议解析器,提供统一的解析接口
type ParserManager struct {
logger *logging.Logger
configMgr *config.ConfigManager
parsers map[string]Parser // 协议名称到解析器的映射
}
// NewParserManager 创建新的解析器管理器
// 返回初始化好的ParserManager实例
func NewParserManager(logger *logging.Logger, configMgr *config.ConfigManager) *ParserManager {
pm := &ParserManager{
logger: logger,
configMgr: configMgr,
parsers: make(map[string]Parser),
}
// 注册所有解析器
pm.registerParsers()
return pm
}
// registerParsers 注册所有解析器
// 将各种代理协议解析器注册到管理器中
func (pm *ParserManager) registerParsers() {
// 注册Shadowsocks解析器
pm.parsers["ss"] = NewShadowsocksParser(pm.logger)
// 注册ShadowsocksR解析器
pm.parsers["ssr"] = NewShadowsocksRParser(pm.logger)
// 注册VMess解析器
pm.parsers["vmess"] = NewVMessParser(pm.logger)
// 注册Trojan解析器
pm.parsers["trojan"] = NewTrojanParser(pm.logger)
// 注册HTTP解析器
pm.parsers["http"] = NewHTTPParser(pm.logger)
// 注册Socks5解析器
pm.parsers["socks5"] = NewSocks5Parser(pm.logger)
pm.logger.Info("Registered parsers: ss, ssr, vmess, trojan, http, socks5")
}
// Parse 解析代理配置
// 自动识别协议并调用相应的解析器
func (pm *ParserManager) Parse(input string) (*ProxyConfig, error) {
pm.logger.Debugf("Parsing proxy configuration: %s", input[:min(len(input), 50)]+"...")
// 尝试自动检测协议
protocol, err := pm.detectProtocol(input)
if err != nil {
pm.logger.WithError(err).Error("Failed to detect protocol")
return nil, err
}
// 获取对应的解析器
parser, exists := pm.parsers[protocol]
if !exists {
pm.logger.Errorf("No parser found for protocol: %s", protocol)
return nil, fmt.Errorf("unsupported protocol: %s", protocol)
}
// 调用解析器进行解析
config, err := parser.Parse(input)
if err != nil {
pm.logger.WithError(err).Errorf("Failed to parse %s configuration", protocol)
return nil, err
}
// 设置协议类型
config.Protocol = protocol
pm.logger.Infof("Successfully parsed %s configuration for server: %s:%d", protocol, config.Server, config.Port)
return config, nil
}
// detectProtocol 检测输入字符串的协议类型
// 通过前缀和格式识别代理协议
func (pm *ParserManager) detectProtocol(input string) (string, error) {
// 去除前后空格
input = strings.TrimSpace(input)
lower := strings.ToLower(input)
// 检查URL格式
switch {
case strings.HasPrefix(lower, "ss://"):
return "ss", nil
case strings.HasPrefix(lower, "ssr://"):
return "ssr", nil
case strings.HasPrefix(lower, "vmess://"), strings.HasPrefix(lower, "vmess1://"):
return "vmess", nil
case strings.HasPrefix(lower, "trojan://"):
return "trojan", nil
case strings.HasPrefix(lower, "socks5://"), strings.HasPrefix(lower, "socks://"), strings.HasPrefix(lower, "https://t.me/socks"), strings.HasPrefix(lower, "tg://socks"):
return "socks5", nil
case strings.HasPrefix(lower, "http://"), strings.HasPrefix(lower, "https://"), strings.HasPrefix(lower, "tg://http"), strings.HasPrefix(lower, "https://t.me/http"):
return "http", nil
}
// 如果没有明确的协议前缀,尝试从内容推断
if strings.Contains(lower, "ssr://") {
return "ssr", nil
}
if strings.Contains(lower, "vmess://") || strings.Contains(lower, "vmess1://") {
return "vmess", nil
}
if strings.Contains(lower, "ss://") {
return "ss", nil
}
if strings.Contains(lower, "trojan://") {
return "trojan", nil
}
if strings.Contains(lower, "socks5://") || strings.Contains(lower, "socks://") {
return "socks5", nil
}
if strings.Contains(lower, "http://") || strings.Contains(lower, "https://") {
return "http", nil
}
return "", fmt.Errorf("unknown protocol for input: %s", input)
}
// GetSupportedProtocols 获取所有支持的协议
// 返回管理器支持的所有代理协议列表
func (pm *ParserManager) GetSupportedProtocols() []string {
protocols := make([]string, 0, len(pm.parsers))
for protocol := range pm.parsers {
protocols = append(protocols, protocol)
}
// 按字母顺序排序
sort.Strings(protocols)
return protocols
}
// GetParser 获取指定协议的解析器
// 返回对应协议的解析器实例
func (pm *ParserManager) GetParser(protocol string) (Parser, error) {
parser, exists := pm.parsers[protocol]
if !exists {
return nil, fmt.Errorf("parser not found for protocol: %s", protocol)
}
return parser, nil
}
// Validate 验证代理配置
// 使用对应的解析器验证配置的有效性
func (pm *ParserManager) Validate(config *ProxyConfig) error {
parser, err := pm.GetParser(config.Protocol)
if err != nil {
return err
}
return parser.Validate(config)
}
// ParseBatch 批量解析代理配置
// 支持从包含多个代理配置的字符串中解析所有配置
func (pm *ParserManager) ParseBatch(input string) ([]*ProxyConfig, error) {
pm.logger.Debugf("Parsing batch proxy configuration")
// 按行分割输入
lines := strings.Split(input, "\n")
var configs []*ProxyConfig
for _, line := range lines {
line = strings.TrimSpace(line)
if line == "" {
continue
}
// 尝试解析每一行
config, err := pm.Parse(line)
if err != nil {
pm.logger.WithError(err).Warnf("Failed to parse line: %s", line)
continue
}
configs = append(configs, config)
}
if len(configs) == 0 {
return nil, fmt.Errorf("no valid proxy configurations found")
}
pm.logger.Infof("Successfully parsed %d proxy configurations", len(configs))
return configs, nil
}
// 辅助函数
func min(a, b int) int {
if a < b {
return a
}
return b
}