UNLOCK Method. @param req The Servlet request @param resp The Servlet response @throws IOException If an IO error occurs
(HttpServletRequest req, HttpServletResponse resp)
| 1831 | * @throws IOException If an IO error occurs |
| 1832 | */ |
| 1833 | protected void doUnlock(HttpServletRequest req, HttpServletResponse resp) throws IOException { |
| 1834 | |
| 1835 | if (isReadOnly()) { |
| 1836 | resp.sendError(WebdavStatus.SC_FORBIDDEN); |
| 1837 | return; |
| 1838 | } |
| 1839 | |
| 1840 | String path = getRelativePath(req); |
| 1841 | |
| 1842 | WebResource resource = resources.getResource(path); |
| 1843 | if (!checkIfHeaders(req, resp, resource)) { |
| 1844 | resp.setStatus(HttpServletResponse.SC_PRECONDITION_FAILED); |
| 1845 | return; |
| 1846 | } |
| 1847 | |
| 1848 | String lockTokenHeader = req.getHeader("Lock-Token"); |
| 1849 | if (lockTokenHeader == null) { |
| 1850 | resp.sendError(HttpServletResponse.SC_BAD_REQUEST); |
| 1851 | return; |
| 1852 | } |
| 1853 | |
| 1854 | boolean unlocked = false; |
| 1855 | String parentPath = path; |
| 1856 | do { |
| 1857 | LockInfo parentLock = resourceLocks.get(parentPath); |
| 1858 | if (parentLock != null) { |
| 1859 | if (parentLock.hasExpired()) { |
| 1860 | resourceLocks.remove(parentPath); |
| 1861 | } else { |
| 1862 | // parentPath == path is a check for the first loop |
| 1863 | if (parentPath == path || parentLock.depth > 0) { |
| 1864 | if (parentLock.isExclusive()) { |
| 1865 | if (lockTokenHeader.contains(":" + parentLock.token + ">") && |
| 1866 | (parentLock.principal == null || |
| 1867 | parentLock.principal.equals(req.getRemoteUser()))) { |
| 1868 | resourceLocks.remove(parentPath); |
| 1869 | unlocked = true; |
| 1870 | } else { |
| 1871 | // No parent exclusive lock will be found |
| 1872 | unlocked = false; |
| 1873 | } |
| 1874 | break; |
| 1875 | } else { |
| 1876 | for (String token : parentLock.sharedTokens) { |
| 1877 | if (lockTokenHeader.contains(":" + token + ">")) { |
| 1878 | LockInfo lock = sharedLocks.get(token); |
| 1879 | if (lock == null) { |
| 1880 | parentLock.sharedTokens.remove(token); |
| 1881 | } else if (lock.principal == null || lock.principal.equals(req.getRemoteUser())) { |
| 1882 | // The shared lock might not have the same depth |
| 1883 | if (parentPath == path || lock.depth > 0) { |
| 1884 | parentLock.sharedTokens.remove(token); |
| 1885 | sharedLocks.remove(token); |
| 1886 | unlocked = true; |
| 1887 | } |
| 1888 | } |
| 1889 | // Unlike the if header, this can only match one token |
| 1890 | break; |
no test coverage detected