You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@knox.apache.org by mo...@apache.org on 2019/05/18 12:57:20 UTC
[knox] branch master updated: KNOX-1858 - Add service name to
X-Forwarded-Context header (#90)
This is an automated email from the ASF dual-hosted git repository.
more pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/knox.git
The following commit(s) were added to refs/heads/master by this push:
new bdfbe08 KNOX-1858 - Add service name to X-Forwarded-Context header (#90)
bdfbe08 is described below
commit bdfbe08ca452b5659e62ca269bd83e33c6c6fd0d
Author: Sandeep Moré <mo...@apache.org>
AuthorDate: Sat May 18 08:57:16 2019 -0400
KNOX-1858 - Add service name to X-Forwarded-Context header (#90)
---
gateway-release/home/conf/gateway-site.xml | 5 +
.../gateway/filter/XForwardedHeaderFilter.java | 22 ++-
.../filter/XForwardedHeaderRequestWrapper.java | 45 +++++-
.../gateway/filter/XForwardHeaderFilterTest.java | 170 +++++++++++++++++++++
.../gateway/config/impl/GatewayConfigImpl.java | 21 +++
.../impl/ApplicationDeploymentContributor.java | 12 +-
.../ServiceDefinitionDeploymentContributor.java | 25 ++-
.../apache/knox/gateway/config/GatewayConfig.java | 11 ++
.../org/apache/knox/gateway/GatewayTestConfig.java | 13 ++
9 files changed, 318 insertions(+), 6 deletions(-)
diff --git a/gateway-release/home/conf/gateway-site.xml b/gateway-release/home/conf/gateway-site.xml
index 535b9d4..2b214da 100644
--- a/gateway-release/home/conf/gateway-site.xml
+++ b/gateway-release/home/conf/gateway-site.xml
@@ -139,5 +139,10 @@ limitations under the License.
<description>The whitelist to be applied for dispatches associated with the service roles specified by gateway.dispatch.whitelist.services.
If the value is DEFAULT, a domain-based whitelist will be derived from the Knox host.</description>
</property>
+ <property>
+ <name>gateway.xforwarded.header.context.append.servicename</name>
+ <value>LIVYSERVER</value>
+ <description>Add service name to x-forward-context header for the list of services defined above.</description>
+ </property>
</configuration>
diff --git a/gateway-server-xforwarded-filter/src/main/java/org/apache/knox/gateway/filter/XForwardedHeaderFilter.java b/gateway-server-xforwarded-filter/src/main/java/org/apache/knox/gateway/filter/XForwardedHeaderFilter.java
index cd6fda9..7b0bc1b 100644
--- a/gateway-server-xforwarded-filter/src/main/java/org/apache/knox/gateway/filter/XForwardedHeaderFilter.java
+++ b/gateway-server-xforwarded-filter/src/main/java/org/apache/knox/gateway/filter/XForwardedHeaderFilter.java
@@ -18,6 +18,7 @@
package org.apache.knox.gateway.filter;
import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -25,8 +26,27 @@ import java.io.IOException;
public class XForwardedHeaderFilter extends AbstractGatewayFilter {
+ private static final String APPEND_SERVICE_NAME_PARAM = "isAppendServiceName";
+ /**
+ * There could be a case where a service might use double context paths
+ * e.g. "/livy/v1" instead of "livy".
+ * This parameter can be used to add such context (/livy/v1) to the
+ * X-Forward-Context header.
+ */
+ private static final String SERVICE_CONTEXT = "serviceContext";
+
+ private boolean isAppendServiceName;
+ private String serviceContext;
+
+ @Override
+ public void init( FilterConfig filterConfig ) throws ServletException {
+ super.init( filterConfig );
+ isAppendServiceName = Boolean.parseBoolean(filterConfig.getInitParameter(APPEND_SERVICE_NAME_PARAM));
+ serviceContext = filterConfig.getInitParameter(SERVICE_CONTEXT);
+ }
+
@Override
protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
- chain.doFilter( new XForwardedHeaderRequestWrapper( request ), response );
+ chain.doFilter( new XForwardedHeaderRequestWrapper( request , isAppendServiceName, serviceContext), response );
}
}
diff --git a/gateway-server-xforwarded-filter/src/main/java/org/apache/knox/gateway/filter/XForwardedHeaderRequestWrapper.java b/gateway-server-xforwarded-filter/src/main/java/org/apache/knox/gateway/filter/XForwardedHeaderRequestWrapper.java
index ba8867d..2d32b5e 100644
--- a/gateway-server-xforwarded-filter/src/main/java/org/apache/knox/gateway/filter/XForwardedHeaderRequestWrapper.java
+++ b/gateway-server-xforwarded-filter/src/main/java/org/apache/knox/gateway/filter/XForwardedHeaderRequestWrapper.java
@@ -55,12 +55,21 @@ public class XForwardedHeaderRequestWrapper extends GatewayRequestWrapper {
public XForwardedHeaderRequestWrapper(HttpServletRequest request) {
super( request );
+ setHeaders(request, false, null);
+ }
+
+ public XForwardedHeaderRequestWrapper(HttpServletRequest request, final boolean isAppendServiceName, final String serviceContext) {
+ super( request );
+ setHeaders(request, isAppendServiceName, serviceContext);
+ }
+
+ private void setHeaders(final HttpServletRequest request, final boolean isAppendServiceName, final String serviceContext) {
setHeader( X_FORWARDED_FOR_LOWER, getForwardedFor( request ) );
setHeader( X_FORWARDED_PROTO_LOWER, getForwardedProto( request ) );
setHeader( X_FORWARDED_PORT_LOWER, getForwardedPort( request ) );
setHeader( X_FORWARDED_HOST_LOWER, getForwardedHost( request ) );
setHeader( X_FORWARDED_SERVER_LOWER, getForwardedServer( request ) );
- setHeader( X_FORWARDED_CONTEXT_LOWER, getForwardedContext( request ) );
+ setHeader( X_FORWARDED_CONTEXT_LOWER, getForwardedContext( request, isAppendServiceName, serviceContext) );
}
@Override
@@ -144,9 +153,39 @@ public class XForwardedHeaderRequestWrapper extends GatewayRequestWrapper {
return request.getServerName();
}
- private static String getForwardedContext( HttpServletRequest request ) {
+ private static String getForwardedContext( HttpServletRequest request, final boolean isAppendServiceName, final String serviceContext) {
String remote = request.getHeader( X_FORWARDED_CONTEXT );
- String local = request.getContextPath();
+ String local;
+ /* prefer parameter defined in topology over the gateway-site.xml property */
+ if(serviceContext != null && !serviceContext.isEmpty()) {
+ local = request.getContextPath() + "/" + serviceContext;
+ }
+ else if(isAppendServiceName) {
+ local = request.getContextPath() + "/" + extractServiceName(request.getContextPath(), request.getRequestURI());
+ } else {
+ local = request.getContextPath();
+ }
return ( remote == null ? "" : remote ) + ( local == null ? "" : local );
}
+
+ /**
+ * Given a URI path and context, this function extracts service name
+ *
+ * @param originalContext {gatewayName}/{topologyname}
+ * @param path request URI
+ * @return service name
+ * @since 1.3.0
+ */
+ private static String extractServiceName(final String originalContext,
+ final String path) {
+ final String[] sub = path.split(originalContext);
+ String serviceName = "";
+
+ if (sub.length > 1) {
+ final String[] paths = sub[1].split("/");
+ serviceName = paths[1];
+ }
+ return serviceName;
+ }
+
}
diff --git a/gateway-server-xforwarded-filter/src/test/java/org/apache/knox/gateway/filter/XForwardHeaderFilterTest.java b/gateway-server-xforwarded-filter/src/test/java/org/apache/knox/gateway/filter/XForwardHeaderFilterTest.java
index 8050a3b..5665139 100644
--- a/gateway-server-xforwarded-filter/src/test/java/org/apache/knox/gateway/filter/XForwardHeaderFilterTest.java
+++ b/gateway-server-xforwarded-filter/src/test/java/org/apache/knox/gateway/filter/XForwardHeaderFilterTest.java
@@ -76,6 +76,63 @@ public class XForwardHeaderFilterTest {
}
}
+ /**
+ * Dummy XForwardedHeaderFilter that is used to call
+ * XForwardedHeaderRequestWrapper letting it know
+ * to append service name.
+ * @since 1.3.0
+ */
+ public static class DummyXForwardedHeaderFilter extends XForwardedHeaderFilter {
+
+ boolean isAppendServiceName;
+ String serviceContext;
+
+ DummyXForwardedHeaderFilter(final boolean isAppendServiceName, final String serviceContext) {
+ super();
+ this.isAppendServiceName = isAppendServiceName;
+ this.serviceContext = serviceContext;
+ }
+
+ @Override
+ protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
+ chain.doFilter( new XForwardedHeaderRequestWrapper( request , this.isAppendServiceName, this.serviceContext), response );
+ }
+ }
+
+ /**
+ * Dummy class that tests for proper X-Forwarded-Context assertion.
+ * @since 1.3.0
+ */
+ public static class AssertProxiedXForwardedContextHeaders extends TestFilterAdapter {
+
+ boolean appendServiceName;
+ String serviceContext;
+
+ AssertProxiedXForwardedContextHeaders(boolean appendServiceName, String serviceContext) {
+ super();
+ this.appendServiceName = appendServiceName;
+ this.serviceContext = serviceContext;
+ }
+
+ @Override
+ public void doFilter( HttpServletRequest request, HttpServletResponse response, FilterChain chain ) throws IOException, ServletException {
+ assertThat( request.getHeader( "X-Forwarded-For" ), is( "127.0.0.0,127.0.0.1" ) );
+ assertThat( request.getHeader( "X-Forwarded-Proto" ), is( "https" ) );
+ assertThat( request.getHeader( "X-Forwarded-Port" ), is( "9999" ) );
+ assertThat( request.getHeader( "X-Forwarded-Host" ), is( "remotehost:9999" ) );
+ assertThat( request.getHeader( "X-Forwarded-Server" ), is( "localhost" ) );
+ if(serviceContext!=null) {
+ assertThat( request.getHeader( "X-Forwarded-Context" ), is( "/gateway/sandbox/"+serviceContext ) );
+ }
+ else if(appendServiceName) {
+ assertThat( request.getHeader( "X-Forwarded-Context" ), is( "/gateway/sandbox/webhdfs" ) );
+ } else {
+ assertThat( request.getHeader( "X-Forwarded-Context" ), is( "/gateway/sandbox" ) );
+ }
+
+ }
+ }
+
@Test
public void testProxiedXForwardHeaders() throws ServletException, IOException {
HttpServletRequest request = EasyMock.createNiceMock( HttpServletRequest.class );
@@ -105,4 +162,117 @@ public class XForwardHeaderFilterTest {
chain.push( filter );
chain.doFilter( request, response );
}
+
+ /**
+ * Test the case where service name is appended to X-Forwarded-Context
+ * along with request context.
+ * @throws ServletException
+ * @throws IOException
+ * @since 1.3.0
+ */
+ @Test
+ public void testProxiedXForwardContextHeaders() throws ServletException, IOException {
+ HttpServletRequest request = EasyMock.createNiceMock( HttpServletRequest.class );
+
+ EasyMock.expect( request.getHeader( "X-Forwarded-For" ) ).andReturn( "127.0.0.0" ).anyTimes();
+ EasyMock.expect( request.getHeader( "X-Forwarded-Proto" ) ).andReturn( "https" ).anyTimes();
+ EasyMock.expect( request.getHeader( "X-Forwarded-Port" ) ).andReturn( "9999" ).anyTimes();
+ EasyMock.expect( request.getHeader( "X-Forwarded-Host" ) ).andReturn( "remotehost:9999" ).anyTimes();
+ EasyMock.expect( request.getHeader( "X-Forwarded-Server" ) ).andReturn( "remotehost" ).anyTimes();
+
+ EasyMock.expect( request.getRemoteAddr() ).andReturn( "127.0.0.1" ).anyTimes();
+ EasyMock.expect( request.isSecure() ).andReturn( false ).anyTimes();
+ EasyMock.expect( request.getLocalPort() ).andReturn( 8888 ).anyTimes();
+ EasyMock.expect( request.getHeader( "Host" ) ).andReturn( "localhost:8888" ).anyTimes();
+ EasyMock.expect( request.getServerName() ).andReturn( "localhost" ).anyTimes();
+ EasyMock.expect( request.getContextPath() ).andReturn( "/gateway/sandbox" ).anyTimes();
+ EasyMock.expect( request.getRequestURI() ).andReturn( "/gateway/sandbox/webhdfs/key?value" ).anyTimes();
+
+ HttpServletResponse response = EasyMock.createNiceMock( HttpServletResponse.class );
+ EasyMock.replay( request, response );
+
+ TestFilterChain chain = new TestFilterChain();
+
+ XForwardedHeaderFilter filter = new DummyXForwardedHeaderFilter(true, null);
+
+ chain.push( new AssertProxiedXForwardedContextHeaders(true, null) );
+ chain.push( filter );
+ chain.doFilter( request, response );
+ }
+
+ /**
+ * Test the case where service name is appended to X-Forwarded-Context
+ * along with request context.
+ * @throws ServletException
+ * @throws IOException
+ * @since 1.3.0
+ */
+ @Test
+ public void testProxiedXForwardContextHeadersServiceParam() throws ServletException, IOException {
+ HttpServletRequest request = EasyMock.createNiceMock( HttpServletRequest.class );
+
+ EasyMock.expect( request.getHeader( "X-Forwarded-For" ) ).andReturn( "127.0.0.0" ).anyTimes();
+ EasyMock.expect( request.getHeader( "X-Forwarded-Proto" ) ).andReturn( "https" ).anyTimes();
+ EasyMock.expect( request.getHeader( "X-Forwarded-Port" ) ).andReturn( "9999" ).anyTimes();
+ EasyMock.expect( request.getHeader( "X-Forwarded-Host" ) ).andReturn( "remotehost:9999" ).anyTimes();
+ EasyMock.expect( request.getHeader( "X-Forwarded-Server" ) ).andReturn( "remotehost" ).anyTimes();
+
+ EasyMock.expect( request.getRemoteAddr() ).andReturn( "127.0.0.1" ).anyTimes();
+ EasyMock.expect( request.isSecure() ).andReturn( false ).anyTimes();
+ EasyMock.expect( request.getLocalPort() ).andReturn( 8888 ).anyTimes();
+ EasyMock.expect( request.getHeader( "Host" ) ).andReturn( "localhost:8888" ).anyTimes();
+ EasyMock.expect( request.getServerName() ).andReturn( "localhost" ).anyTimes();
+ EasyMock.expect( request.getContextPath() ).andReturn( "/gateway/sandbox" ).anyTimes();
+ EasyMock.expect( request.getRequestURI() ).andReturn( "/gateway/sandbox/livy/v1/key?value" ).anyTimes();
+
+ HttpServletResponse response = EasyMock.createNiceMock( HttpServletResponse.class );
+ EasyMock.replay( request, response );
+
+ TestFilterChain chain = new TestFilterChain();
+
+ XForwardedHeaderFilter filter = new DummyXForwardedHeaderFilter(true, "livy/v1");
+
+ chain.push( new AssertProxiedXForwardedContextHeaders(true, "livy/v1") );
+ chain.push( filter );
+ chain.doFilter( request, response );
+ }
+
+ /**
+ * Test the case where appending service name to X-Forwarded-Context is
+ * disabled
+ *
+ * @throws ServletException
+ * @throws IOException
+ * @since 1.3.0
+ */
+ @Test
+ public void testProxiedXForwardContextHeadersNegativeTest() throws ServletException, IOException {
+ HttpServletRequest request = EasyMock.createNiceMock( HttpServletRequest.class );
+
+ EasyMock.expect( request.getHeader( "X-Forwarded-For" ) ).andReturn( "127.0.0.0" ).anyTimes();
+ EasyMock.expect( request.getHeader( "X-Forwarded-Proto" ) ).andReturn( "https" ).anyTimes();
+ EasyMock.expect( request.getHeader( "X-Forwarded-Port" ) ).andReturn( "9999" ).anyTimes();
+ EasyMock.expect( request.getHeader( "X-Forwarded-Host" ) ).andReturn( "remotehost:9999" ).anyTimes();
+ EasyMock.expect( request.getHeader( "X-Forwarded-Server" ) ).andReturn( "remotehost" ).anyTimes();
+
+ EasyMock.expect( request.getRemoteAddr() ).andReturn( "127.0.0.1" ).anyTimes();
+ EasyMock.expect( request.isSecure() ).andReturn( false ).anyTimes();
+ EasyMock.expect( request.getLocalPort() ).andReturn( 8888 ).anyTimes();
+ EasyMock.expect( request.getHeader( "Host" ) ).andReturn( "localhost:8888" ).anyTimes();
+ EasyMock.expect( request.getServerName() ).andReturn( "localhost" ).anyTimes();
+ EasyMock.expect( request.getContextPath() ).andReturn( "/gateway/sandbox" ).anyTimes();
+ EasyMock.expect( request.getRequestURI() ).andReturn( "/gateway/sandbox/webhdfs/key?value" ).anyTimes();
+
+ HttpServletResponse response = EasyMock.createNiceMock( HttpServletResponse.class );
+ EasyMock.replay( request, response );
+
+ TestFilterChain chain = new TestFilterChain();
+
+ XForwardedHeaderFilter filter = new DummyXForwardedHeaderFilter(false, null);
+
+ chain.push( new AssertProxiedXForwardedContextHeaders(false, null) );
+ chain.push( filter );
+ chain.doFilter( request, response );
+ }
+
}
diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java b/gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java
index df7503b..e7e9124 100644
--- a/gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java
@@ -230,6 +230,9 @@ public class GatewayConfigImpl extends Configuration implements GatewayConfig {
"NAMENODE", "JOBTRACKER", "WEBHDFS", "WEBHCAT",
"OOZIE", "WEBHBASE", "HIVE", "RESOURCEMANAGER");
+ /* property that specifies list of services for which we need to append service name to the X-Forward-Context header */
+ public static final String X_FORWARD_CONTEXT_HEADER_APPEND_SERVICES = GATEWAY_CONFIG_FILE_PREFIX + ".xforwarded.header.context.append.servicename";
+
public GatewayConfigImpl() {
init();
}
@@ -1051,4 +1054,22 @@ public class GatewayConfigImpl extends Configuration implements GatewayConfig {
final String result = get(STRICT_TOPOLOGY_VALIDATION, Boolean.toString(DEFAULT_STRICT_TOPOLOGY_VALIDATION));
return Boolean.parseBoolean(result);
}
+
+ /**
+ * Returns a list of services that need service name appended to
+ * X-Forward-Context header as a result of which the new header would look
+ * /{gateway}/{sandbox}/{serviceName}
+ *
+ * @return
+ * @since 1.3.0
+ */
+ @Override
+ public List<String> getXForwardContextAppendServices() {
+ String value = get( X_FORWARD_CONTEXT_HEADER_APPEND_SERVICES );
+ if ( value != null && !value.isEmpty() && !"none".equalsIgnoreCase(value.trim()) ) {
+ return Arrays.asList( value.trim().split("\\s*,\\s*") );
+ } else {
+ return new ArrayList<>();
+ }
+ }
}
diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/deploy/impl/ApplicationDeploymentContributor.java b/gateway-server/src/main/java/org/apache/knox/gateway/deploy/impl/ApplicationDeploymentContributor.java
index f8e3114..8ea6787 100644
--- a/gateway-server/src/main/java/org/apache/knox/gateway/deploy/impl/ApplicationDeploymentContributor.java
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/deploy/impl/ApplicationDeploymentContributor.java
@@ -64,6 +64,7 @@ public class ApplicationDeploymentContributor extends ServiceDeploymentContribut
private static final String XFORWARDED_FILTER_ROLE = "xforwardedheaders";
private static final String COOKIE_SCOPING_FILTER_NAME = "CookieScopeServletFilter";
private static final String COOKIE_SCOPING_FILTER_ROLE = "cookiescopef";
+ private static final String APPEND_SERVICE_NAME_PARAM = "isAppendServiceName";
private ServiceDefinition serviceDefinition;
@@ -185,7 +186,16 @@ public class ApplicationDeploymentContributor extends ServiceDeploymentContribut
resource.pattern(binding.getPath());
//add x-forwarded filter if enabled in config
if (context.getGatewayConfig().isXForwardedEnabled()) {
- resource.addFilter().name(XFORWARDED_FILTER_NAME).role(XFORWARDED_FILTER_ROLE).impl(XForwardedHeaderFilter.class);
+ final FilterDescriptor filter = resource.addFilter()
+ .name(XFORWARDED_FILTER_NAME).role(XFORWARDED_FILTER_ROLE)
+ .impl(XForwardedHeaderFilter.class);
+ /* check if we need to add service name to the context */
+ if (context.getGatewayConfig().getXForwardContextAppendServices() != null
+ && !context.getGatewayConfig().getXForwardContextAppendServices()
+ .isEmpty() && context.getGatewayConfig()
+ .getXForwardContextAppendServices().contains(service.getRole())) {
+ filter.param().name(APPEND_SERVICE_NAME_PARAM).value("true");
+ }
}
if (context.getGatewayConfig().isCookieScopingToPathEnabled()) {
FilterDescriptor filter = resource.addFilter().name(COOKIE_SCOPING_FILTER_NAME).role(COOKIE_SCOPING_FILTER_ROLE).impl(CookieScopeServletFilter.class);
diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/deploy/impl/ServiceDefinitionDeploymentContributor.java b/gateway-server/src/main/java/org/apache/knox/gateway/deploy/impl/ServiceDefinitionDeploymentContributor.java
index b192ee0..202fe1d 100644
--- a/gateway-server/src/main/java/org/apache/knox/gateway/deploy/impl/ServiceDefinitionDeploymentContributor.java
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/deploy/impl/ServiceDefinitionDeploymentContributor.java
@@ -64,6 +64,16 @@ public class ServiceDefinitionDeploymentContributor extends ServiceDeploymentCon
private static final String COOKIE_SCOPING_FILTER_ROLE = "cookiescopef";
+ private static final String APPEND_SERVICE_NAME_PARAM = "isAppendServiceName";
+
+ /**
+ * There could be a case where a service might use double context paths
+ * e.g. "/livy/v1" instead of "livy".
+ * This parameter can be used to add such context (/livy/v1) to the
+ * X-Forward-Context header.
+ */
+ private static final String SERVICE_CONTEXT = "serviceContext";
+
private ServiceDefinition serviceDefinition;
private UrlRewriteRulesDescriptor serviceRules;
@@ -128,7 +138,20 @@ public class ServiceDefinitionDeploymentContributor extends ServiceDeploymentCon
resource.pattern(binding.getPath());
//add x-forwarded filter if enabled in config
if (context.getGatewayConfig().isXForwardedEnabled()) {
- resource.addFilter().name(XFORWARDED_FILTER_NAME).role(XFORWARDED_FILTER_ROLE).impl(XForwardedHeaderFilter.class);
+ final FilterDescriptor filter = resource.addFilter()
+ .name(XFORWARDED_FILTER_NAME).role(XFORWARDED_FILTER_ROLE)
+ .impl(XForwardedHeaderFilter.class);
+ /* check if we need to add service name to the context */
+ if(service.getParams().containsKey(SERVICE_CONTEXT)) {
+ filter.param().name(APPEND_SERVICE_NAME_PARAM).value("true");
+ filter.param().name(SERVICE_CONTEXT).value(service.getParams().get(SERVICE_CONTEXT));
+ }
+ else if (context.getGatewayConfig().getXForwardContextAppendServices() != null
+ && !context.getGatewayConfig().getXForwardContextAppendServices()
+ .isEmpty() && context.getGatewayConfig()
+ .getXForwardContextAppendServices().contains(service.getRole())) {
+ filter.param().name(APPEND_SERVICE_NAME_PARAM).value("true");
+ }
}
if (context.getGatewayConfig().isCookieScopingToPathEnabled()) {
FilterDescriptor filter = resource.addFilter().name(COOKIE_SCOPING_FILTER_NAME).role(COOKIE_SCOPING_FILTER_ROLE).impl(CookieScopeServletFilter.class);
diff --git a/gateway-spi/src/main/java/org/apache/knox/gateway/config/GatewayConfig.java b/gateway-spi/src/main/java/org/apache/knox/gateway/config/GatewayConfig.java
index f9d32ce..5de18b6 100644
--- a/gateway-spi/src/main/java/org/apache/knox/gateway/config/GatewayConfig.java
+++ b/gateway-spi/src/main/java/org/apache/knox/gateway/config/GatewayConfig.java
@@ -606,5 +606,16 @@ public interface GatewayConfig {
*/
boolean isTopologyValidationEnabled();
+ /**
+ * Returns a list of services that need service name appended to
+ * X-Forward-Context header as a result of which the new header would look
+ * /{gateway}/{sandbox}/{serviceName}
+ *
+ * @return List of service names for which service name needs to be appended
+ * to X-Forward-Context header, can be empty list.
+ * @since 1.3.0
+ */
+ List<String> getXForwardContextAppendServices();
+
}
diff --git a/gateway-test-release-utils/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java b/gateway-test-release-utils/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java
index 4572047..951d173 100644
--- a/gateway-test-release-utils/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java
+++ b/gateway-test-release-utils/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java
@@ -746,4 +746,17 @@ public class GatewayTestConfig extends Configuration implements GatewayConfig {
public boolean isTopologyValidationEnabled() {
return false;
}
+
+ /**
+ * Returns a list of services that need service name appended to
+ * X-Forward-Context header as a result of which the new header would look
+ * /{gateway}/{sandbox}/{serviceName}
+ *
+ * @return
+ * @since 1.3.0
+ */
+ @Override
+ public List<String> getXForwardContextAppendServices() {
+ return null;
+ }
}