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