Exemplo n.º 1
0
        /// <summary>
        ///  Returns {@code true} if and only if the two specified buffers are
        ///  identical to each other for {@code length} bytes starting at {@code aStartIndex}
        ///  index for the {@code a} buffer and {@code bStartIndex} index for the {@code b} buffer.
        ///  A more compact way to express this is:
        ///  <p>
        ///  {@code a[aStartIndex : aStartIndex + length] == b[bStartIndex : bStartIndex + length]}
        /// </summary>
        public static bool Equals(IByteBuffer a, int aStartIndex, IByteBuffer b, int bStartIndex, int length)
        {
            if (aStartIndex < 0 || bStartIndex < 0 || length < 0)
            {
                throw new ArgumentException("All indexes and lengths must be non-negative");
            }
            if (a.WriterIndex - length < aStartIndex || b.WriterIndex - length < bStartIndex)
            {
                return(false);
            }

            int longCount = unchecked ((int)((uint)length >> 3));
            int byteCount = length & 7;

            if (a.Order == b.Order)
            {
                for (int i = longCount; i > 0; i--)
                {
                    if (a.GetLong(aStartIndex) != b.GetLong(bStartIndex))
                    {
                        return(false);
                    }
                    aStartIndex += 8;
                    bStartIndex += 8;
                }
            }
            else
            {
                for (int i = longCount; i > 0; i--)
                {
                    if (a.GetLong(aStartIndex) != SwapLong(b.GetLong(bStartIndex)))
                    {
                        return(false);
                    }
                    aStartIndex += 8;
                    bStartIndex += 8;
                }
            }

            for (int i = byteCount; i > 0; i--)
            {
                if (a.GetByte(aStartIndex) != b.GetByte(bStartIndex))
                {
                    return(false);
                }
                aStartIndex++;
                bStartIndex++;
            }

            return(true);
        }
Exemplo n.º 2
0
        /// <summary>
        ///  Returns {@code true} if and only if the two specified buffers are
        ///  identical to each other for {@code length} bytes starting at {@code aStartIndex}
        ///  index for the {@code a} buffer and {@code bStartIndex} index for the {@code b} buffer.
        ///  A more compact way to express this is:
        ///  <p>
        ///  {@code a[aStartIndex : aStartIndex + length] == b[bStartIndex : bStartIndex + length]}
        /// </summary>
        public static bool Equals(IByteBuffer a, int aStartIndex, IByteBuffer b, int bStartIndex, int length)
        {
            if (aStartIndex < 0 || bStartIndex < 0 || length < 0)
            {
                throw new ArgumentException("All indexes and lengths must be non-negative");
            }
            if (a.WriterIndex - length < aStartIndex || b.WriterIndex - length < bStartIndex)
            {
                return false;
            }

            int longCount = unchecked((int)((uint)length >> 3));
            int byteCount = length & 7;

            if (a.Order == b.Order)
            {
                for (int i = longCount; i > 0; i --)
                {
                    if (a.GetLong(aStartIndex) != b.GetLong(bStartIndex))
                    {
                        return false;
                    }
                    aStartIndex += 8;
                    bStartIndex += 8;
                }
            }
            else
            {
                for (int i = longCount; i > 0; i --)
                {
                    if (a.GetLong(aStartIndex) != SwapLong(b.GetLong(bStartIndex)))
                    {
                        return false;
                    }
                    aStartIndex += 8;
                    bStartIndex += 8;
                }
            }

            for (int i = byteCount; i > 0; i --)
            {
                if (a.GetByte(aStartIndex) != b.GetByte(bStartIndex))
                {
                    return false;
                }
                aStartIndex ++;
                bStartIndex ++;
            }

            return true;
        }
        /// <summary>
        ///     Decodes the specified region of the buffer into an unadjusted frame length.  The default implementation is
        ///     capable of decoding the specified region into an unsigned 8/16/24/32/64 bit integer.  Override this method to
        ///     decode the length field encoded differently.
        ///     Note that this method must not modify the state of the specified buffer (e.g.
        ///     <see cref="IByteBuffer.ReaderIndex" />,
        ///     <see cref="IByteBuffer.WriterIndex" />, and the content of the buffer.)
        /// </summary>
        /// <param name="buffer">The buffer we'll be extracting the frame length from.</param>
        /// <param name="offset">The offset from the absolute <see cref="IByteBuffer.ReaderIndex" />.</param>
        /// <param name="length">The length of the framelenght field. Expected: 1, 2, 3, 4, or 8.</param>
        /// <param name="order">The preferred <see cref="ByteOrder" /> of buffer.</param>
        /// <returns>A long integer that represents the unadjusted length of the next frame.</returns>
        protected virtual long GetUnadjustedFrameLength(IByteBuffer buffer, int offset, int length, ByteOrder order)
        {
            long frameLength;

            switch (length)
            {
            case 1:
                frameLength = buffer.GetByte(offset);
                break;

            case 2:
                frameLength = order == ByteOrder.BigEndian ? buffer.GetUnsignedShort(offset) : buffer.GetUnsignedShortLE(offset);
                break;

            case 3:
                frameLength = order == ByteOrder.BigEndian ? buffer.GetUnsignedMedium(offset) : buffer.GetUnsignedMediumLE(offset);
                break;

            case 4:
                frameLength = order == ByteOrder.BigEndian ? buffer.GetInt(offset) : buffer.GetIntLE(offset);
                break;

            case 8:
                frameLength = order == ByteOrder.BigEndian ? buffer.GetLong(offset) : buffer.GetLongLE(offset);
                break;

            default:
                throw new DecoderException("unsupported lengthFieldLength: " + this.lengthFieldLength + " (expected: 1, 2, 3, 4, or 8)");
            }
            return(frameLength);
        }
