Skip to content

Conversation

@kostis-codefresh
Copy link
Collaborator

@kostis-codefresh kostis-codefresh commented Aug 14, 2025

When HTTP headers are used, clone all original filters/matches when creating the new route.

Fixes #87

@kostis-codefresh kostis-codefresh force-pushed the header-based-routing-filters branch from c59942d to c1adbf3 Compare August 14, 2025 15:22
@kostis-codefresh kostis-codefresh force-pushed the header-based-routing-filters branch 2 times, most recently from b34b0bb to bd2bbb1 Compare August 25, 2025 13:14
@kostis-codefresh kostis-codefresh force-pushed the header-based-routing-filters branch from bd2bbb1 to fe94786 Compare August 25, 2025 13:29
@kostis-codefresh kostis-codefresh merged commit 8664fd9 into main Aug 25, 2025
11 of 12 checks passed
@kostis-codefresh
Copy link
Collaborator Author

@CodiumAI-Agent /improve

@QodoAI-Agent
Copy link

QodoAI-Agent commented Aug 25, 2025

PR Code Suggestions ✨

Latest suggestions up to d9f73bc

CategorySuggestion                                                                                                                                    Impact
Possible issue
Prevent nil-pointer on filter copy

Guard against nil elements within httpRouteRule.Filters before calling DeepCopy() to
prevent a potential nil-pointer panic. Also preallocate the destination slice to
avoid repeated allocations and preserve order deterministically.

pkg/plugin/httproute.go [152-157]

 // Copy filters from original route
 if httpRouteRule.Filters != nil {
+	httpHeaderRouteRule.Filters = make([]gatewayv1.HTTPRouteFilter, 0, len(httpRouteRule.Filters))
 	for i := 0; i < len(httpRouteRule.Filters); i++ {
+		if httpRouteRule.Filters[i] == nil {
+			continue
+		}
 		httpHeaderRouteRule.Filters = append(httpHeaderRouteRule.Filters, *httpRouteRule.Filters[i].DeepCopy())
 	}
 }
Suggestion importance[1-10]: 6

__

Why: The code copies Filters without guarding against potential nil elements; adding per-element nil checks and preallocating the slice is a safe, low-overhead improvement. Impact is moderate as nil entries may be rare but would cause a panic if present.

Low
Safely copy gRPC filters

Add a nil check for each grpcRouteRule.Filters[i] before dereferencing and
preallocate the target slice to avoid panics and extra allocations. This ensures
robust copying when filters contain nil entries.

pkg/plugin/grpcroute.go [149-153]

 // Copy filters from original route
 if grpcRouteRule.Filters != nil {
+	grpcHeaderRouteRule.Filters = make([]gatewayv1.GRPCRouteFilter, 0, len(grpcRouteRule.Filters))
 	for i := 0; i < len(grpcRouteRule.Filters); i++ {
+		if grpcRouteRule.Filters[i] == nil {
+			continue
+		}
 		grpcHeaderRouteRule.Filters = append(grpcHeaderRouteRule.Filters, *grpcRouteRule.Filters[i].DeepCopy())
 	}
 }
Suggestion importance[1-10]: 6

__

Why: Similar to HTTP, copying gRPC filters without checking for nil elements could panic; preallocation and nil checks improve robustness with minimal complexity. Useful but not critical unless nil entries occur.

Low

Previous suggestions

Suggestions up to commit d9f73bc
CategorySuggestion                                                                                                                                    Impact
Possible issue
Safely copy HTTP filters

Guard against nil pointer dereferences when copying nested filter fields by using
safe deep copies and checking inner pointers. Some filter variants may have nil
sub-structs, and dereferencing them during deepcopy or later usage can panic.

pkg/plugin/httproute.go [152-157]

 // Copy filters from original route
 if httpRouteRule.Filters != nil {
-	for i := 0; i < len(httpRouteRule.Filters); i++ {
-		httpHeaderRouteRule.Filters = append(httpHeaderRouteRule.Filters, *httpRouteRule.Filters[i].DeepCopy())
+	httpHeaderRouteRule.Filters = make([]gatewayv1.HTTPRouteFilter, 0, len(httpRouteRule.Filters))
+	for i := range httpRouteRule.Filters {
+		src := httpRouteRule.Filters[i]
+		// Use value copy first; then deep copy only when non-nil helper present
+		copied := src
+		if src.RequestHeaderModifier != nil {
+			copied.RequestHeaderModifier = src.RequestHeaderModifier.DeepCopy()
+		}
+		if src.ResponseHeaderModifier != nil {
+			copied.ResponseHeaderModifier = src.ResponseHeaderModifier.DeepCopy()
+		}
+		if src.URLRewrite != nil {
+			copied.URLRewrite = src.URLRewrite.DeepCopy()
+		}
+		if src.RequestMirror != nil {
+			copied.RequestMirror = src.RequestMirror.DeepCopy()
+		}
+		httpHeaderRouteRule.Filters = append(httpHeaderRouteRule.Filters, copied)
 	}
 }
Suggestion importance[1-10]: 7

__

Why: The suggestion replaces pointer-dereference-based DeepCopy with defensive field-wise copies, avoiding potential nil dereferences on optional filter sub-structs while preserving semantics. Impact is moderate as it hardens code against panics during filter copying introduced in this PR.

Medium
Safely copy gRPC filters

Prevent potential nil dereferences by defensively copying nested fields within each
filter. Some GRPCRouteFilter option structs can be nil; copying them blindly risks
panics or unintended shared references.

pkg/plugin/grpcroute.go [149-153]

 // Copy filters from original route
 if grpcRouteRule.Filters != nil {
-	for i := 0; i < len(grpcRouteRule.Filters); i++ {
-		grpcHeaderRouteRule.Filters = append(grpcHeaderRouteRule.Filters, *grpcRouteRule.Filters[i].DeepCopy())
+	grpcHeaderRouteRule.Filters = make([]gatewayv1.GRPCRouteFilter, 0, len(grpcRouteRule.Filters))
+	for i := range grpcRouteRule.Filters {
+		src := grpcRouteRule.Filters[i]
+		copied := src
+		if src.RequestHeaderModifier != nil {
+			copied.RequestHeaderModifier = src.RequestHeaderModifier.DeepCopy()
+		}
+		if src.ResponseHeaderModifier != nil {
+			copied.ResponseHeaderModifier = src.ResponseHeaderModifier.DeepCopy()
+		}
+		if src.RequestMirror != nil {
+			copied.RequestMirror = src.RequestMirror.DeepCopy()
+		}
+		grpcHeaderRouteRule.Filters = append(grpcHeaderRouteRule.Filters, copied)
 	}
 }
Suggestion importance[1-10]: 7

__

Why: Similar to the HTTP case, this reduces risk of nil pointer panics when copying optional GRPCRoute filter fields by copying conditionally per sub-struct. This improves robustness of new filter-preservation logic without changing behavior.

Medium

@kostis-codefresh
Copy link
Collaborator Author

@coderabbitai full review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Header based routing does not work if original HTTP route has filters on it

3 participants