From 0da6f27aacd07a2ac76be487bf3d252b900f48e6 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Mon, 6 Jun 2016 13:43:18 +0100 Subject: [PATCH] Explicitly exclude form-body params that appear in query string Fixes gh-1080 --- .../filters/pre/FormBodyWrapperFilter.java | 24 ++++++++++++-- .../zuul/FormZuulProxyApplicationTests.java | 32 +++++++++++++++++++ 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/FormBodyWrapperFilter.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/FormBodyWrapperFilter.java index c438f61f..553008ba 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/FormBodyWrapperFilter.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/FormBodyWrapperFilter.java @@ -20,12 +20,15 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.lang.reflect.Field; +import java.util.HashSet; import java.util.List; import java.util.Map.Entry; +import java.util.Set; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; +import org.apache.commons.lang3.StringUtils; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpOutputMessage; @@ -165,10 +168,13 @@ public class FormBodyWrapperFilter extends ZuulFilter { private synchronized void buildContentData() { try { MultiValueMap builder = new LinkedMultiValueMap(); + Set queryParams = findQueryParams(); for (Entry entry : this.request.getParameterMap() .entrySet()) { - for (String value : entry.getValue()) { - builder.add(entry.getKey(), value); + if (!queryParams.contains(entry.getKey())) { + for (String value : entry.getValue()) { + builder.add(entry.getKey(), value); + } } } if (this.request instanceof MultipartRequest) { @@ -202,6 +208,20 @@ public class FormBodyWrapperFilter extends ZuulFilter { } } + private Set findQueryParams() { + Set result = new HashSet<>(); + String query = this.request.getQueryString(); + if (query != null) { + for (String value : StringUtils.split(query, "&")) { + if (value.contains("=")) { + value = value.substring(0, value.indexOf("=")); + } + result.add(value); + } + } + return result; + } + private class FormHttpOutputMessage implements HttpOutputMessage { private HttpHeaders headers = new HttpHeaders(); diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/FormZuulProxyApplicationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/FormZuulProxyApplicationTests.java index 2f864550..e734779d 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/FormZuulProxyApplicationTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/FormZuulProxyApplicationTests.java @@ -137,6 +137,32 @@ public class FormZuulProxyApplicationTests { assertEquals(HttpStatus.OK, result.getStatusCode()); assertEquals("Posted! {foo=[bar]}", result.getBody()); } + + @Test + public void postWithUrlParams() throws Exception { + MultiValueMap form = new LinkedMultiValueMap(); + form.set("foo", "bar"); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.valueOf( + MediaType.APPLICATION_FORM_URLENCODED_VALUE + "; charset=UTF-8")); + ResponseEntity result = new TestRestTemplate().exchange( + "http://localhost:" + this.port + "/simple/form?uriParam=uriValue", + HttpMethod.POST, + new HttpEntity>(form, headers), + String.class); + assertEquals(HttpStatus.OK, result.getStatusCode()); + assertEquals("Posted! {uriParam=[uriValue], foo=[bar]}", result.getBody()); + } + + @Test + public void getWithUrlParams() throws Exception { + ResponseEntity result = new TestRestTemplate().exchange( + "http://localhost:" + this.port + "/simple/form?uriParam=uriValue", + HttpMethod.GET, null, String.class); + assertEquals(HttpStatus.OK, result.getStatusCode()); + assertEquals("Posted! {uriParam=[uriValue]}", result.getBody()); + } + } // Don't use @SpringBootApplication because we don't want to component scan @@ -156,6 +182,12 @@ class FormZuulProxyApplication { return "Posted! " + form; } + @RequestMapping(value = "/form", method = RequestMethod.GET) + public String get(@RequestParam MultiValueMap form) + throws IOException { + return "Posted! " + form; + } + // TODO: Why does this not work if you add @RequestParam as above? @RequestMapping(value = "/file", method = RequestMethod.POST) public String file(@RequestParam(required = false) MultipartFile file)