diff --git a/source/java/org/alfresco/repo/webdav/LockMethod.java b/source/java/org/alfresco/repo/webdav/LockMethod.java index acc8560da4..42e54bff6c 100644 --- a/source/java/org/alfresco/repo/webdav/LockMethod.java +++ b/source/java/org/alfresco/repo/webdav/LockMethod.java @@ -368,6 +368,15 @@ public class LockMethod extends WebDAVMethod if (hasLockToken()) { lockInfo = checkNode(lockNodeInfo); + + if (!lockInfo.isLocked() && m_request.getContentLength() == -1) + { + // MNT-11990 fix, LOCK method with If header and without body was sent, according to RFC 2518 section 7.8 + // this form of LOCK MUST only be used to "refresh" a lock. But node is not actually locked. Fail this request. + // see http://www.ics.uci.edu/~ejw/authoring/protocol/rfc2518.html#rfc.section.7.8 + throw new WebDAVServerException(HttpServletResponse.SC_BAD_REQUEST); + } + // If a request body is not defined and "If" header is sent we have createExclusive as false, // but we need to check a previous LOCK was an exclusive. I.e. get the property for node. It // is already has got in a checkNode method, so we need just get a scope from lockInfo. diff --git a/source/test-java/org/alfresco/repo/webdav/LockMethodTest.java b/source/test-java/org/alfresco/repo/webdav/LockMethodTest.java index 427360cd0c..2f3142b93f 100644 --- a/source/test-java/org/alfresco/repo/webdav/LockMethodTest.java +++ b/source/test-java/org/alfresco/repo/webdav/LockMethodTest.java @@ -22,6 +22,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import java.io.Serializable; import java.util.Collections; @@ -338,4 +339,38 @@ public class LockMethodTest assertFalse("File should note exist in repo any more.", nodeService.exists(nodeRef)); assertFalse("File should note exist in trashcan.", nodeService.exists(new NodeRef(StoreRef.STORE_REF_ARCHIVE_SPACESSTORE, nodeRef.getId()))); } + + @Test + public void testMNT_11990() throws Exception + { + MockHttpServletRequest lockRequest = new MockHttpServletRequest(); + lockRequest.addHeader(WebDAV.HEADER_TIMEOUT, WebDAV.SECOND + 3600); + lockRequest.addHeader(WebDAV.HEADER_IF, "(<" + WebDAV.makeLockToken(fileNodeRef, userName) + ">)"); + lockRequest.setRequestURI("/" + TEST_FILE_NAME); + + lockMethod.setDetails(lockRequest, new MockHttpServletResponse(), davHelper, folderNodeRef); + lockMethod.parseRequestHeaders(); + lockMethod.parseRequestBody(); + + RetryingTransactionCallback lockExecuteImplCallBack = new RetryingTransactionCallback() + { + @Override + public Void execute() throws Throwable + { + try + { + lockMethod.executeImpl(); + fail("Lock should not be refreshed for non-locked file."); + } + catch (WebDAVServerException e) + { + assertEquals(e.getHttpStatusCode(), HttpServletResponse.SC_BAD_REQUEST); + } + return null; + } + }; + + // try to refresh lock for non-locked node + this.transactionService.getRetryingTransactionHelper().doInTransaction(lockExecuteImplCallBack); + } }