2424#include " HPACK.h"
2525#include " HuffmanCodec.h"
2626
27+ namespace
28+ {
2729// [RFC 7541] 4.1. Calculating Table Size
2830// The size of an entry is the sum of its name's length in octets (as defined in Section 5.2),
2931// its value's length in octets, and 32.
@@ -181,10 +183,10 @@ static const StaticTable STATIC_TABLE[] = {{"", ""},
181183*/
182184static constexpr uint32_t HPACK_HDR_HEAP_THRESHOLD = sizeof (MIMEHdrImpl) + sizeof (MIMEFieldBlockImpl) * (2 + 7 + 15 );
183185
184- /* *****************
185- * Local functions
186- ***************** * /
187- static inline bool
186+ //
187+ // Local functions
188+ / /
189+ bool
188190hpack_field_is_literal (HpackField ftype)
189191{
190192 return ftype == HpackField::INDEXED_LITERAL || ftype == HpackField::NOINDEX_LITERAL || ftype == HpackField::NEVERINDEX_LITERAL;
@@ -218,9 +220,45 @@ hpack_parse_field_type(uint8_t ftype)
218220 return HpackField::NOINDEX_LITERAL;
219221}
220222
221- /* ***********************
222- * HpackIndexingTable
223- ************************/
223+ //
224+ // HpackStaticTable
225+ //
226+ namespace HpackStaticTable
227+ {
228+ HpackLookupResult
229+ lookup (const char *name, int name_len, const char *value, int value_len)
230+ {
231+ HpackLookupResult result;
232+
233+ for (unsigned int index = 1 ; index < TS_HPACK_STATIC_TABLE_ENTRY_NUM; ++index) {
234+ const char *table_name = STATIC_TABLE[index].name ;
235+ int table_name_len = STATIC_TABLE[index].name_size ;
236+ const char *table_value = STATIC_TABLE[index].value ;
237+ int table_value_len = STATIC_TABLE[index].value_size ;
238+
239+ // Check whether name (and value) are matched
240+ if (ptr_len_casecmp (name, name_len, table_name, table_name_len) == 0 ) {
241+ if ((value_len == table_value_len) && (memcmp (value, table_value, value_len) == 0 )) {
242+ result.index = index;
243+ result.index_type = HpackIndex::STATIC;
244+ result.match_type = HpackMatch::EXACT;
245+ break ;
246+ } else if (!result.index ) {
247+ result.index = index;
248+ result.index_type = HpackIndex::STATIC;
249+ result.match_type = HpackMatch::NAME;
250+ }
251+ }
252+ }
253+
254+ return result;
255+ }
256+ } // namespace HpackStaticTable
257+ } // namespace
258+
259+ //
260+ // HpackIndexingTable
261+ //
224262HpackLookupResult
225263HpackIndexingTable::lookup (const MIMEFieldWrapper &field) const
226264{
@@ -233,45 +271,18 @@ HpackIndexingTable::lookup(const MIMEFieldWrapper &field) const
233271HpackLookupResult
234272HpackIndexingTable::lookup (const char *name, int name_len, const char *value, int value_len) const
235273{
236- HpackLookupResult result;
237- const unsigned int entry_num = TS_HPACK_STATIC_TABLE_ENTRY_NUM + _dynamic_table->length ();
238-
239- for (unsigned int index = 1 ; index < entry_num; ++index) {
240- const char *table_name, *table_value;
241- int table_name_len = 0 , table_value_len = 0 ;
242-
243- if (index < TS_HPACK_STATIC_TABLE_ENTRY_NUM) {
244- // static table
245- table_name = STATIC_TABLE[index].name ;
246- table_value = STATIC_TABLE[index].value ;
247- table_name_len = STATIC_TABLE[index].name_size ;
248- table_value_len = STATIC_TABLE[index].value_size ;
249- } else {
250- // dynamic table
251- const MIMEField *m_field = _dynamic_table->get_header_field (index - TS_HPACK_STATIC_TABLE_ENTRY_NUM);
274+ // static table
275+ HpackLookupResult result = HpackStaticTable::lookup (name, name_len, value, value_len);
252276
253- table_name = m_field->name_get (&table_name_len);
254- table_value = m_field->value_get (&table_value_len);
255- }
256-
257- // Check whether name (and value) are matched
258- if (ptr_len_casecmp (name, name_len, table_name, table_name_len) == 0 ) {
259- if ((value_len == table_value_len) && (memcmp (value, table_value, value_len) == 0 )) {
260- result.index = index;
261- result.match_type = HpackMatch::EXACT;
262- break ;
263- } else if (!result.index ) {
264- result.index = index;
265- result.match_type = HpackMatch::NAME;
266- }
267- }
277+ // if result is not EXACT match, lookup dynamic table
278+ if (result.match_type == HpackMatch::EXACT) {
279+ return result;
268280 }
269- if (result.match_type != HpackMatch::NONE) {
270- if (result.index < TS_HPACK_STATIC_TABLE_ENTRY_NUM) {
271- result.index_type = HpackIndex::STATIC;
272- } else {
273- result.index_type = HpackIndex::DYNAMIC;
274- }
281+
282+ // dynamic table
283+ if (HpackLookupResult dt_result = this ->_dynamic_table .lookup (name, name_len, value, value_len);
284+ dt_result.match_type == HpackMatch::EXACT) {
285+ return dt_result;
275286 }
276287
277288 return result;
@@ -289,9 +300,9 @@ HpackIndexingTable::get_header_field(uint32_t index, MIMEFieldWrapper &field) co
289300 // static table
290301 field.name_set (STATIC_TABLE[index].name , STATIC_TABLE[index].name_size );
291302 field.value_set (STATIC_TABLE[index].value , STATIC_TABLE[index].value_size );
292- } else if (index < TS_HPACK_STATIC_TABLE_ENTRY_NUM + _dynamic_table-> length ()) {
303+ } else if (index < TS_HPACK_STATIC_TABLE_ENTRY_NUM + _dynamic_table. length ()) {
293304 // dynamic table
294- const MIMEField *m_field = _dynamic_table-> get_header_field (index - TS_HPACK_STATIC_TABLE_ENTRY_NUM);
305+ const MIMEField *m_field = _dynamic_table. get_header_field (index - TS_HPACK_STATIC_TABLE_ENTRY_NUM);
295306
296307 int name_len, value_len;
297308 const char *name = m_field->name_get (&name_len);
@@ -312,30 +323,36 @@ HpackIndexingTable::get_header_field(uint32_t index, MIMEFieldWrapper &field) co
312323void
313324HpackIndexingTable::add_header_field (const MIMEField *field)
314325{
315- _dynamic_table-> add_header_field (field);
326+ _dynamic_table. add_header_field (field);
316327}
317328
318329uint32_t
319330HpackIndexingTable::maximum_size () const
320331{
321- return _dynamic_table-> maximum_size ();
332+ return _dynamic_table. maximum_size ();
322333}
323334
324335uint32_t
325336HpackIndexingTable::size () const
326337{
327- return _dynamic_table-> size ();
338+ return _dynamic_table. size ();
328339}
329340
330341void
331342HpackIndexingTable::update_maximum_size (uint32_t new_size)
332343{
333- _dynamic_table-> update_maximum_size (new_size);
344+ _dynamic_table. update_maximum_size (new_size);
334345}
335346
336347//
337348// HpackDynamicTable
338349//
350+ HpackDynamicTable::HpackDynamicTable (uint32_t size) : _maximum_size(size)
351+ {
352+ _mhdr = new MIMEHdr ();
353+ _mhdr->create ();
354+ }
355+
339356HpackDynamicTable::~HpackDynamicTable ()
340357{
341358 this ->_headers .clear ();
@@ -384,6 +401,39 @@ HpackDynamicTable::add_header_field(const MIMEField *field)
384401 }
385402}
386403
404+ HpackLookupResult
405+ HpackDynamicTable::lookup (const char *name, int name_len, const char *value, int value_len) const
406+ {
407+ HpackLookupResult result;
408+ const unsigned int entry_num = TS_HPACK_STATIC_TABLE_ENTRY_NUM + this ->length ();
409+
410+ for (unsigned int index = TS_HPACK_STATIC_TABLE_ENTRY_NUM; index < entry_num; ++index) {
411+ const MIMEField *m_field = this ->get_header_field (index - TS_HPACK_STATIC_TABLE_ENTRY_NUM);
412+
413+ int table_name_len = 0 ;
414+ const char *table_name = m_field->name_get (&table_name_len);
415+
416+ int table_value_len = 0 ;
417+ const char *table_value = m_field->value_get (&table_value_len);
418+
419+ // Check whether name (and value) are matched
420+ if (ptr_len_casecmp (name, name_len, table_name, table_name_len) == 0 ) {
421+ if ((value_len == table_value_len) && (memcmp (value, table_value, value_len) == 0 )) {
422+ result.index = index;
423+ result.index_type = HpackIndex::DYNAMIC;
424+ result.match_type = HpackMatch::EXACT;
425+ break ;
426+ } else if (!result.index ) {
427+ result.index = index;
428+ result.index_type = HpackIndex::DYNAMIC;
429+ result.match_type = HpackMatch::NAME;
430+ }
431+ }
432+ }
433+
434+ return result;
435+ }
436+
387437uint32_t
388438HpackDynamicTable::maximum_size () const
389439{
@@ -463,6 +513,9 @@ HpackDynamicTable::_mime_hdr_gc()
463513 }
464514}
465515
516+ //
517+ // Global functions
518+ //
466519int64_t
467520encode_indexed_header_field (uint8_t *buf_start, const uint8_t *buf_end, uint32_t index)
468521{
0 commit comments