Mercurial > hg > nginx-quic
comparison src/http/v3/ngx_http_v3_encode.c @ 8610:b5a305db30e0 quic
HTTP/3: implemented QPACK Huffman encoding for response fields.
author | Sergey Kandaurov <pluknet@nginx.com> |
---|---|
date | Mon, 13 Sep 2021 16:25:08 +0300 |
parents | 0ac25efb2da3 |
children | 5c86189a1c1b |
comparison
equal
deleted
inserted
replaced
8609:e29c1ede905f | 8610:b5a305db30e0 |
---|---|
135 | 135 |
136 uintptr_t | 136 uintptr_t |
137 ngx_http_v3_encode_field_lri(u_char *p, ngx_uint_t dynamic, ngx_uint_t index, | 137 ngx_http_v3_encode_field_lri(u_char *p, ngx_uint_t dynamic, ngx_uint_t index, |
138 u_char *data, size_t len) | 138 u_char *data, size_t len) |
139 { | 139 { |
140 size_t hlen; | |
141 u_char *p1, *p2; | |
142 | |
140 /* Literal Field Line With Name Reference */ | 143 /* Literal Field Line With Name Reference */ |
141 | 144 |
142 if (p == NULL) { | 145 if (p == NULL) { |
143 return ngx_http_v3_encode_prefix_int(NULL, index, 4) | 146 return ngx_http_v3_encode_prefix_int(NULL, index, 4) |
144 + ngx_http_v3_encode_prefix_int(NULL, len, 7) | 147 + ngx_http_v3_encode_prefix_int(NULL, len, 7) |
146 } | 149 } |
147 | 150 |
148 *p = dynamic ? 0x40 : 0x50; | 151 *p = dynamic ? 0x40 : 0x50; |
149 p = (u_char *) ngx_http_v3_encode_prefix_int(p, index, 4); | 152 p = (u_char *) ngx_http_v3_encode_prefix_int(p, index, 4); |
150 | 153 |
154 p1 = p; | |
151 *p = 0; | 155 *p = 0; |
152 p = (u_char *) ngx_http_v3_encode_prefix_int(p, len, 7); | 156 p = (u_char *) ngx_http_v3_encode_prefix_int(p, len, 7); |
153 | 157 |
154 if (data) { | 158 if (data) { |
155 p = ngx_cpymem(p, data, len); | 159 p2 = p; |
160 hlen = ngx_http_v2_huff_encode(data, len, p, 0); | |
161 | |
162 if (hlen) { | |
163 p = p1; | |
164 *p = 0x80; | |
165 p = (u_char *) ngx_http_v3_encode_prefix_int(p, hlen, 7); | |
166 | |
167 if (p != p2) { | |
168 ngx_memmove(p, p2, hlen); | |
169 } | |
170 | |
171 p += hlen; | |
172 | |
173 } else { | |
174 p = ngx_cpymem(p, data, len); | |
175 } | |
156 } | 176 } |
157 | 177 |
158 return (uintptr_t) p; | 178 return (uintptr_t) p; |
159 } | 179 } |
160 | 180 |
161 | 181 |
162 uintptr_t | 182 uintptr_t |
163 ngx_http_v3_encode_field_l(u_char *p, ngx_str_t *name, ngx_str_t *value) | 183 ngx_http_v3_encode_field_l(u_char *p, ngx_str_t *name, ngx_str_t *value) |
164 { | 184 { |
185 size_t hlen; | |
186 u_char *p1, *p2; | |
187 | |
165 /* Literal Field Line With Literal Name */ | 188 /* Literal Field Line With Literal Name */ |
166 | 189 |
167 if (p == NULL) { | 190 if (p == NULL) { |
168 return ngx_http_v3_encode_prefix_int(NULL, name->len, 3) | 191 return ngx_http_v3_encode_prefix_int(NULL, name->len, 3) |
169 + name->len | 192 + name->len |
170 + ngx_http_v3_encode_prefix_int(NULL, value->len, 7) | 193 + ngx_http_v3_encode_prefix_int(NULL, value->len, 7) |
171 + value->len; | 194 + value->len; |
172 } | 195 } |
173 | 196 |
197 p1 = p; | |
174 *p = 0x20; | 198 *p = 0x20; |
175 p = (u_char *) ngx_http_v3_encode_prefix_int(p, name->len, 3); | 199 p = (u_char *) ngx_http_v3_encode_prefix_int(p, name->len, 3); |
176 | 200 |
177 ngx_strlow(p, name->data, name->len); | 201 p2 = p; |
178 p += name->len; | 202 hlen = ngx_http_v2_huff_encode(name->data, name->len, p, 1); |
179 | 203 |
204 if (hlen) { | |
205 p = p1; | |
206 *p = 0x28; | |
207 p = (u_char *) ngx_http_v3_encode_prefix_int(p, hlen, 3); | |
208 | |
209 if (p != p2) { | |
210 ngx_memmove(p, p2, hlen); | |
211 } | |
212 | |
213 p += hlen; | |
214 | |
215 } else { | |
216 ngx_strlow(p, name->data, name->len); | |
217 p += name->len; | |
218 } | |
219 | |
220 p1 = p; | |
180 *p = 0; | 221 *p = 0; |
181 p = (u_char *) ngx_http_v3_encode_prefix_int(p, value->len, 7); | 222 p = (u_char *) ngx_http_v3_encode_prefix_int(p, value->len, 7); |
182 | 223 |
183 p = ngx_cpymem(p, value->data, value->len); | 224 p2 = p; |
225 hlen = ngx_http_v2_huff_encode(value->data, value->len, p, 0); | |
226 | |
227 if (hlen) { | |
228 p = p1; | |
229 *p = 0x80; | |
230 p = (u_char *) ngx_http_v3_encode_prefix_int(p, hlen, 7); | |
231 | |
232 if (p != p2) { | |
233 ngx_memmove(p, p2, hlen); | |
234 } | |
235 | |
236 p += hlen; | |
237 | |
238 } else { | |
239 p = ngx_cpymem(p, value->data, value->len); | |
240 } | |
184 | 241 |
185 return (uintptr_t) p; | 242 return (uintptr_t) p; |
186 } | 243 } |
187 | 244 |
188 | 245 |
203 | 260 |
204 uintptr_t | 261 uintptr_t |
205 ngx_http_v3_encode_field_lpbi(u_char *p, ngx_uint_t index, u_char *data, | 262 ngx_http_v3_encode_field_lpbi(u_char *p, ngx_uint_t index, u_char *data, |
206 size_t len) | 263 size_t len) |
207 { | 264 { |
265 size_t hlen; | |
266 u_char *p1, *p2; | |
267 | |
208 /* Literal Field Line With Post-Base Name Reference */ | 268 /* Literal Field Line With Post-Base Name Reference */ |
209 | 269 |
210 if (p == NULL) { | 270 if (p == NULL) { |
211 return ngx_http_v3_encode_prefix_int(NULL, index, 3) | 271 return ngx_http_v3_encode_prefix_int(NULL, index, 3) |
212 + ngx_http_v3_encode_prefix_int(NULL, len, 7) | 272 + ngx_http_v3_encode_prefix_int(NULL, len, 7) |
214 } | 274 } |
215 | 275 |
216 *p = 0; | 276 *p = 0; |
217 p = (u_char *) ngx_http_v3_encode_prefix_int(p, index, 3); | 277 p = (u_char *) ngx_http_v3_encode_prefix_int(p, index, 3); |
218 | 278 |
279 p1 = p; | |
219 *p = 0; | 280 *p = 0; |
220 p = (u_char *) ngx_http_v3_encode_prefix_int(p, len, 7); | 281 p = (u_char *) ngx_http_v3_encode_prefix_int(p, len, 7); |
221 | 282 |
222 if (data) { | 283 if (data) { |
223 p = ngx_cpymem(p, data, len); | 284 p2 = p; |
224 } | 285 hlen = ngx_http_v2_huff_encode(data, len, p, 0); |
225 | 286 |
226 return (uintptr_t) p; | 287 if (hlen) { |
227 } | 288 p = p1; |
289 *p = 0x80; | |
290 p = (u_char *) ngx_http_v3_encode_prefix_int(p, hlen, 7); | |
291 | |
292 if (p != p2) { | |
293 ngx_memmove(p, p2, hlen); | |
294 } | |
295 | |
296 p += hlen; | |
297 | |
298 } else { | |
299 p = ngx_cpymem(p, data, len); | |
300 } | |
301 } | |
302 | |
303 return (uintptr_t) p; | |
304 } |