/// <summary> /// Create a response for Depth 0 request - just a root info /// </summary> /// <param name="xmlDocument"></param> /// <returns></returns> private XmlElement CreateDepth0Response(HTTPHeader header, XmlDocument xmlDocument, PropfindProperties propfindProperties, HashSet<String> destinationObjectStreamTypes) { var XMLElemResponse = xmlDocument.CreateElement(S_DAV_PREFIX, "response", S_DAV_NAMESPACE_URI); if(header.IsSVNClient) XMLElemResponse.SetAttribute("xmlns:"+S_SVN_PREFIX, S_SVN_NAMESPACE_URI); #region response elements var XMLElemHref = xmlDocument.CreateElement(S_DAV_PREFIX, "href", S_DAV_NAMESPACE_URI); if (header.IsSVNClient) XMLElemHref.InnerText = header.RawUrl; else XMLElemHref.InnerText = header.FullHTTPDestinationPath(); var Props = new Dictionary<String, String>(); // Should return ALL props var DisplayName = DirectoryHelper.GetObjectName(header.Destination); if (DisplayName == String.Empty) DisplayName = FSPathConstants.PathDelimiter; if (!header.IsSVNClient) { if (!destinationObjectStreamTypes.Contains(FSConstants.INLINEDATA)) { //var ObjectLocator = _AGraphDSSharp.ExportObjectLocator(ObjectLocation.ParseString((Header.Destination)); if (destinationObjectStreamTypes.Contains(FSConstants.DIRECTORYSTREAM)) { Props.Add(PropfindProperties.Getcontenttype.ToString(), System.Net.Mime.MediaTypeNames.Application.Octet); Props.Add(PropfindProperties.Getcontentlength.ToString(), "0"); Props.Add(PropfindProperties.Resourcetype.ToString(), "collection"); // Do we want to add some MS specific data? if (header.ClientType == ClientTypes.MicrosoftWebDAVMiniRedir) { //Props.Add("isFolder", "f"); //If the element contains the 'collection' child element plus additional unrecognized elements, it should generally be treated as a collection. If the element contains no recognized child elements, it should be treated as a non-collection resource //Props.Add("isCollection", "1"); //Props.Add("ishidden", "0"); } } else if (destinationObjectStreamTypes.Contains(FSConstants.FILESTREAM)) { Props.Add(PropfindProperties.Getcontentlength.ToString(), _AGraphDSSharp.GetFSObject<FileObject>(ObjectLocation.ParseString(header.Destination), FSConstants.FILESTREAM, null, null, 0, false).Value.ObjectData.Length.ToString()); } //if ((myPropfindProperties == PropfindProperties.NONE) || ((myPropfindProperties & PropfindProperties.Getlastmodified) == PropfindProperties.Getlastmodified)) //{ //if (ObjectLocator.INodeReference != null) // Props.Add(PropfindProperties.Getlastmodified.ToString(), GetConvertedDateTime(ObjectLocator.INodeReference.LastModificationTime).ToString(S_DATETIME_FORMAT)); //else // Props.Add(PropfindProperties.Getlastmodified.ToString(), GetConvertedDateTime(ObjectLocator.ModificationTime.Ticks).ToString(S_DATETIME_FORMAT)); //} //if ((myPropfindProperties == PropfindProperties.NONE) || ((myPropfindProperties & PropfindProperties.Creationdate) == PropfindProperties.Creationdate)) //{ // Props.Add(PropfindProperties.Creationdate.ToString(), GetConvertedDateTime(ObjectLocator.INodeReference.CreationTime).ToString(S_DATETIME_FORMAT)); //} } if ((propfindProperties == PropfindProperties.NONE) || ((propfindProperties & PropfindProperties.Displayname) == PropfindProperties.Displayname)) Props.Add(PropfindProperties.Displayname.ToString(), DisplayName); //Props.Add(PropfindProperties.Getcontentlanguage.ToString(), ""); // If no Content-Language is specified, the default is that the content is intended for all language audiences. //Props.Add(PropfindProperties.Getetag.ToString(), CacheUUID.NewGuid().ToString()); // to identify a single ressource for update purposes (see If-Match) if ((propfindProperties == PropfindProperties.NONE) || ((propfindProperties & PropfindProperties.Lockdiscovery) == PropfindProperties.Lockdiscovery)) Props.Add(PropfindProperties.Lockdiscovery.ToString(), ""); if ((propfindProperties == PropfindProperties.NONE) || ((propfindProperties & PropfindProperties.Supportedlock) == PropfindProperties.Supportedlock)) Props.Add(PropfindProperties.Supportedlock.ToString(), ""); } else // if (Header.IsSVNClient) { Boolean AllProps = ((propfindProperties & PropfindProperties.AllProp) == PropfindProperties.AllProp); if (destinationObjectStreamTypes.Contains(FSConstants.DIRECTORYSTREAM)) { if (AllProps || (propfindProperties & PropfindProperties.Resourcetype) == PropfindProperties.Resourcetype) Props.Add(PropfindProperties.Resourcetype.ToString(), "collection"); if (AllProps) Props.Add(PropfindProperties.Getcontenttype.ToString(), System.Net.Mime.MediaTypeNames.Application.Octet); } if (AllProps) { if (destinationObjectStreamTypes.Contains(FSConstants.INLINEDATA)) { //ObjectLocator ObjectLocator = _AGraphDSSharp.ExportObjectLocator(ObjectLocation.ParseString((Header.Destination)); //Props.Add(PropfindProperties.Creationdate.ToString(), GetConvertedDateTime(ObjectLocator.INodeReference.CreationTime).ToString(S_DATETIME_FORMAT)); //Props.Add(PropfindProperties.Getlastmodified.ToString(), GetConvertedDateTime(ObjectLocator.INodeReference.LastModificationTime).ToString(S_DATETIME_FORMAT)); } Props.Add(PropfindProperties.CheckedIn.ToString(), "ver"); // handled in special way Props.Add(PropfindProperties.VersionControlledConfiguration.ToString(), ""); // handled in special way Props.Add(PropfindProperties.Getetag.ToString(), Guid.NewGuid().ToString()); // to identify a single ressource for update purposes (see If-Match) Props.Add(PropfindProperties.VersionName.ToString(), "37491"); Props.Add(PropfindProperties.CreatorDisplayname.ToString(), "Stefan"); Props.Add(PropfindProperties.BaselineRelativePath.ToString(), ""); Props.Add(PropfindProperties.RepositoryUuid.ToString(), "612f8ebc-c883-4be0-9ee0-a4e9ef946e3a");//CacheUUID.NewGuid().ToString()); Props.Add(PropfindProperties.DeadpropCount.ToString(), "1"); Props.Add(PropfindProperties.Lockdiscovery.ToString(), ""); } if ((propfindProperties & PropfindProperties.CheckedIn) == PropfindProperties.CheckedIn) Props.Add(PropfindProperties.CheckedIn.ToString(), ""); // handled in special way if ((propfindProperties & PropfindProperties.VersionControlledConfiguration) == PropfindProperties.VersionControlledConfiguration) Props.Add(PropfindProperties.VersionControlledConfiguration.ToString(), ""); // handled in special way if ((propfindProperties & PropfindProperties.BaselineRelativePath) == PropfindProperties.BaselineRelativePath) Props.Add(PropfindProperties.BaselineRelativePath.ToString(), ""); if ((propfindProperties & PropfindProperties.RepositoryUuid) == PropfindProperties.RepositoryUuid) Props.Add(PropfindProperties.RepositoryUuid.ToString(), "612f8ebc-c883-4be0-9ee0-a4e9ef946e3a");//CacheUUID.NewGuid().ToString()); if ((propfindProperties & PropfindProperties.BaselineCollection) == PropfindProperties.BaselineCollection) Props.Add(PropfindProperties.BaselineCollection.ToString(), ""); if ((propfindProperties & PropfindProperties.VersionName) == PropfindProperties.VersionName) Props.Add(PropfindProperties.VersionName.ToString(), ""); } XmlElement ElemPropstat = CreatePropstatElement(header, xmlDocument, Props, header.Destination); #endregion XMLElemResponse.AppendChild(XMLElemHref); XMLElemResponse.AppendChild(ElemPropstat); return XMLElemResponse; }
/// <summary> /// Create a repsonse for a PROPFIND request (Directory(File)-Listing /// </summary> /// <param name="properties"></param> /// <returns></returns> private Byte[] CreatePropfindResponse(HTTPHeader header, PropfindProperties propfindProperties, HashSet<String> _DestinationObjectStreamTypes, params string[] properties) { #region Create XmlDocument XmlDocument XmlDocument = new XmlDocument(); //XmlDeclaration xmlDeclaration = XmlDocument.CreateXmlDeclaration("1.0", "utf-8", ""); //XmlDocument.AppendChild(xmlDeclaration); XmlElement Root = XmlDocument.CreateElement(S_DAV_PREFIX, "multistatus", S_DAV_NAMESPACE_URI); //Root.SetAttribute("xmlns:" + S_SVN_PREFIX, S_SVN_NAMESPACE_URI); if (header.GetDepth() == WebDAVDepth.Depth0) { Root.AppendChild(CreateDepth0Response(header, XmlDocument, propfindProperties, _DestinationObjectStreamTypes)); } Boolean IsLegalDir = true; if (S_INVALID_DIRECTORIES.Contains(String.Concat("|", DirectoryHelper.GetObjectName(header.Destination), "|"))) IsLegalDir = false; var directoryObjectR = _AGraphDSSharp.GetFSObject<DirectoryObject>(ObjectLocation.ParseString(header.Destination), FSConstants.DIRECTORYSTREAM, null, null, 0, false); // uncommented because _AGraphDSSharp.isIDirectoryObject is odd //if (IsLegalDir && _AGraphDSSharp.isIDirectoryObject(ObjectLocation.ParseString((header.Destination)) == Trinary.TRUE) if (IsLegalDir && directoryObjectR.Success()) { #region root elements if (header.GetDepth() != WebDAVDepth.Depth0) { // Get Content of the Current Directory var DirectoryObject = directoryObjectR.Value; foreach (DirectoryEntryInformation actualDirectoryEntry in DirectoryObject.GetExtendedDirectoryListing()) { //if (((String)DirectoryEntries["ObjectName"]).Contains(".forest") || ((String)DirectoryEntries["ObjectName"]).Contains(".fs") || ((String)DirectoryEntries["ObjectName"]).Contains(".metadata") || ((String)DirectoryEntries["ObjectName"]).Contains(".revisions") || ((String)DirectoryEntries["ObjectName"]).Contains(".vfs")) if (S_INVALID_DIRECTORIES.Contains(String.Concat("|", actualDirectoryEntry.Name))) continue; String ObjectDestination = header.Destination + (header.Destination.EndsWith("/") ? "" : FSPathConstants.PathDelimiter) + actualDirectoryEntry.Name; if (actualDirectoryEntry.Streams.Contains(FSConstants.DIRECTORYSTREAM)) { try { IDirectoryObject CurDirectoryObject = _AGraphDSSharp.GetFSObject<DirectoryObject>(ObjectLocation.ParseString(ObjectDestination), FSConstants.DIRECTORYSTREAM, null, null, 0, false).Value; String HRef = header.FullHTTPDestinationPath() + (header.FullHTTPDestinationPath().EndsWith("/") ? "" : FSPathConstants.PathDelimiter) + actualDirectoryEntry.Name; XmlElement XmlElement = CreateResponseElement_Dir(header, XmlDocument, HRef, actualDirectoryEntry.Name, CurDirectoryObject, propfindProperties); Root.AppendChild(XmlElement); } catch { } } else if (actualDirectoryEntry.Streams.Contains(FSConstants.FILESTREAM)) { String HRef = header.FullHTTPDestinationPath() + (header.FullHTTPDestinationPath().EndsWith("/") ? "" : FSPathConstants.PathDelimiter) + actualDirectoryEntry.Name; //INode INode = _AGraphDSSharp.ExportINode(ObjectLocation.ParseString((ObjectDestination)); UInt64 Size = (UInt64)_AGraphDSSharp.GetFSObject<FileObject>(ObjectLocation.ParseString(ObjectDestination), FSConstants.FILESTREAM, null, null, 0, false).Value.ObjectData.Length; XmlElement ResponseElement_File = CreateResponseElement_File(header, XmlDocument, HRef, actualDirectoryEntry.Name, System.Net.Mime.MediaTypeNames.Text.Plain, Size, propfindProperties); Root.AppendChild(ResponseElement_File); } else if (actualDirectoryEntry.Streams.Contains(FSConstants.SYMLINK)) { String HRef = header.FullHTTPDestinationPath() + (header.FullHTTPDestinationPath().EndsWith("/") ? "" : FSPathConstants.PathDelimiter) + actualDirectoryEntry.Name; Root.AppendChild(CreateResponseElement_Dir(header, XmlDocument, HRef, actualDirectoryEntry.Name, null, propfindProperties)); } else if (actualDirectoryEntry.Streams.Contains(FSConstants.INLINEDATA)) { String HRef = header.FullHTTPDestinationPath() + (header.FullHTTPDestinationPath().EndsWith("/") ? "" : FSPathConstants.PathDelimiter) + actualDirectoryEntry.Name; Byte[] Inlinedata = DirectoryObject.GetInlineData(actualDirectoryEntry.Name); // Return CreationTime and LastModificationTime of the DirectoryObject! var _CreationTime = DateTime.Now; var _LastModificationTime = DateTime.Now; var _AGraphObject = DirectoryObject as AFSObject; if (_AGraphObject != null) if (_AGraphObject.INodeReference != null) { _CreationTime = new DateTime((Int64)_AGraphObject.INodeReference.CreationTime); _LastModificationTime = new DateTime((Int64)_AGraphObject.INodeReference.LastModificationTime); } Root.AppendChild( CreateResponseElement_File( header, XmlDocument, HRef, actualDirectoryEntry.Name, System.Net.Mime.MediaTypeNames.Text.Plain, (UInt64)Inlinedata.Length, _LastModificationTime, _CreationTime, propfindProperties ) ); } //else // Root.AppendChild(CreateResponseElement_Dir(XmlDocument, actualDirectoryEntry.StreamTypes + ":" + actualDirectoryEntry.myLogin, actualDirectoryEntry.StreamTypes + actualDirectoryEntry.myLogin, null, myPropfindProperties)); } } #endregion } XmlDocument.AppendChild(Root); #endregion #region Stream XmlDocument to ByteArray XmlWriterSettings settings; settings = new XmlWriterSettings(); settings.Encoding = Encoding.UTF8; using (MemoryStream stream = new MemoryStream()) { using (XmlWriter writer = XmlWriter.Create(stream, settings)) { XmlDocument.WriteContentTo(writer); writer.Flush(); return CleanContent(stream.ToArray()); } } #endregion }
/// <summary> /// Create a repsonse for a PROPPATCH request - after uploading a file /// </summary> /// <param name="properties"></param> /// <returns></returns> private Byte[] CreateProppatchResponse(HTTPHeader header, params string[] properties) { #region Create XmlDocument XmlDocument XmlDocument = new XmlDocument(); XmlElement Root = XmlDocument.CreateElement(S_DAV_PREFIX, "multistatus", S_DAV_NAMESPACE_URI); Root.SetAttribute("xmlns:Z", "urn:schemas-microsoft-com:"); #region Create Response Element XmlElement ElemResponse = XmlDocument.CreateElement(S_DAV_PREFIX, "response", S_DAV_NAMESPACE_URI); XmlElement ElemHref = XmlDocument.CreateElement(S_DAV_PREFIX, "href", S_DAV_NAMESPACE_URI); ElemHref.InnerText = header.FullHTTPDestinationPath(); ElemResponse.AppendChild(ElemHref); foreach (String Property in properties) { XmlElement ElemPropstat = XmlDocument.CreateElement(S_DAV_PREFIX, "propstat", S_DAV_NAMESPACE_URI); XmlElement ElemStatus = XmlDocument.CreateElement(S_DAV_PREFIX, "status", S_DAV_NAMESPACE_URI); ElemStatus.InnerText = "HTTP/1.1 200 OK"; XmlElement ElemProp = XmlDocument.CreateElement(S_DAV_PREFIX, "prop", S_DAV_NAMESPACE_URI); ElemProp.AppendChild(XmlDocument.CreateElement("Z", Property, "urn:schemas-microsoft-com:")); ElemPropstat.AppendChild(ElemProp); ElemPropstat.AppendChild(ElemStatus); ElemResponse.AppendChild(ElemPropstat); } #endregion Root.AppendChild(ElemResponse); XmlDocument.AppendChild(Root); #endregion #region Stream XmlDocument to ByteArray XmlWriterSettings settings; settings = new XmlWriterSettings(); settings.Encoding = Encoding.UTF8; using (MemoryStream stream = new MemoryStream()) { using (XmlWriter writer = XmlWriter.Create(stream, settings)) { XmlDocument.WriteContentTo(writer); writer.Flush(); return CleanContent(stream.ToArray()); } } #endregion }
/// <summary> /// Create a repsonse for a LOCK request - introducing a file copy (get) /// </summary> /// <param name="properties"></param> /// <returns></returns> private Byte[] CreateLockResponse(HTTPHeader header, Byte[] body, WebDAVDepth depth, params string[] properties) { #region Get Owner XmlDocument OwnerXmlDocument = new XmlDocument(); OwnerXmlDocument.LoadXml(Encoding.UTF8.GetString(body)); String NamespacePrefix = OwnerXmlDocument.GetPrefixOfNamespace(S_DAV_NAMESPACE_URI); if (NamespacePrefix == "") NamespacePrefix = S_DAV_PREFIX; XmlNamespaceManager XmlNamespaceManager = new XmlNamespaceManager(OwnerXmlDocument.NameTable); XmlNamespaceManager.AddNamespace(NamespacePrefix, S_DAV_NAMESPACE_URI); XmlElement OwnerRoot = OwnerXmlDocument.DocumentElement; XmlNode OwnerNode = OwnerRoot.SelectSingleNode(String.Concat("/", S_DAV_PREFIX, ":lockinfo/", S_DAV_PREFIX, ":owner/", S_DAV_PREFIX, ":href"), XmlNamespaceManager); String Owner = OwnerNode.InnerText; #endregion String LockTokenString = String.Concat("{" + Guid.NewGuid().ToString() + "}"); TimeSpan LockLifetime; try { LockLifetime = TimeSpan.FromSeconds(Double.Parse(header.Headers["Timeout"].Substring(header.Headers["Timeout"].IndexOf('-') + 1))); } catch { LockLifetime = TimeSpan.FromSeconds(60 * 60); } RessourceLock.LockRessource(LockTokenString, header.Destination, LockLifetime); #region Create XmlDocument XmlDocument XmlDocument = new XmlDocument(); XmlElement Root = XmlDocument.CreateElement(S_DAV_PREFIX, "prop", S_DAV_NAMESPACE_URI); AddPropfindLockdiscoveryElements(Root, header.Destination, header.FullHTTPDestinationPath()); XmlDocument.AppendChild(Root); #endregion #region Stream XmlDocument to ByteArray XmlWriterSettings settings; settings = new XmlWriterSettings(); settings.Encoding = Encoding.UTF8; using (MemoryStream stream = new MemoryStream()) { using (XmlWriter writer = XmlWriter.Create(stream, settings)) { XmlDocument.WriteContentTo(writer); writer.Flush(); return CleanContent(stream.ToArray()); } } #endregion }