proxygen
HPACKDecoder.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015-present, Facebook, Inc.
3  * All rights reserved.
4  *
5  * This source code is licensed under the BSD-style license found in the
6  * LICENSE file in the root directory of this source tree. An additional grant
7  * of patent rights can be found in the PATENTS file in the same directory.
8  *
9  */
11 
13 
14 using folly::IOBuf;
15 using folly::io::Cursor;
16 using std::unique_ptr;
18 
19 namespace proxygen {
20 
22  Cursor& cursor,
23  uint32_t totalBytes,
24  HPACK::StreamingCallback* streamingCb) {
25  HPACKDecodeBuffer dbuf(cursor, totalBytes, maxUncompressed_);
26  uint32_t emittedSize = 0;
27 
28  while (!hasError() && !dbuf.empty()) {
29  emittedSize += decodeHeader(dbuf, streamingCb, nullptr);
30 
31  if (emittedSize > maxUncompressed_) {
32  LOG(ERROR) << "exceeded uncompressed size limit of "
33  << maxUncompressed_ << " bytes";
35  break;
36  }
37  emittedSize += 2;
38  }
39 
41  emittedSize);
42 }
43 
45  HPACKDecodeBuffer& dbuf,
46  HPACK::StreamingCallback* streamingCb,
47  headers_t* emitted) {
48  uint8_t byte = dbuf.peek();
49  bool indexing = byte & HPACK::LITERAL_INC_INDEX.code;
50  HPACKHeader header;
51  uint8_t indexMask = 0x3F; // 0011 1111
53  if (!indexing) {
54  // bool neverIndex = byte & HPACK::LITERAL_NEV_INDEX.code;
55  // TODO: we need to emit this flag with the headers
56  indexMask = 0x0F; // 0000 1111
58  }
59  if (byte & indexMask) {
60  uint64_t index;
61  err_ = dbuf.decodeInteger(length, index);
63  LOG(ERROR) << "Decode error decoding index err_=" << err_;
64  return 0;
65  }
66  // validate the index
67  if (!isValid(index)) {
68  LOG(ERROR) << "received invalid index: " << index;
70  return 0;
71  }
72  header.name = getHeader(index).name;
73  } else {
74  // skip current byte
75  dbuf.next();
76  folly::fbstring headerName;
77  err_ = dbuf.decodeLiteral(headerName);
78  header.name = headerName;
80  LOG(ERROR) << "Error decoding header name err_=" << err_;
81  return 0;
82  }
83  }
84  // value
85  err_ = dbuf.decodeLiteral(header.value);
87  LOG(ERROR) << "Error decoding header value name=" << header.name
88  << " err_=" << err_;
89  return 0;
90  }
91 
92  uint32_t emittedSize = emit(header, streamingCb, emitted);
93 
94  if (indexing) {
95  table_.add(std::move(header));
96  }
97 
98  return emittedSize;
99 }
100 
102  HPACKDecodeBuffer& dbuf,
103  HPACK::StreamingCallback* streamingCb,
104  headers_t* emitted) {
105  uint64_t index;
106  err_ = dbuf.decodeInteger(HPACK::INDEX_REF.prefixLength, index);
108  LOG(ERROR) << "Decode error decoding index err_=" << err_;
109  return 0;
110  }
111  // validate the index
112  if (index == 0 || !isValid(index)) {
113  LOG(ERROR) << "received invalid index: " << index;
115  return 0;
116  }
117 
118  auto& header = getHeader(index);
119  return emit(header, streamingCb, emitted);
120 }
121 
123  if (isStatic(index)) {
124  return getStaticTable().isValid(globalToStaticIndex(index));
125  } else {
126  return table_.isValid(globalToDynamicIndex(index));
127  }
128 }
129 
131  HPACKDecodeBuffer& dbuf,
132  HPACK::StreamingCallback* streamingCb,
133  headers_t* emitted) {
134  uint8_t byte = dbuf.peek();
135  if (byte & HPACK::INDEX_REF.code) {
136  return decodeIndexedHeader(dbuf, streamingCb, emitted);
137  } else if (byte & HPACK::LITERAL_INC_INDEX.code) {
138  // else it's fine, fall through to decodeLiteralHeader
139  } else if (byte & HPACK::TABLE_SIZE_UPDATE.code) {
141  return 0;
142  } // else LITERAL
143  // LITERAL_NO_INDEXING or LITERAL_INCR_INDEXING
144  return decodeLiteralHeader(dbuf, streamingCb, emitted);
145 }
146 
147 }
uint32_t globalToStaticIndex(uint32_t index) const
Definition: HPACKContext.h:76
const Instruction INDEX_REF
std::vector< HPACKHeader > headers_t
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
uint32_t decodeHeader(HPACKDecodeBuffer &dbuf, HPACK::StreamingCallback *streamingCb, headers_t *emitted)
void handleTableSizeUpdate(HPACKDecodeBuffer &dbuf, HeaderTable &table)
bool isValid(uint32_t index) const
uint32_t decodeIndexedHeader(HPACKDecodeBuffer &dbuf, HPACK::StreamingCallback *streamingCb, headers_t *emitted)
const Instruction TABLE_SIZE_UPDATE
uint32_t consumedBytes() const
const Instruction LITERAL_INC_INDEX
const HPACKHeader & getHeader(uint32_t index)
uint32_t emit(const HPACKHeader &header, HPACK::StreamingCallback *streamingCb, headers_t *emitted)
const StaticHeaderTable & getStaticTable() const
Definition: HPACKContext.h:69
HPACK::DecodeError decodeLiteral(folly::fbstring &literal)
HPACKHeaderName name
Definition: HPACKHeader.h:82
uint32_t decodeLiteralHeader(HPACKDecodeBuffer &dbuf, HPACK::StreamingCallback *streamingCb, headers_t *emitted)
void decodeStreaming(folly::io::Cursor &cursor, uint32_t totalBytes, HPACK::StreamingCallback *streamingCb)
folly::fbstring value
Definition: HPACKHeader.h:83
void completeDecode(HeaderCodec::Type type, HPACK::StreamingCallback *streamingCb, uint32_t compressedSize, uint32_t emittedSize)
bool isStatic(uint32_t index) const
HPACK::DecodeError decodeInteger(uint8_t nbit, uint64_t &integer)
const Instruction LITERAL
bool isValid(uint32_t index)
uint32_t globalToDynamicIndex(uint32_t index) const
Definition: HPACKContext.h:73
virtual bool add(HPACKHeader header)
Definition: HeaderTable.cpp:33