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(); } }
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(); } }
public void Close(bool terminate) { if (terminate) { BoshXmppHelper.TerminateBoshSession(context, body); } else { BoshXmppHelper.SendAndCloseResponse(context, new Body()); } }
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); }
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); }
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); } }
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); } } }