/// <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));
        }
Esempio n. 4
0
        /// <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));
        }