Skip to content

Commit 40bf550

Browse files
committed
Ensure multipart data is deleted in WebFlux when connection terminates
Before this change temporary files would not consistently be deleted when the connection which uploads the multipart files closes naturally. This change uses the usingWhen Reactor operator to ensure that the termination of the connection doesn't prevent individual file parts from being deleted due to a cancellation signal. See gh-31217 Closes gh-32638
1 parent f3bdce4 commit 40bf550

File tree

1 file changed

+10
-7
lines changed

1 file changed

+10
-7
lines changed

Diff for: spring-web/src/main/java/org/springframework/web/server/adapter/DefaultServerWebExchange.java

+10-7
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@
2424
import java.util.Set;
2525
import java.util.concurrent.ConcurrentHashMap;
2626
import java.util.function.Function;
27+
import java.util.stream.Collectors;
2728

29+
import reactor.core.publisher.Flux;
2830
import reactor.core.publisher.Mono;
2931

3032
import org.springframework.context.ApplicationContext;
@@ -249,20 +251,21 @@ public Mono<MultiValueMap<String, Part>> getMultipartData() {
249251
public Mono<Void> cleanupMultipart() {
250252
return Mono.defer(() -> {
251253
if (this.multipartRead) {
252-
return getMultipartData()
253-
.onErrorComplete()
254-
.flatMapIterable(Map::values)
255-
.flatMapIterable(Function.identity())
256-
.flatMap(part -> part.delete()
257-
.onErrorComplete())
258-
.then();
254+
return Mono.usingWhen(getMultipartData().onErrorComplete().map(this::collectParts),
255+
parts -> Mono.empty(),
256+
parts -> Flux.fromIterable(parts).flatMap(part -> part.delete().onErrorComplete())
257+
);
259258
}
260259
else {
261260
return Mono.empty();
262261
}
263262
});
264263
}
265264

265+
private List<Part> collectParts(MultiValueMap<String, Part> multipartData) {
266+
return multipartData.values().stream().flatMap(List::stream).collect(Collectors.toList());
267+
}
268+
266269
@Override
267270
public LocaleContext getLocaleContext() {
268271
return this.localeContextResolver.resolveLocaleContext(this);

0 commit comments

Comments
 (0)