コード例 #1
0
        private void OnReceiveSink2(byte[] buffer, IPEndPoint remote, IPEndPoint local)
        {
            HTTPMessage msg;

            try
            {
                msg = HTTPMessage.ParseByteArray(buffer, 0, buffer.Length);
            }
            catch (Exception ex)
            {
                OpenSource.Utilities.EventLogger.Log(ex);
                msg              = new HTTPMessage();
                msg.Directive    = "---";
                msg.DirectiveObj = "---";
                msg.BodyBuffer   = buffer;
            }
            msg.LocalEndPoint  = local;
            msg.RemoteEndPoint = remote;

            HandleSniffer(remote, local, msg);

            DText parser = new DText();

            String Location = msg.GetTag("Location");
            int    MaxAge   = 0;
            String ma       = msg.GetTag("Cache-Control").Trim();

            if (ma != "")
            {
                parser.ATTRMARK = ",";
                parser.MULTMARK = "=";
                parser[0]       = ma;
                for (int i = 1; i <= parser.DCOUNT(); ++i)
                {
                    if (parser[i, 1].Trim().ToUpper() == "MAX-AGE")
                    {
                        MaxAge = int.Parse(parser[i, 2].Trim());
                        break;
                    }
                }
            }
            ma = msg.GetTag("USN");
            String USN = ma.Substring(ma.IndexOf(":") + 1);
            String ST  = msg.GetTag("ST");

            if (USN.IndexOf("::") != -1)
            {
                USN = USN.Substring(0, USN.IndexOf("::"));
            }
            OpenSource.Utilities.EventLogger.Log(this, System.Diagnostics.EventLogEntryType.SuccessAudit, msg.RemoteEndPoint.ToString());
            if (OnSearch != null)
            {
                OnSearch(msg.RemoteEndPoint, msg.LocalEndPoint, new Uri(Location), USN, ST, MaxAge);
            }
        }
コード例 #2
0
ファイル: HTTPRequest.cs プロジェクト: sqirrel99/FreeMi
        private void ReceiveSink(HTTPSession sender, HTTPMessage msg)
        {
            StateData sd  = (StateData)sender.StateObject;
            object    Tag = sd.Tag;

            if (msg.Version == "1.0" || msg.Version == "0.9")
            {
                sender.Close();
            }
            else
            {
                if (msg.GetTag("Connection").ToUpper() == "CLOSE")
                {
                    sender.Close();
                }
            }


            if (OnResponse != null)
            {
                OnResponse(this, msg, Tag);
            }
            // If I don't set this to null, this holds a strong reference, resulting in
            // possible memory leaks
            sender.StateObject = null;
            lock (TagQueue)
            {
                if (TagQueue.Count == 0)
                {
                    this.IdleTimeout = true;
                    KeepAliveTimer.Add(this.GetHashCode(), 10);
                }
            }
        }
コード例 #3
0
ファイル: SSDP.cs プロジェクト: thaugensorg/intel-upnp-dlna
        private bool ValidateSearchPacket(HTTPMessage msg)
        {
            int MX = 0;

            if (msg.GetTag("MAN") != "\"ssdp:discover\"")
            {
                return(false); // { throw (new InvalidSearchPacketException("Invalid MAN")); }
            }
            if (msg.DirectiveObj != "*")
            {
                return(false); // { throw (new InvalidSearchPacketException("Expected * in RequestLine")); }
            }
            if (double.Parse(msg.Version, new CultureInfo("en-US").NumberFormat) < (double)1.1)
            {
                return(false); // { throw (new InvalidSearchPacketException("Version must be at least 1.1")); }
            }
            if (int.TryParse(msg.GetTag("MX"), out MX) == false || MX <= 0)
            {
                return(false); // { throw (new InvalidSearchPacketException("MX must be a positive integer")); }
            }
            return(true);
        }
コード例 #4
0
ファイル: SSDP.cs プロジェクト: thaugensorg/intel-upnp-dlna
        private void ProcessPacket(HTTPMessage msg, IPEndPoint src, IPEndPoint local)
        {
            if (OnSniffPacket != null)
            {
                OnSniffPacket(src, null, msg);
            }

            DText parser = new DText();

            parser.ATTRMARK = "::";

            bool   Alive = false;
            String UDN   = msg.GetTag("USN");

            parser[0] = UDN;
            String USN = parser[1];

            USN = USN.Substring(USN.IndexOf(":") + 1);
            String ST     = parser[2];
            int    MaxAge = 0;

            String NTS = msg.GetTag("NTS").ToUpper();

            if (NTS == "SSDP:ALIVE")
            {
                Alive = true;
                String ma = msg.GetTag("Cache-Control").Trim();
                if (ma != "")
                {
                    parser.ATTRMARK = ",";
                    parser.MULTMARK = "=";
                    parser[0]       = ma;
                    for (int i = 1; i <= parser.DCOUNT(); ++i)
                    {
                        if (parser[i, 1].Trim().ToUpper() == "MAX-AGE")
                        {
                            MaxAge = int.Parse(parser[i, 2].Trim());
                            break;
                        }
                    }
                }
            }

            if (msg.Directive == "NOTIFY" && OnNotify != null)
            {
                Uri    locuri   = null;
                string location = msg.GetTag("Location");
                if (location != null && location.Length > 0)
                {
                    try
                    {
                        locuri = new Uri(location);
                    }
                    catch (Exception ex)
                    {
                        OpenSource.Utilities.EventLogger.Log(ex);
                    }
                }
                OnNotify(src, msg.LocalEndPoint, locuri, Alive, USN, ST, MaxAge, msg);
            }
            else if (msg.Directive == "M-SEARCH" && OnSearch != null)
            {
                if (ValidateSearchPacket(msg) == false)
                {
                    return;
                }
                int          MaxTimer   = int.Parse(msg.GetTag("MX"));
                SearchStruct SearchData = new SearchStruct();
                SearchData.ST     = msg.GetTag("ST");
                SearchData.Source = src;
                SearchData.Local  = local;
                SearchTimer.Add(SearchData, RandomGenerator.Next(0, MaxTimer));
            }
        }
コード例 #5
0
ファイル: UPnPControlPoint.cs プロジェクト: Scannow/SWYH
        private void OnReceiveSink2(byte[] buffer, IPEndPoint remote, IPEndPoint local)
        {
            HTTPMessage msg;

            try
            {
                msg = HTTPMessage.ParseByteArray(buffer, 0, buffer.Length);
            }
            catch (Exception ex)
            {
                OpenSource.Utilities.EventLogger.Log(ex);
                msg = new HTTPMessage();
                msg.Directive = "---";
                msg.DirectiveObj = "---";
                msg.BodyBuffer = buffer;
            }
            msg.LocalEndPoint = local;
            msg.RemoteEndPoint = remote;

            DText parser = new DText();

            String Location = msg.GetTag("Location");
            int MaxAge = 0;
            String ma = msg.GetTag("Cache-Control").Trim();
            if (ma != "")
            {
                parser.ATTRMARK = ",";
                parser.MULTMARK = "=";
                parser[0] = ma;
                for (int i = 1; i <= parser.DCOUNT(); ++i)
                {
                    if (parser[i, 1].Trim().ToUpper() == "MAX-AGE")
                    {
                        MaxAge = int.Parse(parser[i, 2].Trim());
                        break;
                    }
                }
            }
            ma = msg.GetTag("USN");
            String USN = ma.Substring(ma.IndexOf(":") + 1);
            String ST = msg.GetTag("ST");
            if (USN.IndexOf("::") != -1) USN = USN.Substring(0, USN.IndexOf("::"));
            OpenSource.Utilities.EventLogger.Log(this, System.Diagnostics.EventLogEntryType.SuccessAudit, msg.RemoteEndPoint.ToString());
            if (OnSearch != null) OnSearch(msg.RemoteEndPoint, msg.LocalEndPoint, new Uri(Location), USN, ST, MaxAge);
        }
