private static void FailOnFrameLengthLessThanLengthFieldEndOffset(IByteBuffer input,
                                                                   long frameLength,
                                                                   int lengthFieldEndOffset)
 {
     _ = input.SkipBytes(lengthFieldEndOffset);
     CThrowHelper.ThrowCorruptedFrameException_LengthFieldEndOffset(frameLength, lengthFieldEndOffset);
 }
예제 #2
0
        public DefaultHeaders(IHashingStrategy <TKey> nameHashingStrategy,
                              IValueConverter <TValue> valueConverter, INameValidator <TKey> nameValidator, int arraySizeHint)
        {
            if (nameHashingStrategy is null)
            {
                CThrowHelper.ThrowArgumentNullException(CExceptionArgument.nameHashingStrategy);
            }
            if (valueConverter is null)
            {
                CThrowHelper.ThrowArgumentNullException(CExceptionArgument.valueConverter);
            }
            if (nameValidator is null)
            {
                CThrowHelper.ThrowArgumentNullException(CExceptionArgument.nameValidator);
            }

            _hashingStrategy = nameHashingStrategy;
            ValueConverter   = valueConverter;
            _nameValidator   = nameValidator;

            // Enforce a bound of [2, 128] because hashMask is a byte. The max possible value of hashMask is one less
            // than the length of this array, and we want the mask to be > 0.
            _entries  = new HeaderEntry <TKey, TValue> [FindNextPositivePowerOfTwo(Math.Max(2, Math.Min(arraySizeHint, 128)))];
            _hashMask = (byte)(_entries.Length - 1);
            _head     = new HeaderEntry <TKey, TValue>();
        }
예제 #3
0
        public bool TryGet(TKey name, out TValue value)
        {
            if (name is null)
            {
                CThrowHelper.ThrowArgumentNullException(CExceptionArgument.name);
            }

            bool found = false;
            int  h     = _hashingStrategy.HashCode(name);
            int  i     = Index(h);
            HeaderEntry <TKey, TValue> e = _entries[i];

            value = default;
            // loop until the first header was found
            while (e is object)
            {
                if (e.Hash == h && _hashingStrategy.Equals(name, e._key))
                {
                    value = e._value;
                    found = true;
                }

                e = e.Next;
            }
            return(found);
        }
예제 #4
0
        /// <summary>Common constructor</summary>
        /// <param name="maxFrameLength">
        ///     The maximum length of the decoded frame
        ///     NOTE: A see <see cref="DotNetty.Codecs.TooLongFrameException" /> is thrown if the length of the frame exceeds this
        ///     value.
        /// </param>
        /// <param name="stripDelimiter">whether the decoded frame should strip out the delimiter or not</param>
        /// <param name="failFast">
        ///     If true, a <see cref="DotNetty.Codecs.TooLongFrameException" /> is
        ///     thrown as soon as the decoder notices the length of the
        ///     frame will exceed<tt>maxFrameLength</tt> regardless of
        ///     whether the entire frame has been read.
        ///     If false, a <see cref="DotNetty.Codecs.TooLongFrameException" /> is
        ///     thrown after the entire frame that exceeds maxFrameLength has been read.
        /// </param>
        /// <param name="delimiters">delimiters</param>
        public DelimiterBasedFrameDecoder(int maxFrameLength, bool stripDelimiter, bool failFast, params IByteBuffer[] delimiters)
        {
            ValidateMaxFrameLength(maxFrameLength);
            if (delimiters is null)
            {
                CThrowHelper.ThrowNullReferenceException(CExceptionArgument.delimiters);
            }

            if (0u >= (uint)delimiters.Length)
            {
                CThrowHelper.ThrowArgumentException_EmptyDelimiters();
            }

            if (IsLineBased(delimiters) && !IsSubclass())
            {
                _lineBasedDecoder = new LineBasedFrameDecoder(maxFrameLength, stripDelimiter, failFast);
                _delimiters       = null;
            }
            else
            {
                _delimiters = new IByteBuffer[delimiters.Length];
                for (int i = 0; i < delimiters.Length; i++)
                {
                    IByteBuffer d = delimiters[i];
                    ValidateDelimiter(d);
                    _delimiters[i] = d.Slice(d.ReaderIndex, d.ReadableBytes);
                }
                _lineBasedDecoder = null;
            }
            _maxFrameLength = maxFrameLength;
            _stripDelimiter = stripDelimiter;
            _failFast       = failFast;
        }
 private static void FailOnFrameLengthLessThanInitialBytesToStrip(IByteBuffer input,
                                                                  int frameLength,
                                                                  int initialBytesToStrip)
 {
     _ = input.SkipBytes(frameLength);
     CThrowHelper.ThrowCorruptedFrameException_InitialBytesToStrip(frameLength, initialBytesToStrip);
 }
예제 #6
0
 static void ValidateMaxFrameLength(int maxFrameLength)
 {
     if ((uint)(maxFrameLength - 1) > SharedConstants.TooBigOrNegative) // <= 0
     {
         CThrowHelper.ThrowArgumentException_MaxFrameLengthMustBe(maxFrameLength);
     }
 }
예제 #7
0
 public void ValidateName(T name)
 {
     if (name is null)
     {
         CThrowHelper.ThrowArgumentNullException(CExceptionArgument.name);
     }
 }
예제 #8
0
 static void ValidateMaxContentLength(int maxContentLength)
 {
     if ((uint)maxContentLength > SharedConstants.TooBigOrNegative) // < 0
     {
         CThrowHelper.ThrowArgumentException_MaxContentLength(maxContentLength);
     }
 }
예제 #9
0
 protected DecoderResult(Exception cause)
 {
     if (cause is null)
     {
         CThrowHelper.ThrowArgumentNullException(CExceptionArgument.cause);
     }
     this.cause = cause;
 }
예제 #10
0
 public static DecoderResult Failure(Exception cause)
 {
     if (cause is null)
     {
         CThrowHelper.ThrowArgumentNullException(CExceptionArgument.cause);
     }
     return(new DecoderResult(cause));
 }
예제 #11
0
 protected ByteToMessageDecoder()
 {
     // ReSharper disable once DoNotCallOverridableMethodsInConstructor -- used for safety check only
     if (IsSharable)
     {
         CThrowHelper.ThrowInvalidOperationException_ByteToMessageDecoder();
     }
 }
예제 #12
0
 /// <summary>
 /// Set the number of reads after which <see cref="IByteBuffer.DiscardSomeReadBytes"/> are called and so free up memory.
 /// The default is <code>16</code>.
 /// </summary>
 /// <param name="discardAfterReads"></param>
 public void SetDiscardAfterReads(int discardAfterReads)
 {
     if ((uint)(discardAfterReads - 1) > SharedConstants.TooBigOrNegative) // <= 0
     {
         CThrowHelper.ThrowArgumentException_DiscardAfterReads();
     }
     _discardAfterReads = discardAfterReads;
 }
예제 #13
0
        /// <summary>
        /// Allocate a <see cref="IByteBuffer"/> which will be used as argument of <see cref="Encode(IChannelHandlerContext, T, IByteBuffer)"/>.
        /// Sub-classes may override this method to return <see cref="IByteBuffer"/> with a perfect matching <c>initialCapacity</c>.
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        protected virtual IByteBuffer AllocateBuffer(IChannelHandlerContext context)
        {
            if (context is null)
            {
                CThrowHelper.ThrowArgumentNullException(CExceptionArgument.context);
            }

            return(context.Allocator.Buffer());
        }
예제 #14
0
        public virtual IHeaders <TKey, TValue> AddObject(TKey name, object value)
        {
            if (value is null)
            {
                CThrowHelper.ThrowArgumentNullException(CExceptionArgument.value);
            }

            return(Add(name, ValueConverter.ConvertObject(value)));
        }
예제 #15
0
        public bool ContainsObject(TKey name, object value)
        {
            if (value is null)
            {
                CThrowHelper.ThrowArgumentNullException(CExceptionArgument.value);
            }

            return(Contains(name, ValueConverter.ConvertObject(value)));
        }
예제 #16
0
 public virtual void Remove()
 {
     if (_isReadonly)
     {
         CThrowHelper.ThrowNotSupportedException_Readonly();
     }
     Before.After = After;
     After.Before = Before;
 }
