Beispiel #1
0
        public void Encode(string name, string value, byte[] buffer, ref int offset, ref int bytesAvailableInBuffer)
        {
            if (name == null)
            {
                throw new ArgumentNullException(nameof(name));
            }
            var header = GetIndexedHeader(name, value);

            if (header != null && header.Name.Length >= _maxDynamicTableSize)
            {
                header = null;
            }

            if (header != null && header.Value.Equals(value))
            {
                var flagOffset = offset;
                IntegerCodec.Encode(7, header.IndexPosition, buffer, ref offset, ref bytesAvailableInBuffer);
                buffer[flagOffset] += 128;
                return;
            }

            //Literal Header Field with Incremental Indexing — New Name
            if (header == null)
            {
                buffer[offset++]        = 64;
                bytesAvailableInBuffer -= 1;
                _dynamicTable.Append(name, value);
                EncodeLiteral(name, buffer, ref offset, ref bytesAvailableInBuffer);
            }
            else
            {
                var flagOffset = offset;
                IntegerCodec.Encode(6, header.IndexPosition, buffer, ref offset, ref bytesAvailableInBuffer);
                buffer[flagOffset] += 64;
            }

            EncodeLiteral(value, buffer, ref offset, ref bytesAvailableInBuffer);
        }
Beispiel #2
0
        public void Decode(byte[] buffer, ref int offset, ref int count)
        {
            while (count > 0)
            {
                _headerEventArgs.IsIndexingAllowed = true;

                // 6.1 Indexed Header Field Representation
                if ((buffer[offset] & 128) == 128)
                {
                    var index = buffer[offset] & ~128;
                    if (index == 0)
                    {
                        throw new DecoderException(Http2ErrorCode.ProtocolError, "HPACK, Indexed header 0 is not allowed.");
                    }
                    ++offset;
                    --count;

                    AssignIndexedHeaderToEventArgs(index);
                }

                // 6.2.1 Literal Header Field
                else if ((buffer[offset] & 64) == 64)
                {
                    var index = buffer[offset] & ~64;
                    ++offset;
                    --count;

                    // Header name is in the static or dynamic table
                    if (index > 0)
                    {
                        AssignIndexedHeaderToEventArgs(index);
                    }
                    else
                    {
                        _headerEventArgs.Name = ReadStringLiteral(buffer, ref offset, ref count);
                    }

                    _headerEventArgs.Value = ReadStringLiteral(buffer, ref offset, ref count);

                    // A literal header field with incremental indexing representation results in appending a
                    // header field to the decoded header list and inserting it as a new entry into the dynamic table
                    _dynamicTable.Append(_headerEventArgs.Name, _headerEventArgs.Value);
                }

                // 6.2.2 Literal Header Field without Indexing
                else if ((buffer[offset] & 240) == 0)
                {
                    var index = buffer[offset] & ~240;
                    ++offset;
                    --count;

                    // Header name is in the static or dynamic table
                    if (index > 0)
                    {
                        AssignIndexedHeaderToEventArgs(index);
                    }
                    else
                    {
                        _headerEventArgs.Name = ReadStringLiteral(buffer, ref offset, ref count);
                    }

                    _headerEventArgs.Value = ReadStringLiteral(buffer, ref offset, ref count);
                }

                // 6.2.3 Literal Header Field Never Indexed
                else if ((buffer[offset] & 240) == 16)
                {
                    var index = buffer[offset] & ~240;
                    ++offset;
                    --count;

                    // Header name is in the static or dynamic table
                    if (index > 0)
                    {
                        AssignIndexedHeaderToEventArgs(index);
                    }
                    else
                    {
                        _headerEventArgs.Name = ReadStringLiteral(buffer, ref offset, ref count);
                    }

                    _headerEventArgs.Value             = ReadStringLiteral(buffer, ref offset, ref count);
                    _headerEventArgs.IsIndexingAllowed = false;
                }

                // 6.3 Dynamic Table Size Update
                else if ((buffer[offset] & 224) == 32)
                {
                    var maxSize = buffer[offset] & ~224;
                    ++offset;
                    --count;

                    if (DynamicTableSizeReceived != null)
                    {
                        DynamicTableSizeReceived(this, new DynamicTableSizeReceivedEventArgs(maxSize));
                    }
                    return;
                }

                if (HeaderDecoded != null)
                {
                    HeaderDecoded(this, _headerEventArgs);
                }
            }
        }