Merge branch '7.0.x'

This commit is contained in:
Brian Clozel
2026-04-28 23:36:56 +02:00
5 changed files with 45 additions and 18 deletions
@@ -28,7 +28,6 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;
import io.netty.buffer.PooledByteBufAllocator;
import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
@@ -45,9 +44,9 @@ import org.springframework.core.codec.DecodingException;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.core.io.buffer.DataBufferLimitException;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.core.io.buffer.NettyDataBufferFactory;
import org.springframework.core.testfixture.io.buffer.AbstractLeakCheckingTests;
import org.springframework.http.MediaType;
import org.springframework.web.testfixture.http.server.reactive.MockServerHttpRequest;
@@ -60,9 +59,12 @@ import static org.springframework.core.ResolvableType.forClass;
import static org.springframework.core.io.buffer.DataBufferUtils.release;
/**
* Tests for {@link DefaultPartHttpMessageReader}.
*
* @author Arjen Poutsma
* @author Brian Clozel
*/
class DefaultPartHttpMessageReaderTests {
class DefaultPartHttpMessageReaderTests extends AbstractLeakCheckingTests {
private static final String LOREM_IPSUM = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer iaculis metus id vestibulum nullam.";
@@ -70,7 +72,6 @@ class DefaultPartHttpMessageReaderTests {
private static final int BUFFER_SIZE = 64;
private static final DataBufferFactory bufferFactory = new NettyDataBufferFactory(new PooledByteBufAllocator());
@ParameterizedDefaultPartHttpMessageReaderTest
void canRead(DefaultPartHttpMessageReader reader) {
@@ -165,7 +166,7 @@ class DefaultPartHttpMessageReaderTests {
"simple.multipart", "simple-boundary");
Flux<Part> result = reader.read(forClass(Part.class), request, emptyMap());
StepVerifier.create(result, 1)
StepVerifier.create(result)
.consumeNextWith(part -> part.content().subscribe(DataBufferUtils::release))
.thenCancel()
.verify();
@@ -221,7 +222,7 @@ class DefaultPartHttpMessageReaderTests {
@Test
void tooManyParts() throws InterruptedException {
MockServerHttpRequest request = createRequest(
"simple.multipart", "simple-boundary");
"files.multipart", "----WebKitFormBoundaryG8fJ50opQOML0oGD");
DefaultPartHttpMessageReader reader = new DefaultPartHttpMessageReader();
reader.setMaxParts(1);
@@ -230,8 +231,7 @@ class DefaultPartHttpMessageReaderTests {
CountDownLatch latch = new CountDownLatch(1);
StepVerifier.create(result)
.consumeNextWith(part -> testPart(part, null,
"This is implicitly typed plain ASCII text.\r\nIt does NOT end with a linebreak.", latch)).as("Part 1")
.consumeNextWith(part -> testBrowserFile(part, "file2", "a.txt", LOREM_IPSUM, latch)).as("Part 1")
.expectError(DecodingException.class)
.verify();
@@ -276,7 +276,7 @@ class DefaultPartHttpMessageReaderTests {
// gh-27612
@Test
void exceedHeaderLimit() throws InterruptedException {
void largeBufferForHeaderDoesNotExceedLimit() throws InterruptedException {
Flux<DataBuffer> body = DataBufferUtils
.readByteChannel(new ClassPathResource("/org/springframework/http/multipart/files.multipart")::readableChannel, bufferFactory, 282);
@@ -300,6 +300,19 @@ class DefaultPartHttpMessageReaderTests {
latch.await();
}
@Test
void exceedHeaderLimit() {
MockServerHttpRequest request = createRequest("files.multipart", "\"----WebKitFormBoundaryG8fJ50opQOML0oGD\"");
DefaultPartHttpMessageReader reader = new DefaultPartHttpMessageReader();
reader.setMaxHeadersSize(80);
Flux<Part> result = reader.read(forClass(Part.class), request, emptyMap());
StepVerifier.create(result)
.expectError(DataBufferLimitException.class)
.verify();
}
@ParameterizedDefaultPartHttpMessageReaderTest
void emptyLastPart(DefaultPartHttpMessageReader reader) throws InterruptedException {
MockServerHttpRequest request = createRequest(
@@ -20,7 +20,6 @@ import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.function.Consumer;
import io.netty.buffer.PooledByteBufAllocator;
import org.junit.jupiter.api.Test;
import reactor.core.publisher.Flux;
import reactor.test.StepVerifier;
@@ -29,10 +28,9 @@ import org.springframework.core.codec.DecodingException;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.core.io.buffer.DataBufferLimitException;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.core.io.buffer.NettyDataBufferFactory;
import org.springframework.core.testfixture.io.buffer.AbstractLeakCheckingTests;
import org.springframework.http.ContentDisposition;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
@@ -47,12 +45,10 @@ import static org.springframework.core.ResolvableType.forClass;
/**
* @author Arjen Poutsma
*/
class PartEventHttpMessageReaderTests {
class PartEventHttpMessageReaderTests extends AbstractLeakCheckingTests {
private static final int BUFFER_SIZE = 64;
private static final DataBufferFactory bufferFactory = new NettyDataBufferFactory(new PooledByteBufAllocator());
private static final MediaType TEXT_PLAIN_ASCII = new MediaType("text", "plain", StandardCharsets.US_ASCII);
private final PartEventHttpMessageReader reader = new PartEventHttpMessageReader();