Line data Source code
1 : #ifndef HEADER_fd_src_waltz_h2_fd_hpack_h 2 : #define HEADER_fd_src_waltz_h2_fd_hpack_h 3 : 4 : /* fd_hpack.h provides APIs for HPACK compression and decompression. 5 : 6 : Supports the static table and Huffman string coding. Does not use 7 : the dynamic table while encoding. Assumes that the endpoint used 8 : HTTP/2 SETTINGS to force the peer's dynamic table size to zero. */ 9 : 10 : #include "fd_h2_base.h" 11 : 12 : /* fd_h2_hdr_t points to an HTTP/2 header name:value pair. 13 : 14 : {name,value} point to decoded header values stored either in the 15 : hardcoded HPACK static table, the binary frame, or a scratch buffer. 16 : It is not guaranteed that these are valid ASCII. These are NOT 17 : null-terminated. 18 : 19 : (hint&FD_H2_HDR_HINT_INDEXED) indicates that the HPACK coding of the 20 : header referenced a static table entry. The index of the entry is 21 : in the low 6 bits. 22 : 23 : (hint&FD_H2_HDR_HINT_HUFFMAN) is internal and can be safely ignored, 24 : as fd_hpack_rd_next takes care of Huffman coding. */ 25 : 26 : struct fd_h2_hdr { 27 : char const * name; 28 : char const * value; 29 : ushort name_len; 30 : ushort hint; 31 : uint value_len; 32 : }; 33 : 34 : typedef struct fd_h2_hdr fd_h2_hdr_t; 35 : 36 294 : #define FD_H2_HDR_HINT_NAME_HUFFMAN ((ushort)0x8000) /* name is huffman coded */ 37 357 : #define FD_H2_HDR_HINT_VALUE_HUFFMAN ((ushort)0x4000) /* value is huffman coded */ 38 141 : #define FD_H2_HDR_HINT_HUFFMAN ((ushort)(FD_H2_HDR_HINT_NAME_HUFFMAN|FD_H2_HDR_HINT_VALUE_HUFFMAN)) 39 714 : #define FD_H2_HDR_HINT_NAME_INDEXED ((ushort)0x2000) /* name was indexed from table */ 40 66 : #define FD_H2_HDR_HINT_VALUE_INDEXED ((ushort)0x1000) /* value was indexed from table */ 41 : #define FD_H2_HDR_HINT_INDEXED ((ushort)(FD_H2_HDR_HINT_NAME_INDEXED|FD_H2_HDR_HINT_VALUE_INDEXED)) 42 183 : #define FD_H2_HDR_HINT_GET_INDEX(hint) ((uchar)((hint)&0xFF)) 43 : 44 : /* An fd_hpack_rd_t object reads a block of HPACK-encoded HTTP/2 45 : headers. For example usage, see test_hpack. */ 46 : 47 : struct fd_hpack_rd { 48 : uchar const * src; 49 : uchar const * src_end; 50 : }; 51 : 52 : typedef struct fd_hpack_rd fd_hpack_rd_t; 53 : 54 : FD_PROTOTYPES_BEGIN 55 : 56 : /* fd_hpack_rd_init initializes a hpack_rd for reading of the header 57 : block in src. hpack_rd has a read interest in src for its entire 58 : lifetime. */ 59 : 60 : fd_hpack_rd_t * 61 : fd_hpack_rd_init( fd_hpack_rd_t * rd, 62 : uchar const * src, 63 : ulong srcsz ); 64 : 65 : /* fd_hpack_rd_done returns 1 if all header entries were read from 66 : hpack_rd. Returns 0 if fd_hpack_rd_next should be called again. */ 67 : 68 : static inline int 69 189 : fd_hpack_rd_done( fd_hpack_rd_t const * rd ) { 70 189 : return rd->src >= rd->src_end; 71 189 : } 72 : 73 : /* fd_hpack_rd_next reads the next header from hpack_rd. hdr is 74 : populated with pointers to the decoded data. These pointers either 75 : point into hpack_rd->src or *scratch. 76 : 77 : *scratch is assumed to point to the next free byte in a scratch 78 : buffer. scratch_end points one past the last byte of the scratch 79 : buffer. 80 : 81 : Returns FD_H2_SUCCESS, populates header, and updates *scratch on 82 : success. On failure, returns FD_H2_ERR_COMPRESSION and leaves 83 : *scratch intact. Reasons for failure include HPACK parse error, 84 : out-of-bounds table index, use of the dynamic table, Huffman coding 85 : error, or out of scratch space. The caller should assume that *hdr 86 : and **scratch (the free bytes in the scratch buffer, not the pointer 87 : itself) are invalidated/filled with garbage on failure. */ 88 : 89 : uint 90 : fd_hpack_rd_next( fd_hpack_rd_t * hpack_rd, 91 : fd_h2_hdr_t * hdr, 92 : uchar ** scratch, 93 : uchar * scratch_end ); 94 : 95 : FD_PROTOTYPES_END 96 : 97 : #endif /* HEADER_fd_src_waltz_h2_fd_hpack_h */