Exemplo n.º 4
0
        /// <summary>
        ///     Decodes the specified region of the buffer into an unadjusted frame length.  The default implementation is
        ///     capable of decoding the specified region into an unsigned 8/16/24/32/64 bit integer.  Override this method to
        ///     decode the length field encoded differently.
        ///     Note that this method must not modify the state of the specified buffer (e.g.
        ///     <see cref="IByteBuffer.ReaderIndex" />,
        ///     <see cref="IByteBuffer.WriterIndex" />, and the content of the buffer.)
        /// </summary>
        /// <param name="buffer">The buffer we'll be extracting the frame length from.</param>
        /// <param name="offset">The offset from the absolute <see cref="IByteBuffer.ReaderIndex" />.</param>
        /// <param name="length">The length of the framelenght field. Expected: 1, 2, 3, 4, or 8.</param>
        /// <param name="order">The preferred <see cref="ByteOrder" /> of <see cref="buffer" />.</param>
        /// <returns>A long integer that represents the unadjusted length of the next frame.</returns>
        protected long GetUnadjustedFrameLength(IByteBuffer buffer, int offset, int length, ByteOrder order)
        {
            buffer = buffer.WithOrder(order);
            long frameLength;

            switch (length)
            {
            case 1:
                frameLength = buffer.GetByte(offset);
                break;

            case 2:
                frameLength = buffer.GetShort(offset);
                break;

            case 4:
                frameLength = buffer.GetInt(offset);
                break;

            case 8:
                frameLength = buffer.GetLong(offset);
                break;

            default:
                throw new DecoderException("unsupported lengthFieldLength: " + this.lengthFieldLength + " (expected: 1, 2, 3, 4, or 8)");
            }
            return(frameLength);
        }
