diff --git a/source/java/org/alfresco/repo/webdav/LockMethod.java b/source/java/org/alfresco/repo/webdav/LockMethod.java index b07c56c162..4e86354d42 100644 --- a/source/java/org/alfresco/repo/webdav/LockMethod.java +++ b/source/java/org/alfresco/repo/webdav/LockMethod.java @@ -511,6 +511,8 @@ public class LockMethod extends WebDAVMethod // Close off the XML xml.endElement(WebDAV.DAV_NS, WebDAV.XML_PROP, WebDAV.XML_NS_PROP); + // Send remaining data + flushXML(xml); } diff --git a/source/java/org/alfresco/repo/webdav/PropFindMethod.java b/source/java/org/alfresco/repo/webdav/PropFindMethod.java index 7f9dffdf47..b646798f46 100644 --- a/source/java/org/alfresco/repo/webdav/PropFindMethod.java +++ b/source/java/org/alfresco/repo/webdav/PropFindMethod.java @@ -316,22 +316,15 @@ public class PropFindMethod extends WebDAVMethod xml.endElement(WebDAV.DAV_NS, WebDAV.XML_MULTI_STATUS, WebDAV.XML_NS_MULTI_STATUS); // Send remaining data - xml.flush(); + flushXML(xml); } @Override - protected XMLWriter createXMLWriter() throws IOException + protected OutputFormat getXMLOutputFormat() { String userAgent = m_request.getHeader("User-Agent"); - if ((null != userAgent) && userAgent.toLowerCase().startsWith("microsoft-webdav-miniredir/5.1.")) - { - // ALF-9952: XP requires compact XML for this response - return new XMLWriter(m_response.getOutputStream(), OutputFormat.createCompactFormat()); - } - else - { - return super.createXMLWriter(); - } + return ((null != userAgent) && userAgent.toLowerCase().startsWith("microsoft-webdav-miniredir/5.1.")) ? OutputFormat.createCompactFormat() : super.getXMLOutputFormat(); + } /** diff --git a/source/java/org/alfresco/repo/webdav/UnlockMethod.java b/source/java/org/alfresco/repo/webdav/UnlockMethod.java index 7095feb16d..4b6377c0cb 100644 --- a/source/java/org/alfresco/repo/webdav/UnlockMethod.java +++ b/source/java/org/alfresco/repo/webdav/UnlockMethod.java @@ -23,6 +23,7 @@ import java.util.Set; import javax.servlet.http.HttpServletResponse; import org.alfresco.model.ContentModel; +import org.alfresco.repo.security.authentication.AuthenticationException; import org.alfresco.service.cmr.model.FileInfo; import org.alfresco.service.cmr.model.FileNotFoundException; import org.alfresco.service.cmr.repository.NodeRef; @@ -77,20 +78,47 @@ public class UnlockMethod extends WebDAVMethod strLockTokenHeader = "<" + strLockTokenHeader + ">"; } if (strLockTokenHeader.startsWith("<" + WebDAV.OPAQUE_LOCK_TOKEN) && strLockTokenHeader.endsWith(">")) + { + try { - try - { - m_strLockToken = strLockTokenHeader.substring( - WebDAV.OPAQUE_LOCK_TOKEN.length() + 1, - strLockTokenHeader.length() - 1); - } - catch (IndexOutOfBoundsException e) - { - logger.warn("Failed to parse If header: " + strLockTokenHeader); - } + m_strLockToken = strLockTokenHeader.substring( + WebDAV.OPAQUE_LOCK_TOKEN.length() + 1, + strLockTokenHeader.length() - 1); } - } + catch (IndexOutOfBoundsException e) + { + logger.warn("Failed to parse If header: " + strLockTokenHeader); + } + } + } + // ALF-11817 If the header Lock-Token is incorrect (without < and >). + else + { + // Build the lock token. + FileInfo lockNodeInfo = null; + String userName = null; + try + { + userName = getDAVHelper().getAuthenticationService().getCurrentUserName(); + lockNodeInfo = getNodeForPath(getRootNodeRef(), getPath(), getServletPath()); + } + catch (AuthenticationException ex) + { + throw new WebDAVServerException(HttpServletResponse.SC_UNAUTHORIZED); + } + catch (FileNotFoundException e) + { + throw new WebDAVServerException(HttpServletResponse.SC_NOT_FOUND); + } + String buildLockToken = WebDAV.makeLockToken(lockNodeInfo.getNodeRef(), userName); + // End build. + if (strLockTokenHeader.equalsIgnoreCase(buildLockToken)) + { + m_strLockToken = strLockTokenHeader; + } + } + } // If there is no token this is a bad request so send an error back if (m_strLockToken == null) { diff --git a/source/java/org/alfresco/repo/webdav/WebDAVMethod.java b/source/java/org/alfresco/repo/webdav/WebDAVMethod.java index 07663f73d4..894989890d 100644 --- a/source/java/org/alfresco/repo/webdav/WebDAVMethod.java +++ b/source/java/org/alfresco/repo/webdav/WebDAVMethod.java @@ -19,6 +19,7 @@ package org.alfresco.repo.webdav; import java.io.BufferedReader; +import java.io.CharArrayWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -118,6 +119,7 @@ public abstract class WebDAVMethod protected HttpServletResponse m_response; private File m_requestBody; private ServletInputStream m_inputStream; + private CharArrayWriter m_xmlWriter; private BufferedReader m_reader; // WebDAV helper @@ -837,30 +839,26 @@ public abstract class WebDAVMethod return m_strPath; } + /** + * Returns the format required for an XML response. This may vary per method. + */ + protected OutputFormat getXMLOutputFormat() + { + // Check if debug output or XML pretty printing is enabled + return (XMLPrettyPrint || logger.isDebugEnabled()) ? OutputFormat.createPrettyPrint() : OutputFormat.createCompactFormat(); + } + /** * Create an XML writer for the response * * @return XMLWriter * @exception IOException */ - protected XMLWriter createXMLWriter() throws IOException + protected final XMLWriter createXMLWriter() throws IOException { - // Check if debug output or XML pretty printing is enabled - - XMLWriter writer = null; - - if (XMLPrettyPrint == true || logger.isDebugEnabled()) - { - writer = new XMLWriter(m_response.getWriter(), OutputFormat.createPrettyPrint()); - } - else - { - writer = new XMLWriter(m_response.getWriter(), OutputFormat.createCompactFormat()); - } - - // Return the writer - - return writer; + // Buffer the XML response, in case we have to reset mid-transaction + m_xmlWriter = new CharArrayWriter(1024); + return new XMLWriter(m_xmlWriter, getXMLOutputFormat()); } /** @@ -1446,13 +1444,29 @@ public abstract class WebDAVMethod } /** - * Flushs a XML Writer. + * Determines whether the XMLWriter should be flushed when XML is flushed. For some reason this is method specific. + * @return true if the XMLWriter should be flushed when XML is flushed + */ + protected boolean shouldFlushXMLWriter() + { + return true; + } + + /** + * Flushes all XML written so far to the response * * @param xml XMLWriter that should be flushed */ - protected void flushXML(XMLWriter xml) throws IOException + protected final void flushXML(XMLWriter writer) throws IOException { - xml.flush(); + if (shouldFlushXMLWriter()) + { + writer.flush(); + } + + m_response.getWriter().write(m_xmlWriter.toCharArray()); + + m_xmlWriter.reset(); } /**