fscan/Common/Proxy.go
ZacharyZcR 879293e680 refactor: 重构代理系统为模块化架构
将Proxy.go的代理连接逻辑重构为完整的模块化系统,
提供更好的性能、可维护性和功能扩展。

主要变更:
- Proxy.go: 从192行单体实现重构为简洁包装层
- 新增proxy模块包含5个核心文件:Types.go、Manager.go等
- 支持多种代理类型:HTTP、HTTPS、SOCKS5、直连
- 实现连接池、缓存机制和智能资源管理
- 添加详细的连接统计和性能监控
- 提供线程安全的配置管理和动态更新
- 完全保持API向后兼容性,无需修改调用代码

新增功能:
- HTTP/HTTPS代理支持(原来仅支持SOCKS5)
- 连接跟踪和统计分析
- 错误分类和详细上下文信息
- 配置验证和URL解析
- 全局代理管理实例

测试验证:
- 编译无错误 ✓
- 基础连接功能正常 ✓
- 向后兼容性验证通过 ✓
2025-08-05 03:36:53 +08:00

156 lines
4.6 KiB
Go
Raw 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 Common
/*
Proxy.go - 代理连接管理器(重构版)
此文件现在作为向后兼容的包装层内部委托给新的proxy模块。
原有的代理逻辑已迁移到proxy/模块中,提供更好的错误处理、
连接管理、HTTP代理支持和统计功能。
向后兼容性:
- 保持原有函数签名不变
- 保持原有返回值格式
- 支持所有原有功能SOCKS5代理等
- 新增HTTP代理支持
*/
import (
"context"
"crypto/tls"
"fmt"
"net"
"time"
"github.com/shadow1ng/fscan/Common/proxy"
)
// WrapperTcpWithTimeout 创建一个带超时的TCP连接向后兼容包装函数
func WrapperTcpWithTimeout(network, address string, timeout time.Duration) (net.Conn, error) {
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
return proxy.DialContextWithProxy(ctx, network, address)
}
// WrapperTcpWithContext 创建一个带上下文的TCP连接向后兼容包装函数
func WrapperTcpWithContext(ctx context.Context, network, address string) (net.Conn, error) {
return proxy.DialContextWithProxy(ctx, network, address)
}
// WrapperTCP 根据配置创建TCP连接向后兼容包装函数
func WrapperTCP(network, address string, forward *net.Dialer) (net.Conn, error) {
// 确保代理配置是最新的
if err := syncProxyConfig(); err != nil {
LogError(GetText("proxy_config_sync_failed") + ": " + err.Error())
}
conn, err := proxy.DialWithProxy(network, address)
if err != nil {
LogError(GetText("tcp_conn_failed") + ": " + err.Error())
return nil, fmt.Errorf(GetText("tcp_conn_failed"), err)
}
return conn, nil
}
// WrapperTCPWithContext 根据配置创建支持上下文的TCP连接向后兼容包装函数
func WrapperTCPWithContext(ctx context.Context, network, address string, forward *net.Dialer) (net.Conn, error) {
// 确保代理配置是最新的
if err := syncProxyConfig(); err != nil {
LogError(GetText("proxy_config_sync_failed") + ": " + err.Error())
}
conn, err := proxy.DialContextWithProxy(ctx, network, address)
if err != nil {
LogError(GetText("tcp_conn_failed") + ": " + err.Error())
return nil, fmt.Errorf(GetText("tcp_conn_failed"), err)
}
return conn, nil
}
// Socks5Dialer 创建Socks5代理拨号器已弃用重定向到proxy模块
// 保留此函数以确保向后兼容性但建议使用proxy模块的功能
func Socks5Dialer(forward *net.Dialer) (interface{}, error) {
// 确保代理配置是最新的
if err := syncProxyConfig(); err != nil {
return nil, fmt.Errorf(GetText("socks5_create_failed"), err)
}
// 获取全局代理管理器的拨号器
manager := proxy.GetGlobalProxy()
dialer, err := manager.GetDialer()
if err != nil {
return nil, fmt.Errorf(GetText("socks5_create_failed"), err)
}
return dialer, nil
}
// WrapperTlsWithContext 创建一个通过代理的TLS连接向后兼容包装函数
func WrapperTlsWithContext(ctx context.Context, network, address string, tlsConfig *tls.Config) (net.Conn, error) {
// 确保代理配置是最新的
if err := syncProxyConfig(); err != nil {
LogError(GetText("proxy_config_sync_failed") + ": " + err.Error())
}
conn, err := proxy.DialTLSContextWithProxy(ctx, network, address, tlsConfig)
if err != nil {
LogError(GetText("tls_conn_failed") + ": " + err.Error())
return nil, fmt.Errorf(GetText("tls_conn_failed"), err)
}
return conn, nil
}
// syncProxyConfig 同步代理配置到proxy模块
func syncProxyConfig() error {
// 构建代理URL
var proxyURL string
if Socks5Proxy != "" {
proxyURL = Socks5Proxy
} else if HttpProxy != "" {
proxyURL = HttpProxy
}
// 如果代理配置没有变化,则无需更新
if proxy.IsProxyEnabledGlobally() {
currentAddr := proxy.GetGlobalProxyAddress()
if (proxyURL == "" && currentAddr == "") ||
(proxyURL != "" && currentAddr != "" &&
(Socks5Proxy == currentAddr || HttpProxy == currentAddr)) {
return nil
}
}
// 初始化全局代理
if err := proxy.InitGlobalProxy(proxyURL); err != nil {
return fmt.Errorf("初始化代理配置失败: %v", err)
}
// 记录代理状态
if proxyURL != "" {
LogBase(GetText("proxy_enabled", proxy.GetGlobalProxyType(), proxy.GetGlobalProxyAddress()))
} else {
LogBase(GetText("proxy_disabled"))
}
return nil
}
// GetProxyStats 获取代理统计信息
func GetProxyStats() *proxy.ProxyStats {
return proxy.GetGlobalProxyStats()
}
// IsProxyEnabled 检查是否启用了代理
func IsProxyEnabled() bool {
return proxy.IsProxyEnabledGlobally()
}
// CloseProxy 关闭代理连接
func CloseProxy() error {
return proxy.CloseGlobalProxy()
}