Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'jetty-server/src/main/java/org/eclipse/jetty/server/handler/ResourceHandler.java')
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/handler/ResourceHandler.java751
1 files changed, 317 insertions, 434 deletions
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ResourceHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ResourceHandler.java
index b937c2fbf9..adeb05def1 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ResourceHandler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ResourceHandler.java
@@ -19,43 +19,35 @@
package org.eclipse.jetty.server.handler;
import java.io.IOException;
-import java.io.OutputStream;
-import java.net.MalformedURLException;
-import java.nio.ByteBuffer;
-import java.nio.channels.ReadableByteChannel;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
-import javax.servlet.AsyncContext;
-import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.eclipse.jetty.http.HttpFields;
+import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpMethod;
-import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.MimeTypes;
-import org.eclipse.jetty.io.WriterOutputStream;
-import org.eclipse.jetty.server.HttpOutput;
+import org.eclipse.jetty.http.PreEncodedHttpField;
import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.server.ResourceContentFactory;
+import org.eclipse.jetty.server.ResourceService;
import org.eclipse.jetty.server.handler.ContextHandler.Context;
-import org.eclipse.jetty.util.BufferUtil;
-import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
-import org.eclipse.jetty.util.resource.PathResource;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.util.resource.ResourceFactory;
-
/* ------------------------------------------------------------ */
-/** Resource Handler.
+/**
+ * Resource Handler.
*
- * This handle will serve static content and handle If-Modified-Since headers.
- * No caching is done.
- * Requests for resources that do not exist are let pass (Eg no 404's).
+ * This handle will serve static content and handle If-Modified-Since headers. No caching is done. Requests for resources that do not exist are let pass (Eg no
+ * 404's).
*
*
*/
@@ -63,577 +55,468 @@ public class ResourceHandler extends HandlerWrapper implements ResourceFactory
{
private static final Logger LOG = Log.getLogger(ResourceHandler.class);
- ContextHandler _context;
Resource _baseResource;
+ ContextHandler _context;
Resource _defaultStylesheet;
- Resource _stylesheet;
- String[] _welcomeFiles={"index.html"};
MimeTypes _mimeTypes;
- String _cacheControl;
- boolean _directory;
- boolean _gzip;
- boolean _etags;
- int _minMemoryMappedContentLength=0;
- int _minAsyncContentLength=16*1024;
+ private final ResourceService _resourceService;
+ Resource _stylesheet;
+ String[] _welcomes =
+ { "index.html" };
/* ------------------------------------------------------------ */
public ResourceHandler()
{
+ _resourceService = new ResourceService()
+ {
+ @Override
+ protected String getWelcomeFile(String pathInContext)
+ {
+ if (_welcomes == null)
+ return null;
+
+ String welcome_servlet = null;
+ for (int i = 0; i < _welcomes.length; i++)
+ {
+ String welcome_in_context = URIUtil.addPaths(pathInContext,_welcomes[i]);
+ Resource welcome = getResource(welcome_in_context);
+ if (welcome != null && welcome.exists())
+ return _welcomes[i];
+ }
+ return welcome_servlet;
+ }
+ @Override
+ protected void notFound(HttpServletRequest request, HttpServletResponse response) throws IOException
+ {
+ }
+ };
+ _resourceService.setGzipEquivalentFileExtensions(new ArrayList<>(Arrays.asList(new String[]
+ { ".svgz" })));
}
/* ------------------------------------------------------------ */
- public MimeTypes getMimeTypes()
+ @Override
+ public void doStart() throws Exception
{
- return _mimeTypes;
+ Context scontext = ContextHandler.getCurrentContext();
+ _context = (scontext == null?null:scontext.getContextHandler());
+ _mimeTypes = _context == null?new MimeTypes():_context.getMimeTypes();
+
+ _resourceService.setContentFactory(new ResourceContentFactory(this,_mimeTypes,_resourceService.isGzip()));
+
+ super.doStart();
}
/* ------------------------------------------------------------ */
- public void setMimeTypes(MimeTypes mimeTypes)
+ /**
+ * @return Returns the resourceBase.
+ */
+ public Resource getBaseResource()
{
- _mimeTypes = mimeTypes;
+ if (_baseResource == null)
+ return null;
+ return _baseResource;
}
/* ------------------------------------------------------------ */
- /** Get the directory option.
- * @return true if directories are listed.
+ /**
+ * @return the cacheControl header to set on all static content.
*/
- public boolean isDirectoriesListed()
+ public String getCacheControl()
{
- return _directory;
+ return _resourceService.getCacheControl().getValue();
}
/* ------------------------------------------------------------ */
- /** Set the directory.
- * @param directory true if directories are listed.
+ /**
+ * @return file extensions that signify that a file is gzip compressed. Eg ".svgz"
*/
- public void setDirectoriesListed(boolean directory)
+ public List<String> getGzipEquivalentFileExtensions()
{
- _directory = directory;
+ return _resourceService.getGzipEquivalentFileExtensions();
}
/* ------------------------------------------------------------ */
- /** Get minimum memory mapped file content length.
- * @return the minimum size in bytes of a file resource that will
- * be served using a memory mapped buffer, or -1 (default) for no memory mapped
- * buffers.
- */
- public int getMinMemoryMappedContentLength()
+ public MimeTypes getMimeTypes()
{
- return _minMemoryMappedContentLength;
+ return _mimeTypes;
}
/* ------------------------------------------------------------ */
- /** Set minimum memory mapped file content length.
- * @param minMemoryMappedFileSize the minimum size in bytes of a file resource that will
- * be served using a memory mapped buffer, or -1 for no memory mapped
- * buffers.
+ /**
+ * Get the minimum content length for async handling.
+ *
+ * @return The minimum size in bytes of the content before asynchronous handling is used, or -1 for no async handling or 0 (default) for using
+ * {@link HttpServletResponse#getBufferSize()} as the minimum length.
*/
- public void setMinMemoryMappedContentLength(int minMemoryMappedFileSize)
+ @Deprecated
+ public int getMinAsyncContentLength()
{
- _minMemoryMappedContentLength = minMemoryMappedFileSize;
+ return -1;
}
/* ------------------------------------------------------------ */
- /** Get the minimum content length for async handling.
- * @return The minimum size in bytes of the content before asynchronous
- * handling is used, or -1 for no async handling or 0 (default) for using
- * {@link HttpServletResponse#getBufferSize()} as the minimum length.
+ /**
+ * Get minimum memory mapped file content length.
+ *
+ * @return the minimum size in bytes of a file resource that will be served using a memory mapped buffer, or -1 (default) for no memory mapped buffers.
*/
- public int getMinAsyncContentLength()
+ @Deprecated
+ public int getMinMemoryMappedContentLength()
{
- return _minAsyncContentLength;
+ return -1;
}
/* ------------------------------------------------------------ */
- /** Set the minimum content length for async handling.
- * @param minAsyncContentLength The minimum size in bytes of the content before asynchronous
- * handling is used, or -1 for no async handling or 0 for using
- * {@link HttpServletResponse#getBufferSize()} as the minimum length.
+ /*
*/
- public void setMinAsyncContentLength(int minAsyncContentLength)
+ @Override
+ public Resource getResource(String path)
{
- _minAsyncContentLength = minAsyncContentLength;
+ if (LOG.isDebugEnabled())
+ LOG.debug("{} getResource({})",_context == null?_baseResource:_context,_baseResource,path);
+
+ if (path == null || !path.startsWith("/"))
+ return null;
+
+ try
+ {
+ Resource r = null;
+
+ if (_baseResource != null)
+ {
+ path = URIUtil.canonicalPath(path);
+ r = _baseResource.addPath(path);
+
+ if (r != null && r.isAlias() && (_context == null || !_context.checkAlias(path,r)))
+ {
+ if (LOG.isDebugEnabled())
+ LOG.debug("resource={} alias={}",r,r.getAlias());
+ return null;
+ }
+ }
+ else if (_context != null)
+ r = _context.getResource(path);
+
+ if ((r == null || !r.exists()) && path.endsWith("/jetty-dir.css"))
+ r = getStylesheet();
+
+ return r;
+ }
+ catch (Exception e)
+ {
+ LOG.debug(e);
+ }
+
+ return null;
}
/* ------------------------------------------------------------ */
/**
- * @return True if ETag processing is done
+ * @return Returns the base resource as a string.
*/
- public boolean isEtags()
+ public String getResourceBase()
{
- return _etags;
+ if (_baseResource == null)
+ return null;
+ return _baseResource.toString();
}
/* ------------------------------------------------------------ */
/**
- * @param etags True if ETag processing is done
+ * @return Returns the stylesheet as a Resource.
*/
- public void setEtags(boolean etags)
+ public Resource getStylesheet()
{
- _etags = etags;
+ if (_stylesheet != null)
+ {
+ return _stylesheet;
+ }
+ else
+ {
+ if (_defaultStylesheet == null)
+ {
+ _defaultStylesheet = Resource.newResource(this.getClass().getResource("/jetty-dir.css"));
+ }
+ return _defaultStylesheet;
+ }
}
/* ------------------------------------------------------------ */
- @Override
- public void doStart()
- throws Exception
+ public String[] getWelcomeFiles()
{
- Context scontext = ContextHandler.getCurrentContext();
- _context = (scontext==null?null:scontext.getContextHandler());
- _mimeTypes = _context==null?new MimeTypes():_context.getMimeTypes();
-
- super.doStart();
+ return _welcomes;
}
/* ------------------------------------------------------------ */
- /**
- * @return Returns the resourceBase.
+ /*
+ * @see org.eclipse.jetty.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
*/
- public Resource getBaseResource()
+ @Override
+ public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
- if (_baseResource==null)
- return null;
- return _baseResource;
+ if (baseRequest.isHandled())
+ return;
+
+ if (!HttpMethod.GET.is(request.getMethod()))
+ {
+ if (!HttpMethod.HEAD.is(request.getMethod()))
+ {
+ // try another handler
+ super.handle(target,baseRequest,request,response);
+ return;
+ }
+ }
+
+ _resourceService.doGet(request,response);
+
+ if (response.isCommitted())
+ baseRequest.setHandled(true);
+ else
+ // no resource - try other handlers
+ super.handle(target,baseRequest,request,response);
}
/* ------------------------------------------------------------ */
/**
- * @return Returns the base resource as a string.
+ * @return If true, range requests and responses are supported
*/
- public String getResourceBase()
+ public boolean isAcceptRanges()
{
- if (_baseResource==null)
- return null;
- return _baseResource.toString();
+ return _resourceService.isAcceptRanges();
}
+ /**
+ * @return If true, directory listings are returned if no welcome file is found. Else 403 Forbidden.
+ */
+ public boolean isDirAllowed()
+ {
+ return _resourceService.isDirAllowed();
+ }
/* ------------------------------------------------------------ */
/**
- * @param base The resourceBase to set.
+ * Get the directory option.
+ *
+ * @return true if directories are listed.
*/
- public void setBaseResource(Resource base)
+ public boolean isDirectoriesListed()
{
- _baseResource=base;
+ return _resourceService.isDirAllowed();
}
/* ------------------------------------------------------------ */
/**
- * @param resourceBase The base resource as a string.
+ * @return True if ETag processing is done
*/
- public void setResourceBase(String resourceBase)
+ public boolean isEtags()
{
- try
- {
- setBaseResource(Resource.newResource(resourceBase));
- }
- catch (Exception e)
- {
- LOG.warn(e.toString());
- LOG.debug(e);
- throw new IllegalArgumentException(resourceBase);
- }
+ return _resourceService.isEtags();
}
-
+
/* ------------------------------------------------------------ */
/**
- * @return Returns the stylesheet as a Resource.
+ * @return If set to true, then static content will be served as gzip content encoded if a matching resource is found ending with ".gz"
*/
- public Resource getStylesheet()
+ public boolean isGzip()
{
- if(_stylesheet != null)
- {
- return _stylesheet;
- }
- else
- {
- if(_defaultStylesheet == null)
- {
- _defaultStylesheet = Resource.newResource(this.getClass().getResource("/jetty-dir.css"));
- }
- return _defaultStylesheet;
- }
+ return _resourceService.isGzip();
}
/* ------------------------------------------------------------ */
/**
- * @param stylesheet The location of the stylesheet to be used as a String.
+ * @return true, only the path info will be applied to the resourceBase
*/
- public void setStylesheet(String stylesheet)
+ public boolean isPathInfoOnly()
{
- try
- {
- _stylesheet = Resource.newResource(stylesheet);
- if(!_stylesheet.exists())
- {
- LOG.warn("unable to find custom stylesheet: " + stylesheet);
- _stylesheet = null;
- }
- }
- catch(Exception e)
- {
- LOG.warn(e.toString());
- LOG.debug(e);
- throw new IllegalArgumentException(stylesheet);
- }
+ return _resourceService.isPathInfoOnly();
}
/* ------------------------------------------------------------ */
/**
- * @return the cacheControl header to set on all static content.
+ * @return If true, welcome files are redirected rather than forwarded to.
*/
- public String getCacheControl()
+ public boolean isRedirectWelcome()
{
- return _cacheControl;
+ return _resourceService.isRedirectWelcome();
}
/* ------------------------------------------------------------ */
/**
- * @param cacheControl the cacheControl header to set on all static content.
+ * @param acceptRanges If true, range requests and responses are supported
*/
- public void setCacheControl(String cacheControl)
+ public void setAcceptRanges(boolean acceptRanges)
{
- _cacheControl=cacheControl;
+ _resourceService.setAcceptRanges(acceptRanges);
}
/* ------------------------------------------------------------ */
- /*
+ /**
+ * @param base The resourceBase to server content from. If null the
+ * context resource base is used.
*/
- @Override
- public Resource getResource(String path)
+ public void setBaseResource(Resource base)
{
- if (LOG.isDebugEnabled())
- LOG.debug("{} getResource({})",_context==null?_baseResource:_context,_baseResource,path);
-
- if (path==null || !path.startsWith("/"))
- return null;
-
- try
- {
- Resource base = _baseResource;
- if (base==null)
- {
- if (_context==null)
- return null;
- return _context.getResource(path);
- }
-
- path=URIUtil.canonicalPath(path);
- Resource r = base.addPath(path);
- if (r!=null && r.isAlias() && (_context==null || !_context.checkAlias(path, r)))
- {
- if (LOG.isDebugEnabled())
- LOG.debug("resource={} alias={}",r,r.getAlias());
- return null;
- }
- return r;
- }
- catch(Exception e)
- {
- LOG.debug(e);
- }
-
- return null;
+ _baseResource = base;
}
/* ------------------------------------------------------------ */
- protected Resource getResource(HttpServletRequest request) throws MalformedURLException
+ /**
+ * @param cacheControl
+ * the cacheControl header to set on all static content.
+ */
+ public void setCacheControl(String cacheControl)
{
- String servletPath;
- String pathInfo;
- Boolean included = request.getAttribute(RequestDispatcher.INCLUDE_REQUEST_URI) != null;
- if (included != null && included.booleanValue())
- {
- servletPath = (String)request.getAttribute(RequestDispatcher.INCLUDE_SERVLET_PATH);
- pathInfo = (String)request.getAttribute(RequestDispatcher.INCLUDE_PATH_INFO);
+ _resourceService.setCacheControl(new PreEncodedHttpField(HttpHeader.CACHE_CONTROL,cacheControl));
+ }
- if (servletPath == null && pathInfo == null)
- {
- servletPath = request.getServletPath();
- pathInfo = request.getPathInfo();
- }
- }
- else
- {
- servletPath = request.getServletPath();
- pathInfo = request.getPathInfo();
- }
+ /**
+ * @param dirAllowed
+ * If true, directory listings are returned if no welcome file is found. Else 403 Forbidden.
+ */
+ public void setDirAllowed(boolean dirAllowed)
+ {
+ _resourceService.setDirAllowed(dirAllowed);
+ }
- String pathInContext=URIUtil.addPaths(servletPath,pathInfo);
- return getResource(pathInContext);
+ /* ------------------------------------------------------------ */
+ /**
+ * Set the directory.
+ *
+ * @param directory
+ * true if directories are listed.
+ */
+ public void setDirectoriesListed(boolean directory)
+ {
+ _resourceService.setDirAllowed(directory);
}
+ /* ------------------------------------------------------------ */
+ /**
+ * @param etags
+ * True if ETag processing is done
+ */
+ public void setEtags(boolean etags)
+ {
+ _resourceService.setEtags(etags);
+ }
/* ------------------------------------------------------------ */
- public String[] getWelcomeFiles()
+ /**
+ * @param gzip
+ * If set to true, then static content will be served as gzip content encoded if a matching resource is found ending with ".gz"
+ */
+ public void setGzip(boolean gzip)
{
- return _welcomeFiles;
+ _resourceService.setGzip(gzip);
}
/* ------------------------------------------------------------ */
- public void setWelcomeFiles(String[] welcomeFiles)
+ /**
+ * @param gzipEquivalentFileExtensions file extensions that signify that a file is gzip compressed. Eg ".svgz"
+ */
+ public void setGzipEquivalentFileExtensions(List<String> gzipEquivalentFileExtensions)
{
- _welcomeFiles=welcomeFiles;
+ _resourceService.setGzipEquivalentFileExtensions(gzipEquivalentFileExtensions);
}
/* ------------------------------------------------------------ */
- protected Resource getWelcome(Resource directory) throws MalformedURLException, IOException
+ public void setMimeTypes(MimeTypes mimeTypes)
{
- for (int i=0;i<_welcomeFiles.length;i++)
- {
- Resource welcome=directory.addPath(_welcomeFiles[i]);
- if (welcome.exists() && !welcome.isDirectory())
- return welcome;
- }
+ _mimeTypes = mimeTypes;
+ }
- return null;
+ /* ------------------------------------------------------------ */
+ /**
+ * Set the minimum content length for async handling.
+ *
+ * @param minAsyncContentLength
+ * The minimum size in bytes of the content before asynchronous handling is used, or -1 for no async handling or 0 for using
+ * {@link HttpServletResponse#getBufferSize()} as the minimum length.
+ */
+ @Deprecated
+ public void setMinAsyncContentLength(int minAsyncContentLength)
+ {
}
/* ------------------------------------------------------------ */
- /*
- * @see org.eclipse.jetty.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
+ /**
+ * Set minimum memory mapped file content length.
+ *
+ * @param minMemoryMappedFileSize
+ * the minimum size in bytes of a file resource that will be served using a memory mapped buffer, or -1 for no memory mapped buffers.
*/
- @Override
- public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ @Deprecated
+ public void setMinMemoryMappedContentLength(int minMemoryMappedFileSize)
{
- if (baseRequest.isHandled())
- return;
+ }
- boolean skipContentBody = false;
+ /**
+ * @param pathInfoOnly
+ * true, only the path info will be applied to the resourceBase
+ */
+ public void setPathInfoOnly(boolean pathInfoOnly)
+ {
+ _resourceService.setPathInfoOnly(pathInfoOnly);
+ }
- if(!HttpMethod.GET.is(request.getMethod()))
- {
- if(!HttpMethod.HEAD.is(request.getMethod()))
- {
- //try another handler
- super.handle(target, baseRequest, request, response);
- return;
- }
- skipContentBody = true;
- }
+ /**
+ * @param redirectWelcome
+ * If true, welcome files are redirected rather than forwarded to.
+ */
+ public void setRedirectWelcome(boolean redirectWelcome)
+ {
+ _resourceService.setRedirectWelcome(redirectWelcome);
+ }
- Resource resource = getResource(request);
-
- if (LOG.isDebugEnabled())
- {
- if (resource==null)
- LOG.debug("resource=null");
- else
- LOG.debug("resource={} alias={} exists={}",resource,resource.getAlias(),resource.exists());
- }
-
-
- // If resource is not found
- if (resource==null || !resource.exists())
+ /* ------------------------------------------------------------ */
+ /**
+ * @param resourceBase
+ * The base resource as a string.
+ */
+ public void setResourceBase(String resourceBase)
+ {
+ try
{
- // inject the jetty-dir.css file if it matches
- if (target.endsWith("/jetty-dir.css"))
- {
- resource = getStylesheet();
- if (resource==null)
- return;
- response.setContentType("text/css");
- }
- else
- {
- //no resource - try other handlers
- super.handle(target, baseRequest, request, response);
- return;
- }
+ setBaseResource(Resource.newResource(resourceBase));
}
-
- // We are going to serve something
- baseRequest.setHandled(true);
-
- // handle directories
- if (resource.isDirectory())
+ catch (Exception e)
{
- String pathInfo = request.getPathInfo();
- boolean endsWithSlash=(pathInfo==null?request.getServletPath():pathInfo).endsWith(URIUtil.SLASH);
- if (!endsWithSlash)
- {
- response.sendRedirect(response.encodeRedirectURL(URIUtil.addPaths(request.getRequestURI(),URIUtil.SLASH)));
- return;
- }
-
- Resource welcome=getWelcome(resource);
- if (welcome!=null && welcome.exists())
- resource=welcome;
- else
- {
- doDirectory(request,response,resource);
- baseRequest.setHandled(true);
- return;
- }
+ LOG.warn(e.toString());
+ LOG.debug(e);
+ throw new IllegalArgumentException(resourceBase);
}
+ }
- // Handle ETAGS
- long last_modified=resource.lastModified();
- String etag=null;
- if (_etags)
- {
- // simple handling of only a single etag
- String ifnm = request.getHeader(HttpHeader.IF_NONE_MATCH.asString());
- etag=resource.getWeakETag();
- if (ifnm!=null && resource!=null && ifnm.equals(etag))
- {
- response.setStatus(HttpStatus.NOT_MODIFIED_304);
- baseRequest.getResponse().getHttpFields().put(HttpHeader.ETAG,etag);
- return;
- }
- }
-
- // Handle if modified since
- if (last_modified>0)
+ /* ------------------------------------------------------------ */
+ /**
+ * @param stylesheet
+ * The location of the stylesheet to be used as a String.
+ */
+ public void setStylesheet(String stylesheet)
+ {
+ try
{
- long if_modified=request.getDateHeader(HttpHeader.IF_MODIFIED_SINCE.asString());
- if (if_modified>0 && last_modified/1000<=if_modified/1000)
+ _stylesheet = Resource.newResource(stylesheet);
+ if (!_stylesheet.exists())
{
- response.setStatus(HttpStatus.NOT_MODIFIED_304);
- return;
+ LOG.warn("unable to find custom stylesheet: " + stylesheet);
+ _stylesheet = null;
}
}
-
- // set the headers
- String mime=_mimeTypes.getMimeByExtension(resource.toString());
- if (mime==null)
- mime=_mimeTypes.getMimeByExtension(request.getPathInfo());
- doResponseHeaders(response,resource,mime);
- if (_etags)
- baseRequest.getResponse().getHttpFields().put(HttpHeader.ETAG,etag);
- if (last_modified>0)
- response.setDateHeader(HttpHeader.LAST_MODIFIED.asString(),last_modified);
-
- if(skipContentBody)
- return;
-
- // Send the content
- OutputStream out =null;
- try {out = response.getOutputStream();}
- catch(IllegalStateException e) {out = new WriterOutputStream(response.getWriter());}
-
- // Has the output been wrapped
- if (!(out instanceof HttpOutput))
- // Write content via wrapped output
- resource.writeTo(out,0,resource.length());
- else
+ catch (Exception e)
{
- // select async by size
- int min_async_size=_minAsyncContentLength==0?response.getBufferSize():_minAsyncContentLength;
-
- if (request.isAsyncSupported() &&
- min_async_size>0 &&
- resource.length()>=min_async_size)
- {
- final AsyncContext async = request.startAsync();
- async.setTimeout(0);
- Callback callback = new Callback()
- {
- @Override
- public void succeeded()
- {
- async.complete();
- }
-
- @Override
- public void failed(Throwable x)
- {
- LOG.warn(x.toString());
- LOG.debug(x);
- async.complete();
- }
- };
-
- // Can we use a memory mapped file?
- if (_minMemoryMappedContentLength>0 &&
- resource.length()>_minMemoryMappedContentLength &&
- resource.length()<Integer.MAX_VALUE &&
- resource instanceof PathResource)
- {
- ByteBuffer buffer = BufferUtil.toMappedBuffer(resource.getFile());
- ((HttpOutput)out).sendContent(buffer,callback);
- }
- else // Do a blocking write of a channel (if available) or input stream
- {
- // Close of the channel/inputstream is done by the async sendContent
- ReadableByteChannel channel= resource.getReadableByteChannel();
- if (channel!=null)
- ((HttpOutput)out).sendContent(channel,callback);
- else
- ((HttpOutput)out).sendContent(resource.getInputStream(),callback);
- }
- }
- else
- {
- // Can we use a memory mapped file?
- if (_minMemoryMappedContentLength>0 &&
- resource.length()>_minMemoryMappedContentLength &&
- resource instanceof PathResource)
- {
- ByteBuffer buffer = BufferUtil.toMappedBuffer(resource.getFile());
- ((HttpOutput)out).sendContent(buffer);
- }
- else // Do a blocking write of a channel (if available) or input stream
- {
- ReadableByteChannel channel= resource.getReadableByteChannel();
- if (channel!=null)
- ((HttpOutput)out).sendContent(channel);
- else
- ((HttpOutput)out).sendContent(resource.getInputStream());
- }
- }
+ LOG.warn(e.toString());
+ LOG.debug(e);
+ throw new IllegalArgumentException(stylesheet);
}
}
/* ------------------------------------------------------------ */
- protected void doDirectory(HttpServletRequest request,HttpServletResponse response, Resource resource)
- throws IOException
+ public void setWelcomeFiles(String[] welcomeFiles)
{
- if (_directory)
- {
- String listing = resource.getListHTML(request.getRequestURI(),request.getPathInfo().lastIndexOf("/") > 0);
- response.setContentType("text/html;charset=utf-8");
- response.getWriter().println(listing);
- }
- else
- response.sendError(HttpStatus.FORBIDDEN_403);
+ _welcomes = welcomeFiles;
}
- /* ------------------------------------------------------------ */
- /** Set the response headers.
- * This method is called to set the response headers such as content type and content length.
- * May be extended to add additional headers.
- * @param response the http response
- * @param resource the resource
- * @param mimeType the mime type
- */
- protected void doResponseHeaders(HttpServletResponse response, Resource resource, String mimeType)
- {
- if (mimeType!=null)
- response.setContentType(mimeType);
-
- long length=resource.length();
-
- if (response instanceof Response)
- {
- HttpFields fields = ((Response)response).getHttpFields();
-
- if (length>0)
- ((Response)response).setLongContentLength(length);
-
- if (_cacheControl!=null)
- fields.put(HttpHeader.CACHE_CONTROL,_cacheControl);
- }
- else
- {
- if (length>Integer.MAX_VALUE)
- response.setHeader(HttpHeader.CONTENT_LENGTH.asString(),Long.toString(length));
- else if (length>0)
- response.setContentLength((int)length);
-
- if (_cacheControl!=null)
- response.setHeader(HttpHeader.CACHE_CONTROL.asString(),_cacheControl);
- }
- }
}

Back to the top