/// <summary>
        /// Split an URI into a collection and name part.
        /// </summary>
        /// <param name="uri">URI that should be splitted.</param>
        /// <returns>
        /// Splitted URI in a collection URI and a name string.
        /// </returns>
        public static SplitUri SplitUri(WebDavUri uri)
        {
            // Strip a trailing slash
            var trimmedUri = uri.AbsoluteUri;

            if (trimmedUri.EndsWith("/"))
            {
                trimmedUri = trimmedUri.Substring(0, trimmedUri.Length - 1);
            }

            // Determine the offset of the name
            var slashOffset = trimmedUri.LastIndexOf('/');

            if (slashOffset == -1)
            {
                return(null);
            }

            // Separate name from path
            return(new SplitUri
            {
                CollectionUri = new WebDavUri(trimmedUri.Substring(0, slashOffset)),
                Name = Uri.UnescapeDataString(trimmedUri.Substring(slashOffset + 1))
            });
        }
        public Task <IStoreItem> GetItemAsync(WebDavUri uri, IHttpContext httpContext)
        {
            var identity = (HttpListenerBasicIdentity)httpContext.Session.Principal.Identity;
            var path     = uri.Path;

            try
            {
                var item = CloudManager.Instance(identity).GetItem(path).Result;
                if (item != null)
                {
                    return(item.IsFile
                        ? Task.FromResult <IStoreItem>(new MailruStoreItem(LockingManager, (File)item, IsWritable))
                        : Task.FromResult <IStoreItem>(new MailruStoreCollection(httpContext, LockingManager, (Folder)item, IsWritable)));
                }
            }
            catch (AggregateException e)
            {
                var we = e.InnerExceptions.OfType <WebException>().FirstOrDefault();
                if (we == null || we.Status != WebExceptionStatus.ProtocolError)
                {
                    throw;
                }
            }
            // ReSharper disable once RedundantCatchClause
            #if DEBUG
            #pragma warning disable 168
            catch (Exception ex)
            {
                throw;
            }
            #pragma warning restore 168
            #endif

            return(Task.FromResult <IStoreItem>(null));
        }
Example #3
0
        public async Task <IStoreItem> GetItemAsync(WebDavUri uri, IHttpContext httpContext)
        {
            var identity = (HttpListenerBasicIdentity)httpContext.Session.Principal.Identity;
            var path     = uri.Path;

            try
            {
                var item = await CloudManager.Instance(identity).GetItemAsync(path);

                if (item != null)
                {
                    return(item.IsFile
                        ? new LocalStoreItem((File)item, IsWritable, this)
                        : new LocalStoreCollection(httpContext, (Folder)item, IsWritable, this) as IStoreItem);
                }
            }
            // ReSharper disable once RedundantCatchClause
            #pragma warning disable 168
            catch (Exception ex)
            #pragma warning restore 168
            {
                throw;
            }

            return(null);
        }
        public Task <IStoreItem> GetItemAsync(WebDavUri uri, IHttpContext httpContext)
        {
            var identity = (HttpListenerBasicIdentity)httpContext.Session.Principal.Identity;
            var path     = uri.Path;

            try
            {
                var item = CloudManager.Instance(identity).GetItem(path);
                if (item != null)
                {
                    return(item.IsFile
                        ? Task.FromResult <IStoreItem>(new MailruStoreItem(LockingManager, (File)item, IsWritable))
                        : Task.FromResult <IStoreItem>(new MailruStoreCollection(httpContext, LockingManager, (Folder)item, IsWritable)));
                }
            }
            // ReSharper disable once RedundantCatchClause
            #pragma warning disable 168
            catch (Exception ex)
            #pragma warning restore 168
            {
                throw;
            }

            return(Task.FromResult <IStoreItem>(null));
        }
