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