/// <summary>
        /// Moves the
        /// </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>
        /// <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(IWebDavContext context, IWebDavStore store, IWebDavStoreItem sourceWebDavStoreItem)
        {
            Uri destinationUri = GetDestinationHeader(context.Request);
            IWebDavStoreCollection destinationParentCollection = GetParentCollection(store, context, 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.SetStatusCode(isNew ? HttpStatusCode.Created : HttpStatusCode.NoContent);
        }
Beispiel #2
0
        /// <summary>
        /// Copies the item.
        /// </summary>
        /// <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(IWebDavContext context, IWebDavStore store, IWebDavStoreItem source)
        {
            Uri destinationUri = GetDestinationHeader(context.Request);
            IWebDavStoreCollection destinationParentCollection = GetParentCollection(store, context, 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);

            var statusCode = isNew ? HttpStatusCode.Created : HttpStatusCode.NoContent;

            context.SetStatusCode(statusCode);
        }
 /// <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>
        /// 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>
        /// 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)
        {

            foreach (string verb in verbsAllowed)
                context.Response.AppendHeader("Allow", verb);

            foreach (string verb in verbsPublic)
                context.Response.AppendHeader("Public", verb);

            // Sends 200 OK
            context.SetStatusCode();
        }
Beispiel #6
0
        /// <summary>
        /// Sends the response
        /// </summary>
        /// <param name="context">The <see cref="IWebDavContext" /> containing the response</param>
        /// <param name="responseDocument">The <see cref="XmlDocument" /> containing the response body</param>
        private static void MakeResponse(IWebDavContext context, XmlDocument responseDocument)
        {
            // convert the XmlDocument
            byte[] responseBytes = Encoding.UTF8.GetBytes(responseDocument.InnerXml);

            // HttpStatusCode doesn't contain WebDav status codes, but HttpWorkerRequest can handle these WebDav status codes
            context.SetStatusCode((int)WebDavStatusCode.MultiStatus);

            context.Response.ContentLength64 = responseBytes.Length;
            context.Response.AppendHeader("Content-Type", "text/xml");
            context.Response.OutputStream.Write(responseBytes, 0, responseBytes.Length);
        }
        /// <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)
        {
            foreach (string verb in verbsAllowed)
            {
                context.Response.AppendHeader("Allow", verb);
            }

            foreach (string verb in verbsPublic)
            {
                context.Response.AppendHeader("Public", verb);
            }

            // Sends 200 OK
            context.SetStatusCode();
        }
        /// <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.WebDavUnsupportedMediaTypeException"></exception>
        /// <exception cref="WebDAVSharp.Server.Exceptions.WebDavMethodNotAllowedException"></exception>
        public void ProcessRequest(IWebDavContext context, IWebDavStore store)
        {
            if (context.Request.ContentLength64 > 0)
                throw new WebDavUnsupportedMediaTypeException();

            IWebDavStoreCollection collection = GetParentCollection(store, context, context.Request.Url);
                
            string collectionName = Uri.UnescapeDataString(
                context.Request.Url.Segments.Last().TrimEnd('/', '\\')
                );
            if (collection.GetItemByName(collectionName) != null)
                throw new WebDavMethodNotAllowedException();

            collection.CreateCollection(collectionName);

            context.SetStatusCode(HttpStatusCode.Created);
        }
Beispiel #9
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.WebDavMethodNotAllowedException"></exception>
        /// <exception cref="WebDAVSharp.Server.Exceptions.WebDavLengthRequiredException">If the ContentLength header was not found</exception>
        public void ProcessRequest(IWebDavContext context, IWebDavStore store)
        {
            // Get the parent collection
            IWebDavStoreCollection parentCollection = GetParentCollection(store, context, 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.SetStatusCode(HttpStatusCode.Created);
        }
        /// <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"));
        }
Beispiel #11
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="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"));
        }
