/// <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);
        }
Beispiel #3
0
        /// <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);
        }
Beispiel #4
0
        /// <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);
        }
Beispiel #6
0
        /// <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();
        }
Beispiel #7
0
        /// <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);
        }