Documentation
¶
Overview ¶
Package sdk Engine 实现。
Engine 持有一个 *runner.Runner 实例,封装所有扫描业务状态:
- FingerStore:当前 Engine 加载的指纹规则集
- RulePool: 规则评估协程池
- CacheManager:请求 / 响应缓存
- PerformanceMonitor:内存与调度监控器
- HostRateLimiter:可选的 per-host 令牌桶限流器
多个 Engine 可在同一进程并发存在,每个实例持有独立资源。
Package sdk 错误定义。
所有 SDK 返回的错误都通过 fmt.Errorf("%w", sentinel) 包装某个 sentinel error, 调用方使用 errors.Is / errors.As 判断错误类型:
if errors.Is(err, sdk.ErrEngineClosed) {
// 处理引擎已关闭场景
}
Package sdk Functional Options 定义。
Engine 的所有配置通过 Option 注入,NewEngine 在构造期一次性 apply。
Package sdk 是 GXX 指纹识别引擎的对外入口。
所有扫描 API 都是 *Engine 的方法。Engine 通过 sdk.NewEngine 构造, 所有配置由 Functional Options(With* 系列)注入;不再使用时调用 Close 释放资源。
最小用法:
engine, err := sdk.NewEngine(ctx,
sdk.WithFingerOptions(sdk.FingerOptions{PocFile: "fingerYaml"}),
sdk.WithTimeout(15 * time.Second),
sdk.WithRuleConcurrency(500),
)
if err != nil {
return err
}
defer engine.Close()
result, err := engine.Scan(ctx, "https://example.com")
for _, m := range result.Matches { ... }
流式批量:
engine.ScanCallback(ctx, []string{...}, func(r *sdk.TargetResult) bool {
...
return true
})
Package sdk 输出写入器(OutputWriter)。
Writer 是 SDK 自有的输出抽象,对每个完成扫描的 *TargetResult 执行落盘 / 转发动作。 所有内置实现都是实例化的:每个 Engine 通过 Option 注入自己的 Writer, 不依赖任何包级全局状态,多 Engine 可在同进程并发使用而互不污染。
可通过以下 Option 启用:
sdk.WithOutputFile("results.json", "json")
sdk.WithSockOutputFile("/tmp/gxx.sock")
sdk.WithWriter(myCustomWriter) // 自行实现 Writer 接口
多个 Option 会被 MultiWriter 自动合并,写入失败只记录日志,不影响扫描主流程。
Index ¶
- Constants
- Variables
- type BaseInfo
- type CertInfo
- type CertName
- type DetectionRule
- type Engine
- func (e *Engine) CacheStats() map[string]interface{}
- func (e *Engine) Close() error
- func (e *Engine) EnableMemoryMonitor(on bool)
- func (e *Engine) FingerCount() int
- func (e *Engine) GetBaseInfo(ctx context.Context, target string) (*BaseInfo, error)
- func (e *Engine) HostRateLimiter() *HostRateLimiter
- func (e *Engine) IsClosed() bool
- func (e *Engine) LoadFingerOptions(opts FingerOptions) error
- func (e *Engine) MemoryStats() MemoryStats
- func (e *Engine) NormalizeURL(ctx context.Context, target string) (string, error)
- func (e *Engine) PoolStats() PoolStats
- func (e *Engine) ResetPoolStats()
- func (e *Engine) RuleCatalog(ctx context.Context) ([]RuleMetadata, error)
- func (e *Engine) Scan(ctx context.Context, target string) (*TargetResult, error)
- func (e *Engine) ScanBatch(ctx context.Context, targets []string) ([]*TargetResult, error)
- func (e *Engine) ScanCallback(ctx context.Context, targets []string, cb TargetCallback) error
- func (e *Engine) ScanIterator(ctx context.Context, targets iter.Seq[string], cb TargetCallback) error
- func (e *Engine) SetMemoryThresholds(highBytes, criticalBytes uint64)
- func (e *Engine) WappalyzerScan(ctx context.Context, target string) (*TechStack, error)
- type FingerInfo
- type FingerMatch
- type FingerOptions
- type HostRateLimiter
- type MatchEvidence
- type MemoryStats
- type MultiWriter
- type Option
- func WithCacheBytes(size int64) Option
- func WithCacheSize(size int) Option
- func WithCacheTTL(ttl time.Duration) Option
- func WithCustomHeaders(headers map[string]string) Option
- func WithDebug(enable bool) Option
- func WithDisableKeepAlives(disable bool) Option
- func WithFingerOptions(opts FingerOptions) Option
- func WithInsecureSkipVerify(skip bool) Option
- func WithLogger(log *slog.Logger) Option
- func WithMatchDetails(enabled bool) Option
- func WithMemoryMonitor(enable bool) Option
- func WithMemoryThresholds(highBytes, criticalBytes uint64) Option
- func WithOutputFile(path string, format OutputFormat) Option
- func WithProactiveGC(enable bool) Option
- func WithProductCatalog(products []ProductDefinition) Option
- func WithProxy(proxy string) Option
- func WithRateLimit(qps float64, burst int) Option
- func WithReverseConfig(config ReverseConfig) Option
- func WithRuleAssessments(assessments []RuleAssessment) Option
- func WithRuleConcurrency(n int) Option
- func WithRuleSourceVersion(version string) Option
- func WithSockOutputFile(path string) Option
- func WithTimeout(d time.Duration) Option
- func WithTimeoutSeconds(seconds int) Option
- func WithURLConcurrency(n int) Option
- func WithWriter(w Writer) Option
- type OutputFormat
- type PoolStats
- type ProductDefinition
- type ProductInfo
- type ProductMatch
- type ReverseConfig
- type RuleAssessment
- type RuleMetadata
- type RuleSource
- type Scanner
- type ServerInfo
- type SubRuleMatch
- type TargetCallback
- type TargetResult
- type TechStack
- type ValidationInfo
- type Writer
Constants ¶
const Version = "1.2.0"
Version 是 SDK 源版本,不能作为被识别产品的版本。
Variables ¶
var ( // ErrEmptyTarget 目标 URL 为空。 ErrEmptyTarget = errors.New("sdk: target URL is empty") // ErrEngineClosed 引擎已经被 Close(),不能再执行扫描。 ErrEngineClosed = errors.New("sdk: engine has been closed") // ErrEngineNotReady 引擎尚未完成初始化(指纹未加载、规则池未初始化等)。 ErrEngineNotReady = errors.New("sdk: engine is not ready") // ErrFingerNotLoaded 指纹规则尚未加载或加载失败。 ErrFingerNotLoaded = errors.New("sdk: finger rules not loaded") // ErrScanFailed 扫描过程中发生不可恢复错误。 ErrScanFailed = errors.New("sdk: scan failed") // ErrInvalidOption Functional Option 入参非法(如 timeout < 0、cache size <= 0 等)。 ErrInvalidOption = errors.New("sdk: invalid option") // ErrEmptyResult 扫描完成但底层返回空指针,通常意味着目标不可达或被防火墙拦截。 ErrEmptyResult = errors.New("sdk: empty scan result") // ErrLoadFinger 指纹规则加载失败(YAML 文件不存在 / 格式错误等)。 ErrLoadFinger = errors.New("sdk: load finger rules failed") )
Sentinel errors 集中定义,便于调用方做 errors.Is/As 判断。
Functions ¶
This section is empty.
Types ¶
type BaseInfo ¶
type BaseInfo struct {
Target string `json:"target"`
Title string `json:"title"`
StatusCode int32 `json:"status_code"`
Server *ServerInfo `json:"server,omitempty"`
TechStack *TechStack `json:"tech_stack,omitempty"`
ICP string `json:"icp,omitempty"`
Certs []CertInfo `json:"certs,omitempty"`
}
BaseInfo 目标基础信息(不含指纹匹配)。
type CertInfo ¶
type CertInfo struct {
Subject CertName `json:"subject"`
Issuer CertName `json:"issuer"`
NotBefore string `json:"not_before"`
NotAfter string `json:"not_after"`
Valid bool `json:"valid"`
SerialNumber string `json:"serial_number"`
PublicKeyAlgorithm string `json:"public_key_algorithm"`
PublicKey string `json:"public_key,omitempty"`
SignatureAlgorithm string `json:"signature_algorithm"`
Version int `json:"version"`
DNSNames []string `json:"dns_names,omitempty"`
IPAddresses []string `json:"ip_addresses,omitempty"`
EmailAddresses []string `json:"email_addresses,omitempty"`
OCSPServer []string `json:"ocsp_server,omitempty"`
CRLDistributionPoints []string `json:"crl_distribution_points,omitempty"`
}
CertInfo 证书信息。
type CertName ¶
type CertName struct {
CommonName string `json:"common_name,omitempty"`
Organization []string `json:"organization,omitempty"`
OrganizationalUnit []string `json:"organizational_unit,omitempty"`
Country []string `json:"country,omitempty"`
Province []string `json:"province,omitempty"`
Locality []string `json:"locality,omitempty"`
StreetAddress []string `json:"street_address,omitempty"`
PostalCode []string `json:"postal_code,omitempty"`
SerialNumber string `json:"serial_number_dn,omitempty"`
}
CertName 证书名称。
type DetectionRule ¶ added in v1.2.0
type DetectionRule struct {
Key string `json:"key"`
Transport string `json:"transport"`
Method string `json:"method"`
Path string `json:"path"`
Expression string `json:"expression"`
Output map[string]string `json:"output,omitempty"`
}
DetectionRule 展示识别依据与版本提取表达式,不包含执行时的响应数据。
type Engine ¶
type Engine struct {
// contains filtered or unexported fields
}
Engine 指纹识别引擎实例。
func NewEngine ¶
NewEngine 创建并初始化 Engine 实例。
调用方负责在不再使用时执行 engine.Close() 释放资源。
engine, err := sdk.NewEngine(ctx,
sdk.WithFingerOptions(sdk.FingerOptions{PocFile: "fingerYaml"}),
sdk.WithTimeout(15 * time.Second),
sdk.WithRuleConcurrency(500),
sdk.WithRateLimit(50, 100),
)
if err != nil { return err }
defer engine.Close()
func (*Engine) EnableMemoryMonitor ¶
EnableMemoryMonitor 运行期开关内存监控。
func (*Engine) GetBaseInfo ¶
GetBaseInfo 仅获取目标基础信息(不执行指纹匹配)。
func (*Engine) HostRateLimiter ¶
func (e *Engine) HostRateLimiter() *HostRateLimiter
HostRateLimiter 返回当前 Engine 持有的限流器(可能为 nil)。
func (*Engine) LoadFingerOptions ¶
func (e *Engine) LoadFingerOptions(opts FingerOptions) error
LoadFingerOptions 运行期重新加载指纹规则。
func (*Engine) NormalizeURL ¶
NormalizeURL 规范化目标地址(http / https 自动探测)。
func (*Engine) RuleCatalog ¶ added in v1.2.0
func (e *Engine) RuleCatalog(ctx context.Context) ([]RuleMetadata, error)
RuleCatalog 返回全部规则的元数据、检测条件和待核对字段,适用于系统导入。
func (*Engine) Scan ¶
Scan 对单个目标执行完整指纹识别。
扫描结果在返回调用方之前会先送入 Writer;Writer 失败仅记录日志, 不影响 Scan 的返回值,调用方仍能拿到完整的 *TargetResult。
func (*Engine) ScanCallback ¶
ScanCallback 对一批目标执行流式扫描。 每完成一个目标立即调用 cb;cb 返回 false 时通过派生 context 取消后续派发与进行中的 ScanTarget。
func (*Engine) ScanIterator ¶
func (e *Engine) ScanIterator(ctx context.Context, targets iter.Seq[string], cb TargetCallback) error
ScanIterator 按并发预算从迭代器拉取目标,完成后串行调用 cb。 迭代器须遵守 yield 返回 false 即停止的约定,并自行处理输入源的取消。 不保留成功结果;目标错误按 ScanCallback 的约定聚合返回。
func (*Engine) SetMemoryThresholds ¶
SetMemoryThresholds 动态调整内存阈值。
type FingerInfo ¶
type FingerInfo struct {
ID string `json:"id"`
Name string `json:"name"`
Author string `json:"author,omitempty"`
Severity string `json:"severity,omitempty"`
Description string `json:"description,omitempty"`
Tags []string `json:"tags,omitempty"`
Vendor string `json:"vendor,omitempty"`
Verified *bool `json:"verified"`
VerificationStatus string `json:"verification_status"`
Confidence *float64 `json:"confidence"`
References []string `json:"references,omitempty"`
Created string `json:"created,omitempty"`
Source RuleSource `json:"source"`
Product *ProductInfo `json:"product,omitempty"`
Validation ValidationInfo `json:"validation"`
}
FingerInfo 指纹规则元信息。
type FingerMatch ¶
type FingerMatch struct {
Info FingerInfo `json:"info"`
Result bool `json:"result"`
Expression string `json:"expression"`
ProductVersion string `json:"product_version,omitempty"`
ProductVersions []string `json:"product_versions,omitempty"`
VersionConflict bool `json:"version_conflict,omitempty"`
DetailsTruncated bool `json:"details_truncated,omitempty"`
MatchedRules []SubRuleMatch `json:"matched_rules,omitempty"`
}
FingerMatch 单条指纹匹配结果。
type FingerOptions ¶
FingerOptions 指纹规则加载选项(独立类型,不暴露内部 types 包)。
func NewFingerOptions ¶
func NewFingerOptions() (FingerOptions, error)
NewFingerOptions 自动探测当前目录的 fingerYaml/,如果存在则用它,否则返回空 FingerOptions (Engine 会自动 fallback 到嵌入式指纹库)。
type HostRateLimiter ¶
type HostRateLimiter = network.HostRateLimiter
HostRateLimiter 是按目标主机划分的请求限流器。
type MatchEvidence ¶ added in v1.2.0
MatchEvidence 是实际求值分支的证据,位置使用原字段的字节区间。
type MemoryStats ¶
type MemoryStats = runner.MemoryStats
MemoryStats 是进程级运行时内存与调度统计,不代表单个 Engine 的独占内存。
type MultiWriter ¶
type MultiWriter struct {
// contains filtered or unexported fields
}
MultiWriter 把多个 Writer 串行组合,写入按注册顺序依次触发, 单个 writer 错误会被收集到 errors.Join 中返回,不影响后续 writer。
func NewMultiWriter ¶
func NewMultiWriter(writers ...Writer) *MultiWriter
NewMultiWriter 用一组 Writer 构造 MultiWriter,nil 元素会被忽略。
func (*MultiWriter) Write ¶
func (m *MultiWriter) Write(ctx context.Context, result *TargetResult) error
Write 依次调用底层 Writer.Write,收集全部 error 后统一返回。
type Option ¶
type Option func(*engineConfig) error
Option 配置 Engine 的函数式选项。
用法:
engine, err := sdk.NewEngine(ctx,
sdk.WithTimeout(15 * time.Second),
sdk.WithProxy("http://127.0.0.1:8080"),
sdk.WithRuleConcurrency(500),
)
func WithCacheBytes ¶
WithCacheBytes 设置请求缓存的估算字节预算(默认 64 MiB),与条目上限同时生效。
func WithCustomHeaders ¶
WithCustomHeaders 设置当前实例的自定义请求头。
func WithDisableKeepAlives ¶
WithDisableKeepAlives 是否禁用 HTTP Keep-Alive。 默认 false(启用 Keep-Alive),仅在遇 "Unsolicited response" 等兼容性问题时显式关闭。
func WithFingerOptions ¶
func WithFingerOptions(opts FingerOptions) Option
WithFingerOptions 指定指纹规则文件 / 目录路径。 若为空则使用嵌入式指纹库。
func WithInsecureSkipVerify ¶
WithInsecureSkipVerify 是否跳过 TLS 证书验证(默认 true,扫描场景普遍需要)。
func WithMatchDetails ¶ added in v1.2.0
WithMatchDetails 控制命中子规则与证据回传;产品版本和元数据始终保留。
func WithMemoryThresholds ¶
WithMemoryThresholds 设置内存高位 / 临界阈值(字节)。
func WithOutputFile ¶
func WithOutputFile(path string, format OutputFormat) Option
WithOutputFile 把每个完成扫描的目标结果写入本地文件。
- path: 目标文件路径,父目录会被自动创建,空字符串表示不启用;
- format: txt / csv / json,未知值回退到 txt。
内部使用实例化的 FileWriter(自带异步队列),多 Engine 互不影响。
func WithProactiveGC ¶
WithProactiveGC 启用主动 GC(默认关闭,避免 STW 放大尾延迟)。
func WithProductCatalog ¶ added in v1.2.0
func WithProductCatalog(products []ProductDefinition) Option
WithProductCatalog 将系统产品目录映射到明确的规则 ID,不从规则作者推测厂商。 参数及每个 Engine 的配置均使用独立副本。
func WithRateLimit ¶
WithRateLimit 启用 per-host 速率限制。
参数:
- qps: 每个 host 每秒允许的请求数(令牌产生速率)
- burst: 令牌桶容量(瞬时突发上限)
用于防止高并发扫描时单目标被限流误判,每个 host 独立持有令牌桶。
func WithReverseConfig ¶
func WithReverseConfig(config ReverseConfig) Option
WithReverseConfig 按值设置反连服务,多个 Engine 的查询配置互不影响。
func WithRuleAssessments ¶ added in v1.2.0
func WithRuleAssessments(assessments []RuleAssessment) Option
WithRuleAssessments 提供带规则摘要的样本测试记录或校准置信度。 测试记录只作用于完全相同的规则内容。
func WithRuleConcurrency ¶
WithRuleConcurrency 设置规则识别并发上限(默认 200)。 纯匹配与慢网络请求的最佳并发不同,应按实际负载测量。
func WithRuleSourceVersion ¶ added in v1.2.0
WithRuleSourceVersion 声明外部规则包的版本,不影响 SDK 的版本。
func WithSockOutputFile ¶
WithSockOutputFile 通过 Unix domain socket 推送 JSON Lines 结果。
path 为空时不启用;socket 文件已存在时会被删除后重新创建。
func WithTimeoutSeconds ¶
WithTimeoutSeconds 设置请求超时时间,单位为秒。
func WithURLConcurrency ¶
WithURLConcurrency 设置 URL 处理并发数(默认 5)。
func WithWriter ¶
WithWriter 注入自定义 Writer(可调用多次累加), 与 WithOutputFile / WithSockOutputFile 同时使用时会被合并到 MultiWriter。
type OutputFormat ¶
type OutputFormat string
OutputFormat 列举 FileWriter 支持的写出格式。
const ( // FormatTXT 人类可读文本,单条记录用分隔线拼接。 FormatTXT OutputFormat = "txt" // FormatCSV 标准 CSV,带 UTF-8 BOM 表头。 FormatCSV OutputFormat = "csv" // FormatJSON 每行一条 JSON Lines。 FormatJSON OutputFormat = "json" )
type PoolStats ¶
type PoolStats struct {
TotalTasks int64 `json:"total_tasks"`
CompletedTasks int64 `json:"completed_tasks"`
FailedTasks int64 `json:"failed_tasks"`
}
PoolStats 规则池统计信息。
type ProductDefinition ¶ added in v1.2.0
type ProductDefinition struct {
ProductInfo
RuleIDs []string `json:"rule_ids"`
}
func ProductCatalog ¶ added in v1.2.0
func ProductCatalog() ([]ProductDefinition, error)
ProductCatalog 返回内置产品目录的独立副本,便于系统扩展及导入。
type ProductInfo ¶ added in v1.2.0
type ProductInfo struct {
ID string `json:"id"`
Name string `json:"name"`
Vendor string `json:"vendor,omitempty"`
Category string `json:"category,omitempty"`
Tags []string `json:"tags,omitempty"`
Aliases []string `json:"aliases,omitempty"`
CPE []string `json:"cpe,omitempty"`
References []string `json:"references,omitempty"`
Description string `json:"description,omitempty"`
}
ProductInfo 是独立产品目录中的信息;未知厂商、CPE 和分类不从名称自动推断。
type ProductMatch ¶ added in v1.2.0
type ProductMatch struct {
ProductInfo
Version string `json:"version,omitempty"`
Versions []string `json:"versions,omitempty"`
VersionConflict bool `json:"version_conflict,omitempty"`
RuleIDs []string `json:"rule_ids"`
}
ProductMatch 按目录 ID 归并同一产品,保留每个命中规则的来源。 版本冲突时 Version 留空,并在 Versions 中保留各自结果。
type ReverseConfig ¶
type ReverseConfig = types.ReverseConfig
ReverseConfig 描述当前 Engine 的 Ceye 与 JNDI 反连服务。
type RuleAssessment ¶ added in v1.2.0
type RuleAssessment struct {
RuleID string `json:"rule_id"`
RuleSHA256 string `json:"rule_sha256"`
Validation ValidationInfo `json:"validation"`
Confidence *float64 `json:"confidence"`
}
type RuleMetadata ¶ added in v1.2.0
type RuleMetadata struct {
Info FingerInfo `json:"info"`
Transport string `json:"transport"`
Expression string `json:"expression"`
Detection []DetectionRule `json:"detection"`
MissingMetadata []string `json:"missing_metadata,omitempty"`
}
type RuleSource ¶ added in v1.2.0
type Scanner ¶
type Scanner interface {
Scan(ctx context.Context, target string) (*TargetResult, error)
GetBaseInfo(ctx context.Context, target string) (*BaseInfo, error)
WappalyzerScan(ctx context.Context, target string) (*TechStack, error)
Close() error
}
Scanner 是 Engine 实现的最小可用扫描接口(便于 mock 测试)。
type ServerInfo ¶
type ServerInfo struct {
OriginalServer string `json:"original_server"`
ServerType string `json:"server_type"`
Version string `json:"version"`
}
ServerInfo 服务器信息。
type SubRuleMatch ¶ added in v1.2.0
type SubRuleMatch struct {
Key string `json:"key"`
Expression string `json:"expression"`
Method string `json:"method"`
Path string `json:"path"`
URL string `json:"url"`
StatusCode int32 `json:"status_code"`
Evidence []MatchEvidence `json:"evidence,omitempty"`
EvidenceTruncated bool `json:"evidence_truncated,omitempty"`
Outputs map[string]string `json:"outputs,omitempty"`
}
type TargetCallback ¶
type TargetCallback func(result *TargetResult) bool
TargetCallback 流式回调签名。 每完成一个目标立即触发 cb;返回 false 时取消尚未开始或进行中的后续扫描。
type TargetResult ¶
type TargetResult struct {
URL string `json:"url"`
StatusCode int32 `json:"status_code"`
Title string `json:"title"`
Server *ServerInfo `json:"server,omitempty"`
Matches []FingerMatch `json:"matches"`
TechStack *TechStack `json:"tech_stack,omitempty"`
ICP string `json:"icp,omitempty"`
Certs []CertInfo `json:"certs,omitempty"`
Products []ProductMatch `json:"products,omitempty"`
}
TargetResult 单个目标的完整扫描结果。
type TechStack ¶
type TechStack struct {
WebServers []string `json:"web_servers,omitempty"`
ReverseProxies []string `json:"reverse_proxies,omitempty"`
JavaScriptFrameworks []string `json:"java_script_frameworks,omitempty"`
JavaScriptLibraries []string `json:"java_script_libraries,omitempty"`
WebFrameworks []string `json:"web_frameworks,omitempty"`
StaticSiteGenerator []string `json:"static_site_generator,omitempty"`
ProgrammingLanguages []string `json:"programming_languages,omitempty"`
Caching []string `json:"caching,omitempty"`
Security []string `json:"security,omitempty"`
HostingPanels []string `json:"hosting_panels,omitempty"`
Other []string `json:"other,omitempty"`
}
TechStack 站点技术栈信息。
type ValidationInfo ¶ added in v1.2.0
type ValidationInfo struct {
Status string `json:"status"`
Method string `json:"method,omitempty"`
PositiveSamples int `json:"positive_samples,omitempty"`
NegativeSamples int `json:"negative_samples,omitempty"`
ReviewedAt string `json:"reviewed_at,omitempty"`
Scope string `json:"scope,omitempty"`
}
ValidationInfo 描述测试方法和样本范围,不把有限样本测试当作实际准确率。
type Writer ¶
type Writer interface {
Write(ctx context.Context, result *TargetResult) error
Close() error
}
Writer 是 SDK 把 *TargetResult 持久化或转发出去的抽象。
内置实现:FileWriter / SockWriter / MultiWriter / NopWriter。 调用方也可自行实现该接口(如对接 Kafka、Webhook 等),并通过 sdk.WithWriter(w) 注入到 Engine。
Write 必须满足以下并发约束:
- 同一实例可能被多 goroutine 并发调用,实现需自行保证线程安全;
- Write 收到 nil 时必须直接返回 nil,不得 panic;
- 即便返回 error,Engine 也只会记录日志,不会终止扫描。
Close 在 Engine.Close 中被调用,实现应释放底层资源并 flush 缓冲; 重复调用必须幂等。
func NewFileWriter ¶
func NewFileWriter(path string, format OutputFormat) (Writer, error)
NewFileWriter 创建一个把 *TargetResult 写到本地文件的 Writer。
- path: 目标文件路径,父目录会被自动创建;空字符串时返回 NopWriter;
- format: txt / csv / json,未知值回退到 txt。
已存在的文件会以追加模式打开(CSV 例外:仅在新建时写入 UTF-8 BOM + 表头)。
func NewSockWriter ¶
NewSockWriter 创建并监听一个 Unix domain socket, 把每条扫描结果以 JSON Lines 形式广播到所有客户端连接。
path 为空字符串时返回 NopWriter;socket 文件存在时会先删除再重新创建。