Mercurial > hg > nginx
annotate src/http/v3/ngx_http_v3_encode.c @ 9282:acb8548c00e9
HTTP/3: fixed dynamic table overflow.
While inserting a new entry into the dynamic table, first the entry is added,
and then older entries are evicted until table size is within capacity. After
the first step, the number of entries may temporarily exceed the maximum
calculated from capacity by one entry, which previously caused table overflow.
The easiest way to trigger the issue is to keep adding entries with empty names
and values until first eviction.
The issue was introduced by 987bee4363d1.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Tue, 28 May 2024 17:18:50 +0400 |
parents | 5c86189a1c1b |
children |
rev | line source |
---|---|
8215 | 1 |
2 /* | |
3 * Copyright (C) Roman Arutyunyan | |
4 * Copyright (C) Nginx, Inc. | |
5 */ | |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 #include <ngx_http.h> | |
11 | |
12 | |
13 uintptr_t | |
14 ngx_http_v3_encode_varlen_int(u_char *p, uint64_t value) | |
15 { | |
16 if (value <= 63) { | |
17 if (p == NULL) { | |
18 return 1; | |
19 } | |
20 | |
21 *p++ = value; | |
22 return (uintptr_t) p; | |
23 } | |
24 | |
25 if (value <= 16383) { | |
26 if (p == NULL) { | |
27 return 2; | |
28 } | |
29 | |
30 *p++ = 0x40 | (value >> 8); | |
31 *p++ = value; | |
32 return (uintptr_t) p; | |
33 } | |
34 | |
35 if (value <= 1073741823) { | |
36 if (p == NULL) { | |
8349
b13176e717ba
HTTP/3: fixed encoding variable-length integers.
Roman Arutyunyan <arut@nginx.com>
parents:
8226
diff
changeset
|
37 return 4; |
8215 | 38 } |
39 | |
8349
b13176e717ba
HTTP/3: fixed encoding variable-length integers.
Roman Arutyunyan <arut@nginx.com>
parents:
8226
diff
changeset
|
40 *p++ = 0x80 | (value >> 24); |
b13176e717ba
HTTP/3: fixed encoding variable-length integers.
Roman Arutyunyan <arut@nginx.com>
parents:
8226
diff
changeset
|
41 *p++ = (value >> 16); |
8215 | 42 *p++ = (value >> 8); |
43 *p++ = value; | |
44 return (uintptr_t) p; | |
45 } | |
46 | |
47 if (p == NULL) { | |
8349
b13176e717ba
HTTP/3: fixed encoding variable-length integers.
Roman Arutyunyan <arut@nginx.com>
parents:
8226
diff
changeset
|
48 return 8; |
8215 | 49 } |
50 | |
8349
b13176e717ba
HTTP/3: fixed encoding variable-length integers.
Roman Arutyunyan <arut@nginx.com>
parents:
8226
diff
changeset
|
51 *p++ = 0xc0 | (value >> 56); |
b13176e717ba
HTTP/3: fixed encoding variable-length integers.
Roman Arutyunyan <arut@nginx.com>
parents:
8226
diff
changeset
|
52 *p++ = (value >> 48); |
b13176e717ba
HTTP/3: fixed encoding variable-length integers.
Roman Arutyunyan <arut@nginx.com>
parents:
8226
diff
changeset
|
53 *p++ = (value >> 40); |
b13176e717ba
HTTP/3: fixed encoding variable-length integers.
Roman Arutyunyan <arut@nginx.com>
parents:
8226
diff
changeset
|
54 *p++ = (value >> 32); |
b13176e717ba
HTTP/3: fixed encoding variable-length integers.
Roman Arutyunyan <arut@nginx.com>
parents:
8226
diff
changeset
|
55 *p++ = (value >> 24); |
8215 | 56 *p++ = (value >> 16); |
57 *p++ = (value >> 8); | |
58 *p++ = value; | |
59 return (uintptr_t) p; | |
60 } | |
61 | |
62 | |
63 uintptr_t | |
64 ngx_http_v3_encode_prefix_int(u_char *p, uint64_t value, ngx_uint_t prefix) | |
65 { | |
66 ngx_uint_t thresh, n; | |
67 | |
68 thresh = (1 << prefix) - 1; | |
69 | |
70 if (value < thresh) { | |
71 if (p == NULL) { | |
72 return 1; | |
73 } | |
74 | |
75 *p++ |= value; | |
76 return (uintptr_t) p; | |
77 } | |
78 | |
79 value -= thresh; | |
80 | |
8455
b0e81f49d7c0
HTTP/3: fixed prefixed integer encoding and decoding.
Roman Arutyunyan <arut@nginx.com>
parents:
8349
diff
changeset
|
81 if (p == NULL) { |
b0e81f49d7c0
HTTP/3: fixed prefixed integer encoding and decoding.
Roman Arutyunyan <arut@nginx.com>
parents:
8349
diff
changeset
|
82 for (n = 2; value >= 128; n++) { |
b0e81f49d7c0
HTTP/3: fixed prefixed integer encoding and decoding.
Roman Arutyunyan <arut@nginx.com>
parents:
8349
diff
changeset
|
83 value >>= 7; |
8215 | 84 } |
85 | |
8455
b0e81f49d7c0
HTTP/3: fixed prefixed integer encoding and decoding.
Roman Arutyunyan <arut@nginx.com>
parents:
8349
diff
changeset
|
86 return n; |
8215 | 87 } |
88 | |
89 *p++ |= thresh; | |
90 | |
8455
b0e81f49d7c0
HTTP/3: fixed prefixed integer encoding and decoding.
Roman Arutyunyan <arut@nginx.com>
parents:
8349
diff
changeset
|
91 while (value >= 128) { |
b0e81f49d7c0
HTTP/3: fixed prefixed integer encoding and decoding.
Roman Arutyunyan <arut@nginx.com>
parents:
8349
diff
changeset
|
92 *p++ = 0x80 | value; |
b0e81f49d7c0
HTTP/3: fixed prefixed integer encoding and decoding.
Roman Arutyunyan <arut@nginx.com>
parents:
8349
diff
changeset
|
93 value >>= 7; |
8215 | 94 } |
95 | |
8455
b0e81f49d7c0
HTTP/3: fixed prefixed integer encoding and decoding.
Roman Arutyunyan <arut@nginx.com>
parents:
8349
diff
changeset
|
96 *p++ = value; |
8215 | 97 |
98 return (uintptr_t) p; | |
99 } | |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
100 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
101 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
102 uintptr_t |
8807
0ac25efb2da3
HTTP/3: quic-qpack term updates.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8534
diff
changeset
|
103 ngx_http_v3_encode_field_section_prefix(u_char *p, ngx_uint_t insert_count, |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
104 ngx_uint_t sign, ngx_uint_t delta_base) |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
105 { |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
106 if (p == NULL) { |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
107 return ngx_http_v3_encode_prefix_int(NULL, insert_count, 8) |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
108 + ngx_http_v3_encode_prefix_int(NULL, delta_base, 7); |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
109 } |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
110 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
111 *p = 0; |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
112 p = (u_char *) ngx_http_v3_encode_prefix_int(p, insert_count, 8); |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
113 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
114 *p = sign ? 0x80 : 0; |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
115 p = (u_char *) ngx_http_v3_encode_prefix_int(p, delta_base, 7); |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
116 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
117 return (uintptr_t) p; |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
118 } |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
119 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
120 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
121 uintptr_t |
8807
0ac25efb2da3
HTTP/3: quic-qpack term updates.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8534
diff
changeset
|
122 ngx_http_v3_encode_field_ri(u_char *p, ngx_uint_t dynamic, ngx_uint_t index) |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
123 { |
8807
0ac25efb2da3
HTTP/3: quic-qpack term updates.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8534
diff
changeset
|
124 /* Indexed Field Line */ |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
125 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
126 if (p == NULL) { |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
127 return ngx_http_v3_encode_prefix_int(NULL, index, 6); |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
128 } |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
129 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
130 *p = dynamic ? 0x80 : 0xc0; |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
131 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
132 return ngx_http_v3_encode_prefix_int(p, index, 6); |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
133 } |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
134 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
135 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
136 uintptr_t |
8807
0ac25efb2da3
HTTP/3: quic-qpack term updates.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8534
diff
changeset
|
137 ngx_http_v3_encode_field_lri(u_char *p, ngx_uint_t dynamic, ngx_uint_t index, |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
138 u_char *data, size_t len) |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
139 { |
8848
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
140 size_t hlen; |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
141 u_char *p1, *p2; |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
142 |
8807
0ac25efb2da3
HTTP/3: quic-qpack term updates.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8534
diff
changeset
|
143 /* Literal Field Line With Name Reference */ |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
144 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
145 if (p == NULL) { |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
146 return ngx_http_v3_encode_prefix_int(NULL, index, 4) |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
147 + ngx_http_v3_encode_prefix_int(NULL, len, 7) |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
148 + len; |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
149 } |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
150 |
8534
985f9351dd87
HTTP/3: do not set the never-indexed literal bit by default.
Roman Arutyunyan <arut@nginx.com>
parents:
8491
diff
changeset
|
151 *p = dynamic ? 0x40 : 0x50; |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
152 p = (u_char *) ngx_http_v3_encode_prefix_int(p, index, 4); |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
153 |
8848
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
154 p1 = p; |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
155 *p = 0; |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
156 p = (u_char *) ngx_http_v3_encode_prefix_int(p, len, 7); |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
157 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
158 if (data) { |
8848
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
159 p2 = p; |
8942
5c86189a1c1b
Merged with the default branch.
Ruslan Ermilov <ru@nginx.com>
parents:
8848
diff
changeset
|
160 hlen = ngx_http_huff_encode(data, len, p, 0); |
8848
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
161 |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
162 if (hlen) { |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
163 p = p1; |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
164 *p = 0x80; |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
165 p = (u_char *) ngx_http_v3_encode_prefix_int(p, hlen, 7); |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
166 |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
167 if (p != p2) { |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
168 ngx_memmove(p, p2, hlen); |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
169 } |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
170 |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
171 p += hlen; |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
172 |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
173 } else { |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
174 p = ngx_cpymem(p, data, len); |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
175 } |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
176 } |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
177 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
178 return (uintptr_t) p; |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
179 } |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
180 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
181 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
182 uintptr_t |
8807
0ac25efb2da3
HTTP/3: quic-qpack term updates.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8534
diff
changeset
|
183 ngx_http_v3_encode_field_l(u_char *p, ngx_str_t *name, ngx_str_t *value) |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
184 { |
8848
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
185 size_t hlen; |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
186 u_char *p1, *p2; |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
187 |
8807
0ac25efb2da3
HTTP/3: quic-qpack term updates.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8534
diff
changeset
|
188 /* Literal Field Line With Literal Name */ |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
189 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
190 if (p == NULL) { |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
191 return ngx_http_v3_encode_prefix_int(NULL, name->len, 3) |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
192 + name->len |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
193 + ngx_http_v3_encode_prefix_int(NULL, value->len, 7) |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
194 + value->len; |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
195 } |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
196 |
8848
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
197 p1 = p; |
8534
985f9351dd87
HTTP/3: do not set the never-indexed literal bit by default.
Roman Arutyunyan <arut@nginx.com>
parents:
8491
diff
changeset
|
198 *p = 0x20; |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
199 p = (u_char *) ngx_http_v3_encode_prefix_int(p, name->len, 3); |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
200 |
8848
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
201 p2 = p; |
8942
5c86189a1c1b
Merged with the default branch.
Ruslan Ermilov <ru@nginx.com>
parents:
8848
diff
changeset
|
202 hlen = ngx_http_huff_encode(name->data, name->len, p, 1); |
8848
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
203 |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
204 if (hlen) { |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
205 p = p1; |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
206 *p = 0x28; |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
207 p = (u_char *) ngx_http_v3_encode_prefix_int(p, hlen, 3); |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
208 |
8848
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
209 if (p != p2) { |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
210 ngx_memmove(p, p2, hlen); |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
211 } |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
212 |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
213 p += hlen; |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
214 |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
215 } else { |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
216 ngx_strlow(p, name->data, name->len); |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
217 p += name->len; |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
218 } |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
219 |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
220 p1 = p; |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
221 *p = 0; |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
222 p = (u_char *) ngx_http_v3_encode_prefix_int(p, value->len, 7); |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
223 |
8848
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
224 p2 = p; |
8942
5c86189a1c1b
Merged with the default branch.
Ruslan Ermilov <ru@nginx.com>
parents:
8848
diff
changeset
|
225 hlen = ngx_http_huff_encode(value->data, value->len, p, 0); |
8848
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
226 |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
227 if (hlen) { |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
228 p = p1; |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
229 *p = 0x80; |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
230 p = (u_char *) ngx_http_v3_encode_prefix_int(p, hlen, 7); |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
231 |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
232 if (p != p2) { |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
233 ngx_memmove(p, p2, hlen); |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
234 } |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
235 |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
236 p += hlen; |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
237 |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
238 } else { |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
239 p = ngx_cpymem(p, value->data, value->len); |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
240 } |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
241 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
242 return (uintptr_t) p; |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
243 } |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
244 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
245 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
246 uintptr_t |
8807
0ac25efb2da3
HTTP/3: quic-qpack term updates.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8534
diff
changeset
|
247 ngx_http_v3_encode_field_pbi(u_char *p, ngx_uint_t index) |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
248 { |
8807
0ac25efb2da3
HTTP/3: quic-qpack term updates.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8534
diff
changeset
|
249 /* Indexed Field Line With Post-Base Index */ |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
250 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
251 if (p == NULL) { |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
252 return ngx_http_v3_encode_prefix_int(NULL, index, 4); |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
253 } |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
254 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
255 *p = 0x10; |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
256 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
257 return ngx_http_v3_encode_prefix_int(p, index, 4); |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
258 } |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
259 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
260 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
261 uintptr_t |
8807
0ac25efb2da3
HTTP/3: quic-qpack term updates.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8534
diff
changeset
|
262 ngx_http_v3_encode_field_lpbi(u_char *p, ngx_uint_t index, u_char *data, |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
263 size_t len) |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
264 { |
8848
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
265 size_t hlen; |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
266 u_char *p1, *p2; |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
267 |
8807
0ac25efb2da3
HTTP/3: quic-qpack term updates.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8534
diff
changeset
|
268 /* Literal Field Line With Post-Base Name Reference */ |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
269 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
270 if (p == NULL) { |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
271 return ngx_http_v3_encode_prefix_int(NULL, index, 3) |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
272 + ngx_http_v3_encode_prefix_int(NULL, len, 7) |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
273 + len; |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
274 } |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
275 |
8534
985f9351dd87
HTTP/3: do not set the never-indexed literal bit by default.
Roman Arutyunyan <arut@nginx.com>
parents:
8491
diff
changeset
|
276 *p = 0; |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
277 p = (u_char *) ngx_http_v3_encode_prefix_int(p, index, 3); |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
278 |
8848
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
279 p1 = p; |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
280 *p = 0; |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
281 p = (u_char *) ngx_http_v3_encode_prefix_int(p, len, 7); |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
282 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
283 if (data) { |
8848
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
284 p2 = p; |
8942
5c86189a1c1b
Merged with the default branch.
Ruslan Ermilov <ru@nginx.com>
parents:
8848
diff
changeset
|
285 hlen = ngx_http_huff_encode(data, len, p, 0); |
8848
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
286 |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
287 if (hlen) { |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
288 p = p1; |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
289 *p = 0x80; |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
290 p = (u_char *) ngx_http_v3_encode_prefix_int(p, hlen, 7); |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
291 |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
292 if (p != p2) { |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
293 ngx_memmove(p, p2, hlen); |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
294 } |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
295 |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
296 p += hlen; |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
297 |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
298 } else { |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
299 p = ngx_cpymem(p, data, len); |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
300 } |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
301 } |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
302 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
303 return (uintptr_t) p; |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
304 } |