/// <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)); }
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)); }
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)); }
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); }
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))); }
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)}")); }
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 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)}")); }
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); }
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); }
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))); }