feat: dedupe geoip rules
This commit is contained in:
@ -381,7 +381,7 @@ func (m *Manager) mergeSubscriptions(subs []*model.Subscription) (map[string]int
|
||||
combined = deepMerge(combined, data)
|
||||
}
|
||||
|
||||
combined["rules"] = dedupeMatchRule(combined["rules"])
|
||||
combined["rules"] = dedupeMatchRule(dedupeGeoIPRule(combined["rules"]))
|
||||
mergeProxySelection(combined, selectionGroups)
|
||||
|
||||
return combined, proxies, true
|
||||
@ -408,6 +408,55 @@ func dedupeMatchRule(rulesRaw interface{}) interface{} {
|
||||
return append(filtered, "MATCH,all proxies")
|
||||
}
|
||||
|
||||
// dedupeGeoIPRule keeps only the last occurrence of each "GEOIP,<payload>"
|
||||
// rule contributed by the merged subscriptions — several subscriptions
|
||||
// commonly ship their own copy of the same rule (e.g. "GEOIP,CN,DIRECT"),
|
||||
// and concatenating them would leave redundant earlier copies ahead of the
|
||||
// one that should actually apply.
|
||||
func dedupeGeoIPRule(rulesRaw interface{}) interface{} {
|
||||
rules, ok := rulesRaw.([]interface{})
|
||||
if !ok {
|
||||
return rulesRaw
|
||||
}
|
||||
|
||||
lastIndex := make(map[string]int)
|
||||
for i, item := range rules {
|
||||
if key, ok := geoIPRuleKey(item); ok {
|
||||
lastIndex[key] = i
|
||||
}
|
||||
}
|
||||
|
||||
filtered := make([]interface{}, 0, len(rules))
|
||||
for i, item := range rules {
|
||||
if key, ok := geoIPRuleKey(item); ok && lastIndex[key] != i {
|
||||
continue
|
||||
}
|
||||
filtered = append(filtered, item)
|
||||
}
|
||||
return filtered
|
||||
}
|
||||
|
||||
// geoIPRuleKey returns the "GEOIP,<payload>" portion of a rule line (i.e.
|
||||
// everything but its target and any trailing "no-resolve" modifier), and
|
||||
// whether the line is a GEOIP rule at all.
|
||||
func geoIPRuleKey(item interface{}) (string, bool) {
|
||||
line, ok := item.(string)
|
||||
if !ok || !strings.HasPrefix(line, "GEOIP,") {
|
||||
return "", false
|
||||
}
|
||||
|
||||
body := line
|
||||
if idx := strings.LastIndex(body, ","); idx != -1 && strings.EqualFold(body[idx+1:], "no-resolve") {
|
||||
body = body[:idx]
|
||||
}
|
||||
|
||||
idx := strings.LastIndex(body, ",")
|
||||
if idx == -1 {
|
||||
return line, true
|
||||
}
|
||||
return body[:idx], true
|
||||
}
|
||||
|
||||
func openInEditor(path string) bool {
|
||||
return editor.OpenFileInEditor(path)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user