Skip to content

Commit d746dca

Browse files
committed
SPR-5628 Use MediaType to parse the content type in HttpPutFormContentFilter
1 parent 9a40021 commit d746dca

File tree

2 files changed

+47
-25
lines changed

2 files changed

+47
-25
lines changed

org.springframework.web/src/main/java/org/springframework/web/filter/HttpPutFormContentFilter.java

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,29 +36,30 @@
3636
import javax.servlet.http.HttpServletResponse;
3737

3838
import org.springframework.http.HttpInputMessage;
39+
import org.springframework.http.MediaType;
3940
import org.springframework.http.converter.FormHttpMessageConverter;
4041
import org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter;
4142
import org.springframework.http.server.ServletServerHttpRequest;
4243
import org.springframework.util.LinkedMultiValueMap;
4344
import org.springframework.util.MultiValueMap;
4445

4546
/**
46-
* {@link javax.servlet.Filter} that makes form encoded data available through the
47-
* {@code ServletRequest.getParameter*()} family of methods during HTTP PUT requests.
47+
* {@link javax.servlet.Filter} that makes form encoded data available through
48+
* the {@code ServletRequest.getParameter*()} family of methods during HTTP PUT
49+
* requests.
4850
*
49-
* <p>The Servlet spec requires form data to be available for HTTP POST but not for
50-
* HTTP PUT requests. This filter intercepts HTTP PUT requests
51-
* where {@code 'Content-Type:application/x-www-form-urlencoded'}, reads the form
52-
* data from the body of the request, and wraps the ServletRequest in order to make
53-
* the form data available as request parameters.
51+
* <p>The Servlet spec requires form data to be available for HTTP POST but
52+
* not for HTTP PUT requests. This filter intercepts HTTP PUT requests where
53+
* content type is {@code 'application/x-www-form-urlencoded'}, reads form
54+
* encoded content from the body of the request, and wraps the ServletRequest
55+
* in order to make the form data available as request parameters just like
56+
* it is for HTTP POST requests.
5457
*
5558
* @author Rossen Stoyanchev
5659
* @since 3.1
5760
*/
5861
public class HttpPutFormContentFilter extends OncePerRequestFilter {
5962

60-
private static final String FORM_CONTENT_TYPE = "application/x-www-form-urlencoded";
61-
6263
private final FormHttpMessageConverter formConverter = new XmlAwareFormHttpMessageConverter();
6364

6465
/**
@@ -69,8 +70,8 @@ public void setCharset(Charset charset) {
6970
}
7071

7172
@Override
72-
protected void doFilterInternal(final HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
73-
throws ServletException, IOException {
73+
protected void doFilterInternal(final HttpServletRequest request, HttpServletResponse response,
74+
FilterChain filterChain) throws ServletException, IOException {
7475

7576
if ("PUT".equals(request.getMethod()) && isFormContentType(request)) {
7677
HttpInputMessage inputMessage = new ServletServerHttpRequest(request) {
@@ -91,7 +92,13 @@ public InputStream getBody() throws IOException {
9192

9293
private boolean isFormContentType(HttpServletRequest request) {
9394
String contentType = request.getContentType();
94-
return ((contentType != null) && contentType.equals(FORM_CONTENT_TYPE));
95+
if (contentType != null) {
96+
MediaType mediaType = MediaType.parseMediaType(contentType);
97+
return (MediaType.APPLICATION_FORM_URLENCODED.includes(mediaType));
98+
}
99+
else {
100+
return false;
101+
}
95102
}
96103

97104
private static class HttpPutFormContentRequestWrapper extends HttpServletRequestWrapper {

org.springframework.web/src/test/java/org/springframework/web/filter/HttpPutFormContentFilterTests.java

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import static org.junit.Assert.assertArrayEquals;
2020
import static org.junit.Assert.assertEquals;
21+
import static org.junit.Assert.assertNotSame;
2122
import static org.junit.Assert.assertNull;
2223
import static org.junit.Assert.assertSame;
2324

@@ -52,7 +53,7 @@ public void setup() {
5253
filter = new HttpPutFormContentFilter();
5354
request = new MockHttpServletRequest("PUT", "/");
5455
request.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=ISO-8859-1");
55-
request.setContentType("application/x-www-form-urlencoded");
56+
request.setContentType("application/x-www-form-urlencoded; charset=ISO-8859-1");
5657
response = new MockHttpServletResponse();
5758
filterChain = new MockFilterChain();
5859
}
@@ -90,20 +91,22 @@ public void getParameter() throws Exception {
9091
}
9192

9293
@Test
93-
public void queryStringParam() throws Exception {
94+
public void getParameterFromQueryString() throws Exception {
9495
request.addParameter("name", "value1");
9596
request.setContent("name=value2".getBytes("ISO-8859-1"));
9697
filter.doFilter(request, response, filterChain);
97-
98+
99+
assertNotSame("Request not wrapped", request, filterChain.getRequest());
98100
assertEquals("Query string parameters should be listed ahead of form parameters",
99101
"value1", filterChain.getRequest().getParameter("name"));
100102
}
101103

102104
@Test
103-
public void nullParameter() throws Exception {
105+
public void getParameterNullValue() throws Exception {
104106
request.setContent("name=value".getBytes("ISO-8859-1"));
105107
filter.doFilter(request, response, filterChain);
106108

109+
assertNotSame("Request not wrapped", request, filterChain.getRequest());
107110
assertNull(filterChain.getRequest().getParameter("noSuchParam"));
108111
}
109112

@@ -112,9 +115,11 @@ public void getParameterNames() throws Exception {
112115
request.addParameter("name1", "value1");
113116
request.addParameter("name2", "value2");
114117
request.setContent("name1=value1&name3=value3&name4=value4".getBytes("ISO-8859-1"));
118+
115119
filter.doFilter(request, response, filterChain);
116-
117120
List<String> names = Collections.list(filterChain.getRequest().getParameterNames());
121+
122+
assertNotSame("Request not wrapped", request, filterChain.getRequest());
118123
assertEquals(Arrays.asList("name1", "name2", "name3", "name4"), names);
119124
}
120125

@@ -123,42 +128,50 @@ public void getParameterValues() throws Exception {
123128
request.addParameter("name", "value1");
124129
request.addParameter("name", "value2");
125130
request.setContent("name=value3&name=value4".getBytes("ISO-8859-1"));
131+
126132
filter.doFilter(request, response, filterChain);
127-
128133
String[] values = filterChain.getRequest().getParameterValues("name");
134+
135+
assertNotSame("Request not wrapped", request, filterChain.getRequest());
129136
assertArrayEquals(new String[]{"value1", "value2", "value3", "value4"}, values);
130137
}
131138

132139
@Test
133-
public void getQueryStringParameterValuesOnly() throws Exception {
140+
public void getParameterValuesFromQueryString() throws Exception {
134141
request.addParameter("name", "value1");
135142
request.addParameter("name", "value2");
136143
request.setContent("anotherName=anotherValue".getBytes("ISO-8859-1"));
137-
filter.doFilter(request, response, filterChain);
138144

145+
filter.doFilter(request, response, filterChain);
139146
String[] values = filterChain.getRequest().getParameterValues("name");
147+
148+
assertNotSame("Request not wrapped", request, filterChain.getRequest());
140149
assertArrayEquals(new String[]{"value1", "value2"}, values);
141150
}
142151

143152
@Test
144-
public void getFormParameterValuesOnly() throws Exception {
153+
public void getParameterValuesFromFormContent() throws Exception {
145154
request.addParameter("name", "value1");
146155
request.addParameter("name", "value2");
147156
request.setContent("anotherName=anotherValue".getBytes("ISO-8859-1"));
157+
148158
filter.doFilter(request, response, filterChain);
149-
150159
String[] values = filterChain.getRequest().getParameterValues("anotherName");
160+
161+
assertNotSame("Request not wrapped", request, filterChain.getRequest());
151162
assertArrayEquals(new String[]{"anotherValue"}, values);
152163
}
153164

154165
@Test
155-
public void noParameterValuesOnly() throws Exception {
166+
public void getParameterValuesInvalidName() throws Exception {
156167
request.addParameter("name", "value1");
157168
request.addParameter("name", "value2");
158169
request.setContent("anotherName=anotherValue".getBytes("ISO-8859-1"));
170+
159171
filter.doFilter(request, response, filterChain);
160-
161172
String[] values = filterChain.getRequest().getParameterValues("noSuchParameter");
173+
174+
assertNotSame("Request not wrapped", request, filterChain.getRequest());
162175
assertNull(values);
163176
}
164177

@@ -167,9 +180,11 @@ public void getParameterMap() throws Exception {
167180
request.addParameter("name", "value1");
168181
request.addParameter("name", "value2");
169182
request.setContent("name=value3&name4=value4".getBytes("ISO-8859-1"));
170-
filter.doFilter(request, response, filterChain);
171183

184+
filter.doFilter(request, response, filterChain);
172185
Map<String, String[]> parameters = filterChain.getRequest().getParameterMap();
186+
187+
assertNotSame("Request not wrapped", request, filterChain.getRequest());
173188
assertEquals(2, parameters.size());
174189
assertArrayEquals(new String[] {"value1", "value2", "value3"}, parameters.get("name"));
175190
assertArrayEquals(new String[] {"value4"}, parameters.get("name4"));

0 commit comments

Comments
 (0)