From 01c824bbfa322beeb99b1260235b7656b1e11fa0 Mon Sep 17 00:00:00 2001 From: Vasiliy Tolstov Date: Wed, 29 Apr 2020 15:23:10 +0300 Subject: [PATCH] api/router: avoid unneeded loops and fix path match (#1594) * api/router: avoid unneeded loops and fix path match * if match found in google api path syntax, not try pcre loop * if path is not ending via $ sign, append it to pcre to avoid matching other strings like /api/account/register can be matched to /api/account * api: add tests and validations Signed-off-by: Vasiliy Tolstov --- static.go | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/static.go b/static.go index 367a53d..7bcf1d7 100644 --- a/static.go +++ b/static.go @@ -110,10 +110,14 @@ func (r *staticRouter) Register(ep *api.Endpoint) error { for _, p := range ep.Path { var pcreok bool - pcrereg, err := regexp.CompilePOSIX(p) - if err == nil { - pcreregs = append(pcreregs, pcrereg) - pcreok = true + + // pcre only when we have start and end markers + if p[0] == '^' && p[len(p)-1] == '$' { + pcrereg, err := regexp.CompilePOSIX(p) + if err == nil { + pcreregs = append(pcreregs, pcrereg) + pcreok = true + } } rule, err := util.Parse(p) @@ -122,6 +126,7 @@ func (r *staticRouter) Register(ep *api.Endpoint) error { } else if err != nil && pcreok { continue } + tpl := rule.Compile() pathreg, err := util.NewPattern(tpl.Version, tpl.OpCodes, tpl.Pool, "") if err != nil { @@ -280,6 +285,9 @@ func (r *staticRouter) endpoint(req *http.Request) (*endpoint, error) { } continue } + if logger.V(logger.DebugLevel, logger.DefaultLogger) { + logger.Debugf("api gpath match %s = %v", path, pathreg) + } pMatch = true ctx := req.Context() md, ok := metadata.FromContext(ctx) @@ -294,16 +302,18 @@ func (r *staticRouter) endpoint(req *http.Request) (*endpoint, error) { break } - // 4. try path via pcre path matching - for _, pathreg := range ep.pcreregs { - if !pathreg.MatchString(req.URL.Path) { - if logger.V(logger.DebugLevel, logger.DefaultLogger) { - logger.Debugf("api pcre path not match %s != %v", req.URL.Path, pathreg) + if !pMatch { + // 4. try path via pcre path matching + for _, pathreg := range ep.pcreregs { + if !pathreg.MatchString(req.URL.Path) { + if logger.V(logger.DebugLevel, logger.DefaultLogger) { + logger.Debugf("api pcre path not match %s != %v", req.URL.Path, pathreg) + } + continue } - continue + pMatch = true + break } - pMatch = true - break } if !pMatch {