修复规则问题

This commit is contained in:
Alex Yang
2025-12-15 16:04:45 +08:00
parent bcf3e865b6
commit 9aa328d466
31 changed files with 930011 additions and 2022 deletions

View File

@@ -36,50 +36,48 @@ type regexRule struct {
// ShieldManager 屏蔽管理器
type ShieldManager struct {
config *config.ShieldConfig
domainRules map[string]bool
domainExceptions map[string]bool
domainRulesIsLocal map[string]bool // 标记域名规则是否为本地规则
domainExceptionsIsLocal map[string]bool // 标记域名排除规则是否为本地规则
domainRulesSource map[string]string // 标记域名规则来源
domainExceptionsSource map[string]string // 标记域名排除规则来源
domainRulesOriginal map[string]string // 存储域名规则的原始字符串
domainExceptionsOriginal map[string]string // 存储域名排除规则的原始字符串
regexRules []regexRule
regexExceptions []regexRule
hostsMap map[string]string
blockedDomainsCount map[string]int
resolvedDomainsCount map[string]int
rulesMutex sync.RWMutex
updateCtx context.Context
updateCancel context.CancelFunc
updateRunning bool
localRulesCount int // 本地规则数量
remoteRulesCount int // 远程规则数量
config *config.ShieldConfig
domainRules map[string]bool
domainExceptions map[string]bool
domainRulesIsLocal map[string]bool // 标记域名规则是否为本地规则
domainExceptionsIsLocal map[string]bool // 标记域名排除规则是否为本地规则
domainRulesSource map[string]string // 标记域名规则来源
domainExceptionsSource map[string]string // 标记域名排除规则来源
regexRules []regexRule
regexExceptions []regexRule
hostsMap map[string]string
blockedDomainsCount map[string]int
resolvedDomainsCount map[string]int
rulesMutex sync.RWMutex
updateCtx context.Context
updateCancel context.CancelFunc
updateRunning bool
localRulesCount int // 本地规则数量
remoteRulesCount int // 远程规则数量
urlToBlacklistName map[string]string // URL到黑名单名称的映射
}
// NewShieldManager 创建屏蔽管理器实例
func NewShieldManager(config *config.ShieldConfig) *ShieldManager {
ctx, cancel := context.WithCancel(context.Background())
manager := &ShieldManager{
config: config,
domainRules: make(map[string]bool),
domainExceptions: make(map[string]bool),
domainRulesIsLocal: make(map[string]bool),
domainExceptionsIsLocal: make(map[string]bool),
domainRulesSource: make(map[string]string),
domainExceptionsSource: make(map[string]string),
domainRulesOriginal: make(map[string]string),
domainExceptionsOriginal: make(map[string]string),
regexRules: []regexRule{},
regexExceptions: []regexRule{},
hostsMap: make(map[string]string),
blockedDomainsCount: make(map[string]int),
resolvedDomainsCount: make(map[string]int),
updateCtx: ctx,
updateCancel: cancel,
localRulesCount: 0,
remoteRulesCount: 0,
config: config,
domainRules: make(map[string]bool),
domainExceptions: make(map[string]bool),
domainRulesIsLocal: make(map[string]bool),
domainExceptionsIsLocal: make(map[string]bool),
domainRulesSource: make(map[string]string),
domainExceptionsSource: make(map[string]string),
regexRules: []regexRule{},
regexExceptions: []regexRule{},
hostsMap: make(map[string]string),
blockedDomainsCount: make(map[string]int),
resolvedDomainsCount: make(map[string]int),
updateCtx: ctx,
updateCancel: cancel,
localRulesCount: 0,
remoteRulesCount: 0,
urlToBlacklistName: make(map[string]string),
}
// 加载已保存的计数数据
@@ -100,8 +98,6 @@ func (m *ShieldManager) LoadRules() error {
m.domainExceptionsIsLocal = make(map[string]bool)
m.domainRulesSource = make(map[string]string)
m.domainExceptionsSource = make(map[string]string)
m.domainRulesOriginal = make(map[string]string)
m.domainExceptionsOriginal = make(map[string]string)
m.regexRules = []regexRule{}
m.regexExceptions = []regexRule{}
m.hostsMap = make(map[string]string)
@@ -165,7 +161,13 @@ func (m *ShieldManager) loadLocalRules() error {
// loadRemoteRules 加载远程规则
func (m *ShieldManager) loadRemoteRules() error {
// 清空URL到黑名单名称的映射
m.urlToBlacklistName = make(map[string]string)
// 构建URL到黑名单名称的映射
for _, blacklist := range m.config.Blacklists {
m.urlToBlacklistName[blacklist.URL] = blacklist.Name
if blacklist.Enabled {
if err := m.fetchRemoteRules(blacklist.URL); err != nil {
logger.Error("获取远程规则失败", "url", blacklist.URL, "error", err)
@@ -339,9 +341,6 @@ func (m *ShieldManager) loadHosts() error {
// parseRule 解析规则行
func (m *ShieldManager) parseRule(line string, isLocal bool, source string) {
// 保存原始规则用于后续使用
originalLine := line
// 处理注释
if strings.HasPrefix(line, "!") || strings.HasPrefix(line, "#") || line == "" {
return
@@ -366,12 +365,12 @@ func (m *ShieldManager) parseRule(line string, isLocal bool, source string) {
case strings.HasPrefix(line, "||") && strings.HasSuffix(line, "^"):
// AdGuardHome域名规则格式: ||example.com^
domain := strings.TrimSuffix(strings.TrimPrefix(line, "||"), "^")
m.addDomainRule(domain, !isException, isLocal, source, originalLine)
m.addDomainRule(domain, !isException, isLocal, source)
case strings.HasPrefix(line, "||"):
// 精确域名匹配规则
domain := strings.TrimPrefix(line, "||")
m.addDomainRule(domain, !isException, isLocal, source, originalLine)
m.addDomainRule(domain, !isException, isLocal, source)
case strings.HasPrefix(line, "*"):
// 通配符规则,转换为正则表达式
@@ -379,7 +378,7 @@ func (m *ShieldManager) parseRule(line string, isLocal bool, source string) {
pattern = "^" + pattern + "$"
if re, err := regexp.Compile(pattern); err == nil {
// 保存原始规则字符串
m.addRegexRule(re, originalLine, !isException, isLocal, source)
m.addRegexRule(re, line, !isException, isLocal, source)
}
case strings.HasPrefix(line, "/") && strings.HasSuffix(line, "/"):
@@ -389,7 +388,7 @@ func (m *ShieldManager) parseRule(line string, isLocal bool, source string) {
// 对于像 /domain/ 这样的规则,应该匹配包含 domain 字符串的任何域名
if re, err := regexp.Compile("(?i).*" + regexp.QuoteMeta(pattern) + ".*"); err == nil {
// 保存原始规则字符串
m.addRegexRule(re, originalLine, !isException, isLocal, source)
m.addRegexRule(re, line, !isException, isLocal, source)
}
case strings.HasPrefix(line, "|") && strings.HasSuffix(line, "|"):
@@ -398,7 +397,7 @@ func (m *ShieldManager) parseRule(line string, isLocal bool, source string) {
// 将URL模式转换为正则表达式
pattern := "^" + regexp.QuoteMeta(urlPattern) + "$"
if re, err := regexp.Compile(pattern); err == nil {
m.addRegexRule(re, originalLine, !isException, isLocal, source)
m.addRegexRule(re, line, !isException, isLocal, source)
}
case strings.HasPrefix(line, "|"):
@@ -406,7 +405,7 @@ func (m *ShieldManager) parseRule(line string, isLocal bool, source string) {
urlPattern := strings.TrimPrefix(line, "|")
pattern := "^" + regexp.QuoteMeta(urlPattern)
if re, err := regexp.Compile(pattern); err == nil {
m.addRegexRule(re, originalLine, !isException, isLocal, source)
m.addRegexRule(re, line, !isException, isLocal, source)
}
case strings.HasSuffix(line, "|"):
@@ -414,12 +413,12 @@ func (m *ShieldManager) parseRule(line string, isLocal bool, source string) {
urlPattern := strings.TrimSuffix(line, "|")
pattern := regexp.QuoteMeta(urlPattern) + "$"
if re, err := regexp.Compile(pattern); err == nil {
m.addRegexRule(re, originalLine, !isException, isLocal, source)
m.addRegexRule(re, line, !isException, isLocal, source)
}
default:
// 默认作为普通域名规则
m.addDomainRule(line, !isException, isLocal, source, originalLine)
m.addDomainRule(line, !isException, isLocal, source)
}
}
@@ -443,7 +442,7 @@ func (m *ShieldManager) parseRuleOptions(optionsStr string) map[string]string {
}
// addDomainRule 添加域名规则,支持是否为阻止规则
func (m *ShieldManager) addDomainRule(domain string, block bool, isLocal bool, source string, original string) {
func (m *ShieldManager) addDomainRule(domain string, block bool, isLocal bool, source string) {
if block {
// 如果是远程规则,检查是否已经存在本地规则,如果存在则不覆盖
if !isLocal {
@@ -455,7 +454,6 @@ func (m *ShieldManager) addDomainRule(domain string, block bool, isLocal bool, s
m.domainRules[domain] = true
m.domainRulesIsLocal[domain] = isLocal
m.domainRulesSource[domain] = source
m.domainRulesOriginal[domain] = original
} else {
// 添加到排除规则
// 如果是远程规则,检查是否已经存在本地规则,如果存在则不覆盖
@@ -468,7 +466,6 @@ func (m *ShieldManager) addDomainRule(domain string, block bool, isLocal bool, s
m.domainExceptions[domain] = true
m.domainExceptionsIsLocal[domain] = isLocal
m.domainExceptionsSource[domain] = source
m.domainExceptionsOriginal[domain] = original
}
}
@@ -524,6 +521,7 @@ func (m *ShieldManager) CheckDomainBlockDetails(domain string) map[string]interf
"blockRule": "",
"blockRuleType": "",
"blocksource": "",
"blacklistName": "",
"excluded": false,
"excludeRule": "",
"excludeRuleType": "",
@@ -539,67 +537,49 @@ func (m *ShieldManager) CheckDomainBlockDetails(domain string) map[string]interf
// 检查排除规则(优先级最高)
// 检查域名排除规则
if m.domainExceptions[domain] {
source := m.domainExceptionsSource[domain]
result["excluded"] = true
result["excludeRule"] = m.domainExceptionsOriginal[domain]
result["excludeRule"] = domain
result["excludeRuleType"] = "exact_domain"
result["blocksource"] = m.domainExceptionsSource[domain]
result["blocksource"] = source
result["blacklistName"] = m.getBlacklistNameByURL(source)
return result
}
// 检查子域名排除规则
parts := strings.Split(domain, ".")
for i := 0; i < len(parts)-1; i++ {
subdomain := strings.Join(parts[i:], ".")
if m.domainExceptions[subdomain] {
result["excluded"] = true
result["excludeRule"] = m.domainExceptionsOriginal[subdomain]
result["excludeRuleType"] = "subdomain"
result["blocksource"] = m.domainExceptionsSource[subdomain]
return result
}
}
// 检查正则表达式排除规则
for _, re := range m.regexExceptions {
if re.pattern.MatchString(domain) {
source := re.source
result["excluded"] = true
result["excludeRule"] = re.original
result["excludeRuleType"] = "regex"
result["blocksource"] = re.source
result["blocksource"] = source
result["blacklistName"] = m.getBlacklistNameByURL(source)
return result
}
}
// 检查阻止规则 - 先检查精确域名匹配,再检查子域名匹配
// 检查阻止规则
// 检查精确域名匹配
if m.domainRules[domain] {
source := m.domainRulesSource[domain]
result["blocked"] = true
result["blockRule"] = m.domainRulesOriginal[domain]
result["blockRule"] = domain
result["blockRuleType"] = "exact_domain"
result["blocksource"] = m.domainRulesSource[domain]
result["blocksource"] = source
result["blacklistName"] = m.getBlacklistNameByURL(source)
return result
}
// 检查子域名匹配AdGuardHome风格
// 从最长的子域名开始匹配,确保优先级正确
for i := 0; i < len(parts)-1; i++ {
subdomain := strings.Join(parts[i:], ".")
if m.domainRules[subdomain] {
result["blocked"] = true
result["blockRule"] = m.domainRulesOriginal[subdomain]
result["blockRuleType"] = "subdomain"
result["blocksource"] = m.domainRulesSource[subdomain]
return result
}
}
// 检查正则表达式匹配
for _, re := range m.regexRules {
if re.pattern.MatchString(domain) {
source := re.source
result["blocked"] = true
result["blockRule"] = re.original
result["blockRuleType"] = "regex"
result["blocksource"] = re.source
result["blocksource"] = source
result["blacklistName"] = m.getBlacklistNameByURL(source)
return result
}
}
@@ -1271,6 +1251,14 @@ func (m *ShieldManager) UpdateBlacklist(blacklists []config.BlacklistEntry) {
m.config.Blacklists = blacklists
}
// getBlacklistNameByURL 根据URL获取黑名单名称如果没有找到则返回URL本身
func (m *ShieldManager) getBlacklistNameByURL(url string) string {
if name, exists := m.urlToBlacklistName[url]; exists {
return name
}
return url
}
// GetAllHosts 获取所有hosts条目
func (m *ShieldManager) GetAllHosts() map[string]string {
m.rulesMutex.RLock()