示例#1
0
        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);
                    sendBuffer.Clear();
                    log.DebugFormat("Connection {0} Send buffer:\r\n{1}", Id, body);
                }
            }
            catch (Exception e)
            {
                log.DebugFormat("Connection {0} Error send buffer: {1}", Id, e);
                Close();
            }
        }
        private void SendAnswer(Body body, HttpListenerContext ctx)
        {
            try
            {
                var copy = Interlocked.Exchange(ref sendBuffer, new ConcurrentQueue <Node>());
                foreach (var node in copy)
                {
                    body.AddChild(node);
                    if (node.Namespace == Uri.STREAM)
                    {
                        body.SetAttribute("xmlns:stream", Uri.STREAM);
                    }
                }

                if (Volatile.Read(ref closed) == 1)
                {
                    body.Type = BoshType.terminate;
                }
                BoshXmppHelper.SendAndCloseResponse(ctx, body.ToString(), true, null);

                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();
            }
        }
示例#3
0
 public void Close(bool terminate)
 {
     if (terminate)
     {
         BoshXmppHelper.TerminateBoshSession(context, body);
     }
     else
     {
         BoshXmppHelper.SendAndCloseResponse(context, new Body());
     }
 }
示例#4
0
        public void SendAndClose(IEnumerable <Node> buffer, bool terminate)
        {
            foreach (var node in buffer)
            {
                body.AddChild(node);
                if (node.Namespace == Uri.STREAM)
                {
                    body.SetAttribute("xmlns:stream", Uri.STREAM);
                }
            }

            if (terminate)
            {
                body.Type = BoshType.terminate;
            }
            BoshXmppHelper.SendAndCloseResponse(context, body);
        }
示例#5
0
        private void SendPolicy(HttpListenerContext ctx)
        {
            log.DebugFormat("{0}: Send policy.", Name);

            if (!policyLoaded)
            {
                try
                {
                    policy = File.ReadAllText(policyFile);
                }
                catch (Exception ex)
                {
                    log.ErrorFormat("Can not load policy file: {0}, error: {1}", policyFile, ex);
                }
                policyLoaded = true;
            }
            BoshXmppHelper.SendAndCloseResponse(ctx, policy);
        }
示例#6
0
        private void GetContextCallback(IAsyncResult asyncResult)
        {
            HttpListenerContext ctx = null;

            try
            {
                try
                {
                    ctx = httpListener.EndGetContext(asyncResult);
                }
                finally
                {
                    BeginGetContext();
                }

                if (maxPacket < ctx.Request.ContentLength64)
                {
                    BoshXmppHelper.TerminateBoshSession(ctx, "request-too-large");
                    return;
                }

                if (ctx.Request.Url.AbsolutePath == bindUri.AbsolutePath)
                {
                    var body = BoshXmppHelper.ReadBodyFromRequest(ctx);
                    if (body == null)
                    {
                        BoshXmppHelper.TerminateBoshSession(ctx, "bad-request");
                        return;
                    }

                    var connection = GetXmppConnection(body.Sid) as BoshXmppConnection;

                    if (!string.IsNullOrEmpty(body.Sid) && connection == null)
                    {
                        BoshXmppHelper.TerminateBoshSession(ctx, "item-not-found");
                        return;
                    }

                    if (connection == null)
                    {
                        connection = new BoshXmppConnection(body);
                        log.DebugFormat("Create new Bosh connection Id = {0}", connection.Id);

                        AddNewXmppConnection(connection);
                    }
                    connection.ProcessBody(body, ctx);
                }
                else
                {
                    BoshXmppHelper.TerminateBoshSession(ctx, "bad-request");
                    log.DebugFormat("{0}: Unknown uri request {1}", Name, ctx.Request.Url);
                }
            }
            catch (Exception e)
            {
                BoshXmppHelper.TerminateBoshSession(ctx, "internal-server-error");
                if (Started && !(e is ObjectDisposedException))
                {
                    log.ErrorFormat("{0}: Error GetContextCallback: {1}", Name, e);
                }
            }
        }
示例#7
0
        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);
            }
        }
