Skip to content

Commit c35aac0

Browse files
committed
Merge branch '6.2.x'
2 parents a787088 + 290c9c4 commit c35aac0

File tree

2 files changed

+47
-23
lines changed

2 files changed

+47
-23
lines changed

spring-web/src/main/java/org/springframework/http/server/ServletServerHttpRequest.java

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -266,25 +266,25 @@ private static boolean isFormPost(HttpServletRequest request) {
266266
*/
267267
private InputStream getBodyFromServletRequestParameters(HttpServletRequest request) throws IOException {
268268
ByteArrayOutputStream bos = new ByteArrayOutputStream(1024);
269-
Writer writer = new OutputStreamWriter(bos, FORM_CHARSET);
269+
Charset charset = getFormCharset();
270+
Writer writer = new OutputStreamWriter(bos, charset);
270271

271272
Map<String, String[]> form = request.getParameterMap();
272-
for (Iterator<Map.Entry<String, String[]>> entryIterator = form.entrySet().iterator(); entryIterator.hasNext();) {
273-
Map.Entry<String, String[]> entry = entryIterator.next();
274-
String name = entry.getKey();
273+
for (Iterator<Map.Entry<String, String[]>> entryItr = form.entrySet().iterator(); entryItr.hasNext();) {
274+
Map.Entry<String, String[]> entry = entryItr.next();
275275
List<String> values = Arrays.asList(entry.getValue());
276-
for (Iterator<String> valueIterator = values.iterator(); valueIterator.hasNext();) {
277-
String value = valueIterator.next();
278-
writer.write(URLEncoder.encode(name, FORM_CHARSET));
276+
for (Iterator<String> valueItr = values.iterator(); valueItr.hasNext();) {
277+
String value = valueItr.next();
278+
writer.write(URLEncoder.encode(entry.getKey(), charset));
279279
if (value != null) {
280280
writer.write('=');
281-
writer.write(URLEncoder.encode(value, FORM_CHARSET));
282-
if (valueIterator.hasNext()) {
281+
writer.write(URLEncoder.encode(value, charset));
282+
if (valueItr.hasNext()) {
283283
writer.write('&');
284284
}
285285
}
286286
}
287-
if (entryIterator.hasNext()) {
287+
if (entryItr.hasNext()) {
288288
writer.append('&');
289289
}
290290
}
@@ -298,6 +298,19 @@ private InputStream getBodyFromServletRequestParameters(HttpServletRequest reque
298298
return new ByteArrayInputStream(bytes);
299299
}
300300

301+
private Charset getFormCharset() {
302+
try {
303+
MediaType contentType = getHeaders().getContentType();
304+
if (contentType != null && contentType.getCharset() != null) {
305+
return contentType.getCharset();
306+
}
307+
}
308+
catch (Exception ex) {
309+
// ignore
310+
}
311+
return FORM_CHARSET;
312+
}
313+
301314

302315
private final class AttributesMap extends AbstractMap<String, Object> {
303316

spring-web/src/test/java/org/springframework/http/server/ServletServerHttpRequestTests.java

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@
1818

1919
import java.io.IOException;
2020
import java.net.URI;
21+
import java.net.URLDecoder;
2122
import java.nio.charset.StandardCharsets;
2223
import java.util.List;
2324

@@ -182,19 +183,15 @@ void getFormBody() throws IOException {
182183
mockRequest.addParameter("name 2", "value 2+1", "value 2+2");
183184
mockRequest.addParameter("name 3", (String) null);
184185

185-
byte[] result = FileCopyUtils.copyToByteArray(request.getBody());
186-
byte[] content = "name+1=value+1&name+2=value+2%2B1&name+2=value+2%2B2&name+3".getBytes(StandardCharsets.UTF_8);
187-
assertThat(result).as("Invalid content returned").isEqualTo(content);
186+
assertFormContent("name+1=value+1&name+2=value+2%2B1&name+2=value+2%2B2&name+3");
188187
}
189188

190189
@Test
191190
void getEmptyFormBody() throws IOException {
192191
mockRequest.setContentType("application/x-www-form-urlencoded; charset=UTF-8");
193192
mockRequest.setMethod("POST");
194193

195-
byte[] result = FileCopyUtils.copyToByteArray(request.getBody());
196-
byte[] content = "".getBytes(StandardCharsets.UTF_8);
197-
assertThat(result).as("Invalid content returned").isEqualTo(content);
194+
assertFormContent("");
198195
}
199196

200197
@Test // gh-31327
@@ -206,9 +203,7 @@ void getFormBodyWhenQueryParamsAlsoPresent() throws IOException {
206203
mockRequest.setContent("foo=bar".getBytes(StandardCharsets.UTF_8));
207204
mockRequest.addHeader("Content-Length", 7);
208205

209-
byte[] result = FileCopyUtils.copyToByteArray(request.getBody());
210-
byte[] content = "foo=bar".getBytes(StandardCharsets.UTF_8);
211-
assertThat(result).as("Invalid content returned").isEqualTo(content);
206+
assertFormContent("foo=bar");
212207
}
213208

214209
@Test // gh-32471
@@ -219,9 +214,25 @@ void getFormBodyWhenNotEncodedCharactersPresent() throws IOException {
219214
mockRequest.addParameter("lastName", "Test@er");
220215
mockRequest.addHeader("Content-Length", 26);
221216

217+
int contentLength = assertFormContent("name=Test&lastName=Test%40er");
218+
assertThat(request.getHeaders().getContentLength()).isEqualTo(contentLength);
219+
}
220+
221+
@Test // gh-34675
222+
void getFormBodyWithNotUtf8Charset() throws IOException {
223+
String charset = "windows-1251";
224+
mockRequest.setContentType("application/x-www-form-urlencoded; charset=" + charset);
225+
mockRequest.setMethod("POST");
226+
mockRequest.addParameter("x", URLDecoder.decode("%e0%e0%e0", charset));
227+
228+
assertFormContent("x=%E0%E0%E0");
229+
}
230+
231+
private int assertFormContent(String expected) throws IOException {
222232
byte[] result = FileCopyUtils.copyToByteArray(request.getBody());
223-
assertThat(result).isEqualTo("name=Test&lastName=Test%40er".getBytes(StandardCharsets.UTF_8));
224-
assertThat(request.getHeaders().getContentLength()).isEqualTo(result.length);
233+
byte[] content = expected.getBytes(StandardCharsets.UTF_8);
234+
assertThat(result).as("Invalid content returned").isEqualTo(content);
235+
return result.length;
225236
}
226237

227238
@Test

0 commit comments

Comments
 (0)