コード例 #6
0
        private void HandleSubscribeResponse(HTTPRequest sender, HTTPMessage response, object Tag)
        {
            UPnPEventSubscribeHandler CB = (UPnPEventSubscribeHandler)Tag;
            SubscribeRequestTable.Remove(sender);
            sender.Dispose();
            if (response != null)
            {
                if (response.StatusCode != 200)
                {
                    if (CB != null)
                    {
                        CB(this, false);
                    }
                    else
                    {
                        if (OnSubscribe != null) OnSubscribe(this, false);
                    }
                }
                else
                {
                    CurrentSID = response.GetTag("SID");
                    if (CB != null)
                    {
                        CB(this, true);
                    }
                    else
                    {
                        if (OnSubscribe != null) OnSubscribe(this, true);
                    }

                    if (CurrentTimeout != 0)
                    {
                        EventLogger.Log(this, System.Diagnostics.EventLogEntryType.SuccessAudit, "SUBSCRIBE [" + this.CurrentSID + "] Duration: " + CurrentTimeout.ToString() + " <" + DateTime.Now.ToLongTimeString() + ">");
                        SubscribeCycle.Add(this.GetHashCode(), CurrentTimeout / 2);
                    }
                }
            }
            else
            {
                if (CB != null)
                {
                    CB(this, false);
                }
                else
                {
                    if (OnSubscribe != null) OnSubscribe(this, false);
                }
            }
        }
コード例 #7
0
        /// <summary>
        /// Parses a Byte Array at a specific location, and builds a Packet.
        /// </summary>
        /// <param name="buffer">The Array of Bytes</param>
        /// <param name="indx">The Start Index</param>
        /// <param name="count">The number of Bytes to process</param>
        /// <returns></returns>
        static public HTTPMessage ParseByteArray(byte[] buffer, int indx, int count)
        {
            HTTPMessage  TheMessage = new HTTPMessage();
            UTF8Encoding UTF8       = new UTF8Encoding();
            String       TempData   = UTF8.GetString(buffer, indx, count);
            DText        parser     = new DText();
            String       TempString;

            int idx = TempData.IndexOf("\r\n\r\n");

            if (idx < 0)
            {
                return(null);
            }
            TempData = TempData.Substring(0, idx);

            parser.ATTRMARK = "\r\n";
            parser.MULTMARK = ":";
            parser[0]       = TempData;
            string CurrentLine = parser[1];

            DText HdrParser = new DText();

            HdrParser.ATTRMARK = " ";
            HdrParser.MULTMARK = "/";
            HdrParser[0]       = CurrentLine;

            if (CurrentLine.ToUpper().StartsWith("HTTP/") == true)
            {
                TheMessage.ResponseCode = int.Parse(HdrParser[2]);
                int s1 = CurrentLine.IndexOf(" ");
                s1 = CurrentLine.IndexOf(" ", s1 + 1);
                TheMessage.ResponseData = HTTPMessage.UnEscapeString(CurrentLine.Substring(s1));
                try
                {
                    TheMessage.Version = HdrParser[1, 2];
                }
                catch (Exception ex)
                {
                    OpenSource.Utilities.EventLogger.Log(ex);
                    TheMessage.Version = "0.9";
                }
            }
            else
            {
                TheMessage.Directive = HdrParser[1];
                TempString           = CurrentLine.Substring(CurrentLine.LastIndexOf(" ") + 1);
                if (TempString.ToUpper().StartsWith("HTTP/") == false)
                {
                    TheMessage.Version      = "0.9";
                    TheMessage.DirectiveObj = HTTPMessage.UnEscapeString(TempString);
                }
                else
                {
                    TheMessage.Version = TempString.Substring(TempString.IndexOf("/") + 1);
                    int fs = CurrentLine.IndexOf(" ") + 1;
                    TheMessage.DirectiveObj = HTTPMessage.UnEscapeString(CurrentLine.Substring(
                                                                             fs,
                                                                             CurrentLine.Length - fs - TempString.Length - 1));
                }
            }
            String Tag     = "";
            String TagData = "";

            for (int line = 2; line <= parser.DCOUNT(); ++line)
            {
                if (Tag != "" && parser[line, 1].StartsWith(" "))
                {
                    TagData = parser[line, 1].Substring(1);
                }
                else
                {
                    Tag     = parser[line, 1];
                    TagData = "";
                    for (int i = 2; i <= parser.DCOUNT(line); ++i)
                    {
                        if (TagData == "")
                        {
                            TagData = parser[line, i];
                        }
                        else
                        {
                            TagData = TagData + parser.MULTMARK + parser[line, i];
                        }
                    }
                }
                TheMessage.AppendTag(Tag, TagData);
            }
            int cl = 0;

            if (TheMessage.HasTag("Content-Length"))
            {
                try
                {
                    cl = int.Parse(TheMessage.GetTag("Content-Length"));
                }
                catch (Exception ex)
                {
                    OpenSource.Utilities.EventLogger.Log(ex);
                    cl = -1;
                }
            }
            else
            {
                cl = -1;
            }

            byte[] tbuffer;
            if (cl > 0)
            {
                tbuffer = new byte[cl];
                if ((idx + 4 + cl) > count)
                {
                    // NOP
                }
                else
                {
                    Array.Copy(buffer, idx + 4, tbuffer, 0, cl);
                    TheMessage.DataBuffer = tbuffer;
                }
            }
            if (cl == -1)
            {
                tbuffer = new Byte[count - (idx + 4)];
                Array.Copy(buffer, idx + 4, tbuffer, 0, tbuffer.Length);
                TheMessage.DataBuffer = tbuffer;
            }
            if (cl == 0)
            {
                TheMessage.DataBuffer = new byte[0];
            }
            return(TheMessage);
        }
コード例 #8
0
        /// <summary>
        /// Examines an <see cref="HTTPMessage"/> object and
        /// attempts to find the content length of the message body.
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        private long ExtractContentLength(HTTPMessage msg)
        {
            long expectedLength = 0;
            string contentLengthString = msg.GetTag("CONTENT-LENGTH");
            try
            {
                expectedLength = long.Parse(contentLengthString);
            }
            catch{}

            return expectedLength;
        }
