Skip to content

Commit f0e75dc

Browse files
committed
Support response header filter for GRPCRoute
1 parent 9ca10f6 commit f0e75dc

File tree

4 files changed

+41
-25
lines changed

4 files changed

+41
-25
lines changed

internal/mode/static/nginx/config/servers_test.go

-22
Original file line numberDiff line numberDiff line change
@@ -650,19 +650,16 @@ func TestCreateServers(t *testing.T) {
650650
Path: "@rule0-route0",
651651
ProxyPass: "http://test_foo_80$request_uri",
652652
ProxySetHeaders: httpBaseHeaders,
653-
ResponseHeaders: http.ResponseHeaders{},
654653
},
655654
{
656655
Path: "@rule0-route1",
657656
ProxyPass: "http://test_foo_80$request_uri",
658657
ProxySetHeaders: httpBaseHeaders,
659-
ResponseHeaders: http.ResponseHeaders{},
660658
},
661659
{
662660
Path: "@rule0-route2",
663661
ProxyPass: "http://test_foo_80$request_uri",
664662
ProxySetHeaders: httpBaseHeaders,
665-
ResponseHeaders: http.ResponseHeaders{},
666663
},
667664
{
668665
Path: "/",
@@ -672,7 +669,6 @@ func TestCreateServers(t *testing.T) {
672669
Path: "@rule1-route0",
673670
ProxyPass: "http://$test__route1_rule1$request_uri",
674671
ProxySetHeaders: httpBaseHeaders,
675-
ResponseHeaders: http.ResponseHeaders{},
676672
},
677673
{
678674
Path: "/test/",
@@ -682,13 +678,11 @@ func TestCreateServers(t *testing.T) {
682678
Path: "/path-only/",
683679
ProxyPass: "http://invalid-backend-ref$request_uri",
684680
ProxySetHeaders: httpBaseHeaders,
685-
ResponseHeaders: http.ResponseHeaders{},
686681
},
687682
{
688683
Path: "= /path-only",
689684
ProxyPass: "http://invalid-backend-ref$request_uri",
690685
ProxySetHeaders: httpBaseHeaders,
691-
ResponseHeaders: http.ResponseHeaders{},
692686
},
693687
{
694688
Path: "/backend-tls-policy/",
@@ -756,21 +750,18 @@ func TestCreateServers(t *testing.T) {
756750
Rewrites: []string{"^ /replacement break"},
757751
ProxyPass: "http://test_foo_80",
758752
ProxySetHeaders: rewriteProxySetHeaders,
759-
ResponseHeaders: http.ResponseHeaders{},
760753
},
761754
{
762755
Path: "= /rewrite",
763756
Rewrites: []string{"^ /replacement break"},
764757
ProxyPass: "http://test_foo_80",
765758
ProxySetHeaders: rewriteProxySetHeaders,
766-
ResponseHeaders: http.ResponseHeaders{},
767759
},
768760
{
769761
Path: "@rule8-route0",
770762
Rewrites: []string{"^/rewrite-with-headers(.*)$ /prefix-replacement$1 break"},
771763
ProxyPass: "http://test_foo_80",
772764
ProxySetHeaders: rewriteProxySetHeaders,
773-
ResponseHeaders: http.ResponseHeaders{},
774765
},
775766
{
776767
Path: "/rewrite-with-headers/",
@@ -810,13 +801,11 @@ func TestCreateServers(t *testing.T) {
810801
Path: "= /exact",
811802
ProxyPass: "http://test_foo_80$request_uri",
812803
ProxySetHeaders: httpBaseHeaders,
813-
ResponseHeaders: http.ResponseHeaders{},
814804
},
815805
{
816806
Path: "@rule12-route0",
817807
ProxyPass: "http://test_foo_80$request_uri",
818808
ProxySetHeaders: httpBaseHeaders,
819-
ResponseHeaders: http.ResponseHeaders{},
820809
},
821810
{
822811
Path: "= /test",
@@ -1029,13 +1018,11 @@ func TestCreateServersConflicts(t *testing.T) {
10291018
Path: "/coffee/",
10301019
ProxyPass: "http://test_foo_80$request_uri",
10311020
ProxySetHeaders: httpBaseHeaders,
1032-
ResponseHeaders: http.ResponseHeaders{},
10331021
},
10341022
{
10351023
Path: "= /coffee",
10361024
ProxyPass: "http://test_bar_80$request_uri",
10371025
ProxySetHeaders: httpBaseHeaders,
1038-
ResponseHeaders: http.ResponseHeaders{},
10391026
},
10401027
createDefaultRootLocation(),
10411028
},
@@ -1069,13 +1056,11 @@ func TestCreateServersConflicts(t *testing.T) {
10691056
Path: "= /coffee",
10701057
ProxyPass: "http://test_foo_80$request_uri",
10711058
ProxySetHeaders: httpBaseHeaders,
1072-
ResponseHeaders: http.ResponseHeaders{},
10731059
},
10741060
{
10751061
Path: "/coffee/",
10761062
ProxyPass: "http://test_bar_80$request_uri",
10771063
ProxySetHeaders: httpBaseHeaders,
1078-
ResponseHeaders: http.ResponseHeaders{},
10791064
},
10801065
createDefaultRootLocation(),
10811066
},
@@ -1119,13 +1104,11 @@ func TestCreateServersConflicts(t *testing.T) {
11191104
Path: "/coffee/",
11201105
ProxyPass: "http://test_bar_80$request_uri",
11211106
ProxySetHeaders: httpBaseHeaders,
1122-
ResponseHeaders: http.ResponseHeaders{},
11231107
},
11241108
{
11251109
Path: "= /coffee",
11261110
ProxyPass: "http://test_baz_80$request_uri",
11271111
ProxySetHeaders: httpBaseHeaders,
1128-
ResponseHeaders: http.ResponseHeaders{},
11291112
},
11301113
createDefaultRootLocation(),
11311114
},
@@ -1244,13 +1227,11 @@ func TestCreateLocationsRootPath(t *testing.T) {
12441227
Path: "/path-1",
12451228
ProxyPass: "http://test_foo_80$request_uri",
12461229
ProxySetHeaders: httpBaseHeaders,
1247-
ResponseHeaders: http.ResponseHeaders{},
12481230
},
12491231
{
12501232
Path: "/path-2",
12511233
ProxyPass: "http://test_foo_80$request_uri",
12521234
ProxySetHeaders: httpBaseHeaders,
1253-
ResponseHeaders: http.ResponseHeaders{},
12541235
},
12551236
{
12561237
Path: "/",
@@ -1297,19 +1278,16 @@ func TestCreateLocationsRootPath(t *testing.T) {
12971278
Path: "/path-1",
12981279
ProxyPass: "http://test_foo_80$request_uri",
12991280
ProxySetHeaders: httpBaseHeaders,
1300-
ResponseHeaders: http.ResponseHeaders{},
13011281
},
13021282
{
13031283
Path: "/path-2",
13041284
ProxyPass: "http://test_foo_80$request_uri",
13051285
ProxySetHeaders: httpBaseHeaders,
1306-
ResponseHeaders: http.ResponseHeaders{},
13071286
},
13081287
{
13091288
Path: "/",
13101289
ProxyPass: "http://test_foo_80$request_uri",
13111290
ProxySetHeaders: httpBaseHeaders,
1312-
ResponseHeaders: http.ResponseHeaders{},
13131291
},
13141292
},
13151293
},

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

+9
Original file line numberDiff line numberDiff line change
@@ -249,12 +249,15 @@ func validateGRPCFilter(
249249
switch filter.Type {
250250
case v1alpha2.GRPCRouteFilterRequestHeaderModifier:
251251
return validateFilterHeaderModifier(validator, filter.RequestHeaderModifier, filterPath.Child(string(filter.Type)))
252+
case v1alpha2.GRPCRouteFilterResponseHeaderModifier:
253+
return validateFilterHeaderModifier(validator, filter.ResponseHeaderModifier, filterPath.Child(string(filter.Type)))
252254
default:
253255
valErr := field.NotSupported(
254256
filterPath.Child("type"),
255257
filter.Type,
256258
[]string{
257259
string(v1alpha2.GRPCRouteFilterRequestHeaderModifier),
260+
string(v1alpha2.GRPCRouteFilterResponseHeaderModifier),
258261
},
259262
)
260263
allErrs = append(allErrs, valErr)
@@ -277,6 +280,12 @@ func convertGRPCFilters(filters []v1alpha2.GRPCRouteFilter) []v1.HTTPRouteFilter
277280
RequestHeaderModifier: filter.RequestHeaderModifier,
278281
}
279282
httpFilters = append(httpFilters, httpRequestHeaderFilter)
283+
case v1alpha2.GRPCRouteFilterResponseHeaderModifier:
284+
httpResponseHeaderFilter := v1.HTTPRouteFilter{
285+
Type: v1.HTTPRouteFilterResponseHeaderModifier,
286+
ResponseHeaderModifier: filter.ResponseHeaderModifier,
287+
}
288+
httpFilters = append(httpFilters, httpResponseHeaderFilter)
280289
default:
281290
continue
282291
}

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

+29-1
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,14 @@ func TestBuildGRPCRoute(t *testing.T) {
243243
Remove: []string{"header"},
244244
},
245245
},
246+
{
247+
Type: "ResponseHeaderModifier",
248+
ResponseHeaderModifier: &v1.HTTPHeaderFilter{
249+
Add: []v1.HTTPHeader{
250+
{Name: "Accept-Encoding", Value: "gzip"},
251+
},
252+
},
253+
},
246254
}
247255

