Mercurial > hg > nginx-quic
annotate src/http/v3/ngx_http_v3_parse.c @ 7870:e169cce912c7 quic
Avoid retransmitting of packets with discarded keys.
Sections 4.10.1 and 4.10.2 of quic transport describe discarding of initial
and handshake keys. Since the keys are discarded, we no longer need
to retransmit packets and corresponding queues should be emptied.
This patch removes previously added workaround that did not require
acknowledgement for initial packets, resulting in avoiding retransmission,
which is wrong because a packet could be lost and we have to retransmit it.
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Mon, 18 May 2020 13:54:53 +0300 |
parents | 5649079a41f4 |
children | 032cb35ce758 |
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 { | |
402 ngx_uint_t n; | |
403 enum { | |
404 sw_start = 0, | |
405 sw_value | |
406 }; | |
407 | |
408 switch (st->state) { | |
409 | |
410 case sw_start: | |
411 | |
412 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
413 "http3 parse literal huff:%ui, len:%ui", | |
414 st->huffman, st->length); | |
415 | |
416 n = st->length; | |
417 | |
418 if (st->huffman) { | |
419 n = n * 8 / 5; | |
420 st->huffstate = 0; | |
421 } | |
422 | |
423 st->last = ngx_pnalloc(c->pool, n + 1); | |
424 if (st->last == NULL) { | |
425 return NGX_ERROR; | |
426 } | |
427 | |
428 st->value.data = st->last; | |
429 st->state = sw_value; | |
430 | |
431 /* fall through */ | |
432 | |
433 case sw_value: | |
434 | |
435 if (st->huffman) { | |
436 if (ngx_http_v2_huff_decode(&st->huffstate, &ch, 1, &st->last, | |
437 st->length == 1, c->log) | |
438 != NGX_OK) | |
439 { | |
440 return NGX_ERROR; | |
441 } | |
442 | |
443 } else { | |
444 *st->last++ = ch; | |
445 } | |
446 | |
447 if (--st->length) { | |
448 break; | |
449 } | |
450 | |
451 st->value.len = st->last - st->value.data; | |
452 *st->last = '\0'; | |
453 goto done; | |
454 } | |
455 | |
456 return NGX_AGAIN; | |
457 | |
458 done: | |
459 | |
460 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
461 "http3 parse literal done \"%V\"", &st->value); | |
462 | |
463 st->state = sw_start; | |
464 return NGX_DONE; | |
465 } | |
466 | |
467 | |
468 ngx_int_t | |
469 ngx_http_v3_parse_header_ri(ngx_connection_t *c, ngx_http_v3_parse_header_t *st, | |
470 u_char ch) | |
471 { | |
472 ngx_http_v3_header_t *h; | |
473 enum { | |
474 sw_start = 0, | |
475 sw_index | |
476 }; | |
477 | |
478 switch (st->state) { | |
479 | |
480 case sw_start: | |
481 | |
482 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse header ri"); | |
483 | |
484 st->dynamic = (ch & 0x40) ? 0 : 1; | |
485 st->state = sw_index; | |
486 | |
487 /* fall through */ | |
488 | |
489 case sw_index: | |
490 | |
491 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 6, ch) != NGX_DONE) { | |
492 break; | |
493 } | |
494 | |
495 st->index = st->pint.value; | |
496 goto done; | |
497 } | |
498 | |
499 return NGX_AGAIN; | |
500 | |
501 done: | |
502 | |
503 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
504 "http3 parse header ri done %s%ui]", | |
505 st->dynamic ? "dynamic[-" : "static[", st->index); | |
506 | |
507 if (st->dynamic) { | |
508 st->index = st->base - st->index - 1; | |
509 } | |
510 | |
511 h = ngx_http_v3_lookup_table(c, st->dynamic, st->index); | |
512 if (h == NULL) { | |
513 return NGX_ERROR; | |
514 } | |
515 | |
516 st->name = h->name; | |
517 st->value = h->value; | |
518 st->state = sw_start; | |
519 | |
520 return NGX_DONE; | |
521 } | |
522 | |
523 | |
524 ngx_int_t | |
525 ngx_http_v3_parse_header_lri(ngx_connection_t *c, | |
526 ngx_http_v3_parse_header_t *st, u_char ch) | |
527 { | |
528 ngx_int_t rc; | |
529 ngx_http_v3_header_t *h; | |
530 enum { | |
531 sw_start = 0, | |
532 sw_index, | |
533 sw_value_len, | |
534 sw_read_value_len, | |
535 sw_value | |
536 }; | |
537 | |
538 switch (st->state) { | |
539 | |
540 case sw_start: | |
541 | |
542 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse header lri"); | |
543 | |
544 st->dynamic = (ch & 0x10) ? 0 : 1; | |
545 st->state = sw_index; | |
546 | |
547 /* fall through */ | |
548 | |
549 case sw_index: | |
550 | |
551 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 4, ch) != NGX_DONE) { | |
552 break; | |
553 } | |
554 | |
555 st->index = st->pint.value; | |
556 st->state = sw_value_len; | |
557 break; | |
558 | |
559 case sw_value_len: | |
560 | |
561 st->literal.huffman = (ch & 0x80) ? 1 : 0; | |
562 st->state = sw_read_value_len; | |
563 | |
564 /* fall through */ | |
565 | |
566 case sw_read_value_len: | |
567 | |
568 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 7, ch) != NGX_DONE) { | |
569 break; | |
570 } | |
571 | |
572 st->literal.length = st->pint.value; | |
573 if (st->literal.length == 0) { | |
574 goto done; | |
575 } | |
576 | |
577 st->state = sw_value; | |
578 break; | |
579 | |
580 case sw_value: | |
581 | |
582 rc = ngx_http_v3_parse_literal(c, &st->literal, ch); | |
583 | |
584 if (rc == NGX_ERROR) { | |
585 return NGX_ERROR; | |
586 } | |
587 | |
588 if (rc == NGX_DONE) { | |
589 st->value = st->literal.value; | |
590 goto done; | |
591 } | |
592 | |
593 break; | |
594 } | |
595 | |
596 return NGX_AGAIN; | |
597 | |
598 done: | |
599 | |
600 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
601 "http3 parse header lri done %s%ui] \"%V\"", | |
602 st->dynamic ? "dynamic[-" : "static[", | |
603 st->index, &st->value); | |
604 | |
605 if (st->dynamic) { | |
606 st->index = st->base - st->index - 1; | |
607 } | |
608 | |
609 h = ngx_http_v3_lookup_table(c, st->dynamic, st->index); | |
610 if (h == NULL) { | |
611 return NGX_ERROR; | |
612 } | |
613 | |
614 st->name = h->name; | |
615 st->state = sw_start; | |
616 return NGX_DONE; | |
617 } | |
618 | |
619 | |
620 ngx_int_t | |
621 ngx_http_v3_parse_header_l(ngx_connection_t *c, | |
622 ngx_http_v3_parse_header_t *st, u_char ch) | |
623 { | |
624 ngx_int_t rc; | |
625 enum { | |
626 sw_start = 0, | |
627 sw_name_len, | |
628 sw_name, | |
629 sw_value_len, | |
630 sw_read_value_len, | |
631 sw_value | |
632 }; | |
633 | |
634 switch (st->state) { | |
635 | |
636 case sw_start: | |
637 | |
638 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse header l"); | |
639 | |
640 st->literal.huffman = (ch & 0x08) ? 1 : 0; | |
641 st->state = sw_name_len; | |
642 | |
643 /* fall through */ | |
644 | |
645 case sw_name_len: | |
646 | |
647 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 3, ch) != NGX_DONE) { | |
648 break; | |
649 } | |
650 | |
651 st->literal.length = st->pint.value; | |
652 if (st->literal.length == 0) { | |
653 return NGX_ERROR; | |
654 } | |
655 | |
656 st->state = sw_name; | |
657 break; | |
658 | |
659 case sw_name: | |
660 | |
661 rc = ngx_http_v3_parse_literal(c, &st->literal, ch); | |
662 | |
663 if (rc == NGX_ERROR) { | |
664 return NGX_ERROR; | |
665 } | |
666 | |
667 if (rc == NGX_DONE) { | |
668 st->name = st->literal.value; | |
669 st->state = sw_value_len; | |
670 } | |
671 | |
672 break; | |
673 | |
674 case sw_value_len: | |
675 | |
676 st->literal.huffman = (ch & 0x80) ? 1 : 0; | |
677 st->state = sw_read_value_len; | |
678 | |
679 /* fall through */ | |
680 | |
681 case sw_read_value_len: | |
682 | |
683 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 7, ch) != NGX_DONE) { | |
684 break; | |
685 } | |
686 | |
687 st->literal.length = st->pint.value; | |
688 if (st->literal.length == 0) { | |
689 goto done; | |
690 } | |
691 | |
692 st->state = sw_value; | |
693 break; | |
694 | |
695 case sw_value: | |
696 | |
697 rc = ngx_http_v3_parse_literal(c, &st->literal, ch); | |
698 | |
699 if (rc == NGX_ERROR) { | |
700 return NGX_ERROR; | |
701 } | |
702 | |
703 if (rc == NGX_DONE) { | |
704 st->value = st->literal.value; | |
705 goto done; | |
706 } | |
707 | |
708 break; | |
709 } | |
710 | |
711 return NGX_AGAIN; | |
712 | |
713 done: | |
714 | |
715 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
716 "http3 parse header l done \"%V\" \"%V\"", | |
717 &st->name, &st->value); | |
718 | |
719 st->state = sw_start; | |
720 return NGX_DONE; | |
721 } | |
722 | |
723 | |
724 ngx_int_t | |
725 ngx_http_v3_parse_header_pbi(ngx_connection_t *c, | |
726 ngx_http_v3_parse_header_t *st, u_char ch) | |
727 { | |
728 ngx_http_v3_header_t *h; | |
729 enum { | |
730 sw_start = 0, | |
731 sw_index | |
732 }; | |
733 | |
734 switch (st->state) { | |
735 | |
736 case sw_start: | |
737 | |
738 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse header pbi"); | |
739 | |
740 st->state = sw_index; | |
741 | |
742 /* fall through */ | |
743 | |
744 case sw_index: | |
745 | |
746 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 4, ch) != NGX_DONE) { | |
747 break; | |
748 } | |
749 | |
750 st->index = st->pint.value; | |
751 goto done; | |
752 } | |
753 | |
754 return NGX_AGAIN; | |
755 | |
756 done: | |
757 | |
758 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
759 "http3 parse header pbi done dynamic[+%ui]", st->index); | |
760 | |
761 h = ngx_http_v3_lookup_table(c, 1, st->base + st->index); | |
762 if (h == NULL) { | |
763 return NGX_ERROR; | |
764 } | |
765 | |
766 st->name = h->name; | |
767 st->value = h->value; | |
768 st->state = sw_start; | |
769 return NGX_DONE; | |
770 } | |
771 | |
772 | |
773 ngx_int_t | |
774 ngx_http_v3_parse_header_lpbi(ngx_connection_t *c, | |
775 ngx_http_v3_parse_header_t *st, u_char ch) | |
776 { | |
777 ngx_int_t rc; | |
778 ngx_http_v3_header_t *h; | |
779 enum { | |
780 sw_start = 0, | |
781 sw_index, | |
782 sw_value_len, | |
783 sw_read_value_len, | |
784 sw_value | |
785 }; | |
786 | |
787 switch (st->state) { | |
788 | |
789 case sw_start: | |
790 | |
791 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
792 "http3 parse header lpbi"); | |
793 | |
794 st->state = sw_index; | |
795 | |
796 /* fall through */ | |
797 | |
798 case sw_index: | |
799 | |
800 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 3, ch) != NGX_DONE) { | |
801 break; | |
802 } | |
803 | |
804 st->index = st->pint.value; | |
805 st->state = sw_value_len; | |
806 break; | |
807 | |
808 case sw_value_len: | |
809 | |
810 st->literal.huffman = (ch & 0x80) ? 1 : 0; | |
811 st->state = sw_read_value_len; | |
812 | |
813 /* fall through */ | |
814 | |
815 case sw_read_value_len: | |
816 | |
817 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 7, ch) != NGX_DONE) { | |
818 break; | |
819 } | |
820 | |
821 st->literal.length = st->pint.value; | |
822 if (st->literal.length == 0) { | |
823 goto done; | |
824 } | |
825 | |
826 st->state = sw_value; | |
827 break; | |
828 | |
829 case sw_value: | |
830 | |
831 rc = ngx_http_v3_parse_literal(c, &st->literal, ch); | |
832 | |
833 if (rc == NGX_ERROR) { | |
834 return NGX_ERROR; | |
835 } | |
836 | |
837 if (rc == NGX_DONE) { | |
838 st->value = st->literal.value; | |
839 goto done; | |
840 } | |
841 | |
842 break; | |
843 } | |
844 | |
845 return NGX_AGAIN; | |
846 | |
847 done: | |
848 | |
849 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
850 "http3 parse header lpbi done dynamic[+%ui] \"%V\"", | |
851 st->index, &st->value); | |
852 | |
853 h = ngx_http_v3_lookup_table(c, 1, st->base + st->index); | |
854 if (h == NULL) { | |
855 return NGX_ERROR; | |
856 } | |
857 | |
858 st->name = h->name; | |
859 st->state = sw_start; | |
860 return NGX_DONE; | |
861 } | |
862 | |
863 | |
864 ngx_int_t | |
865 ngx_http_v3_parse_control(ngx_connection_t *c, void *data, u_char ch) | |
866 { | |
867 ngx_http_v3_parse_control_t *st = data; | |
868 | |
869 ngx_int_t rc; | |
870 enum { | |
871 sw_start = 0, | |
872 sw_type, | |
873 sw_length, | |
874 sw_settings, | |
875 sw_max_push_id, | |
876 sw_skip | |
877 }; | |
878 | |
879 switch (st->state) { | |
880 | |
881 case sw_start: | |
882 | |
883 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse control"); | |
884 | |
885 st->state = sw_type; | |
886 | |
887 /* fall through */ | |
888 | |
889 case sw_type: | |
890 | |
891 if (ngx_http_v3_parse_varlen_int(c, &st->vlint, ch) != NGX_DONE) { | |
892 break; | |
893 } | |
894 | |
895 st->type = st->vlint.value; | |
896 | |
897 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
898 "http3 parse frame type:%ui", st->type); | |
899 | |
900 st->state = sw_length; | |
901 break; | |
902 | |
903 case sw_length: | |
904 | |
905 if (ngx_http_v3_parse_varlen_int(c, &st->vlint, ch) != NGX_DONE) { | |
906 break; | |
907 } | |
908 | |
909 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
910 "http3 parse frame len:%uL", st->vlint.value); | |
911 | |
912 st->length = st->vlint.value; | |
913 if (st->length == 0) { | |
914 st->state = sw_type; | |
915 break; | |
916 } | |
917 | |
918 switch (st->type) { | |
919 | |
920 case NGX_HTTP_V3_FRAME_SETTINGS: | |
921 st->state = sw_settings; | |
922 break; | |
923 | |
924 case NGX_HTTP_V3_FRAME_MAX_PUSH_ID: | |
925 st->state = sw_max_push_id; | |
926 break; | |
927 | |
928 default: | |
929 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
930 "http3 parse skip unknown frame"); | |
931 st->state = sw_skip; | |
932 } | |
933 | |
934 break; | |
935 | |
936 case sw_settings: | |
937 | |
938 rc = ngx_http_v3_parse_settings(c, &st->settings, ch); | |
939 | |
940 if (rc == NGX_ERROR) { | |
941 return NGX_ERROR; | |
942 } | |
943 | |
944 if (--st->length > 0) { | |
945 break; | |
946 } | |
947 | |
948 if (rc != NGX_DONE) { | |
949 return NGX_ERROR; | |
950 } | |
951 | |
952 st->state = sw_type; | |
953 break; | |
954 | |
955 case sw_max_push_id: | |
956 | |
957 if (ngx_http_v3_parse_varlen_int(c, &st->vlint, ch) != NGX_DONE) { | |
958 break; | |
959 } | |
960 | |
961 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
962 "http3 parse MAX_PUSH_ID:%uL", st->vlint.value); | |
963 | |
964 st->state = sw_type; | |
965 break; | |
966 | |
967 case sw_skip: | |
968 | |
969 if (--st->length == 0) { | |
970 st->state = sw_type; | |
971 } | |
972 | |
973 break; | |
974 } | |
975 | |
976 return NGX_AGAIN; | |
977 } | |
978 | |
979 | |
980 ngx_int_t | |
981 ngx_http_v3_parse_settings(ngx_connection_t *c, | |
982 ngx_http_v3_parse_settings_t *st, u_char ch) | |
983 { | |
984 enum { | |
985 sw_start = 0, | |
986 sw_id, | |
987 sw_value | |
988 }; | |
989 | |
990 switch (st->state) { | |
991 | |
992 case sw_start: | |
993 | |
994 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse settings"); | |
995 | |
996 st->state = sw_id; | |
997 | |
998 /* fall through */ | |
999 | |
1000 case sw_id: | |
1001 | |
1002 if (ngx_http_v3_parse_varlen_int(c, &st->vlint, ch) != NGX_DONE) { | |
1003 break; | |
1004 } | |
1005 | |
1006 st->id = st->vlint.value; | |
1007 st->state = sw_value; | |
1008 break; | |
1009 | |
1010 case sw_value: | |
1011 | |
1012 if (ngx_http_v3_parse_varlen_int(c, &st->vlint, ch) != NGX_DONE) { | |
1013 break; | |
1014 } | |
1015 | |
1016 if (ngx_http_v3_set_param(c, st->id, st->vlint.value) != NGX_OK) { | |
1017 return NGX_ERROR; | |
1018 } | |
1019 | |
1020 goto done; | |
1021 } | |
1022 | |
1023 return NGX_AGAIN; | |
1024 | |
1025 done: | |
1026 | |
1027 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse settings done"); | |
1028 | |
1029 st->state = sw_start; | |
1030 return NGX_DONE; | |
1031 } | |
1032 | |
1033 | |
1034 ngx_int_t | |
1035 ngx_http_v3_parse_encoder(ngx_connection_t *c, void *data, u_char ch) | |
1036 { | |
1037 ngx_http_v3_parse_encoder_t *st = data; | |
1038 | |
1039 ngx_int_t rc; | |
1040 enum { | |
1041 sw_start = 0, | |
1042 sw_inr, | |
1043 sw_iwnr, | |
1044 sw_capacity, | |
1045 sw_duplicate | |
1046 }; | |
1047 | |
1048 if (st->state == sw_start) { | |
1049 | |
1050 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1051 "http3 parse encoder instruction"); | |
1052 | |
1053 if (ch & 0x80) { | |
1054 /* Insert With Name Reference */ | |
1055 | |
1056 st->state = sw_inr; | |
1057 | |
1058 } else if (ch & 0x40) { | |
1059 /* Insert Without Name Reference */ | |
1060 | |
1061 st->state = sw_iwnr; | |
1062 | |
1063 } else if (ch & 0x20) { | |
1064 /* Set Dynamic Table Capacity */ | |
1065 | |
1066 st->state = sw_capacity; | |
1067 | |
1068 } else { | |
1069 /* Duplicate */ | |
1070 | |
1071 st->state = sw_duplicate; | |
1072 } | |
1073 } | |
1074 | |
1075 switch (st->state) { | |
1076 | |
1077 case sw_inr: | |
1078 | |
1079 rc = ngx_http_v3_parse_header_inr(c, &st->header, ch); | |
1080 | |
1081 if (rc == NGX_ERROR) { | |
1082 return NGX_ERROR; | |
1083 } | |
1084 | |
1085 if (rc != NGX_DONE) { | |
1086 break; | |
1087 } | |
1088 | |
1089 goto done; | |
1090 | |
1091 case sw_iwnr: | |
1092 | |
1093 rc = ngx_http_v3_parse_header_iwnr(c, &st->header, ch); | |
1094 | |
1095 if (rc == NGX_ERROR) { | |
1096 return NGX_ERROR; | |
1097 } | |
1098 | |
1099 if (rc != NGX_DONE) { | |
1100 break; | |
1101 } | |
1102 | |
1103 goto done; | |
1104 | |
1105 case sw_capacity: | |
1106 | |
1107 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 5, ch) != NGX_DONE) { | |
1108 break; | |
1109 } | |
1110 | |
1111 if (ngx_http_v3_set_capacity(c, st->pint.value) != NGX_OK) { | |
1112 return NGX_ERROR; | |
1113 } | |
1114 | |
1115 goto done; | |
1116 | |
1117 case sw_duplicate: | |
1118 | |
1119 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 5, ch) != NGX_DONE) { | |
1120 break; | |
1121 } | |
1122 | |
1123 if (ngx_http_v3_duplicate(c, st->pint.value) != NGX_OK) { | |
1124 return NGX_ERROR; | |
1125 } | |
1126 | |
1127 goto done; | |
1128 } | |
1129 | |
1130 return NGX_AGAIN; | |
1131 | |
1132 done: | |
1133 | |
1134 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1135 "http3 parse encoder instruction done"); | |
1136 | |
1137 st->state = sw_start; | |
1138 return NGX_DONE; | |
1139 } | |
1140 | |
1141 | |
1142 ngx_int_t | |
1143 ngx_http_v3_parse_header_inr(ngx_connection_t *c, | |
1144 ngx_http_v3_parse_header_t *st, u_char ch) | |
1145 { | |
1146 ngx_int_t rc; | |
1147 enum { | |
1148 sw_start = 0, | |
1149 sw_name_index, | |
1150 sw_value_len, | |
1151 sw_read_value_len, | |
1152 sw_value | |
1153 }; | |
1154 | |
1155 switch (st->state) { | |
1156 | |
1157 case sw_start: | |
1158 | |
1159 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse header inr"); | |
1160 | |
1161 st->dynamic = (ch & 0x40) ? 0 : 1; | |
1162 st->state = sw_name_index; | |
1163 | |
1164 /* fall through */ | |
1165 | |
1166 case sw_name_index: | |
1167 | |
1168 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 6, ch) != NGX_DONE) { | |
1169 break; | |
1170 } | |
1171 | |
1172 st->index = st->pint.value; | |
1173 st->state = sw_value_len; | |
1174 break; | |
1175 | |
1176 case sw_value_len: | |
1177 | |
1178 st->literal.huffman = (ch & 0x80) ? 1 : 0; | |
1179 st->state = sw_read_value_len; | |
1180 | |
1181 /* fall through */ | |
1182 | |
1183 case sw_read_value_len: | |
1184 | |
1185 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 7, ch) != NGX_DONE) { | |
1186 break; | |
1187 } | |
1188 | |
1189 st->literal.length = st->pint.value; | |
1190 if (st->literal.length == 0) { | |
1191 goto done; | |
1192 } | |
1193 | |
1194 st->state = sw_value; | |
1195 break; | |
1196 | |
1197 case sw_value: | |
1198 | |
1199 rc = ngx_http_v3_parse_literal(c, &st->literal, ch); | |
1200 | |
1201 if (rc == NGX_ERROR) { | |
1202 return NGX_ERROR; | |
1203 } | |
1204 | |
1205 if (rc == NGX_DONE) { | |
1206 st->value = st->literal.value; | |
1207 goto done; | |
1208 } | |
1209 | |
1210 break; | |
1211 } | |
1212 | |
1213 return NGX_AGAIN; | |
1214 | |
1215 done: | |
1216 | |
1217 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1218 "http3 parse header inr done %s[%ui] \"%V\"", | |
1219 st->dynamic ? "dynamic" : "static", | |
1220 st->index, &st->value); | |
1221 | |
1222 if (ngx_http_v3_ref_insert(c, st->dynamic, st->index, &st->value) != NGX_OK) | |
1223 { | |
1224 return NGX_ERROR; | |
1225 } | |
1226 | |
1227 st->state = sw_start; | |
1228 return NGX_DONE; | |
1229 } | |
1230 | |
1231 | |
1232 ngx_int_t | |
1233 ngx_http_v3_parse_header_iwnr(ngx_connection_t *c, | |
1234 ngx_http_v3_parse_header_t *st, u_char ch) | |
1235 { | |
1236 ngx_int_t rc; | |
1237 enum { | |
1238 sw_start = 0, | |
1239 sw_name_len, | |
1240 sw_name, | |
1241 sw_value_len, | |
1242 sw_read_value_len, | |
1243 sw_value | |
1244 }; | |
1245 | |
1246 switch (st->state) { | |
1247 | |
1248 case sw_start: | |
1249 | |
1250 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1251 "http3 parse header iwnr"); | |
1252 | |
1253 st->literal.huffman = (ch & 0x20) ? 1 : 0; | |
1254 st->state = sw_name_len; | |
1255 | |
1256 /* fall through */ | |
1257 | |
1258 case sw_name_len: | |
1259 | |
1260 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 5, ch) != NGX_DONE) { | |
1261 break; | |
1262 } | |
1263 | |
1264 st->literal.length = st->pint.value; | |
1265 if (st->literal.length == 0) { | |
1266 return NGX_ERROR; | |
1267 } | |
1268 | |
1269 st->state = sw_name; | |
1270 break; | |
1271 | |
1272 case sw_name: | |
1273 | |
1274 rc = ngx_http_v3_parse_literal(c, &st->literal, ch); | |
1275 | |
1276 if (rc == NGX_ERROR) { | |
1277 return NGX_ERROR; | |
1278 } | |
1279 | |
1280 if (rc == NGX_DONE) { | |
1281 st->name = st->literal.value; | |
1282 st->state = sw_value_len; | |
1283 } | |
1284 | |
1285 break; | |
1286 | |
1287 case sw_value_len: | |
1288 | |
1289 st->literal.huffman = (ch & 0x80) ? 1 : 0; | |
1290 st->state = sw_read_value_len; | |
1291 | |
1292 /* fall through */ | |
1293 | |
1294 case sw_read_value_len: | |
1295 | |
1296 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 7, ch) != NGX_DONE) { | |
1297 break; | |
1298 } | |
1299 | |
1300 st->literal.length = st->pint.value; | |
1301 if (st->literal.length == 0) { | |
1302 goto done; | |
1303 } | |
1304 | |
1305 st->state = sw_value; | |
1306 break; | |
1307 | |
1308 case sw_value: | |
1309 | |
1310 rc = ngx_http_v3_parse_literal(c, &st->literal, ch); | |
1311 | |
1312 if (rc == NGX_ERROR) { | |
1313 return NGX_ERROR; | |
1314 } | |
1315 | |
1316 if (rc == NGX_DONE) { | |
1317 st->value = st->literal.value; | |
1318 goto done; | |
1319 } | |
1320 | |
1321 break; | |
1322 } | |
1323 | |
1324 return NGX_AGAIN; | |
1325 | |
1326 done: | |
1327 | |
1328 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1329 "http3 parse header iwnr done \"%V\":\"%V\"", | |
1330 &st->name, &st->value); | |
1331 | |
1332 if (ngx_http_v3_insert(c, &st->name, &st->value) != NGX_OK) { | |
1333 return NGX_ERROR; | |
1334 } | |
1335 | |
1336 st->state = sw_start; | |
1337 return NGX_DONE; | |
1338 } | |
1339 | |
1340 | |
1341 ngx_int_t | |
1342 ngx_http_v3_parse_decoder(ngx_connection_t *c, void *data, u_char ch) | |
1343 { | |
1344 ngx_http_v3_parse_decoder_t *st = data; | |
1345 | |
1346 enum { | |
1347 sw_start = 0, | |
1348 sw_ack_header, | |
1349 sw_cancel_stream, | |
1350 sw_inc_insert_count | |
1351 }; | |
1352 | |
1353 if (st->state == sw_start) { | |
1354 | |
1355 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1356 "http3 parse decoder instruction"); | |
1357 | |
1358 if (ch & 0x80) { | |
1359 /* Header Acknowledgement */ | |
1360 | |
1361 st->state = sw_ack_header; | |
1362 | |
1363 } else if (ch & 0x40) { | |
1364 /* Stream Cancellation */ | |
1365 | |
1366 st->state = sw_cancel_stream; | |
1367 | |
1368 } else { | |
1369 /* Insert Count Increment */ | |
1370 | |
1371 st->state = sw_inc_insert_count; | |
1372 } | |
1373 } | |
1374 | |
1375 switch (st->state) { | |
1376 | |
1377 case sw_ack_header: | |
1378 | |
1379 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 6, ch) != NGX_DONE) { | |
1380 break; | |
1381 } | |
1382 | |
1383 if (ngx_http_v3_ack_header(c, st->pint.value) != NGX_OK) { | |
1384 return NGX_ERROR; | |
1385 } | |
1386 | |
1387 goto done; | |
1388 | |
1389 case sw_cancel_stream: | |
1390 | |
1391 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 6, ch) != NGX_DONE) { | |
1392 break; | |
1393 } | |
1394 | |
1395 if (ngx_http_v3_cancel_stream(c, st->pint.value) != NGX_OK) { | |
1396 return NGX_ERROR; | |
1397 } | |
1398 | |
1399 goto done; | |
1400 | |
1401 case sw_inc_insert_count: | |
1402 | |
1403 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 6, ch) != NGX_DONE) { | |
1404 break; | |
1405 } | |
1406 | |
1407 if (ngx_http_v3_inc_insert_count(c, st->pint.value) != NGX_OK) { | |
1408 return NGX_ERROR; | |
1409 } | |
1410 | |
1411 goto done; | |
1412 } | |
1413 | |
1414 return NGX_AGAIN; | |
1415 | |
1416 done: | |
1417 | |
1418 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1419 "http3 parse decoder instruction done"); | |
1420 | |
1421 st->state = sw_start; | |
1422 return NGX_DONE; | |
1423 } | |
7761
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1424 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1425 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1426 ngx_int_t |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1427 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
|
1428 u_char ch) |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1429 { |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1430 enum { |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1431 sw_start = 0, |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1432 sw_type, |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1433 sw_length |
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 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1436 switch (st->state) { |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1437 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1438 case sw_start: |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1439 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1440 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
|
1441 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1442 st->state = sw_type; |
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 /* fall through */ |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1445 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1446 case sw_type: |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1447 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1448 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
|
1449 break; |
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 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1452 if (st->vlint.value != NGX_HTTP_V3_FRAME_DATA) { |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1453 return NGX_ERROR; |
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 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1456 st->state = sw_length; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1457 break; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1458 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1459 case sw_length: |
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 (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
|
1462 break; |
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->length = st->vlint.value; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1466 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1467 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
|
1468 "http3 parse data frame len:%ui", st->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 goto done; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1471 } |
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 return NGX_AGAIN; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1474 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1475 done: |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1476 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1477 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
|
1478 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1479 st->state = sw_start; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1480 return NGX_DONE; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
7693
diff
changeset
|
1481 } |