From ce5189a0a03e78cdd6c2ada96b8d692d663e0340 Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Thu, 8 Jun 2023 16:31:53 +0200 Subject: [PATCH] Default ServerWebExchange::cleanupMultipart implementation This commit provided a default implementation for ServerWebExchange::cleanupMultipart. See gh-30590 --- .../web/server/ServerWebExchange.java | 10 +++++- .../server/DefaultServerRequestBuilder.java | 32 ++++--------------- 2 files changed, 16 insertions(+), 26 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/web/server/ServerWebExchange.java b/spring-web/src/main/java/org/springframework/web/server/ServerWebExchange.java index bdd01bba6567..c1f758c7e771 100644 --- a/spring-web/src/main/java/org/springframework/web/server/ServerWebExchange.java +++ b/spring-web/src/main/java/org/springframework/web/server/ServerWebExchange.java @@ -146,7 +146,15 @@ default T getAttributeOrDefault(String name, T defaultValue) { * @since 6.0.10 * @see Part#delete() */ - Mono cleanupMultipart(); + default Mono cleanupMultipart() { + return getMultipartData() + .onErrorResume(t -> Mono.empty()) // ignore errors reading multipart data + .flatMapIterable(Map::values) + .flatMapIterable(Function.identity()) + .flatMap(part -> part.delete() + .onErrorResume(ex -> Mono.empty())) + .then(); + } /** * Return the {@link LocaleContext} using the configured diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerRequestBuilder.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerRequestBuilder.java index 3cf12536f8e5..a97fbd902563 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerRequestBuilder.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerRequestBuilder.java @@ -324,30 +324,28 @@ private static class DelegatingServerWebExchange implements ServerWebExchange { private final Mono> multipartDataMono; - private volatile boolean multipartRead = false; - - DelegatingServerWebExchange(ServerHttpRequest request, Map attributes, ServerWebExchange delegate, List> messageReaders) { this.request = request; this.attributes = attributes; this.delegate = delegate; - this.formDataMono = initFormData(messageReaders); + this.formDataMono = initFormData(request, messageReaders); this.multipartDataMono = initMultipartData(request, messageReaders); } @SuppressWarnings("unchecked") - private Mono> initFormData(List> readers) { + private static Mono> initFormData(ServerHttpRequest request, + List> readers) { + try { - MediaType contentType = this.request.getHeaders().getContentType(); + MediaType contentType = request.getHeaders().getContentType(); if (MediaType.APPLICATION_FORM_URLENCODED.isCompatibleWith(contentType)) { return ((HttpMessageReader>) readers.stream() .filter(reader -> reader.canRead(FORM_DATA_TYPE, MediaType.APPLICATION_FORM_URLENCODED)) .findFirst() .orElseThrow(() -> new IllegalStateException("No form data HttpMessageReader."))) - .readMono(FORM_DATA_TYPE, this.request, Hints.none()) - .doOnNext(ignored -> this.multipartRead = true) + .readMono(FORM_DATA_TYPE, request, Hints.none()) .switchIfEmpty(EMPTY_FORM_DATA) .cache(); } @@ -400,23 +398,7 @@ public Mono> getMultipartData() { return this.multipartDataMono; } - @Override - public Mono cleanupMultipart() { - if (this.multipartRead) { - return getMultipartData() - .onErrorResume(t -> Mono.empty()) // ignore errors reading multipart data - .flatMapIterable(Map::values) - .flatMapIterable(Function.identity()) - .flatMap(part -> part.delete() - .onErrorResume(ex -> Mono.empty())) - .then(); - } - else { - return Mono.empty(); - } - } - - // Delegating methods + // Delegating methods @Override public ServerHttpResponse getResponse() {