Beispiel #12
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.WebDavUnsupportedMediaTypeException"></exception>
        /// <exception cref="WebDAVSharp.Server.Exceptions.WebDavMethodNotAllowedException"></exception>
        public void ProcessRequest(IWebDavContext context, IWebDavStore store)
        {
            if (context.Request.ContentLength64 > 0)
            {
                throw new WebDavUnsupportedMediaTypeException();
            }

            IWebDavStoreCollection collection = GetParentCollection(store, context, context.Request.Url);

            string collectionName = Uri.UnescapeDataString(
                context.Request.Url.Segments.Last().TrimEnd('/', '\\')
                );

            if (collection.GetItemByName(collectionName) != null)
            {
                throw new WebDavMethodNotAllowedException();
            }

            collection.CreateCollection(collectionName);

            context.SetStatusCode(HttpStatusCode.Created);
        }
        /// <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);
        }
        /// <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)
        {
            /***************************************************************************************************
             * Retreive al the information from the request
             ***************************************************************************************************/

            // Get the URI to the location
            Uri requestUri = context.Request.Url;

            // Initiate the XmlNamespaceManager and the XmlNodes
            XmlNamespaceManager manager = null;
            XmlNode propNode = null;

            // try to read the body
            try
            {
                StreamReader reader = new StreamReader(context.Request.InputStream, Encoding.UTF8);
                string requestBody = reader.ReadToEnd();

                if (!String.IsNullOrEmpty(requestBody))
                {
                    XmlDocument requestDocument = new XmlDocument();
                    requestDocument.LoadXml(requestBody);

                    if (requestDocument.DocumentElement != null)
                    {
                        if (requestDocument.DocumentElement.LocalName != "propertyupdate")
                        {
                            WebDavServer.Log.Debug("PROPPATCH method without propertyupdate 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:");

                        propNode = requestDocument.DocumentElement.SelectSingleNode("D:set/D:prop", manager);
                    }
                }
            }
            catch (Exception ex)
            {
                WebDavServer.Log.Warn(ex.Message);
            }

            /***************************************************************************************************
             * Take action
             ***************************************************************************************************/

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

            FileInfo fileInfo = new FileInfo(item.ItemPath);

            if (propNode != null && fileInfo.Exists)
            {
                foreach (XmlNode node in propNode.ChildNodes)
                {
                    switch (node.LocalName)
                    {
                        case "Win32CreationTime":
                            fileInfo.CreationTime = Convert.ToDateTime(node.InnerText).ToUniversalTime();
                            break;
                        case "Win32LastAccessTime":
                            fileInfo.LastAccessTime = Convert.ToDateTime(node.InnerText).ToUniversalTime();
                            break;
                        case "Win32LastModifiedTime":
                            fileInfo.LastWriteTime = Convert.ToDateTime(node.InnerText).ToUniversalTime();
                            break;
                        case "Win32FileAttributes":
                            //todo Win32FileAttributes
                            //fileInfo.Attributes = 
                            //fileInfo.Attributes = Convert.ToDateTime(node.InnerText);
                            break;
                    }
                }
            }


            /***************************************************************************************************
             * 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:multistatus " +
                                       "xmlns:Z=\"urn:schemas-microsoft-com:\" xmlns:D=\"DAV:\">" +
                                       "<D:response></D:response></D:multistatus>";
            responseDoc.LoadXml(responseXml);

            // Select the response node
            XmlNode responseNode = responseDoc.DocumentElement.SelectSingleNode("D:response", manager);

            // Add the elements

            // The href element
            WebDavProperty hrefProperty = new WebDavProperty("href", requestUri.ToString());
            responseNode.AppendChild(hrefProperty.ToXmlElement(responseDoc));

            // The propstat element
            WebDavProperty propstatProperty = new WebDavProperty("propstat", string.Empty);
            XmlElement propstatElement = propstatProperty.ToXmlElement(responseDoc);

            // The propstat/status element
            WebDavProperty statusProperty = new WebDavProperty("status", "HTTP/1.1 " + context.Response.StatusCode + " " +
                    HttpWorkerRequest.GetStatusDescription(context.Response.StatusCode));
            propstatElement.AppendChild(statusProperty.ToXmlElement(responseDoc));

            // The other propstat children
            foreach (WebDavProperty property in from XmlNode child in propNode.ChildNodes
                where child.Name.ToLower()
                    .Contains("creationtime") || child.Name.ToLower()
                        .Contains("fileattributes") || child.Name.ToLower()
                            .Contains("lastaccesstime") || child.Name.ToLower()
                                .Contains("lastmodifiedtime")
                let node = propNode.SelectSingleNode(child.Name, manager)

                select new WebDavProperty(child.LocalName, string.Empty, node != null ? node.NamespaceURI : string.Empty))

                propstatElement.AppendChild(property.ToXmlElement(responseDoc));

            responseNode.AppendChild(propstatElement);

            /***************************************************************************************************
            * Send the response
            ***************************************************************************************************/
            
            // convert the StringBuilder
            string resp = responseDoc.InnerXml;
            byte[] responseBytes = Encoding.UTF8.GetBytes(resp);


            // HttpStatusCode doesn't contain WebDav status codes, but HttpWorkerRequest can handle these WebDav status codes
            context.SetStatusCode((int)WebDavStatusCode.MultiStatus);

            // set the headers of the response
            context.Response.ContentLength64 = responseBytes.Length;
            context.Response.AppendHeader("Content-Type", "text/xml");

            // the body
            context.Response.OutputStream.Write(responseBytes, 0, responseBytes.Length);

            context.Response.Close();
        }
        /// <summary>
        /// Copies the item.
        /// </summary>
        /// <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(IWebDavContext context, IWebDavStore store, IWebDavStoreItem source)
        {
            Uri destinationUri = GetDestinationHeader(context.Request);
            IWebDavStoreCollection destinationParentCollection = GetParentCollection(store, context, 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);

            var statusCode = isNew ? HttpStatusCode.Created : HttpStatusCode.NoContent;
            context.SetStatusCode(statusCode);
        }
        /// <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)
        {
            /***************************************************************************************************
            * Retreive al the information from the request
            ***************************************************************************************************/

            // Get the URI to the location
            Uri requestUri = context.Request.Url;

            // Initiate the XmlNamespaceManager and the XmlNodes
            XmlNamespaceManager manager  = null;
            XmlNode             propNode = null;

            // try to read the body
            try
            {
                StreamReader reader      = new StreamReader(context.Request.InputStream, Encoding.UTF8);
                string       requestBody = reader.ReadToEnd();

                if (!String.IsNullOrEmpty(requestBody))
                {
                    XmlDocument requestDocument = new XmlDocument();
                    requestDocument.LoadXml(requestBody);

                    if (requestDocument.DocumentElement != null)
                    {
                        if (requestDocument.DocumentElement.LocalName != "propertyupdate")
                        {
                            WebDavServer.Log.Debug("PROPPATCH method without propertyupdate 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:");

                        propNode = requestDocument.DocumentElement.SelectSingleNode("D:set/D:prop", manager);
                    }
                }
            }
            catch (Exception ex)
            {
                WebDavServer.Log.Warn(ex.Message);
            }

            /***************************************************************************************************
            * Take action
            ***************************************************************************************************/

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

            FileInfo fileInfo = new FileInfo(item.ItemPath);

            if (propNode != null && fileInfo.Exists)
            {
                foreach (XmlNode node in propNode.ChildNodes)
                {
                    switch (node.LocalName)
                    {
                    case "Win32CreationTime":
                        fileInfo.CreationTime = Convert.ToDateTime(node.InnerText).ToUniversalTime();
                        break;

                    case "Win32LastAccessTime":
                        fileInfo.LastAccessTime = Convert.ToDateTime(node.InnerText).ToUniversalTime();
                        break;

                    case "Win32LastModifiedTime":
                        fileInfo.LastWriteTime = Convert.ToDateTime(node.InnerText).ToUniversalTime();
                        break;

                    case "Win32FileAttributes":
                        //todo Win32FileAttributes
                        //fileInfo.Attributes =
                        //fileInfo.Attributes = Convert.ToDateTime(node.InnerText);
                        break;
                    }
                }
            }


            /***************************************************************************************************
            * 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:multistatus " +
                                       "xmlns:Z=\"urn:schemas-microsoft-com:\" xmlns:D=\"DAV:\">" +
                                       "<D:response></D:response></D:multistatus>";

            responseDoc.LoadXml(responseXml);

            // Select the response node
            XmlNode responseNode = responseDoc.DocumentElement.SelectSingleNode("D:response", manager);

            // Add the elements

            // The href element
            WebDavProperty hrefProperty = new WebDavProperty("href", requestUri.ToString());

            responseNode.AppendChild(hrefProperty.ToXmlElement(responseDoc));

            // The propstat element
            WebDavProperty propstatProperty = new WebDavProperty("propstat", string.Empty);
            XmlElement     propstatElement  = propstatProperty.ToXmlElement(responseDoc);

            // The propstat/status element
            WebDavProperty statusProperty = new WebDavProperty("status", "HTTP/1.1 " + context.Response.StatusCode + " " +
                                                               HttpWorkerRequest.GetStatusDescription(context.Response.StatusCode));

            propstatElement.AppendChild(statusProperty.ToXmlElement(responseDoc));

            // The other propstat children
            foreach (WebDavProperty property in from XmlNode child in propNode.ChildNodes
                     where child.Name.ToLower()
                     .Contains("creationtime") || child.Name.ToLower()
                     .Contains("fileattributes") || child.Name.ToLower()
                     .Contains("lastaccesstime") || child.Name.ToLower()
                     .Contains("lastmodifiedtime")
                     let node = propNode.SelectSingleNode(child.Name, manager)

                                select new WebDavProperty(child.LocalName, string.Empty, node != null ? node.NamespaceURI : string.Empty))
            {
                propstatElement.AppendChild(property.ToXmlElement(responseDoc));
            }

            responseNode.AppendChild(propstatElement);

            /***************************************************************************************************
            * Send the response
            ***************************************************************************************************/

            // convert the StringBuilder
            string resp = responseDoc.InnerXml;

            byte[] responseBytes = Encoding.UTF8.GetBytes(resp);


            // HttpStatusCode doesn't contain WebDav status codes, but HttpWorkerRequest can handle these WebDav status codes
            context.SetStatusCode((int)WebDavStatusCode.MultiStatus);

            // set the headers of the response
            context.Response.ContentLength64 = responseBytes.Length;
            context.Response.AppendHeader("Content-Type", "text/xml");

            // the body
            context.Response.OutputStream.Write(responseBytes, 0, responseBytes.Length);

            context.Response.Close();
        }
        /// <summary>
        /// Sends the response
        /// </summary>
        /// <param name="context">The <see cref="IWebDavContext" /> containing the response</param>
        /// <param name="responseDocument">The <see cref="XmlDocument" /> containing the response body</param>
        private static void MakeResponse(IWebDavContext context, XmlDocument responseDocument)
        {
            // convert the XmlDocument
            byte[] responseBytes = Encoding.UTF8.GetBytes(responseDocument.InnerXml);

            // HttpStatusCode doesn't contain WebDav status codes, but HttpWorkerRequest can handle these WebDav status codes
            context.SetStatusCode((int)WebDavStatusCode.MultiStatus);

            context.Response.ContentLength64 = responseBytes.Length;
            context.Response.AppendHeader("Content-Type", "text/xml");
            context.Response.OutputStream.Write(responseBytes, 0, responseBytes.Length);
        }
Beispiel #18
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);
        }
        /// <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.WebDavMethodNotAllowedException"></exception>
        /// <exception cref="WebDAVSharp.Server.Exceptions.WebDavLengthRequiredException">If the ContentLength header was not found</exception>
        public void ProcessRequest(IWebDavContext context, IWebDavStore store)
        {
            // Get the parent collection
            IWebDavStoreCollection parentCollection = GetParentCollection(store, context, 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.SetStatusCode(HttpStatusCode.Created);
        }