diff --git a/today-web/src/main/java/cn/taketoday/http/codec/multipart/PartEventHttpMessageReader.java b/today-web/src/main/java/cn/taketoday/http/codec/multipart/PartEventHttpMessageReader.java index afb2b7cce1..f237de5108 100644 --- a/today-web/src/main/java/cn/taketoday/http/codec/multipart/PartEventHttpMessageReader.java +++ b/today-web/src/main/java/cn/taketoday/http/codec/multipart/PartEventHttpMessageReader.java @@ -191,7 +191,14 @@ private boolean tooManyParts(AtomicInteger partCount) { private Publisher createEvents(HttpHeaders headers, Flux bodyTokens) { if (MultipartUtils.isFormField(headers)) { Flux contents = bodyTokens.map(MultipartParser.BodyToken::getBuffer); - int maxSize = (int) Math.min(this.maxInMemorySize, this.maxPartSize); + int maxSize; + if (this.maxPartSize == -1) { + maxSize = this.maxInMemorySize; + } + else { + // maxInMemorySize is an int, so we can safely cast the long result of Math.min + maxSize = (int) Math.min(this.maxInMemorySize, this.maxPartSize); + } return DataBufferUtils.join(contents, maxSize) .map(content -> { String value = content.toString(MultipartUtils.charset(headers)); @@ -222,8 +229,12 @@ private Publisher createEvents(HttpHeaders headers, Flux 0 && size > this.maxPartSize; + if (this.maxPartSize != -1) { + long size = partSize.addAndGet(buffer.readableByteCount()); + return size > this.maxPartSize; + } + else { + return false; + } } - } diff --git a/today-web/src/test/java/cn/taketoday/http/codec/multipart/PartEventHttpMessageReaderTests.java b/today-web/src/test/java/cn/taketoday/http/codec/multipart/PartEventHttpMessageReaderTests.java index 5a49fa4ade..c4e2d30d32 100644 --- a/today-web/src/test/java/cn/taketoday/http/codec/multipart/PartEventHttpMessageReaderTests.java +++ b/today-web/src/test/java/cn/taketoday/http/codec/multipart/PartEventHttpMessageReaderTests.java @@ -17,7 +17,6 @@ package cn.taketoday.http.codec.multipart; -import org.assertj.core.api.AssertionsForClassTypes; import org.junit.jupiter.api.Test; import java.nio.charset.StandardCharsets; @@ -46,6 +45,7 @@ import static java.util.Collections.emptyMap; import static java.util.Collections.singletonMap; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.AssertionsForClassTypes.entry; /** * @author Harry Yang @@ -146,8 +146,8 @@ public void noBody() { Flux result = this.reader.read(forClass(PartEvent.class), request, emptyMap()); StepVerifier.create(result) - .assertNext(form(headers -> assertThat(headers).contains(AssertionsForClassTypes.entry("Part", List.of("1"))), "")) - .assertNext(data(headers -> assertThat(headers).contains(AssertionsForClassTypes.entry("Part", List.of("2"))), bodyText("a"), true)) + .assertNext(form(headers -> assertThat(headers).contains(entry("Part", List.of("1"))), "")) + .assertNext(data(headers -> assertThat(headers).contains(entry("Part", List.of("2"))), bodyText("a"), true)) .verifyComplete(); } @@ -258,7 +258,21 @@ void partSizeTooLarge() { .assertNext(data(headersFormField("text2"), bodyText("b"), true)) .expectError(DataBufferLimitException.class) .verify(); + } + + @Test + void formPartTooLarge() { + MockServerHttpRequest request = createRequest( + new ClassPathResource("simple.multipart", getClass()), "simple-boundary"); + + PartEventHttpMessageReader reader = new PartEventHttpMessageReader(); + reader.setMaxInMemorySize(40); + + Flux result = reader.read(forClass(PartEvent.class), request, emptyMap()); + StepVerifier.create(result) + .expectError(DataBufferLimitException.class) + .verify(); } @Test