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 2017/09/01 13:17:15 UTC
[17/64] [partial] knox git commit: KNOX-998 - Refactoring save 1
http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/api/UrlRewriteRulesDescriptorFactoryTest.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/api/UrlRewriteRulesDescriptorFactoryTest.java b/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/api/UrlRewriteRulesDescriptorFactoryTest.java
new file mode 100644
index 0000000..f1d9687
--- /dev/null
+++ b/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/api/UrlRewriteRulesDescriptorFactoryTest.java
@@ -0,0 +1,253 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.filter.rewrite.api;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.hamcrest.Matchers;
+import org.junit.Test;
+import org.xmlmatchers.transform.XmlConverters;
+
+import javax.xml.transform.Source;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.StringWriter;
+import java.net.URL;
+import java.util.List;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.CoreMatchers.sameInstance;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+import static org.xmlmatchers.XmlMatchers.hasXPath;
+
+public class UrlRewriteRulesDescriptorFactoryTest {
+
+ @Test
+ public void testCreate() throws Exception {
+ UrlRewriteRulesDescriptor descriptor = UrlRewriteRulesDescriptorFactory.create();
+ assertThat( descriptor, notNullValue() );
+ assertThat( descriptor.getRules(), notNullValue() );
+ assertThat( descriptor.getRules().isEmpty(), is( true ) );
+
+ UrlRewriteRuleDescriptor rule = descriptor.newRule();
+ assertThat( rule, notNullValue() );
+ assertThat( descriptor.getRules().isEmpty(), is( true ) );
+ rule.name( "first" );
+ descriptor.addRule( rule );
+ assertThat( descriptor.getRules().size(), is( 1 ) );
+ assertThat( descriptor.getRule( "first" ), sameInstance( rule ) );
+
+ rule = descriptor.addRule( "second" );
+ assertThat( descriptor.getRules().size(), is( 2 ) );
+ }
+
+ private static URL getTestResourceUrl( String name ) throws FileNotFoundException {
+ name = UrlRewriteRulesDescriptorFactoryTest.class.getName().replaceAll( "\\.", "/" ) + "/" + name;
+ URL url = ClassLoader.getSystemResource( name );
+ if( url == null ) {
+ throw new FileNotFoundException( name );
+ }
+ return url;
+ }
+
+ private static InputStream getTestResourceStream( String name ) throws IOException {
+ URL url = getTestResourceUrl( name );
+ InputStream stream = url.openStream();
+ return stream;
+ }
+
+ private static Reader getTestResourceReader( String name, String charset ) throws IOException {
+ return new InputStreamReader( getTestResourceStream( name ), charset );
+ }
+
+ @Test
+ public void testLoadMissingFile() throws IOException {
+ try {
+ UrlRewriteRulesDescriptorFactory.load( "xml", getTestResourceReader( "missing.xml", "UTF-8" ) );
+ fail( "Should have thrown a FileNotFoundException." );
+ } catch ( FileNotFoundException e ) {
+ assertThat( e.getMessage(), containsString( "missing.xml" ) );
+ }
+ }
+
+ @Test
+ public void testLoadEmptyFile() throws IOException {
+ Logger logger = org.apache.log4j.LogManager.getLogger( "org.apache.commons.digester3.Digester" );
+ Level level = logger.getLevel();
+ try {
+ logger.setLevel( org.apache.log4j.Level.OFF );
+ UrlRewriteRulesDescriptorFactory.load( "xml", getTestResourceReader( "empty.xml", "UTF-8" ) );
+ fail( "Should have thrown an IOException." );
+ } catch ( IOException e ) {
+ // Expected.
+ } catch ( Throwable t ) {
+ fail( "Should have thrown an IOException." );
+ } finally {
+ logger.setLevel( level );
+ }
+ }
+
+ @Test
+ public void testLoadInvalidFile() throws IOException {
+ Logger logger = org.apache.log4j.LogManager.getLogger( "org.apache.commons.digester3.Digester" );
+ Level level = logger.getLevel();
+ try {
+ logger.setLevel( org.apache.log4j.Level.OFF );
+ UrlRewriteRulesDescriptorFactory.load( "xml", getTestResourceReader( "invalid.xml", "UTF-8" ) );
+ fail( "Should have thrown an IOException." );
+ } catch ( IOException e ) {
+ // Expected.
+ } catch ( Throwable t ) {
+ fail( "Should have thrown an IOException." );
+ } finally {
+ logger.setLevel( level );
+ }
+ }
+
+ @Test
+ public void testLoadNoopFile() throws IOException {
+ UrlRewriteRulesDescriptor config =
+ UrlRewriteRulesDescriptorFactory.load( "xml", getTestResourceReader( "noop.xml", "UTF-8" ) );
+ assertThat( "Rules should be an empty list.", config.getRules().isEmpty(), Matchers.is( true ) );
+ }
+
+ @Test
+ public void testLoadSimpleFile() throws IOException {
+ UrlRewriteRulesDescriptor config =
+ UrlRewriteRulesDescriptorFactory.load( "xml", getTestResourceReader( "simple.xml", "UTF-8" ) );
+ assertThat( "Failed to load simple config file.", config, notNullValue() );
+ }
+
+ @Test
+ public void testLoadSimpleFilterFile() throws IOException {
+ UrlRewriteRulesDescriptor config =
+ UrlRewriteRulesDescriptorFactory.load( "xml", getTestResourceReader( "filter-simple.xml", "UTF-8" ) );
+ List<UrlRewriteFilterDescriptor> filters = config.getFilters();
+ assertThat( filters.size(), is( 1 ) );
+ UrlRewriteFilterDescriptor filter = config.getFilter( "test-filter-1" );
+ assertThat( filter, notNullValue() );
+ assertThat( config.getFilters().get(0), sameInstance( filter ) );
+ }
+
+ @Test
+ public void testLoadStoreCompleteFilterFile() throws IOException {
+ UrlRewriteRulesDescriptor config =
+ UrlRewriteRulesDescriptorFactory.load( "xml", getTestResourceReader( "filter-complete.xml", "UTF-8" ) );
+
+ List<UrlRewriteFilterDescriptor> filters = config.getFilters();
+ assertThat( filters.size(), is( 1 ) );
+
+ UrlRewriteFilterDescriptor filter = config.getFilter( "test-filter-name-1" );
+ assertThat( filter, notNullValue() );
+ assertThat( config.getFilters().get(0), sameInstance( filter ) );
+ assertThat( filter.name(), is( "test-filter-name-1" ) );
+
+ UrlRewriteFilterContentDescriptor content = filter.getContent( "test-content-type-1/test-content-subtype-1" );
+ assertThat( content, notNullValue() );
+ assertThat( content.type(), is( "test-content-type-1/test-content-subtype-1" ) );
+
+ List<UrlRewriteFilterPathDescriptor> selectors = content.getSelectors();
+ assertThat( selectors, notNullValue() );
+ assertThat( selectors.size(), is( 3 ) );
+
+ UrlRewriteFilterApplyDescriptor apply = (UrlRewriteFilterApplyDescriptor)selectors.get( 0 );
+ assertThat( apply, notNullValue() );
+ assertThat( apply.path(), is( "test-apply-path-1" ) );
+ assertThat( apply.rule(), is( "test-apply-rule-1" ) );
+ assertThat( apply.compiledPath(), nullValue() );
+
+ UrlRewriteFilterScopeDescriptor scope = (UrlRewriteFilterScopeDescriptor)selectors.get( 1 );
+ assertThat( scope, notNullValue() );
+ assertThat( scope.path(), is( "test-scope-path-1" ) );
+ assertThat( scope.compiledPath(), nullValue() );
+ List<UrlRewriteFilterPathDescriptor> scopeSelectors = scope.getSelectors();
+ assertThat( scopeSelectors, notNullValue() );
+ assertThat( scopeSelectors.size(), is( 1 ) );
+ UrlRewriteFilterApplyDescriptor scopeApply = (UrlRewriteFilterApplyDescriptor)scopeSelectors.get( 0 );
+ assertThat( scopeApply, notNullValue() );
+ assertThat( scopeApply.path(), is( "test-apply-path-2" ) );
+ assertThat( scopeApply.compiledPath(), nullValue() );
+ assertThat( scopeApply.rule(), is( "test-apply-rule-2" ) );
+
+ UrlRewriteFilterBufferDescriptor buffer = (UrlRewriteFilterBufferDescriptor)selectors.get( 2 );
+ assertThat( buffer, notNullValue() );
+ assertThat( buffer.path(), is( "test-buffer-path-1" ) );
+ assertThat( buffer.compiledPath(), nullValue() );
+ List<UrlRewriteFilterPathDescriptor> bufferSelectors = buffer.getSelectors();
+ assertThat( bufferSelectors, notNullValue() );
+ assertThat( bufferSelectors.size(), is( 2 ) );
+ UrlRewriteFilterApplyDescriptor bufferApply = (UrlRewriteFilterApplyDescriptor)bufferSelectors.get( 0 );
+ assertThat( bufferApply, notNullValue() );
+ assertThat( bufferApply.path(), is( "test-apply-path-3" ) );
+ assertThat( bufferApply.compiledPath(), nullValue() );
+ assertThat( bufferApply.rule(), is( "test-apply-rule-3" ) );
+ UrlRewriteFilterDetectDescriptor bufferDetect = (UrlRewriteFilterDetectDescriptor)bufferSelectors.get( 1 );
+ assertThat( bufferDetect, notNullValue() );
+ assertThat( bufferDetect.value(), is( "test-detect-value-1" ) );
+ assertThat( bufferDetect.compiledValue(), nullValue() );
+ List<UrlRewriteFilterPathDescriptor> detectSelectors = bufferDetect.getSelectors();
+ assertThat( detectSelectors, notNullValue() );
+ assertThat( detectSelectors.size(), is( 1 ) );
+ UrlRewriteFilterApplyDescriptor detectApply = (UrlRewriteFilterApplyDescriptor)detectSelectors.get( 0 );
+ assertThat( detectApply, notNullValue() );
+ assertThat( detectApply.path(), is( "test-apply-path-4" ) );
+ assertThat( detectApply.compiledPath(), nullValue() );
+ assertThat( detectApply.rule(), is( "test-apply-rule-4" ) );
+
+ StringWriter writer = new StringWriter();
+ UrlRewriteRulesDescriptorFactory.store( config, "xml", writer );
+ Source xml = XmlConverters.the( writer.toString() );
+
+ assertThat( xml, notNullValue() );
+ assertThat( xml, hasXPath( "/" ) );
+ assertThat( xml, hasXPath( "/rules" ) );
+ assertThat( xml, hasXPath( "/rules/filter" ) );
+ assertThat( xml, hasXPath( "/rules/filter/@name", equalTo( "test-filter-name-1" ) ) );
+ assertThat( xml, hasXPath( "/rules/filter/content" ) );
+ assertThat( xml, hasXPath( "/rules/filter/content/@type", equalTo( "test-content-type-1/test-content-subtype-1" ) ) );
+ assertThat( xml, hasXPath( "/rules/filter/content/apply" ) );
+ assertThat( xml, hasXPath( "/rules/filter/content/apply/@path", equalTo( "test-apply-path-1" ) ) );
+ assertThat( xml, hasXPath( "/rules/filter/content/apply/@rule", equalTo( "test-apply-rule-1" ) ) );
+ assertThat( xml, hasXPath( "/rules/filter/content/scope" ) );
+ assertThat( xml, hasXPath( "/rules/filter/content/scope/@path", equalTo( "test-scope-path-1" ) ) );
+ assertThat( xml, hasXPath( "/rules/filter/content/scope/apply" ) );
+ assertThat( xml, hasXPath( "/rules/filter/content/scope/apply/@path", equalTo( "test-apply-path-2" ) ) );
+ assertThat( xml, hasXPath( "/rules/filter/content/scope/apply/@rule", equalTo( "test-apply-rule-2" ) ) );
+ assertThat( xml, hasXPath( "/rules/filter/content/buffer" ) );
+ assertThat( xml, hasXPath( "/rules/filter/content/buffer/@path", equalTo( "test-buffer-path-1" ) ) );
+ assertThat( xml, hasXPath( "/rules/filter/content/buffer/apply" ) );
+ assertThat( xml, hasXPath( "/rules/filter/content/buffer/apply/@path", equalTo( "test-apply-path-3" ) ) );
+ assertThat( xml, hasXPath( "/rules/filter/content/buffer/apply/@rule", equalTo( "test-apply-rule-3" ) ) );
+ assertThat( xml, hasXPath( "/rules/filter/content/buffer/detect" ) );
+ assertThat( xml, hasXPath( "/rules/filter/content/buffer/detect/@path", equalTo( "test-detect-path-1" ) ) );
+ assertThat( xml, hasXPath( "/rules/filter/content/buffer/detect/@value", equalTo( "test-detect-value-1" ) ) );
+ assertThat( xml, hasXPath( "/rules/filter/content/buffer/detect/apply" ) );
+ assertThat( xml, hasXPath( "/rules/filter/content/buffer/detect/apply/@path", equalTo( "test-apply-path-4" ) ) );
+ assertThat( xml, hasXPath( "/rules/filter/content/buffer/detect/apply/@rule", equalTo( "test-apply-rule-4" ) ) );
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/api/UrlRewriteServletContextListenerTest.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/api/UrlRewriteServletContextListenerTest.java b/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/api/UrlRewriteServletContextListenerTest.java
new file mode 100644
index 0000000..1d0d72d
--- /dev/null
+++ b/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/api/UrlRewriteServletContextListenerTest.java
@@ -0,0 +1,89 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.filter.rewrite.api;
+
+import org.apache.hadoop.test.mock.MockInteraction;
+import org.apache.hadoop.test.mock.MockServlet;
+import org.eclipse.jetty.servlet.FilterHolder;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.eclipse.jetty.http.HttpTester;
+import org.eclipse.jetty.servlet.ServletTester;
+import org.eclipse.jetty.util.ArrayQueue;
+import org.junit.After;
+import org.junit.Before;
+
+import javax.servlet.DispatcherType;
+import java.net.URL;
+import java.util.EnumSet;
+
+import static org.junit.Assert.fail;
+
+public class UrlRewriteServletContextListenerTest {
+
+ private ServletTester server;
+ private HttpTester.Request request;
+ private HttpTester.Response response;
+ private ArrayQueue<MockInteraction> interactions;
+ private MockInteraction interaction;
+
+ private static URL getTestResource( String name ) {
+ name = UrlRewriteServletFilterTest.class.getName().replaceAll( "\\.", "/" ) + "/" + name;
+ URL url = ClassLoader.getSystemResource( name );
+ return url;
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ String descriptorUrl = getTestResource( "rewrite.xml" ).toExternalForm();
+
+ server = new ServletTester();
+ server.setContextPath( "/" );
+ server.getContext().addEventListener( new UrlRewriteServletContextListener() );
+ server.getContext().setInitParameter(
+ UrlRewriteServletContextListener.DESCRIPTOR_LOCATION_INIT_PARAM_NAME, descriptorUrl );
+
+ FilterHolder filter = server.addFilter( UrlRewriteServletFilter.class, "/*", EnumSet.of( DispatcherType.REQUEST ) );
+ filter.setFilter( new UrlRewriteServletFilter() );
+
+ interactions = new ArrayQueue<MockInteraction>();
+
+ ServletHolder servlet = server.addServlet( MockServlet.class, "/" );
+ servlet.setServlet( new MockServlet( "mock-servlet", interactions ) );
+ servlet.setInitParameter(
+ UrlRewriteServletContextListener.DESCRIPTOR_LOCATION_INIT_PARAM_NAME,
+ getTestResource( "rewrite.xml" ).toExternalForm() );
+
+ server.start();
+
+ interaction = new MockInteraction();
+ request = HttpTester.newRequest();
+ response = null;
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ server.stop();
+ }
+
+// @Test
+// @Ignore("TODO")
+// public void testProvider() throws Exception {
+// fail( "TODO" );
+// }
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/api/UrlRewriteServletEnvironmentTest.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/api/UrlRewriteServletEnvironmentTest.java b/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/api/UrlRewriteServletEnvironmentTest.java
new file mode 100644
index 0000000..8b860fc
--- /dev/null
+++ b/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/api/UrlRewriteServletEnvironmentTest.java
@@ -0,0 +1,60 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.filter.rewrite.api;
+
+import org.easymock.EasyMock;
+import org.junit.Test;
+
+import javax.servlet.ServletContext;
+
+import java.net.URL;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.collection.IsIterableContainingInOrder.contains;
+
+public class UrlRewriteServletEnvironmentTest {
+
+ @Test
+ public void testGetResource() throws Exception {
+ ServletContext context = EasyMock.createNiceMock( ServletContext.class );
+ EasyMock.expect( context.getResource( "test-resource-name" ) ).andReturn( new URL( "http:/test-resource-value" ) ).anyTimes();
+ EasyMock.replay( context );
+ UrlRewriteServletEnvironment env = new UrlRewriteServletEnvironment( context );
+ assertThat( env.getResource( "test-resource-name" ), is( new URL( "http:/test-resource-value" ) ) );
+ }
+
+ @Test
+ public void testGetAttribute() throws Exception {
+ ServletContext context = EasyMock.createNiceMock( ServletContext.class );
+ EasyMock.expect( context.getAttribute( "test-attribute-name" ) ).andReturn( "test-attribute-value" ).anyTimes();
+ EasyMock.replay( context );
+ UrlRewriteServletEnvironment env = new UrlRewriteServletEnvironment( context );
+ assertThat( (String)env.getAttribute( "test-attribute-name" ), is( "test-attribute-value" ) );
+ }
+
+ @Test
+ public void testResolve() throws Exception {
+ ServletContext context = EasyMock.createNiceMock( ServletContext.class );
+ EasyMock.expect( context.getInitParameter( "test-parameter-name" ) ).andReturn( "test-parameter-value" );
+ EasyMock.replay( context );
+ UrlRewriteServletEnvironment env = new UrlRewriteServletEnvironment( context );
+ assertThat( env.resolve( "test-parameter-name" ), contains( "test-parameter-value" ) );
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/api/UrlRewriteServletFilterTest.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/api/UrlRewriteServletFilterTest.java b/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/api/UrlRewriteServletFilterTest.java
new file mode 100644
index 0000000..484786e
--- /dev/null
+++ b/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/api/UrlRewriteServletFilterTest.java
@@ -0,0 +1,920 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.filter.rewrite.api;
+
+import com.jayway.jsonassert.JsonAssert;
+import org.apache.knox.gateway.filter.AbstractGatewayFilter;
+import org.apache.knox.gateway.util.urltemplate.Parser;
+import org.apache.hadoop.test.TestUtils;
+import org.apache.hadoop.test.log.NoOpAppender;
+import org.apache.hadoop.test.mock.MockInteraction;
+import org.apache.hadoop.test.mock.MockServlet;
+import org.apache.log4j.Appender;
+import org.apache.log4j.Logger;
+import org.eclipse.jetty.http.HttpHeader;
+import org.eclipse.jetty.servlet.FilterHolder;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.eclipse.jetty.http.HttpTester;
+import org.eclipse.jetty.servlet.ServletTester;
+import org.eclipse.jetty.util.ArrayQueue;
+import org.junit.After;
+import org.junit.Test;
+
+import javax.servlet.DispatcherType;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.charset.Charset;
+import java.util.EnumSet;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.anyOf;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.fail;
+import static org.xmlmatchers.XmlMatchers.hasXPath;
+import static org.xmlmatchers.transform.XmlConverters.the;
+
+public class UrlRewriteServletFilterTest {
+
+ Logger LOG = Logger.getLogger(UrlRewriteServletFilterTest.class);
+
+ private ServletTester server;
+ private HttpTester.Request request;
+ private HttpTester.Response response;
+ private ArrayQueue<MockInteraction> interactions;
+ private MockInteraction interaction;
+
+ private static URL getTestResource( String name ) {
+ name = UrlRewriteServletFilterTest.class.getName().replaceAll( "\\.", "/" ) + "/" + name;
+ URL url = ClassLoader.getSystemResource( name );
+ return url;
+ }
+
+ public void setUp( Map<String,String> initParams ) throws Exception {
+ String descriptorUrl = getTestResource( "rewrite.xml" ).toExternalForm();
+
+ server = new ServletTester();
+ server.setContextPath( "/" );
+ server.getContext().addEventListener( new UrlRewriteServletContextListener() );
+ server.getContext().setInitParameter(
+ UrlRewriteServletContextListener.DESCRIPTOR_LOCATION_INIT_PARAM_NAME, descriptorUrl );
+
+ FilterHolder setupFilter = server.addFilter( SetupFilter.class, "/*", EnumSet.of( DispatcherType.REQUEST ) );
+ setupFilter.setFilter( new SetupFilter() );
+ FilterHolder rewriteFilter = server.addFilter( UrlRewriteServletFilter.class, "/*", EnumSet.of( DispatcherType.REQUEST ) );
+ if( initParams != null ) {
+ for( Map.Entry<String,String> entry : initParams.entrySet() ) {
+ rewriteFilter.setInitParameter( entry.getKey(), entry.getValue() );
+ }
+ }
+ rewriteFilter.setFilter( new UrlRewriteServletFilter() );
+
+ interactions = new ArrayQueue<MockInteraction>();
+
+ ServletHolder servlet = server.addServlet( MockServlet.class, "/" );
+ servlet.setServlet( new MockServlet( "mock-servlet", interactions ) );
+
+ server.start();
+
+ interaction = new MockInteraction();
+ request = HttpTester.newRequest();
+ response = null;
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ if( server != null ) {
+ server.stop();
+ }
+ }
+
+ @Test
+ public void testInboundRequestUrlRewrite() throws Exception {
+ setUp( null );
+ // Setup the server side request/response interaction.
+ interaction.expect()
+ .method( "GET" )
+ .requestUrl( "http://mock-host:1/test-output-path-1" );
+ interaction.respond().status( 200 ).content( "test-response-content".getBytes() );
+ interactions.add( interaction );
+ // Create the client request.
+ request.setMethod( "GET" );
+ request.setURI( "/test-input-path" );
+ //request.setVersion( "HTTP/1.1" );
+ request.setHeader( "Host", "mock-host:1" );
+ // Execute the request.
+ response = TestUtils.execute( server, request );
+
+ // Test the results.
+ assertThat( response.getStatus(), is( 200 ) );
+ assertThat( response.getContent(), is( "test-response-content" ) );
+ }
+
+ @Test
+ public void testInboundHeaderRewrite() throws Exception {
+ setUp( null );
+ // Setup the server side request/response interaction.
+ interaction.expect()
+ .method( "GET" )
+ .requestUrl( "http://mock-host:1/test-output-path-1" )
+ .header( "Location", "http://mock-host:1/test-output-path-1" );
+ interaction.respond()
+ .status( 200 );
+ interactions.add( interaction );
+ // Create the client request.
+ request.setMethod( "GET" );
+ request.setURI( "/test-input-path" );
+ //request.setVersion( "HTTP/1.1" );
+ request.setHeader( "Host", "mock-host:1" );
+ request.setHeader( "Location", "http://mock-host:1/test-input-path" );
+ // Execute the request.
+ response = TestUtils.execute( server, request );
+
+ // Test the results.
+ assertThat( response.getStatus(), is( 200 ) );
+ }
+
+ @Test
+ public void testOutboundHeaderRewrite() throws Exception {
+ setUp( null );
+ // Setup the server side request/response interaction.
+ interaction.expect()
+ .method( "GET" )
+ .requestUrl( "http://mock-host:1/test-output-path-1" );
+ interaction.respond()
+ .status( 201 )
+ .header( "Location", "http://mock-host:1/test-input-path" );
+ interactions.add( interaction );
+ // Create the client request.
+ request.setMethod( "GET" );
+ request.setURI( "/test-input-path" );
+ //request.setVersion( "HTTP/1.1" );
+ request.setHeader( "Host", "mock-host:1" );
+ // Execute the request.
+ response = TestUtils.execute( server, request );
+
+ // Test the results.
+ assertThat( response.getStatus(), is( 201 ) );
+ assertThat( response.get( HttpHeader.LOCATION ), is( "http://mock-host:1/test-output-path-1" ) );
+ }
+
+// @Ignore( "Need to figure out how to handle cookies since domain and path are separate." )
+// @Test
+// public void testRequestCookieRewrite() throws Exception {
+// setUp( null );
+// // Setup the server side request/response interaction.
+// interaction.expect()
+// .method( "GET" )
+// .requestUrl( "http://mock-host:1/test-output-path-1" )
+// .header( "Cookie", "cookie-name=cookie-value; Domain=docs.foo.com; Path=/accounts; Expires=Wed, 13-Jan-2021 22:23:01 GMT; Secure; HttpOnly" );
+// interaction.respond()
+// .status( 201 );
+// interactions.add( interaction );
+// // Create the client request.
+// request.setMethod( "GET" );
+// request.setURI( "/test-input-path" );
+// //request.setVersion( "HTTP/1.1" );
+// request.setHeader( "Host", "mock-host:1" );
+// request.setHeader( "Cookie", "cookie-name=cookie-value; Domain=docs.foo.com; Path=/accounts; Expires=Wed, 13-Jan-2021 22:23:01 GMT; Secure; HttpOnly" );
+//
+// // Execute the request.
+// response = TestUtils.execute( server, request );
+//
+// // Test the results.
+// assertThat( response.getStatus(), is( 201 ) );
+// fail( "TODO" );
+// }
+
+// @Ignore( "Need to figure out how to handle cookies since domain and path are separate." )
+// @Test
+// public void testResponseCookieRewrite() throws Exception {
+// setUp( null );
+// // Setup the server side request/response interaction.
+// interaction.expect()
+// .method( "GET" )
+// .requestUrl( "http://mock-host:1/test-output-path-1" );
+// interaction.respond()
+// .status( 200 )
+// .header( "Set-Cookie", "cookie-name=cookie-value; Domain=docs.foo.com; Path=/accounts; Expires=Wed, 13-Jan-2021 22:23:01 GMT; Secure; HttpOnly" );
+// interactions.add( interaction );
+// // Create the client request.
+// request.setMethod( "GET" );
+// request.setURI( "/test-input-path" );
+// //request.setVersion( "HTTP/1.1" );
+// request.setHeader( "Host", "mock-host:1" );
+//
+// // Execute the request.
+// response = TestUtils.execute( server, request );
+//
+// // Test the results.
+// assertThat( response.getStatus(), is( 200 ) );
+// assertThat( response.get( HttpHeader.SET_COOKIE ), is( "TODO" ) );
+// fail( "TODO" );
+// }
+
+ @Test
+ public void testInboundJsonBodyRewrite() throws Exception {
+ setUp( null );
+
+ String inputJson = "{\"url\":\"http://mock-host:1/test-input-path\"}";
+ String outputJson = "{\"url\":\"http://mock-host:1/test-output-path-1\"}";
+
+ // Setup the server side request/response interaction.
+ interaction.expect()
+ .method( "PUT" )
+ .requestUrl( "http://mock-host:1/test-output-path-1" )
+ .content( outputJson, Charset.forName( "UTF-8" ) );
+ interaction.respond()
+ .status( 200 );
+ interactions.add( interaction );
+ request.setMethod( "PUT" );
+ request.setURI( "/test-input-path" );
+ //request.setVersion( "HTTP/1.1" );
+ request.setHeader( "Host", "mock-host:1" );
+ request.setHeader( "Content-Type", "application/json; charset=UTF-8" );
+ request.setContent( inputJson );
+
+ // Execute the request.
+ response = TestUtils.execute( server, request );
+
+ // Test the results.
+ assertThat( response.getStatus(), is( 200 ) );
+ }
+
+ @Test
+ public void testInboundXmlBodyRewrite() throws Exception {
+ setUp( null );
+ String input = "<root attribute=\"http://mock-host:1/test-input-path\">http://mock-host:1/test-input-path</root>";
+ String output = null;
+ if(System.getProperty("java.vendor").contains("IBM")){
+ output = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><root attribute=\"http://mock-host:1/test-output-path-1\">http://mock-host:1/test-output-path-1</root>";
+ }else {
+ output = "<?xml version=\"1.0\" standalone=\"no\"?><root attribute=\"http://mock-host:1/test-output-path-1\">http://mock-host:1/test-output-path-1</root>";
+ }
+ // Setup the server side request/response interaction.
+ interaction.expect()
+ .method( "PUT" )
+ .requestUrl( "http://mock-host:1/test-output-path-1" )
+ .content( output, Charset.forName( "UTF-8" ) );
+ interaction.respond()
+ .status( 200 );
+ interactions.add( interaction );
+ request.setMethod( "PUT" );
+ request.setURI( "/test-input-path" );
+ //request.setVersion( "HTTP/1.1" );
+ request.setHeader( "Host", "mock-host:1" );
+ request.setHeader( "Content-Type", "application/xml; charset=UTF-8" );
+ request.setContent( input );
+
+ // Execute the request.
+ response = TestUtils.execute( server, request );
+
+ // Test the results.
+ assertThat( response.getStatus(), is( 200 ) );
+ }
+
+ // MatcherAssert.assertThat( XmlConverters.the( outputHtml ), XmlMatchers.hasXPath( "/html" ) );
+ @Test
+ public void testOutboundJsonBodyRewrite() throws Exception {
+ setUp( null );
+
+ String input = "{\"url\":\"http://mock-host:1/test-input-path\"}";
+ String expect = "{\"url\":\"http://mock-host:1/test-output-path-1\"}";
+
+ // Setup the server side request/response interaction.
+ interaction.expect()
+ .method( "PUT" )
+ .requestUrl( "http://mock-host:1/test-output-path-1" );
+ interaction.respond()
+ .status( 200 )
+ .contentType( "application/json" )
+ .content( input, Charset.forName( "UTF-8" ) );
+ interactions.add( interaction );
+ request.setMethod( "PUT" );
+ request.setURI( "/test-input-path" );
+ //request.setVersion( "HTTP/1.1" );
+ request.setHeader( "Host", "mock-host:1" );
+
+ // Execute the request.
+ response = TestUtils.execute( server, request );
+
+ // Test the results.
+ assertThat( response.getStatus(), is( 200 ) );
+ assertThat( response.getContent(), is( expect ) );
+ }
+
+ @Test
+ public void testOutboundHtmlBodyRewrite() throws Exception {
+ setUp( null );
+
+ String input = "<html><head></head><body><a href=\"http://mock-host:1/test-input-path\">link text</a></body></html>";
+ String output = "<html><head></head><body><a href=\"http://mock-host:1/test-output-path-1\">link text</a></body></html>";
+
+ // Setup the server side request/response interaction.
+ interaction.expect()
+ .method( "PUT" )
+ .requestUrl( "http://mock-host:1/test-output-path-1" )
+ .content( output, Charset.forName( "UTF-8" ) );
+ interaction.respond()
+ .status( 200 );
+ interactions.add( interaction );
+ request.setMethod( "PUT" );
+ request.setURI( "/test-input-path" );
+ //request.setVersion( "HTTP/1.1" );
+ request.setHeader( "Host", "mock-host:1" );
+ request.setHeader( "Content-Type", "application/html; charset=UTF-8" );
+ request.setContent( input );
+
+ // Execute the request.
+ response = TestUtils.execute( server, request );
+
+ // Test the results.
+ assertThat( response.getStatus(), is( 200 ) );
+ }
+
+ @Test
+ public void testInboundHtmlFormRewrite() throws Exception {
+ setUp( null );
+
+ String input = "Name=Jonathan+Doe&Age=23&Formula=a+%2B+b+%3D%3D+13%25%21&url=http%3A%2F%2Fmock-host%3A1%2Ftest-input-path";
+ String expect = "Name=Jonathan+Doe&Age=23&Formula=a+%2B+b+%3D%3D+13%25%21&url=http%3A%2F%2Fmock-host%3A1%2Ftest-output-path-1";
+
+ // Setup the server side request/response interaction.
+ interaction.expect()
+ .method( "PUT" )
+ .requestUrl( "http://mock-host:1/test-output-path-1" )
+ .content( expect, Charset.forName( "UTF-8" ) );
+ interaction.respond()
+ .status( 200 );
+ interactions.add( interaction );
+ request.setMethod( "PUT" );
+ request.setURI( "/test-input-path" );
+ //request.setVersion( "HTTP/1.1" );
+ request.setHeader( "Host", "mock-host:1" );
+ request.setHeader( "Content-Type", "application/x-www-form-urlencoded; charset=UTF-8" );
+ request.setContent( input );
+
+ // Execute the request.
+ response = TestUtils.execute( server, request );
+
+ // Test the results.
+ assertThat( response.getStatus(), is( 200 ) );
+ }
+
+ @Test
+ public void testRequestUrlRewriteWithFilterInitParam() throws Exception {
+ Map<String,String> initParams = new HashMap<>();
+ initParams.put( "request.url", "test-rule-2" );
+ setUp( initParams );
+
+ String input = "<root/>";
+ String expect = "<root/>";
+
+ // Setup the server side request/response interaction.
+ interaction.expect()
+ .method( "PUT" )
+ .requestUrl( "http://mock-host:42/test-output-path-2" )
+ .contentType( "text/xml" )
+ .characterEncoding( "UTF-8" )
+ .content( expect, Charset.forName( "UTF-8" ) );
+ interaction.respond()
+ .status( 200 );
+ interactions.add( interaction );
+ request.setMethod( "PUT" );
+ request.setURI( "/test-input-path" );
+ //request.setVersion( "HTTP/1.1" );
+ request.setHeader( "Host", "mock-host:42" );
+ request.setHeader( "Content-Type", "text/xml; charset=UTF-8" );
+ request.setContent( input );
+
+ // Execute the request.
+ response = TestUtils.execute( server, request );
+
+ // Test the results.
+ assertThat( response.getStatus(), is( 200 ) );
+ }
+
+ @Test
+ public void testRequestHeaderRewriteWithFilterInitParam() throws Exception {
+ Map<String,String> initParams = new HashMap<>();
+ initParams.put( "request.headers", "test-filter-2" );
+ setUp( initParams );
+
+ String input = "<root/>";
+ String expect = "<root/>";
+
+ // Setup the server side request/response interaction.
+ interaction.expect()
+ .method( "PUT" )
+ .requestUrl( "http://mock-host:42/test-output-path-1" )
+ .contentType( "text/xml" )
+ .characterEncoding( "UTF-8" )
+ .content( expect, Charset.forName( "UTF-8" ) )
+ .header( "Location", "http://mock-host:42/test-output-path-2" );
+ interaction.respond()
+ .status( 200 );
+ interactions.add( interaction );
+ request.setMethod( "PUT" );
+ request.setURI( "/test-input-path" );
+ //request.setVersion( "HTTP/1.1" );
+ request.setHeader( "Host", "mock-host:42" );
+ request.setHeader( "Location", "http://mock-host:42/test-input-path-1" );
+ request.setHeader( "Content-Type", "text/xml; charset=UTF-8" );
+ request.setContent( input );
+
+ // Execute the request.
+ response = TestUtils.execute( server, request );
+
+ // Test the results.
+ assertThat( response.getStatus(), is( 200 ) );
+ }
+
+// @Ignore( "Not Implemented Yet" )
+// @Test
+// public void testRequestCookieRewriteWithFilterInitParam() {
+// fail( "TODO" );
+// }
+
+ @Test
+ public void testRequestJsonBodyRewriteWithFilterInitParam() throws Exception {
+ Map<String,String> initParams = new HashMap<>();
+ //initParams.put( "url, "" );
+ initParams.put( "request.body", "test-filter-2" );
+ //initParams.put( "response", "" );
+ setUp( initParams );
+
+ String inputJson = "{\"url\":\"http://mock-host:42/test-input-path-1\"}";
+ String expectJson = "{\"url\":\"http://mock-host:42/test-output-path-2\"}";
+
+ // Setup the server side request/response interaction.
+ interaction.expect()
+ .method( "PUT" )
+ .requestUrl( "http://mock-host:42/test-output-path-1" )
+ .contentType( "application/json" )
+ .content( expectJson, Charset.forName( "UTF-8" ) );
+ interaction.respond()
+ .status( 200 );
+ interactions.add( interaction );
+ request.setMethod( "PUT" );
+ request.setURI( "/test-input-path" );
+ //request.setVersion( "HTTP/1.1" );
+ request.setHeader( "Host", "mock-host:42" );
+ request.setHeader( "Content-Type", "application/json; charset=UTF-8" );
+ request.setContent( inputJson );
+
+ // Execute the request.
+ response = TestUtils.execute( server, request );
+
+ // Test the results.
+ assertThat( response.getStatus(), is( 200 ) );
+ }
+
+ @Test
+ public void testRequestXmlBodyRewriteWithFilterInitParam() throws Exception {
+ Map<String,String> initParams = new HashMap<>();
+ initParams.put( "request.body", "test-filter-2" );
+ setUp( initParams );
+
+ String input = "<root url='http://mock-host:42/test-input-path-1'><url>http://mock-host:42/test-input-path-1</url></root>";
+ String expect = "<root url='http://mock-host:42/test-output-path-2'><url>http://mock-host:42/test-output-path-2</url></root>";
+
+ // Setup the server side request/response interaction.
+ interaction.expect()
+ .method( "PUT" )
+ .requestUrl( "http://mock-host:42/test-output-path-1" )
+ .contentType( "text/xml" )
+ .characterEncoding( "UTF-8" )
+ .content( expect, Charset.forName( "UTF-8" ) );
+ interaction.respond()
+ .status( 200 );
+ interactions.add( interaction );
+ request.setMethod( "PUT" );
+ request.setURI( "/test-input-path" );
+ //request.setVersion( "HTTP/1.1" );
+ request.setHeader( "Host", "mock-host:42" );
+ request.setHeader( "Content-Type", "text/xml; charset=UTF-8" );
+ request.setContent( input );
+
+ // Execute the request.
+ response = TestUtils.execute( server, request );
+
+ // Test the results.
+ assertThat( response.getStatus(), is( 200 ) );
+ }
+
+ @Test
+ public void testRequestXmlBodyRewriteWithFilterInitParamForInvalidFilterConfig() throws Exception {
+ Enumeration<Appender> realAppenders = NoOpAppender.setUp();
+ try {
+
+ Map<String,String> initParams = new HashMap<>();
+ initParams.put( "request.body", "test-filter-3" );
+ setUp( initParams );
+
+ String input = "<root url='http://mock-host:42/test-input-path-1'><url>http://mock-host:42/test-input-path-2</url></root>";
+ String expect = "<root url='http://mock-host:42/test-input-path-2'><url>http://mock-host:42/test-input-path-2</url></root>";
+
+ // Setup the server side request/response interaction.
+ interaction.expect()
+ .method( "PUT" )
+ .requestUrl( "http://mock-host:42/test-output-path-1" )
+ .contentType( "text/xml" )
+ .characterEncoding( "UTF-8" )
+ .content( expect, Charset.forName( "UTF-8" ) );
+ interaction.respond()
+ .status( 200 );
+ interactions.add( interaction );
+ request.setMethod( "PUT" );
+ request.setURI( "/test-input-path" );
+ //request.setVersion( "HTTP/1.1" );
+ request.setHeader( "Host", "mock-host:42" );
+ request.setHeader( "Content-Type", "text/xml; charset=UTF-8" );
+ request.setContent( input );
+
+ // Execute the request.
+ response = TestUtils.execute( server, request );
+
+ // Test the results.
+ assertThat( response.getStatus(), is( 500 ) );
+ } finally {
+ NoOpAppender.tearDown( realAppenders );
+ }
+ }
+
+ @Test
+ public void testRequestFormBodyRewriteWithFilterInitParam() throws Exception {
+ Map<String,String> initParams = new HashMap<>();
+ initParams.put( "request.body", "test-filter-2" );
+ setUp( initParams );
+
+ String input = "Name=Jonathan+Doe&Age=23&Formula=a+%2B+b+%3D%3D+13%25%21&url=http%3A%2F%2Fmock-host%3A1%2Ftest-input-path";
+ String expect = "Name=Jonathan+Doe&Age=23&Formula=a+%2B+b+%3D%3D+13%25%21&url=http%3A%2F%2Fmock-host%3A1%2Ftest-output-path-2";
+
+ // Setup the server side request/response interaction.
+ interaction.expect()
+ .method( "PUT" )
+ .requestUrl( "http://mock-host:1/test-output-path-1" )
+ .content( expect, Charset.forName( "UTF-8" ) )
+ .characterEncoding( "UTF-8" );
+ interaction.respond()
+ .status( 200 );
+ interactions.add( interaction );
+ request.setMethod( "PUT" );
+ request.setURI( "/test-input-path" );
+ //request.setVersion( "HTTP/1.1" );
+ request.setHeader( "Host", "mock-host:1" );
+ request.setHeader( "Content-Type", "application/x-www-form-urlencoded; charset=UTF-8" );
+ request.setContent( input );
+
+ // Execute the request.
+ response = TestUtils.execute( server, request );
+
+ // Test the results.
+ assertThat( response.getStatus(), is( 200 ) );
+ }
+
+ @Test
+ public void testResponseHeaderRewriteWithFilterInitParam() throws Exception {
+ Map<String,String> initParams = new HashMap<>();
+ initParams.put( "response.headers", "test-filter-2" );
+ setUp( initParams );
+
+ String output = "<root url='http://mock-host:42/test-input-path-2'><url>http://mock-host:42/test-input-path-3</url></root>";
+
+ // Setup the server side request/response interaction.
+ interaction.expect()
+ .method( "GET" )
+ .requestUrl( "http://mock-host:42/test-output-path-1" );
+ interaction.respond()
+ .content( output, Charset.forName( "UTF-8" ) )
+ .contentType( "text/xml" )
+ .header( "Location", "http://mock-host:42/test-input-path-4" )
+ .status( 307 );
+ interactions.add( interaction );
+ request.setMethod( "GET" );
+ request.setURI( "/test-input-path-1" );
+ //request.setVersion( "HTTP/1.1" );
+ request.setHeader( "Host", "mock-host:42" );
+
+ // Execute the request.
+ response = TestUtils.execute( server, request );
+
+ // Test the results.
+ assertThat( response.getStatus(), is( 307 ) );
+ assertThat( response.get( HttpHeader.LOCATION ), is( "http://mock-host:42/test-output-path-2" ) );
+
+ String actual = response.getContent();
+
+ assertThat( the( actual ), hasXPath( "/root/@url", equalTo( "http://mock-host:42/test-output-path-1" ) ) );
+ assertThat( the( actual ), hasXPath( "/root/url/text()", equalTo( "http://mock-host:42/test-output-path-1" ) ) );
+ }
+
+// @Ignore( "Not Implemented Yet" )
+// @Test
+// public void testResponseCookieRewriteWithFilterInitParam() {
+// fail( "TODO" );
+// }
+
+ @Test
+ public void testResponseJsonBodyRewriteWithFilterInitParam() throws Exception {
+ Map<String,String> initParams = new HashMap<>();
+ //initParams.put( "url, "" );
+ initParams.put( "response.body", "test-filter-2" );
+ //initParams.put( "response", "" );
+ setUp( initParams );
+
+ String responseJson = "{\"url\":\"http://mock-host:42/test-input-path-1\"}";
+
+ // Setup the server side request/response interaction.
+ interaction.expect()
+ .method( "GET" )
+ .requestUrl( "http://mock-host:42/test-output-path-1" );
+ interaction.respond()
+ .contentType( "application/json" )
+ .content( responseJson, Charset.forName( "UTF-8" ) )
+ .status( 200 );
+ interactions.add( interaction );
+ request.setMethod( "GET" );
+ request.setURI( "/test-input-path" );
+ //request.setVersion( "HTTP/1.1" );
+ request.setHeader( "Host", "mock-host:42" );
+ request.setHeader( "Content-Type", "application/json; charset=UTF-8" );
+ request.setContent( responseJson );
+
+ // Execute the request.
+ response = TestUtils.execute( server, request );
+
+ assertThat( response.getStatus(), is( 200 ) );
+ JsonAssert.with( response.getContent() ).assertThat( "$.url", is( "http://mock-host:42/test-output-path-2" ) );
+ }
+
+ @Test
+ public void testResponseHtmlBodyRewriteWithFilterInitParam() throws Exception {
+ Map<String,String> initParams = new HashMap<>();
+ //initParams.put( "url, "" );
+ initParams.put( "response.body", "test-filter-4" );
+ //initParams.put( "response", "" );
+ setUp( initParams );
+
+ String responseHtml = "<!DOCTYPE html>\n" +
+ "<html>\n" +
+ " <head>\n" +
+ " <meta charset=\"UTF-8\">\n" +
+ " <link rel=\"stylesheet\" href=\"pretty.css\">\n" +
+ " <script src=\"script.js\"></script>\n" +
+ " </head>\n" +
+ " <body>\n" +
+ " </body>\n" +
+ "</html>";
+ String rewrittenResponseHtml = "<!DOCTYPE html>\n" +
+ "<html>\n" +
+ " <head>\n" +
+ " <meta charset=\"UTF-8\">\n" +
+ " <link rel=\"stylesheet\" href=\"http://someotherhost/stylesheets/pretty.css\">\n" +
+ " <script src=\"script.js\"></script>\n" +
+ " </head>\n" +
+ " <body>\n" +
+ " </body>\n" +
+ "</html>";
+
+ // Setup the server side request/response interaction.
+ interaction.expect()
+ .method( "GET" )
+ .requestUrl( "http://mock-host:42/test-output-path-1" );
+ interaction.respond()
+ .contentType( "application/html" )
+ .content( responseHtml, Charset.forName( "UTF-8" ) )
+ .status( 200 );
+ interactions.add( interaction );
+ request.setMethod( "GET" );
+ request.setURI( "/test-input-path" );
+ request.setHeader( "Host", "mock-host:42" );
+ request.setHeader( "Content-Type", "application/html" );
+
+ // Execute the request.
+ response = TestUtils.execute( server, request );
+
+ assertThat( response.getStatus(), is( 200 ) );
+ String content = response.getContent();
+ assertThat(content, is(rewrittenResponseHtml));
+ }
+
+ @Test
+ public void testResponseXmlBodyRewriteWithFilterInitParam() throws Exception {
+ Map<String,String> initParams = new HashMap<>();
+ initParams.put( "response.body", "test-filter-2" );
+ setUp( initParams );
+
+ String output = "<root url='http://mock-host:42/test-input-path-1'><url>http://mock-host:42/test-input-path-1</url></root>";
+
+ // Setup the server side request/response interaction.
+ interaction.expect()
+ .method( "GET" )
+ .requestUrl( "http://mock-host:42/test-output-path-1" );
+ interaction.respond()
+ .content( output, Charset.forName( "UTF-8" ) )
+ .contentType( "text/xml" )
+ .status( 200 );
+ interactions.add( interaction );
+ request.setMethod( "GET" );
+ request.setURI( "/test-input-path" );
+ request.setVersion( "HTTP/1.0" );
+ request.setHeader( "Host", "mock-host:42" );
+
+ // Execute the request.
+ response = TestUtils.execute( server, request );
+
+ // Test the results.
+ assertThat( response.getStatus(), is( 200 ) );
+
+ String actual = response.getContent();
+
+ assertThat( the( actual ), hasXPath( "/root/@url", equalTo( "http://mock-host:42/test-output-path-2" ) ) );
+ assertThat( the( actual ), hasXPath( "/root/url/text()", equalTo( "http://mock-host:42/test-output-path-2" ) ) );
+ }
+
+ @Test
+ public void testResponseHtmlBodyRewriteCSSImport() throws Exception {
+ Map<String,String> initParams = new HashMap<>();
+ //initParams.put( "url, "" );
+ initParams.put( "response.body", "test-filter-5" );
+ //initParams.put( "response", "" );
+ setUp( initParams );
+
+ String responseHtml = "<html>" +
+ " <head>" +
+ " <style type=\"text/css\">@import \"pretty.css\";</style>" +
+ " </head>" +
+ "</html>";
+ String responseHtmlOne = "<html>" +
+ " <head>" +
+ " <style type=\"text/css\">@import \"http://0.0.0.0:0/stylesheets/pretty.css\";</style>" +
+ " </head>" +
+ "</html>";
+ String responseHtmlTwo = "<html>" +
+ " <head>" +
+ " <style type=\"text/css\">@import \"http://localhost:0/stylesheets/pretty.css\";</style>" +
+ " </head>" +
+ "</html>";
+
+ // Setup the server side request/response interaction.
+ interaction.expect()
+ .method( "GET" )
+ .requestUrl( "http://mock-host:42/test-output-path-1" );
+ interaction.respond()
+ .contentType( "application/html" )
+ .content( responseHtml, Charset.forName( "UTF-8" ) )
+ .status( 200 );
+ interactions.add( interaction );
+ request.setMethod( "GET" );
+ request.setURI( "/test-input-path" );
+ request.setHeader( "Host", "mock-host:42" );
+ request.setHeader( "Content-Type", "application/html" );
+
+ // Execute the request.
+ response = TestUtils.execute( server, request );
+
+ assertThat( response.getStatus(), is( 200 ) );
+ String content = response.getContent();
+// assertThat( the( content ), hasXPath( "//style/text()", equalTo( "@import \\\"http://0.0.0.0:0/stylesheets/pretty.css\\\";" ) ) );
+ assertThat(content, anyOf( is(responseHtmlOne), is(responseHtmlTwo)));
+ }
+
+ /**
+ * Test the prefix function
+ * @see KNOX-994
+ * @since 0.14.0
+ */
+ @Test
+ public void testResponseHtmlBodyRewritePrefixFunctionTestPrefix() throws Exception {
+
+ Map<String,String> initParams = new HashMap<>();
+ initParams.put( "response.body", "test-filter-6" );
+ setUp( initParams );
+
+ String responseHtml = "<html><div src=\"'components/navbar/navbar.html?v=1496201914075\"></div></html>";
+ String responseHtmlOne = "<html><div src=\"'http://0.0.0.0:0/zeppelin/components/navbar/navbar.html?v=1496201914075\"></div></html>";
+
+ // Setup the server side request/response interaction.
+ interaction.expect()
+ .method( "GET" )
+ .requestUrl( "http://mock-host:42/test-output-path-1" );
+ interaction.respond()
+ .contentType( "application/html" )
+ .content( responseHtml, Charset.forName( "UTF-8" ) )
+ .status( 200 );
+ interactions.add( interaction );
+ request.setMethod( "GET" );
+ request.setURI( "/test-input-path" );
+ request.setHeader( "Host", "mock-host:42" );
+ request.setHeader( "Content-Type", "application/html" );
+
+ // Execute the request.
+ response = TestUtils.execute( server, request );
+
+ assertThat( response.getStatus(), is( 200 ) );
+ String content = response.getContent();
+
+ assertThat(content, is(responseHtmlOne));
+
+ }
+
+
+ /**
+ * See KNOX-791
+ * @since 0.11.0
+ * @throws Exception
+ */
+ @Test
+ public void testResponseHtmlAttributeEscaping() throws Exception {
+ final Map<String, String> initParams = new HashMap<>();
+ initParams.put("response.body", "test-filter-4");
+ setUp(initParams);
+
+ final String responseHtml = "<!DOCTYPE html>\n" + "<html>\n" + " <head>\n"
+ + " <meta charset=\"UTF-8\">\n"
+ + " <link rel=\"stylesheet\" href=\"pretty.css\">\n"
+ + " <script escaped-data=\"<>\" src=\"script.js\"></script>\n"
+ + " </head>\n" + " <body>\n" + " </body>\n" + "</html>";
+ final String rewrittenResponseHtml = "<!DOCTYPE html>\n" + "<html>\n"
+ + " <head>\n" + " <meta charset=\"UTF-8\">\n"
+ + " <link rel=\"stylesheet\" href=\"http://someotherhost/stylesheets/pretty.css\">\n"
+ + " <script escaped-data=\"<>\" src=\"script.js\"></script>\n"
+ + " </head>\n" + " <body>\n" + " </body>\n" + "</html>";
+
+ // Setup the server side request/response interaction.
+ interaction.expect().method("GET")
+ .requestUrl("http://mock-host:42/test-output-path-1");
+ interaction.respond().contentType("application/html")
+ .content(responseHtml, Charset.forName("UTF-8")).status(200);
+ interactions.add(interaction);
+ request.setMethod("GET");
+ request.setURI("/test-input-path");
+ request.setHeader("Host", "mock-host:42");
+ request.setHeader("Content-Type", "application/html");
+
+ // Execute the request.
+ response = TestUtils.execute(server, request);
+
+ assertThat(response.getStatus(), is(200));
+ String content = response.getContent();
+ assertThat(content, is(rewrittenResponseHtml));
+ }
+
+
+ private static class SetupFilter implements Filter {
+ @Override
+ public void init( FilterConfig filterConfig ) throws ServletException {
+ }
+
+ @Override
+ public void doFilter( ServletRequest request, ServletResponse response, FilterChain chain ) throws IOException, ServletException {
+ HttpServletRequest httpRequest = ((HttpServletRequest)request);
+ StringBuffer sourceUrl = httpRequest.getRequestURL();
+ String queryString = httpRequest.getQueryString();
+ if( queryString != null ) {
+ sourceUrl.append( "?" );
+ sourceUrl.append( queryString );
+ }
+ try {
+ request.setAttribute(
+ AbstractGatewayFilter.SOURCE_REQUEST_URL_ATTRIBUTE_NAME,
+ Parser.parseLiteral( sourceUrl.toString() ) );
+ } catch( URISyntaxException e ) {
+ throw new ServletException( e );
+ }
+ chain.doFilter( request, response );
+ }
+
+ @Override
+ public void destroy() {
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/CookieScopeResponseWrapperTest.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/CookieScopeResponseWrapperTest.java b/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/CookieScopeResponseWrapperTest.java
new file mode 100644
index 0000000..2c01fa8
--- /dev/null
+++ b/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/CookieScopeResponseWrapperTest.java
@@ -0,0 +1,91 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.filter.rewrite.impl;
+
+import org.easymock.Capture;
+import org.easymock.EasyMock;
+import org.easymock.EasyMockSupport;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.servlet.http.HttpServletResponse;
+
+public class CookieScopeResponseWrapperTest extends EasyMockSupport {
+
+ private HttpServletResponse mock;
+
+ private Capture<String> captureKey;
+
+ private Capture<String> captureValue;
+
+ @Before
+ public void init(){
+ mock = EasyMock.createNiceMock(HttpServletResponse.class);
+ captureKey = new Capture<>();
+ captureValue = new Capture<>();
+ mock.addHeader( EasyMock.capture(captureKey), EasyMock.capture(captureValue));
+ EasyMock.replay(mock);
+ }
+
+ @Test
+ public void testNoPath() {
+ CookieScopeResponseWrapper underTest = new CookieScopeResponseWrapper(mock, "gw");
+ underTest.addHeader("Set-Cookie", "SESSIONID=jn0zexg59r1jo1n66hd7tg5anl;HttpOnly;");
+
+ Assert.assertEquals("Set-Cookie", captureKey.getValue());
+ Assert.assertEquals("SESSIONID=jn0zexg59r1jo1n66hd7tg5anl;HttpOnly; Path=/gw/;", captureValue.getValue());
+ }
+
+ @Test
+ public void testRootPath() {
+ CookieScopeResponseWrapper underTest = new CookieScopeResponseWrapper(mock, "gw");
+ underTest.addHeader("Set-Cookie", "SESSIONID=jn0zexg59r1jo1n66hd7tg5anl; Path=/; HttpOnly;");
+
+ Assert.assertEquals("Set-Cookie", captureKey.getValue());
+ Assert.assertEquals("SESSIONID=jn0zexg59r1jo1n66hd7tg5anl; Path=/gw/; HttpOnly;", captureValue.getValue());
+ }
+
+ @Test
+ public void testMultiSegmentPath() {
+ CookieScopeResponseWrapper underTest = new CookieScopeResponseWrapper(mock, "some/path");
+ underTest.addHeader("Set-Cookie", "SESSIONID=jn0zexg59r1jo1n66hd7tg5anl; Path=/; HttpOnly;");
+
+ Assert.assertEquals("Set-Cookie", captureKey.getValue());
+ Assert.assertEquals("SESSIONID=jn0zexg59r1jo1n66hd7tg5anl; Path=/some/path/; HttpOnly;", captureValue.getValue());
+ }
+
+ @Test
+ public void testAlreadyScopedPath() {
+ CookieScopeResponseWrapper underTest = new CookieScopeResponseWrapper(mock, "some/path");
+ underTest.addHeader("Set-Cookie", "SESSIONID=jn0zexg59r1jo1n66hd7tg5anl; Path=/already-scoped/; HttpOnly;");
+
+ Assert.assertEquals("Set-Cookie", captureKey.getValue());
+ Assert.assertEquals("SESSIONID=jn0zexg59r1jo1n66hd7tg5anl; Path=/some/path/already-scoped/; HttpOnly;", captureValue.getValue());
+ }
+
+ @Test
+ public void testCaseSensitive() {
+ CookieScopeResponseWrapper underTest = new CookieScopeResponseWrapper(mock, "some/path");
+ underTest.addHeader("set-cookie", "SESSIONID=jn0zexg59r1jo1n66hd7tg5anl; Path=/not-touched/; HttpOnly;");
+
+ Assert.assertEquals("set-cookie", captureKey.getValue());
+ Assert.assertEquals("SESSIONID=jn0zexg59r1jo1n66hd7tg5anl; Path=/not-touched/; HttpOnly;", captureValue.getValue());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/FrontendFunctionProcessorTest.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/FrontendFunctionProcessorTest.java b/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/FrontendFunctionProcessorTest.java
new file mode 100644
index 0000000..d40edc9
--- /dev/null
+++ b/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/FrontendFunctionProcessorTest.java
@@ -0,0 +1,303 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.filter.rewrite.impl;
+
+import com.jayway.jsonassert.JsonAssert;
+import org.apache.knox.gateway.filter.AbstractGatewayFilter;
+import org.apache.knox.gateway.filter.rewrite.api.FrontendFunctionDescriptor;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteEnvironment;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteServletContextListener;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteServletFilter;
+import org.apache.knox.gateway.filter.rewrite.spi.UrlRewriteFunctionProcessor;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.registry.ServiceRegistry;
+import org.apache.knox.gateway.util.urltemplate.Parser;
+import org.apache.hadoop.test.TestUtils;
+import org.apache.hadoop.test.log.NoOpLogger;
+import org.apache.hadoop.test.mock.MockInteraction;
+import org.apache.hadoop.test.mock.MockServlet;
+import org.apache.http.auth.BasicUserPrincipal;
+import org.easymock.EasyMock;
+import org.eclipse.jetty.http.HttpTester;
+import org.eclipse.jetty.servlet.FilterHolder;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.eclipse.jetty.servlet.ServletTester;
+import org.eclipse.jetty.util.ArrayQueue;
+import org.eclipse.jetty.util.Attributes;
+import org.eclipse.jetty.util.AttributesMap;
+import org.eclipse.jetty.util.log.Log;
+import org.hamcrest.core.Is;
+import org.junit.Test;
+
+import javax.security.auth.Subject;
+import javax.servlet.DispatcherType;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.charset.Charset;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.ServiceLoader;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.anyOf;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.fail;
+
+public class FrontendFunctionProcessorTest {
+
+ private ServletTester server;
+ private HttpTester.Request request;
+ private HttpTester.Response response;
+ private ArrayQueue<MockInteraction> interactions;
+ private MockInteraction interaction;
+
+ @SuppressWarnings("rawtypes")
+ @Test
+ public void testServiceLoader() throws Exception {
+ ServiceLoader loader = ServiceLoader.load( UrlRewriteFunctionProcessor.class );
+ Iterator iterator = loader.iterator();
+ assertThat( "Service iterator empty.", iterator.hasNext() );
+ while( iterator.hasNext() ) {
+ Object object = iterator.next();
+ if( object instanceof FrontendFunctionProcessor ) {
+ return;
+ }
+ }
+ fail( "Failed to find " + FrontendFunctionProcessor.class.getName() + " via service loader." );
+ }
+
+ @Test
+ public void testName() throws Exception {
+ FrontendFunctionProcessor processor = new FrontendFunctionProcessor();
+ assertThat( processor.name(), is( "frontend" ) );
+ }
+
+ @Test
+ public void testNullHandling() throws Exception {
+ UrlRewriteEnvironment badEnv = EasyMock.createNiceMock( UrlRewriteEnvironment.class );
+ UrlRewriteEnvironment goodEnv = EasyMock.createNiceMock( UrlRewriteEnvironment.class );
+ EasyMock.expect( goodEnv.getAttribute(FrontendFunctionDescriptor.FRONTEND_URI_ATTRIBUTE) ).andReturn( new URI( "http://mock-host:80/mock-root/mock-topo" ) ).anyTimes();
+ EasyMock.replay( badEnv,goodEnv );
+
+ FrontendFunctionProcessor processor = new FrontendFunctionProcessor();
+ try {
+ processor.initialize( null, null );
+ } catch ( IllegalArgumentException e ) {
+ assertThat( e.getMessage(), containsString( "environment" ) );
+ }
+ try {
+ processor.initialize( badEnv, null );
+ } catch ( IllegalArgumentException e ) {
+ assertThat( e.getMessage(), containsString( "org.apache.hadoop.knox.frontend.context.uri" ) );
+ }
+ processor.initialize( goodEnv, null );
+ processor.resolve( null, null );
+ }
+
+ public void setUp( String username, Map<String, String> initParams, Attributes attributes ) throws Exception {
+ ServiceRegistry mockServiceRegistry = EasyMock.createNiceMock( ServiceRegistry.class );
+ EasyMock.expect( mockServiceRegistry.lookupServiceURL( "test-cluster", "NAMENODE" ) ).andReturn( "test-nn-scheme://test-nn-host:411" ).anyTimes();
+ EasyMock.expect( mockServiceRegistry.lookupServiceURL( "test-cluster", "JOBTRACKER" ) ).andReturn( "test-jt-scheme://test-jt-host:511" ).anyTimes();
+
+ GatewayServices mockGatewayServices = EasyMock.createNiceMock( GatewayServices.class );
+ EasyMock.expect( mockGatewayServices.getService(GatewayServices.SERVICE_REGISTRY_SERVICE) ).andReturn( mockServiceRegistry ).anyTimes();
+
+ EasyMock.replay( mockServiceRegistry, mockGatewayServices );
+
+ String descriptorUrl = TestUtils.getResourceUrl( FrontendFunctionProcessorTest.class, "rewrite.xml" ).toExternalForm();
+
+ Log.setLog( new NoOpLogger() );
+
+ server = new ServletTester();
+ server.setContextPath( "/" );
+ server.getContext().addEventListener( new UrlRewriteServletContextListener() );
+ server.getContext().setInitParameter(
+ UrlRewriteServletContextListener.DESCRIPTOR_LOCATION_INIT_PARAM_NAME, descriptorUrl );
+
+ if( attributes != null ) {
+ server.getContext().setAttributes( attributes );
+ }
+ server.getContext().setAttribute( GatewayServices.GATEWAY_CLUSTER_ATTRIBUTE, "test-cluster" );
+ server.getContext().setAttribute( GatewayServices.GATEWAY_SERVICES_ATTRIBUTE, mockGatewayServices );
+
+ FilterHolder setupFilter = server.addFilter( SetupFilter.class, "/*", EnumSet.of( DispatcherType.REQUEST ) );
+ setupFilter.setFilter( new SetupFilter( username ) );
+ FilterHolder rewriteFilter = server.addFilter( UrlRewriteServletFilter.class, "/*", EnumSet.of( DispatcherType.REQUEST ) );
+ if( initParams != null ) {
+ for( Map.Entry<String,String> entry : initParams.entrySet() ) {
+ rewriteFilter.setInitParameter( entry.getKey(), entry.getValue() );
+ }
+ }
+ rewriteFilter.setFilter( new UrlRewriteServletFilter() );
+
+ interactions = new ArrayQueue<MockInteraction>();
+
+ ServletHolder servlet = server.addServlet( MockServlet.class, "/" );
+ servlet.setServlet( new MockServlet( "mock-servlet", interactions ) );
+
+ server.start();
+
+ interaction = new MockInteraction();
+ request = HttpTester.newRequest();
+ response = null;
+ }
+
+ @Test
+ public void testFrontendFunctionsOnJsonRequestBody() throws Exception {
+ Map<String,String> initParams = new HashMap<>();
+ initParams.put( "response.body", "test-filter" );
+ setUp( "test-user", initParams, null );
+
+ String input = TestUtils.getResourceString( FrontendFunctionProcessorTest.class, "test-input-body.json", "UTF-8" );
+
+ interaction.expect()
+ .method( "GET" )
+ .requestUrl( "http://test-host:42/test-path" );
+ interaction.respond()
+ .status( 200 )
+ .contentType( "application/json" )
+ .characterEncoding( "UTF-8" )
+ .content( input, Charset.forName( "UTF-8" ) );
+ interactions.add( interaction );
+ request.setMethod( "GET" );
+ request.setURI( "/test-path" );
+ //request.setVersion( "HTTP/1.1" );
+ request.setHeader( "Host", "test-host:42" );
+
+ response = TestUtils.execute( server, request );
+
+ assertThat( response.getStatus(), Is.is( 200 ) );
+
+ String json = response.getContent();
+
+ // Note: The Jetty ServletTester/HttpTester doesn't return very good values.
+ JsonAssert.with( json ).assertThat( "$.url", anyOf( is( "http://localhost:0" ), is( "http://0.0.0.0:0" ) ) );
+ JsonAssert.with( json ).assertThat( "$.scheme", is( "http" ) );
+ JsonAssert.with( json ).assertThat( "$.host", anyOf( is( "localhost" ), is( "0.0.0.0" ) ) );
+ JsonAssert.with( json ).assertThat( "$.port", is( "0" ) );
+ JsonAssert.with( json ).assertThat( "$.addr", anyOf( is( "localhost:0" ), is( "0.0.0.0:0" ) ) );
+ JsonAssert.with( json ).assertThat( "$.address", anyOf( is( "localhost:0" ), is( "0.0.0.0:0" ) ) );
+ JsonAssert.with( json ).assertThat( "$.path", is( "" ) );
+ JsonAssert.with( json ).assertThat( "$.topology", is( "test-cluster" ) );
+ }
+
+ @Test
+ public void testFrontendFunctionsWithFrontendUriConfigOnJsonRequestBody() throws Exception {
+
+ // This hooks up the filter in rewrite.xml in this class' test resource directory.
+ Map<String,String> initParams = new HashMap<>();
+ initParams.put( "response.body", "test-filter" );
+
+ // This simulates having gateway.frontend.uri in gateway-site.xml
+ Attributes attributes = new AttributesMap( );
+ attributes.setAttribute( FrontendFunctionDescriptor.FRONTEND_URI_ATTRIBUTE, new URI( "mock-frontend-scheme://mock-frontend-host:777/mock-frontend-path" ) );
+
+ setUp( "test-user", initParams, attributes );
+
+ String input = TestUtils.getResourceString( FrontendFunctionProcessorTest.class, "test-input-body.json", "UTF-8" );
+
+ interaction.expect()
+ .method( "GET" )
+ .requestUrl( "http://test-host:42/test-path" );
+ interaction.respond()
+ .status( 200 )
+ .contentType( "application/json" )
+ .characterEncoding( "UTF-8" )
+ .content( input, Charset.forName( "UTF-8" ) );
+ interactions.add( interaction );
+ request.setMethod( "GET" );
+ request.setURI( "/test-path" );
+ //request.setVersion( "HTTP/1.1" );
+ request.setHeader( "Host", "test-host:42" );
+
+ response = TestUtils.execute( server, request );
+
+ assertThat( response.getStatus(), Is.is( 200 ) );
+
+ String json = response.getContent();
+
+ // Note: The Jetty ServletTester/HttpTester doesn't return very good values.
+ JsonAssert.with( json ).assertThat( "$.url", is( "mock-frontend-scheme://mock-frontend-host:777/mock-frontend-path" ) );
+ JsonAssert.with( json ).assertThat( "$.scheme", is( "mock-frontend-scheme" ) );
+ JsonAssert.with( json ).assertThat( "$.host", is( "mock-frontend-host" ) );
+ JsonAssert.with( json ).assertThat( "$.port", is( "777" ) );
+ JsonAssert.with( json ).assertThat( "$.addr", is( "mock-frontend-host:777" ) );
+ JsonAssert.with( json ).assertThat( "$.address", is( "mock-frontend-host:777" ) );
+ JsonAssert.with( json ).assertThat( "$.path", is( "/mock-frontend-path" ) );
+ }
+
+ private static class SetupFilter implements Filter {
+ private Subject subject;
+
+ public SetupFilter( String userName ) {
+ subject = new Subject();
+ subject.getPrincipals().add( new BasicUserPrincipal( userName ) );
+ }
+
+ @Override
+ public void init( FilterConfig filterConfig ) throws ServletException {
+ }
+
+ @Override
+ public void doFilter( final ServletRequest request, final ServletResponse response, final FilterChain chain ) throws IOException, ServletException {
+ HttpServletRequest httpRequest = ((HttpServletRequest)request);
+ StringBuffer sourceUrl = httpRequest.getRequestURL();
+ String queryString = httpRequest.getQueryString();
+ if( queryString != null ) {
+ sourceUrl.append( "?" );
+ sourceUrl.append( queryString );
+ }
+ try {
+ request.setAttribute(
+ AbstractGatewayFilter.SOURCE_REQUEST_URL_ATTRIBUTE_NAME,
+ Parser.parseLiteral( sourceUrl.toString() ) );
+ } catch( URISyntaxException e ) {
+ throw new ServletException( e );
+ }
+ try {
+ Subject.doAs( subject, new PrivilegedExceptionAction<Void>() {
+ @Override
+ public Void run() throws Exception {
+ chain.doFilter( request, response );
+ return null;
+ }
+ } );
+ } catch( PrivilegedActionException e ) {
+ throw new ServletException( e );
+ }
+ }
+
+ @Override
+ public void destroy() {
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/UrlRewriteContextImplTest.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/UrlRewriteContextImplTest.java b/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/UrlRewriteContextImplTest.java
new file mode 100644
index 0000000..14db347
--- /dev/null
+++ b/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/UrlRewriteContextImplTest.java
@@ -0,0 +1,71 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.filter.rewrite.impl;
+
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteEnvironment;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriter;
+import org.apache.knox.gateway.filter.rewrite.spi.UrlRewriteFunctionProcessor;
+import org.apache.knox.gateway.util.urltemplate.Params;
+import org.apache.knox.gateway.util.urltemplate.Parser;
+import org.apache.knox.gateway.util.urltemplate.Resolver;
+import org.apache.knox.gateway.util.urltemplate.Template;
+import org.easymock.EasyMock;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+public class UrlRewriteContextImplTest {
+
+ @Test
+ public void testResolve() throws Exception {
+
+ UrlRewriteEnvironment environment = EasyMock.createNiceMock( UrlRewriteEnvironment.class );
+ EasyMock.expect( environment.resolve( "test-env-param-name" ) ).andReturn( Arrays.asList( "test-env-param-value" ) ).anyTimes();
+
+ Resolver resolver = EasyMock.createNiceMock( Resolver.class );
+ EasyMock.expect( resolver.resolve( "test-ctx-param-name" ) ).andReturn( Arrays.asList( "test-ctx-param-value" ) );
+
+ EasyMock.replay( environment, resolver );
+
+ Map<String,UrlRewriteFunctionProcessor> functions = new HashMap<>();
+
+ UrlRewriter.Direction direction = UrlRewriter.Direction.OUT;
+ Template template = Parser.parseLiteral( "scheme://host:port/dir/file" );
+
+ UrlRewriteContextImpl context = new UrlRewriteContextImpl( environment, resolver, functions, direction, template );
+
+ Params params = context.getParameters();
+ List<String> values = params.resolve( "test-env-param-name" );
+ assertThat( values, notNullValue() );
+ assertThat( values.size(), is( 1 ) );
+ assertThat( values.get( 0 ), is( "test-env-param-value" ) );
+
+ values = params.resolve( "test-ctx-param-name" );
+ assertThat( values, notNullValue() );
+ assertThat( values.size(), is( 1 ) );
+ assertThat( values.get( 0 ), is( "test-ctx-param-value" ) );
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/UrlRewriteResponseTest.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/UrlRewriteResponseTest.java b/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/UrlRewriteResponseTest.java
new file mode 100644
index 0000000..d3a9e33
--- /dev/null
+++ b/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/UrlRewriteResponseTest.java
@@ -0,0 +1,171 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.filter.rewrite.impl;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteProcessor;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteServletContextListener;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteServletFilter;
+import org.easymock.EasyMock;
+import org.junit.Test;
+
+import javax.activation.MimeTypeParseException;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.List;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.IsCollectionContaining.hasItems;
+
+public class UrlRewriteResponseTest {
+
+ @Test
+ public void testResolve() throws Exception {
+
+ UrlRewriteProcessor rewriter = EasyMock.createNiceMock( UrlRewriteProcessor.class );
+
+ ServletContext context = EasyMock.createNiceMock( ServletContext.class );
+ EasyMock.expect( context.getServletContextName() ).andReturn( "test-cluster-name" ).anyTimes();
+ EasyMock.expect( context.getInitParameter( "test-init-param-name" ) ).andReturn( "test-init-param-value" ).anyTimes();
+ EasyMock.expect( context.getAttribute( UrlRewriteServletContextListener.PROCESSOR_ATTRIBUTE_NAME ) ).andReturn( rewriter ).anyTimes();
+
+ FilterConfig config = EasyMock.createNiceMock( FilterConfig.class );
+ EasyMock.expect( config.getInitParameter( "test-filter-init-param-name" ) ).andReturn( "test-filter-init-param-value" ).anyTimes();
+ EasyMock.expect( config.getServletContext() ).andReturn( context ).anyTimes();
+
+ HttpServletRequest request = EasyMock.createNiceMock( HttpServletRequest.class );
+ HttpServletResponse response = EasyMock.createNiceMock( HttpServletResponse.class );
+
+ EasyMock.replay( rewriter, context, config, request, response );
+
+ UrlRewriteResponse rewriteResponse = new UrlRewriteResponse( config, request, response );
+
+ List<String> names = rewriteResponse.resolve( "test-filter-init-param-name" );
+ assertThat( names.size(), is( 1 ) );
+ assertThat( names.get( 0 ), is( "test-filter-init-param-value" ) );
+ }
+
+ @Test
+ public void testResolveGatewayParams() throws Exception {
+
+ UrlRewriteProcessor rewriter = EasyMock.createNiceMock( UrlRewriteProcessor.class );
+
+ ServletContext context = EasyMock.createNiceMock( ServletContext.class );
+ EasyMock.expect( context.getAttribute( UrlRewriteServletContextListener.PROCESSOR_ATTRIBUTE_NAME ) ).andReturn( rewriter ).anyTimes();
+
+ FilterConfig config = EasyMock.createNiceMock( FilterConfig.class );
+ EasyMock.expect( config.getServletContext() ).andReturn( context ).anyTimes();
+
+ HttpServletRequest request = EasyMock.createNiceMock( HttpServletRequest.class );
+ EasyMock.expect( request.getScheme() ).andReturn( "mock-scheme" ).anyTimes();
+ EasyMock.expect( request.getLocalName() ).andReturn( "mock-host" ).anyTimes();
+ EasyMock.expect( request.getLocalPort() ).andReturn( 42 ).anyTimes();
+ EasyMock.expect( request.getContextPath() ).andReturn( "/mock-path" ).anyTimes();
+ HttpServletResponse response = EasyMock.createNiceMock( HttpServletResponse.class );
+
+ EasyMock.replay( rewriter, context, config, request, response );
+
+ UrlRewriteResponse rewriteResponse = new UrlRewriteResponse( config, request, response );
+
+ List<String> url = rewriteResponse.resolve( "gateway.url" );
+ assertThat( url, hasItems( new String[]{ "mock-scheme://mock-host:42/mock-path" } ) );
+
+ List<String> scheme = rewriteResponse.resolve( "gateway.scheme" );
+ assertThat( scheme, hasItems( new String[]{ "mock-scheme" } ) );
+
+ List<String> host = rewriteResponse.resolve( "gateway.host" );
+ assertThat( host, hasItems( new String[]{ "mock-host" } ) );
+
+ List<String> port = rewriteResponse.resolve( "gateway.port" );
+ assertThat( port, hasItems( new String[]{ "42" } ) );
+
+ List<String> addr = rewriteResponse.resolve( "gateway.addr" );
+ assertThat( addr, hasItems( new String[]{ "mock-host:42" } ) );
+
+ List<String> address = rewriteResponse.resolve( "gateway.addr" );
+ assertThat( address, hasItems( new String[]{ "mock-host:42" } ) );
+
+ List<String> path = rewriteResponse.resolve( "gateway.path" );
+ assertThat( path, hasItems( new String[]{ "/mock-path" } ) );
+ }
+
+ @Test
+ public void testStreamResponse() throws IOException, MimeTypeParseException {
+ UrlRewriteProcessor rewriter = EasyMock.createNiceMock( UrlRewriteProcessor.class );
+ EasyMock.expect( rewriter.getConfig() ).andReturn( null ).anyTimes();
+
+ ServletContext context = EasyMock.createNiceMock( ServletContext.class );
+ EasyMock.expect( context.getAttribute( UrlRewriteServletContextListener.PROCESSOR_ATTRIBUTE_NAME ) ).andReturn( rewriter ).anyTimes();
+
+ FilterConfig config = EasyMock.createNiceMock( FilterConfig.class );
+ EasyMock.expect( config.getInitParameter( UrlRewriteServletFilter.RESPONSE_BODY_FILTER_PARAM ) ).andReturn( "test-filter" ).anyTimes();
+ EasyMock.expect( config.getServletContext() ).andReturn( context ).anyTimes();
+
+ HttpServletRequest request = EasyMock.createNiceMock( HttpServletRequest.class );
+ HttpServletResponse response = EasyMock.createNiceMock( HttpServletResponse.class );
+
+ EasyMock.replay( rewriter, context, config, request, response );
+
+ UrlRewriteResponse rewriteResponse = new UrlRewriteResponse( config, request, response );
+
+ String content = "content to test gzip streaming";
+ testStreamResponseGzip ( content, rewriteResponse, false );
+ testStreamResponseGzip ( content, rewriteResponse, true );
+ }
+
+ private void testStreamResponseGzip( String content, UrlRewriteResponse rewriteResponse , boolean isGzip ) throws IOException {
+ File targetDir = new File( System.getProperty( "user.dir" ), "target" );
+ File inputFile = new File( targetDir, "input.test" );
+ File outputFile = new File( targetDir, "output.test" );
+ OutputStream outStream = null, output = null;
+ InputStream inStream = null, input = null;
+ try {
+ outStream = isGzip ? new GZIPOutputStream( new FileOutputStream( inputFile ) ) : new FileOutputStream( inputFile );
+ outStream.write( content.getBytes() );
+ outStream.close();
+
+ input = new FileInputStream( inputFile );
+ output = new FileOutputStream( outputFile );
+ rewriteResponse.streamResponse( input, output );
+
+ inStream = isGzip ? new GZIPInputStream( new FileInputStream( outputFile ) ) : new FileInputStream( outputFile );
+ assertThat( String.valueOf( IOUtils.toCharArray( inStream ) ), is( content ) );
+ } finally {
+ if ( inStream != null ) {
+ inStream.close();
+ }
+ if ( input != null ) {
+ input.close();
+ }
+ inputFile.delete();
+ outputFile.delete();
+ }
+ }
+}