Example #5
0
        public Task <IStoreItem> GetItemAsync(WebDavUri uri, IHttpContext httpContext)
        {
            var identity = (HttpListenerBasicIdentity)httpContext.Session.Principal.Identity;
            var path     = uri.Path;

            try
            {
                var item = CloudManager.Instance(identity).GetItem(path);
                if (item != null)
                {
                    return(item.IsFile
                        ? Task.FromResult <IStoreItem>(new MailruStoreItem(LockingManager, (File)item, IsWritable))
                        : Task.FromResult <IStoreItem>(new MailruStoreCollection(httpContext, LockingManager, (Folder)item, IsWritable)));
                }
            }
            //catch (AggregateException e)
            //{
            //    var we = e.InnerExceptions.OfType<WebException>().FirstOrDefault();
            //    if (we == null || we.Status != WebExceptionStatus.ProtocolError) throw;
            //}
            catch (Exception ex)
            {
                throw;
            }

            return(Task.FromResult <IStoreItem>(null));
        }
            public static string LocalPath(WebDavUri lockTokenUri)
            {
                // LockTokenUri does not contains "//" ?
                ///<see cref="ImMemoryLockingManager.GetTokenFromLockToken"/>
                int pos = lockTokenUri.AbsoluteUri.IndexOf(":", StringComparison.OrdinalIgnoreCase);

                return(lockTokenUri.AbsoluteUri.Substring(pos + 1));
            }
Example #7
0
        public DavStatusCode Unlock(IStoreItem item, WebDavUri lockTokenUri)
        {
            // Determine the actual lock token
            var lockToken = GetTokenFromLockToken(lockTokenUri);

            if (lockToken == null)
            {
                return(DavStatusCode.PreconditionFailed);
            }

            // Determine the item's key
            var key = item.UniqueKey;

            lock (_itemLocks)
            {
                // Make sure the item is in the dictionary
                ItemLockTypeDictionary itemLockTypeDictionary;
                if (!_itemLocks.TryGetValue(key, out itemLockTypeDictionary))
                {
                    return(DavStatusCode.PreconditionFailed);
                }

                // Scan both the dictionaries for the token
                foreach (var kv in itemLockTypeDictionary)
                {
                    var itemLockList = kv.Value;

                    // Remove this lock from the list
                    for (var i = 0; i < itemLockList.Count; ++i)
                    {
                        if (itemLockList[i].Token == lockToken.Value)
                        {
                            // Remove the item
                            itemLockList.RemoveAt(i);

                            // Check if there are any locks left for this type
                            if (!itemLockList.Any())
                            {
                                // Remove the type
                                itemLockTypeDictionary.Remove(kv.Key);

                                // Check if there are any types left
                                if (!itemLockTypeDictionary.Any())
                                {
                                    _itemLocks.Remove(key);
                                }
                            }

                            // Lock has been removed
                            return(DavStatusCode.NoContent);
                        }
                    }
                }
            }

            // Item cannot be unlocked (token cannot be found)
            return(DavStatusCode.PreconditionFailed);
        }
Example #8
0
        public async Task <IStoreCollection> GetCollectionAsync(WebDavUri uri, IHttpContext httpContext)
        {
            var path = uri.Path;

            var item = await CloudManager.Instance(httpContext.Session.Principal.Identity)
                       .GetItemAsync(path, Cloud.ItemType.Folder);

            return(new LocalStoreCollection(httpContext, (Folder)item, IsWritable, this));
        }
        public Task <IStoreCollection> GetCollectionAsync(WebDavUri uri, IHttpContext httpContext)
        {
            var path = uri.Path;

            var folder = (Folder)CloudManager.Instance(httpContext.Session.Principal.Identity)
                         .GetItem(path, MailRuCloud.Api.MailRuCloud.ItemType.Folder).Result;

            return(Task.FromResult <IStoreCollection>(new MailruStoreCollection(httpContext, LockingManager, folder, IsWritable)));
        }
Example #10
0
        public static WebDavUri Combine(WebDavUri baseUri, string path)
        {
            var uriText = baseUri.OriginalString;

            if (uriText.EndsWith("/"))
            {
                uriText = uriText.Substring(0, uriText.Length - 1);
            }
            return(new WebDavUri($"{uriText}/{Uri.EscapeDataString(path)}"));
        }
Example #11
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;
 }
