Fix zuul error when there are colons in request param name.

Previously, parameter names with colons (ie foo:bar), caused an IllegalArgumentException because 41c36400 introduced UriTemplate to properly encode. fixes gh-1193
parent 622cc832
......@@ -249,6 +249,12 @@ public class ProxyRequestHelper {
MultiValueMap<String, String> headers) {
}
/**
* Get url encoded query string. Pay special attention to single parameters with no values
* and parameter names with colon (:) from use of UriTemplate.
* @param params Un-encoded request parameters
* @return
*/
public String getQueryString(MultiValueMap<String, String> params) {
if (params.isEmpty()) {
return "";
......@@ -260,10 +266,21 @@ public class ProxyRequestHelper {
for (String value : params.get(param)) {
query.append("&");
query.append(param);
if (!"".equals(value)) {
singles.put(param + i, value);
if (!"".equals(value)) { // don't add =, if original is ?wsdl, output is not ?wsdl=
String key = param;
// if form feed is already part of param name double
// since form feed is used as the colon replacement below
if (key.contains("\f")) {
key = (key.replaceAll("\f", "\f\f"));
}
// colon is special to UriTemplate
if (key.contains(":")) {
key = key.replaceAll(":", "\f");
}
key = key + i;
singles.put(key, value);
query.append("={");
query.append(param + i);
query.append(key);
query.append("}");
}
i++;
......
......@@ -260,6 +260,28 @@ public class ProxyRequestHelperTests {
}
@Test
public void getQueryStringEncoded() {
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("foo", "weird#chars");
String queryString = new ProxyRequestHelper().getQueryString(params);
assertThat(queryString, is("?foo=weird%23chars"));
}
@Test
public void getQueryParamNameWithColon() {
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("foo:bar", "baz");
params.add("foobar", "bam");
params.add("foo\fbar", "bat"); // form feed is the colon replacement char
String queryString = new ProxyRequestHelper().getQueryString(params);
assertThat(queryString, is("?foo:bar=baz&foobar=bam&foo%0Cbar=bat"));
}
@Test
public void buildZuulRequestURIWithUTF8() throws Exception {
String encodedURI = "/resource/esp%C3%A9cial-char";
String decodedURI = "/resource/espécial-char";
......
......@@ -187,6 +187,17 @@ public class RestClientRibbonCommandIntegrationTests extends ZuulProxyTestBase {
}
@Test
public void simpleHostRouteWithColonParamNames() {
this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/");
this.endpoint.reset();
ResponseEntity<String> result = new TestRestTemplate().exchange(
"http://localhost:" + this.port + "/self/colonquery?foo:bar={foobar0}&foobar={foobar1}", HttpMethod.GET,
new HttpEntity<>((Void) null), String.class, "baz", "bam");
assertEquals(HttpStatus.OK, result.getStatusCode());
assertEquals("/colonquery?foo:bar=baz&foobar=bam", result.getBody());
}
@Test
public void simpleHostRouteWithContentType() {
this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/");
this.endpoint.reset();
......@@ -295,10 +306,15 @@ public class RestClientRibbonCommandIntegrationTests extends ZuulProxyTestBase {
}
@RequestMapping("/query")
public String addQuery(HttpServletRequest request, @RequestParam String foo) {
public String query(HttpServletRequest request, @RequestParam String foo) {
return request.getRequestURI() + "?foo=" + foo;
}
@RequestMapping("/colonquery")
public String colonQuery(HttpServletRequest request, @RequestParam(name = "foo:bar") String foobar0, @RequestParam(name = "foobar") String foobar1) {
return request.getRequestURI() + "?foo:bar=" + foobar0 + "&foobar=" + foobar1;
}
@RequestMapping("/matrix/{name}/{another}")
public String matrix(@PathVariable("name") String name,
@MatrixVariable(value = "p", pathVar = "name") int p,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment