Merge remote-tracking branch 'origin/jetty-12.0.x' into jetty-12.0.x-8426-aliaschecker-review

This commit is contained in:
Lachlan Roberts 2022-08-15 13:16:51 +10:00
commit ffc14a80b9
53 changed files with 414 additions and 230 deletions

View File

@ -94,17 +94,17 @@
* gzip content encoded if a matching resource is
* found ending with ".gz"
*
* resourceBase Set to replace the context resource base
* baseResource Set to replace the context resource base
*
* resourceCache If set, this is a context attribute name, which the servlet
* will use to look for a shared ResourceCache instance.
*
* relativeResourceBase
* relativeBaseResource
* Set with a pathname relative to the base of the
* servlet context root. Useful for only serving static content out
* of only specific subdirectories.
*
* pathInfoOnly If true, only the path info will be applied to the resourceBase
* pathInfoOnly If true, only the path info will be applied to the baseResource
*
* stylesheet Set with the location of an optional stylesheet that will be used
* to decorate the directory listing html.

View File

@ -54,7 +54,7 @@ public class AllowedResourceAliasChecker extends AbstractLifeCycle implements Al
*/
public AllowedResourceAliasChecker(ContextHandler contextHandler)
{
this(contextHandler, contextHandler::getResourceBase);
this(contextHandler, contextHandler::getBaseResource);
}
public AllowedResourceAliasChecker(ContextHandler contextHandler, Resource baseResource)

View File

@ -13,24 +13,18 @@
package org.eclipse.jetty.server;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.attribute.FileTime;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.eclipse.jetty.util.Fields;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.UrlEncoded;
import org.eclipse.jetty.util.resource.PathCollators;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.util.resource.ResourceCollators;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -58,26 +52,8 @@ public class ResourceListing
base = URIUtil.normalizePath(base);
if (base == null || !resource.isDirectory())
return null;
Path path = resource.getPath();
if (path == null) // Should never happen, as new Resource contract is that all Resources are a Path.
return null;
List<Path> listing = null;
try (Stream<Path> listStream = Files.list(resource.getPath()))
{
listing = listStream.collect(Collectors.toCollection(ArrayList::new));
}
catch (IOException e)
{
if (LOG.isDebugEnabled())
LOG.debug("Unable to get Directory Listing for: {}", resource, e);
}
if (listing == null)
{
return null;
}
List<Resource> listing = new ArrayList<>(resource.list().stream().map(URIUtil::encodePath).map(resource::resolve).toList());
boolean sortOrderAscending = true;
String sortColumn = "N"; // name (or "M" for Last Modified, or "S" for Size)
@ -108,18 +84,13 @@ public class ResourceListing
}
// Perform sort
if (sortColumn.equals("M"))
Comparator<? super Resource> sort = switch (sortColumn)
{
listing.sort(PathCollators.byLastModified(sortOrderAscending));
}
else if (sortColumn.equals("S"))
{
listing.sort(PathCollators.bySize(sortOrderAscending));
}
else
{
listing.sort(PathCollators.byName(sortOrderAscending));
}
case "M" -> ResourceCollators.byLastModified(sortOrderAscending);
case "S" -> ResourceCollators.bySize(sortOrderAscending);
default -> ResourceCollators.byName(sortOrderAscending);
};
listing.sort(sort);
String decodedBase = URIUtil.decodePath(base);
String title = "Directory: " + deTag(decodedBase);
@ -229,30 +200,22 @@ public class ResourceListing
DateFormat dfmt = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);
for (Path item : listing)
for (Resource item : listing)
{
Path fileName = item.getFileName();
if (fileName == null)
{
continue; // skip
}
String name = fileName.toString();
// TODO this feels fragile, as collections probably should not return a Path here
// and even if they do, it might not be named correctly
String name = item.getPath().toFile().getName();
if (StringUtil.isBlank(name))
{
return null;
}
continue;
if (Files.isDirectory(item))
{
if (item.isDirectory() && !name.endsWith("/"))
name += URIUtil.SLASH;
}
// Name
buf.append("<tr><td class=\"name\"><a href=\"");
String href = URIUtil.addEncodedPaths(encodedBase, URIUtil.encodePath(name));
buf.append(href);
// TODO should this be a relative link?
String path = URIUtil.addEncodedPaths(encodedBase, URIUtil.encodePath(name));
buf.append(path);
buf.append("\">");
buf.append(deTag(name));
buf.append("&nbsp;");
@ -260,35 +223,21 @@ public class ResourceListing
// Last Modified
buf.append("<td class=\"lastmodified\">");
try
{
FileTime lastModified = Files.getLastModifiedTime(item, LinkOption.NOFOLLOW_LINKS);
buf.append(dfmt.format(new Date(lastModified.toMillis())));
}
catch (IOException ignore)
{
// do nothing (lastModifiedTime not supported by this file system)
}
long lastModified = item.lastModified();
if (lastModified > 0)
buf.append(dfmt.format(new Date(item.lastModified())));
buf.append("&nbsp;</td>");
// Size
buf.append("<td class=\"size\">");
try
long length = item.length();
if (length >= 0)
{
long length = Files.size(item);
if (length >= 0)
{
buf.append(String.format("%,d bytes", length));
}
}
catch (IOException ignore)
{
// do nothing (size not supported by this file system)
buf.append(String.format("%,d bytes", item.length()));
}
buf.append("&nbsp;</td></tr>\n");
}
buf.append("</tbody>\n");
buf.append("</table>\n");
buf.append("</body></html>\n");

View File

@ -93,7 +93,7 @@ public class ContextHandler extends Handler.Wrapper implements Attributes, Grace
private String _displayName;
private String _contextPath = "/";
private Resource _resourceBase;
private Resource _baseResource;
private ClassLoader _classLoader;
private Request.Processor _errorProcessor;
private boolean _allowNullPathInContext;
@ -701,9 +701,9 @@ public class ContextHandler extends Handler.Wrapper implements Attributes, Grace
* @return Returns the base resource as a string.
*/
@ManagedAttribute("document root for context")
public Resource getResourceBase()
public Resource getBaseResource()
{
return _resourceBase;
return _baseResource;
}
/**
@ -715,10 +715,9 @@ public class ContextHandler extends Handler.Wrapper implements Attributes, Grace
{
if (isStarted())
throw new IllegalStateException(getState());
_resourceBase = resourceBase;
_baseResource = resourceBase;
}
// TODO inline this ???
public void setBaseResource(Path path)
{
setBaseResource(path == null ? null : ResourceFactory.root().newResource(path));
@ -884,7 +883,7 @@ public class ContextHandler extends Handler.Wrapper implements Attributes, Grace
if (getDisplayName() != null)
b.append(getDisplayName()).append(',');
b.append(getContextPath());
b.append(",b=").append(getResourceBase());
b.append(",b=").append(getBaseResource());
b.append(",a=").append(_availability.get());
if (!vhosts.isEmpty())
@ -977,7 +976,7 @@ public class ContextHandler extends Handler.Wrapper implements Attributes, Grace
@Override
public Resource getBaseResource()
{
return _resourceBase;
return _baseResource;
}
@Override

View File

@ -123,7 +123,7 @@ public class ResourceHandler extends Handler.Wrapper
/**
* @return Returns the resourceBase.
*/
public Resource getResourceBase()
public Resource getBaseResource()
{
return _resourceBase;
}
@ -216,6 +216,8 @@ public class ResourceHandler extends Handler.Wrapper
*/
public void setBaseResource(Resource base)
{
if (isStarted())
throw new IllegalStateException(getState());
_resourceBase = base;
}

