1Tutorial: HPACK API 2=================== 3 4In this tutorial, we describe basic use of nghttp2's HPACK API. We 5briefly describe the APIs for deflating and inflating header fields. 6The full example of using these APIs, `deflate.c`_, is attached at the 7end of this page. It also resides in the examples directory in the 8archive or repository. 9 10Deflating (encoding) headers 11---------------------------- 12 13First we need to initialize a :type:`nghttp2_hd_deflater` object using 14the `nghttp2_hd_deflate_new()` function:: 15 16 int nghttp2_hd_deflate_new(nghttp2_hd_deflater **deflater_ptr, 17 size_t deflate_hd_table_bufsize_max); 18 19This function allocates a :type:`nghttp2_hd_deflater` object, 20initializes it, and assigns its pointer to ``*deflater_ptr``. The 21*deflate_hd_table_bufsize_max* is the upper bound of header table size 22the deflater will use. This will limit the memory usage by the 23deflater object for the dynamic header table. If in doubt, just 24specify 4096 here, which is the default upper bound of dynamic header 25table buffer size. 26 27To encode header fields, use the `nghttp2_hd_deflate_hd()` function:: 28 29 ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater, 30 uint8_t *buf, size_t buflen, 31 const nghttp2_nv *nva, size_t nvlen); 32 33The *deflater* is the deflater object initialized by 34`nghttp2_hd_deflate_new()` described above. The encoded byte string is 35written to the buffer *buf*, which has length *buflen*. The *nva* is 36a pointer to an array of headers fields, each of type 37:type:`nghttp2_nv`. *nvlen* is the number of header fields which 38*nva* contains. 39 40It is important to initialize and assign all members of 41:type:`nghttp2_nv`. For security sensitive header fields (such as 42cookies), set the :macro:`NGHTTP2_NV_FLAG_NO_INDEX` flag in 43:member:`nghttp2_nv.flags`. Setting this flag prevents recovery of 44sensitive header fields by compression based attacks: This is achieved 45by not inserting the header field into the dynamic header table. 46 47`nghttp2_hd_deflate_hd()` processes all headers given in *nva*. The 48*nva* must include all request or response header fields to be sent in 49one HEADERS (or optionally following (multiple) CONTINUATION 50frame(s)). The *buf* must have enough space to store the encoded 51result, otherwise the function will fail. To estimate the upper bound 52of the encoded result length, use `nghttp2_hd_deflate_bound()`:: 53 54 size_t nghttp2_hd_deflate_bound(nghttp2_hd_deflater *deflater, 55 const nghttp2_nv *nva, size_t nvlen); 56 57Pass this function the same parameters (*deflater*, *nva*, and 58*nvlen*) which will be passed to `nghttp2_hd_deflate_hd()`. 59 60Subsequent calls to `nghttp2_hd_deflate_hd()` will use the current 61encoder state and perform differential encoding, which yields HPAC's 62fundamental compression gain. 63 64If `nghttp2_hd_deflate_hd()` fails, the failure is fatal and any 65further calls with the same deflater object will fail. Thus it's very 66important to use `nghttp2_hd_deflate_bound()` to determine the 67required size of the output buffer. 68 69To delete a :type:`nghttp2_hd_deflater` object, use the 70`nghttp2_hd_deflate_del()` function. 71 72Inflating (decoding) headers 73---------------------------- 74 75A :type:`nghttp2_hd_inflater` object is used to inflate compressed 76header data. To initialize the object, use 77`nghttp2_hd_inflate_new()`:: 78 79 int nghttp2_hd_inflate_new(nghttp2_hd_inflater **inflater_ptr); 80 81To inflate header data, use `nghttp2_hd_inflate_hd2()`:: 82 83 ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater, 84 nghttp2_nv *nv_out, int *inflate_flags, 85 const uint8_t *in, size_t inlen, 86 int in_final); 87 88`nghttp2_hd_inflate_hd2()` reads a stream of bytes and outputs a 89single header field at a time. Multiple calls are normally required to 90read a full stream of bytes and output all of the header fields. 91 92The *inflater* is the inflater object initialized above. The *nv_out* 93is a pointer to a :type:`nghttp2_nv` into which one header field may 94be stored. The *in* is a pointer to input data, and *inlen* is its 95length. The caller is not required to specify the whole deflated 96header data via *in* at once: Instead it can call this function 97multiple times as additional data bytes become available. If 98*in_final* is nonzero, it tells the function that the passed data is 99the final sequence of deflated header data. 100 101The *inflate_flags* is an output parameter; on success the function 102sets it to a bitset of flags. It will be described later. 103 104This function returns when each header field is inflated. When this 105happens, the function sets the :macro:`NGHTTP2_HD_INFLATE_EMIT` flag 106in *inflate_flags*, and a header field is stored in *nv_out*. The 107return value indicates the number of bytes read from *in* processed so 108far, which may be less than *inlen*. The caller should call the 109function repeatedly until all bytes are processed. Processed bytes 110should be removed from *in*, and *inlen* should be adjusted 111appropriately. 112 113If *in_final* is nonzero and all given data was processed, the 114function sets the :macro:`NGHTTP2_HD_INFLATE_FINAL` flag in 115*inflate_flags*. When you see this flag set, call the 116`nghttp2_hd_inflate_end_headers()` function. 117 118If *in_final* is zero and the :macro:`NGHTTP2_HD_INFLATE_EMIT` flag is 119not set, it indicates that all given data was processed. The caller 120is required to pass additional data. 121 122Example usage of `nghttp2_hd_inflate_hd2()` is shown in the 123`inflate_header_block()` function in `deflate.c`_. 124 125Finally, to delete a :type:`nghttp2_hd_inflater` object, use 126`nghttp2_hd_inflate_del()`. 127