コード例 #9
0
        private void EventProcesser(UPnPDevice sender, HTTPMessage msg, HTTPSession WebSession, string VirtualDir)
        {
            if (ControlPointOnly == true)
            {
                String Method = msg.Directive;
                HTTPMessage Response = new HTTPMessage();

                if (Method != "NOTIFY")
                {
                    Response.StatusCode = 405;
                    Response.StatusData = Method + " not supported";
                    WebSession.Send(Response);
                    return; // Other methods are unknown to us
                }
                else if (Method == "NOTIFY")
                {
                    for (int id = 0; id < Services.Length; ++id)
                    {
                        //						SSDP.ParseURL(Services[id].__eventurl,out WebIP, out WebPort, out WebData);
                        //						if (WebData==MethodData)
                        //						{
                        if (Services[id].IsYourEvent(msg.GetTag("SID")) == true)
                        {
                            Response.StatusCode = 200;
                            Response.StatusData = "OK";
                            WebSession.Send(Response);

                            Services[id]._TriggerEvent(msg.GetTag("SID"), long.Parse(msg.GetTag("SEQ")), msg.StringBuffer, 0);
                            break;
                        }
                        //						}
                    }
                }
            }
        }
コード例 #10
0
 private bool ValidateSearchPacket(HTTPMessage msg)
 {
     int MX = 0;
     if (msg.GetTag("MAN") != "\"ssdp:discover\"") return false; // { throw (new InvalidSearchPacketException("Invalid MAN")); }
     if (msg.DirectiveObj != "*") return false; // { throw (new InvalidSearchPacketException("Expected * in RequestLine")); }
     if (double.Parse(msg.Version, new CultureInfo("en-US").NumberFormat) < (double)1.1) return false; // { throw (new InvalidSearchPacketException("Version must be at least 1.1")); }
     if (int.TryParse(msg.GetTag("MX"), out MX) == false || MX <= 0) return false; // { throw (new InvalidSearchPacketException("MX must be a positive integer")); }
     return true;
 }
コード例 #11
0
        private void ProcessPacket(HTTPMessage msg, IPEndPoint src, IPEndPoint local)
        {
            if (OnSniffPacket != null) OnSniffPacket(src, null, msg);

            DText parser = new DText();
            parser.ATTRMARK = "::";

            bool Alive = false;
            String UDN = msg.GetTag("USN");

            parser[0] = UDN;
            String USN = parser[1];
            USN = USN.Substring(USN.IndexOf(":") + 1);
            String ST = parser[2];
            int MaxAge = 0;

            String NTS = msg.GetTag("NTS").ToUpper();
            if (NTS == "SSDP:ALIVE")
            {
                Alive = true;
                String ma = msg.GetTag("Cache-Control").Trim();
                if (ma != "")
                {
                    parser.ATTRMARK = ",";
                    parser.MULTMARK = "=";
                    parser[0] = ma;
                    for (int i = 1; i <= parser.DCOUNT(); ++i)
                    {
                        if (parser[i, 1].Trim().ToUpper() == "MAX-AGE")
                        {
                            MaxAge = int.Parse(parser[i, 2].Trim());
                            break;
                        }
                    }
                }
            }

            if (msg.Directive == "NOTIFY" && OnNotify != null)
            {
                Uri locuri = null;
                string location = msg.GetTag("Location");
                if (location != null && location.Length > 0) { try { locuri = new Uri(location); } catch (Exception) { } }
                OnNotify(src, msg.LocalEndPoint, locuri, Alive, USN, ST, MaxAge, msg);
            }
            else if (msg.Directive == "M-SEARCH" && OnSearch != null)
            {
                if (ValidateSearchPacket(msg) == false) return;
                int MaxTimer = int.Parse(msg.GetTag("MX"));
                SearchStruct SearchData = new SearchStruct();
                SearchData.ST = msg.GetTag("ST");
                SearchData.Source = src;
                SearchData.Local = local;
                SearchTimer.Add(SearchData, RandomGenerator.Next(0, MaxTimer));
            }
        }
