/// <summary> /// Starts the server. /// Authentication used: Negotiate /// </summary> private static void StartServer() { IWebDavStoreItemLock lockSystem = new WebDavStoreItemLock(); IWebDavStore store = new WebDavDiskStore(Localpath, lockSystem); WebDavServer server = new WebDavServer(ref store); server.Start(Url); }
/// <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) { /*************************************************************************************************** * Send the response ***************************************************************************************************/ WindowsIdentity Identity = (WindowsIdentity)Thread.GetData(Thread.GetNamedDataSlot(Constants.HttpUser)); var statusCode = WebDavStoreItemLock.UnLock(context.Request.Url, GetLockTokenHeader(context.Request), Identity.Name); context.SetStatusCode(statusCode); }
/// <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="path"></param> /// <param name="responsedoc"></param> /// <returns></returns> private static XmlNode LockDiscovery(Uri path, ref XmlDocument responsedoc) { XmlNode node = new WebDavProperty("lockdiscovery").ToXmlElement(responsedoc); foreach (var ilock in WebDavStoreItemLock.GetLocks(path)) { 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; locktoken.AppendChild(tokenhref); XmlNode lockroot = new WebDavProperty("lockroot").ToXmlElement(responsedoc); activelock.AppendChild(lockroot); XmlNode lockroothref = new WebDavProperty("href").ToXmlElement(responsedoc); lockroothref.InnerText = ilock.Path.ToString(); lockroot.AppendChild(lockroothref); } return(node); }
/// <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="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) { if (!WebDavStoreItemLock.LockEnabled) { throw new WebDavNotImplementedException("Lock support disabled"); } /*************************************************************************************************** * Send the response ***************************************************************************************************/ WindowsIdentity Identity = (WindowsIdentity)Thread.GetData(Thread.GetNamedDataSlot(WebDavServer.HttpUser)); var unlockResult = WebDavStoreItemLock.UnLock(context.Request.Url, GetLockTokenHeader(context.Request), Identity.Name); IWebDavStoreCollection collection = GetParentCollection(server, store, context.Request.Url); try { var item = GetItemFromCollection(collection, context.Request.Url); if (item != null) { //we already have an item var resourceCanBeUnLocked = item.UnLock(Identity.Name); if (!resourceCanBeUnLocked) { //TODO: decide what to do if the resource cannot be locked. } } } catch (Exception ex) { WebDavServer.Log.Warn( String.Format("Request unlock on a resource that does not exists: {0}", context.Request.Url), ex); } context.SendSimpleResponse(unlockResult); }
/// <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.WebDavPreconditionFailedException"></exception> /// <param name="response"></param> /// <param name="request"></param> protected override void OnProcessRequest( WebDavServer server, IHttpListenerContext context, IWebDavStore store, XmlDocument request, XmlDocument response) { if (!WebDavStoreItemLock.LockEnabled) { throw new WebDavNotImplementedException("Lock support disabled"); } /*************************************************************************************************** * Retreive al the information from the request ***************************************************************************************************/ // read the headers int depth = GetDepthHeader(context.Request); string timeout = GetTimeoutHeader(context.Request); string locktoken = GetLockTokenIfHeader(context.Request); int lockResult = 0; // Initiate the XmlNamespaceManager and the XmlNodes XmlNamespaceManager manager; XmlNode lockscopeNode, locktypeNode, ownerNode; if (string.IsNullOrEmpty(locktoken)) { #region New Lock // try to read the body try { StreamReader reader = new StreamReader(context.Request.InputStream, Encoding.UTF8); string requestBody = reader.ReadToEnd(); if (!requestBody.Equals("") && requestBody.Length != 0) { request.LoadXml(requestBody); if (request.DocumentElement != null && request.DocumentElement.LocalName != "prop" && request.DocumentElement.LocalName != "lockinfo") { WebDavServer.Log.Debug("LOCK method without prop or lockinfo element in xml document"); } manager = new XmlNamespaceManager(request.NameTable); manager.AddNamespace("D", "DAV:"); manager.AddNamespace("Office", "schemas-microsoft-com:office:office"); manager.AddNamespace("Repl", "http://schemas.microsoft.com/repl/"); manager.AddNamespace("Z", "urn:schemas-microsoft-com:"); // Get the lockscope, locktype and owner as XmlNodes from the XML document lockscopeNode = request.DocumentElement.SelectSingleNode("D:lockscope", manager); locktypeNode = request.DocumentElement.SelectSingleNode("D:locktype", manager); ownerNode = request.DocumentElement.SelectSingleNode("D:owner", manager); } else { throw new WebDavPreconditionFailedException(); } } catch (Exception ex) { WebDavServer.Log.Warning(ex.Message); throw; } /*************************************************************************************************** * Lock the file or folder ***************************************************************************************************/ // Get the parent collection of the item IWebDavStoreCollection collection = GetParentCollection(server, store, context.Request.Url); WebDavLockScope lockscope = (lockscopeNode.InnerXml.StartsWith("<D:exclusive")) ? WebDavLockScope.Exclusive : WebDavLockScope.Shared; //Only lock available at this time is a Write Lock according to RFC WebDavLockType locktype = (locktypeNode.InnerXml.StartsWith("<D:write")) ? WebDavLockType.Write : WebDavLockType.Write; string userAgent = context.Request.Headers["User-Agent"]; WindowsIdentity Identity = (WindowsIdentity)Thread.GetData(Thread.GetNamedDataSlot(WebDavServer.HttpUser)); // Get the item from the collection try { var item = GetItemFromCollection(collection, context.Request.Url); String lockLogicalKey = context.Request.Url.AbsoluteUri; if (item != null) { lockLogicalKey = item.LockLogicalKey; } if (item != null && !item.Lock()) { lockResult = 423; //Resource cannot be locked } else { //try acquiring a standard lock, lockResult = WebDavStoreItemLock.Lock( context.Request.Url, lockLogicalKey, lockscope, locktype, Identity.Name, userAgent, ref timeout, out locktoken, request, depth); } } catch (Exception ex) { WebDavServer.Log.Error(String.Format("Error occourred while acquiring lock {0}", context.Request.Url), ex); lockResult = 423; //Resource cannot be locked some exception occurred } #endregion } else { #region Refreshing a lock //Refresh lock will ref us back the original XML document which was used to request this lock, from //this we will grab the data we need to build the response to the lock refresh request. lockResult = WebDavStoreItemLock.RefreshLock(context.Request.Url, locktoken, ref timeout, out request); if (request == null) { context.SendSimpleResponse(409); return; } try { if (request.DocumentElement != null && request.DocumentElement.LocalName != "prop" && request.DocumentElement.LocalName != "lockinfo") { WebDavServer.Log.Debug("LOCK method without prop or lockinfo element in xml document"); } manager = new XmlNamespaceManager(request.NameTable); manager.AddNamespace("D", "DAV:"); manager.AddNamespace("Office", "schemas-microsoft-com:office:office"); manager.AddNamespace("Repl", "http://schemas.microsoft.com/repl/"); manager.AddNamespace("Z", "urn:schemas-microsoft-com:"); // Get the lockscope, locktype and owner as XmlNodes from the XML document lockscopeNode = request.DocumentElement.SelectSingleNode("D:lockscope", manager); locktypeNode = request.DocumentElement.SelectSingleNode("D:locktype", manager); ownerNode = request.DocumentElement.SelectSingleNode("D:owner", manager); } catch (Exception ex) { WebDavServer.Log.Warning(ex.Message); throw; } #endregion } /*************************************************************************************************** * Create the body for the response ***************************************************************************************************/ // Create the basic response XmlDocument const string responseXml = "<?xml version=\"1.0\" encoding=\"utf-8\" ?><D:prop xmlns:D=\"DAV:\"><D:lockdiscovery><D:activelock/></D:lockdiscovery></D:prop>"; response.LoadXml(responseXml); // Select the activelock XmlNode XmlNode activelock = response.DocumentElement.SelectSingleNode("D:lockdiscovery/D:activelock", manager); // Import the given nodes activelock.AppendChild(response.ImportNode(lockscopeNode, true)); activelock.AppendChild(response.ImportNode(locktypeNode, true)); activelock.AppendChild(response.ImportNode(ownerNode, true)); // Add the additional elements, e.g. the header elements // The timeout element WebDavProperty timeoutProperty = new WebDavProperty("timeout", timeout);// timeout); activelock.AppendChild(timeoutProperty.ToXmlElement(response)); // The depth element WebDavProperty depthProperty = new WebDavProperty("depth", (depth == 0 ? "0" : "Infinity")); activelock.AppendChild(depthProperty.ToXmlElement(response)); // The locktoken element WebDavProperty locktokenProperty = new WebDavProperty("locktoken", string.Empty); XmlElement locktokenElement = locktokenProperty.ToXmlElement(response); WebDavProperty hrefProperty = new WebDavProperty("href", locktoken);//"opaquelocktoken:e71d4fae-5dec-22df-fea5-00a0c93bd5eb1"); locktokenElement.AppendChild(hrefProperty.ToXmlElement(response)); activelock.AppendChild(locktokenElement); // The lockroot element WebDavProperty lockRootProperty = new WebDavProperty("lockroot", string.Empty); XmlElement lockRootElement = lockRootProperty.ToXmlElement(response); WebDavProperty hrefRootProperty = new WebDavProperty("href", context.Request.Url.AbsoluteUri);//"lockroot lockRootElement.AppendChild(hrefRootProperty.ToXmlElement(response)); activelock.AppendChild(lockRootElement); /*************************************************************************************************** * Send the response ***************************************************************************************************/ // convert the StringBuilder string resp = response.InnerXml; if (WebDavServer.Log.IsEnabled(Serilog.Events.LogEventLevel.Debug)) { WebDavServer.Log.Debug( @"Request {0}:{1}:{2} Request {3} Response: {4}", context.Request.HttpMethod, context.Request.RemoteEndPoint, context.Request.Url, request.Beautify(), response.Beautify()); } byte[] responseBytes = Encoding.UTF8.GetBytes(resp); context.Response.StatusCode = lockResult; context.Response.StatusDescription = HttpWorkerRequest.GetStatusDescription(lockResult); // set the headers of the response context.Response.ContentLength64 = responseBytes.Length; context.Response.AdaptedInstance.ContentType = "text/xml"; // the body context.Response.OutputStream.Write(responseBytes, 0, responseBytes.Length); context.Response.Close(); }
/// <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.WebDavPreconditionFailedException"></exception> public void ProcessRequest(IWebDavContext context, IWebDavStore store) { /*************************************************************************************************** * Retreive al the information from the request ***************************************************************************************************/ // read the headers int depth = GetDepthHeader(context.Request); string timeout = GetTimeoutHeader(context.Request); string locktoken = GetLockTokenIfHeader(context.Request); int lockResult; // Initiate the XmlNamespaceManager and the XmlNodes XmlNamespaceManager manager; XmlNode lockscopeNode, locktypeNode, ownerNode; XmlDocument requestDocument = new XmlDocument(); if (string.IsNullOrEmpty(locktoken)) { #region New Lock // try to read the body try { StreamReader reader = new StreamReader(context.Request.InputStream, Encoding.UTF8); string requestBody = reader.ReadToEnd(); if (!requestBody.Equals("") && requestBody.Length != 0) { requestDocument.LoadXml(requestBody); if (requestDocument.DocumentElement != null && requestDocument.DocumentElement.LocalName != "prop" && requestDocument.DocumentElement.LocalName != "lockinfo") { WebDavServer.Log.Debug("LOCK method without prop or lockinfo element in xml document"); } manager = new XmlNamespaceManager(requestDocument.NameTable); manager.AddNamespace("D", "DAV:"); manager.AddNamespace("Office", "schemas-microsoft-com:office:office"); manager.AddNamespace("Repl", "http://schemas.microsoft.com/repl/"); manager.AddNamespace("Z", "urn:schemas-microsoft-com:"); // Get the lockscope, locktype and owner as XmlNodes from the XML document lockscopeNode = requestDocument.DocumentElement.SelectSingleNode("D:lockscope", manager); locktypeNode = requestDocument.DocumentElement.SelectSingleNode("D:locktype", manager); ownerNode = requestDocument.DocumentElement.SelectSingleNode("D:owner", manager); } else { throw new WebDavPreconditionFailedException(); } } catch (Exception ex) { WebDavServer.Log.Warn(ex.Message); throw; } /*************************************************************************************************** * Lock the file or folder ***************************************************************************************************/ // Get the parent collection of the item IWebDavStoreCollection collection = GetParentCollection(store, context, context.Request.Url); WebDavLockScope lockscope = (lockscopeNode.InnerXml.StartsWith("<D:exclusive")) ? WebDavLockScope.Exclusive : WebDavLockScope.Shared; //Only lock available at this time is a Write Lock according to RFC WebDavLockType locktype = (locktypeNode.InnerXml.StartsWith("<D:write")) ? WebDavLockType.Write : WebDavLockType.Write; string lockuser = ownerNode.InnerText; WindowsIdentity Identity = (WindowsIdentity)Thread.GetData(Thread.GetNamedDataSlot(Constants.HttpUser)); lockResult = WebDavStoreItemLock.Lock(context.Request.Url, lockscope, locktype, Identity.Name, ref timeout, out locktoken, requestDocument, depth); // Get the item from the collection try { GetItemFromCollection(collection, context.Request.Url); } catch (Exception) { lockResult = (int)HttpStatusCode.Created; } #endregion } else { #region Refreshing a lock //Refresh lock will ref us back the original XML document which was used to request this lock, from //this we will grab the data we need to build the response to the lock refresh request. lockResult = WebDavStoreItemLock.RefreshLock(context.Request.Url, locktoken, ref timeout, out requestDocument); if (requestDocument == null) { context.SetStatusCode(409); return; } try { if (requestDocument.DocumentElement != null && requestDocument.DocumentElement.LocalName != "prop" && requestDocument.DocumentElement.LocalName != "lockinfo") { WebDavServer.Log.Debug("LOCK method without prop or lockinfo element in xml document"); } manager = new XmlNamespaceManager(requestDocument.NameTable); manager.AddNamespace("D", "DAV:"); manager.AddNamespace("Office", "schemas-microsoft-com:office:office"); manager.AddNamespace("Repl", "http://schemas.microsoft.com/repl/"); manager.AddNamespace("Z", "urn:schemas-microsoft-com:"); // Get the lockscope, locktype and owner as XmlNodes from the XML document lockscopeNode = requestDocument.DocumentElement.SelectSingleNode("D:lockscope", manager); locktypeNode = requestDocument.DocumentElement.SelectSingleNode("D:locktype", manager); ownerNode = requestDocument.DocumentElement.SelectSingleNode("D:owner", manager); } catch (Exception ex) { WebDavServer.Log.Warn(ex.Message); throw; } #endregion } /*************************************************************************************************** * Create the body for the response ***************************************************************************************************/ // Create the basic response XmlDocument XmlDocument responseDoc = new XmlDocument(); const string responseXml = "<?xml version=\"1.0\" encoding=\"utf-8\" ?><D:prop xmlns:D=\"DAV:\"><D:lockdiscovery><D:activelock/></D:lockdiscovery></D:prop>"; responseDoc.LoadXml(responseXml); // Select the activelock XmlNode XmlNode activelock = responseDoc.DocumentElement.SelectSingleNode("D:lockdiscovery/D:activelock", manager); // Import the given nodes activelock.AppendChild(responseDoc.ImportNode(lockscopeNode, true)); activelock.AppendChild(responseDoc.ImportNode(locktypeNode, true)); activelock.AppendChild(responseDoc.ImportNode(ownerNode, true)); // Add the additional elements, e.g. the header elements // The timeout element WebDavProperty timeoutProperty = new WebDavProperty("timeout", timeout);// timeout); activelock.AppendChild(timeoutProperty.ToXmlElement(responseDoc)); // The depth element WebDavProperty depthProperty = new WebDavProperty("depth", (depth == 0 ? "0" : "Infinity")); activelock.AppendChild(depthProperty.ToXmlElement(responseDoc)); // The locktoken element WebDavProperty locktokenProperty = new WebDavProperty("locktoken", string.Empty); XmlElement locktokenElement = locktokenProperty.ToXmlElement(responseDoc); WebDavProperty hrefProperty = new WebDavProperty("href", locktoken);//"opaquelocktoken:e71d4fae-5dec-22df-fea5-00a0c93bd5eb1"); locktokenElement.AppendChild(hrefProperty.ToXmlElement(responseDoc)); activelock.AppendChild(locktokenElement); /*************************************************************************************************** * Send the response ***************************************************************************************************/ // convert the StringBuilder string resp = responseDoc.InnerXml; byte[] responseBytes = Encoding.UTF8.GetBytes(resp); context.SetStatusCode(lockResult); context.Response.StatusDescription = HttpWorkerRequest.GetStatusDescription(lockResult); // set the headers of the response context.Response.ContentLength64 = responseBytes.Length; context.Response.AppendHeader("ContentType", "text/xml"); // the body context.Response.OutputStream.Write(responseBytes, 0, responseBytes.Length); }