You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@knox.apache.org by km...@apache.org on 2015/09/23 10:00:42 UTC
knox git commit: KNOX-599: Template with {**} in queries are expanded
with =null for query params without a value
Repository: knox
Updated Branches:
refs/heads/master e20e5b06e -> f165a6d19
KNOX-599: Template with {**} in queries are expanded with =null for query params without a value
Project: http://git-wip-us.apache.org/repos/asf/knox/repo
Commit: http://git-wip-us.apache.org/repos/asf/knox/commit/f165a6d1
Tree: http://git-wip-us.apache.org/repos/asf/knox/tree/f165a6d1
Diff: http://git-wip-us.apache.org/repos/asf/knox/diff/f165a6d1
Branch: refs/heads/master
Commit: f165a6d1901bb5023faba2d61eb5d256012b34eb
Parents: e20e5b0
Author: Kevin Minder <ke...@hortonworks.com>
Authored: Wed Sep 23 04:00:33 2015 -0400
Committer: Kevin Minder <ke...@hortonworks.com>
Committed: Wed Sep 23 04:00:33 2015 -0400
----------------------------------------------------------------------
CHANGES | 1 +
.../pom.xml | 4 +
...entityAsserterHttpServletRequestWrapper.java | 10 +-
.../apache/hadoop/gateway/util/HttpUtils.java | 99 +++++++++
.../hadoop/gateway/util/HttpUtilsTest.java | 203 +++++++++++++++++++
.../gateway/util/urltemplate/Expander.java | 21 +-
.../gateway/util/urltemplate/ExpanderTest.java | 54 +++++
.../gateway/util/urltemplate/MatcherTest.java | 25 +++
.../gateway/util/urltemplate/ParserTest.java | 19 ++
9 files changed, 423 insertions(+), 13 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/knox/blob/f165a6d1/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index c91d83d..7b33de1 100644
--- a/CHANGES
+++ b/CHANGES
@@ -21,6 +21,7 @@ Release Notes - Apache Knox - Version 0.7.0
* [KNOX-554] - Fixed support for gateway.path change + added support for X-Forward-* headers in admin topology API.
* [KNOX-581] - Hive dispatch not propagating effective principal name
* [KNOX-598] - Concurrent JDBC clients via KNOX to Kerberized HiveServer2 causes HTTP 401 error (due to Kerberos Replay attack error)
+ * [KNOX-599] - Template with {**} in queries are expanded with =null for query params without a value
------------------------------------------------------------------------------
Release Notes - Apache Knox - Version 0.6.0
http://git-wip-us.apache.org/repos/asf/knox/blob/f165a6d1/gateway-provider-identity-assertion-common/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-common/pom.xml b/gateway-provider-identity-assertion-common/pom.xml
index 0926e20..5a02373 100644
--- a/gateway-provider-identity-assertion-common/pom.xml
+++ b/gateway-provider-identity-assertion-common/pom.xml
@@ -44,6 +44,10 @@
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
+ <dependency>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ </dependency>
<dependency>
<groupId>${gateway-group}</groupId>
http://git-wip-us.apache.org/repos/asf/knox/blob/f165a6d1/gateway-provider-identity-assertion-common/src/main/java/org/apache/hadoop/gateway/identityasserter/common/filter/IdentityAsserterHttpServletRequestWrapper.java
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-common/src/main/java/org/apache/hadoop/gateway/identityasserter/common/filter/IdentityAsserterHttpServletRequestWrapper.java b/gateway-provider-identity-assertion-common/src/main/java/org/apache/hadoop/gateway/identityasserter/common/filter/IdentityAsserterHttpServletRequestWrapper.java
index 50e9e60..d32cc58 100644
--- a/gateway-provider-identity-assertion-common/src/main/java/org/apache/hadoop/gateway/identityasserter/common/filter/IdentityAsserterHttpServletRequestWrapper.java
+++ b/gateway-provider-identity-assertion-common/src/main/java/org/apache/hadoop/gateway/identityasserter/common/filter/IdentityAsserterHttpServletRequestWrapper.java
@@ -21,6 +21,7 @@ import org.apache.commons.io.IOUtils;
import org.apache.hadoop.gateway.SpiGatewayMessages;
import org.apache.hadoop.gateway.config.GatewayConfig;
import org.apache.hadoop.gateway.i18n.messages.MessagesFactory;
+import org.apache.hadoop.gateway.util.HttpUtils;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
@@ -92,7 +93,7 @@ public class IdentityAsserterHttpServletRequestWrapper extends HttpServletReques
Map<String, String[]> params = null;
if (getMethod().equals("GET")) {
if (qString != null && qString.length() > 0) {
- params = parseQueryString(qString);
+ params = HttpUtils.parseQueryString( qString );
}
else {
params = new HashMap<String, String[]>();
@@ -103,7 +104,7 @@ public class IdentityAsserterHttpServletRequestWrapper extends HttpServletReques
return null;
}
else {
- params = parseQueryString(qString);
+ params = HttpUtils.parseQueryString( qString );
}
}
return params;
@@ -213,11 +214,6 @@ public class IdentityAsserterHttpServletRequestWrapper extends HttpServletReques
return sb.toString();
}
- @SuppressWarnings({ "deprecation", "unchecked" })
- private static Map<String,String[]> parseQueryString( String queryString ) {
- return javax.servlet.http.HttpUtils.parseQueryString( queryString );
- }
-
private class ServletInputStreamWrapper extends ServletInputStream {
private InputStream stream;
http://git-wip-us.apache.org/repos/asf/knox/blob/f165a6d1/gateway-util-common/src/main/java/org/apache/hadoop/gateway/util/HttpUtils.java
----------------------------------------------------------------------
diff --git a/gateway-util-common/src/main/java/org/apache/hadoop/gateway/util/HttpUtils.java b/gateway-util-common/src/main/java/org/apache/hadoop/gateway/util/HttpUtils.java
new file mode 100644
index 0000000..6a80a41
--- /dev/null
+++ b/gateway-util-common/src/main/java/org/apache/hadoop/gateway/util/HttpUtils.java
@@ -0,0 +1,99 @@
+/**
+ * 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.hadoop.gateway.util;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+public class HttpUtils {
+
+ public static Map<String,String[]> parseQueryString( String queryString ) {
+ Map<String,String[]> map = new HashMap<String,String[]>();
+ if( queryString != null && !queryString.isEmpty() ) {
+ StringTokenizer parser = new StringTokenizer( queryString, "&?;=", true );
+ String name = null;
+ String value = null;
+ while( parser.hasMoreTokens() ) {
+ String token = parser.nextToken();
+ String ttoken = token.trim();
+ if( ttoken.length() == 1 ) {
+ char c = ttoken.charAt( 0 );
+ switch( c ) {
+ case '&':
+ case '?':
+ case ';':
+ addQueryStringParam( map, name, value );
+ name = null;
+ value = null;
+ continue;
+ case '=':
+ if( name == null ) {
+ name = "";
+ value = "";
+ } else if( name.isEmpty() ) {
+ addQueryStringParam( map, name, value );
+ name = "";
+ value = "";
+ } else {
+ value = "";
+ }
+ continue;
+ }
+ }
+ if( name == null ) {
+ name = token;
+ } else {
+ value = token;
+ }
+ } // while
+ if( name != null ) {
+ addQueryStringParam( map, name, value );
+ }
+ }
+ return map;
+ }
+
+ private final static String urlDecodeUtf8( String s ) {
+ if( s != null ) {
+ try {
+ s = URLDecoder.decode( s, "UTF-8" );
+ } catch( UnsupportedEncodingException e ) {
+ // Ignore it.
+ }
+ }
+ return s;
+ }
+
+ final static void addQueryStringParam( final Map<String,String[]> map, String name, String value ) {
+ name = urlDecodeUtf8( name );
+ value = urlDecodeUtf8( value );
+ String[] values = map.get( name );
+ if( values == null ) {
+ values = new String[]{ value };
+ } else {
+ values = Arrays.copyOf( values, values.length + 1 );
+ values[ values.length-1 ] = value;
+ }
+ map.put( name, values );
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/f165a6d1/gateway-util-common/src/test/java/org/apache/hadoop/gateway/util/HttpUtilsTest.java
----------------------------------------------------------------------
diff --git a/gateway-util-common/src/test/java/org/apache/hadoop/gateway/util/HttpUtilsTest.java b/gateway-util-common/src/test/java/org/apache/hadoop/gateway/util/HttpUtilsTest.java
new file mode 100644
index 0000000..0e86a3b
--- /dev/null
+++ b/gateway-util-common/src/test/java/org/apache/hadoop/gateway/util/HttpUtilsTest.java
@@ -0,0 +1,203 @@
+/**
+ * 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.hadoop.gateway.util;
+
+import org.junit.Test;
+
+import java.util.Map;
+
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+
+public class HttpUtilsTest {
+
+ @Test
+ public void testParseQueryString_BugKnox599() {
+
+ Map<String,String[]> map;
+
+ map = HttpUtils.parseQueryString( null );
+ assertThat( map, notNullValue() );
+ assertThat( map.isEmpty(), is( true ) );
+
+ map = HttpUtils.parseQueryString( "" );
+ assertThat( map, notNullValue() );
+ assertThat( map.isEmpty(), is( true ) );
+
+ map = HttpUtils.parseQueryString( "test-name=test-value" );
+ assertThat( map, notNullValue() );
+ assertThat( map.size(), is( 1 ) );
+ assertThat( map.containsKey( "test-name" ), is( true ) );
+ assertThat( map.get( "test-name" ).length, is( 1 ) );
+ assertThat( map.get( "test-name" )[0], is( "test-value" ) );
+
+ map = HttpUtils.parseQueryString( "test-name-one=test-value-one&test-name-two=two=test-value-two" );
+ assertThat( map, notNullValue() );
+ assertThat( map.size(), is( 2 ) );
+ assertThat( map.containsKey( "test-name-one" ), is( true ) );
+ assertThat( map.get( "test-name-one" ).length, is( 1 ) );
+ assertThat( map.get( "test-name-one" )[0], is( "test-value-one" ) );
+ assertThat( map.containsKey( "test-name-two" ), is( true ) );
+ assertThat( map.get( "test-name-two" ).length, is( 1 ) );
+ assertThat( map.get( "test-name-two" )[0], is( "test-value-two" ) );
+
+ map = HttpUtils.parseQueryString( "test-name-one=test-value-one?test-name-two=two=test-value-two" );
+ assertThat( map, notNullValue() );
+ assertThat( map.size(), is( 2 ) );
+ assertThat( map.containsKey( "test-name-one" ), is( true ) );
+ assertThat( map.get( "test-name-one" ).length, is( 1 ) );
+ assertThat( map.get( "test-name-one" )[0], is( "test-value-one" ) );
+ assertThat( map.containsKey( "test-name-two" ), is( true ) );
+ assertThat( map.get( "test-name-two" ).length, is( 1 ) );
+ assertThat( map.get( "test-name-two" )[0], is( "test-value-two" ) );
+
+ map = HttpUtils.parseQueryString( "test-name-one=test-value-one;test-name-two=two=test-value-two" );
+ assertThat( map, notNullValue() );
+ assertThat( map.size(), is( 2 ) );
+ assertThat( map.containsKey( "test-name-one" ), is( true ) );
+ assertThat( map.get( "test-name-one" ).length, is( 1 ) );
+ assertThat( map.get( "test-name-one" )[0], is( "test-value-one" ) );
+ assertThat( map.containsKey( "test-name-two" ), is( true ) );
+ assertThat( map.get( "test-name-two" ).length, is( 1 ) );
+ assertThat( map.get( "test-name-two" )[0], is( "test-value-two" ) );
+
+ map = HttpUtils.parseQueryString( "test-name=test-value-one?test-name=test-value-two" );
+ assertThat( map, notNullValue() );
+ assertThat( map.size(), is( 1 ) );
+ assertThat( map.containsKey( "test-name" ), is( true ) );
+ assertThat( map.get( "test-name" ).length, is( 2 ) );
+ assertThat( map.get( "test-name" )[0], is( "test-value-one" ) );
+ assertThat( map.get( "test-name" )[1], is( "test-value-two" ) );
+
+ map = HttpUtils.parseQueryString( "test-name=test-value-one&test-name=test-value-two" );
+ assertThat( map, notNullValue() );
+ assertThat( map.size(), is( 1 ) );
+ assertThat( map.containsKey( "test-name" ), is( true ) );
+ assertThat( map.get( "test-name" ).length, is( 2 ) );
+ assertThat( map.get( "test-name" )[0], is( "test-value-one" ) );
+ assertThat( map.get( "test-name" )[1], is( "test-value-two" ) );
+
+ map = HttpUtils.parseQueryString( "test-name=test-value-one;test-name=test-value-two" );
+ assertThat( map, notNullValue() );
+ assertThat( map.size(), is( 1 ) );
+ assertThat( map.containsKey( "test-name" ), is( true ) );
+ assertThat( map.get( "test-name" ).length, is( 2 ) );
+ assertThat( map.get( "test-name" )[0], is( "test-value-one" ) );
+ assertThat( map.get( "test-name" )[1], is( "test-value-two" ) );
+
+ map = HttpUtils.parseQueryString( "test-name=" );
+ assertThat( map, notNullValue() );
+ assertThat( map.size(), is( 1 ) );
+ assertThat( map.containsKey( "test-name" ), is( true ) );
+ assertThat( map.get( "test-name" ).length, is( 1 ) );
+ assertThat( map.get( "test-name" )[0], is( "" ) );
+
+ map = HttpUtils.parseQueryString( "test-name" );
+ assertThat( map, notNullValue() );
+ assertThat( map.size(), is( 1 ) );
+ assertThat( map.containsKey( "test-name" ), is( true ) );
+ assertThat( map.get( "test-name" ).length, is( 1 ) );
+ assertThat( map.get( "test-name" )[0], nullValue() );
+
+ map = HttpUtils.parseQueryString( "=test-value" );
+ assertThat( map, notNullValue() );
+ assertThat( map.size(), is( 1 ) );
+ assertThat( map.containsKey( "" ), is( true ) );
+ assertThat( map.get( "" ).length, is( 1 ) );
+ assertThat( map.get( "" )[0], is( "test-value" ) );
+
+ map = HttpUtils.parseQueryString( "=" );
+ assertThat( map, notNullValue() );
+ assertThat( map.size(), is( 1 ) );
+ assertThat( map.containsKey( "" ), is( true ) );
+ assertThat( map.get( "" ).length, is( 1 ) );
+ assertThat( map.get( "" )[0], is( "" ) );
+
+ map = HttpUtils.parseQueryString( "==" );
+ assertThat( map, notNullValue() );
+ assertThat( map.size(), is( 1 ) );
+ assertThat( map.containsKey( "" ), is( true ) );
+ assertThat( map.get( "" ).length, is( 2 ) );
+ assertThat( map.get( "" )[0], is( "" ) );
+ assertThat( map.get( "" )[1], is( "" ) );
+
+ map = HttpUtils.parseQueryString( "&" );
+ assertThat( map, notNullValue() );
+ assertThat( map.size(), is( 1 ) );
+ assertThat( map.containsKey( null ), is( true ) );
+ assertThat( map.get( null ).length, is( 1 ) );
+ assertThat( map.get( null )[0], nullValue() );
+
+ map = HttpUtils.parseQueryString( "?" );
+ assertThat( map, notNullValue() );
+ assertThat( map.size(), is( 1 ) );
+ assertThat( map.containsKey( null ), is( true ) );
+ assertThat( map.get( null ).length, is( 1 ) );
+ assertThat( map.get( null )[0], nullValue() );
+
+ map = HttpUtils.parseQueryString( ";" );
+ assertThat( map, notNullValue() );
+ assertThat( map.size(), is( 1 ) );
+ assertThat( map.containsKey( null ), is( true ) );
+ assertThat( map.get( null ).length, is( 1 ) );
+ assertThat( map.get( null )[0], nullValue() );
+
+ map = HttpUtils.parseQueryString( "&=" );
+ assertThat( map, notNullValue() );
+ assertThat( map.size(), is( 2 ) );
+ assertThat( map.containsKey( "" ), is( true ) );
+ assertThat( map.get( "" ).length, is( 1 ) );
+ assertThat( map.get( "" )[0], is( "" ) );
+ assertThat( map.containsKey( null ), is( true ) );
+ assertThat( map.get( null ).length, is( 1 ) );
+ assertThat( map.get( null )[0], nullValue() );
+
+ map = HttpUtils.parseQueryString( "=&" );
+ assertThat( map, notNullValue() );
+ assertThat( map.size(), is( 1 ) );
+ assertThat( map.containsKey( "" ), is( true ) );
+ assertThat( map.get( "" ).length, is( 1 ) );
+ assertThat( map.get( "" )[0], is( "" ) );
+
+ map = HttpUtils.parseQueryString( "&&" );
+ assertThat( map, notNullValue() );
+ assertThat( map.size(), is( 1 ) );
+ assertThat( map.containsKey( null ), is( true ) );
+ assertThat( map.get( null ).length, is( 2 ) );
+ assertThat( map.get( null )[0], nullValue() );
+ assertThat( map.get( null )[1], nullValue() );
+
+ map = HttpUtils.parseQueryString( "test+name=test+value" );
+ assertThat( map, notNullValue() );
+ assertThat( map.size(), is( 1 ) );
+ assertThat( map.containsKey( "test name" ), is( true ) );
+ assertThat( map.get( "test name" ).length, is( 1 ) );
+ assertThat( map.get( "test name" )[0], is( "test value" ) );
+
+ map = HttpUtils.parseQueryString( "test%26name=test%3Dvalue" );
+ assertThat( map, notNullValue() );
+ assertThat( map.size(), is( 1 ) );
+ assertThat( map.containsKey( "test&name" ), is( true ) );
+ assertThat( map.get( "test&name" ).length, is( 1 ) );
+ assertThat( map.get( "test&name" )[0], is( "test=value" ) );
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/f165a6d1/gateway-util-urltemplate/src/main/java/org/apache/hadoop/gateway/util/urltemplate/Expander.java
----------------------------------------------------------------------
diff --git a/gateway-util-urltemplate/src/main/java/org/apache/hadoop/gateway/util/urltemplate/Expander.java b/gateway-util-urltemplate/src/main/java/org/apache/hadoop/gateway/util/urltemplate/Expander.java
index 4337f7a..ad6dc82 100644
--- a/gateway-util-urltemplate/src/main/java/org/apache/hadoop/gateway/util/urltemplate/Expander.java
+++ b/gateway-util-urltemplate/src/main/java/org/apache/hadoop/gateway/util/urltemplate/Expander.java
@@ -213,8 +213,10 @@ public class Expander {
builder.append( "&" );
}
builder.append( name );
- builder.append( "=" );
- builder.append( value );
+ if( value != null ) {
+ builder.append( "=" );
+ builder.append( value );
+ }
}
}
}
@@ -222,6 +224,7 @@ public class Expander {
}
private static void expandQueryValues( Query segment, String queryName, List<String> values, StringBuilder builder ) {
+ String value;
if( values == null || values.size() == 0 ) {
builder.append( queryName );
} else {
@@ -232,13 +235,19 @@ public class Expander {
builder.append( "&" );
}
builder.append( queryName );
- builder.append( "=" );
- builder.append( values.get( i ) );
+ value = values.get( i );
+ if( value != null ) {
+ builder.append( "=" );
+ builder.append( value );
+ }
}
} else {
builder.append( queryName );
- builder.append( "=" );
- builder.append( values.get( 0 ) );
+ value = values.get( 0 );
+ if( value != null ) {
+ builder.append( "=" );
+ builder.append( value );
+ }
}
}
}
http://git-wip-us.apache.org/repos/asf/knox/blob/f165a6d1/gateway-util-urltemplate/src/test/java/org/apache/hadoop/gateway/util/urltemplate/ExpanderTest.java
----------------------------------------------------------------------
diff --git a/gateway-util-urltemplate/src/test/java/org/apache/hadoop/gateway/util/urltemplate/ExpanderTest.java b/gateway-util-urltemplate/src/test/java/org/apache/hadoop/gateway/util/urltemplate/ExpanderTest.java
index 5b47b55..4b32979 100644
--- a/gateway-util-urltemplate/src/test/java/org/apache/hadoop/gateway/util/urltemplate/ExpanderTest.java
+++ b/gateway-util-urltemplate/src/test/java/org/apache/hadoop/gateway/util/urltemplate/ExpanderTest.java
@@ -335,4 +335,58 @@ public class ExpanderTest {
equalTo( "schemeA://host/pathA/pathB?server=host&query=queryA&query=queryB&host=hostA&extra=extraA" ) );
}
+
+ @Test
+ public void testBugKnox599() throws Exception {
+ String text;
+ Template template;
+ MockParams params;
+ URI expanded;
+
+ text = "{scheme}://{host}:{port}/{path=**}?{**}";
+ template = Parser.parse( text );
+ params = new MockParams();
+ params.addValue( "scheme", "http" );
+ params.addValue( "host", "hortonworks.com" );
+ params.addValue( "port", "8888" );
+ params.addValue( "path", "top" );
+ params.addValue( "path", "mid" );
+ params.addValue( "path", "bot" );
+ params.addValue( "path", "file" );
+ params.addValue( "name", "value" );
+ params.addValue( "flag", "" );
+ expanded = Expander.expand( template, params, null );
+ assertThat( expanded.toString(), equalTo( "http://hortonworks.com:8888/top/mid/bot/file?flag=&name=value" ) ) ;
+
+ text = "{scheme}://{host}:{port}/{path=**}?{**}";
+ template = Parser.parse( text );
+ params = new MockParams();
+ params.addValue( "scheme", "http" );
+ params.addValue( "host", "hortonworks.com" );
+ params.addValue( "port", "8888" );
+ params.addValue( "path", "top" );
+ params.addValue( "path", "mid" );
+ params.addValue( "path", "bot" );
+ params.addValue( "path", "file" );
+ params.addValue( "name", "value" );
+ params.addValue( "flag", null );
+ expanded = Expander.expand( template, params, null );
+ assertThat( expanded.toString(), equalTo( "http://hortonworks.com:8888/top/mid/bot/file?flag&name=value" ) ) ;
+
+ text = "{scheme}://{host}:{port}/{path=**}?{name=*}&{**}";
+ template = Parser.parse( text );
+ params = new MockParams();
+ params.addValue( "scheme", "http" );
+ params.addValue( "host", "hortonworks.com" );
+ params.addValue( "port", "8888" );
+ params.addValue( "path", "top" );
+ params.addValue( "path", "mid" );
+ params.addValue( "path", "bot" );
+ params.addValue( "path", "file" );
+ params.addValue( "name", null );
+ params.addValue( "flag", "" );
+ expanded = Expander.expand( template, params, null );
+ assertThat( expanded.toString(), equalTo( "http://hortonworks.com:8888/top/mid/bot/file?name&flag=" ) ) ;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/knox/blob/f165a6d1/gateway-util-urltemplate/src/test/java/org/apache/hadoop/gateway/util/urltemplate/MatcherTest.java
----------------------------------------------------------------------
diff --git a/gateway-util-urltemplate/src/test/java/org/apache/hadoop/gateway/util/urltemplate/MatcherTest.java b/gateway-util-urltemplate/src/test/java/org/apache/hadoop/gateway/util/urltemplate/MatcherTest.java
index 9cacb55..b172f99 100644
--- a/gateway-util-urltemplate/src/test/java/org/apache/hadoop/gateway/util/urltemplate/MatcherTest.java
+++ b/gateway-util-urltemplate/src/test/java/org/apache/hadoop/gateway/util/urltemplate/MatcherTest.java
@@ -24,6 +24,7 @@ import org.hamcrest.CoreMatchers;
import org.junit.Test;
import org.junit.experimental.categories.Category;
+import java.net.URI;
import java.net.URISyntaxException;
import static org.hamcrest.CoreMatchers.equalTo;
@@ -944,4 +945,28 @@ public class MatcherTest {
assertThat( params.getNames().size(), equalTo( 0 ) );
}
+ @Test
+ public void testBugKnox599() throws Exception {
+ Template template;
+ Template input;
+ Matcher<String> matcher;
+ Matcher<?>.Match match;
+
+ matcher = new Matcher<String>();
+ template = Parser.parse( "*://*:*/**/webhdfs/v1/{path=**}?{**}" );
+ matcher.add( template, "test-value" );
+
+ input = Parser.parse( "http://kminder-os-u14-23-knoxha-150922-1352-2.novalocal:1022/gateway/sandbox/webhdfs/v1/user/hrt_qa/knox-ha/knox_webhdfs_client_dir/test_file?op=CREATE&delegation=XXX&namenoderpcaddress=nameservice&createflag=&createparent=true&overwrite=true" );
+
+ match = matcher.match( input );
+ assertThat( match, notNullValue() );
+ assertThat( (String)match.getValue(), is( "test-value" ) );
+
+ template = Parser.parse( "http://host:42/root/webhdfs/v1/{path=**}?{**}" );
+ URI expanded = Expander.expand( template, match.getParams(), null );
+ assertThat(
+ expanded.toString(),
+ equalTo( "http://host:42/root/webhdfs/v1/user/hrt_qa/knox-ha/knox_webhdfs_client_dir/test_file?delegation=XXX&op=CREATE&namenoderpcaddress=nameservice&createflag=&overwrite=true&createparent=true" ) ) ;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/knox/blob/f165a6d1/gateway-util-urltemplate/src/test/java/org/apache/hadoop/gateway/util/urltemplate/ParserTest.java
----------------------------------------------------------------------
diff --git a/gateway-util-urltemplate/src/test/java/org/apache/hadoop/gateway/util/urltemplate/ParserTest.java b/gateway-util-urltemplate/src/test/java/org/apache/hadoop/gateway/util/urltemplate/ParserTest.java
index eeabba9..8e14f1f 100644
--- a/gateway-util-urltemplate/src/test/java/org/apache/hadoop/gateway/util/urltemplate/ParserTest.java
+++ b/gateway-util-urltemplate/src/test/java/org/apache/hadoop/gateway/util/urltemplate/ParserTest.java
@@ -1261,4 +1261,23 @@ public class ParserTest {
assertThat( output.getEffectivePattern(), is( "" ) );
}
+ @Test
+ public void testBugKnox599() throws Exception {
+ Template template;
+ Template input;
+ Matcher<String> matcher;
+
+ matcher = new Matcher<String>();
+ template = Parser.parse( "*://*:*/**/webhdfs/v1/{path=**}?{**}" );
+ matcher.add( template, "test-value" );
+
+ input = Parser.parse( "http://kminder-os-u14-23-knoxha-150922-1352-2.novalocal:1022/gateway/sandbox/webhdfs/v1/user/hrt_qa/knox-ha/knox_webhdfs_client_dir/test_file?op=CREATE&delegation=XXX&namenoderpcaddress=nameservice&createflag=&createparent=true&overwrite=true" );
+
+ assertThat( input.getQuery().get( "createflag" ).getFirstValue().getPattern(), is( "" ) );
+
+ input = Parser.parse( "http://kminder-os-u14-23-knoxha-150922-1352-2.novalocal:1022/gateway/sandbox/webhdfs/v1/user/hrt_qa/knox-ha/knox_webhdfs_client_dir/test_file?op=CREATE&delegation=XXX&namenoderpcaddress=nameservice&createflag&createparent=true&overwrite=true" );
+
+ assertThat( input.getQuery().get( "createflag" ).getFirstValue().getPattern(), nullValue() );
+ }
+
}