示例#8
0
        private void GetContextCallback(IAsyncResult asyncResult)
        {
            HttpListenerContext ctx = null;

            try
            {
                try
                {
                    ctx = httpListener.EndGetContext(asyncResult);
                }
                finally
                {
                    BeginGetContext();
                }

                if (maxPacket < ctx.Request.ContentLength64)
                {
                    BoshXmppHelper.TerminateBoshSession(ctx, "request-too-large");
                    return;
                }

                var url = ctx.Request.Url;
                log.DebugFormat("{0}: Begin process http request {1}", Name, url);

                if (url.AbsolutePath == bindUri.AbsolutePath)
                {
                    var body = BoshXmppHelper.ReadBodyFromRequest(ctx);
                    if (body == null)
                    {
                        BoshXmppHelper.TerminateBoshSession(ctx, "bad-request");
                        return;
                    }

                    var connection = GetXmppConnection(body.Sid) as BoshXmppConnection;

                    if (!string.IsNullOrEmpty(body.Sid) && connection == null)
                    {
                        BoshXmppHelper.TerminateBoshSession(ctx, "item-not-found");
                        return;
                    }

                    if (connection == null)
                    {
                        connection = new BoshXmppConnection();
                        AddNewXmppConnection(connection);
                    }

                    connection.ProcessBody(body, ctx);
                }
                else if ((url.AbsolutePath == domainUri.AbsolutePath || url.AbsolutePath == "/crossdomain.xml") && ctx.Request.HttpMethod == "GET")
                {
                    SendPolicy(ctx);
                }
                else
                {
                    BoshXmppHelper.TerminateBoshSession(ctx, "bad-request");
                }
            }
            catch (ObjectDisposedException) { }
            catch (Exception e)
            {
                if (ctx != null)
                {
                    BoshXmppHelper.TerminateBoshSession(ctx, "internal-server-error");
                }
                if (Started)
                {
                    log.ErrorFormat("{0}: Error GetContextCallback: {1}", Name, e);
                }
            }
        }
示例#9
0
        private void GetContextCallback(IAsyncResult asyncResult)
        {
            HttpListenerContext ctx = null;

            try
            {
                try
                {
                    ctx = httpListener.EndGetContext(asyncResult);
                }
                finally
                {
                    BeginGetContext();
                }

                if (maxPacket < ctx.Request.ContentLength64)
                {
                    BoshXmppHelper.TerminateBoshSession(ctx, "request-too-large");
                    return;
                }

                var url = ctx.Request.Url;
                log.DebugFormat("{0}: Begin process http request {1}", Name, url);

                if (url.AbsolutePath == bindUri.AbsolutePath)
                {
                    var body = BoshXmppHelper.ReadBodyFromRequest(ctx);
                    if (body == null)
                    {
                        BoshXmppHelper.TerminateBoshSession(ctx, "bad-request");
                        return;
                    }

                    var connection = GetXmppConnection(body.Sid) as BoshXmppConnection;

                    if (!string.IsNullOrEmpty(body.Sid) && connection == null)
                    {
                        BoshXmppHelper.TerminateBoshSession(ctx, "item-not-found");
                        return;
                    }

                    if (connection == null)
                    {
                        connection = new BoshXmppConnection();
                        AddNewXmppConnection(connection);
                    }

                    connection.ProcessBody(body, ctx);
                }
                else if ((url.AbsolutePath == domainUri.AbsolutePath || url.AbsolutePath == "/crossdomain.xml") && ctx.Request.HttpMethod == "GET")
                {
                    SendPolicy(ctx);
                }
                else
                {
                    IHttpResponder responder;
                    if (apiUri != null && url.AbsolutePath.Length > apiUri.AbsolutePath.Length)
                    {
                        var urlPath = url.AbsolutePath.Substring(apiUri.AbsolutePath.Length).Trim('/');
                        if ((responder = httpResponders.FirstOrDefault(x => x.Path == urlPath)) != null)
                        {
                            //To responder
                            try
                            {
                                var responce = responder.Process(ctx.Request).ToString();
                                BoshXmppHelper.SendAndCloseResponse(ctx, responce);
                            }
                            catch (UnauthorizedAccessException)
                            {
                                ctx.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                                BoshXmppHelper.TerminateBoshSession(ctx, "unathorized");
                            }
                            catch (Exception)
                            {
                                ctx.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
                                BoshXmppHelper.TerminateBoshSession(ctx, "server-error");
                            }
                        }
                        else
                        {
                            BoshXmppHelper.TerminateBoshSession(ctx, "bad-request");
                        }
                    }
                    else
                    {
                        BoshXmppHelper.TerminateBoshSession(ctx, "bad-request");
                    }
                }
            }
            catch (ObjectDisposedException) { }
            catch (Exception e)
            {
                if (ctx != null)
                {
                    BoshXmppHelper.TerminateBoshSession(ctx, "internal-server-error");
                }
                if (Started)
                {
                    log.ErrorFormat("{0}: Error GetContextCallback: {1}", Name, e);
                }
            }
        }