diff --git a/spring-web/src/main/java/org/springframework/http/converter/StringHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/StringHttpMessageConverter.java index 8b8793e277eb..5a408d874976 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/StringHttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/StringHttpMessageConverter.java @@ -93,7 +93,11 @@ public boolean supports(Class clazz) { @Override protected String readInternal(Class clazz, HttpInputMessage inputMessage) throws IOException { Charset charset = getContentTypeCharset(inputMessage.getHeaders().getContentType()); - return StreamUtils.copyToString(inputMessage.getBody(), charset); + long length = inputMessage.getHeaders().getContentLength(); + byte[] bytes = (length >= 0 && length <= Integer.MAX_VALUE ? + inputMessage.getBody().readNBytes((int) length) : + inputMessage.getBody().readAllBytes()); + return new String(bytes, charset); } @Override 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 ee2af3a17e6a..47789cf114f5 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 @@ -209,7 +209,7 @@ public InetSocketAddress getRemoteAddress() { @Override public InputStream getBody() throws IOException { - if (isFormPost(this.servletRequest)) { + if (isFormPost(this.servletRequest) && this.servletRequest.getQueryString() == null) { return getBodyFromServletRequestParameters(this.servletRequest); } else { 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 d2ccc761e7b0..91eb6c1a1f90 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2023 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. @@ -167,9 +167,8 @@ void getBody() throws IOException { assertThat(result).as("Invalid content returned").isEqualTo(content); } - @Test + @Test // gh-13318 void getFormBody() throws IOException { - // Charset (SPR-8676) mockRequest.setContentType("application/x-www-form-urlencoded; charset=UTF-8"); mockRequest.setMethod("POST"); mockRequest.addParameter("name 1", "value 1"); @@ -177,8 +176,7 @@ void getFormBody() throws IOException { mockRequest.addParameter("name 3", (String) null); byte[] result = FileCopyUtils.copyToByteArray(request.getBody()); - byte[] content = "name+1=value+1&name+2=value+2%2B1&name+2=value+2%2B2&name+3".getBytes( - StandardCharsets.UTF_8); + byte[] content = "name+1=value+1&name+2=value+2%2B1&name+2=value+2%2B2&name+3".getBytes(StandardCharsets.UTF_8); assertThat(result).as("Invalid content returned").isEqualTo(content); } @@ -192,4 +190,18 @@ void getEmptyFormBody() throws IOException { assertThat(result).as("Invalid content returned").isEqualTo(content); } + @Test // gh-31327 + void getFormBodyWhenQueryParamsAlsoPresent() throws IOException { + mockRequest.setContentType("application/x-www-form-urlencoded; charset=UTF-8"); + mockRequest.setMethod("POST"); + mockRequest.setQueryString("q=1"); + mockRequest.addParameter("q", "1"); + mockRequest.setContent("foo=bar".getBytes(StandardCharsets.UTF_8)); + mockRequest.addHeader("Content-Length", 7); + + byte[] result = FileCopyUtils.copyToByteArray(request.getBody()); + byte[] content = "foo=bar".getBytes(StandardCharsets.UTF_8); + assertThat(result).as("Invalid content returned").isEqualTo(content); + } + }