key filter support regex and optimize code (#883)
This commit is contained in:
parent
7b2fd6fcf1
commit
e3bf5c2315
|
@ -19,6 +19,8 @@ type FilterOptions struct {
|
|||
AllowKeySuffix []string `mapstructure:"allow_key_suffix" default:"[]"`
|
||||
BlockKeyPrefix []string `mapstructure:"block_key_prefix" default:"[]"`
|
||||
BlockKeySuffix []string `mapstructure:"block_key_suffix" default:"[]"`
|
||||
AllowKeyRegex []string `mapstructure:"allow_key_regex" default:"[]"`
|
||||
BlockKeyRegex []string `mapstructure:"block_key_regex" default:"[]"`
|
||||
AllowDB []int `mapstructure:"allow_db" default:"[]"`
|
||||
BlockDB []int `mapstructure:"block_db" default:"[]"`
|
||||
AllowCommand []string `mapstructure:"allow_command" default:"[]"`
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"log"
|
||||
"slices"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Filter returns:
|
||||
|
@ -18,38 +19,12 @@ func Filter(e *entry.Entry) bool {
|
|||
}
|
||||
|
||||
for inx, key := range e.Keys {
|
||||
// Check if the key matches any of the allowed patterns
|
||||
allow := false
|
||||
for _, prefix := range config.Opt.Filter.AllowKeyPrefix {
|
||||
if strings.HasPrefix(key, prefix) {
|
||||
allow = true
|
||||
}
|
||||
}
|
||||
for _, suffix := range config.Opt.Filter.AllowKeySuffix {
|
||||
if strings.HasSuffix(key, suffix) {
|
||||
allow = true
|
||||
}
|
||||
}
|
||||
if len(config.Opt.Filter.AllowKeyPrefix) == 0 && len(config.Opt.Filter.AllowKeySuffix) == 0 {
|
||||
allow = true
|
||||
}
|
||||
if !allow {
|
||||
keyResults[inx] = false
|
||||
}
|
||||
|
||||
// Check if the key matches any of the blocked patterns
|
||||
block := false
|
||||
for _, prefix := range config.Opt.Filter.BlockKeyPrefix {
|
||||
if strings.HasPrefix(key, prefix) {
|
||||
block = true
|
||||
}
|
||||
if blockKeyFilter(key) {
|
||||
keyResults[inx] = false
|
||||
continue
|
||||
}
|
||||
for _, suffix := range config.Opt.Filter.BlockKeySuffix {
|
||||
if strings.HasSuffix(key, suffix) {
|
||||
block = true
|
||||
}
|
||||
}
|
||||
if block {
|
||||
if !allowKeyFilter(key) {
|
||||
keyResults[inx] = false
|
||||
}
|
||||
}
|
||||
|
@ -119,3 +94,93 @@ func Filter(e *entry.Entry) bool {
|
|||
|
||||
return true
|
||||
}
|
||||
|
||||
// blockKeyFilter is block key? default false
|
||||
func blockKeyFilter(key string) bool {
|
||||
if len(config.Opt.Filter.BlockKeyRegex) == 0 && len(config.Opt.Filter.BlockKeyPrefix) == 0 &&
|
||||
len(config.Opt.Filter.BlockKeySuffix) == 0 {
|
||||
return false
|
||||
}
|
||||
if blockKeyMatch(config.Opt.Filter.BlockKeyRegex, key) {
|
||||
return true
|
||||
}
|
||||
for _, prefix := range config.Opt.Filter.BlockKeyPrefix {
|
||||
if strings.HasPrefix(key, prefix) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
for _, suffix := range config.Opt.Filter.BlockKeySuffix {
|
||||
if strings.HasSuffix(key, suffix) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// allowKeyFilter is allow key? default true
|
||||
func allowKeyFilter(key string) bool {
|
||||
// if all allow filter is empty. default is true
|
||||
if len(config.Opt.Filter.AllowKeyRegex) == 0 && len(config.Opt.Filter.AllowKeyPrefix) == 0 &&
|
||||
len(config.Opt.Filter.AllowKeySuffix) == 0 {
|
||||
return true
|
||||
}
|
||||
// If the RE matches, there is no need to iterate over the others
|
||||
if allowKeyMatch(config.Opt.Filter.AllowKeyRegex, key) {
|
||||
return true
|
||||
}
|
||||
|
||||
for _, prefix := range config.Opt.Filter.AllowKeyPrefix {
|
||||
if strings.HasPrefix(key, prefix) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
for _, suffix := range config.Opt.Filter.AllowKeySuffix {
|
||||
if strings.HasSuffix(key, suffix) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var (
|
||||
blockListOnce sync.Once
|
||||
blockListKeyPatterns *KeysPattern
|
||||
)
|
||||
|
||||
// blockKeyMatch
|
||||
func blockKeyMatch(regList []string, key string) bool {
|
||||
blockListOnce.Do(func() {
|
||||
var err error
|
||||
blockListKeyPatterns, err = NewKeysPattern(regList)
|
||||
if err != nil {
|
||||
log.Panicf("%s,conf.Options.BlockKeyRegex[%+v]", err, regList)
|
||||
}
|
||||
})
|
||||
|
||||
return blockListKeyPatterns.MatchKey(key)
|
||||
}
|
||||
|
||||
var (
|
||||
allowOnce sync.Once
|
||||
allowListKeyPatterns *KeysPattern
|
||||
)
|
||||
|
||||
// allowKeyMatch
|
||||
func allowKeyMatch(regList []string, key string) bool {
|
||||
if len(regList) == 1 {
|
||||
first := regList[0]
|
||||
if first == "*" || first == ".*" || first == "^.*$" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
allowOnce.Do(func() {
|
||||
var err error
|
||||
allowListKeyPatterns, err = NewKeysPattern(regList)
|
||||
if err != nil {
|
||||
log.Panicf("%s,conf.Options.AllowKeyRegex[%+v]", err, regList)
|
||||
}
|
||||
})
|
||||
|
||||
return allowListKeyPatterns.MatchKey(key)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
package filter
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// keys pattern
|
||||
type KeysPattern struct {
|
||||
regList []*regexp.Regexp
|
||||
}
|
||||
|
||||
// new keys patterns
|
||||
func NewKeysPattern(patternList01 []string) (ret *KeysPattern, err error) {
|
||||
ret = &KeysPattern{
|
||||
regList: []*regexp.Regexp{},
|
||||
}
|
||||
for _, k01 := range patternList01 {
|
||||
k01 = strings.TrimSpace(k01)
|
||||
if k01 == "" {
|
||||
continue
|
||||
}
|
||||
regItem, err := regexp.Compile(k01)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("%s regexp.Compile fail,err:%v", regItem, err)
|
||||
return nil, err
|
||||
}
|
||||
ret.regList = append(ret.regList, regItem)
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// match Key
|
||||
func (f *KeysPattern) MatchKey(k01 string) bool {
|
||||
if len(f.regList) == 0 {
|
||||
return false
|
||||
}
|
||||
for _, reg01 := range f.regList {
|
||||
regItem := reg01
|
||||
if regItem.MatchString(k01) == true {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
|
@ -42,17 +42,23 @@ off_reply = false # turn off the server reply
|
|||
# Examples:
|
||||
# allow_key_prefix = ["user:", "product:"]
|
||||
# allow_key_suffix = [":active", ":valid"]
|
||||
# allow A collection of keys containing 11-digit mobile phone numbers
|
||||
# allow_key_regex = [":\\d{11}:"]
|
||||
# Leave empty to allow all keys
|
||||
allow_key_prefix = []
|
||||
allow_key_suffix = []
|
||||
allow_key_regex = []
|
||||
|
||||
# Block keys with specific prefixes or suffixes
|
||||
# Examples:
|
||||
# block_key_prefix = ["temp:", "cache:"]
|
||||
# block_key_suffix = [":tmp", ":old"]
|
||||
# block test 11-digit mobile phone numbers keys
|
||||
# block_key_regex = [":test:\\d{11}:"]
|
||||
# Leave empty to block nothing
|
||||
block_key_prefix = []
|
||||
block_key_suffix = []
|
||||
block_key_regex = []
|
||||
|
||||
# Specify allowed and blocked database numbers (e.g., allow_db = [0, 1, 2], block_db = [3, 4, 5])
|
||||
# Leave empty to allow all databases
|
||||
|
|
Loading…
Reference in New Issue