blob: a0fc0f37c548a4ddf82609977b99906553595c38 [file] [log] [blame]
Willy Tarreau1be4f3d2017-09-21 14:35:57 +02001/*
2 * HPACK compressor (RFC7541)
3 *
4 * Copyright (C) 2014-2017 Willy Tarreau <willy@haproxy.org>
5 * Copyright (C) 2017 HAProxy Technologies
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining
8 * a copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sublicense, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be
16 * included in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 * OTHER DEALINGS IN THE SOFTWARE.
26 */
27
28#ifndef _COMMON_HPACK_ENC_H
29#define _COMMON_HPACK_ENC_H
30
31#include <stdint.h>
Willy Tarreau2df026f2018-12-11 09:03:07 +010032#include <common/buf.h>
Willy Tarreau1be4f3d2017-09-21 14:35:57 +020033#include <common/config.h>
34#include <common/ist.h>
35
Willy Tarreau83061a82018-07-13 11:56:34 +020036int hpack_encode_header(struct buffer *out, const struct ist n,
37 const struct ist v);
Willy Tarreau1be4f3d2017-09-21 14:35:57 +020038
Willy Tarreaubad0a382018-12-11 07:44:00 +010039/* Returns the number of bytes required to encode the string length <len>. The
40 * number of usable bits is an integral multiple of 7 plus 6 for the last byte.
41 * The maximum number of bytes returned is 4 (2097279 max length). Larger values
42 * return 0.
43 */
44static inline int hpack_len_to_bytes(size_t len)
45{
46 ssize_t slen = len;
47
48 slen -= 127;
49 if (__builtin_expect(slen < 0, 1))
50 return 1;
51 if (slen < (1 << 14)) {
52 if (__builtin_expect(slen < (1 << 7), 1))
53 return 2;
54 else
55 return 3;
56 }
57 if (slen < (1 << 21))
58 return 4;
59 return 0;
60}
61
62/* Encodes <len> into <out>+<pos> and return the new position. The caller is
63 * responsible for checking for available room using hpack_len_to_bytes()
64 * first.
65 */
66static inline int hpack_encode_len(char *out, int pos, int len)
67{
68 int code = len - 127;
69
70 if (code < 0) {
71 out[pos++] = len;
72 } else {
73 out[pos++] = 127;
74 for (; code >= 128; code >>= 7)
75 out[pos++] = code | 128;
76 out[pos++] = code;
77 }
78 return pos;
79}
80
Willy Tarreau30eb8092018-12-11 06:16:45 +010081/* Tries to encode header field index <idx> with short value <val> into the
82 * aligned buffer <out>. Returns non-zero on success, 0 on failure (buffer
83 * full). The caller is responsible for ensuring that the length of <val> is
84 * strictly lower than 127, and that <idx> is lower than 64 (static list only),
85 * and that the buffer is aligned (head==0).
86 */
87static inline int hpack_encode_short_idx(struct buffer *out, int idx, struct ist val)
88{
89 if (out->data + 2 + val.len > out->size)
90 return 0;
91
92 /* literal header field with incremental indexing */
93 out->area[out->data++] = idx | 0x40;
94 out->area[out->data++] = val.len;
95 ist2bin(&out->area[out->data], val);
96 out->data += val.len;
97 return 1;
98}
99
Willy Tarreau1be4f3d2017-09-21 14:35:57 +0200100#endif /* _COMMON_HPACK_ENC_H */