-
Notifications
You must be signed in to change notification settings - Fork 2
fix: httproute matching #121
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -3,6 +3,7 @@ package translator | |||||||||
| import ( | ||||||||||
| "encoding/json" | ||||||||||
| "fmt" | ||||||||||
| "sort" | ||||||||||
| "strings" | ||||||||||
|
|
||||||||||
| "github.com/api7/gopkg/pkg/log" | ||||||||||
|
|
@@ -341,6 +342,33 @@ func (t *Translator) translateBackendRef(tctx *provider.TranslateContext, ref ga | |||||||||
| return t.translateEndpointSlice(portName, weight, endpointSlices) | ||||||||||
| } | ||||||||||
|
|
||||||||||
| // calculateMatchPriority calculate the priority of HTTPRouteMatch, according to the Gateway API specification | ||||||||||
| // the higher the return value, the higher the priority | ||||||||||
| func calculateMatchPriority(match *gatewayv1.HTTPRouteMatch) int64 { | ||||||||||
| var score int64 = 0 | ||||||||||
|
|
||||||||||
| // 1. Exact path matches have the highest priority | ||||||||||
| if match.Path != nil && match.Path.Type != nil && *match.Path.Type == gatewayv1.PathMatchExact { | ||||||||||
| score += 10000 | ||||||||||
| } else if match.Path != nil && match.Path.Type != nil && *match.Path.Type == gatewayv1.PathMatchPathPrefix && match.Path.Value != nil { | ||||||||||
| // 2. Prefix path matches, the longer the string, the higher the priority | ||||||||||
| score += 1000 + int64(len(*match.Path.Value)) | ||||||||||
| } | ||||||||||
|
|
||||||||||
| // 3. Method matching | ||||||||||
| if match.Method != nil { | ||||||||||
| score += 100 | ||||||||||
| } | ||||||||||
|
|
||||||||||
| // 4. Header matching, the more headers, the higher the priority | ||||||||||
| score += int64(len(match.Headers) * 10) | ||||||||||
|
|
||||||||||
| // 5. Query parameter matching, the more query parameters, the higher the priority | ||||||||||
| score += int64(len(match.QueryParams)) | ||||||||||
|
|
||||||||||
| return score | ||||||||||
| } | ||||||||||
|
|
||||||||||
| func (t *Translator) TranslateHTTPRoute(tctx *provider.TranslateContext, httpRoute *gatewayv1.HTTPRoute) (*TranslateResult, error) { | ||||||||||
| result := &TranslateResult{} | ||||||||||
|
|
||||||||||
|
|
@@ -388,6 +416,11 @@ func (t *Translator) TranslateHTTPRoute(tctx *provider.TranslateContext, httpRou | |||||||||
| }, | ||||||||||
| }, | ||||||||||
| } | ||||||||||
| } else { | ||||||||||
| // Sort the matches by priority | ||||||||||
| sort.Slice(matches, func(a, b int) bool { | ||||||||||
| return calculateMatchPriority(&matches[a]) > calculateMatchPriority(&matches[b]) | ||||||||||
| }) | ||||||||||
| } | ||||||||||
|
|
||||||||||
| routes := []*adctypes.Route{} | ||||||||||
|
|
@@ -402,6 +435,11 @@ func (t *Translator) TranslateHTTPRoute(tctx *provider.TranslateContext, httpRou | |||||||||
| route.ID = id.GenID(name) | ||||||||||
| route.Labels = labels | ||||||||||
| route.EnableWebsocket = ptr.To(true) | ||||||||||
|
|
||||||||||
| // Set the route priority | ||||||||||
| priority := calculateMatchPriority(&match) | ||||||||||
| route.Priority = &priority | ||||||||||
|
|
||||||||||
| routes = append(routes, route) | ||||||||||
| } | ||||||||||
| t.fillHTTPRoutePoliciesForHTTPRoute(tctx, routes, rule) | ||||||||||
|
|
@@ -422,7 +460,14 @@ func (t *Translator) translateGatewayHTTPRouteMatch(match *gatewayv1.HTTPRouteMa | |||||||||
| case gatewayv1.PathMatchExact: | ||||||||||
| route.Uris = []string{*match.Path.Value} | ||||||||||
| case gatewayv1.PathMatchPathPrefix: | ||||||||||
| route.Uris = []string{*match.Path.Value + "*"} | ||||||||||
| pathValue := *match.Path.Value | ||||||||||
| route.Uris = []string{pathValue} | ||||||||||
|
|
||||||||||
|
||||||||||
| // If the path ends with a slash, append "*" to match all subpaths. | |
| // Otherwise, append "/*" to match the path itself and all its subpaths. |
Copilot
AI
May 6, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The default assignment of the header match type improves clarity, but adding a brief comment explaining this default value could help future maintainers understand the decision process.
| // Default to HeaderMatchExact if no specific header match type is provided. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new logic separates the original path and its wildcard extension into two URIs. Please add inline documentation to clarify the intent and ensure that this change aligns with the expected backend matching behavior.