uint32_t HPACKDecoder::decodeLiteralHeader(HPACKDecodeBuffer& dbuf, headers_t* emitted) { uint8_t byte = dbuf.peek(); bool indexing = byte & HPACK::HeaderEncoding::LITERAL_INCR_INDEXING; HPACKHeader header; uint8_t indexMask = 0x3F; // 0011 1111 uint8_t length = 6; if (!indexing) { bool tableSizeUpdate = byte & HPACK::HeaderEncoding::TABLE_SIZE_UPDATE; if (tableSizeUpdate) { handleTableSizeUpdate(dbuf); return 0; } else { bool neverIndex = byte & HPACK::HeaderEncoding::LITERAL_NEVER_INDEXING; // TODO: we need to emit this flag with the headers } indexMask = 0x0F; // 0000 1111 length = 4; } if (byte & indexMask) { uint32_t index; err_ = dbuf.decodeInteger(length, index); if (err_ != HPACK::DecodeError::NONE) { LOG(ERROR) << "Decode error decoding index err_=" << err_; return 0; } // validate the index if (!isValid(index)) { LOG(ERROR) << "received invalid index: " << index; err_ = HPACK::DecodeError::INVALID_INDEX; return 0; } header.name = getHeader(index).name; } else { // skip current byte dbuf.next(); err_ = dbuf.decodeLiteral(header.name); if (err_ != HPACK::DecodeError::NONE) { LOG(ERROR) << "Error decoding header name err_=" << err_; return 0; } } // value err_ = dbuf.decodeLiteral(header.value); if (err_ != HPACK::DecodeError::NONE) { LOG(ERROR) << "Error decoding header value name=" << header.name << " err_=" << err_; return 0; } uint32_t emittedSize = emit(header, emitted); if (indexing) { table_.add(header); } return emittedSize; }
uint32_t HPACKDecoder::decodeHeader(HPACKDecodeBuffer& dbuf, headers_t* emitted) { uint8_t byte = dbuf.peek(); if (byte & HPACK::HeaderEncoding::INDEXED) { return decodeIndexedHeader(dbuf, emitted); } // LITERAL_NO_INDEXING or LITERAL_INCR_INDEXING return decodeLiteralHeader(dbuf, emitted); }
uint32_t HPACKDecoder::decodeLiteralHeader(HPACKDecodeBuffer& dbuf, headers_t* emitted) { uint8_t byte = dbuf.peek(); bool indexing = !(byte & HPACK::HeaderEncoding::LITERAL_NO_INDEXING); HPACKHeader header; // check for indexed name const uint8_t indexMask = 0x3F; // 0011 1111 if (byte & indexMask) { uint32_t index; err_ = dbuf.decodeInteger(6, index); if (err_ != DecodeError::NONE) { LOG(ERROR) << "Decode error decoding literal index err_=" << err_; return 0; } // validate the index if (!isValid(index)) { LOG(ERROR) << "received invalid index: " << index; err_ = DecodeError::INVALID_INDEX; return 0; } header.name = getHeader(index).name; } else { // skip current byte dbuf.next(); err_ = dbuf.decodeLiteral(header.name); if (err_ != DecodeError::NONE) { LOG(ERROR) << "Error decoding header name err_=" << err_; return 0; } } // value err_ = dbuf.decodeLiteral(header.value); if (err_ != DecodeError::NONE) { LOG(ERROR) << "Error decoding header value name=" << header.name << " err_=" << err_; return 0; } uint32_t emittedSize = emit(header, emitted); if (indexing && table_.add(header)) { // only add it to the refset if the header fit in the table table_.addReference(1); } return emittedSize; }