Add cache for compiled glob patterns

This commit is contained in:
Ingo Oppermann
2024-04-30 14:12:01 +02:00
parent cb3c6de2c8
commit 3a511ac393
2 changed files with 52 additions and 6 deletions

View File

@@ -101,3 +101,23 @@ func TestAccessManager(t *testing.T) {
ok, _ = am.Enforce("foobar", "group", "blubb", "/", "write") ok, _ = am.Enforce("foobar", "group", "blubb", "/", "write")
require.True(t, ok) require.True(t, ok)
} }
func BenchmarkEnforce(b *testing.B) {
adapter, err := createAdapter()
require.NoError(b, err)
am, err := New(Config{
Adapter: adapter,
Logger: nil,
})
require.NoError(b, err)
am.AddPolicy("$anon", "$none", []string{"foobar"}, "**", []string{"ANY"})
b.ResetTimer()
for i := 0; i < b.N; i++ {
ok, _ := am.Enforce("$anon", "$none", "foobar", "baz", "read")
require.True(b, ok)
}
}

View File

@@ -2,10 +2,14 @@ package access
import ( import (
"strings" "strings"
"sync"
"github.com/datarhei/core/v16/glob" "github.com/datarhei/core/v16/glob"
) )
var globcache = map[string]glob.Glob{}
var globcacheMu = sync.RWMutex{}
func resourceMatch(request, policy string) bool { func resourceMatch(request, policy string) bool {
reqPrefix, reqResource := getPrefix(request) reqPrefix, reqResource := getPrefix(request)
polPrefix, polResource := getPrefix(policy) polPrefix, polResource := getPrefix(policy)
@@ -31,16 +35,38 @@ func resourceMatch(request, policy string) bool {
match = false match = false
key := reqType + polResource
if reqType == "api" || reqType == "fs" || reqType == "rtmp" || reqType == "srt" { if reqType == "api" || reqType == "fs" || reqType == "rtmp" || reqType == "srt" {
match, err = glob.Match(polResource, reqResource, rune('/')) globcacheMu.RLock()
if err != nil { matcher, ok := globcache[key]
return false globcacheMu.RUnlock()
if !ok {
matcher, err = glob.Compile(polResource, rune('/'))
if err != nil {
return false
}
globcacheMu.Lock()
globcache[key] = matcher
globcacheMu.Unlock()
} }
match = matcher.Match(reqResource)
} else { } else {
match, err = glob.Match(polResource, reqResource) globcacheMu.RLock()
if err != nil { matcher, ok := globcache[key]
return false globcacheMu.RUnlock()
if !ok {
matcher, err = glob.Compile(polResource)
if err != nil {
return false
}
globcacheMu.Lock()
globcache[key] = matcher
globcacheMu.Unlock()
} }
match = matcher.Match(reqResource)
} }
return match return match