View File

@ -13,7 +13,6 @@
package org.eclipse.jetty.server.jmx;
import java.io.IOException;
import java.util.List;
import org.eclipse.jetty.jmx.ObjectMBean;
@ -71,8 +70,8 @@ public class AbstractHandlerMBean extends ObjectMBean
name = "ROOT";
}
if (name == null && context.getResourceBase() != null)
name = context.getResourceBase().getPath().getFileName().toString();
if (name == null && context.getBaseResource() != null)
name = context.getBaseResource().getPath().getFileName().toString();
List<String> vhosts = context.getVirtualHosts();
if (vhosts.size() > 0)

View File

@ -55,6 +55,7 @@ import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.QuotedStringTokenizer;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.resource.FileSystemPool;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.util.resource.ResourceFactory;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.AfterEach;
@ -1771,6 +1772,153 @@ public class ResourceHandlerTest
assertThat(response.get(LOCATION), endsWith("/context/directory/;JSESSIONID=12345678?name=value"));
}
@Test
public void testDirectory() throws Exception
{
copySimpleTestResource(docRoot);
HttpTester.Response response = HttpTester.parseResponse(
_local.getResponse("""
GET /context/ HTTP/1.1\r
Host: local\r
Connection: close\r
\r
"""));
assertThat(response.getStatus(), is(HttpStatus.OK_200));
String content = response.getContent();
assertThat(content, containsString("<link href=\"jetty-dir.css\" rel=\"stylesheet\" />"));
assertThat(content, containsString("Directory: /context"));
assertThat(content, containsString("/context/big.txt")); // TODO should these be relative links?
assertThat(content, containsString("/context/simple.txt"));
assertThat(content, containsString("/context/directory/"));
response = HttpTester.parseResponse(
_local.getResponse("""
GET /context/jetty-dir.css HTTP/1.1\r
Host: local\r
Connection: close\r
\r
"""));
// TODO fix this!
// assertThat(response.getStatus(), is(HttpStatus.OK_200));
}
@Test
public void testDirectoryOfCollection() throws Exception
{
copySimpleTestResource(docRoot);
_rootResourceHandler.stop();
_rootResourceHandler.setBaseResource(Resource.combine(
ResourceFactory.root().newResource(MavenTestingUtils.getTestResourcePathDir("layer0/")),
_rootResourceHandler.getBaseResource()));
_rootResourceHandler.start();
HttpTester.Response response = HttpTester.parseResponse(
_local.getResponse("""
GET /context/other/ HTTP/1.1\r
Host: local\r
Connection: close\r
\r
"""));
assertThat(response.getStatus(), is(HttpStatus.OK_200));
String content = response.getContent();
assertThat(content, containsString("<link href=\"jetty-dir.css\" rel=\"stylesheet\" />"));
assertThat(content, containsString("Directory: /context/other"));
assertThat(content, containsString("/context/other/data.txt"));
response = HttpTester.parseResponse(
_local.getResponse("""
GET /context/other/jetty-dir.css HTTP/1.1\r
Host: local\r
Connection: close\r
\r
"""));
// TODO fix this!
// assertThat(response.getStatus(), is(HttpStatus.OK_200));
response = HttpTester.parseResponse(
_local.getResponse("""
GET /context/double/ HTTP/1.1\r
Host: local\r
Connection: close\r
\r
"""));
assertThat(response.getStatus(), is(HttpStatus.OK_200));
content = response.getContent();
assertThat(content, containsString("<link href=\"jetty-dir.css\" rel=\"stylesheet\" />"));
assertThat(content, containsString("Directory: /context/double"));
assertThat(content, containsString("/context/double/zero.txt"));
response = HttpTester.parseResponse(
_local.getResponse("""
GET /context/double/jetty-dir.css HTTP/1.1\r
Host: local\r
Connection: close\r
\r
"""));
// TODO fix this!
// assertThat(response.getStatus(), is(HttpStatus.OK_200));
}
@Test
public void testDirectoryOfCollections() throws Exception
{
copySimpleTestResource(docRoot);
_rootResourceHandler.stop();
_rootResourceHandler.setBaseResource(Resource.combine(
ResourceFactory.root().newResource(MavenTestingUtils.getTestResourcePathDir("layer0/")),
ResourceFactory.root().newResource(MavenTestingUtils.getTestResourcePathDir("layer1/")),
_rootResourceHandler.getBaseResource()));
_rootResourceHandler.start();
HttpTester.Response response = HttpTester.parseResponse(
_local.getResponse("""
GET /context/ HTTP/1.1\r
Host: local\r
Connection: close\r
\r
"""));
assertThat(response.getStatus(), is(HttpStatus.OK_200));
String content = response.getContent();
assertThat(content, containsString("<link href=\"jetty-dir.css\" rel=\"stylesheet\" />"));
assertThat(content, containsString("Directory: /context"));
assertThat(content, containsString("/context/big.txt")); // TODO should these be relative links?
assertThat(content, containsString("/context/simple.txt"));
assertThat(content, containsString("/context/directory/"));
assertThat(content, containsString("/context/other/"));
assertThat(content, containsString("/context/double/"));
response = HttpTester.parseResponse(
_local.getResponse("""
GET /context/double/ HTTP/1.1\r
Host: local\r
Connection: close\r
\r
"""));
assertThat(response.getStatus(), is(HttpStatus.OK_200));
content = response.getContent();
assertThat(content, containsString("<link href=\"jetty-dir.css\" rel=\"stylesheet\" />"));
assertThat(content, containsString("Directory: /context/double"));
assertThat(content, containsString("/context/double/zero.txt"));
assertThat(content, containsString("/context/double/one.txt"));
response = HttpTester.parseResponse(
_local.getResponse("""
GET /context/double/jetty-dir.css HTTP/1.1\r
Host: local\r
Connection: close\r
\r
"""));
// TODO fix this!
// assertThat(response.getStatus(), is(HttpStatus.OK_200));
}
@Test
public void testEtagIfMatchAlwaysFailsDueToWeakEtag() throws Exception
{

View File

@ -0,0 +1 @@
From layer zero

View File

@ -0,0 +1 @@
some data

View File

@ -0,0 +1 @@
From layer 1

View File

@ -102,17 +102,17 @@
* If set to a boolean True, then a default set of compressed formats
* will be used, otherwise no precompressed formats.
*
* resourceBase Set to replace the context resource base
* baseResource Set to replace the context resource base
*
* resourceCache If set, this is a context attribute name, which the servlet
* will use to look for a shared ResourceCache instance.
*
* relativeResourceBase
* relativeBaseResource
* Set with a pathname relative to the base of the
* servlet context root. Useful for only serving static content out
* of only specific subdirectories.
*
* pathInfoOnly If true, only the path info will be applied to the resourceBase
* pathInfoOnly If true, only the path info will be applied to the baseResource
*
* stylesheet Set with the location of an optional stylesheet that will be used
* to decorate the directory listing html.

View File

@ -16,7 +16,7 @@ detected.
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- Required minimal context configuration : -->
<!-- + contextPath -->
<!-- + war OR resourceBase -->
<!-- + war OR baseResource -->
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<Set name="contextPath">/</Set>
<Set name="war"><SystemProperty name="jetty.home" default="."/>/webapps/test.war</Set>

View File

@ -10,7 +10,7 @@ Configure and deploy the test web application
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- Required minimal context configuration : -->
<!-- + contextPath -->
<!-- + war OR resourceBase -->
<!-- + war OR baseResource -->
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<Set name="contextPath">/ee10-test</Set>
<Set name="war"><Property name="jetty.webapps" default="." />/ee10-demo-jetty.war

View File

@ -126,7 +126,7 @@ public abstract class AbstractUnassembledWebAppMojo extends AbstractWebAppMojo
//The first time we run, remember the original base dir
if (originalBaseResource == null)
{
if (webApp.getResourceBase() == null)
if (webApp.getBaseResource() == null)
{
//Use the default static resource location
if (!webAppSourceDirectory.exists())
@ -134,7 +134,7 @@ public abstract class AbstractUnassembledWebAppMojo extends AbstractWebAppMojo
originalBaseResource = ResourceFactory.of(webApp).newResource(webAppSourceDirectory.getCanonicalPath());
}
else
originalBaseResource = webApp.getResourceBase();
originalBaseResource = webApp.getBaseResource();
}
//On every subsequent re-run set it back to the original base dir before
@ -175,11 +175,11 @@ public abstract class AbstractUnassembledWebAppMojo extends AbstractWebAppMojo
}
//Still don't have a web.xml file: try the resourceBase of the webapp, if it is set
if (webApp.getDescriptor() == null && webApp.getResourceBase() != null)
if (webApp.getDescriptor() == null && webApp.getBaseResource() != null)
{
// TODO: should never return from WEB-INF/lib/foo.jar!/WEB-INF/web.xml
// TODO: should also never return from a META-INF/versions/#/WEB-INF/web.xml location
Resource r = webApp.getResourceBase().resolve("WEB-INF/web.xml");
Resource r = webApp.getBaseResource().resolve("WEB-INF/web.xml");
if (r.exists() && !r.isDirectory())
{
webApp.setDescriptor(r.toString());

View File

@ -46,7 +46,7 @@ public class MavenQuickStartConfiguration extends QuickStartConfiguration
//Iterate over all of the resource bases and ignore any that were original bases, just
//deleting the overlays
Resource res = context.getResourceBase();
Resource res = context.getBaseResource();
if (res instanceof ResourceCollection)
{
for (Resource r : ((ResourceCollection)res).getResources())

View File

@ -47,21 +47,21 @@ public class OverlayManager
for (Overlay o : getOverlays())
{
//can refer to the current project in list of overlays for ordering purposes
if (o.getConfig() != null && o.getConfig().isCurrentProject() && webApp.getResourceBase().exists())
if (o.getConfig() != null && o.getConfig().isCurrentProject() && webApp.getBaseResource().exists())
{
resourceBases.add(webApp.getResourceBase());
resourceBases.add(webApp.getBaseResource());
continue;
}
//add in the selectively unpacked overlay in the correct order to the webapp's resource base
resourceBases.add(unpackOverlay(o));
}
if (!resourceBases.contains(webApp.getResourceBase()) && webApp.getResourceBase().exists())
if (!resourceBases.contains(webApp.getBaseResource()) && webApp.getBaseResource().exists())
{
if (webApp.getBaseAppFirst())
resourceBases.add(0, webApp.getResourceBase());
resourceBases.add(0, webApp.getBaseResource());
else
resourceBases.add(webApp.getResourceBase());
resourceBases.add(webApp.getBaseResource());
}
webApp.setBaseResource(Resource.combine(resourceBases));

View File

@ -105,11 +105,11 @@ public class WebAppPropertyConverter
props.put(TMP_DIR_PERSIST, Boolean.toString(webApp.isPersistTempDirectory()));
//send over the calculated resource bases that includes unpacked overlays
Resource baseResource = webApp.getResourceBase();
Resource baseResource = webApp.getBaseResource();
if (baseResource instanceof ResourceCollection)
props.put(BASE_DIRS, toCSV(((ResourceCollection)webApp.getResourceBase()).getResources()));
props.put(BASE_DIRS, toCSV(((ResourceCollection)webApp.getBaseResource()).getResources()));
else if (baseResource instanceof Resource)
props.put(BASE_DIRS, webApp.getResourceBase().toString());
props.put(BASE_DIRS, webApp.getBaseResource().toString());
//if there is a war file, use that
if (webApp.getWar() != null)

View File

@ -152,9 +152,9 @@ public class TestWebAppPropertyConverter
assertEquals(true, webApp.isPersistTempDirectory());
assertEquals(war.getAbsolutePath(), webApp.getWar());
assertEquals(webXml.getAbsolutePath(), webApp.getDescriptor());
assertThat(webApp.getResourceBase(), instanceOf(ResourceCollection.class));
assertThat(webApp.getBaseResource(), instanceOf(ResourceCollection.class));
ResourceCollection resourceCollection = (ResourceCollection)webApp.getResourceBase();
ResourceCollection resourceCollection = (ResourceCollection)webApp.getBaseResource();
List<URI> actual = resourceCollection.getResources().stream().filter(Objects::nonNull).map(Resource::getURI).toList();
URI[] expected = new URI[]{base1.toURI(), base2.toURI()};
assertThat(actual, containsInAnyOrder(expected));

View File

@ -94,17 +94,17 @@
* gzip content encoded if a matching resource is
* found ending with ".gz"
*
* resourceBase Set to replace the context resource base
* baseResource Set to replace the context resource base
*
* resourceCache If set, this is a context attribute name, which the servlet
* will use to look for a shared ResourceCache instance.
*
* relativeResourceBase
* relativeBaseResource
* Set with a pathname relative to the base of the
* servlet context root. Useful for only serving static content out
* of only specific subdirectories.
*
* pathInfoOnly If true, only the path info will be applied to the resourceBase
* pathInfoOnly If true, only the path info will be applied to the baseResource
*
* stylesheet Set with the location of an optional stylesheet that will be used
* to decorate the directory listing html.

View File

@ -18,7 +18,6 @@ import java.nio.file.Files;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.jetty.ee10.annotations.AnnotationConfiguration;
import org.eclipse.jetty.ee10.annotations.AnnotationDecorator;
import org.eclipse.jetty.ee10.webapp.AbstractConfiguration;
import org.eclipse.jetty.ee10.webapp.Configuration;
@ -96,7 +95,7 @@ public class QuickStartConfiguration extends AbstractConfiguration
//check that webapp is suitable for quick start - it is not a packed war
String war = context.getWar();
if (war == null || war.length() <= 0 || !context.getResourceBase().isDirectory())
if (war == null || war.length() <= 0 || !context.getBaseResource().isDirectory())
throw new IllegalStateException("Bad Quickstart location");
//look for quickstart-web.xml in WEB-INF of webapp
@ -233,7 +232,7 @@ public class QuickStartConfiguration extends AbstractConfiguration
Resource webInf = context.getWebInf();
if (webInf == null || !webInf.exists())
{
Files.createDirectories(context.getResourceBase().getPath().resolve("WEB-INF"));
Files.createDirectories(context.getBaseResource().getPath().resolve("WEB-INF"));
webInf = context.getWebInf();
}

View File

@ -151,7 +151,7 @@ public class QuickStartDescriptorProcessor extends IterativeDescriptorProcessor
default -> values.add(value);
}
AttributeNormalizer normalizer = new AttributeNormalizer(context.getResourceBase());
AttributeNormalizer normalizer = new AttributeNormalizer(context.getBaseResource());
// handle values
switch (name)
{
@ -240,7 +240,7 @@ public class QuickStartDescriptorProcessor extends IterativeDescriptorProcessor
//also add to base resource of webapp
List<Resource> collection = new ArrayList<>();
collection.add(context.getResourceBase());
collection.add(context.getBaseResource());
collection.addAll(metaInfResources);
context.setBaseResource(Resource.combine(collection));
}

View File

@ -142,7 +142,7 @@ public class QuickStartGeneratorConfiguration extends AbstractConfiguration
_originAttribute = DEFAULT_ORIGIN_ATTRIBUTE_NAME;
context.getMetaData().getOrigins();
if (context.getResourceBase() == null)
if (context.getBaseResource() == null)
throw new IllegalArgumentException("No base resource for " + this);
MetaData md = context.getMetaData();
@ -166,7 +166,7 @@ public class QuickStartGeneratorConfiguration extends AbstractConfiguration
// Set some special context parameters
// The location of the war file on disk
AttributeNormalizer normalizer = new AttributeNormalizer(context.getResourceBase());
AttributeNormalizer normalizer = new AttributeNormalizer(context.getBaseResource());
// The library order
addContextParamFromAttribute(context, out, ServletContext.ORDERED_LIBS);

View File

@ -16,7 +16,7 @@ detected.
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- Required minimal context configuration : -->
<!-- + contextPath -->
<!-- + war OR resourceBase -->
<!-- + war OR baseResource -->
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<Set name="contextPath">/test</Set>

View File

@ -73,6 +73,9 @@ import org.eclipse.jetty.util.resource.ResourceFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* TODO restore javadoc
*/
public class DefaultServlet extends HttpServlet
{
private static final Logger LOG = LoggerFactory.getLogger(DefaultServlet.class);
@ -94,8 +97,8 @@ public class DefaultServlet extends HttpServlet
_resourceService = new ServletResourceService(servletContextHandler);
_resourceService.setWelcomeFactory(_resourceService);
_baseResource = servletContextHandler.getResourceBase();
String rb = getInitParameter("resourceBase");
_baseResource = servletContextHandler.getBaseResource();
String rb = getInitParameter("baseResource", "resourceBase");
if (rb != null)
{
try
@ -105,7 +108,7 @@ public class DefaultServlet extends HttpServlet
}
catch (Exception e)
{
LOG.warn("Unable to create resourceBase from {}", rb, e);
LOG.warn("Unable to create baseResource from {}", rb, e);
throw new UnavailableException(e.toString());
}
}
@ -225,6 +228,25 @@ public class DefaultServlet extends HttpServlet
LOG.debug("base resource = {}", _baseResource);
}
private String getInitParameter(String name, String... deprecated)
{
String value = super.getInitParameter(name);
if (value != null)
return value;
for (String d : deprecated)
{
value = super.getInitParameter(d);
if (value != name)
{
LOG.warn("Deprecated {} used instead of {}", d, name);
return value;
}
}
return null;
}
@Override
public void destroy()
{

View File

@ -781,7 +781,7 @@ public class ServletContextHandler extends ContextHandler implements Graceful
if (pathInContext == null || !pathInContext.startsWith(URIUtil.SLASH))
throw new MalformedURLException(pathInContext);
Resource baseResource = getResourceBase();
Resource baseResource = getBaseResource();
if (baseResource == null)
return null;
@ -1079,7 +1079,7 @@ public class ServletContextHandler extends ContextHandler implements Graceful
if (getContextPath() == null)
throw new IllegalStateException("Null contextPath");
Resource baseResource = getResourceBase();
Resource baseResource = getBaseResource();
if (baseResource != null && baseResource.isAlias())
LOG.warn("BaseResource {} is aliased to {} in {}. May not be supported in future releases.",
baseResource, baseResource.getAlias(), this);

View File

@ -197,7 +197,7 @@ public class ServletTester extends ContainerLifeCycle
public Resource getResourceBase()
{
return _context.getResourceBase();
return _context.getBaseResource();
}
public void setResourceBase(Resource base)

View File

@ -29,7 +29,7 @@
<Item>
<New id="defcontext" class="org.eclipse.jetty.server.handler.ContextHandler">
<Set name="contextPath">/tests</Set>
<Set name="ResourceBase"><Property name="test.docroot.base"/>/default
<Set name="baseResource"><Property name="test.docroot.base"/>/default
</Set>
<Set name="Handler">
<New id="reshandler" class="org.eclipse.jetty.server.handler.ResourceHandler"/>

View File

@ -47,7 +47,7 @@
<Item>VirtualHost</Item>
</Array>
</Set>
<Set name="ResourceBase"><Property name="test.docroot.base"/>/virtualhost</Set>
<Set name="BaseResource"><Property name="test.docroot.base"/>/virtualhost</Set>
<Set name="Handler"><New id="reshandler1" class="org.eclipse.jetty.server.handler.ResourceHandler"/></Set>
<Set name="DisplayName">virtual</Set>
</New>
@ -55,7 +55,7 @@
<Item>
<New id="defcontext" class="org.eclipse.jetty.server.handler.ContextHandler">
<Set name="contextPath">/tests</Set>
<Set name="ResourceBase"><Property name="test.docroot.base"/>/default</Set>
<Set name="BaseResource"><Property name="test.docroot.base"/>/default</Set>
<Set name="Handler"><New id="reshandler2" class="org.eclipse.jetty.server.handler.ResourceHandler"/></Set>
<Set name="DisplayName">default</Set>
</New>

View File

@ -94,17 +94,17 @@
* gzip content encoded if a matching resource is
* found ending with ".gz"
*
* resourceBase Set to replace the context resource base
* baseResource Set to replace the context resource base
*
* resourceCache If set, this is a context attribute name, which the servlet
* will use to look for a shared ResourceCache instance.
*
* relativeResourceBase
* relativeBaseResource
* Set with a pathname relative to the base of the
* servlet context root. Useful for only serving static content out
* of only specific subdirectories.
*
* pathInfoOnly If true, only the path info will be applied to the resourceBase
* pathInfoOnly If true, only the path info will be applied to the baseResource
*
* stylesheet Set with the location of an optional stylesheet that will be used
* to decorate the directory listing html.

View File

@ -94,17 +94,17 @@
* If set to a boolean True, then a default set of compressed formats
* will be used, otherwise no precompressed formats.
*
* resourceBase Set to replace the context resource base
* baseResource Set to replace the context resource base
*
* resourceCache If set, this is a context attribute name, which the servlet
* will use to look for a shared ResourceCache instance.
*
* relativeResourceBase
* relativeBaseResource
* Set with a pathname relative to the base of the
* servlet context root. Useful for only serving static content out
* of only specific subdirectories.
*
* pathInfoOnly If true, only the path info will be applied to the resourceBase
* pathInfoOnly If true, only the path info will be applied to the baseResource
*
* stylesheet Set with the location of an optional stylesheet that will be used
* to decorate the directory listing html.

View File

@ -264,7 +264,7 @@ public class MetaInfConfiguration extends AbstractConfiguration
if (resources != null && !resources.isEmpty())
{
List<Resource> collection = new ArrayList<>();
collection.add(context.getResourceBase());
collection.add(context.getBaseResource());
collection.addAll(resources);
context.setBaseResource(Resource.combine(collection));
}

View File

@ -786,7 +786,7 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
/**
* @return Returns the war as a file or URL string (Resource).
* The war may be different to the @link {@link #getResourceBase()}
* The war may be different to the @link {@link #getBaseResource()}
* if the war has been expanded and/or copied.
*/
@ManagedAttribute(value = "war file location", readonly = true)
@ -794,9 +794,9 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
{
if (_war == null)
{
if (getResourceBase() != null)
if (getBaseResource() != null)
{
Path warPath = getResourceBase().getPath();
Path warPath = getBaseResource().getPath();
if (warPath != null)
_war = warPath.toUri().toASCIIString();
}
@ -806,7 +806,7 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
public Resource getWebInf() throws IOException
{
if (getResourceBase() == null)
if (getBaseResource() == null)
return null;
// Is there a WEB-INF directory anywhere in the Resource Base?
@ -814,7 +814,7 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
// The result could be a ResourceCollection with multiple WEB-INF directories
// Can return from WEB-INF/lib/foo.jar!/WEB-INF
// Can also never return from a META-INF/versions/#/WEB-INF location
Resource webInf = getResourceBase().resolve("WEB-INF/");
Resource webInf = getBaseResource().resolve("WEB-INF/");
if (!webInf.exists() || !webInf.isDirectory())
return null;
@ -929,9 +929,9 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
else
name = _war;
}
else if (getResourceBase() != null)
else if (getBaseResource() != null)
{
name = getResourceBase().getURI().toASCIIString();
name = getBaseResource().getURI().toASCIIString();
int webapps = name.indexOf("/webapps/");
if (webapps >= 0)
name = name.substring(webapps + 8);

View File

@ -281,9 +281,9 @@ public class WebInfConfiguration extends AbstractConfiguration
public void unpack(WebAppContext context) throws IOException
{
Resource webApp = context.getResourceBase();
Resource webApp = context.getBaseResource();
_resourceFactory = ResourceFactory.closeable();
_preUnpackBaseResource = context.getResourceBase();
_preUnpackBaseResource = context.getBaseResource();
if (webApp == null)
{
@ -291,7 +291,7 @@ public class WebInfConfiguration extends AbstractConfiguration
if (war != null && war.length() > 0)
webApp = context.newResource(war);
else
webApp = context.getResourceBase();
webApp = context.getBaseResource();
if (webApp == null)
throw new IllegalStateException("No resourceBase or war set for context");
@ -516,7 +516,7 @@ public class WebInfConfiguration extends AbstractConfiguration
// Resource base
try
{
Resource resource = context.getResourceBase();
Resource resource = context.getBaseResource();
if (resource == null)
{
if (context.getWar() == null || context.getWar().length() == 0)

View File

@ -53,7 +53,6 @@ import org.eclipse.jetty.util.resource.ResourceFactory;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
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;
@ -306,9 +305,15 @@ public class WebAppContextTest
assertFalse(context.isProtectedTarget("/something-else/web-inf"));
}
@Disabled //TODO
@Test
public void testProtectedTarget() throws Exception
@ParameterizedTest
@ValueSource(strings = {
"/test.xml",
"/%2e/%2e/test.xml",
"/%u002e/%u002e/test.xml",
"/foo/%2e%2e/test.xml",
"/foo/%u002e%u002e/test.xml"
})
public void testUnProtectedTarget(String target) throws Exception
{
Server server = newServer();
@ -328,46 +333,58 @@ public class WebAppContextTest
server.start();
assertThat(HttpTester.parseResponse(connector.getResponse("GET /test.xml HTTP/1.1\r\nHost: localhost:8080\r\nConnection: close\r\n\r\n")).getStatus(), is(HttpStatus.OK_200));
assertThat(HttpTester.parseResponse(connector.getResponse("GET /%2e/%2e/test.xml HTTP/1.1\r\nHost: localhost:8080\r\nConnection: close\r\n\r\n")).getStatus(), is(HttpStatus.OK_200));
assertThat(HttpTester.parseResponse(connector.getResponse("GET /%u002e/%u002e/test.xml HTTP/1.1\r\nHost: localhost:8080\r\nConnection: close\r\n\r\n")).getStatus(), is(HttpStatus.OK_200));
assertThat(HttpTester.parseResponse(connector.getResponse("GET /foo/%2e%2e/test.xml HTTP/1.1\r\nHost: localhost:8080\r\nConnection: close\r\n\r\n")).getStatus(), is(HttpStatus.OK_200));
assertThat(HttpTester.parseResponse(connector.getResponse("GET /foo/%u002e%u002e/test.xml HTTP/1.1\r\nHost: localhost:8080\r\nConnection: close\r\n\r\n")).getStatus(), is(HttpStatus.OK_200));
assertThat(HttpTester.parseResponse(connector.getResponse("GET /WEB-INF HTTP/1.1\r\nHost: localhost:8080\r\nConnection: close\r\n\r\n")).getStatus(), is(HttpStatus.NOT_FOUND_404));
assertThat(HttpTester.parseResponse(connector.getResponse("GET /WEB-INF/ HTTP/1.1\r\nHost: localhost:8080\r\nConnection: close\r\n\r\n")).getStatus(), is(HttpStatus.NOT_FOUND_404));
assertThat(HttpTester.parseResponse(connector.getResponse("GET /WEB-INF/test.xml HTTP/1.1\r\nHost: localhost:8080\r\nConnection: close\r\n\r\n")).getStatus(), is(HttpStatus.NOT_FOUND_404));
assertThat(HttpTester.parseResponse(connector.getResponse("GET /web-inf/test.xml HTTP/1.1\r\nHost: localhost:8080\r\nConnection: close\r\n\r\n")).getStatus(), is(HttpStatus.NOT_FOUND_404));
assertThat(HttpTester.parseResponse(connector.getResponse("GET /%2e/WEB-INF/test.xml HTTP/1.1\r\nHost: localhost:8080\r\nConnection: close\r\n\r\n")).getStatus(), is(HttpStatus.NOT_FOUND_404));
assertThat(HttpTester.parseResponse(connector.getResponse("GET /%u002e/WEB-INF/test.xml HTTP/1.1\r\nHost: localhost:8080\r\nConnection: close\r\n\r\n")).getStatus(), is(HttpStatus.NOT_FOUND_404));
assertThat(HttpTester.parseResponse(connector.getResponse("GET /%2e/%2e/WEB-INF/test.xml HTTP/1.1\r\nHost: localhost:8080\r\nConnection: close\r\n\r\n")).getStatus(), is(HttpStatus.NOT_FOUND_404));
assertThat(HttpTester.parseResponse(connector.getResponse("GET /%u002e/%u002e/WEB-INF/test.xml HTTP/1.1\r\nHost: localhost:8080\r\nConnection: close\r\n\r\n")).getStatus(), is(HttpStatus.NOT_FOUND_404));
assertThat(HttpTester.parseResponse(connector.getResponse("GET /foo/%2e%2e/WEB-INF/test.xml HTTP/1.1\r\nHost: localhost:8080\r\nConnection: close\r\n\r\n")).getStatus(), is(HttpStatus.NOT_FOUND_404));
assertThat(HttpTester.parseResponse(connector.getResponse("GET /foo/%u002e%u002e/WEB-INF/test.xml HTTP/1.1\r\nHost: localhost:8080\r\nConnection: close\r\n\r\n")).getStatus(), is(HttpStatus.NOT_FOUND_404));
assertThat(HttpTester.parseResponse(connector.getResponse("GET /%2E/WEB-INF/test.xml HTTP/1.1\r\nHost: localhost:8080\r\nConnection: close\r\n\r\n")).getStatus(), is(HttpStatus.NOT_FOUND_404));
assertThat(HttpTester.parseResponse(connector.getResponse("GET /%u002E/WEB-INF/test.xml HTTP/1.1\r\nHost: localhost:8080\r\nConnection: close\r\n\r\n")).getStatus(), is(HttpStatus.NOT_FOUND_404));
assertThat(HttpTester.parseResponse(connector.getResponse("GET //WEB-INF/test.xml HTTP/1.1\r\nHost: localhost:8080\r\nConnection: close\r\n\r\n")).getStatus(), is(HttpStatus.NOT_FOUND_404));
assertThat(HttpTester.parseResponse(connector.getResponse("GET /WEB-INF%2ftest.xml HTTP/1.1\r\nHost: localhost:8080\r\nConnection: close\r\n\r\n")).getStatus(), is(HttpStatus.NOT_FOUND_404));
assertThat(HttpTester.parseResponse(connector.getResponse("GET " + target + " HTTP/1.1\r\nHost: localhost:8080\r\nConnection: close\r\n\r\n")).getStatus(), is(HttpStatus.OK_200));
}
@ParameterizedTest
@ValueSource(strings = {
"/WEB-INF",
"/WEB-INF/",
"/WEB-INF%2F",
"/WEB-INF/test.xml",
"/web-inf/test.xml",
"/%2e/WEB-INF/test.xml",
"/%u002e/WEB-INF/test.xml",
"/%2e/%2e/WEB-INF/test.xml",
"/%u002e/%u002e/WEB-INF/test.xml",
"/foo/%2e%2e/WEB-INF/test.xml",
"/foo/%u002e%u002e/WEB-INF/test.xml",
"/%2E/WEB-INF/test.xml",
"//WEB-INF/test.xml",
"/WEB-INF%2ftest.xml",
"/.%00/WEB-INF/test.xml",
"/WEB-INF%00/test.xml"
"/%u002E/WEB-INF/test.xml",
"//WEB-INF/test.xml" /* TODO,
"/WEB-INF%2Ftest.xml",
"/WEB-INF%u002Ftest.xml",
"/WEB-INF%2ftest.xml" */
})
public void testProtectedTarget(String target) throws Exception
{
Server server = newServer();
Handler.Collection handlers = new Handler.Collection();
ContextHandlerCollection contexts = new ContextHandlerCollection();
WebAppContext context = new WebAppContext();
Path testWebapp = MavenTestingUtils.getProjectDirPath("src/test/webapp");
context.setBaseResource(testWebapp);
context.setContextPath("/");
server.setHandler(handlers);
handlers.addHandler(contexts);
contexts.addHandler(context);
LocalConnector connector = new LocalConnector(server);
server.addConnector(connector);
connector.getConnectionFactory(HttpConnectionFactory.class).getHttpConfiguration().setUriCompliance(UriCompliance.RFC3986);
server.start();
assertThat(HttpTester.parseResponse(connector.getResponse("GET " + target + " HTTP/1.1\r\nHost: localhost:8080\r\nConnection: close\r\n\r\n")).getStatus(), is(HttpStatus.NOT_FOUND_404));
}
@ParameterizedTest
@ValueSource(strings = {
"/.%00/WEB-INF/test.xml",
"/WEB-INF%00/test.xml",
"/WEB-INF%u0000/test.xml"
})
@Disabled //TODO
@Test
public void testProtectedTargetFailure(String path) throws Exception
{
Server server = newServer();
@ -389,10 +406,9 @@ public class WebAppContextTest
server.start();
assertThat(HttpTester.parseResponse(connector.getResponse("GET " + path + " HTTP/1.1\r\nHost: localhost:8080\r\nConnection: close\r\n\r\n")).getStatus(),
Matchers.anyOf(is(HttpStatus.NOT_FOUND_404), is(HttpStatus.BAD_REQUEST_400)));
Matchers.anyOf(is(HttpStatus.BAD_REQUEST_400)));
}
@Disabled //TODO
@Test
public void testNullPath() throws Exception
{

View File

@ -16,7 +16,7 @@ detected.
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- Required minimal context configuration : -->
<!-- + contextPath -->
<!-- + war OR resourceBase -->
<!-- + war OR baseResource -->
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<Set name="contextPath">/</Set>
<Set name="war"><SystemProperty name="jetty.home" default="."/>/webapps/ee9-demo-jetty.war</Set>

View File

@ -10,7 +10,7 @@ Configure and deploy the test web application
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- Required minimal context configuration : -->
<!-- + contextPath -->
<!-- + war OR resourceBase -->
<!-- + war OR baseResource -->
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<Set name="contextPath">/ee8-test</Set>
<Set name="war"><Property name="jetty.webapps" default="." />/ee8-demo-jetty.war

View File

@ -102,17 +102,17 @@
* If set to a boolean True, then a default set of compressed formats
* will be used, otherwise no precompressed formats.
*
* resourceBase Set to replace the context resource base
* baseResource Set to replace the context resource base
*
* resourceCache If set, this is a context attribute name, which the servlet
* will use to look for a shared ResourceCache instance.
*
* relativeResourceBase
* relativeBaseResource
* Set with a pathname relative to the base of the
* servlet context root. Useful for only serving static content out
* of only specific subdirectories.
*
* pathInfoOnly If true, only the path info will be applied to the resourceBase
* pathInfoOnly If true, only the path info will be applied to the baseResource
*
* stylesheet Set with the location of an optional stylesheet that will be used
* to decorate the directory listing html.

View File

@ -102,17 +102,17 @@
* If set to a boolean True, then a default set of compressed formats
* will be used, otherwise no precompressed formats.
*
* resourceBase Set to replace the context resource base
* baseResource Set to replace the context resource base
*
* resourceCache If set, this is a context attribute name, which the servlet
* will use to look for a shared ResourceCache instance.
*
* relativeResourceBase
* relativeBaseResource
* Set with a pathname relative to the base of the
* servlet context root. Useful for only serving static content out
* of only specific subdirectories.
*
* pathInfoOnly If true, only the path info will be applied to the resourceBase
* pathInfoOnly If true, only the path info will be applied to the baseResource
*
* stylesheet Set with the location of an optional stylesheet that will be used
* to decorate the directory listing html.

View File

@ -16,7 +16,7 @@ detected.
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- Required minimal context configuration : -->
<!-- + contextPath -->
<!-- + war OR resourceBase -->
<!-- + war OR baseResource -->
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<Set name="contextPath">/</Set>
<Set name="war"><SystemProperty name="jetty.home" default="."/>/webapps/ee9-demo-jetty.war</Set>

View File

@ -10,7 +10,7 @@ Configure and deploy the test web application
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- Required minimal context configuration : -->
<!-- + contextPath -->
<!-- + war OR resourceBase -->
<!-- + war OR baseResource -->
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<Set name="contextPath">/ee9-test</Set>
<Set name="war"><Property name="jetty.webapps" default="." />/ee9-demo-jetty.war

View File

@ -1103,7 +1103,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
*/
public Resource getBaseResource()
{
return _coreContextHandler.getResourceBase();
return _coreContextHandler.getBaseResource();
}
/**
@ -1112,7 +1112,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
@ManagedAttribute("document root for context")
public String getResourceBase()
{
Resource resourceBase = _coreContextHandler.getResourceBase();
Resource resourceBase = _coreContextHandler.getBaseResource();
return resourceBase == null ? null : resourceBase.toString();
}
@ -1127,12 +1127,25 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
_coreContextHandler.setBaseResource(base);
}
/**
* Set the base resource for this context.
*
* @param base The resource used as the base for all static content of this context.
* @see #setResourceBase(String)
*/
public void setBaseResource(Path base)
{
_coreContextHandler.setBaseResource(base);
}
/**
* Set the base resource for this context.
*
* @param resourceBase A string representing the base resource for the context. Any string accepted by {@link ResourceFactory#newResource(String)} may be passed and the
* call is equivalent to <code>setBaseResource(newResource(resourceBase));</code>
* @deprecated use #setBaseResource
*/
@Deprecated
public void setResourceBase(String resourceBase)
{
try
@ -1357,7 +1370,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
if (pathInContext == null || !pathInContext.startsWith(URIUtil.SLASH))
throw new MalformedURLException(pathInContext);
Resource baseResource = _coreContextHandler.getResourceBase();
Resource baseResource = _coreContextHandler.getBaseResource();
if (baseResource == null)
return null;

View File

@ -15,6 +15,7 @@ package org.eclipse.jetty.ee9.nested;
import java.io.IOException;
import java.net.URI;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@ -193,6 +194,7 @@ public class ResourceHandler extends HandlerWrapper implements ResourceFactory,
/**
* @return Returns the base resource as a string.
*/
@Deprecated
public String getResourceBase()
{
if (_baseResource == null)
@ -319,6 +321,15 @@ public class ResourceHandler extends HandlerWrapper implements ResourceFactory,
_baseResource = base;
}
/**
* @param basePath The resourceBase to server content from. If null the
* context resource base is used.
*/
public void setBaseResource(Path basePath)
{
setBaseResource(ResourceFactory.root().newResource(basePath));
}
/**
* @param cacheControl the cacheControl header to set on all static content.
*/
@ -395,7 +406,9 @@ public class ResourceHandler extends HandlerWrapper implements ResourceFactory,
/**
* @param resourceBase The base resource as a string.
* @deprecated use {@link #setBaseResource(Resource)}
*/
@Deprecated
public void setResourceBase(String resourceBase)
{
try

View File

@ -94,17 +94,17 @@
* gzip content encoded if a matching resource is
* found ending with ".gz"
*
* resourceBase Set to replace the context resource base
* baseResource Set to replace the context resource base
*
* resourceCache If set, this is a context attribute name, which the servlet
* will use to look for a shared ResourceCache instance.
*
* relativeResourceBase
* relativeBaseResource
* Set with a pathname relative to the base of the
* servlet context root. Useful for only serving static content out
* of only specific subdirectories.
*
* pathInfoOnly If true, only the path info will be applied to the resourceBase
* pathInfoOnly If true, only the path info will be applied to the baseResource
*
* stylesheet Set with the location of an optional stylesheet that will be used
* to decorate the directory listing html.

View File

@ -125,7 +125,7 @@ public class PreconfigureQuickStartWar
XmlConfiguration xmlConfiguration = new XmlConfiguration(xml);
xmlConfiguration.configure(webapp);
}
webapp.setResourceBase(dir.getPath().toAbsolutePath().toString());
webapp.setBaseResource(dir.getPath().toAbsolutePath());
server.setHandler(webapp);
try
{

View File

@ -16,7 +16,7 @@ detected.
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- Required minimal context configuration : -->
<!-- + contextPath -->
<!-- + war OR resourceBase -->
<!-- + war OR baseResource -->
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<Set name="contextPath">/test</Set>

View File

@ -83,17 +83,17 @@ import org.slf4j.LoggerFactory;
* If set to a boolean True, then a default set of compressed formats
* will be used, otherwise no precompressed formats.
*
* resourceBase Set to replace the context resource base
* baseResource Set to replace the context resource base
*
* resourceCache If set, this is a context attribute name, which the servlet
* will use to look for a shared ResourceCache instance.
*
* relativeResourceBase
* relativeBaseResource
* Set with a pathname relative to the base of the
* servlet context root. Useful for only serving static content out
* of only specific subdirectories.
*
* pathInfoOnly If true, only the path info will be applied to the resourceBase
* pathInfoOnly If true, only the path info will be applied to the baseResource
*
* stylesheet Set with the location of an optional stylesheet that will be used
* to decorate the directory listing html.
@ -136,7 +136,7 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory, Welc
private boolean _welcomeServlets = false;
private boolean _welcomeExactServlets = false;
private Resource _resourceBase;
private Resource _baseResource;
private CachedContentFactory _cache;
private MimeTypes _mimeTypes;
@ -144,7 +144,7 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory, Welc
private ResourceFactory.Closeable _resourceFactory;
private Resource _stylesheet;
private boolean _useFileMappedBuffer = false;
private String _relativeResourceBase;
private String _relativeBaseResource;
private ServletHandler _servletHandler;
public DefaultServlet(ResourceService resourceService)
@ -188,20 +188,20 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory, Welc
_useFileMappedBuffer = getInitBoolean("useFileMappedBuffer", _useFileMappedBuffer);
_relativeResourceBase = getInitParameter("relativeResourceBase");
_relativeBaseResource = getInitParameter("relativeBaseResource", "relativeResourceBase");
String rb = getInitParameter("resourceBase");
if (rb != null)
String br = getInitParameter("baseResource", "resourceBase");
if (br != null)
{
if (_relativeResourceBase != null)
throw new UnavailableException("resourceBase & relativeResourceBase");
if (_relativeBaseResource != null)
throw new UnavailableException("baseResource & relativeBaseResource");
try
{
_resourceBase = _contextHandler.newResource(rb);
_baseResource = _contextHandler.newResource(br);
}
catch (Exception e)
{
LOG.warn("Unable to create resourceBase from {}", rb, e);
LOG.warn("Unable to create baseResource from {}", br, e);
throw new UnavailableException(e.toString());
}
}
@ -248,7 +248,7 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory, Welc
{
if (maxCacheSize != -1 || maxCachedFileSize != -2 || maxCachedFiles != -2)
LOG.debug("ignoring resource cache configuration, using resourceCache attribute");
if (_relativeResourceBase != null || _resourceBase != null)
if (_relativeBaseResource != null || _baseResource != null)
throw new UnavailableException("resourceCache specified with resource bases");
_cache = (CachedContentFactory)_servletContext.getAttribute(resourceCache);
}
@ -305,7 +305,26 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory, Welc
_servletHandler = _contextHandler.getChildHandlerByClass(ServletHandler.class);
if (LOG.isDebugEnabled())
LOG.debug("resource base = {}", _resourceBase);
LOG.debug("resource base = {}", _baseResource);
}
private String getInitParameter(String name, String... deprecated)
{
String value = super.getInitParameter(name);
if (value != null)
return value;
for (String d : deprecated)
{
value = super.getInitParameter(d);
if (value != name)
{
LOG.warn("Deprecated {} used instead of {}", d, name);
return value;
}
}
return null;
}
private CompressedContentFormat[] parsePrecompressedFormats(String precompressed, Boolean gzip, CompressedContentFormat[] dft)
@ -431,14 +450,14 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory, Welc
subUriPath = URIUtil.encodePath(subUriPath);
Resource r = null;
if (_relativeResourceBase != null)
subUriPath = URIUtil.addPaths(_relativeResourceBase, subUriPath);
if (_relativeBaseResource != null)
subUriPath = URIUtil.addPaths(_relativeBaseResource, subUriPath);
try
{
if (_resourceBase != null)
if (_baseResource != null)
{
r = _resourceBase.resolve(subUriPath);
r = _baseResource.resolve(subUriPath);
if (!_contextHandler.checkAlias(subUriPath, r))
r = null;
}

View File

@ -203,11 +203,13 @@ public class ServletTester extends ContainerLifeCycle
_context.setBaseResource(resource);
}
@Deprecated
public String getResourceBase()
{
return _context.getResourceBase();
}
@Deprecated
public void setResourceBase(String resourceBase)
{
_context.setResourceBase(resourceBase);

View File

@ -94,7 +94,7 @@ public class DispatcherTest
_contextHandler.setContextPath("/context");
_contextCollection.addHandler(_contextHandler);
_resourceHandler = new ResourceHandler();
_resourceHandler.setResourceBase(MavenTestingUtils.getTargetFile("test-classes/dispatchResourceTest").getAbsolutePath());
_resourceHandler.setBaseResource(MavenTestingUtils.getTargetFile("test-classes/dispatchResourceTest").toPath());
_resourceHandler.setPathInfoOnly(true);
ContextHandler resourceContextHandler = new ContextHandler("/resource");
resourceContextHandler.setHandler(_resourceHandler);

View File

@ -29,7 +29,7 @@
<Item>
<New id="defcontext" class="org.eclipse.jetty.server.handler.ContextHandler">
<Set name="contextPath">/tests</Set>
<Set name="ResourceBase"><Property name="test.docroot.base"/>/default
<Set name="baseResource"><Property name="test.docroot.base"/>/default
</Set>
<Set name="Handler">
<New id="reshandler" class="org.eclipse.jetty.server.handler.ResourceHandler"/>

View File

@ -47,7 +47,7 @@
<Item>VirtualHost</Item>
</Array>
</Set>
<Set name="ResourceBase"><Property name="test.docroot.base"/>/virtualhost</Set>
<Set name="BaseResource"><Property name="test.docroot.base"/>/virtualhost</Set>
<Set name="Handler"><New id="reshandler1" class="org.eclipse.jetty.server.handler.ResourceHandler"/></Set>
<Set name="DisplayName">virtual</Set>
</New>
@ -55,7 +55,7 @@
<Item>
<New id="defcontext" class="org.eclipse.jetty.server.handler.ContextHandler">
<Set name="contextPath">/tests</Set>
<Set name="ResourceBase"><Property name="test.docroot.base"/>/default</Set>
<Set name="baseResource"><Property name="test.docroot.base"/>/default</Set>
<Set name="Handler"><New id="reshandler2" class="org.eclipse.jetty.server.handler.ResourceHandler"/></Set>
<Set name="DisplayName">default</Set>
</New>

View File

@ -94,17 +94,17 @@
* gzip content encoded if a matching resource is
* found ending with ".gz"
*
* resourceBase Set to replace the context resource base
* baseResource Set to replace the context resource base
*
* resourceCache If set, this is a context attribute name, which the servlet
* will use to look for a shared ResourceCache instance.
*
* relativeResourceBase
* relativeBaseResource
* Set with a pathname relative to the base of the
* servlet context root. Useful for only serving static content out
* of only specific subdirectories.
*
* pathInfoOnly If true, only the path info will be applied to the resourceBase
* pathInfoOnly If true, only the path info will be applied to the baseResource
*
* stylesheet Set with the location of an optional stylesheet that will be used
* to decorate the directory listing html.

View File

@ -102,17 +102,17 @@
* If set to a boolean True, then a default set of compressed formats
* will be used, otherwise no precompressed formats.
*
* resourceBase Set to replace the context resource base
* baseResource Set to replace the context resource base
*
* resourceCache If set, this is a context attribute name, which the servlet
* will use to look for a shared ResourceCache instance.
*
* relativeResourceBase
* relativeBaseResource
* Set with a pathname relative to the base of the
* servlet context root. Useful for only serving static content out
* of only specific subdirectories.
*
* pathInfoOnly If true, only the path info will be applied to the resourceBase
* pathInfoOnly If true, only the path info will be applied to the baseResource
*
* stylesheet Set with the location of an optional stylesheet that will be used
* to decorate the directory listing html.

View File

@ -100,7 +100,7 @@ public class WSServer extends LocalServer implements LocalFuzzer.Provider
context = new WebAppContext();
context.setContextPath("/" + contextName);
context.setInitParameter("org.eclipse.jetty.ee9.servlet.Default.dirAllowed", "false");
context.setResourceBase(contextDir.toAbsolutePath().toString());
context.setBaseResource(contextDir.toAbsolutePath());
context.setAttribute("org.eclipse.jetty.websocket.jakarta", Boolean.TRUE);
context.addConfiguration(new JakartaWebSocketConfiguration());
}