예제 #17
0
 public virtual IHeaders <TKey, TValue> Add(IHeaders <TKey, TValue> headers)
 {
     if (ReferenceEquals(headers, this))
     {
         CThrowHelper.ThrowArgumentException_CannotAddToItSelf();
     }
     AddImpl(headers);
     return(this);
 }
예제 #18
0
        /// <inheritdoc />
        protected internal override void Encode(IChannelHandlerContext context, IByteBuffer message, List <object> output)
        {
            int length         = message.ReadableBytes + this.lengthAdjustment;
            var lengthFieldLen = this.lengthFieldLength;

            if (this.lengthFieldIncludesLengthFieldLength)
            {
                length += lengthFieldLen;
            }

            uint nlen = unchecked ((uint)length);

            if (nlen > SharedConstants.TooBigOrNegative)
            {
                CThrowHelper.ThrowArgumentException_LessThanZero(length);
            }

            switch (lengthFieldLen)
            {
            case 1:
                if (nlen >= 256u)
                {
                    CThrowHelper.ThrowArgumentException_Byte(length);
                }
                output.Add(context.Allocator.Buffer(1).WriteByte((byte)length));
                break;

            case 2:
                if (nlen >= 65536u)
                {
                    CThrowHelper.ThrowArgumentException_Short(length);
                }
                output.Add(context.Allocator.Buffer(2).WriteShort((short)length));
                break;

            case 3:
                if (nlen >= 16777216u)
                {
                    CThrowHelper.ThrowArgumentException_Medium(length);
                }
                output.Add(context.Allocator.Buffer(3).WriteMedium(length));
                break;

            case 4:
                output.Add(context.Allocator.Buffer(4).WriteInt(length));
                break;

            case 8:
                output.Add(context.Allocator.Buffer(8).WriteLong(length));
                break;

            default:
                CThrowHelper.ThrowException_UnknownLen(); break;
            }

            output.Add(message.Retain());
        }
예제 #19
0
        /// <summary>
        ///     Initializes a new instance of the <see cref="StringDecoder" /> class with the specified character
        ///     set..
        /// </summary>
        /// <param name="encoding">Encoding.</param>
        public StringDecoder(Encoding encoding)
        {
            if (encoding is null)
            {
                CThrowHelper.ThrowNullReferenceException(CExceptionArgument.encoding);
            }

            _encoding = encoding;
        }
예제 #20
0
        /// <summary>
        /// Set the <see cref="ICumulator"/> to use for cumulate the received <see cref="IByteBuffer"/>s.
        /// </summary>
        /// <param name="cumulator"></param>
        public void SetCumulator(ICumulator cumulator)
        {
            if (cumulator is null)
            {
                CThrowHelper.ThrowArgumentNullException(CExceptionArgument.cumulator);
            }

            _cumulator = cumulator;
        }
예제 #21
0
        /// <summary>
        /// Create an encoder that encodes the content in <see cref="IAddressedEnvelope{T}"/> to <see cref="DatagramPacket"/> using
        /// the specified message encoder.
        /// </summary>
        /// <param name="encoder">the specified message encoder</param>
        public DatagramPacketEncoder(MessageToMessageEncoder <T> encoder)
        {
            if (encoder is null)
            {
                CThrowHelper.ThrowArgumentNullException(CExceptionArgument.encoder);
            }

            this.encoder = encoder;
        }
예제 #22
0
        /// <summary>
        /// Create a <see cref="DatagramPacket"/> decoder using the specified <see cref="IByteBuffer"/> decoder.
        /// </summary>
        /// <param name="decoder">the specified <see cref="IByteBuffer"/> decoder</param>
        public DatagramPacketDecoder(MessageToMessageDecoder <IByteBuffer> decoder)
        {
            if (decoder is null)
            {
                CThrowHelper.ThrowArgumentNullException(CExceptionArgument.decoder);
            }

            this.decoder = decoder;
        }
예제 #23
0
        public long ConvertToTimeMillis(ICharSequence value)
        {
            DateTime?dateTime = DateFormatter.ParseHttpDate(value);

            if (dateTime is null)
            {
                CThrowHelper.ThrowFormatException(value);
            }
            return(dateTime.Value.Ticks / TimeSpan.TicksPerMillisecond);
        }