Example #12
0
        public static WebDavUri Combine(WebDavUri baseUri, string path)
        {
            var uriText = baseUri.OriginalString;

            if (uriText.EndsWith("/", StringComparison.OrdinalIgnoreCase))
            {
                return(new WebDavUri($"{uriText}{Uri.EscapeDataString(path)}"));
            }

            return(new WebDavUri($"{uriText}/{Uri.EscapeDataString(path)}"));
        }
Example #13
0
            public XElement GetXmlMultiStatus(WebDavUri uri)
            {
                var xResponse    = new XElement(WebDavNamespaces.DavNs + "response", new XElement(WebDavNamespaces.DavNs + "href", uri));
                var xMultiStatus = new XElement(WebDavNamespaces.DavNs + "multistatus", xResponse);

                foreach (var result in _propertySetters.Where(ps => ps.Result != DavStatusCode.Ok))
                {
                    xResponse.Add(result.GetXmlResponse());
                }
                return(xMultiStatus);
            }
            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);
            }
        private static Guid?GetTokenFromLockToken(WebDavUri lockTokenUri)
        {
            // We should always use opaquetokens
            if (LockTokenUri.Scheme(lockTokenUri) != TokenScheme)
            {
                return(null);
            }

            // Parse the token
            if (!Guid.TryParse(LockTokenUri.LocalPath(lockTokenUri), out var lockToken))
            {
                return(null);
            }

            // Return the token
            return(lockToken);
        }
        public bool HasLock(IStoreItem item, WebDavUri lockTokenUri)
        {
            // If no lock is specified, then we should abort
            if (lockTokenUri == null)
            {
                return(false);
            }

            // Determine the item's key
            var key = item.UniqueKey;

            // Determine the actual lock token
            var lockToken = GetTokenFromLockToken(lockTokenUri);

            if (lockToken == null)
            {
                return(false);
            }

            lock (_itemLocks)
            {
                // Make sure the item is in the dictionary
                if (!_itemLocks.TryGetValue(key, out var itemLockTypeDictionary))
                {
                    return(false);
                }

                // Scan both the dictionaries for the token
                foreach (var kv in itemLockTypeDictionary)
                {
                    // Refresh the lock
                    var itemLockInfo = kv.Value.FirstOrDefault(lt => lt.Token == lockToken.Value && !lt.IsExpired);
                    if (itemLockInfo != null)
                    {
                        return(true);
                    }
                }
            }

            // No lock
            return(false);
        }
