in java/org/apache/catalina/servlets/WebdavServlet.java [485:708]
protected void doPropfind(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
if (!listings) {
sendNotAllowed(req, resp);
return;
}
String path = getRelativePath(req);
if (path.length() > 1 && path.endsWith("/"))
path = path.substring(0, path.length() - 1);
// Properties which are to be displayed.
Vector<String> properties = null;
// Propfind depth
int depth = maxDepth;
// Propfind type
int type = FIND_ALL_PROP;
String depthStr = req.getHeader("Depth");
if (depthStr == null) {
depth = maxDepth;
} else {
if (depthStr.equals("0")) {
depth = 0;
} else if (depthStr.equals("1")) {
depth = 1;
} else if (depthStr.equals("infinity")) {
depth = maxDepth;
}
}
Node propNode = null;
if (req.getContentLengthLong() > 0) {
DocumentBuilder documentBuilder = getDocumentBuilder();
try {
Document document = documentBuilder.parse
(new InputSource(req.getInputStream()));
// Get the root element of the document
Element rootElement = document.getDocumentElement();
NodeList childList = rootElement.getChildNodes();
for (int i=0; i < childList.getLength(); i++) {
Node currentNode = childList.item(i);
switch (currentNode.getNodeType()) {
case Node.TEXT_NODE:
break;
case Node.ELEMENT_NODE:
if (currentNode.getNodeName().endsWith("prop")) {
type = FIND_BY_PROPERTY;
propNode = currentNode;
}
if (currentNode.getNodeName().endsWith("propname")) {
type = FIND_PROPERTY_NAMES;
}
if (currentNode.getNodeName().endsWith("allprop")) {
type = FIND_ALL_PROP;
}
break;
}
}
} catch (SAXException e) {
// Something went wrong - bad request
resp.sendError(WebdavStatus.SC_BAD_REQUEST);
return;
} catch (IOException e) {
// Something went wrong - bad request
resp.sendError(WebdavStatus.SC_BAD_REQUEST);
return;
}
}
if (type == FIND_BY_PROPERTY) {
properties = new Vector<>();
// propNode must be non-null if type == FIND_BY_PROPERTY
@SuppressWarnings("null")
NodeList childList = propNode.getChildNodes();
for (int i=0; i < childList.getLength(); i++) {
Node currentNode = childList.item(i);
switch (currentNode.getNodeType()) {
case Node.TEXT_NODE:
break;
case Node.ELEMENT_NODE:
String nodeName = currentNode.getNodeName();
String propertyName = null;
if (nodeName.indexOf(':') != -1) {
propertyName = nodeName.substring
(nodeName.indexOf(':') + 1);
} else {
propertyName = nodeName;
}
// href is a live property which is handled differently
properties.addElement(propertyName);
break;
}
}
}
WebResource resource = resources.getResource(path);
if (!resource.exists()) {
int slash = path.lastIndexOf('/');
if (slash != -1) {
String parentPath = path.substring(0, slash);
Vector<String> currentLockNullResources =
lockNullResources.get(parentPath);
if (currentLockNullResources != null) {
Enumeration<String> lockNullResourcesList =
currentLockNullResources.elements();
while (lockNullResourcesList.hasMoreElements()) {
String lockNullPath =
lockNullResourcesList.nextElement();
if (lockNullPath.equals(path)) {
resp.setStatus(WebdavStatus.SC_MULTI_STATUS);
resp.setContentType("text/xml; charset=UTF-8");
// Create multistatus object
XMLWriter generatedXML =
new XMLWriter(resp.getWriter());
generatedXML.writeXMLHeader();
generatedXML.writeElement("D", DEFAULT_NAMESPACE,
"multistatus", XMLWriter.OPENING);
parseLockNullProperties
(req, generatedXML, lockNullPath, type,
properties);
generatedXML.writeElement("D", "multistatus",
XMLWriter.CLOSING);
generatedXML.sendData();
return;
}
}
}
}
}
if (!resource.exists()) {
resp.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
resp.setStatus(WebdavStatus.SC_MULTI_STATUS);
resp.setContentType("text/xml; charset=UTF-8");
// Create multistatus object
XMLWriter generatedXML = new XMLWriter(resp.getWriter());
generatedXML.writeXMLHeader();
generatedXML.writeElement("D", DEFAULT_NAMESPACE, "multistatus",
XMLWriter.OPENING);
if (depth == 0) {
parseProperties(req, generatedXML, path, type,
properties);
} else {
// The stack always contains the object of the current level
Stack<String> stack = new Stack<>();
stack.push(path);
// Stack of the objects one level below
Stack<String> stackBelow = new Stack<>();
while ((!stack.isEmpty()) && (depth >= 0)) {
String currentPath = stack.pop();
parseProperties(req, generatedXML, currentPath,
type, properties);
resource = resources.getResource(currentPath);
if (resource.isDirectory() && (depth > 0)) {
String[] entries = resources.list(currentPath);
for (String entry : entries) {
String newPath = currentPath;
if (!(newPath.endsWith("/")))
newPath += "/";
newPath += entry;
stackBelow.push(newPath);
}
// Displaying the lock-null resources present in that
// collection
String lockPath = currentPath;
if (lockPath.endsWith("/"))
lockPath =
lockPath.substring(0, lockPath.length() - 1);
Vector<String> currentLockNullResources =
lockNullResources.get(lockPath);
if (currentLockNullResources != null) {
Enumeration<String> lockNullResourcesList =
currentLockNullResources.elements();
while (lockNullResourcesList.hasMoreElements()) {
String lockNullPath =
lockNullResourcesList.nextElement();
parseLockNullProperties
(req, generatedXML, lockNullPath, type,
properties);
}
}
}
if (stack.isEmpty()) {
depth--;
stack = stackBelow;
stackBelow = new Stack<>();
}
generatedXML.sendData();
}
}
generatedXML.writeElement("D", "multistatus", XMLWriter.CLOSING);
generatedXML.sendData();
}