示例#1
0
        /// <summary>
        /// create a map of header name to index value to allow quick lookup
        /// </summary>
        /// <returns>The map.</returns>
        private static Dictionary <string, int> CreateMap()
        {
            int length = STATIC_TABLE.Count;
            var ret    = new Dictionary <string, int>(length);

            // Iterate through the static table in reverse order to
            // save the smallest index for a given name in the map.
            for (int index = length; index > 0; index--)
            {
                HeaderField entry = GetEntry(index);
                string      name  = Encoding.UTF8.GetString(entry.Name);
                ret[name] = index;
            }
            return(ret);
        }
示例#2
0
        /// <summary>
        /// Remove and return the oldest header field from the dynamic table.
        /// </summary>
        public HeaderField Remove()
        {
            HeaderField removed = headerFields[tail];

            if (removed == null)
            {
                return(null);
            }
            size -= removed.Size;
            headerFields[tail++] = null;
            if (tail == headerFields.Length)
            {
                tail = 0;
            }
            return(removed);
        }
示例#3
0
 private void IndexHeader(int index, AddHeaderDelegate addHeaderDelegate)
 {
     if (index <= StaticTable.Length)
     {
         HeaderField headerField = StaticTable.GetEntry(index);
         this.AddHeader(addHeaderDelegate, headerField.Name, headerField.Value, false);
     }
     else if (index - StaticTable.Length <= this.dynamicTable.Length())
     {
         HeaderField headerField = this.dynamicTable.GetEntry(index - StaticTable.Length);
         this.AddHeader(addHeaderDelegate, headerField.Name, headerField.Value, false);
     }
     else
     {
         throw new IOException("illegal index value (" + index + ")");
     }
 }
示例#4
0
 private void ReadName(int index)
 {
     if (index <= StaticTable.Length)
     {
         HeaderField headerField = StaticTable.GetEntry(index);
         name = headerField.Name;
     }
     else if (index - StaticTable.Length <= this.dynamicTable.Length())
     {
         HeaderField headerField = this.dynamicTable.GetEntry(index - StaticTable.Length);
         name = headerField.Name;
     }
     else
     {
         throw new IOException("illegal index value (" + index + ")");
     }
 }
示例#5
0
        /// <summary>
        /// Add the header field to the dynamic table.
        /// Entries are evicted from the dynamic table until the size of the table
        /// and the new header field is less than or equal to the table's capacity.
        /// If the size of the new entry is larger than the table's capacity,
        /// the dynamic table will be cleared.
        /// </summary>
        /// <param name="header">Header.</param>
        public void Add(HeaderField header)
        {
            int headerSize = header.Size;

            if (headerSize > capacity)
            {
                this.Clear();
                return;
            }
            while (size + headerSize > capacity)
            {
                this.Remove();
            }
            headerFields[head++] = header;
            size += header.Size;
            if (head == headerFields.Length)
            {
                head = 0;
            }
        }
示例#6
0
        /// <summary>
        /// Encode the header field into the header block.
        /// </summary>
        /// <param name="output">Output.</param>
        /// <param name="name">Name.</param>
        /// <param name="value">Value.</param>
        /// <param name="sensitive">If set to <c>true</c> sensitive.</param>
        public void EncodeHeader(BinaryWriter output, byte[] name, byte[] value, bool sensitive)
        {
            // If the header value is sensitive then it must never be indexed
            if (sensitive)
            {
                int nameIndex = this.GetNameIndex(name);
                this.EncodeLiteral(output, name, value, HPackUtil.IndexType.NEVER, nameIndex);
                return;
            }

            // If the peer will only use the static table
            if (this.capacity == 0)
            {
                int staticTableIndex = StaticTable.GetIndex(name, value);
                if (staticTableIndex == -1)
                {
                    int nameIndex = StaticTable.GetIndex(name);
                    this.EncodeLiteral(output, name, value, HPackUtil.IndexType.NONE, nameIndex);
                }
                else
                {
                    Encoder.EncodeInteger(output, 0x80, 7, staticTableIndex);
                }
                return;
            }

            int headerSize = HeaderField.SizeOf(name, value);

            // If the headerSize is greater than the max table size then it must be encoded literally
            if (headerSize > this.capacity)
            {
                int nameIndex = this.GetNameIndex(name);
                this.EncodeLiteral(output, name, value, HPackUtil.IndexType.NONE, nameIndex);
                return;
            }

            HeaderEntry headerField = this.GetEntry(name, value);

            if (headerField != null)
            {
                int index = this.GetIndex(headerField.Index) + StaticTable.Length;
                // Section 6.1. Indexed Header Field Representation
                Encoder.EncodeInteger(output, 0x80, 7, index);
            }
            else
            {
                int staticTableIndex = StaticTable.GetIndex(name, value);
                if (staticTableIndex != -1)
                {
                    // Section 6.1. Indexed Header Field Representation
                    Encoder.EncodeInteger(output, 0x80, 7, staticTableIndex);
                }
                else
                {
                    int nameIndex = this.GetNameIndex(name);
                    if (useIndexing)
                    {
                        this.EnsureCapacity(headerSize);
                    }
                    var indexType = useIndexing ? HPackUtil.IndexType.INCREMENTAL : HPackUtil.IndexType.NONE;
                    this.EncodeLiteral(output, name, value, indexType, nameIndex);
                    if (useIndexing)
                    {
                        this.Add(name, value);
                    }
                }
            }
        }