Merge remote-tracking branch 'origin/jetty-12.0.x' into jetty-12.1.x
This commit is contained in:
commit
d43da5279c
|
@ -17,6 +17,7 @@ import java.io.File;
|
|||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URLClassLoader;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
@ -40,6 +41,7 @@ import org.eclipse.jetty.server.AliasCheck;
|
|||
import org.eclipse.jetty.server.Connector;
|
||||
import org.eclipse.jetty.server.Context;
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.NetworkConnector;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.server.Response;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
|
@ -57,6 +59,7 @@ import org.eclipse.jetty.util.annotation.ManagedObject;
|
|||
import org.eclipse.jetty.util.component.ClassLoaderDump;
|
||||
import org.eclipse.jetty.util.component.DumpableAttributes;
|
||||
import org.eclipse.jetty.util.component.LifeCycle;
|
||||
import org.eclipse.jetty.util.resource.MountedPathResource;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.eclipse.jetty.util.resource.Resources;
|
||||
|
@ -143,6 +146,7 @@ public class ContextHandler extends Handler.Wrapper implements Attributes, Alias
|
|||
private File _tempDirectory;
|
||||
private boolean _tempDirectoryPersisted = false;
|
||||
private boolean _tempDirectoryCreated = false;
|
||||
private boolean _createdTempDirectoryName = false;
|
||||
private boolean _crossContextDispatchSupported = false;
|
||||
|
||||
public enum Availability
|
||||
|
@ -236,6 +240,8 @@ public class ContextHandler extends Handler.Wrapper implements Attributes, Alias
|
|||
if (isStarted())
|
||||
throw new IllegalStateException("Started");
|
||||
|
||||
File oldTempDirectory = _tempDirectory;
|
||||
|
||||
if (tempDirectory != null)
|
||||
{
|
||||
try
|
||||
|
@ -247,7 +253,23 @@ public class ContextHandler extends Handler.Wrapper implements Attributes, Alias
|
|||
LOG.warn("Unable to find canonical path for {}", tempDirectory, e);
|
||||
}
|
||||
}
|
||||
|
||||
if (oldTempDirectory != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
//if we had made up the name of the tmp directory previously, delete it if the new name is different
|
||||
if (_createdTempDirectoryName && (tempDirectory == null || (!Files.isSameFile(oldTempDirectory.toPath(), tempDirectory.toPath()))))
|
||||
IO.delete(oldTempDirectory);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Unable to delete old temp directory {}", oldTempDirectory, e);
|
||||
}
|
||||
}
|
||||
_tempDirectory = tempDirectory;
|
||||
_createdTempDirectoryName = false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -788,7 +810,187 @@ public class ContextHandler extends Handler.Wrapper implements Attributes, Alias
|
|||
|
||||
// if we're not persisting the temp dir contents delete it
|
||||
if (tempDirectory != null && tempDirectory.exists() && !isTempDirectoryPersistent())
|
||||
{
|
||||
IO.delete(tempDirectory);
|
||||
}
|
||||
|
||||
//if it was jetty that created the tmp dir, it can be reset, otherwise we need to retain the name
|
||||
if (_createdTempDirectoryName)
|
||||
{
|
||||
setTempDirectory(null);
|
||||
_createdTempDirectoryName = false;
|
||||
}
|
||||
}
|
||||
|
||||
/** Generate a reasonable name for the temp directory because one has not been
|
||||
* explicitly configured by the user with {@link #setTempDirectory(File)}. The
|
||||
* directory may also be created, if it is not persistent. If it is persistent
|
||||
* it will be created as necessary by {@link #createTempDirectory()} later
|
||||
* during the startup of the context.
|
||||
*
|
||||
* @throws Exception IllegalStateException if the parent tmp directory does
|
||||
* not exist, or IOException if the child tmp directory cannot be created.
|
||||
*/
|
||||
protected void makeTempDirectory()
|
||||
throws Exception
|
||||
{
|
||||
File parent = getServer().getContext().getTempDirectory();
|
||||
if (parent == null || !parent.exists() || !parent.canWrite() || !parent.isDirectory())
|
||||
throw new IllegalStateException("Parent for temp dir not configured correctly: " + (parent == null ? "null" : "writeable=" + parent.canWrite()));
|
||||
|
||||
boolean persistent = isTempDirectoryPersistent() || "work".equals(parent.toPath().getFileName().toString());
|
||||
|
||||
//Create a name for the temp dir
|
||||
String temp = getCanonicalNameForTmpDir();
|
||||
File tmpDir;
|
||||
if (persistent)
|
||||
{
|
||||
//if it is to be persisted, make sure it will be the same name
|
||||
//by not using File.createTempFile, which appends random digits
|
||||
tmpDir = new File(parent, temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
// ensure dir will always be unique by having classlib generate random path name
|
||||
tmpDir = Files.createTempDirectory(parent.toPath(), temp).toFile();
|
||||
tmpDir.deleteOnExit();
|
||||
}
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Set temp dir {}", tmpDir);
|
||||
setTempDirectory(tmpDir);
|
||||
setTempDirectoryPersistent(persistent);
|
||||
_createdTempDirectoryName = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a canonical name for a context temp directory.
|
||||
* <p>
|
||||
* The form of the name is:
|
||||
*
|
||||
* <pre>"jetty-"+host+"-"+port+"-"+resourceBase+"-_"+context+"-"+virtualhost+"-"+randomdigits+".dir"</pre>
|
||||
*
|
||||
* host and port uniquely identify the server
|
||||
* context and virtual host uniquely identify the context
|
||||
* randomdigits ensure every tmp directory is unique
|
||||
*
|
||||
* @return the canonical name for the context temp directory
|
||||
*/
|
||||
protected String getCanonicalNameForTmpDir()
|
||||
{
|
||||
StringBuilder canonicalName = new StringBuilder();
|
||||
canonicalName.append("jetty-");
|
||||
|
||||
//get the host and the port from the first connector
|
||||
Server server = getServer();
|
||||
if (server != null)
|
||||
{
|
||||
Connector[] connectors = server.getConnectors();
|
||||
|
||||
if (connectors.length > 0)
|
||||
{
|
||||
//Get the host
|
||||
String host = null;
|
||||
int port = 0;
|
||||
if (connectors[0] instanceof NetworkConnector connector)
|
||||
{
|
||||
host = connector.getHost();
|
||||
port = connector.getLocalPort();
|
||||
if (port < 0)
|
||||
port = connector.getPort();
|
||||
}
|
||||
if (host == null)
|
||||
host = "0.0.0.0";
|
||||
canonicalName.append(host);
|
||||
canonicalName.append("-");
|
||||
canonicalName.append(port);
|
||||
canonicalName.append("-");
|
||||
}
|
||||
}
|
||||
|
||||
// Resource base
|
||||
try
|
||||
{
|
||||
Resource resource = getResourceForTempDirName();
|
||||
String resourceBaseName = getBaseName(resource);
|
||||
canonicalName.append(resourceBaseName);
|
||||
canonicalName.append("-");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Can't get resource base name", e);
|
||||
|
||||
canonicalName.append("-"); // empty resourceBaseName segment
|
||||
}
|
||||
|
||||
//Context name
|
||||
String contextPath = getContextPath();
|
||||
contextPath = contextPath.replace('/', '_');
|
||||
contextPath = contextPath.replace('\\', '_');
|
||||
canonicalName.append(contextPath);
|
||||
|
||||
//Virtual host (if there is one)
|
||||
canonicalName.append("-");
|
||||
List<String> vhosts = getVirtualHosts();
|
||||
if (vhosts == null || vhosts.size() <= 0)
|
||||
canonicalName.append("any");
|
||||
else
|
||||
canonicalName.append(vhosts.get(0));
|
||||
|
||||
// sanitize
|
||||
for (int i = 0; i < canonicalName.length(); i++)
|
||||
{
|
||||
char c = canonicalName.charAt(i);
|
||||
if (!Character.isJavaIdentifierPart(c) && "-.".indexOf(c) < 0)
|
||||
canonicalName.setCharAt(i, '.');
|
||||
}
|
||||
|
||||
canonicalName.append("-");
|
||||
|
||||
return StringUtil.sanitizeFileSystemName(canonicalName.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the baseResource for the context to use in the temp dir name
|
||||
*/
|
||||
protected Resource getResourceForTempDirName()
|
||||
{
|
||||
return getBaseResource();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param resource the resource whose filename minus suffix to extract
|
||||
* @return the filename of the resource without suffix
|
||||
*/
|
||||
protected static String getBaseName(Resource resource)
|
||||
{
|
||||
// Use File System and File interface if present
|
||||
Path resourceFile = resource.getPath();
|
||||
|
||||
if ((resourceFile != null) && (resource instanceof MountedPathResource))
|
||||
{
|
||||
resourceFile = ((MountedPathResource)resource).getContainerPath();
|
||||
}
|
||||
|
||||
if (resourceFile != null)
|
||||
{
|
||||
Path fileName = resourceFile.getFileName();
|
||||
return fileName == null ? "" : fileName.toString();
|
||||
}
|
||||
|
||||
// Use URI itself.
|
||||
URI uri = resource.getURI();
|
||||
if (uri == null)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("Resource has no URI reference: {}", resource);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
return URIUtil.getUriLastPathSegment(uri);
|
||||
}
|
||||
|
||||
public boolean checkVirtualHost(Request request)
|
||||
|
|
|
@ -1569,6 +1569,40 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
|||
return _metadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void makeTempDirectory() throws Exception
|
||||
{
|
||||
super.makeTempDirectory();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getCanonicalNameForTmpDir()
|
||||
{
|
||||
return super.getCanonicalNameForTmpDir();
|
||||
}
|
||||
|
||||
/**
|
||||
* If the webapp has no baseresource yet, use
|
||||
* the war to make the temp directory name.
|
||||
*
|
||||
* @return the baseresource if non null, or the war
|
||||
*/
|
||||
@Override
|
||||
protected Resource getResourceForTempDirName()
|
||||
{
|
||||
Resource resource = super.getResourceForTempDirName();
|
||||
|
||||
if (resource == null)
|
||||
{
|
||||
if (getWar() == null || getWar().length() == 0)
|
||||
throw new IllegalStateException("No resourceBase or war set for context");
|
||||
|
||||
// Use name of given resource in the temporary dirname
|
||||
resource = newResource(getWar());
|
||||
}
|
||||
return resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a Server Class pattern to use for all WebAppContexts.
|
||||
* @param server The {@link Server} instance to add classes to
|
||||
|
|
|
@ -39,7 +39,6 @@ public class WebInfConfiguration extends AbstractConfiguration
|
|||
{
|
||||
private static final Logger LOG = LoggerFactory.getLogger(WebInfConfiguration.class);
|
||||
|
||||
public static final String TEMPDIR_CONFIGURED = "org.eclipse.jetty.tmpdirConfigured";
|
||||
public static final String TEMPORARY_RESOURCE_BASE = "org.eclipse.jetty.webapp.tmpResourceBase";
|
||||
public static final String ORIGINAL_RESOURCE_BASE = "org.eclipse.jetty.webapp.originalResourceBase";
|
||||
|
||||
|
@ -89,10 +88,6 @@ public class WebInfConfiguration extends AbstractConfiguration
|
|||
@Override
|
||||
public void deconfigure(WebAppContext context) throws Exception
|
||||
{
|
||||
//if it wasn't explicitly configured by the user, then unset it
|
||||
if (!(context.getAttribute(TEMPDIR_CONFIGURED) instanceof Boolean tmpdirConfigured && tmpdirConfigured))
|
||||
context.setTempDirectory(null);
|
||||
|
||||
//reset the base resource back to what it was before we did any unpacking of resources
|
||||
Resource originalBaseResource = (Resource)context.removeAttribute(ORIGINAL_RESOURCE_BASE);
|
||||
context.setBaseResource(originalBaseResource);
|
||||
|
@ -133,7 +128,6 @@ public class WebInfConfiguration extends AbstractConfiguration
|
|||
File tempDirectory = context.getTempDirectory();
|
||||
if (tempDirectory != null)
|
||||
{
|
||||
context.setAttribute(TEMPDIR_CONFIGURED, Boolean.TRUE); //the tmp dir was set explicitly
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -148,37 +142,14 @@ public class WebInfConfiguration extends AbstractConfiguration
|
|||
return;
|
||||
}
|
||||
|
||||
makeTempDirectory(context.getServer().getContext().getTempDirectory(), context);
|
||||
context.makeTempDirectory();
|
||||
}
|
||||
|
||||
@Deprecated (forRemoval = true, since = "12.0.12")
|
||||
public void makeTempDirectory(File parent, WebAppContext context)
|
||||
throws Exception
|
||||
{
|
||||
if (parent == null || !parent.exists() || !parent.canWrite() || !parent.isDirectory())
|
||||
throw new IllegalStateException("Parent for temp dir not configured correctly: " + (parent == null ? "null" : "writeable=" + parent.canWrite()));
|
||||
|
||||
boolean persistent = context.isTempDirectoryPersistent() || "work".equals(parent.toPath().getFileName().toString());
|
||||
|
||||
//Create a name for the webapp
|
||||
String temp = getCanonicalNameForWebAppTmpDir(context);
|
||||
File tmpDir;
|
||||
if (persistent)
|
||||
{
|
||||
//if it is to be persisted, make sure it will be the same name
|
||||
//by not using File.createTempFile, which appends random digits
|
||||
tmpDir = new File(parent, temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
// ensure dir will always be unique by having classlib generate random path name
|
||||
tmpDir = Files.createTempDirectory(parent.toPath(), temp).toFile();
|
||||
tmpDir.deleteOnExit();
|
||||
}
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Set temp dir {}", tmpDir);
|
||||
context.setTempDirectory(tmpDir);
|
||||
context.setTempDirectoryPersistent(persistent);
|
||||
context.makeTempDirectory();
|
||||
}
|
||||
|
||||
public void unpack(WebAppContext context) throws IOException
|
||||
|
@ -395,91 +366,20 @@ public class WebInfConfiguration extends AbstractConfiguration
|
|||
*
|
||||
* @param context the context to get the canonical name from
|
||||
* @return the canonical name for the webapp temp directory
|
||||
* @deprecated this method is no longer used
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "12.0.12")
|
||||
public static String getCanonicalNameForWebAppTmpDir(WebAppContext context)
|
||||
{
|
||||
StringBuilder canonicalName = new StringBuilder();
|
||||
canonicalName.append("jetty-");
|
||||
|
||||
//get the host and the port from the first connector
|
||||
Server server = context.getServer();
|
||||
if (server != null)
|
||||
{
|
||||
Connector[] connectors = server.getConnectors();
|
||||
|
||||
if (connectors.length > 0)
|
||||
{
|
||||
//Get the host
|
||||
String host = null;
|
||||
int port = 0;
|
||||
if (connectors[0] instanceof NetworkConnector connector)
|
||||
{
|
||||
host = connector.getHost();
|
||||
port = connector.getLocalPort();
|
||||
if (port < 0)
|
||||
port = connector.getPort();
|
||||
}
|
||||
if (host == null)
|
||||
host = "0.0.0.0";
|
||||
canonicalName.append(host);
|
||||
canonicalName.append("-");
|
||||
canonicalName.append(port);
|
||||
canonicalName.append("-");
|
||||
}
|
||||
}
|
||||
|
||||
// Resource base
|
||||
try
|
||||
{
|
||||
Resource resource = context.getBaseResource();
|
||||
if (resource == null)
|
||||
{
|
||||
if (StringUtil.isBlank(context.getWar()))
|
||||
throw new IllegalStateException("No resourceBase or war set for context");
|
||||
|
||||
// Set dir or WAR to resource
|
||||
resource = context.newResource(context.getWar());
|
||||
}
|
||||
|
||||
String resourceBaseName = getResourceBaseName(resource);
|
||||
canonicalName.append(resourceBaseName);
|
||||
canonicalName.append("-");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Can't get resource base name", e);
|
||||
|
||||
canonicalName.append("-"); // empty resourceBaseName segment
|
||||
}
|
||||
|
||||
//Context name
|
||||
String contextPath = context.getContextPath();
|
||||
contextPath = contextPath.replace('/', '_');
|
||||
contextPath = contextPath.replace('\\', '_');
|
||||
canonicalName.append(contextPath);
|
||||
|
||||
//Virtual host (if there is one)
|
||||
canonicalName.append("-");
|
||||
List<String> vhosts = context.getVirtualHosts();
|
||||
if (vhosts == null || vhosts.size() <= 0)
|
||||
canonicalName.append("any");
|
||||
else
|
||||
canonicalName.append(vhosts.get(0));
|
||||
|
||||
// sanitize
|
||||
for (int i = 0; i < canonicalName.length(); i++)
|
||||
{
|
||||
char c = canonicalName.charAt(i);
|
||||
if (!Character.isJavaIdentifierPart(c) && "-.".indexOf(c) < 0)
|
||||
canonicalName.setCharAt(i, '.');
|
||||
}
|
||||
|
||||
canonicalName.append("-");
|
||||
|
||||
return StringUtil.sanitizeFileSystemName(canonicalName.toString());
|
||||
return context.getCanonicalNameForTmpDir();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param resource the Resource for which to extract a short name
|
||||
* @return extract a short name for the resource
|
||||
* @deprecated this method is no longer needed
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "12.0.12")
|
||||
protected static String getResourceBaseName(Resource resource)
|
||||
{
|
||||
// Use File System and File interface if present
|
||||
|
|
|
@ -31,7 +31,6 @@ import org.eclipse.jetty.toolchain.test.jupiter.WorkDir;
|
|||
import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension;
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
|
@ -40,6 +39,8 @@ import org.junit.jupiter.params.provider.ValueSource;
|
|||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
|
||||
@ExtendWith(WorkDirExtension.class)
|
||||
public class TempDirTest
|
||||
|
@ -174,11 +175,11 @@ public class TempDirTest
|
|||
_server.start();
|
||||
File tempDirectory = webAppContext.getTempDirectory();
|
||||
webAppContext.stop();
|
||||
assertNull(webAppContext.getTempDirectory());
|
||||
webAppContext.start();
|
||||
assertThat(tempDirectory.toPath(), not(PathMatchers.isSame(webAppContext.getTempDirectory().toPath())));
|
||||
}
|
||||
|
||||
@Disabled ("Enable after issue 11548 fixed")
|
||||
@Test
|
||||
public void testSameTempDir(WorkDir workDir) throws Exception
|
||||
{
|
||||
|
@ -209,7 +210,38 @@ public class TempDirTest
|
|||
File tempDirectory = webAppContext.getTempDirectory();
|
||||
assertThat(tempDirectory.toPath(), PathMatchers.isSame(configuredTmpDir));
|
||||
webAppContext.stop();
|
||||
assertNotNull(webAppContext.getTempDirectory());
|
||||
webAppContext.start();
|
||||
assertThat(tempDirectory.toPath(), PathMatchers.isSame(webAppContext.getTempDirectory().toPath()));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTempDirDeleted(WorkDir workDir) throws Exception
|
||||
{
|
||||
// Create war on the fly
|
||||
Path testWebappDir = MavenTestingUtils.getProjectDirPath("src/test/webapp");
|
||||
Path warFile = workDir.getEmptyPathDir().resolve("test.war");
|
||||
|
||||
Map<String, String> env = new HashMap<>();
|
||||
env.put("create", "true");
|
||||
|
||||
URI uri = URI.create("jar:" + warFile.toUri().toASCIIString());
|
||||
// Use ZipFS so that we can create paths that are just "/"
|
||||
try (FileSystem zipfs = FileSystems.newFileSystem(uri, env))
|
||||
{
|
||||
Path root = zipfs.getPath("/");
|
||||
IO.copyDir(testWebappDir, root);
|
||||
}
|
||||
|
||||
_server = new Server();
|
||||
WebAppContext webAppContext = new WebAppContext();
|
||||
webAppContext.setContextPath("/");
|
||||
webAppContext.setWarResource(webAppContext.getResourceFactory().newResource(warFile));
|
||||
_server.setHandler(webAppContext);
|
||||
_server.start();
|
||||
File tempDirectory = webAppContext.getTempDirectory();
|
||||
_server.stop();
|
||||
assertThat("Temp dir exists", !Files.exists(tempDirectory.toPath()));
|
||||
assertNull(webAppContext.getTempDirectory());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1464,4 +1464,66 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
|||
{
|
||||
return _metadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void makeTempDirectory() throws Exception
|
||||
{
|
||||
super.makeTempDirectory();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getCanonicalNameForTmpDir()
|
||||
{
|
||||
return super.getCanonicalNameForTmpDir();
|
||||
}
|
||||
|
||||
/**
|
||||
* If the webapp has no baseresource yet, use
|
||||
* the war to make the temp directory name.
|
||||
*
|
||||
* @return the baseresource if non null, or the war
|
||||
*/
|
||||
@Override
|
||||
protected Resource getResourceForTempDirName()
|
||||
{
|
||||
Resource resource = super.getResourceForTempDirName();
|
||||
|
||||
if (resource == null)
|
||||
{
|
||||
if (getWar() == null || getWar().length() == 0)
|
||||
throw new IllegalStateException("No resourceBase or war set for context");
|
||||
|
||||
// Use name of given resource in the temporary dirname
|
||||
resource = newResource(getWar());
|
||||
}
|
||||
return resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a Server Class pattern to use for all WebAppContexts.
|
||||
* @param server The {@link Server} instance to add classes to
|
||||
* @param patterns the patterns to use
|
||||
* @see #getHiddenClassMatcher()
|
||||
* @see #getHiddenClasses()
|
||||
* @deprecated use {@link WebAppClassLoading#addProtectedClasses(Server, String...)}
|
||||
*/
|
||||
@Deprecated(since = "12.0.8", forRemoval = true)
|
||||
public static void addServerClasses(Server server, String... patterns)
|
||||
{
|
||||
WebAppClassLoading.addHiddenClasses(server, patterns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a System Class pattern to use for all WebAppContexts.
|
||||
* @param server The {@link Server} instance to add classes to
|
||||
* @param patterns the patterns to use
|
||||
* @see #getProtectedClassMatcher()
|
||||
* @see #getProtectedClasses()
|
||||
* @deprecated use {@link WebAppClassLoading#addHiddenClasses(Server, String...)}
|
||||
*/
|
||||
@Deprecated(since = "12.0.8", forRemoval = true)
|
||||
public static void addSystemClasses(Server server, String... patterns)
|
||||
{
|
||||
WebAppClassLoading.addProtectedClasses(server, patterns);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!-- // -->
|
||||
<!-- // ======================================================================== -->
|
||||
<!-- // Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -->
|
||||
<!-- // -->
|
||||
<!-- // This program and the accompanying materials are made available under the -->
|
||||
<!-- // terms of the Eclipse Public License v. 2.0 which is available at -->
|
||||
<!-- // https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -->
|
||||
<!-- // which is available at https://www.apache.org/licenses/LICENSE-2.0. -->
|
||||
<!-- // -->
|
||||
<!-- // SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -->
|
||||
<!-- // ======================================================================== -->
|
||||
<!-- // -->
|
||||
|
||||
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
|
||||
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
|
||||
version="3.1">
|
||||
|
||||
|
||||
</web-app>
|
|
@ -2673,6 +2673,24 @@ public class ContextHandler extends ScopedHandler implements Attributes, Supplie
|
|||
installBean(ContextHandler.this, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void makeTempDirectory() throws Exception
|
||||
{
|
||||
super.makeTempDirectory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCanonicalNameForTmpDir()
|
||||
{
|
||||
return super.getCanonicalNameForTmpDir();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resource getResourceForTempDirName()
|
||||
{
|
||||
return super.getResourceForTempDirName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContextPath(String contextPath)
|
||||
{
|
||||
|
|
|
@ -1171,6 +1171,31 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
|||
return getCoreContextHandler().getTempDirectory();
|
||||
}
|
||||
|
||||
protected void makeTempDirectory() throws Exception
|
||||
{
|
||||
getCoreContextHandler().makeTempDirectory();
|
||||
}
|
||||
|
||||
protected String getCanonicalNameForTmpDir()
|
||||
{
|
||||
return getCoreContextHandler().getCanonicalNameForTmpDir();
|
||||
}
|
||||
|
||||
protected Resource getResourceForTempDirName()
|
||||
{
|
||||
Resource resource = getCoreContextHandler().getResourceForTempDirName();
|
||||
|
||||
if (resource == null)
|
||||
{
|
||||
if (getWar() == null || getWar().length() == 0)
|
||||
throw new IllegalStateException("No resourceBase or war set for context");
|
||||
|
||||
// Use name of given resource in the temporary dirname
|
||||
resource = getResourceFactory().newResource(getWar());
|
||||
}
|
||||
return resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* If true the temp directory for this
|
||||
* webapp will be kept when the webapp stops. Otherwise,
|
||||
|
|
|
@ -38,7 +38,6 @@ public class WebInfConfiguration extends AbstractConfiguration
|
|||
{
|
||||
private static final Logger LOG = LoggerFactory.getLogger(WebInfConfiguration.class);
|
||||
|
||||
public static final String TEMPDIR_CONFIGURED = "org.eclipse.jetty.tmpdirConfigured";
|
||||
public static final String TEMPORARY_RESOURCE_BASE = "org.eclipse.jetty.webapp.tmpResourceBase";
|
||||
|
||||
protected Resource _preUnpackBaseResource;
|
||||
|
@ -83,10 +82,6 @@ public class WebInfConfiguration extends AbstractConfiguration
|
|||
@Override
|
||||
public void deconfigure(WebAppContext context) throws Exception
|
||||
{
|
||||
//if it wasn't explicitly configured by the user, then unset it
|
||||
if (!(context.getAttribute(TEMPDIR_CONFIGURED) instanceof Boolean tmpdirConfigured && tmpdirConfigured))
|
||||
context.setTempDirectory(null);
|
||||
|
||||
//reset the base resource back to what it was before we did any unpacking of resources
|
||||
context.setBaseResource(_preUnpackBaseResource);
|
||||
}
|
||||
|
@ -135,7 +130,6 @@ public class WebInfConfiguration extends AbstractConfiguration
|
|||
File tempDirectory = context.getTempDirectory();
|
||||
if (tempDirectory != null)
|
||||
{
|
||||
context.setAttribute(TEMPDIR_CONFIGURED, Boolean.TRUE); //the tmp dir was set explicitly
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -150,37 +144,14 @@ public class WebInfConfiguration extends AbstractConfiguration
|
|||
return;
|
||||
}
|
||||
|
||||
makeTempDirectory(context.getServer().getContext().getTempDirectory(), context);
|
||||
context.makeTempDirectory();
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true, since = "12.0.12")
|
||||
public void makeTempDirectory(File parent, WebAppContext context)
|
||||
throws Exception
|
||||
{
|
||||
if (parent == null || !parent.exists() || !parent.canWrite() || !parent.isDirectory())
|
||||
throw new IllegalStateException("Parent for temp dir not configured correctly: " + (parent == null ? "null" : "writeable=" + parent.canWrite()));
|
||||
|
||||
boolean persistent = context.isPersistTempDirectory() || "work".equals(parent.toPath().getFileName().toString());
|
||||
|
||||
//Create a name for the webapp
|
||||
String temp = getCanonicalNameForWebAppTmpDir(context);
|
||||
File tmpDir;
|
||||
if (persistent)
|
||||
{
|
||||
//if it is to be persisted, make sure it will be the same name
|
||||
//by not using File.createTempFile, which appends random digits
|
||||
tmpDir = new File(parent, temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
// ensure dir will always be unique by having classlib generate random path name
|
||||
tmpDir = Files.createTempDirectory(parent.toPath(), temp).toFile();
|
||||
tmpDir.deleteOnExit();
|
||||
}
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Set temp dir {}", tmpDir);
|
||||
context.setTempDirectory(tmpDir);
|
||||
context.setPersistTempDirectory(persistent);
|
||||
context.makeTempDirectory();
|
||||
}
|
||||
|
||||
public void unpack(WebAppContext context) throws IOException
|
||||
|
@ -397,94 +368,10 @@ public class WebInfConfiguration extends AbstractConfiguration
|
|||
*/
|
||||
public static String getCanonicalNameForWebAppTmpDir(WebAppContext context)
|
||||
{
|
||||
StringBuffer canonicalName = new StringBuffer();
|
||||
canonicalName.append("jetty-");
|
||||
|
||||
//get the host and the port from the first connector
|
||||
Server server = context.getServer();
|
||||
if (server != null)
|
||||
{
|
||||
Connector[] connectors = context.getServer().getConnectors();
|
||||
|
||||
if (connectors.length > 0)
|
||||
{
|
||||
//Get the host
|
||||
String host = null;
|
||||
int port = 0;
|
||||
if (connectors != null && (connectors[0] instanceof NetworkConnector))
|
||||
{
|
||||
NetworkConnector connector = (NetworkConnector)connectors[0];
|
||||
host = connector.getHost();
|
||||
port = connector.getLocalPort();
|
||||
if (port < 0)
|
||||
port = connector.getPort();
|
||||
}
|
||||
if (host == null)
|
||||
host = "0.0.0.0";
|
||||
canonicalName.append(host);
|
||||
|
||||
//Get the port
|
||||
canonicalName.append("-");
|
||||
|
||||
//if not available (eg no connectors or connector not started),
|
||||
//try getting one that was configured.
|
||||
canonicalName.append(port);
|
||||
canonicalName.append("-");
|
||||
}
|
||||
}
|
||||
|
||||
// Resource base
|
||||
try
|
||||
{
|
||||
Resource resource = context.getBaseResource();
|
||||
if (resource == null)
|
||||
{
|
||||
if (context.getWar() == null || context.getWar().length() == 0)
|
||||
throw new IllegalStateException("No resourceBase or war set for context");
|
||||
|
||||
// Set dir or WAR to resource
|
||||
resource = context.newResource(context.getWar());
|
||||
}
|
||||
|
||||
String resourceBaseName = getResourceBaseName(resource);
|
||||
canonicalName.append(resourceBaseName);
|
||||
canonicalName.append("-");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Can't get resource base name", e);
|
||||
|
||||
canonicalName.append("-"); // empty resourceBaseName segment
|
||||
}
|
||||
|
||||
//Context name
|
||||
String contextPath = context.getContextPath();
|
||||
contextPath = contextPath.replace('/', '_');
|
||||
contextPath = contextPath.replace('\\', '_');
|
||||
canonicalName.append(contextPath);
|
||||
|
||||
//Virtual host (if there is one)
|
||||
canonicalName.append("-");
|
||||
String[] vhosts = context.getVirtualHosts();
|
||||
if (vhosts == null || vhosts.length <= 0)
|
||||
canonicalName.append("any");
|
||||
else
|
||||
canonicalName.append(vhosts[0]);
|
||||
|
||||
// sanitize
|
||||
for (int i = 0; i < canonicalName.length(); i++)
|
||||
{
|
||||
char c = canonicalName.charAt(i);
|
||||
if (!Character.isJavaIdentifierPart(c) && "-.".indexOf(c) < 0)
|
||||
canonicalName.setCharAt(i, '.');
|
||||
}
|
||||
|
||||
canonicalName.append("-");
|
||||
|
||||
return StringUtil.sanitizeFileSystemName(canonicalName.toString());
|
||||
return context.getCanonicalNameForTmpDir();
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true, since = "12.0.12")
|
||||
protected static String getResourceBaseName(Resource resource)
|
||||
{
|
||||
// Use File System and File interface if present
|
||||
|
|
|
@ -14,15 +14,22 @@
|
|||
package org.eclipse.jetty.ee9.webapp;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import jakarta.servlet.ServletContext;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.toolchain.test.FS;
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.eclipse.jetty.toolchain.test.PathMatchers;
|
||||
import org.eclipse.jetty.toolchain.test.jupiter.WorkDir;
|
||||
import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension;
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.eclipse.jetty.util.resource.FileSystemPool;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
@ -34,6 +41,7 @@ import static org.hamcrest.Matchers.empty;
|
|||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
@ExtendWith(WorkDirExtension.class)
|
||||
|
@ -139,4 +147,35 @@ public class TempDirTest
|
|||
webInfConfiguration.resolveTempDirectory(webAppContext);
|
||||
assertThat(webAppContext.getTempDirectory().getParentFile().toPath(), PathMatchers.isSame(workDir));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTempDirDeleted(WorkDir workDir) throws Exception
|
||||
{
|
||||
// Create war on the fly
|
||||
Path testWebappDir = MavenTestingUtils.getProjectDirPath("src/test/webapp");
|
||||
Path warFile = workDir.getEmptyPathDir().resolve("test.war");
|
||||
|
||||
Map<String, String> env = new HashMap<>();
|
||||
env.put("create", "true");
|
||||
|
||||
URI uri = URI.create("jar:" + warFile.toUri().toASCIIString());
|
||||
// Use ZipFS so that we can create paths that are just "/"
|
||||
try (FileSystem zipfs = FileSystems.newFileSystem(uri, env))
|
||||
{
|
||||
Path root = zipfs.getPath("/");
|
||||
IO.copyDir(testWebappDir, root);
|
||||
}
|
||||
|
||||
//Let jetty create the tmp dir on the fly
|
||||
Server server = new Server();
|
||||
WebAppContext webAppContext = new WebAppContext();
|
||||
webAppContext.setContextPath("/");
|
||||
webAppContext.setWarResource(webAppContext.getResourceFactory().newResource(warFile));
|
||||
server.setHandler(webAppContext);
|
||||
server.start();
|
||||
File tempDirectory = webAppContext.getTempDirectory();
|
||||
server.stop();
|
||||
assertNull(webAppContext.getTempDirectory());
|
||||
assertThat("Temp dir exists", !Files.exists(tempDirectory.toPath()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -593,6 +593,18 @@ case "$ACTION" in
|
|||
|
||||
testFileSystemPermissions
|
||||
|
||||
if running $JETTY_PID
|
||||
then
|
||||
echo "Already Running $(cat $JETTY_PID)!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# remove any lingering state file
|
||||
if [ -f $JETTY_STATE ]
|
||||
then
|
||||
rm $JETTY_STATE
|
||||
fi
|
||||
|
||||
echo -n "Starting Jetty: "
|
||||
|
||||
# Startup from a service file
|
||||
|
@ -616,13 +628,6 @@ case "$ACTION" in
|
|||
--
|
||||
(( DEBUG )) && echo "Starting: start-stop-daemon"
|
||||
else
|
||||
|
||||
if running $JETTY_PID
|
||||
then
|
||||
echo "Already Running $(cat $JETTY_PID)!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Startup if switching users (not as a service, or from root)
|
||||
if [ -n "$JETTY_USER" ] && [ `whoami` != "$JETTY_USER" ]
|
||||
then
|
||||
|
|
Loading…
Reference in New Issue