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