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 <v.tolstov@unistack.org>
This commit is contained in:
Василий Толстов 2020-04-29 15:23:10 +03:00
parent 5821c18193
commit 01c824bbfa

View File

@ -110,11 +110,15 @@ func (r *staticRouter) Register(ep *api.Endpoint) error {
for _, p := range ep.Path {
var pcreok bool
// 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)
if err != nil && !pcreok {
@ -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,6 +302,7 @@ func (r *staticRouter) endpoint(req *http.Request) (*endpoint, error) {
break
}
if !pMatch {
// 4. try path via pcre path matching
for _, pathreg := range ep.pcreregs {
if !pathreg.MatchString(req.URL.Path) {
@ -305,6 +314,7 @@ func (r *staticRouter) endpoint(req *http.Request) (*endpoint, error) {
pMatch = true
break
}
}
if !pMatch {
continue