feat(rules): compile path rules directly to glob

This commit is contained in:
yusing 2025-05-05 14:42:55 +08:00
parent dd65a8d04b
commit ef95682116
3 changed files with 21 additions and 32 deletions

View file

@ -5,6 +5,7 @@ import (
"slices"
"github.com/gobwas/glob"
"github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/net/types"
"github.com/yusing/go-proxy/internal/utils/strutils"
@ -176,15 +177,15 @@ var checkers = map[string]struct {
"path": "the request path",
},
},
validate: validateURLPath,
validate: validateURLPathGlob,
builder: func(args any) CheckFunc {
pat := args.(string)
pat := args.(glob.Glob)
return func(cached Cache, r *http.Request) bool {
reqPath := r.URL.Path
if len(reqPath) > 0 && reqPath[0] != '/' {
reqPath = "/" + reqPath
}
return strutils.GlobMatch(pat, reqPath)
return pat.Match(reqPath)
}
},
},

View file

@ -4,8 +4,10 @@ import (
"fmt"
"os"
"path"
"path/filepath"
"strings"
"github.com/gobwas/glob"
"github.com/yusing/go-proxy/internal/gperr"
gphttp "github.com/yusing/go-proxy/internal/net/gphttp"
"github.com/yusing/go-proxy/internal/net/types"
@ -111,6 +113,20 @@ func validateURLPath(args []string) (any, gperr.Error) {
return p, nil
}
// validateURLPathGlob returns []string with each element validated.
func validateURLPathGlob(args []string) (any, gperr.Error) {
p, err := validateURLPath(args)
if err != nil {
return nil, err
}
g, gErr := glob.Compile(p.(string))
if gErr != nil {
return nil, ErrInvalidArguments.With(gErr)
}
return g, nil
}
// validateURLPaths returns []string with each element validated.
func validateURLPaths(paths []string) (any, gperr.Error) {
errs := gperr.NewBuilder("invalid url paths")
@ -133,7 +149,7 @@ func validateFSPath(args []string) (any, gperr.Error) {
if len(args) != 1 {
return nil, ErrExpectOneArg
}
p := path.Clean(args[0])
p := filepath.Clean(args[0])
if _, err := os.Stat(p); err != nil {
return nil, ErrInvalidArguments.With(err)
}

View file

@ -1,28 +0,0 @@
package strutils
import (
"sync"
"github.com/gobwas/glob"
)
var (
globPatterns = make(map[string]glob.Glob)
globPatternsMu sync.Mutex
)
func GlobMatch(pattern string, s string) bool {
if glob, ok := globPatterns[pattern]; ok {
return glob.Match(s)
}
globPatternsMu.Lock()
defer globPatternsMu.Unlock()
glob, err := glob.Compile(pattern)
if err != nil {
return false
}
globPatterns[pattern] = glob
return glob.Match(s)
}