コード例 #12
0
ファイル: HTTPSession.cs プロジェクト: Scannow/SWYH
		private void HandleReceive(AsyncSocket sender, Byte[] buffer, int BeginPointer, int BufferSize, int BytesRead, IPEndPoint source, IPEndPoint remote)
		{

			if (BytesRead!=0)
			{
				OnSniffEvent.Fire(buffer,BufferSize-BytesRead, BytesRead);
			}
		

			if (this.FinishedHeader==false)
			{
				if (BufferSize<4)
				{
					sender.BufferReadLength = 1;
					sender.BufferBeginPointer = 0;
					return;
				}
				/* This is New */
				for(int i=4;i<BufferSize-4;++i)
				{
					if ((buffer[i-4]==13)&&(buffer[i-3]==10)&&
						(buffer[i-2]==13)&&(buffer[i-1]==10))
					{
						BufferSize = i;
						break;
					}
				}


				if ((buffer[BufferSize-4]==13)&&(buffer[BufferSize-3]==10)&&
					(buffer[BufferSize-2]==13)&&(buffer[BufferSize-1]==10))
				{
					// End Of Headers
					Headers = HTTPMessage.ParseByteArray(buffer,0,BufferSize);
					

					if (Headers.StatusCode!=-1)
					{
						if (Headers.StatusCode>=100 && Headers.StatusCode<=199)
						{
							//Informational
							if (OpenSource.Utilities.EventLogger.Enabled)
							{
								OpenSource.Utilities.EventLogger.Log(this,System.Diagnostics.EventLogEntryType.Information,"<<IGNORING>>\r\n" + Headers.StringPacket);
							}
//							OnHeaderEvent.Fire(this,Headers, UserStream);
							OnSniffPacketEvent.Fire(this,Headers);
//							OnReceiveEvent.Fire(this, Headers);
//							DONE_ReadingPacket();
							BeginHeader(BufferSize);
							return;
						}

						if (Headers.StatusCode==204 || Headers.StatusCode==304)
						{
							//No Body or No Change
							if (OpenSource.Utilities.EventLogger.Enabled)
							{
								OpenSource.Utilities.EventLogger.Log(this,System.Diagnostics.EventLogEntryType.Information,Headers.StringPacket);
							}
							OnHeaderEvent.Fire(this,Headers, UserStream);
							OnSniffPacketEvent.Fire(this,Headers);
							OnReceiveEvent.Fire(this, Headers);
							DONE_ReadingPacket();
							BeginHeader(BufferSize);
							return;
						}
					}
					else
					{
						SET_START_OF_REQUEST();
					}

					FinishedHeader = true;
					if (Headers.GetTag("Content-Length")=="")
					{
						if (Headers.GetTag("Transfer-Encoding").ToUpper()=="CHUNKED")
						{
							IsChunked = true;
						}
						else
						{
							if (Headers.StatusCode!=-1)
							{
								this.NeedToWaitToClose = true;
							}
						}
					}
					else
					{
						if (Headers.GetTag("Transfer-Encoding").ToUpper()=="CHUNKED")
						{
							IsChunked = true;
						}
						else
						{
							BodySize = int.Parse(Headers.GetTag("Content-Length"));
						}
					}
					if (Headers.GetTag("Connection").ToUpper()=="CLOSE")
					{
						this.ConnectionCloseSpecified=true;
					}
					
					if (!IsChunked && NeedToWaitToClose && !ConnectionCloseSpecified &&!IsLegacy && Headers.Version!="1.0")
					{
						NeedToWaitToClose = false;
						BodySize = 0;
					}

					OnHeaderEvent.Fire(this,Headers, UserStream);
					if (this.NeedToWaitToClose==true)
					{
						sender.BufferBeginPointer = BufferSize;
						sender.BufferReadLength = 4096;
					}
					else
					{
						if (IsChunked==true)
						{
							// Chunked
							BeginChunk(BufferSize);
						}
						else
						{
							// Normal
							if (BodySize==0)
							{
								// Already have the packet
								if (OpenSource.Utilities.EventLogger.Enabled)
								{
									OpenSource.Utilities.EventLogger.Log(this,System.Diagnostics.EventLogEntryType.Information,Headers.StringPacket);
								}
								OnSniffPacketEvent.Fire(this,Headers);
								OnReceiveEvent.Fire(this, Headers);
								if (UserStream!=null)
								{
									UserStream.Flush();
									OnStreamDoneEvent.Fire(this,UserStream);
								}
								DONE_ReadingPacket();
								BeginHeader(BufferSize);
							}
							else
							{
								if (BodySize<=4096)
								{
									sender.BufferBeginPointer = BufferSize;
									sender.BufferReadLength = BodySize;
								}
								else
								{
									sender.BufferBeginPointer = BufferSize;
									sender.BufferReadLength = 4096;
								}
							}
						} // End Normal Else Clause
					} // End Non HTTP/1.0 Else Clause
					return;
				} // End of Processing Header
				else
				{
					// Need to read more of the header
					sender.BufferBeginPointer = 0;
					sender.BufferReadLength = 1;
				}
				return;
			} // End of If FinishedHeader
			

			// Have some body data
			if (IsChunked == false)
			{
				/* This is New */
				if (this.NeedToWaitToClose==false)
				{
					if (BufferSize>BodySize) BufferSize = BodySize;
				}

				// Normal Data
				if (UserStream!=null)
				{
					UserStream.Write(buffer,0,BufferSize);
				}
				else
				{
//					OpenSource.Utilities.EventLogger.Log(this,System.Diagnostics.EventLogEntryType.SuccessAudit,"NONChunk Data: " + BufferSize.ToString() + " bytes");
//					OpenSource.Utilities.EventLogger.Log(this,System.Diagnostics.EventLogEntryType.SuccessAudit,"Writing["+SocketStream.GetHashCode().ToString()+"]: " + U.GetString(buffer,0,BufferSize));

					SocketStream.Write(buffer,0,BufferSize);
				}

				if (this.NeedToWaitToClose==false)
				{
					BodySize -= BufferSize;
					if (BodySize>0)
					{
						// More To Read
						sender.BufferBeginPointer  = BufferSize;
						if (BodySize < 4096)
						{
							sender.BufferReadLength = BodySize;
						}
						else
						{
							sender.BufferReadLength = 4096;
						}
					}
					else
					{
						// Finished Reading
						if (UserStream==null)
						{
							SocketStream.Flush();
							Headers.BodyBuffer = SocketStream.ToArray();
							if (OpenSource.Utilities.EventLogger.Enabled)
							{
								OpenSource.Utilities.EventLogger.Log(this,System.Diagnostics.EventLogEntryType.Information,Headers.StringPacket);
							}
							OnSniffPacketEvent.Fire(this,Headers);
							OnReceiveEvent.Fire(this, Headers);
						}
						else
						{
							UserStream.Flush();
							OnStreamDoneEvent.Fire(this,UserStream);
						}
						DONE_ReadingPacket();
						BeginHeader(BufferSize);
					}
				}
				else
				{
					// HTTP/1.0 Socket
					sender.BufferReadLength = 4096;
					sender.BufferBeginPointer = BufferSize;
				}
			}
			else
			{
				// Chunked Data
				ProcessChunk(buffer, BufferSize);
			}
		}
