private static void WriteKeyName(WritableBuffer buffer, Header header, ref HeaderTable headerTable, byte preamble, int n) { var nameIndex = headerTable.GetKey(header.Name); WriteUInt32(buffer, nameIndex, preamble, n); if (nameIndex == 0) { WriteNameString(buffer, header.Name, header.Options); } }
internal static HttpHeader ParseHttpHeader(ref ReadableBuffer buffer, ref HeaderTable headerTable, IBufferPool memoryPool) { var headers = new List <Header>(); while (!buffer.IsEmpty) { var header = Hpack.ReadHeader(ref buffer, ref headerTable, memoryPool); if (!header.IsResize) { headers.Add(header); } } return(new HttpHeader(headers)); }
private static Header ReadHeader(ref ReadableBuffer buffer, ref HeaderTable headerTable, int header, int prefixBytes, HeaderOptions options) { var index = ReadUInt32(ref buffer, header, prefixBytes); string name, value; bool compressed; if (index == 0) { name = ReadString(ref buffer, out compressed); options |= compressed ? HeaderOptions.NameCompressionOn : HeaderOptions.NameCompressionOff; } else { name = headerTable.GetHeaderName(index); } value = ReadString(ref buffer, out compressed); options |= compressed ? HeaderOptions.ValueCompressionOn : HeaderOptions.ValueCompressionOff; return(new Header(name, value, options)); }
public static Header ReadHeader(ref ReadableBuffer buffer, ref HeaderTable headerTable, IBufferPool memoryPool) { int firstByte = buffer.Peek(); if (firstByte < 0) { ThrowEndOfStreamException(); } buffer = buffer.Slice(1); if ((firstByte & 0x80) != 0) { // 6.1. Indexed Header Field Representation return(headerTable.GetHeader(ReadUInt32(ref buffer, firstByte, 7))); } else if ((firstByte & 0x40) != 0) { // 6.2.1. Literal Header Field with Incremental Indexing var result = ReadHeader(ref buffer, ref headerTable, firstByte, 6, HeaderOptions.IndexAddNewValue); headerTable = headerTable.Add(result, memoryPool); return(result); } else if ((firstByte & 0x20) != 0) { // 6.3. Dynamic Table Size Update var newSize = ReadInt32(ref buffer, firstByte, 5); headerTable = headerTable.SetMaxLength(newSize, memoryPool); return(Header.Resize(newSize)); } else { // 6.2.2.Literal Header Field without Indexing // 6.2.3.Literal Header Field Never Indexed return(ReadHeader(ref buffer, ref headerTable, firstByte, 4, (firstByte & 0x10) == 0 ? HeaderOptions.IndexNotIndexed : HeaderOptions.IndexNeverIndexed)); } }
public static void WriteHeader(WritableBuffer buffer, Header header, ref HeaderTable headerTable, MemoryPool memoryPool) { switch (header.Options & HeaderOptions.IndexMask) { case HeaderOptions.IndexAddNewValue: WriteKeyName(buffer, header, ref headerTable, 0x40, 6); WriteValueString(buffer, header.Value, header.Options); headerTable = headerTable.Add(header, memoryPool); break; case HeaderOptions.IndexExistingValue: var index = headerTable.GetKey(header.Name, header.Value); if (index == 0) { throw new InvalidOperationException("Attempted to use a header that did not exist: " + header.ToString() + Environment.NewLine + headerTable.ToString()); } WriteUInt32(buffer, index, 0x80, 7); break; case HeaderOptions.IndexNeverIndexed: WriteKeyName(buffer, header, ref headerTable, 0x10, 4); WriteValueString(buffer, header.Value, header.Options); break; case HeaderOptions.IndexNotIndexed: WriteKeyName(buffer, header, ref headerTable, 0x00, 4); WriteValueString(buffer, header.Value, header.Options); break; case HeaderOptions.IndexResize: uint len; if (!uint.TryParse(header.Value, out len)) { throw new InvalidOperationException("Invalid index length change: " + header.Value); } WriteUInt32(buffer, len, 0x20, 5); break; case HeaderOptions.IndexAutomatic: index = headerTable.GetKey(header.Name, header.Value); if (index == 0) { index = headerTable.GetKey(header.Name); switch (index) { case 1: // :authority case 15: // accept-charset case 16: // accept-encoding case 17: // accept-language case 38: // host case 58: // user-agent // AddNewValue WriteUInt32(buffer, index, 0x40, 6); headerTable = headerTable.Add(header, memoryPool); break; default: // NotIndexed WriteUInt32(buffer, index, 0x00, 4); if (index == 0) { WriteNameString(buffer, header.Name, header.Options); } break; } WriteValueString(buffer, header.Value, header.Options); } else { // ExistingValue WriteUInt32(buffer, index, 0x80, 7); } break; default: throw new InvalidOperationException("Invalid header indexing: " + header.Options); } }
public static void WriteHttpHeader(WritableBuffer buffer, HttpHeader httpHeader, ref HeaderTable headerTable, MemoryPool memoryPool) { foreach (var header in httpHeader) { WriteHeader(buffer, header, ref headerTable, memoryPool); } }
public void Dispose() { _decoderTable.Dispose(); _decoderTable = default(HeaderTable); }