use of org.apache.naming.resources.CacheEntry in project tomcat70 by apache.
the class DefaultServlet method serveResource.
/**
* Serve the specified resource, optionally including the data content.
*
* @param request The servlet request we are processing
* @param response The servlet response we are creating
* @param content Should the content be included?
*
* @exception IOException if an input/output error occurs
* @exception ServletException if a servlet-specified error occurs
*/
protected void serveResource(HttpServletRequest request, HttpServletResponse response, boolean content) throws IOException, ServletException {
boolean serveContent = content;
// Identify the requested resource path
String path = getRelativePath(request, true);
if (debug > 0) {
if (serveContent)
log("DefaultServlet.serveResource: Serving resource '" + path + "' headers and data");
else
log("DefaultServlet.serveResource: Serving resource '" + path + "' headers only");
}
if (path.length() == 0) {
// Context root redirect
doDirectoryRedirect(request, response);
return;
}
CacheEntry cacheEntry = resources.lookupCache(path);
boolean isError = DispatcherType.ERROR == request.getDispatcherType();
if (!cacheEntry.exists) {
// Check if we're included so we can return the appropriate
// missing resource name in the error
String requestUri = (String) request.getAttribute(RequestDispatcher.INCLUDE_REQUEST_URI);
if (requestUri == null) {
requestUri = request.getRequestURI();
} else {
// SRV.9.3 says we must throw a FNFE
throw new FileNotFoundException(sm.getString("defaultServlet.missingResource", requestUri));
}
if (isError) {
response.sendError(((Integer) request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE)).intValue());
} else {
response.sendError(HttpServletResponse.SC_NOT_FOUND, requestUri);
}
return;
}
// satisfied.
if (cacheEntry.context == null) {
// Checking If headers
boolean included = (request.getAttribute(RequestDispatcher.INCLUDE_CONTEXT_PATH) != null);
if (!included && !isError && !checkIfHeaders(request, response, cacheEntry.attributes)) {
return;
}
}
// Find content type.
String contentType = cacheEntry.attributes.getMimeType();
if (contentType == null) {
contentType = getServletContext().getMimeType(cacheEntry.name);
cacheEntry.attributes.setMimeType(contentType);
}
ArrayList<Range> ranges = null;
long contentLength = -1L;
if (cacheEntry.context != null) {
if (!path.endsWith("/")) {
doDirectoryRedirect(request, response);
return;
}
// suppress them
if (!listings) {
response.sendError(HttpServletResponse.SC_NOT_FOUND, request.getRequestURI());
return;
}
contentType = "text/html;charset=UTF-8";
} else {
if (!isError) {
if (useAcceptRanges) {
// Accept ranges header
response.setHeader("Accept-Ranges", "bytes");
}
// Parse range specifier
ranges = parseRange(request, response, cacheEntry.attributes);
// ETag header
response.setHeader("ETag", cacheEntry.attributes.getETag());
// Last-Modified header
response.setHeader("Last-Modified", cacheEntry.attributes.getLastModifiedHttp());
}
// Get content length
contentLength = cacheEntry.attributes.getContentLength();
// (silent) ISE when setting the output buffer size
if (contentLength == 0L) {
serveContent = false;
}
}
ServletOutputStream ostream = null;
PrintWriter writer = null;
if (serveContent) {
try {
ostream = response.getOutputStream();
} catch (IllegalStateException e) {
// trying to serve a text file
if ((contentType == null) || (contentType.startsWith("text")) || (contentType.endsWith("xml")) || (contentType.contains("/javascript"))) {
writer = response.getWriter();
// Cannot reliably serve partial content with a Writer
ranges = FULL;
} else {
throw e;
}
}
}
// Check to see if a Filter, Valve of wrapper has written some content.
// If it has, disable range requests and setting of a content length
// since neither can be done reliably.
ServletResponse r = response;
long contentWritten = 0;
while (r instanceof ServletResponseWrapper) {
r = ((ServletResponseWrapper) r).getResponse();
}
if (r instanceof ResponseFacade) {
contentWritten = ((ResponseFacade) r).getContentWritten();
}
if (contentWritten > 0) {
ranges = FULL;
}
if ((cacheEntry.context != null) || isError || (((ranges == null) || (ranges.isEmpty())) && (request.getHeader("Range") == null)) || (ranges == FULL)) {
// Set the appropriate output headers
if (contentType != null) {
if (debug > 0)
log("DefaultServlet.serveFile: contentType='" + contentType + "'");
response.setContentType(contentType);
}
if ((cacheEntry.resource != null) && (contentLength >= 0) && (!serveContent || ostream != null)) {
if (debug > 0)
log("DefaultServlet.serveFile: contentLength=" + contentLength);
// written to the response.
if (contentWritten == 0) {
if (contentLength < Integer.MAX_VALUE) {
response.setContentLength((int) contentLength);
} else {
// Set the content-length as String to be able to use a
// long
response.setHeader("content-length", "" + contentLength);
}
}
}
InputStream renderResult = null;
if (cacheEntry.context != null) {
if (serveContent) {
// Serve the directory browser
renderResult = render(getPathPrefix(request), cacheEntry);
}
}
// Copy the input stream to our output stream (if requested)
if (serveContent) {
try {
response.setBufferSize(output);
} catch (IllegalStateException e) {
// Silent catch
}
if (ostream != null) {
if (!checkSendfile(request, response, cacheEntry, contentLength, null))
copy(cacheEntry, renderResult, ostream);
} else {
copy(cacheEntry, renderResult, writer);
}
}
} else {
if ((ranges == null) || (ranges.isEmpty()))
return;
// Partial content response.
response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
if (ranges.size() == 1) {
Range range = ranges.get(0);
response.addHeader("Content-Range", "bytes " + range.start + "-" + range.end + "/" + range.length);
long length = range.end - range.start + 1;
if (length < Integer.MAX_VALUE) {
response.setContentLength((int) length);
} else {
// Set the content-length as String to be able to use a long
response.setHeader("content-length", "" + length);
}
if (contentType != null) {
if (debug > 0)
log("DefaultServlet.serveFile: contentType='" + contentType + "'");
response.setContentType(contentType);
}
if (serveContent) {
try {
response.setBufferSize(output);
} catch (IllegalStateException e) {
// Silent catch
}
if (ostream != null) {
if (!checkSendfile(request, response, cacheEntry, range.end - range.start + 1, range))
copy(cacheEntry, ostream, range);
} else {
// we should not get here
throw new IllegalStateException();
}
}
} else {
response.setContentType("multipart/byteranges; boundary=" + mimeSeparation);
if (serveContent) {
try {
response.setBufferSize(output);
} catch (IllegalStateException e) {
// Silent catch
}
if (ostream != null) {
copy(cacheEntry, ostream, ranges.iterator(), contentType);
} else {
// we should not get here
throw new IllegalStateException();
}
}
}
}
}
use of org.apache.naming.resources.CacheEntry in project tomcat70 by apache.
the class DefaultServlet method renderXml.
/**
* Return an InputStream to an HTML representation of the contents
* of this directory.
*
* @param contextPath Context path to which our internal paths are
* relative
*/
protected InputStream renderXml(String contextPath, CacheEntry cacheEntry, Source xsltSource) throws IOException, ServletException {
StringBuilder sb = new StringBuilder();
sb.append("<?xml version=\"1.0\"?>");
sb.append("<listing ");
sb.append(" contextPath='");
sb.append(contextPath);
sb.append("'");
sb.append(" directory='");
sb.append(cacheEntry.name);
sb.append("' ");
sb.append(" hasParent='").append(!cacheEntry.name.equals("/"));
sb.append("'>");
sb.append("<entries>");
try {
// Render the directory entries within this directory
NamingEnumeration<NameClassPair> enumeration = resources.list(cacheEntry.name);
// rewriteUrl(contextPath) is expensive. cache result for later reuse
String rewrittenContextPath = rewriteUrl(contextPath);
while (enumeration.hasMoreElements()) {
NameClassPair ncPair = enumeration.nextElement();
String resourceName = ncPair.getName();
String trimmed = resourceName;
if (trimmed.equalsIgnoreCase("WEB-INF") || trimmed.equalsIgnoreCase("META-INF") || trimmed.equalsIgnoreCase(localXsltFile))
continue;
if ((cacheEntry.name + trimmed).equals(contextXsltFile))
continue;
CacheEntry childCacheEntry = resources.lookupCache(cacheEntry.name + resourceName);
if (!childCacheEntry.exists) {
continue;
}
sb.append("<entry");
sb.append(" type='").append((childCacheEntry.context != null) ? "dir" : "file").append("'");
sb.append(" urlPath='").append(rewrittenContextPath).append(rewriteUrl(cacheEntry.name + resourceName)).append((childCacheEntry.context != null) ? "/" : "").append("'");
if (childCacheEntry.resource != null) {
sb.append(" size='").append(renderSize(childCacheEntry.attributes.getContentLength())).append("'");
}
sb.append(" date='").append(childCacheEntry.attributes.getLastModifiedHttp()).append("'");
sb.append(">");
sb.append(RequestUtil.filter(trimmed));
if (childCacheEntry.context != null)
sb.append("/");
sb.append("</entry>");
}
} catch (NamingException e) {
// Something went wrong
throw new ServletException("Error accessing resource", e);
}
sb.append("</entries>");
String readme = getReadme(cacheEntry.context);
if (readme != null) {
sb.append("<readme><![CDATA[");
sb.append(readme);
sb.append("]]></readme>");
}
sb.append("</listing>");
// Prevent possible memory leak. Ensure Transformer and
// TransformerFactory are not loaded from the web application.
ClassLoader original;
if (Globals.IS_SECURITY_ENABLED) {
PrivilegedGetTccl pa = new PrivilegedGetTccl();
original = AccessController.doPrivileged(pa);
} else {
original = Thread.currentThread().getContextClassLoader();
}
try {
if (Globals.IS_SECURITY_ENABLED) {
PrivilegedSetTccl pa = new PrivilegedSetTccl(DefaultServlet.class.getClassLoader());
AccessController.doPrivileged(pa);
} else {
Thread.currentThread().setContextClassLoader(DefaultServlet.class.getClassLoader());
}
TransformerFactory tFactory = TransformerFactory.newInstance();
Source xmlSource = new StreamSource(new StringReader(sb.toString()));
Transformer transformer = tFactory.newTransformer(xsltSource);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
OutputStreamWriter osWriter = new OutputStreamWriter(stream, "UTF8");
StreamResult out = new StreamResult(osWriter);
transformer.transform(xmlSource, out);
osWriter.flush();
return (new ByteArrayInputStream(stream.toByteArray()));
} catch (TransformerException e) {
throw new ServletException("XSL transformer error", e);
} finally {
if (Globals.IS_SECURITY_ENABLED) {
PrivilegedSetTccl pa = new PrivilegedSetTccl(original);
AccessController.doPrivileged(pa);
} else {
Thread.currentThread().setContextClassLoader(original);
}
}
}
use of org.apache.naming.resources.CacheEntry in project tomcat70 by apache.
the class WebdavStatus method parseProperties.
/**
* Propfind helper method.
*
* @param req The servlet request
* @param resources Resources object associated with this context
* @param generatedXML XML response to the Propfind request
* @param path Path of the current resource
* @param type Propfind type
* @param propertiesVector If the propfind type is find properties by
* name, then this Vector contains those properties
*/
private void parseProperties(HttpServletRequest req, XMLWriter generatedXML, String path, int type, Vector<String> propertiesVector) {
// Exclude any resource in the /WEB-INF and /META-INF subdirectories
if (isSpecialPath(path))
return;
CacheEntry cacheEntry = resources.lookupCache(path);
if (!cacheEntry.exists) {
// Broken symlink or odd permission settings?
return;
}
generatedXML.writeElement("D", "response", XMLWriter.OPENING);
String status = "HTTP/1.1 " + WebdavStatus.SC_OK + " " + WebdavStatus.getStatusText(WebdavStatus.SC_OK);
// Generating href element
generatedXML.writeElement("D", "href", XMLWriter.OPENING);
String href = req.getContextPath() + req.getServletPath();
if ((href.endsWith("/")) && (path.startsWith("/")))
href += path.substring(1);
else
href += path;
if ((cacheEntry.context != null) && (!href.endsWith("/")))
href += "/";
generatedXML.writeText(rewriteUrl(href));
generatedXML.writeElement("D", "href", XMLWriter.CLOSING);
String resourceName = path;
int lastSlash = path.lastIndexOf('/');
if (lastSlash != -1)
resourceName = resourceName.substring(lastSlash + 1);
switch(type) {
case FIND_ALL_PROP:
generatedXML.writeElement("D", "propstat", XMLWriter.OPENING);
generatedXML.writeElement("D", "prop", XMLWriter.OPENING);
generatedXML.writeProperty("D", "creationdate", getISOCreationDate(cacheEntry.attributes.getCreation()));
generatedXML.writeElement("D", "displayname", XMLWriter.OPENING);
generatedXML.writeData(resourceName);
generatedXML.writeElement("D", "displayname", XMLWriter.CLOSING);
if (cacheEntry.resource != null) {
generatedXML.writeProperty("D", "getlastmodified", FastHttpDateFormat.formatDate(cacheEntry.attributes.getLastModified(), null));
generatedXML.writeProperty("D", "getcontentlength", String.valueOf(cacheEntry.attributes.getContentLength()));
String contentType = getServletContext().getMimeType(cacheEntry.name);
if (contentType != null) {
generatedXML.writeProperty("D", "getcontenttype", contentType);
}
generatedXML.writeProperty("D", "getetag", cacheEntry.attributes.getETag());
generatedXML.writeElement("D", "resourcetype", XMLWriter.NO_CONTENT);
} else {
generatedXML.writeElement("D", "resourcetype", XMLWriter.OPENING);
generatedXML.writeElement("D", "collection", XMLWriter.NO_CONTENT);
generatedXML.writeElement("D", "resourcetype", XMLWriter.CLOSING);
}
generatedXML.writeProperty("D", "source", "");
String supportedLocks = "<D:lockentry>" + "<D:lockscope><D:exclusive/></D:lockscope>" + "<D:locktype><D:write/></D:locktype>" + "</D:lockentry>" + "<D:lockentry>" + "<D:lockscope><D:shared/></D:lockscope>" + "<D:locktype><D:write/></D:locktype>" + "</D:lockentry>";
generatedXML.writeElement("D", "supportedlock", XMLWriter.OPENING);
generatedXML.writeText(supportedLocks);
generatedXML.writeElement("D", "supportedlock", XMLWriter.CLOSING);
generateLockDiscovery(path, generatedXML);
generatedXML.writeElement("D", "prop", XMLWriter.CLOSING);
generatedXML.writeElement("D", "status", XMLWriter.OPENING);
generatedXML.writeText(status);
generatedXML.writeElement("D", "status", XMLWriter.CLOSING);
generatedXML.writeElement("D", "propstat", XMLWriter.CLOSING);
break;
case FIND_PROPERTY_NAMES:
generatedXML.writeElement("D", "propstat", XMLWriter.OPENING);
generatedXML.writeElement("D", "prop", XMLWriter.OPENING);
generatedXML.writeElement("D", "creationdate", XMLWriter.NO_CONTENT);
generatedXML.writeElement("D", "displayname", XMLWriter.NO_CONTENT);
if (cacheEntry.resource != null) {
generatedXML.writeElement("D", "getcontentlanguage", XMLWriter.NO_CONTENT);
generatedXML.writeElement("D", "getcontentlength", XMLWriter.NO_CONTENT);
generatedXML.writeElement("D", "getcontenttype", XMLWriter.NO_CONTENT);
generatedXML.writeElement("D", "getetag", XMLWriter.NO_CONTENT);
generatedXML.writeElement("D", "getlastmodified", XMLWriter.NO_CONTENT);
}
generatedXML.writeElement("D", "resourcetype", XMLWriter.NO_CONTENT);
generatedXML.writeElement("D", "source", XMLWriter.NO_CONTENT);
generatedXML.writeElement("D", "lockdiscovery", XMLWriter.NO_CONTENT);
generatedXML.writeElement("D", "prop", XMLWriter.CLOSING);
generatedXML.writeElement("D", "status", XMLWriter.OPENING);
generatedXML.writeText(status);
generatedXML.writeElement("D", "status", XMLWriter.CLOSING);
generatedXML.writeElement("D", "propstat", XMLWriter.CLOSING);
break;
case FIND_BY_PROPERTY:
Vector<String> propertiesNotFound = new Vector<String>();
// Parse the list of properties
generatedXML.writeElement("D", "propstat", XMLWriter.OPENING);
generatedXML.writeElement("D", "prop", XMLWriter.OPENING);
Enumeration<String> properties = propertiesVector.elements();
while (properties.hasMoreElements()) {
String property = properties.nextElement();
if (property.equals("creationdate")) {
generatedXML.writeProperty("D", "creationdate", getISOCreationDate(cacheEntry.attributes.getCreation()));
} else if (property.equals("displayname")) {
generatedXML.writeElement("D", "displayname", XMLWriter.OPENING);
generatedXML.writeData(resourceName);
generatedXML.writeElement("D", "displayname", XMLWriter.CLOSING);
} else if (property.equals("getcontentlanguage")) {
if (cacheEntry.context != null) {
propertiesNotFound.addElement(property);
} else {
generatedXML.writeElement("D", "getcontentlanguage", XMLWriter.NO_CONTENT);
}
} else if (property.equals("getcontentlength")) {
if (cacheEntry.context != null) {
propertiesNotFound.addElement(property);
} else {
generatedXML.writeProperty("D", "getcontentlength", (String.valueOf(cacheEntry.attributes.getContentLength())));
}
} else if (property.equals("getcontenttype")) {
if (cacheEntry.context != null) {
propertiesNotFound.addElement(property);
} else {
generatedXML.writeProperty("D", "getcontenttype", getServletContext().getMimeType(cacheEntry.name));
}
} else if (property.equals("getetag")) {
if (cacheEntry.context != null) {
propertiesNotFound.addElement(property);
} else {
generatedXML.writeProperty("D", "getetag", cacheEntry.attributes.getETag());
}
} else if (property.equals("getlastmodified")) {
if (cacheEntry.context != null) {
propertiesNotFound.addElement(property);
} else {
generatedXML.writeProperty("D", "getlastmodified", FastHttpDateFormat.formatDate(cacheEntry.attributes.getLastModified(), null));
}
} else if (property.equals("resourcetype")) {
if (cacheEntry.context != null) {
generatedXML.writeElement("D", "resourcetype", XMLWriter.OPENING);
generatedXML.writeElement("D", "collection", XMLWriter.NO_CONTENT);
generatedXML.writeElement("D", "resourcetype", XMLWriter.CLOSING);
} else {
generatedXML.writeElement("D", "resourcetype", XMLWriter.NO_CONTENT);
}
} else if (property.equals("source")) {
generatedXML.writeProperty("D", "source", "");
} else if (property.equals("supportedlock")) {
supportedLocks = "<D:lockentry>" + "<D:lockscope><D:exclusive/></D:lockscope>" + "<D:locktype><D:write/></D:locktype>" + "</D:lockentry>" + "<D:lockentry>" + "<D:lockscope><D:shared/></D:lockscope>" + "<D:locktype><D:write/></D:locktype>" + "</D:lockentry>";
generatedXML.writeElement("D", "supportedlock", XMLWriter.OPENING);
generatedXML.writeText(supportedLocks);
generatedXML.writeElement("D", "supportedlock", XMLWriter.CLOSING);
} else if (property.equals("lockdiscovery")) {
if (!generateLockDiscovery(path, generatedXML))
propertiesNotFound.addElement(property);
} else {
propertiesNotFound.addElement(property);
}
}
generatedXML.writeElement("D", "prop", XMLWriter.CLOSING);
generatedXML.writeElement("D", "status", XMLWriter.OPENING);
generatedXML.writeText(status);
generatedXML.writeElement("D", "status", XMLWriter.CLOSING);
generatedXML.writeElement("D", "propstat", XMLWriter.CLOSING);
Enumeration<String> propertiesNotFoundList = propertiesNotFound.elements();
if (propertiesNotFoundList.hasMoreElements()) {
status = "HTTP/1.1 " + WebdavStatus.SC_NOT_FOUND + " " + WebdavStatus.getStatusText(WebdavStatus.SC_NOT_FOUND);
generatedXML.writeElement("D", "propstat", XMLWriter.OPENING);
generatedXML.writeElement("D", "prop", XMLWriter.OPENING);
while (propertiesNotFoundList.hasMoreElements()) {
generatedXML.writeElement("D", propertiesNotFoundList.nextElement(), XMLWriter.NO_CONTENT);
}
generatedXML.writeElement("D", "prop", XMLWriter.CLOSING);
generatedXML.writeElement("D", "status", XMLWriter.OPENING);
generatedXML.writeText(status);
generatedXML.writeElement("D", "status", XMLWriter.CLOSING);
generatedXML.writeElement("D", "propstat", XMLWriter.CLOSING);
}
break;
}
generatedXML.writeElement("D", "response", XMLWriter.CLOSING);
}
Aggregations