@@ -3,6 +3,7 @@ package translator
33import (
44 "encoding/json"
55 "fmt"
6+ "sort"
67 "strings"
78
89 "github.com/api7/gopkg/pkg/log"
@@ -341,6 +342,33 @@ func (t *Translator) translateBackendRef(tctx *provider.TranslateContext, ref ga
341342 return t .translateEndpointSlice (portName , weight , endpointSlices )
342343}
343344
345+ // calculateMatchPriority calculate the priority of HTTPRouteMatch, according to the Gateway API specification
346+ // the higher the return value, the higher the priority
347+ func calculateMatchPriority (match * gatewayv1.HTTPRouteMatch ) int64 {
348+ var score int64 = 0
349+
350+ // 1. Exact path matches have the highest priority
351+ if match .Path != nil && match .Path .Type != nil && * match .Path .Type == gatewayv1 .PathMatchExact {
352+ score += 10000
353+ } else if match .Path != nil && match .Path .Type != nil && * match .Path .Type == gatewayv1 .PathMatchPathPrefix && match .Path .Value != nil {
354+ // 2. Prefix path matches, the longer the string, the higher the priority
355+ score += 1000 + int64 (len (* match .Path .Value ))
356+ }
357+
358+ // 3. Method matching
359+ if match .Method != nil {
360+ score += 100
361+ }
362+
363+ // 4. Header matching, the more headers, the higher the priority
364+ score += int64 (len (match .Headers ) * 10 )
365+
366+ // 5. Query parameter matching, the more query parameters, the higher the priority
367+ score += int64 (len (match .QueryParams ))
368+
369+ return score
370+ }
371+
344372func (t * Translator ) TranslateHTTPRoute (tctx * provider.TranslateContext , httpRoute * gatewayv1.HTTPRoute ) (* TranslateResult , error ) {
345373 result := & TranslateResult {}
346374
@@ -388,6 +416,11 @@ func (t *Translator) TranslateHTTPRoute(tctx *provider.TranslateContext, httpRou
388416 },
389417 },
390418 }
419+ } else {
420+ // Sort the matches by priority
421+ sort .Slice (matches , func (a , b int ) bool {
422+ return calculateMatchPriority (& matches [a ]) > calculateMatchPriority (& matches [b ])
423+ })
391424 }
392425
393426 routes := []* adctypes.Route {}
@@ -402,6 +435,11 @@ func (t *Translator) TranslateHTTPRoute(tctx *provider.TranslateContext, httpRou
402435 route .ID = id .GenID (name )
403436 route .Labels = labels
404437 route .EnableWebsocket = ptr .To (true )
438+
439+ // Set the route priority
440+ priority := calculateMatchPriority (& match )
441+ route .Priority = & priority
442+
405443 routes = append (routes , route )
406444 }
407445 t .fillHTTPRoutePoliciesForHTTPRoute (tctx , routes , rule )
@@ -422,7 +460,14 @@ func (t *Translator) translateGatewayHTTPRouteMatch(match *gatewayv1.HTTPRouteMa
422460 case gatewayv1 .PathMatchExact :
423461 route .Uris = []string {* match .Path .Value }
424462 case gatewayv1 .PathMatchPathPrefix :
425- route .Uris = []string {* match .Path .Value + "*" }
463+ pathValue := * match .Path .Value
464+ route .Uris = []string {pathValue }
465+
466+ if strings .HasSuffix (pathValue , "/" ) {
467+ route .Uris = append (route .Uris , pathValue + "*" )
468+ } else {
469+ route .Uris = append (route .Uris , pathValue + "/*" )
470+ }
426471 case gatewayv1 .PathMatchRegularExpression :
427472 var this []adctypes.StringOrSlice
428473 this = append (this , adctypes.StringOrSlice {
@@ -439,6 +484,11 @@ func (t *Translator) translateGatewayHTTPRouteMatch(match *gatewayv1.HTTPRouteMa
439484 default :
440485 return nil , errors .New ("unknown path match type " + string (* match .Path .Type ))
441486 }
487+ } else {
488+ /* If no matches are specified, the default is a prefix
489+ path match on "/", which has the effect of matching every
490+ HTTP request. */
491+ route .Uris = []string {"/" , "/*" }
442492 }
443493
444494 if len (match .Headers ) > 0 {
@@ -451,7 +501,12 @@ func (t *Translator) translateGatewayHTTPRouteMatch(match *gatewayv1.HTTPRouteMa
451501 StrVal : "http_" + name ,
452502 })
453503
454- switch * header .Type {
504+ matchType := gatewayv1 .HeaderMatchExact
505+ if header .Type != nil {
506+ matchType = * header .Type
507+ }
508+
509+ switch matchType {
455510 case gatewayv1 .HeaderMatchExact :
456511 this = append (this , adctypes.StringOrSlice {
457512 StrVal : "==" ,
@@ -461,7 +516,7 @@ func (t *Translator) translateGatewayHTTPRouteMatch(match *gatewayv1.HTTPRouteMa
461516 StrVal : "~~" ,
462517 })
463518 default :
464- return nil , errors .New ("unknown header match type " + string (* header . Type ))
519+ return nil , errors .New ("unknown header match type " + string (matchType ))
465520 }
466521
467522 this = append (this , adctypes.StringOrSlice {
@@ -479,7 +534,12 @@ func (t *Translator) translateGatewayHTTPRouteMatch(match *gatewayv1.HTTPRouteMa
479534 StrVal : "arg_" + strings .ToLower (fmt .Sprintf ("%v" , query .Name )),
480535 })
481536
482- switch * query .Type {
537+ queryType := gatewayv1 .QueryParamMatchExact
538+ if query .Type != nil {
539+ queryType = * query .Type
540+ }
541+
542+ switch queryType {
483543 case gatewayv1 .QueryParamMatchExact :
484544 this = append (this , adctypes.StringOrSlice {
485545 StrVal : "==" ,
@@ -489,7 +549,7 @@ func (t *Translator) translateGatewayHTTPRouteMatch(match *gatewayv1.HTTPRouteMa
489549 StrVal : "~~" ,
490550 })
491551 default :
492- return nil , errors .New ("unknown query match type " + string (* query . Type ))
552+ return nil , errors .New ("unknown query match type " + string (queryType ))
493553 }
494554
495555 this = append (this , adctypes.StringOrSlice {
0 commit comments