diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/headers/XForwardedHeadersFilter.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/headers/XForwardedHeadersFilter.java index 789ba171..a5ec3a5e 100644 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/headers/XForwardedHeadersFilter.java +++ b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/headers/XForwardedHeadersFilter.java @@ -242,11 +242,12 @@ public class XForwardedHeadersFilter implements HttpHeadersFilter, Ordered { if(requestUriPath!=null && (originalUriPath.endsWith(requestUriPath))) { prefix = originalUriPath.replace(requestUriPath, ""); + if (prefix != null && prefix.length() > 0 && + prefix.length() <= originalUri.getPath().length()) { + write(updated, X_FORWARDED_PREFIX_HEADER, prefix, isPrefixAppend()); + } } - if (prefix != null && prefix.length() > 0 && - prefix.length() < originalUri.getPath().length()) { - write(updated, X_FORWARDED_PREFIX_HEADER, prefix, isPrefixAppend()); - } + } }); } diff --git a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/headers/XForwardedHeadersFilterTests.java b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/headers/XForwardedHeadersFilterTests.java index 31bade18..4049fe7c 100644 --- a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/headers/XForwardedHeadersFilterTests.java +++ b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/headers/XForwardedHeadersFilterTests.java @@ -20,6 +20,7 @@ package org.springframework.cloud.gateway.filter.headers; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.URI; +import java.net.UnknownHostException; import java.util.LinkedHashSet; import org.junit.Test; @@ -186,6 +187,29 @@ public class XForwardedHeadersFilterTests { assertThat(headers.getFirst(X_FORWARDED_PREFIX_HEADER)).isEqualTo("/prefix"); } + @Test + public void prefixAddedWithoutTrailingSlash() throws Exception { + MockServerHttpRequest request = MockServerHttpRequest + .get("http://originalhost:8080/foo/bar") + .remoteAddress(new InetSocketAddress(InetAddress.getByName("10.0.0.1"), 80)) + .build(); + + XForwardedHeadersFilter filter = new XForwardedHeadersFilter(); + filter.setPrefixAppend(true); + filter.setPrefixEnabled(true); + + ServerWebExchange exchange = MockServerWebExchange.from(request); + LinkedHashSet originalUris = new LinkedHashSet<>(); + originalUris.add(UriComponentsBuilder.fromUriString("http://originalhost:8080/foo/bar").build().toUri()); + exchange.getAttributes().put(GATEWAY_ORIGINAL_REQUEST_URL_ATTR, originalUris); + URI requestUri = UriComponentsBuilder.fromUriString("http://routedservice:8090/").build().toUri(); + exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, requestUri); + + HttpHeaders headers = filter.filter(request.getHeaders(), exchange); + + assertThat(headers.getFirst(X_FORWARDED_PREFIX_HEADER)).isEqualTo("/foo/bar"); + } + @Test public void noPrefixToInfer() throws Exception { MockServerHttpRequest request = MockServerHttpRequest