修复规则优先级问题,修复添加自定义规则后需要重启服务器的问题
This commit is contained in:
@@ -30,7 +30,7 @@ type ShieldStatsData struct {
|
||||
type regexRule struct {
|
||||
pattern *regexp.Regexp
|
||||
original string
|
||||
isLocal bool // 是否为本地规则
|
||||
isLocal bool // 是否为自定义规则
|
||||
source string // 规则来源
|
||||
}
|
||||
|
||||
@@ -39,8 +39,8 @@ type ShieldManager struct {
|
||||
config *config.ShieldConfig
|
||||
domainRules map[string]bool
|
||||
domainExceptions map[string]bool
|
||||
domainRulesIsLocal map[string]bool // 标记域名规则是否为本地规则
|
||||
domainExceptionsIsLocal map[string]bool // 标记域名排除规则是否为本地规则
|
||||
domainRulesIsLocal map[string]bool // 标记域名规则是否为自定义规则
|
||||
domainExceptionsIsLocal map[string]bool // 标记域名排除规则是否为自定义规则
|
||||
domainRulesSource map[string]string // 标记域名规则来源
|
||||
domainExceptionsSource map[string]string // 标记域名排除规则来源
|
||||
domainRulesOriginal map[string]string // 存储域名规则的原始字符串
|
||||
@@ -54,7 +54,7 @@ type ShieldManager struct {
|
||||
updateCtx context.Context
|
||||
updateCancel context.CancelFunc
|
||||
updateRunning bool
|
||||
localRulesCount int // 本地规则数量
|
||||
localRulesCount int // 自定义规则数量
|
||||
remoteRulesCount int // 远程规则数量
|
||||
}
|
||||
|
||||
@@ -109,9 +109,9 @@ func (m *ShieldManager) LoadRules() error {
|
||||
m.remoteRulesCount = 0
|
||||
// 保留计数数据,不随规则重新加载而清空
|
||||
|
||||
// 加载本地规则文件
|
||||
// 加载自定义规则文件
|
||||
if err := m.loadLocalRules(); err != nil {
|
||||
logger.Error("加载本地规则失败", "error", err)
|
||||
logger.Error("加载自定义规则失败", "error", err)
|
||||
// 继续执行,不返回错误
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ func (m *ShieldManager) LoadRules() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// loadLocalRules 加载本地规则文件
|
||||
// loadLocalRules 加载自定义规则文件
|
||||
func (m *ShieldManager) loadLocalRules() error {
|
||||
if m.config.LocalRulesFile == "" {
|
||||
return nil
|
||||
@@ -144,7 +144,7 @@ func (m *ShieldManager) loadLocalRules() error {
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// 记录加载前的规则数量,用于计算本地规则数量
|
||||
// 记录加载前的规则数量,用于计算自定义规则数量
|
||||
beforeDomainRules := len(m.domainRules)
|
||||
beforeRegexRules := len(m.regexRules)
|
||||
|
||||
@@ -154,10 +154,10 @@ func (m *ShieldManager) loadLocalRules() error {
|
||||
if line == "" || strings.HasPrefix(line, "#") {
|
||||
continue
|
||||
}
|
||||
m.parseRule(line, true, "本地规则") // 本地规则,isLocal=true,来源为"本地规则"
|
||||
m.parseRule(line, true, "自定义规则") // 自定义规则,isLocal=true,来源为"自定义规则"
|
||||
}
|
||||
|
||||
// 更新本地规则计数
|
||||
// 更新自定义规则计数
|
||||
m.localRulesCount = (len(m.domainRules) - beforeDomainRules) + (len(m.regexRules) - beforeRegexRules)
|
||||
|
||||
return scanner.Err()
|
||||
@@ -445,10 +445,16 @@ func (m *ShieldManager) parseRuleOptions(optionsStr string) map[string]string {
|
||||
// addDomainRule 添加域名规则,支持是否为阻止规则
|
||||
func (m *ShieldManager) addDomainRule(domain string, block bool, isLocal bool, source string, original string) {
|
||||
if block {
|
||||
// 如果是远程规则,检查是否已经存在本地规则,如果存在则不覆盖
|
||||
// 如果是远程规则,检查是否已经存在自定义规则(阻止或排除),如果存在则不覆盖
|
||||
if !isLocal {
|
||||
// 检查是否存在自定义阻止规则
|
||||
if _, exists := m.domainRulesIsLocal[domain]; exists && m.domainRulesIsLocal[domain] {
|
||||
// 已经存在本地规则,不覆盖
|
||||
// 已经存在自定义规则,不覆盖
|
||||
return
|
||||
}
|
||||
// 检查是否存在自定义排除规则
|
||||
if _, exists := m.domainExceptionsIsLocal[domain]; exists && m.domainExceptionsIsLocal[domain] {
|
||||
// 已经存在自定义规则,不覆盖
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -458,10 +464,16 @@ func (m *ShieldManager) addDomainRule(domain string, block bool, isLocal bool, s
|
||||
m.domainRulesOriginal[domain] = original
|
||||
} else {
|
||||
// 添加到排除规则
|
||||
// 如果是远程规则,检查是否已经存在本地规则,如果存在则不覆盖
|
||||
// 如果是远程规则,检查是否已经存在自定义规则(阻止或排除),如果存在则不覆盖
|
||||
if !isLocal {
|
||||
// 检查是否存在自定义阻止规则
|
||||
if _, exists := m.domainRulesIsLocal[domain]; exists && m.domainRulesIsLocal[domain] {
|
||||
// 已经存在自定义规则,不覆盖
|
||||
return
|
||||
}
|
||||
// 检查是否存在自定义排除规则
|
||||
if _, exists := m.domainExceptionsIsLocal[domain]; exists && m.domainExceptionsIsLocal[domain] {
|
||||
// 已经存在本地规则,不覆盖
|
||||
// 已经存在自定义规则,不覆盖
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -481,11 +493,19 @@ func (m *ShieldManager) addRegexRule(re *regexp.Regexp, original string, block b
|
||||
source: source,
|
||||
}
|
||||
if block {
|
||||
// 如果是远程规则,检查是否已经存在相同的本地规则,如果存在则不添加
|
||||
// 如果是远程规则,检查是否已经存在任何自定义规则,如果存在则不添加
|
||||
if !isLocal {
|
||||
// 检查是否存在自定义阻止规则
|
||||
for _, existingRule := range m.regexRules {
|
||||
if existingRule.original == original && existingRule.isLocal {
|
||||
// 已经存在相同的本地规则,不添加
|
||||
if existingRule.pattern.String() == re.String() && existingRule.isLocal {
|
||||
// 已经存在相同的自定义阻止规则,不添加
|
||||
return
|
||||
}
|
||||
}
|
||||
// 检查是否存在自定义排除规则
|
||||
for _, existingRule := range m.regexExceptions {
|
||||
if existingRule.pattern.String() == re.String() && existingRule.isLocal {
|
||||
// 已经存在相同的自定义排除规则,不添加
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -493,11 +513,19 @@ func (m *ShieldManager) addRegexRule(re *regexp.Regexp, original string, block b
|
||||
m.regexRules = append(m.regexRules, rule)
|
||||
} else {
|
||||
// 添加到排除规则
|
||||
// 如果是远程规则,检查是否已经存在相同的本地规则,如果存在则不添加
|
||||
// 如果是远程规则,检查是否已经存在任何自定义规则,如果存在则不添加
|
||||
if !isLocal {
|
||||
// 检查是否存在自定义阻止规则
|
||||
for _, existingRule := range m.regexRules {
|
||||
if existingRule.pattern.String() == re.String() && existingRule.isLocal {
|
||||
// 已经存在相同的自定义阻止规则,不添加
|
||||
return
|
||||
}
|
||||
}
|
||||
// 检查是否存在自定义排除规则
|
||||
for _, existingRule := range m.regexExceptions {
|
||||
if existingRule.original == original && existingRule.isLocal {
|
||||
// 已经存在相同的本地规则,不添加
|
||||
if existingRule.pattern.String() == re.String() && existingRule.isLocal {
|
||||
// 已经存在相同的自定义排除规则,不添加
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -537,8 +565,17 @@ func (m *ShieldManager) CheckDomainBlockDetails(domain string) map[string]interf
|
||||
result["hostsIP"] = hostsIP
|
||||
|
||||
// 检查排除规则(优先级最高)
|
||||
// 检查域名排除规则
|
||||
if m.domainExceptions[domain] {
|
||||
// 1. 先检查本地域名排除规则
|
||||
if m.domainExceptions[domain] && m.domainExceptionsIsLocal[domain] {
|
||||
result["excluded"] = true
|
||||
result["excludeRule"] = m.domainExceptionsOriginal[domain]
|
||||
result["excludeRuleType"] = "exact_domain"
|
||||
result["blocksource"] = m.domainExceptionsSource[domain]
|
||||
return result
|
||||
}
|
||||
|
||||
// 2. 再检查远程域名排除规则
|
||||
if m.domainExceptions[domain] && !m.domainExceptionsIsLocal[domain] {
|
||||
result["excluded"] = true
|
||||
result["excludeRule"] = m.domainExceptionsOriginal[domain]
|
||||
result["excludeRuleType"] = "exact_domain"
|
||||
@@ -548,9 +585,11 @@ func (m *ShieldManager) CheckDomainBlockDetails(domain string) map[string]interf
|
||||
|
||||
// 检查子域名排除规则
|
||||
parts := strings.Split(domain, ".")
|
||||
|
||||
// 3. 先检查本地子域名排除规则
|
||||
for i := 0; i < len(parts)-1; i++ {
|
||||
subdomain := strings.Join(parts[i:], ".")
|
||||
if m.domainExceptions[subdomain] {
|
||||
if m.domainExceptions[subdomain] && m.domainExceptionsIsLocal[subdomain] {
|
||||
result["excluded"] = true
|
||||
result["excludeRule"] = m.domainExceptionsOriginal[subdomain]
|
||||
result["excludeRuleType"] = "subdomain"
|
||||
@@ -559,9 +598,32 @@ func (m *ShieldManager) CheckDomainBlockDetails(domain string) map[string]interf
|
||||
}
|
||||
}
|
||||
|
||||
// 检查正则表达式排除规则
|
||||
// 4. 再检查远程子域名排除规则
|
||||
for i := 0; i < len(parts)-1; i++ {
|
||||
subdomain := strings.Join(parts[i:], ".")
|
||||
if m.domainExceptions[subdomain] && !m.domainExceptionsIsLocal[subdomain] {
|
||||
result["excluded"] = true
|
||||
result["excludeRule"] = m.domainExceptionsOriginal[subdomain]
|
||||
result["excludeRuleType"] = "subdomain"
|
||||
result["blocksource"] = m.domainExceptionsSource[subdomain]
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
// 5. 先检查本地正则表达式排除规则
|
||||
for _, re := range m.regexExceptions {
|
||||
if re.pattern.MatchString(domain) {
|
||||
if re.isLocal && re.pattern.MatchString(domain) {
|
||||
result["excluded"] = true
|
||||
result["excludeRule"] = re.original
|
||||
result["excludeRuleType"] = "regex"
|
||||
result["blocksource"] = re.source
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
// 6. 再检查远程正则表达式排除规则
|
||||
for _, re := range m.regexExceptions {
|
||||
if !re.isLocal && re.pattern.MatchString(domain) {
|
||||
result["excluded"] = true
|
||||
result["excludeRule"] = re.original
|
||||
result["excludeRuleType"] = "regex"
|
||||
@@ -571,8 +633,17 @@ func (m *ShieldManager) CheckDomainBlockDetails(domain string) map[string]interf
|
||||
}
|
||||
|
||||
// 检查阻止规则 - 先检查精确域名匹配,再检查子域名匹配
|
||||
// 检查精确域名匹配
|
||||
if m.domainRules[domain] {
|
||||
// 7. 先检查本地域名阻止规则
|
||||
if m.domainRules[domain] && m.domainRulesIsLocal[domain] {
|
||||
result["blocked"] = true
|
||||
result["blockRule"] = m.domainRulesOriginal[domain]
|
||||
result["blockRuleType"] = "exact_domain"
|
||||
result["blocksource"] = m.domainRulesSource[domain]
|
||||
return result
|
||||
}
|
||||
|
||||
// 8. 再检查远程域名阻止规则
|
||||
if m.domainRules[domain] && !m.domainRulesIsLocal[domain] {
|
||||
result["blocked"] = true
|
||||
result["blockRule"] = m.domainRulesOriginal[domain]
|
||||
result["blockRuleType"] = "exact_domain"
|
||||
@@ -582,9 +653,11 @@ func (m *ShieldManager) CheckDomainBlockDetails(domain string) map[string]interf
|
||||
|
||||
// 检查子域名匹配(AdGuardHome风格)
|
||||
// 从最长的子域名开始匹配,确保优先级正确
|
||||
|
||||
// 9. 先检查本地子域名阻止规则
|
||||
for i := 0; i < len(parts)-1; i++ {
|
||||
subdomain := strings.Join(parts[i:], ".")
|
||||
if m.domainRules[subdomain] {
|
||||
if m.domainRules[subdomain] && m.domainRulesIsLocal[subdomain] {
|
||||
result["blocked"] = true
|
||||
result["blockRule"] = m.domainRulesOriginal[subdomain]
|
||||
result["blockRuleType"] = "subdomain"
|
||||
@@ -593,9 +666,32 @@ func (m *ShieldManager) CheckDomainBlockDetails(domain string) map[string]interf
|
||||
}
|
||||
}
|
||||
|
||||
// 检查正则表达式匹配
|
||||
// 10. 再检查远程子域名阻止规则
|
||||
for i := 0; i < len(parts)-1; i++ {
|
||||
subdomain := strings.Join(parts[i:], ".")
|
||||
if m.domainRules[subdomain] && !m.domainRulesIsLocal[subdomain] {
|
||||
result["blocked"] = true
|
||||
result["blockRule"] = m.domainRulesOriginal[subdomain]
|
||||
result["blockRuleType"] = "subdomain"
|
||||
result["blocksource"] = m.domainRulesSource[subdomain]
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
// 11. 先检查本地正则表达式阻止规则
|
||||
for _, re := range m.regexRules {
|
||||
if re.pattern.MatchString(domain) {
|
||||
if re.isLocal && re.pattern.MatchString(domain) {
|
||||
result["blocked"] = true
|
||||
result["blockRule"] = re.original
|
||||
result["blockRuleType"] = "regex"
|
||||
result["blocksource"] = re.source
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
// 12. 再检查远程正则表达式阻止规则
|
||||
for _, re := range m.regexRules {
|
||||
if !re.isLocal && re.pattern.MatchString(domain) {
|
||||
result["blocked"] = true
|
||||
result["blockRule"] = re.original
|
||||
result["blockRuleType"] = "regex"
|
||||
@@ -722,13 +818,13 @@ func (m *ShieldManager) GetHostsIP(domain string) (string, bool) {
|
||||
return ip, exists
|
||||
}
|
||||
|
||||
// AddRule 添加屏蔽规则,用户添加的规则是本地规则
|
||||
// AddRule 添加屏蔽规则,用户添加的规则是自定义规则
|
||||
func (m *ShieldManager) AddRule(rule string) error {
|
||||
m.rulesMutex.Lock()
|
||||
defer m.rulesMutex.Unlock()
|
||||
|
||||
// 解析并添加规则到内存,isLocal=true表示本地规则,来源为"本地规则"
|
||||
m.parseRule(rule, true, "本地规则")
|
||||
// 解析并添加规则到内存,isLocal=true表示自定义规则,来源为"自定义规则"
|
||||
m.parseRule(rule, true, "自定义规则")
|
||||
|
||||
// 持久化保存规则到文件
|
||||
if m.config.LocalRulesFile != "" {
|
||||
@@ -957,7 +1053,7 @@ func (m *ShieldManager) StopAutoUpdate() {
|
||||
logger.Info("规则自动更新已停止")
|
||||
}
|
||||
|
||||
// saveRulesToFile 保存规则到文件,只保存本地规则
|
||||
// saveRulesToFile 保存规则到文件,只保存自定义规则
|
||||
func (m *ShieldManager) saveRulesToFile() error {
|
||||
var rules []string
|
||||
|
||||
@@ -1293,12 +1389,12 @@ func (m *ShieldManager) GetHostsCount() int {
|
||||
return len(m.hostsMap)
|
||||
}
|
||||
|
||||
// GetLocalRules 获取仅本地规则
|
||||
// GetLocalRules 获取仅自定义规则
|
||||
func (m *ShieldManager) GetLocalRules() map[string]interface{} {
|
||||
m.rulesMutex.RLock()
|
||||
defer m.rulesMutex.RUnlock()
|
||||
|
||||
// 转换map和slice为字符串列表,只包含本地规则
|
||||
// 转换map和slice为字符串列表,只包含自定义规则
|
||||
domainRulesList := make([]string, 0)
|
||||
for domain, isLocal := range m.domainRulesIsLocal {
|
||||
if isLocal && m.domainRules[domain] {
|
||||
@@ -1329,7 +1425,7 @@ func (m *ShieldManager) GetLocalRules() map[string]interface{} {
|
||||
}
|
||||
}
|
||||
|
||||
// 计算本地规则数量
|
||||
// 计算自定义规则数量
|
||||
localDomainRulesCount := 0
|
||||
for _, isLocal := range m.domainRulesIsLocal {
|
||||
if isLocal {
|
||||
|
||||
Reference in New Issue
Block a user