예제 #1
0
        public bool OnRead(BaseSocket sock, byte[] buf, int offset, int length)
        {
            if (!m_running)
            {
                Debug.WriteLine("shutting down.  extra bytes received.");
                return false;
            }

            Debug.WriteLine("OnRead: " + ((HttpSocket)sock).Name);

            // Parse out the first start tag or empty element, which will be
            // <body/>.
            Kixeye.Xpnet.UTF8Encoding e = new Kixeye.Xpnet.UTF8Encoding();
            Kixeye.Xpnet.ContentToken ct = new Kixeye.Xpnet.ContentToken();
            Kixeye.Xpnet.TOK tok = e.tokenizeContent(buf, offset, offset + length, ct);

            if ((tok != Kixeye.Xpnet.TOK.START_TAG_WITH_ATTS) &&
                (tok != Kixeye.Xpnet.TOK.EMPTY_ELEMENT_WITH_ATTS))
            {
                m_listener.OnError(this, new ProtocolViolationException("Invalid HTTP binding XML.  Token type: " + tok.ToString()));
                return false;
            }

            string name = ENC.GetString(buf,
                                        offset + e.MinBytesPerChar,
                                        ct.NameEnd - offset - e.MinBytesPerChar);
            Debug.Assert(name == "body");
            Body b = new Body(m_doc);
            string val;
            int start;
            int end;
            for (int i = 0; i < ct.getAttributeSpecifiedCount(); i++)
            {
                start = ct.getAttributeNameStart(i);
                end = ct.getAttributeNameEnd(i);
                name = ENC.GetString(buf, start, end - start);

                start = ct.getAttributeValueStart(i);
                end = ct.getAttributeValueEnd(i);
                val = ENC.GetString(buf, start, end - start);

                if (!name.StartsWith("xmlns"))
                    b.SetAttribute(name, val);
            }

            if (b.SID != null)
                m_sid = b.SID;

            if (m_sid == null)
            {
                m_listener.OnError(this, new ProtocolViolationException("Invalid HTTP binding.  No SID."));
                return false;
            }

            if (b.Wait != -1)
                m_wait = b.Wait;

            if (StartStream)
            {
                StartStream = false;
                m_authID = b.AuthID;
                if (!FakeReceivedStream())
                    return false;
            }

            lock (m_queue)
            {
                if (!m_running)
                    return false;

                if (b.Type == BodyType.terminate)
                {
                    m_running = false;
                    Error err = new Error(m_doc);
                    err.AppendChild(m_doc.CreateElement(b.GetAttribute("condition"), URI.STREAM_ERROR));
                    byte[] sbuf = ENC.GetBytes(err.OuterXml);
                    m_listener.OnRead(this, sbuf, 0, sbuf.Length);
                    sbuf = ENC.GetBytes("</stream:stream>");
                    m_listener.OnRead(this, sbuf, 0, sbuf.Length);
                    Close();
                    return false;
                }
            }


            if (tok == Kixeye.Xpnet.TOK.START_TAG_WITH_ATTS)
            {
                // len(</body>) = 7
                start = ct.TokenEnd;
                if (m_listener.OnRead(this, buf, start, offset + length - start - 7))
                    RequestRead();
            }
            else
                RequestRead();

            lock (m_queue)
            {
                Monitor.Pulse(m_queue);
            }
            return true;
        }
예제 #2
0
        private Body CreateOpenBodyTag()
        {
            Body body = new Body(m_doc);

            if (m_rid == -1L)
            {
                Random rnd = new Random();
                long r = m_rid = (long)rnd.Next();
                body.Content = CONTENT_TYPE;
                
                body.To = m_hostid;
                body.Wait = m_wait;
                body.Hold = m_hold;
                body.Lang = m_lang;
                body.RID = r;
            }
            else
            {
                body.SID = m_sid;
            }
            
            return body;
        }