Skip to content

Commit 12123fb

Browse files
committed
update
1 parent 2213a64 commit 12123fb

File tree

2 files changed

+236
-1
lines changed

2 files changed

+236
-1
lines changed

internal/mode/static/state/graph/httproute.go

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -705,7 +705,9 @@ func validateFilter(
705705
case v1.HTTPRouteFilterRequestHeaderModifier:
706706
return validateFilterHeaderModifier(validator, filter.RequestHeaderModifier, filterPath.Child(string(filter.Type)))
707707
case v1.HTTPRouteFilterResponseHeaderModifier:
708-
return validateFilterHeaderModifier(validator, filter.ResponseHeaderModifier, filterPath.Child(string(filter.Type)))
708+
return validateFilterResponseHeaderModifier(
709+
validator, filter.ResponseHeaderModifier, filterPath.Child(string(filter.Type)),
710+
)
709711
default:
710712
valErr := field.NotSupported(
711713
filterPath.Child("type"),
@@ -878,6 +880,61 @@ func validateFilterHeaderModifierFields(
878880
return allErrs
879881
}
880882

883+
func validateFilterResponseHeaderModifier(
884+
validator validation.HTTPFieldsValidator,
885+
responseHeaderModifier *v1.HTTPHeaderFilter,
886+
filterPath *field.Path,
887+
) field.ErrorList {
888+
if errList := validateFilterHeaderModifier(validator, responseHeaderModifier, filterPath); errList != nil {
889+
return errList
890+
}
891+
var allErrs field.ErrorList
892+
disallowedResponseHeaderSet := map[string]struct{}{
893+
"server": {},
894+
"date": {},
895+
"x-pad": {},
896+
"content-type": {},
897+
"content-length": {},
898+
"connection": {},
899+
}
900+
invalidPrefix := "x-accel"
901+
for _, h := range responseHeaderModifier.Add {
902+
valErr := field.Invalid(filterPath.Child("add"), h, "header name is not allowed")
903+
name := strings.ToLower(string(h.Name))
904+
if _, exists := disallowedResponseHeaderSet[name]; exists {
905+
allErrs = append(allErrs, valErr)
906+
} else {
907+
if strings.HasPrefix(name, strings.ToLower(invalidPrefix)) {
908+
allErrs = append(allErrs, valErr)
909+
}
910+
}
911+
}
912+
for _, h := range responseHeaderModifier.Set {
913+
valErr := field.Invalid(filterPath.Child("set"), h, "header name is not allowed")
914+
name := strings.ToLower(string(h.Name))
915+
if _, exists := disallowedResponseHeaderSet[name]; exists {
916+
allErrs = append(allErrs, valErr)
917+
} else {
918+
if strings.HasPrefix(name, strings.ToLower(invalidPrefix)) {
919+
allErrs = append(allErrs, valErr)
920+
}
921+
}
922+
}
923+
for _, h := range responseHeaderModifier.Remove {
924+
valErr := field.Invalid(filterPath.Child("remove"), h, "header name is not allowed")
925+
name := strings.ToLower(h)
926+
if _, exists := disallowedResponseHeaderSet[name]; exists {
927+
allErrs = append(allErrs, valErr)
928+
} else {
929+
if strings.HasPrefix(name, strings.ToLower(invalidPrefix)) {
930+
allErrs = append(allErrs, valErr)
931+
}
932+
}
933+
}
934+
935+
return allErrs
936+
}
937+
881938
func validateRequestHeadersCaseInsensitiveUnique(
882939
headers []v1.HTTPHeader,
883940
path *field.Path,

internal/mode/static/state/graph/httproute_test.go

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2418,3 +2418,181 @@ func TestValidateFilterRequestHeaderModifier(t *testing.T) {
24182418
})
24192419
}
24202420
}
2421+
2422+
func TestValidateFilterResponseHeaderModifier(t *testing.T) {
2423+
createAllValidValidator := func() *validationfakes.FakeHTTPFieldsValidator {
2424+
v := &validationfakes.FakeHTTPFieldsValidator{}
2425+
return v
2426+
}
2427+
2428+
tests := []struct {
2429+
filter gatewayv1.HTTPRouteFilter
2430+
validator *validationfakes.FakeHTTPFieldsValidator
2431+
name string
2432+
expectErrCount int
2433+
}{
2434+
{
2435+
validator: createAllValidValidator(),
2436+
filter: gatewayv1.HTTPRouteFilter{
2437+
Type: gatewayv1.HTTPRouteFilterResponseHeaderModifier,
2438+
ResponseHeaderModifier: &gatewayv1.HTTPHeaderFilter{
2439+
Set: []gatewayv1.HTTPHeader{
2440+
{Name: "MyBespokeHeader", Value: "my-value"},
2441+
},
2442+
Add: []gatewayv1.HTTPHeader{
2443+
{Name: "Accept-Encoding", Value: "gzip"},
2444+
},
2445+
Remove: []string{"Cache-Control"},
2446+
},
2447+
},
2448+
expectErrCount: 0,
2449+
name: "valid response header modifier filter",
2450+
},
2451+
{
2452+
validator: createAllValidValidator(),
2453+
filter: gatewayv1.HTTPRouteFilter{
2454+
Type: gatewayv1.HTTPRouteFilterResponseHeaderModifier,
2455+
ResponseHeaderModifier: nil,
2456+
},
2457+
expectErrCount: 1,
2458+
name: "nil response header modifier filter",
2459+
},
2460+
{
2461+
validator: func() *validationfakes.FakeHTTPFieldsValidator {
2462+
v := createAllValidValidator()
2463+
v.ValidateFilterHeaderNameReturns(errors.New("Invalid header"))
2464+
return v
2465+
}(),
2466+
filter: gatewayv1.HTTPRouteFilter{
2467+
Type: gatewayv1.HTTPRouteFilterResponseHeaderModifier,
2468+
ResponseHeaderModifier: &gatewayv1.HTTPHeaderFilter{
2469+
Add: []gatewayv1.HTTPHeader{
2470+
{Name: "$var_name", Value: "gzip"},
2471+
},
2472+
},
2473+
},
2474+
expectErrCount: 1,
2475+
name: "response header modifier filter with invalid add",
2476+
},
2477+
{
2478+
validator: func() *validationfakes.FakeHTTPFieldsValidator {
2479+
v := createAllValidValidator()
2480+
v.ValidateFilterHeaderNameReturns(errors.New("Invalid header"))
2481+
return v
2482+
}(),
2483+
filter: gatewayv1.HTTPRouteFilter{
2484+
Type: gatewayv1.HTTPRouteFilterResponseHeaderModifier,
2485+
ResponseHeaderModifier: &gatewayv1.HTTPHeaderFilter{
2486+
Remove: []string{"$var-name"},
2487+
},
2488+
},
2489+
expectErrCount: 1,
2490+
name: "response header modifier filter with invalid remove",
2491+
},
2492+
{
2493+
validator: func() *validationfakes.FakeHTTPFieldsValidator {
2494+
v := createAllValidValidator()
2495+
v.ValidateFilterHeaderValueReturns(errors.New("Invalid header value"))
2496+
return v
2497+
}(),
2498+
filter: gatewayv1.HTTPRouteFilter{
2499+
Type: gatewayv1.HTTPRouteFilterResponseHeaderModifier,
2500+
ResponseHeaderModifier: &gatewayv1.HTTPHeaderFilter{
2501+
Add: []gatewayv1.HTTPHeader{
2502+
{Name: "Accept-Encoding", Value: "yhu$"},
2503+
},
2504+
},
2505+
},
2506+
expectErrCount: 1,
2507+
name: "response header modifier filter with invalid header value",
2508+
},
2509+
{
2510+
validator: func() *validationfakes.FakeHTTPFieldsValidator {
2511+
v := createAllValidValidator()
2512+
v.ValidateFilterHeaderValueReturns(errors.New("Invalid header value"))
2513+
v.ValidateFilterHeaderNameReturns(errors.New("Invalid header"))
2514+
return v
2515+
}(),
2516+
filter: gatewayv1.HTTPRouteFilter{
2517+
Type: gatewayv1.HTTPRouteFilterResponseHeaderModifier,
2518+
ResponseHeaderModifier: &gatewayv1.HTTPHeaderFilter{
2519+
Set: []gatewayv1.HTTPHeader{
2520+
{Name: "Host", Value: "my_host"},
2521+
},
2522+
Add: []gatewayv1.HTTPHeader{
2523+
{Name: "}90yh&$", Value: "gzip$"},
2524+
{Name: "}67yh&$", Value: "compress$"},
2525+
},
2526+
Remove: []string{"Cache-Control$}"},
2527+
},
2528+
},
2529+
expectErrCount: 7,
2530+
name: "response header modifier filter all fields invalid",
2531+
},
2532+
{
2533+
validator: createAllValidValidator(),
2534+
filter: gatewayv1.HTTPRouteFilter{
2535+
Type: gatewayv1.HTTPRouteFilterResponseHeaderModifier,
2536+
ResponseHeaderModifier: &gatewayv1.HTTPHeaderFilter{
2537+
Set: []gatewayv1.HTTPHeader{
2538+
{Name: "MyBespokeHeader", Value: "my-value"},
2539+
{Name: "mYbespokeHEader", Value: "duplicate"},
2540+
},
2541+
Add: []gatewayv1.HTTPHeader{
2542+
{Name: "Accept-Encoding", Value: "gzip"},
2543+
{Name: "accept-encodING", Value: "gzip"},
2544+
},
2545+
Remove: []string{"Cache-Control", "cache-control"},
2546+
},
2547+
},
2548+
expectErrCount: 3,
2549+
name: "response header modifier filter not unique names",
2550+
},
2551+
{
2552+
validator: createAllValidValidator(),
2553+
filter: gatewayv1.HTTPRouteFilter{
2554+
Type: gatewayv1.HTTPRouteFilterResponseHeaderModifier,
2555+
ResponseHeaderModifier: &gatewayv1.HTTPHeaderFilter{
2556+
Set: []gatewayv1.HTTPHeader{
2557+
{Name: "Content-Length", Value: "163"},
2558+
},
2559+
Add: []gatewayv1.HTTPHeader{
2560+
{Name: "Content-Type", Value: "text/plain"},
2561+
},
2562+
Remove: []string{"X-Pad"},
2563+
},
2564+
},
2565+
expectErrCount: 3,
2566+
name: "invalid response header modifier filter",
2567+
},
2568+
{
2569+
validator: createAllValidValidator(),
2570+
filter: gatewayv1.HTTPRouteFilter{
2571+
Type: gatewayv1.HTTPRouteFilterResponseHeaderModifier,
2572+
ResponseHeaderModifier: &gatewayv1.HTTPHeaderFilter{
2573+
Set: []gatewayv1.HTTPHeader{
2574+
{Name: "X-Accel-Redirect", Value: "/protected/iso.img"},
2575+
},
2576+
Add: []gatewayv1.HTTPHeader{
2577+
{Name: "X-Accel-Limit-Rate", Value: "1024"},
2578+
},
2579+
Remove: []string{"X-Accel-Charset"},
2580+
},
2581+
},
2582+
expectErrCount: 3,
2583+
name: "invalid response header modifier filter",
2584+
},
2585+
}
2586+
2587+
filterPath := field.NewPath("test")
2588+
2589+
for _, test := range tests {
2590+
t.Run(test.name, func(t *testing.T) {
2591+
g := NewWithT(t)
2592+
allErrs := validateFilterResponseHeaderModifier(
2593+
test.validator, test.filter.ResponseHeaderModifier, filterPath,
2594+
)
2595+
g.Expect(allErrs).To(HaveLen(test.expectErrCount))
2596+
})
2597+
}
2598+
}

0 commit comments

Comments
 (0)