diff --git a/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpRequest.java b/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpRequest.java index da932206c85..d5045c137dd 100644 --- a/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpRequest.java @@ -270,7 +270,8 @@ public class ServletServerHttpRequest implements ServerHttpRequest { */ private InputStream getBodyFromServletRequestParameters(HttpServletRequest request) throws IOException { ByteArrayOutputStream bos = new ByteArrayOutputStream(1024); - Writer writer = new OutputStreamWriter(bos, FORM_CHARSET); + Charset charset = getFormCharset(); + Writer writer = new OutputStreamWriter(bos, charset); Map form = request.getParameterMap(); for (Iterator> entryItr = form.entrySet().iterator(); entryItr.hasNext();) { @@ -278,10 +279,10 @@ public class ServletServerHttpRequest implements ServerHttpRequest { List values = Arrays.asList(entry.getValue()); for (Iterator valueItr = values.iterator(); valueItr.hasNext();) { String value = valueItr.next(); - writer.write(URLEncoder.encode(entry.getKey(), FORM_CHARSET)); + writer.write(URLEncoder.encode(entry.getKey(), charset)); if (value != null) { writer.write('='); - writer.write(URLEncoder.encode(value, FORM_CHARSET)); + writer.write(URLEncoder.encode(value, charset)); if (valueItr.hasNext()) { writer.write('&'); } @@ -301,6 +302,19 @@ public class ServletServerHttpRequest implements ServerHttpRequest { return new ByteArrayInputStream(bytes); } + private Charset getFormCharset() { + try { + MediaType contentType = getHeaders().getContentType(); + if (contentType != null && contentType.getCharset() != null) { + return contentType.getCharset(); + } + } + catch (Exception ex) { + // ignore + } + return FORM_CHARSET; + } + private final class AttributesMap extends AbstractMap { diff --git a/spring-web/src/test/java/org/springframework/http/server/ServletServerHttpRequestTests.java b/spring-web/src/test/java/org/springframework/http/server/ServletServerHttpRequestTests.java index 55fd33e08eb..87994561e68 100644 --- a/spring-web/src/test/java/org/springframework/http/server/ServletServerHttpRequestTests.java +++ b/spring-web/src/test/java/org/springframework/http/server/ServletServerHttpRequestTests.java @@ -18,6 +18,7 @@ package org.springframework.http.server; import java.io.IOException; import java.net.URI; +import java.net.URLDecoder; import java.nio.charset.StandardCharsets; import java.util.List; @@ -217,6 +218,16 @@ class ServletServerHttpRequestTests { assertThat(request.getHeaders().getContentLength()).isEqualTo(contentLength); } + @Test // gh-34675 + void getFormBodyWithNotUtf8Charset() throws IOException { + String charset = "windows-1251"; + mockRequest.setContentType("application/x-www-form-urlencoded; charset=" + charset); + mockRequest.setMethod("POST"); + mockRequest.addParameter("x", URLDecoder.decode("%e0%e0%e0", charset)); + + assertFormContent("x=%E0%E0%E0"); + } + private int assertFormContent(String expected) throws IOException { byte[] result = FileCopyUtils.copyToByteArray(request.getBody()); byte[] content = expected.getBytes(StandardCharsets.UTF_8);