/// <summary> /// Updates lock timeout information on this item. /// </summary> /// <param name="token">Lock token.</param> /// <param name="requestedTimeOut">Lock timeout which was requested by client. /// Server may ignore this parameter and set any timeout.</param> /// <returns> /// Instance of <see cref="LockResult"/> with information about the lock. /// </returns> public async Task <RefreshLockResult> RefreshLockAsync(string token, TimeSpan?requestedTimeOut) { if (string.IsNullOrEmpty(token)) { throw new DavException("Lock can not be found.", DavStatus.BAD_REQUEST); } List <DateLockInfo> locks = await GetLocksAsync(getAllWithExpired : true); DateLockInfo lockInfo = locks.SingleOrDefault(x => x.LockToken == token); if (lockInfo == null || lockInfo.Expiration <= DateTime.UtcNow) { throw new DavException("Lock can not be found.", DavStatus.CONFLICT); } else { lockInfo.TimeOut = TimeSpan.FromMinutes(5); if (requestedTimeOut.HasValue && requestedTimeOut < TimeSpan.MaxValue) { lockInfo.TimeOut = requestedTimeOut.Value; } lockInfo.Expiration = DateTime.UtcNow + lockInfo.TimeOut; await SaveLockAsync(lockInfo); } await context.socketService.NotifyRefreshAsync(GetParentPath(Path)); return(new RefreshLockResult(lockInfo.Level, lockInfo.IsDeep, lockInfo.TimeOut, lockInfo.ClientOwner)); }
/// <summary> /// Saves lock acquired on this file/folder. /// </summary> private async Task SaveLockAsync(DateLockInfo lockInfo) { List <DateLockInfo> locks = await GetLocksAsync(getAllWithExpired : true); //remove all expired locks //await RemoveExpiretLocksAsync(); //you can call this method but it will be second file operation locks.RemoveAll(x => x.Expiration <= DateTime.UtcNow); if (locks.Any(x => x.LockToken == lockInfo.LockToken)) { //update value DateLockInfo existingLock = locks.Single(x => x.LockToken == lockInfo.LockToken); existingLock.TimeOut = lockInfo.TimeOut; existingLock.Level = lockInfo.Level; existingLock.IsDeep = lockInfo.IsDeep; existingLock.LockRoot = lockInfo.LockRoot; existingLock.Expiration = lockInfo.Expiration; existingLock.ClientOwner = lockInfo.ClientOwner; } else { //add new item locks.Add(lockInfo); } await fileSystemInfo.SetExtendedAttributeAsync(locksAttributeName, locks); }
/// <summary> /// Locks this item. /// </summary> /// <param name="level">Whether lock is share or exclusive.</param> /// <param name="isDeep">Whether lock is deep.</param> /// <param name="requestedTimeOut">Lock timeout which was requested by client. /// Server may ignore this parameter and set any timeout.</param> /// <param name="owner">Owner of the lock as specified by client.</param> /// <returns> /// Instance of <see cref="LockResult"/> with information about the lock. /// </returns> public async Task <LockResult> LockAsync(LockLevel level, bool isDeep, TimeSpan?requestedTimeOut, string owner) { await RequireUnlockedAsync(level == LockLevel.Shared); string token = Guid.NewGuid().ToString(); // If timeout is absent or infinit timeout requested, // grant 5 minute lock. TimeSpan timeOut = TimeSpan.FromMinutes(5); if (requestedTimeOut.HasValue && requestedTimeOut < TimeSpan.MaxValue) { timeOut = requestedTimeOut.Value; } DateLockInfo lockInfo = new DateLockInfo { Expiration = DateTime.UtcNow + timeOut, IsDeep = false, Level = level, LockRoot = Path, LockToken = token, ClientOwner = owner, TimeOut = timeOut }; await SaveLockAsync(lockInfo); await context.socketService.NotifyRefreshAsync(GetParentPath(Path)); return(new LockResult(lockInfo.LockToken, lockInfo.TimeOut)); }
/// <summary> /// Removes lock with the specified token from this item. /// </summary> /// <param name="lockToken">Lock with this token should be removed from the item.</param> public async Task UnlockAsync(string lockToken) { if (string.IsNullOrEmpty(lockToken)) { throw new DavException("Lock can not be found.", DavStatus.BAD_REQUEST); } List <DateLockInfo> locks = await GetLocksAsync(getAllWithExpired : true); DateLockInfo lockInfo = locks.SingleOrDefault(x => x.LockToken == lockToken); await RemoveExpiredLocksAsync(lockToken); if (lockInfo == null || lockInfo.Expiration <= DateTime.UtcNow) { throw new DavException("The lock could not be found.", DavStatus.CONFLICT); } await context.socketService.NotifyRefreshAsync(GetParentPath(Path)); }