Пример #1
0
        /// <summary>
        /// Creates a Web-socket session.
        /// </summary>
        public override async void CreateSession()
        {
            try
            {
                lock (this.queue)
                {
                    this.terminated = false;
                    this.writing    = false;
                    this.closeSent  = false;
                    this.queue.Clear();

                    this.webSocketClient?.Dispose();
                    this.webSocketClient = null;

                    this.webSocketClient = new ClientWebSocket();
                    this.webSocketClient.Options.KeepAliveInterval = TimeSpan.FromSeconds(30);
                }

                await this.webSocketClient.ConnectAsync(this.url, CancellationToken.None);

                // TODO: this.xmppClient.TrustServer

                if (this.xmppClient.HasSniffers)
                {
                    this.xmppClient.Information("Initiating session.");
                }

                await this.SendAsync("<?");

                string XmlResponse = await this.ReadText();

                XmlDocument ResponseXml = new XmlDocument()
                {
                    PreserveWhitespace = true
                };
                ResponseXml.LoadXml(XmlResponse);

                XmlElement Open;

                if ((Open = ResponseXml.DocumentElement) is null || Open.LocalName != "open" ||
                    Open.NamespaceURI != FramingNamespace)
                {
                    throw new Exception("Unexpected response returned.");
                }

                string StreamPrefix = "stream";
                LinkedList <KeyValuePair <string, string> > Namespaces = null;

                this.to       = null;
                this.from     = null;
                this.version  = 0;
                this.language = null;

                foreach (XmlAttribute Attr in Open.Attributes)
                {
                    switch (Attr.Name)
                    {
                    case "version":
                        if (!CommonTypes.TryParse(Attr.Value, out this.version))
                        {
                            throw new Exception("Invalid version number.");
                        }
                        break;

                    case "to":
                        this.to = Attr.Value;
                        break;

                    case "from":
                        this.from = Attr.Value;
                        break;

                    case "xml:lang":
                        this.language = Attr.Value;
                        break;

                    default:
                        if (Attr.Prefix == "xmlns")
                        {
                            if (Attr.Value == XmppClient.NamespaceStream)
                            {
                                StreamPrefix = Attr.LocalName;
                            }
                            else
                            {
                                if (Namespaces is null)
                                {
                                    Namespaces = new LinkedList <KeyValuePair <string, string> >();
                                }

                                Namespaces.AddLast(new KeyValuePair <string, string>(Attr.Prefix, Attr.Value));
                            }
                        }
                        break;
                    }
                }

                StringBuilder sb = new StringBuilder();

                sb.Append('<');
                sb.Append(StreamPrefix);
                sb.Append(":stream xmlns:");
                sb.Append(StreamPrefix);
                sb.Append("='");
                sb.Append(XmppClient.NamespaceStream);

                if (!(this.to is null))
                {
                    sb.Append("' to='");
                    sb.Append(XML.Encode(this.to));
                }

                if (!(this.from is null))
                {
                    sb.Append("' from='");
                    sb.Append(XML.Encode(this.from));
                }

                if (this.version > 0)
                {
                    sb.Append("' version='");
                    sb.Append(CommonTypes.Encode(this.version));
                }

                if (!(this.language is null))
                {
                    sb.Append("' xml:lang='");
                    sb.Append(XML.Encode(this.language));
                }

                sb.Append("' xmlns='");
                sb.Append(XmppClient.NamespaceClient);

                if (!(Namespaces is null))
                {
                    foreach (KeyValuePair <string, string> P in Namespaces)
                    {
                        sb.Append("' xmlns:");
                        sb.Append(P.Key);
                        sb.Append("='");
                        sb.Append(XML.Encode(P.Value));
                    }
                }

                sb.Append("'>");

                this.bindingInterface.StreamHeader = sb.ToString();

                sb.Clear();
                sb.Append("</");
                sb.Append(StreamPrefix);
                sb.Append(":stream>");

                this.bindingInterface.StreamFooter = sb.ToString();

                this.StartReading();
            }
            catch (Exception ex)
            {
                await this.bindingInterface.ConnectionError(ex);
            }
        }
