public override IWebSocketFragment Filter(IAppSession <IWebSocketFragment> session, byte[] readBuffer, int offset, int length, bool isReusableBuffer, out int left)
        {
            left = 0;

            var skipByteCount = 0;

            if (!m_Type.HasValue)
            {
                byte startByte = readBuffer[offset];
                skipByteCount = 1;
                m_Type        = startByte;
            }

            //0xxxxxxx: Collect protocol data by end mark
            if ((m_Type.Value & 0x80) == 0x00)
            {
                byte lookForByte = 0xFF;

                int i;

                for (i = offset + skipByteCount; i < offset + length; i++)
                {
                    if (readBuffer[i] == lookForByte)
                    {
                        left = length - (i - offset + 1);

                        if (BufferSegments.Count <= 0)
                        {
                            var commandInfo = new PlainFragment(Encoding.UTF8.GetString(readBuffer, offset + skipByteCount, i - offset - skipByteCount));
                            Reset();
                            return(commandInfo);
                        }
                        else
                        {
                            AddArraySegment(readBuffer, offset + skipByteCount, i - offset - skipByteCount, false);
                            var commandInfo = new PlainFragment(BufferSegments.Decode(Encoding.UTF8));
                            Reset();
                            return(commandInfo);
                        }
                    }
                }

                AddArraySegment(readBuffer, offset + skipByteCount, length - skipByteCount, isReusableBuffer);
                return(null);
            }
            else//10000000: Collect protocol data by length
            {
                while (!m_Length.HasValue)
                {
                    if (length <= skipByteCount)
                    {
                        //No data to read
                        return(null);
                    }

                    byte lengthByte = readBuffer[skipByteCount];
                    //Closing handshake
                    if (lengthByte == 0x00 && m_Type.Value == m_ClosingHandshakeType)
                    {
                        session.Close(CloseReason.ClientClosing);
                        return(null);
                    }

                    int thisLength = (int)(lengthByte & 0x7F);
                    m_TempLength = m_TempLength * 128 + thisLength;
                    skipByteCount++;

                    if ((lengthByte & 0x80) != 0x80)
                    {
                        m_Length = m_TempLength;
                        break;
                    }
                }

                int requiredSize = m_Length.Value - BufferSegments.Count;

                int leftSize = length - skipByteCount;

                if (leftSize < requiredSize)
                {
                    AddArraySegment(readBuffer, skipByteCount, length - skipByteCount, isReusableBuffer);
                    return(null);
                }
                else
                {
                    left = leftSize - requiredSize;

                    if (BufferSegments.Count <= 0)
                    {
                        var commandInfo = new PlainFragment(Encoding.UTF8.GetString(readBuffer, offset + skipByteCount, requiredSize));
                        Reset();
                        return(commandInfo);
                    }
                    else
                    {
                        AddArraySegment(readBuffer, offset + skipByteCount, requiredSize, false);
                        var commandInfo = new PlainFragment(BufferSegments.Decode(Encoding.UTF8));
                        Reset();
                        return(commandInfo);
                    }
                }
            }
        }
        public override IWebSocketFragment Filter(IAppSession session, byte[] readBuffer, int offset, int length, bool isReusableBuffer, out int left)
        {
            left = 0;

            int prevMatched = m_SearchState.Matched;

            var result = readBuffer.SearchMark(offset, length, m_SearchState);

            if (result < 0)
            {
                this.AddArraySegment(readBuffer, offset, length, isReusableBuffer);
                return null;
            }

            int findLen = result - offset;
            string header = string.Empty;

            if (this.BufferSegments.Count > 0)
            {
                if (findLen > 0)
                {
                    this.AddArraySegment(readBuffer, offset, findLen, false);
                    header = this.BufferSegments.Decode(Encoding.UTF8);
                }
                else
                {
                    header = this.BufferSegments.Decode(Encoding.UTF8, 0, this.BufferSegments.Count - prevMatched);
                }
            }
            else
            {
                header = Encoding.UTF8.GetString(readBuffer, offset, findLen);
            }

            var webSocketSession = session as IWebSocketSession;

            try
            {
                WebSocketServer.ParseHandshake(webSocketSession, new StringReader(header));
            }
            catch (Exception e)
            {
                session.Logger.Error("Failed to parse handshake!" + Environment.NewLine + header, e);
                session.Close(CloseReason.ProtocolError);
                return null;
            }

            var secWebSocketKey1 = webSocketSession.Items.GetValue<string>(WebSocketConstant.SecWebSocketKey1, string.Empty);
            var secWebSocketKey2 = webSocketSession.Items.GetValue<string>(WebSocketConstant.SecWebSocketKey2, string.Empty);
            var secWebSocketVersion = webSocketSession.SecWebSocketVersion;

            left = length - findLen - (m_HeaderTerminator.Length - prevMatched);

            this.ClearBufferSegments();

            if (string.IsNullOrEmpty(secWebSocketKey1) && string.IsNullOrEmpty(secWebSocketKey2))
            {
                //draft-hixie-thewebsocketprotocol-75
                if(Handshake(webSocketSession.AppServer.WebSocketProtocolProcessor, webSocketSession))
                    return HandshakeRequestInfo;
            }
            else if ("6".Equals(secWebSocketVersion)) //draft-ietf-hybi-thewebsocketprotocol-06
            {
                if(Handshake(webSocketSession.AppServer.WebSocketProtocolProcessor, webSocketSession))
                    return HandshakeRequestInfo;
            }
            else
            {
                //draft-hixie-thewebsocketprotocol-76/draft-ietf-hybi-thewebsocketprotocol-00
                //Read SecWebSocketKey3(8 bytes)
                if (left == SecKey3Len)
                {
                    webSocketSession.Items[WebSocketConstant.SecWebSocketKey3] = readBuffer.CloneRange(offset + length - left, left);
                    left = 0;
                    if(Handshake(webSocketSession.AppServer.WebSocketProtocolProcessor, webSocketSession))
                        return HandshakeRequestInfo;
                }
                else if (left > SecKey3Len)
                {
                    webSocketSession.Items[WebSocketConstant.SecWebSocketKey3] = readBuffer.CloneRange(offset + length - left, 8);
                    left -= 8;
                    if(Handshake(webSocketSession.AppServer.WebSocketProtocolProcessor, webSocketSession))
                        return HandshakeRequestInfo;
                }
                else
                {
                    //left < 8
                    if (left > 0)
                    {
                        AddArraySegment(readBuffer, offset + length - left, left, isReusableBuffer);
                        left = 0;
                    }

                    NextRequestFilter = new WebSocketSecKey3RequestFilter(this);
                    return null;
                }
            }

            return null;
        }
        public override IWebSocketFragment FindCommandInfo(IAppSession session, byte[] readBuffer, int offset, int length, bool isReusableBuffer, out int left)
        {
            left = 0;

            int prevMatched = m_SearchState.Matched;

            var result = readBuffer.SearchMark(offset, length, m_SearchState);

            if (result < 0)
            {
                this.AddArraySegment(readBuffer, offset, length, isReusableBuffer);
                return(null);
            }

            int    findLen = result - offset;
            string header  = string.Empty;

            if (this.BufferSegments.Count > 0)
            {
                if (findLen > 0)
                {
                    this.AddArraySegment(readBuffer, offset, findLen, false);
                    header = this.BufferSegments.Decode(Encoding.UTF8);
                }
                else
                {
                    header = this.BufferSegments.Decode(Encoding.UTF8, 0, this.BufferSegments.Count - prevMatched);
                }
            }
            else
            {
                header = Encoding.UTF8.GetString(readBuffer, offset, findLen);
            }

            var webSocketSession = session as IWebSocketSession;

            try
            {
                WebSocketServer.ParseHandshake(webSocketSession, new StringReader(header));
            }
            catch (Exception e)
            {
                session.Logger.LogError("Failed to parse handshake!" + Environment.NewLine + header, e);
                session.Close(CloseReason.Unknown);
                return(null);
            }

            var secWebSocketKey1    = webSocketSession.Items.GetValue <string>(WebSocketConstant.SecWebSocketKey1, string.Empty);
            var secWebSocketKey2    = webSocketSession.Items.GetValue <string>(WebSocketConstant.SecWebSocketKey2, string.Empty);
            var secWebSocketVersion = webSocketSession.SecWebSocketVersion;

            left = length - findLen - (m_HeaderTerminator.Length - prevMatched);

            this.ClearBufferSegments();

            if (string.IsNullOrEmpty(secWebSocketKey1) && string.IsNullOrEmpty(secWebSocketKey2))
            {
                //draft-hixie-thewebsocketprotocol-75
                if (Handshake(webSocketSession.AppServer.WebSocketProtocolProcessor, webSocketSession))
                {
                    return(HandshakeCommandInfo);
                }
            }
            else if ("6".Equals(secWebSocketVersion)) //draft-ietf-hybi-thewebsocketprotocol-06
            {
                if (Handshake(webSocketSession.AppServer.WebSocketProtocolProcessor, webSocketSession))
                {
                    return(HandshakeCommandInfo);
                }
            }
            else
            {
                //draft-hixie-thewebsocketprotocol-76/draft-ietf-hybi-thewebsocketprotocol-00
                //Read SecWebSocketKey3(8 bytes)
                if (left == SecKey3Len)
                {
                    webSocketSession.Items[WebSocketConstant.SecWebSocketKey3] = readBuffer.CloneRange(offset + length - left, left);
                    left = 0;
                    if (Handshake(webSocketSession.AppServer.WebSocketProtocolProcessor, webSocketSession))
                    {
                        return(HandshakeCommandInfo);
                    }
                }
                else if (left > SecKey3Len)
                {
                    webSocketSession.Items[WebSocketConstant.SecWebSocketKey3] = readBuffer.CloneRange(offset + length - left, 8);
                    left -= 8;
                    if (Handshake(webSocketSession.AppServer.WebSocketProtocolProcessor, webSocketSession))
                    {
                        return(HandshakeCommandInfo);
                    }
                }
                else
                {
                    //left < 8
                    if (left > 0)
                    {
                        AddArraySegment(readBuffer, offset + length - left, left, isReusableBuffer);
                        left = 0;
                    }

                    NextCommandReader = new WebSocketSecKey3Reader(this);
                    return(null);
                }
            }

            return(null);
        }
