예제 #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="sock"></param>
        public virtual void OnConnect(BaseSocket sock)
        {
            if (m_ssl)
            {
#if !NO_SSL
                m_sock.StartTLS();
#else
                throw new NotImplementedException("SSL not compiled in");
#endif
            }
            m_listener.OnConnect(sock);
        }
예제 #2
0
        void ISocketEventListener.OnError(BaseSocket sock, Exception ex)
        {
            if (Interlocked.Increment(ref m_errorCount) > m_maxErrors)
            {
                m_keepRunning = false;
                m_listener.OnError(null, ex);
            }

            lock (m_lock)
            {
                Monitor.Pulse(m_lock);
            }
        }
예제 #3
0
        void ISocketEventListener.OnConnect(BaseSocket sock)
        {
            lock (m_queue)
            {
                if (!m_running &&
                    (m_sockA != null) && m_sockA.Connected &&
                    (m_sockB != null) && m_sockB.Connected)
                {
                    m_running  = true;
                    m_lastSock = m_sockB;

                    m_thread = new Thread(ProcessThread);
                    m_thread.IsBackground = true;
                    m_thread.Name         = "XEP 124 processing thread";
                    m_thread.Start();

                    m_listener.OnConnect(this);
                }
            }
        }
예제 #4
0
 /// <summary>
 /// An error happened in processing.  The socket is no longer open.
 /// </summary>
 /// <param name="sock">Socket in error</param>
 /// <param name="ec">Exception that caused the error</param>
 public virtual void OnError(BaseSocket sock, System.Exception ec)
 {
 }
예제 #5
0
 /// <summary>
 /// Outbound connection was connected.
 /// </summary>
 /// <param name="sock">Connected socket.</param>
 public virtual void OnConnect(BaseSocket sock)
 {
 }
예제 #6
0
 /// <summary>
 /// Connection was closed.
 /// </summary>
 /// <param name="sock">Closed socket.  Already closed!</param>
 public virtual void OnClose(BaseSocket sock)
 {
 }
예제 #7
0
 void ISocketEventListener.OnWrite(BaseSocket sock, byte[] buf, int offset, int length)
 {
     m_listener.OnWrite(this, buf, offset, length);
 }
예제 #8
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="newSock"></param>
 /// <returns></returns>
 public virtual ISocketEventListener GetListener(BaseSocket newSock)
 {
     return(m_listener.GetListener(newSock));
 }
예제 #9
0
 bool ISocketEventListener.OnAccept(BaseSocket newsocket)
 {
     throw new Exception("The method or operation is not implemented.");
 }
예제 #10
0
 void ISocketEventListener.OnClose(BaseSocket sock)
 {
     throw new Exception("The method or operation is not implemented.");
 }
예제 #11
0
 /// <summary>
 /// Bytes were read from the socket.
 /// </summary>
 /// <param name="sock">The socket that was read from.</param>
 /// <param name="buf">The bytes that were read.</param>
 /// <returns>true if RequestRead() should be called automatically again</returns>
 /// <param name="offset">Offset into the buffer to start at</param>
 /// <param name="length">Number of bytes to use out of the buffer</param>
 public virtual bool OnRead(BaseSocket sock, byte[] buf, int offset, int length)
 {
     return(true);
 }
예제 #12
0
 void ISocketEventListener.OnInit(BaseSocket newSock)
 {
     m_listener.OnInit(newSock);
 }
예제 #13
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="sock"></param>
 /// <param name="buf"></param>
 /// <param name="offset"></param>
 /// <param name="length"></param>
 public virtual void OnWrite(BaseSocket sock, byte[] buf, int offset, int length)
 {
     m_listener.OnWrite(sock, buf, offset, length);
 }
예제 #14
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="sock"></param>
 /// <param name="buf"></param>
 /// <param name="offset"></param>
 /// <param name="length"></param>
 /// <returns></returns>
 public virtual bool OnRead(BaseSocket sock, byte[] buf, int offset, int length)
 {
     return(m_listener.OnRead(sock, buf, offset, length));
 }
예제 #15
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="sock"></param>
 /// <param name="ex"></param>
 public virtual void OnError(BaseSocket sock, System.Exception ex)
 {
     m_listener.OnError(sock, ex);
 }
예제 #16
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="sock"></param>
 public virtual void OnClose(BaseSocket sock)
 {
     m_listener.OnClose(sock);
 }
예제 #17
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="newsocket"></param>
 /// <returns></returns>
 public virtual bool OnAccept(BaseSocket newsocket)
 {
     return(m_listener.OnAccept(newsocket));
 }
예제 #18
0
 /// <summary>
 /// Bytes were written to the socket.
 /// </summary>
 /// <param name="sock">The socket that was written to.</param>
 /// <param name="buf">The bytes that were written.</param>
 /// <param name="offset">Offset into the buffer to start at</param>
 /// <param name="length">Number of bytes to use out of the buffer</param>
 public virtual void OnWrite(BaseSocket sock, byte[] buf, int offset, int length)
 {
 }
