/// <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); }
/// <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); }
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 + ")"); } }
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 + ")"); } }
/// <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; } }
/// <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); } } } }