-
Notifications
You must be signed in to change notification settings - Fork 364
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: huabing zhao <[email protected]>
- Loading branch information
1 parent
51517c5
commit e528962
Showing
3 changed files
with
153 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
// Copyright Envoy Gateway Authors | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// The full text of the Apache license is available in the LICENSE file at | ||
// the root of the repo. | ||
|
||
package translator | ||
|
||
import ( | ||
"sort" | ||
|
||
hcmv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3" | ||
"github.com/envoyproxy/go-control-plane/pkg/wellknown" | ||
|
||
"github.com/envoyproxy/gateway/internal/ir" | ||
xdsfilters "github.com/envoyproxy/gateway/internal/xds/filters" | ||
) | ||
|
||
type OrderedHTTPFilter struct { | ||
filter *hcmv3.HttpFilter | ||
order int | ||
} | ||
|
||
type OrderedHTTPFilters []*OrderedHTTPFilter | ||
|
||
func newOrderedHTTPFilter(filter *hcmv3.HttpFilter) *OrderedHTTPFilter { | ||
order := 50 | ||
|
||
// Set a rational order for all the filters. | ||
switch filter.Name { | ||
case wellknown.CORS: | ||
order = 1 | ||
case jwtAuthenFilter: | ||
order = 2 | ||
case wellknown.HTTPRateLimit: | ||
order = 3 | ||
case wellknown.Router: | ||
order = 100 | ||
} | ||
|
||
return &OrderedHTTPFilter{ | ||
filter: filter, | ||
order: order, | ||
} | ||
} | ||
|
||
// sort.Interface implementation. | ||
func (o OrderedHTTPFilters) Len() int { | ||
return len(o) | ||
} | ||
|
||
func (o OrderedHTTPFilters) Less(i, j int) bool { | ||
return o[i].order < o[j].order | ||
} | ||
|
||
func (o OrderedHTTPFilters) Swap(i, j int) { | ||
o[i], o[j] = o[j], o[i] | ||
} | ||
|
||
// sortHTTPFilters sorts the HTTP filters in the correct order. | ||
// This is needed because the order of the filters is important. | ||
// For example, the cors filter must be before the router filter. | ||
// The router filter must be the last one. | ||
func sortHTTPFilters(filters []*hcmv3.HttpFilter) []*hcmv3.HttpFilter { | ||
orderedFilters := make(OrderedHTTPFilters, len(filters)) | ||
for i := 0; i < len(filters); i++ { | ||
orderedFilters[i] = newOrderedHTTPFilter(filters[i]) | ||
} | ||
sort.Sort(orderedFilters) | ||
|
||
for i := 0; i < len(filters); i++ { | ||
filters[i] = orderedFilters[i].filter | ||
} | ||
return filters | ||
} | ||
|
||
// patchHCMWithFilters builds and appends HTTP Filters to the HTTP connection | ||
// manager. | ||
func (t *Translator) patchHCMWithFilters(mgr *hcmv3.HttpConnectionManager, irListener *ir.HTTPListener) error { | ||
// The order of filter patching is not relevant here. | ||
// All the filters will be sorted in correct order after the patching is done. | ||
// TODO: Make this a generic interface for all API Gateway features. | ||
// https://github.com/envoyproxy/gateway/issues/882 | ||
t.patchHCMWithRateLimit(mgr, irListener) | ||
|
||
// Add the jwt authn filter, if needed. | ||
if err := patchHCMWithJwtAuthnFilter(mgr, irListener); err != nil { | ||
return err | ||
} | ||
|
||
// Add the cors filter, if needed | ||
if err := patchHCMWithCorsFilter(mgr, irListener); err != nil { | ||
return err | ||
} | ||
|
||
// Add the router filter | ||
mgr.HttpFilters = append(mgr.HttpFilters, xdsfilters.HTTPRouter) | ||
|
||
// Sort the filters in the correct order. | ||
mgr.HttpFilters = sortHTTPFilters(mgr.HttpFilters) | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
// Copyright Envoy Gateway Authors | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// The full text of the Apache license is available in the LICENSE file at | ||
// the root of the repo. | ||
|
||
package translator | ||
|
||
import ( | ||
"testing" | ||
|
||
hcmv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3" | ||
"github.com/envoyproxy/go-control-plane/pkg/wellknown" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func Test_sortHTTPFilters(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
filters []*hcmv3.HttpFilter | ||
want []*hcmv3.HttpFilter | ||
}{ | ||
{ | ||
name: "sort filters", | ||
filters: []*hcmv3.HttpFilter{ | ||
httpFilterForTest(wellknown.Router), | ||
httpFilterForTest(wellknown.CORS), | ||
httpFilterForTest(jwtAuthenFilter), | ||
httpFilterForTest(wellknown.HTTPRateLimit), | ||
}, | ||
want: []*hcmv3.HttpFilter{ | ||
httpFilterForTest(wellknown.CORS), | ||
httpFilterForTest(jwtAuthenFilter), | ||
httpFilterForTest(wellknown.HTTPRateLimit), | ||
httpFilterForTest(wellknown.Router), | ||
}, | ||
}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
assert.Equalf(t, tt.want, sortHTTPFilters(tt.filters), "sortHTTPFilters(%v)", tt.filters) | ||
}) | ||
} | ||
} | ||
|
||
func httpFilterForTest(name string) *hcmv3.HttpFilter { | ||
return &hcmv3.HttpFilter{ | ||
Name: name, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters