Esempio n. 1
0
        private void ProcessHeaderValue(IHttpHeadersHandler handler)
        {
            OnString(nextState: State.Ready);

            var headerNameSpan  = new Span <byte>(_headerName, 0, _headerNameLength);
            var headerValueSpan = new Span <byte>(_headerValueOctets, 0, _headerValueLength);

            handler.OnHeader(headerNameSpan, headerValueSpan);

            if (_index)
            {
                _dynamicTable.Insert(headerNameSpan, headerValueSpan);
            }
        }
Esempio n. 2
0
        public void OnByte(byte b, IHttpHeadersHandler handler)
        {
            switch (_state)
            {
            case State.Ready:
                if ((b & IndexedHeaderFieldMask) == IndexedHeaderFieldRepresentation)
                {
                    var val = b & ~IndexedHeaderFieldMask;

                    if (_integerDecoder.BeginDecode((byte)val, IndexedHeaderFieldPrefix))
                    {
                        OnIndexedHeaderField(_integerDecoder.Value, handler);
                    }
                    else
                    {
                        _state = State.HeaderFieldIndex;
                    }
                }
                else if ((b & LiteralHeaderFieldWithIncrementalIndexingMask) == LiteralHeaderFieldWithIncrementalIndexingRepresentation)
                {
                    _index = true;
                    var val = b & ~LiteralHeaderFieldWithIncrementalIndexingMask;

                    if (val == 0)
                    {
                        _state = State.HeaderNameLength;
                    }
                    else if (_integerDecoder.BeginDecode((byte)val, LiteralHeaderFieldWithIncrementalIndexingPrefix))
                    {
                        OnIndexedHeaderName(_integerDecoder.Value);
                    }
                    else
                    {
                        _state = State.HeaderNameIndex;
                    }
                }
                else if ((b & LiteralHeaderFieldWithoutIndexingMask) == LiteralHeaderFieldWithoutIndexingRepresentation)
                {
                    _index = false;
                    var val = b & ~LiteralHeaderFieldWithoutIndexingMask;

                    if (val == 0)
                    {
                        _state = State.HeaderNameLength;
                    }
                    else if (_integerDecoder.BeginDecode((byte)val, LiteralHeaderFieldWithoutIndexingPrefix))
                    {
                        OnIndexedHeaderName(_integerDecoder.Value);
                    }
                    else
                    {
                        _state = State.HeaderNameIndex;
                    }
                }
                else if ((b & LiteralHeaderFieldNeverIndexedMask) == LiteralHeaderFieldNeverIndexedRepresentation)
                {
                    _index = false;
                    var val = b & ~LiteralHeaderFieldNeverIndexedMask;

                    if (val == 0)
                    {
                        _state = State.HeaderNameLength;
                    }
                    else if (_integerDecoder.BeginDecode((byte)val, LiteralHeaderFieldNeverIndexedPrefix))
                    {
                        OnIndexedHeaderName(_integerDecoder.Value);
                    }
                    else
                    {
                        _state = State.HeaderNameIndex;
                    }
                }
                else if ((b & DynamicTableSizeUpdateMask) == DynamicTableSizeUpdateRepresentation)
                {
                    if (_integerDecoder.BeginDecode((byte)(b & ~DynamicTableSizeUpdateMask), DynamicTableSizeUpdatePrefix))
                    {
                        // TODO: validate that it's less than what's defined via SETTINGS
                        _dynamicTable.Resize(_integerDecoder.Value);
                    }
                    else
                    {
                        _state = State.DynamicTableSizeUpdate;
                    }
                }
                else
                {
                    // Can't happen
                    throw new HPackDecodingException($"Byte value {b} does not encode a valid header field representation.");
                }

                break;

            case State.HeaderFieldIndex:
                if (_integerDecoder.Decode(b))
                {
                    OnIndexedHeaderField(_integerDecoder.Value, handler);
                }

                break;

            case State.HeaderNameIndex:
                if (_integerDecoder.Decode(b))
                {
                    OnIndexedHeaderName(_integerDecoder.Value);
                }

                break;

            case State.HeaderNameLength:
                _huffman = (b & HuffmanMask) != 0;

                if (_integerDecoder.BeginDecode((byte)(b & ~HuffmanMask), StringLengthPrefix))
                {
                    OnStringLength(_integerDecoder.Value, nextState: State.HeaderName);
                }
                else
                {
                    _state = State.HeaderNameLengthContinue;
                }

                break;

            case State.HeaderNameLengthContinue:
                if (_integerDecoder.Decode(b))
                {
                    OnStringLength(_integerDecoder.Value, nextState: State.HeaderName);
                }

                break;

            case State.HeaderName:
                _stringOctets[_stringIndex++] = b;

                if (_stringIndex == _stringLength)
                {
                    OnString(nextState: State.HeaderValueLength);
                }

                break;

            case State.HeaderValueLength:
                _huffman = (b & HuffmanMask) != 0;

                if (_integerDecoder.BeginDecode((byte)(b & ~HuffmanMask), StringLengthPrefix))
                {
                    OnStringLength(_integerDecoder.Value, nextState: State.HeaderValue);
                }
                else
                {
                    _state = State.HeaderValueLengthContinue;
                }

                break;

            case State.HeaderValueLengthContinue:
                if (_integerDecoder.Decode(b))
                {
                    OnStringLength(_integerDecoder.Value, nextState: State.HeaderValue);
                }

                break;

            case State.HeaderValue:
                _stringOctets[_stringIndex++] = b;

                if (_stringIndex == _stringLength)
                {
                    OnString(nextState: State.Ready);

                    var headerNameSpan  = new Span <byte>(_headerName, 0, _headerNameLength);
                    var headerValueSpan = new Span <byte>(_headerValueOctets, 0, _headerValueLength);

                    handler.OnHeader(headerNameSpan, headerValueSpan);

                    if (_index)
                    {
                        _dynamicTable.Insert(headerNameSpan, headerValueSpan);
                    }
                }

                break;

            case State.DynamicTableSizeUpdate:
                if (_integerDecoder.Decode(b))
                {
                    if (_integerDecoder.Value > _maxDynamicTableSize)
                    {
                        throw new HPackDecodingException(
                                  CoreStrings.FormatHPackErrorDynamicTableSizeUpdateTooLarge(_integerDecoder.Value, _maxDynamicTableSize));
                    }

                    _dynamicTable.Resize(_integerDecoder.Value);
                    _state = State.Ready;
                }

                break;

            default:
                // Can't happen
                throw new HPackDecodingException("The HPACK decoder reached an invalid state.");
            }
        }