Skip reconstructing body from request params if query present

This allows restoring optimization in StringHttpMessageConverter
that was undone in 23162b for 6.0.x.

Closes gh-31327
This commit is contained in:
rstoyanchev 2023-09-29 17:59:02 +01:00
parent a6ab636614
commit 8fa428f825
3 changed files with 23 additions and 7 deletions

View File

@ -93,7 +93,11 @@ public class StringHttpMessageConverter extends AbstractHttpMessageConverter<Str
@Override @Override
protected String readInternal(Class<? extends String> clazz, HttpInputMessage inputMessage) throws IOException { protected String readInternal(Class<? extends String> clazz, HttpInputMessage inputMessage) throws IOException {
Charset charset = getContentTypeCharset(inputMessage.getHeaders().getContentType()); 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 @Override

View File

@ -209,7 +209,7 @@ public class ServletServerHttpRequest implements ServerHttpRequest {
@Override @Override
public InputStream getBody() throws IOException { public InputStream getBody() throws IOException {
if (isFormPost(this.servletRequest)) { if (isFormPost(this.servletRequest) && this.servletRequest.getQueryString() == null) {
return getBodyFromServletRequestParameters(this.servletRequest); return getBodyFromServletRequestParameters(this.servletRequest);
} }
else { else {

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -167,9 +167,8 @@ public class ServletServerHttpRequestTests {
assertThat(result).as("Invalid content returned").isEqualTo(content); assertThat(result).as("Invalid content returned").isEqualTo(content);
} }
@Test @Test // gh-13318
void getFormBody() throws IOException { void getFormBody() throws IOException {
// Charset (SPR-8676)
mockRequest.setContentType("application/x-www-form-urlencoded; charset=UTF-8"); mockRequest.setContentType("application/x-www-form-urlencoded; charset=UTF-8");
mockRequest.setMethod("POST"); mockRequest.setMethod("POST");
mockRequest.addParameter("name 1", "value 1"); mockRequest.addParameter("name 1", "value 1");
@ -177,8 +176,7 @@ public class ServletServerHttpRequestTests {
mockRequest.addParameter("name 3", (String) null); mockRequest.addParameter("name 3", (String) null);
byte[] result = FileCopyUtils.copyToByteArray(request.getBody()); 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( byte[] content = "name+1=value+1&name+2=value+2%2B1&name+2=value+2%2B2&name+3".getBytes(StandardCharsets.UTF_8);
StandardCharsets.UTF_8);
assertThat(result).as("Invalid content returned").isEqualTo(content); assertThat(result).as("Invalid content returned").isEqualTo(content);
} }
@ -192,4 +190,18 @@ public class ServletServerHttpRequestTests {
assertThat(result).as("Invalid content returned").isEqualTo(content); 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);
}
} }