예제 #4
0
        public override IWebSocketFragment FindCommandInfo(IAppSession session, byte[] readBuffer, int offset, int length, bool isReusableBuffer, out int left)
        {
            left = 0;

            var skipByteCount = 0;

            if (!m_Type.HasValue)
            {
                byte startByte = readBuffer[offset];
                skipByteCount = 1;
                m_Type = startByte;
            }

            //0xxxxxxx: Collect protocol data by end mark
            if ((m_Type.Value & 0x80) == 0x00)
            {
                byte lookForByte = 0xFF;

                int i;

                for (i = offset + skipByteCount; i < offset + length; i++)
                {
                    if (readBuffer[i] == lookForByte)
                    {
                        left = length - (i - offset + 1);

                        if (BufferSegments.Count <= 0)
                        {
                            var commandInfo = new PlainFragment(Encoding.UTF8.GetString(readBuffer, offset + skipByteCount, i - offset - skipByteCount));
                            Reset();
                            return commandInfo;
                        }
                        else
                        {
                            AddArraySegment(readBuffer, offset + skipByteCount, i - offset - skipByteCount, false);
                            var commandInfo = new PlainFragment(BufferSegments.Decode(Encoding.UTF8));
                            Reset();
                            return commandInfo;
                        }
                    }
                }

                AddArraySegment(readBuffer, offset + skipByteCount, length - skipByteCount, isReusableBuffer);
                return null;
            }
            else//10000000: Collect protocol data by length
            {
                while (!m_Length.HasValue)
                {
                    if (length <= skipByteCount)
                    {
                        //No data to read
                        return null;
                    }

                    byte lengthByte = readBuffer[skipByteCount];
                    //Closing handshake
                    if (lengthByte == 0x00 && m_Type.Value == m_ClosingHandshakeType)
                    {
                        session.Close(CloseReason.ClientClosing);
                        return null;
                    }

                    int thisLength = (int)(lengthByte & 0x7F);
                    m_TempLength = m_TempLength * 128 + thisLength;
                    skipByteCount++;

                    if ((lengthByte & 0x80) != 0x80)
                    {
                        m_Length = m_TempLength;
                        break;
                    }
                }

                int requiredSize = m_Length.Value - BufferSegments.Count;

                int leftSize = length - skipByteCount;

                if (leftSize < requiredSize)
                {
                    AddArraySegment(readBuffer, skipByteCount, length - skipByteCount, isReusableBuffer);
                    return null;
                }
                else
                {
                    left = leftSize - requiredSize;

                    if (BufferSegments.Count <= 0)
                    {
                        var commandInfo = new PlainFragment(Encoding.UTF8.GetString(readBuffer, offset + skipByteCount, requiredSize));
                        Reset();
                        return commandInfo;
                    }
                    else
                    {
                        AddArraySegment(readBuffer, offset + skipByteCount, requiredSize, false);
                        var commandInfo = new PlainFragment(BufferSegments.Decode(Encoding.UTF8));
                        Reset();
                        return commandInfo;
                    }
                }
            }
        }