| 688 | } |
| 689 | |
| 690 | int64_t |
| 691 | hpack_decode_header_block(HpackIndexingTable &indexing_table, HTTPHdr *hdr, const uint8_t *in_buf, const size_t in_buf_len, |
| 692 | uint32_t max_header_size, uint32_t maximum_table_size) |
| 693 | { |
| 694 | const uint8_t *cursor = in_buf; |
| 695 | const uint8_t *const in_buf_end = in_buf + in_buf_len; |
| 696 | HdrHeap *heap = hdr->m_heap; |
| 697 | HTTPHdrImpl *hh = hdr->m_http; |
| 698 | bool header_field_started = false; |
| 699 | bool has_http2_violation = false; |
| 700 | uint32_t total_header_size = 0; |
| 701 | |
| 702 | while (cursor < in_buf_end) { |
| 703 | int64_t read_bytes = 0; |
| 704 | |
| 705 | // decode a header field encoded by HPACK |
| 706 | MIMEField *field = mime_field_create(heap, hh->m_fields_impl); |
| 707 | MIMEFieldWrapper header(field, heap, hh->m_fields_impl); |
| 708 | HpackField ftype = hpack_parse_field_type(*cursor); |
| 709 | |
| 710 | switch (ftype) { |
| 711 | case HpackField::INDEX: |
| 712 | read_bytes = decode_indexed_header_field(header, cursor, in_buf_end, indexing_table); |
| 713 | if (read_bytes == HPACK_ERROR_COMPRESSION_ERROR) { |
| 714 | return HPACK_ERROR_COMPRESSION_ERROR; |
| 715 | } |
| 716 | cursor += read_bytes; |
| 717 | header_field_started = true; |
| 718 | break; |
| 719 | case HpackField::INDEXED_LITERAL: |
| 720 | case HpackField::NOINDEX_LITERAL: |
| 721 | case HpackField::NEVERINDEX_LITERAL: |
| 722 | read_bytes = decode_literal_header_field(header, cursor, in_buf_end, indexing_table); |
| 723 | if (read_bytes == HPACK_ERROR_COMPRESSION_ERROR) { |
| 724 | return HPACK_ERROR_COMPRESSION_ERROR; |
| 725 | } |
| 726 | if (read_bytes < 0) { |
| 727 | has_http2_violation = true; |
| 728 | read_bytes = -read_bytes; |
| 729 | } |
| 730 | cursor += read_bytes; |
| 731 | header_field_started = true; |
| 732 | break; |
| 733 | case HpackField::TABLESIZE_UPDATE: |
| 734 | if (header_field_started) { |
| 735 | return HPACK_ERROR_COMPRESSION_ERROR; |
| 736 | } |
| 737 | read_bytes = update_dynamic_table_size(cursor, in_buf_end, indexing_table, maximum_table_size); |
| 738 | if (read_bytes == HPACK_ERROR_COMPRESSION_ERROR) { |
| 739 | return HPACK_ERROR_COMPRESSION_ERROR; |
| 740 | } |
| 741 | cursor += read_bytes; |
| 742 | continue; |
| 743 | } |
| 744 | |
| 745 | auto name{field->name_get()}; |
| 746 | auto value{field->value_get()}; |
| 747 | |