コード例 #13
0
        public override void Start(UPnPDevice device)
        {
            if(!Enabled) return;

            UPnPDevice dv = device;
            while(dv.ParentDevice!=null)
            {
                dv = dv.ParentDevice;
            }

            state = UPnPTestStates.Running;
            UPnPService[] _S = device.GetServices("urn:");

            foreach(UPnPService s in _S)
            {
                bool ok = false;
                foreach(UPnPStateVariable v in s.GetStateVariables())
                {
                    if(v.SendEvent)
                    {
                        ok = true;
                        break;
                    }
                }
                if(ok)
                {

                    UPnPDebugObject d = new UPnPDebugObject(s);
                    Uri EventUri = new Uri((string)d.GetField("__eventurl"));

                    IPEndPoint dest = new IPEndPoint(IPAddress.Parse(EventUri.Host),EventUri.Port);
                    HTTPMessage R = new HTTPMessage();
                    R.Directive = "SUBSCRIBE";
                    R.DirectiveObj = HTTPMessage.UnEscapeString(EventUri.PathAndQuery);
                    R.AddTag("Host",dest.ToString());
                    R.AddTag("Callback","<http://" + dv.InterfaceToHost.ToString()+ ":" + NetworkInfo.GetFreePort(10000,50000,dv.InterfaceToHost).ToString() + ">");
                    //R.AddTag("Callback","<http://127.0.0.1:55555>");
                    R.AddTag("NT","upnp:event");
                    R.AddTag("Timeout","Second-15");

                    System.Console.WriteLine(R.GetTag("Callback"));

                    MRE.Reset();
                    SID = "";
                    StartCountDown(30);
                    HTTPRequest rq = new HTTPRequest();
                    rq.OnResponse += new HTTPRequest.RequestHandler(SubscribeSink);

                    AddHTTPMessage(R);

                    rq.PipelineRequest(dest,R,s);
                    MRE.WaitOne(30000,false);
                    AbortCountDown();

                    if (SID=="")
                    {
                        AddEvent(LogImportance.Critical,"Subscribe","SUBSCRIBE: " + s.ServiceURN + " << FAILED >>");
                        AddEvent(LogImportance.Remark,"Subscribe","Aborting tests");

                        result = "Subscription test failed."; // TODO
                        state = UPnPTestStates.Failed;
                        return;
                    }
                    else
                    {
                        AddEvent(LogImportance.Remark,"Subscribe","SUBSCRIBE: " + s.ServiceURN + " << OK >>");

                        // Renew Test
                        R = new HTTPMessage();
                        R.Directive = "SUBSCRIBE";
                        R.DirectiveObj = HTTPMessage.UnEscapeString(EventUri.PathAndQuery);
                        R.AddTag("Host",dest.ToString());
                        R.AddTag("SID",SID);
                        R.AddTag("Timeout","Second-15");
                        StartCountDown(30);
                        SID = "";
                        MRE.Reset();

                        AddHTTPMessage(R);

                        rq = new HTTPRequest();
                        rq.OnResponse += new HTTPRequest.RequestHandler(SubscribeSink);
                        rq.PipelineRequest(dest,R,s);

                        MRE.WaitOne(30000,false);
                        AbortCountDown();

                        if (SID=="")
                        {
                            AddEvent(LogImportance.Critical,"Subscribe","SUBSCRIBE (Renew): " + s.ServiceURN + " << FAILED >>");
                            AddEvent(LogImportance.Remark,"Subscribe","Aborting tests");

                            result = "Subscription test failed."; // TODO
                            state = UPnPTestStates.Failed;
                            return;
                        }
                        else
                        {
                            AddEvent(LogImportance.Remark,"Subscribe","SUBSCRIBE (Renew): " + s.ServiceURN + " << OK >>");

                            // Cancel
                            R = new HTTPMessage();
                            R.Directive = "UNSUBSCRIBE";
                            R.DirectiveObj = HTTPMessage.UnEscapeString(EventUri.PathAndQuery);
                            R.AddTag("Host",dest.ToString());
                            R.AddTag("SID",SID);

                            StartCountDown(30);
                            SID = "";
                            MRE.Reset();
                            rq = new HTTPRequest();
                            rq.OnResponse += new HTTPRequest.RequestHandler(CancelSink);

                            AddHTTPMessage(R);

                            rq.PipelineRequest(dest,R,s);

                            MRE.WaitOne(30000,false);
                            AbortCountDown();

                            if (SID=="")
                            {
                                AddEvent(LogImportance.Critical,"Subscribe","UNSUBSCRIBE: " + s.ServiceURN + " << FAILED >>");
                                AddEvent(LogImportance.Remark,"Subscribe","Aborting tests");

                                result = "Subscription test failed.";
                                state = UPnPTestStates.Failed;
                                return;
                            }
                            else
                            {
                                AddEvent(LogImportance.Remark,"Subscribe","UNSUBSCRIBE: " + s.ServiceURN + " << OK >>");
                            }

                            /* Test for duplicate SID
                             * as well as initial events */

                            EventTable.Clear();
                            NumEvents = 0;
                            foreach(UPnPStateVariable V in s.GetStateVariables())
                            {
                                if(V.SendEvent)
                                {
                                    ++ NumEvents;
                                    EventTable[V.Name] = false;
                                    V.OnModified -= new UPnPStateVariable.ModifiedHandler(StateVarModifiedSink);
                                    V.OnModified += new UPnPStateVariable.ModifiedHandler(StateVarModifiedSink);
                                }
                            }
                            if(EventTable.Count>0)
                            {
                                MRE.Reset();
                                s.OnSubscribe -= new UPnPService.UPnPEventSubscribeHandler(OnSubscribeSink);
                                s.OnSubscribe += new UPnPService.UPnPEventSubscribeHandler(OnSubscribeSink);
                                s.UnSubscribe(null);
                                foreach(UPnPStateVariable V in s.GetStateVariables())
                                {
                                    V.Clear();
                                }
                                s.Subscribe(120,null);
                                MRE.WaitOne(30000,false);
                                if(SID=="")
                                {
                                    // Subscribe Failed
                                    AddEvent(LogImportance.Critical,"Subscribe","SUBSCRIBE(2): " + s.ServiceURN + " << FAILED >>");
                                    AddEvent(LogImportance.Remark,"Subscribe","Aborting tests");

                                    result = "Subscription test failed.";
                                    state = UPnPTestStates.Failed;
                                    return;
                                }
                                else
                                {
                                    if(SID==null)
                                    {
                                        // Duplicate SID
                                        // Subscribe Failed
                                        AddEvent(LogImportance.Critical,"Subscribe","SUBSCRIBE(2): " + s.ServiceURN + " << FAILED, duplicate SID >>");
                                        AddEvent(LogImportance.Remark,"Subscribe","Aborting tests");

                                        result = "Subscription test failed.";
                                        state = UPnPTestStates.Failed;
                                        return;
                                    }
                                    else
                                    {
                                        // Check Hashtable
                                        IDictionaryEnumerator de = EventTable.GetEnumerator();
                                        bool OK = true;
                                        while(de.MoveNext())
                                        {
                                            if((bool)de.Value==false)
                                            {
                                                // No Event Received
                                                OK = false;
                                                AddEvent(LogImportance.Critical,"Subscribe","   StateVariable: " + (string)de.Key + " >> Event NOT received");
                                            }
                                            else
                                            {
                                                // OK
                                                AddEvent(LogImportance.Remark,"Subscribe","   StateVariable: " + (string)de.Key + " >> Event OK");
                                            }
                                        }
                                        if(OK==false)
                                        {
                                            AddEvent(LogImportance.Critical,"Subscribe","SUBSCRIBE(2): " + s.ServiceURN + " << FAILED, Did not receive all events >>");
                                            AddEvent(LogImportance.Remark,"Subscribe","Aborting tests");

                                            result = "Subscription test failed.";
                                            state = UPnPTestStates.Failed;
                                            return;
                                        }
                                    }
                                }
                            }
                        }

                    }
                }
            }

            result = "Subscribe Tests OK";
            state = UPnPTestStates.Pass;
        }
コード例 #14
0
        private void SubscribeSink(HTTPRequest sender, HTTPMessage MSG, object Tag)
        {
            if (MSG!=null)
            {
                AddPacket(MSG);

                if (MSG.StatusCode==200)
                {
                    SID = MSG.GetTag("SID");
                }
            }
            MRE.Set();
        }