Example #17
0
        private async Task CopyAsync(IStoreItem source, IStoreCollection destinationCollection, string name, bool overwrite, int depth, IHttpContext httpContext, WebDavUri baseUri, UriResultCollection errors)
        {
            // Determine the new base Uri
            var newBaseUri = UriHelper.Combine(baseUri, name);

            // Copy the item
            var copyResult = await source.CopyAsync(destinationCollection, name, overwrite, httpContext).ConfigureAwait(false);

            if (copyResult.Result != DavStatusCode.Created && copyResult.Result != DavStatusCode.NoContent)
            {
                errors.AddResult(newBaseUri, copyResult.Result);
                return;
            }

            // Check if the source is a collection and we are requested to copy recursively
            var sourceCollection = source as IStoreCollection;

            if (sourceCollection != null && depth > 0)
            {
                // The result should also contain a collection
                var newCollection = (IStoreCollection)copyResult.Item;

                // Copy all childs of the source collection
                foreach (var entry in await sourceCollection.GetItemsAsync(httpContext).ConfigureAwait(false))
                {
                    await CopyAsync(entry, newCollection, entry.Name, overwrite, depth - 1, httpContext, newBaseUri, errors).ConfigureAwait(false);
                }
            }
        }
 public PropertyEntry(WebDavUri uri, IStoreItem entry)
 {
     Uri   = uri;
     Entry = entry;
 }
        //TODO: something wrong with unused depth?
        private async Task CopyAsync(IStoreItem source, IStoreCollection destinationCollection, string name, bool overwrite, int depth, IHttpContext httpContext, WebDavUri baseUri, UriResultCollection errors)
        {
            // Determine the new base Uri
            var newBaseUri = UriHelper.Combine(baseUri, name);

            // Copy the item
            var copyResult = await source.CopyAsync(destinationCollection, name, overwrite, httpContext).ConfigureAwait(false);

            if (copyResult.Result != DavStatusCode.Created && copyResult.Result != DavStatusCode.NoContent)
            {
                errors.AddResult(newBaseUri, copyResult.Result);
            }

            //do not copy recursively
        }
 public LockResult Lock(IStoreItem item, LockType lockType, LockScope lockScope, XElement owner, WebDavUri lockRootUri,
                        bool recursiveLock, IEnumerable <int> timeouts)
 {
     return(LR);
 }
 public DavStatusCode Unlock(IStoreItem item, WebDavUri token)
 {
     return(DavStatusCode.Ok);
 }
        private async Task MoveAsync(IStoreCollection sourceCollection, string sourceName, IStoreCollection destinationCollection, string destinationName, bool overwrite, IHttpContext httpContext, WebDavUri baseUri, UriResultCollection errors)
        {
            // Determine the new base URI
            var subBaseUri = UriHelper.Combine(baseUri, destinationName);

            // Obtain the actual item
            if (await sourceCollection.GetItemAsync(sourceName, httpContext).ConfigureAwait(false) is IStoreCollection moveCollection)
            {
                // Create a new collection
                var newCollectionResult = await destinationCollection.CreateCollectionAsync(destinationName, overwrite, httpContext);

                if (newCollectionResult.Result != DavStatusCode.Created && newCollectionResult.Result != DavStatusCode.NoContent)
                {
                    errors.AddResult(subBaseUri, newCollectionResult.Result);
                    return;
                }

                // Move all subitems
                foreach (var entry in await moveCollection.GetItemsAsync(httpContext).ConfigureAwait(false))
                {
                    await MoveAsync(moveCollection, entry.Name, newCollectionResult.Collection, entry.Name, overwrite, httpContext, subBaseUri, errors);
                }

                // Delete the source collection
                var deleteResult = await sourceCollection.DeleteItemAsync(sourceName, httpContext);

                if (deleteResult != DavStatusCode.Ok)
                {
                    errors.AddResult(subBaseUri, newCollectionResult.Result);
                    return;
                }
            }
            else
            {
                // Items should be moved directly
                var result = await sourceCollection.MoveItemAsync(sourceName, destinationCollection, destinationName, overwrite, httpContext);

                if (result.Result != DavStatusCode.Created && result.Result != DavStatusCode.NoContent)
                {
                    errors.AddResult(subBaseUri, result.Result);
                    return;
                }
            }
        }
        public LockResult Lock(IStoreItem item, LockType lockType, LockScope lockScope, XElement owner, WebDavUri lockRootUri, bool recursive, IEnumerable <int> timeouts)
        {
            // Determine the expiration based on the first time-out
            var timeout = timeouts.Cast <int?>().FirstOrDefault();

            // Determine the item's key
            var key = item.UniqueKey;

            lock (_itemLocks)
            {
                // Make sure the item is in the dictionary
                if (!_itemLocks.TryGetValue(key, out var itemLockTypeDictionary))
                {
                    _itemLocks.Add(key, itemLockTypeDictionary = new ItemLockTypeDictionary());
                }

                // Make sure there is already a lock-list for this type
                if (!itemLockTypeDictionary.TryGetValue(lockType, out var itemLockList))
                {
                    // Create a new lock-list
                    itemLockTypeDictionary.Add(lockType, itemLockList = new ItemLockList());
                }
                else
                {
                    // Check if there is already an exclusive lock
                    if (itemLockList.Any(l => l.Scope == LockScope.Exclusive))
                    {
                        return(new LockResult(DavStatusCode.Locked));
                    }
                }

                // Create the lock info object
                var itemLockInfo = new ItemLockInfo(item, lockType, lockScope, lockRootUri, recursive, owner, timeout ?? -1);

                // Add the lock
                itemLockList.Add(itemLockInfo);

                // Return the active lock
                return(new LockResult(DavStatusCode.Ok, GetActiveLockInfo(itemLockInfo)));
            }
        }
 public LockResult RefreshLock(IStoreItem item, bool recursiveLock, IEnumerable <int> timeouts, WebDavUri lockTokenUri)
 {
     return(LR);
 }
        public LockResult RefreshLock(IStoreItem item, bool recursiveLock, IEnumerable <int> timeouts, WebDavUri lockTokenUri)
        {
            var timeout      = timeouts.Cast <int?>().FirstOrDefault();
            var itemLockInfo = new ItemLockInfo(item, LockType.Write, LockScope.Exclusive, lockTokenUri, recursiveLock, null, timeout ?? -1);

            return(new LockResult(DavStatusCode.Ok, GetActiveLockInfo(itemLockInfo)));
        }
        private async Task AddEntriesAsync(IStoreCollection collection, int depth, IHttpContext httpContext, WebDavUri uri, IList <PropertyEntry> entries)
        {
            // Add the collection to the list
            entries.Add(new PropertyEntry(uri, collection));

            // If we have enough depth, then add the children
            if (depth > 0)
            {
                // Add all child collections
                foreach (var childEntry in await collection.GetItemsAsync(httpContext).ConfigureAwait(false))
                {
                    var subUri = UriHelper.Combine(uri, childEntry.Name);
                    if (childEntry is IStoreCollection subCollection)
                    {
                        await AddEntriesAsync(subCollection, depth - 1, httpContext, subUri, entries).ConfigureAwait(false);
                    }
                    else
                    {
                        entries.Add(new PropertyEntry(subUri, childEntry));
                    }
                }
            }
        }
        public LockResult RefreshLock(IStoreItem item, bool recursiveLock, IEnumerable <int> timeouts, WebDavUri lockTokenUri)
        {
            // Determine the actual lock token
            var lockToken = GetTokenFromLockToken(lockTokenUri);

            if (lockToken == null)
            {
                return(new LockResult(DavStatusCode.PreconditionFailed));
            }

            // Determine the item's key
            var key = item.UniqueKey;

            lock (_itemLocks)
            {
                // Make sure the item is in the dictionary
                if (!_itemLocks.TryGetValue(key, out var itemLockTypeDictionary))
                {
                    return(new LockResult(DavStatusCode.PreconditionFailed));
                }

                // Scan both the dictionaries for the token
                foreach (var kv in itemLockTypeDictionary)
                {
                    // Refresh the lock
                    var itemLockInfo = kv.Value.FirstOrDefault(lt => lt.Token == lockToken.Value && !lt.IsExpired);
                    if (itemLockInfo != null)
                    {
                        // Determine the expiration based on the first time-out
                        var timeout = timeouts.Cast <int?>().FirstOrDefault() ?? itemLockInfo.Timeout;
                        itemLockInfo.RefreshExpiration(timeout);

                        // Return the active lock
                        return(new LockResult(DavStatusCode.Ok, GetActiveLockInfo(itemLockInfo)));
                    }
                }
            }

            // Item cannot be unlocked (token cannot be found)
            return(new LockResult(DavStatusCode.PreconditionFailed));
        }
 public bool HasLock(IStoreItem item, WebDavUri lockToken)
 {
     return(false);
 }
Example #29
0
        private async Task <DavStatusCode> DeleteItemAsync(IStoreCollection collection, string name, IHttpContext httpContext, WebDavUri baseUri, UriResultCollection errors)
        {
            // Obtain the actual item
            var deleteCollection = await collection.GetItemAsync(name, httpContext).ConfigureAwait(false) as IStoreCollection;

            if (deleteCollection != null)
            {
                // Determine the new base URI
                var subBaseUri = UriHelper.Combine(baseUri, name);

                // Delete all entries first
                foreach (var entry in await deleteCollection.GetItemsAsync(httpContext).ConfigureAwait(false))
                {
                    await DeleteItemAsync(deleteCollection, entry.Name, httpContext, subBaseUri, errors).ConfigureAwait(false);
                }
            }

            // Attempt to delete the item
            return(await collection.DeleteItemAsync(name, httpContext).ConfigureAwait(false));
        }
        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)));
        }