annotate src/http/v3/ngx_http_v3_request.c @ 8723:265062a99043 quic

HTTP/3: send GOAWAY when last request is accepted. The last request in connection is determined according to the keepalive_requests directive. Requests beyond keepalive_requests are rejected.
author Roman Arutyunyan <arut@nginx.com>
date Mon, 15 Mar 2021 19:26:04 +0300
parents ffcaf0aad9f2
children fc64ab301bad
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
1
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
2 /*
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
3 * Copyright (C) Roman Arutyunyan
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
4 * Copyright (C) Nginx, Inc.
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
5 */
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
6
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
7
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
8 #include <ngx_config.h>
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
9 #include <ngx_core.h>
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
10 #include <ngx_http.h>
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
11
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
12
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
13 static void ngx_http_v3_process_request(ngx_event_t *rev);
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
14 static ngx_int_t ngx_http_v3_process_header(ngx_http_request_t *r,
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
15 ngx_str_t *name, ngx_str_t *value);
8682
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
16 static ngx_int_t ngx_http_v3_validate_header(ngx_http_request_t *r,
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
17 ngx_str_t *name, ngx_str_t *value);
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
18 static ngx_int_t ngx_http_v3_process_pseudo_header(ngx_http_request_t *r,
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
19 ngx_str_t *name, ngx_str_t *value);
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
20 static ngx_int_t ngx_http_v3_init_pseudo_headers(ngx_http_request_t *r);
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
21 static ngx_int_t ngx_http_v3_process_request_header(ngx_http_request_t *r);
8689
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
22 static void ngx_http_v3_read_client_request_body_handler(ngx_http_request_t *r);
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
23 static ngx_int_t ngx_http_v3_do_read_client_request_body(ngx_http_request_t *r);
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
24 static ngx_int_t ngx_http_v3_request_body_filter(ngx_http_request_t *r,
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
25 ngx_chain_t *in);
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
26
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
27
8665
96eb6915d244 HTTP/3: staticize ngx_http_v3_methods.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8653
diff changeset
28 static const struct {
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
29 ngx_str_t name;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
30 ngx_uint_t method;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
31 } ngx_http_v3_methods[] = {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
32
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
33 { ngx_string("GET"), NGX_HTTP_GET },
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
34 { ngx_string("POST"), NGX_HTTP_POST },
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
35 { ngx_string("HEAD"), NGX_HTTP_HEAD },
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
36 { ngx_string("OPTIONS"), NGX_HTTP_OPTIONS },
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
37 { ngx_string("PROPFIND"), NGX_HTTP_PROPFIND },
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
38 { ngx_string("PUT"), NGX_HTTP_PUT },
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
39 { ngx_string("MKCOL"), NGX_HTTP_MKCOL },
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
40 { ngx_string("DELETE"), NGX_HTTP_DELETE },
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
41 { ngx_string("COPY"), NGX_HTTP_COPY },
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
42 { ngx_string("MOVE"), NGX_HTTP_MOVE },
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
43 { ngx_string("PROPPATCH"), NGX_HTTP_PROPPATCH },
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
44 { ngx_string("LOCK"), NGX_HTTP_LOCK },
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
45 { ngx_string("UNLOCK"), NGX_HTTP_UNLOCK },
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
46 { ngx_string("PATCH"), NGX_HTTP_PATCH },
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
47 { ngx_string("TRACE"), NGX_HTTP_TRACE }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
48 };
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
49
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
50
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
51 void
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
52 ngx_http_v3_init(ngx_connection_t *c)
8226
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
53 {
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
54 size_t size;
8723
265062a99043 HTTP/3: send GOAWAY when last request is accepted.
Roman Arutyunyan <arut@nginx.com>
parents: 8707
diff changeset
55 uint64_t n;
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
56 ngx_buf_t *b;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
57 ngx_event_t *rev;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
58 ngx_http_request_t *r;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
59 ngx_http_connection_t *hc;
8723
265062a99043 HTTP/3: send GOAWAY when last request is accepted.
Roman Arutyunyan <arut@nginx.com>
parents: 8707
diff changeset
60 ngx_http_core_loc_conf_t *clcf;
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
61 ngx_http_core_srv_conf_t *cscf;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
62
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
63 if (ngx_http_v3_init_session(c) != NGX_OK) {
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
64 ngx_http_v3_finalize_connection(c, NGX_HTTP_V3_ERR_INTERNAL_ERROR,
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
65 "internal error");
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
66 ngx_http_close_connection(c);
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
67 return;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
68 }
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
69
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
70 if (c->quic->id & NGX_QUIC_STREAM_UNIDIRECTIONAL) {
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
71 ngx_http_v3_init_uni_stream(c);
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
72 return;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
73 }
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
74
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
75 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 init request stream");
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
76
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
77 hc = c->data;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
78
8723
265062a99043 HTTP/3: send GOAWAY when last request is accepted.
Roman Arutyunyan <arut@nginx.com>
parents: 8707
diff changeset
79 clcf = ngx_http_get_module_loc_conf(hc->conf_ctx, ngx_http_core_module);
265062a99043 HTTP/3: send GOAWAY when last request is accepted.
Roman Arutyunyan <arut@nginx.com>
parents: 8707
diff changeset
80
265062a99043 HTTP/3: send GOAWAY when last request is accepted.
Roman Arutyunyan <arut@nginx.com>
parents: 8707
diff changeset
81 n = c->quic->id >> 2;
265062a99043 HTTP/3: send GOAWAY when last request is accepted.
Roman Arutyunyan <arut@nginx.com>
parents: 8707
diff changeset
82
265062a99043 HTTP/3: send GOAWAY when last request is accepted.
Roman Arutyunyan <arut@nginx.com>
parents: 8707
diff changeset
83 if (n >= clcf->keepalive_requests) {
265062a99043 HTTP/3: send GOAWAY when last request is accepted.
Roman Arutyunyan <arut@nginx.com>
parents: 8707
diff changeset
84 ngx_quic_reset_stream(c, NGX_HTTP_V3_ERR_REQUEST_REJECTED);
265062a99043 HTTP/3: send GOAWAY when last request is accepted.
Roman Arutyunyan <arut@nginx.com>
parents: 8707
diff changeset
85 ngx_http_close_connection(c);
265062a99043 HTTP/3: send GOAWAY when last request is accepted.
Roman Arutyunyan <arut@nginx.com>
parents: 8707
diff changeset
86 return;
265062a99043 HTTP/3: send GOAWAY when last request is accepted.
Roman Arutyunyan <arut@nginx.com>
parents: 8707
diff changeset
87 }
265062a99043 HTTP/3: send GOAWAY when last request is accepted.
Roman Arutyunyan <arut@nginx.com>
parents: 8707
diff changeset
88
265062a99043 HTTP/3: send GOAWAY when last request is accepted.
Roman Arutyunyan <arut@nginx.com>
parents: 8707
diff changeset
89 if (n + 1 == clcf->keepalive_requests) {
265062a99043 HTTP/3: send GOAWAY when last request is accepted.
Roman Arutyunyan <arut@nginx.com>
parents: 8707
diff changeset
90 if (ngx_http_v3_send_goaway(c, (n + 1) << 2) != NGX_OK) {
265062a99043 HTTP/3: send GOAWAY when last request is accepted.
Roman Arutyunyan <arut@nginx.com>
parents: 8707
diff changeset
91 ngx_http_v3_finalize_connection(c, NGX_HTTP_V3_ERR_INTERNAL_ERROR,
265062a99043 HTTP/3: send GOAWAY when last request is accepted.
Roman Arutyunyan <arut@nginx.com>
parents: 8707
diff changeset
92 "goaway error");
265062a99043 HTTP/3: send GOAWAY when last request is accepted.
Roman Arutyunyan <arut@nginx.com>
parents: 8707
diff changeset
93 ngx_http_close_connection(c);
265062a99043 HTTP/3: send GOAWAY when last request is accepted.
Roman Arutyunyan <arut@nginx.com>
parents: 8707
diff changeset
94 return;
265062a99043 HTTP/3: send GOAWAY when last request is accepted.
Roman Arutyunyan <arut@nginx.com>
parents: 8707
diff changeset
95 }
265062a99043 HTTP/3: send GOAWAY when last request is accepted.
Roman Arutyunyan <arut@nginx.com>
parents: 8707
diff changeset
96 }
265062a99043 HTTP/3: send GOAWAY when last request is accepted.
Roman Arutyunyan <arut@nginx.com>
parents: 8707
diff changeset
97
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
98 cscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_core_module);
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
99
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
100 size = cscf->client_header_buffer_size;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
101
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
102 b = c->buffer;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
103
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
104 if (b == NULL) {
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
105 b = ngx_create_temp_buf(c->pool, size);
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
106 if (b == NULL) {
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
107 ngx_http_close_connection(c);
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
108 return;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
109 }
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
110
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
111 c->buffer = b;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
112
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
113 } else if (b->start == NULL) {
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
114
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
115 b->start = ngx_palloc(c->pool, size);
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
116 if (b->start == NULL) {
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
117 ngx_http_close_connection(c);
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
118 return;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
119 }
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
120
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
121 b->pos = b->start;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
122 b->last = b->start;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
123 b->end = b->last + size;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
124 }
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
125
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
126 c->log->action = "reading client request";
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
127
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
128 r = ngx_http_create_request(c);
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
129 if (r == NULL) {
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
130 ngx_http_close_connection(c);
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
131 return;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
132 }
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
133
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
134 r->http_version = NGX_HTTP_VERSION_30;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
135
8706
3057bae4dba7 HTTP/3: introduced ngx_http_v3_parse_t structure.
Roman Arutyunyan <arut@nginx.com>
parents: 8690
diff changeset
136 r->v3_parse = ngx_pcalloc(r->pool, sizeof(ngx_http_v3_parse_t));
3057bae4dba7 HTTP/3: introduced ngx_http_v3_parse_t structure.
Roman Arutyunyan <arut@nginx.com>
parents: 8690
diff changeset
137 if (r->v3_parse == NULL) {
3057bae4dba7 HTTP/3: introduced ngx_http_v3_parse_t structure.
Roman Arutyunyan <arut@nginx.com>
parents: 8690
diff changeset
138 ngx_http_close_connection(c);
3057bae4dba7 HTTP/3: introduced ngx_http_v3_parse_t structure.
Roman Arutyunyan <arut@nginx.com>
parents: 8690
diff changeset
139 return;
3057bae4dba7 HTTP/3: introduced ngx_http_v3_parse_t structure.
Roman Arutyunyan <arut@nginx.com>
parents: 8690
diff changeset
140 }
3057bae4dba7 HTTP/3: introduced ngx_http_v3_parse_t structure.
Roman Arutyunyan <arut@nginx.com>
parents: 8690
diff changeset
141
8707
ffcaf0aad9f2 HTTP/3: limited client header size.
Roman Arutyunyan <arut@nginx.com>
parents: 8706
diff changeset
142 r->v3_parse->header_limit = cscf->large_client_header_buffers.size
ffcaf0aad9f2 HTTP/3: limited client header size.
Roman Arutyunyan <arut@nginx.com>
parents: 8706
diff changeset
143 * cscf->large_client_header_buffers.num;
ffcaf0aad9f2 HTTP/3: limited client header size.
Roman Arutyunyan <arut@nginx.com>
parents: 8706
diff changeset
144
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
145 c->data = r;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
146
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
147 rev = c->read;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
148 rev->handler = ngx_http_v3_process_request;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
149
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
150 ngx_http_v3_process_request(rev);
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
151 }
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
152
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
153
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
154 static void
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
155 ngx_http_v3_process_request(ngx_event_t *rev)
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
156 {
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
157 ssize_t n;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
158 ngx_buf_t *b;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
159 ngx_int_t rc;
8226
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
160 ngx_connection_t *c;
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
161 ngx_http_request_t *r;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
162 ngx_http_core_srv_conf_t *cscf;
8226
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
163 ngx_http_v3_parse_headers_t *st;
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
164
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
165 c = rev->data;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
166 r = c->data;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
167
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
168 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "http3 process request");
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
169
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
170 if (rev->timedout) {
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
171 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
172 c->timedout = 1;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
173 ngx_http_close_request(r, NGX_HTTP_REQUEST_TIME_OUT);
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
174 return;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
175 }
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
176
8706
3057bae4dba7 HTTP/3: introduced ngx_http_v3_parse_t structure.
Roman Arutyunyan <arut@nginx.com>
parents: 8690
diff changeset
177 st = &r->v3_parse->headers;
8226
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
178
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
179 b = r->header_in;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
180
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
181 for ( ;; ) {
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
182
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
183 if (b->pos == b->last) {
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
184
8685
dbe33ef9cd9a HTTP/3: call ngx_handle_read_event() from client header handler.
Roman Arutyunyan <arut@nginx.com>
parents: 8682
diff changeset
185 if (rev->ready) {
dbe33ef9cd9a HTTP/3: call ngx_handle_read_event() from client header handler.
Roman Arutyunyan <arut@nginx.com>
parents: 8682
diff changeset
186 n = c->recv(c, b->start, b->end - b->start);
dbe33ef9cd9a HTTP/3: call ngx_handle_read_event() from client header handler.
Roman Arutyunyan <arut@nginx.com>
parents: 8682
diff changeset
187
dbe33ef9cd9a HTTP/3: call ngx_handle_read_event() from client header handler.
Roman Arutyunyan <arut@nginx.com>
parents: 8682
diff changeset
188 } else {
dbe33ef9cd9a HTTP/3: call ngx_handle_read_event() from client header handler.
Roman Arutyunyan <arut@nginx.com>
parents: 8682
diff changeset
189 n = NGX_AGAIN;
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
190 }
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
191
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
192 if (n == NGX_AGAIN) {
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
193 if (!rev->timer_set) {
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
194 cscf = ngx_http_get_module_srv_conf(r,
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
195 ngx_http_core_module);
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
196 ngx_add_timer(rev, cscf->client_header_timeout);
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
197 }
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
198
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
199 if (ngx_handle_read_event(rev, 0) != NGX_OK) {
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
200 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
201 }
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
202
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
203 break;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
204 }
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
205
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
206 if (n == 0) {
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
207 ngx_log_error(NGX_LOG_INFO, c->log, 0,
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
208 "client prematurely closed connection");
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
209 }
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
210
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
211 if (n == 0 || n == NGX_ERROR) {
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
212 c->error = 1;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
213 c->log->action = "reading client request";
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
214
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
215 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
216 break;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
217 }
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
218
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
219 b->pos = b->start;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
220 b->last = b->start + n;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
221 }
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
222
8456
c9538aef3211 HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents: 8452
diff changeset
223 rc = ngx_http_v3_parse_headers(c, st, *b->pos);
8226
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
224
8460
72f9ff4e0a88 HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents: 8456
diff changeset
225 if (rc > 0) {
72f9ff4e0a88 HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents: 8456
diff changeset
226 ngx_http_v3_finalize_connection(c, rc,
72f9ff4e0a88 HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents: 8456
diff changeset
227 "could not parse request headers");
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
228 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
229 break;
8460
72f9ff4e0a88 HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents: 8456
diff changeset
230 }
72f9ff4e0a88 HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents: 8456
diff changeset
231
8226
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
232 if (rc == NGX_ERROR) {
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
233 ngx_http_v3_finalize_connection(c, NGX_HTTP_V3_ERR_INTERNAL_ERROR,
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
234 "internal error");
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
235 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
236 break;
8226
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
237 }
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
238
8456
c9538aef3211 HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents: 8452
diff changeset
239 if (rc == NGX_BUSY) {
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
240 if (rev->error) {
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
241 ngx_http_close_request(r, NGX_HTTP_CLOSE);
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
242 break;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
243 }
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
244
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
245 if (ngx_handle_read_event(rev, 0) != NGX_OK) {
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
246 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
247 }
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
248
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
249 break;
8456
c9538aef3211 HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents: 8452
diff changeset
250 }
c9538aef3211 HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents: 8452
diff changeset
251
c9538aef3211 HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents: 8452
diff changeset
252 b->pos++;
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
253 r->request_length++;
8456
c9538aef3211 HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents: 8452
diff changeset
254
8226
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
255 if (rc == NGX_AGAIN) {
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
256 continue;
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
257 }
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
258
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
259 /* rc == NGX_OK || rc == NGX_DONE */
8233
1e45c02f6376 HTTP/3 $request_line variable.
Roman Arutyunyan <arut@nginx.com>
parents: 8230
diff changeset
260
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
261 if (ngx_http_v3_process_header(r, &st->header_rep.header.name,
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
262 &st->header_rep.header.value)
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
263 != NGX_OK)
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
264 {
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
265 break;
8405
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
266 }
8226
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
267
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
268 if (rc == NGX_DONE) {
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
269 if (ngx_http_v3_process_request_header(r) != NGX_OK) {
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
270 break;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
271 }
8405
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
272
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
273 ngx_http_process_request(r);
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
274 break;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
275 }
8226
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
276 }
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
277
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
278 ngx_http_run_posted_requests(c);
8226
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
279
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
280 return;
8405
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
281 }
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
282
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
283
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
284 static ngx_int_t
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
285 ngx_http_v3_process_header(ngx_http_request_t *r, ngx_str_t *name,
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
286 ngx_str_t *value)
8405
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
287 {
8707
ffcaf0aad9f2 HTTP/3: limited client header size.
Roman Arutyunyan <arut@nginx.com>
parents: 8706
diff changeset
288 size_t len;
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
289 ngx_table_elt_t *h;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
290 ngx_http_header_t *hh;
8682
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
291 ngx_http_core_srv_conf_t *cscf;
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
292 ngx_http_core_main_conf_t *cmcf;
8452
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
293
8707
ffcaf0aad9f2 HTTP/3: limited client header size.
Roman Arutyunyan <arut@nginx.com>
parents: 8706
diff changeset
294 len = name->len + value->len;
ffcaf0aad9f2 HTTP/3: limited client header size.
Roman Arutyunyan <arut@nginx.com>
parents: 8706
diff changeset
295
ffcaf0aad9f2 HTTP/3: limited client header size.
Roman Arutyunyan <arut@nginx.com>
parents: 8706
diff changeset
296 if (len > r->v3_parse->header_limit) {
ffcaf0aad9f2 HTTP/3: limited client header size.
Roman Arutyunyan <arut@nginx.com>
parents: 8706
diff changeset
297 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
ffcaf0aad9f2 HTTP/3: limited client header size.
Roman Arutyunyan <arut@nginx.com>
parents: 8706
diff changeset
298 "client sent too large header");
ffcaf0aad9f2 HTTP/3: limited client header size.
Roman Arutyunyan <arut@nginx.com>
parents: 8706
diff changeset
299 ngx_http_finalize_request(r, NGX_HTTP_REQUEST_HEADER_TOO_LARGE);
ffcaf0aad9f2 HTTP/3: limited client header size.
Roman Arutyunyan <arut@nginx.com>
parents: 8706
diff changeset
300 return NGX_ERROR;
ffcaf0aad9f2 HTTP/3: limited client header size.
Roman Arutyunyan <arut@nginx.com>
parents: 8706
diff changeset
301 }
ffcaf0aad9f2 HTTP/3: limited client header size.
Roman Arutyunyan <arut@nginx.com>
parents: 8706
diff changeset
302
ffcaf0aad9f2 HTTP/3: limited client header size.
Roman Arutyunyan <arut@nginx.com>
parents: 8706
diff changeset
303 r->v3_parse->header_limit -= len;
ffcaf0aad9f2 HTTP/3: limited client header size.
Roman Arutyunyan <arut@nginx.com>
parents: 8706
diff changeset
304
8682
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
305 if (ngx_http_v3_validate_header(r, name, value) != NGX_OK) {
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
306 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
307 return NGX_ERROR;
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
308 }
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
309
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
310 if (r->invalid_header) {
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
311 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
312
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
313 if (cscf->ignore_invalid_headers) {
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
314 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
315 "client sent invalid header: \"%V\"", name);
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
316
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
317 return NGX_OK;
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
318 }
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
319 }
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
320
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
321 if (name->len && name->data[0] == ':') {
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
322 return ngx_http_v3_process_pseudo_header(r, name, value);
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
323 }
8452
a6675a976560 HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents: 8451
diff changeset
324
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
325 if (ngx_http_v3_init_pseudo_headers(r) != NGX_OK) {
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
326 return NGX_ERROR;
8405
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
327 }
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
328
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
329 h = ngx_list_push(&r->headers_in.headers);
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
330 if (h == NULL) {
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
331 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
332 return NGX_ERROR;
8405
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
333 }
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
334
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
335 h->key = *name;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
336 h->value = *value;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
337 h->lowcase_key = h->key.data;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
338 h->hash = ngx_hash_key(h->key.data, h->key.len);
8406
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
339
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
340 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
8405
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
341
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
342 hh = ngx_hash_find(&cmcf->headers_in_hash, h->hash,
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
343 h->lowcase_key, h->key.len);
8406
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
344
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
345 if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
346 return NGX_ERROR;
8406
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
347 }
66feab03d9b7 HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents: 8405
diff changeset
348
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
349 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
350 "http3 header: \"%V: %V\"", name, value);
8405
d2759e4cc437 HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents: 8394
diff changeset
351 return NGX_OK;
8226
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
352 }
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
353
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
354
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
355 static ngx_int_t
8682
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
356 ngx_http_v3_validate_header(ngx_http_request_t *r, ngx_str_t *name,
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
357 ngx_str_t *value)
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
358 {
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
359 u_char ch;
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
360 ngx_uint_t i;
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
361 ngx_http_core_srv_conf_t *cscf;
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
362
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
363 r->invalid_header = 0;
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
364
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
365 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
366
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
367 for (i = (name->data[0] == ':'); i != name->len; i++) {
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
368 ch = name->data[i];
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
369
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
370 if ((ch >= 'a' && ch <= 'z')
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
371 || (ch == '-')
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
372 || (ch >= '0' && ch <= '9')
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
373 || (ch == '_' && cscf->underscores_in_headers))
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
374 {
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
375 continue;
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
376 }
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
377
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
378 if (ch == '\0' || ch == LF || ch == CR || ch == ':'
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
379 || (ch >= 'A' && ch <= 'Z'))
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
380 {
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
381 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
382 "client sent invalid header name: \"%V\"", name);
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
383
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
384 return NGX_ERROR;
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
385 }
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
386
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
387 r->invalid_header = 1;
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
388 }
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
389
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
390 for (i = 0; i != value->len; i++) {
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
391 ch = value->data[i];
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
392
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
393 if (ch == '\0' || ch == LF || ch == CR) {
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
394 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
395 "client sent header \"%V\" with "
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
396 "invalid value: \"%V\"", name, value);
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
397
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
398 return NGX_ERROR;
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
399 }
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
400 }
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
401
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
402 return NGX_OK;
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
403 }
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
404
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
405
916a2e1d6617 HTTP/3: client header validation.
Roman Arutyunyan <arut@nginx.com>
parents: 8680
diff changeset
406 static ngx_int_t
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
407 ngx_http_v3_process_pseudo_header(ngx_http_request_t *r, ngx_str_t *name,
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
408 ngx_str_t *value)
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
409 {
8680
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
410 u_char ch, c;
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
411 ngx_uint_t i;
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
412
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
413 if (r->request_line.len) {
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
414 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
415 "client sent out of order pseudo-headers");
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
416 goto failed;
8226
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
417 }
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
418
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
419 if (name->len == 7 && ngx_strncmp(name->data, ":method", 7) == 0) {
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
420
8680
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
421 if (r->method_name.len) {
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
422 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
423 "client sent duplicate \":method\" header");
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
424 goto failed;
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
425 }
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
426
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
427 if (value->len == 0) {
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
428 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
429 "client sent empty \":method\" header");
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
430 goto failed;
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
431 }
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
432
8650
9dce2978e4fd HTTP/3: eliminated r->method_start.
Roman Arutyunyan <arut@nginx.com>
parents: 8630
diff changeset
433 r->method_name = *value;
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
434
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
435 for (i = 0; i < sizeof(ngx_http_v3_methods)
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
436 / sizeof(ngx_http_v3_methods[0]); i++)
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
437 {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
438 if (value->len == ngx_http_v3_methods[i].name.len
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
439 && ngx_strncmp(value->data,
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
440 ngx_http_v3_methods[i].name.data, value->len)
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
441 == 0)
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
442 {
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
443 r->method = ngx_http_v3_methods[i].method;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
444 break;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
445 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
446 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
447
8680
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
448 for (i = 0; i < value->len; i++) {
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
449 ch = value->data[i];
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
450
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
451 if ((ch < 'A' || ch > 'Z') && ch != '_' && ch != '-') {
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
452 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
453 "client sent invalid method: \"%V\"", value);
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
454 goto failed;
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
455 }
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
456 }
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
457
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
458 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
459 "http3 method \"%V\" %ui", value, r->method);
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
460 return NGX_OK;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
461 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
462
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
463 if (name->len == 5 && ngx_strncmp(name->data, ":path", 5) == 0) {
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
464
8680
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
465 if (r->uri_start) {
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
466 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
467 "client sent duplicate \":path\" header");
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
468 goto failed;
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
469 }
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
470
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
471 if (value->len == 0) {
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
472 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
473 "client sent empty \":path\" header");
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
474 goto failed;
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
475 }
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
476
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
477 r->uri_start = value->data;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
478 r->uri_end = value->data + value->len;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
479
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
480 if (ngx_http_parse_uri(r) != NGX_OK) {
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
481 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
482 "client sent invalid \":path\" header: \"%V\"",
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
483 value);
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
484 goto failed;
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
485 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
486
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
487 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
488 "http3 path \"%V\"", value);
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
489 return NGX_OK;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
490 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
491
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
492 if (name->len == 7 && ngx_strncmp(name->data, ":scheme", 7) == 0) {
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
493
8680
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
494 if (r->schema.len) {
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
495 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
496 "client sent duplicate \":scheme\" header");
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
497 goto failed;
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
498 }
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
499
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
500 if (value->len == 0) {
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
501 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
502 "client sent empty \":scheme\" header");
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
503 goto failed;
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
504 }
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
505
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
506 for (i = 0; i < value->len; i++) {
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
507 ch = value->data[i];
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
508
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
509 c = (u_char) (ch | 0x20);
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
510 if (c >= 'a' && c <= 'z') {
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
511 continue;
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
512 }
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
513
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
514 if (((ch >= '0' && ch <= '9')
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
515 || ch == '+' || ch == '-' || ch == '.')
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
516 && i > 0)
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
517 {
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
518 continue;
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
519 }
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
520
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
521 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
522 "client sent invalid \":scheme\" header: \"%V\"",
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
523 value);
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
524 goto failed;
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
525 }
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
526
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
527 r->schema = *value;
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
528
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
529 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
530 "http3 schema \"%V\"", value);
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
531 return NGX_OK;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
532 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
533
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
534 if (name->len == 10 && ngx_strncmp(name->data, ":authority", 10) == 0) {
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
535
8680
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
536 if (r->host_start) {
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
537 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
538 "client sent duplicate \":authority\" header");
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
539 goto failed;
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
540 }
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
541
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
542 r->host_start = value->data;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
543 r->host_end = value->data + value->len;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
544
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
545 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
546 "http3 authority \"%V\"", value);
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
547 return NGX_OK;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
548 }
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
549
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
550 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
551 "client sent unknown pseudo-header \"%V\"", name);
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
552
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
553 failed:
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
554
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
555 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
556 return NGX_ERROR;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
557 }
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
558
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
559
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
560 static ngx_int_t
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
561 ngx_http_v3_init_pseudo_headers(ngx_http_request_t *r)
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
562 {
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
563 size_t len;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
564 u_char *p;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
565 ngx_int_t rc;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
566 ngx_str_t host;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
567
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
568 if (r->request_line.len) {
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
569 return NGX_OK;
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
570 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
571
8680
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
572 if (r->method_name.len == 0) {
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
573 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
574 "client sent no \":method\" header");
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
575 goto failed;
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
576 }
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
577
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
578 if (r->schema.len == 0) {
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
579 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
580 "client sent no \":scheme\" header");
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
581 goto failed;
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
582 }
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
583
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
584 if (r->uri_start == NULL) {
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
585 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
586 "client sent no \":path\" header");
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
587 goto failed;
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
588 }
58acdba9b3b2 HTTP/3: client pseudo-headers restrictions.
Roman Arutyunyan <arut@nginx.com>
parents: 8679
diff changeset
589
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
590 len = r->method_name.len + 1
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
591 + (r->uri_end - r->uri_start) + 1
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
592 + sizeof("HTTP/3.0") - 1;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
593
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
594 p = ngx_pnalloc(r->pool, len);
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
595 if (p == NULL) {
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
596 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
597 return NGX_ERROR;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
598 }
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
599
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
600 r->request_line.data = p;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
601
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
602 p = ngx_cpymem(p, r->method_name.data, r->method_name.len);
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
603 *p++ = ' ';
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
604 p = ngx_cpymem(p, r->uri_start, r->uri_end - r->uri_start);
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
605 *p++ = ' ';
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
606 p = ngx_cpymem(p, "HTTP/3.0", sizeof("HTTP/3.0") - 1);
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
607
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
608 r->request_line.len = p - r->request_line.data;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
609
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
610 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
611 "http3 request line: \"%V\"", &r->request_line);
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
612
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
613 ngx_str_set(&r->http_protocol, "HTTP/3.0");
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
614
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
615 if (ngx_http_process_request_uri(r) != NGX_OK) {
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
616 return NGX_ERROR;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
617 }
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
618
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
619 if (r->host_end) {
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
620
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
621 host.len = r->host_end - r->host_start;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
622 host.data = r->host_start;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
623
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
624 rc = ngx_http_validate_host(&host, r->pool, 0);
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
625
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
626 if (rc == NGX_DECLINED) {
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
627 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
628 "client sent invalid host in request line");
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
629 goto failed;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
630 }
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
631
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
632 if (rc == NGX_ERROR) {
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
633 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
634 return NGX_ERROR;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
635 }
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
636
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
637 if (ngx_http_set_virtual_server(r, &host) == NGX_ERROR) {
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
638 return NGX_ERROR;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
639 }
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
640
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
641 r->headers_in.server = host;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
642 }
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
643
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
644 if (ngx_list_init(&r->headers_in.headers, r->pool, 20,
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
645 sizeof(ngx_table_elt_t))
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
646 != NGX_OK)
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
647 {
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
648 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
649 return NGX_ERROR;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
650 }
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
651
8226
268f4389130d Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8219
diff changeset
652 return NGX_OK;
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
653
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
654 failed:
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
655
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
656 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
657 return NGX_ERROR;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
658 }
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
659
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
660
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
661 static ngx_int_t
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
662 ngx_http_v3_process_request_header(ngx_http_request_t *r)
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
663 {
8689
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
664 ssize_t n;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
665 ngx_buf_t *b;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
666 ngx_connection_t *c;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
667
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
668 c = r->connection;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
669
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
670 if (ngx_http_v3_init_pseudo_headers(r) != NGX_OK) {
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
671 return NGX_ERROR;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
672 }
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
673
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
674 if (r->headers_in.server.len == 0) {
8689
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
675 ngx_log_error(NGX_LOG_INFO, c->log, 0,
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
676 "client sent neither \":authority\" nor \"Host\" header");
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
677 goto failed;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
678 }
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
680 if (r->headers_in.host) {
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
681 if (r->headers_in.host->value.len != r->headers_in.server.len
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
682 || ngx_memcmp(r->headers_in.host->value.data,
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
683 r->headers_in.server.data,
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
684 r->headers_in.server.len)
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
685 != 0)
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
686 {
8689
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
687 ngx_log_error(NGX_LOG_INFO, c->log, 0,
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
688 "client sent \":authority\" and \"Host\" headers "
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
689 "with different values");
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
690 goto failed;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
691 }
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
692 }
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
693
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
694 if (r->headers_in.content_length) {
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
695 r->headers_in.content_length_n =
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
696 ngx_atoof(r->headers_in.content_length->value.data,
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
697 r->headers_in.content_length->value.len);
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
698
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
699 if (r->headers_in.content_length_n == NGX_ERROR) {
8689
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
700 ngx_log_error(NGX_LOG_INFO, c->log, 0,
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
701 "client sent invalid \"Content-Length\" header");
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
702 goto failed;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
703 }
8689
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
704
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
705 } else {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
706 b = r->header_in;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
707 n = b->last - b->pos;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
708
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
709 if (n == 0) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
710 n = c->recv(c, b->start, b->end - b->start);
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
711
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
712 if (n == NGX_ERROR) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
713 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
714 return NGX_ERROR;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
715 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
716
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
717 if (n > 0) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
718 b->pos = b->start;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
719 b->last = b->start + n;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
720 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
721 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
722
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
723 if (n != 0) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
724 r->headers_in.chunked = 1;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
725 }
8679
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
726 }
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
727
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
728 return NGX_OK;
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
729
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
730 failed:
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
731
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
732 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
e1eb7f4ca9f1 HTTP/3: refactored request parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8665
diff changeset
733 return NGX_ERROR;
8215
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
734 }
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
735
38c0898b6df7 HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
736
8295
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
737 ngx_int_t
8689
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
738 ngx_http_v3_read_request_body(ngx_http_request_t *r)
8295
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
739 {
8689
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
740 size_t preread;
8295
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
741 ngx_int_t rc;
8689
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
742 ngx_chain_t *cl, out;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
743 ngx_http_request_body_t *rb;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
744 ngx_http_core_loc_conf_t *clcf;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
745
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
746 rb = r->request_body;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
747
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
748 preread = r->header_in->last - r->header_in->pos;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
749
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
750 if (preread) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
751
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
752 /* there is the pre-read part of the request body */
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
753
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
754 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
755 "http3 client request body preread %uz", preread);
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
756
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
757 out.buf = r->header_in;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
758 out.next = NULL;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
759 cl = &out;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
760
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
761 } else {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
762 cl = NULL;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
763 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
764
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
765 rc = ngx_http_v3_request_body_filter(r, cl);
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
766 if (rc != NGX_OK) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
767 return rc;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
768 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
769
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
770 if (rb->rest == 0) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
771 /* the whole request body was pre-read */
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
772 r->request_body_no_buffering = 0;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
773 rb->post_handler(r);
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
774 return NGX_OK;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
775 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
776
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
777 if (rb->rest < 0) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
778 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
779 "negative request body rest");
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
780 return NGX_HTTP_INTERNAL_SERVER_ERROR;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
781 }
8295
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
782
8689
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
783 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
784
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
785 rb->buf = ngx_create_temp_buf(r->pool, clcf->client_body_buffer_size);
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
786 if (rb->buf == NULL) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
787 return NGX_HTTP_INTERNAL_SERVER_ERROR;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
788 }
8295
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
789
8689
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
790 r->read_event_handler = ngx_http_v3_read_client_request_body_handler;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
791 r->write_event_handler = ngx_http_request_empty_handler;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
792
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
793 return ngx_http_v3_do_read_client_request_body(r);
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
794 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
795
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
796
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
797 static void
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
798 ngx_http_v3_read_client_request_body_handler(ngx_http_request_t *r)
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
799 {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
800 ngx_int_t rc;
8295
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
801
8689
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
802 if (r->connection->read->timedout) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
803 r->connection->timedout = 1;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
804 ngx_http_finalize_request(r, NGX_HTTP_REQUEST_TIME_OUT);
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
805 return;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
806 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
807
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
808 rc = ngx_http_v3_do_read_client_request_body(r);
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
809
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
810 if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
811 ngx_http_finalize_request(r, rc);
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
812 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
813 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
814
8295
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
815
8689
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
816 ngx_int_t
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
817 ngx_http_v3_read_unbuffered_request_body(ngx_http_request_t *r)
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
818 {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
819 ngx_int_t rc;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
820
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
821 if (r->connection->read->timedout) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
822 r->connection->timedout = 1;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
823 return NGX_HTTP_REQUEST_TIME_OUT;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
824 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
825
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
826 rc = ngx_http_v3_do_read_client_request_body(r);
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
827
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
828 if (rc == NGX_OK) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
829 r->reading_body = 0;
8295
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
830 }
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
831
8689
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
832 return rc;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
833 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
834
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
835
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
836 static ngx_int_t
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
837 ngx_http_v3_do_read_client_request_body(ngx_http_request_t *r)
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
838 {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
839 off_t rest;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
840 size_t size;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
841 ssize_t n;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
842 ngx_int_t rc;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
843 ngx_chain_t out;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
844 ngx_connection_t *c;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
845 ngx_http_request_body_t *rb;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
846 ngx_http_core_loc_conf_t *clcf;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
847
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
848 c = r->connection;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
849 rb = r->request_body;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
850
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
851 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
852 "http3 read client request body");
8295
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
853
8689
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
854 for ( ;; ) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
855 for ( ;; ) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
856 if (rb->buf->last == rb->buf->end) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
857
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
858 /* update chains */
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
859
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
860 rc = ngx_http_v3_request_body_filter(r, NULL);
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
861
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
862 if (rc != NGX_OK) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
863 return rc;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
864 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
865
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
866 if (rb->busy != NULL) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
867 if (r->request_body_no_buffering) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
868 if (c->read->timer_set) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
869 ngx_del_timer(c->read);
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
870 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
871
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
872 if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
873 return NGX_HTTP_INTERNAL_SERVER_ERROR;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
874 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
875
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
876 return NGX_AGAIN;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
877 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
878
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
879 ngx_log_error(NGX_LOG_ALERT, c->log, 0,
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
880 "busy buffers after request body flush");
8295
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
881
8689
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
882 return NGX_HTTP_INTERNAL_SERVER_ERROR;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
883 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
884
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
885 rb->buf->pos = rb->buf->start;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
886 rb->buf->last = rb->buf->start;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
887 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
888
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
889 size = rb->buf->end - rb->buf->last;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
890 rest = rb->rest - (rb->buf->last - rb->buf->pos);
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
891
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
892 if ((off_t) size > rest) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
893 size = (size_t) rest;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
894 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
895
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
896 n = c->recv(c, rb->buf->last, size);
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
897
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
898 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
899 "http3 client request body recv %z", n);
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
900
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
901 if (n == NGX_AGAIN) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
902 break;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
903 }
8460
72f9ff4e0a88 HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents: 8456
diff changeset
904
8689
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
905 if (n == 0) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
906 rb->buf->last_buf = 1;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
907 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
908
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
909 if (n == NGX_ERROR) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
910 c->error = 1;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
911 return NGX_HTTP_BAD_REQUEST;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
912 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
913
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
914 rb->buf->last += n;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
915
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
916 /* pass buffer to request body filter chain */
8295
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
917
8689
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
918 out.buf = rb->buf;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
919 out.next = NULL;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
920
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
921 rc = ngx_http_v3_request_body_filter(r, &out);
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
922
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
923 if (rc != NGX_OK) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
924 return rc;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
925 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
926
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
927 if (rb->rest == 0) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
928 break;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
929 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
930
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
931 if (rb->buf->last < rb->buf->end) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
932 break;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
933 }
8295
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
934 }
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
935
8689
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
936 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
937 "http3 client request body rest %O", rb->rest);
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
938
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
939 if (rb->rest == 0) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
940 break;
8549
d70a38acaea0 HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents: 8548
diff changeset
941 }
d70a38acaea0 HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents: 8548
diff changeset
942
8689
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
943 if (!c->read->ready) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
944
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
945 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
946 ngx_add_timer(c->read, clcf->client_body_timeout);
8295
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
947
8689
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
948 if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
949 return NGX_HTTP_INTERNAL_SERVER_ERROR;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
950 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
951
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
952 return NGX_AGAIN;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
953 }
8295
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
954 }
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
955
8689
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
956 if (c->read->timer_set) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
957 ngx_del_timer(c->read);
8295
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
958 }
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
959
8689
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
960 if (!r->request_body_no_buffering) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
961 r->read_event_handler = ngx_http_block_reading;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
962 rb->post_handler(r);
8295
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
963 }
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
964
8548
9ffef6054abf HTTP/3: fixed handling request body eof.
Roman Arutyunyan <arut@nginx.com>
parents: 8511
diff changeset
965 return NGX_OK;
8689
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
966 }
8295
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
967
8689
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
968
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
969 static ngx_int_t
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
970 ngx_http_v3_request_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
971 {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
972 off_t max;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
973 size_t size;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
974 ngx_int_t rc;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
975 ngx_buf_t *b;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
976 ngx_uint_t last;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
977 ngx_chain_t *cl, *out, *tl, **ll;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
978 ngx_http_request_body_t *rb;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
979 ngx_http_core_loc_conf_t *clcf;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
980 ngx_http_core_srv_conf_t *cscf;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
981 ngx_http_v3_parse_data_t *st;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
982
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
983 rb = r->request_body;
8706
3057bae4dba7 HTTP/3: introduced ngx_http_v3_parse_t structure.
Roman Arutyunyan <arut@nginx.com>
parents: 8690
diff changeset
984 st = &r->v3_parse->body;
8689
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
985
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
986 if (rb->rest == -1) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
987
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
988 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
989 "http3 request body filter");
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
990
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
991 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
992
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
993 rb->rest = cscf->large_client_header_buffers.size;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
994 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
995
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
996 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
997
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
998 max = r->headers_in.content_length_n;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
999
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1000 if (max == -1 && clcf->client_max_body_size) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1001 max = clcf->client_max_body_size;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1002 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1003
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1004 out = NULL;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1005 ll = &out;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1006 last = 0;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1007
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1008 for (cl = in; cl; cl = cl->next) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1009
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1010 ngx_log_debug7(NGX_LOG_DEBUG_EVENT, r->connection->log, 0,
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1011 "http3 body buf "
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1012 "t:%d f:%d %p, pos %p, size: %z file: %O, size: %O",
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1013 cl->buf->temporary, cl->buf->in_file,
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1014 cl->buf->start, cl->buf->pos,
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1015 cl->buf->last - cl->buf->pos,
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1016 cl->buf->file_pos,
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1017 cl->buf->file_last - cl->buf->file_pos);
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1018
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1019 if (cl->buf->last_buf) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1020 last = 1;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1021 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1022
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1023 b = NULL;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1024
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1025 while (cl->buf->pos < cl->buf->last) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1026
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1027 if (st->length == 0) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1028 r->request_length++;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1029
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1030 rc = ngx_http_v3_parse_data(r->connection, st, *cl->buf->pos++);
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1031
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1032 if (rc == NGX_AGAIN) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1033 continue;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1034 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1035
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1036 if (rc == NGX_DONE) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1037 last = 1;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1038 goto done;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1039 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1040
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1041 if (rc > 0) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1042 ngx_http_v3_finalize_connection(r->connection, rc,
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1043 "client sent invalid body");
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1044 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1045 "client sent invalid body");
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1046 return NGX_HTTP_BAD_REQUEST;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1047 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1048
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1049 if (rc == NGX_ERROR) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1050 ngx_http_v3_finalize_connection(r->connection,
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1051 NGX_HTTP_V3_ERR_INTERNAL_ERROR,
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1052 "internal error");
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1053 return NGX_HTTP_INTERNAL_SERVER_ERROR;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1054 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1055
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1056 /* rc == NGX_OK */
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1057 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1058
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1059 if (max != -1 && (uint64_t) (max - rb->received) < st->length) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1060 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1061 "client intended to send too large "
8690
a9034b10dacc HTTP/3: fixed format specifier.
Roman Arutyunyan <arut@nginx.com>
parents: 8689
diff changeset
1062 "body: %O+%ui bytes",
8689
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1063 rb->received, st->length);
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1064
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1065 return NGX_HTTP_REQUEST_ENTITY_TOO_LARGE;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1066 }
8295
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
1067
8689
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1068 if (b
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1069 && st->length <= 128
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1070 && (uint64_t) (cl->buf->last - cl->buf->pos) >= st->length)
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1071 {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1072 rb->received += st->length;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1073 r->request_length += st->length;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1074
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1075 if (st->length < 8) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1076
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1077 while (st->length) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1078 *b->last++ = *cl->buf->pos++;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1079 st->length--;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1080 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1081
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1082 } else {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1083 ngx_memmove(b->last, cl->buf->pos, st->length);
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1084 b->last += st->length;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1085 cl->buf->pos += st->length;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1086 st->length = 0;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1087 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1088
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1089 continue;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1090 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1091
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1092 tl = ngx_chain_get_free_buf(r->pool, &rb->free);
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1093 if (tl == NULL) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1094 return NGX_HTTP_INTERNAL_SERVER_ERROR;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1095 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1096
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1097 b = tl->buf;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1098
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1099 ngx_memzero(b, sizeof(ngx_buf_t));
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1100
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1101 b->temporary = 1;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1102 b->tag = (ngx_buf_tag_t) &ngx_http_read_client_request_body;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1103 b->start = cl->buf->pos;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1104 b->pos = cl->buf->pos;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1105 b->last = cl->buf->last;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1106 b->end = cl->buf->end;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1107 b->flush = r->request_body_no_buffering;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1108
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1109 *ll = tl;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1110 ll = &tl->next;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1111
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1112 size = cl->buf->last - cl->buf->pos;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1113
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1114 if (size > st->length) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1115 cl->buf->pos += (size_t) st->length;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1116 rb->received += st->length;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1117 r->request_length += st->length;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1118 st->length = 0;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1119
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1120 } else {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1121 st->length -= size;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1122 rb->received += size;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1123 r->request_length += size;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1124 cl->buf->pos = cl->buf->last;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1125 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1126
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1127 b->last = cl->buf->pos;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1128 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1129 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1130
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1131 done:
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1132
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1133 if (last) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1134
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1135 if (st->length > 0) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1136 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1137 "client prematurely closed stream");
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1138 r->connection->error = 1;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1139 return NGX_HTTP_BAD_REQUEST;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1140 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1141
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1142 if (r->headers_in.content_length_n == -1) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1143 r->headers_in.content_length_n = rb->received;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1144
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1145 } else if (r->headers_in.content_length_n != rb->received) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1146 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1147 "client sent less body data than expected: "
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1148 "%O out of %O bytes of request body received",
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1149 rb->received, r->headers_in.content_length_n);
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1150 return NGX_HTTP_BAD_REQUEST;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1151 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1152
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1153 rb->rest = 0;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1154
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1155 tl = ngx_chain_get_free_buf(r->pool, &rb->free);
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1156 if (tl == NULL) {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1157 return NGX_HTTP_INTERNAL_SERVER_ERROR;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1158 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1159
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1160 b = tl->buf;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1161
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1162 ngx_memzero(b, sizeof(ngx_buf_t));
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1163
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1164 b->last_buf = 1;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1165
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1166 *ll = tl;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1167 ll = &tl->next;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1168
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1169 } else {
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1170
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1171 /* set rb->rest, amount of data we want to see next time */
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1172
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1173 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1174
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1175 rb->rest = (off_t) cscf->large_client_header_buffers.size;
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1176 }
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1177
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1178 rc = ngx_http_top_request_body_filter(r, out);
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1179
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1180 ngx_chain_update_chains(r->pool, &rb->free, &rb->busy, &out,
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1181 (ngx_buf_tag_t) &ngx_http_read_client_request_body);
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1182
6bd8ed493b85 HTTP/3: refactored request body parser.
Roman Arutyunyan <arut@nginx.com>
parents: 8685
diff changeset
1183 return rc;
8295
5649079a41f4 Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents: 8292
diff changeset
1184 }