Skip to content

Commit 6aa7880

Browse files
committed
Merge branch '2.0.x' into 2.1.x
2 parents 21adbde + 6507d17 commit 6aa7880

File tree

3 files changed

+67
-7
lines changed

3 files changed

+67
-7
lines changed

spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3067,13 +3067,6 @@ https://github.com/undertow-io/undertow[Undertow] servers. Most developers use t
30673067
appropriate "`Starter`" to obtain a fully configured instance. By default, the embedded
30683068
server listens for HTTP requests on port `8080`.
30693069

3070-
WARNING: If you choose to use Tomcat on https://www.centos.org/[CentOS], be aware that, by
3071-
default, a temporary directory is used to store compiled JSPs, file uploads, and so on.
3072-
This directory may be deleted by `tmpwatch` while your application is running, leading to
3073-
failures. To avoid this behavior, you may want to customize your `tmpwatch` configuration
3074-
such that `tomcat.*` directories are not deleted or configure `server.tomcat.basedir` such
3075-
that embedded Tomcat uses a different location.
3076-
30773070

30783071

30793072
[[boot-features-embedded-container-servlets-filters-listeners]]

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactory.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,12 @@ protected void prepareContext(Host host, ServletContextInitializer[] initializer
200200
resetDefaultLocaleMapping(context);
201201
addLocaleMappings(context);
202202
context.setUseRelativeRedirects(false);
203+
try {
204+
context.setCreateUploadTargets(true);
205+
}
206+
catch (NoSuchMethodError ex) {
207+
// Tomcat is < 8.5.39. Continue.
208+
}
203209
configureTldSkipPatterns(context);
204210
WebappLoader loader = new WebappLoader(context.getParentClassLoader());
205211
loader.setLoaderClass(TomcatEmbeddedWebappClassLoader.class.getName());

spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactoryTests.java

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import java.io.File;
2020
import java.io.IOException;
21+
import java.net.URISyntaxException;
2122
import java.net.URL;
2223
import java.nio.charset.Charset;
2324
import java.nio.charset.StandardCharsets;
@@ -26,10 +27,17 @@
2627
import java.util.HashMap;
2728
import java.util.Locale;
2829
import java.util.Map;
30+
import java.util.concurrent.atomic.AtomicReference;
2931

3032
import javax.naming.InitialContext;
3133
import javax.naming.NamingException;
34+
import javax.servlet.MultipartConfigElement;
35+
import javax.servlet.ServletContext;
3236
import javax.servlet.ServletException;
37+
import javax.servlet.ServletRegistration.Dynamic;
38+
import javax.servlet.http.HttpServlet;
39+
import javax.servlet.http.HttpServletRequest;
40+
import javax.servlet.http.HttpServletResponse;
3341

3442
import org.apache.catalina.Container;
3543
import org.apache.catalina.Context;
@@ -58,9 +66,20 @@
5866

5967
import org.springframework.boot.testsupport.rule.OutputCapture;
6068
import org.springframework.boot.web.server.WebServerException;
69+
import org.springframework.boot.web.servlet.ServletContextInitializer;
6170
import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactory;
6271
import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactoryTests;
72+
import org.springframework.core.io.ByteArrayResource;
73+
import org.springframework.http.HttpEntity;
74+
import org.springframework.http.HttpHeaders;
75+
import org.springframework.http.HttpStatus;
76+
import org.springframework.http.MediaType;
77+
import org.springframework.http.ResponseEntity;
6378
import org.springframework.test.util.ReflectionTestUtils;
79+
import org.springframework.util.FileSystemUtils;
80+
import org.springframework.util.LinkedMultiValueMap;
81+
import org.springframework.util.MultiValueMap;
82+
import org.springframework.web.client.RestTemplate;
6483

6584
import static org.assertj.core.api.Assertions.assertThat;
6685
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -457,6 +476,48 @@ public void referenceClearingIsDisabled() {
457476
assertThat(context.getClearReferencesThreadLocals()).isFalse();
458477
}
459478

479+
@Test
480+
public void nonExistentUploadDirectoryIsCreatedUponMultipartUpload()
481+
throws IOException, URISyntaxException {
482+
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory(0);
483+
AtomicReference<ServletContext> servletContextReference = new AtomicReference<>();
484+
factory.addInitializers(new ServletContextInitializer() {
485+
486+
@Override
487+
public void onStartup(ServletContext servletContext) throws ServletException {
488+
servletContextReference.set(servletContext);
489+
Dynamic servlet = servletContext.addServlet("upload", new HttpServlet() {
490+
491+
@Override
492+
protected void doPost(HttpServletRequest req,
493+
HttpServletResponse resp)
494+
throws ServletException, IOException {
495+
req.getParts();
496+
}
497+
498+
});
499+
servlet.addMapping("/upload");
500+
servlet.setMultipartConfig(new MultipartConfigElement((String) null));
501+
}
502+
503+
});
504+
this.webServer = factory.getWebServer();
505+
this.webServer.start();
506+
File temp = (File) servletContextReference.get()
507+
.getAttribute(ServletContext.TEMPDIR);
508+
FileSystemUtils.deleteRecursively(temp);
509+
RestTemplate restTemplate = new RestTemplate();
510+
HttpHeaders headers = new HttpHeaders();
511+
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
512+
body.add("file", new ByteArrayResource(new byte[1024 * 1024]));
513+
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
514+
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body,
515+
headers);
516+
ResponseEntity<String> response = restTemplate
517+
.postForEntity(getLocalUrl("/upload"), requestEntity, String.class);
518+
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
519+
}
520+
460521
@Override
461522
protected JspServlet getJspServlet() throws ServletException {
462523
Tomcat tomcat = ((TomcatWebServer) this.webServer).getTomcat();

0 commit comments

Comments
 (0)