コード例 #15
0
        /// <summary>
        /// This method is called by <see cref="MediaServerDevice.WebServer_OnPacketReceiveSink"/>
        /// and handles the HTTP-GET or HTTP-GET message requests and provides
        /// the appropriate response. In either case, the handler is intended
        /// to handle requests for resource URIs that have been mapped to local
        /// files using the <see cref="MediaResource.AUTOMAPFILE"/> convention.
        /// <para>
        /// If a resource cannot be mapped to a local file, 
        /// then the method will ask upper-layer application logic 
        /// for a stream object to send in response to the request.
        /// This is used primarily in scenarios where the application intentionally
        /// specified a contentUri value for a resource that uses the 
        /// <see cref="MediaResource.AUTOMAPFILE"/> convention but doesn't
        /// actually map to a local file. This gives the upper application layer
        /// to provide transcoded stream objects or some specialized file stream
        /// that is not stored on the local file system.
        /// </para>
        /// <para>
        /// Upper application layers can always opt to leave the stream object
        /// blank, effectively indicating that the HTTP-GET or head request 
        /// cannot be handled because such a file does not exist.
        /// </para>
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="session"></param>
        private void HandleGetOrHeadRequest(HTTPMessage msg, HTTPSession session)
        {
            // Format of DirectiveObj will be
            // "/[res.m_ResourceID]/[item.ID]/[item.Title].[ext]"
            // We want the
            bool is404 = true;
            Exception problem = null;

            string resourceID = null;
            string objectID = null;

            try
            {
                DText DirectiveParser = new DText();
                DirectiveParser.ATTRMARK = "/";

                DirectiveParser[0] = msg.DirectiveObj;
                resourceID = DirectiveParser[2];
                objectID = DirectiveParser[3];
                IDvResource res = this.GetResource(objectID, resourceID);

                if (res == null)
                {
                    throw new Error_GetRequestError(msg.DirectiveObj, null);
                }
                else
                {
                    // attempt to figure otu the local file path and the mime type
                    string f = MediaResource.AUTOMAPFILE;
                    string fileName = res.ContentUri.Substring(f.Length);
                    string type = res.ProtocolInfo.MimeType;

                    if ((type == null) || (type == "") || (type == "*"))
                    {
                        //content-type not known, programmer
                        //that built content-hierarchy didn't provide one

                        throw new Error_GetRequestError(msg.DirectiveObj, res);
                    }
                    else
                    {
                        // must be a get or head request

                        // check if the file actually exists
                        if (Directory.Exists(fileName))
                        {
                            throw new Error_GetRequestError(msg.DirectiveObj, res);
                        }

                        FileNotMapped mapping = new FileNotMapped();
                        mapping.RequestedResource = res;
                        mapping.LocalInterface = session.Source.ToString();
                        mapping.RedirectedStream = null;
                        if (File.Exists(fileName))
                        {
                            // the file exists, so go ahead and send it
                            mapping.RedirectedStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
                        }
                        else
                        {
                            try
                            {
                                // the file doesn't exist but the owner of this
                                // server specified some kind of locally mapped file
                                // so perhaps they may want to route a stream object themselves
                                if (this.OnFileNotMapped != null)
                                {
                                    this.OnFileNotMapped (this, mapping);
                                }
                            }
                            catch (Exception ofnm)
                            {
                                mapping.RedirectedStream = null;
                            }
                        }

                        // if the RedirectedStream is blank, then it means
                        // no stream can be sent in response to the request

                        if (mapping.RedirectedStream != null)
                        {
                            lock (session)
                            {
                                // get the intended length, if known
                                long expectedLength = -1;
                                if (mapping.OverrideRedirectedStreamLength)
                                {
                                    expectedLength = mapping.ExpectedStreamLength;
                                }
                                else
                                {
                                    expectedLength = mapping.RedirectedStream.Length;
                                }

                                if (String.Compare(msg.Directive, "HEAD", true) == 0)
                                {
                                    // must be a head request - reply with 200/OK, content type, content length
                                    HTTPMessage head = new HTTPMessage();
                                    head.StatusCode = 200;
                                    head.StatusData = "OK";
                                    head.ContentType = type;
                                    if (expectedLength >= 0)
                                    {
                                        // if we can calculate the length,
                                        // then we provide a content-length and
                                        // also indicate that range requests can be
                                        // handled.

                                        head.OverrideContentLength = true;

                                        string rangeStr = msg.GetTag("RANGE");
                                        if ((rangeStr == null) || (rangeStr == ""))
                                        {
                                            head.AddTag("CONTENT-LENGTH", expectedLength.ToString());
                                            head.AddTag("ACCEPT-RANGES", "bytes");
                                        }
                                        else
                                        {
                                            ArrayList rangeSets = new ArrayList();
                                            head.StatusCode = 206;
                                            AddRangeSets(rangeSets, rangeStr.Trim().ToLower(), expectedLength);
                                            if (rangeSets.Count == 1)
                                            {
                                                head.AddTag("Content-Range", "bytes " + ((HTTPSession.Range)(rangeSets[0])).Position.ToString() + "-" + ((int)(((HTTPSession.Range)(rangeSets[0])).Position+((HTTPSession.Range)(rangeSets[0])).Length-1)).ToString() + "/" + expectedLength.ToString());
                                                head.AddTag("Content-Length", ((HTTPSession.Range)(rangeSets[0])).Length.ToString());
                                            }
                                        }
                                    }
                                    else
                                    {
                                        // can't calculate length => can't do range
                                        head.AddTag("ACCEPT-RANGES", "none");
                                    }
                                    session.Send(head);
                                    is404 = false;
                                }
                                else
                                {
                                    ArrayList rangeSets = new ArrayList();
                                    string rangeStr = msg.GetTag("RANGE");

                                    // Only allow range requests for content where we have the
                                    // entire length and also only for requests that have
                                    // also provided an allowed range.
                                    if ((rangeStr == null) || (rangeStr != ""))
                                    {
                                        if (expectedLength >= 0)
                                        {
                                            // validate the requested ranges; if invalid range
                                            // found, send the entire document...
                                            AddRangeSets(rangeSets, rangeStr.Trim().ToLower(), expectedLength);
                                        }
                                    }

                                    // must be a get request
                                    // create an outgoing transfer that is not visible to UPNP
                                    // GetTransferProgress method, and add the transfer
                                    HttpTransfer transferInfo = new HttpTransfer(false, false, session, res, mapping.RedirectedStream, expectedLength);
                                    this.AddTransfer(session, transferInfo);

                                    if (rangeSets.Count > 0)
                                    {
                                        session.SendStreamObject(mapping.RedirectedStream, (HTTPSession.Range[])rangeSets.ToArray(typeof(HTTPSession.Range)), type);
                                    }
                                    else
                                    {
                                        //start from the beginning
                                        mapping.RedirectedStream.Seek(0, SeekOrigin.Begin);
                                        if (expectedLength >= 0)
                                        {
                                            session.SendStreamObject(mapping.RedirectedStream, expectedLength, type);
                                        }
                                        else
                                        {
                                            session.SendStreamObject(mapping.RedirectedStream, type);
                                        }
                                    }
                                    is404 = false;
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception error)
            {
                problem = error;
            }

            if (is404)
            {
                StringBuilder sb = new StringBuilder();

                sb.Append("File not found.");
                sb.AppendFormat("\r\n\tRequested: \"{0}\"", msg.DirectiveObj);

                if (objectID != null)
                {
                    sb.AppendFormat("\r\n\tObjectID=\"{0}\"", objectID);
                }

                if (resourceID != null)
                {
                    sb.AppendFormat("\r\n\tResourceID=\"{0}\"", resourceID);
                }

                Error_GetRequestError getHeadError = problem as Error_GetRequestError;

                if (getHeadError != null)
                {
                    sb.Append("\r\n");

                    IUPnPMedia mobj = this._GetEntry(objectID);

                    if (mobj == null)
                    {
                        sb.AppendFormat("\r\n\tCould not find object with ID=\"{0}\"", objectID);
                    }
                    else
                    {
                        sb.AppendFormat("\r\n\tFound object with ID=\"{0}\"", objectID);
                        sb.Append("\r\n---Metadata---\r\n");
                        sb.Append(mobj.ToDidl());
                    }

                    sb.Append("\r\n");

                    if (getHeadError.Resource == null)
                    {
                        sb.Append("\r\n\tResource is null.");
                    }
                    else
                    {
                        sb.Append("\r\n\tResource is not null.");

                        string uri = getHeadError.Resource.ContentUri;
                        if (uri== null)
                        {
                            sb.Append("\r\n\t\tContentUri of resource is null.");
                        }
                        else if (uri == "")
                        {
                            sb.Append("\r\n\t\tContentUri of resource is empty.");
                        }
                        else
                        {
                            sb.AppendFormat("\r\n\t\tContentUri of resource is \"{0}\"", uri);
                        }
                    }
                }

                if (problem != null)
                {
                    sb.Append("\r\n");

                    Exception e = problem;
                    sb.Append("\r\n!!! Exception information !!!");

                    while (e != null)
                    {
                        sb.AppendFormat("\r\nMessage=\"{0}\".\r\nStackTrace=\"{1}\"", e.Message, e.StackTrace);

                        e = e.InnerException;
                        if (e != null)
                        {
                            sb.Append("\r\n---InnerException---");
                        }
                    }
                }

                // file has not been found so return a valid HTTP 404 error message
                HTTPMessage error = new HTTPMessage();
                error.StatusCode = 404;
                error.StatusData = "File not found";
                error.StringBuffer = sb.ToString();
                session.Send(error);
            }
        }
コード例 #16
0
ファイル: HTTPRequest.cs プロジェクト: Scannow/SWYH
        private void ReceiveSink(HTTPSession sender, HTTPMessage msg)
        {
            StateData sd = (StateData)sender.StateObject;
            object Tag = sd.Tag;

            if (msg.Version == "1.0" || msg.Version == "0.9")
            {
                sender.Close();
            }
            else
            {
                if (msg.GetTag("Connection").ToUpper() == "CLOSE")
                {
                    sender.Close();
                }
            }


            if (OnResponse != null) OnResponse(this, msg, Tag);
            // If I don't set this to null, this holds a strong reference, resulting in
            // possible memory leaks
            sender.StateObject = null;
            lock (TagQueue)
            {
                if (TagQueue.Count == 0)
                {
                    this.IdleTimeout = true;
                    KeepAliveTimer.Add(this.GetHashCode(), 10);
                }
            }
        }
コード例 #17
0
        /// <summary>
        /// Parses a Byte Array at a specific location, and builds a Packet.
        /// </summary>
        /// <param name="buffer">The Array of Bytes</param>
        /// <param name="indx">The Start Index</param>
        /// <param name="count">The number of Bytes to process</param>
        /// <returns></returns>
        public static HTTPMessage ParseByteArray(byte[] buffer, int indx, int count)
        {
            HTTPMessage TheMessage = new HTTPMessage();
            UTF8Encoding UTF8 = new UTF8Encoding();
            String TempData = UTF8.GetString(buffer,indx,count);
            DText parser = new DText();
            String TempString;

            int idx = TempData.IndexOf("\r\n\r\n");
            if (idx < 0) return null;
            TempData = TempData.Substring(0,idx);

            parser.ATTRMARK = "\r\n";
            parser.MULTMARK = ":";
            parser[0] = TempData;
            string CurrentLine = parser[1];

            DText HdrParser = new DText();
            HdrParser.ATTRMARK = " ";
            HdrParser.MULTMARK = "/";
            HdrParser[0] = CurrentLine;

            if (CurrentLine.ToUpper().StartsWith("HTTP/")==true)
            {
                TheMessage.ResponseCode = int.Parse(HdrParser[2]);
                int s1 = CurrentLine.IndexOf(" ");
                s1 = CurrentLine.IndexOf(" ",s1+1);
                TheMessage.ResponseData = HTTPMessage.UnEscapeString(CurrentLine.Substring(s1));
                try
                {
                    TheMessage.Version = HdrParser[1,2];
                }
                catch(Exception)
                {
                    TheMessage.Version = "0.9";
                }
            }
            else
            {
                TheMessage.Directive = HdrParser[1];
                TempString = CurrentLine.Substring(CurrentLine.LastIndexOf(" ") + 1);
                if (TempString.ToUpper().StartsWith("HTTP/")==false)
                {
                    TheMessage.Version = "0.9";
                    TheMessage.DirectiveObj = HTTPMessage.UnEscapeString(TempString);
                }
                else
                {
                    TheMessage.Version = TempString.Substring(TempString.IndexOf("/")+1);
                    int fs = CurrentLine.IndexOf(" ") + 1;
                    TheMessage.DirectiveObj = HTTPMessage.UnEscapeString(CurrentLine.Substring(
                        fs,
                        CurrentLine.Length-fs-TempString.Length-1));
                }
            }
            String Tag="";
            String TagData="";

            for(int line=2;line<=parser.DCOUNT();++line)
            {
                if (Tag!="" && parser[line,1].StartsWith(" "))
                {
                    TagData = parser[line,1].Substring(1);
                }
                else
                {
                    Tag = parser[line,1];
                    TagData = "";
                    for(int i=2;i<=parser.DCOUNT(line);++i)
                    {
                        if (TagData=="")
                        {
                            TagData = parser[line,i];
                        }
                        else
                        {
                            TagData = TagData + parser.MULTMARK + parser[line,i];
                        }
                    }
                }
                TheMessage.AppendTag(Tag,TagData);
            }
            int cl=0;
            if (TheMessage.HasTag("Content-Length"))
            {
                try
                {
                    cl = int.Parse(TheMessage.GetTag("Content-Length"));
                }
                catch(Exception)
                {
                    cl = -1;
                }
            }
            else
            {
                cl = -1;
            }

            byte[] tbuffer;
            if (cl>0)
            {
                tbuffer = new byte[cl];
                if ((idx+4+cl)>count)
                {
                    // NOP
                }
                else
                {
                    Array.Copy(buffer,idx+4,tbuffer,0,cl);
                    TheMessage.DataBuffer = tbuffer;
                }
            }
            if (cl==-1)
            {
                tbuffer = new Byte[count-(idx+4)];
                Array.Copy(buffer,idx+4,tbuffer,0,tbuffer.Length);
                TheMessage.DataBuffer = tbuffer;
            }
            if (cl==0)
            {
                TheMessage.DataBuffer = new byte[0];
            }
            return(TheMessage);
        }
コード例 #18
0
        private void HandleWebRequest(HTTPMessage msg, HTTPSession WebSession)
        {
            DText parser = new DText();
            HTTPMessage Response = new HTTPMessage();
            HTTPMessage Response2 = null;
            String Method = msg.Directive;
            String MethodData = msg.DirectiveObj;

            if (WebSession.InternalStateObject != null)
            {
                HTTPMessage _msg = (HTTPMessage)msg.Clone();
                object[] state = (object[])WebSession.InternalStateObject;
                _msg.DirectiveObj = (string)state[1];
                VirtualDirectoryHandler t = (VirtualDirectoryHandler)state[2];
                WebSession.InternalStateObject = null;
                t(this, _msg, WebSession, (string)state[0]);
                return;

            }

            if ((Method != "GET") && (Method != "HEAD") && (Method != "POST") &&
                (Method != "SUBSCRIBE") && (Method != "UNSUBSCRIBE") &&
                (Method != "NOTIFY"))
            {
                Response.StatusCode = 405;
                Response.StatusData = Method + " not supported";
                WebSession.Send(Response);
                return; // Other methods are unknown to us
            }

            // Process Headers
            if (Method == "GET" || Method == "HEAD")
            {
                try
                {
                    Response = Get(MethodData, WebSession.Source);
                }
                catch (UPnPCustomException ce)
                {
                    OpenSource.Utilities.EventLogger.Log(ce);
                    Response.StatusCode = ce.ErrorCode;
                    Response.StatusData = ce.ErrorDescription;
                    WebSession.Send(Response);
                    return;
                }
                catch (Exception e)
                {
                    OpenSource.Utilities.EventLogger.Log(e);
                    Response.StatusCode = 500;
                    Response.StatusData = "Internal";
                    Response.StringBuffer = e.ToString();
                }
                if (Method == "HEAD")
                {
                    Response.BodyBuffer = null;
                }
                WebSession.Send(Response);
            }

            if (Method == "POST")
            {
                //InvokerInfo[Thread.CurrentThread.GetHashCode()] = WebSession;
                try
                {
                    Response = Post(MethodData, msg.StringBuffer, msg.GetTag("SOAPACTION"), WebSession);
                }
                catch (DelayedResponseException ex)
                {
                    OpenSource.Utilities.EventLogger.Log(ex);
                    InvokerInfo.Remove(Thread.CurrentThread.GetHashCode());
                    WebSession.StopReading();
                    return;
                }
                catch (UPnPCustomException ce)
                {
                    OpenSource.Utilities.EventLogger.Log(this, System.Diagnostics.EventLogEntryType.Error, "UPnP Error [" + ce.ErrorCode.ToString() + "] " + ce.ErrorDescription);
                    Response.StatusCode = 500;
                    Response.StatusData = "Internal";
                    Response.StringBuffer = BuildErrorBody(ce);
                    WebSession.Send(Response);
                    InvokerInfo.Remove(Thread.CurrentThread.GetHashCode());
                    return;
                }
                catch (UPnPInvokeException ie)
                {
                    Response.StatusCode = 500;
                    Response.StatusData = "Internal";
                    if (ie.UPNP != null)
                    {
                        OpenSource.Utilities.EventLogger.Log(this, System.Diagnostics.EventLogEntryType.Error, "UPnP Error [" + ie.UPNP.ErrorCode.ToString() + "] " + ie.UPNP.ErrorDescription);
                        Response.StringBuffer = BuildErrorBody(ie.UPNP);
                    }
                    else
                    {
                        OpenSource.Utilities.EventLogger.Log(this, System.Diagnostics.EventLogEntryType.Error, "UPnP Invocation Error [" + ie.MethodName + "] " + ie.Message);
                        Response.StringBuffer = BuildErrorBody(new UPnPCustomException(500, ie.Message));
                    }
                    WebSession.Send(Response);
                    InvokerInfo.Remove(Thread.CurrentThread.GetHashCode());
                    return;
                }
                catch (UPnPTypeMismatchException tme)
                {
                    OpenSource.Utilities.EventLogger.Log(tme);
                    Response.StatusCode = 500;
                    Response.StatusData = "Internal";
                    Response.StringBuffer = BuildErrorBody(new UPnPCustomException(402, tme.Message));
                    WebSession.Send(Response);
                    InvokerInfo.Remove(Thread.CurrentThread.GetHashCode());
                    return;
                }
                catch (UPnPStateVariable.OutOfRangeException oor)
                {
                    OpenSource.Utilities.EventLogger.Log(oor);
                    Response.StatusCode = 500;
                    Response.StatusData = "Internal";
                    Response.StringBuffer = BuildErrorBody(new UPnPCustomException(402, oor.Message));
                    WebSession.Send(Response);
                    InvokerInfo.Remove(Thread.CurrentThread.GetHashCode());
                    return;
                }
                catch (System.Reflection.TargetInvocationException tie)
                {
                    Exception inner = tie.InnerException;
                    OpenSource.Utilities.EventLogger.Log(tie);
                    while (inner.InnerException != null && (typeof(UPnPCustomException).IsInstanceOfType(inner) == false))
                    {
                        inner = inner.InnerException;
                    }
                    if (typeof(UPnPCustomException).IsInstanceOfType(inner))
                    {
                        UPnPCustomException ce = (UPnPCustomException)inner;
                        OpenSource.Utilities.EventLogger.Log(this, System.Diagnostics.EventLogEntryType.Error, "UPnP Error [" + ce.ErrorCode.ToString() + "] " + ce.ErrorDescription);
                        Response.StatusCode = 500;
                        Response.StatusData = "Internal";
                        Response.StringBuffer = BuildErrorBody(ce);
                        WebSession.Send(Response);
                        InvokerInfo.Remove(Thread.CurrentThread.GetHashCode());
                        return;
                    }
                    else
                    {
                        Response.StatusCode = 500;
                        Response.StatusData = "Internal";
                        Response.StringBuffer = BuildErrorBody(new UPnPCustomException(500, inner.ToString()));
                        WebSession.Send(Response);
                        OpenSource.Utilities.EventLogger.Log(inner);
                        return;
                    }
                }
                catch (Exception e)
                {
                    Response.StatusCode = 500;
                    Response.StatusData = "Internal";
                    Response.StringBuffer = BuildErrorBody(new UPnPCustomException(500, e.ToString()));
                    WebSession.Send(Response);
                    OpenSource.Utilities.EventLogger.Log(e);
                    return;
                }

                WebSession.Send(Response);
                InvokerInfo.Remove(Thread.CurrentThread.GetHashCode());
                return;
            }

            if (Method == "SUBSCRIBE")
            {
                String SID = msg.GetTag("SID");
                String NT = msg.GetTag("NT");
                String Timeout = msg.GetTag("Timeout");
                String CallbackURL = msg.GetTag("Callback");
                if (Timeout == "")
                {
                    Timeout = "7200"; // Default  = 2 Hours
                }
                else
                {
                    Timeout = Timeout.Substring(Timeout.IndexOf("-") + 1).Trim().ToUpper();
                    if (Timeout == "INFINITE")
                    {
                        Timeout = "0";
                    }
                }
                if (SID != "")
                {
                    // Renew
                    RenewEvents(MethodData.Substring(1), SID, Timeout);
                }
                else
                {
                    // Subscribe
                    try
                    {
                        Response2 = SubscribeEvents(ref SID, MethodData.Substring(1), CallbackURL, Timeout);
                    }
                    catch (Exception s_exception)
                    {
                        OpenSource.Utilities.EventLogger.Log(s_exception);
                        HTTPMessage err = new HTTPMessage();
                        err.StatusCode = 500;
                        err.StatusData = s_exception.Message;
                        WebSession.Send(err);
                        return;
                    }
                }
                if (Timeout == "0")
                {
                    Timeout = "Second-infinite";
                }
                else
                {
                    Timeout = "Second-" + Timeout;
                }
                Response.StatusCode = 200;
                Response.StatusData = "OK";
                Response.AddTag("Server", "Windows NT/5.0, UPnP/1.0");
                Response.AddTag("SID", SID);
                Response.AddTag("Timeout", Timeout);
                WebSession.Send(Response);
                if (Response2 != null)
                {
                    Uri[] cbURL = ParseEventURL(CallbackURL);
                    for (int x = 0; x < cbURL.Length; ++x)
                    {
                        Response2.DirectiveObj = HTTPMessage.UnEscapeString(cbURL[x].PathAndQuery);
                        Response2.AddTag("Host", cbURL[x].Host + ":" + cbURL[x].Port.ToString());

                        IPEndPoint d = new IPEndPoint(IPAddress.Parse(cbURL[x].Host), cbURL[x].Port);
                        HTTPRequest R = new HTTPRequest();
                        R.OnResponse += new HTTPRequest.RequestHandler(HandleInitialEvent);
                        this.InitialEventTable[R] = R;
                        R.PipelineRequest(d, Response2, null);
                    }
                }
            }

            if (Method == "UNSUBSCRIBE")
            {
                CancelEvent(MethodData.Substring(1), msg.GetTag("SID"));
                Response.StatusCode = 200;
                Response.StatusData = "OK";
                WebSession.Send(Response);
            }
        }