cache compiled globs

This commit is contained in:
David Sharnoff 2023-03-01 15:37:04 -08:00
parent 8da9b5f665
commit 9c8fa464ae
6 changed files with 81 additions and 5 deletions

1
go.mod
View file

@ -12,6 +12,7 @@ require (
github.com/gorilla/mux v1.8.0
github.com/gorilla/schema v1.2.0
github.com/gorilla/securecookie v1.1.1
github.com/hashicorp/golang-lru v0.6.0 // indirect
github.com/jeremija/gosubmit v0.2.7
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
github.com/rs/cors v1.8.3

2
go.sum
View file

@ -117,6 +117,8 @@ github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyC
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.6.0 h1:uL2shRDx7RTrOrTCUZEGP/wJUFiUI8QT6E7z5o8jga4=
github.com/hashicorp/golang-lru v0.6.0/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/jeremija/gosubmit v0.2.7 h1:At0OhGCFGPXyjPYAsCchoBUhE099pcBXmsb4iZqROIc=
github.com/jeremija/gosubmit v0.2.7/go.mod h1:Ui+HS073lCFREXBbdfrJzMB57OI/bdxTiLtrDHHhFPI=

View file

@ -9,7 +9,6 @@ import (
"strings"
"time"
"github.com/gobwas/glob"
"github.com/gorilla/mux"
httphelper "github.com/zitadel/oidc/pkg/http"
@ -283,7 +282,7 @@ func checkURIAginstRedirects(client Client, uri string) error {
}
if globClient, ok := client.(HasRedirectGlobs); ok {
for _, uriGlob := range globClient.RedirectURIGlobs() {
matcher, err := glob.Compile(uriGlob)
matcher, err := CompileGlob(uriGlob)
if err != nil {
return oidc.ErrServerError().WithParent(err)
}

32
pkg/op/glob_cache.go Normal file
View file

@ -0,0 +1,32 @@
package op
import (
"github.com/gobwas/glob"
lru "github.com/hashicorp/golang-lru"
)
var globCache *lru.ARCCache
func init() {
var err error
globCache, err = lru.NewARC(10000)
if err != nil {
panic(err)
}
}
type cacheEntry struct {
compiled glob.Glob
err error
}
func CompileGlob(s string) (glob.Glob, error) {
cachedRaw, ok := globCache.Get(s)
if ok {
cached := cachedRaw.(cacheEntry)
return cached.compiled, cached.err
}
compiled, err := glob.Compile(s)
globCache.Add(s, cacheEntry{compiled: compiled, err: err})
return compiled, err
}

44
pkg/op/glob_cache_test.go Normal file
View file

@ -0,0 +1,44 @@
package op_test
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/zitadel/oidc/pkg/op"
)
func TestCompileGlob(t *testing.T) {
cases := []struct {
glob string
uri string
expectError bool
expectMatch bool
}{
{
glob: "http://example.com/foo/*",
uri: "http://example.com/foo/index.html",
expectMatch: true,
},
{
glob: "http://example.com/foo/*",
uri: "http://example.com/index.html",
expectMatch: false,
},
{
glob: "http://example.com/foo/[xl",
expectError: true,
},
}
for _, tc := range cases {
t.Logf("glob: %s", tc.glob)
compiled, err := op.CompileGlob(tc.glob)
if tc.expectError {
assert.Error(t, err, "compile")
return
}
require.NoError(t, err, "compile")
assert.Equal(t, tc.expectMatch, compiled.Match(tc.uri), tc.uri)
}
}

View file

@ -5,8 +5,6 @@ import (
"net/http"
"net/url"
"github.com/gobwas/glob"
httphelper "github.com/zitadel/oidc/pkg/http"
"github.com/zitadel/oidc/pkg/oidc"
)
@ -102,7 +100,7 @@ func ValidateEndSessionPostLogoutRedirectURI(postLogoutRedirectURI string, clien
}
if globClient, ok := client.(HasRedirectGlobs); ok {
for _, uriGlob := range globClient.PostLogoutRedirectURIGlobs() {
matcher, err := glob.Compile(uriGlob)
matcher, err := CompileGlob(uriGlob)
if err != nil {
return oidc.ErrServerError().WithParent(err)
}