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 { for _, p := range ep.Path {
var pcreok bool var pcreok bool
// pcre only when we have start and end markers
if p[0] == '^' && p[len(p)-1] == '$' {
pcrereg, err := regexp.CompilePOSIX(p) pcrereg, err := regexp.CompilePOSIX(p)
if err == nil { if err == nil {
pcreregs = append(pcreregs, pcrereg) pcreregs = append(pcreregs, pcrereg)
pcreok = true pcreok = true
} }
}
rule, err := util.Parse(p) rule, err := util.Parse(p)
if err != nil && !pcreok { if err != nil && !pcreok {
@ -122,6 +126,7 @@ func (r *staticRouter) Register(ep *api.Endpoint) error {
} else if err != nil && pcreok { } else if err != nil && pcreok {
continue continue
} }
tpl := rule.Compile() tpl := rule.Compile()
pathreg, err := util.NewPattern(tpl.Version, tpl.OpCodes, tpl.Pool, "") pathreg, err := util.NewPattern(tpl.Version, tpl.OpCodes, tpl.Pool, "")
if err != nil { if err != nil {
@ -280,6 +285,9 @@ func (r *staticRouter) endpoint(req *http.Request) (*endpoint, error) {
} }
continue continue
} }
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
logger.Debugf("api gpath match %s = %v", path, pathreg)
}
pMatch = true pMatch = true
ctx := req.Context() ctx := req.Context()
md, ok := metadata.FromContext(ctx) md, ok := metadata.FromContext(ctx)
@ -294,6 +302,7 @@ func (r *staticRouter) endpoint(req *http.Request) (*endpoint, error) {
break break
} }
if !pMatch {
// 4. try path via pcre path matching // 4. try path via pcre path matching
for _, pathreg := range ep.pcreregs { for _, pathreg := range ep.pcreregs {
if !pathreg.MatchString(req.URL.Path) { if !pathreg.MatchString(req.URL.Path) {
@ -305,6 +314,7 @@ func (r *staticRouter) endpoint(req *http.Request) (*endpoint, error) {
pMatch = true pMatch = true
break break
} }
}
if !pMatch { if !pMatch {
continue continue