Mercurial > hg > nginx-quic
comparison src/http/v3/ngx_http_v3_filter_module.c @ 8624:3fdf0afd5d45 quic
HTTP/3: fixed pushed request finalization in case of error.
Previously request could be finalized twice. For example, this could happen
if "Host" header was invalid.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Fri, 17 Sep 2021 15:28:31 +0300 |
parents | 6a383020d61e |
children | 33578b8d453d |
comparison
equal
deleted
inserted
replaced
8623:630ecd703805 | 8624:3fdf0afd5d45 |
---|---|
878 | 878 |
879 static ngx_int_t | 879 static ngx_int_t |
880 ngx_http_v3_create_push_request(ngx_http_request_t *pr, ngx_str_t *path, | 880 ngx_http_v3_create_push_request(ngx_http_request_t *pr, ngx_str_t *path, |
881 uint64_t push_id) | 881 uint64_t push_id) |
882 { | 882 { |
883 ngx_pool_t *pool; | |
884 ngx_connection_t *c, *pc; | 883 ngx_connection_t *c, *pc; |
885 ngx_http_request_t *r; | 884 ngx_http_request_t *r; |
886 ngx_http_log_ctx_t *ctx; | 885 ngx_http_log_ctx_t *ctx; |
887 ngx_http_connection_t *hc, *phc; | 886 ngx_http_connection_t *hc, *phc; |
888 ngx_http_core_srv_conf_t *cscf; | 887 ngx_http_core_srv_conf_t *cscf; |
889 | 888 |
890 pc = pr->connection; | 889 pc = pr->connection; |
891 | 890 |
892 r = NULL; | |
893 | |
894 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0, | 891 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0, |
895 "http3 create push request id:%uL", push_id); | 892 "http3 create push request id:%uL", push_id); |
896 | 893 |
897 c = ngx_http_v3_create_push_stream(pc, push_id); | 894 c = ngx_http_v3_create_push_stream(pc, push_id); |
898 if (c == NULL) { | 895 if (c == NULL) { |
899 return NGX_ABORT; | 896 return NGX_ABORT; |
900 } | 897 } |
901 | 898 |
902 hc = ngx_palloc(c->pool, sizeof(ngx_http_connection_t)); | 899 hc = ngx_palloc(c->pool, sizeof(ngx_http_connection_t)); |
903 if (hc == NULL) { | 900 if (hc == NULL) { |
904 goto failed; | 901 ngx_http_close_connection(c); |
902 return NGX_ERROR; | |
905 } | 903 } |
906 | 904 |
907 phc = ngx_http_quic_get_connection(pc); | 905 phc = ngx_http_quic_get_connection(pc); |
908 ngx_memcpy(hc, phc, sizeof(ngx_http_connection_t)); | 906 ngx_memcpy(hc, phc, sizeof(ngx_http_connection_t)); |
909 c->data = hc; | 907 c->data = hc; |
910 | 908 |
911 ctx = ngx_palloc(c->pool, sizeof(ngx_http_log_ctx_t)); | 909 ctx = ngx_palloc(c->pool, sizeof(ngx_http_log_ctx_t)); |
912 if (ctx == NULL) { | 910 if (ctx == NULL) { |
913 goto failed; | 911 ngx_http_close_connection(c); |
912 return NGX_ERROR; | |
914 } | 913 } |
915 | 914 |
916 ctx->connection = c; | 915 ctx->connection = c; |
917 ctx->request = NULL; | 916 ctx->request = NULL; |
918 ctx->current_request = NULL; | 917 ctx->current_request = NULL; |
923 | 922 |
924 c->log_error = NGX_ERROR_INFO; | 923 c->log_error = NGX_ERROR_INFO; |
925 | 924 |
926 r = ngx_http_create_request(c); | 925 r = ngx_http_create_request(c); |
927 if (r == NULL) { | 926 if (r == NULL) { |
928 goto failed; | 927 ngx_http_close_connection(c); |
928 return NGX_ERROR; | |
929 } | 929 } |
930 | 930 |
931 c->data = r; | 931 c->data = r; |
932 | 932 |
933 ngx_str_set(&r->http_protocol, "HTTP/3.0"); | 933 ngx_str_set(&r->http_protocol, "HTTP/3.0"); |
939 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); | 939 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); |
940 | 940 |
941 r->header_in = ngx_create_temp_buf(r->pool, | 941 r->header_in = ngx_create_temp_buf(r->pool, |
942 cscf->client_header_buffer_size); | 942 cscf->client_header_buffer_size); |
943 if (r->header_in == NULL) { | 943 if (r->header_in == NULL) { |
944 goto failed; | 944 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); |
945 return NGX_ERROR; | |
945 } | 946 } |
946 | 947 |
947 if (ngx_list_init(&r->headers_in.headers, r->pool, 4, | 948 if (ngx_list_init(&r->headers_in.headers, r->pool, 4, |
948 sizeof(ngx_table_elt_t)) | 949 sizeof(ngx_table_elt_t)) |
949 != NGX_OK) | 950 != NGX_OK) |
950 { | 951 { |
951 goto failed; | 952 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); |
953 return NGX_ERROR; | |
952 } | 954 } |
953 | 955 |
954 r->headers_in.connection_type = NGX_HTTP_CONNECTION_CLOSE; | 956 r->headers_in.connection_type = NGX_HTTP_CONNECTION_CLOSE; |
955 | 957 |
956 r->schema.data = ngx_pstrdup(r->pool, &pr->schema); | 958 r->schema.data = ngx_pstrdup(r->pool, &pr->schema); |
957 if (r->schema.data == NULL) { | 959 if (r->schema.data == NULL) { |
958 goto failed; | 960 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); |
961 return NGX_ERROR; | |
959 } | 962 } |
960 | 963 |
961 r->schema.len = pr->schema.len; | 964 r->schema.len = pr->schema.len; |
962 | 965 |
963 r->uri_start = ngx_pstrdup(r->pool, path); | 966 r->uri_start = ngx_pstrdup(r->pool, path); |
964 if (r->uri_start == NULL) { | 967 if (r->uri_start == NULL) { |
965 goto failed; | 968 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); |
969 return NGX_ERROR; | |
966 } | 970 } |
967 | 971 |
968 r->uri_end = r->uri_start + path->len; | 972 r->uri_end = r->uri_start + path->len; |
969 | 973 |
970 if (ngx_http_parse_uri(r) != NGX_OK) { | 974 if (ngx_http_parse_uri(r) != NGX_OK) { |
971 goto failed; | 975 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); |
976 return NGX_ERROR; | |
972 } | 977 } |
973 | 978 |
974 if (ngx_http_process_request_uri(r) != NGX_OK) { | 979 if (ngx_http_process_request_uri(r) != NGX_OK) { |
975 goto failed; | 980 return NGX_ERROR; |
976 } | 981 } |
977 | 982 |
978 if (ngx_http_v3_set_push_header(r, "host", &pr->headers_in.server) | 983 if (ngx_http_v3_set_push_header(r, "host", &pr->headers_in.server) |
979 != NGX_OK) | 984 != NGX_OK) |
980 { | 985 { |
981 goto failed; | 986 return NGX_ERROR; |
982 } | 987 } |
983 | 988 |
984 if (pr->headers_in.accept_encoding) { | 989 if (pr->headers_in.accept_encoding) { |
985 if (ngx_http_v3_set_push_header(r, "accept-encoding", | 990 if (ngx_http_v3_set_push_header(r, "accept-encoding", |
986 &pr->headers_in.accept_encoding->value) | 991 &pr->headers_in.accept_encoding->value) |
987 != NGX_OK) | 992 != NGX_OK) |
988 { | 993 { |
989 goto failed; | 994 return NGX_ERROR; |
990 } | 995 } |
991 } | 996 } |
992 | 997 |
993 if (pr->headers_in.accept_language) { | 998 if (pr->headers_in.accept_language) { |
994 if (ngx_http_v3_set_push_header(r, "accept-language", | 999 if (ngx_http_v3_set_push_header(r, "accept-language", |
995 &pr->headers_in.accept_language->value) | 1000 &pr->headers_in.accept_language->value) |
996 != NGX_OK) | 1001 != NGX_OK) |
997 { | 1002 { |
998 goto failed; | 1003 return NGX_ERROR; |
999 } | 1004 } |
1000 } | 1005 } |
1001 | 1006 |
1002 if (pr->headers_in.user_agent) { | 1007 if (pr->headers_in.user_agent) { |
1003 if (ngx_http_v3_set_push_header(r, "user-agent", | 1008 if (ngx_http_v3_set_push_header(r, "user-agent", |
1004 &pr->headers_in.user_agent->value) | 1009 &pr->headers_in.user_agent->value) |
1005 != NGX_OK) | 1010 != NGX_OK) |
1006 { | 1011 { |
1007 goto failed; | 1012 return NGX_ERROR; |
1008 } | 1013 } |
1009 } | 1014 } |
1010 | 1015 |
1011 c->read->handler = ngx_http_v3_push_request_handler; | 1016 c->read->handler = ngx_http_v3_push_request_handler; |
1012 c->read->handler = ngx_http_v3_push_request_handler; | 1017 c->read->handler = ngx_http_v3_push_request_handler; |
1013 | 1018 |
1014 ngx_post_event(c->read, &ngx_posted_events); | 1019 ngx_post_event(c->read, &ngx_posted_events); |
1015 | 1020 |
1016 return NGX_OK; | 1021 return NGX_OK; |
1017 | |
1018 failed: | |
1019 | |
1020 if (r) { | |
1021 ngx_http_free_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
1022 } | |
1023 | |
1024 c->destroyed = 1; | |
1025 | |
1026 pool = c->pool; | |
1027 | |
1028 ngx_close_connection(c); | |
1029 | |
1030 ngx_destroy_pool(pool); | |
1031 | |
1032 return NGX_ERROR; | |
1033 } | 1022 } |
1034 | 1023 |
1035 | 1024 |
1036 static ngx_int_t | 1025 static ngx_int_t |
1037 ngx_http_v3_set_push_header(ngx_http_request_t *r, const char *name, | 1026 ngx_http_v3_set_push_header(ngx_http_request_t *r, const char *name, |
1047 | 1036 |
1048 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); | 1037 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); |
1049 | 1038 |
1050 p = ngx_pnalloc(r->pool, value->len + 1); | 1039 p = ngx_pnalloc(r->pool, value->len + 1); |
1051 if (p == NULL) { | 1040 if (p == NULL) { |
1041 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
1052 return NGX_ERROR; | 1042 return NGX_ERROR; |
1053 } | 1043 } |
1054 | 1044 |
1055 ngx_memcpy(p, value->data, value->len); | 1045 ngx_memcpy(p, value->data, value->len); |
1056 p[value->len] = '\0'; | 1046 p[value->len] = '\0'; |
1057 | 1047 |
1058 h = ngx_list_push(&r->headers_in.headers); | 1048 h = ngx_list_push(&r->headers_in.headers); |
1059 if (h == NULL) { | 1049 if (h == NULL) { |
1050 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
1060 return NGX_ERROR; | 1051 return NGX_ERROR; |
1061 } | 1052 } |
1062 | 1053 |
1063 h->key.data = (u_char *) name; | 1054 h->key.data = (u_char *) name; |
1064 h->key.len = ngx_strlen(name); | 1055 h->key.len = ngx_strlen(name); |