예제 #24
0
        public bool TryGetAndRemove(TKey name, out TValue value)
        {
            if (name is null)
            {
                CThrowHelper.ThrowArgumentNullException(CExceptionArgument.name);
            }

            int h = _hashingStrategy.HashCode(name);

            return(TryRemove0(h, Index(h), name, out value));
        }
 /// <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),
     });
예제 #26
0
        public virtual IHeaders <TKey, TValue> SetObject(TKey name, object value)
        {
            if (value is null)
            {
                CThrowHelper.ThrowArgumentNullException(CExceptionArgument.value);
            }

            TValue convertedValue = ValueConverter.ConvertObject(value);

            return(Set(name, convertedValue));
        }
예제 #27
0
        /// <inheritdoc />
        public override void Write(IChannelHandlerContext context, object message, IPromise promise)
        {
            if (context is null)
            {
                CThrowHelper.ThrowArgumentNullException(CExceptionArgument.context);
            }

            IByteBuffer buffer = null;

            try
            {
                if (this.AcceptOutboundMessage(message))
                {
                    var input = (T)message;
                    buffer = this.AllocateBuffer(context);
                    try
                    {
                        this.Encode(context, input, buffer);
                    }
                    finally
                    {
                        _ = ReferenceCountUtil.Release(input);
                    }

                    if (buffer.IsReadable())
                    {
                        _ = context.WriteAsync(buffer, promise);
                    }
                    else
                    {
                        _ = buffer.Release();
                        _ = context.WriteAsync(Unpooled.Empty, promise);
                    }

                    buffer = null;
                }
                else
                {
                    _ = context.WriteAsync(message, promise);
                }
            }
            catch (EncoderException)
            {
                throw;
            }
            catch (Exception ex)
            {
                CThrowHelper.ThrowEncoderException(ex);
            }
            finally
            {
                _ = (buffer?.Release());
            }
        }
예제 #28
0
 void Fail(long frameLength)
 {
     if (frameLength > 0)
     {
         CThrowHelper.ThrowTooLongFrameException(_maxFrameLength, frameLength);
     }
     else
     {
         CThrowHelper.ThrowTooLongFrameException(_maxFrameLength);
     }
 }
예제 #29
0
        static void ValidateDelimiter(IByteBuffer delimiter)
        {
            if (delimiter is null)
            {
                CThrowHelper.ThrowNullReferenceException(CExceptionArgument.delimiter);
            }

            if (!delimiter.IsReadable())
            {
                CThrowHelper.ThrowArgumentException_EmptyDelimiter();
            }
        }
예제 #30
0
        /// <inheritdoc />
        public override void ChannelRead(IChannelHandlerContext context, object message)
        {
            if (message is IByteBuffer data)
            {
                ThreadLocalObjectList output = ThreadLocalObjectList.NewInstance();
                try
                {
                    _first      = _cumulation is null;
                    _cumulation = _cumulator.Cumulate(context.Allocator, _first ? Unpooled.Empty : _cumulation, data);
                    CallDecode(context, _cumulation, output);
                }
                catch (DecoderException)
                {
                    throw;
                }
                catch (Exception ex)
                {
                    CThrowHelper.ThrowDecoderException(ex);
                }
                finally
                {
                    try
                    {
                        if (_cumulation is object && !_cumulation.IsReadable())
                        {
                            _numReads   = 0;
                            _           = _cumulation.Release();
                            _cumulation = null;
                        }
                        else if (++_numReads >= _discardAfterReads)
                        {
                            // We did enough reads already try to discard some bytes so we not risk to see a OOME.
                            // See https://github.com/netty/netty/issues/4275
                            _numReads = 0;
                            DiscardSomeReadBytes();
                        }

                        int size = output.Count;
                        _firedChannelRead |= (uint)size > 0u;
                        FireChannelRead(context, output, size);
                    }
                    finally
                    {
                        output.Return();
                    }
                }
            }
            else
            {
                _ = context.FireChannelRead(message);
            }
        }