Repository: knox Updated Branches: refs/heads/v0.9.0 f0ec8f052 -> a1db6ee40
[KNOX-709] - HBase request URLs must not be URL encoded Project: http://git-wip-us.apache.org/repos/asf/knox/repo Commit: http://git-wip-us.apache.org/repos/asf/knox/commit/a1db6ee4 Tree: http://git-wip-us.apache.org/repos/asf/knox/tree/a1db6ee4 Diff: http://git-wip-us.apache.org/repos/asf/knox/diff/a1db6ee4 Branch: refs/heads/v0.9.0 Commit: a1db6ee4028274f7959c626b73934cb79bb2493a Parents: f0ec8f0 Author: Kevin Minder <kmin...@apache.org> Authored: Wed Apr 13 14:23:03 2016 -0400 Committer: Kevin Minder <kmin...@apache.org> Committed: Wed Apr 13 14:23:43 2016 -0400 ---------------------------------------------------------------------- CHANGES | 1 + .../gateway/ha/dispatch/DefaultHaDispatch.java | 9 -- gateway-service-hbase/pom.xml | 5 ++ .../hadoop/gateway/hbase/HBaseDispatch.java | 22 +++++ .../hadoop/gateway/hbase/HBaseDispatchTest.java | 88 ++++++++++++++++++++ .../hdfs/dispatch/WebHdfsHaDispatch.java | 11 --- .../dispatch/AbstractGatewayDispatch.java | 12 +++ .../hadoop/gateway/dispatch/Dispatch.java | 2 + .../gateway/dispatch/GatewayDispatchFilter.java | 21 ++--- .../gateway/dispatch/DefaultDispatchTest.java | 55 ++++++++++++ 10 files changed, 190 insertions(+), 36 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/knox/blob/a1db6ee4/CHANGES ---------------------------------------------------------------------- diff --git a/CHANGES b/CHANGES index 6463762..b04d78f 100644 --- a/CHANGES +++ b/CHANGES @@ -65,6 +65,7 @@ Release Notes - Apache Knox - Version 0.9.0 * [KNOX-706] - KnoxSSO Default IDP must not require specific URL * [KNOX-707] - Enter Key within KnoxSSO Default IDP Form does not Submit * [KNOX-708] - Wrong CSS link in KnoxAuth Application's redirecting.html + * [KNOX-709] - HBase request URLs must not be URL encoded ------------------------------------------------------------------------------ Release Notes - Apache Knox - Version 0.8.0 http://git-wip-us.apache.org/repos/asf/knox/blob/a1db6ee4/gateway-provider-ha/src/main/java/org/apache/hadoop/gateway/ha/dispatch/DefaultHaDispatch.java ---------------------------------------------------------------------- diff --git a/gateway-provider-ha/src/main/java/org/apache/hadoop/gateway/ha/dispatch/DefaultHaDispatch.java b/gateway-provider-ha/src/main/java/org/apache/hadoop/gateway/ha/dispatch/DefaultHaDispatch.java index 82db972..4f66273 100644 --- a/gateway-provider-ha/src/main/java/org/apache/hadoop/gateway/ha/dispatch/DefaultHaDispatch.java +++ b/gateway-provider-ha/src/main/java/org/apache/hadoop/gateway/ha/dispatch/DefaultHaDispatch.java @@ -127,13 +127,4 @@ public class DefaultHaDispatch extends DefaultDispatch { } } - private static URI getDispatchUrl(HttpServletRequest request) { - StringBuffer str = request.getRequestURL(); - String query = request.getQueryString(); - if ( query != null ) { - str.append('?'); - str.append(query); - } - return URI.create(str.toString()); - } } http://git-wip-us.apache.org/repos/asf/knox/blob/a1db6ee4/gateway-service-hbase/pom.xml ---------------------------------------------------------------------- diff --git a/gateway-service-hbase/pom.xml b/gateway-service-hbase/pom.xml index caed7a5..c536815 100644 --- a/gateway-service-hbase/pom.xml +++ b/gateway-service-hbase/pom.xml @@ -37,6 +37,11 @@ <scope>test</scope> </dependency> <dependency> + <groupId>org.easymock</groupId> + <artifactId>easymock</artifactId> + <scope>test</scope> + </dependency> + <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> http://git-wip-us.apache.org/repos/asf/knox/blob/a1db6ee4/gateway-service-hbase/src/main/java/org/apache/hadoop/gateway/hbase/HBaseDispatch.java ---------------------------------------------------------------------- diff --git a/gateway-service-hbase/src/main/java/org/apache/hadoop/gateway/hbase/HBaseDispatch.java b/gateway-service-hbase/src/main/java/org/apache/hadoop/gateway/hbase/HBaseDispatch.java index f909852..beb9f02 100644 --- a/gateway-service-hbase/src/main/java/org/apache/hadoop/gateway/hbase/HBaseDispatch.java +++ b/gateway-service-hbase/src/main/java/org/apache/hadoop/gateway/hbase/HBaseDispatch.java @@ -17,6 +17,11 @@ */ package org.apache.hadoop.gateway.hbase; +import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.net.URLDecoder; +import javax.servlet.http.HttpServletRequest; + import org.apache.hadoop.gateway.dispatch.DefaultDispatch; /** @@ -26,5 +31,22 @@ import org.apache.hadoop.gateway.dispatch.DefaultDispatch; @Deprecated public class HBaseDispatch extends DefaultDispatch { + // KNOX-709: HBase can't handle URL encoded paths. + public URI getDispatchUrl( HttpServletRequest request) { + String base = request.getRequestURI(); + StringBuffer str = new StringBuffer(); + try { + str.append( URLDecoder.decode( base, "UTF-8" ) ); + } catch( UnsupportedEncodingException e ) { + str.append( base ); + } String query = request.getQueryString(); + if ( query != null ) { + str.append( '?' ); + str.append( query ); + } + URI uri = URI.create( str.toString() ); + return uri; + } + } http://git-wip-us.apache.org/repos/asf/knox/blob/a1db6ee4/gateway-service-hbase/src/test/java/org/apache/hadoop/gateway/hbase/HBaseDispatchTest.java ---------------------------------------------------------------------- diff --git a/gateway-service-hbase/src/test/java/org/apache/hadoop/gateway/hbase/HBaseDispatchTest.java b/gateway-service-hbase/src/test/java/org/apache/hadoop/gateway/hbase/HBaseDispatchTest.java new file mode 100644 index 0000000..349f768 --- /dev/null +++ b/gateway-service-hbase/src/test/java/org/apache/hadoop/gateway/hbase/HBaseDispatchTest.java @@ -0,0 +1,88 @@ +/** + * 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.hadoop.gateway.hbase; + +import java.net.URI; +import javax.servlet.http.HttpServletRequest; + +import org.apache.hadoop.gateway.dispatch.Dispatch; +import org.apache.hadoop.test.TestUtils; +import org.apache.hadoop.test.category.FastTests; +import org.apache.hadoop.test.category.UnitTests; +import org.easymock.EasyMock; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.*; + +@Category( { UnitTests.class, FastTests.class } ) +public class HBaseDispatchTest { + + @Test( timeout = TestUtils.SHORT_TIMEOUT ) + public void testGetDispatchUrl() throws Exception { + HttpServletRequest request; + Dispatch dispatch; + String path; + String query; + URI uri; + + dispatch = new HBaseDispatch(); + + path = "http://test-host:42/test-path"; + request = EasyMock.createNiceMock( HttpServletRequest.class ); + EasyMock.expect( request.getRequestURI() ).andReturn( path ).anyTimes(); + EasyMock.expect( request.getRequestURL() ).andReturn( new StringBuffer( path ) ).anyTimes(); + EasyMock.expect( request.getQueryString() ).andReturn( null ).anyTimes(); + EasyMock.replay( request ); + uri = dispatch.getDispatchUrl( request ); + assertThat( uri.toASCIIString(), is( "http://test-host:42/test-path" ) ); + + path = "http://test-host:42/test,path"; + request = EasyMock.createNiceMock( HttpServletRequest.class ); + EasyMock.expect( request.getRequestURI() ).andReturn( path ).anyTimes(); + EasyMock.expect( request.getRequestURL() ).andReturn( new StringBuffer( path ) ).anyTimes(); + EasyMock.expect( request.getQueryString() ).andReturn( null ).anyTimes(); + EasyMock.replay( request ); + uri = dispatch.getDispatchUrl( request ); + assertThat( uri.toASCIIString(), is( "http://test-host:42/test,path" ) ); + + // KNOX-709: HBase request URLs must not be URL encoded + path = "http://test-host:42/test%2Cpath"; + request = EasyMock.createNiceMock( HttpServletRequest.class ); + EasyMock.expect( request.getRequestURI() ).andReturn( path ).anyTimes(); + EasyMock.expect( request.getRequestURL() ).andReturn( new StringBuffer( path ) ).anyTimes(); + EasyMock.expect( request.getQueryString() ).andReturn( null ).anyTimes(); + EasyMock.replay( request ); + uri = dispatch.getDispatchUrl( request ); + assertThat( uri.toASCIIString(), is( "http://test-host:42/test,path" ) ); + + // KNOX-709: HBase request URLs must not be URL encoded + path = "http://test-host:42/test%2Cpath"; + query = "test%26name=test%3Dvalue"; + request = EasyMock.createNiceMock( HttpServletRequest.class ); + EasyMock.expect( request.getRequestURI() ).andReturn( path ).anyTimes(); + EasyMock.expect( request.getRequestURL() ).andReturn( new StringBuffer( path ) ).anyTimes(); + EasyMock.expect( request.getQueryString() ).andReturn( query ).anyTimes(); + EasyMock.replay( request ); + uri = dispatch.getDispatchUrl( request ); + assertThat( uri.toASCIIString(), is( "http://test-host:42/test,path?test%26name=test%3Dvalue" ) ); + + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/knox/blob/a1db6ee4/gateway-service-webhdfs/src/main/java/org/apache/hadoop/gateway/hdfs/dispatch/WebHdfsHaDispatch.java ---------------------------------------------------------------------- diff --git a/gateway-service-webhdfs/src/main/java/org/apache/hadoop/gateway/hdfs/dispatch/WebHdfsHaDispatch.java b/gateway-service-webhdfs/src/main/java/org/apache/hadoop/gateway/hdfs/dispatch/WebHdfsHaDispatch.java index d0bfd34..dbb5374 100644 --- a/gateway-service-webhdfs/src/main/java/org/apache/hadoop/gateway/hdfs/dispatch/WebHdfsHaDispatch.java +++ b/gateway-service-webhdfs/src/main/java/org/apache/hadoop/gateway/hdfs/dispatch/WebHdfsHaDispatch.java @@ -181,15 +181,4 @@ public class WebHdfsHaDispatch extends HdfsHttpClientDispatch { } } - private static URI getDispatchUrl(HttpServletRequest request) { - StringBuffer str = request.getRequestURL(); - String query = request.getQueryString(); - if ( query != null ) { - str.append('?'); - str.append(query); - } - URI url = URI.create(str.toString()); - return url; - } - } http://git-wip-us.apache.org/repos/asf/knox/blob/a1db6ee4/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/AbstractGatewayDispatch.java ---------------------------------------------------------------------- diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/AbstractGatewayDispatch.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/AbstractGatewayDispatch.java index 622d37b..ddb806b 100644 --- a/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/AbstractGatewayDispatch.java +++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/AbstractGatewayDispatch.java @@ -77,6 +77,18 @@ public abstract class AbstractGatewayDispatch implements Dispatch { this.client = client; } + @Override + public URI getDispatchUrl(HttpServletRequest request) { + StringBuffer str = request.getRequestURL(); + String query = request.getQueryString(); + if ( query != null ) { + str.append('?'); + str.append(query); + } + URI url = URI.create(str.toString()); + return url; + } + public void doGet( URI url, HttpServletRequest request, HttpServletResponse response ) throws IOException, URISyntaxException { response.sendError( HttpServletResponse.SC_METHOD_NOT_ALLOWED ); http://git-wip-us.apache.org/repos/asf/knox/blob/a1db6ee4/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/Dispatch.java ---------------------------------------------------------------------- diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/Dispatch.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/Dispatch.java index 0ce1339..de08117 100644 --- a/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/Dispatch.java +++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/Dispatch.java @@ -36,6 +36,8 @@ public interface Dispatch { void setHttpClient(HttpClient httpClient); + URI getDispatchUrl( HttpServletRequest request ); + void doGet( URI url, HttpServletRequest request, HttpServletResponse response ) throws IOException, ServletException, URISyntaxException; http://git-wip-us.apache.org/repos/asf/knox/blob/a1db6ee4/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/GatewayDispatchFilter.java ---------------------------------------------------------------------- diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/GatewayDispatchFilter.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/GatewayDispatchFilter.java index 86601db..acfa92e 100644 --- a/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/GatewayDispatchFilter.java +++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/GatewayDispatchFilter.java @@ -112,17 +112,6 @@ public class GatewayDispatchFilter extends AbstractGatewayFilter { } } - protected static URI getDispatchUrl(HttpServletRequest request) { - StringBuffer str = request.getRequestURL(); - String query = request.getQueryString(); - if ( query != null ) { - str.append('?'); - str.append(query); - } - URI url = URI.create(str.toString()); - return url; - } - private interface Adapter { public void doMethod(Dispatch dispatch, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException, URISyntaxException; @@ -131,35 +120,35 @@ public class GatewayDispatchFilter extends AbstractGatewayFilter { private static class GetAdapter implements Adapter { public void doMethod(Dispatch dispatch, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException, URISyntaxException { - dispatch.doGet(getDispatchUrl(request), request, response); + dispatch.doGet( dispatch.getDispatchUrl(request), request, response); } } private static class PostAdapter implements Adapter { public void doMethod(Dispatch dispatch, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException, URISyntaxException { - dispatch.doPost(getDispatchUrl(request), request, response); + dispatch.doPost( dispatch.getDispatchUrl(request), request, response); } } private static class PutAdapter implements Adapter { public void doMethod(Dispatch dispatch, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException, URISyntaxException { - dispatch.doPut(getDispatchUrl(request), request, response); + dispatch.doPut( dispatch.getDispatchUrl(request), request, response); } } private static class DeleteAdapter implements Adapter { public void doMethod(Dispatch dispatch, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException, URISyntaxException { - dispatch.doDelete(getDispatchUrl(request), request, response); + dispatch.doDelete( dispatch.getDispatchUrl(request), request, response); } } private static class OptionsAdapter implements Adapter { public void doMethod(Dispatch dispatch, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException, URISyntaxException { - dispatch.doOptions(getDispatchUrl(request), request, response); + dispatch.doOptions( dispatch.getDispatchUrl(request), request, response); } } http://git-wip-us.apache.org/repos/asf/knox/blob/a1db6ee4/gateway-spi/src/test/java/org/apache/hadoop/gateway/dispatch/DefaultDispatchTest.java ---------------------------------------------------------------------- diff --git a/gateway-spi/src/test/java/org/apache/hadoop/gateway/dispatch/DefaultDispatchTest.java b/gateway-spi/src/test/java/org/apache/hadoop/gateway/dispatch/DefaultDispatchTest.java index 4c360ff..37451fd 100644 --- a/gateway-spi/src/test/java/org/apache/hadoop/gateway/dispatch/DefaultDispatchTest.java +++ b/gateway-spi/src/test/java/org/apache/hadoop/gateway/dispatch/DefaultDispatchTest.java @@ -17,6 +17,7 @@ */ package org.apache.hadoop.gateway.dispatch; +import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.instanceOf; @@ -39,6 +40,9 @@ import javax.servlet.http.HttpServletResponse; import org.apache.hadoop.gateway.config.GatewayConfig; import org.apache.hadoop.gateway.servlet.SynchronousServletOutputStreamAdapter; +import org.apache.hadoop.test.TestUtils; +import org.apache.hadoop.test.category.FastTests; +import org.apache.hadoop.test.category.UnitTests; import org.apache.http.HttpEntity; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.impl.client.DefaultHttpClient; @@ -46,7 +50,9 @@ import org.apache.http.params.BasicHttpParams; import org.easymock.EasyMock; import org.easymock.IAnswer; import org.junit.Test; +import org.junit.experimental.categories.Category; +@Category( { UnitTests.class, FastTests.class } ) public class DefaultDispatchTest { // Make sure Hadoop cluster topology isn't exposed to client when there is a connectivity issue. @@ -165,4 +171,53 @@ public class DefaultDispatchTest { assertEquals(defaultDispatch.getReplayBufferSize(), 16); } + @Test( timeout = TestUtils.SHORT_TIMEOUT ) + public void testGetDispatchUrl() throws Exception { + HttpServletRequest request; + Dispatch dispatch; + String path; + String query; + URI uri; + + dispatch = new DefaultDispatch(); + + path = "http://test-host:42/test-path"; + request = EasyMock.createNiceMock( HttpServletRequest.class ); + EasyMock.expect( request.getRequestURI() ).andReturn( path ).anyTimes(); + EasyMock.expect( request.getRequestURL() ).andReturn( new StringBuffer( path ) ).anyTimes(); + EasyMock.expect( request.getQueryString() ).andReturn( null ).anyTimes(); + EasyMock.replay( request ); + uri = dispatch.getDispatchUrl( request ); + assertThat( uri.toASCIIString(), is( "http://test-host:42/test-path" ) ); + + path = "http://test-host:42/test,path"; + request = EasyMock.createNiceMock( HttpServletRequest.class ); + EasyMock.expect( request.getRequestURI() ).andReturn( path ).anyTimes(); + EasyMock.expect( request.getRequestURL() ).andReturn( new StringBuffer( path ) ).anyTimes(); + EasyMock.expect( request.getQueryString() ).andReturn( null ).anyTimes(); + EasyMock.replay( request ); + uri = dispatch.getDispatchUrl( request ); + assertThat( uri.toASCIIString(), is( "http://test-host:42/test,path" ) ); + + path = "http://test-host:42/test%2Cpath"; + request = EasyMock.createNiceMock( HttpServletRequest.class ); + EasyMock.expect( request.getRequestURI() ).andReturn( path ).anyTimes(); + EasyMock.expect( request.getRequestURL() ).andReturn( new StringBuffer( path ) ).anyTimes(); + EasyMock.expect( request.getQueryString() ).andReturn( null ).anyTimes(); + EasyMock.replay( request ); + uri = dispatch.getDispatchUrl( request ); + assertThat( uri.toASCIIString(), is( "http://test-host:42/test%2Cpath" ) ); + + path = "http://test-host:42/test%2Cpath"; + query = "test%26name=test%3Dvalue"; + request = EasyMock.createNiceMock( HttpServletRequest.class ); + EasyMock.expect( request.getRequestURI() ).andReturn( path ).anyTimes(); + EasyMock.expect( request.getRequestURL() ).andReturn( new StringBuffer( path ) ).anyTimes(); + EasyMock.expect( request.getQueryString() ).andReturn( query ).anyTimes(); + EasyMock.replay( request ); + uri = dispatch.getDispatchUrl( request ); + assertThat( uri.toASCIIString(), is( "http://test-host:42/test%2Cpath?test%26name=test%3Dvalue" ) ); + + } + }