From 10cb2ccaefa2736000ae94155ce357c1f2a6590e Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 27 Mar 2018 00:25:05 +0200 Subject: [PATCH] Avoid triggering lazy resolution in MultipartResolver.cleanupMultipart Issue: SPR-16640 --- .../commons/CommonsMultipartResolver.java | 16 +++++++++----- .../AbstractMultipartHttpServletRequest.java | 14 +++++++++++- .../StandardMultipartHttpServletRequest.java | 8 ++++--- .../StandardServletMultipartResolver.java | 22 +++++++++++-------- 4 files changed, 41 insertions(+), 19 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/web/multipart/commons/CommonsMultipartResolver.java b/spring-web/src/main/java/org/springframework/web/multipart/commons/CommonsMultipartResolver.java index af75af77955..18a7627bda4 100644 --- a/spring-web/src/main/java/org/springframework/web/multipart/commons/CommonsMultipartResolver.java +++ b/spring-web/src/main/java/org/springframework/web/multipart/commons/CommonsMultipartResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2018 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. @@ -33,6 +33,7 @@ import org.springframework.web.multipart.MaxUploadSizeExceededException; import org.springframework.web.multipart.MultipartException; import org.springframework.web.multipart.MultipartHttpServletRequest; import org.springframework.web.multipart.MultipartResolver; +import org.springframework.web.multipart.support.AbstractMultipartHttpServletRequest; import org.springframework.web.multipart.support.DefaultMultipartHttpServletRequest; import org.springframework.web.util.WebUtils; @@ -188,11 +189,14 @@ public class CommonsMultipartResolver extends CommonsFileUploadSupport @Override public void cleanupMultipart(MultipartHttpServletRequest request) { - try { - cleanupFileItems(request.getMultiFileMap()); - } - catch (Throwable ex) { - logger.warn("Failed to perform multipart cleanup for servlet request", ex); + if (!(request instanceof AbstractMultipartHttpServletRequest) || + ((AbstractMultipartHttpServletRequest) request).isResolved()) { + try { + cleanupFileItems(request.getMultiFileMap()); + } + catch (Throwable ex) { + logger.warn("Failed to perform multipart cleanup for servlet request", ex); + } } } diff --git a/spring-web/src/main/java/org/springframework/web/multipart/support/AbstractMultipartHttpServletRequest.java b/spring-web/src/main/java/org/springframework/web/multipart/support/AbstractMultipartHttpServletRequest.java index e94dca671cf..58010cc4d8c 100644 --- a/spring-web/src/main/java/org/springframework/web/multipart/support/AbstractMultipartHttpServletRequest.java +++ b/spring-web/src/main/java/org/springframework/web/multipart/support/AbstractMultipartHttpServletRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2018 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. @@ -108,6 +108,18 @@ public abstract class AbstractMultipartHttpServletRequest extends HttpServletReq return getMultipartFiles(); } + /** + * Determine whether the underlying multipart request has been resolved. + * @return {@code true} when eagerly initialized or lazily triggered, + * {@code false} in case of a lazy-resolution request that got aborted + * before any parameters or multipart files have been accessed + * @since 4.3.15 + * @see #getMultipartFiles() + */ + public boolean isResolved() { + return (this.multipartFiles != null); + } + /** * Set a Map with parameter names as keys and list of MultipartFile objects as values. diff --git a/spring-web/src/main/java/org/springframework/web/multipart/support/StandardMultipartHttpServletRequest.java b/spring-web/src/main/java/org/springframework/web/multipart/support/StandardMultipartHttpServletRequest.java index 99151906776..fa6ae7dbdaf 100644 --- a/spring-web/src/main/java/org/springframework/web/multipart/support/StandardMultipartHttpServletRequest.java +++ b/spring-web/src/main/java/org/springframework/web/multipart/support/StandardMultipartHttpServletRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2018 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. @@ -52,6 +52,7 @@ import org.springframework.web.multipart.MultipartFile; * @author Juergen Hoeller * @author Rossen Stoyanchev * @since 3.1 + * @see StandardServletMultipartResolver */ public class StandardMultipartHttpServletRequest extends AbstractMultipartHttpServletRequest { @@ -75,9 +76,10 @@ public class StandardMultipartHttpServletRequest extends AbstractMultipartHttpSe * @param lazyParsing whether multipart parsing should be triggered lazily on * first access of multipart files or parameters * @throws MultipartException if an immediate parsing attempt failed + * @since 3.2.9 */ - public StandardMultipartHttpServletRequest(HttpServletRequest request, - boolean lazyParsing) throws MultipartException { + public StandardMultipartHttpServletRequest(HttpServletRequest request, boolean lazyParsing) + throws MultipartException { super(request); if (!lazyParsing) { diff --git a/spring-web/src/main/java/org/springframework/web/multipart/support/StandardServletMultipartResolver.java b/spring-web/src/main/java/org/springframework/web/multipart/support/StandardServletMultipartResolver.java index 0ac3326d2cd..34d40edb190 100644 --- a/spring-web/src/main/java/org/springframework/web/multipart/support/StandardServletMultipartResolver.java +++ b/spring-web/src/main/java/org/springframework/web/multipart/support/StandardServletMultipartResolver.java @@ -71,6 +71,7 @@ public class StandardServletMultipartResolver implements MultipartResolver { * corresponding exceptions at the time of the {@link #resolveMultipart} call. * Switch this to "true" for lazy multipart parsing, throwing parse exceptions * once the application attempts to obtain multipart files or parameters. + * @since 3.2.9 */ public void setResolveLazily(boolean resolveLazily) { this.resolveLazily = resolveLazily; @@ -94,17 +95,20 @@ public class StandardServletMultipartResolver implements MultipartResolver { @Override public void cleanupMultipart(MultipartHttpServletRequest request) { - // To be on the safe side: explicitly delete the parts, - // but only actual file parts (for Resin compatibility) - try { - for (Part part : request.getParts()) { - if (request.getFile(part.getName()) != null) { - part.delete(); + if (!(request instanceof AbstractMultipartHttpServletRequest) || + ((AbstractMultipartHttpServletRequest) request).isResolved()) { + // To be on the safe side: explicitly delete the parts, + // but only actual file parts (for Resin compatibility) + try { + for (Part part : request.getParts()) { + if (request.getFile(part.getName()) != null) { + part.delete(); + } } } - } - catch (Throwable ex) { - LogFactory.getLog(getClass()).warn("Failed to perform cleanup of multipart items", ex); + catch (Throwable ex) { + LogFactory.getLog(getClass()).warn("Failed to perform cleanup of multipart items", ex); + } } }