From 5613e48141002d52fc2d442db3f1720f8ce221f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20PERALTA?= Date: Wed, 27 Apr 2016 14:05:32 +0200 Subject: [PATCH] Append to X-Forwarded-Prefix in case it already exists Fixes gh-993 --- .../zuul/filters/pre/PreDecorationFilter.java | 13 ++++++++++- .../filters/pre/PreDecorationFilterTests.java | 22 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/PreDecorationFilter.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/PreDecorationFilter.java index d15178ca..866bb164 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/PreDecorationFilter.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/PreDecorationFilter.java @@ -114,7 +114,18 @@ public class PreDecorationFilter extends ZuulFilter { ctx.addZuulRequestHeader(ZuulHeaders.X_FORWARDED_PROTO, ctx.getRequest().getScheme()); if (StringUtils.hasText(route.getPrefix())) { - ctx.addZuulRequestHeader("X-Forwarded-Prefix", route.getPrefix()); + String existingPrefix = ctx.getRequest().getHeader("X-Forwarded-Prefix"); + StringBuilder newPrefixBuilder = new StringBuilder(); + if (StringUtils.hasLength(existingPrefix)) { + if (existingPrefix.endsWith("/") && route.getPrefix().startsWith("/")) { + newPrefixBuilder.append(existingPrefix, 0, existingPrefix.length() - 1); + } + else { + newPrefixBuilder.append(existingPrefix); + } + } + newPrefixBuilder.append(route.getPrefix()); + ctx.addZuulRequestHeader("X-Forwarded-Prefix", newPrefixBuilder.toString()); } String xforwardedfor = ctx.getRequest().getHeader("X-Forwarded-For"); String remoteAddr = ctx.getRequest().getRemoteAddr(); diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/pre/PreDecorationFilterTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/pre/PreDecorationFilterTests.java index cfea9d5d..13245117 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/pre/PreDecorationFilterTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/pre/PreDecorationFilterTests.java @@ -106,6 +106,28 @@ public class PreDecorationFilterTests { getHeader(ctx.getOriginResponseHeaders(), "x-zuul-serviceid")); } + @Test + public void prefixRouteWithPrefixHeaderConcatsHeader() throws Exception { + this.properties.setPrefix("/api"); + this.properties.setStripPrefix(true); + this.request.setRequestURI("/api/foo/1"); + this.request.setRemoteAddr("5.6.7.8"); + this.request.addHeader("X-Forwarded-For", "1.2.3.4"); + this.request.addHeader("X-Forwarded-Prefix", "/prefix"); + this.routeLocator.addRoute( + new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); + this.filter.run(); + RequestContext ctx = RequestContext.getCurrentContext(); + assertEquals("/foo/1", ctx.get("requestURI")); + assertEquals("localhost", ctx.getZuulRequestHeaders().get("x-forwarded-host")); + assertEquals("80", ctx.getZuulRequestHeaders().get("x-forwarded-port")); + assertEquals("http", ctx.getZuulRequestHeaders().get("x-forwarded-proto")); + assertEquals("/prefix/api", ctx.getZuulRequestHeaders().get("x-forwarded-prefix")); + assertEquals("1.2.3.4, 5.6.7.8", ctx.getZuulRequestHeaders().get("x-forwarded-for")); + assertEquals("foo", + getHeader(ctx.getOriginResponseHeaders(), "x-zuul-serviceid")); + } + @Test public void forwardRouteAddsLocation() throws Exception { this.properties.setPrefix("/api");