For lb: scheme, put associated filters last.
This makes sure the lb filter runs after path modifying filters like stripPrefix. See gh-3443
This commit is contained in:
@@ -43,6 +43,8 @@ spring:
|
||||
- Path=/api/**
|
||||
----
|
||||
|
||||
WARNING: If using the `lb()` filter, it needs to be after any filter that manipulates the path such as `setPath()` or `stripPrefix()`, otherwise the resulting url could be incorrect. The `lb:` scheme handler in configuration, automatically puts the filter in the highest precedence order.
|
||||
|
||||
NOTE: By default, when a service instance cannot be found by the `ReactorLoadBalancer`, a `503` is returned.
|
||||
// TODO: implement use404
|
||||
// You can configure the gateway to return a `404` by setting `spring.cloud.gateway.loadbalancer.use404=true`.
|
||||
|
||||
@@ -33,7 +33,7 @@ class RouteConfiguration {
|
||||
public RouterFunction<ServerResponse> gatewayRouterFunctionsPrefixPath() {
|
||||
return route("prefixpath_route")
|
||||
.GET("/**", http("https://example.org"))
|
||||
.before("/mypath")
|
||||
.before(prefixPath("/mypath"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -42,3 +42,4 @@ class RouteConfiguration {
|
||||
This prefixes `/mypath` to the path of all matching requests.
|
||||
So a request to `/hello` is sent to `/mypath/hello`.
|
||||
|
||||
WARNING: If using the `lb()` filter, it needs to be after the `prefixPath()` filter, otherwise the resulting url could be incorrect. The `lb:` scheme handler in configuration, automatically puts the filter in the highest precedence order.
|
||||
|
||||
@@ -43,3 +43,4 @@ class RouteConfiguration {
|
||||
|
||||
For a request path of `/red/blue`, this sets the path to `/blue` before making the downstream request. Note that in `application.yml` the `$` should be replaced with `$\` because of the YAML specification.
|
||||
|
||||
WARNING: If using the `lb()` filter, it needs to be after the `rewritePath()` filter, otherwise the resulting url could be incorrect. The `lb:` scheme handler in configuration, automatically puts the filter in the highest precedence order.
|
||||
@@ -45,3 +45,4 @@ class RouteConfiguration {
|
||||
|
||||
For a request path of `/red/blue`, this sets the path to `/blue` before making the downstream request.
|
||||
|
||||
WARNING: If using the `lb()` filter, it needs to be after the `setPath()` filter, otherwise the resulting url could be incorrect. The `lb:` scheme handler in configuration, automatically puts the filter in the highest precedence order.
|
||||
@@ -43,3 +43,4 @@ class RouteConfiguration {
|
||||
|
||||
When a request is made through the gateway to `/name/blue/red`, the request made to `nameservice` looks like `https://nameservice/red`.
|
||||
|
||||
WARNING: If using the `lb()` filter, it needs to be after the `stripPrefix()` filter, otherwise the resulting url could be incorrect. The `lb:` scheme handler in configuration, automatically puts the filter in the highest precedence order.
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.cloud.gateway.server.mvc.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
@@ -178,12 +179,15 @@ public class RouterFunctionHolderFactory {
|
||||
NormalizedOperationMethod normalizedOpMethod = handlerOperationMethod.get();
|
||||
Object response = invokeOperation(normalizedOpMethod, normalizedOpMethod.getNormalizedArgs());
|
||||
HandlerFunction<ServerResponse> handlerFunction = null;
|
||||
|
||||
// filters added by HandlerDiscoverer need to go last, so save them
|
||||
List<HandlerFilterFunction<ServerResponse, ServerResponse>> handlerFilterFunctionFilters = new ArrayList<>();
|
||||
if (response instanceof HandlerFunction<?>) {
|
||||
handlerFunction = (HandlerFunction<ServerResponse>) response;
|
||||
}
|
||||
else if (response instanceof HandlerDiscoverer.Result result) {
|
||||
handlerFunction = result.getHandlerFunction();
|
||||
result.getFilters().forEach(builder::filter);
|
||||
handlerFilterFunctionFilters.addAll(result.getFilters());
|
||||
}
|
||||
if (handlerFunction == null) {
|
||||
throw new IllegalStateException(
|
||||
@@ -221,6 +225,9 @@ public class RouterFunctionHolderFactory {
|
||||
translate(filterOperations, filterProperties.getName(), args, HandlerFilterFunction.class, builder::filter);
|
||||
});
|
||||
|
||||
// HandlerDiscoverer filters need higher priority, so put them last
|
||||
handlerFilterFunctionFilters.forEach(builder::filter);
|
||||
|
||||
builder.withAttribute(MvcUtils.GATEWAY_ROUTE_ID_ATTR, routeId);
|
||||
|
||||
return builder.build();
|
||||
|
||||
@@ -122,7 +122,7 @@ public class GatewayMvcPropertiesBeanDefinitionRegistrarTests {
|
||||
predicate.accept(new AbstractRequestPredicatesVisitor() {
|
||||
@Override
|
||||
public void path(String pattern) {
|
||||
assertThat(pattern).isEqualTo("/anything/listRoute3");
|
||||
assertThat(pattern).isEqualTo("/extra/anything/listRoute3");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -181,7 +181,7 @@ public class GatewayMvcPropertiesBeanDefinitionRegistrarTests {
|
||||
@SuppressWarnings("unchecked")
|
||||
public void lbRouteWorks() {
|
||||
restClient.get()
|
||||
.uri("/anything/listRoute3")
|
||||
.uri("/extra/anything/listRoute3")
|
||||
.header("MyHeaderName", "MyHeaderVal")
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
|
||||
@@ -38,9 +38,12 @@ spring.cloud.gateway.mvc:
|
||||
- id: listRoute3
|
||||
uri: lb://httpbin
|
||||
predicates:
|
||||
- Path=/anything/listRoute3
|
||||
- Path=/extra/anything/listRoute3
|
||||
- Header=MyHeaderName,MyHeader.*
|
||||
filters:
|
||||
- name: StripPrefix
|
||||
args:
|
||||
parts: 1
|
||||
- name: AddRequestHeader
|
||||
args:
|
||||
name: X-Test
|
||||
|
||||
Reference in New Issue
Block a user