/// <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> /// 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); }
/// <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); }
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), });
/// <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); }
/// <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); }
/// <summary>获取未调整的长度 /// </summary> protected long GetUnadjustedFrameLength(IByteBuffer buffer, int offset) { return(buffer.GetLong(offset)); }
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; }
public long GetLong(int index) { CheckIndex(index, 8); return(_buffer.GetLong(index)); }
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; } }
public static double GetDouble(this IByteBuffer buf, int index) => BitConverter.Int64BitsToDouble(buf.GetLong(index));