refactor: 引入 ScanSession,替代全局状态穿透扫描管道 (Phase 1-3)

- 新增 common/session.go: ScanSession 结构体封装 Config/State/Params/Dialer
- RunScan/Strategy/ExecuteScanTasks/executeScanTask 全部接收 session
- Plugin 接口从 Scan(ctx, info, config, state) 改为 Scan(ctx, info, session)
- 48 个插件实现统一更新签名
- Web API 构建 ScanSession 传给 RunScan
- CLI 模式通过 Initialize() 创建 session
This commit is contained in:
ZacharyZcR
2026-04-27 23:00:06 +08:00
parent 3d7cdcbe5f
commit a865e5d45e
62 changed files with 283 additions and 89 deletions
+15 -8
View File
@@ -18,7 +18,7 @@ import (
// ScanStrategy 定义扫描策略接口
type ScanStrategy interface {
Execute(ctx context.Context, config *common.Config, state *common.State, info common.HostInfo, ch chan struct{}, wg *sync.WaitGroup)
Execute(ctx context.Context, session *common.ScanSession, info common.HostInfo, ch chan struct{}, wg *sync.WaitGroup)
GetPlugins(config *common.Config) ([]string, bool)
IsPluginApplicableByName(pluginName string, targetHost string, targetPort int, isCustomMode bool, config *common.Config) bool
}
@@ -73,10 +73,13 @@ func selectStrategy(config *common.Config, state *common.State, info common.Host
}
// RunScan 执行整体扫描流程
func RunScan(ctx context.Context, info common.HostInfo, config *common.Config, state *common.State) {
func RunScan(ctx context.Context, info common.HostInfo, session *common.ScanSession) {
ctx, cancel := context.WithCancel(ctx)
defer cancel()
config := session.Config
state := session.State
// 初始化HTTP客户端(静默,无需日志)
if err := lib.Inithttp(config); err != nil {
common.LogError(i18n.Tr("http_client_init_failed", err))
@@ -91,7 +94,7 @@ func RunScan(ctx context.Context, info common.HostInfo, config *common.Config, s
wg := sync.WaitGroup{}
// 执行策略
strategy.Execute(ctx, config, state, info, ch, &wg)
strategy.Execute(ctx, session, info, ch, &wg)
// 等待所有扫描完成
wg.Wait()
@@ -142,7 +145,9 @@ func finishScan(config *common.Config, state *common.State) {
}
// ExecuteScanTasks 任务执行通用框架
func ExecuteScanTasks(ctx context.Context, config *common.Config, state *common.State, targets []common.HostInfo, strategy ScanStrategy, ch chan struct{}, wg *sync.WaitGroup) {
func ExecuteScanTasks(ctx context.Context, session *common.ScanSession, targets []common.HostInfo, strategy ScanStrategy, ch chan struct{}, wg *sync.WaitGroup) {
config := session.Config
// 获取要执行的插件
pluginsToRun, isCustomMode := strategy.GetPlugins(config)
@@ -174,7 +179,7 @@ func ExecuteScanTasks(ctx context.Context, config *common.Config, state *common.
// 检查插件是否适用于当前目标
if strategy.IsPluginApplicableByName(pluginName, target.Host, targetPort, isCustomMode, config) {
executeScanTask(ctx, config, state, pluginName, target, ch, wg)
executeScanTask(ctx, session, pluginName, target, ch, wg)
}
}
}
@@ -205,7 +210,9 @@ var longRunningPlugins = map[string]bool{
}
// executeScanTask 执行单个扫描任务
func executeScanTask(ctx context.Context, config *common.Config, state *common.State, pluginName string, target common.HostInfo, ch chan struct{}, wg *sync.WaitGroup) {
func executeScanTask(ctx context.Context, session *common.ScanSession, pluginName string, target common.HostInfo, ch chan struct{}, wg *sync.WaitGroup) {
state := session.State
// 检查取消
select {
case <-ctx.Done():
@@ -218,7 +225,7 @@ func executeScanTask(ctx context.Context, config *common.Config, state *common.S
go func() {
plugin := plugins.Get(pluginName)
if plugin != nil {
plugin.Scan(ctx, &target, config, state)
plugin.Scan(ctx, &target, session)
}
}()
return
@@ -257,7 +264,7 @@ func executeScanTask(ctx context.Context, config *common.Config, state *common.S
plugin := plugins.Get(pluginName)
if plugin != nil {
result := plugin.Scan(ctx, &target, config, state)
result := plugin.Scan(ctx, &target, session)
if result != nil {
if result.Success {
// 保存成功的扫描结果到文件