Пример #2
0
        private Task <bool> BodyReceived(string Xml, bool First)
        {
            string Body;
            int    i, j;

            i = Xml.IndexOf("<body");
            if (i >= 0)
            {
                i = Xml.IndexOf('>', i + 5);
                if (i > 0)
                {
                    Body = Xml.Substring(0, i + 1);

                    if (Xml[i - 1] == '/')
                    {
                        Xml = null;
                    }
                    else
                    {
                        Body += "</body>";

                        j = Xml.LastIndexOf("</body");
                        if (i < 0)
                        {
                            Xml = Xml.Substring(i + 1);
                        }
                        else
                        {
                            Xml = Xml.Substring(i + 1, j - i - 1).Trim();
                        }
                    }

                    bool        Terminate    = false;
                    string      Condition    = null;
                    string      To           = null;
                    string      From         = null;
                    string      Version      = null;
                    string      Language     = null;
                    string      StreamPrefix = "stream";
                    XmlDocument BodyDoc      = new XmlDocument();
                    LinkedList <KeyValuePair <string, string> > Namespaces = null;
                    BodyDoc.LoadXml(Body);

                    foreach (XmlAttribute Attr in BodyDoc.DocumentElement.Attributes)
                    {
                        switch (Attr.Name)
                        {
                        case "type":
                            if (Attr.Value == "terminate")
                            {
                                Terminate = true;
                            }
                            break;

                        case "condition":
                            Condition = Attr.Value;
                            break;

                        case "xml:lang":
                            Language = Attr.Value;
                            break;

                        default:
                            if (Attr.Prefix == "xmlns")
                            {
                                if (Attr.Value == XmppClient.NamespaceStream)
                                {
                                    StreamPrefix = Attr.LocalName;
                                }
                                else
                                {
                                    if (Namespaces is null)
                                    {
                                        Namespaces = new LinkedList <KeyValuePair <string, string> >();
                                    }

                                    Namespaces.AddLast(new KeyValuePair <string, string>(Attr.Prefix, Attr.Value));
                                }
                            }
                            else if (Attr.LocalName == "version" && Attr.NamespaceURI == BoshNamespace)
                            {
                                Version = Attr.Value;
                            }
                            break;
                        }
                    }

                    if (Terminate)
                    {
                        this.terminated = true;

                        lock (this.httpClients)
                        {
                            this.outputQueue.Clear();
                        }

                        throw new Exception("Session terminated. Condition: " + Condition);
                    }

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

                        sb.Append('<');
                        sb.Append(StreamPrefix);
                        sb.Append(":stream xmlns:");
                        sb.Append(StreamPrefix);
                        sb.Append("='");
                        sb.Append(XmppClient.NamespaceStream);

                        if (To != null)
                        {
                            sb.Append("' to='");
                            sb.Append(XML.Encode(To));
                        }

                        if (From != null)
                        {
                            sb.Append("' from='");
                            sb.Append(XML.Encode(From));
                        }

                        if (Version != null)
                        {
                            sb.Append("' version='");
                            sb.Append(XML.Encode(Version));
                        }

                        if (Language != null)
                        {
                            sb.Append("' xml:lang='");
                            sb.Append(XML.Encode(Language));
                        }

                        sb.Append("' xmlns='");
                        sb.Append(XmppClient.NamespaceClient);

                        if (Namespaces != null)
                        {
                            foreach (KeyValuePair <string, string> P in Namespaces)
                            {
                                sb.Append("' xmlns:");
                                sb.Append(P.Key);
                                sb.Append("='");
                                sb.Append(XML.Encode(P.Value));
                            }
                        }

                        sb.Append("'>");

                        this.bindingInterface.StreamHeader = sb.ToString();

                        sb.Clear();
                        sb.Append("</");
                        sb.Append(StreamPrefix);
                        sb.Append(":stream>");

                        this.bindingInterface.StreamFooter = sb.ToString();
                    }
                }
            }

            if (Xml != null)
            {
                return(this.RaiseOnReceived(Xml));
            }
            else
            {
                return(Task.FromResult <bool>(true));
            }
        }