/// <inheritdoc /> public async Task <IWebDavResult> UnlockAsync(string path, LockTokenHeader stateToken, CancellationToken cancellationToken) { if (_lockManager == null) { throw new NotSupportedException(); } var releaseStatus = await _lockManager.ReleaseAsync(path, stateToken.StateToken, cancellationToken).ConfigureAwait(false); if (releaseStatus != LockReleaseStatus.Success) { var href = new Uri(_context.PublicControllerUrl, path); href = new Uri("/" + _context.PublicRootUrl.MakeRelativeUri(href).OriginalString); return(new WebDavResult <error>( WebDavStatusCode.Conflict, new error() { ItemsElementName = new[] { ItemsChoiceType.locktokenmatchesrequesturi, }, Items = new object[] { new errorNoconflictinglock() { href = new[] { href.OriginalString }, }, }, })); } return(new WebDavResult(WebDavStatusCode.NoContent)); }
/// <inheritdoc /> public Task DisposeAsync(CancellationToken cancellationToken) { if (!IsTemporaryLock) { return(Task.FromResult(0)); } // A temporary lock is always on its own var l = OwnedLocks.Single(); // Ignore errors, because the only error that may happen // is, that the lock already expired. return(_lockManager.ReleaseAsync(l.Path, new Uri(l.StateToken, UriKind.RelativeOrAbsolute), cancellationToken)); }
/// <summary> /// Disposes the lock by releasing it. /// </summary> /// <remarks>It is important to note that this operation does not block, meaning you cannot guarentee that the lock has been fully released when Dispose returns. Use <see cref="RedisLockManager.ReleaseAsync(ILockHandle)"/> instead.</remarks> public void Dispose() { _manager.ReleaseAsync(this).ConfigureAwait(false); }
/// <inheritdoc /> public async Task <IWebDavResult> LockAsync(string path, lockinfo info, CancellationToken cancellationToken) { if (_lockManager == null) { throw new NotSupportedException(); } var owner = info.owner; var recursive = (_context.RequestHeaders.Depth ?? DepthHeader.Infinity) == DepthHeader.Infinity; var accessType = LockAccessType.Write; var shareType = info.lockscope.ItemElementName == ItemChoiceType.exclusive ? LockShareMode.Exclusive : LockShareMode.Shared; var timeout = _timeoutPolicy?.SelectTimeout( _context.RequestHeaders.Timeout?.Values ?? new[] { TimeoutHeader.Infinite }) ?? TimeoutHeader.Infinite; var href = GetHref(path); var l = new Lock( path, href, recursive, owner, accessType, shareType, timeout); Debug.Assert(_lockManager != null, "_lockManager != null"); var lockResult = await _lockManager.LockAsync(l, cancellationToken); if (lockResult.ConflictingLocks != null) { // Lock cannot be acquired if (lockResult.ConflictingLocks.ChildLocks.Count == 0) { return(new WebDavResult <error>(WebDavStatusCode.Locked, CreateError(lockResult.ConflictingLocks.GetLocks()))); } var errorResponses = new List <response>(); if (lockResult.ConflictingLocks.ChildLocks.Count != 0 || lockResult.ConflictingLocks.ReferenceLocks.Count != 0) { errorResponses.Add(CreateErrorResponse( WebDavStatusCode.Forbidden, lockResult.ConflictingLocks.ChildLocks.Concat(lockResult.ConflictingLocks.ReferenceLocks))); } if (lockResult.ConflictingLocks.ParentLocks.Count != 0) { var errorResponse = CreateErrorResponse( WebDavStatusCode.Forbidden, lockResult.ConflictingLocks.ChildLocks); errorResponse.error = CreateError(new IActiveLock[0]); errorResponses.Add(errorResponse); } errorResponses.Add(new response() { href = GetHref(l.Path), ItemsElementName = new[] { ItemsChoiceType2.status, }, Items = new object[] { new Status(_context.RequestProtocol, WebDavStatusCode.FailedDependency).ToString(), }, }); var multistatus = new multistatus() { response = errorResponses.ToArray(), }; return(new WebDavResult <multistatus>(WebDavStatusCode.MultiStatus, multistatus)); } var activeLock = lockResult.Lock; Debug.Assert(activeLock != null, "activeLock != null"); try { var selectionResult = await _rootFileSystem.SelectAsync(path, cancellationToken); WebDavStatusCode statusCode; if (selectionResult.IsMissing) { if (_context.RequestHeaders.IfNoneMatch != null) { throw new WebDavException(WebDavStatusCode.PreconditionFailed); } if (selectionResult.MissingNames.Count > 1) { return(new WebDavResult(WebDavStatusCode.Conflict)); } var current = selectionResult.Collection; var docName = selectionResult.MissingNames.Single(); await current.CreateDocumentAsync(docName, cancellationToken); statusCode = WebDavStatusCode.Created; } else { await _context .RequestHeaders.ValidateAsync(selectionResult.TargetEntry, cancellationToken) ; statusCode = WebDavStatusCode.OK; } var activeLockXml = activeLock.ToXElement(); var result = new prop() { Any = new[] { new XElement(WebDavXml.Dav + "lockdiscovery", activeLockXml) }, }; var webDavResult = new WebDavResult <prop>(statusCode, result); webDavResult.Headers["Lock-Token"] = new[] { new LockTokenHeader(new Uri(activeLock.StateToken)).ToString() }; return(webDavResult); } catch { await _lockManager .ReleaseAsync(activeLock.Path, new Uri(activeLock.StateToken, UriKind.RelativeOrAbsolute), cancellationToken) ; throw; } }