uint32_t HPACKDecoder::emit(const HPACKHeader& header, headers_t* emitted) { if (streamingCb_) { streamingCb_->onHeader(header.name, header.value); } else if (emitted) { emitted->push_back(header); } return header.bytes(); }
bool HeaderTable::add(const HPACKHeader& header) { // handle size overflow if (bytes_ + header.bytes() > capacity_) { evict(header.bytes()); } // this means the header entry is larger than our table if (bytes_ + header.bytes() > capacity_) { return false; } if (size_ > 0) { head_ = next(head_); } table_[head_] = header; // index name names_[header.name].push_back(head_); bytes_ += header.bytes(); ++size_; return true; }
void HPACKEncoder::encodeEvictedReferences(const HPACKHeader& header) { uint32_t index = table_.size(); uint32_t bytes = table_.bytes(); // the header will be added to the header table while (index > 0 && (bytes + header.bytes() > table_.capacity())) { // double encode only if the element is in the reference set if (table_.isSkippedReference(index)) { // 1. this will remove the entry from the refset encodeAsIndex(dynamicToGlobalIndex(index)); // 2. this will add the same entry to the refset and emit it encodeAsIndex(dynamicToGlobalIndex(index)); } bytes -= table_[index].bytes(); index--; } }
void HPACKEncoder::encodeAsLiteral(const HPACKHeader& header) { bool indexing = header.isIndexable(); uint8_t prefix = indexing ? HPACK::HeaderEncoding::LITERAL_INCR_INDEXING : HPACK::HeaderEncoding::LITERAL_NO_INDEXING; // name uint32_t index = nameIndex(header.name); if (index) { buffer_.encodeInteger(index, prefix, 6); } else { buffer_.encodeInteger(0, prefix, 6); buffer_.encodeLiteral(header.name); } // value buffer_.encodeLiteral(header.value); // indexed ones need to get added to the header table if (indexing) { if (table_.add(header)) { table_.addReference(1); } } }
bool HPACKEncoder::willBeAdded(const HPACKHeader& header) { auto index = getIndex(header); return isStatic(index) || (index == 0 && header.isIndexable()); }
uint32_t HPACKDecoder::emit(const HPACKHeader& header, headers_t& emitted) { emitted.push_back(header); return header.bytes(); }