func SortHTTPRoutes()

in pkg/ingress/kube/common/tool.go [172:246]


func SortHTTPRoutes(routes []*WrapperHTTPRoute) {
	isDefaultBackend := func(route *WrapperHTTPRoute) bool {
		return route.IsDefaultBackend
	}

	isAllCatch := func(route *WrapperHTTPRoute) bool {
		if route.OriginPathType == Prefix && route.OriginPath == "/" {
			if route.HTTPRoute.Match == nil {
				return true
			}

			match := route.HTTPRoute.Match[0]
			if len(match.Headers) == 0 && len(match.QueryParams) == 0 && match.Method == nil {
				return true
			}
		}
		return false
	}

	// default backend,user specified root path => path type => path length =>
	// methods => header => query param
	// refer https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteSpec
	sort.SliceStable(routes, func(i, j int) bool {
		// Move default backend to end
		if isDefaultBackend(routes[i]) {
			return false
		}
		if isDefaultBackend(routes[j]) {
			return true
		}

		// Move user specified root path match to end
		if isAllCatch(routes[i]) {
			return false
		}
		if isAllCatch(routes[j]) {
			return true
		}

		if routes[i].OriginPathType == routes[j].OriginPathType {
			if in, jn := len(routes[i].OriginPath), len(routes[j].OriginPath); in != jn {
				return in > jn
			}

			match1, match2 := routes[i].HTTPRoute.Match[0], routes[j].HTTPRoute.Match[0]
			// methods
			if in, jn := len(match1.Method.GetRegex()), len(match2.Method.GetRegex()); in != jn {
				if in != 0 && jn != 0 {
					return in < jn
				}
				return in != 0
			}
			// headers
			if in, jn := len(match1.Headers), len(match2.Headers); in != jn {
				return in > jn
			}
			// query params
			if in, jn := len(match1.QueryParams), len(match2.QueryParams); in != jn {
				return in > jn
			}
			return false
		}

		if routes[i].OriginPathType == Exact {
			return true
		}

		if routes[i].OriginPathType != Exact &&
			routes[j].OriginPathType != Exact {
			return routes[i].OriginPathType == Prefix
		}

		return false
	})
}