Exemplo n.º 5
0
        private static bool EqualsSlow(IByteBuffer a, int aStartIndex, IByteBuffer b, int bStartIndex, int length)
        {
            int longCount = unchecked ((int)((uint)length >> 3));
            int byteCount = length & 7;

            for (int i = longCount; i > 0; i--)
            {
                if (a.GetLong(aStartIndex) != b.GetLong(bStartIndex))
                {
                    return(false);
                }
                aStartIndex += 8;
                bStartIndex += 8;
            }

            for (int i = byteCount; i > 0; i--)
            {
                if (a.GetByte(aStartIndex) != b.GetByte(bStartIndex))
                {
                    return(false);
                }
                aStartIndex++;
                bStartIndex++;
            }

            return(true);
        }
 /// <summary>
 ///     Decodes the specified region of the buffer into an unadjusted frame length.  The default implementation is
 ///     capable of decoding the specified region into an unsigned 8/16/24/32/64 bit integer.  Override this method to
 ///     decode the length field encoded differently.
 ///     Note that this method must not modify the state of the specified buffer (e.g.
 ///     <see cref="IByteBuffer.ReaderIndex" />,
 ///     <see cref="IByteBuffer.WriterIndex" />, and the content of the buffer.)
 /// </summary>
 /// <param name="buffer">The buffer we'll be extracting the frame length from.</param>
 /// <param name="offset">The offset from the absolute <see cref="IByteBuffer.ReaderIndex" />.</param>
 /// <param name="length">The length of the framelenght field. Expected: 1, 2, 3, 4, or 8.</param>
 /// <returns>A long integer that represents the unadjusted length of the next frame.</returns>
 protected static long GetUnadjustedFrameLength(IByteBuffer buffer, int offset, int length)
 {
     return(length switch
     {
         1 => buffer.GetByte(offset),
         2 => buffer.GetUnsignedShort(offset),
         3 => buffer.GetUnsignedMedium(offset),
         4 => buffer.GetInt(offset),
         8 => buffer.GetLong(offset),
         _ => CThrowHelper.ThrowDecoderException(length),
     });
Exemplo n.º 7
0
        /// <summary>
        ///     Decodes the specified region of the buffer into an unadjusted frame length.  The default implementation is
        ///     capable of decoding the specified region into an unsigned 8/16/24/32/64 bit integer.  Override this method to
        ///     decode the length field encoded differently.
        ///     Note that this method must not modify the state of the specified buffer (e.g.
        ///     <see cref="IByteBuffer.ReaderIndex" />,
        ///     <see cref="IByteBuffer.WriterIndex" />, and the content of the buffer.)
        /// </summary>
        /// <param name="buffer">The buffer we'll be extracting the frame length from.</param>
        /// <param name="offset">The offset from the absolute <see cref="IByteBuffer.ReaderIndex" />.</param>
        /// <param name="length">The length of the framelenght field. Expected: 1, 2, 3, 4, or 8.</param>
        /// <param name="order">The preferred <see cref="ByteOrder" /> of buffer.</param>
        /// <returns>A long integer that represents the unadjusted length of the next frame.</returns>
        protected long GetUnadjustedFrameLength(IByteBuffer buffer, int offset, int length, ByteOrder order)
        {
            long frameLength;

            switch (length)
            {
            case 1:
                frameLength = buffer.GetByte(offset);
                break;

            case 2:
                frameLength = order == ByteOrder.BigEndian ? buffer.GetUnsignedShort(offset) : buffer.GetUnsignedShortLE(offset);
                break;

            case 3:
                frameLength = order == ByteOrder.BigEndian ? buffer.GetUnsignedMedium(offset) : buffer.GetUnsignedMediumLE(offset);
                break;

            case 4:
                frameLength = order == ByteOrder.BigEndian ? buffer.GetInt(offset) : buffer.GetIntLE(offset);
                break;

            case 8:
                frameLength = order == ByteOrder.BigEndian ? buffer.GetLong(offset) : buffer.GetLongLE(offset);
                break;

            default:
                throw new DecoderException("unsupported lengthFieldLength: " + this.lengthFieldLength + " (expected: 1, 2, 3, 4, or 8)");
            }
            byte[] bytes = BitConverter.GetBytes(frameLength);

            string slength = Encoding.UTF8.GetString(bytes);

            frameLength = long.Parse(slength);

            return(frameLength);
        }
Exemplo n.º 8
0
        /// <summary>
        ///     Create a frame out of the <see cref="IByteBuffer" /> and return it.
        /// </summary>
        /// <param name="context">
        ///     The <see cref="IChannelHandlerContext" /> which this <see cref="ByteToMessageDecoder" /> belongs
        ///     to.
        /// </param>
        /// <param name="input">The <see cref="IByteBuffer" /> from which to read data.</param>
        /// <returns>The <see cref="IByteBuffer" /> which represents the frame or <c>null</c> if no frame could be created.</returns>
        protected virtual object Decode(IChannelHandlerContext context, IByteBuffer input)
        {
            var transportContext = _getContextAction();

            var package = new ReceivedPackage()
            {
                IsComplete     = false,
                IsOutputStream = transportContext.IsOutputStream,
                OutputFilePath = transportContext.OutputFilePath
            };

            if (transportContext.IsOutputStream)
            {
                if (!_foundHeader)
                {
                    //未读取到头部,并且长度不足头部
                    if (input.ReadableBytes < lengthFieldEndOffset)
                    {
                        return(null);
                    }
                    //整个数据包的长度,应该是包长度+2+body
                    long frameLength = input.GetLong(input.ReaderIndex) + lengthFieldEndOffset;

                    int frameLengthInt = (int)frameLength;
                    if (input.ReadableBytes < frameLengthInt)
                    {
                        //读取全部的数据
                        var         readLength = input.ReadableBytes;
                        IByteBuffer frame      = this.ExtractFrame(context, input, input.ReaderIndex, readLength);
                        input.SetReaderIndex(input.ReaderIndex + readLength);

                        _length  = frame.ReadLong();
                        _command = frame.ReadByte();
                        _status  = frame.ReadByte();

                        package.Length  = _length;
                        package.Command = _command;
                        package.Status  = _status;

                        var bodyLength = readLength - lengthFieldEndOffset;

                        package.Body = new byte[bodyLength];
                        frame.ReadBytes(package.Body, 0, package.Body.Length);

                        //设置读取的进度
                        _readPosition += bodyLength;

                        _foundHeader = true;
                    }
                    else
                    {
                        //全部读完,则直接完成
                        // extract frame
                        int         readerIndex = input.ReaderIndex;
                        IByteBuffer frame       = ExtractFrame(context, input, readerIndex, frameLengthInt);
                        input.SetReaderIndex(readerIndex + frameLengthInt);

                        package.Length  = frame.ReadLong();
                        package.Command = frame.ReadByte();
                        package.Status  = frame.ReadByte();

                        package.Body = new byte[package.Length];
                        frame.ReadBytes(package.Body, 0, (int)package.Length);

                        //重置
                        Reset();

                        package.IsComplete = true;
                    }
                }
                else
                {
                    //不是第一次读

                    package.Length  = _length;
                    package.Command = _command;
                    package.Status  = _status;

                    //未读的长度
                    var unreadLength = _length - _readPosition;
                    //需要写的长度,剩余长度与当前接收包体两者取小值
                    var         chunkSize = Math.Min(unreadLength, input.ReadableBytes);
                    IByteBuffer frame     = this.ExtractFrame(context, input, input.ReaderIndex, (int)chunkSize);
                    //设置读的标记,读到头为止
                    input.SetReaderIndex(input.ReaderIndex + (int)chunkSize);

                    package.Body = new byte[chunkSize];
                    frame.ReadBytes(package.Body, 0, (int)chunkSize);

                    //判断是否完成
                    if (_readPosition + chunkSize >= _length)
                    {
                        //完成
                        Reset();

                        package.IsComplete = true;
                    }
                    else
                    {
                        //设置读取进度
                        _readPosition += chunkSize;
                    }
                }
            }
            else
            {
                //读取不到头部
                if (input.ReadableBytes < lengthFieldEndOffset)
                {
                    return(null);
                }
                //整个数据包的长度,应该是包长度+2+body
                long frameLength    = input.GetLong(input.ReaderIndex) + lengthFieldEndOffset;
                int  frameLengthInt = (int)frameLength;
                if (input.ReadableBytes < frameLengthInt)
                {
                    return(null);
                }
                // extract frame
                int         readerIndex = input.ReaderIndex;
                IByteBuffer frame       = ExtractFrame(context, input, readerIndex, frameLengthInt);
                input.SetReaderIndex(readerIndex + frameLengthInt);

                package.Length  = frame.ReadLong();
                package.Command = frame.ReadByte();
                package.Status  = frame.ReadByte();

                package.Body = new byte[package.Length];
                frame.ReadBytes(package.Body, 0, (int)package.Length);

                //重置
                Reset();

                package.IsComplete = true;
            }

            return(package);
        }
Exemplo n.º 9
0
 /// <summary>获取未调整的长度
 /// </summary>
 protected long GetUnadjustedFrameLength(IByteBuffer buffer, int offset)
 {
     return(buffer.GetLong(offset));
 }
Exemplo n.º 10
0
 public virtual long GetLong(int index) => Buf.GetLong(index);
 /// <summary>
 ///     Decodes the specified region of the buffer into an unadjusted frame length.  The default implementation is
 ///     capable of decoding the specified region into an unsigned 8/16/24/32/64 bit integer.  Override this method to
 ///     decode the length field encoded differently.
 ///     Note that this method must not modify the state of the specified buffer (e.g.
 ///     <see cref="IByteBuffer.ReaderIndex" />,
 ///     <see cref="IByteBuffer.WriterIndex" />, and the content of the buffer.)
 /// </summary>
 /// <param name="buffer">The buffer we'll be extracting the frame length from.</param>
 /// <param name="offset">The offset from the absolute <see cref="IByteBuffer.ReaderIndex" />.</param>
 /// <param name="length">The length of the framelenght field. Expected: 1, 2, 3, 4, or 8.</param>
 /// <param name="order">The preferred <see cref="ByteOrder" /> of <see cref="buffer" />.</param>
 /// <returns>A long integer that represents the unadjusted length of the next frame.</returns>
 protected long GetUnadjustedFrameLength(IByteBuffer buffer, int offset, int length, ByteOrder order)
 {
     buffer = buffer.WithOrder(order);
     long frameLength;
     switch (length)
     {
         case 1:
             frameLength = buffer.GetByte(offset);
             break;
         case 2:
             frameLength = buffer.GetShort(offset);
             break;
         case 4:
             frameLength = buffer.GetInt(offset);
             break;
         case 8:
             frameLength = buffer.GetLong(offset);
             break;
         default:
             throw new DecoderException("unsupported lengthFieldLength: " + this.lengthFieldLength + " (expected: 1, 2, 3, 4, or 8)");
     }
     return frameLength;
 }
Exemplo n.º 12
0
 public long GetLong(int index)
 {
     CheckIndex(index, 8);
     return(_buffer.GetLong(index));
 }
Exemplo n.º 13
0
        public override void ChannelRead(IChannelHandlerContext context, object message)
        {
            while (true)
            {
                if (_isWebSocket)
                {
                    IByteBuffer buffer;
                    _lastReadBuffer?.ResetReaderIndex();
                    if (_lastReadBuffer != null && _lastReadBuffer.ReadableBytes != 0)
                    {
                        buffer = ByteBufferUtil.DefaultAllocator.HeapBuffer(
                            _lastReadBuffer.ReadableBytes + ((IByteBuffer)message).ReadableBytes);
                        buffer.WriteBytes(_lastReadBuffer);
                        buffer.WriteBytes((IByteBuffer)message);
                        _lastReadBuffer = buffer;
                    }
                    else
                    {
                        buffer          = (IByteBuffer)message;
                        _lastReadBuffer = buffer;
                    }

                    if (buffer.ReadableBytes < 2)
                    {
                        return;
                    }

                    IByteBuffer bufferCopy = ByteBufferUtil.DefaultAllocator.HeapBuffer(buffer.Capacity);
                    buffer.ReadBytes(bufferCopy, 2);
                    if ((bufferCopy.GetByte(0) & 8) == 8)
                    {
                        //操作码位8表示断开连接
                        context.CloseAsync();

                        return;
                    }

                    byte[] maskKey = { 0, 0, 0, 0 };
                    bool   masked  = false;
                    byte   lenMark = bufferCopy.GetByte(1);
                    if (lenMark >= 128)
                    {
                        masked   = true;
                        lenMark -= 128;
                    }

                    int offset = 0;
                    int len    = 0;
                    if (lenMark <= 125)
                    {
                        offset = 2;
                        len    = lenMark;
                    }
                    else if (lenMark == 126)
                    {
                        offset = 4;

                        if (buffer.ReadableBytes < 2)
                        {
                            return;
                        }

                        buffer.ReadBytes(bufferCopy, 2);
                        len = bufferCopy.GetUnsignedShort(2);
                    }
                    else if (lenMark == 127)
                    {
                        offset = 10;

                        if (buffer.ReadableBytes < 8)
                        {
                            return;
                        }

                        buffer.ReadBytes(bufferCopy, 8);
                        len = (int)bufferCopy.GetLong(2);
                    }

                    if (masked)
                    {
                        if (buffer.ReadableBytes < 4)
                        {
                            return;
                        }

                        buffer.ReadBytes(bufferCopy, 4);
                        for (int i = 0; i < 4; i++)
                        {
                            maskKey[i] = bufferCopy.GetByte(offset + i);
                        }

                        offset += 4;
                    }

                    if (buffer.ReadableBytes < len)
                    {
                        return;
                    }

                    buffer.ReadBytes(bufferCopy, len);
                    IByteBuffer output = ByteBufferUtil.DefaultAllocator.HeapBuffer(len);
                    for (int i = 0; i < len; i++)
                    {
                        output.WriteByte(bufferCopy.GetByte(offset + i) ^ maskKey[i % 4]);
                    }

                    _lastReadBuffer.MarkReaderIndex();
                    base.ChannelRead(context, output);

                    if (_lastReadBuffer.ReadableBytes <= 0)
                    {
                        return;
                    }

                    _lastReadBuffer = null;
                    message         = buffer;

                    continue;
                }

                try
                {
                    var         buffer     = (IByteBuffer)message;
                    IByteBuffer bufferCopy = buffer.Copy();
                    var         bytes      = new byte[bufferCopy.ReadableBytes];
                    bufferCopy.ReadBytes(bytes);
                    string       data = Encoding.ASCII.GetString(bytes);
                    const string requestWebSocketMark = "Sec-WebSocket-Key:";
                    int          index = data.IndexOf(requestWebSocketMark, StringComparison.Ordinal);
                    if (index < 0)
                    {
                        throw new Exception();
                    }

                    data = data.Substring(index + requestWebSocketMark.Length + 1);
                    var key = new StringBuilder();
                    foreach (char t in data)
                    {
                        if (IsBase64Char(t))
                        {
                            key.Append(t);
                        }
                        else
                        {
                            break;
                        }
                    }

                    key.Append("258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
                    SHA1 sha1 = new SHA1CryptoServiceProvider();
                    data = Convert.ToBase64String(sha1.ComputeHash(Encoding.UTF8.GetBytes(key.ToString())));
                    sha1.Dispose();
                    StringBuilder ret = new StringBuilder();
                    ret.Append("HTTP/1.1 101 Switching Protocols\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: ");
                    ret.Append(data);
                    ret.Append("\r\nUpgrade: websocket\r\n\r\n");
                    IByteBuffer output = ByteBufferUtil.DefaultAllocator.HeapBuffer();
                    output.WriteBytes(Encoding.UTF8.GetBytes(ret.ToString()));
                    context.WriteAndFlushAsync(output);

                    _isWebSocket = true;
                }
                catch
                {
                    base.ChannelRead(context, message);
                }
                finally
                {
                    if (_isWebSocket)
                    {
                        context.Channel.Pipeline.Remove <LengthFieldBasedFrameDecoder>();
                        context.Channel.Pipeline.Remove <LengthFieldPrepender>();
                    }
                    else
                    {
                        context.Channel.Pipeline.Remove(this);
                    }
                }

                break;
            }
        }
Exemplo n.º 14
0
 public static double GetDouble(this IByteBuffer buf, int index) => BitConverter.Int64BitsToDouble(buf.GetLong(index));