Skip to content

Commit

Permalink
Ensure multipart data is deleted in WebFlux when connection terminates
Browse files Browse the repository at this point in the history
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 spring-projectsgh-31217
Closes spring-projectsgh-32638
  • Loading branch information
simonbasle committed Apr 15, 2024
1 parent f3bdce4 commit 40bf550
Showing 1 changed file with 10 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.stream.Collectors;

import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import org.springframework.context.ApplicationContext;
Expand Down Expand Up @@ -249,20 +251,21 @@ public Mono<MultiValueMap<String, Part>> getMultipartData() {
public Mono<Void> cleanupMultipart() {
return Mono.defer(() -> {
if (this.multipartRead) {
return getMultipartData()
.onErrorComplete()
.flatMapIterable(Map::values)
.flatMapIterable(Function.identity())
.flatMap(part -> part.delete()
.onErrorComplete())
.then();
return Mono.usingWhen(getMultipartData().onErrorComplete().map(this::collectParts),
parts -> Mono.empty(),
parts -> Flux.fromIterable(parts).flatMap(part -> part.delete().onErrorComplete())
);
}
else {
return Mono.empty();
}
});
}

private List<Part> collectParts(MultiValueMap<String, Part> multipartData) {
return multipartData.values().stream().flatMap(List::stream).collect(Collectors.toList());
}

@Override
public LocaleContext getLocaleContext() {
return this.localeContextResolver.resolveLocaleContext(this);
Expand Down

0 comments on commit 40bf550

Please sign in to comment.