Example #1
0
        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));
            }
        }
Example #2
0
        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);
            }
        }