mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
Fixed AR-1321: Allow '&' in filename
The following filename is valid now: "x ¬ £ % & + ; x.txt" This was a restriction imposed by WebDAV, but the encoding of the repsonses is working well and these restrictions be removed as a result. Fixed AR-1281: WebDAV upload was assigning incorrect encoding I added a bean 'charset.finder', which can be fetched from the MimetypeService. Various pluggins now exist to decode a stream and figure out what the encoding is. WebDAV and CIFS/FTP are now hooked into this so that they guess a little better. Fixed others: Added retrying transactions to WebDAV. Read/write transactions for WebDAV. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@6073 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -141,6 +141,15 @@ public class GetMethod extends WebDAVMethod
|
|||||||
// Nothing to do in this method
|
// Nothing to do in this method
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Returns <tt>true</tt> always
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected boolean isReadOnly()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exceute the WebDAV request
|
* Exceute the WebDAV request
|
||||||
*
|
*
|
||||||
|
@@ -69,6 +69,15 @@ public class OptionsMethod extends WebDAVMethod
|
|||||||
// Nothing to do in this method
|
// Nothing to do in this method
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Returns <tt>true</tt> always
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected boolean isReadOnly()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform the main request processing
|
* Perform the main request processing
|
||||||
*
|
*
|
||||||
|
@@ -24,14 +24,17 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.webdav;
|
package org.alfresco.repo.webdav;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
|
import org.alfresco.repo.content.encoding.ContentCharsetFinder;
|
||||||
import org.alfresco.service.cmr.model.FileExistsException;
|
import org.alfresco.service.cmr.model.FileExistsException;
|
||||||
import org.alfresco.service.cmr.model.FileFolderService;
|
import org.alfresco.service.cmr.model.FileFolderService;
|
||||||
import org.alfresco.service.cmr.model.FileInfo;
|
import org.alfresco.service.cmr.model.FileInfo;
|
||||||
@@ -142,23 +145,28 @@ public class PutMethod extends WebDAVMethod
|
|||||||
// Access the content
|
// Access the content
|
||||||
ContentWriter writer = fileFolderService.getWriter(contentNodeInfo.getNodeRef());
|
ContentWriter writer = fileFolderService.getWriter(contentNodeInfo.getNodeRef());
|
||||||
// set content properties
|
// set content properties
|
||||||
|
String mimetype = null;
|
||||||
if (m_strContentType != null)
|
if (m_strContentType != null)
|
||||||
{
|
{
|
||||||
writer.setMimetype(m_strContentType);
|
mimetype = m_strContentType;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
String guessedMimetype = getServiceRegistry().getMimetypeService().guessMimetype(contentNodeInfo.getName());
|
String guessedMimetype = getMimetypeService().guessMimetype(contentNodeInfo.getName());
|
||||||
writer.setMimetype(guessedMimetype);
|
mimetype = guessedMimetype;
|
||||||
}
|
}
|
||||||
// use default encoding
|
writer.setMimetype(mimetype);
|
||||||
writer.setEncoding("UTF-8");
|
|
||||||
|
|
||||||
// Get the input stream from the request data
|
// Get the input stream from the request data
|
||||||
InputStream input = m_request.getInputStream();
|
InputStream is = m_request.getInputStream();
|
||||||
|
is = is.markSupported() ? is : new BufferedInputStream(is);
|
||||||
|
|
||||||
|
ContentCharsetFinder charsetFinder = getMimetypeService().getContentCharsetFinder();
|
||||||
|
Charset encoding = charsetFinder.getCharset(is, mimetype);
|
||||||
|
writer.setEncoding(encoding.name());
|
||||||
|
|
||||||
// Write the new data to the content node
|
// Write the new data to the content node
|
||||||
writer.putContent(input);
|
writer.putContent(is);
|
||||||
|
|
||||||
// Set the response status, depending if the node existed or not
|
// Set the response status, depending if the node existed or not
|
||||||
m_response.setStatus(created ? HttpServletResponse.SC_CREATED : HttpServletResponse.SC_NO_CONTENT);
|
m_response.setStatus(created ? HttpServletResponse.SC_CREATED : HttpServletResponse.SC_NO_CONTENT);
|
||||||
|
@@ -88,9 +88,6 @@ public class WebDAVHelper
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Class constructor
|
* Class constructor
|
||||||
*
|
|
||||||
* @param serviceRegistry ServiceRegistry
|
|
||||||
* @param authService AuthenticationService
|
|
||||||
*/
|
*/
|
||||||
protected WebDAVHelper(ServiceRegistry serviceRegistry, AuthenticationService authService)
|
protected WebDAVHelper(ServiceRegistry serviceRegistry, AuthenticationService authService)
|
||||||
{
|
{
|
||||||
@@ -108,9 +105,7 @@ public class WebDAVHelper
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the authentication service
|
* @return Return the authentication service
|
||||||
*
|
|
||||||
* @return AuthenticationService
|
|
||||||
*/
|
*/
|
||||||
public final AuthenticationService getAuthenticationService()
|
public final AuthenticationService getAuthenticationService()
|
||||||
{
|
{
|
||||||
@@ -118,9 +113,7 @@ public class WebDAVHelper
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the service registry
|
* @return Return the service registry
|
||||||
*
|
|
||||||
* @return ServiceRegistry
|
|
||||||
*/
|
*/
|
||||||
public final ServiceRegistry getServiceRegistry()
|
public final ServiceRegistry getServiceRegistry()
|
||||||
{
|
{
|
||||||
@@ -128,9 +121,7 @@ public class WebDAVHelper
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the node service
|
* @return Return the node service
|
||||||
*
|
|
||||||
* @return NodeService
|
|
||||||
*/
|
*/
|
||||||
public final NodeService getNodeService()
|
public final NodeService getNodeService()
|
||||||
{
|
{
|
||||||
@@ -143,9 +134,7 @@ public class WebDAVHelper
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the search service
|
* @return Return the search service
|
||||||
*
|
|
||||||
* @return SearchService
|
|
||||||
*/
|
*/
|
||||||
public final SearchService getSearchService()
|
public final SearchService getSearchService()
|
||||||
{
|
{
|
||||||
@@ -153,9 +142,7 @@ public class WebDAVHelper
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the namespace service
|
* @return Return the namespace service
|
||||||
*
|
|
||||||
* @return NamespaceService
|
|
||||||
*/
|
*/
|
||||||
public final NamespaceService getNamespaceService()
|
public final NamespaceService getNamespaceService()
|
||||||
{
|
{
|
||||||
@@ -163,9 +150,7 @@ public class WebDAVHelper
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the dictionary service
|
* @return Return the dictionary service
|
||||||
*
|
|
||||||
* @return DictionaryService
|
|
||||||
*/
|
*/
|
||||||
public final DictionaryService getDictionaryService()
|
public final DictionaryService getDictionaryService()
|
||||||
{
|
{
|
||||||
@@ -173,9 +158,7 @@ public class WebDAVHelper
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the mimetype service
|
* @return Return the mimetype service
|
||||||
*
|
|
||||||
* @return MimetypeService
|
|
||||||
*/
|
*/
|
||||||
public final MimetypeService getMimetypeService()
|
public final MimetypeService getMimetypeService()
|
||||||
{
|
{
|
||||||
@@ -183,9 +166,7 @@ public class WebDAVHelper
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the lock service
|
* @return Return the lock service
|
||||||
*
|
|
||||||
* @return LockService
|
|
||||||
*/
|
*/
|
||||||
public final LockService getLockService()
|
public final LockService getLockService()
|
||||||
{
|
{
|
||||||
@@ -193,9 +174,7 @@ public class WebDAVHelper
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the copy service
|
* @return Return the copy service
|
||||||
*
|
|
||||||
* @return CopyService
|
|
||||||
*/
|
*/
|
||||||
public final CopyService getCopyService()
|
public final CopyService getCopyService()
|
||||||
{
|
{
|
||||||
@@ -237,8 +216,8 @@ public class WebDAVHelper
|
|||||||
/**
|
/**
|
||||||
* Split the path into all the component directories and filename
|
* Split the path into all the component directories and filename
|
||||||
*
|
*
|
||||||
* @param path String
|
* @param path the string to split
|
||||||
* @return String[]
|
* @return an array of all the path components
|
||||||
*/
|
*/
|
||||||
public final List<String> splitAllPaths(String path)
|
public final List<String> splitAllPaths(String path)
|
||||||
{
|
{
|
||||||
@@ -260,11 +239,12 @@ public class WebDAVHelper
|
|||||||
/**
|
/**
|
||||||
* Get the file info for the given paths
|
* Get the file info for the given paths
|
||||||
*
|
*
|
||||||
* @param rootNodeRef the acting webdav root
|
* @param rootNodeRef the acting webdav root
|
||||||
* @param path the path to search for
|
* @param path the path to search for
|
||||||
* @param servletPath the base servlet path, which may be null or empty
|
* @param servletPath the base servlet path, which may be null or empty
|
||||||
* @return Return the file info for the path
|
* @return Return the file info for the path
|
||||||
* @throws FileNotFoundException if the path doesn't refer to a valid node
|
* @throws FileNotFoundException
|
||||||
|
* if the path doesn't refer to a valid node
|
||||||
*/
|
*/
|
||||||
public final FileInfo getNodeForPath(NodeRef rootNodeRef, String path, String servletPath) throws FileNotFoundException
|
public final FileInfo getNodeForPath(NodeRef rootNodeRef, String path, String servletPath) throws FileNotFoundException
|
||||||
{
|
{
|
||||||
@@ -366,9 +346,6 @@ public class WebDAVHelper
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Make an ETag value for a node using the GUID and modify date/time
|
* Make an ETag value for a node using the GUID and modify date/time
|
||||||
*
|
|
||||||
* @param node NodeRef
|
|
||||||
* @return String
|
|
||||||
*/
|
*/
|
||||||
public final String makeETag(NodeRef node)
|
public final String makeETag(NodeRef node)
|
||||||
{
|
{
|
||||||
@@ -381,9 +358,6 @@ public class WebDAVHelper
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Make an ETag value for a node using the GUID and modify date/time
|
* Make an ETag value for a node using the GUID and modify date/time
|
||||||
*
|
|
||||||
* @param node NodeRef
|
|
||||||
* @return String
|
|
||||||
*/
|
*/
|
||||||
public final String makeQuotedETag(NodeRef node)
|
public final String makeQuotedETag(NodeRef node)
|
||||||
{
|
{
|
||||||
@@ -397,9 +371,6 @@ public class WebDAVHelper
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Make an ETag value for a node using the GUID and modify date/time
|
* Make an ETag value for a node using the GUID and modify date/time
|
||||||
*
|
|
||||||
* @param node NodeRef
|
|
||||||
* @param str StringBuilder
|
|
||||||
*/
|
*/
|
||||||
protected final void makeETagString(NodeRef node, StringBuilder etag)
|
protected final void makeETagString(NodeRef node, StringBuilder etag)
|
||||||
{
|
{
|
||||||
@@ -417,9 +388,7 @@ public class WebDAVHelper
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the null XML attribute list
|
* @return Return the null XML attribute list
|
||||||
*
|
|
||||||
* @return AttributesImpl
|
|
||||||
*/
|
*/
|
||||||
public final AttributesImpl getNullAttributes()
|
public final AttributesImpl getNullAttributes()
|
||||||
{
|
{
|
||||||
@@ -429,7 +398,7 @@ public class WebDAVHelper
|
|||||||
/**
|
/**
|
||||||
* Encodes the given string to valid URL format
|
* Encodes the given string to valid URL format
|
||||||
*
|
*
|
||||||
* @param s the String to convert
|
* @param s the String to convert
|
||||||
*/
|
*/
|
||||||
public final static String encodeURL(String s)
|
public final static String encodeURL(String s)
|
||||||
{
|
{
|
||||||
@@ -446,11 +415,7 @@ public class WebDAVHelper
|
|||||||
/**
|
/**
|
||||||
* Replace one string instance with another within the specified string
|
* Replace one string instance with another within the specified string
|
||||||
*
|
*
|
||||||
* @param str
|
* @return Returns the replaced string
|
||||||
* @param repl
|
|
||||||
* @param with
|
|
||||||
*
|
|
||||||
* @return replaced string
|
|
||||||
*/
|
*/
|
||||||
public static String replace(String str, String repl, String with)
|
public static String replace(String str, String repl, String with)
|
||||||
{
|
{
|
||||||
@@ -478,7 +443,7 @@ public class WebDAVHelper
|
|||||||
/**
|
/**
|
||||||
* Encodes the given string to valid HTML format
|
* Encodes the given string to valid HTML format
|
||||||
*
|
*
|
||||||
* @param string the String to convert
|
* @param string the String to convert
|
||||||
*/
|
*/
|
||||||
public final static String encodeHTML(String string)
|
public final static String encodeHTML(String string)
|
||||||
{
|
{
|
||||||
|
@@ -37,8 +37,7 @@ import javax.xml.parsers.ParserConfigurationException;
|
|||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
||||||
import org.alfresco.repo.transaction.TransactionUtil;
|
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||||
import org.alfresco.repo.transaction.TransactionUtil.TransactionWork;
|
|
||||||
import org.alfresco.service.ServiceRegistry;
|
import org.alfresco.service.ServiceRegistry;
|
||||||
import org.alfresco.service.cmr.lock.LockService;
|
import org.alfresco.service.cmr.lock.LockService;
|
||||||
import org.alfresco.service.cmr.model.FileFolderService;
|
import org.alfresco.service.cmr.model.FileFolderService;
|
||||||
@@ -114,11 +113,23 @@ public abstract class WebDAVMethod
|
|||||||
|
|
||||||
m_strPath = WebDAV.getRepositoryPath(req);
|
m_strPath = WebDAV.getRepositoryPath(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override and return <tt>true</tt> if the method is a query method only. The default implementation
|
||||||
|
* returns <tt>false</tt>.
|
||||||
|
*
|
||||||
|
* @return Returns <tt>true</tt> if the method transaction may be read-only
|
||||||
|
*/
|
||||||
|
protected boolean isReadOnly()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes the method
|
* Executes the method, wrapping the call to {@link #executeImpl()} in an appropriate transaction
|
||||||
|
* and handling the error conditions.
|
||||||
*/
|
*/
|
||||||
public void execute() throws WebDAVServerException
|
public final void execute() throws WebDAVServerException
|
||||||
{
|
{
|
||||||
// Parse the HTTP headers
|
// Parse the HTTP headers
|
||||||
parseRequestHeaders();
|
parseRequestHeaders();
|
||||||
@@ -126,9 +137,9 @@ public abstract class WebDAVMethod
|
|||||||
// Parse the HTTP body
|
// Parse the HTTP body
|
||||||
parseRequestBody();
|
parseRequestBody();
|
||||||
|
|
||||||
TransactionWork<WebDAVServerException> executeWork = new TransactionWork<WebDAVServerException>()
|
RetryingTransactionCallback<Object> executeImplCallback = new RetryingTransactionCallback<Object>()
|
||||||
{
|
{
|
||||||
public WebDAVServerException doWork() throws Exception
|
public Object execute() throws Exception
|
||||||
{
|
{
|
||||||
executeImpl();
|
executeImpl();
|
||||||
return null;
|
return null;
|
||||||
@@ -136,9 +147,9 @@ public abstract class WebDAVMethod
|
|||||||
};
|
};
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
boolean isReadOnly = isReadOnly();
|
||||||
// Execute the method
|
// Execute the method
|
||||||
TransactionService transactionService = getTransactionService();
|
getTransactionService().getRetryingTransactionHelper().doInTransaction(executeImplCallback, isReadOnly);
|
||||||
TransactionUtil.executeInUserTransaction(transactionService, executeWork);
|
|
||||||
}
|
}
|
||||||
catch (AccessDeniedException e)
|
catch (AccessDeniedException e)
|
||||||
{
|
{
|
||||||
|
@@ -37,8 +37,6 @@ import javax.transaction.UserTransaction;
|
|||||||
|
|
||||||
import org.alfresco.filesys.server.config.ServerConfiguration;
|
import org.alfresco.filesys.server.config.ServerConfiguration;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
||||||
import org.alfresco.repo.transaction.TransactionUtil;
|
|
||||||
import org.alfresco.repo.transaction.TransactionUtil.TransactionWork;
|
|
||||||
import org.alfresco.service.ServiceRegistry;
|
import org.alfresco.service.ServiceRegistry;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeService;
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
@@ -127,16 +125,8 @@ public class WebDAVServlet extends HttpServlet
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute the WebDAV request, wrapped in a transaction
|
// Execute the WebDAV request, which must take care of its own transaction
|
||||||
TransactionWork<Object> methodWork = new TransactionWork<Object>()
|
method.execute();
|
||||||
{
|
|
||||||
public Object doWork() throws Exception
|
|
||||||
{
|
|
||||||
method.execute();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
TransactionUtil.executeInUserTransaction(m_transactionService, methodWork);
|
|
||||||
}
|
}
|
||||||
catch (Throwable e)
|
catch (Throwable e)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user