Ejemplo n.º 1
0
        public override BinaryCommandInfo FindCommandInfo(IAppSession session, byte[] readBuffer, int offset, int length, bool isReusableBuffer, out int left)
        {
            left = 0;

            int lastSegmentOffset   = BufferSegments.Count;
            int searchEndMarkLength = length;

            this.AddArraySegment(readBuffer, offset, length, isReusableBuffer);

            if (!m_FoundStart)
            {
                var pos = BufferSegments.SearchMark(lastSegmentOffset, length, m_StartMark);

                if (!pos.HasValue || pos.Value < 0)
                {
                    return(null);
                }

                //Found start mark
                m_StartPos   = pos.Value;
                m_FoundStart = true;

                lastSegmentOffset = pos.Value + 2;

                //The end mark could not exist in this round received data
                if (lastSegmentOffset + 2 > BufferSegments.Count)
                {
                    return(null);
                }

                searchEndMarkLength = BufferSegments.Count - lastSegmentOffset;
            }

            var endPos = BufferSegments.SearchMark(lastSegmentOffset, searchEndMarkLength, m_EndMark);

            //Haven't found end mark
            if (!endPos.HasValue || endPos.Value < 0)
            {
                return(null);
            }

            //Found end mark
            left = BufferSegments.Count - endPos.Value - 2;

            var commandData = BufferSegments.ToArrayData(m_StartPos, endPos.Value - m_StartPos + 2);
            var commandInfo = new BinaryCommandInfo(BitConverter.ToString(commandData, 15, 1), commandData);

            //Reset state
            m_FoundStart = false;
            m_StartPos   = -1;

            BufferSegments.ClearSegements();

            return(commandInfo);
        }
