public static void TerminateBoshSession(HttpListenerContext ctx, Body body, string condition)
		{
			if (ctx == null || ctx.Response == null) return;

			if (body == null) body = new Body();
			try
			{
				body.Type = BoshType.terminate;
				if (!string.IsNullOrEmpty(condition)) body.SetAttribute("condition", condition);

				SendAndCloseResponse(ctx, body.ToString());

				log.DebugFormat("TerminateBoshSession body: {0}", body);
			}
			catch (Exception e)
			{
				try
				{
					ctx.Response.Close();
				}
				catch { }
				log.ErrorFormat("Error TerminateBoshSession body: {0}\r\n{1}", body, e);
			}
		}
        private void InvokeStreamStart(Body body)
        {
            var stream = new Stream();
            stream.Prefix = Uri.PREFIX;
            stream.Namespace = Uri.STREAM;
            stream.Version = body.Version;
            stream.Language = body.GetAttribute("lang");
            stream.To = body.To;

            var handler = XmppStreamStart;
            if (handler != null) handler(this, new XmppStreamStartEventArgs(Id, stream, Uri.CLIENT));
        }
        private void SendAnswer(Body body, HttpListenerContext ctx)
        {
            try
            {
                lock (sendBuffer)
                {
                    foreach (var node in sendBuffer)
                    {
                        body.AddChild(node);
                        if (node.Namespace == Uri.STREAM) body.SetAttribute("xmlns:stream", Uri.STREAM);
                    }

                    if (closed) body.Type = BoshType.terminate;
                    BoshXmppHelper.SendAndCloseResponse(ctx, body.ToString(), true, null);
                    sendBuffer.Clear();
                    log.DebugFormat("Connection {0} Send buffer:\r\n{1}", Id, body);
                }
            }
            catch (Exception e)
            {
                //BUG: Я думаю баг тут из за обрыва соединения при говенном кач-ве соединения.
                log.DebugFormat("Connection {0} Error send buffer: {1}", Id, e);
                Close();
            }
        }
 private Body WriteBodyHeaders(Body body)
 {
     if (string.IsNullOrEmpty(body.Sid))
     {
         body.Sid = Id;
         body.Secure = false;
     }
     body.Ack = body.Rid != 0 ? body.Rid : rid;
     body.RemoveAttribute("rid");
     body.To = null;
     if (body.HasAttribute("xmpp:version") || body.HasAttribute("xmpp:restart"))
     {
         body.SetAttribute("xmlns:xmpp", "urn:xmpp:xbosh");
     }
     body.RemoveAllChildNodes();
     return body;
 }
 private void ReadBodyHeaders(Body body)
 {
     rid = body.Rid;
     if (0 < body.Wait) waitPeriod = TimeSpan.FromSeconds(body.Wait);
     if (0 < body.Inactivity) inactivityPeriod = TimeSpan.FromSeconds(body.Inactivity);
 }
        private bool ValidateBody(Body body)
        {
            if (0 < body.Window) window = body.Window;
            if (0 < body.Polling) window = body.Polling;

            if (closed) return false;
            if (rid != 0 && window < Math.Abs(body.Rid - rid)) return false;
            return true;
        }
        public void ProcessBody(Body body, HttpListenerContext ctx)
        {
            try
            {
                IdleWatcher.UpdateTimeout(Id, TimeSpan.MaxValue);

                if (body == null) throw new ArgumentNullException("body");
                if (ctx == null) throw new ArgumentNullException("httpContext");

                log.DebugFormat("Start process body connection {0}\r\n{1}\r\n", Id, body);

                if (!ValidateBody(body))
                {
                    BoshXmppHelper.TerminateBoshSession(ctx, "bad-request");
                    return;
                }
                if (body.Type == BoshType.terminate)
                {
                    Close();
                    ctx.Response.Close();
                    return;
                }

                waitDrop.Set();
                waitDrop.Reset();

                ReadBodyHeaders(body);

                if (string.IsNullOrEmpty(body.Sid) || body.XmppRestart)
                {
                    InvokeStreamStart(body);
                }
                foreach (var node in body.ChildNodes)
                {
                    if (node is Element) InvokeStreamElement((Element)node);
                }

                WriteBodyHeaders(body);

                log.DebugFormat("Connection {0} WAIT ...", Id);
                var waitResult = WaitAnswerOrDrop();

                if (waitResult == WaitResult.Success)
                {
                    log.DebugFormat("Connection {0} send answer", Id);
                    SendAnswer(body, ctx);
                }
                else if (waitResult == WaitResult.Timeout)
                {
                    log.DebugFormat("Connection {0} drop by timeout", Id);
                    BoshXmppHelper.SendAndCloseResponse(ctx, new Body().ToString());
                }
                else
                {
                    log.DebugFormat("Connection {0} terminate", Id);
                    BoshXmppHelper.TerminateBoshSession(ctx, body);
                }
            }
            finally
            {
                IdleWatcher.UpdateTimeout(Id, inactivityPeriod);
            }
        }
 public static void TerminateBoshSession(HttpListenerContext ctx, Body body)
 {
     TerminateBoshSession(ctx, body, null);
 }