markt 2003/12/10 13:36:05 Modified: catalina/src/share/org/apache/catalina/servlets WebdavServlet.java Log: - Fix bug 23999, 24001, 24005 Revision Changes Path 1.30 +122 -96 jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/servlets/WebdavServlet.java Index: WebdavServlet.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/servlets/WebdavServlet.java,v retrieving revision 1.29 retrieving revision 1.30 diff -u -r1.29 -r1.30 --- WebdavServlet.java 6 Oct 2003 12:24:01 -0000 1.29 +++ WebdavServlet.java 10 Dec 2003 21:36:05 -0000 1.30 @@ -65,60 +65,39 @@ package org.apache.catalina.servlets; -import java.io.BufferedInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.InputStream; import java.io.IOException; -import java.io.PrintWriter; import java.io.StringWriter; import java.io.Writer; -import java.net.MalformedURLException; -import java.net.URL; -import java.sql.Timestamp; +import java.text.SimpleDateFormat; import java.util.Date; import java.util.Enumeration; -import java.util.Vector; -import java.util.Stack; -import java.util.StringTokenizer; -import java.util.Locale; import java.util.Hashtable; -import java.util.Calendar; +import java.util.Stack; import java.util.TimeZone; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.w3c.dom.Element; -import org.w3c.dom.Document; -import org.xml.sax.InputSource; -import javax.servlet.RequestDispatcher; +import java.util.Vector; + +import javax.naming.NameClassPair; +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; +import javax.naming.directory.DirContext; import javax.servlet.ServletException; -import javax.servlet.ServletContext; -import javax.servlet.ServletOutputStream; -import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; -import javax.naming.NamingException; -import javax.naming.InitialContext; -import javax.naming.Context; -import javax.naming.NamingEnumeration; -import javax.naming.NameClassPair; -import javax.naming.directory.DirContext; -import javax.naming.directory.Attribute; -import javax.naming.directory.Attributes; -import org.apache.naming.resources.Resource; -import org.apache.naming.resources.ResourceAttributes; -import org.apache.catalina.util.MD5Encoder; -import org.apache.catalina.util.StringManager; -import org.apache.catalina.util.XMLWriter; + import org.apache.catalina.util.DOMWriter; import org.apache.catalina.util.RequestUtil; +import org.apache.catalina.util.XMLWriter; +import org.apache.naming.resources.Resource; +import org.apache.tomcat.util.http.FastHttpDateFormat; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; /** @@ -134,7 +113,7 @@ // -------------------------------------------------------------- Constants - + private static final String METHOD_HEAD = "HEAD"; private static final String METHOD_PROPFIND = "PROPFIND"; @@ -359,11 +338,8 @@ protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - String path = getRelativePath(req); - resp.addHeader("DAV", "1,2"); - String methodsAllowed = null; - + // Retrieve the resources DirContext resources = getResources(); @@ -372,28 +348,10 @@ return; } - boolean exists = true; - Object object = null; - try { - object = resources.lookup(path); - } catch (NamingException e) { - exists = false; - } - - if (!exists) { - methodsAllowed = "OPTIONS, MKCOL, PUT, LOCK"; - resp.addHeader("Allow", methodsAllowed); - return; - } - - methodsAllowed = "OPTIONS, GET, HEAD, POST, DELETE, TRACE, " - + "PROPFIND, PROPPATCH, COPY, MOVE, LOCK, UNLOCK"; - if (!(object instanceof DirContext)) { - methodsAllowed += ", PUT"; - } - - resp.addHeader("Allow", methodsAllowed); + StringBuffer methodsAllowed = determineMethodsAllowed(resources, + req); + resp.addHeader("Allow", methodsAllowed.toString()); resp.addHeader("MS-Author-Via", "DAV"); } @@ -406,6 +364,19 @@ throws ServletException, IOException { if (!listings) { + // Retrieve the resources + DirContext resources = getResources(); + + if (resources == null) { + resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + return; + } + + // Get allowed methods + StringBuffer methodsAllowed = determineMethodsAllowed(resources, + req); + + resp.addHeader("Allow", methodsAllowed.toString()); resp.sendError(WebdavStatus.SC_METHOD_NOT_ALLOWED); return; } @@ -670,7 +641,7 @@ return; } - resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED); + resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED); } @@ -718,10 +689,32 @@ // Can't create a collection if a resource already exists at the given // path if (exists) { + // Get allowed methods + StringBuffer methodsAllowed = determineMethodsAllowed(resources, + req); + + resp.addHeader("Allow", methodsAllowed.toString()); + resp.sendError(WebdavStatus.SC_METHOD_NOT_ALLOWED); return; } + if (req.getInputStream().available() > 0) { + DocumentBuilder documentBuilder = getDocumentBuilder(); + try { + Document document = documentBuilder.parse + (new InputSource(req.getInputStream())); + // TODO : Process this request body + resp.sendError(WebdavStatus.SC_NOT_IMPLEMENTED); + return; + + } catch(SAXException saxe) { + // Parse error - assume invalid content + resp.sendError(WebdavStatus.SC_BAD_REQUEST); + return; + } + } + boolean result = true; try { resources.createSubcontext(path); @@ -871,6 +864,11 @@ if (lockDurationStr == null) { lockDuration = DEFAULT_TIMEOUT; } else { + int commaPos = lockDurationStr.indexOf(","); + // If multiple timeouts, just use the first + if (commaPos != -1) { + lockDurationStr = lockDurationStr.substring(0,commaPos); + } if (lockDurationStr.startsWith("Second-")) { lockDuration = (new Integer(lockDurationStr.substring(7))).intValue(); @@ -1388,12 +1386,6 @@ // -------------------------------------------------------- Private Methods - - protected String getETagValue(ResourceInfo resourceInfo) { - return resourceInfo.length + "-" + resourceInfo.date; - } - - /** * Generate the namespace declarations. */ @@ -2037,19 +2029,20 @@ generatedXML.writeElement(null, "displayname", XMLWriter.OPENING); generatedXML.writeData(resourceName); generatedXML.writeElement(null, "displayname", XMLWriter.CLOSING); - generatedXML.writeProperty(null, "getcontentlanguage", - Locale.getDefault().toString()); if (!resourceInfo.collection) { generatedXML.writeProperty (null, "getlastmodified", resourceInfo.httpDate); generatedXML.writeProperty (null, "getcontentlength", String.valueOf(resourceInfo.length)); - generatedXML.writeProperty - (null, "getcontenttype", - getServletContext().getMimeType(resourceInfo.path)); + String contentType = getServletContext().getMimeType + (resourceInfo.path); + if (contentType != null) { + generatedXML.writeProperty(null, "getcontenttype", + contentType); + } generatedXML.writeProperty(null, "getetag", - getETagValue(resourceInfo)); + getETag(resourceInfo)); generatedXML.writeElement(null, "resourcetype", XMLWriter.NO_CONTENT); } else { @@ -2150,9 +2143,8 @@ if (resourceInfo.collection) { propertiesNotFound.addElement(property); } else { - generatedXML.writeProperty - (null, "getcontentlanguage", - Locale.getDefault().toString()); + generatedXML.writeElement(null, "getcontentlanguage", + XMLWriter.NO_CONTENT); } } else if (property.equals("getcontentlength")) { if (resourceInfo.collection) { @@ -2176,7 +2168,7 @@ propertiesNotFound.addElement(property); } else { generatedXML.writeProperty - (null, "getetag", getETagValue(resourceInfo)); + (null, "getetag", getETag(resourceInfo)); } } else if (property.equals("getlastmodified")) { if (resourceInfo.collection) { @@ -2326,10 +2318,9 @@ generatedXML.writeData(resourceName); generatedXML.writeElement (null, "displayname", XMLWriter.CLOSING); - generatedXML.writeProperty(null, "getcontentlanguage", - Locale.getDefault().toString()); generatedXML.writeProperty(null, "getlastmodified", - formats[0].format(lock.creationDate)); + FastHttpDateFormat.formatDate + (lock.creationDate.getTime(), null)); generatedXML.writeProperty (null, "getcontentlength", String.valueOf(0)); generatedXML.writeProperty(null, "getcontenttype", ""); @@ -2425,9 +2416,8 @@ generatedXML.writeElement (null, "displayname", XMLWriter.CLOSING); } else if (property.equals("getcontentlanguage")) { - generatedXML.writeProperty - (null, "getcontentlanguage", - Locale.getDefault().toString()); + generatedXML.writeElement(null, "getcontentlanguage", + XMLWriter.NO_CONTENT); } else if (property.equals("getcontentlength")) { generatedXML.writeProperty (null, "getcontentlength", (String.valueOf(0))); @@ -2439,7 +2429,8 @@ } else if (property.equals("getlastmodified")) { generatedXML.writeProperty (null, "getlastmodified", - formats[0].format(lock.creationDate)); + FastHttpDateFormat.formatDate + (lock.creationDate.getTime(), null)); } else if (property.equals("resourcetype")) { generatedXML.writeElement(null, "resourcetype", XMLWriter.OPENING); @@ -2585,6 +2576,42 @@ return creationDateValue.toString(); } + /** + * Determines the methods normally allowed for the resource. + * + */ + private StringBuffer determineMethodsAllowed(DirContext resources, + HttpServletRequest req) { + + StringBuffer methodsAllowed = new StringBuffer(); + boolean exists = true; + Object object = null; + try { + String path = getRelativePath(req); + + object = resources.lookup(path); + } catch (NamingException e) { + exists = false; + } + + if (!exists) { + methodsAllowed.append("OPTIONS, MKCOL, PUT, LOCK"); + return methodsAllowed; + } + + methodsAllowed.append("OPTIONS, GET, HEAD, POST, DELETE, TRACE"); + methodsAllowed.append(", PROPPATCH, COPY, MOVE, LOCK, UNLOCK"); + + if (listings) { + methodsAllowed.append(", PROPFIND"); + } + + if (!(object instanceof DirContext)) { + methodsAllowed.append(", PUT"); + } + + return methodsAllowed; + } // -------------------------------------------------- LockInfo Inner Class @@ -2633,8 +2660,8 @@ result += "Scope:" + scope + "\n"; result += "Depth:" + depth + "\n"; result += "Owner:" + owner + "\n"; - result += "Expiration:" + - formats[0].format(new Date(expiresAt)) + "\n"; + result += "Expiration:" + + FastHttpDateFormat.formatDate(expiresAt, null) + "\n"; Enumeration tokensList = tokens.elements(); while (tokensList.hasMoreElements()) { result += "Token:" + tokensList.nextElement() + "\n"; @@ -3060,7 +3087,6 @@ private static void addStatusCodeMap(int nKey, String strVal) { mapStatusCodes.put(new Integer(nKey), strVal); } - };
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]