예제 #19
0
        bool ISocketEventListener.OnRead(BaseSocket sock, byte[] buf, int offset, int length)
        {
            Debug.WriteLine("IN HTTP(" + m_name + "): " + ENC.GetString(buf, offset, length));
            int    i      = offset;
            string header = null;
            int    last   = offset + length;

            while (i < last)
            {
                // HTTP/1.1 200 OK
                // Header: value
                // Header: value
                //
                // Content
                switch (m_state)
                {
                case ParseState.START:
                    if (!ParseAt(buf, ref i, last, HTTP11_SP, 0))
                    {
                        goto ERROR;
                    }
                    m_state = ParseState.RESPONSE;
                    break;

                case ParseState.RESPONSE:
                    string code = ParseTo(buf, ref i, last, SPACE);
                    if (code == null)
                    {
                        goto ERROR;
                    }

                    if (code != "200")
                    {
                        Debug.WriteLine("Non-OK response from server (" + code + ").  STOP!");
                        goto ERROR;
                    }

                    try
                    {
                        // I know this can never fail.  it's here for when we
                        // implement redirects and the like.
                        m_current.Code = int.Parse(code);
                    }
                    catch (Exception)
                    {
                        Debug.WriteLine("invalid response code");
                        goto ERROR;
                    }

                    m_state = ParseState.RESPONSE_TEXT;
                    break;

                case ParseState.RESPONSE_TEXT:
                    m_current.ResponseText = ParseTo(buf, ref i, last, CRLF);
                    if (m_current.ResponseText == null)
                    {
                        goto ERROR;
                    }
                    m_state = ParseState.HEADER_NAME;
                    break;

                case ParseState.HEADER_NAME:
                    if (ParseAt(buf, ref i, last, CRLF, 0))
                    {
                        m_state = ParseState.BODY_START;
                        break;
                    }
                    header = ParseTo(buf, ref i, last, COL_SP);
                    if (header == null)
                    {
                        goto ERROR;
                    }
                    m_state = ParseState.HEADER_VALUE;
                    break;

                case ParseState.HEADER_VALUE:
                    string val = ParseTo(buf, ref i, last, CRLF);
                    if (val == null)
                    {
                        goto ERROR;
                    }
                    m_current.Headers.Add(header, val);
                    m_state = ParseState.HEADER_NAME;
                    break;

                case ParseState.BODY_START:
                    // if we have the whole response, which is typical in XEP-124, then return it all at
                    // once, without creating a MemoryStream.
                    int len = m_current.ContentLength;
                    if (len == -1)
                    {
                        goto ERROR;
                    }
                    if (i + len <= last)
                    {
                        Done();
                        if (!m_listener.OnRead(this, buf, i, len) || !m_keepRunning)
                        {
                            Close();
                            return(false);
                        }
                        return(false);
                    }

                    // We got a partial response.  We're going to have to wait until OnRead is called
                    // again before we can pass a full response upstream.  Hold on to the pieces in a
                    // MemoryStream.
                    m_current.Response = new MemoryStream(len);
                    m_current.Response.Write(buf, i, last - i);
                    m_state = ParseState.BODY_CONTINUE;
                    return(true);

                case ParseState.BODY_CONTINUE:
                    m_current.Response.Write(buf, i, last - i);
                    if (m_current.Response.Length == m_current.Response.Capacity)
                    {
                        PendingRequest req = m_current;
                        Done();

                        byte[] resp = req.Response.ToArray();
                        if (!m_listener.OnRead(this, resp, 0, resp.Length) || !m_keepRunning)
                        {
                            Close();
                            return(false);
                        }

                        return(false);
                    }
                    return(true);

                default:
                    break;
                }
            }
            return(true);

ERROR:
            m_listener.OnError(null, new ProtocolViolationException("Error parsing HTTP response"));
            Close();
            return(false);
        }
예제 #20
0
 ISocketEventListener ISocketEventListener.GetListener(BaseSocket newSock)
 {
     throw new Exception("The method or operation is not implemented.");
 }
예제 #21
0
 bool ISocketEventListener.OnInvalidCertificate(BaseSocket sock, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
 {
     // TODO: pass up the chain
     return(m_listener.OnInvalidCertificate(null, certificate, chain, sslPolicyErrors));
 }
예제 #22
0
 /// <summary>
 /// An accept socket is about to be bound, or a connect socket is about to connect,
 /// or an incoming socket just came in.  Use this as an opportunity to
 /// </summary>
 /// <param name="newSock">The new socket that is about to be connected.</param>
 public virtual void OnInit(BaseSocket newSock)
 {
 }
예제 #23
0
 /// <summary>
 /// We accepted a socket, and need to get a listener.
 /// If the return value is null, then the socket will be closed,
 /// and RequestAccept will ALWAYS be called.
 /// </summary>
 /// <param name="newSock">The new socket.</param>
 /// <returns>The listener for the *new* socket, as compared to
 /// the listener for the *listen* socket</returns>
 public virtual ISocketEventListener GetListener(BaseSocket newSock)
 {
     return(this);
 }
예제 #24
0
        bool ISocketEventListener.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/>.
            xpnet.UTF8Encoding e   = new xpnet.UTF8Encoding();
            xpnet.ContentToken ct  = new xpnet.ContentToken();
            xpnet.TOK          tok = e.tokenizeContent(buf, offset, offset + length, ct);

            if ((tok != xpnet.TOK.START_TAG_WITH_ATTS) &&
                (tok != 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 == 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);
        }
예제 #25
0
 /// <summary>
 /// A new incoming connection was accepted.
 /// </summary>
 /// <param name="newsocket">Socket for new connection.</param>
 /// <returns>true if RequestAccept() should be called automatically again</returns>
 public virtual bool OnAccept(BaseSocket newsocket)
 {
     return(true);
 }
예제 #26
0
 bool ISocketEventListener.OnInvalidCertificate(BaseSocket sock, X509Certificate certificate, X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
 {
     return(m_listener.OnInvalidCertificate(this, certificate, chain, sslPolicyErrors));
 }
예제 #27
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="newSock"></param>
 public virtual void OnInit(BaseSocket newSock)
 {
     m_listener.OnInit(newSock);
 }