mirror of
https://github.com/shadow1ng/fscan.git
synced 2025-09-14 14:06:44 +08:00

将Proxy.go的代理连接逻辑重构为完整的模块化系统, 提供更好的性能、可维护性和功能扩展。 主要变更: - Proxy.go: 从192行单体实现重构为简洁包装层 - 新增proxy模块包含5个核心文件:Types.go、Manager.go等 - 支持多种代理类型:HTTP、HTTPS、SOCKS5、直连 - 实现连接池、缓存机制和智能资源管理 - 添加详细的连接统计和性能监控 - 提供线程安全的配置管理和动态更新 - 完全保持API向后兼容性,无需修改调用代码 新增功能: - HTTP/HTTPS代理支持(原来仅支持SOCKS5) - 连接跟踪和统计分析 - 错误分类和详细上下文信息 - 配置验证和URL解析 - 全局代理管理实例 测试验证: - 编译无错误 ✓ - 基础连接功能正常 ✓ - 向后兼容性验证通过 ✓
186 lines
4.2 KiB
Go
186 lines
4.2 KiB
Go
package proxy
|
|
|
|
import (
|
|
"fmt"
|
|
"net/url"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// ParseProxyURL 解析代理URL
|
|
func ParseProxyURL(proxyURL string) (*ProxyConfig, error) {
|
|
if proxyURL == "" {
|
|
return DefaultProxyConfig(), nil
|
|
}
|
|
|
|
u, err := url.Parse(proxyURL)
|
|
if err != nil {
|
|
return nil, NewProxyError(ErrTypeConfig, "代理URL解析失败", 6001, err)
|
|
}
|
|
|
|
config := DefaultProxyConfig()
|
|
|
|
// 设置代理类型
|
|
switch strings.ToLower(u.Scheme) {
|
|
case "http":
|
|
config.Type = ProxyTypeHTTP
|
|
case "https":
|
|
config.Type = ProxyTypeHTTPS
|
|
case "socks5":
|
|
config.Type = ProxyTypeSOCKS5
|
|
default:
|
|
return nil, NewProxyError(ErrTypeConfig,
|
|
fmt.Sprintf("不支持的代理协议: %s", u.Scheme), 6002, nil)
|
|
}
|
|
|
|
// 设置地址
|
|
config.Address = u.Host
|
|
|
|
// 设置认证信息
|
|
if u.User != nil {
|
|
config.Username = u.User.Username()
|
|
config.Password, _ = u.User.Password()
|
|
}
|
|
|
|
// 解析查询参数中的配置
|
|
query := u.Query()
|
|
|
|
// 超时设置
|
|
if timeout := query.Get("timeout"); timeout != "" {
|
|
if t, err := time.ParseDuration(timeout); err == nil {
|
|
config.Timeout = t
|
|
}
|
|
}
|
|
|
|
// 最大重试次数
|
|
if retries := query.Get("retries"); retries != "" {
|
|
if r, err := strconv.Atoi(retries); err == nil {
|
|
config.MaxRetries = r
|
|
}
|
|
}
|
|
|
|
// 保活时间
|
|
if keepalive := query.Get("keepalive"); keepalive != "" {
|
|
if ka, err := time.ParseDuration(keepalive); err == nil {
|
|
config.KeepAlive = ka
|
|
}
|
|
}
|
|
|
|
return config, nil
|
|
}
|
|
|
|
// CreateProxyManager 创建代理管理器
|
|
func CreateProxyManager(proxyURL string) (ProxyManager, error) {
|
|
config, err := ParseProxyURL(proxyURL)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return NewProxyManager(config), nil
|
|
}
|
|
|
|
// ValidateProxyConfig 验证代理配置
|
|
func ValidateProxyConfig(config *ProxyConfig) error {
|
|
if config == nil {
|
|
return NewProxyError(ErrTypeConfig, "配置不能为空", 6003, nil)
|
|
}
|
|
|
|
// 验证代理类型
|
|
if config.Type < ProxyTypeNone || config.Type > ProxyTypeSOCKS5 {
|
|
return NewProxyError(ErrTypeConfig, "无效的代理类型", 6004, nil)
|
|
}
|
|
|
|
// 如果不是直连,必须有地址
|
|
if config.Type != ProxyTypeNone && config.Address == "" {
|
|
return NewProxyError(ErrTypeConfig, "代理地址不能为空", 6005, nil)
|
|
}
|
|
|
|
// 验证超时时间
|
|
if config.Timeout <= 0 {
|
|
return NewProxyError(ErrTypeConfig, "超时时间必须大于0", 6006, nil)
|
|
}
|
|
|
|
// 验证重试次数
|
|
if config.MaxRetries < 0 {
|
|
return NewProxyError(ErrTypeConfig, "最大重试次数不能为负数", 6007, nil)
|
|
}
|
|
|
|
// 验证连接池配置
|
|
if config.MaxIdleConns < 0 {
|
|
return NewProxyError(ErrTypeConfig, "最大空闲连接数不能为负数", 6008, nil)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetProxyTypeFromString 从字符串获取代理类型
|
|
func GetProxyTypeFromString(typeStr string) ProxyType {
|
|
switch strings.ToLower(typeStr) {
|
|
case "none", "direct":
|
|
return ProxyTypeNone
|
|
case "http":
|
|
return ProxyTypeHTTP
|
|
case "https":
|
|
return ProxyTypeHTTPS
|
|
case "socks5":
|
|
return ProxyTypeSOCKS5
|
|
default:
|
|
return ProxyTypeNone
|
|
}
|
|
}
|
|
|
|
// BuildProxyURL 构建代理URL
|
|
func BuildProxyURL(config *ProxyConfig) string {
|
|
if config == nil || config.Type == ProxyTypeNone {
|
|
return ""
|
|
}
|
|
|
|
var scheme string
|
|
switch config.Type {
|
|
case ProxyTypeHTTP:
|
|
scheme = "http"
|
|
case ProxyTypeHTTPS:
|
|
scheme = "https"
|
|
case ProxyTypeSOCKS5:
|
|
scheme = "socks5"
|
|
default:
|
|
return ""
|
|
}
|
|
|
|
url := fmt.Sprintf("%s://", scheme)
|
|
|
|
if config.Username != "" {
|
|
if config.Password != "" {
|
|
url += fmt.Sprintf("%s:%s@", config.Username, config.Password)
|
|
} else {
|
|
url += fmt.Sprintf("%s@", config.Username)
|
|
}
|
|
}
|
|
|
|
url += config.Address
|
|
|
|
return url
|
|
}
|
|
|
|
// IsProxyEnabled 检查是否启用了代理
|
|
func IsProxyEnabled(config *ProxyConfig) bool {
|
|
return config != nil && config.Type != ProxyTypeNone && config.Address != ""
|
|
}
|
|
|
|
// GetDefaultProxyConfigForType 获取指定类型的默认配置
|
|
func GetDefaultProxyConfigForType(proxyType ProxyType, address string) *ProxyConfig {
|
|
config := DefaultProxyConfig()
|
|
config.Type = proxyType
|
|
config.Address = address
|
|
|
|
// 根据类型调整默认配置
|
|
switch proxyType {
|
|
case ProxyTypeHTTP, ProxyTypeHTTPS:
|
|
config.Timeout = 15 * time.Second
|
|
case ProxyTypeSOCKS5:
|
|
config.Timeout = 30 * time.Second
|
|
}
|
|
|
|
return config
|
|
} |