non-file parts are rejected with {@link DataBufferLimitException}.
*
* By default this is set to 256K.
- *
Note that this property is ignored when
- * {@linkplain #setStreaming(boolean) streaming} is enabled.
* @param maxInMemorySize the in-memory limit in bytes; if set to -1 the entire
* contents will be stored in memory
*/
@@ -112,7 +108,6 @@ public class DefaultPartHttpMessageReader extends LoggingCodecSupport implements
* Configure the maximum amount of disk space allowed for file parts.
*
By default this is set to -1, meaning that there is no maximum.
*
Note that this property is ignored when
- * {@linkplain #setStreaming(boolean) streaming} is enabled, or when
* {@link #setMaxInMemorySize(int) maxInMemorySize} is set to -1.
*/
public void setMaxDiskUsagePerPart(long maxDiskUsagePerPart) {
@@ -133,7 +128,6 @@ public class DefaultPartHttpMessageReader extends LoggingCodecSupport implements
* named {@code spring-webflux-multipart} is created under the system
* temporary directory.
*
Note that this property is ignored when
- * {@linkplain #setStreaming(boolean) streaming} is enabled, or when
* {@link #setMaxInMemorySize(int) maxInMemorySize} is set to -1.
* @throws IOException if an I/O error occurs, or the parent directory
* does not exist
@@ -149,7 +143,6 @@ public class DefaultPartHttpMessageReader extends LoggingCodecSupport implements
* {@link Schedulers#boundedElastic()} is used, but this property allows for
* changing it to an externally managed scheduler.
*
Note that this property is ignored when
- * {@linkplain #setStreaming(boolean) streaming} is enabled, or when
* {@link #setMaxInMemorySize(int) maxInMemorySize} is set to -1.
* @see Schedulers#newBoundedElastic
*/
@@ -162,30 +155,6 @@ public class DefaultPartHttpMessageReader extends LoggingCodecSupport implements
return this.blockingOperationScheduler;
}
- /**
- * When set to {@code true}, the {@linkplain Part#content() part content}
- * is streamed directly from the parsed input buffer stream, and not stored
- * in memory nor file.
- * When {@code false}, parts are backed by
- * in-memory and/or file storage. Defaults to {@code false}.
- *
NOTE that with streaming enabled, the
- * {@code Flux} that is produced by this message reader must be
- * consumed in the original order, i.e. the order of the HTTP message.
- * Additionally, the {@linkplain Part#content() body contents} must either
- * be completely consumed or canceled before moving to the next part.
- * Also note that enabling this property effectively ignores
- * {@link #setMaxInMemorySize(int) maxInMemorySize},
- * {@link #setMaxDiskUsagePerPart(long) maxDiskUsagePerPart},
- * {@link #setFileStorageDirectory(Path) fileStorageDirectory}, and
- * {@link #setBlockingOperationScheduler(Scheduler) fileCreationScheduler}.
- * @deprecated as of 6.0, in favor of {@link PartEvent} and
- * {@link PartEventHttpMessageReader}
- */
- @Deprecated(since = "6.0", forRemoval = true)
- public void setStreaming(boolean streaming) {
- this.streaming = streaming;
- }
-
/**
* Set the character set used to decode headers.
* Defaults to UTF-8 as per RFC 7578.
@@ -236,7 +205,7 @@ public class DefaultPartHttpMessageReader extends LoggingCodecSupport implements
}
else {
return PartGenerator.createPart(partsTokens,
- this.maxInMemorySize, this.maxDiskUsagePerPart, this.streaming,
+ this.maxInMemorySize, this.maxDiskUsagePerPart,
this.fileStorage.directory(), this.blockingOperationScheduler);
}
});
diff --git a/spring-web/src/main/java/org/springframework/http/codec/multipart/PartGenerator.java b/spring-web/src/main/java/org/springframework/http/codec/multipart/PartGenerator.java
index c00189e068f..6519b8c7b0d 100644
--- a/spring-web/src/main/java/org/springframework/http/codec/multipart/PartGenerator.java
+++ b/spring-web/src/main/java/org/springframework/http/codec/multipart/PartGenerator.java
@@ -38,7 +38,6 @@ import org.apache.commons.logging.LogFactory;
import org.reactivestreams.Subscription;
import reactor.core.publisher.BaseSubscriber;
import reactor.core.publisher.Flux;
-import reactor.core.publisher.FluxSink;
import reactor.core.publisher.Mono;
import reactor.core.publisher.MonoSink;
import reactor.core.scheduler.Scheduler;
@@ -68,8 +67,6 @@ final class PartGenerator extends BaseSubscriber {
private final MonoSink sink;
- private final boolean streaming;
-
private final int maxInMemorySize;
private final long maxDiskUsagePerPart;
@@ -80,12 +77,11 @@ final class PartGenerator extends BaseSubscriber {
private PartGenerator(MonoSink sink, int maxInMemorySize, long maxDiskUsagePerPart,
- boolean streaming, Mono fileStorageDirectory, Scheduler blockingOperationScheduler) {
+ Mono fileStorageDirectory, Scheduler blockingOperationScheduler) {
this.sink = sink;
this.maxInMemorySize = maxInMemorySize;
this.maxDiskUsagePerPart = maxDiskUsagePerPart;
- this.streaming = streaming;
this.fileStorageDirectory = fileStorageDirectory;
this.blockingOperationScheduler = blockingOperationScheduler;
}
@@ -94,11 +90,10 @@ final class PartGenerator extends BaseSubscriber {
* Creates parts from a given stream of tokens.
*/
public static Mono createPart(Flux tokens, int maxInMemorySize,
- long maxDiskUsagePerPart, boolean streaming, Mono fileStorageDirectory,
- Scheduler blockingOperationScheduler) {
+ long maxDiskUsagePerPart, Mono fileStorageDirectory, Scheduler blockingOperationScheduler) {
return Mono.create(sink -> {
- PartGenerator generator = new PartGenerator(sink, maxInMemorySize, maxDiskUsagePerPart, streaming,
+ PartGenerator generator = new PartGenerator(sink, maxInMemorySize, maxDiskUsagePerPart,
fileStorageDirectory, blockingOperationScheduler);
sink.onCancel(generator);
@@ -134,20 +129,10 @@ final class PartGenerator extends BaseSubscriber {
changeState(currentState, new FormFieldState(headers));
requestToken();
}
- else if (!this.streaming) {
+ else {
changeState(currentState, new InMemoryState(headers));
requestToken();
}
- else {
- Flux streamingContent = Flux.create(contentSink -> {
- State newState = new StreamingState(contentSink);
- if (changeState(currentState, newState)) {
- contentSink.onRequest(l -> requestToken());
- requestToken();
- }
- });
- emitPart(DefaultParts.part(headers, streamingContent));
- }
}
@Override
@@ -225,8 +210,6 @@ final class PartGenerator extends BaseSubscriber {
*
* - If the part is a {@linkplain MultipartUtils#isFormField(HttpHeaders) form field},
* the creator will be in the {@link FormFieldState}.
- * - If {@linkplain #streaming} is enabled, the creator will be in the
- * {@link StreamingState}.
* - Otherwise, the creator will initially be in the
* {@link InMemoryState}, but will switch over to {@link CreateFileState}
* when the part byte count exceeds {@link #maxInMemorySize},
@@ -352,61 +335,11 @@ final class PartGenerator extends BaseSubscriber {
/**
- * The creator state when {@link #streaming} is {@code true} (and not
- * handling a form field). Relays all received buffers to a sink.
- */
- private final class StreamingState implements State {
-
- private final FluxSink bodySink;
-
- public StreamingState(FluxSink bodySink) {
- this.bodySink = bodySink;
- }
-
- @Override
- public void body(DataBuffer dataBuffer) {
- if (!this.bodySink.isCancelled()) {
- this.bodySink.next(dataBuffer);
- if (this.bodySink.requestedFromDownstream() > 0) {
- requestToken();
- }
- }
- else {
- DataBufferUtils.release(dataBuffer);
- // even though the body sink is canceled, the (outer) part sink
- // might not be, so request another token
- requestToken();
- }
- }
-
- @Override
- public void onComplete() {
- if (!this.bodySink.isCancelled()) {
- this.bodySink.complete();
- }
- }
-
- @Override
- public void error(Throwable throwable) {
- if (!this.bodySink.isCancelled()) {
- this.bodySink.error(throwable);
- }
- }
-
- @Override
- public String toString() {
- return "STREAMING";
- }
-
- }
-
-
- /**
- * The creator state when {@link #streaming} is {@code false} (and not
- * handling a form field). Stores all received buffers in a queue.
+ * The creator state when not handling a form field.
+ * Stores all received buffers in a queue.
* If the byte count exceeds {@link #maxInMemorySize}, the creator state
* is changed to {@link CreateFileState}, and eventually to
- * {@link CreateFileState}.
+ * {@link WritingFileState}.
*/
private final class InMemoryState implements State {
diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractServerHttpRequest.java b/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractServerHttpRequest.java
index 0abd973b56f..829a2202a81 100644
--- a/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractServerHttpRequest.java
+++ b/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractServerHttpRequest.java
@@ -51,8 +51,6 @@ public abstract class AbstractServerHttpRequest implements ServerHttpRequest {
private final HttpHeaders headers;
- // TODO: remove @Nullable once deprecated constructors have been removed
- @Nullable
private final HttpMethod method;
@Nullable
@@ -71,22 +69,6 @@ public abstract class AbstractServerHttpRequest implements ServerHttpRequest {
private String logPrefix;
- /**
- * Constructor with the URI and headers for the request.
- * @param uri the URI for the request
- * @param contextPath the context path for the request
- * @param headers the headers for the request (as {@link MultiValueMap})
- * @since 5.3
- * @deprecated since 6.0.8, in favor of {@link #AbstractServerHttpRequest(HttpMethod, URI, String, MultiValueMap)}
- */
- @Deprecated(since = "6.0.8", forRemoval = true)
- public AbstractServerHttpRequest(URI uri, @Nullable String contextPath, MultiValueMap headers) {
- this.uri = uri;
- this.path = RequestPath.parse(uri, contextPath);
- this.headers = HttpHeaders.readOnlyHttpHeaders(headers);
- this.method = null;
- }
-
/**
* Constructor with the method, URI and headers for the request.
* @param method the HTTP method for the request
@@ -108,21 +90,6 @@ public abstract class AbstractServerHttpRequest implements ServerHttpRequest {
this.headers = HttpHeaders.readOnlyHttpHeaders(headers);
}
- /**
- * Constructor with the URI and headers for the request.
- * @param uri the URI for the request
- * @param contextPath the context path for the request
- * @param headers the headers for the request (as {@link HttpHeaders})
- * @deprecated since 6.0.8, in favor of {@link #AbstractServerHttpRequest(HttpMethod, URI, String, MultiValueMap)}
- */
- @Deprecated(since = "6.0.8", forRemoval = true)
- public AbstractServerHttpRequest(URI uri, @Nullable String contextPath, HttpHeaders headers) {
- this.uri = uri;
- this.path = RequestPath.parse(uri, contextPath);
- this.headers = HttpHeaders.readOnlyHttpHeaders(headers);
- this.method = null;
- }
-
@Override
public String getId() {
@@ -147,14 +114,7 @@ public abstract class AbstractServerHttpRequest implements ServerHttpRequest {
@Override
public HttpMethod getMethod() {
- // TODO: remove null check once deprecated constructors have been removed
- if (this.method != null) {
- return this.method;
- }
- else {
- throw new IllegalStateException("No HttpMethod provided in constructor, " +
- "and AbstractServerHttpRequest::getMethod not overridden");
- }
+ return this.method;
}
@Override
diff --git a/spring-web/src/test/java/org/springframework/http/codec/multipart/DefaultPartHttpMessageReaderTests.java b/spring-web/src/test/java/org/springframework/http/codec/multipart/DefaultPartHttpMessageReaderTests.java
index 1c9596fb5b1..7dd36e0bbf9 100644
--- a/spring-web/src/test/java/org/springframework/http/codec/multipart/DefaultPartHttpMessageReaderTests.java
+++ b/spring-web/src/test/java/org/springframework/http/codec/multipart/DefaultPartHttpMessageReaderTests.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.
@@ -420,9 +420,6 @@ class DefaultPartHttpMessageReaderTests {
@SuppressWarnings("removal")
static Stream messageReaders() {
- DefaultPartHttpMessageReader streaming = new DefaultPartHttpMessageReader();
- streaming.setStreaming(true);
-
DefaultPartHttpMessageReader inMemory = new DefaultPartHttpMessageReader();
inMemory.setMaxInMemorySize(1000);
@@ -430,7 +427,6 @@ class DefaultPartHttpMessageReaderTests {
onDisk.setMaxInMemorySize(100);
return Stream.of(
- arguments(named("streaming", streaming)),
arguments(named("in-memory", inMemory)),
arguments(named("on-disk", onDisk)));
}