package parser import ( "fmt" "net/url" "strconv" "strings" "github.com/subconverter-go/internal/logging" ) // HTTPParser HTTP协议解析器 // 实现HTTP代理配置的解析功能 type HTTPParser struct { logger *logging.Logger } // NewHTTPParser 创建新的HTTP解析器 // 返回初始化好的HTTPParser实例 func NewHTTPParser(logger *logging.Logger) *HTTPParser { return &HTTPParser{ logger: logger, } } // Parse 解析HTTP配置 // 支持http://和https://格式 func (p *HTTPParser) Parse(input string) (*ProxyConfig, error) { p.logger.Debugf("Parsing HTTP configuration") // 检查是否已经是URL格式 var parsedURL *url.URL var err error if strings.HasPrefix(input, "http://") || strings.HasPrefix(input, "https://") { parsedURL, err = url.Parse(input) } else { // 尝试添加http://前缀 parsedURL, err = url.Parse("http://" + input) } if err != nil { return nil, fmt.Errorf("failed to parse HTTP URL: %v", err) } config := &ProxyConfig{ Type: "http", Protocol: "http", Server: parsedURL.Hostname(), } // 解析端口 port, err := strconv.Atoi(parsedURL.Port()) if err != nil { // 如果没有指定端口,使用默认端口 if parsedURL.Scheme == "https" { config.Port = 443 } else { config.Port = 80 } } else { config.Port = port } // 解析用户名和密码 var username, password string if parsedURL.User != nil { username = parsedURL.User.Username() password, _ = parsedURL.User.Password() } // 解析备注 if parsedURL.Fragment != "" { config.Name = parsedURL.Fragment } else { config.Name = fmt.Sprintf("http-%s:%d", config.Server, config.Port) } // 创建设置映射 settings := map[string]interface{}{ "udp": false, // HTTP代理不支持UDP } // 添加认证信息 if username != "" { settings["username"] = username if password != "" { settings["password"] = password } } // 如果是HTTPS,添加TLS配置 if parsedURL.Scheme == "https" { settings["tls"] = true } config.Settings = settings config.UDP = false p.logger.Infof("Successfully parsed HTTP configuration for server: %s:%d", config.Server, config.Port) return config, nil } // Validate 验证HTTP配置 func (p *HTTPParser) Validate(config *ProxyConfig) error { p.logger.Debugf("Validating HTTP 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) } // 验证认证信息 username := p.getUsername(config) password := p.getPassword(config) // 如果提供了用户名,验证密码是否也提供 if username != "" && password == "" { p.logger.Warn("Username provided but password is empty") } // 如果没有提供用户名,确保也没有密码 if username == "" && password != "" { return fmt.Errorf("password provided without username") } // 验证TLS配置 tlsEnabled := p.getTLS(config) if tlsEnabled && config.Port != 443 { p.logger.Warnf("HTTPS proxy detected but port is not 443: %d", config.Port) } p.logger.Debug("HTTP configuration validation passed") return nil } // getUsername 从配置中获取用户名 func (p *HTTPParser) getUsername(config *ProxyConfig) string { if username, exists := config.Settings["username"]; exists { if usernameStr, ok := username.(string); ok { return usernameStr } } return "" } // getPassword 从配置中获取密码 func (p *HTTPParser) getPassword(config *ProxyConfig) string { if password, exists := config.Settings["password"]; exists { if passwordStr, ok := password.(string); ok { return passwordStr } } return "" } // getTLS 从配置中获取TLS设置 func (p *HTTPParser) getTLS(config *ProxyConfig) bool { if tls, exists := config.Settings["tls"]; exists { if tlsBool, ok := tls.(bool); ok { return tlsBool } } return false } // GetSupportedProtocols 获取支持的协议 func (p *HTTPParser) GetSupportedProtocols() []string { return []string{"http", "https"} }