annotate src/http/v3/ngx_http_v3_request.c @ 8546:d80365ca678d quic

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