248256
grValidFilter := createGRPCRoute(
@@ -259,6 +267,14 @@ func TestBuildGRPCRoute(t *testing.T) {
259267
Remove: []string{"header"},
260268
},
261269
},
270+
{
271+
Type: v1.HTTPRouteFilterResponseHeaderModifier,
272+
ResponseHeaderModifier: &v1.HTTPHeaderFilter{
273+
Add: []v1.HTTPHeader{
274+
{Name: "Accept-Encoding", Value: "gzip"},
275+
},
276+
},
277+
},
262278
}
263279

264280
createAllValidValidator := func() *validationfakes.FakeHTTPFieldsValidator {
@@ -580,7 +596,7 @@ func TestBuildGRPCRoute(t *testing.T) {
580596
Conditions: []conditions.Condition{
581597
staticConds.NewRouteUnsupportedValue(
582598
`All rules are invalid: spec.rules[0].filters[0].type: ` +
583-
`Unsupported value: "RequestMirror": supported values: "RequestHeaderModifier"`,
599+
`Unsupported value: "RequestMirror": supported values: "RequestHeaderModifier", "ResponseHeaderModifier"`,
584600
),
585601
},
586602
Spec: L7RouteSpec{
@@ -719,6 +735,14 @@ func TestConvertGRPCFilters(t *testing.T) {
719735
Remove: []string{"header"},
720736
},
721737
},
738+
{
739+
Type: "ResponseHeaderModifier",
740+
ResponseHeaderModifier: &v1.HTTPHeaderFilter{
741+
Add: []v1.HTTPHeader{
742+
{Name: "Accept-Encoding", Value: "gzip"},
743+
},
744+
},
745+
},
722746
{
723747
Type: "RequestMirror",
724748
},
@@ -729,6 +753,10 @@ func TestConvertGRPCFilters(t *testing.T) {
729753
Type: v1.HTTPRouteFilterRequestHeaderModifier,
730754
RequestHeaderModifier: grFilters[0].RequestHeaderModifier,
731755
},
756+
{
757+
Type: v1.HTTPRouteFilterResponseHeaderModifier,
758+
ResponseHeaderModifier: grFilters[1].ResponseHeaderModifier,
759+
},
732760
}
733761

734762
g := NewWithT(t)

site/content/overview/gateway-api-compatibility.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ See the [static-mode]({{< relref "/reference/cli-help.md#static-mode">}}) comman
187187
{{< bootstrap-table "table table-striped table-bordered" >}}
188188
| Resource | Core Support Level | Extended Support Level | Implementation-Specific Support Level | API Version |
189189
| --------- | ------------------- | ---------------------- | ------------------------------------- | ----------- |
190-
| GRPCRoute | Partially Supported | Not supported | Not supported | v1alpha2 |
190+
| GRPCRoute | Supported | Not supported | Not supported | v1alpha2 |
191191
{{< /bootstrap-table >}}
192192

193193
**Fields**:
@@ -202,7 +202,8 @@ See the [static-mode]({{< relref "/reference/cli-help.md#static-mode">}}) comman
202202
- `filters`
203203
- `type`: Supported.
204204
- `requestHeaderModifier`: Supported. If multiple filters are configured, NGINX Gateway Fabric will choose the first and ignore the rest.
205-
- `responseHeaderModifier`, `requestMirror`, `extensionRef`: Not supported.
205+
- `responseHeaderModifier`: Supported. If multiple filters are configured, NGINX Gateway Fabric will choose the first and ignore the rest.
206+
- `requestMirror`, `extensionRef`: Not supported.
206207
- `backendRefs`: Partially supported. Backend ref `filters` are not supported.
207208
- `status`
208209
- `parents`

0 commit comments

Comments
 (0)