Mercurial > hg > nginx-quic
annotate src/http/v3/ngx_http_v3_parse.c @ 7949:032cb35ce758 quic
HTTP/3: http3_max_field_size directive to limit string size.
Client streams may send literal strings which are now limited in size by the
new directive. The default value is 4096.
The directive is similar to HTTP/2 directive http2_max_field_size.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Mon, 29 Jun 2020 15:56:14 +0300 |
parents | 5649079a41f4 |
children | b0e81f49d7c0 |
rev | line source |
---|---|
7692 | 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 ngx_int_t | |
14 ngx_http_v3_parse_varlen_int(ngx_connection_t *c, | |
15 ngx_http_v3_parse_varlen_int_t *st, u_char ch) | |
16 { | |
17 enum { | |
18 sw_start = 0, | |
19 sw_length_2, | |
20 sw_length_3, | |
21 sw_length_4, | |
22 sw_length_5, | |
23 sw_length_6, | |
24 sw_length_7, | |
25 sw_length_8 | |
26 }; | |
27 | |
28 switch (st->state) { | |
29 | |
30 case sw_start: | |
31 | |
32 st->value = ch; | |
33 if (st->value & 0xc0) { | |
34 st->state = sw_length_2; | |
35 break; | |
36 } | |
37 | |
38 goto done; | |
39 | |
40 case sw_length_2: | |
41 | |
42 st->value = (st->value << 8) + ch; | |
43 if ((st->value & 0xc000) == 0x4000) { | |
44 st->value &= 0x3fff; | |
45 goto done; | |
46 } | |
47 | |
48 st->state = sw_length_3; | |
49 break; | |
50 | |
51 case sw_length_4: | |
52 | |
53 st->value = (st->value << 8) + ch; | |
54 if ((st->value & 0xc0000000) == 0x80000000) { | |
55 st->value &= 0x3fffffff; | |
56 goto done; | |
57 } | |
58 | |
59 st->state = sw_length_5; | |
60 break; | |
61 | |
62 case sw_length_3: | |
63 case sw_length_5: | |
64 case sw_length_6: | |
65 case sw_length_7: | |
66 | |
67 st->value = (st->value << 8) + ch; | |
68 st->state++; | |
69 break; | |
70 | |
71 case sw_length_8: | |
72 | |
73 st->value = (st->value << 8) + ch; | |
74 st->value &= 0x3fffffffffffffff; | |
75 goto done; | |
76 } | |
77 | |
78 return NGX_AGAIN; | |
79 | |
80 done: | |
81 | |
82 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
83 "http3 parse varlen int %uL", st->value); | |
84 | |
85 st->state = sw_start; | |
86 return NGX_DONE; | |
87 } | |
88 | |
89 | |
90 ngx_int_t | |
91 ngx_http_v3_parse_prefix_int(ngx_connection_t *c, | |
92 ngx_http_v3_parse_prefix_int_t *st, ngx_uint_t prefix, u_char ch) | |
93 { | |
94 enum { | |
95 sw_start = 0, | |
96 sw_value | |
97 }; | |
98 | |
99 switch (st->state) { | |
100 | |
101 case sw_start: | |
102 | |
103 st->mask = (1 << prefix) - 1; | |
104 st->value = (ch & st->mask); | |
105 | |
106 if (st->value != st->mask) { | |
107 goto done; | |
108 } | |
109 | |
110 st->value = 0; | |
111 st->state = sw_value; | |
112 break; | |
113 | |
114 case sw_value: | |
115 | |
116 st->value = (st->value << 7) + (ch & 0x7f); | |
117 if (ch & 0x80) { | |
118 break; | |
119 } | |
120 | |
121 st->value += st->mask; | |
122 goto done; | |
123 } | |
124 | |
125 return NGX_AGAIN; | |
126 | |
127 done: | |
128 | |
129 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
130 "http3 parse prefix int %uL", st->value); | |
131 | |
132 st->state = sw_start; | |
133 return NGX_DONE; | |
134 } | |
135 | |
136 | |
137 ngx_int_t | |
138 ngx_http_v3_parse_headers(ngx_connection_t *c, ngx_http_v3_parse_headers_t *st, | |
139 u_char ch) | |
140 { | |
141 ngx_int_t rc; | |
142 enum { | |
143 sw_start = 0, | |
144 sw_length, | |
145 sw_prefix, | |
146 sw_header_rep, | |
147 sw_done | |
148 }; | |
149 | |
150 switch (st->state) { | |
151 | |
152 case sw_start: | |
153 | |
154 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse headers"); | |
155 | |
156 if (ch != NGX_HTTP_V3_FRAME_HEADERS) { | |
157 return NGX_ERROR; | |
158 } | |
159 | |
160 st->state = sw_length; | |
161 break; | |
162 | |
163 case sw_length: | |
164 | |
165 if (ngx_http_v3_parse_varlen_int(c, &st->vlint, ch) != NGX_DONE) { | |
166 break; | |
167 } | |
168 | |
169 st->length = st->vlint.value; | |
170 | |
171 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
172 "http3 parse headers len:%ui", st->length); | |
173 | |
174 st->state = sw_prefix; | |
175 break; | |
176 | |
177 case sw_prefix: | |
178 | |
179 if (st->length-- == 0) { | |
180 return NGX_ERROR; | |
181 } | |
182 | |
183 rc = ngx_http_v3_parse_header_block_prefix(c, &st->prefix, ch); | |
184 | |
185 if (rc == NGX_ERROR) { | |
186 return NGX_ERROR; | |
187 } | |
188 | |
189 if (rc != NGX_DONE) { | |
190 break; | |
191 } | |
192 | |
193 if (st->length == 0) { | |
194 return NGX_ERROR; | |
195 } | |
196 | |
197 st->state = sw_header_rep; | |
198 break; | |
199 | |
200 case sw_header_rep: | |
201 | |
202 rc = ngx_http_v3_parse_header_rep(c, &st->header_rep, st->prefix.base, | |
203 ch); | |
204 | |
205 if (rc == NGX_ERROR) { | |
206 return NGX_ERROR; | |
207 } | |
208 | |
209 if (--st->length == 0) { | |
210 if (rc != NGX_DONE) { | |
211 return NGX_ERROR; | |
212 } | |
213 | |
214 goto done; | |
215 } | |
216 | |
217 if (rc == NGX_DONE) { | |
218 return NGX_OK; | |
219 } | |
220 | |
221 break; | |
222 } | |
223 | |
224 return NGX_AGAIN; | |
225 | |
226 done: | |
227 | |
228 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse headers done"); | |
229 | |
230 st->state = sw_start; | |
231 return NGX_DONE; | |
232 } | |
233 | |
234 | |
235 ngx_int_t | |
236 ngx_http_v3_parse_header_block_prefix(ngx_connection_t *c, | |
237 ngx_http_v3_parse_header_block_prefix_t *st, u_char ch) | |
238 { | |
239 enum { | |
240 sw_start = 0, | |
241 sw_req_insert_count, | |
242 sw_delta_base, | |
243 sw_read_delta_base | |
244 }; | |
245 | |
246 switch (st->state) { | |
247 | |
248 case sw_start: | |
249 | |
250 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
251 "http3 parse header block prefix"); | |
252 | |
253 st->state = sw_req_insert_count; | |
254 | |
255 /* fall through */ | |
256 | |
257 case sw_req_insert_count: | |
258 | |
259 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 8, ch) != NGX_DONE) { | |
260 break; | |
261 } | |
262 | |
263 st->insert_count = st->pint.value; | |
264 st->state = sw_delta_base; | |
265 break; | |
266 | |
267 case sw_delta_base: | |
268 | |
269 st->sign = (ch & 0x80) ? 1 : 0; | |
270 st->state = sw_read_delta_base; | |
271 | |
272 /* fall through */ | |
273 | |
274 case sw_read_delta_base: | |
275 | |
276 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 7, ch) != NGX_DONE) { | |
277 break; | |
278 } | |
279 | |
280 st->delta_base = st->pint.value; | |
281 goto done; | |
282 } | |
283 | |
284 return NGX_AGAIN; | |
285 | |
286 done: | |
287 | |
288 if (st->sign) { | |
289 st->base = st->insert_count - st->delta_base - 1; | |
290 } else { | |
291 st->base = st->insert_count + st->delta_base; | |
292 } | |
293 | |
294 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
295 "http3 parse header block prefix done " | |
296 "i:%ui, s:%ui, d:%ui, base:%uL", | |
297 st->insert_count, st->sign, st->delta_base, st->base); | |
298 | |
299 st->state = sw_start; | |
300 return NGX_DONE; | |
301 } | |
302 | |
303 | |
304 ngx_int_t | |
305 ngx_http_v3_parse_header_rep(ngx_connection_t *c, | |
306 ngx_http_v3_parse_header_rep_t *st, ngx_uint_t base, u_char ch) | |
307 { | |
308 ngx_int_t rc; | |
309 enum { | |
310 sw_start = 0, | |
311 sw_header_ri, | |
312 sw_header_lri, | |
313 sw_header_l, | |
314 sw_header_pbi, | |
315 sw_header_lpbi | |
316 }; | |
317 | |
318 if (st->state == sw_start) { | |
319 | |
320 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
321 "http3 parse header representation"); | |
322 | |
323 ngx_memzero(&st->header, sizeof(ngx_http_v3_parse_header_t)); | |
324 | |
325 st->header.base = base; | |
326 | |
327 if (ch & 0x80) { | |
328 /* Indexed Header Field */ | |
329 | |
330 st->state = sw_header_ri; | |
331 | |
332 } else if (ch & 0x40) { | |
333 /* Literal Header Field With Name Reference */ | |
334 | |
335 st->state = sw_header_lri; | |
336 | |
337 } else if (ch & 0x20) { | |
338 /* Literal Header Field Without Name Reference */ | |
339 | |
340 st->state = sw_header_l; | |
341 | |
342 } else if (ch & 0x10) { | |
343 /* Indexed Header Field With Post-Base Index */ | |
344 | |
345 st->state = sw_header_pbi; | |
346 | |
347 } else { | |
348 /* Literal Header Field With Post-Base Name Reference */ | |
349 | |
350 st->state = sw_header_lpbi; | |
351 } | |
352 } | |
353 | |
354 switch (st->state) { | |
355 | |
356 case sw_header_ri: | |
357 rc = ngx_http_v3_parse_header_ri(c, &st->header, ch); | |
358 break; | |
359 | |
360 case sw_header_lri: | |
361 rc = ngx_http_v3_parse_header_lri(c, &st->header, ch); | |
362 break; | |
363 | |
364 case sw_header_l: | |
365 rc = ngx_http_v3_parse_header_l(c, &st->header, ch); | |
366 break; | |
367 | |
368 case sw_header_pbi: | |
369 rc = ngx_http_v3_parse_header_pbi(c, &st->header, ch); | |
370 break; | |
371 | |
372 case sw_header_lpbi: | |
373 rc = ngx_http_v3_parse_header_lpbi(c, &st->header, ch); | |
374 break; | |
375 | |
376 default: | |
377 rc = NGX_OK; | |
378 } | |
379 | |
380 if (rc == NGX_ERROR) { | |
381 return NGX_ERROR; | |
382 } | |
383 | |
384 if (rc == NGX_AGAIN) { | |
385 return NGX_AGAIN; | |
386 } | |
387 | |
388 /* rc == NGX_DONE */ | |
389 | |
390 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
391 "http3 parse header representation done"); | |
392 | |
393 st->state = sw_start; | |
394 return NGX_DONE; | |
395 } | |
396 | |
397 | |
398 ngx_int_t | |
399 ngx_http_v3_parse_literal(ngx_connection_t *c, ngx_http_v3_parse_literal_t *st, | |
400 u_char ch) | |
401 { | |
7949
032cb35ce758
HTTP/3: http3_max_field_size directive to limit string size.
Roman Arutyunyan <arut@nginx.com>
parents:
7761
diff
changeset
|
402 ngx_uint_t n; |
032cb35ce758
HTTP/3: http3_max_field_size directive to limit string size.
Roman Arutyunyan <arut@nginx.com>
parents:
7761
diff
changeset
|
403 ngx_http_v3_srv_conf_t *v3cf; |
7692 | 404 enum { |
405 sw_start = 0, | |
406 sw_value | |
407 }; | |
408 | |
409 switch (st->state) { | |
410 | |
411 case sw_start: | |
412 | |
413 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
414 "http3 parse literal huff:%ui, len:%ui", | |
415 st->huffman, st->length); | |
416 | |
417 n = st->length; | |
418 | |
7949
032cb35ce758
HTTP/3: http3_max_field_size directive to limit string size.
Roman Arutyunyan <arut@nginx.com>
parents:
7761
diff
changeset
|
419 v3cf = ngx_http_v3_get_module_srv_conf(c, ngx_http_v3_module); |
032cb35ce758
HTTP/3: http3_max_field_size directive to limit string size.
Roman Arutyunyan <arut@nginx.com>
parents:
7761
diff
changeset
|
420 |
032cb35ce758
HTTP/3: http3_max_field_size directive to limit string size.
Roman Arutyunyan <arut@nginx.com>
parents:
7761
diff
changeset
|
421 if (n > v3cf->max_field_size) { |
032cb35ce758
HTTP/3: http3_max_field_size directive to limit string size.
Roman Arutyunyan <arut@nginx.com>
parents:
7761
diff
changeset
|
422 ngx_log_error(NGX_LOG_ERR, c->log, 0, |
032cb35ce758
HTTP/3: http3_max_field_size directive to limit string size.
Roman Arutyunyan <arut@nginx.com>
parents:
7761
diff
changeset
|
423 "client exceeded http3_max_field_size limit"); |
032cb35ce758
HTTP/3: http3_max_field_size directive to limit string size.
Roman Arutyunyan <arut@nginx.com>
parents:
7761
diff
changeset
|
424 return NGX_ERROR; |
032cb35ce758
HTTP/3: http3_max_field_size directive to limit string size.
Roman Arutyunyan <arut@nginx.com>
parents:
7761
diff
changeset
|
425 } |
032cb35ce758
HTTP/3: http3_max_field_size directive to limit string size.
Roman Arutyunyan <arut@nginx.com>
parents:
7761
diff
changeset
|
426 |
7692 | 427 if (st->huffman) { |
428 n = n * 8 / 5; | |
429 st->huffstate = 0; | |
430 } | |
431 | |
432 st->last = ngx_pnalloc(c->pool, n + 1); | |
433 if (st->last == NULL) { | |
434 return NGX_ERROR; | |
435 } | |
436 | |
437 st->value.data = st->last; | |
438 st->state = sw_value; | |
439 | |
440 /* fall through */ | |
441 | |
442 case sw_value: | |
443 | |
444 if (st->huffman) { | |
445 if (ngx_http_v2_huff_decode(&st->huffstate, &ch, 1, &st->last, | |
446 st->length == 1, c->log) | |
447 != NGX_OK) | |
448 { | |
449 return NGX_ERROR; | |
450 } | |
451 | |
452 } else { | |
453 *st->last++ = ch; | |
454 } | |
455 | |
456 if (--st->length) { | |
457 break; | |
458 } | |
459 | |
460 st->value.len = st->last - st->value.data; | |
461 *st->last = '\0'; | |
462 goto done; | |
463 } | |
464 | |
465 return NGX_AGAIN; | |
466 | |
467 done: | |
468 | |
469 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
470 "http3 parse literal done \"%V\"", &st->value); | |
471 | |
472 st->state = sw_start; | |
473 return NGX_DONE; | |
474 } | |
475 | |
476 | |
477 ngx_int_t | |
478 ngx_http_v3_parse_header_ri(ngx_connection_t *c, ngx_http_v3_parse_header_t *st, | |
479 u_char ch) | |
480 { | |
481 ngx_http_v3_header_t *h; | |
482 enum { | |
483 sw_start = 0, | |
484 sw_index | |
485 }; | |
486 | |
487 switch (st->state) { | |
488 | |
489 case sw_start: | |
490 | |
491 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse header ri"); | |
492 | |
493 st->dynamic = (ch & 0x40) ? 0 : 1; | |
494 st->state = sw_index; | |
495 | |
496 /* fall through */ | |
497 | |
498 case sw_index: | |
499 | |
500 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 6, ch) != NGX_DONE) { | |
501 break; | |
502 } | |
503 | |
504 st->index = st->pint.value; | |
505 goto done; | |
506 } | |
507 | |
508 return NGX_AGAIN; | |
509 | |
510 done: | |
511 | |
512 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
513 "http3 parse header ri done %s%ui]", | |
514 st->dynamic ? "dynamic[-" : "static[", st->index); | |
515 | |
516 if (st->dynamic) { | |
517 st->index = st->base - st->index - 1; | |
518 } | |
519 | |
520 h = ngx_http_v3_lookup_table(c, st->dynamic, st->index); | |
521 if (h == NULL) { | |
522 return NGX_ERROR; | |
523 } | |
524 | |
525 st->name = h->name; | |
526 st->value = h->value; | |
527 st->state = sw_start; | |
528 | |
529 return NGX_DONE; | |
530 } | |
531 | |
532 | |
533 ngx_int_t | |
534 ngx_http_v3_parse_header_lri(ngx_connection_t *c, | |
535 ngx_http_v3_parse_header_t *st, u_char ch) | |
536 { | |
537 ngx_int_t rc; | |
538 ngx_http_v3_header_t *h; | |
539 enum { | |
540 sw_start = 0, | |
541 sw_index, | |
542 sw_value_len, | |
543 sw_read_value_len, | |
544 sw_value | |
545 }; | |
546 | |
547 switch (st->state) { | |
548 | |
549 case sw_start: | |
550 | |
551 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse header lri"); | |
552 | |
553 st->dynamic = (ch & 0x10) ? 0 : 1; | |
554 st->state = sw_index; | |
555 | |
556 /* fall through */ | |
557 | |
558 case sw_index: | |
559 | |
560 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 4, ch) != NGX_DONE) { | |
561 break; | |
562 } | |
563 | |
564 st->index = st->pint.value; | |
565 st->state = sw_value_len; | |
566 break; | |
567 | |
568 case sw_value_len: | |
569 | |
570 st->literal.huffman = (ch & 0x80) ? 1 : 0; | |
571 st->state = sw_read_value_len; | |
572 | |
573 /* fall through */ | |
574 | |
575 case sw_read_value_len: | |
576 | |
577 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 7, ch) != NGX_DONE) { | |
578 break; | |
579 } | |
580 | |
581 st->literal.length = st->pint.value; | |
582 if (st->literal.length == 0) { | |
583 goto done; | |
584 } | |
585 | |
586 st->state = sw_value; | |
587 break; | |
588 | |
589 case sw_value: | |
590 | |
591 rc = ngx_http_v3_parse_literal(c, &st->literal, ch); | |
592 | |
593 if (rc == NGX_ERROR) { | |
594 return NGX_ERROR; | |
595 } | |
596 | |
597 if (rc == NGX_DONE) { | |
598 st->value = st->literal.value; | |
599 goto done; | |
600 } | |
601 | |
602 break; | |
603 } | |
604 | |
605 return NGX_AGAIN; | |
606 | |
607 done: | |
608 | |
609 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
610 "http3 parse header lri done %s%ui] \"%V\"", | |
611 st->dynamic ? "dynamic[-" : "static[", | |
612 st->index, &st->value); | |
613 | |
614 if (st->dynamic) { | |
615 st->index = st->base - st->index - 1; | |
616 } | |
617 | |
618 h = ngx_http_v3_lookup_table(c, st->dynamic, st->index); | |
619 if (h == NULL) { | |
620 return NGX_ERROR; | |
621 } | |
622 | |
623 st->name = h->name; | |
624 st->state = sw_start; | |
625 return NGX_DONE; | |
626 } | |
627 | |
628 | |
629 ngx_int_t | |
630 ngx_http_v3_parse_header_l(ngx_connection_t *c, | |
631 ngx_http_v3_parse_header_t *st, u_char ch) | |
632 { | |
633 ngx_int_t rc; | |
634 enum { | |
635 sw_start = 0, | |
636 sw_name_len, | |
637 sw_name, | |
638 sw_value_len, | |
639 sw_read_value_len, | |
640 sw_value | |
641 }; | |
642 | |
643 switch (st->state) { | |
644 | |
645 case sw_start: | |
646 | |
647 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse header l"); | |
648 | |
649 st->literal.huffman = (ch & 0x08) ? 1 : 0; | |
650 st->state = sw_name_len; | |
651 | |
652 /* fall through */ | |
653 | |
654 case sw_name_len: | |
655 | |
656 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 3, ch) != NGX_DONE) { | |
657 break; | |
658 } | |
659 | |
660 st->literal.length = st->pint.value; | |
661 if (st->literal.length == 0) { | |
662 return NGX_ERROR; | |
663 } | |
664 | |
665 st->state = sw_name; | |
666 break; | |
667 | |
668 case sw_name: | |
669 | |
670 rc = ngx_http_v3_parse_literal(c, &st->literal, ch); | |
671 | |
672 if (rc == NGX_ERROR) { | |
673 return NGX_ERROR; | |
674 } | |
675 | |
676 if (rc == NGX_DONE) { | |
677 st->name = st->literal.value; | |
678 st->state = sw_value_len; | |
679 } | |
680 | |
681 break; | |
682 | |
683 case sw_value_len: | |
684 | |
685 st->literal.huffman = (ch & 0x80) ? 1 : 0; | |
686 st->state = sw_read_value_len; | |
687 | |
688 /* fall through */ | |
689 | |
690 case sw_read_value_len: | |
691 | |
692 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 7, ch) != NGX_DONE) { | |
693 break; | |
694 } | |
695 | |
696 st->literal.length = st->pint.value; | |
697 if (st->literal.length == 0) { | |
698 goto done; | |
699 } | |
700 | |
701 st->state = sw_value; | |
702 break; | |
703 | |
704 case sw_value: | |
705 | |
706 rc = ngx_http_v3_parse_literal(c, &st->literal, ch); | |
707 | |
708 if (rc == NGX_ERROR) { | |
709 return NGX_ERROR; | |
710 } | |
711 | |
712 if (rc == NGX_DONE) { | |
713 st->value = st->literal.value; | |
714 goto done; | |
715 } | |
716 | |
717 break; | |
718 } | |
719 | |
720 return NGX_AGAIN; | |
721 | |
722 done: | |
723 | |
724 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
725 "http3 parse header l done \"%V\" \"%V\"", | |
726 &st->name, &st->value); | |
727 | |
728 st->state = sw_start; | |
729 return NGX_DONE; | |
730 } | |
731 | |
732 | |
733 ngx_int_t | |
734 ngx_http_v3_parse_header_pbi(ngx_connection_t *c, | |
735 ngx_http_v3_parse_header_t *st, u_char ch) | |
736 { | |
737 ngx_http_v3_header_t *h; | |
738 enum { | |
739 sw_start = 0, | |
740 sw_index | |
741 }; | |
742 | |
743 switch (st->state) { | |
744 | |
745 case sw_start: | |
746 | |
747 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse header pbi"); | |
748 | |
749 st->state = sw_index; | |
750 | |
751 /* fall through */ | |
752 | |
753 case sw_index: | |
754 | |
755 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 4, ch) != NGX_DONE) { | |
756 break; | |
757 } | |
758 | |
759 st->index = st->pint.value; | |
760 goto done; | |
761 } | |
762 | |
763 return NGX_AGAIN; | |
764 | |
765 done: | |
766 | |
767 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
768 "http3 parse header pbi done dynamic[+%ui]", st->index); | |
769 | |
770 h = ngx_http_v3_lookup_table(c, 1, st->base + st->index); | |
771 if (h == NULL) { | |
772 return NGX_ERROR; | |
773 } | |
774 | |
775 st->name = h->name; | |
776 st->value = h->value; | |
777 st->state = sw_start; | |
778 return NGX_DONE; | |
779 } | |
780 | |
781 | |
782 ngx_int_t | |
783 ngx_http_v3_parse_header_lpbi(ngx_connection_t *c, | |
784 ngx_http_v3_parse_header_t *st, u_char ch) | |
785 { | |
786 ngx_int_t rc; | |
787 ngx_http_v3_header_t *h; | |
788 enum { | |
789 sw_start = 0, | |
790 sw_index, | |
791 sw_value_len, | |
792 sw_read_value_len, | |
793 sw_value | |
794 }; | |
795 | |
796 switch (st->state) { | |
797 | |
798 case sw_start: | |
799 | |
800 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
801 "http3 parse header lpbi"); | |
802 | |
803 st->state = sw_index; | |
804 | |
805 /* fall through */ | |
806 | |
807 case sw_index: | |
808 | |
809 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 3, ch) != NGX_DONE) { | |
810 break; | |
811 } | |
812 | |
813 st->index = st->pint.value; | |
814 st->state = sw_value_len; | |
815 break; | |
816 | |
817 case sw_value_len: | |
818 | |
819 st->literal.huffman = (ch & 0x80) ? 1 : 0; | |
820 st->state = sw_read_value_len; | |
821 | |
822 /* fall through */ | |
823 | |
824 case sw_read_value_len: | |
825 | |
826 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 7, ch) != NGX_DONE) { | |
827 break; | |
828 } | |
829 | |
830 st->literal.length = st->pint.value; | |
831 if (st->literal.length == 0) { | |
832 goto done; | |
833 } | |
834 | |
835 st->state = sw_value; | |
836 break; | |
837 | |
838 case sw_value: | |
839 | |
840 rc = ngx_http_v3_parse_literal(c, &st->literal, ch); | |
841 | |
842 if (rc == NGX_ERROR) { | |
843 return NGX_ERROR; | |
844 } | |
845 | |
846 if (rc == NGX_DONE) { | |
847 st->value = st->literal.value; | |
848 goto done; | |
849 } | |
850 | |
851 break; | |
852 } | |
853 | |
854 return NGX_AGAIN; | |
855 | |
856 done: | |
857 | |
858 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
859 "http3 parse header lpbi done dynamic[+%ui] \"%V\"", | |
860 st->index, &st->value); | |
861 | |
862 h = ngx_http_v3_lookup_table(c, 1, st->base + st->index); | |
863 if (h == NULL) { | |
864 return NGX_ERROR; | |
865 } | |
866 | |
867 st->name = h->name; | |
868 st->state = sw_start; | |
869 return NGX_DONE; | |
870 } | |
871 | |
872 | |
873 ngx_int_t | |
874 ngx_http_v3_parse_control(ngx_connection_t *c, void *data, u_char ch) | |
875 { | |
876 ngx_http_v3_parse_control_t *st = data; | |
877 | |
878 ngx_int_t rc; | |
879 enum { | |
880 sw_start = 0, | |
881 sw_type, | |
882 sw_length, | |
883 sw_settings, | |
884 sw_max_push_id, | |
885 sw_skip | |
886 }; | |
887 | |
888 switch (st->state) { | |
889 | |
890 case sw_start: | |
891 | |
892 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse control"); | |
893 | |
894 st->state = sw_type; | |
895 | |
896 /* fall through */ | |
897 | |
898 case sw_type: | |
899 | |
900 if (ngx_http_v3_parse_varlen_int(c, &st->vlint, ch) != NGX_DONE) { | |
901 break; | |
902 } | |
903 | |
904 st->type = st->vlint.value; | |
905 | |
906 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
907 "http3 parse frame type:%ui", st->type); | |
908 | |
909 st->state = sw_length; | |
910 break; | |
911 | |
912 case sw_length: | |
913 | |
914 if (ngx_http_v3_parse_varlen_int(c, &st->vlint, ch) != NGX_DONE) { | |
915 break; | |
916 } | |
917 | |
918 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
919 "http3 parse frame len:%uL", st->vlint.value); | |
920 | |
921 st->length = st->vlint.value; | |
922 if (st->length == 0) { | |
923 st->state = sw_type; | |
924 break; | |
925 } | |
926 | |
927 switch (st->type) { | |
928 | |
929 case NGX_HTTP_V3_FRAME_SETTINGS: | |
930 st->state = sw_settings; | |
931 break; | |
932 | |
933 case NGX_HTTP_V3_FRAME_MAX_PUSH_ID: | |
934 st->state = sw_max_push_id; | |
935 break; | |
936 | |
937 default: | |
938 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
939 "http3 parse skip unknown frame"); | |
940 st->state = sw_skip; | |
941 } | |
942 | |
943 break; | |
944 | |
945 case sw_settings: | |
946 | |
947 rc = ngx_http_v3_parse_settings(c, &st->settings, ch); | |
948 | |
949 if (rc == NGX_ERROR) { | |
950 return NGX_ERROR; | |
951 } | |
952 | |
953 if (--st->length > 0) { | |
954 break; | |
955 } | |
956 | |
957 if (rc != NGX_DONE) { | |
958 return NGX_ERROR; | |
959 } | |
960 | |
961 st->state = sw_type; | |
962 break; | |
963 | |
964 case sw_max_push_id: | |
965 | |
966 if (ngx_http_v3_parse_varlen_int(c, &st->vlint, ch) != NGX_DONE) { | |
967 break; | |
968 } | |
969 | |
970 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
971 "http3 parse MAX_PUSH_ID:%uL", st->vlint.value); | |
972 | |
973 st->state = sw_type; | |
974 break; | |
975 | |
976 case sw_skip: | |
977 | |
978 if (--st->length == 0) { | |
979 st->state = sw_type; | |
980 } | |
981 | |
982 break; | |
983 } | |
984 | |
985 return NGX_AGAIN; | |
986 } | |
987 | |
988 | |
989 ngx_int_t | |
990 ngx_http_v3_parse_settings(ngx_connection_t *c, | |
991 ngx_http_v3_parse_settings_t *st, u_char ch) | |
992 { | |
993 enum { | |
994 sw_start = 0, | |
995 sw_id, | |
996 sw_value | |
997 }; | |
998 | |
999 switch (st->state) { | |
1000 | |
1001 case sw_start: | |
1002 | |
1003 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse settings"); | |
1004 | |
1005 st->state = sw_id; | |
1006 | |
1007 /* fall through */ | |
1008 | |
1009 case sw_id: | |
1010 | |
1011 if (ngx_http_v3_parse_varlen_int(c, &st->vlint, ch) != NGX_DONE) { | |
1012 break; | |
1013 } | |
1014 | |
1015 st->id = st->vlint.value; | |
1016 st->state = sw_value; | |
1017 break; | |
1018 | |
1019 case sw_value: | |
1020 | |
1021 if (ngx_http_v3_parse_varlen_int(c, &st->vlint, ch) != NGX_DONE) { | |
1022 break; | |
1023 } | |
1024 | |
1025 if (ngx_http_v3_set_param(c, st->id, st->vlint.value) != NGX_OK) { | |
1026 return NGX_ERROR; | |
1027 } | |
1028 | |
1029 goto done; | |
1030 } | |
1031 | |
1032 return NGX_AGAIN; | |
1033 | |
1034 done: | |
1035 | |
1036 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse settings done"); | |
1037 | |
1038 st->state = sw_start; | |
1039 return NGX_DONE; | |
1040 } | |
1041 | |
1042 | |
1043 ngx_int_t | |
1044 ngx_http_v3_parse_encoder(ngx_connection_t *c, void *data, u_char ch) | |
1045 { | |
1046 ngx_http_v3_parse_encoder_t *st = data; | |
1047 | |
1048 ngx_int_t rc; | |
1049 enum { | |
1050 sw_start = 0, | |
1051 sw_inr, | |
1052 sw_iwnr, | |
1053 sw_capacity, | |
1054 sw_duplicate | |
1055 }; | |
1056 | |
1057 if (st->state == sw_start) { | |
1058 | |
1059 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1060 "http3 parse encoder instruction"); | |
1061 | |
1062 if (ch & 0x80) { | |
1063 /* Insert With Name Reference */ | |
1064 | |
1065 st->state = sw_inr; | |
1066 | |
1067 } else if (ch & 0x40) { | |
1068 /* Insert Without Name Reference */ | |
1069 | |
1070 st->state = sw_iwnr; | |
1071 | |
1072 } else if (ch & 0x20) { | |
1073 /* Set Dynamic Table Capacity */ | |
1074 | |
1075 st->state = sw_capacity; | |
1076 | |
1077 } else { | |
1078 /* Duplicate */ | |
1079 | |
1080 st->state = sw_duplicate; | |
1081 } | |
1082 } | |
1083 | |
1084 switch (st->state) { | |
1085 | |
1086 case sw_inr: | |
1087 | |
1088 rc = ngx_http_v3_parse_header_inr(c, &st->header, ch); | |
1089 | |
1090 if (rc == NGX_ERROR) { | |
1091 return NGX_ERROR; | |
1092 } | |
1093 | |
1094 if (rc != NGX_DONE) { | |
1095 break; | |
1096 } | |
1097 | |
1098 goto done; | |
1099 | |
1100 case sw_iwnr: | |
1101 | |
1102 rc = ngx_http_v3_parse_header_iwnr(c, &st->header, ch); | |
1103 | |
1104 if (rc == NGX_ERROR) { | |
1105 return NGX_ERROR; | |
1106 } | |
1107 | |
1108 if (rc != NGX_DONE) { | |
1109 break; | |
1110 } | |
1111 | |
1112 goto done; | |
1113 | |
1114 case sw_capacity: | |
1115 | |
1116 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 5, ch) != NGX_DONE) { | |
1117 break; | |
1118 } | |
1119 | |
1120 if (ngx_http_v3_set_capacity(c, st->pint.value) != NGX_OK) { | |
1121 return NGX_ERROR; | |
1122 } | |
1123 | |
1124 goto done; | |
1125 | |
1126 case sw_duplicate: | |
1127 | |
1128 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 5, ch) != NGX_DONE) { | |
1129 break; | |
1130 } | |
1131 | |
1132 if (ngx_http_v3_duplicate(c, st->pint.value) != NGX_OK) { | |
1133 return NGX_ERROR; | |
1134 } | |
1135 | |
1136 goto done; | |
1137 } | |
1138 | |
1139 return NGX_AGAIN; | |
1140 | |
1141 done: | |
1142 | |
1143 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1144 "http3 parse encoder instruction done"); | |
1145 | |
1146 st->state = sw_start; | |
1147 return NGX_DONE; | |
1148 } | |
1149 | |
1150 | |
1151 ngx_int_t | |
1152 ngx_http_v3_parse_header_inr(ngx_connection_t *c, | |
1153 ngx_http_v3_parse_header_t *st, u_char ch) | |
1154 { | |
1155 ngx_int_t rc; | |
1156 enum { | |
1157 sw_start = 0, | |
1158 sw_name_index, | |
1159 sw_value_len, | |
1160 sw_read_value_len, | |
1161 sw_value | |
1162 }; | |
1163 | |
1164 switch (st->state) { | |
1165 | |
1166 case sw_start: | |
1167 | |
1168 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse header inr"); | |
1169 | |
1170 st->dynamic = (ch & 0x40) ? 0 : 1; | |
1171 st->state = sw_name_index; | |
1172 | |
1173 /* fall through */ | |
1174 | |
1175 case sw_name_index: | |
1176 | |
1177 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 6, ch) != NGX_DONE) { | |
1178 break; | |
1179 } | |
1180 | |
1181 st->index = st->pint.value; | |
1182 st->state = sw_value_len; | |
1183 break; | |
1184 | |
1185 case sw_value_len: | |
1186 | |
1187 st->literal.huffman = (ch & 0x80) ? 1 : 0; | |
1188 st->state = sw_read_value_len; | |
1189 | |
1190 /* fall through */ | |
1191 | |
1192 case sw_read_value_len: | |
1193 | |
1194 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 7, ch) != NGX_DONE) { | |
1195 break; | |
1196 } | |
1197 | |
1198 st->literal.length = st->pint.value; | |
1199 if (st->literal.length == 0) { | |
1200 goto done; | |
1201 } | |
1202 | |
1203 st->state = sw_value; | |
1204 break; | |
1205 | |
1206 case sw_value: | |
1207 | |
1208 rc = ngx_http_v3_parse_literal(c, &st->literal, ch); | |
1209 | |
1210 if (rc == NGX_ERROR) { | |
1211 return NGX_ERROR; | |
1212 } | |
1213 | |
1214 if (rc == NGX_DONE) { | |
1215 st->value = st->literal.value; | |
1216 goto done; | |
1217 } | |
1218 | |
1219 break; | |
1220 } | |
1221 | |
1222 return NGX_AGAIN; | |
1223 | |
1224 done: | |
1225 | |
1226 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1227 "http3 parse header inr done %s[%ui] \"%V\"", | |
1228 st->dynamic ? "dynamic" : "static", | |
1229 st->index, &st->value); | |
1230 | |
1231 if (ngx_http_v3_ref_insert(c, st->dynamic, st->index, &st->value) != NGX_OK) | |
1232 { | |
1233 return NGX_ERROR; | |
1234 } | |
1235 | |
1236 st->state = sw_start; | |
1237 return NGX_DONE; | |
1238 } | |
1239 | |
1240 | |
1241 ngx_int_t | |
1242 ngx_http_v3_parse_header_iwnr(ngx_connection_t *c, | |
1243 ngx_http_v3_parse_header_t *st, u_char ch) | |
1244 { | |
1245 ngx_int_t rc; | |
1246 enum { | |
1247 sw_start = 0, | |
1248 sw_name_len, | |
1249 sw_name, | |
1250 sw_value_len, | |
1251 sw_read_value_len, | |
1252 sw_value | |
1253 }; | |
1254 | |
1255 switch (st->state) { | |
1256 | |
1257 case sw_start: | |
1258 | |
1259 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1260 "http3 parse header iwnr"); | |
1261 | |
1262 st->literal.huffman = (ch & 0x20) ? 1 : 0; | |
1263 st->state = sw_name_len; | |
1264 | |
1265 /* fall through */ | |
1266 | |
1267 case sw_name_len: | |
1268 | |
1269 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 5, ch) != NGX_DONE) { | |
1270 break; | |
1271 } | |
1272 | |
1273 st->literal.length = st->pint.value; | |
1274 if (st->literal.length == 0) { | |
1275 return NGX_ERROR; | |
1276 } | |
1277 | |
1278 st->state = sw_name; | |
1279 break; | |
1280 | |
1281 case sw_name: | |
1282 | |
1283 rc = ngx_http_v3_parse_literal(c, &st->literal, ch); | |
1284 | |
1285 if (rc == NGX_ERROR) { | |
1286 return NGX_ERROR; | |
1287 } | |
1288 | |
1289 if (rc == NGX_DONE) { | |
1290 st->name = st->literal.value; | |
1291 st->state = sw_value_len; | |
1292 } | |
1293 | |
1294 break; | |
1295 | |
1296 case sw_value_len: | |
1297 | |
1298 st->literal.huffman = (ch & 0x80) ? 1 : 0; | |
1299 st->state = sw_read_value_len; | |
1300 | |
1301 /* fall through */ | |
1302 | |
1303 case sw_read_value_len: | |
1304 | |
1305 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 7, ch) != NGX_DONE) { | |
1306 break; | |
1307 } | |
1308 | |
1309 st->literal.length = st->pint.value; | |
1310 if (st->literal.length == 0) { | |
1311 goto done; | |
1312 } | |
1313 | |
1314 st->state = sw_value; | |
1315 break; | |
1316 | |
1317 case sw_value: | |
1318 | |
1319 rc = ngx_http_v3_parse_literal(c, &st->literal, ch); | |
1320 | |
1321 if (rc == NGX_ERROR) { | |
1322 return NGX_ERROR; | |
1323 } | |
1324 | |
1325 if (rc == NGX_DONE) { | |
1326 st->value = st->literal.value; | |
1327 goto done; | |
1328 } | |
1329 | |
1330 break; | |
1331 } | |
1332 | |
1333 return NGX_AGAIN; | |
1334 | |
1335 done: | |
1336 | |
1337 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1338 "http3 parse header iwnr done \"%V\":\"%V\"", | |
1339 &st->name, &st->value); | |
1340 | |
1341 if (ngx_http_v3_insert(c, &st->name, &st->value) != NGX_OK) { | |
1342 return NGX_ERROR; | |
1343 } | |
1344 | |
1345 st->state = sw_start; | |
1346 return NGX_DONE; | |
1347 } | |
1348 | |
1349 | |
1350 ngx_int_t | |
1351 ngx_http_v3_parse_decoder(ngx_connection_t *c, void *data, u_char ch) | |
1352 { | |
1353 ngx_http_v3_parse_decoder_t *st = data; | |
1354 | |
1355 enum { | |
1356 sw_start = 0, | |
1357 sw_ack_header, | |
1358 sw_cancel_stream, | |
1359 sw_inc_insert_count | |
1360 }; | |
1361 | |
1362 if (st->state == sw_start) { | |
1363 | |
1364 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1365 "http3 parse decoder instruction"); | |
1366 | |
1367 if (ch & 0x80) { | |
1368 /* Header Acknowledgement */ | |
1369 | |
1370 st->state = sw_ack_header; | |
1371 | |
1372 } else if (ch & 0x40) { | |
1373 /* Stream Cancellation */ | |
1374 | |
1375 st->state = sw_cancel_stream; | |
1376 | |
1377 } else { | |
1378 /* Insert Count Increment */ | |
1379 | |
1380 st->state = sw_inc_insert_count; | |
1381 } | |
1382 } | |
1383 | |
1384 switch (st->state) { | |
1385 | |
1386 case sw_ack_header: | |
1387 | |
1388 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 6, ch) != NGX_DONE) { | |
1389 break; | |
1390 } | |
1391 | |
1392 if (ngx_http_v3_ack_header(c, st->pint.value) != NGX_OK) { | |
1393 return NGX_ERROR; | |
1394 } | |
1395 | |
1396 goto done; | |
1397 | |
1398 case sw_cancel_stream: | |
1399 | |
1400 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 6, ch) != NGX_DONE) { | |
1401 break; | |
1402 } | |
1403 | |
1404 if (ngx_http_v3_cancel_stream(c, st->pint.value) != NGX_OK) { | |
1405 return NGX_ERROR; | |
1406 } | |
1407 | |
1408 goto done; | |
1409 | |
1410 case sw_inc_insert_count: | |
1411 | |
1412 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 6, ch) != NGX_DONE) { | |
1413 break; | |
1414 } | |
1415 | |
1416 if (ngx_http_v3_inc_insert_count(c, st->pint.value) != NGX_OK) { | |
1417 return NGX_ERROR; | |
1418 } | |
1419 | |
1420 goto done; | |
1421 } | |
1422 | |
1423 return NGX_AGAIN; | |
1424 | |
1425 done: | |
1426 | |
1427 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1428 "http3 parse decoder instruction done"); | |
1429 | |
1430 st->state = sw_start; | |
1431 return NGX_DONE; | |
1432 } | |
7761
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1433 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1434 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1435 ngx_int_t |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1436 ngx_http_v3_parse_data(ngx_connection_t *c, ngx_http_v3_parse_data_t *st, |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1437 u_char ch) |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1438 { |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1439 enum { |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1440 sw_start = 0, |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1441 sw_type, |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1442 sw_length |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1443 }; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1444 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1445 switch (st->state) { |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1446 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1447 case sw_start: |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1448 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1449 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse data"); |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1450 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1451 st->state = sw_type; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1452 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1453 /* fall through */ |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1454 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1455 case sw_type: |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1456 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1457 if (ngx_http_v3_parse_varlen_int(c, &st->vlint, ch) != NGX_DONE) { |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1458 break; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1459 } |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1460 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1461 if (st->vlint.value != NGX_HTTP_V3_FRAME_DATA) { |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1462 return NGX_ERROR; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1463 } |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1464 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1465 st->state = sw_length; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1466 break; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1467 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1468 case sw_length: |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1469 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1470 if (ngx_http_v3_parse_varlen_int(c, &st->vlint, ch) != NGX_DONE) { |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1471 break; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1472 } |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1473 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1474 st->length = st->vlint.value; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1475 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1476 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1477 "http3 parse data frame len:%ui", st->length); |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1478 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1479 goto done; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1480 } |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1481 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1482 return NGX_AGAIN; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1483 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1484 done: |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1485 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1486 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse data done"); |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1487 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1488 st->state = sw_start; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1489 return NGX_DONE; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1490 } |