Explicitly exclude form-body params that appear in query string

Fixes gh-1080
This commit is contained in:
Dave Syer
2016-06-06 13:43:18 +01:00
parent b5f8c73060
commit 0da6f27aac
2 changed files with 54 additions and 2 deletions

View File

@@ -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<String, Object> builder = new LinkedMultiValueMap<String, Object>();
Set<String> queryParams = findQueryParams();
for (Entry<String, String[]> 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<String> findQueryParams() {
Set<String> 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();

View File

@@ -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<String, String> form = new LinkedMultiValueMap<String, String>();
form.set("foo", "bar");
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.valueOf(
MediaType.APPLICATION_FORM_URLENCODED_VALUE + "; charset=UTF-8"));
ResponseEntity<String> result = new TestRestTemplate().exchange(
"http://localhost:" + this.port + "/simple/form?uriParam=uriValue",
HttpMethod.POST,
new HttpEntity<MultiValueMap<String, String>>(form, headers),
String.class);
assertEquals(HttpStatus.OK, result.getStatusCode());
assertEquals("Posted! {uriParam=[uriValue], foo=[bar]}", result.getBody());
}
@Test
public void getWithUrlParams() throws Exception {
ResponseEntity<String> 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<String, String> 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)