public void UIT_WebDavClient_LockAndPutWithToken() { var client = CreateWebDavClientWithDebugHttpMessageHandler(); // Lock. var lockInfo = new LockInfo(); lockInfo.LockScope = LockScope.CreateExclusiveLockScope(); lockInfo.LockType = LockType.CreateWriteLockType(); lockInfo.OwnerHref = "*****@*****.**"; var response = client.LockAsync(this.webDavRootFolder, WebDavTimeoutHeaderValue.CreateWebDavTimeout(TimeSpan.FromSeconds(15)), WebDavDepthHeaderValue.Infinity, lockInfo).Result; var lockResponseSuccess = response.IsSuccessStatusCode; LockToken lockToken = WebDavHelper.GetLockTokenFromWebDavResponseMessage(response); // Put file. var content = new StreamContent(File.OpenRead(TestFile)); var requestUrl = UriHelper.CombineUrl(this.webDavRootFolder, TestFile, true); response = client.PutAsync(requestUrl, content, lockToken).Result; var putResponseSuccess = response.IsSuccessStatusCode; // Delete file. response = client.DeleteAsync(requestUrl, lockToken).Result; var deleteResponseSuccess = response.IsSuccessStatusCode; // Unlock. response = client.UnlockAsync(this.webDavRootFolder, lockToken).Result; var unlockResponseSuccess = response.IsSuccessStatusCode; Assert.IsTrue(lockResponseSuccess); Assert.IsNotNull(lockToken); Assert.IsTrue(putResponseSuccess); Assert.IsTrue(deleteResponseSuccess); Assert.IsTrue(unlockResponseSuccess); }
public void UIT_WebDavClient_LockRefreshLockUnlock() { var client = CreateWebDavClientWithDebugHttpMessageHandler(); // Lock. var lockInfo = new LockInfo(); lockInfo.LockScope = LockScope.CreateExclusiveLockScope(); lockInfo.LockType = LockType.CreateWriteLockType(); lockInfo.OwnerHref = "*****@*****.**"; var response = client.LockAsync(this.webDavRootFolder, WebDavTimeoutHeaderValue.CreateWebDavTimeout(TimeSpan.FromSeconds(15)), WebDavDepthHeaderValue.Infinity, lockInfo).Result; var lockResponseSuccess = response.IsSuccessStatusCode; LockToken lockToken = WebDavHelper.GetLockTokenFromWebDavResponseMessage(response); // Refresh lock. response = client.RefreshLockAsync(this.webDavRootFolder, WebDavTimeoutHeaderValue.CreateWebDavTimeout(TimeSpan.FromSeconds(10)), lockToken).Result; var refreshLockResponseSuccess = response.IsSuccessStatusCode; // Unlock. response = client.UnlockAsync(this.webDavRootFolder, lockToken).Result; var unlockResponseSuccess = response.IsSuccessStatusCode; Assert.IsTrue(lockResponseSuccess); Assert.IsNotNull(lockToken); Assert.IsTrue(refreshLockResponseSuccess); Assert.IsTrue(unlockResponseSuccess); }
// Methods public SortableInMemoryIndexSearchContext(ILuceneIndex index) { Assert.ArgumentNotNull(index, "index"); var idx = new RAMDirectory(index.Directory); this._scope = new LockScope(idx); this._writer = index.CreateWriter(false); }
public async Task <IDisposable> Lock(object token) { var scope = new LockScope(this, token); LockScope waitScope; lock (_sync) { LockScope tail; // if there is no currently executing tasks create new scope and set is as currently executing task // we will immediately return current scope, because we do not have to wait anyone if (!_tails.TryGetValue(token, out tail)) { _tails[token] = scope; return(scope); } // else we will wait for last executed task to complete waitScope = tail; _tails[token] = scope; } // and wait for that task await waitScope.Task; return(scope); }
public async Task <IDisposable> TryAcquireAsync(int timeoutMillis, SqlApplicationLock.Mode mode, CancellationToken cancellationToken, IDisposable contextHandle) { if (contextHandle != null) { return(await this.CreateContextLock(contextHandle).TryAcquireAsync(timeoutMillis, mode, cancellationToken, contextHandle: null).ConfigureAwait(false)); } IDisposable result = null; var connection = new SqlConnection(this.connectionString); try { await connection.OpenAsync(cancellationToken).ConfigureAwait(false); if (await SqlApplicationLock.ExecuteAcquireCommandAsync(connection, this.lockName, timeoutMillis, mode, cancellationToken).ConfigureAwait(false)) { result = new LockScope(connection, this.lockName); } } finally { // if we fail to acquire or throw, make sure to clean up the connection if (result == null) { connection.Dispose(); } } return(result); }
public async Task AddLockToRootRecursiveWithPrincipalOwnerTest() { var response = await Client.LockAsync( "/", WebDavTimeoutHeaderValue.CreateInfiniteWebDavTimeout(), WebDavDepthHeaderValue.Infinity, new LockInfo() { LockScope = LockScope.CreateExclusiveLockScope(), LockType = LockType.CreateWriteLockType(), OwnerRaw = new XElement("{DAV:}owner", "principal"), }) ; var prop = await WebDavResponseContentParser.ParsePropResponseContentAsync(response.EnsureSuccessStatusCode().Content); Assert.Collection( prop.LockDiscovery.ActiveLock, activeLock => { Assert.Equal("/", activeLock.LockRoot.Href); Assert.Equal(WebDavDepthHeaderValue.Infinity.ToString(), activeLock.Depth, StringComparer.OrdinalIgnoreCase); Assert.IsType <Exclusive>(activeLock.LockScope.Item); Assert.Equal("<owner xmlns=\"DAV:\">principal</owner>", activeLock.OwnerRaw.ToString(SaveOptions.DisableFormatting)); Assert.Equal(WebDavTimeoutHeaderValue.CreateInfiniteWebDavTimeout().ToString(), activeLock.Timeout, StringComparer.OrdinalIgnoreCase); Assert.NotNull(activeLock.LockToken?.Href); Assert.True(Uri.IsWellFormedUriString(activeLock.LockToken.Href, UriKind.RelativeOrAbsolute)); }); }
public IDisposable?TryAcquire <TLockCookie>(int timeoutMillis, ISqlSynchronizationStrategy <TLockCookie> strategy, IDisposable?contextHandle) where TLockCookie : class { if (contextHandle != null) { return(this.CreateContextLock <TLockCookie>(contextHandle).TryAcquire(timeoutMillis, strategy, contextHandle: null)); } IDisposable?result = null; var connection = SqlHelpers.CreateConnection(this.connectionString); try { connection.Open(); var lockCookie = strategy.TryAcquire(connection, this.lockName, timeoutMillis); if (lockCookie != null) { result = new LockScope <TLockCookie>(connection, strategy, this.lockName, lockCookie); } } finally { // if we fail to acquire or throw, make sure to clean up the connection if (result == null) { connection.Dispose(); } } return(result); }
public IDisposable TryAcquire(int timeoutMillis, SqlApplicationLock.Mode mode, IDisposable contextHandle) { if (contextHandle != null) { return(this.CreateContextLock(contextHandle).TryAcquire(timeoutMillis, mode, contextHandle: null)); } IDisposable result = null; var connection = new SqlConnection(this.connectionString); SqlTransaction transaction = null; try { connection.Open(); // when creating a transaction, the isolation level doesn't matter, since we're using sp_getapplock transaction = connection.BeginTransaction(); if (SqlApplicationLock.ExecuteAcquireCommand(transaction, this.lockName, timeoutMillis, mode)) { result = new LockScope(transaction); } } finally { // if we fail to acquire or throw, make sure to clean up if (result == null) { transaction?.Dispose(); connection.Dispose(); } } return(result); }
public IDisposable TryAcquire(int timeoutMillis, SqlApplicationLock.Mode mode, IDisposable contextHandle) { if (contextHandle != null) { return(this.CreateContextLock(contextHandle).TryAcquire(timeoutMillis, mode, contextHandle: null)); } IDisposable result = null; var connection = new SqlConnection(this.connectionString); try { connection.Open(); if (SqlApplicationLock.ExecuteAcquireCommand(connection, this.lockName, timeoutMillis, mode)) { result = new LockScope(connection, this.lockName); } } finally { // if we fail to acquire or throw, make sure to clean up the connection if (result == null) { connection.Dispose(); } } return(result); }
public async Task <IDisposable> TryAcquireAsync(int timeoutMillis, SqlApplicationLock.Mode mode, CancellationToken cancellationToken, IDisposable contextHandle = null) { if (contextHandle != null) { return(await this.CreateContextLock(contextHandle).TryAcquireAsync(timeoutMillis, mode, cancellationToken, contextHandle: null).ConfigureAwait(false)); } IDisposable result = null; var connection = new SqlConnection(this.connectionString); SqlTransaction transaction = null; try { await connection.OpenAsync(cancellationToken).ConfigureAwait(false); // when creating a transaction, the isolation level doesn't matter, since we're using sp_getapplock transaction = connection.BeginTransaction(); if (await SqlApplicationLock.ExecuteAcquireCommandAsync(transaction, this.lockName, timeoutMillis, mode, cancellationToken).ConfigureAwait(false)) { result = new LockScope(transaction); } } finally { // if we fail to acquire or throw, make sure to clean up if (result == null) { transaction?.Dispose(); connection.Dispose(); } } return(result); }
public async Task UT_WebDavClient_LockRootFolder() { var lockRequestContent = "<?xml version=\"1.0\" encoding=\"utf-8\"?><D:lockinfo xmlns:D=\"DAV:\"><D:lockscope><D:exclusive /></D:lockscope><D:locktype><D:write /></D:locktype><D:owner><D:href>[email protected]</D:href></D:owner></D:lockinfo>"; var lockResponseContent = "<?xml version=\"1.0\" encoding=\"utf-8\"?><D:prop xmlns:D=\"DAV:\"><D:lockdiscovery><D:activelock><D:locktype><D:write/></D:locktype><D:lockscope><D:exclusive/></D:lockscope><D:depth>infinity</D:depth><D:owner><D:href>[email protected]</D:href></D:owner><D:timeout>Second-60</D:timeout><D:locktoken><D:href>opaquelocktoken:a2324814-cbe3-4fb4-9c55-cba99a62ef5d.008f01d2b2dafba0</D:href></D:locktoken><D:lockroot><D:href>http://127.0.0.1/webdav/</D:href></D:lockroot></D:activelock></D:lockdiscovery></D:prop>"; var oneMinuteTimeout = WebDavTimeoutHeaderValue.CreateWebDavTimeout(TimeSpan.FromMinutes(1)); var depth = WebDavDepthHeaderValue.Infinity; var lockInfo = new LockInfo() { LockScope = LockScope.CreateExclusiveLockScope(), LockType = LockType.CreateWriteLockType(), OwnerHref = "*****@*****.**" }; var mockHandler = new MockHttpMessageHandler(); var requestHeaders = new List <KeyValuePair <string, string> > { new KeyValuePair <string, string>(WebDavConstants.Depth, depth.ToString()), new KeyValuePair <string, string>(WebDavRequestHeader.Timeout, oneMinuteTimeout.ToString()) }; mockHandler.When(WebDavMethod.Lock, WebDavRootFolder).WithHeaders(requestHeaders).WithContent(lockRequestContent).Respond(HttpStatusCode.OK, new StringContent(lockResponseContent)); using (var client = CreateWebDavClient(mockHandler)) { var response = await client.LockAsync(WebDavRootFolder, oneMinuteTimeout, depth, lockInfo); Assert.IsTrue(response.IsSuccessStatusCode); } }
public async Task <IDisposable?> TryAcquireAsync <TLockCookie>(int timeoutMillis, ISqlSynchronizationStrategy <TLockCookie> strategy, CancellationToken cancellationToken, IDisposable?contextHandle) where TLockCookie : class { if (contextHandle != null) { return(await this.CreateContextLock <TLockCookie>(contextHandle).TryAcquireAsync(timeoutMillis, strategy, cancellationToken, contextHandle: null).ConfigureAwait(false)); } IDisposable?result = null; var connection = SqlHelpers.CreateConnection(this.connectionString); try { await connection.OpenAsync(cancellationToken).ConfigureAwait(false); var lockCookie = await strategy.TryAcquireAsync(connection, this.lockName, timeoutMillis, cancellationToken).ConfigureAwait(false); if (lockCookie != null) { result = new LockScope <TLockCookie>(connection, strategy, this.lockName, lockCookie); } } finally { // if we fail to acquire or throw, make sure to clean up the connection if (result == null) { connection.Dispose(); } } return(result); }
public async Task GetSucceedsAccessToLockedDocumentTest() { var response = await Client.LockAsync( "/test1.txt", WebDavTimeoutHeaderValue.CreateInfiniteWebDavTimeout(), WebDavDepthHeaderValue.Zero, new LockInfo() { LockScope = LockScope.CreateExclusiveLockScope(), LockType = LockType.CreateWriteLockType(), }).ConfigureAwait(false); var prop = await WebDavResponseContentParser.ParsePropResponseContentAsync(response.EnsureSuccessStatusCode().Content).ConfigureAwait(false); Assert.NotNull(prop.LockDiscovery); Assert.Collection( prop.LockDiscovery.ActiveLock, activeLock => { Assert.Equal("/test1.txt", activeLock.LockRoot.Href); Assert.Equal(WebDavDepthHeaderValue.Zero.ToString(), activeLock.Depth, StringComparer.OrdinalIgnoreCase); Assert.IsType <Exclusive>(activeLock.LockScope.Item); Assert.Null(activeLock.OwnerRaw); Assert.Equal(WebDavTimeoutHeaderValue.CreateInfiniteWebDavTimeout().ToString(), activeLock.Timeout, StringComparer.OrdinalIgnoreCase); Assert.NotNull(activeLock.LockToken?.Href); Assert.True(Uri.IsWellFormedUriString(activeLock.LockToken.Href, UriKind.RelativeOrAbsolute)); }); var ct = CancellationToken.None; var getResponse = await Client.GetAsync("/test1.txt", ct).ConfigureAwait(false); getResponse.EnsureSuccessStatusCode(); }
public async Task AddLockToRootRecursiveWithTimeoutTest() { var response = await Client.LockAsync( "/", WebDavTimeoutHeaderValue.CreateWebDavTimeout(TimeSpan.FromSeconds(1)), WebDavDepthHeaderValue.Infinity, new LockInfo() { LockScope = LockScope.CreateExclusiveLockScope(), LockType = LockType.CreateWriteLockType(), }); var prop = await WebDavResponseContentParser.ParsePropResponseContentAsync(response.EnsureSuccessStatusCode().Content); Assert.Collection( prop.LockDiscovery.ActiveLock, activeLock => { Assert.Equal("/", activeLock.LockRoot.Href); Assert.Equal(WebDavDepthHeaderValue.Infinity.ToString(), activeLock.Depth, StringComparer.OrdinalIgnoreCase); Assert.IsType <Exclusive>(activeLock.LockScope.Item); Assert.Null(activeLock.OwnerRaw); Assert.Equal(WebDavTimeoutHeaderValue.CreateWebDavTimeout(TimeSpan.FromSeconds(1)).ToString(), activeLock.Timeout, StringComparer.OrdinalIgnoreCase); Assert.NotNull(activeLock.LockToken?.Href); Assert.True(Uri.IsWellFormedUriString(activeLock.LockToken.Href, UriKind.RelativeOrAbsolute)); }); }
public async Task AddLockToRootAndTryRefreshTest() { var lockResponse = await Client.LockAsync( "/", WebDavTimeoutHeaderValue.CreateInfiniteWebDavTimeout(), WebDavDepthHeaderValue.Infinity, new LockInfo() { LockScope = LockScope.CreateExclusiveLockScope(), LockType = LockType.CreateWriteLockType(), }) ; lockResponse.EnsureSuccessStatusCode(); var prop = await WebDavResponseContentParser.ParsePropResponseContentAsync(lockResponse.Content); var lockToken = prop.LockDiscovery.ActiveLock.Single().LockToken; Assert.True(AbsoluteUri.TryParse(lockToken.Href, out var lockTokenUri)); var refreshResponse = await Client.RefreshLockAsync( "/", WebDavTimeoutHeaderValue.CreateInfiniteWebDavTimeout(), new LockToken(lockTokenUri)); refreshResponse.EnsureSuccessStatusCode(); var refreshProp = await WebDavResponseContentParser.ParsePropResponseContentAsync(refreshResponse.Content); Assert.NotNull(refreshProp.LockDiscovery); }
public IDisposable TryAcquire <TLockCookie>(int timeoutMillis, ISqlSynchronizationStrategy <TLockCookie> strategy, IDisposable contextHandle) where TLockCookie : class { if (contextHandle != null) { return(this.CreateContextLock(contextHandle).TryAcquire(timeoutMillis, strategy, contextHandle: null)); } IDisposable result = null; var connection = new SqlConnection(this.connectionString); SqlTransaction transaction = null; try { connection.Open(); // when creating a transaction, the isolation level doesn't matter, since we're using sp_getapplock transaction = connection.BeginTransaction(); var lockCookie = strategy.TryAcquire(transaction, this.lockName, timeoutMillis); if (lockCookie != null) { result = new LockScope(transaction); } } finally { // if we fail to acquire or throw, make sure to clean up if (result == null) { transaction?.Dispose(); connection.Dispose(); } } return(result); }
public async Task AddLockToRootAndQueryLockDiscoveryTest() { var lockResponse = await Client.LockAsync( "/", WebDavTimeoutHeaderValue.CreateInfiniteWebDavTimeout(), WebDavDepthHeaderValue.Infinity, new LockInfo() { LockScope = LockScope.CreateExclusiveLockScope(), LockType = LockType.CreateWriteLockType(), }) ; lockResponse.EnsureSuccessStatusCode(); var propFindResponse = await Client.PropFindAsync( "/", WebDavDepthHeaderValue.Zero, new PropFind() { Item = new Prop() { LockDiscovery = new LockDiscovery(), }, }); Assert.Equal(WebDavStatusCode.MultiStatus, propFindResponse.StatusCode); var multiStatus = await WebDavResponseContentParser.ParseMultistatusResponseContentAsync(propFindResponse.Content); Assert.Collection( multiStatus.Response, response => { Assert.Equal("/", response.Href); Assert.Collection( response.ItemsElementName, n => Assert.Equal(ItemsChoiceType.propstat, n)); Assert.Collection( response.Items, item => { var propStat = Assert.IsType <Propstat>(item); var status = WebDav.Server.Model.Status.Parse(propStat.Status); Assert.Equal(200, status.StatusCode); Assert.NotNull(propStat.Prop?.LockDiscovery?.ActiveLock); Assert.Collection( propStat.Prop.LockDiscovery.ActiveLock, activeLock => { Assert.Equal("/", activeLock.LockRoot.Href); Assert.Equal(WebDavDepthHeaderValue.Infinity.ToString(), activeLock.Depth, StringComparer.OrdinalIgnoreCase); Assert.IsType <Exclusive>(activeLock.LockScope.Item); Assert.Null(activeLock.OwnerRaw); Assert.Equal(WebDavTimeoutHeaderValue.CreateInfiniteWebDavTimeout().ToString(), activeLock.Timeout, StringComparer.OrdinalIgnoreCase); Assert.NotNull(activeLock.LockToken?.Href); Assert.True(Uri.IsWellFormedUriString(activeLock.LockToken.Href, UriKind.RelativeOrAbsolute)); }); }); }); }
public LockResult Lock(IStoreItem item, LockType lockType, LockScope lockScope, XElement owner, WebDavUri lockRootUri, bool recursiveLock, IEnumerable <int> timeouts) { var timeout = timeouts.Cast <int?>().FirstOrDefault(); var itemLockInfo = new ItemLockInfo(item, lockType, lockScope, lockRootUri, recursiveLock, owner, timeout ?? -1); return(new LockResult(DavStatusCode.Ok, GetActiveLockInfo(itemLockInfo))); }
internal LockInfo(String path, LockType lockType, LockScope lockScope, int depth, String owner, String lockToken) { Path = path; LockType = lockType; LockScope = lockScope; Depth = depth; Owner = owner; LockToken = lockToken; }
public ActiveLock(LockType type, LockScope scope, int depth, XElement owner, int timeout, WebDavUri lockToken, WebDavUri lockRoot) { Type = type; Scope = scope; Depth = depth; Owner = owner; Timeout = timeout; LockToken = lockToken; LockRoot = lockRoot; }
public static object Lock(IHierarchyItem item, LockScope scope, string owner) { try { return(item.Lock(scope, false, owner, TimeSpan.MaxValue)); } catch (Exception e) { return(e.InnerException ?? e); } }
public async Task <IDisposable> TryAcquireAsync <TLockCookie>(int timeoutMillis, ISqlSynchronizationStrategy <TLockCookie> strategy, CancellationToken cancellationToken, IDisposable contextHandle) where TLockCookie : class { if (contextHandle != null) { cancellationToken.ThrowIfCancellationRequested(); // if already canceled, exit immediately // if we are taking a nested lock, we don't want to start another keepalive on the same connection. // However, we do need to stop our current keepalive while we take the nested lock to avoid threading issues var lockScope = (LockScope)contextHandle; await lockScope.Keepalive.StopAsync().ConfigureAwait(false); try { var internalHandle = await lockScope.InternalLock.TryAcquireAsync(timeoutMillis, strategy, cancellationToken, contextHandle : lockScope.InternalHandle).ConfigureAwait(false); return(internalHandle != null ? new LockScope(internalHandle, lockScope.InternalLock, lockScope.Keepalive, connection: null) : null); } finally { // always restart, even if the acquisition fails lockScope.Keepalive.Start(); } } var connection = new SqlConnection(this.connectionString); LockScope result = null; try { await connection.OpenAsync(cancellationToken).ConfigureAwait(false); var internalLock = new ExternalConnectionOrTransactionSqlDistributedLock(this.lockName, connection); var internalHandle = await internalLock.TryAcquireAsync(timeoutMillis, strategy, cancellationToken, contextHandle : null).ConfigureAwait(false); if (internalHandle != null) { var keepalive = new KeepaliveHelper(connection); keepalive.Start(); result = new LockScope(internalHandle, internalLock, keepalive, connection); } } finally { if (result == null) { connection.Dispose(); } } return(result); }
private void Release(LockScope lockScope) { lock (_sync) { // we are the last task in the queue. LockScope tail; if (_tails.TryGetValue(lockScope.Token, out tail) && tail == lockScope) { _tails.Remove(lockScope.Token); } } }
public async Task UIT_WebDavClient_LockAndPutWithToken() { // This won't work on ownCloud/Nextcloud because they do not support WebDAV locking. // These unit integration test are skipped for ownCloud/Nextcloud. if (webDavRootFolder.Contains("nextcloud") || webDavRootFolder.Contains("owncloud")) { return; } using (var client = CreateWebDavClientWithDebugHttpMessageHandler()) { // Lock. var lockInfo = new LockInfo() { LockScope = LockScope.CreateExclusiveLockScope(), LockType = LockType.CreateWriteLockType(), OwnerHref = "*****@*****.**" }; var response = await client.LockAsync(webDavRootFolder, WebDavTimeoutHeaderValue.CreateWebDavTimeout(TimeSpan.FromSeconds(15)), WebDavDepthHeaderValue.Infinity, lockInfo); var lockResponseSuccess = response.IsSuccessStatusCode; LockToken lockToken = await WebDavHelper.GetLockTokenFromWebDavResponseMessage(response); var requestUrl = UriHelper.CombineUrl(webDavRootFolder, TestFile, true); // Put file. using (var fileStream = File.OpenRead(TestFile)) { var content = new StreamContent(fileStream); response = await client.PutAsync(requestUrl, content, lockToken); } var putResponseSuccess = response.IsSuccessStatusCode; // Delete file. response = await client.DeleteAsync(requestUrl, lockToken); var deleteResponseSuccess = response.IsSuccessStatusCode; // Unlock. response = await client.UnlockAsync(webDavRootFolder, lockToken); var unlockResponseSuccess = response.IsSuccessStatusCode; Assert.IsTrue(lockResponseSuccess); Assert.IsNotNull(lockToken); Assert.IsTrue(putResponseSuccess); Assert.IsTrue(deleteResponseSuccess); Assert.IsTrue(unlockResponseSuccess); } }
/// <summary> /// Locks a file or directory at the URL specified. /// </summary> /// <param name="uri">The URI of the file or directory to lock.</param> /// <returns>The <see cref="Task"/> representing the asynchronous operation.</returns> public async Task <bool> LockAsync(Uri uri) { uri = UriHelper.GetCombinedUriWithTrailingSlash(this.BaseUri, uri, true, false); if (this.permanentLocks.ContainsKey(uri)) { return(true); // Lock already set. } var lockInfo = new LockInfo(); lockInfo.LockScope = LockScope.CreateExclusiveLockScope(); lockInfo.LockType = LockType.CreateWriteLockType(); var response = await this.webDavClient.LockAsync(uri, WebDavTimeoutHeaderValue.CreateInfiniteWebDavTimeout(), WebDavDepthHeaderValue.Infinity, lockInfo); if (!response.IsSuccessStatusCode) { return(false); // Lock already exists. } var lockToken = WebDavHelper.GetLockTokenFromWebDavResponseMessage(response); var prop = await WebDavResponseContentParser.ParsePropResponseContentAsync(response.Content); var lockDiscovery = prop.LockDiscovery; if (lockDiscovery == null) { return(false); } var url = uri.ToString(); var lockGranted = lockDiscovery.ActiveLock.FirstOrDefault(x => url.EndsWith(UriHelper.AddTrailingSlash(x.LockRoot.Href, false), StringComparison.OrdinalIgnoreCase)); if (lockGranted == null) { // Try with file expected. lockGranted = lockDiscovery.ActiveLock.FirstOrDefault(x => url.EndsWith(UriHelper.AddTrailingSlash(x.LockRoot.Href, true), StringComparison.OrdinalIgnoreCase)); } if (lockGranted == null) { return(false); } var permanentLock = new PermanentLock(this.webDavClient, lockToken, uri, lockGranted.Timeout); if (!this.permanentLocks.TryAdd(uri, permanentLock)) { throw new WebDavException("Lock with lock root " + uri.ToString() + " already exists."); } return(response.IsSuccessStatusCode); }
public ItemLockInfo(IStoreItem item, LockType lockType, LockScope lockScope, WebDavUri lockRootUri, bool recursive, XElement owner, int timeout) { Token = Guid.NewGuid(); Item = item; Type = lockType; Scope = lockScope; LockRootUri = lockRootUri; Recursive = recursive; Owner = owner; Timeout = timeout; RefreshExpiration(timeout); }
public async Task AsyncLock_TryAcquireAsync_Out_WithGcCollect_Test() { LockScope scope = await GetLockScope().ConfigureAwait(false); CollectGC(); scope.Dispose(); Task <LockScope> GetLockScope() { var locker = new AsyncLock(TimeSpan.FromMilliseconds(200)); return(locker.TryAcquireAsync(TimeSpan.FromSeconds(5))); // locker can be disposed if not held } }
public IDisposable TryAcquire <TLockCookie>(int timeoutMillis, ISqlSynchronizationStrategy <TLockCookie> strategy, IDisposable contextHandle) where TLockCookie : class { if (contextHandle != null) { // if we are taking a nested lock, we don't want to start another keepalive on the same connection. // However, we do need to stop our current keepalive while we take the nested lock to avoid threading issues var lockScope = (LockScope)contextHandle; lockScope.Keepalive.Stop(); try { var internalHandle = lockScope.InternalLock.TryAcquire(timeoutMillis, strategy, contextHandle: lockScope.InternalHandle); return(internalHandle != null ? new LockScope(internalHandle, lockScope.InternalLock, lockScope.Keepalive, connection: null) : null); } finally { // always restart, even if the acquisition fails lockScope.Keepalive.Start(); } } var connection = new SqlConnection(this.connectionString); LockScope result = null; try { connection.Open(); var internalLock = new ExternalConnectionOrTransactionSqlDistributedLock(this.lockName, connection); var internalHandle = internalLock.TryAcquire(timeoutMillis, strategy, contextHandle: null); if (internalHandle != null) { var keepalive = new KeepaliveHelper(connection); keepalive.Start(); result = new LockScope(internalHandle, internalLock, keepalive, connection); } } finally { if (result == null) { connection.Dispose(); } } return(result); }
private static XElement GetLockScope(LockScope lockScope) { var lockscope = new XElement("{DAV:}lockscope"); switch (lockScope) { case LockScope.Shared: lockscope.Add(new XElement("{DAV:}shared")); break; case LockScope.Exclusive: lockscope.Add(new XElement("{DAV:}exclusive")); break; default: throw new InvalidEnumArgumentException("lockScope", (int)lockScope, typeof(LockScope)); } return lockscope; }
public IDisposable TryAcquire(int timeoutMillis, SqlApplicationLock.Mode mode, IDisposable contextHandle) { if (contextHandle != null) { // if we are taking a nested lock, we don't want to start another keepalive on the same connection. // However, we do need to stop our current keepalive while we take the nested lock to avoid threading issues var lockScope = (LockScope)contextHandle; lockScope.Keepalive.Stop(); try { var internalHandle = lockScope.InternalLock.TryAcquire(timeoutMillis, mode, contextHandle: lockScope.InternalHandle); return(internalHandle != null ? new LockScope(internalHandle, lockScope.InternalLock, lockScope.Keepalive, ownsKeepalive: false) : null); } finally { // always restart, even if the acquisition fails lockScope.Keepalive.Start(); } } var connection = new SqlConnection(this.connectionString); LockScope result = null; try { connection.Open(); var internalLock = new ConnectionScopedSqlDistributedLock(this.lockName, connection); var internalHandle = internalLock.TryAcquire(timeoutMillis, mode, contextHandle: null); if (internalHandle != null) { var keepalive = new KeepaliveHelper(connection); keepalive.Start(); result = new LockScope(internalHandle, internalLock, keepalive, ownsKeepalive: true); } } finally { if (result == null) { connection.Dispose(); } } return(result); }
public async Task UIT_WebDavClient_LockRefreshLockUnlock() { // This won't work on ownCloud/Nextcloud because they do not support WebDAV locking. // These unit integration test are skipped for ownCloud/Nextcloud. if (webDavRootFolder.Contains("nextcloud") || webDavRootFolder.Contains("owncloud")) { return; } using (var client = CreateWebDavClientWithDebugHttpMessageHandler()) { var userEmail = "*****@*****.**"; // Lock. var lockInfo = new LockInfo() { LockScope = LockScope.CreateExclusiveLockScope(), LockType = LockType.CreateWriteLockType(), OwnerHref = userEmail }; var response = await client.LockAsync(webDavRootFolder, WebDavTimeoutHeaderValue.CreateWebDavTimeout(TimeSpan.FromMinutes(1)), WebDavDepthHeaderValue.Infinity, lockInfo); var lockResponseSuccess = response.IsSuccessStatusCode; LockToken lockToken = await WebDavHelper.GetLockTokenFromWebDavResponseMessage(response); ActiveLock activeLock = await WebDavHelper.GetActiveLockFromWebDavResponseMessage(response); // Refresh lock. response = await client.RefreshLockAsync(webDavRootFolder, WebDavTimeoutHeaderValue.CreateWebDavTimeout(TimeSpan.FromSeconds(10)), lockToken); var refreshLockResponseSuccess = response.IsSuccessStatusCode; // Unlock. response = await client.UnlockAsync(webDavRootFolder, lockToken); var unlockResponseSuccess = response.IsSuccessStatusCode; Assert.IsTrue(lockResponseSuccess); Assert.IsNotNull(lockToken); Assert.AreEqual(userEmail, activeLock.OwnerHref); Assert.IsTrue(refreshLockResponseSuccess); Assert.IsTrue(unlockResponseSuccess); } }
public int Handle() { this._LockDepth = WebDavHelper.getRequestDepth(this._httpApplication); //No support for ResourceChildren LOCKing if ( this._LockDepth == DepthType.ResourceChildren) return (int)DavLockResponseCode.BadRequest; this._requestPath = WebDavHelper.getRelativePath(this._httpApplication, this._httpApplication.Request.FilePath); //Check to see if this is a lock refresh request. if (this._httpApplication.Request.Headers["If"] != null) { _LockToken = WebDavHelper.ParseOpaqueLockToken(_httpApplication.Request.Headers["If"]); _LockTimeOut = WebDavHelper.ParseTimeoutHeader(_httpApplication,this._LockTimeOut); //Check to see that the lock exists on the requested resource. LocksDS.LocksRow ltr = WebDavHelper.getFileLockbyToken(_LockToken); if (ltr==null) return (int)DavLockResponseCode.PreconditionFailed; //Check if the lock is expired , include token grace timeout in calculation TimeSpan span = DateTime.Now.Subtract(ltr.update_date_stamp); if (span.TotalSeconds > ltr.Timeout + this._GraceLockTimeOut) { //the Lock has expired so delete it an return as if it did not exist WebDavHelper.RemoveLock(ltr.ID); return (int)DavLockResponseCode.PreconditionFailed; } //the lock exists and is not expired so update the timeout and update_date_stamp ltr.Timeout = _LockTimeOut; WebDavHelper.SaveLock(ltr); //Send timeout header back to client _httpApplication.Response.AppendHeader("Timeout", "Second-" + this._LockTimeOut.ToString()); //Deserialise the lock token in the DB to get the rest of the data DeserialiseLock(ltr); BuildResponse(); return (int)DavLockResponseCode.Ok; }else{ //This is not a refresh it is a new LOCK request. So check that it is valid //Check to see if the resource exists Search_FilesDS.FilesRow _fileInfo = WebDavHelper.getFileAttribsOnly(this._requestPath); if (_fileInfo == null) return (int)DavLockResponseCode.BadRequest; //Need to workout how to resolve this problem where office attempts to lock a resource //it knows does not exist. //Check that it is not already locked LocksDS.LocksRow ltr = WebDavHelper.getLock(_fileInfo.ID); if (ltr != null) { //Check if the lock is expired , include token grace timeout in calculation TimeSpan span = DateTime.Now.Subtract(ltr.update_date_stamp); if (span.TotalSeconds > ltr.Timeout + this._GraceLockTimeOut) { //the Lock has expired so delete it an return as if it did not exist WebDavHelper.RemoveLock(ltr.ID); } else { return (int)DavLockResponseCode.Locked; } } //Check that the request XML is valid for the LOCK request if (_requestXmlNavigator == null) return (int)ServerResponseCode.BadRequest; //Load the valid properties XPathNodeIterator _lockInfoNodeIterator =_requestXmlNavigator.SelectDescendants("lockinfo", "DAV:", false); if (!_lockInfoNodeIterator.MoveNext()) return (int)ServerResponseCode.BadRequest; //Create a new Lock this._LockToken = System.Guid.NewGuid().ToString("D"); this._LockTimeOut = WebDavHelper.ParseTimeoutHeader(_httpApplication,this._LockTimeOut); //Get the lock type _LockType = LockType.Write; XPathNodeIterator _lockTypeNodeIterator = _lockInfoNodeIterator.Current.SelectDescendants("locktype", "DAV:", false); if (_lockTypeNodeIterator.MoveNext()) { XPathNavigator _currentNode = _lockTypeNodeIterator.Current; if (_currentNode.MoveToFirstChild()) { switch (_currentNode.LocalName.ToLower(CultureInfo.InvariantCulture)) { case "read": _LockType = LockType.Read; break; case "write": _LockType = LockType.Write; break; } } } //Get the lock scope _LockScope = LockScope.Exclusive; XPathNodeIterator _lockScopeNodeIterator = _lockInfoNodeIterator.Current.SelectDescendants("lockscope", "DAV:", false); if (_lockScopeNodeIterator.MoveNext()) { XPathNavigator _currentNode = _lockScopeNodeIterator.Current; if (_currentNode.MoveToFirstChild()) { switch (_currentNode.LocalName.ToLower(CultureInfo.InvariantCulture)) { case "shared": _LockScope = LockScope.Shared; break; case "exclusive": _LockScope = LockScope.Exclusive; break; } } } //Get the lock owner _LockOwnerType = LockOwnerType.User; XPathNodeIterator _lockOwnerNodeIterator = _lockInfoNodeIterator.Current.SelectDescendants("owner", "DAV:", false); if (_lockOwnerNodeIterator.MoveNext()) { XPathNavigator _currentNode = _lockOwnerNodeIterator.Current; if (_currentNode.NodeType == XPathNodeType.Text) { _LockOwnerType = LockOwnerType.User; } else { if (_currentNode.MoveToFirstChild()) { //TODO: Expand this to other LockOwnerTypes switch (_currentNode.LocalName.ToLower(CultureInfo.InvariantCulture)) { case "href": _LockOwnerType = LockOwnerType.Href; break; } } } _LockOwner = _currentNode.Value; } //Now save the Lock to the DB; saveLock(_fileInfo.ID); BuildResponse(); } return (int)DavLockResponseCode.Ok; }
private void DeserialiseLock(LocksDS.LocksRow _lockrow) { this._LockOwner = _lockrow.LockOwner; this._LockDepth = (DepthType)_lockrow.LockDepth; this._LockOwnerType = (LockOwnerType)_lockrow.LockOwnerType; this._LockType = (LockType)_lockrow.LockType; this._LockScope = (LockScope)_lockrow.LockScope; }
/// <summary> /// Creates a new locking object. /// </summary> /// <param name="type"></param> /// <param name="scope"></param> public DAVLocking(LockType type, LockScope scope) { Type = type; Scope = scope; }