Skip to content

Commit

Permalink
key filter support regex and optimize code (#883)
Browse files Browse the repository at this point in the history
  • Loading branch information
OMG-By authored Nov 22, 2024
1 parent 7b2fd6f commit e3bf5c2
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 30 deletions.
2 changes: 2 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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:"[]"`
Expand Down
125 changes: 95 additions & 30 deletions internal/filter/filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"log"
"slices"
"strings"
"sync"
)

// Filter returns:
Expand All @@ -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 {
// Check if the key matches any of the blocked patterns
if blockKeyFilter(key) {
keyResults[inx] = false
continue
}

// 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
}
}
for _, suffix := range config.Opt.Filter.BlockKeySuffix {
if strings.HasSuffix(key, suffix) {
block = true
}
}
if block {
if !allowKeyFilter(key) {
keyResults[inx] = false
}
}
Expand Down Expand Up @@ -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)
}
46 changes: 46 additions & 0 deletions internal/filter/filter_keys_pattern.go
Original file line number Diff line number Diff line change
@@ -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
}
6 changes: 6 additions & 0 deletions shake.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit e3bf5c2

Please sign in to comment.