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 47789cf114f5..85850d138ffc 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -242,7 +242,7 @@ private static boolean isFormPost(HttpServletRequest request) { * from the body, which can fail if any other code has used the ServletRequest * to access a parameter, thus causing the input stream to be "consumed". */ - private static InputStream getBodyFromServletRequestParameters(HttpServletRequest request) throws IOException { + private InputStream getBodyFromServletRequestParameters(HttpServletRequest request) throws IOException { ByteArrayOutputStream bos = new ByteArrayOutputStream(1024); Writer writer = new OutputStreamWriter(bos, FORM_CHARSET); @@ -268,7 +268,12 @@ private static InputStream getBodyFromServletRequestParameters(HttpServletReques } writer.flush(); - return new ByteArrayInputStream(bos.toByteArray()); + byte[] bytes = bos.toByteArray(); + if (bytes.length > 0 && getHeaders().containsKey(HttpHeaders.CONTENT_LENGTH)) { + getHeaders().setContentLength(bytes.length); + } + + return new ByteArrayInputStream(bytes); } } 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 d5f67995983d..2e1792f6da6b 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 @@ -203,4 +203,17 @@ void getFormBodyWhenQueryParamsAlsoPresent() throws IOException { assertThat(result).as("Invalid content returned").isEqualTo(content); } + @Test // gh-32471 + void getFormBodyWhenNotEncodedCharactersPresent() throws IOException { + mockRequest.setContentType("application/x-www-form-urlencoded; charset=UTF-8"); + mockRequest.setMethod("POST"); + mockRequest.addParameter("name", "Test"); + mockRequest.addParameter("lastName", "Test@er"); + mockRequest.addHeader("Content-Length", 26); + + byte[] result = FileCopyUtils.copyToByteArray(request.getBody()); + assertThat(result).isEqualTo("name=Test&lastName=Test%40er".getBytes(StandardCharsets.UTF_8)); + assertThat(request.getHeaders().getContentLength()).isEqualTo(result.length); + } + }