/// <summary> /// Convert the given /// <see cref="IWebDavStoreItem" /> to a /// <see cref="List{T}" /> of /// <see cref="IWebDavStoreItem" /> /// This list depends on the "Depth" header /// </summary> /// <param name="iWebDavStoreItem">The <see cref="IWebDavStoreItem" /> that needs to be converted</param> /// <param name="depth">The "Depth" header</param> /// <returns> /// A <see cref="List{T}" /> of <see cref="IWebDavStoreItem" /> /// </returns> /// <exception cref="WebDAVSharp.Server.Exceptions.WebDavConflictException"></exception> private static List <IWebDavStoreItem> GetWebDavStoreItems(IWebDavStoreItem iWebDavStoreItem, int depth) { List <IWebDavStoreItem> list = new List <IWebDavStoreItem>(); //IWebDavStoreCollection // if the item is a collection IWebDavStoreCollection collection = iWebDavStoreItem as IWebDavStoreCollection; if (collection != null) { list.Add(collection); if (depth == 0) { return(list); } foreach (IWebDavStoreItem item in collection.Items.Where(item => !list.Contains(item))) { list.Add(item); } return(list); } // if the item is not a document, throw conflict exception if (!(iWebDavStoreItem is IWebDavStoreDocument)) { throw new WebDavConflictException(); } // add the item to the list list.Add(iWebDavStoreItem); return(list); }
/// <summary> /// Retrieves a store item through the specified /// <see cref="Uri" /> from the /// specified /// <see cref="WebDavServer" /> and /// <see cref="IWebDavStore" />. /// </summary> /// <param name="uri">The <see cref="Uri" /> to retrieve the store item for.</param> /// <param name="server">The <see cref="WebDavServer" /> that hosts the <paramref name="store" />.</param> /// <param name="store">The <see cref="IWebDavStore" /> from which to retrieve the store item.</param> /// <returns> /// The retrieved store item. /// </returns> /// <exception cref="System.ArgumentNullException"><para> /// <paramref name="uri" /> is <c>null</c>.</para> /// <para> /// <paramref name="server" /> is <c>null</c>.</para> /// <para> /// <paramref name="store" /> is <c>null</c>.</para></exception> /// <exception cref="WebDAVSharp.Server.Exceptions.WebDavNotFoundException">If the item was not found.</exception> /// <exception cref="WebDavConflictException"><paramref name="uri" /> refers to a document in a collection, where the collection does not exist.</exception> /// <exception cref="WebDavNotFoundException"><paramref name="uri" /> refers to a document that does not exist.</exception> public static IWebDavStoreItem GetItem( this Uri uri, WebDavServer server, IWebDavStore store) { if (uri == null) { throw new ArgumentNullException("uri"); } if (server == null) { throw new ArgumentNullException("server"); } if (store == null) { throw new ArgumentNullException("store"); } Uri prefixUri = uri.GetPrefixUri(server); IWebDavStoreCollection collection = store.Root; IWebDavStoreItem item = null; if (prefixUri.Segments.Length == uri.Segments.Length) { return(collection); } string[] segments = SplitUri(uri, prefixUri); for (int index = 0; index < segments.Length; index++) { string segmentName = Uri.UnescapeDataString(segments[index]); IWebDavStoreItem nextItem = collection.GetItemByName(segmentName); if (nextItem == null) { throw new WebDavNotFoundException(String.Format("Cannot find item {0} from collection {1}", segmentName, collection.ItemPath)); //throw new WebDavConflictException(); } if (index == segments.Length - 1) { item = nextItem; } else { collection = nextItem as IWebDavStoreCollection; if (collection == null) { throw new WebDavNotFoundException(String.Format("NextItem [{0}] is not a collection", nextItem.ItemPath)); } } } if (item == null) { throw new WebDavNotFoundException(String.Format("Unable to find {0}", uri)); } return(item); }
/// <summary> /// Convert the given /// <see cref="IWebDavStoreItem" /> to a /// <see cref="List{T}" /> of /// <see cref="IWebDavStoreItem" /> /// This list depends on the "Depth" header /// </summary> /// <param name="iWebDavStoreItem">The <see cref="IWebDavStoreItem" /> that needs to be converted</param> /// <param name="depth">The "Depth" header</param> /// <returns> /// A <see cref="List{T}" /> of <see cref="IWebDavStoreItem" /> /// </returns> /// <exception cref="WebDAVSharp.Server.Exceptions.WebDavConflictException"></exception> private HashSet <IWebDavStoreItem> GetWebDavStoreItems(IWebDavStoreItem iWebDavStoreItem, int depth) { HashSet <IWebDavStoreItem> list = new HashSet <IWebDavStoreItem>(); //IWebDavStoreCollection // if the item is a collection IWebDavStoreCollection collection = iWebDavStoreItem as IWebDavStoreCollection; if (collection != null) { list.Add(collection); if (depth == 0) { return(list); } foreach (var item in collection.Items) { list.Add(item); } return(list); } // if the item is not a document, throw conflict exception if (!(iWebDavStoreItem is IWebDavStoreDocument)) { throw new WebDavConflictException(String.Format("Web dav item is not a document nor a collection: {0} depth {1}", iWebDavStoreItem.ItemPath, depth)); } // add the item to the list list.Add(iWebDavStoreItem); return(list); }
/// <summary> /// Moves the /// </summary> /// <param name="server">The <see cref="WebDavServer" /> through which the request came in from the client.</param> /// <param name="context">The /// <see cref="IHttpListenerContext" /> object containing both the request and response /// objects to use.</param> /// <param name="store">The <see cref="IWebDavStore" /> that the <see cref="WebDavServer" /> is hosting.</param> /// <param name="sourceWebDavStoreItem">The <see cref="IWebDavStoreItem" /> that will be moved</param> /// <exception cref="WebDAVSharp.Server.Exceptions.WebDavForbiddenException">If the source path is the same as the destination path</exception> /// <exception cref="WebDAVSharp.Server.Exceptions.WebDavPreconditionFailedException">If one of the preconditions failed</exception> private static void MoveItem(WebDavServer server, IHttpListenerContext context, IWebDavStore store, IWebDavStoreItem sourceWebDavStoreItem) { Uri destinationUri = GetDestinationHeader(context.Request); IWebDavStoreCollection destinationParentCollection = GetParentCollection(server, store, destinationUri); bool isNew = true; string destinationName = destinationUri.GetLastSegment(); IWebDavStoreItem destination = destinationParentCollection.GetItemByName(destinationName); if (destination != null) { if (sourceWebDavStoreItem.ItemPath == destination.ItemPath) throw new WebDavForbiddenException(); // if the overwrite header is F, statuscode = precondition failed if (!GetOverwriteHeader(context.Request)) throw new WebDavPreconditionFailedException(); // else delete destination and set isNew to false destinationParentCollection.Delete(destination); isNew = false; } destinationParentCollection.MoveItemHere(sourceWebDavStoreItem, destinationName); // send correct response context.SendSimpleResponse(isNew ? (int)HttpStatusCode.Created : (int)HttpStatusCode.NoContent); }
/// <summary> /// Copies the item. /// </summary> /// <param name="server">The server.</param> /// <param name="context">The context.</param> /// <param name="store">The store.</param> /// <param name="source">The source.</param> /// <exception cref="WebDAVSharp.Server.Exceptions.WebDavForbiddenException"></exception> /// <exception cref="WebDAVSharp.Server.Exceptions.WebDavPreconditionFailedException"></exception> private static void CopyItem(WebDavServer server, IHttpListenerContext context, IWebDavStore store, IWebDavStoreItem source) { var destinationUri = GetDestinationHeader(context.Request); var destinationParentCollection = GetParentCollection(server, store, destinationUri); var copyContent = (GetDepthHeader(context.Request) != 0); var isNew = true; var destinationName = Uri.UnescapeDataString(destinationUri.Segments.Last().TrimEnd('/', '\\')); var destination = destinationParentCollection.GetItemByName(destinationName); if (destination != null) { if (source.ItemPath == destination.ItemPath) { throw new WebDavForbiddenException(); } if (!GetOverwriteHeader(context.Request)) { throw new WebDavPreconditionFailedException(); } if (destination is IWebDavStoreCollection) { destinationParentCollection.Delete(destination); } isNew = false; } destinationParentCollection.CopyItemHere(source, destinationName, copyContent); context.SendSimpleResponse(isNew ? HttpStatusCode.Created : HttpStatusCode.NoContent); }
/// <summary> /// Copies the item. /// </summary> /// <param name="server">The server.</param> /// <param name="context">The context.</param> /// <param name="store">The store.</param> /// <param name="source">The source.</param> /// <exception cref="WebDAVSharp.Server.Exceptions.WebDavForbiddenException"></exception> /// <exception cref="WebDAVSharp.Server.Exceptions.WebDavPreconditionFailedException"></exception> private static void CopyItem(WebDavServer server, IHttpListenerContext context, IWebDavStore store, IWebDavStoreItem source) { Uri destinationUri = GetDestinationHeader(context.Request); IWebDavStoreCollection destinationParentCollection = GetParentCollection(server, store, destinationUri); bool copyContent = (GetDepthHeader(context.Request) != 0); bool isNew = true; string destinationName = destinationUri.GetLastSegment(); IWebDavStoreItem destination = destinationParentCollection.GetItemByName(destinationName); if (destination != null) { if (source.ItemPath == destination.ItemPath) { throw new WebDavForbiddenException(); } if (!GetOverwriteHeader(context.Request)) { throw new WebDavPreconditionFailedException(); } if (destination is IWebDavStoreCollection) { destinationParentCollection.Delete(destination); } isNew = false; } destinationParentCollection.CopyItemHere(source, destinationName, copyContent); context.SendSimpleResponse(isNew ? (int)HttpStatusCode.Created : (int)HttpStatusCode.NoContent); }
/// <summary> /// Copies the item. /// </summary> /// <param name="server">The server.</param> /// <param name="context">The context.</param> /// <param name="store">The store.</param> /// <param name="source">The source.</param> /// <exception cref="WebDAVSharp.Server.Exceptions.WebDavForbiddenException"></exception> /// <exception cref="WebDAVSharp.Server.Exceptions.WebDavPreconditionFailedException"></exception> private static void CopyItem(WebDavServer server, IHttpListenerContext context, IWebDavStore store, IWebDavStoreItem source) { Uri destinationUri = GetDestinationHeader(context.Request); IWebDavStoreCollection destinationParentCollection = GetParentCollection(server, store, destinationUri); bool copyContent = (GetDepthHeader(context.Request) != 0); bool isNew = true; string destinationName = Uri.UnescapeDataString(destinationUri.Segments.Last().TrimEnd('/', '\\')); IWebDavStoreItem destination = destinationParentCollection.GetItemByName(destinationName); if (destination != null) { if (source.ItemPath == destination.ItemPath) throw new WebDavForbiddenException(); if (!GetOverwriteHeader(context.Request)) throw new WebDavPreconditionFailedException(); if (destination is IWebDavStoreCollection) destinationParentCollection.Delete(destination); isNew = false; } destinationParentCollection.CopyItemHere(source, destinationName, copyContent); context.SendSimpleResponse(isNew ? HttpStatusCode.Created : HttpStatusCode.NoContent); }
/// <summary> /// Moves the /// </summary> /// <param name="server">The <see cref="WebDavServer" /> through which the request came in from the client.</param> /// <param name="context">The /// <see cref="IHttpListenerContext" /> object containing both the request and response /// objects to use.</param> /// <param name="store">The <see cref="IWebDavStore" /> that the <see cref="WebDavServer" /> is hosting.</param> /// <param name="sourceWebDavStoreItem">The <see cref="IWebDavStoreItem" /> that will be moved</param> /// <exception cref="WebDAVSharp.Server.Exceptions.WebDavForbiddenException">If the source path is the same as the destination path</exception> /// <exception cref="WebDAVSharp.Server.Exceptions.WebDavPreconditionFailedException">If one of the preconditions failed</exception> private void MoveItem(WebDavServer server, IHttpListenerContext context, IWebDavStore store, IWebDavStoreItem sourceWebDavStoreItem) { Uri destinationUri = GetDestinationHeader(context.Request); IWebDavStoreCollection destinationParentCollection = GetParentCollection(server, store, destinationUri); bool isNew = true; string destinationName = Uri.UnescapeDataString(destinationUri.Segments.Last().TrimEnd('/', '\\')); IWebDavStoreItem destination = destinationParentCollection.GetItemByName(destinationName); if (destination != null) { if (sourceWebDavStoreItem.ItemPath == destination.ItemPath) { throw new WebDavForbiddenException(); } // if the overwrite header is F, statuscode = precondition failed if (!GetOverwriteHeader(context.Request)) { throw new WebDavPreconditionFailedException(); } // else delete destination and set isNew to false destinationParentCollection.Delete(destination); isNew = false; } destinationParentCollection.MoveItemHere(sourceWebDavStoreItem, destinationName); // send correct response context.SendSimpleResponse(isNew ? HttpStatusCode.Created : HttpStatusCode.NoContent); }
/// <summary> /// This function will refresh an existing lock. /// </summary> /// <param name="storeItem">Target URI to the file or folder </param> /// <param name="locktoken">The token issued when the lock was established</param> /// <param name="requestedlocktimeout">The requested timeout</param> /// <param name="requestDocument"> /// Output parameter, returns the Request document that was used when the lock was /// established. /// </param> /// <returns></returns> public override int RefreshLock(IWebDavStoreItem storeItem, Guid? locktoken, double? requestedlocktimeout, out XmlDocument requestDocument) { CleanLocks(storeItem); //Refreshing an existing lock //If a lock doesn't exist then lets just reply with a Precondition Failed. //412 (Precondition Failed), with 'lock-token-matches-request-uri' precondition code - The LOCK request was //made with an If header, indicating that the client wishes to refresh the given lock. However, the Request-URI //did not fall within the scope of the lock identified by the token. The lock may have a scope that does not //include the Request-URI, or the lock could have disappeared, or the token may be invalid. requestDocument = null; lock (ObjectLocks) { IWebDavStoreItemLockInstance ilock = ObjectLocks[storeItem.ItemPath].FirstOrDefault(d => (d.Token == locktoken)); if (ilock == null) { #if DEBUG WebDavServer.Log.Debug("Lock Refresh Failed , Lock does not exist."); #endif return 412; } #if DEBUG WebDavServer.Log.Debug("Lock Refresh Successful."); #endif ilock.RefreshLock(requestedlocktimeout); requestDocument = ilock.RequestDocument; return (int) HttpStatusCode.OK; } }
/// <summary> /// Retrieves a store item by its name. /// </summary> /// <param name="name">The name of the store item to retrieve.</param> /// <returns> /// The store item that has the specified /// <paramref name="name" />; /// or /// <c>null</c> if there is no store item with that name. /// </returns> public IWebDavStoreItem GetItemByName(string name) { var path = Path.Combine(ItemPath, name); IWebDavStoreItem document = null; WindowsIdentity.RunImpersonated(WindowsIdentity.GetCurrent().AccessToken, () => { if (File.Exists(path) && CanReadFile(path)) { document = new WebDavDiskStoreDocument(this, path); } if (Directory.Exists(path) && CanReadDirectory(path)) { document = new WebDavDiskStoreCollection(this, path); } }); return(document); //using (Identity.Impersonate()) //{ // if (File.Exists(path) && CanReadFile(path)) // return new WebDavDiskStoreDocument(this, path); // if (Directory.Exists(path) && CanReadDirectory(path)) // return new WebDavDiskStoreCollection(this, path); //} //return null; }
/// <summary> /// Copies an existing store item into this collection, overwriting any existing items. /// </summary> /// <param name="source">The store item to copy from.</param> /// <param name="destinationName">The name of the copy to create of <paramref name="source" />.</param> /// <param name="includeContent">The boolean for copying the containing files/folders or not.</param> /// <returns> /// The created <see cref="IWebDavStoreItem" /> instance. /// </returns> /// <exception cref="WebDAVSharp.Server.Exceptions.WebDavUnauthorizedException">If the user is unauthorized or has no access</exception> public IWebDavStoreItem CopyItemHere(IWebDavStoreItem source, string destinationName, bool includeContent) { // We get the path of var destinationItemPath = Path.Combine(ItemPath, destinationName); // the moving of the item if (source.IsCollection) { try { // Impersonate the current user and move the directory WindowsIdentity.RunImpersonated(WindowsIdentity.GetCurrent().AccessToken, () => { DirectoryCopy(source.ItemPath, destinationItemPath, true); }); //WindowsImpersonationContext wic = Identity.Impersonate(); //DirectoryCopy(source.ItemPath, destinationItemPath, true); //wic.Undo(); } catch { throw new WebDavUnauthorizedException(); } // We return the moved file as a WebDAVDiskStoreDocument var collection = new WebDavDiskStoreCollection(this, destinationItemPath); _items.Add(destinationName, new WeakReference(collection)); return(collection); } // We copy the file with an override. try { // Impersonate the current user and copy the file WindowsIdentity.RunImpersonated(WindowsIdentity.GetCurrent().AccessToken, () => { File.Copy(source.ItemPath, destinationItemPath, true); }); // WindowsImpersonationContext wic = Identity.Impersonate(); // File.Copy(source.ItemPath, destinationItemPath, true); // wic.Undo(); } catch { throw new WebDavUnauthorizedException(); } // We return the moved file as a WebDAVDiskStoreDocument var document = new WebDavDiskStoreDocument(this, destinationItemPath); _items.Add(destinationName, new WeakReference(document)); return(document); }
/// <summary> /// Processes the request. /// </summary> /// <param name="server">The <see cref="WebDavServer" /> through which the request came in from the client.</param> /// <param name="context">The /// <see cref="IHttpListenerContext" /> object containing both the request and response /// objects to use.</param> /// <param name="store">The <see cref="IWebDavStore" /> that the <see cref="WebDavServer" /> is hosting.</param> /// <exception cref="WebDAVSharp.Server.Exceptions.WebDavMethodNotAllowedException"></exception> /// <exception cref="WebDAVSharp.Server.Exceptions.WebDavLengthRequiredException">If the ContentLength header was not found</exception> /// <param name="response"></param> /// <param name="request"></param> protected override void OnProcessRequest( WebDavServer server, IHttpListenerContext context, IWebDavStore store, XmlDocument request, XmlDocument response) { // Get the parent collection IWebDavStoreCollection parentCollection = GetParentCollection(server, store, context.Request.Url); // Gets the item name from the url string itemName = context.Request.Url.GetLastSegment(); IWebDavStoreItem item = parentCollection.GetItemByName(itemName); IWebDavStoreDocument doc; if (item != null) { doc = item as IWebDavStoreDocument; if (doc == null) { throw new WebDavMethodNotAllowedException(); } } else { doc = parentCollection.CreateDocument(itemName); } Int64 contentLength = context.Request.ContentLength64; if (context.Request.ContentLength64 < 0) { var XLength = context.Request.Headers["x-expected-entity-length"]; if (!Int64.TryParse(XLength, out contentLength)) { throw new WebDavLengthRequiredException(); } } using (Stream stream = doc.OpenWriteStream(false)) { long left = contentLength; byte[] buffer = new byte[4096]; while (left > 0) { int toRead = Convert.ToInt32(Math.Min(left, buffer.Length)); int inBuffer = context.Request.InputStream.Read(buffer, 0, toRead); stream.Write(buffer, 0, inBuffer); left -= inBuffer; } } doc.FinishWriteOperation(); context.SendSimpleResponse((int)HttpStatusCode.Created); }
///// <summary> ///// Gets the prefix <see cref="Uri" /> that matches the specified <see cref="Uri" />. ///// </summary> ///// <param name="uri">The <see cref="Uri" /> to find the most specific prefix <see cref="Uri" /> for.</param> ///// <param name="context">Context</param> ///// <returns> ///// The most specific <see cref="Uri" /> for the given <paramref name="uri" />. ///// </returns> ///// <exception cref="WebDAVSharp.Server.Exceptions.WebDavInternalServerException">Unable to find correct server root</exception> ///// <exception cref="WebDavInternalServerException"><paramref name="uri" /> specifies a <see cref="Uri" /> that is not known to the <paramref name="server" />.</exception> //public static Uri GetPrefixUri(this Uri uri, IWebDavContext context) //{ // string.Format("{0}://{1}", context.Request.Url.Scheme, context.Request.Url.Authority); // string url = uri.ToString(); // foreach ( // string prefix in // server.Listener.Prefixes.Where( // prefix => url.StartsWith(uri.ToString(), StringComparison.OrdinalIgnoreCase))) // return new Uri(prefix); // throw new WebDavInternalServerException("Unable to find correct server root"); //} /// <summary> /// Retrieves a store item through the specified /// <see cref="Uri" /> from the /// specified /// <see cref="WebDavServer" /> and /// <see cref="IWebDavStore" />. /// </summary> /// <param name="uri">The <see cref="Uri" /> to retrieve the store item for.</param> /// <param name="store">The <see cref="IWebDavStore" /> from which to retrieve the store item.</param> /// <param name="context">Context</param> /// <returns> /// The retrieved store item. /// </returns> /// <exception cref="System.ArgumentNullException"><para> /// <paramref name="uri" /> is <c>null</c>.</para> /// <para> /// <paramref name="context" /> is <c>null</c>.</para> /// <para> /// <paramref name="store" /> is <c>null</c>.</para></exception> /// <exception cref="WebDAVSharp.Server.Exceptions.WebDavNotFoundException">If the item was not found.</exception> /// <exception cref="WebDavConflictException"><paramref name="uri" /> refers to a document in a collection, where the collection does not exist.</exception> /// <exception cref="WebDavNotFoundException"><paramref name="uri" /> refers to a document that does not exist.</exception> public static IWebDavStoreItem GetItem(this Uri uri, IWebDavStore store, IWebDavContext context) { if (uri == null) { throw new ArgumentNullException("uri"); } if (context == null) { throw new ArgumentNullException("context"); } if (store == null) { throw new ArgumentNullException("store"); } IWebDavStoreCollection collection = store.Root; IWebDavStoreItem item = null; if (context.Request.Url.Segments.Length - 1 == uri.Segments.Length) { return(collection); } //todo пути с глубиной больше рута глючат. надо дописать логику далее. for (int index = uri.Segments.Length; index < context.Request.Url.Segments.Length; index++) { string segmentName = Uri.UnescapeDataString(context.Request.Url.Segments[index]); IWebDavStoreItem nextItem = collection.GetItemByName(segmentName.TrimEnd('/', '\\')); if (nextItem == null) { throw new WebDavNotFoundException(); //throw new WebDavConflictException(); } if (index == context.Request.Url.Segments.Length - 1) { item = nextItem; } else { collection = nextItem as IWebDavStoreCollection; if (collection == null) { throw new WebDavNotFoundException(); } } } if (item == null) { throw new WebDavNotFoundException(); } return(item); }
/// <summary> /// Moves an existing store item into this collection, overwriting any existing items. /// </summary> /// <param name="source">The store item to move.</param> /// <param name="destinationName">The /// <see cref="IWebDavStoreItem" /> that refers to the item that was moved, /// in its new location.</param> /// <returns> /// The moved <see cref="IWebDavStoreItem" /> instance. /// </returns> /// <exception cref="System.Exception">Path to the source item not defined.</exception> /// <exception cref="WebDAVSharp.Server.Exceptions.WebDavUnauthorizedException">If the user is unauthorized or has no access</exception> /// <remarks> /// Note that the method should fail without creating or overwriting content in the /// target collection if the move cannot go through. /// </remarks> public IWebDavStoreItem MoveItemHere(IWebDavStoreItem source, string destinationName) { // try to get the path of the source item string sourceItemPath = ""; WebDavDiskStoreItem sourceItem = (WebDavDiskStoreItem)source; sourceItemPath = sourceItem.ItemPath; if (sourceItemPath.Equals("")) { throw new Exception("Path to the source item not defined."); } // We get the path of string destinationItemPath = Path.Combine(ItemPath, destinationName); // the moving of the item if (source.IsCollection) { try { // Impersonate the current user and move the directory WindowsImpersonationContext wic = Identity.Impersonate(); Directory.Move(sourceItemPath, destinationItemPath); wic.Undo(); } catch { throw new WebDavUnauthorizedException(); } // We return the moved file as a WebDAVDiskStoreDocument var collection = new WebDavDiskStoreCollection(this, destinationItemPath); _items.Add(destinationName, new WeakReference(collection)); return(collection); } try { // Impersonate the current user and move the file WindowsImpersonationContext wic = Identity.Impersonate(); File.Move(sourceItemPath, destinationItemPath); wic.Undo(); } catch { throw new WebDavUnauthorizedException(); } // We return the moved file as a WebDAVDiskStoreDocument WebDavDiskStoreDocument document = new WebDavDiskStoreDocument(this, destinationItemPath); _items.Add(destinationName, new WeakReference(document)); return(document); }
/// <summary> /// Processes the request. /// </summary> /// <param name="context">The /// <see cref="IWebDavContext" /> object containing both the request and response /// objects to use.</param> /// <param name="store">The <see cref="IWebDavStore" /> that the <see cref="WebDavServer" /> is hosting.</param> public void ProcessRequest(IWebDavContext context, IWebDavStore store) { // Get the parent collection of the item IWebDavStoreCollection collection = GetParentCollection(store, context, context.Request.Url); // Get the item from the collection IWebDavStoreItem item = GetItemFromCollection(collection, context.Request.Url); // Deletes the item collection.Delete(item); }
/// <summary> /// Processes the request. /// </summary> /// <param name="server">The <see cref="WebDavServer" /> through which the request came in from the client.</param> /// <param name="context">The /// <see cref="IHttpListenerContext" /> object containing both the request and response /// objects to use.</param> /// <param name="store">The <see cref="IWebDavStore" /> that the <see cref="WebDavServer" /> is hosting.</param> /// <param name="response"></param> /// <param name="request"></param> protected override void OnProcessRequest( WebDavServer server, IHttpListenerContext context, IWebDavStore store, XmlDocument request, XmlDocument response) { IWebDavStoreItem source = context.Request.Url.GetItem(server, store); MoveItem(server, context, store, source); }
/// <summary> /// Retrieves a store item through the specified /// <see cref="Uri" /> from the /// specified /// <see cref="WebDavServer" /> and /// <see cref="IWebDavStore" />. /// </summary> /// <param name="uri">The <see cref="Uri" /> to retrieve the store item for.</param> /// <param name="server">The <see cref="WebDavServer" /> that hosts the <paramref name="store" />.</param> /// <param name="store">The <see cref="IWebDavStore" /> from which to retrieve the store item.</param> /// <returns> /// The retrieved store item. /// </returns> /// <exception cref="System.ArgumentNullException"><para> /// <paramref name="uri" /> is <c>null</c>.</para> /// <para> /// <paramref name="server" /> is <c>null</c>.</para> /// <para> /// <paramref name="store" /> is <c>null</c>.</para></exception> /// <exception cref="WebDAVSharp.Server.Exceptions.WebDavNotFoundException">If the item was not found.</exception> /// <exception cref="WebDavConflictException"><paramref name="uri" /> refers to a document in a collection, where the collection does not exist.</exception> /// <exception cref="WebDavNotFoundException"><paramref name="uri" /> refers to a document that does not exist.</exception> public static IWebDavStoreItem GetItem(this Uri uri, WebDavServer server, IWebDavStore store) { if (uri == null) { throw new ArgumentNullException("uri"); } if (server == null) { throw new ArgumentNullException("server"); } if (store == null) { throw new ArgumentNullException("store"); } Uri prefixUri = uri.GetPrefixUri(server); var collection = store.Root; IWebDavStoreItem item = null; if (prefixUri.Segments.Length == uri.Segments.Length) { return(collection); } for (var index = prefixUri.Segments.Length; index < uri.Segments.Length; index++) { var segmentName = Uri.UnescapeDataString(uri.Segments[index]); var nextItem = collection.GetItemByName(segmentName.TrimEnd('/', '\\')); if (nextItem == null) { throw new WebDavNotFoundException(); //throw new WebDavConflictException(); } if (index == uri.Segments.Length - 1) { item = nextItem; } else { collection = nextItem as IWebDavStoreCollection; if (collection == null) { throw new WebDavNotFoundException(); } } } if (item == null) { throw new WebDavNotFoundException(); } return(item); }
/// <summary> /// Processes the request. /// </summary> /// <param name="server">The <see cref="WebDavServer" /> through which the request came in from the client.</param> /// <param name="context">The /// <see cref="IHttpListenerContext" /> object containing both the request and response /// objects to use.</param> /// <param name="store">The <see cref="IWebDavStore" /> that the <see cref="WebDavServer" /> is hosting.</param> public void ProcessRequest(WebDavServer server, IHttpListenerContext context, IWebDavStore store) { // Get the parent collection of the item IWebDavStoreCollection collection = GetParentCollection(server, store, context.Request.Url); // Get the item from the collection IWebDavStoreItem item = GetItemFromCollection(collection, context.Request.Url); // Deletes the item collection.Delete(item); context.SendSimpleResponse(); }
/// <summary> /// </summary> /// <param name="storeItem"></param> public void CleanLocks(IWebDavStoreItem storeItem) { lock (ObjectLocks) { if (!ObjectLocks.ContainsKey(storeItem.ItemPath)) return; foreach ( IWebDavStoreItemLockInstance ilock in ObjectLocks[storeItem.ItemPath].ToList() .Where(ilock => ilock.ExpirationDate != null && (DateTime) ilock.ExpirationDate < DateTime.Now) ) ObjectLocks[storeItem.ItemPath].Remove(ilock); } }
/// <summary> /// Processes the request. /// </summary> /// <param name="context">The /// <see cref="IHttpListenerContext" /> object containing both the request and response /// objects to use.</param> /// <param name="store">The <see cref="IWebDavStore" /> that the <see cref="WebDavServer" /> is hosting.</param> /// <exception cref="WebDAVSharp.Server.Exceptions.WebDavMethodNotAllowedException"></exception> public void ProcessRequest(IWebDavContext context, IWebDavStore store) { IWebDavStoreItem source = context.Request.Url.GetItem(store, context); if (source is IWebDavStoreDocument || source is IWebDavStoreCollection) { CopyItem(context, store, source); } else { throw new WebDavMethodNotAllowedException(); } }
/// <summary> /// Processes the request. /// </summary> /// <param name="server">The <see cref="WebDavServer" /> through which the request came in from the client.</param> /// <param name="context">The /// <see cref="IHttpListenerContext" /> object containing both the request and response /// objects to use.</param> /// <param name="store">The <see cref="IWebDavStore" /> that the <see cref="WebDavServer" /> is hosting.</param> public void ProcessRequest(WebDavServer server, IHttpListenerContext context, IWebDavStore store) { // Get the parent collection of the item IWebDavStoreCollection collection = GetParentCollection(server, store, context.Request.Url); // Get the item from the collection IWebDavStoreItem item = GetItemFromCollection(collection, context.Request.Url); /*************************************************************************************************** * Send the response ***************************************************************************************************/ context.SendSimpleResponse(HttpStatusCode.NoContent); }
/// <summary> /// Retrieves all locks for the passed object /// </summary> /// <param name="storeItem">Item to look for locks for.</param> /// <returns></returns> public override List<IWebDavStoreItemLockInstance> GetLocks(IWebDavStoreItem storeItem) { try { List<IWebDavStoreItemLockInstance> items = new List<IWebDavStoreItemLockInstance>(); using (var context = new OnlineFilesEntities()) { List<ObjectLockInfo> result; WebDavSqlStoreCollection item = storeItem as WebDavSqlStoreCollection; if (item != null) { var collection = item; result = context.ObjectLockInfoes.AsNoTracking().Where(d => d.ObjectGuid == collection.ObjectGuid && d.isFolder).ToList(); } else { WebDavSqlStoreDocument storeDocument = storeItem as WebDavSqlStoreDocument; if (storeDocument != null) { var document = storeDocument; result = context.ObjectLockInfoes.AsNoTracking().Where(d => d.ObjectGuid == document.ObjectGuid && !d.isFolder).ToList(); } else { throw new NotSupportedException(); } } items.AddRange(result.Select(lockInfo => new WebDavSqlStoreItemLockInstance( PrincipleFactory.Instance.GetPrinciple(FromType.WebDav).UserProfile, lockInfo.Path, (WebDavLockScope) lockInfo.LockScope, (WebDavLockType) lockInfo.LockType, lockInfo.Owner.ToString(), lockInfo.RequestedLockTimeout, lockInfo.Token, new XmlDocument(), lockInfo.Depth, this, lockInfo.CreateDt ))); return items; } } catch (Exception ex) { Console.WriteLine(ex.Message + ex.StackTrace); throw; } }
/// <summary> /// Retrieves all locks for the passed object /// </summary> /// <param name="storeItem">Item to look for locks for.</param> /// <returns></returns> public override List <IWebDavStoreItemLockInstance> GetLocks(IWebDavStoreItem storeItem) { try { List <IWebDavStoreItemLockInstance> items = new List <IWebDavStoreItemLockInstance>(); using (var context = new OnlineFilesEntities()) { List <ObjectLockInfo> result; WebDavSqlStoreCollection item = storeItem as WebDavSqlStoreCollection; if (item != null) { var collection = item; result = context.ObjectLockInfoes.AsNoTracking().Where(d => d.ObjectGuid == collection.ObjectGuid && d.isFolder).ToList(); } else { WebDavSqlStoreDocument storeDocument = storeItem as WebDavSqlStoreDocument; if (storeDocument != null) { var document = storeDocument; result = context.ObjectLockInfoes.AsNoTracking().Where(d => d.ObjectGuid == document.ObjectGuid && !d.isFolder).ToList(); } else { throw new NotSupportedException(); } } items.AddRange(result.Select(lockInfo => new WebDavSqlStoreItemLockInstance( PrincipleFactory.Instance.GetPrinciple(FromType.WebDav).UserProfile, lockInfo.Path, (WebDavLockScope)lockInfo.LockScope, (WebDavLockType)lockInfo.LockType, lockInfo.Owner.ToString(), lockInfo.RequestedLockTimeout, lockInfo.Token, new XmlDocument(), lockInfo.Depth, this, lockInfo.CreateDt ))); return(items); } } catch (Exception ex) { Console.WriteLine(ex.Message + ex.StackTrace); throw; } }
/// <summary> /// Processes the request. /// </summary> /// <param name="context">The /// <see cref="IWebDavContext" /> object containing both the request and response /// objects to use.</param> /// <param name="store">The <see cref="IWebDavStore" /> that the <see cref="WebDavServer" /> is hosting.</param> /// <exception cref="WebDAVSharp.Server.Exceptions.WebDavNotFoundException"></exception> /// <exception cref="WebDavNotFoundException"><para> /// <paramref name="context" /> specifies a request for a store item that does not exist.</para> /// <para>- or -</para> /// <para> /// <paramref name="context" /> specifies a request for a store item that is not a document.</para></exception> /// <exception cref="WebDavConflictException"><paramref name="context" /> specifies a request for a store item using a collection path that does not exist.</exception> public void ProcessRequest(IWebDavContext context, IWebDavStore store) { IWebDavStoreCollection collection = GetParentCollection(store, context, context.Request.Url); IWebDavStoreItem item = GetItemFromCollection(collection, context.Request.Url); IWebDavStoreDocument doc = item as IWebDavStoreDocument; if (doc == null) { throw new WebDavNotFoundException(); } long docSize = doc.Size; if (docSize == 0) { context.Response.StatusCode = (int)HttpStatusCode.OK; context.Response.ContentLength64 = 0; } using (Stream stream = doc.OpenReadStream()) { if (stream == null) { context.Response.StatusCode = (int)HttpStatusCode.OK; context.Response.ContentLength64 = 0; } else { context.Response.StatusCode = (int)HttpStatusCode.OK; //todo Это статика. Надо определять MIME тип по расширению context.Response.AppendHeader("Content-type", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"); if (docSize > 0) { context.Response.ContentLength64 = docSize; } byte[] buffer = new byte[4096]; int inBuffer; while ((inBuffer = stream.Read(buffer, 0, buffer.Length)) > 0) { context.Response.OutputStream.Write(buffer, 0, inBuffer); } context.Response.OutputStream.Flush(); } } }
/// <summary> /// Processes the request. /// </summary> /// <param name="server">The <see cref="WebDavServer" /> through which the request came in from the client.</param> /// <param name="context">The /// <see cref="IHttpListenerContext" /> object containing both the request and response /// objects to use.</param> /// <param name="store">The <see cref="IWebDavStore" /> that the <see cref="WebDavServer" /> is hosting.</param> /// <exception cref="WebDAVSharp.Server.Exceptions.WebDavMethodNotAllowedException"></exception> /// <exception cref="WebDAVSharp.Server.Exceptions.WebDavLengthRequiredException">If the ContentLength header was not found</exception> public void ProcessRequest(WebDavServer server, IHttpListenerContext context, IWebDavStore store) { // Get the parent collection IWebDavStoreCollection parentCollection = GetParentCollection(server, store, context.Request.Url); // Gets the item name from the url string itemName = Uri.UnescapeDataString(context.Request.Url.Segments.Last().TrimEnd('/', '\\')); IWebDavStoreItem item = parentCollection.GetItemByName(itemName); IWebDavStoreDocument doc; if (item != null) { doc = item as IWebDavStoreDocument; if (doc == null) { throw new WebDavMethodNotAllowedException(); } } else { doc = parentCollection.CreateDocument(itemName); } if (context.Request.ContentLength64 < 0) { throw new WebDavLengthRequiredException(); } using (Stream stream = doc.OpenWriteStream(false)) { long left = context.Request.ContentLength64; byte[] buffer = new byte[4096]; while (left > 0) { int toRead = Convert.ToInt32(Math.Min(left, buffer.Length)); int inBuffer = context.Request.InputStream.Read(buffer, 0, toRead); stream.Write(buffer, 0, inBuffer); left -= inBuffer; } } context.SendSimpleResponse(HttpStatusCode.Created); }
/// <summary> /// Gets the correct value for a <see cref="WebDavProperty" /> /// </summary> /// <param name="webDavStoreItem">The <see cref="IWebDavStoreItem" /> defines the values</param> /// <param name="davProperty">The <see cref="WebDavProperty" /> that needs a value</param> /// <returns> /// A <see cref="string" /> containing the value /// </returns> private string GetWebDavPropertyValue(IWebDavStoreItem webDavStoreItem, WebDavProperty davProperty) { switch (davProperty.Name) { case "creationdate": return(webDavStoreItem.CreationDate.ToUniversalTime().ToString("s") + "Z"); case "displayname": return(webDavStoreItem.Name); case "getcontentlanguage": // still to implement !!! return(String.Empty); case "getcontentlength": return(!webDavStoreItem.IsCollection ? "" + ((IWebDavStoreDocument)webDavStoreItem).Size : ""); case "getcontenttype": return(!webDavStoreItem.IsCollection ? "" + ((IWebDavStoreDocument)webDavStoreItem).MimeType : ""); case "getetag": return(!webDavStoreItem.IsCollection ? "" + ((IWebDavStoreDocument)webDavStoreItem).Etag : ""); case "getlastmodified": return(webDavStoreItem.ModificationDate.ToUniversalTime().ToString("R")); case "lockdiscovery": // still to implement !!! return(String.Empty); case "resourcetype": return(""); case "supportedlock": // still to implement !!! return(""); //webDavProperty.Value = "<D:lockentry><D:lockscope><D:shared/></D:lockscope><D:locktype><D:write/></D:locktype></D:lockentry>"; case "ishidden": return("" + webDavStoreItem.Hidden); default: return(String.Empty); } }
/// <summary> /// </summary> /// <param name="item"></param> public void Delete(IWebDavStoreItem item) { #if DEBUG Log.Info("Deleting Item: " + item.Name); #endif if (IsCheckedOut(item)) { throw new Exception("Item is checked out."); } using (var context = new OnlineFilesEntities()) { var collection = item as WebDavSqlStoreCollection; if (collection != null) { Folder folder = context.Folders.FirstOrDefault(d => d.pk_FolderId == collection.ObjectGuid); if (folder == null) { throw new WebDavNotFoundException("Folder Not Found."); } folder.SetDeleted(PrincipleFactory.Instance.GetPrinciple(FromType.WebDav).UserProfile); context.SaveChanges(); WebDavSqlStoreCollectionFactory.Instance.InvalidateCollection(item.ItemPath); WebDavSqlStoreCollectionFactory.Instance.InvalidateCollection(ItemPath); } else { WebDavSqlStoreDocument document = item as WebDavSqlStoreDocument; if (document == null) { return; } var doc = document; File file = context.Files.FirstOrDefault(d => d.pk_FileId == doc.ObjectGuid); if (file == null) { throw new WebDavNotFoundException("Folder Not Found."); } file.SetDeleted(PrincipleFactory.Instance.GetPrinciple(FromType.WebDav).UserProfile); context.SaveChanges(); WebDavSqlStoreCollectionFactory.Instance.InvalidateCollection(ItemPath); WebDavSqlStoreDocumentFactory.Instance.InvalidateDocumentPath(doc.ItemPath); } } }
/// <summary> /// Processes the request. /// </summary> /// <param name="server">The <see cref="WebDavServer" /> through which the request came in from the client.</param> /// <param name="context">The /// <see cref="IHttpListenerContext" /> object containing both the request and response /// objects to use.</param> /// <param name="request"></param> /// <param name="response"></param> /// <param name="store">The <see cref="IWebDavStore" /> that the <see cref="WebDavServer" /> is hosting.</param> /// <exception cref="WebDAVSharp.Server.Exceptions.WebDavMethodNotAllowedException"></exception> protected override void OnProcessRequest( WebDavServer server, IHttpListenerContext context, IWebDavStore store, XmlDocument request, XmlDocument response) { IWebDavStoreItem source = context.Request.Url.GetItem(server, store); if (source is IWebDavStoreDocument || source is IWebDavStoreCollection) { CopyItem(server, context, store, source); } else { throw new WebDavMethodNotAllowedException(); } }
/// <summary> /// </summary> /// <param name="source"></param> /// <param name="destinationName"></param> /// <returns></returns> public IWebDavStoreItem MoveItemHere(IWebDavStoreItem source, string destinationName) { //this -> is where it wants to be moved to. //source is the item //destination name is the name they want it to be. IWebDavStoreItem returnitem; using (var context = new OnlineFilesEntities()) { var sourceFolder = source as WebDavSqlStoreCollection; if (sourceFolder != null) { Folder targetFolder = context.Folders.FirstOrDefault(d => d.pk_FolderId == sourceFolder.ObjectGuid); if (targetFolder == null) { return(null); } Folder destination = context.Folders.FirstOrDefault(d => d.pk_FolderId == ObjectGuid); destination.MoveFolderHere(targetFolder.pk_FolderId, destinationName, PrincipleFactory.Instance.GetPrinciple(FromType.WebDav)); context.SaveChanges(); WebDavSqlStoreCollectionFactory.Instance.InvalidateCollection(ItemPath); WebDavSqlStoreCollectionFactory.Instance.InvalidateCollection(sourceFolder.ItemPath); WebDavSqlStoreCollectionFactory.Instance.InvalidateCollection(Path.Combine(ItemPath, destinationName)); returnitem = WebDavSqlStoreCollectionFactory.Instance.GetCollection(this, Path.Combine(ItemPath, destinationName), RootPath, RootGuid); } else { WebDavSqlStoreDocument document = source as WebDavSqlStoreDocument; if (document == null) { return(null); } WebDavSqlStoreDocument doc = document; var destFolder = context.Folders.FirstOrDefault(d => d.pk_FolderId == ObjectGuid); destFolder.MoveFileHere((Guid)document.ObjectGuid, destinationName, PrincipleFactory.Instance.GetPrinciple(FromType.WebDav)); WebDavSqlStoreDocumentFactory.Instance.InvalidateDocumentPath(Path.Combine(ItemPath, destinationName)); WebDavSqlStoreCollectionFactory.Instance.InvalidateCollection(ItemPath); returnitem = WebDavSqlStoreDocumentFactory.Instance.GetDocument(this, Path.Combine(ItemPath, destinationName), RootPath, RootGuid); } } return(returnitem); }
/// <summary> /// Deletes a store item by its name. /// </summary> /// <param name="item">The name of the store item to delete.</param> /// <exception cref="WebDAVSharp.Server.Exceptions.WebDavNotFoundException">If the item was not found.</exception> /// <exception cref="WebDAVSharp.Server.Exceptions.WebDavUnauthorizedException">If the user is unauthorized or has no access.</exception> public void Delete(IWebDavStoreItem item) { WebDavDiskStoreItem diskItem = (WebDavDiskStoreItem)item; string itemPath = diskItem.ItemPath; if (item is WebDavDiskStoreDocument) { if (!File.Exists(itemPath)) { throw new WebDavNotFoundException(); } try { // Impersonate the current user and delete the file WindowsImpersonationContext wic = Identity.Impersonate(); File.Delete(itemPath); wic.Undo(); } catch { throw new WebDavUnauthorizedException(); } } else { if (!Directory.Exists(itemPath)) { throw new WebDavNotFoundException(); } try { // Impersonate the current user and delete the directory WindowsImpersonationContext wic = Identity.Impersonate(); Directory.Delete(diskItem.ItemPath); wic.Undo(); } catch { throw new WebDavUnauthorizedException(); } } }
/// <summary> /// Processes the request. /// </summary> /// <param name="server">The <see cref="WebDavServer" /> through which the request came in from the client.</param> /// <param name="context">The /// <see cref="IHttpListenerContext" /> object containing both the request and response /// objects to use.</param> /// <param name="response"></param> /// <param name="request"></param> /// <param name="store">The <see cref="IWebDavStore" /> that the <see cref="WebDavServer" /> is hosting.</param> protected override void OnProcessRequest( WebDavServer server, IHttpListenerContext context, IWebDavStore store, XmlDocument request, XmlDocument response) { // Get the parent collection of the item IWebDavStoreCollection collection = GetParentCollection(server, store, context.Request.Url); // Get the item from the collection IWebDavStoreItem item = GetItemFromCollection(collection, context.Request.Url); // Deletes the item collection.Delete(item); //do not forget to clear all locks, if the object gets deleted there is no need to keep locks around. WebDavStoreItemLock.ClearLocks(context.Request.Url); context.SendSimpleResponse(); }
/// <summary> /// Processes the request. /// </summary> /// <param name="context">The /// <see cref="IWebDavContext" /> object containing both the request and response /// objects to use.</param> /// <param name="store">The <see cref="IWebDavStore" /> that the <see cref="WebDavServer" /> is hosting.</param> /// <exception cref="WebDavNotFoundException"><para> /// <paramref name="context" /> specifies a request for a store item that does not exist.</para> /// <para>- or -</para> /// <para> /// <paramref name="context" /> specifies a request for a store item that is not a document.</para></exception> /// <exception cref="WebDavConflictException"><paramref name="context" /> specifies a request for a store item using a collection path that does not exist.</exception> public void ProcessRequest(IWebDavContext context, IWebDavStore store) { // Get the parent collection of the item IWebDavStoreCollection collection = GetParentCollection(store, context, context.Request.Url); // Get the item from the collection IWebDavStoreItem item = GetItemFromCollection(collection, context.Request.Url); /*************************************************************************************************** * Send the response ***************************************************************************************************/ // HttpStatusCode doesn't contain WebDav status codes, but HttpWorkerRequest can handle these WebDav status codes context.SetStatusCode(); // set the headers of the response context.Response.ContentLength64 = 0; context.Response.AppendHeader("Content-Type", "text/html"); context.Response.AppendHeader("Last-Modified", item.ModificationDate.ToUniversalTime().ToString("R")); }
/// <summary> /// Refreshes an existing lock /// </summary> /// <param name="storeItem"></param> /// <param name="locktoken"></param> /// <param name="requestedlocktimeout"></param> /// <param name="requestDocument"></param> /// <returns></returns> public override int RefreshLock(IWebDavStoreItem storeItem, Guid?locktoken, double?requestedlocktimeout, out XmlDocument requestDocument) { try { CleanLocks(); requestDocument = null; if (locktoken == null) { throw new WebDavNotFoundException("Must have a lock to refresh."); } using (var context = new OnlineFilesEntities()) { var info = context.ObjectLockInfoes.FirstOrDefault(d => d.Token == locktoken); if (info == null) { throw new WebDavNotFoundException("Lock Token Not Found."); } IWebDavStoreItemLockInstance inst = new WebDavSqlStoreItemLockInstance( PrincipleFactory.Instance.GetPrinciple(FromType.WebDav).UserProfile, info.Path, (WebDavLockScope)info.LockScope, (WebDavLockType)info.LockType, info.Owner.ToString(), info.RequestedLockTimeout, info.Token, new XmlDocument(), info.Depth, this, info.CreateDt ); inst.RefreshLock(requestedlocktimeout); info.CreateDt = inst.CreateDate; info.ExpirationDate = inst.ExpirationDate; info.RequestedLockTimeout = inst.RequestedLockTimeout; context.SaveChanges(); requestDocument = new XmlDocument(); return((int)HttpStatusCode.OK); } } catch (Exception ex) { Console.WriteLine(ex.Message + ex.StackTrace); throw; } }
/// <summary> /// Convert the given /// <see cref="IWebDavStoreItem" /> to a /// <see cref="List{T}" /> of /// <see cref="IWebDavStoreItem" /> /// This list depends on the "Depth" header /// </summary> /// <param name="iWebDavStoreItem">The <see cref="IWebDavStoreItem" /> that needs to be converted</param> /// <param name="depth">The "Depth" header</param> /// <returns> /// A <see cref="List{T}" /> of <see cref="IWebDavStoreItem" /> /// </returns> /// <exception cref="WebDAVSharp.Server.Exceptions.WebDavConflictException"></exception> private static List <IWebDavStoreItem> GetWebDavStoreItems(IWebDavStoreItem iWebDavStoreItem, int depth) { //ILog _log = LogManager.GetCurrentClassLogger(); var _log = LogManager.GetLogger(typeof(WebDavPropfindMethodHandler).Name); var list = new List <IWebDavStoreItem>(); //IWebDavStoreCollection // if the item is a collection var collection = iWebDavStoreItem as IWebDavStoreCollection; if (collection != null) { list.Add(collection); if (depth == 0) { return(list); } foreach (var item in collection.Items) { try { list.Add(item); } catch (Exception ex) { _log.Debug(ex.Message + "\r\n" + ex.StackTrace); } } return(list); } // if the item is not a document, throw conflict exception if (!(iWebDavStoreItem is IWebDavStoreDocument)) { throw new WebDavConflictException(); } // add the item to the list list.Add(iWebDavStoreItem); return(list); }
public bool IsCheckedOut(IWebDavStoreItem item) { using (var context = new OnlineFilesEntities()) { List <SpDoAnyChildrenHaveLocksResult> cellData = context.Database.SqlQuery <SpDoAnyChildrenHaveLocksResult> ($"dbo.sp_DoAnyChildrenHaveLocks '{((WebDavSqlStoreItem) item).ObjectGuid}'").ToList(); if (cellData.Any()) { if (cellData[0].Exists) { return(true); } } else { throw new WebDavNotFoundException("Shouldn't get here."); } return(false); } }
/// <summary> /// </summary> /// <param name="item"></param> public void Delete(IWebDavStoreItem item) { #if DEBUG Log.Info("Deleting Item: " + item.Name); #endif if (IsCheckedOut(item)) throw new Exception("Item is checked out."); using (var context = new OnlineFilesEntities()) { var collection = item as WebDavSqlStoreCollection; if (collection != null) { Folder folder = context.Folders.FirstOrDefault(d => d.pk_FolderId == collection.ObjectGuid); if (folder == null) throw new WebDavNotFoundException("Folder Not Found."); folder.SetDeleted(PrincipleFactory.Instance.GetPrinciple(FromType.WebDav).UserProfile); context.SaveChanges(); WebDavSqlStoreCollectionFactory.Instance.InvalidateCollection(item.ItemPath); WebDavSqlStoreCollectionFactory.Instance.InvalidateCollection(ItemPath); } else { WebDavSqlStoreDocument document = item as WebDavSqlStoreDocument; if (document == null) return; var doc = document; File file = context.Files.FirstOrDefault(d => d.pk_FileId == doc.ObjectGuid); if (file == null) throw new WebDavNotFoundException("Folder Not Found."); file.SetDeleted(PrincipleFactory.Instance.GetPrinciple(FromType.WebDav).UserProfile); context.SaveChanges(); WebDavSqlStoreCollectionFactory.Instance.InvalidateCollection(ItemPath); WebDavSqlStoreDocumentFactory.Instance.InvalidateDocumentPath(doc.ItemPath); } } }
/// <summary> /// Unlocks the URI passed if the token matches a lock token in use. /// </summary> /// <param name="storeItem">URI to resource</param> /// <param name="locktoken">Token used to lock.</param> /// <param name="owner">Owner.</param> /// <returns></returns> public override int UnLock(IWebDavStoreItem storeItem, Guid? locktoken, string owner) { CleanLocks(storeItem); if (locktoken == null) { #if DEBUG WebDavServer.Log.Debug("Unlock failed, No Token!."); #endif return (int) HttpStatusCode.BadRequest; } lock (ObjectLocks) { if (!ObjectLocks.ContainsKey(storeItem.ItemPath)) { #if DEBUG WebDavServer.Log.Debug("Unlock failed, Lock does not exist!."); #endif return (int) HttpStatusCode.Conflict; } WebDavStoreItemLockInstance ilock = (WebDavStoreItemLockInstance) ObjectLocks[storeItem.ItemPath].FirstOrDefault(d => d.Token == locktoken && d.Owner == owner); if (ilock == null) return (int) HttpStatusCode.Conflict; //Remove the lock ObjectLocks[storeItem.ItemPath].Remove(ilock); //if there are no locks left of the uri then remove it from ObjectLocks. if (ObjectLocks[storeItem.ItemPath].Count == 0) ObjectLocks.Remove(storeItem.ItemPath); #if DEBUG WebDavServer.Log.Debug("Unlock successful."); #endif return (int) HttpStatusCode.NoContent; } }
/// <summary> /// Refreshes an existing lock /// </summary> /// <param name="storeItem"></param> /// <param name="locktoken"></param> /// <param name="requestedlocktimeout"></param> /// <param name="requestDocument"></param> /// <returns></returns> public override int RefreshLock(IWebDavStoreItem storeItem, Guid? locktoken, double? requestedlocktimeout, out XmlDocument requestDocument) { try { CleanLocks(); requestDocument = null; if (locktoken == null) throw new WebDavNotFoundException("Must have a lock to refresh."); using (var context = new OnlineFilesEntities()) { var info = context.ObjectLockInfoes.FirstOrDefault(d => d.Token == locktoken); if (info == null) throw new WebDavNotFoundException("Lock Token Not Found."); IWebDavStoreItemLockInstance inst = new WebDavSqlStoreItemLockInstance( PrincipleFactory.Instance.GetPrinciple(FromType.WebDav).UserProfile, info.Path, (WebDavLockScope) info.LockScope, (WebDavLockType) info.LockType, info.Owner.ToString(), info.RequestedLockTimeout, info.Token, new XmlDocument(), info.Depth, this, info.CreateDt ); inst.RefreshLock(requestedlocktimeout); info.CreateDt = inst.CreateDate; info.ExpirationDate = inst.ExpirationDate; info.RequestedLockTimeout = inst.RequestedLockTimeout; context.SaveChanges(); requestDocument = new XmlDocument(); return (int) HttpStatusCode.OK; } } catch (Exception ex) { Console.WriteLine(ex.Message + ex.StackTrace); throw; } }
/// <summary> /// Gets the correct value for a <see cref="WebDavProperty" /> /// </summary> /// <param name="webDavStoreItem">The <see cref="IWebDavStoreItem" /> defines the values</param> /// <param name="davProperty">The <see cref="WebDavProperty" /> that needs a value</param> /// <returns> /// A <see cref="string" /> containing the value /// </returns> private static string GetWebDavPropertyValue(IWebDavStoreItem webDavStoreItem, WebDavProperty davProperty) { switch (davProperty.Name) { case "creationdate": return webDavStoreItem.CreationDate.ToUniversalTime().ToString("s") + "Z"; case "displayname": return webDavStoreItem.Name; case "getcontentlanguage": //todo getcontentlanguage return String.Empty; case "getcontentlength": return (!webDavStoreItem.IsCollection ? "" + ((IWebDavStoreDocument)webDavStoreItem).Size : string.Empty); case "getcontenttype": return (!webDavStoreItem.IsCollection ? "" + ((IWebDavStoreDocument)webDavStoreItem).MimeType : string.Empty); case "getetag": return (!webDavStoreItem.IsCollection ? "" + ((IWebDavStoreDocument)webDavStoreItem).Etag : string.Empty); case "getlastmodified": return webDavStoreItem.ModificationDate.ToUniversalTime().ToString("R"); case "resourcetype": //todo Add resourceType return ""; case "ishidden": return webDavStoreItem.Hidden.ToString(CultureInfo.InvariantCulture); default: return String.Empty; } }
/// <summary> /// Copies an existing store item into this collection, overwriting any existing items. /// </summary> /// <param name="source">The store item to copy from.</param> /// <param name="destinationName">The name of the copy to create of <paramref name="source" />.</param> /// <param name="includeContent">The boolean for copying the containing files/folders or not.</param> /// <returns> /// The created <see cref="IWebDavStoreItem" /> instance. /// </returns> /// <exception cref="WebDAVSharp.Server.Exceptions.WebDavUnauthorizedException">If the user is unauthorized or has no access</exception> public IWebDavStoreItem CopyItemHere(IWebDavStoreItem source, string destinationName, bool includeContent) { // We get the path of string destinationItemPath = Path.Combine(ItemPath, destinationName); // the moving of the item if (source.IsCollection) { try { // Impersonate the current user and move the directory WindowsImpersonationContext wic = Identity.Impersonate(); DirectoryCopy(source.ItemPath, destinationItemPath, true); wic.Undo(); } catch { throw new WebDavUnauthorizedException(); } // We return the moved file as a WebDAVDiskStoreDocument WebDavDiskStoreCollection collection = new WebDavDiskStoreCollection(this, destinationItemPath); _items.Add(destinationName, new WeakReference(collection)); return collection; } // We copy the file with an override. try { // Impersonate the current user and copy the file WindowsImpersonationContext wic = Identity.Impersonate(); File.Copy(source.ItemPath, destinationItemPath, true); wic.Undo(); } catch { throw new WebDavUnauthorizedException(); } // We return the moved file as a WebDAVDiskStoreDocument WebDavDiskStoreDocument document = new WebDavDiskStoreDocument(this, destinationItemPath); _items.Add(destinationName, new WeakReference(document)); return document; }
/// <summary> /// Convert the given /// <see cref="IWebDavStoreItem" /> to a /// <see cref="List{T}" /> of /// <see cref="IWebDavStoreItem" /> /// This list depends on the "Depth" header /// </summary> /// <param name="iWebDavStoreItem">The <see cref="IWebDavStoreItem" /> that needs to be converted</param> /// <param name="depth">The "Depth" header</param> /// <returns> /// A <see cref="List{T}" /> of <see cref="IWebDavStoreItem" /> /// </returns> /// <exception cref="WebDAVSharp.Server.Exceptions.WebDavConflictException"></exception> private HashSet<IWebDavStoreItem> GetWebDavStoreItems(IWebDavStoreItem iWebDavStoreItem, int depth) { HashSet<IWebDavStoreItem> list = new HashSet<IWebDavStoreItem>(); //IWebDavStoreCollection // if the item is a collection IWebDavStoreCollection collection = iWebDavStoreItem as IWebDavStoreCollection; if (collection != null) { list.Add(collection); if (depth == 0) return list; foreach (var item in collection.Items) { list.Add(item); } return list; } // if the item is not a document, throw conflict exception if (!(iWebDavStoreItem is IWebDavStoreDocument)) throw new WebDavConflictException(String.Format("Web dav item is not a document nor a collection: {0} depth {1}", iWebDavStoreItem.ItemPath, depth)); // add the item to the list list.Add(iWebDavStoreItem); return list; }
/// <summary> /// </summary> /// <param name="storeItem"></param> /// <param name="locktoken"></param> /// <param name="owner"></param> /// <returns></returns> public virtual int UnLock(IWebDavStoreItem storeItem, Guid? locktoken, string owner) { throw new NotImplementedException(); }
/// <summary> /// unlocks an existing lock /// </summary> /// <param name="storeItem"></param> /// <param name="locktoken"></param> /// <param name="owner"></param> /// <returns></returns> public override int UnLock(IWebDavStoreItem storeItem, Guid? locktoken, string owner) { try { CleanLocks(); if (locktoken == null) { //#if DEBUG // WebDavServer.Log.Debug("Unlock failed, No Token!."); //#endif return (int) HttpStatusCode.BadRequest; } using (var context = new OnlineFilesEntities()) { var info = context.ObjectLockInfoes.FirstOrDefault(d => d.Token == locktoken); if (info == null) throw new WebDavNotFoundException("Lock Token Not Found."); if (info.OwnerId != PrincipleFactory.Instance.GetPrinciple(FromType.WebDav).UserProfile.SecurityObjectId) throw new WebDavUnauthorizedException("You did not create the lock."); context.ObjectLockInfoes.Remove(info); context.SaveChanges(); return (int) HttpStatusCode.NoContent; } } catch (Exception ex) { Console.WriteLine(ex.Message + ex.StackTrace); throw; } }
/// <summary> /// </summary> /// <param name="storeItem"></param> /// <returns></returns> public virtual List<IWebDavStoreItemLockInstance> GetLocks(IWebDavStoreItem storeItem) { throw new NotImplementedException(); }
public bool IsCheckedOut(IWebDavStoreItem item) { using (var context = new OnlineFilesEntities()) { List<SpDoAnyChildrenHaveLocksResult> cellData = context.Database.SqlQuery<SpDoAnyChildrenHaveLocksResult> ($"dbo.sp_DoAnyChildrenHaveLocks '{((WebDavSqlStoreItem) item).ObjectGuid}'").ToList(); if (cellData.Any()) { if (cellData[0].Exists) return true; } else throw new WebDavNotFoundException("Shouldn't get here."); return false; } }
/// <summary> /// Convert the given /// <see cref="IWebDavStoreItem" /> to a /// <see cref="List{T}" /> of /// <see cref="IWebDavStoreItem" /> /// This list depends on the "Depth" header /// </summary> /// <param name="iWebDavStoreItem">The <see cref="IWebDavStoreItem" /> that needs to be converted</param> /// <param name="depth">The "Depth" header</param> /// <returns> /// A <see cref="List{T}" /> of <see cref="IWebDavStoreItem" /> /// </returns> /// <exception cref="WebDAVSharp.Server.Exceptions.WebDavConflictException"></exception> private static List<IWebDavStoreItem> GetWebDavStoreItems(IWebDavStoreItem iWebDavStoreItem, int depth) { List<IWebDavStoreItem> list = new List<IWebDavStoreItem>(); // if the item is a collection IWebDavStoreCollection collection = iWebDavStoreItem as IWebDavStoreCollection; if (collection != null) { list.Add(collection); if (depth == 0) return list; foreach (IWebDavStoreItem item in collection.Items.Where(item => !list.Contains(item))) list.Add(item); return list; } // if the item is not a document, throw conflict exception if (!(iWebDavStoreItem is IWebDavStoreDocument)) throw new WebDavConflictException(); // add the item to the list list.Add(iWebDavStoreItem); return list; }
/// <summary> /// Deletes a store item by its name. /// </summary> /// <param name="item">The name of the store item to delete.</param> /// <exception cref="WebDAVSharp.Server.Exceptions.WebDavNotFoundException">If the item was not found.</exception> /// <exception cref="WebDAVSharp.Server.Exceptions.WebDavUnauthorizedException">If the user is unauthorized or has no access.</exception> public void Delete(IWebDavStoreItem item) { WebDavDiskStoreItem diskItem = (WebDavDiskStoreItem)item; string itemPath = diskItem.ItemPath; if (item is WebDavDiskStoreDocument) { if (!File.Exists(itemPath)) throw new WebDavNotFoundException(); try { // Impersonate the current user and delete the file WindowsImpersonationContext wic = Identity.Impersonate(); File.Delete(itemPath); wic.Undo(); } catch { throw new WebDavUnauthorizedException(); } } else { if (!Directory.Exists(itemPath)) throw new WebDavNotFoundException(); try { // Impersonate the current user and delete the directory WindowsImpersonationContext wic = Identity.Impersonate(); Directory.Delete(diskItem.ItemPath); wic.Undo(); } catch { throw new WebDavUnauthorizedException(); } } }
/// <summary> /// Convert the given /// <see cref="IWebDavStoreItem" /> to a /// <see cref="List{T}" /> of /// <see cref="IWebDavStoreItem" /> /// This list depends on the "Depth" header /// </summary> /// <param name="iWebDavStoreItem">The <see cref="IWebDavStoreItem" /> that needs to be converted</param> /// <param name="depth">The "Depth" header</param> /// <returns> /// A <see cref="List{T}" /> of <see cref="IWebDavStoreItem" /> /// </returns> /// <exception cref="WebDAVSharp.Server.Exceptions.WebDavConflictException"></exception> private static List<IWebDavStoreItem> GetWebDavStoreItems(IWebDavStoreItem iWebDavStoreItem, int depth) { ILog _log = LogManager.GetCurrentClassLogger(); List<IWebDavStoreItem> list = new List<IWebDavStoreItem>(); //IWebDavStoreCollection // if the item is a collection IWebDavStoreCollection collection = iWebDavStoreItem as IWebDavStoreCollection; if (collection != null) { list.Add(collection); if (depth == 0) return list; foreach (IWebDavStoreItem item in collection.Items) { try { list.Add(item); } catch (Exception ex) { _log.Debug(ex.Message + "\r\n" + ex.StackTrace); } } return list; } // if the item is not a document, throw conflict exception if (!(iWebDavStoreItem is IWebDavStoreDocument)) throw new WebDavConflictException(); // add the item to the list list.Add(iWebDavStoreItem); return list; }
/// <summary> /// Moves an existing store item into this collection, overwriting any existing items. /// </summary> /// <param name="source">The store item to move.</param> /// <param name="destinationName">The /// <see cref="IWebDavStoreItem" /> that refers to the item that was moved, /// in its new location.</param> /// <returns> /// The moved <see cref="IWebDavStoreItem" /> instance. /// </returns> /// <exception cref="System.Exception">Path to the source item not defined.</exception> /// <exception cref="WebDAVSharp.Server.Exceptions.WebDavUnauthorizedException">If the user is unauthorized or has no access</exception> /// <remarks> /// Note that the method should fail without creating or overwriting content in the /// target collection if the move cannot go through. /// </remarks> public IWebDavStoreItem MoveItemHere(IWebDavStoreItem source, string destinationName) { // try to get the path of the source item WebDavDiskStoreItem sourceItem = (WebDavDiskStoreItem)source; string sourceItemPath = sourceItem.ItemPath; if (sourceItemPath.Equals(string.Empty)) { throw new Exception("Path to the source item not defined."); } // We get the path of string destinationItemPath = Path.Combine(ItemPath, destinationName); // the moving of the item if (source.IsCollection) { try { // Impersonate the current user and move the directory WindowsImpersonationContext wic = Identity.Impersonate(); Directory.Move(sourceItemPath, destinationItemPath); wic.Undo(); } catch { throw new WebDavUnauthorizedException(); } // We return the moved file as a WebDAVDiskStoreDocument var collection = new WebDavDiskStoreCollection(this, destinationItemPath); _items.Add(destinationName, new WeakReference(collection)); return collection; } try { // Impersonate the current user and move the file WindowsImpersonationContext wic = Identity.Impersonate(); File.Move(sourceItemPath, destinationItemPath); wic.Undo(); } catch { throw new WebDavUnauthorizedException(); } // We return the moved file as a WebDAVDiskStoreDocument WebDavDiskStoreDocument document = new WebDavDiskStoreDocument(this, destinationItemPath); _items.Add(destinationName, new WeakReference(document)); return document; }
/// <summary> /// Gives the /// <see cref="XmlElement" /> of a /// <see cref="WebDavProperty" /> /// with or without values /// or with or without child elements /// </summary> /// <param name="webDavProperty">The <see cref="WebDavProperty" /></param> /// <param name="xmlDocument">The <see cref="XmlDocument" /> containing the response body</param> /// <param name="iWebDavStoreItem">The <see cref="IWebDavStoreItem" /></param> /// <param name="isPropname">The boolean defining the Propfind propname request</param> /// <returns> /// The <see cref="XmlElement" /> of the <see cref="WebDavProperty" /> containing a value or child elements /// </returns> private static XmlElement PropChildElement(WebDavProperty webDavProperty, XmlDocument xmlDocument, IWebDavStoreItem iWebDavStoreItem, bool isPropname) { // If Propfind request contains a propname element if (isPropname) { webDavProperty.Value = Empty; return webDavProperty.ToXmlElement(xmlDocument); } // If not, add the values to webDavProperty webDavProperty.Value = GetWebDavPropertyValue(iWebDavStoreItem, webDavProperty); if (webDavProperty.Value == null) return null; XmlElement xmlElement = webDavProperty.ToXmlElement(xmlDocument); // If the webDavProperty is the resourcetype property // and the webDavStoreItem is a collection // add the collection XmlElement as a child to the xmlElement if (!webDavProperty.Name.Equals("resourcetype", StringComparison.InvariantCultureIgnoreCase) || !iWebDavStoreItem.IsCollection) return xmlElement; WebDavProperty collectionProperty = new WebDavProperty("collection", Empty); xmlElement.AppendChild(collectionProperty.ToXmlElement(xmlDocument)); return xmlElement; }
/// <summary> /// </summary> /// <param name="storeItem"></param> /// <param name="locktoken"></param> /// <param name="requestedlocktimeout"></param> /// <param name="requestDocument"></param> /// <returns></returns> public virtual int RefreshLock(IWebDavStoreItem storeItem, Guid? locktoken, double? requestedlocktimeout, out XmlDocument requestDocument) { throw new NotImplementedException(); }
/// <summary> /// Gets the correct value for a <see cref="WebDavProperty" /> /// </summary> /// <param name="webDavStoreItem">The <see cref="IWebDavStoreItem" /> defines the values</param> /// <param name="davProperty">The <see cref="WebDavProperty" /> that needs a value</param> /// <returns> /// A <see cref="string" /> containing the value /// </returns> private static string GetWebDavPropertyValue(IWebDavStoreItem webDavStoreItem, WebDavProperty davProperty) { if (webDavStoreItem is IWebDavStoreCollection && davProperty.StoreItemType == WebDavProperty.StoreItemTypeFlag.Document) return null; if (webDavStoreItem is IWebDavStoreDocument && davProperty.StoreItemType == WebDavProperty.StoreItemTypeFlag.Collection) return null; switch (davProperty.Name) { case "creationdate": return webDavStoreItem.CreationDate.ToUniversalTime().ToString("s") + "Z"; case "displayname": return webDavStoreItem.Name; case "getcontentlanguage": //todo getcontentlanguage return Empty; case "getcontentlength": return webDavStoreItem.Size.ToString(CultureInfo.InvariantCulture); case "getcontenttype": return webDavStoreItem.MimeType; case "getetag": return "\"{" + webDavStoreItem.Etag + "},0\""; case "getlastmodified": return webDavStoreItem.ModificationDate.ToUniversalTime().ToString("R"); case "resourcetype": //todo Add resourceType return ""; case "ishidden": return webDavStoreItem.GetFileInfo().Hidden ? "1" : "0"; case "win32fileattributes": string s = Convert.ToString((int) webDavStoreItem.GetFileInfo().GetAttributes(), 16); char[] bits = s.PadLeft(8, '0').ToCharArray(); return new string(bits); case "isfolder": return (webDavStoreItem is IWebDavStoreCollection) ? "t" : ""; case "iscollection": return (webDavStoreItem is IWebDavStoreCollection) ? "1" : "0"; case "authoritative-directory": return "t"; case "repl-uid": return "rid:{" + webDavStoreItem.GetRepl_uId() + "}"; case "resourcetag": return "rt:" + webDavStoreItem.GetRepl_uId() + "@00000000000"; default: return Empty; } }
/// <summary> /// </summary> /// <param name="storeItem"></param> /// <returns></returns> public override List<IWebDavStoreItemLockInstance> GetLocks(IWebDavStoreItem storeItem) { lock (ObjectLocks) { return ObjectLocks.ContainsKey(storeItem.ItemPath) ? ObjectLocks[storeItem.ItemPath].ToList() : new List<IWebDavStoreItemLockInstance>(); } }
/// <summary> /// Returns the XML Format according to RFC /// Name: /// lockdiscovery /// Purpose: /// Describes the active locks on a resource /// Protected: /// MUST be protected. Clients change the list of locks through LOCK and UNLOCK, not through PROPPATCH. /// COPY/MOVE behavior: /// The value of this property depends on the lock state of the destination, not on the locks of the source resource. /// Recall /// that locks are not moved in a MOVE operation. /// Description: /// Returns a listing of who has a lock, what type of lock he has, the timeout type and the time remaining on the /// timeout, /// and the associated lock token. Owner information MAY be omitted if it is considered sensitive. If there are no /// locks, but /// the server supports locks, the property will be present but contain zero 'activelock' elements. If there are one or /// more locks, /// an 'activelock' element appears for each lock on the resource. This property is NOT lockable with respect to write /// locks (Section 7). /// </summary> /// <param name="storeItem"></param> /// <param name="responsedoc"></param> /// <param name="lockSystem"></param> /// <returns></returns> private static XmlNode LockDiscovery(IWebDavStoreItem storeItem, ref XmlDocument responsedoc, IWebDavStoreItemLock lockSystem) { XmlNode node = new WebDavProperty("lockdiscovery").ToXmlElement(responsedoc); foreach (IWebDavStoreItemLockInstance ilock in lockSystem.GetLocks(storeItem)) { XmlNode activelock = new WebDavProperty("activelock").ToXmlElement(responsedoc); node.AppendChild(activelock); XmlNode locktype = new WebDavProperty("locktype").ToXmlElement(responsedoc); activelock.AppendChild(locktype); XmlNode locktypeitem = new WebDavProperty(ilock.LockType.ToString().ToLower()).ToXmlElement(responsedoc); locktype.AppendChild(locktypeitem); XmlNode lockscope = new WebDavProperty("lockscope").ToXmlElement(responsedoc); activelock.AppendChild(lockscope); XmlNode lockscopeitem = new WebDavProperty(ilock.LockScope.ToString().ToLower()).ToXmlElement(responsedoc); lockscope.AppendChild(lockscopeitem); XmlNode depth = new WebDavProperty("depth").ToXmlElement(responsedoc); depth.InnerText = ilock.Depth.ToString(CultureInfo.InvariantCulture); activelock.AppendChild(depth); XmlNode owner = new WebDavProperty("owner").ToXmlElement(responsedoc); owner.InnerText = ilock.Owner; activelock.AppendChild(owner); XmlNode timeout = new WebDavProperty("timeout").ToXmlElement(responsedoc); timeout.InnerText = ilock.RequestedTimeout; activelock.AppendChild(timeout); XmlNode locktoken = new WebDavProperty("locktoken").ToXmlElement(responsedoc); activelock.AppendChild(locktoken); XmlNode tokenhref = new WebDavProperty("href").ToXmlElement(responsedoc); tokenhref.InnerText = ilock.Token.ToLockToken(); locktoken.AppendChild(tokenhref); XmlNode lockroot = new WebDavProperty("lockroot").ToXmlElement(responsedoc); activelock.AppendChild(lockroot); XmlNode lockroothref = new WebDavProperty("href").ToXmlElement(responsedoc); lockroothref.InnerText = ilock.Path; lockroot.AppendChild(lockroothref); } return node; }
/// <summary> /// Locks the object passed. /// </summary> /// <param name="storeItem"></param> /// <param name="lockscope"></param> /// <param name="locktype"></param> /// <param name="lockowner"></param> /// <param name="requestedlocktimeout"></param> /// <param name="locktoken"></param> /// <param name="requestDocument"></param> /// <param name="depth"></param> /// <returns></returns> public override int Lock(IWebDavStoreItem storeItem, WebDavLockScope lockscope, WebDavLockType locktype, string lockowner, double? requestedlocktimeout, out Guid? locktoken, XmlDocument requestDocument, int depth) { locktoken = null; try { var sqlStoreItem = (WebDavSqlStoreItem) storeItem; CleanLocks(); using (OnlineFilesEntities context = new OnlineFilesEntities()) { WebDavSqlStoreItemLockInstance inst; if (!context.ObjectLockInfoes.Any(d => d.ObjectGuid == sqlStoreItem.ObjectGuid && d.isFolder == sqlStoreItem.IsCollection)) { inst = new WebDavSqlStoreItemLockInstance( PrincipleFactory.Instance.GetPrinciple(FromType.WebDav).UserProfile, storeItem.ItemPath, lockscope, locktype, lockowner, requestedlocktimeout, null, requestDocument, depth, this); locktoken = CreateSqlLock(ref inst, sqlStoreItem); return (int) HttpStatusCode.OK; } switch (lockscope) { case WebDavLockScope.Exclusive: //#if DEBUG // WebDavServer.Log.Debug("Lock Creation Failed (Exclusive), URI already has a lock."); //#endif return 423; case WebDavLockScope.Shared: if (context.ObjectLockInfoes.Any(d => d.ObjectGuid == sqlStoreItem.ObjectGuid && d.isFolder == sqlStoreItem.IsCollection && d.LockScope == (int) WebDavLockScope.Exclusive)) { //#if DEBUG // WebDavServer.Log.Debug("Lock Creation Failed (Shared), URI has exclusive lock."); //#endif return 423; } break; } //If the scope is shared and all other locks on this uri are shared we are ok, otherwise we fail. //423 (Locked), potentially with 'no-conflicting-lock' precondition code - //There is already a lock on the resource that is not compatible with the //requested lock (see lock compatibility table above). //If it gets to here, then we are most likely creating another shared lock on the file. inst = new WebDavSqlStoreItemLockInstance( PrincipleFactory.Instance.GetPrinciple(FromType.WebDav).UserProfile, storeItem.ItemPath, lockscope, locktype, lockowner, requestedlocktimeout, null, requestDocument, depth, this); locktoken = CreateSqlLock(ref inst, sqlStoreItem); return (int) HttpStatusCode.OK; } } catch (Exception ex) { Console.WriteLine(ex.Message + ex.StackTrace); throw; } }
/// <summary> /// </summary> /// <param name="lockscope"></param> /// <param name="locktype"></param> /// <param name="lockowner"></param> /// <param name="requestedlocktimeout"></param> /// <param name="locktoken"></param> /// <param name="requestDocument"></param> /// <param name="depth"></param> /// <param name="storeItem"></param> /// <returns></returns> public virtual int Lock(IWebDavStoreItem storeItem, WebDavLockScope lockscope, WebDavLockType locktype, string lockowner, double? requestedlocktimeout, out Guid? locktoken, XmlDocument requestDocument, int depth) { throw new NotImplementedException(); }
internal string CreateFragment(bool isRoot, XmlDocument responseDoc, IWebDavStoreItem webDavStoreItem, IHttpListenerContext context, bool propname, Uri requestUri, List<WebDavProperty> requestedProperties, IWebDavStoreItemLock lockSystem) { // Create the response element WebDavProperty responseProperty = new WebDavProperty("response", Empty); XmlElement responseElement = responseProperty.ToXmlElement(responseDoc); // The href element Uri result; if (isRoot) Uri.TryCreate(requestUri, Empty, out result); else Uri.TryCreate(requestUri, webDavStoreItem.Name, out result); WebDavProperty hrefProperty = new WebDavProperty("href", result.AbsoluteUri); responseElement.AppendChild(hrefProperty.ToXmlElement(responseDoc)); // The propstat element WebDavProperty propstatProperty = new WebDavProperty("propstat", Empty); XmlElement propstatElement = propstatProperty.ToXmlElement(responseDoc); // The prop element WebDavProperty propProperty = new WebDavProperty("prop", Empty); XmlElement propElement = propProperty.ToXmlElement(responseDoc); //All properties but lockdiscovery and supportedlock can be handled here. foreach (WebDavProperty davProperty in requestedProperties) { XmlNode toAdd; switch (davProperty.Name) { case "lockdiscovery": toAdd = LockDiscovery(webDavStoreItem, ref responseDoc, lockSystem); break; case "supportedlock": toAdd = SupportedLocks(ref responseDoc); break; default: toAdd = PropChildElement(davProperty, responseDoc, webDavStoreItem, propname); break; } if (toAdd != null) propElement.AppendChild(toAdd); } // Add the prop element to the propstat element propstatElement.AppendChild(propElement); // The status element WebDavProperty statusProperty = new WebDavProperty("status", "HTTP/1.1 " + context.Response.StatusCode + " " + HttpWorkerRequest.GetStatusDescription(context.Response.StatusCode)); propstatElement.AppendChild(statusProperty.ToXmlElement(responseDoc)); // Add the propstat element to the response element responseElement.AppendChild(propstatElement); if (responseDoc.DocumentElement == null) throw new Exception("Not Possible."); return responseElement.OuterXml.Replace("xmlns:D=\"DAV:\"", ""); }
/// <summary> /// Gets the correct value for a <see cref="WebDavProperty" /> /// </summary> /// <param name="webDavStoreItem">The <see cref="IWebDavStoreItem" /> defines the values</param> /// <param name="davProperty">The <see cref="WebDavProperty" /> that needs a value</param> /// <returns> /// A <see cref="string" /> containing the value /// </returns> private string GetWebDavPropertyValue(IWebDavStoreItem webDavStoreItem, WebDavProperty davProperty) { switch (davProperty.Name) { case "creationdate": return webDavStoreItem.CreationDate.ToUniversalTime().ToString("s") + "Z"; case "displayname": return webDavStoreItem.Name; case "getcontentlanguage": // still to implement !!! return String.Empty; case "getcontentlength": return (!webDavStoreItem.IsCollection ? "" + ((IWebDavStoreDocument) webDavStoreItem).Size : ""); case "getcontenttype": return (!webDavStoreItem.IsCollection ? "" + ((IWebDavStoreDocument) webDavStoreItem).MimeType : ""); case "getetag": return (!webDavStoreItem.IsCollection ? "" + ((IWebDavStoreDocument) webDavStoreItem).Etag : ""); case "getlastmodified": return webDavStoreItem.ModificationDate.ToUniversalTime().ToString("R"); case "lockdiscovery": // still to implement !!! return String.Empty; case "resourcetype": return ""; case "supportedlock": // still to implement !!! return ""; //webDavProperty.Value = "<D:lockentry><D:lockscope><D:shared/></D:lockscope><D:locktype><D:write/></D:locktype></D:lockentry>"; case "ishidden": return "" + webDavStoreItem.Hidden; default: return String.Empty; } }
/// <summary> /// Gives the /// <see cref="XmlElement" /> of a /// <see cref="WebDavProperty" /> /// with or without values /// or with or without child elements /// </summary> /// <param name="webDavProperty">The <see cref="WebDavProperty" /></param> /// <param name="xmlDocument">The <see cref="XmlDocument" /> containing the response body</param> /// <param name="iWebDavStoreItem">The <see cref="IWebDavStoreItem" /></param> /// <param name="isPropname">The boolean defining the Propfind propname request</param> /// <returns> /// The <see cref="XmlElement" /> of the <see cref="WebDavProperty" /> containing a value or child elements /// </returns> private XmlElement PropChildElement(WebDavProperty webDavProperty, XmlDocument xmlDocument, IWebDavStoreItem iWebDavStoreItem, bool isPropname) { // If Propfind request contains a propname element if (isPropname) { webDavProperty.Value = String.Empty; return webDavProperty.ToXmlElement(xmlDocument); } // If not, add the values to webDavProperty webDavProperty.Value = GetWebDavPropertyValue(iWebDavStoreItem, webDavProperty); XmlElement xmlElement = webDavProperty.ToXmlElement(xmlDocument); // If the webDavProperty is the resourcetype property // and the webDavStoreItem is a collection // add the collection XmlElement as a child to the xmlElement if (webDavProperty.Name != "resourcetype" || !iWebDavStoreItem.IsCollection) return xmlElement; WebDavProperty collectionProperty = new WebDavProperty("collection", ""); xmlElement.AppendChild(collectionProperty.ToXmlElement(xmlDocument)); return xmlElement; }
/// <summary> /// Locks the request Path. /// </summary> /// <param name="storeItem">URI to the item to be locked</param> /// <param name="lockscope">The lock Scope used for locking</param> /// <param name="locktype">The lock Type used for locking</param> /// <param name="lockowner">The owner of the lock</param> /// <param name="requestedlocktimeout">The requested timeout</param> /// <param name="locktoken">Out parameter, returns the issued token</param> /// <param name="requestDocument">the Request Document</param> /// <param name="depth">How deep to lock, 0,1, or infinity</param> /// <returns></returns> public override int Lock(IWebDavStoreItem storeItem, WebDavLockScope lockscope, WebDavLockType locktype, string lockowner, double? requestedlocktimeout, out Guid? locktoken, XmlDocument requestDocument, int depth) { CleanLocks(storeItem); #if DEBUG WebDavServer.Log.Info("Lock Requested Timeout:" + requestedlocktimeout); #endif locktoken = null; Guid tmpLockToken = Guid.NewGuid(); lock (ObjectLocks) { /* The table below describes the behavior that occurs when a lock request is made on a resource. Current State Shared Lock OK Exclusive Lock OK None True True Shared Lock True False Exclusive Lock False False* Legend: True = lock may be granted. False = lock MUST NOT be granted. *=It is illegal for a principal to request the same lock twice. The current lock state of a resource is given in the leftmost column, and lock requests are listed in the first row. The intersection of a row and column gives the result of a lock request. For example, if a shared lock is held on a resource, and an exclusive lock is requested, the table entry is "false", indicating that the lock must not be granted. */ //if ObjectLocks doesn't contain the path, then this is a new lock and regardless //of whether it is Exclusive or Shared it is successful. if (!ObjectLocks.ContainsKey(storeItem.ItemPath)) { ObjectLocks.Add(storeItem.ItemPath, new List<IWebDavStoreItemLockInstance>()); ObjectLocks[storeItem.ItemPath].Add(new WebDavStoreItemLockInstance(storeItem.ItemPath, lockscope, locktype, lockowner, requestedlocktimeout, tmpLockToken, requestDocument, depth, this)); locktoken = tmpLockToken; #if DEBUG WebDavServer.Log.Debug("Created New Lock (" + lockscope + "), URI had no locks. Timeout:" + requestedlocktimeout); #endif return (int) HttpStatusCode.OK; } if (ObjectLocks[storeItem.ItemPath].Count == 0) { ObjectLocks[storeItem.ItemPath].Add(new WebDavStoreItemLockInstance(storeItem.ItemPath, lockscope, locktype, lockowner, requestedlocktimeout, tmpLockToken, requestDocument, depth, this)); locktoken = tmpLockToken; return (int) HttpStatusCode.OK; } //The fact that ObjectLocks contains this URI means that there is already a lock on this object, //This means the lock fails because you can only have 1 exclusive lock. switch (lockscope) { case WebDavLockScope.Exclusive: #if DEBUG WebDavServer.Log.Debug("Lock Creation Failed (Exclusive), URI already has a lock."); #endif return 423; case WebDavLockScope.Shared: if (ObjectLocks[storeItem.ItemPath].Any(itemLock => itemLock.LockScope == WebDavLockScope.Exclusive)) { #if DEBUG WebDavServer.Log.Debug("Lock Creation Failed (Shared), URI has exclusive lock."); #endif return 423; } break; } //If the scope is shared and all other locks on this uri are shared we are ok, otherwise we fail. //423 (Locked), potentially with 'no-conflicting-lock' precondition code - //There is already a lock on the resource that is not compatible with the //requested lock (see lock compatibility table above). //If it gets to here, then we are most likely creating another shared lock on the file. #region Create New Lock ObjectLocks[storeItem.ItemPath].Add(new WebDavStoreItemLockInstance(storeItem.ItemPath, lockscope, locktype, lockowner, requestedlocktimeout, tmpLockToken, requestDocument, depth, this)); locktoken = tmpLockToken; #if DEBUG WebDavServer.Log.Debug("Created New Lock (" + lockscope + "), URI had no locks. Timeout:" + requestedlocktimeout); #endif #endregion return (int) HttpStatusCode.OK; } }