2 * nghttp2 - HTTP/2 C Library
4 * Copyright (c) 2013 Tatsuhiro Tsujikawa
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice shall be
15 * included in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 #endif /* HAVE_CONFIG_H */
32 #include <nghttp2/nghttp2.h>
34 #include "nghttp2_hd_huffman.h"
35 #include "nghttp2_buf.h"
36 #include "nghttp2_mem.h"
37 #include "nghttp2_rcbuf.h"
39 #define NGHTTP2_HD_DEFAULT_MAX_BUFFER_SIZE NGHTTP2_DEFAULT_HEADER_TABLE_SIZE
40 #define NGHTTP2_HD_ENTRY_OVERHEAD 32
42 /* The maximum length of one name/value pair. This is the sum of the
43 length of name and value. This is not specified by the spec. We
44 just chose the arbitrary size */
45 #define NGHTTP2_HD_MAX_NV 65536
47 /* Default size of maximum table buffer size for encoder. Even if
48 remote decoder notifies larger buffer size for its decoding,
49 encoder only uses the memory up to this value. */
50 #define NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE (1 << 12)
52 /* Exported for unit test */
53 #define NGHTTP2_STATIC_TABLE_LENGTH 61
55 /* Generated by genlibtokenlookup.py */
57 NGHTTP2_TOKEN__AUTHORITY = 0,
58 NGHTTP2_TOKEN__METHOD = 1,
59 NGHTTP2_TOKEN__PATH = 3,
60 NGHTTP2_TOKEN__SCHEME = 5,
61 NGHTTP2_TOKEN__STATUS = 7,
62 NGHTTP2_TOKEN_ACCEPT_CHARSET = 14,
63 NGHTTP2_TOKEN_ACCEPT_ENCODING = 15,
64 NGHTTP2_TOKEN_ACCEPT_LANGUAGE = 16,
65 NGHTTP2_TOKEN_ACCEPT_RANGES = 17,
66 NGHTTP2_TOKEN_ACCEPT = 18,
67 NGHTTP2_TOKEN_ACCESS_CONTROL_ALLOW_ORIGIN = 19,
68 NGHTTP2_TOKEN_AGE = 20,
69 NGHTTP2_TOKEN_ALLOW = 21,
70 NGHTTP2_TOKEN_AUTHORIZATION = 22,
71 NGHTTP2_TOKEN_CACHE_CONTROL = 23,
72 NGHTTP2_TOKEN_CONTENT_DISPOSITION = 24,
73 NGHTTP2_TOKEN_CONTENT_ENCODING = 25,
74 NGHTTP2_TOKEN_CONTENT_LANGUAGE = 26,
75 NGHTTP2_TOKEN_CONTENT_LENGTH = 27,
76 NGHTTP2_TOKEN_CONTENT_LOCATION = 28,
77 NGHTTP2_TOKEN_CONTENT_RANGE = 29,
78 NGHTTP2_TOKEN_CONTENT_TYPE = 30,
79 NGHTTP2_TOKEN_COOKIE = 31,
80 NGHTTP2_TOKEN_DATE = 32,
81 NGHTTP2_TOKEN_ETAG = 33,
82 NGHTTP2_TOKEN_EXPECT = 34,
83 NGHTTP2_TOKEN_EXPIRES = 35,
84 NGHTTP2_TOKEN_FROM = 36,
85 NGHTTP2_TOKEN_HOST = 37,
86 NGHTTP2_TOKEN_IF_MATCH = 38,
87 NGHTTP2_TOKEN_IF_MODIFIED_SINCE = 39,
88 NGHTTP2_TOKEN_IF_NONE_MATCH = 40,
89 NGHTTP2_TOKEN_IF_RANGE = 41,
90 NGHTTP2_TOKEN_IF_UNMODIFIED_SINCE = 42,
91 NGHTTP2_TOKEN_LAST_MODIFIED = 43,
92 NGHTTP2_TOKEN_LINK = 44,
93 NGHTTP2_TOKEN_LOCATION = 45,
94 NGHTTP2_TOKEN_MAX_FORWARDS = 46,
95 NGHTTP2_TOKEN_PROXY_AUTHENTICATE = 47,
96 NGHTTP2_TOKEN_PROXY_AUTHORIZATION = 48,
97 NGHTTP2_TOKEN_RANGE = 49,
98 NGHTTP2_TOKEN_REFERER = 50,
99 NGHTTP2_TOKEN_REFRESH = 51,
100 NGHTTP2_TOKEN_RETRY_AFTER = 52,
101 NGHTTP2_TOKEN_SERVER = 53,
102 NGHTTP2_TOKEN_SET_COOKIE = 54,
103 NGHTTP2_TOKEN_STRICT_TRANSPORT_SECURITY = 55,
104 NGHTTP2_TOKEN_TRANSFER_ENCODING = 56,
105 NGHTTP2_TOKEN_USER_AGENT = 57,
106 NGHTTP2_TOKEN_VARY = 58,
107 NGHTTP2_TOKEN_VIA = 59,
108 NGHTTP2_TOKEN_WWW_AUTHENTICATE = 60,
110 NGHTTP2_TOKEN_CONNECTION,
111 NGHTTP2_TOKEN_KEEP_ALIVE,
112 NGHTTP2_TOKEN_PROXY_CONNECTION,
113 NGHTTP2_TOKEN_UPGRADE,
116 struct nghttp2_hd_entry;
117 typedef struct nghttp2_hd_entry nghttp2_hd_entry;
120 /* The buffer containing header field name. NULL-termination is
123 /* The buffer containing header field value. NULL-termination is
125 nghttp2_rcbuf *value;
126 /* nghttp2_token value for name. It could be -1 if we have no token
127 for that header field name. */
129 /* Bitwise OR of one or more of nghttp2_nv_flag. */
133 struct nghttp2_hd_entry {
134 /* The header field name/value pair */
136 /* This is solely for nghttp2_hd_{deflate,inflate}_get_table_entry
137 APIs to keep backward compatibility. */
139 /* The next entry which shares same bucket in hash table. */
140 nghttp2_hd_entry *next;
141 /* The sequence number. We will increment it by one whenever we
142 store nghttp2_hd_entry to dynamic header table. */
144 /* The hash value for header name (nv.name). */
148 /* The entry used for static header table. */
155 } nghttp2_hd_static_entry;
158 nghttp2_hd_entry **buffer;
162 } nghttp2_hd_ringbuf;
165 NGHTTP2_HD_OPCODE_NONE,
166 NGHTTP2_HD_OPCODE_INDEXED,
167 NGHTTP2_HD_OPCODE_NEWNAME,
168 NGHTTP2_HD_OPCODE_INDNAME
172 NGHTTP2_HD_STATE_EXPECT_TABLE_SIZE,
173 NGHTTP2_HD_STATE_INFLATE_START,
174 NGHTTP2_HD_STATE_OPCODE,
175 NGHTTP2_HD_STATE_READ_TABLE_SIZE,
176 NGHTTP2_HD_STATE_READ_INDEX,
177 NGHTTP2_HD_STATE_NEWNAME_CHECK_NAMELEN,
178 NGHTTP2_HD_STATE_NEWNAME_READ_NAMELEN,
179 NGHTTP2_HD_STATE_NEWNAME_READ_NAMEHUFF,
180 NGHTTP2_HD_STATE_NEWNAME_READ_NAME,
181 NGHTTP2_HD_STATE_CHECK_VALUELEN,
182 NGHTTP2_HD_STATE_READ_VALUELEN,
183 NGHTTP2_HD_STATE_READ_VALUEHUFF,
184 NGHTTP2_HD_STATE_READ_VALUE
185 } nghttp2_hd_inflate_state;
188 NGHTTP2_HD_WITH_INDEXING,
189 NGHTTP2_HD_WITHOUT_INDEXING,
190 NGHTTP2_HD_NEVER_INDEXING
191 } nghttp2_hd_indexing_mode;
194 /* dynamic header table */
195 nghttp2_hd_ringbuf hd_table;
196 /* Memory allocator */
198 /* Abstract buffer size of hd_table as described in the spec. This
199 is the sum of length of name/value in hd_table +
200 NGHTTP2_HD_ENTRY_OVERHEAD bytes overhead per each entry. */
201 size_t hd_table_bufsize;
202 /* The effective header table size. */
203 size_t hd_table_bufsize_max;
204 /* Next sequence number for nghttp2_hd_entry */
206 /* If inflate/deflate error occurred, this value is set to 1 and
207 further invocation of inflate/deflate will fail with
208 NGHTTP2_ERR_HEADER_COMP. */
210 } nghttp2_hd_context;
212 #define HD_MAP_SIZE 128
214 typedef struct { nghttp2_hd_entry *table[HD_MAP_SIZE]; } nghttp2_hd_map;
216 struct nghttp2_hd_deflater {
217 nghttp2_hd_context ctx;
219 /* The upper limit of the header table size the deflater accepts. */
220 size_t deflate_hd_table_bufsize_max;
221 /* Minimum header table size notified in the next context update */
222 size_t min_hd_table_bufsize_max;
223 /* If nonzero, send header table size using encoding context update
224 in the next deflate process */
225 uint8_t notify_table_size_change;
228 struct nghttp2_hd_inflater {
229 nghttp2_hd_context ctx;
230 /* Stores current state of huffman decoding */
231 nghttp2_hd_huff_decode_context huff_decode_ctx;
233 nghttp2_buf namebuf, valuebuf;
234 nghttp2_rcbuf *namercbuf, *valuercbuf;
235 /* Pointer to the name/value pair which are used in the current
237 nghttp2_rcbuf *nv_name_keep, *nv_value_keep;
238 /* The number of bytes to read */
240 /* The index in indexed repr or indexed name */
242 /* The maximum header table size the inflater supports. This is the
243 same value transmitted in SETTINGS_HEADER_TABLE_SIZE */
244 size_t settings_hd_table_bufsize_max;
245 /* Minimum header table size set by nghttp2_hd_inflate_change_table_size */
246 size_t min_hd_table_bufsize_max;
247 /* The number of next shift to decode integer */
249 nghttp2_hd_opcode opcode;
250 nghttp2_hd_inflate_state state;
251 /* nonzero if string is huffman encoded */
252 uint8_t huffman_encoded;
253 /* nonzero if deflater requires that current entry is indexed */
254 uint8_t index_required;
255 /* nonzero if deflater requires that current entry must not be
261 * Initializes the |ent| members. The reference counts of nv->name
262 * and nv->value are increased by one for each.
264 void nghttp2_hd_entry_init(nghttp2_hd_entry *ent, nghttp2_hd_nv *nv);
267 * This function decreases the reference counts of nv->name and
270 void nghttp2_hd_entry_free(nghttp2_hd_entry *ent);
273 * Initializes |deflater| for deflating name/values pairs.
275 * The encoder only uses up to
276 * NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE bytes for header table
277 * even if the larger value is specified later in
278 * nghttp2_hd_change_table_size().
280 * This function returns 0 if it succeeds, or one of the following
281 * negative error codes:
286 int nghttp2_hd_deflate_init(nghttp2_hd_deflater *deflater, nghttp2_mem *mem);
289 * Initializes |deflater| for deflating name/values pairs.
291 * The encoder only uses up to |deflate_hd_table_bufsize_max| bytes
292 * for header table even if the larger value is specified later in
293 * nghttp2_hd_change_table_size().
295 * This function returns 0 if it succeeds, or one of the following
296 * negative error codes:
301 int nghttp2_hd_deflate_init2(nghttp2_hd_deflater *deflater,
302 size_t deflate_hd_table_bufsize_max,
306 * Deallocates any resources allocated for |deflater|.
308 void nghttp2_hd_deflate_free(nghttp2_hd_deflater *deflater);
311 * Deflates the |nva|, which has the |nvlen| name/value pairs, into
314 * This function expands |bufs| as necessary to store the result. If
315 * buffers is full and the process still requires more space, this
316 * funtion fails and returns NGHTTP2_ERR_HEADER_COMP.
318 * After this function returns, it is safe to delete the |nva|.
320 * This function returns 0 if it succeeds, or one of the following
321 * negative error codes:
325 * NGHTTP2_ERR_HEADER_COMP
326 * Deflation process has failed.
327 * NGHTTP2_ERR_BUFFER_ERROR
328 * Out of buffer space.
330 int nghttp2_hd_deflate_hd_bufs(nghttp2_hd_deflater *deflater,
331 nghttp2_bufs *bufs, const nghttp2_nv *nva,
335 * Initializes |inflater| for inflating name/values pairs.
337 * This function returns 0 if it succeeds, or one of the following
338 * negative error codes:
340 * :enum:`NGHTTP2_ERR_NOMEM`
343 int nghttp2_hd_inflate_init(nghttp2_hd_inflater *inflater, nghttp2_mem *mem);
346 * Deallocates any resources allocated for |inflater|.
348 void nghttp2_hd_inflate_free(nghttp2_hd_inflater *inflater);
351 * Similar to nghttp2_hd_inflate_hd(), but this takes nghttp2_hd_nv
352 * instead of nghttp2_nv as output parameter |nv_out|. Other than
353 * that return values and semantics are the same as
354 * nghttp2_hd_inflate_hd().
356 ssize_t nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater,
357 nghttp2_hd_nv *nv_out, int *inflate_flags,
358 const uint8_t *in, size_t inlen, int in_final);
360 /* For unittesting purpose */
361 int nghttp2_hd_emit_indname_block(nghttp2_bufs *bufs, size_t index,
362 nghttp2_nv *nv, int indexing_mode);
364 /* For unittesting purpose */
365 int nghttp2_hd_emit_newname_block(nghttp2_bufs *bufs, nghttp2_nv *nv,
368 /* For unittesting purpose */
369 int nghttp2_hd_emit_table_size(nghttp2_bufs *bufs, size_t table_size);
371 /* For unittesting purpose */
372 nghttp2_hd_nv nghttp2_hd_table_get(nghttp2_hd_context *context, size_t index);
374 /* For unittesting purpose */
375 ssize_t nghttp2_hd_decode_length(uint32_t *res, size_t *shift_ptr, int *final,
376 uint32_t initial, size_t shift, uint8_t *in,
377 uint8_t *last, size_t prefix);
379 /* Huffman encoding/decoding functions */
382 * Counts the required bytes to encode |src| with length |len|.
384 * This function returns the number of required bytes to encode given
385 * data, including padding of prefix of terminal symbol code. This
386 * function always succeeds.
388 size_t nghttp2_hd_huff_encode_count(const uint8_t *src, size_t len);
391 * Encodes the given data |src| with length |srclen| to the |bufs|.
392 * This function expands extra buffers in |bufs| if necessary.
394 * This function returns 0 if it succeeds, or one of the following
395 * negative error codes:
399 * NGHTTP2_ERR_BUFFER_ERROR
400 * Out of buffer space.
402 int nghttp2_hd_huff_encode(nghttp2_bufs *bufs, const uint8_t *src,
405 void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx);
408 * Decodes the given data |src| with length |srclen|. The |ctx| must
409 * be initialized by nghttp2_hd_huff_decode_context_init(). The result
410 * will be written to |buf|. This function assumes that |buf| has the
411 * enough room to store the decoded byte string.
413 * The caller must set the |final| to nonzero if the given input is
416 * This function returns the number of read bytes from the |in|.
418 * If this function fails, it returns one of the following negative
423 * NGHTTP2_ERR_HEADER_COMP
424 * Decoding process has failed.
426 ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
427 nghttp2_buf *buf, const uint8_t *src,
428 size_t srclen, int final);
430 #endif /* NGHTTP2_HD_H */