diff --git a/config/alfresco/remote-api-context.xml b/config/alfresco/remote-api-context.xml index 199585bf26..f8534e65b1 100644 --- a/config/alfresco/remote-api-context.xml +++ b/config/alfresco/remote-api-context.xml @@ -24,8 +24,8 @@ - - + + @@ -74,14 +74,8 @@ ${system.webdav.url.path.prefix} - - - - - - - - + + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/thumbnail/thumbnail.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/thumbnail/thumbnail.get.desc.xml index 3727d6adef..46a62ad01a 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/thumbnail/thumbnail.get.desc.xml +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/thumbnail/thumbnail.get.desc.xml @@ -12,6 +12,7 @@ /api/path/{store_type}/{store_id}/{id}/content{property}/thumbnails/{thumbnailname}?c={queueforcecreate?}&ph={placeholder?} /api/node/{store_type}/{store_id}/{id}/content{property}/thumbnails/{thumbnailname}/{filename}?c={queueforcecreate?}&ph={placeholder?} /api/path/{store_type}/{store_id}/{id}/content{property}/thumbnails/{thumbnailname}/{filename}?c={queueforcecreate?}&ph={placeholder?} + required argument user required diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/upload/upload.post.js b/config/alfresco/templates/webscripts/org/alfresco/repository/upload/upload.post.js index cc99b0e219..1a5a1adbc9 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/upload/upload.post.js +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/upload/upload.post.js @@ -61,10 +61,14 @@ function main() { switch (String(field.name).toLowerCase()) { + case "filename": + filename = fnFieldValue(field); + break; + case "filedata": if (field.isFile) { - filename = field.filename; + filename = filename ? filename : field.filename; content = field.content; mimetype = field.mimetype; } @@ -346,7 +350,6 @@ function main() newFile.properties.content.write(content, false, true); newFile.save(); - // TODO (THOR-175) - review // Ensure the file is versionable (autoVersion = true, autoVersionProps = false) newFile.ensureVersioningEnabled(true, false); diff --git a/config/alfresco/web-scripts-application-context.xml b/config/alfresco/web-scripts-application-context.xml index 3b76e85f92..3171be2f3c 100644 --- a/config/alfresco/web-scripts-application-context.xml +++ b/config/alfresco/web-scripts-application-context.xml @@ -244,6 +244,12 @@ + + + + + + @@ -496,6 +502,13 @@ + + + + + + @@ -747,9 +760,7 @@ - + @@ -1272,9 +1283,7 @@ - + @@ -1307,9 +1316,7 @@ - + @@ -1588,9 +1595,7 @@ - + @@ -1640,9 +1645,7 @@ - + @@ -1696,9 +1699,7 @@ - + @@ -1781,9 +1782,7 @@ - + @@ -1875,7 +1874,32 @@ - + + + + + + + + + + + + + + + + + + + + @@ -1907,10 +1931,6 @@ - - - - @@ -1928,6 +1948,10 @@ + + + + @@ -1953,34 +1977,5 @@ parent="org.alfresco.repository.download.abstract"> - - - - - - - - - - - - - - - - - - - - - diff --git a/source/java/org/alfresco/repo/web/scripts/TenantRepositoryContainer.java b/source/java/org/alfresco/repo/web/scripts/TenantRepositoryContainer.java index 0a313bb192..8a34ea5f10 100644 --- a/source/java/org/alfresco/repo/web/scripts/TenantRepositoryContainer.java +++ b/source/java/org/alfresco/repo/web/scripts/TenantRepositoryContainer.java @@ -70,11 +70,15 @@ public class TenantRepositoryContainer extends RepositoryContainer implements Te this.tenantAdminService = tenantAdminService; } + /** + * @param transactionService the transactionService to set + */ public void setTransactionService(TransactionService transactionService) { - this.transactionService = transactionService; super.setTransactionService(transactionService); + this.transactionService = transactionService; } + /* (non-Javadoc) * @see org.alfresco.web.scripts.AbstractRuntimeContainer#getRegistry() @@ -139,7 +143,7 @@ public class TenantRepositoryContainer extends RepositoryContainer implements Te * @see org.alfresco.web.scripts.AbstractRuntimeContainer#reset() */ @Override - public void reset() + public void reset() { transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback() { @@ -147,7 +151,7 @@ public class TenantRepositoryContainer extends RepositoryContainer implements Te { destroy(); init(); - + return null; } }, true, false); diff --git a/source/java/org/alfresco/repo/web/scripts/content/StreamContent.java b/source/java/org/alfresco/repo/web/scripts/content/StreamContent.java index cf99fe899b..26089ab31e 100644 --- a/source/java/org/alfresco/repo/web/scripts/content/StreamContent.java +++ b/source/java/org/alfresco/repo/web/scripts/content/StreamContent.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2013 Alfresco Software Limited. + * Copyright (C) 2005-2013 Alfresco Software Limited. * * This file is part of Alfresco * @@ -37,7 +37,7 @@ import org.alfresco.model.ContentModel; import org.alfresco.repo.content.MimetypeMap; import org.alfresco.repo.content.filestore.FileContentReader; import org.alfresco.repo.web.util.HttpRangeProcessor; -import org.alfresco.repo.webdav.WebDAVHelper; +import org.alfresco.repo.webdav.WebDAVHelper; import org.alfresco.service.cmr.repository.ContentIOException; import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentService; @@ -493,6 +493,7 @@ public class StreamContent extends AbstractWebScript implements ResourceLoaderAw { streamContent(req, res, resourcePath, attach, attachFileName, null); } + /** * Streams content back to client from a given resource path. * @@ -635,6 +636,7 @@ public class StreamContent extends AbstractWebScript implements ResourceLoaderAw { streamContent(req, res, file, modifiedTime, attach, attachFileName, null); } + /** * Streams content back to client from a given File. * @@ -858,7 +860,7 @@ public class StreamContent extends AbstractWebScript implements ResourceLoaderAw if (logger.isDebugEnabled()) logger.debug("Attaching content using filename: " + attachFileName); - headerValue += "; filename=\"" + attachFileName + "\"; filename*=UTF-8''" + WebDAVHelper.encodeURL(attachFileName); + headerValue += "; filename=\"" + attachFileName + "\"; filename*=UTF-8''" + WebDAVHelper.encodeURL(attachFileName); } // set header based on filename - will force a Save As from the browse if it doesn't recognize it diff --git a/source/java/org/alfresco/repo/web/scripts/workflow/JBPMWorkflowRestApiTest.java b/source/java/org/alfresco/repo/web/scripts/workflow/JBPMWorkflowRestApiTest.java index ab4e1ce0c4..dda5b93c75 100644 --- a/source/java/org/alfresco/repo/web/scripts/workflow/JBPMWorkflowRestApiTest.java +++ b/source/java/org/alfresco/repo/web/scripts/workflow/JBPMWorkflowRestApiTest.java @@ -118,6 +118,11 @@ public class JBPMWorkflowRestApiTest extends AbstractWorkflowRestApiTest assertTrue("Transition 'Approve' not found", found); } + public void testNothing() throws Exception + { + //NOOP + } + @Override protected String getEngine() { diff --git a/source/java/org/alfresco/repo/webdav/ExceptionHandler.java b/source/java/org/alfresco/repo/webdav/ExceptionHandler.java new file mode 100644 index 0000000000..5a4d238a80 --- /dev/null +++ b/source/java/org/alfresco/repo/webdav/ExceptionHandler.java @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2005-2012 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.repo.webdav; + +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Create a suitable HttpServletResponse when face with an exception. + * + * @author Matt Ward + */ +public class ExceptionHandler +{ + private static final Log logger = LogFactory.getLog(ExceptionHandler.class); + private Throwable e; + private final HttpServletRequest request; + private final HttpServletResponse response; + + /** + * Create an ExceptionHandler. + * + * @param e + * @param request + * @param response + */ + public ExceptionHandler(Throwable e, HttpServletRequest request, HttpServletResponse response) + { + this.e = e; + this.request = request; + this.response = response; + } + + + public void handle() throws IOException + { + if (!(e instanceof WebDAVServerException) && e.getCause() != null) + { + if (e.getCause() instanceof WebDAVServerException) + { + e = e.getCause(); + } + } + // Work out how to handle the error + if (e instanceof WebDAVServerException) + { + WebDAVServerException error = (WebDAVServerException) e; + if (error.getCause() != null) + { + logger.error("Exception thrown.", e); + } + + if (logger.isDebugEnabled()) + { + // Show what status code the method sent back + + logger.debug(request.getMethod() + " is returning status code: " + error.getHttpStatusCode()); + } + + if (response.isCommitted()) + { + logger.warn("Could not return the status code to the client as the response has already been committed!"); + } + else + { + response.sendError(error.getHttpStatusCode()); + } + } + else + { + logger.error("Exception thrown.", e); + + if (response.isCommitted()) + { + logger.warn("Could not return the internal server error code to the client as the response has already been committed!"); + } + else + { + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + } + } + } +} diff --git a/source/java/org/alfresco/repo/webdav/GetMethod.java b/source/java/org/alfresco/repo/webdav/GetMethod.java index 09e3cf7a31..cae4cae89c 100644 --- a/source/java/org/alfresco/repo/webdav/GetMethod.java +++ b/source/java/org/alfresco/repo/webdav/GetMethod.java @@ -386,8 +386,9 @@ public class GetMethod extends WebDAVMethod fileInfo = getFileFolderService().getFileInfo(fileInfo.getLinkNodeRef()); wasLink = true; } + // Get the list of child nodes for the parent node - List childNodeInfos = fileFolderService.list(fileInfo.getNodeRef()); + List childNodeInfos = getDAVHelper().getChildren(fileInfo); // Send back the start of the HTML writer.write(""); diff --git a/source/java/org/alfresco/repo/webdav/HierarchicalMethod.java b/source/java/org/alfresco/repo/webdav/HierarchicalMethod.java index 0b624dbb6c..aa507b6d36 100644 --- a/source/java/org/alfresco/repo/webdav/HierarchicalMethod.java +++ b/source/java/org/alfresco/repo/webdav/HierarchicalMethod.java @@ -18,15 +18,8 @@ */ package org.alfresco.repo.webdav; -import java.net.InetAddress; -import java.net.MalformedURLException; -import java.net.NetworkInterface; -import java.net.URL; - import javax.servlet.http.HttpServletResponse; -import org.alfresco.jlan.util.IPAddress; - /** * Abstract base class for the hierarchical methods COPY and MOVE * @@ -83,6 +76,7 @@ public abstract class HierarchicalMethod extends WebDAVMethod // Check that the URL is on this server and refers to the WebDAV // path, if not then return an error getDAVHelper().checkDestinationURL(m_request, destURL); + m_strDestinationPath = getDAVHelper().getDestinationPath(getContextPath(), getServletPath(), destURL); diff --git a/source/java/org/alfresco/repo/webdav/PropFindMethod.java b/source/java/org/alfresco/repo/webdav/PropFindMethod.java index c3eb70b908..badd1eb612 100644 --- a/source/java/org/alfresco/repo/webdav/PropFindMethod.java +++ b/source/java/org/alfresco/repo/webdav/PropFindMethod.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2013 Alfresco Software Limited. + * Copyright (C) 2005-2010 Alfresco Software Limited. * * This file is part of Alfresco * @@ -32,7 +32,6 @@ import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; import org.alfresco.repo.SessionUser; import org.alfresco.repo.webdav.auth.AuthenticationFilter; -import org.alfresco.service.cmr.model.FileFolderService; import org.alfresco.service.cmr.model.FileInfo; import org.alfresco.service.cmr.model.FileNotFoundException; import org.alfresco.service.cmr.repository.ContentData; @@ -182,9 +181,7 @@ public class PropFindMethod extends WebDAVMethod protected void executeImpl() throws WebDAVServerException, Exception { m_response.setStatus(WebDAV.WEBDAV_SC_MULTI_STATUS); - - FileFolderService fileFolderService = getFileFolderService(); - + FileInfo pathNodeInfo = null; try { @@ -268,8 +265,8 @@ public class PropFindMethod extends WebDAVMethod for (FileInfo curNodeInfo : nodeInfos) { // Get the list of child nodes for the current node - List<FileInfo> childNodeInfos = fileFolderService.list(curNodeInfo.getNodeRef()); - + List<FileInfo> childNodeInfos = getDAVHelper().getChildren(curNodeInfo); + // can skip the current node if it doesn't have children if (childNodeInfos.size() == 0) { @@ -282,7 +279,17 @@ public class PropFindMethod extends WebDAVMethod baseBuild.setLength(baseLen); try { - String pathSnippet = getDAVHelper().getPathFromNode(pathNodeInfo.getNodeRef(), curNodeInfo.getNodeRef()); + String pathSnippet = null; + if ((pathNodeInfo.getNodeRef() == null) && (curNodeInfo.getNodeRef() == null)) + { + // TODO review - note: can be null in case of Thor + pathSnippet = "/"; + } + else + { + pathSnippet = getDAVHelper().getPathFromNode(pathNodeInfo.getNodeRef(), curNodeInfo.getNodeRef()); + } + baseBuild.append(pathSnippet); } catch (FileNotFoundException e) diff --git a/source/java/org/alfresco/repo/webdav/PropPatchMethod.java b/source/java/org/alfresco/repo/webdav/PropPatchMethod.java index e3619321c7..46251fcf9d 100644 --- a/source/java/org/alfresco/repo/webdav/PropPatchMethod.java +++ b/source/java/org/alfresco/repo/webdav/PropPatchMethod.java @@ -318,7 +318,6 @@ public class PropPatchMethod extends PropFindMethod propertyAction.setResult(statusCode, statusCodeDescription); } - if (deadProperties != null) { persistDeadProperties(nodeInfo.getNodeRef(), deadProperties); diff --git a/source/java/org/alfresco/repo/webdav/PutMethod.java b/source/java/org/alfresco/repo/webdav/PutMethod.java index 75893c2397..31b96c7551 100644 --- a/source/java/org/alfresco/repo/webdav/PutMethod.java +++ b/source/java/org/alfresco/repo/webdav/PutMethod.java @@ -24,6 +24,7 @@ import javax.servlet.http.HttpServletResponse; import org.alfresco.model.ContentModel; import org.alfresco.repo.action.executer.ContentMetadataExtracter; +import org.alfresco.repo.security.permissions.AccessDeniedException; import org.alfresco.repo.transaction.RetryingTransactionHelper; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.service.cmr.action.Action; @@ -182,14 +183,14 @@ public class PutMethod extends WebDAVMethod implements ActivityPostProducer { FileInfo parentNodeInfo = getNodeForPath(getRootNodeRef(), paths[0]); // create file - contentNodeInfo = fileFolderService.create(parentNodeInfo.getNodeRef(), paths[1], ContentModel.TYPE_CONTENT); + contentNodeInfo = getDAVHelper().createFile(parentNodeInfo, paths[1]); created = true; } catch (FileNotFoundException ee) { // bad path - throw new WebDAVServerException(HttpServletResponse.SC_BAD_REQUEST); + throw new WebDAVServerException(HttpServletResponse.SC_CONFLICT); } catch (FileExistsException ee) { @@ -283,6 +284,10 @@ public class PutMethod extends WebDAVMethod implements ActivityPostProducer // Set the response status, depending if the node existed or not m_response.setStatus(created ? HttpServletResponse.SC_CREATED : HttpServletResponse.SC_NO_CONTENT); } + catch (AccessDeniedException e) + { + throw new WebDAVServerException(HttpServletResponse.SC_FORBIDDEN, e); + } catch (Throwable e) { // check if the node was marked with noContent aspect previously by lock method AND diff --git a/source/java/org/alfresco/repo/webdav/WebDAV.java b/source/java/org/alfresco/repo/webdav/WebDAV.java index 4ad5a74b43..0bfac9fae4 100644 --- a/source/java/org/alfresco/repo/webdav/WebDAV.java +++ b/source/java/org/alfresco/repo/webdav/WebDAV.java @@ -350,7 +350,7 @@ public class WebDAV } return value; } - + /** /** * Returns a context-relative path, beginning with a "/", that represents the canonical version * of the specified path after ".." and "." elements are resolved out. If the specified path diff --git a/source/java/org/alfresco/repo/webdav/WebDAVHelper.java b/source/java/org/alfresco/repo/webdav/WebDAVHelper.java index de0ce27348..58be09db0e 100644 --- a/source/java/org/alfresco/repo/webdav/WebDAVHelper.java +++ b/source/java/org/alfresco/repo/webdav/WebDAVHelper.java @@ -72,7 +72,6 @@ import org.xml.sax.helpers.AttributesImpl; public class WebDAVHelper { // Constants - public static final String BEAN_NAME = "webDAVHelper"; private static final String HTTPS_SCHEME = "https://"; @@ -85,7 +84,7 @@ public class WebDAVHelper public static final String EMPTY_SITE_ID = ""; // Logging - private static Log logger = LogFactory.getLog("org.alfresco.webdav.protocol"); + protected static Log logger = LogFactory.getLog("org.alfresco.webdav.protocol"); // Service registry TODO: eliminate this - not dependency injection! private ServiceRegistry m_serviceRegistry; @@ -553,6 +552,11 @@ public class WebDAVHelper } return sb.toString(); } + + public FileInfo createFile(FileInfo parentNodeInfo, String path) throws WebDAVServerException + { + return m_fileFolderService.create(parentNodeInfo.getNodeRef(), path, ContentModel.TYPE_CONTENT); + } public List<FileInfo> getChildren(FileInfo fileInfo) throws WebDAVServerException { @@ -775,7 +779,7 @@ public class WebDAVHelper public String determineSiteId(WebDAVMethod method) { SiteService siteService = getServiceRegistry().getSiteService(); - String siteId = null; + String siteId; try { FileInfo fileInfo = getNodeForPath(method.getRootNodeRef(), method.getPath()); diff --git a/source/java/org/alfresco/repo/webdav/WebDAVMethod.java b/source/java/org/alfresco/repo/webdav/WebDAVMethod.java index baa26f6ca9..feb69bd04f 100644 --- a/source/java/org/alfresco/repo/webdav/WebDAVMethod.java +++ b/source/java/org/alfresco/repo/webdav/WebDAVMethod.java @@ -667,7 +667,13 @@ public abstract class WebDAVMethod if (index != -1) { // TODO: implement parsing of weak ETags: W/"123..". - eTag = conditions[j].substring(index + 1, conditions[j].indexOf("]")); + int index2 = conditions[j].indexOf("]"); + if (index2 == -1) + { + logger.warn("No closing ']': "+conditions[j]); + index2 = conditions[j].length(); + } + eTag = conditions[j].substring(index + 1, index2); c.addETag(eTag, fNot); } @@ -1216,6 +1222,12 @@ public abstract class WebDAVMethod */ protected LockInfo getNodeLockInfo(final FileInfo nodeInfo) { + if (nodeInfo.getNodeRef() == null) + { + // TODO review - note: can be null in case of Thor root + return new LockInfoImpl(); + } + // perf optimisation - effectively run against unprotected nodeService (to bypass repeated permission checks) return AuthenticationUtil.runAs(new RunAsWork<LockInfo>() { @@ -1366,30 +1378,15 @@ public abstract class WebDAVMethod parentLock.getRWLock().readLock().lock(); try - { - // In this case node is locked indirectly. + { + // now check for lock status ... if (parentLock.isLocked() && WebDAV.INFINITY.equals(parentLock.getDepth())) { // In this case node is locked indirectly. - //Get lock scope - // Get shared lock tokens - - // Store lock information to the lockInfo object - - // Get lock token of the locked node - this is indirect lock token. - return parentLock; - } - return null; } - // No has no exclusive lock but can be locked with shared lock - // Check node lock depth. - // If depth is WebDAV.INFINITY then return this node's Lock token. - // In this case node is locked indirectly. - - //Get lock scope - - // Node has it's own Lock token. + return null; + } finally { parentLock.getRWLock().readLock().unlock(); diff --git a/source/java/org/alfresco/repo/webdav/WebDAVServlet.java b/source/java/org/alfresco/repo/webdav/WebDAVServlet.java index 741981ba65..50a88e02f5 100644 --- a/source/java/org/alfresco/repo/webdav/WebDAVServlet.java +++ b/source/java/org/alfresco/repo/webdav/WebDAVServlet.java @@ -1,516 +1,468 @@ -/* - * Copyright (C) 2005-2012 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see <http://www.gnu.org/licenses/>. - */ -package org.alfresco.repo.webdav; - -import java.io.IOException; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.Hashtable; -import java.util.List; - -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.UnavailableException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.transaction.UserTransaction; - -import org.alfresco.repo.cache.SimpleCache; -import org.alfresco.repo.security.authentication.AuthenticationContext; -import org.alfresco.repo.tenant.TenantService; -import org.alfresco.service.ServiceRegistry; -import org.alfresco.service.cmr.activities.ActivityService; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.cmr.repository.StoreRef; -import org.alfresco.service.cmr.search.SearchService; -import org.alfresco.service.namespace.NamespaceService; -import org.alfresco.service.transaction.TransactionService; -import org.alfresco.util.FileFilterMode; -import org.alfresco.util.FileFilterMode.Client; -import org.alfresco.util.PropertyCheck; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.web.context.WebApplicationContext; -import org.springframework.web.context.support.WebApplicationContextUtils; - -/** - * Servlet that accepts WebDAV requests for the hub. The request is served by the hub's content - * repository framework and the response sent back using the WebDAV protocol. - * - * @author gavinc - */ -public class WebDAVServlet extends HttpServlet -{ - private static final long serialVersionUID = 6900069445027527165L; - - // Logging - private static Log logger = LogFactory.getLog("org.alfresco.webdav.protocol"); - - // Constants - public static final String WEBDAV_PREFIX = "webdav"; - //private static final String INTERNAL_SERVER_ERROR = "Internal Server Error: "; - - // Init parameter names - private static final String BEAN_INIT_PARAMS = "webdav.initParams"; - - // Service registry, used by methods to find services to process requests - private ServiceRegistry serviceRegistry; - - private TransactionService transactionService; - private static TenantService tenantService; - private static NodeService nodeService; - private static SearchService searchService; - private static NamespaceService namespaceService; - - // WebDAV method handlers - protected Hashtable<String,Class<? extends WebDAVMethod>> m_davMethods; - - // note: cache is tenant-aware (if using EhCacheAdapter shared cache) - - private static SimpleCache<String, NodeRef> singletonCache; // eg. for webdavRootNodeRef - private static final String KEY_WEBDAV_ROOT_NODEREF = "key.webdavRoot.noderef"; - - private static String rootPath; - - private static NodeRef defaultRootNode; // for default domain - - // WebDAV helper class - private WebDAVHelper m_davHelper; - private ActivityPoster activityPoster; - - /** - * @see javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest, - * javax.servlet.http.HttpServletResponse) - */ - protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, - IOException - { - long startTime = 0; - if (logger.isInfoEnabled()) - { - startTime = System.currentTimeMillis(); - } - - FileFilterMode.setClient(Client.webdav); - - try - { - // Create the appropriate WebDAV method for the request and execute it - final WebDAVMethod method = createMethod(request, response); - - if (method == null) - { - if ( logger.isErrorEnabled()) - logger.error("WebDAV method not implemented - " + request.getMethod()); - - // Return an error status - - response.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED); - return; - } - else if (method.getRootNodeRef() == null) - { - if ( logger.isErrorEnabled()) - logger.error("No root node for request"); - - // Return an error status - response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - return; - } - - // Execute the WebDAV request, which must take care of its own transaction - method.execute(); - } - catch (Throwable e) - { - if (!(e instanceof WebDAVServerException) && e.getCause() != null) - { - if (e.getCause() instanceof WebDAVServerException) - { - e = e.getCause(); - } - } - // Work out how to handle the error - if (e instanceof WebDAVServerException) - { - WebDAVServerException error = (WebDAVServerException) e; - if (error.getCause() != null) - { - StringWriter writer = new StringWriter(); - PrintWriter print = new PrintWriter(writer); - error.printStackTrace(print); - logger.error(print.toString(), e); - } - - if (logger.isDebugEnabled()) - { - // Show what status code the method sent back - - logger.debug(request.getMethod() + " is returning status code: " + error.getHttpStatusCode()); - } - - if (response.isCommitted()) - { - logger.warn("Could not return the status code to the client as the response has already been committed!"); - } - else - { - response.sendError(error.getHttpStatusCode()); - } - } - else - { - StringWriter writer = new StringWriter(); - PrintWriter print = new PrintWriter(writer); - e.printStackTrace(print); - logger.error(print.toString(), e); - - if (response.isCommitted()) - { - logger.warn("Could not return the internal server error code to the client as the response has already been committed!"); - } - else - { - response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - } - } - } - finally - { - if (logger.isInfoEnabled()) - { - logger.info(request.getMethod() + " took " + (System.currentTimeMillis()-startTime) + "ms to execute ["+request.getRequestURI()+"]"); - } - - FileFilterMode.clearClient(); - } - } - - /** - * Create a WebDAV method handler - * - * @param request HttpServletRequest - * @param response HttpServletResponse - * @return WebDAVMethod - */ - protected WebDAVMethod createMethod(HttpServletRequest request, HttpServletResponse response) - { - // Get the type of the current request - - String strHttpMethod = request.getMethod(); - - if (logger.isDebugEnabled()) - logger.debug("WebDAV request " + strHttpMethod + " on path " - + request.getRequestURI()); - - Class<? extends WebDAVMethod> methodClass = m_davMethods.get(strHttpMethod); - WebDAVMethod method = null; - - if (methodClass != null) - { - try - { - // Create the handler method - method = methodClass.newInstance(); - method.setDetails(request, response, m_davHelper, getRootNodeRef()); - - // A very few WebDAV methods produce activity posts. - if (method instanceof ActivityPostProducer) - { - ActivityPostProducer activityPostProducer = (ActivityPostProducer) method; - activityPostProducer.setActivityPoster(activityPoster); - } - } - catch (Exception ex) - { - // Debug - - if ( logger.isDebugEnabled()) - logger.debug(ex); - } - } - - // Return the WebDAV method handler, or null if not supported - - return method; - } - - private static NodeRef getRootNodeRef() - { - NodeRef rootNodeRef = singletonCache.get(KEY_WEBDAV_ROOT_NODEREF); - - if (rootNodeRef == null) - { - rootNodeRef = tenantService.getRootNode(nodeService, searchService, namespaceService, rootPath, defaultRootNode); - singletonCache.put(KEY_WEBDAV_ROOT_NODEREF, rootNodeRef); - } - - return rootNodeRef; - } - - /** - * Initialize the servlet - * - * @param config ServletConfig - * @exception ServletException - */ - @SuppressWarnings("unchecked") - public void init(ServletConfig config) throws ServletException - { - super.init(config); - - // Get service registry - WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(getServletContext()); - - // If no context has been initialised, exit silently so config changes can be made - if (context == null) - { - return; - } - - // Get global configuration properties - WebApplicationContext wc = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext()); - WebDAVInitParameters initParams = (WebDAVInitParameters) wc.getBean(BEAN_INIT_PARAMS); - - // Render this servlet permanently unavailable if its enablement property is not set - if (!initParams.getEnabled()) - { - throw new UnavailableException("WebDAV not enabled."); - } - - // Get root paths - - String storeValue = initParams.getStoreName(); - - rootPath = initParams.getRootPath(); - - // Get beans - - serviceRegistry = (ServiceRegistry)context.getBean(ServiceRegistry.SERVICE_REGISTRY); - - transactionService = serviceRegistry.getTransactionService(); - tenantService = (TenantService) context.getBean("tenantService"); - - nodeService = (NodeService) context.getBean("NodeService"); - searchService = (SearchService) context.getBean("SearchService"); - namespaceService = (NamespaceService) context.getBean("NamespaceService"); - ActivityService activityService = (ActivityService) context.getBean("activityService"); - singletonCache = (SimpleCache<String, NodeRef>)context.getBean("immutableSingletonCache"); - - // Collaborator used by WebDAV methods to create activity posts. - activityPoster = new ActivityPosterImpl("WebDAV", activityService); - - // Get the WebDAV helper - m_davHelper = (WebDAVHelper) context.getBean("webDAVHelper"); - - // Initialize the root node - initializeRootNode(storeValue, rootPath, context, nodeService, searchService, namespaceService, tenantService, transactionService); - - // Create the WebDAV methods table - - m_davMethods = new Hashtable<String, Class<? extends WebDAVMethod>>(); - - m_davMethods.put(WebDAV.METHOD_PROPFIND, PropFindMethod.class); - m_davMethods.put(WebDAV.METHOD_PROPPATCH, PropPatchMethod.class); - m_davMethods.put(WebDAV.METHOD_COPY, CopyMethod.class); - m_davMethods.put(WebDAV.METHOD_DELETE, DeleteMethod.class); - m_davMethods.put(WebDAV.METHOD_GET, GetMethod.class); - m_davMethods.put(WebDAV.METHOD_HEAD, HeadMethod.class); - m_davMethods.put(WebDAV.METHOD_LOCK, LockMethod.class); - m_davMethods.put(WebDAV.METHOD_MKCOL, MkcolMethod.class); - m_davMethods.put(WebDAV.METHOD_MOVE, MoveMethod.class); - m_davMethods.put(WebDAV.METHOD_OPTIONS, OptionsMethod.class); - m_davMethods.put(WebDAV.METHOD_POST, PostMethod.class); - m_davMethods.put(WebDAV.METHOD_PUT, PutMethod.class); - m_davMethods.put(WebDAV.METHOD_UNLOCK, UnlockMethod.class); - } - - protected WebDAVHelper getDAVHelper() - { - return m_davHelper; - } - - /** - * @param storeValue - * @param rootPath - * @param context - * @param nodeService - * @param searchService - * @param namespaceService - * @param tenantService - * @param m_transactionService - */ - private void initializeRootNode(String storeValue, String rootPath, WebApplicationContext context, NodeService nodeService, SearchService searchService, - NamespaceService namespaceService, TenantService tenantService, TransactionService m_transactionService) - { - - // Use the system user as the authenticated context for the filesystem initialization - - AuthenticationContext authComponent = (AuthenticationContext) context.getBean("authenticationContext"); - authComponent.setSystemUserAsCurrentUser(); - - // Wrap the initialization in a transaction - - UserTransaction tx = m_transactionService.getUserTransaction(true); - - try - { - // Start the transaction - - if (tx != null) - tx.begin(); - - StoreRef storeRef = new StoreRef(storeValue); - - if (nodeService.exists(storeRef) == false) - { - throw new RuntimeException("No store for path: " + storeRef); - } - - NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef); - - List<NodeRef> nodeRefs = searchService.selectNodes(storeRootNodeRef, rootPath, null, namespaceService, false); - - if (nodeRefs.size() > 1) - { - throw new RuntimeException("Multiple possible children for : \n" + " path: " + rootPath + "\n" + " results: " + nodeRefs); - } - else if (nodeRefs.size() == 0) - { - throw new RuntimeException("Node is not found for : \n" + " root path: " + rootPath); - } - - defaultRootNode = nodeRefs.get(0); - - // Commit the transaction - if (tx != null) - tx.commit(); - } - catch (Exception ex) - { - logger.error(ex); - } - finally - { - // Clear the current system user - - authComponent.clearCurrentSecurityContext(); - } - } - - /** - * - * @return root node for WebDAV - */ - public static NodeRef getWebdavRootNode() - { - return getRootNodeRef(); - } - - /** - * Bean to hold injected initialization parameters. - * - * @author Derek Hulley - * @since V3.5 Team - */ - public static class WebDAVInitParameters - { - private boolean enabled = false; - private String storeName; - private String rootPath; - private String urlPathPrefix; - - public boolean getEnabled() - { - return enabled; - } - public void setEnabled(boolean enabled) - { - this.enabled = enabled; - } - /** - * @return Returns the name of the store - * @throws ServletException if the store name was not set - */ - public String getStoreName() throws ServletException - { - if (!PropertyCheck.isValidPropertyString(storeName)) - { - throw new ServletException("WebDAV missing 'storeName' value."); - } - return storeName; - } - public void setStoreName(String storeName) - { - this.storeName = storeName; - } - /** - * @return Returns the WebDAV root path within the store - * @throws ServletException if the root path was not set - */ - public String getRootPath() throws ServletException - { - if (!PropertyCheck.isValidPropertyString(rootPath)) - { - throw new ServletException("WebDAV missing 'rootPath' value."); - } - return rootPath; - } - public void setRootPath(String rootPath) - { - this.rootPath = rootPath; - } - - /** - * Get the path prefix that generated URLs should exhibit, e.g. - * <pre> - * http://server.name<prefix>/path/to/file.txt - * </pre> - * In the default set up this would be of the form /context-path/servlet-name e.g. /alfresco/webdav: - * <pre> - * http://server.name/alfresco/webdav/path/to/file.txt - * </pre> - * however if using URL rewriting rules or a reverse proxy in front of the webdav server - * you may choose to use, for example / for shorter URLs. - * <pre> - * http://server.name/path/to/file.txt - * </pre> - * <p> - * Leaving this property blank will cause the prefix used to be /context-path/servlet-name - * - * @return the urlPathPrefix - */ - public String getUrlPathPrefix() - { - return urlPathPrefix; - } - - /** - * See {@link #getUrlPathPrefix()} - * - * @param urlPathPrefix - */ - public void setUrlPathPrefix(String urlPathPrefix) - { - this.urlPathPrefix = urlPathPrefix; - } - } -} +/* + * Copyright (C) 2005-2012 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see <http://www.gnu.org/licenses/>. + */ +package org.alfresco.repo.webdav; + +import java.io.IOException; +import java.util.Hashtable; +import java.util.List; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.UnavailableException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.transaction.UserTransaction; + +import org.alfresco.repo.cache.SimpleCache; +import org.alfresco.repo.security.authentication.AuthenticationContext; +import org.alfresco.repo.tenant.TenantService; +import org.alfresco.service.ServiceRegistry; +import org.alfresco.service.cmr.activities.ActivityService; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.repository.StoreRef; +import org.alfresco.service.cmr.search.SearchService; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.transaction.TransactionService; +import org.alfresco.util.FileFilterMode; +import org.alfresco.util.FileFilterMode.Client; +import org.alfresco.util.PropertyCheck; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.context.support.WebApplicationContextUtils; + +/** + * Servlet that accepts WebDAV requests for the hub. The request is served by the hub's content + * repository framework and the response sent back using the WebDAV protocol. + * + * @author gavinc + */ +public class WebDAVServlet extends HttpServlet +{ + private static final long serialVersionUID = 6900069445027527165L; + + // Logging + private static Log logger = LogFactory.getLog("org.alfresco.webdav.protocol"); + + // Constants + public static final String WEBDAV_PREFIX = "webdav"; + //private static final String INTERNAL_SERVER_ERROR = "Internal Server Error: "; + + // Init parameter names + private static final String BEAN_INIT_PARAMS = "webdav.initParams"; + + // Service registry, used by methods to find services to process requests + private ServiceRegistry serviceRegistry; + + private TransactionService transactionService; + private static TenantService tenantService; + private static NodeService nodeService; + private static SearchService searchService; + private static NamespaceService namespaceService; + + // WebDAV method handlers + protected Hashtable<String,Class<? extends WebDAVMethod>> m_davMethods; + + // note: cache is tenant-aware (if using EhCacheAdapter shared cache) + + private static SimpleCache<String, NodeRef> singletonCache; // eg. for webdavRootNodeRef + private static final String KEY_WEBDAV_ROOT_NODEREF = "key.webdavRoot.noderef"; + + private static String rootPath; + + private static NodeRef defaultRootNode; // for default domain + + // WebDAV helper class + private WebDAVHelper m_davHelper; + private ActivityPoster activityPoster; + + /** + * @see javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest, + * javax.servlet.http.HttpServletResponse) + */ + protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, + IOException + { + long startTime = 0; + if (logger.isInfoEnabled()) + { + startTime = System.currentTimeMillis(); + } + + FileFilterMode.setClient(Client.webdav); + + try + { + // Create the appropriate WebDAV method for the request and execute it + final WebDAVMethod method = createMethod(request, response); + + if (method == null) + { + if ( logger.isErrorEnabled()) + logger.error("WebDAV method not implemented - " + request.getMethod()); + + // Return an error status + + response.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED); + return; + } + else if (method.getRootNodeRef() == null) + { + if ( logger.isErrorEnabled()) + logger.error("No root node for request"); + + // Return an error status + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + return; + } + + // Execute the WebDAV request, which must take care of its own transaction + method.execute(); + } + catch (Throwable e) + { + ExceptionHandler exHandler = new ExceptionHandler(e, request, response); + exHandler.handle(); + } + finally + { + if (logger.isInfoEnabled()) + { + logger.info(request.getMethod() + " took " + (System.currentTimeMillis()-startTime) + "ms to execute ["+request.getRequestURI()+"]"); + } + + FileFilterMode.clearClient(); + } + } + + /** + * Create a WebDAV method handler + * + * @param request HttpServletRequest + * @param response HttpServletResponse + * @return WebDAVMethod + */ + protected WebDAVMethod createMethod(HttpServletRequest request, HttpServletResponse response) + { + // Get the type of the current request + + String strHttpMethod = request.getMethod(); + + if (logger.isDebugEnabled()) + logger.debug("WebDAV request " + strHttpMethod + " on path " + + request.getRequestURI()); + + Class<? extends WebDAVMethod> methodClass = m_davMethods.get(strHttpMethod); + WebDAVMethod method = null; + + if (methodClass != null) + { + try + { + // Create the handler method + method = methodClass.newInstance(); + method.setDetails(request, response, m_davHelper, getRootNodeRef()); + + // A very few WebDAV methods produce activity posts. + if (method instanceof ActivityPostProducer) + { + ActivityPostProducer activityPostProducer = (ActivityPostProducer) method; + activityPostProducer.setActivityPoster(activityPoster); + } + } + catch (Exception ex) + { + // Debug + + if ( logger.isDebugEnabled()) + logger.debug(ex); + } + } + + // Return the WebDAV method handler, or null if not supported + + return method; + } + + private static NodeRef getRootNodeRef() + { + NodeRef rootNodeRef = singletonCache.get(KEY_WEBDAV_ROOT_NODEREF); + + if (rootNodeRef == null) + { + rootNodeRef = tenantService.getRootNode(nodeService, searchService, namespaceService, rootPath, defaultRootNode); + singletonCache.put(KEY_WEBDAV_ROOT_NODEREF, rootNodeRef); + } + + return rootNodeRef; + } + + /** + * Initialize the servlet + * + * @param config ServletConfig + * @exception ServletException + */ + @SuppressWarnings("unchecked") + public void init(ServletConfig config) throws ServletException + { + super.init(config); + + // Get service registry + WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(getServletContext()); + + // If no context has been initialised, exit silently so config changes can be made + if (context == null) + { + return; + } + + // Get global configuration properties + WebApplicationContext wc = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext()); + WebDAVInitParameters initParams = (WebDAVInitParameters) wc.getBean(BEAN_INIT_PARAMS); + + // Render this servlet permanently unavailable if its enablement property is not set + if (!initParams.getEnabled()) + { + throw new UnavailableException("WebDAV not enabled."); + } + + // Get root paths + + String storeValue = initParams.getStoreName(); + + rootPath = initParams.getRootPath(); + + // Get beans + + serviceRegistry = (ServiceRegistry)context.getBean(ServiceRegistry.SERVICE_REGISTRY); + + transactionService = serviceRegistry.getTransactionService(); + tenantService = (TenantService) context.getBean("tenantService"); + + nodeService = (NodeService) context.getBean("NodeService"); + searchService = (SearchService) context.getBean("SearchService"); + namespaceService = (NamespaceService) context.getBean("NamespaceService"); + ActivityService activityService = (ActivityService) context.getBean("activityService"); + singletonCache = (SimpleCache<String, NodeRef>)context.getBean("immutableSingletonCache"); + + + + // Collaborator used by WebDAV methods to create activity posts. + activityPoster = new ActivityPosterImpl("WebDAV", activityService); + + // Create the WebDAV helper + m_davHelper = (WebDAVHelper) context.getBean("webDAVHelper"); + + // Initialize the root node + initializeRootNode(storeValue, rootPath, context, nodeService, searchService, namespaceService, tenantService, transactionService); + + // Create the WebDAV methods table + + m_davMethods = new Hashtable<String, Class<? extends WebDAVMethod>>(); + + m_davMethods.put(WebDAV.METHOD_PROPFIND, PropFindMethod.class); + m_davMethods.put(WebDAV.METHOD_PROPPATCH, PropPatchMethod.class); + m_davMethods.put(WebDAV.METHOD_COPY, CopyMethod.class); + m_davMethods.put(WebDAV.METHOD_DELETE, DeleteMethod.class); + m_davMethods.put(WebDAV.METHOD_GET, GetMethod.class); + m_davMethods.put(WebDAV.METHOD_HEAD, HeadMethod.class); + m_davMethods.put(WebDAV.METHOD_LOCK, LockMethod.class); + m_davMethods.put(WebDAV.METHOD_MKCOL, MkcolMethod.class); + m_davMethods.put(WebDAV.METHOD_MOVE, MoveMethod.class); + m_davMethods.put(WebDAV.METHOD_OPTIONS, OptionsMethod.class); + m_davMethods.put(WebDAV.METHOD_POST, PostMethod.class); + m_davMethods.put(WebDAV.METHOD_PUT, PutMethod.class); + m_davMethods.put(WebDAV.METHOD_UNLOCK, UnlockMethod.class); + } + + protected WebDAVHelper getDAVHelper() + { + return m_davHelper; + } + + + /** + * @param storeValue + * @param rootPath + * @param context + * @param nodeService + * @param searchService + * @param namespaceService + * @param tenantService + * @param m_transactionService + */ + private void initializeRootNode(String storeValue, String rootPath, WebApplicationContext context, NodeService nodeService, SearchService searchService, + NamespaceService namespaceService, TenantService tenantService, TransactionService m_transactionService) + { + + // Use the system user as the authenticated context for the filesystem initialization + + AuthenticationContext authComponent = (AuthenticationContext) context.getBean("authenticationContext"); + authComponent.setSystemUserAsCurrentUser(); + + // Wrap the initialization in a transaction + + UserTransaction tx = m_transactionService.getUserTransaction(true); + + try + { + // Start the transaction + + if (tx != null) + tx.begin(); + + StoreRef storeRef = new StoreRef(storeValue); + + if (nodeService.exists(storeRef) == false) + { + throw new RuntimeException("No store for path: " + storeRef); + } + + NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef); + + List<NodeRef> nodeRefs = searchService.selectNodes(storeRootNodeRef, rootPath, null, namespaceService, false); + + if (nodeRefs.size() > 1) + { + throw new RuntimeException("Multiple possible children for : \n" + " path: " + rootPath + "\n" + " results: " + nodeRefs); + } + else if (nodeRefs.size() == 0) + { + throw new RuntimeException("Node is not found for : \n" + " root path: " + rootPath); + } + + defaultRootNode = nodeRefs.get(0); + + // Commit the transaction + if (tx != null) + tx.commit(); + } + catch (Exception ex) + { + logger.error(ex); + } + finally + { + // Clear the current system user + + authComponent.clearCurrentSecurityContext(); + } + } + + /** + * + * @return root node for WebDAV + */ + public static NodeRef getWebdavRootNode() + { + return getRootNodeRef(); + } + + /** + * Bean to hold injected initialization parameters. + * + * @author Derek Hulley + * @since V3.5 Team + */ + public static class WebDAVInitParameters + { + private boolean enabled = false; + private String storeName; + private String rootPath; + private String urlPathPrefix; + + public boolean getEnabled() + { + return enabled; + } + public void setEnabled(boolean enabled) + { + this.enabled = enabled; + } + /** + * @return Returns the name of the store + * @throws ServletException if the store name was not set + */ + public String getStoreName() throws ServletException + { + if (!PropertyCheck.isValidPropertyString(storeName)) + { + throw new ServletException("WebDAV missing 'storeName' value."); + } + return storeName; + } + public void setStoreName(String storeName) + { + this.storeName = storeName; + } + /** + * @return Returns the WebDAV root path within the store + * @throws ServletException if the root path was not set + */ + public String getRootPath() throws ServletException + { + if (!PropertyCheck.isValidPropertyString(rootPath)) + { + throw new ServletException("WebDAV missing 'rootPath' value."); + } + return rootPath; + } + public void setRootPath(String rootPath) + { + this.rootPath = rootPath; + } + + /** + * Get the path prefix that generated URLs should exhibit, e.g. + * <pre> + * http://server.name<prefix>/path/to/file.txt + * </pre> + * In the default set up this would be of the form /context-path/servlet-name e.g. /alfresco/webdav: + * <pre> + * http://server.name/alfresco/webdav/path/to/file.txt + * </pre> + * however if using URL rewriting rules or a reverse proxy in front of the webdav server + * you may choose to use, for example / for shorter URLs. + * <pre> + * http://server.name/path/to/file.txt + * </pre> + * <p> + * Leaving this property blank will cause the prefix used to be /context-path/servlet-name + * + * @return the urlPathPrefix + */ + public String getUrlPathPrefix() + { + return urlPathPrefix; + } + + /** + * See {@link #getUrlPathPrefix()} + * + * @param urlPathPrefix + */ + public void setUrlPathPrefix(String urlPathPrefix) + { + this.urlPathPrefix = urlPathPrefix; + } + } +} diff --git a/source/java/org/alfresco/repo/webdav/auth/BaseAuthenticationFilter.java b/source/java/org/alfresco/repo/webdav/auth/BaseAuthenticationFilter.java index 349e535dfd..2f22f80255 100644 --- a/source/java/org/alfresco/repo/webdav/auth/BaseAuthenticationFilter.java +++ b/source/java/org/alfresco/repo/webdav/auth/BaseAuthenticationFilter.java @@ -215,7 +215,6 @@ public abstract class BaseAuthenticationFilter SessionUser sessionUser = (SessionUser) session.getAttribute(sessionAttrib); if (sessionUser != null) { - String ticket = sessionUser.getTicket(); try { if (getLogger().isDebugEnabled())