Ejemplo n.º 2
0
        public override WebSocketCommandInfo GetCommandInfo(byte[] readBuffer, int offset, int length, out int left)
        {
            left = 0;

            var prevMatched = m_HeadSeachState.Matched;

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

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

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

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

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

            BufferSegments.ClearSegements();

            if (!handshake.StartsWith(m_BadRequestPrefix, StringComparison.OrdinalIgnoreCase))
            {
                return(new WebSocketCommandInfo
                {
                    Key = OpCode.Handshake.ToString(),
                    Text = handshake
                });
            }
            else
            {
                return(new WebSocketCommandInfo
                {
                    Key = OpCode.BadRequest.ToString(),
                    Text = handshake
                });
            }
        }
        void Reset(bool clearBuffer)
        {
            m_Type       = null;
            m_Length     = null;
            m_TempLength = 0;

            if (clearBuffer)
            {
                BufferSegments.ClearSegements();
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Finds the command.
        /// "SEND 0008 xg^89W(v"
        /// Read 10 chars as command name and command data length
        /// </summary>
        /// <param name="session">The session.</param>
        /// <param name="readBuffer">The read buffer.</param>
        /// <param name="offset">The offset.</param>
        /// <param name="length">The length.</param>
        /// <param name="isReusableBuffer">if set to <c>true</c> [is reusable buffer].</param>
        /// <returns></returns>
        public override BinaryCommandInfo FindCommandInfo(IAppSession session, byte[] readBuffer, int offset, int length, bool isReusableBuffer, out int left)
        {
            left = 0;

            int leftLength = 10 - this.BufferSegments.Count;

            if (length < leftLength)
            {
                AddArraySegment(readBuffer, offset, length, isReusableBuffer);
                NextCommandReader = this;
                return(null);
            }

            AddArraySegment(readBuffer, offset, leftLength, isReusableBuffer);

            string commandName       = BufferSegments.Decode(Encoding.ASCII, 0, 4);
            int    commandDataLength = Convert.ToInt32(BufferSegments.Decode(Encoding.ASCII, 5, 4).TrimStart('0'));

            if (length > leftLength)
            {
                int leftDataLength = length - leftLength;
                if (leftDataLength >= commandDataLength)
                {
                    byte[] commandData = readBuffer.CloneRange(offset + leftLength, commandDataLength);
                    BufferSegments.ClearSegements();
                    NextCommandReader = this;
                    var commandInfo = new BinaryCommandInfo(commandName, commandData);

                    //The next commandInfo is comming
                    if (leftDataLength > commandDataLength)
                    {
                        left = leftDataLength - commandDataLength;
                    }

                    return(commandInfo);
                }
                else// if (leftDataLength < commandDataLength)
                {
                    //Clear previous cached header data
                    BufferSegments.ClearSegements();
                    //Save left data part
                    AddArraySegment(readBuffer, offset + leftLength, length - leftLength, isReusableBuffer);
                    NextCommandReader = GetMyCommandDataReader(commandName, commandDataLength);
                    return(null);
                }
            }
            else//length == leftLength
            {
                BufferSegments.ClearSegements();
                NextCommandReader = GetMyCommandDataReader(commandName, commandDataLength);
                return(null);
            }
        }
Ejemplo n.º 5
0
        public override BinaryRequestInfo Filter(IAppSession <BinaryRequestInfo> session, byte[] readBuffer, int offset, int length, bool toBeCopied, out int left)
        {
            left = 0;

            int leftLength = 6 - this.BufferSegments.Count;

            if (length < leftLength)
            {
                AddArraySegment(readBuffer, offset, length, toBeCopied);
                NextRequestFilter = this;
                return(null);
            }

            AddArraySegment(readBuffer, offset, leftLength, toBeCopied);

            string commandName = BufferSegments.Decode(Encoding.ASCII, 0, 4);

            int commandDataLength = (int)BufferSegments[4] * 256 + (int)BufferSegments[5];

            if (length > leftLength)
            {
                int leftDataLength = length - leftLength;
                if (leftDataLength >= commandDataLength)
                {
                    byte[] commandData = readBuffer.CloneRange(offset + leftLength, commandDataLength);
                    BufferSegments.ClearSegements();
                    NextRequestFilter = this;
                    var requestInfo = new BinaryRequestInfo(commandName, commandData);

                    //The next requestInfo is comming
                    if (leftDataLength > commandDataLength)
                    {
                        left = leftDataLength - commandDataLength;
                    }

                    return(requestInfo);
                }
                else// if (leftDataLength < commandDataLength)
                {
                    //Clear previous cached header data
                    BufferSegments.ClearSegements();
                    //Save left data part
                    AddArraySegment(readBuffer, offset + leftLength, length - leftLength, toBeCopied);
                    NextRequestFilter = GetMyCommandDataReader(commandName, commandDataLength);
                    return(null);
                }
            }
            else
            {
                NextRequestFilter = GetMyCommandDataReader(commandName, commandDataLength);
                return(null);
            }
        }
Ejemplo n.º 6
0
        public override BinaryCommandInfo FindCommandInfo(IAppSession session, byte[] readBuffer, int offset, int length, bool isReusableBuffer, out int left)
        {
            left = 0;


            this.AddArraySegment(readBuffer, offset, length, isReusableBuffer);

            if (length < 14)
            {
                BufferSegments.ClearSegements();
                return(null);
            }

            var commandData = BufferSegments.ToArrayData(0, length);

            BufferSegments.ClearSegements();

            return(new BinaryCommandInfo("WMDEVICE", commandData));
        }
Ejemplo n.º 7
0
        public override IWebSocketFragment Filter(byte[] readBuffer, int offset, int length, bool isReusableBuffer, out int rest)
        {
            var webSocketSession = Session;

            int total = BufferSegments.Count + length;

            if (total == SecKey3Len)
            {
                byte[] key = new byte[SecKey3Len];
                BufferSegments.CopyTo(key);
                Array.Copy(readBuffer, offset, key, BufferSegments.Count, length);
                webSocketSession.Items[WebSocketConstant.SecWebSocketKey3] = key;
                BufferSegments.ClearSegements();
                rest = 0;
                if (Handshake(webSocketSession.AppServer.WebSocketProtocolProcessor, webSocketSession))
                {
                    return(HandshakeRequestInfo);
                }
            }
            else if (total > SecKey3Len)
            {
                byte[] key = new byte[8];
                BufferSegments.CopyTo(key);
                Array.Copy(readBuffer, offset, key, BufferSegments.Count, SecKey3Len - BufferSegments.Count);
                webSocketSession.Items[WebSocketConstant.SecWebSocketKey3] = key;
                BufferSegments.ClearSegements();
                rest = total - SecKey3Len;
                if (Handshake(webSocketSession.AppServer.WebSocketProtocolProcessor, webSocketSession))
                {
                    return(HandshakeRequestInfo);
                }
            }
            else
            {
                AddArraySegment(readBuffer, offset, length, isReusableBuffer);
                rest = 0;
                NextReceiveFilter = this;
                return(null);
            }

            return(null);
        }
Ejemplo n.º 8
0
 /// <summary>
 /// Clears the buffer segments.
 /// </summary>
 protected void ClearBufferSegments()
 {
     BufferSegments.ClearSegements();
 }
        public override WebSocketCommandInfo GetCommandInfo(byte[] readBuffer, int offset, int length, out int left)
        {
            left = 0;

            // prevMatched is needed because handshake may have come
            // in a number of segments, and the HeaderTerminator that
            // we're looking for might lie across previous segments
            // and `readBuffer`.
            //
            // More precisely, prevMatched > 0 if and only if the last
            // byte(s) at end of the previous segment **started like**
            // an incomplete HeaderTerminator that **may or may not**
            // be continued and completed in current `readBuffer`.  --
            // fidergo-stephane-gourichon
            var prevMatched = m_HeadSeachState.Matched;

            // At this point in code **we don't know yet** if the
            // `prevMatched` bytes that match the `HeaderTerminator`
            // at end of previous segment are part of a **full match**
            // (in this case the value of `prevMatched` is useful) or
            // just a **partial** (in that cas the value of
            // `prevMatched` is irrelevant).

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

            if (result < 0)
            {
                // We've not found the HeaderTerminator yet.  We'll be
                // called again when more data arrives.  --
                // fidergo-stephane-gourichon
                AddArraySegment(readBuffer, offset, length);
                return(null);
            }

            // We've found the HeaderTerminator.  All might be in
            // readBuffer, or handshake might be cut across the last
            // segment, or just the HeaderTerminator might be in
            // readBuffer or even cut across.  We must handle all
            // those cases.  -- fidergo-stephane-gourichon

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

            if (this.BufferSegments.Count > 0)
            {
                if (findLen > 0)
                {
                    // In this code path we know that the handshake
                    // was cut across at least previous segments and
                    // `readBuffer`.  In other words,
                    // `readBuffer[offset]` starts with at least one
                    // byte that belongs to the handshake proper
                    // (excluding `HeaderTerminator`).  So, we add
                    // those bytes and extract the handshake.

                    this.AddArraySegment(readBuffer, offset, findLen);
                    handshake = this.BufferSegments.Decode(Encoding.UTF8);

                    // Now, we need to correct `prevMatched`.  Indeed,
                    // in this code path, any byte(s) matched at end
                    // of previous segment were not part of an actual
                    // HeaderTerminator cut across.  If
                    // `prevMatched`>0, such byte(s) was / were a
                    // partial match that `readBuffer` content
                    // disproved.
                    //
                    // So, basically, there were actually zero bytes
                    // of the actual `HeaderTerminator` match in
                    // previous segment.  We reflect that by setting
                    // prevMatched = 0. -- fidergo-stephane-gourichon

                    prevMatched = 0;

                    // If we did not set prevMatched to zero, `left`
                    // would be too big and our read pointer would not
                    // advance enough, causing desynchronization in WS
                    // protocol decoding, failure to recognize further
                    // messages, server closing connection for lack of
                    // reply to ping. -- fidergo-stephane-gourichon
                }
                else
                {
                    // The handshake was actually fully inside the
                    // previous segment.  That segment possibly ended
                    // with `prevMatch` bytes of the
                    // `HeaderTerminator` that we have to shave
                    // off. -- fidergo-stephane-gourichon

                    handshake = this.BufferSegments.Decode(Encoding.UTF8, 0, this.BufferSegments.Count - prevMatched);
                }
            }
            else
            {
                // In this code path, there was no previous segment.
                // Everything is in `readBuffer`.
                handshake = Encoding.UTF8.GetString(readBuffer, offset, findLen);
                // I'm nearly sure prevMatched is always zero already,
                // if reset between invocations (see below
                // `m_HeadSeachState.Matched = 0`).  I'm definitely
                // sure it should be zero here.  An assert would be
                // good.  As a fallback set it. --
                // fidergo-stephane-gourichon
                prevMatched = 0;
            }

            // We must tell caller how many bytes are left, with a
            // formula that works in all cases.
            // It works if prevMatched reflects actual match, not
            // partial match, as set to zero above. --
            // fidergo-stephane-gourichon

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

            // Rationale: left bytes are all bytes minus bytes
            // consumed.  We consume the part of the handshake that's
            // in `readBuffer`, which is `findLen` bytes.  We also
            // consume the part of the `HeaderTerminator` that is in
            // `readBuffer`, which is `(HeaderTerminator.Length -
            // prevMatched)` bytes.

            BufferSegments.ClearSegements();

            // In case the object is reused, reset search state.  I'm
            // nearly sure this is always zero already. An assert
            // would be good.  As a fallback set it. --
            // fidergo-stephane-gourichon

            m_HeadSeachState.Matched = 0;

            if (!handshake.StartsWith(m_BadRequestPrefix, StringComparison.OrdinalIgnoreCase))
            {
                return(new WebSocketCommandInfo
                {
                    Key = OpCode.Handshake.ToString(),
                    Text = handshake
                });
            }
            else
            {
                return(new WebSocketCommandInfo
                {
                    Key = OpCode.BadRequest.ToString(),
                    Text = handshake
                });
            }
        }