Exemple #1
0
 public HTTPContext(HTTPHeader myRequestHeader, Byte[] myRequestBody, HTTPHeader myResponseHeader, Stream myResponseStream)
 {
     _RequestHeader  = myRequestHeader;
     _RequestBody    = myRequestBody;
     _ResponseHeader = myResponseHeader;
     _ResponseStream = myResponseStream;
 }
Exemple #2
0
 public HTTPContext(HTTPHeader myRequestHeader, Byte[] myRequestBody, HTTPHeader myResponseHeader, Stream myResponseStream)
 {
     _RequestHeader  = myRequestHeader;
     _RequestBody    = myRequestBody;
     _ResponseHeader = myResponseHeader;
     _ResponseStream = myResponseStream;
 }
        public Boolean GetHeaderAndBody(NetworkStream myStream, out HTTPHeader myHttpHeader, out Byte[] myBody)
        {
            myHttpHeader = null;
            myBody = null;

            #region Data Definition

            var ReadBuffer = new Byte[16 * 1024];

            Int32 BytesRead = 0;
            var FirstBytesList = new List<Byte>();

            #endregion

            #region Read the FirstBytes until no Data is available or we read more than we can store in a List of Bytes

            do
            {

                BytesRead = myStream.Read(ReadBuffer, 0, ReadBuffer.Length);

                if (BytesRead == ReadBuffer.Length)
                {
                    FirstBytesList.AddRange(ReadBuffer);
                }

                else
                {
                    var _TempBytes = new Byte[BytesRead];
                    Array.Copy(ReadBuffer, 0, _TempBytes, 0, BytesRead);
                    FirstBytesList.AddRange(_TempBytes);
                }

            }
            while (myStream.DataAvailable && BytesRead > 0 && FirstBytesList.Count < (Int32.MaxValue - ReadBuffer.Length));

            #endregion

            #region Find Header

            Int32 CurPos = 4;
            Byte[] FirstBytes = FirstBytesList.ToArray();

            if (FirstBytes.Length <= CurPos)
            {

                // If header length < 4 we have an invalid header
                myStream.Close();

                return false;

            }

            while ((CurPos < FirstBytes.Length) && !(FirstBytes[CurPos - 4] == 13 && FirstBytes[CurPos - 3] == 10 && FirstBytesList[CurPos - 2] == 13 && FirstBytesList[CurPos - 1] == 10))
            {
                CurPos++;
            }

            var HeaderBytes = new Byte[CurPos];
            Array.Copy(FirstBytes, 0, HeaderBytes, 0, CurPos);

            var HeaderString = Encoding.UTF8.GetString(HeaderBytes);
            myHttpHeader = new HTTPHeader(HeaderString);

            #endregion

            #region Body

            myBody = new Byte[myHttpHeader.ContentLength];

            if (myHttpHeader.ContentLength > 0)
            {

                if (myHttpHeader.ContentLength < (UInt64)(FirstBytes.Length - CurPos))
                {
                    // contentlength defined in the header is lower than the recieved bytes
                    return false;
                }

                Array.Copy(FirstBytes, CurPos, myBody, 0, FirstBytes.Length - CurPos);

                // Read the rest of the bytes
                if (myHttpHeader.ContentLength > (UInt64)(FirstBytes.Length - CurPos))
                {

                    var TotalBytesRead = (Int64) FirstBytes.Length - CurPos;

                    while ((UInt64) TotalBytesRead < myHttpHeader.ContentLength)
                    {
                        if (!WaitForStreamDataAvailable())
                            return true;

                        BytesRead = myStream.Read(ReadBuffer, 0, ReadBuffer.Length);
                        Array.Copy(ReadBuffer, 0, myBody, TotalBytesRead, BytesRead);
                        TotalBytesRead += (Int64)BytesRead;
                    }

                }

            }

            #endregion

            return true;
        }
        private HashSet<String> GetDestinationObjectStreamTypes(HTTPHeader header)
        {
            // check validity of folder
            try
            {

                var streams = _AGraphDSSharp.GetObjectStreams(ObjectLocation.ParseString(header.Destination));
                if (streams.Failed())
                {
                    return null;
                }

                return new HashSet<string>(streams.Value);

                // We found a InlineData Element
                //if (_DestinationObjectStreamTypes.Contains(FSConstants.INLINEDATA))
                //    _DestinationObjectLocator = _AGraphDSSharp.ExportObjectLocator(ObjectLocation.ParseString((DirectoryHelper.GetObjectPath(Header.Destination)));
                //else
                //    _DestinationObjectLocator = _AGraphDSSharp.ExportObjectLocator(ObjectLocation.ParseString((Header.Destination));
            }
            catch
            {
                return null;
            }
        }
        /// <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 usual Response Element for a File
        /// </summary>
        /// <param name="xmlDocument">The Parent XmlDocument</param>
        /// <param name="hRef">The Full HTTP reference to the File</param>
        /// <param name="displayname">The display Name (currently not use in WebDAV MS Explorer Client)</param>
        /// <param name="mediaTypeName">The MIMEType</param>
        /// <param name="FilestreamObject">A File Object</param>
        /// <returns></returns>
        private XmlElement CreateResponseElement_File(HTTPHeader header, XmlDocument xmlDocument, String hRef, String displayname, String mediaTypeName, UInt64 size, PropfindProperties propfindProperties)
        {
            //DateTime CreationDate = GetConvertedDateTime(INode.CreationTime);
            //DateTime LastModificationDate = GetConvertedDateTime(INode.LastModificationTime);

            DateTime CreationDate = DateTime.Now;
            DateTime LastModificationDate = DateTime.Now;

            return CreateResponseElement_File(header, xmlDocument, hRef, displayname, mediaTypeName, size, CreationDate, LastModificationDate, propfindProperties);
        }
        /// <summary>
        /// Create a usual Response Element for a File or InlineData
        /// </summary>
        /// <param name="xmlDocument"></param>
        /// <param name="hRef"></param>
        /// <param name="displayname"></param>
        /// <returns></returns>
        private XmlElement CreateResponseElement_File(HTTPHeader header, XmlDocument xmlDocument, String hRef, String displayname, String mediaTypeName, UInt64 contentLength, DateTime creationDate, DateTime lastModificationDate, PropfindProperties propfindProperties)
        {
            // need to convert the DateTime because WebDAV needs this as Zulu converted Timestamp
            //LastModificationDate = TimeZoneInfo.ConvertTime(LastModificationDate, TimeZoneInfo.Utc);
            //CreationDate = TimeZoneInfo.ConvertTime(CreationDate, TimeZoneInfo.Utc);

            XmlElement ElemResponse = xmlDocument.CreateElement(S_DAV_PREFIX, "response", S_DAV_NAMESPACE_URI);

            #region Add response elements

            XmlElement ElemHref = xmlDocument.CreateElement(S_DAV_PREFIX, "href", S_DAV_NAMESPACE_URI);
            ElemHref.InnerText = hRef;

            Dictionary<String, String> Props = new Dictionary<String, String>();

            //Props.Add("displayname", Displayname);
            /*
            if (myPropfindProperties == PropfindProperties.NONE)
            {
                Props.Add(PropfindProperties.Creationdate.ToString(), CreationDate.ToString(S_DATETIME_FORMAT));//, "2008-12-29T15:28:29Z");
                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.Getcontentlength.ToString(), ContentLength.ToString());
                //Props.Add(PropfindProperties.Getcontenttype.ToString(), MediaTypeName);
                //Props.Add(PropfindProperties.Getetag.ToString(), CacheUUID.NewGuid().ToString()); // to identify a single ressource for update purposes (see If-Match)
                Props.Add(PropfindProperties.Getlastmodified.ToString(), LastModificationDate.ToString(S_DATETIME_FORMAT));//"2009-02-09T08:11:12Z");
                Props.Add(PropfindProperties.Lockdiscovery.ToString(), "");
                //Props.Add(PropfindProperties.Resourcetype.ToString(), ""); // is empty for files!
                Props.Add(PropfindProperties.Supportedlock.ToString(), "");
            }
            else
            {
             * */
            if ((propfindProperties == PropfindProperties.NONE) || ((propfindProperties & PropfindProperties.Creationdate)       == PropfindProperties.Creationdate))
                Props.Add(PropfindProperties.Creationdate.ToString(), creationDate.ToString(S_DATETIME_FORMAT));
            if ((propfindProperties == PropfindProperties.NONE) || ((propfindProperties & PropfindProperties.Displayname)        == PropfindProperties.Displayname))
                Props.Add(PropfindProperties.Displayname.ToString(), displayname);
            if ((propfindProperties == PropfindProperties.NONE) || ((propfindProperties & PropfindProperties.Getcontentlanguage) == PropfindProperties.Getcontentlanguage))
                Props.Add(PropfindProperties.Getcontentlanguage.ToString(), "");
            if ((propfindProperties == PropfindProperties.NONE) || ((propfindProperties & PropfindProperties.Getcontentlength)   == PropfindProperties.Getcontentlength))
                Props.Add(PropfindProperties.Getcontentlength.ToString(), contentLength.ToString());
            if ((propfindProperties == PropfindProperties.NONE) || ((propfindProperties & PropfindProperties.Getcontenttype)     == PropfindProperties.Getcontenttype))
                Props.Add(PropfindProperties.Getcontenttype.ToString(), mediaTypeName);
            if ((propfindProperties == PropfindProperties.NONE) || ((propfindProperties & PropfindProperties.Getetag)            == PropfindProperties.Getetag))
                Props.Add(PropfindProperties.Getetag.ToString(), Guid.NewGuid().ToString());
            if ((propfindProperties == PropfindProperties.NONE) || ((propfindProperties & PropfindProperties.Getlastmodified)    == PropfindProperties.Getlastmodified))
                Props.Add(PropfindProperties.Getlastmodified.ToString(), lastModificationDate.ToString(S_DATETIME_FORMAT));
            if ((propfindProperties == PropfindProperties.NONE) || ((propfindProperties & PropfindProperties.Lockdiscovery)      == PropfindProperties.Lockdiscovery))
                Props.Add(PropfindProperties.Lockdiscovery.ToString(), "");
            //if ((myPropfindProperties == PropfindProperties.NONE) || ((myPropfindProperties & PropfindProperties.Resourcetype)       == PropfindProperties.Resourcetype))
            //    Props.Add(PropfindProperties.Resourcetype.ToString(), "");
            if ((propfindProperties == PropfindProperties.NONE) || ((propfindProperties & PropfindProperties.Supportedlock)      == PropfindProperties.Supportedlock))
                Props.Add(PropfindProperties.Supportedlock.ToString(), "");

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

            XmlElement ElemPropstat = CreatePropstatElement(header, xmlDocument, Props, hRef);

            #endregion

            ElemResponse.AppendChild(ElemHref);
            ElemResponse.AppendChild(ElemPropstat);

            return ElemResponse;
        }
        /// <summary>
        /// Create a repsonse for a PUT request - uploading a file
        /// </summary>
        /// <param name="properties"></param>
        /// <returns></returns>
        private Byte[] CreatePutResponse(HTTPHeader header, Byte[] body, 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

            #region Create XmlDocument

            XmlDocument XmlDocument = new XmlDocument();

            XmlElement Root = XmlDocument.CreateElement(S_DAV_PREFIX, "prop", S_DAV_NAMESPACE_URI);
            XmlElement LockDiscovery = XmlDocument.CreateElement(S_DAV_PREFIX, "lockdiscovery", S_DAV_NAMESPACE_URI);
            XmlElement ActiveLock = XmlDocument.CreateElement(S_DAV_PREFIX, "activelock", S_DAV_NAMESPACE_URI);
            XmlElement LockType = XmlDocument.CreateElement(S_DAV_PREFIX, "locktype", S_DAV_NAMESPACE_URI);
            LockType.AppendChild(XmlDocument.CreateElement(S_DAV_PREFIX, "write", S_DAV_NAMESPACE_URI));
            XmlElement LockScope = XmlDocument.CreateElement(S_DAV_PREFIX, "lockscope", S_DAV_NAMESPACE_URI);
            LockType.AppendChild(XmlDocument.CreateElement(S_DAV_PREFIX, "exclusive", S_DAV_NAMESPACE_URI));

            Dictionary<String, String> MoreProps = new Dictionary<String, String>();
            MoreProps.Add("depth", "0");
            MoreProps.Add("owner", Owner);
            MoreProps.Add("timeout", "Second-3600");
            XmlElement ElemMoreActivelockProps = CreatePropstatElement(header, XmlDocument, MoreProps, header.Destination);

            #region LockToken

            XmlElement LockToken = XmlDocument.CreateElement(S_DAV_PREFIX, "locktoken", S_DAV_NAMESPACE_URI);
            XmlElement LockTokenHRef = XmlDocument.CreateElement(S_DAV_PREFIX, "href", S_DAV_NAMESPACE_URI);
            //"opaquelocktoken:{A2E9F1BD-47DB-487E-AA85-8A10ACFA391D}20090323T091747Z";
            LockTokenHRef.InnerText = "opaquelocktoken:{" + Guid.NewGuid().ToString() + "}" + TimestampNonce.AsString(S_DATETIME_FORMAT); //20090323T091747Z";
            LockToken.AppendChild(LockTokenHRef);

            #endregion

            ActiveLock.AppendChild(LockType);
            ActiveLock.AppendChild(LockScope);
            ActiveLock.AppendChild(ElemMoreActivelockProps);
            ActiveLock.AppendChild(LockToken);

            LockDiscovery.AppendChild(ActiveLock);
            Root.AppendChild(LockDiscovery);

            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 stream.ToArray();

                }

            }

            #endregion
        }
        /// <summary>
        /// Create a usual Response Element for an directory
        /// </summary>
        /// <param name="xmlDocument"></param>
        /// <param name="hRef"></param>
        /// <param name="displayname"></param>
        /// <returns></returns>
        private XmlElement CreateResponseElement_Dir(HTTPHeader header, XmlDocument xmlDocument, String hRef, String displayname, IDirectoryObject directoryObject, PropfindProperties propfindProperties)
        {
            String CreationDate = "";
            String LastModificationDate = "";

            //if (DirectoryObject != null && DirectoryObject.INodeReference != null)
            //{
            //    CreationDate = GetConvertedDateTime(DirectoryObject.INodeReference.CreationTime).ToString(S_DATETIME_FORMAT);
            //    LastModificationDate = GetConvertedDateTime(DirectoryObject.INodeReference.LastModificationTime).ToString(S_DATETIME_FORMAT);
            //}

            XmlElement ElemResponse = xmlDocument.CreateElement(S_DAV_PREFIX, "response", S_DAV_NAMESPACE_URI);
            #region response elements

            XmlElement ElemHref = xmlDocument.CreateElement(S_DAV_PREFIX, "href", S_DAV_NAMESPACE_URI);
            ElemHref.InnerText = hRef;

            Dictionary<String, String> Props = new Dictionary<String, String>();
            /*
            if (myPropfindProperties == PropfindProperties.NONE)
            {
                // Should return ALL props

                Props.Add(PropfindProperties.Creationdate.ToString(), CreationDate);//, "2008-12-29T15:28:29Z");
                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.Getcontentlength.ToString(), "0");
                Props.Add(PropfindProperties.Getcontenttype.ToString(), System.Net.Mime.MediaTypeNames.Application.Octet);
                Props.Add(PropfindProperties.Getetag.ToString(), CacheUUID.NewGuid().ToString()); // to identify a single ressource for update purposes (see If-Match)
                Props.Add(PropfindProperties.Getlastmodified.ToString(), LastModificationDate);//"2009-02-09T08:11:12Z");
                Props.Add(PropfindProperties.Lockdiscovery.ToString(), "");
                Props.Add(PropfindProperties.Resourcetype.ToString(), "collection");
                Props.Add(PropfindProperties.Supportedlock.ToString(), "");

                // 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 ((propfindProperties == PropfindProperties.NONE) || ((propfindProperties & PropfindProperties.Creationdate)       == PropfindProperties.Creationdate))
                Props.Add(PropfindProperties.Creationdate.ToString(), CreationDate);
            if ((propfindProperties == PropfindProperties.NONE) || ((propfindProperties & PropfindProperties.Displayname)        == PropfindProperties.Displayname))
                Props.Add(PropfindProperties.Displayname.ToString(), displayname);
            if ((propfindProperties == PropfindProperties.NONE) || ((propfindProperties & PropfindProperties.Getcontentlanguage) == PropfindProperties.Getcontentlanguage))
                Props.Add(PropfindProperties.Getcontentlanguage.ToString(), "");
            if ((propfindProperties == PropfindProperties.NONE) || ((propfindProperties & PropfindProperties.Getcontentlength)   == PropfindProperties.Getcontentlength))
                Props.Add(PropfindProperties.Getcontentlength.ToString(), "0");
            if ((propfindProperties == PropfindProperties.NONE) || ((propfindProperties & PropfindProperties.Getcontenttype)     == PropfindProperties.Getcontenttype))
                Props.Add(PropfindProperties.Getcontenttype.ToString(), System.Net.Mime.MediaTypeNames.Application.Octet);
            if ((propfindProperties == PropfindProperties.NONE) || ((propfindProperties & PropfindProperties.Getetag)            == PropfindProperties.Getetag))
                Props.Add(PropfindProperties.Getetag.ToString(), Guid.NewGuid().ToString());
            if ((propfindProperties == PropfindProperties.NONE) || ((propfindProperties & PropfindProperties.Getlastmodified)    == PropfindProperties.Getlastmodified))
                Props.Add(PropfindProperties.Getlastmodified.ToString(), LastModificationDate);
            if ((propfindProperties == PropfindProperties.NONE) || ((propfindProperties & PropfindProperties.Lockdiscovery)      == PropfindProperties.Lockdiscovery))
                Props.Add(PropfindProperties.Lockdiscovery.ToString(), "");
            if ((propfindProperties == PropfindProperties.NONE) || ((propfindProperties & PropfindProperties.Resourcetype)       == PropfindProperties.Resourcetype))
                Props.Add(PropfindProperties.Resourcetype.ToString(), "collection");
            if ((propfindProperties == PropfindProperties.NONE) || ((propfindProperties & PropfindProperties.Supportedlock)      == PropfindProperties.Supportedlock))
                Props.Add(PropfindProperties.Supportedlock.ToString(), "");
            //}

            XmlElement ElemPropstat = CreatePropstatElement(header, xmlDocument, Props, hRef.Replace(header.GetFullHTTPHost(), ""));

            #endregion
            ElemResponse.AppendChild(ElemHref);
            ElemResponse.AppendChild(ElemPropstat);

            return ElemResponse;
        }
        /// <summary>
        /// Create a WebDAV propstat Element
        /// </summary>
        /// <param name="xmlDocument">The XMLDocument where this propstat element will be added to</param>
        /// <param name="props">A list of properties where the key is the property Name and value is the content (innerText) or Empty</param>
        /// <param name="status">The HTTP status, usually "HTTP/1.1 200 OK"</param>
        /// <returns>An XmlElement containing all Properties etc.</returns>
        private XmlElement CreatePropstatElement(HTTPHeader header, XmlDocument xmlDocument, Dictionary<String, String> props, String status, String target)
        {
            XmlElement ElemPropstat = xmlDocument.CreateElement(S_DAV_PREFIX, "propstat", S_DAV_NAMESPACE_URI);

            #region propstat elements

            XmlElement ElemStatus = xmlDocument.CreateElement(S_DAV_PREFIX, "status", S_DAV_NAMESPACE_URI);
            ElemStatus.InnerText = status;

            XmlElement ElemProp = xmlDocument.CreateElement(S_DAV_PREFIX, "prop", S_DAV_NAMESPACE_URI);

            #region prop elements

            foreach (KeyValuePair<String, String> PropItem in props)
            {

                if (PropItem.Key == PropfindProperties.Lockdiscovery.ToString())
                    AddPropfindLockdiscoveryElements(ElemProp, target.Replace(header.GetFullHTTPHost(), ""), target);
                else if (PropItem.Key == PropfindProperties.Lockdiscovery.ToString())
                    AddPropfindSupportedLockElements(ElemProp);
                else if (PropItem.Key == PropfindProperties.Resourcetype.ToString())
                {
                    XmlElement ElemResourceType = xmlDocument.CreateElement(S_DAV_PREFIX, PropItem.Key.ToLower(), S_DAV_NAMESPACE_URI);
                    //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
                    XmlElement ElemCollection = xmlDocument.CreateElement(S_DAV_PREFIX, PropItem.Value, S_DAV_NAMESPACE_URI);
                    ElemResourceType.AppendChild(ElemCollection);

                    ElemProp.AppendChild(ElemResourceType);
                }

                #region SVN prop elements

                else if (PropItem.Key == PropfindProperties.VersionControlledConfiguration.ToString())
                {

                    XmlElement XmlVCC = xmlDocument.CreateElement(S_DAV_PREFIX, "version-controlled-configuration", S_DAV_NAMESPACE_URI);
                    XmlElement XmlVCCHref = xmlDocument.CreateElement(S_DAV_PREFIX, "href", S_DAV_NAMESPACE_URI);
                    XmlVCCHref.InnerText = DirectoryHelper.Combine(target.Replace(header.GetFullHTTPHost(), ""), "!svn/vcc/default");
                    XmlVCC.AppendChild(XmlVCCHref);

                    ElemProp.AppendChild(XmlVCC);

                }
                else if (PropItem.Key == PropfindProperties.CheckedIn.ToString())
                {

                    XmlElement XmlCI = xmlDocument.CreateElement(S_DAV_PREFIX, "checked-in", S_DAV_NAMESPACE_URI);
                    XmlElement XmlCIHref = xmlDocument.CreateElement(S_DAV_PREFIX, "href", S_DAV_NAMESPACE_URI);

                    if(PropItem.Value == "ver")
                        XmlCIHref.InnerText = DirectoryHelper.Combine(target.Replace(header.GetFullHTTPHost(), ""), "!svn/ver/37491");
                    else
                        XmlCIHref.InnerText = DirectoryHelper.Combine(target.Replace(header.GetFullHTTPHost(), ""), "!svn/bln/37491");

                    XmlCI.AppendChild(XmlCIHref);

                    ElemProp.AppendChild(XmlCI);

                }
                else if (PropItem.Key == PropfindProperties.BaselineRelativePath.ToString())
                {

                    XmlElement Eleme = xmlDocument.CreateElement(S_SVN_PREFIX, "baseline-relative-path", S_SVN_NAMESPACE_URI);
                    ElemProp.AppendChild(Eleme);

                }
                else if (PropItem.Key == PropfindProperties.RepositoryUuid.ToString())
                {

                    XmlElement Eleme = xmlDocument.CreateElement(S_SVN_PREFIX, "repository-uuid", S_SVN_NAMESPACE_URI);
                    Eleme.InnerText = PropItem.Value;
                    ElemProp.AppendChild(Eleme);

                }
                else if (PropItem.Key == PropfindProperties.BaselineCollection.ToString())
                {

                    XmlElement XmlCI = xmlDocument.CreateElement(S_DAV_PREFIX, "baseline-collection", S_DAV_NAMESPACE_URI);
                    XmlElement XmlCIHref = xmlDocument.CreateElement(S_DAV_PREFIX, "href", S_DAV_NAMESPACE_URI);
                    if (header.SVNParameters != null && header.SVNParameters.Contains("bln"))
                        XmlCIHref.InnerText = DirectoryHelper.Combine(target.Replace(header.GetFullHTTPHost(), ""), "!svn/bc/37491");
                    else
                        XmlCIHref.InnerText = DirectoryHelper.Combine(target.Replace(header.GetFullHTTPHost(), ""), "!svn/bln/37491");

                    XmlCI.AppendChild(XmlCIHref);

                    ElemProp.AppendChild(XmlCI);

                }
                else if (PropItem.Key == PropfindProperties.VersionName.ToString())
                {

                    XmlElement XmlCI = xmlDocument.CreateElement(S_DAV_PREFIX, "version-Name", S_DAV_NAMESPACE_URI);
                    if (header.SVNParameters != null && header.SVNParameters.Contains("bln"))
                    {
                        XmlCI.InnerText = "37491";
                    }
                    else
                    {
                        XmlElement XmlCIHref = xmlDocument.CreateElement(S_DAV_PREFIX, "href", S_DAV_NAMESPACE_URI);
                        XmlCIHref.InnerText = "37491";
                        XmlCI.AppendChild(XmlCIHref);
                    }
                    ElemProp.AppendChild(XmlCI);

                }
                #endregion

                else
                {

                    XmlElement XmlElement = xmlDocument.CreateElement(S_DAV_PREFIX, PropItem.Key.ToLower(), S_DAV_NAMESPACE_URI);
                    if (PropItem.Value != null && PropItem.Value != String.Empty)
                        XmlElement.InnerText = PropItem.Value;

                    ElemProp.AppendChild(XmlElement);
                }

            }

            #endregion

            #endregion

            ElemPropstat.AppendChild(ElemStatus);
            ElemPropstat.AppendChild(ElemProp);

            return ElemPropstat;
        }
 /// <summary>
 /// Create a WebDAV propstat Element
 /// </summary>
 /// <param name="xmlDocument">The XMLDocument where this propstat element will be added to</param>
 /// <param name="props">A list of properties where the key is the property Name and value is the content (innerText) or Empty</param>
 /// <returns>An XmlElement containing all Properties etc.</returns>
 private XmlElement CreatePropstatElement(HTTPHeader header, XmlDocument xmlDocument, Dictionary<String, String> props, String target)
 {
     return CreatePropstatElement(header, xmlDocument, props, "HTTP/1.1 200 OK", target);
 }
        /// <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 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 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
        }
 private Byte[] CreateGetFileResponse(HTTPHeader header, params string[] properties)
 {
     return _AGraphDSSharp.GetFSObject<FileObject>(ObjectLocation.ParseString(header.Destination), FSConstants.FILESTREAM, null, null, 0, false).Value.ObjectData;
 }
Exemple #16
0
        public override Boolean ConnectionEstablished()
        {
            //NetworkStream dataStream = null;
            using (var _DataStream = GetStream(TcpClientConnection))
            {
                try
                {
                    #region Wait until new StreamData is available (returns true), timeout or server shutdown

                    if (!WaitForStreamDataAvailable())
                    {
                        return(false);
                    }

                    #endregion

                    #region Get header & body

                    HTTPHeader  requestHeader       = null;
                    Byte[]      requestBody         = null;
                    Byte[]      responseBodyBytes   = new byte[0];
                    Byte[]      responseHeaderBytes = null;
                    HTTPContext _HTTPWebContext     = null;
                    Exception   _LastException      = null;
                    var         _HeaderErrors       = GetHeaderAndBody(_DataStream, out requestHeader, out requestBody);

#if DEBUG
                    if (requestHeader.Destination == null)
                    {
                        return(false);
                    }
                    if (requestHeader.Headers.AllKeys.Contains("SENDER"))
                    {
                        Debug.WriteLine(string.Format("{0} Retrieved a request to resource {1} from {2}", DateTime.Now.TimeOfDay, requestHeader.Destination, requestHeader.Headers["SENDER"]), "HttpHandler");
                    }
                    else
                    {
                        Debug.WriteLine(string.Format("{0} Retrieved a request to resource {1}", DateTime.Now.TimeOfDay, requestHeader.Destination), "HttpHandler");
                    }
#endif
                    if (requestHeader == null || requestBody == null)
                    {
                        return(false);
                    }

                    #endregion

                    #region Trace

                    //System.Diagnostics.Trace.WriteLine("-------------------request started-------------------");
                    //System.Diagnostics.Trace.Indent();
                    //System.Diagnostics.Trace.WriteLine("requestHeader:");
                    //System.Diagnostics.Trace.Indent();
                    //System.Diagnostics.Trace.WriteLine(requestHeader.PlainHeader);
                    //System.Diagnostics.Trace.Unindent();
                    //System.Diagnostics.Trace.WriteLine("requestBody:");
                    //System.Diagnostics.Trace.Indent();
                    //System.Diagnostics.Trace.WriteLine(Encoding.UTF8.GetString(requestBody));
                    //System.Diagnostics.Trace.Unindent();
                    //System.Diagnostics.Trace.Unindent();
                    //System.Diagnostics.Trace.WriteLine("-----------------------------------------------------");

                    #endregion

                    #region Check if a error occurred during header processing...

                    HTTPHeader responseHeader = null;

                    if (requestHeader.HttpStatusCode != HTTPStatusCodes.OK)
                    {
                        responseHeader = new HTTPHeader()
                        {
                            HttpStatusCode = requestHeader.HttpStatusCode,
                        };

                        _HTTPWebContext        = new HTTPContext(requestHeader, requestBody, responseHeader, _DataStream);
                        HTTPServer.HTTPContext = _HTTPWebContext;
                    }

                    #endregion

                    #region ... or process request and create a response header

                    else
                    {
                        responseHeader = new HTTPHeader()
                        {
                            HttpStatusCode = HTTPStatusCodes.OK,
                            ContentType    = new ContentType("text/html")
                        };

                        #region Create and set HTTPContext

                        _HTTPWebContext        = new HTTPContext(requestHeader, requestBody, responseHeader, _DataStream);
                        HTTPServer.HTTPContext = _HTTPWebContext;

                        #endregion

                        // Process request
                        try
                        {
                            // Get Callback
                            var parsedCallback = _Parser.GetCallback(_HTTPWebContext.RequestHeader.RawUrl, _HTTPWebContext.RequestHeader.HttpMethodString);

                            #region Check callback...

                            if (parsedCallback == null || parsedCallback.Item1 == null)
                            {
                                Debug.WriteLine("Could not find a valid handler for url: " + _HTTPWebContext.RequestHeader.RawUrl);
                                responseBodyBytes = Encoding.UTF8.GetBytes("Could not find a valid handler for url: " + _HTTPWebContext.RequestHeader.RawUrl);

                                _HTTPWebContext.ResponseHeader = new HTTPHeader()
                                {
                                    HttpStatusCode = HTTPStatusCodes.NotFound,
                                    ContentType    = new ContentType("text/plain"),
                                    ContentLength  = responseBodyBytes.ULongLength()
                                };

                                responseHeaderBytes = _HTTPWebContext.ResponseHeader.ToBytes();
                            }

                            #endregion

                            #region ...check authentication and invoke method callback

                            else
                            {
                                var authenticated = false;

                                #region Check HTTPSecurity

                                // the server switched on authentication AND the method does not explicit allow not authentication
                                if (HTTPSecurity != null && !(parsedCallback.Item1.NeedsExplicitAuthentication.HasValue && !parsedCallback.Item1.NeedsExplicitAuthentication.Value))
                                {
                                    #region Authentication

                                    //in this case the client is already been authenticated by his certificate
                                    if (HTTPSecurity.CredentialType == HttpClientCredentialType.Certificate)
                                    {
                                        authenticated = true;
                                    }

                                    if (HTTPSecurity.CredentialType == HttpClientCredentialType.Basic)
                                    {
                                        if (requestHeader.Authorization == null)
                                        {
                                            #region No authorisation info was sent

                                            responseHeader      = GetAuthenticationRequiredHeader();
                                            responseHeaderBytes = responseHeader.ToBytes();

                                            #endregion
                                        }
                                        else if (!Authorize(_HTTPWebContext.RequestHeader.Authorization))
                                        {
                                            #region Authorization failed

                                            responseHeader      = GetAuthenticationRequiredHeader();
                                            responseHeaderBytes = responseHeader.ToBytes();

                                            #endregion
                                        }
                                        else
                                        {
                                            authenticated = true;
                                        }
                                    }
                                    else
                                    {
                                        if (HTTPSecurity.CredentialType != HttpClientCredentialType.Certificate)
                                        {
                                            responseBodyBytes = Encoding.UTF8.GetBytes("Authentication other than Basic or Certificate currently not provided");
                                            responseHeader    = new HTTPHeader()
                                            {
                                                HttpStatusCode = HTTPStatusCodes.InternalServerError, ContentLength = responseBodyBytes.ULongLength()
                                            };
                                            responseHeaderBytes = responseHeader.ToBytes();

                                            Debug.WriteLine("------------------------------------------------------------");
                                            Debug.WriteLine("!!!Authentication other than Basic or Certificate currently not provided!!!");
                                        }
                                    }

                                    #endregion
                                }

                                else if (parsedCallback.Item1.NeedsExplicitAuthentication.HasValue && parsedCallback.Item1.NeedsExplicitAuthentication.Value)
                                {
                                    #region The server does not have authentication but the Interface explicitly needs authentication

                                    responseBodyBytes = Encoding.UTF8.GetBytes("Authentication not provided from server");
                                    responseHeader    = new HTTPHeader()
                                    {
                                        HttpStatusCode = HTTPStatusCodes.InternalServerError, ContentLength = responseBodyBytes.ULongLength()
                                    };
                                    responseHeaderBytes = responseHeader.ToBytes();

                                    #endregion

                                    Debug.WriteLine("---------------------------------------------");
                                    Debug.WriteLine("!!!Authentication not provided from server!!!");
                                }
                                else
                                {
                                    authenticated = true;
                                }

                                #endregion

                                if (authenticated)
                                {
                                    InvokeURL(parsedCallback, _HTTPWebContext, ref responseHeaderBytes, ref responseBodyBytes);
                                }
                            }

                            #endregion
                        }

                        #region Handle exceptions occurred during request processing

                        catch (Exception ex)
                        {
                            Debug.WriteLine(ex.ToString());

                            responseBodyBytes = Encoding.UTF8.GetBytes(ex.ToString());

                            responseHeader = new HTTPHeader()
                            {
                                HttpStatusCode = HTTPStatusCodes.InternalServerError,
                                ContentType    = new ContentType("text/plain"),
                                ContentLength  = responseBodyBytes.ULongLength()
                            };

                            responseHeaderBytes = responseHeader.ToBytes();

                            ExceptionThrowed(this, ex);

                            _LastException = ex;
                        }

                        #endregion
                    }

                    #endregion


                    #region Handle errors...

                    if ((Int32)responseHeader.HttpStatusCode >= 400 && (Int32)responseHeader.HttpStatusCode <= 599)
                    {
                        #region Handle custom error pages...

                        var _CustomErrorPage = _Instance as ICustomErrorPageHandler;

                        if (_CustomErrorPage != null)
                        {
                            responseBodyBytes            = _CustomErrorPage.GetCustomErrorPage(responseHeader.HttpStatusCode, _HTTPWebContext.RequestHeader, _HTTPWebContext.RequestBody, _LastException);
                            responseHeader.ContentLength = responseBodyBytes.ULongLength();
                            responseHeaderBytes          = responseHeader.ToBytes();
                        }

                        #endregion

                        #region ...or generate a generic errorpage!

                        else
                        {
                            var _StringBuilder = new StringBuilder();

                            _StringBuilder.AppendLine("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">");
                            _StringBuilder.AppendLine("<html>");
                            _StringBuilder.AppendLine("  <head>");
                            _StringBuilder.Append("    <title>").Append((Int32)responseHeader.HttpStatusCode).Append(" ").Append(HTTPHeader.HttpStatusCodeToSimpleString(responseHeader.HttpStatusCode)).AppendLine("</title>");
                            _StringBuilder.AppendLine("  </head>");
                            _StringBuilder.AppendLine("  <body>");
                            _StringBuilder.Append("    <h1>Error ").Append((Int32)responseHeader.HttpStatusCode).Append(" - ").Append(HTTPHeader.HttpStatusCodeToSimpleString(responseHeader.HttpStatusCode)).AppendLine("</h1>");
                            _StringBuilder.AppendLine("    Your client sent a request which led to an error!<br />");
                            _StringBuilder.AppendLine("  </body>");
                            _StringBuilder.AppendLine("</html>");
                            _StringBuilder.AppendLine();

                            responseBodyBytes            = Encoding.UTF8.GetBytes(_StringBuilder.ToString());
                            responseHeader.ContentLength = responseBodyBytes.ULongLength();
                            responseHeaderBytes          = responseHeader.ToBytes();
                        }

                        #endregion
                    }

                    #endregion

                    #region Send Response

                    // Remove HttpWebContext
                    HTTPServer.HTTPContext = null;

                    if (!_HTTPWebContext.StreamDataAvailable)
                    {
                        // The user did not write into the stream itself - we will add header and the invocation result
                        var BytesToSend = new Byte[responseBodyBytes.Length + responseHeaderBytes.Length];
                        Array.Copy(responseHeaderBytes, BytesToSend, responseHeaderBytes.Length);
                        Array.Copy(responseBodyBytes, 0, BytesToSend, responseHeaderBytes.Length, responseBodyBytes.Length);

                        _DataStream.Write(BytesToSend, 0, BytesToSend.Length);
                    }

                    #endregion
                }
                finally
                {
                    if (_DataStream != null)
                    {
                        _DataStream.Close();
                    }
                    if (TcpClientConnection != null)
                    {
                        TcpClientConnection.Close();
                    }
                }
            }

            #region Trace

            //System.Diagnostics.Trace.WriteLine("-------------------response started-------------------");
            //System.Diagnostics.Trace.Indent();
            //System.Diagnostics.Trace.WriteLine("responseHeader:");
            //System.Diagnostics.Trace.Indent();
            //System.Diagnostics.Trace.WriteLine(responseHeader.ToString());
            //System.Diagnostics.Trace.Unindent();
            //System.Diagnostics.Trace.WriteLine("responseBody:");
            //System.Diagnostics.Trace.Indent();
            //System.Diagnostics.Trace.WriteLine(Encoding.UTF8.GetString(responseBodyBytes));
            //System.Diagnostics.Trace.Unindent();
            //System.Diagnostics.Trace.Unindent();
            //System.Diagnostics.Trace.WriteLine("-----------------------------------------------------");

            #endregion

            return(true);
        }