Fix HTTPRoute Redirect Filter with port and scheme
Co-authored-by: Kevin Pollet <pollet.kevin@gmail.com>
This commit is contained in:
parent
7eac92f49c
commit
28d40e7f3c
13 changed files with 431 additions and 93 deletions
|
@ -39,13 +39,7 @@ spec:
|
|||
hostnames:
|
||||
- "example.org"
|
||||
rules:
|
||||
- backendRefs:
|
||||
- name: whoami
|
||||
port: 80
|
||||
weight: 1
|
||||
kind: Service
|
||||
group: ""
|
||||
filters:
|
||||
- filters:
|
||||
- type: RequestRedirect
|
||||
requestRedirect:
|
||||
scheme: https
|
||||
|
|
|
@ -39,13 +39,7 @@ spec:
|
|||
hostnames:
|
||||
- "example.org"
|
||||
rules:
|
||||
- backendRefs:
|
||||
- name: whoami
|
||||
port: 80
|
||||
weight: 1
|
||||
kind: Service
|
||||
group: ""
|
||||
filters:
|
||||
- filters:
|
||||
- type: RequestRedirect
|
||||
requestRedirect:
|
||||
hostname: example.com
|
||||
|
|
|
@ -135,7 +135,7 @@ func (p *Provider) loadHTTPRoute(ctx context.Context, client Client, listener ga
|
|||
var wrr dynamic.WeightedRoundRobin
|
||||
wrrName := provider.Normalize(routerKey + "-wrr")
|
||||
|
||||
middlewares, err := p.loadMiddlewares(listener.Protocol, route.Namespace, routerKey, routeRule.Filters)
|
||||
middlewares, err := p.loadMiddlewares(route.Namespace, routerKey, routeRule.Filters)
|
||||
if err != nil {
|
||||
log.Ctx(ctx).Error().
|
||||
Err(err).
|
||||
|
@ -294,14 +294,14 @@ func (p *Provider) loadHTTPBackendRef(namespace string, backendRef gatev1.HTTPBa
|
|||
return backendFunc(string(backendRef.Name), namespace)
|
||||
}
|
||||
|
||||
func (p *Provider) loadMiddlewares(listenerProtocol gatev1.ProtocolType, namespace, prefix string, filters []gatev1.HTTPRouteFilter) (map[string]*dynamic.Middleware, error) {
|
||||
func (p *Provider) loadMiddlewares(namespace, prefix string, filters []gatev1.HTTPRouteFilter) (map[string]*dynamic.Middleware, error) {
|
||||
middlewares := make(map[string]*dynamic.Middleware)
|
||||
|
||||
for i, filter := range filters {
|
||||
switch filter.Type {
|
||||
case gatev1.HTTPRouteFilterRequestRedirect:
|
||||
middlewareName := provider.Normalize(fmt.Sprintf("%s-%s-%d", prefix, strings.ToLower(string(filter.Type)), i))
|
||||
middlewares[middlewareName] = createRedirectRegexMiddleware(listenerProtocol, filter.RequestRedirect)
|
||||
middlewares[middlewareName] = createRedirectMiddleware(filter.RequestRedirect)
|
||||
|
||||
case gatev1.HTTPRouteFilterRequestHeaderModifier:
|
||||
middlewareName := provider.Normalize(fmt.Sprintf("%s-%s-%d", prefix, strings.ToLower(string(filter.Type)), i))
|
||||
|
@ -573,25 +573,27 @@ func createRequestHeaderModifier(filter *gatev1.HTTPHeaderFilter) *dynamic.Middl
|
|||
}
|
||||
}
|
||||
|
||||
func createRedirectRegexMiddleware(listenerProtocol gatev1.ProtocolType, filter *gatev1.HTTPRequestRedirectFilter) *dynamic.Middleware {
|
||||
// The spec allows for an empty string in which case we should use the
|
||||
// scheme of the request which in this case is the listener scheme.
|
||||
filterScheme := ptr.Deref(filter.Scheme, strings.ToLower(string(listenerProtocol)))
|
||||
statusCode := ptr.Deref(filter.StatusCode, http.StatusFound)
|
||||
func createRedirectMiddleware(filter *gatev1.HTTPRequestRedirectFilter) *dynamic.Middleware {
|
||||
filterScheme := ptr.Deref(filter.Scheme, "${scheme}")
|
||||
|
||||
port := "${port}"
|
||||
if filterScheme == "http" || filterScheme == "https" {
|
||||
port = ""
|
||||
}
|
||||
if filter.Port != nil {
|
||||
port = fmt.Sprintf(":%d", *filter.Port)
|
||||
}
|
||||
|
||||
statusCode := ptr.Deref(filter.StatusCode, http.StatusFound)
|
||||
|
||||
hostname := "${hostname}"
|
||||
if filter.Hostname != nil && *filter.Hostname != "" {
|
||||
hostname = string(*filter.Hostname)
|
||||
}
|
||||
|
||||
return &dynamic.Middleware{
|
||||
RedirectRegex: &dynamic.RedirectRegex{
|
||||
Regex: `^[a-z]+:\/\/(?P<userInfo>.+@)?(?P<hostname>\[[\w:\.]+\]|[\w\._-]+)(?P<port>:\d+)?\/(?P<path>.*)`,
|
||||
RequestRedirect: &dynamic.RequestRedirect{
|
||||
Regex: `^(?P<scheme>[a-z]+):\/\/(?P<userinfo>.+@)?(?P<hostname>\[[\w:\.]+\]|[\w\._-]+)(?P<port>:\d+)?\/(?P<path>.*)`,
|
||||
Replacement: fmt.Sprintf("%s://${userinfo}%s%s/${path}", filterScheme, hostname, port),
|
||||
Permanent: statusCode == http.StatusMovedPermanently,
|
||||
},
|
||||
|
|
|
@ -1669,39 +1669,16 @@ func TestLoadHTTPRoutes(t *testing.T) {
|
|||
},
|
||||
Middlewares: map[string]*dynamic.Middleware{
|
||||
"default-http-app-1-my-gateway-web-fa136e10345bd0e7248d-requestredirect-0": {
|
||||
RedirectRegex: &dynamic.RedirectRegex{
|
||||
Regex: "^[a-z]+:\\/\\/(?P<userInfo>.+@)?(?P<hostname>\\[[\\w:\\.]+\\]|[\\w\\._-]+)(?P<port>:\\d+)?\\/(?P<path>.*)",
|
||||
Replacement: "https://${userinfo}${hostname}${port}/${path}",
|
||||
RequestRedirect: &dynamic.RequestRedirect{
|
||||
Regex: "^(?P<scheme>[a-z]+):\\/\\/(?P<userinfo>.+@)?(?P<hostname>\\[[\\w:\\.]+\\]|[\\w\\._-]+)(?P<port>:\\d+)?\\/(?P<path>.*)",
|
||||
Replacement: "https://${userinfo}${hostname}/${path}",
|
||||
Permanent: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-http-app-1-my-gateway-web-fa136e10345bd0e7248d-wrr": {
|
||||
Weighted: &dynamic.WeightedRoundRobin{
|
||||
Services: []dynamic.WRRService{
|
||||
{
|
||||
Name: "default-whoami-80",
|
||||
Weight: ptr.To(1),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"default-whoami-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
},
|
||||
{
|
||||
URL: "http://10.10.0.2:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: ptr.To(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
},
|
||||
Weighted: &dynamic.WeightedRoundRobin{},
|
||||
},
|
||||
},
|
||||
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||
|
@ -1739,38 +1716,15 @@ func TestLoadHTTPRoutes(t *testing.T) {
|
|||
},
|
||||
Middlewares: map[string]*dynamic.Middleware{
|
||||
"default-http-app-1-my-gateway-web-fa136e10345bd0e7248d-requestredirect-0": {
|
||||
RedirectRegex: &dynamic.RedirectRegex{
|
||||
Regex: "^[a-z]+:\\/\\/(?P<userInfo>.+@)?(?P<hostname>\\[[\\w:\\.]+\\]|[\\w\\._-]+)(?P<port>:\\d+)?\\/(?P<path>.*)",
|
||||
Replacement: "http://${userinfo}example.com:443/${path}",
|
||||
RequestRedirect: &dynamic.RequestRedirect{
|
||||
Regex: "^(?P<scheme>[a-z]+):\\/\\/(?P<userinfo>.+@)?(?P<hostname>\\[[\\w:\\.]+\\]|[\\w\\._-]+)(?P<port>:\\d+)?\\/(?P<path>.*)",
|
||||
Replacement: "${scheme}://${userinfo}example.com:443/${path}",
|
||||
},
|
||||
},
|
||||
},
|
||||
Services: map[string]*dynamic.Service{
|
||||
"default-http-app-1-my-gateway-web-fa136e10345bd0e7248d-wrr": {
|
||||
Weighted: &dynamic.WeightedRoundRobin{
|
||||
Services: []dynamic.WRRService{
|
||||
{
|
||||
Name: "default-whoami-80",
|
||||
Weight: ptr.To(1),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"default-whoami-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:80",
|
||||
},
|
||||
{
|
||||
URL: "http://10.10.0.2:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: ptr.To(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
},
|
||||
Weighted: &dynamic.WeightedRoundRobin{},
|
||||
},
|
||||
},
|
||||
ServersTransports: map[string]*dynamic.ServersTransport{},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue