comparison src/http/v3/ngx_http_v3_encode.c @ 8848: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
8847:e29c1ede905f 8848: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 }