annotate src/http/v3/ngx_http_v3_request.c @ 8384:c61fcdc1b8e3 quic

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