Merge branch '1.5.x' into 2.0.x

This commit is contained in:
Andy Wilkinson 2019-03-29 10:58:59 +00:00
commit 6507d1723d
3 changed files with 67 additions and 8 deletions

View File

@ -2927,13 +2927,6 @@ https://github.com/undertow-io/undertow[Undertow] servers. Most developers use t
appropriate "`Starter`" to obtain a fully configured instance. By default, the embedded
server listens for HTTP requests on port `8080`.
WARNING: If you choose to use Tomcat on https://www.centos.org/[CentOS], be aware that, by
default, a temporary directory is used to store compiled JSPs, file uploads, and so on.
This directory may be deleted by `tmpwatch` while your application is running, leading to
failures. To avoid this behavior, you may want to customize your `tmpwatch` configuration
such that `tomcat.*` directories are not deleted or configure `server.tomcat.basedir` such
that embedded Tomcat uses a different location.
[[boot-features-embedded-container-servlets-filters-listeners]]

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2018 the original author or authors.
* Copyright 2012-2019 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.
@ -200,6 +200,12 @@ public class TomcatServletWebServerFactory extends AbstractServletWebServerFacto
resetDefaultLocaleMapping(context);
addLocaleMappings(context);
context.setUseRelativeRedirects(false);
try {
context.setCreateUploadTargets(true);
}
catch (NoSuchMethodError ex) {
// Tomcat is < 8.5.39. Continue.
}
configureTldSkipPatterns(context);
WebappLoader loader = new WebappLoader(context.getParentClassLoader());
loader.setLoaderClass(TomcatEmbeddedWebappClassLoader.class.getName());

View File

@ -18,6 +18,7 @@ package org.springframework.boot.web.embedded.tomcat;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
@ -26,11 +27,17 @@ import java.util.Arrays;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration.Dynamic;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.catalina.Container;
import org.apache.catalina.Context;
@ -58,9 +65,20 @@ import org.mockito.InOrder;
import org.springframework.boot.testsupport.rule.OutputCapture;
import org.springframework.boot.web.server.WebServerException;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactory;
import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactoryTests;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.util.FileSystemUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;
@ -443,6 +461,48 @@ public class TomcatServletWebServerFactoryTests
this.webServer.start();
}
@Test
public void nonExistentUploadDirectoryIsCreatedUponMultipartUpload()
throws IOException, URISyntaxException {
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory(0);
AtomicReference<ServletContext> servletContextReference = new AtomicReference<>();
factory.addInitializers(new ServletContextInitializer() {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
servletContextReference.set(servletContext);
Dynamic servlet = servletContext.addServlet("upload", new HttpServlet() {
@Override
protected void doPost(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException, IOException {
req.getParts();
}
});
servlet.addMapping("/upload");
servlet.setMultipartConfig(new MultipartConfigElement((String) null));
}
});
this.webServer = factory.getWebServer();
this.webServer.start();
File temp = (File) servletContextReference.get()
.getAttribute(ServletContext.TEMPDIR);
FileSystemUtils.deleteRecursively(temp);
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("file", new ByteArrayResource(new byte[1024 * 1024]));
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body,
headers);
ResponseEntity<String> response = restTemplate
.postForEntity(getLocalUrl("/upload"), requestEntity, String.class);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
}
@Override
protected JspServlet getJspServlet() throws ServletException {
Tomcat tomcat = ((TomcatWebServer) this.webServer).getTomcat();