Exemple #1
0
        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);
        }
Exemple #2
0
        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);
        }
Exemple #11
0
        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);
        }
Exemple #13
0
        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)));
        }
        // 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);
        }
 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;
 }
Exemple #21
0
 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;
 }
Exemple #22
0
 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);
     }
 }
Exemple #23
0
        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);
            }
        }
Exemple #26
0
        /// <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
            }
        }
Exemple #29
0
        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);
            }
        }
Exemple #33
0
        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;
        }
Exemple #34
0
 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;
 }
Exemple #35
0
 /// <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;
 }