WebDavProppatchMethodHandler.cs 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Web;
  8. using System.Xml;
  9. using Mtp2Dav.WebDAVSharp.Server._1d2086a502937936ebc6bfe19cfa15d855be1c31.Adapters;
  10. using Mtp2Dav.WebDAVSharp.Server._1d2086a502937936ebc6bfe19cfa15d855be1c31.Stores;
  11. using Mtp2Dav.WebDAVSharp.Server._1d2086a502937936ebc6bfe19cfa15d855be1c31.Utilities;
  12. namespace Mtp2Dav.WebDAVSharp.Server._1d2086a502937936ebc6bfe19cfa15d855be1c31.MethodHandlers
  13. {
  14. /// <summary>
  15. /// This class implements the <c>PROPPATCH</c> HTTP method for WebDAV#.
  16. /// </summary>
  17. internal class WebDavProppatchMethodHandler : WebDavMethodHandlerBase, IWebDavMethodHandler
  18. {
  19. /// <summary>
  20. /// Gets the collection of the names of the HTTP methods handled by this instance.
  21. /// </summary>
  22. /// <value>
  23. /// The names.
  24. /// </value>
  25. public IEnumerable<string> Names => new[]
  26. {
  27. "PROPPATCH"
  28. };
  29. /// <summary>
  30. /// Processes the request.
  31. /// </summary>
  32. /// <param name="server">The <see cref="WebDavServer" /> through which the request came in from the client.</param>
  33. /// <param name="context">
  34. /// The
  35. /// <see cref="IHttpListenerContext" /> object containing both the request and response
  36. /// objects to use.
  37. /// </param>
  38. /// <param name="store">The <see cref="IWebDavStore" /> that the <see cref="WebDavServer" /> is hosting.</param>
  39. public void ProcessRequest(WebDavServer server, IHttpListenerContext context, IWebDavStore store)
  40. {
  41. /***************************************************************************************************
  42. * Retreive al the information from the request
  43. ***************************************************************************************************/
  44. // Get the URI to the location
  45. var requestUri = context.Request.Url;
  46. // Initiate the XmlNamespaceManager and the XmlNodes
  47. XmlNamespaceManager manager = null;
  48. XmlNode propNode = null;
  49. // try to read the body
  50. try
  51. {
  52. var reader = new StreamReader(context.Request.InputStream, Encoding.UTF8);
  53. var requestBody = reader.ReadToEnd();
  54. if (!string.IsNullOrEmpty(requestBody))
  55. {
  56. var requestDocument = new XmlDocument();
  57. requestDocument.LoadXml(requestBody);
  58. if (requestDocument.DocumentElement != null)
  59. {
  60. if (requestDocument.DocumentElement.LocalName != "propertyupdate")
  61. {
  62. }
  63. manager = new XmlNamespaceManager(requestDocument.NameTable);
  64. manager.AddNamespace("D", "DAV:");
  65. manager.AddNamespace("Office", "schemas-microsoft-com:office:office");
  66. manager.AddNamespace("Repl", "http://schemas.microsoft.com/repl/");
  67. manager.AddNamespace("Z", "urn:schemas-microsoft-com:");
  68. propNode = requestDocument.DocumentElement.SelectSingleNode("D:set/D:prop", manager);
  69. }
  70. }
  71. }
  72. catch (Exception ex)
  73. {
  74. Debug.Print(ex.ToString());
  75. }
  76. /***************************************************************************************************
  77. * Take action
  78. ***************************************************************************************************/
  79. // Get the parent collection of the item
  80. var collection = GetParentCollection(server, store, context.Request.Url);
  81. // Get the item from the collection
  82. var item = GetItemFromCollection(collection, context.Request.Url);
  83. var fileInfo = new FileInfo(item.ItemPath);
  84. if (propNode != null && fileInfo.Exists)
  85. {
  86. foreach (XmlNode node in propNode.ChildNodes)
  87. {
  88. switch (node.LocalName)
  89. {
  90. case "Win32CreationTime":
  91. fileInfo.CreationTime = Convert.ToDateTime(node.InnerText).ToUniversalTime();
  92. break;
  93. case "Win32LastAccessTime":
  94. fileInfo.LastAccessTime = Convert.ToDateTime(node.InnerText).ToUniversalTime();
  95. break;
  96. case "Win32LastModifiedTime":
  97. fileInfo.LastWriteTime = Convert.ToDateTime(node.InnerText).ToUniversalTime();
  98. break;
  99. case "Win32FileAttributes":
  100. //fileInfo.Attributes =
  101. //fileInfo.Attributes = Convert.ToDateTime(node.InnerText);
  102. break;
  103. }
  104. }
  105. }
  106. /***************************************************************************************************
  107. * Create the body for the response
  108. ***************************************************************************************************/
  109. // Create the basic response XmlDocument
  110. var responseDoc = new XmlDocument();
  111. const string responseXml = "<?xml version=\"1.0\" encoding=\"utf-8\" ?><D:multistatus " +
  112. "xmlns:Z=\"urn:schemas-microsoft-com:\" xmlns:D=\"DAV:\">" +
  113. "<D:response></D:response></D:multistatus>";
  114. responseDoc.LoadXml(responseXml);
  115. // Select the response node
  116. var responseNode = responseDoc.DocumentElement.SelectSingleNode("D:response", manager);
  117. // Add the elements
  118. // The href element
  119. var hrefProperty = new WebDavProperty("href", requestUri.ToString());
  120. responseNode.AppendChild(hrefProperty.ToXmlElement(responseDoc));
  121. // The propstat element
  122. var propstatProperty = new WebDavProperty("propstat", "");
  123. var propstatElement = propstatProperty.ToXmlElement(responseDoc);
  124. // The propstat/status element
  125. var statusProperty = new WebDavProperty("status", "HTTP/1.1 " + context.Response.StatusCode + " " +
  126. HttpWorkerRequest.GetStatusDescription(
  127. context.Response.StatusCode));
  128. propstatElement.AppendChild(statusProperty.ToXmlElement(responseDoc));
  129. // The other propstat children
  130. foreach (var property in from XmlNode child in propNode.ChildNodes
  131. where child.Name.ToLower()
  132. .Contains("creationtime") || child.Name.ToLower()
  133. .Contains("fileattributes") || child.Name.ToLower()
  134. .Contains("lastaccesstime") || child.Name.ToLower()
  135. .Contains("lastmodifiedtime")
  136. let node = propNode.SelectSingleNode(child.Name, manager)
  137. select node != null
  138. ? new WebDavProperty(child.LocalName, "", node.NamespaceURI)
  139. : new WebDavProperty(child.LocalName, "", ""))
  140. propstatElement.AppendChild(property.ToXmlElement(responseDoc));
  141. responseNode.AppendChild(propstatElement);
  142. /***************************************************************************************************
  143. * Send the response
  144. ***************************************************************************************************/
  145. // convert the StringBuilder
  146. var resp = responseDoc.InnerXml;
  147. var responseBytes = Encoding.UTF8.GetBytes(resp);
  148. // HttpStatusCode doesn't contain WebDav status codes, but HttpWorkerRequest can handle these WebDav status codes
  149. context.Response.StatusCode = (int) WebDavStatusCode.MultiStatus;
  150. context.Response.StatusDescription =
  151. HttpWorkerRequest.GetStatusDescription((int) WebDavStatusCode.MultiStatus);
  152. // set the headers of the response
  153. context.Response.ContentLength64 = responseBytes.Length;
  154. context.Response.AdaptedInstance.ContentType = "text/xml";
  155. // the body
  156. context.Response.OutputStream.Write(responseBytes, 0, responseBytes.Length);
  157. context.Response.Close();
  158. }
  159. }
  160. }