Files
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

174 lines
4.0 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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"}
}