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
255 lines
7.2 KiB
Go
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
|
|
}
|