Fixing DefaultServletTest.testWelcomeMultipleDefaultServletsDifferentBases
This commit is contained in:
parent
7133c0827e
commit
e1ee2e3fa2
|
@ -177,6 +177,7 @@ public class CachingContentFactory implements HttpContent.ContentFactory
|
||||||
else
|
else
|
||||||
removeFromCache(cachingHttpContent);
|
removeFromCache(cachingHttpContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpContent httpContent = _authority.getContent(path, maxBuffer);
|
HttpContent httpContent = _authority.getContent(path, maxBuffer);
|
||||||
// Do not cache directories or files that are too big
|
// Do not cache directories or files that are too big
|
||||||
if (httpContent != null && !httpContent.getResource().isDirectory() && httpContent.getContentLengthValue() <= _maxCachedFileSize)
|
if (httpContent != null && !httpContent.getResource().isDirectory() && httpContent.getContentLengthValue() <= _maxCachedFileSize)
|
||||||
|
|
|
@ -19,7 +19,6 @@ import java.nio.channels.ReadableByteChannel;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.InvalidPathException;
|
import java.nio.file.InvalidPathException;
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -43,7 +42,6 @@ import org.eclipse.jetty.util.Callback;
|
||||||
import org.eclipse.jetty.util.IO;
|
import org.eclipse.jetty.util.IO;
|
||||||
import org.eclipse.jetty.util.IteratingCallback;
|
import org.eclipse.jetty.util.IteratingCallback;
|
||||||
import org.eclipse.jetty.util.URIUtil;
|
import org.eclipse.jetty.util.URIUtil;
|
||||||
import org.eclipse.jetty.util.resource.Resource;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -59,7 +57,6 @@ public class ResourceService
|
||||||
private static final int NO_CONTENT_LENGTH = -1;
|
private static final int NO_CONTENT_LENGTH = -1;
|
||||||
private static final int USE_KNOWN_CONTENT_LENGTH = -2;
|
private static final int USE_KNOWN_CONTENT_LENGTH = -2;
|
||||||
|
|
||||||
private boolean _pathInfoOnly = false;
|
|
||||||
private CompressedContentFormat[] _precompressedFormats = new CompressedContentFormat[0];
|
private CompressedContentFormat[] _precompressedFormats = new CompressedContentFormat[0];
|
||||||
private WelcomeFactory _welcomeFactory;
|
private WelcomeFactory _welcomeFactory;
|
||||||
private boolean _redirectWelcome = false;
|
private boolean _redirectWelcome = false;
|
||||||
|
@ -392,7 +389,7 @@ public class ResourceService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// look for a welcome file
|
// process optional Welcome behaviors
|
||||||
if (welcome(request, response, callback))
|
if (welcome(request, response, callback))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -400,41 +397,81 @@ public class ResourceService
|
||||||
sendDirectory(request, response, content, callback, pathInContext);
|
sendDirectory(request, response, content, callback, pathInContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum WelcomeActionType
|
||||||
|
{
|
||||||
|
REDIRECT,
|
||||||
|
SERVE
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Behavior for a potential welcome action
|
||||||
|
* as determined by {@link ResourceService#processWelcome(Request, Response)}
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* For {@link WelcomeActionType#REDIRECT} this is the resulting `Location` response header.
|
||||||
|
* For {@link WelcomeActionType#SERVE} this is the resulting path to for welcome serve, note that
|
||||||
|
* this is just a path, and can point to a real file, or a dynamic handler for
|
||||||
|
* welcome processing (such as Jetty core Handler, or EE Servlet), it's up
|
||||||
|
* to the implementation of {@link ResourceService#welcome(Request, Response, Callback)}
|
||||||
|
* to handle the various action types.
|
||||||
|
* </p>
|
||||||
|
* @param type the type of action
|
||||||
|
* @param target The target URI path of the action.
|
||||||
|
*/
|
||||||
|
public record WelcomeAction(WelcomeActionType type, String target) {}
|
||||||
|
|
||||||
protected boolean welcome(Request request, Response response, Callback callback) throws IOException
|
protected boolean welcome(Request request, Response response, Callback callback) throws IOException
|
||||||
{
|
{
|
||||||
String pathInContext = request.getPathInContext();
|
WelcomeAction welcomeAction = processWelcome(request, response);
|
||||||
String welcome = _welcomeFactory == null ? null : _welcomeFactory.getWelcomeFile(pathInContext);
|
if (welcomeAction == null)
|
||||||
if (welcome != null)
|
return false;
|
||||||
|
|
||||||
|
switch (welcomeAction.type)
|
||||||
{
|
{
|
||||||
String contextPath = request.getContext().getContextPath();
|
case REDIRECT ->
|
||||||
|
|
||||||
if (_pathInfoOnly)
|
|
||||||
welcome = URIUtil.addPaths(contextPath, welcome);
|
|
||||||
|
|
||||||
if (LOG.isDebugEnabled())
|
|
||||||
LOG.debug("welcome={}", welcome);
|
|
||||||
|
|
||||||
if (_redirectWelcome)
|
|
||||||
{
|
{
|
||||||
// Redirect to the index
|
|
||||||
response.getHeaders().putLongField(HttpHeader.CONTENT_LENGTH, 0);
|
response.getHeaders().putLongField(HttpHeader.CONTENT_LENGTH, 0);
|
||||||
// TODO need URI util that handles param and query without reconstructing entire URI with scheme and authority
|
Response.sendRedirect(request, response, callback, welcomeAction.target);
|
||||||
HttpURI.Mutable uri = HttpURI.build(request.getHttpURI());
|
return true;
|
||||||
String parameter = uri.getParam();
|
}
|
||||||
uri.path(URIUtil.addPaths(request.getContext().getContextPath(), welcome));
|
case SERVE ->
|
||||||
uri.param(parameter);
|
{
|
||||||
Response.sendRedirect(request, response, callback, uri.getPathQuery());
|
// TODO output buffer size????
|
||||||
|
HttpContent c = _contentFactory.getContent(welcomeAction.target, 16 * 1024);
|
||||||
|
sendData(request, response, callback, c, null);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Serve welcome file
|
|
||||||
HttpContent c = _contentFactory.getContent(welcome, 16 * 1024); // TODO output buffer size????
|
|
||||||
sendData(request, response, callback, c, null);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected WelcomeAction processWelcome(Request request, Response response) throws IOException
|
||||||
|
{
|
||||||
|
String welcomeTarget = _welcomeFactory.getWelcomeTarget(request);
|
||||||
|
if (welcomeTarget == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
String contextPath = request.getContext().getContextPath();
|
||||||
|
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("welcome={}", welcomeTarget);
|
||||||
|
|
||||||
|
if (_redirectWelcome)
|
||||||
|
{
|
||||||
|
// Redirect to the index
|
||||||
|
response.getHeaders().putLongField(HttpHeader.CONTENT_LENGTH, 0);
|
||||||
|
// TODO need URI util that handles param and query without reconstructing entire URI with scheme and authority
|
||||||
|
HttpURI.Mutable uri = HttpURI.build(request.getHttpURI());
|
||||||
|
String parameter = uri.getParam();
|
||||||
|
uri.path(URIUtil.addPaths(request.getContext().getContextPath(), welcomeTarget));
|
||||||
|
uri.param(parameter);
|
||||||
|
return new WelcomeAction(WelcomeActionType.REDIRECT, uri.getPathQuery());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Serve welcome file
|
||||||
|
return new WelcomeAction(WelcomeActionType.SERVE, welcomeTarget);
|
||||||
|
}
|
||||||
|
|
||||||
private void sendDirectory(Request request, Response response, HttpContent httpContent, Callback callback, String pathInContext) throws IOException
|
private void sendDirectory(Request request, Response response, HttpContent httpContent, Callback callback, String pathInContext) throws IOException
|
||||||
{
|
{
|
||||||
if (!_dirAllowed)
|
if (!_dirAllowed)
|
||||||
|
@ -678,14 +715,6 @@ public class ResourceService
|
||||||
return _precompressedFormats;
|
return _precompressedFormats;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return true, only the path info will be applied to the resourceBase
|
|
||||||
*/
|
|
||||||
public boolean isPathInfoOnly()
|
|
||||||
{
|
|
||||||
return _pathInfoOnly;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return If true, welcome files are redirected rather than forwarded to.
|
* @return If true, welcome files are redirected rather than forwarded to.
|
||||||
*/
|
*/
|
||||||
|
@ -761,14 +790,6 @@ public class ResourceService
|
||||||
return _encodingCacheSize;
|
return _encodingCacheSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param pathInfoOnly true, only the path info will be applied to the resourceBase
|
|
||||||
*/
|
|
||||||
public void setPathInfoOnly(boolean pathInfoOnly)
|
|
||||||
{
|
|
||||||
_pathInfoOnly = pathInfoOnly;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param redirectWelcome If true, welcome files are redirected rather than forwarded to.
|
* @param redirectWelcome If true, welcome files are redirected rather than forwarded to.
|
||||||
* redirection is always used if the ResourceHandler is not scoped by
|
* redirection is always used if the ResourceHandler is not scoped by
|
||||||
|
@ -786,14 +807,14 @@ public class ResourceService
|
||||||
|
|
||||||
public interface WelcomeFactory
|
public interface WelcomeFactory
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds a matching welcome file for the supplied {@link Resource}.
|
* Finds a matching welcome target URI path for the request.
|
||||||
* TODO would be better to pass back a URI or a Resource
|
*
|
||||||
* @param pathInContext the path of the request
|
* @param request the request to use to determine the matching welcome target from.
|
||||||
* @return The path of the matching welcome file in context or null.
|
* @return The URI path of the matching welcome target in context or null
|
||||||
|
* (null means no welcome target was found)
|
||||||
*/
|
*/
|
||||||
String getWelcomeFile(String pathInContext) throws IOException;
|
String getWelcomeTarget(Request request) throws IOException;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ContentWriterIteratingCallback extends IteratingCallback
|
private static class ContentWriterIteratingCallback extends IteratingCallback
|
||||||
|
|
|
@ -81,15 +81,15 @@ public class ResourceHandler extends Handler.Wrapper
|
||||||
{
|
{
|
||||||
HttpContent.ContentFactory contentFactory = new CachingContentFactory(new ResourceContentFactory(_resourceBase, _mimeTypes, _resourceService.getPrecompressedFormats()));
|
HttpContent.ContentFactory contentFactory = new CachingContentFactory(new ResourceContentFactory(_resourceBase, _mimeTypes, _resourceService.getPrecompressedFormats()));
|
||||||
_resourceService.setContentFactory(contentFactory);
|
_resourceService.setContentFactory(contentFactory);
|
||||||
_resourceService.setWelcomeFactory(pathInContext ->
|
_resourceService.setWelcomeFactory(request ->
|
||||||
{
|
{
|
||||||
if (_welcomes == null)
|
if (_welcomes == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
for (String welcome : _welcomes)
|
for (String welcome : _welcomes)
|
||||||
{
|
{
|
||||||
String welcomeInContext = URIUtil.addPaths(pathInContext, welcome);
|
String welcomeInContext = URIUtil.addPaths(request.getPathInContext(), welcome);
|
||||||
Resource welcomePath = _resourceBase.resolve(pathInContext).resolve(welcome);
|
Resource welcomePath = _resourceBase.resolve(request.getPathInContext()).resolve(welcome);
|
||||||
if (welcomePath != null && welcomePath.exists())
|
if (welcomePath != null && welcomePath.exists())
|
||||||
return welcomeInContext;
|
return welcomeInContext;
|
||||||
}
|
}
|
||||||
|
@ -204,14 +204,6 @@ public class ResourceHandler extends Handler.Wrapper
|
||||||
return _resourceService.getPrecompressedFormats();
|
return _resourceService.getPrecompressedFormats();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return true, only the path info will be applied to the resourceBase
|
|
||||||
*/
|
|
||||||
public boolean isPathInfoOnly()
|
|
||||||
{
|
|
||||||
return _resourceService.isPathInfoOnly();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return If true, welcome files are redirected rather than forwarded to.
|
* @return If true, welcome files are redirected rather than forwarded to.
|
||||||
*/
|
*/
|
||||||
|
@ -296,14 +288,6 @@ public class ResourceHandler extends Handler.Wrapper
|
||||||
setupContentFactory();
|
setupContentFactory();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param pathInfoOnly true, only the path info will be applied to the resourceBase
|
|
||||||
*/
|
|
||||||
public void setPathInfoOnly(boolean pathInfoOnly)
|
|
||||||
{
|
|
||||||
_resourceService.setPathInfoOnly(pathInfoOnly);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param redirectWelcome If true, welcome files are redirected rather than forwarded to.
|
* @param redirectWelcome If true, welcome files are redirected rather than forwarded to.
|
||||||
* redirection is always used if the ResourceHandler is not scoped by
|
* redirection is always used if the ResourceHandler is not scoped by
|
||||||
|
|
|
@ -75,10 +75,13 @@ public class DefaultServlet extends HttpServlet
|
||||||
private boolean _welcomeExactServlets = false;
|
private boolean _welcomeExactServlets = false;
|
||||||
|
|
||||||
private Resource.Mount _resourceBaseMount;
|
private Resource.Mount _resourceBaseMount;
|
||||||
|
private Resource _baseResource;
|
||||||
private Resource.Mount _stylesheetMount;
|
private Resource.Mount _stylesheetMount;
|
||||||
private Resource _stylesheet;
|
private Resource _stylesheet;
|
||||||
private boolean _useFileMappedBuffer = false;
|
private boolean _useFileMappedBuffer = false;
|
||||||
|
|
||||||
|
private boolean _isPathInfoOnly = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init() throws ServletException
|
public void init() throws ServletException
|
||||||
{
|
{
|
||||||
|
@ -86,7 +89,7 @@ public class DefaultServlet extends HttpServlet
|
||||||
_resourceService = new ServletResourceService(servletContextHandler);
|
_resourceService = new ServletResourceService(servletContextHandler);
|
||||||
_resourceService.setWelcomeFactory(_resourceService);
|
_resourceService.setWelcomeFactory(_resourceService);
|
||||||
|
|
||||||
Resource baseResource = servletContextHandler.getResourceBase();
|
_baseResource = servletContextHandler.getResourceBase();
|
||||||
String rb = getInitParameter("resourceBase");
|
String rb = getInitParameter("resourceBase");
|
||||||
if (rb != null)
|
if (rb != null)
|
||||||
{
|
{
|
||||||
|
@ -94,7 +97,7 @@ public class DefaultServlet extends HttpServlet
|
||||||
{
|
{
|
||||||
URI resourceUri = Resource.toURI(rb);
|
URI resourceUri = Resource.toURI(rb);
|
||||||
_resourceBaseMount = Resource.mountIfNeeded(resourceUri);
|
_resourceBaseMount = Resource.mountIfNeeded(resourceUri);
|
||||||
baseResource = Resource.newResource(resourceUri);
|
_baseResource = Resource.newResource(resourceUri);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -109,7 +112,7 @@ public class DefaultServlet extends HttpServlet
|
||||||
CompressedContentFormat[] precompressedFormats = new CompressedContentFormat[0];
|
CompressedContentFormat[] precompressedFormats = new CompressedContentFormat[0];
|
||||||
|
|
||||||
_useFileMappedBuffer = getInitBoolean("useFileMappedBuffer", _useFileMappedBuffer);
|
_useFileMappedBuffer = getInitBoolean("useFileMappedBuffer", _useFileMappedBuffer);
|
||||||
ResourceContentFactory resourceContentFactory = new ResourceContentFactory(baseResource, mimeTypes, precompressedFormats);
|
ResourceContentFactory resourceContentFactory = new ResourceContentFactory(_baseResource, mimeTypes, precompressedFormats);
|
||||||
CachingContentFactory cached = new CachingContentFactory(resourceContentFactory, _useFileMappedBuffer);
|
CachingContentFactory cached = new CachingContentFactory(resourceContentFactory, _useFileMappedBuffer);
|
||||||
|
|
||||||
int maxCacheSize = getInitInt("maxCacheSize", -2);
|
int maxCacheSize = getInitInt("maxCacheSize", -2);
|
||||||
|
@ -145,9 +148,10 @@ public class DefaultServlet extends HttpServlet
|
||||||
_resourceService.setDirAllowed(getInitBoolean("dirAllowed", _resourceService.isDirAllowed()));
|
_resourceService.setDirAllowed(getInitBoolean("dirAllowed", _resourceService.isDirAllowed()));
|
||||||
_resourceService.setRedirectWelcome(getInitBoolean("redirectWelcome", _resourceService.isRedirectWelcome()));
|
_resourceService.setRedirectWelcome(getInitBoolean("redirectWelcome", _resourceService.isRedirectWelcome()));
|
||||||
_resourceService.setPrecompressedFormats(parsePrecompressedFormats(getInitParameter("precompressed"), getInitBoolean("gzip"), _resourceService.getPrecompressedFormats()));
|
_resourceService.setPrecompressedFormats(parsePrecompressedFormats(getInitParameter("precompressed"), getInitBoolean("gzip"), _resourceService.getPrecompressedFormats()));
|
||||||
_resourceService.setPathInfoOnly(getInitBoolean("pathInfoOnly", _resourceService.isPathInfoOnly()));
|
|
||||||
_resourceService.setEtags(getInitBoolean("etags", _resourceService.isEtags()));
|
_resourceService.setEtags(getInitBoolean("etags", _resourceService.isEtags()));
|
||||||
|
|
||||||
|
_isPathInfoOnly = getInitBoolean("pathInfoOnly", _isPathInfoOnly);
|
||||||
|
|
||||||
if ("exact".equals(getInitParameter("welcomeServlets")))
|
if ("exact".equals(getInitParameter("welcomeServlets")))
|
||||||
{
|
{
|
||||||
_welcomeExactServlets = true;
|
_welcomeExactServlets = true;
|
||||||
|
@ -216,7 +220,7 @@ public class DefaultServlet extends HttpServlet
|
||||||
// TODO: remove? _servletHandler = _contextHandler.getChildHandlerByClass(ServletHandler.class);
|
// TODO: remove? _servletHandler = _contextHandler.getChildHandlerByClass(ServletHandler.class);
|
||||||
|
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("base resource = {}", baseResource);
|
LOG.debug("base resource = {}", _baseResource);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -302,10 +306,19 @@ public class DefaultServlet extends HttpServlet
|
||||||
servletContext.getClass().getName() + " is not " + ContextHandler.Context.class.getName());
|
servletContext.getClass().getName() + " is not " + ContextHandler.Context.class.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean isPathInfoOnly()
|
||||||
|
{
|
||||||
|
return _isPathInfoOnly;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
|
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
|
||||||
{
|
{
|
||||||
String pathInContext = _resourceService.isPathInfoOnly() ? req.getPathInfo() : URIUtil.addPaths(req.getServletPath(), req.getPathInfo());
|
// TODO: need special handling here for included if request.getAttribute(RequestDispatcher.INCLUDE_REQUEST_URI) is not null?
|
||||||
|
// Handling things like RequestDispatcher.INCLUDE_PATH_INFO?
|
||||||
|
// or is this handled elsewhere now?
|
||||||
|
|
||||||
|
String pathInContext = isPathInfoOnly() ? req.getPathInfo() : URIUtil.addPaths(req.getServletPath(), req.getPathInfo());
|
||||||
HttpContent content = _resourceService.getContent(pathInContext, resp.getBufferSize());
|
HttpContent content = _resourceService.getContent(pathInContext, resp.getBufferSize());
|
||||||
if (content == null)
|
if (content == null)
|
||||||
{
|
{
|
||||||
|
@ -776,20 +789,23 @@ public class DefaultServlet extends HttpServlet
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getWelcomeFile(String pathInContext) throws IOException
|
public String getWelcomeTarget(Request coreRequest) throws IOException
|
||||||
{
|
{
|
||||||
String[] welcomes = _servletContextHandler.getWelcomeFiles();
|
String[] welcomes = _servletContextHandler.getWelcomeFiles();
|
||||||
|
|
||||||
if (welcomes == null)
|
if (welcomes == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
// TODO this feels inefficient
|
HttpServletRequest request = getServletRequest(coreRequest);
|
||||||
Resource base = _servletContextHandler.getResourceBase().resolve(pathInContext);
|
|
||||||
|
String requestTarget = isPathInfoOnly() ? request.getPathInfo() : coreRequest.getPathInContext();
|
||||||
|
|
||||||
|
Resource base = _baseResource.resolve(requestTarget);
|
||||||
String welcomeServlet = null;
|
String welcomeServlet = null;
|
||||||
for (String welcome : welcomes)
|
for (String welcome : welcomes)
|
||||||
{
|
{
|
||||||
Resource welcomePath = base.resolve(welcome);
|
Resource welcomePath = base.resolve(welcome);
|
||||||
String welcomeInContext = URIUtil.addPaths(pathInContext, welcome);
|
String welcomeInContext = URIUtil.addPaths(coreRequest.getPathInContext(), welcome);
|
||||||
|
|
||||||
if (welcomePath != null && welcomePath.exists())
|
if (welcomePath != null && welcomePath.exists())
|
||||||
return welcomeInContext;
|
return welcomeInContext;
|
||||||
|
@ -806,81 +822,92 @@ public class DefaultServlet extends HttpServlet
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean welcome(Request rq, Response rs, Callback callback) throws IOException
|
protected boolean welcome(Request coreRequest, Response coreResponse, Callback callback) throws IOException
|
||||||
{
|
{
|
||||||
// TODO The contract of this method is very confused: it has a callback a return and throws?
|
HttpServletRequest request = getServletRequest(coreRequest);
|
||||||
|
HttpServletResponse response = getServletResponse(coreResponse);
|
||||||
// TODO, this unwrapping is fragile
|
|
||||||
HttpServletRequest request = ((ServletCoreRequest)rq)._request;
|
|
||||||
HttpServletResponse response = ((ServletCoreResponse)rs)._response;
|
|
||||||
String pathInContext = rq.getPathInContext();
|
|
||||||
WelcomeFactory welcomeFactory = getWelcomeFactory();
|
|
||||||
String welcome = welcomeFactory == null ? null : welcomeFactory.getWelcomeFile(pathInContext);
|
|
||||||
boolean included = request.getAttribute(RequestDispatcher.INCLUDE_REQUEST_URI) != null;
|
boolean included = request.getAttribute(RequestDispatcher.INCLUDE_REQUEST_URI) != null;
|
||||||
|
|
||||||
if (welcome == null)
|
WelcomeAction welcomeAction = super.processWelcome(coreRequest, coreResponse);
|
||||||
|
if (welcomeAction == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
String servletPath = included ? (String)request.getAttribute(RequestDispatcher.INCLUDE_SERVLET_PATH)
|
String welcome = welcomeAction.target();
|
||||||
: request.getServletPath();
|
|
||||||
|
|
||||||
if (isPathInfoOnly())
|
|
||||||
welcome = URIUtil.addPaths(servletPath, welcome);
|
|
||||||
|
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("welcome={}", welcome);
|
LOG.debug("welcome={}", welcome);
|
||||||
|
|
||||||
ServletContext context = request.getServletContext();
|
ServletContext context = request.getServletContext();
|
||||||
|
switch (welcomeAction.type())
|
||||||
if (isRedirectWelcome() || context == null)
|
|
||||||
{
|
{
|
||||||
// Redirect to the index
|
case REDIRECT ->
|
||||||
response.setContentLength(0);
|
|
||||||
// TODO need URI util that handles param and query without reconstructing entire URI with scheme and authority
|
|
||||||
HttpURI.Mutable uri = HttpURI.build(rq.getHttpURI());
|
|
||||||
String parameter = uri.getParam();
|
|
||||||
uri.path(URIUtil.addPaths(rq.getContext().getContextPath(), welcome));
|
|
||||||
uri.param(parameter);
|
|
||||||
response.sendRedirect(response.encodeRedirectURL(uri.getPathQuery()));
|
|
||||||
callback.succeeded();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
RequestDispatcher dispatcher = context.getRequestDispatcher(URIUtil.encodePath(welcome));
|
|
||||||
if (dispatcher != null)
|
|
||||||
{
|
|
||||||
// Forward to the index
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
if (included)
|
if (isRedirectWelcome() || context == null)
|
||||||
{
|
{
|
||||||
dispatcher.include(request, response);
|
String servletPath = included ? (String)request.getAttribute(RequestDispatcher.INCLUDE_SERVLET_PATH)
|
||||||
|
: request.getServletPath();
|
||||||
|
|
||||||
|
if (isPathInfoOnly())
|
||||||
|
welcome = URIUtil.addPaths(servletPath, welcome);
|
||||||
|
|
||||||
|
response.setContentLength(0);
|
||||||
|
response.sendRedirect(welcome);
|
||||||
|
callback.succeeded();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
request.setAttribute("org.eclipse.jetty.server.welcome", welcome);
|
|
||||||
dispatcher.forward(request, response);
|
|
||||||
}
|
|
||||||
callback.succeeded();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (ServletException e)
|
case SERVE ->
|
||||||
{
|
{
|
||||||
callback.failed(e);
|
RequestDispatcher dispatcher = context.getRequestDispatcher(welcome);
|
||||||
|
if (dispatcher != null)
|
||||||
|
{
|
||||||
|
// Forward to the index
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (included)
|
||||||
|
{
|
||||||
|
dispatcher.include(request, response);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
request.setAttribute("org.eclipse.jetty.server.welcome", welcomeAction.target());
|
||||||
|
dispatcher.forward(request, response);
|
||||||
|
}
|
||||||
|
callback.succeeded();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (ServletException e)
|
||||||
|
{
|
||||||
|
callback.failed(e);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean passConditionalHeaders(Request request, Response response, HttpContent content, Callback callback) throws IOException
|
protected boolean passConditionalHeaders(Request request, Response response, HttpContent content, Callback callback) throws IOException
|
||||||
{
|
{
|
||||||
boolean included = ((ServletCoreRequest)request)._request.getAttribute(RequestDispatcher.INCLUDE_REQUEST_URI) != null;
|
boolean included = getServletRequest(request).getAttribute(RequestDispatcher.INCLUDE_REQUEST_URI) != null;
|
||||||
if (included)
|
if (included)
|
||||||
return true;
|
return true;
|
||||||
return super.passConditionalHeaders(request, response, content, callback);
|
return super.passConditionalHeaders(request, response, content, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private HttpServletRequest getServletRequest(Request request)
|
||||||
|
{
|
||||||
|
// TODO, this unwrapping is fragile
|
||||||
|
return ((ServletCoreRequest)request)._request;
|
||||||
|
}
|
||||||
|
|
||||||
|
private HttpServletResponse getServletResponse(Response response)
|
||||||
|
{
|
||||||
|
// TODO, this unwrapping is fragile
|
||||||
|
return ((ServletCoreResponse)response)._response;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,6 @@ package org.eclipse.jetty.ee10.servlet;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLClassLoader;
|
import java.net.URLClassLoader;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
|
@ -153,7 +152,7 @@ public class DefaultServletTest
|
||||||
response = HttpTester.parseResponse(rawResponse);
|
response = HttpTester.parseResponse(rawResponse);
|
||||||
assertThat(response.toString(), response.getStatus(), is(HttpStatus.NOT_FOUND_404));
|
assertThat(response.toString(), response.getStatus(), is(HttpStatus.NOT_FOUND_404));
|
||||||
|
|
||||||
createFile(file, "How now brown cow");
|
Files.writeString(file, "How now brown cow", UTF_8);
|
||||||
|
|
||||||
rawResponse = connector.getResponse("""
|
rawResponse = connector.getResponse("""
|
||||||
GET /context/file.txt HTTP/1.1\r
|
GET /context/file.txt HTTP/1.1\r
|
||||||
|
@ -418,7 +417,6 @@ public class DefaultServletTest
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Disabled
|
|
||||||
public void testListingProperUrlEncoding() throws Exception
|
public void testListingProperUrlEncoding() throws Exception
|
||||||
{
|
{
|
||||||
ServletHolder defholder = context.addServlet(DefaultServlet.class, "/*");
|
ServletHolder defholder = context.addServlet(DefaultServlet.class, "/*");
|
||||||
|
@ -710,7 +708,7 @@ public class DefaultServletTest
|
||||||
/* create some content in the docroot */
|
/* create some content in the docroot */
|
||||||
|
|
||||||
Path index = docRoot.resolve("index.html");
|
Path index = docRoot.resolve("index.html");
|
||||||
createFile(index, "<h1>Hello Index</h1>");
|
Files.writeString(index, "<h1>Hello Index</h1>", UTF_8);
|
||||||
|
|
||||||
if (!OS.WINDOWS.isCurrentOs())
|
if (!OS.WINDOWS.isCurrentOs())
|
||||||
{
|
{
|
||||||
|
@ -725,7 +723,7 @@ public class DefaultServletTest
|
||||||
Path sekret = workDir.getPath().resolve("sekret");
|
Path sekret = workDir.getPath().resolve("sekret");
|
||||||
FS.ensureDirExists(sekret);
|
FS.ensureDirExists(sekret);
|
||||||
Path pass = sekret.resolve("pass");
|
Path pass = sekret.resolve("pass");
|
||||||
createFile(pass, "Sssh, you shouldn't be seeing this");
|
Files.writeString(pass, "Sssh, you shouldn't be seeing this", UTF_8);
|
||||||
|
|
||||||
/* At this point we have the following
|
/* At this point we have the following
|
||||||
* testListingContextBreakout/
|
* testListingContextBreakout/
|
||||||
|
@ -814,11 +812,11 @@ public class DefaultServletTest
|
||||||
FS.ensureDirExists(two);
|
FS.ensureDirExists(two);
|
||||||
FS.ensureDirExists(three);
|
FS.ensureDirExists(three);
|
||||||
|
|
||||||
createFile(one.resolve("index.htm"), "<h1>Hello Inde</h1>");
|
Files.writeString(one.resolve("index.htm"), "<h1>Hello Inde</h1>", UTF_8);
|
||||||
createFile(two.resolve("index.html"), "<h1>Hello Index</h1>");
|
Files.writeString(two.resolve("index.html"), "<h1>Hello Index</h1>", UTF_8);
|
||||||
|
|
||||||
createFile(three.resolve("index.html"), "<h1>Three Index</h1>");
|
Files.writeString(three.resolve("index.html"), "<h1>Three Index</h1>", UTF_8);
|
||||||
createFile(three.resolve("index.htm"), "<h1>Three Inde</h1>");
|
Files.writeString(three.resolve("index.htm"), "<h1>Three Inde</h1>", UTF_8);
|
||||||
|
|
||||||
ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
|
ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
|
||||||
defholder.setInitParameter("dirAllowed", "false");
|
defholder.setInitParameter("dirAllowed", "false");
|
||||||
|
@ -841,8 +839,7 @@ public class DefaultServletTest
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Disabled
|
public void testWelcomeMultipleDefaultServletsDifferentBases() throws Exception
|
||||||
public void testWelcomeMultipleBasesBase() throws Exception
|
|
||||||
{
|
{
|
||||||
Path dir = docRoot.resolve("dir");
|
Path dir = docRoot.resolve("dir");
|
||||||
FS.ensureDirExists(dir);
|
FS.ensureDirExists(dir);
|
||||||
|
@ -892,9 +889,9 @@ public class DefaultServletTest
|
||||||
""");
|
""");
|
||||||
response = HttpTester.parseResponse(rawResponse);
|
response = HttpTester.parseResponse(rawResponse);
|
||||||
assertThat(response.toString(), response.getStatus(), is(HttpStatus.MOVED_TEMPORARILY_302));
|
assertThat(response.toString(), response.getStatus(), is(HttpStatus.MOVED_TEMPORARILY_302));
|
||||||
assertThat(response, containsHeaderValue("Location", "http://0.0.0.0/context/other/"));
|
assertThat(response, containsHeaderValue("Location", "http://local/context/other/"));
|
||||||
|
|
||||||
// Test alt default
|
// Test alt default, should see no directory listing output (dirAllowed == false per config)
|
||||||
rawResponse = connector.getResponse("""
|
rawResponse = connector.getResponse("""
|
||||||
GET /context/alt/dir/ HTTP/1.1\r
|
GET /context/alt/dir/ HTTP/1.1\r
|
||||||
Host: local\r
|
Host: local\r
|
||||||
|
@ -904,7 +901,9 @@ public class DefaultServletTest
|
||||||
response = HttpTester.parseResponse(rawResponse);
|
response = HttpTester.parseResponse(rawResponse);
|
||||||
assertThat(response.toString(), response.getStatus(), is(HttpStatus.FORBIDDEN_403));
|
assertThat(response.toString(), response.getStatus(), is(HttpStatus.FORBIDDEN_403));
|
||||||
|
|
||||||
createFile(altIndex, "<h1>Alt Index</h1>");
|
// Test alt welcome file, there's no index.html here yet, so let's create it and try
|
||||||
|
// accessing it directly
|
||||||
|
Files.writeString(altIndex, "<h1>Alt Index</h1>", UTF_8);
|
||||||
rawResponse = connector.getResponse("""
|
rawResponse = connector.getResponse("""
|
||||||
GET /context/alt/dir/index.html HTTP/1.1\r
|
GET /context/alt/dir/index.html HTTP/1.1\r
|
||||||
Host: local\r
|
Host: local\r
|
||||||
|
@ -915,6 +914,8 @@ public class DefaultServletTest
|
||||||
assertThat(response.toString(), response.getStatus(), is(HttpStatus.OK_200));
|
assertThat(response.toString(), response.getStatus(), is(HttpStatus.OK_200));
|
||||||
assertThat(response.getContent(), containsString("<h1>Alt Index</h1>"));
|
assertThat(response.getContent(), containsString("<h1>Alt Index</h1>"));
|
||||||
|
|
||||||
|
// Test alt welcome file, there now exists an index.html, lets try accessing
|
||||||
|
// it via the welcome file behaviors
|
||||||
rawResponse = connector.getResponse("""
|
rawResponse = connector.getResponse("""
|
||||||
GET /context/alt/dir/ HTTP/1.1\r
|
GET /context/alt/dir/ HTTP/1.1\r
|
||||||
Host: local\r
|
Host: local\r
|
||||||
|
@ -925,7 +926,10 @@ public class DefaultServletTest
|
||||||
assertThat(response.toString(), response.getStatus(), is(HttpStatus.OK_200));
|
assertThat(response.toString(), response.getStatus(), is(HttpStatus.OK_200));
|
||||||
assertThat(response.getContent(), containsString("<h1>Alt Index</h1>"));
|
assertThat(response.getContent(), containsString("<h1>Alt Index</h1>"));
|
||||||
|
|
||||||
createFile(altInde, "<h1>Alt Inde</h1>");
|
// Let's create an index.htm (no 'l') and see if the welcome file logic holds,
|
||||||
|
// we should still see the original `index.html` as that's the first welcome
|
||||||
|
// file listed
|
||||||
|
Files.writeString(altInde, "<h1>Alt Inde</h1>", UTF_8);
|
||||||
rawResponse = connector.getResponse("""
|
rawResponse = connector.getResponse("""
|
||||||
GET /context/alt/dir/ HTTP/1.1\r
|
GET /context/alt/dir/ HTTP/1.1\r
|
||||||
Host: local\r
|
Host: local\r
|
||||||
|
@ -936,8 +940,12 @@ public class DefaultServletTest
|
||||||
assertThat(response.toString(), response.getStatus(), is(HttpStatus.OK_200));
|
assertThat(response.toString(), response.getStatus(), is(HttpStatus.OK_200));
|
||||||
assertThat(response.getContent(), containsString("<h1>Alt Index</h1>"));
|
assertThat(response.getContent(), containsString("<h1>Alt Index</h1>"));
|
||||||
|
|
||||||
|
// Let's try deleting the `index.html` and accesing the welcome file at `index.htm`
|
||||||
|
// We skip this section of the test if the OS or filesystem doesn't support instantaneous delete
|
||||||
|
// such as what happens on Microsoft Windows.
|
||||||
if (deleteFile(altIndex))
|
if (deleteFile(altIndex))
|
||||||
{
|
{
|
||||||
|
// Access welcome file `index.htm` via the directory request.
|
||||||
rawResponse = connector.getResponse("""
|
rawResponse = connector.getResponse("""
|
||||||
GET /context/alt/dir/ HTTP/1.1\r
|
GET /context/alt/dir/ HTTP/1.1\r
|
||||||
Host: local\r
|
Host: local\r
|
||||||
|
@ -948,6 +956,8 @@ public class DefaultServletTest
|
||||||
assertThat(response.toString(), response.getStatus(), is(HttpStatus.OK_200));
|
assertThat(response.toString(), response.getStatus(), is(HttpStatus.OK_200));
|
||||||
assertThat(response.getContent(), containsString("<h1>Alt Inde</h1>"));
|
assertThat(response.getContent(), containsString("<h1>Alt Inde</h1>"));
|
||||||
|
|
||||||
|
// Delete the welcome file `index.htm`, and access the directory.
|
||||||
|
// We should see no directory listing output (dirAllowed == false per config)
|
||||||
if (deleteFile(altInde))
|
if (deleteFile(altInde))
|
||||||
{
|
{
|
||||||
rawResponse = connector.getResponse("""
|
rawResponse = connector.getResponse("""
|
||||||
|
@ -971,7 +981,7 @@ public class DefaultServletTest
|
||||||
response = HttpTester.parseResponse(rawResponse);
|
response = HttpTester.parseResponse(rawResponse);
|
||||||
assertThat(response.toString(), response.getStatus(), is(HttpStatus.FORBIDDEN_403));
|
assertThat(response.toString(), response.getStatus(), is(HttpStatus.FORBIDDEN_403));
|
||||||
|
|
||||||
createFile(index, "<h1>Hello Index</h1>");
|
Files.writeString(index, "<h1>Hello Index</h1>", UTF_8);
|
||||||
rawResponse = connector.getResponse("""
|
rawResponse = connector.getResponse("""
|
||||||
GET /context/dir/ HTTP/1.1\r
|
GET /context/dir/ HTTP/1.1\r
|
||||||
Host: local\r
|
Host: local\r
|
||||||
|
@ -982,7 +992,7 @@ public class DefaultServletTest
|
||||||
assertThat(response.toString(), response.getStatus(), is(HttpStatus.OK_200));
|
assertThat(response.toString(), response.getStatus(), is(HttpStatus.OK_200));
|
||||||
assertThat(response.getContent(), containsString("<h1>Hello Index</h1>"));
|
assertThat(response.getContent(), containsString("<h1>Hello Index</h1>"));
|
||||||
|
|
||||||
createFile(inde, "<h1>Hello Inde</h1>");
|
Files.writeString(inde, "<h1>Hello Inde</h1>", UTF_8);
|
||||||
rawResponse = connector.getResponse("""
|
rawResponse = connector.getResponse("""
|
||||||
GET /context/dir/ HTTP/1.1\r
|
GET /context/dir/ HTTP/1.1\r
|
||||||
Host: local\r
|
Host: local\r
|
||||||
|
@ -1060,7 +1070,7 @@ public class DefaultServletTest
|
||||||
// should be used
|
// should be used
|
||||||
assertThat(response.toString(), response.getStatus(), is(HttpStatus.INTERNAL_SERVER_ERROR_500));
|
assertThat(response.toString(), response.getStatus(), is(HttpStatus.INTERNAL_SERVER_ERROR_500));
|
||||||
|
|
||||||
createFile(altIndex, "<h1>Alt Index</h1>");
|
Files.writeString(altIndex, "<h1>Alt Index</h1>", UTF_8);
|
||||||
rawResponse = connector.getResponse("""
|
rawResponse = connector.getResponse("""
|
||||||
GET /context/gateway HTTP/1.1\r
|
GET /context/gateway HTTP/1.1\r
|
||||||
Host: local\r
|
Host: local\r
|
||||||
|
@ -1105,7 +1115,7 @@ public class DefaultServletTest
|
||||||
response = HttpTester.parseResponse(rawResponse);
|
response = HttpTester.parseResponse(rawResponse);
|
||||||
assertThat(response.toString(), response.getStatus(), is(HttpStatus.FORBIDDEN_403));
|
assertThat(response.toString(), response.getStatus(), is(HttpStatus.FORBIDDEN_403));
|
||||||
|
|
||||||
createFile(index, "<h1>Hello Index</h1>");
|
Files.writeString(index, "<h1>Hello Index</h1>", UTF_8);
|
||||||
rawResponse = connector.getResponse("""
|
rawResponse = connector.getResponse("""
|
||||||
GET /context/dir/ HTTP/1.1\r
|
GET /context/dir/ HTTP/1.1\r
|
||||||
Host: local\r
|
Host: local\r
|
||||||
|
@ -1116,7 +1126,7 @@ public class DefaultServletTest
|
||||||
assertThat(response.toString(), response.getStatus(), is(HttpStatus.MOVED_TEMPORARILY_302));
|
assertThat(response.toString(), response.getStatus(), is(HttpStatus.MOVED_TEMPORARILY_302));
|
||||||
assertThat(response, headerValue("Location", "http://local/context/dir/index.html"));
|
assertThat(response, headerValue("Location", "http://local/context/dir/index.html"));
|
||||||
|
|
||||||
createFile(inde, "<h1>Hello Inde</h1>");
|
Files.writeString(inde, "<h1>Hello Inde</h1>", UTF_8);
|
||||||
rawResponse = connector.getResponse("""
|
rawResponse = connector.getResponse("""
|
||||||
GET /context/dir HTTP/1.1\r
|
GET /context/dir HTTP/1.1\r
|
||||||
Host: local\r
|
Host: local\r
|
||||||
|
@ -1169,7 +1179,7 @@ public class DefaultServletTest
|
||||||
Path dir = docRoot.resolve("dir");
|
Path dir = docRoot.resolve("dir");
|
||||||
FS.ensureDirExists(dir);
|
FS.ensureDirExists(dir);
|
||||||
Path index = dir.resolve("index.html");
|
Path index = dir.resolve("index.html");
|
||||||
createFile(index, "<h1>Hello Index</h1>");
|
Files.writeString(index, "<h1>Hello Index</h1>", UTF_8);
|
||||||
|
|
||||||
context.addAliasCheck((p, r) -> true);
|
context.addAliasCheck((p, r) -> true);
|
||||||
connector.getConnectionFactory(HttpConfiguration.ConnectionFactory.class).getHttpConfiguration().setRelativeRedirectAllowed(true);
|
connector.getConnectionFactory(HttpConfiguration.ConnectionFactory.class).getHttpConfiguration().setRelativeRedirectAllowed(true);
|
||||||
|
@ -1228,7 +1238,7 @@ public class DefaultServletTest
|
||||||
Path dir = assumeMkDirSupported(docRoot, "dir?");
|
Path dir = assumeMkDirSupported(docRoot, "dir?");
|
||||||
|
|
||||||
Path index = dir.resolve("index.html");
|
Path index = dir.resolve("index.html");
|
||||||
createFile(index, "<h1>Hello Index</h1>");
|
Files.writeString(index, "<h1>Hello Index</h1>", UTF_8);
|
||||||
|
|
||||||
ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
|
ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
|
||||||
defholder.setInitParameter("dirAllowed", "false");
|
defholder.setInitParameter("dirAllowed", "false");
|
||||||
|
@ -1280,7 +1290,7 @@ public class DefaultServletTest
|
||||||
Path dir = assumeMkDirSupported(docRoot, "dir;");
|
Path dir = assumeMkDirSupported(docRoot, "dir;");
|
||||||
|
|
||||||
Path index = dir.resolve("index.html");
|
Path index = dir.resolve("index.html");
|
||||||
createFile(index, "<h1>Hello Index</h1>");
|
Files.writeString(index, "<h1>Hello Index</h1>", UTF_8);
|
||||||
|
|
||||||
ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
|
ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
|
||||||
defholder.setInitParameter("dirAllowed", "false");
|
defholder.setInitParameter("dirAllowed", "false");
|
||||||
|
@ -1299,7 +1309,7 @@ public class DefaultServletTest
|
||||||
""");
|
""");
|
||||||
response = HttpTester.parseResponse(rawResponse);
|
response = HttpTester.parseResponse(rawResponse);
|
||||||
assertThat(response.toString(), response.getStatus(), is(HttpStatus.MOVED_TEMPORARILY_302));
|
assertThat(response.toString(), response.getStatus(), is(HttpStatus.MOVED_TEMPORARILY_302));
|
||||||
assertThat(response, containsHeaderValue("Location", "http://0.0.0.0/context/dir%3B/"));
|
assertThat(response, containsHeaderValue("Location", "http://local/context/dir%3B/"));
|
||||||
|
|
||||||
rawResponse = connector.getResponse("""
|
rawResponse = connector.getResponse("""
|
||||||
GET /context/dir%3B/ HTTP/1.1\r
|
GET /context/dir%3B/ HTTP/1.1\r
|
||||||
|
@ -1309,7 +1319,7 @@ public class DefaultServletTest
|
||||||
""");
|
""");
|
||||||
response = HttpTester.parseResponse(rawResponse);
|
response = HttpTester.parseResponse(rawResponse);
|
||||||
assertThat(response.toString(), response.getStatus(), is(HttpStatus.MOVED_TEMPORARILY_302));
|
assertThat(response.toString(), response.getStatus(), is(HttpStatus.MOVED_TEMPORARILY_302));
|
||||||
assertThat(response, containsHeaderValue("Location", "http://0.0.0.0/context/dir%3B/index.html"));
|
assertThat(response, containsHeaderValue("Location", "http://local/context/dir%3B/index.html"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -1340,7 +1350,7 @@ public class DefaultServletTest
|
||||||
assertThat(response.toString(), response.getStatus(), is(HttpStatus.INTERNAL_SERVER_ERROR_500));
|
assertThat(response.toString(), response.getStatus(), is(HttpStatus.INTERNAL_SERVER_ERROR_500));
|
||||||
assertThat(response.getContent(), containsString("JSP support not configured"));
|
assertThat(response.getContent(), containsString("JSP support not configured"));
|
||||||
|
|
||||||
createFile(index, "<h1>Hello Index</h1>");
|
Files.writeString(index, "<h1>Hello Index</h1>", UTF_8);
|
||||||
rawResponse = connector.getResponse("""
|
rawResponse = connector.getResponse("""
|
||||||
GET /context/ HTTP/1.1\r
|
GET /context/ HTTP/1.1\r
|
||||||
Host: local\r
|
Host: local\r
|
||||||
|
@ -1351,7 +1361,7 @@ public class DefaultServletTest
|
||||||
assertThat(response.toString(), response.getStatus(), is(HttpStatus.OK_200));
|
assertThat(response.toString(), response.getStatus(), is(HttpStatus.OK_200));
|
||||||
assertThat(response.getContent(), containsString("<h1>Hello Index</h1>"));
|
assertThat(response.getContent(), containsString("<h1>Hello Index</h1>"));
|
||||||
|
|
||||||
createFile(inde, "<h1>Hello Inde</h1>");
|
Files.writeString(inde, "<h1>Hello Inde</h1>", UTF_8);
|
||||||
rawResponse = connector.getResponse("""
|
rawResponse = connector.getResponse("""
|
||||||
GET /context/ HTTP/1.1\r
|
GET /context/ HTTP/1.1\r
|
||||||
Host: local\r
|
Host: local\r
|
||||||
|
@ -1401,7 +1411,7 @@ public class DefaultServletTest
|
||||||
Path foobar = dir.resolve("foobar.txt");
|
Path foobar = dir.resolve("foobar.txt");
|
||||||
Path link = dir.resolve("link.txt");
|
Path link = dir.resolve("link.txt");
|
||||||
Path rLink = dir.resolve("rlink.txt");
|
Path rLink = dir.resolve("rlink.txt");
|
||||||
createFile(foobar, "Foo Bar");
|
Files.writeString(foobar, "Foo Bar", UTF_8);
|
||||||
ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
|
ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
|
||||||
|
|
||||||
defholder.setInitParameter("gzip", "false");
|
defholder.setInitParameter("gzip", "false");
|
||||||
|
@ -1579,11 +1589,11 @@ public class DefaultServletTest
|
||||||
FS.ensureDirExists(two);
|
FS.ensureDirExists(two);
|
||||||
FS.ensureDirExists(three);
|
FS.ensureDirExists(three);
|
||||||
|
|
||||||
createFile(one.resolve("index.htm"), "<h1>Hello Inde</h1>");
|
Files.writeString(one.resolve("index.htm"), "<h1>Hello Inde</h1>", UTF_8);
|
||||||
createFile(two.resolve("index.html"), "<h1>Hello Index</h1>");
|
Files.writeString(two.resolve("index.html"), "<h1>Hello Index</h1>", UTF_8);
|
||||||
|
|
||||||
createFile(three.resolve("index.html"), "<h1>Three Index</h1>");
|
Files.writeString(three.resolve("index.html"), "<h1>Three Index</h1>", UTF_8);
|
||||||
createFile(three.resolve("index.htm"), "<h1>Three Inde</h1>");
|
Files.writeString(three.resolve("index.htm"), "<h1>Three Inde</h1>", UTF_8);
|
||||||
|
|
||||||
ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
|
ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
|
||||||
defholder.setInitParameter("dirAllowed", "false");
|
defholder.setInitParameter("dirAllowed", "false");
|
||||||
|
@ -1607,7 +1617,7 @@ public class DefaultServletTest
|
||||||
{
|
{
|
||||||
FS.ensureDirExists(docRoot);
|
FS.ensureDirExists(docRoot);
|
||||||
Path index = docRoot.resolve("index.html");
|
Path index = docRoot.resolve("index.html");
|
||||||
createFile(index, "<h1>Hello World</h1>");
|
Files.writeString(index, "<h1>Hello World</h1>", UTF_8);
|
||||||
|
|
||||||
ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
|
ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
|
||||||
defholder.setInitParameter("dirAllowed", "true");
|
defholder.setInitParameter("dirAllowed", "true");
|
||||||
|
@ -1883,11 +1893,11 @@ public class DefaultServletTest
|
||||||
{
|
{
|
||||||
FS.ensureDirExists(docRoot);
|
FS.ensureDirExists(docRoot);
|
||||||
Path data = docRoot.resolve("data.txt");
|
Path data = docRoot.resolve("data.txt");
|
||||||
createFile(data, "01234567890123456789012345678901234567890123456789012345678901234567890123456789");
|
Files.writeString(data, "01234567890123456789012345678901234567890123456789012345678901234567890123456789", UTF_8);
|
||||||
|
|
||||||
// test a range request with a file with no suffix, therefore no mimetype
|
// test a range request with a file with no suffix, therefore no mimetype
|
||||||
Path nofilesuffix = docRoot.resolve("nofilesuffix");
|
Path nofilesuffix = docRoot.resolve("nofilesuffix");
|
||||||
createFile(nofilesuffix, "01234567890123456789012345678901234567890123456789012345678901234567890123456789");
|
Files.writeString(nofilesuffix, "01234567890123456789012345678901234567890123456789012345678901234567890123456789", UTF_8);
|
||||||
|
|
||||||
ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
|
ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
|
||||||
defholder.setInitParameter("dirAllowed", "false");
|
defholder.setInitParameter("dirAllowed", "false");
|
||||||
|
@ -1909,9 +1919,9 @@ public class DefaultServletTest
|
||||||
{
|
{
|
||||||
FS.ensureDirExists(docRoot);
|
FS.ensureDirExists(docRoot);
|
||||||
Path file0 = docRoot.resolve("data0.txt");
|
Path file0 = docRoot.resolve("data0.txt");
|
||||||
createFile(file0, "Hello Text 0");
|
Files.writeString(file0, "Hello Text 0", UTF_8);
|
||||||
Path image = docRoot.resolve("image.jpg");
|
Path image = docRoot.resolve("image.jpg");
|
||||||
createFile(image, "not an image");
|
Files.writeString(image, "not an image", UTF_8);
|
||||||
|
|
||||||
server.stop();
|
server.stop();
|
||||||
ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
|
ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
|
||||||
|
@ -1994,9 +2004,9 @@ public class DefaultServletTest
|
||||||
{
|
{
|
||||||
FS.ensureDirExists(docRoot);
|
FS.ensureDirExists(docRoot);
|
||||||
Path file0 = docRoot.resolve("data0.txt");
|
Path file0 = docRoot.resolve("data0.txt");
|
||||||
createFile(file0, "Hello Text 0");
|
Files.writeString(file0, "Hello Text 0", UTF_8);
|
||||||
Path file0gz = docRoot.resolve("data0.txt.gz");
|
Path file0gz = docRoot.resolve("data0.txt.gz");
|
||||||
createFile(file0gz, "fake gzip");
|
Files.writeString(file0gz, "fake gzip", UTF_8);
|
||||||
|
|
||||||
ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
|
ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
|
||||||
defholder.setInitParameter("dirAllowed", "false");
|
defholder.setInitParameter("dirAllowed", "false");
|
||||||
|
@ -2147,9 +2157,9 @@ public class DefaultServletTest
|
||||||
{
|
{
|
||||||
FS.ensureDirExists(docRoot);
|
FS.ensureDirExists(docRoot);
|
||||||
Path file0 = docRoot.resolve("data0.txt");
|
Path file0 = docRoot.resolve("data0.txt");
|
||||||
createFile(file0, "Hello Text 0");
|
Files.writeString(file0, "Hello Text 0", UTF_8);
|
||||||
Path file0gz = docRoot.resolve("data0.txt.gz");
|
Path file0gz = docRoot.resolve("data0.txt.gz");
|
||||||
createFile(file0gz, "fake gzip");
|
Files.writeString(file0gz, "fake gzip", UTF_8);
|
||||||
|
|
||||||
ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
|
ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
|
||||||
defholder.setInitParameter("dirAllowed", "false");
|
defholder.setInitParameter("dirAllowed", "false");
|
||||||
|
@ -2273,8 +2283,8 @@ public class DefaultServletTest
|
||||||
@Disabled
|
@Disabled
|
||||||
public void testBrotli() throws Exception
|
public void testBrotli() throws Exception
|
||||||
{
|
{
|
||||||
createFile(docRoot.resolve("data0.txt"), "Hello Text 0");
|
Files.writeString(docRoot.resolve("data0.txt"), "Hello Text 0", UTF_8);
|
||||||
createFile(docRoot.resolve("data0.txt.br"), "fake brotli");
|
Files.writeString(docRoot.resolve("data0.txt.br"), "fake brotli", UTF_8);
|
||||||
|
|
||||||
ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
|
ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
|
||||||
defholder.setInitParameter("dirAllowed", "false");
|
defholder.setInitParameter("dirAllowed", "false");
|
||||||
|
@ -2413,8 +2423,8 @@ public class DefaultServletTest
|
||||||
@Disabled
|
@Disabled
|
||||||
public void testCachedBrotli() throws Exception
|
public void testCachedBrotli() throws Exception
|
||||||
{
|
{
|
||||||
createFile(docRoot.resolve("data0.txt"), "Hello Text 0");
|
Files.writeString(docRoot.resolve("data0.txt"), "Hello Text 0", UTF_8);
|
||||||
createFile(docRoot.resolve("data0.txt.br"), "fake brotli");
|
Files.writeString(docRoot.resolve("data0.txt.br"), "fake brotli", UTF_8);
|
||||||
|
|
||||||
ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
|
ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
|
||||||
defholder.setInitParameter("dirAllowed", "false");
|
defholder.setInitParameter("dirAllowed", "false");
|
||||||
|
@ -2538,9 +2548,9 @@ public class DefaultServletTest
|
||||||
@Disabled
|
@Disabled
|
||||||
public void testDefaultBrotliOverGzip() throws Exception
|
public void testDefaultBrotliOverGzip() throws Exception
|
||||||
{
|
{
|
||||||
createFile(docRoot.resolve("data0.txt"), "Hello Text 0");
|
Files.writeString(docRoot.resolve("data0.txt"), "Hello Text 0", UTF_8);
|
||||||
createFile(docRoot.resolve("data0.txt.br"), "fake brotli");
|
Files.writeString(docRoot.resolve("data0.txt.br"), "fake brotli", UTF_8);
|
||||||
createFile(docRoot.resolve("data0.txt.gz"), "fake gzip");
|
Files.writeString(docRoot.resolve("data0.txt.gz"), "fake gzip", UTF_8);
|
||||||
|
|
||||||
ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
|
ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
|
||||||
defholder.setInitParameter("precompressed", "true");
|
defholder.setInitParameter("precompressed", "true");
|
||||||
|
@ -2587,10 +2597,10 @@ public class DefaultServletTest
|
||||||
@Disabled
|
@Disabled
|
||||||
public void testCustomCompressionFormats() throws Exception
|
public void testCustomCompressionFormats() throws Exception
|
||||||
{
|
{
|
||||||
createFile(docRoot.resolve("data0.txt"), "Hello Text 0");
|
Files.writeString(docRoot.resolve("data0.txt"), "Hello Text 0", UTF_8);
|
||||||
createFile(docRoot.resolve("data0.txt.br"), "fake brotli");
|
Files.writeString(docRoot.resolve("data0.txt.br"), "fake brotli", UTF_8);
|
||||||
createFile(docRoot.resolve("data0.txt.gz"), "fake gzip");
|
Files.writeString(docRoot.resolve("data0.txt.gz"), "fake gzip", UTF_8);
|
||||||
createFile(docRoot.resolve("data0.txt.bz2"), "fake bzip2");
|
Files.writeString(docRoot.resolve("data0.txt.bz2"), "fake bzip2", UTF_8);
|
||||||
|
|
||||||
ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
|
ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
|
||||||
defholder.setInitParameter("precompressed", "bzip2=.bz2,gzip=.gz,br=.br");
|
defholder.setInitParameter("precompressed", "bzip2=.bz2,gzip=.gz,br=.br");
|
||||||
|
@ -2638,10 +2648,10 @@ public class DefaultServletTest
|
||||||
@Disabled
|
@Disabled
|
||||||
public void testProgrammaticCustomCompressionFormats() throws Exception
|
public void testProgrammaticCustomCompressionFormats() throws Exception
|
||||||
{
|
{
|
||||||
createFile(docRoot.resolve("data0.txt"), "Hello Text 0");
|
Files.writeString(docRoot.resolve("data0.txt"), "Hello Text 0", UTF_8);
|
||||||
createFile(docRoot.resolve("data0.txt.br"), "fake brotli");
|
Files.writeString(docRoot.resolve("data0.txt.br"), "fake brotli", UTF_8);
|
||||||
createFile(docRoot.resolve("data0.txt.gz"), "fake gzip");
|
Files.writeString(docRoot.resolve("data0.txt.gz"), "fake gzip", UTF_8);
|
||||||
createFile(docRoot.resolve("data0.txt.bz2"), "fake bzip2");
|
Files.writeString(docRoot.resolve("data0.txt.bz2"), "fake bzip2", UTF_8);
|
||||||
|
|
||||||
ResourceService resourceService = new ResourceService();
|
ResourceService resourceService = new ResourceService();
|
||||||
resourceService.setPrecompressedFormats(new CompressedContentFormat[]{
|
resourceService.setPrecompressedFormats(new CompressedContentFormat[]{
|
||||||
|
@ -2739,7 +2749,7 @@ public class DefaultServletTest
|
||||||
response = HttpTester.parseResponse(rawResponse);
|
response = HttpTester.parseResponse(rawResponse);
|
||||||
assertThat(response.toString(), response.getStatus(), is(HttpStatus.NOT_FOUND_404));
|
assertThat(response.toString(), response.getStatus(), is(HttpStatus.NOT_FOUND_404));
|
||||||
|
|
||||||
createFile(file, content);
|
Files.writeString(file, content, UTF_8);
|
||||||
|
|
||||||
rawResponse = connector.getResponse("""
|
rawResponse = connector.getResponse("""
|
||||||
GET /context/file.txt HTTP/1.1\r
|
GET /context/file.txt HTTP/1.1\r
|
||||||
|
@ -2812,7 +2822,7 @@ public class DefaultServletTest
|
||||||
@Disabled
|
@Disabled
|
||||||
public void testIfETag(String content) throws Exception
|
public void testIfETag(String content) throws Exception
|
||||||
{
|
{
|
||||||
createFile(docRoot.resolve("file.txt"), content);
|
Files.writeString(docRoot.resolve("file.txt"), content, UTF_8);
|
||||||
|
|
||||||
ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
|
ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
|
||||||
|
|
||||||
|
@ -2927,7 +2937,7 @@ public class DefaultServletTest
|
||||||
|
|
||||||
// Create file with UTF-8 NFC format
|
// Create file with UTF-8 NFC format
|
||||||
String filename = "swedish-" + new String(StringUtil.fromHexString("C3A5"), UTF_8) + ".txt";
|
String filename = "swedish-" + new String(StringUtil.fromHexString("C3A5"), UTF_8) + ".txt";
|
||||||
createFile(docRoot.resolve(filename), "hi a-with-circle");
|
Files.writeString(docRoot.resolve(filename), "hi a-with-circle", UTF_8);
|
||||||
|
|
||||||
// Using filesystem, attempt to access via NFD format
|
// Using filesystem, attempt to access via NFD format
|
||||||
Path nfdPath = docRoot.resolve("swedish-a" + new String(StringUtil.fromHexString("CC8A"), UTF_8) + ".txt");
|
Path nfdPath = docRoot.resolve("swedish-a" + new String(StringUtil.fromHexString("CC8A"), UTF_8) + ".txt");
|
||||||
|
@ -2977,7 +2987,7 @@ public class DefaultServletTest
|
||||||
|
|
||||||
// Create file with UTF-8 NFD format
|
// Create file with UTF-8 NFD format
|
||||||
String filename = "swedish-a" + new String(StringUtil.fromHexString("CC8A"), UTF_8) + ".txt";
|
String filename = "swedish-a" + new String(StringUtil.fromHexString("CC8A"), UTF_8) + ".txt";
|
||||||
createFile(docRoot.resolve(filename), "hi a-with-circle");
|
Files.writeString(docRoot.resolve(filename), "hi a-with-circle", UTF_8);
|
||||||
|
|
||||||
// Using filesystem, attempt to access via NFC format
|
// Using filesystem, attempt to access via NFC format
|
||||||
Path nfcPath = docRoot.resolve("swedish-" + new String(StringUtil.fromHexString("C3A5"), UTF_8) + ".txt");
|
Path nfcPath = docRoot.resolve("swedish-" + new String(StringUtil.fromHexString("C3A5"), UTF_8) + ".txt");
|
||||||
|
@ -3057,15 +3067,6 @@ public class DefaultServletTest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createFile(Path path, String str) throws IOException
|
|
||||||
{
|
|
||||||
try (OutputStream out = Files.newOutputStream(path))
|
|
||||||
{
|
|
||||||
out.write(str.getBytes(UTF_8));
|
|
||||||
out.flush();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean deleteFile(Path file) throws IOException
|
private boolean deleteFile(Path file) throws IOException
|
||||||
{
|
{
|
||||||
if (!Files.exists(file))
|
if (!Files.exists(file))
|
||||||
|
|
|
@ -97,7 +97,6 @@ public class DispatcherTest
|
||||||
_resourceHandler = new ResourceHandler();
|
_resourceHandler = new ResourceHandler();
|
||||||
Path basePath = MavenTestingUtils.getTestResourcePathDir("dispatchResourceTest");
|
Path basePath = MavenTestingUtils.getTestResourcePathDir("dispatchResourceTest");
|
||||||
_resourceHandler.setBaseResource(Resource.newResource(basePath));
|
_resourceHandler.setBaseResource(Resource.newResource(basePath));
|
||||||
_resourceHandler.setPathInfoOnly(true);
|
|
||||||
ContextHandler resourceContextHandler = new ContextHandler("/resource");
|
ContextHandler resourceContextHandler = new ContextHandler("/resource");
|
||||||
resourceContextHandler.setHandler(_resourceHandler);
|
resourceContextHandler.setHandler(_resourceHandler);
|
||||||
_contextCollection.addHandler(resourceContextHandler);
|
_contextCollection.addHandler(resourceContextHandler);
|
||||||
|
|
Loading…
Reference in New Issue