Skip to content

Commit 5cf94a4

Browse files
committed
For lb: scheme, put associated filters last.
This makes sure the lb filter runs after path modifying filters like stripPrefix. See gh-3443
1 parent 5cc6323 commit 5cf94a4

File tree

8 files changed

+21
-5
lines changed

8 files changed

+21
-5
lines changed

docs/modules/ROOT/pages/spring-cloud-gateway-server-mvc/filters/loadbalancer.adoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ spring:
4343
- Path=/api/**
4444
----
4545

46+
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.
47+
4648
NOTE: By default, when a service instance cannot be found by the `ReactorLoadBalancer`, a `503` is returned.
4749
// TODO: implement use404
4850
// You can configure the gateway to return a `404` by setting `spring.cloud.gateway.loadbalancer.use404=true`.

docs/modules/ROOT/pages/spring-cloud-gateway-server-mvc/filters/prefixpath.adoc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class RouteConfiguration {
3333
public RouterFunction<ServerResponse> gatewayRouterFunctionsPrefixPath() {
3434
return route("prefixpath_route")
3535
.GET("/**", http("https://example.org"))
36-
.before("/mypath")
36+
.before(prefixPath("/mypath"))
3737
.build();
3838
}
3939
}
@@ -42,3 +42,4 @@ class RouteConfiguration {
4242
This prefixes `/mypath` to the path of all matching requests.
4343
So a request to `/hello` is sent to `/mypath/hello`.
4444

45+
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.

docs/modules/ROOT/pages/spring-cloud-gateway-server-mvc/filters/rewritepath.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,4 @@ class RouteConfiguration {
4343

4444
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.
4545

46+
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.

docs/modules/ROOT/pages/spring-cloud-gateway-server-mvc/filters/setpath.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,4 @@ class RouteConfiguration {
4545

4646
For a request path of `/red/blue`, this sets the path to `/blue` before making the downstream request.
4747

48+
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.

docs/modules/ROOT/pages/spring-cloud-gateway-server-mvc/filters/stripprefix.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,4 @@ class RouteConfiguration {
4343

4444
When a request is made through the gateway to `/name/blue/red`, the request made to `nameservice` looks like `https://nameservice/red`.
4545

46+
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.

spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/config/RouterFunctionHolderFactory.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.cloud.gateway.server.mvc.config;
1818

19+
import java.util.ArrayList;
1920
import java.util.Arrays;
2021
import java.util.Collections;
2122
import java.util.Comparator;
@@ -178,12 +179,15 @@ private RouterFunction getRouterFunction(RouteProperties routeProperties, String
178179
NormalizedOperationMethod normalizedOpMethod = handlerOperationMethod.get();
179180
Object response = invokeOperation(normalizedOpMethod, normalizedOpMethod.getNormalizedArgs());
180181
HandlerFunction<ServerResponse> handlerFunction = null;
182+
183+
// filters added by HandlerDiscoverer need to go last, so save them
184+
List<HandlerFilterFunction<ServerResponse, ServerResponse>> handlerFilterFunctionFilters = new ArrayList<>();
181185
if (response instanceof HandlerFunction<?>) {
182186
handlerFunction = (HandlerFunction<ServerResponse>) response;
183187
}
184188
else if (response instanceof HandlerDiscoverer.Result result) {
185189
handlerFunction = result.getHandlerFunction();
186-
result.getFilters().forEach(builder::filter);
190+
handlerFilterFunctionFilters.addAll(result.getFilters());
187191
}
188192
if (handlerFunction == null) {
189193
throw new IllegalStateException(
@@ -221,6 +225,9 @@ else if (response instanceof HandlerDiscoverer.Result result) {
221225
translate(filterOperations, filterProperties.getName(), args, HandlerFilterFunction.class, builder::filter);
222226
});
223227

228+
// HandlerDiscoverer filters need higher priority, so put them last
229+
handlerFilterFunctionFilters.forEach(builder::filter);
230+
224231
builder.withAttribute(MvcUtils.GATEWAY_ROUTE_ID_ATTR, routeId);
225232

226233
return builder.build();

spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/config/GatewayMvcPropertiesBeanDefinitionRegistrarTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ public void route(RequestPredicate predicate, HandlerFunction<?> handlerFunction
122122
predicate.accept(new AbstractRequestPredicatesVisitor() {
123123
@Override
124124
public void path(String pattern) {
125-
assertThat(pattern).isEqualTo("/anything/listRoute3");
125+
assertThat(pattern).isEqualTo("/extra/anything/listRoute3");
126126
}
127127

128128
@Override
@@ -181,7 +181,7 @@ public void configuredRouteWorks() {
181181
@SuppressWarnings("unchecked")
182182
public void lbRouteWorks() {
183183
restClient.get()
184-
.uri("/anything/listRoute3")
184+
.uri("/extra/anything/listRoute3")
185185
.header("MyHeaderName", "MyHeaderVal")
186186
.exchange()
187187
.expectStatus()

spring-cloud-gateway-server-mvc/src/test/resources/application-propertiesbeandefinitionregistrartests.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,12 @@ spring.cloud.gateway.mvc:
3838
- id: listRoute3
3939
uri: lb://httpbin
4040
predicates:
41-
- Path=/anything/listRoute3
41+
- Path=/extra/anything/listRoute3
4242
- Header=MyHeaderName,MyHeader.*
4343
filters:
44+
- name: StripPrefix
45+
args:
46+
parts: 1
4447
- name: AddRequestHeader
4548
args:
4649
name: X-Test

0 commit comments

Comments
 (0)