Mercurial > hg > nginx-quic
comparison src/http/v3/ngx_http_v3_parse.c @ 7955:72f9ff4e0a88 quic
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Previously errors led only to closing streams.
To simplify closing QUIC connection from a QUIC stream context, new macro
ngx_http_v3_finalize_connection() is introduced. It calls
ngx_quic_finalize_connection() for the parent connection.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Thu, 02 Jul 2020 16:47:51 +0300 |
parents | a7f64438aa3c |
children | 153bffee3d7e |
comparison
equal
deleted
inserted
replaced
7954:1ed698947172 | 7955:72f9ff4e0a88 |
---|---|
158 case sw_start: | 158 case sw_start: |
159 | 159 |
160 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse headers"); | 160 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse headers"); |
161 | 161 |
162 if (ch != NGX_HTTP_V3_FRAME_HEADERS) { | 162 if (ch != NGX_HTTP_V3_FRAME_HEADERS) { |
163 return NGX_ERROR; | 163 return NGX_HTTP_V3_ERR_FRAME_UNEXPECTED; |
164 } | 164 } |
165 | 165 |
166 st->state = sw_length; | 166 st->state = sw_length; |
167 break; | 167 break; |
168 | 168 |
181 break; | 181 break; |
182 | 182 |
183 case sw_prefix: | 183 case sw_prefix: |
184 | 184 |
185 if (st->length-- == 0) { | 185 if (st->length-- == 0) { |
186 return NGX_ERROR; | 186 return NGX_HTTP_V3_ERR_FRAME_ERROR; |
187 } | 187 } |
188 | 188 |
189 rc = ngx_http_v3_parse_header_block_prefix(c, &st->prefix, ch); | 189 rc = ngx_http_v3_parse_header_block_prefix(c, &st->prefix, ch); |
190 | 190 |
191 if (rc == NGX_ERROR) { | 191 if (rc == NGX_AGAIN) { |
192 return NGX_ERROR; | 192 break; |
193 } | 193 } |
194 | 194 |
195 if (rc != NGX_DONE) { | 195 if (rc != NGX_DONE) { |
196 break; | 196 return rc; |
197 } | 197 } |
198 | 198 |
199 if (st->length == 0) { | 199 if (st->length == 0) { |
200 return NGX_ERROR; | 200 return NGX_HTTP_V3_ERR_FRAME_ERROR; |
201 } | 201 } |
202 | 202 |
203 st->state = sw_verify; | 203 st->state = sw_verify; |
204 break; | 204 break; |
205 | 205 |
216 | 216 |
217 case sw_header_rep: | 217 case sw_header_rep: |
218 | 218 |
219 rc = ngx_http_v3_parse_header_rep(c, &st->header_rep, st->prefix.base, | 219 rc = ngx_http_v3_parse_header_rep(c, &st->header_rep, st->prefix.base, |
220 ch); | 220 ch); |
221 | 221 st->length--; |
222 if (rc == NGX_ERROR) { | 222 |
223 return NGX_ERROR; | 223 if (rc == NGX_AGAIN) { |
224 } | 224 if (st->length == 0) { |
225 | 225 return NGX_HTTP_V3_ERR_FRAME_ERROR; |
226 if (--st->length == 0) { | |
227 if (rc != NGX_DONE) { | |
228 return NGX_ERROR; | |
229 } | 226 } |
230 | 227 |
228 break; | |
229 } | |
230 | |
231 if (rc != NGX_DONE) { | |
232 return rc; | |
233 } | |
234 | |
235 if (st->length == 0) { | |
231 goto done; | 236 goto done; |
232 } | 237 } |
233 | 238 |
234 if (rc == NGX_DONE) { | 239 return NGX_OK; |
235 return NGX_OK; | |
236 } | |
237 | |
238 break; | |
239 } | 240 } |
240 | 241 |
241 return NGX_AGAIN; | 242 return NGX_AGAIN; |
242 | 243 |
243 done: | 244 done: |
257 | 258 |
258 ngx_int_t | 259 ngx_int_t |
259 ngx_http_v3_parse_header_block_prefix(ngx_connection_t *c, | 260 ngx_http_v3_parse_header_block_prefix(ngx_connection_t *c, |
260 ngx_http_v3_parse_header_block_prefix_t *st, u_char ch) | 261 ngx_http_v3_parse_header_block_prefix_t *st, u_char ch) |
261 { | 262 { |
263 ngx_int_t rc; | |
262 enum { | 264 enum { |
263 sw_start = 0, | 265 sw_start = 0, |
264 sw_req_insert_count, | 266 sw_req_insert_count, |
265 sw_delta_base, | 267 sw_delta_base, |
266 sw_read_delta_base | 268 sw_read_delta_base |
306 | 308 |
307 return NGX_AGAIN; | 309 return NGX_AGAIN; |
308 | 310 |
309 done: | 311 done: |
310 | 312 |
311 if (ngx_http_v3_decode_insert_count(c, &st->insert_count) != NGX_OK) { | 313 rc = ngx_http_v3_decode_insert_count(c, &st->insert_count); |
312 return NGX_ERROR; | 314 if (rc != NGX_OK) { |
315 return rc; | |
313 } | 316 } |
314 | 317 |
315 if (st->sign) { | 318 if (st->sign) { |
316 st->base = st->insert_count - st->delta_base - 1; | 319 st->base = st->insert_count - st->delta_base - 1; |
317 } else { | 320 } else { |
402 | 405 |
403 default: | 406 default: |
404 rc = NGX_OK; | 407 rc = NGX_OK; |
405 } | 408 } |
406 | 409 |
407 if (rc == NGX_ERROR) { | 410 if (rc != NGX_DONE) { |
408 return NGX_ERROR; | 411 return rc; |
409 } | 412 } |
410 | |
411 if (rc == NGX_AGAIN) { | |
412 return NGX_AGAIN; | |
413 } | |
414 | |
415 /* rc == NGX_DONE */ | |
416 | 413 |
417 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | 414 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, |
418 "http3 parse header representation done"); | 415 "http3 parse header representation done"); |
419 | 416 |
420 st->state = sw_start; | 417 st->state = sw_start; |
446 v3cf = ngx_http_v3_get_module_srv_conf(c, ngx_http_v3_module); | 443 v3cf = ngx_http_v3_get_module_srv_conf(c, ngx_http_v3_module); |
447 | 444 |
448 if (n > v3cf->max_field_size) { | 445 if (n > v3cf->max_field_size) { |
449 ngx_log_error(NGX_LOG_INFO, c->log, 0, | 446 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
450 "client exceeded http3_max_field_size limit"); | 447 "client exceeded http3_max_field_size limit"); |
451 return NGX_ERROR; | 448 return NGX_HTTP_V3_ERR_EXCESSIVE_LOAD; |
452 } | 449 } |
453 | 450 |
454 if (st->huffman) { | 451 if (st->huffman) { |
455 n = n * 8 / 5; | 452 n = n * 8 / 5; |
456 st->huffstate = 0; | 453 st->huffstate = 0; |
503 | 500 |
504 ngx_int_t | 501 ngx_int_t |
505 ngx_http_v3_parse_header_ri(ngx_connection_t *c, ngx_http_v3_parse_header_t *st, | 502 ngx_http_v3_parse_header_ri(ngx_connection_t *c, ngx_http_v3_parse_header_t *st, |
506 u_char ch) | 503 u_char ch) |
507 { | 504 { |
505 ngx_int_t rc; | |
508 enum { | 506 enum { |
509 sw_start = 0, | 507 sw_start = 0, |
510 sw_index | 508 sw_index |
511 }; | 509 }; |
512 | 510 |
541 | 539 |
542 if (st->dynamic) { | 540 if (st->dynamic) { |
543 st->index = st->base - st->index - 1; | 541 st->index = st->base - st->index - 1; |
544 } | 542 } |
545 | 543 |
546 if (ngx_http_v3_parse_lookup(c, st->dynamic, st->index, &st->name, | 544 rc = ngx_http_v3_parse_lookup(c, st->dynamic, st->index, &st->name, |
547 &st->value) | 545 &st->value); |
548 != NGX_OK) | 546 if (rc != NGX_OK) { |
549 { | 547 return rc; |
550 return NGX_ERROR; | |
551 } | 548 } |
552 | 549 |
553 st->state = sw_start; | 550 st->state = sw_start; |
554 return NGX_DONE; | 551 return NGX_DONE; |
555 } | 552 } |
612 | 609 |
613 case sw_value: | 610 case sw_value: |
614 | 611 |
615 rc = ngx_http_v3_parse_literal(c, &st->literal, ch); | 612 rc = ngx_http_v3_parse_literal(c, &st->literal, ch); |
616 | 613 |
617 if (rc == NGX_ERROR) { | |
618 return NGX_ERROR; | |
619 } | |
620 | |
621 if (rc == NGX_DONE) { | 614 if (rc == NGX_DONE) { |
622 st->value = st->literal.value; | 615 st->value = st->literal.value; |
623 goto done; | 616 goto done; |
617 } | |
618 | |
619 if (rc != NGX_AGAIN) { | |
620 return rc; | |
624 } | 621 } |
625 | 622 |
626 break; | 623 break; |
627 } | 624 } |
628 | 625 |
637 | 634 |
638 if (st->dynamic) { | 635 if (st->dynamic) { |
639 st->index = st->base - st->index - 1; | 636 st->index = st->base - st->index - 1; |
640 } | 637 } |
641 | 638 |
642 if (ngx_http_v3_parse_lookup(c, st->dynamic, st->index, &st->name, NULL) | 639 rc = ngx_http_v3_parse_lookup(c, st->dynamic, st->index, &st->name, NULL); |
643 != NGX_OK) | 640 if (rc != NGX_OK) { |
644 { | 641 return rc; |
645 return NGX_ERROR; | |
646 } | 642 } |
647 | 643 |
648 st->state = sw_start; | 644 st->state = sw_start; |
649 return NGX_DONE; | 645 return NGX_DONE; |
650 } | 646 } |
691 | 687 |
692 case sw_name: | 688 case sw_name: |
693 | 689 |
694 rc = ngx_http_v3_parse_literal(c, &st->literal, ch); | 690 rc = ngx_http_v3_parse_literal(c, &st->literal, ch); |
695 | 691 |
696 if (rc == NGX_ERROR) { | |
697 return NGX_ERROR; | |
698 } | |
699 | |
700 if (rc == NGX_DONE) { | 692 if (rc == NGX_DONE) { |
701 st->name = st->literal.value; | 693 st->name = st->literal.value; |
702 st->state = sw_value_len; | 694 st->state = sw_value_len; |
695 break; | |
696 } | |
697 | |
698 if (rc != NGX_AGAIN) { | |
699 return rc; | |
703 } | 700 } |
704 | 701 |
705 break; | 702 break; |
706 | 703 |
707 case sw_value_len: | 704 case sw_value_len: |
727 | 724 |
728 case sw_value: | 725 case sw_value: |
729 | 726 |
730 rc = ngx_http_v3_parse_literal(c, &st->literal, ch); | 727 rc = ngx_http_v3_parse_literal(c, &st->literal, ch); |
731 | 728 |
732 if (rc == NGX_ERROR) { | |
733 return NGX_ERROR; | |
734 } | |
735 | |
736 if (rc == NGX_DONE) { | 729 if (rc == NGX_DONE) { |
737 st->value = st->literal.value; | 730 st->value = st->literal.value; |
738 goto done; | 731 goto done; |
739 } | 732 } |
740 | 733 |
734 if (rc != NGX_AGAIN) { | |
735 return rc; | |
736 } | |
737 | |
741 break; | 738 break; |
742 } | 739 } |
743 | 740 |
744 return NGX_AGAIN; | 741 return NGX_AGAIN; |
745 | 742 |
756 | 753 |
757 ngx_int_t | 754 ngx_int_t |
758 ngx_http_v3_parse_header_pbi(ngx_connection_t *c, | 755 ngx_http_v3_parse_header_pbi(ngx_connection_t *c, |
759 ngx_http_v3_parse_header_t *st, u_char ch) | 756 ngx_http_v3_parse_header_t *st, u_char ch) |
760 { | 757 { |
758 ngx_int_t rc; | |
761 enum { | 759 enum { |
762 sw_start = 0, | 760 sw_start = 0, |
763 sw_index | 761 sw_index |
764 }; | 762 }; |
765 | 763 |
788 done: | 786 done: |
789 | 787 |
790 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | 788 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, |
791 "http3 parse header pbi done dynamic[+%ui]", st->index); | 789 "http3 parse header pbi done dynamic[+%ui]", st->index); |
792 | 790 |
793 if (ngx_http_v3_parse_lookup(c, 1, st->base + st->index, &st->name, | 791 rc = ngx_http_v3_parse_lookup(c, 1, st->base + st->index, &st->name, |
794 &st->value) | 792 &st->value); |
795 != NGX_OK) | 793 if (rc != NGX_OK) { |
796 { | 794 return rc; |
797 return NGX_ERROR; | |
798 } | 795 } |
799 | 796 |
800 st->state = sw_start; | 797 st->state = sw_start; |
801 return NGX_DONE; | 798 return NGX_DONE; |
802 } | 799 } |
859 | 856 |
860 case sw_value: | 857 case sw_value: |
861 | 858 |
862 rc = ngx_http_v3_parse_literal(c, &st->literal, ch); | 859 rc = ngx_http_v3_parse_literal(c, &st->literal, ch); |
863 | 860 |
864 if (rc == NGX_ERROR) { | |
865 return NGX_ERROR; | |
866 } | |
867 | |
868 if (rc == NGX_DONE) { | 861 if (rc == NGX_DONE) { |
869 st->value = st->literal.value; | 862 st->value = st->literal.value; |
870 goto done; | 863 goto done; |
871 } | 864 } |
872 | 865 |
866 if (rc != NGX_AGAIN) { | |
867 return rc; | |
868 } | |
869 | |
873 break; | 870 break; |
874 } | 871 } |
875 | 872 |
876 return NGX_AGAIN; | 873 return NGX_AGAIN; |
877 | 874 |
879 | 876 |
880 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | 877 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, |
881 "http3 parse header lpbi done dynamic[+%ui] \"%V\"", | 878 "http3 parse header lpbi done dynamic[+%ui] \"%V\"", |
882 st->index, &st->value); | 879 st->index, &st->value); |
883 | 880 |
884 if (ngx_http_v3_parse_lookup(c, 1, st->base + st->index, &st->name, NULL) | 881 rc = ngx_http_v3_parse_lookup(c, 1, st->base + st->index, &st->name, NULL); |
885 != NGX_OK) | 882 if (rc != NGX_OK) { |
886 { | 883 return rc; |
887 return NGX_ERROR; | |
888 } | 884 } |
889 | 885 |
890 st->state = sw_start; | 886 st->state = sw_start; |
891 return NGX_DONE; | 887 return NGX_DONE; |
892 } | 888 } |
897 ngx_uint_t index, ngx_str_t *name, ngx_str_t *value) | 893 ngx_uint_t index, ngx_str_t *name, ngx_str_t *value) |
898 { | 894 { |
899 u_char *p; | 895 u_char *p; |
900 | 896 |
901 if (!dynamic) { | 897 if (!dynamic) { |
902 return ngx_http_v3_lookup_static(c, index, name, value); | 898 if (ngx_http_v3_lookup_static(c, index, name, value) != NGX_OK) { |
899 return NGX_HTTP_V3_ERR_DECOMPRESSION_FAILED; | |
900 } | |
901 | |
902 return NGX_OK; | |
903 } | 903 } |
904 | 904 |
905 if (ngx_http_v3_lookup(c, index, name, value) != NGX_OK) { | 905 if (ngx_http_v3_lookup(c, index, name, value) != NGX_OK) { |
906 return NGX_ERROR; | 906 return NGX_HTTP_V3_ERR_DECOMPRESSION_FAILED; |
907 } | 907 } |
908 | 908 |
909 if (name) { | 909 if (name) { |
910 p = ngx_pnalloc(c->pool, name->len + 1); | 910 p = ngx_pnalloc(c->pool, name->len + 1); |
911 if (p == NULL) { | 911 if (p == NULL) { |
938 ngx_http_v3_parse_control_t *st = data; | 938 ngx_http_v3_parse_control_t *st = data; |
939 | 939 |
940 ngx_int_t rc; | 940 ngx_int_t rc; |
941 enum { | 941 enum { |
942 sw_start = 0, | 942 sw_start = 0, |
943 sw_first_type, | |
943 sw_type, | 944 sw_type, |
944 sw_length, | 945 sw_length, |
945 sw_settings, | 946 sw_settings, |
946 sw_max_push_id, | 947 sw_max_push_id, |
947 sw_skip | 948 sw_skip |
951 | 952 |
952 case sw_start: | 953 case sw_start: |
953 | 954 |
954 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse control"); | 955 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse control"); |
955 | 956 |
956 st->state = sw_type; | 957 st->state = sw_first_type; |
957 | 958 |
958 /* fall through */ | 959 /* fall through */ |
959 | 960 |
961 case sw_first_type: | |
960 case sw_type: | 962 case sw_type: |
961 | 963 |
962 if (ngx_http_v3_parse_varlen_int(c, &st->vlint, ch) != NGX_DONE) { | 964 if (ngx_http_v3_parse_varlen_int(c, &st->vlint, ch) != NGX_DONE) { |
963 break; | 965 break; |
964 } | 966 } |
965 | 967 |
966 st->type = st->vlint.value; | 968 st->type = st->vlint.value; |
967 | 969 |
968 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | 970 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, |
969 "http3 parse frame type:%ui", st->type); | 971 "http3 parse frame type:%ui", st->type); |
972 | |
973 if (st->state == sw_first_type | |
974 && st->type != NGX_HTTP_V3_FRAME_SETTINGS) | |
975 { | |
976 return NGX_HTTP_V3_ERR_MISSING_SETTINGS; | |
977 } | |
970 | 978 |
971 st->state = sw_length; | 979 st->state = sw_length; |
972 break; | 980 break; |
973 | 981 |
974 case sw_length: | 982 case sw_length: |
1006 | 1014 |
1007 case sw_settings: | 1015 case sw_settings: |
1008 | 1016 |
1009 rc = ngx_http_v3_parse_settings(c, &st->settings, ch); | 1017 rc = ngx_http_v3_parse_settings(c, &st->settings, ch); |
1010 | 1018 |
1011 if (rc == NGX_ERROR) { | 1019 st->length--; |
1012 return NGX_ERROR; | 1020 |
1013 } | 1021 if (rc == NGX_AGAIN) { |
1014 | 1022 if (st->length == 0) { |
1015 if (--st->length > 0) { | 1023 return NGX_HTTP_V3_ERR_SETTINGS_ERROR; |
1024 } | |
1025 | |
1016 break; | 1026 break; |
1017 } | 1027 } |
1018 | 1028 |
1019 if (rc != NGX_DONE) { | 1029 if (rc != NGX_DONE) { |
1020 return NGX_ERROR; | 1030 return rc; |
1021 } | 1031 } |
1022 | 1032 |
1023 st->state = sw_type; | 1033 if (st->length == 0) { |
1034 st->state = sw_type; | |
1035 } | |
1036 | |
1024 break; | 1037 break; |
1025 | 1038 |
1026 case sw_max_push_id: | 1039 case sw_max_push_id: |
1027 | 1040 |
1028 if (ngx_http_v3_parse_varlen_int(c, &st->vlint, ch) != NGX_DONE) { | 1041 if (ngx_http_v3_parse_varlen_int(c, &st->vlint, ch) != NGX_DONE) { |
1083 if (ngx_http_v3_parse_varlen_int(c, &st->vlint, ch) != NGX_DONE) { | 1096 if (ngx_http_v3_parse_varlen_int(c, &st->vlint, ch) != NGX_DONE) { |
1084 break; | 1097 break; |
1085 } | 1098 } |
1086 | 1099 |
1087 if (ngx_http_v3_set_param(c, st->id, st->vlint.value) != NGX_OK) { | 1100 if (ngx_http_v3_set_param(c, st->id, st->vlint.value) != NGX_OK) { |
1088 return NGX_ERROR; | 1101 return NGX_HTTP_V3_ERR_SETTINGS_ERROR; |
1089 } | 1102 } |
1090 | 1103 |
1091 goto done; | 1104 goto done; |
1092 } | 1105 } |
1093 | 1106 |
1147 | 1160 |
1148 case sw_inr: | 1161 case sw_inr: |
1149 | 1162 |
1150 rc = ngx_http_v3_parse_header_inr(c, &st->header, ch); | 1163 rc = ngx_http_v3_parse_header_inr(c, &st->header, ch); |
1151 | 1164 |
1152 if (rc == NGX_ERROR) { | 1165 if (rc == NGX_AGAIN) { |
1153 return NGX_ERROR; | 1166 break; |
1154 } | 1167 } |
1155 | 1168 |
1156 if (rc != NGX_DONE) { | 1169 if (rc != NGX_DONE) { |
1157 break; | 1170 return rc; |
1158 } | 1171 } |
1159 | 1172 |
1160 goto done; | 1173 goto done; |
1161 | 1174 |
1162 case sw_iwnr: | 1175 case sw_iwnr: |
1163 | 1176 |
1164 rc = ngx_http_v3_parse_header_iwnr(c, &st->header, ch); | 1177 rc = ngx_http_v3_parse_header_iwnr(c, &st->header, ch); |
1165 | 1178 |
1166 if (rc == NGX_ERROR) { | 1179 if (rc == NGX_AGAIN) { |
1167 return NGX_ERROR; | 1180 break; |
1168 } | 1181 } |
1169 | 1182 |
1170 if (rc != NGX_DONE) { | 1183 if (rc != NGX_DONE) { |
1171 break; | 1184 return rc; |
1172 } | 1185 } |
1173 | 1186 |
1174 goto done; | 1187 goto done; |
1175 | 1188 |
1176 case sw_capacity: | 1189 case sw_capacity: |
1177 | 1190 |
1178 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 5, ch) != NGX_DONE) { | 1191 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 5, ch) != NGX_DONE) { |
1179 break; | 1192 break; |
1180 } | 1193 } |
1181 | 1194 |
1182 if (ngx_http_v3_set_capacity(c, st->pint.value) != NGX_OK) { | 1195 rc = ngx_http_v3_set_capacity(c, st->pint.value); |
1183 return NGX_ERROR; | 1196 if (rc != NGX_OK) { |
1197 return rc; | |
1184 } | 1198 } |
1185 | 1199 |
1186 goto done; | 1200 goto done; |
1187 | 1201 |
1188 case sw_duplicate: | 1202 case sw_duplicate: |
1189 | 1203 |
1190 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 5, ch) != NGX_DONE) { | 1204 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 5, ch) != NGX_DONE) { |
1191 break; | 1205 break; |
1192 } | 1206 } |
1193 | 1207 |
1194 if (ngx_http_v3_duplicate(c, st->pint.value) != NGX_OK) { | 1208 rc = ngx_http_v3_duplicate(c, st->pint.value); |
1195 return NGX_ERROR; | 1209 if (rc != NGX_OK) { |
1210 return rc; | |
1196 } | 1211 } |
1197 | 1212 |
1198 goto done; | 1213 goto done; |
1199 } | 1214 } |
1200 | 1215 |
1267 | 1282 |
1268 case sw_value: | 1283 case sw_value: |
1269 | 1284 |
1270 rc = ngx_http_v3_parse_literal(c, &st->literal, ch); | 1285 rc = ngx_http_v3_parse_literal(c, &st->literal, ch); |
1271 | 1286 |
1272 if (rc == NGX_ERROR) { | |
1273 return NGX_ERROR; | |
1274 } | |
1275 | |
1276 if (rc == NGX_DONE) { | 1287 if (rc == NGX_DONE) { |
1277 st->value = st->literal.value; | 1288 st->value = st->literal.value; |
1278 goto done; | 1289 goto done; |
1290 } | |
1291 | |
1292 if (rc != NGX_AGAIN) { | |
1293 return rc; | |
1279 } | 1294 } |
1280 | 1295 |
1281 break; | 1296 break; |
1282 } | 1297 } |
1283 | 1298 |
1288 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, | 1303 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, |
1289 "http3 parse header inr done %s[%ui] \"%V\"", | 1304 "http3 parse header inr done %s[%ui] \"%V\"", |
1290 st->dynamic ? "dynamic" : "static", | 1305 st->dynamic ? "dynamic" : "static", |
1291 st->index, &st->value); | 1306 st->index, &st->value); |
1292 | 1307 |
1293 if (ngx_http_v3_ref_insert(c, st->dynamic, st->index, &st->value) != NGX_OK) | 1308 rc = ngx_http_v3_ref_insert(c, st->dynamic, st->index, &st->value); |
1294 { | 1309 if (rc != NGX_OK) { |
1295 return NGX_ERROR; | 1310 return rc; |
1296 } | 1311 } |
1297 | 1312 |
1298 st->state = sw_start; | 1313 st->state = sw_start; |
1299 return NGX_DONE; | 1314 return NGX_DONE; |
1300 } | 1315 } |
1342 | 1357 |
1343 case sw_name: | 1358 case sw_name: |
1344 | 1359 |
1345 rc = ngx_http_v3_parse_literal(c, &st->literal, ch); | 1360 rc = ngx_http_v3_parse_literal(c, &st->literal, ch); |
1346 | 1361 |
1347 if (rc == NGX_ERROR) { | |
1348 return NGX_ERROR; | |
1349 } | |
1350 | |
1351 if (rc == NGX_DONE) { | 1362 if (rc == NGX_DONE) { |
1352 st->name = st->literal.value; | 1363 st->name = st->literal.value; |
1353 st->state = sw_value_len; | 1364 st->state = sw_value_len; |
1365 break; | |
1366 } | |
1367 | |
1368 if (rc != NGX_AGAIN) { | |
1369 return rc; | |
1354 } | 1370 } |
1355 | 1371 |
1356 break; | 1372 break; |
1357 | 1373 |
1358 case sw_value_len: | 1374 case sw_value_len: |
1378 | 1394 |
1379 case sw_value: | 1395 case sw_value: |
1380 | 1396 |
1381 rc = ngx_http_v3_parse_literal(c, &st->literal, ch); | 1397 rc = ngx_http_v3_parse_literal(c, &st->literal, ch); |
1382 | 1398 |
1383 if (rc == NGX_ERROR) { | |
1384 return NGX_ERROR; | |
1385 } | |
1386 | |
1387 if (rc == NGX_DONE) { | 1399 if (rc == NGX_DONE) { |
1388 st->value = st->literal.value; | 1400 st->value = st->literal.value; |
1389 goto done; | 1401 goto done; |
1390 } | 1402 } |
1391 | 1403 |
1404 if (rc != NGX_AGAIN) { | |
1405 return rc; | |
1406 } | |
1407 | |
1392 break; | 1408 break; |
1393 } | 1409 } |
1394 | 1410 |
1395 return NGX_AGAIN; | 1411 return NGX_AGAIN; |
1396 | 1412 |
1398 | 1414 |
1399 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | 1415 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, |
1400 "http3 parse header iwnr done \"%V\":\"%V\"", | 1416 "http3 parse header iwnr done \"%V\":\"%V\"", |
1401 &st->name, &st->value); | 1417 &st->name, &st->value); |
1402 | 1418 |
1403 if (ngx_http_v3_insert(c, &st->name, &st->value) != NGX_OK) { | 1419 rc = ngx_http_v3_insert(c, &st->name, &st->value); |
1404 return NGX_ERROR; | 1420 if (rc != NGX_OK) { |
1421 return rc; | |
1405 } | 1422 } |
1406 | 1423 |
1407 st->state = sw_start; | 1424 st->state = sw_start; |
1408 return NGX_DONE; | 1425 return NGX_DONE; |
1409 } | 1426 } |
1412 ngx_int_t | 1429 ngx_int_t |
1413 ngx_http_v3_parse_decoder(ngx_connection_t *c, void *data, u_char ch) | 1430 ngx_http_v3_parse_decoder(ngx_connection_t *c, void *data, u_char ch) |
1414 { | 1431 { |
1415 ngx_http_v3_parse_decoder_t *st = data; | 1432 ngx_http_v3_parse_decoder_t *st = data; |
1416 | 1433 |
1434 ngx_int_t rc; | |
1417 enum { | 1435 enum { |
1418 sw_start = 0, | 1436 sw_start = 0, |
1419 sw_ack_header, | 1437 sw_ack_header, |
1420 sw_cancel_stream, | 1438 sw_cancel_stream, |
1421 sw_inc_insert_count | 1439 sw_inc_insert_count |
1449 | 1467 |
1450 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 6, ch) != NGX_DONE) { | 1468 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 6, ch) != NGX_DONE) { |
1451 break; | 1469 break; |
1452 } | 1470 } |
1453 | 1471 |
1454 if (ngx_http_v3_ack_header(c, st->pint.value) != NGX_OK) { | 1472 rc = ngx_http_v3_ack_header(c, st->pint.value); |
1455 return NGX_ERROR; | 1473 if (rc != NGX_OK) { |
1474 return rc; | |
1456 } | 1475 } |
1457 | 1476 |
1458 goto done; | 1477 goto done; |
1459 | 1478 |
1460 case sw_cancel_stream: | 1479 case sw_cancel_stream: |
1461 | 1480 |
1462 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 6, ch) != NGX_DONE) { | 1481 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 6, ch) != NGX_DONE) { |
1463 break; | 1482 break; |
1464 } | 1483 } |
1465 | 1484 |
1466 if (ngx_http_v3_cancel_stream(c, st->pint.value) != NGX_OK) { | 1485 rc = ngx_http_v3_cancel_stream(c, st->pint.value); |
1467 return NGX_ERROR; | 1486 if (rc != NGX_OK) { |
1487 return rc; | |
1468 } | 1488 } |
1469 | 1489 |
1470 goto done; | 1490 goto done; |
1471 | 1491 |
1472 case sw_inc_insert_count: | 1492 case sw_inc_insert_count: |
1473 | 1493 |
1474 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 6, ch) != NGX_DONE) { | 1494 if (ngx_http_v3_parse_prefix_int(c, &st->pint, 6, ch) != NGX_DONE) { |
1475 break; | 1495 break; |
1476 } | 1496 } |
1477 | 1497 |
1478 if (ngx_http_v3_inc_insert_count(c, st->pint.value) != NGX_OK) { | 1498 rc = ngx_http_v3_inc_insert_count(c, st->pint.value); |
1479 return NGX_ERROR; | 1499 if (rc != NGX_OK) { |
1500 return rc; | |
1480 } | 1501 } |
1481 | 1502 |
1482 goto done; | 1503 goto done; |
1483 } | 1504 } |
1484 | 1505 |
1519 if (ngx_http_v3_parse_varlen_int(c, &st->vlint, ch) != NGX_DONE) { | 1540 if (ngx_http_v3_parse_varlen_int(c, &st->vlint, ch) != NGX_DONE) { |
1520 break; | 1541 break; |
1521 } | 1542 } |
1522 | 1543 |
1523 if (st->vlint.value != NGX_HTTP_V3_FRAME_DATA) { | 1544 if (st->vlint.value != NGX_HTTP_V3_FRAME_DATA) { |
1524 return NGX_ERROR; | 1545 return NGX_HTTP_V3_ERR_FRAME_UNEXPECTED; |
1525 } | 1546 } |
1526 | 1547 |
1527 st->state = sw_length; | 1548 st->state = sw_length; |
1528 break; | 1549 break; |
1529 | 1550 |