Mercurial > hg > nginx
annotate src/http/v3/ngx_http_v3_parse.c @ 8801:2029a30863e2 quic
QUIC: using compile time block/iv length for tokens.
Reference values can be found in RFC 3602, 2.1, 2.4.
author | Sergey Kandaurov <pluknet@nginx.com> |
---|---|
date | Wed, 16 Jun 2021 18:03:33 +0300 |
parents | 1fec68e322d0 |
children | 0ac25efb2da3 |
rev | line source |
---|---|
8226 | 1 |
2 /* | |
3 * Copyright (C) Roman Arutyunyan | |
4 * Copyright (C) Nginx, Inc. | |
5 */ | |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 #include <ngx_http.h> | |
11 | |
12 | |
8550
234e9d89ff7f
HTTP/3: reject HTTP/2 frames.
Roman Arutyunyan <arut@nginx.com>
parents:
8549
diff
changeset
|
13 #define ngx_http_v3_is_v2_frame(type) \ |
234e9d89ff7f
HTTP/3: reject HTTP/2 frames.
Roman Arutyunyan <arut@nginx.com>
parents:
8549
diff
changeset
|
14 ((type) == 0x02 || (type) == 0x06 || (type) == 0x08 || (type) == 0x09) |
234e9d89ff7f
HTTP/3: reject HTTP/2 frames.
Roman Arutyunyan <arut@nginx.com>
parents:
8549
diff
changeset
|
15 |
234e9d89ff7f
HTTP/3: reject HTTP/2 frames.
Roman Arutyunyan <arut@nginx.com>
parents:
8549
diff
changeset
|
16 |
8666
ab6aaa8e86b0
HTTP/3: staticize internal parsing functions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8649
diff
changeset
|
17 static ngx_int_t ngx_http_v3_parse_varlen_int(ngx_connection_t *c, |
ab6aaa8e86b0
HTTP/3: staticize internal parsing functions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8649
diff
changeset
|
18 ngx_http_v3_parse_varlen_int_t *st, u_char ch); |
ab6aaa8e86b0
HTTP/3: staticize internal parsing functions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8649
diff
changeset
|
19 static ngx_int_t ngx_http_v3_parse_prefix_int(ngx_connection_t *c, |
ab6aaa8e86b0
HTTP/3: staticize internal parsing functions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8649
diff
changeset
|
20 ngx_http_v3_parse_prefix_int_t *st, ngx_uint_t prefix, u_char ch); |
ab6aaa8e86b0
HTTP/3: staticize internal parsing functions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8649
diff
changeset
|
21 |
ab6aaa8e86b0
HTTP/3: staticize internal parsing functions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8649
diff
changeset
|
22 static ngx_int_t ngx_http_v3_parse_header_block_prefix(ngx_connection_t *c, |
ab6aaa8e86b0
HTTP/3: staticize internal parsing functions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8649
diff
changeset
|
23 ngx_http_v3_parse_header_block_prefix_t *st, u_char ch); |
ab6aaa8e86b0
HTTP/3: staticize internal parsing functions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8649
diff
changeset
|
24 static ngx_int_t ngx_http_v3_parse_header_rep(ngx_connection_t *c, |
ab6aaa8e86b0
HTTP/3: staticize internal parsing functions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8649
diff
changeset
|
25 ngx_http_v3_parse_header_rep_t *st, ngx_uint_t base, u_char ch); |
ab6aaa8e86b0
HTTP/3: staticize internal parsing functions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8649
diff
changeset
|
26 static ngx_int_t ngx_http_v3_parse_literal(ngx_connection_t *c, |
ab6aaa8e86b0
HTTP/3: staticize internal parsing functions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8649
diff
changeset
|
27 ngx_http_v3_parse_literal_t *st, u_char ch); |
ab6aaa8e86b0
HTTP/3: staticize internal parsing functions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8649
diff
changeset
|
28 static ngx_int_t ngx_http_v3_parse_header_ri(ngx_connection_t *c, |
ab6aaa8e86b0
HTTP/3: staticize internal parsing functions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8649
diff
changeset
|
29 ngx_http_v3_parse_header_t *st, u_char ch); |
ab6aaa8e86b0
HTTP/3: staticize internal parsing functions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8649
diff
changeset
|
30 static ngx_int_t ngx_http_v3_parse_header_lri(ngx_connection_t *c, |
ab6aaa8e86b0
HTTP/3: staticize internal parsing functions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8649
diff
changeset
|
31 ngx_http_v3_parse_header_t *st, u_char ch); |
ab6aaa8e86b0
HTTP/3: staticize internal parsing functions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8649
diff
changeset
|
32 static ngx_int_t ngx_http_v3_parse_header_l(ngx_connection_t *c, |
ab6aaa8e86b0
HTTP/3: staticize internal parsing functions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8649
diff
changeset
|
33 ngx_http_v3_parse_header_t *st, u_char ch); |
ab6aaa8e86b0
HTTP/3: staticize internal parsing functions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8649
diff
changeset
|
34 static ngx_int_t ngx_http_v3_parse_header_pbi(ngx_connection_t *c, |
ab6aaa8e86b0
HTTP/3: staticize internal parsing functions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8649
diff
changeset
|
35 ngx_http_v3_parse_header_t *st, u_char ch); |
ab6aaa8e86b0
HTTP/3: staticize internal parsing functions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8649
diff
changeset
|
36 static ngx_int_t ngx_http_v3_parse_header_lpbi(ngx_connection_t *c, |
ab6aaa8e86b0
HTTP/3: staticize internal parsing functions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8649
diff
changeset
|
37 ngx_http_v3_parse_header_t *st, u_char ch); |
ab6aaa8e86b0
HTTP/3: staticize internal parsing functions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8649
diff
changeset
|
38 |
8772
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
39 static ngx_int_t ngx_http_v3_parse_control(ngx_connection_t *c, |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
40 ngx_http_v3_parse_control_t *st, u_char ch); |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
41 static ngx_int_t ngx_http_v3_parse_settings(ngx_connection_t *c, |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
42 ngx_http_v3_parse_settings_t *st, u_char ch); |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
43 |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
44 static ngx_int_t ngx_http_v3_parse_encoder(ngx_connection_t *c, |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
45 ngx_http_v3_parse_encoder_t *st, u_char ch); |
8666
ab6aaa8e86b0
HTTP/3: staticize internal parsing functions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8649
diff
changeset
|
46 static ngx_int_t ngx_http_v3_parse_header_inr(ngx_connection_t *c, |
ab6aaa8e86b0
HTTP/3: staticize internal parsing functions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8649
diff
changeset
|
47 ngx_http_v3_parse_header_t *st, u_char ch); |
ab6aaa8e86b0
HTTP/3: staticize internal parsing functions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8649
diff
changeset
|
48 static ngx_int_t ngx_http_v3_parse_header_iwnr(ngx_connection_t *c, |
ab6aaa8e86b0
HTTP/3: staticize internal parsing functions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8649
diff
changeset
|
49 ngx_http_v3_parse_header_t *st, u_char ch); |
ab6aaa8e86b0
HTTP/3: staticize internal parsing functions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8649
diff
changeset
|
50 |
8772
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
51 static ngx_int_t ngx_http_v3_parse_decoder(ngx_connection_t *c, |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
52 ngx_http_v3_parse_decoder_t *st, u_char ch); |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
53 |
8456
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
54 static ngx_int_t ngx_http_v3_parse_lookup(ngx_connection_t *c, |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
55 ngx_uint_t dynamic, ngx_uint_t index, ngx_str_t *name, ngx_str_t *value); |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
56 |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
57 |
8666
ab6aaa8e86b0
HTTP/3: staticize internal parsing functions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8649
diff
changeset
|
58 static ngx_int_t |
8226 | 59 ngx_http_v3_parse_varlen_int(ngx_connection_t *c, |
60 ngx_http_v3_parse_varlen_int_t *st, u_char ch) | |
61 { | |
62 enum { | |
63 sw_start = 0, | |
64 sw_length_2, | |
65 sw_length_3, | |
66 sw_length_4, | |
67 sw_length_5, | |
68 sw_length_6, | |
69 sw_length_7, | |
70 sw_length_8 | |
71 }; | |
72 | |
73 switch (st->state) { | |
74 | |
75 case sw_start: | |
76 | |
77 st->value = ch; | |
78 if (st->value & 0xc0) { | |
79 st->state = sw_length_2; | |
80 break; | |
81 } | |
82 | |
83 goto done; | |
84 | |
85 case sw_length_2: | |
86 | |
87 st->value = (st->value << 8) + ch; | |
88 if ((st->value & 0xc000) == 0x4000) { | |
89 st->value &= 0x3fff; | |
90 goto done; | |
91 } | |
92 | |
93 st->state = sw_length_3; | |
94 break; | |
95 | |
96 case sw_length_4: | |
97 | |
98 st->value = (st->value << 8) + ch; | |
99 if ((st->value & 0xc0000000) == 0x80000000) { | |
100 st->value &= 0x3fffffff; | |
101 goto done; | |
102 } | |
103 | |
104 st->state = sw_length_5; | |
105 break; | |
106 | |
107 case sw_length_3: | |
108 case sw_length_5: | |
109 case sw_length_6: | |
110 case sw_length_7: | |
111 | |
112 st->value = (st->value << 8) + ch; | |
113 st->state++; | |
114 break; | |
115 | |
116 case sw_length_8: | |
117 | |
118 st->value = (st->value << 8) + ch; | |
119 st->value &= 0x3fffffffffffffff; | |
120 goto done; | |
121 } | |
122 | |
123 return NGX_AGAIN; | |
124 | |
125 done: | |
126 | |
127 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
128 "http3 parse varlen int %uL", st->value); | |
129 | |
130 st->state = sw_start; | |
131 return NGX_DONE; | |
132 } | |
133 | |
134 | |
8666
ab6aaa8e86b0
HTTP/3: staticize internal parsing functions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8649
diff
changeset
|
135 static ngx_int_t |
8226 | 136 ngx_http_v3_parse_prefix_int(ngx_connection_t *c, |
137 ngx_http_v3_parse_prefix_int_t *st, ngx_uint_t prefix, u_char ch) | |
138 { | |
8455
b0e81f49d7c0
HTTP/3: fixed prefixed integer encoding and decoding.
Roman Arutyunyan <arut@nginx.com>
parents:
8454
diff
changeset
|
139 ngx_uint_t mask; |
8226 | 140 enum { |
141 sw_start = 0, | |
142 sw_value | |
143 }; | |
144 | |
145 switch (st->state) { | |
146 | |
147 case sw_start: | |
148 | |
8455
b0e81f49d7c0
HTTP/3: fixed prefixed integer encoding and decoding.
Roman Arutyunyan <arut@nginx.com>
parents:
8454
diff
changeset
|
149 mask = (1 << prefix) - 1; |
b0e81f49d7c0
HTTP/3: fixed prefixed integer encoding and decoding.
Roman Arutyunyan <arut@nginx.com>
parents:
8454
diff
changeset
|
150 st->value = ch & mask; |
8226 | 151 |
8455
b0e81f49d7c0
HTTP/3: fixed prefixed integer encoding and decoding.
Roman Arutyunyan <arut@nginx.com>
parents:
8454
diff
changeset
|
152 if (st->value != mask) { |
8226 | 153 goto done; |
154 } | |
155 | |
8455
b0e81f49d7c0
HTTP/3: fixed prefixed integer encoding and decoding.
Roman Arutyunyan <arut@nginx.com>
parents:
8454
diff
changeset
|
156 st->shift = 0; |
8226 | 157 st->state = sw_value; |
158 break; | |
159 | |
160 case sw_value: | |
161 | |
8463
2576485b93d4
HTTP/3: fixed overflow in prefixed integer parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8462
diff
changeset
|
162 st->value += (uint64_t) (ch & 0x7f) << st->shift; |
8464
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
163 |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
164 if (st->shift == 56 |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
165 && ((ch & 0x80) || (st->value & 0xc000000000000000))) |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
166 { |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
167 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
168 "client exceeded integer size limit"); |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
169 return NGX_HTTP_V3_ERR_EXCESSIVE_LOAD; |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
170 } |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
171 |
8226 | 172 if (ch & 0x80) { |
8455
b0e81f49d7c0
HTTP/3: fixed prefixed integer encoding and decoding.
Roman Arutyunyan <arut@nginx.com>
parents:
8454
diff
changeset
|
173 st->shift += 7; |
8226 | 174 break; |
175 } | |
176 | |
177 goto done; | |
178 } | |
179 | |
180 return NGX_AGAIN; | |
181 | |
182 done: | |
183 | |
184 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
185 "http3 parse prefix int %uL", st->value); | |
186 | |
187 st->state = sw_start; | |
188 return NGX_DONE; | |
189 } | |
190 | |
191 | |
192 ngx_int_t | |
193 ngx_http_v3_parse_headers(ngx_connection_t *c, ngx_http_v3_parse_headers_t *st, | |
194 u_char ch) | |
195 { | |
196 ngx_int_t rc; | |
197 enum { | |
198 sw_start = 0, | |
8549
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
199 sw_type, |
8226 | 200 sw_length, |
8549
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
201 sw_skip, |
8226 | 202 sw_prefix, |
8456
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
203 sw_verify, |
8226 | 204 sw_header_rep, |
205 sw_done | |
206 }; | |
207 | |
208 switch (st->state) { | |
209 | |
210 case sw_start: | |
211 | |
212 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse headers"); | |
213 | |
8549
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
214 st->state = sw_type; |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
215 |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
216 /* fall through */ |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
217 |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
218 case sw_type: |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
219 |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
220 rc = ngx_http_v3_parse_varlen_int(c, &st->vlint, ch); |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
221 if (rc != NGX_DONE) { |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
222 return rc; |
8226 | 223 } |
224 | |
8549
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
225 st->type = st->vlint.value; |
8550
234e9d89ff7f
HTTP/3: reject HTTP/2 frames.
Roman Arutyunyan <arut@nginx.com>
parents:
8549
diff
changeset
|
226 |
8795
278ab0ed24f2
HTTP/3: generate more H3_FRAME_UNEXPECTED.
Roman Arutyunyan <arut@nginx.com>
parents:
8794
diff
changeset
|
227 if (ngx_http_v3_is_v2_frame(st->type) |
278ab0ed24f2
HTTP/3: generate more H3_FRAME_UNEXPECTED.
Roman Arutyunyan <arut@nginx.com>
parents:
8794
diff
changeset
|
228 || st->type == NGX_HTTP_V3_FRAME_DATA |
278ab0ed24f2
HTTP/3: generate more H3_FRAME_UNEXPECTED.
Roman Arutyunyan <arut@nginx.com>
parents:
8794
diff
changeset
|
229 || st->type == NGX_HTTP_V3_FRAME_GOAWAY |
278ab0ed24f2
HTTP/3: generate more H3_FRAME_UNEXPECTED.
Roman Arutyunyan <arut@nginx.com>
parents:
8794
diff
changeset
|
230 || st->type == NGX_HTTP_V3_FRAME_SETTINGS |
278ab0ed24f2
HTTP/3: generate more H3_FRAME_UNEXPECTED.
Roman Arutyunyan <arut@nginx.com>
parents:
8794
diff
changeset
|
231 || st->type == NGX_HTTP_V3_FRAME_MAX_PUSH_ID |
278ab0ed24f2
HTTP/3: generate more H3_FRAME_UNEXPECTED.
Roman Arutyunyan <arut@nginx.com>
parents:
8794
diff
changeset
|
232 || st->type == NGX_HTTP_V3_FRAME_CANCEL_PUSH |
278ab0ed24f2
HTTP/3: generate more H3_FRAME_UNEXPECTED.
Roman Arutyunyan <arut@nginx.com>
parents:
8794
diff
changeset
|
233 || st->type == NGX_HTTP_V3_FRAME_PUSH_PROMISE) |
278ab0ed24f2
HTTP/3: generate more H3_FRAME_UNEXPECTED.
Roman Arutyunyan <arut@nginx.com>
parents:
8794
diff
changeset
|
234 { |
8550
234e9d89ff7f
HTTP/3: reject HTTP/2 frames.
Roman Arutyunyan <arut@nginx.com>
parents:
8549
diff
changeset
|
235 return NGX_HTTP_V3_ERR_FRAME_UNEXPECTED; |
234e9d89ff7f
HTTP/3: reject HTTP/2 frames.
Roman Arutyunyan <arut@nginx.com>
parents:
8549
diff
changeset
|
236 } |
234e9d89ff7f
HTTP/3: reject HTTP/2 frames.
Roman Arutyunyan <arut@nginx.com>
parents:
8549
diff
changeset
|
237 |
8226 | 238 st->state = sw_length; |
239 break; | |
240 | |
241 case sw_length: | |
242 | |
8466
4fd709540daf
HTTP/3: put ngx_http_v3_parse_varlen_int() return code in variable.
Roman Arutyunyan <arut@nginx.com>
parents:
8465
diff
changeset
|
243 rc = ngx_http_v3_parse_varlen_int(c, &st->vlint, ch); |
4fd709540daf
HTTP/3: put ngx_http_v3_parse_varlen_int() return code in variable.
Roman Arutyunyan <arut@nginx.com>
parents:
8465
diff
changeset
|
244 if (rc != NGX_DONE) { |
4fd709540daf
HTTP/3: put ngx_http_v3_parse_varlen_int() return code in variable.
Roman Arutyunyan <arut@nginx.com>
parents:
8465
diff
changeset
|
245 return rc; |
8226 | 246 } |
247 | |
248 st->length = st->vlint.value; | |
249 | |
8549
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
250 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
251 "http3 parse headers type:%ui, len:%ui", |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
252 st->type, st->length); |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
253 |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
254 if (st->type != NGX_HTTP_V3_FRAME_HEADERS) { |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
255 st->state = st->length > 0 ? sw_skip : sw_type; |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
256 break; |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
257 } |
8226 | 258 |
8552
351d62300832
HTTP/3: rearranged length check when parsing header.
Roman Arutyunyan <arut@nginx.com>
parents:
8550
diff
changeset
|
259 if (st->length == 0) { |
351d62300832
HTTP/3: rearranged length check when parsing header.
Roman Arutyunyan <arut@nginx.com>
parents:
8550
diff
changeset
|
260 return NGX_HTTP_V3_ERR_FRAME_ERROR; |
351d62300832
HTTP/3: rearranged length check when parsing header.
Roman Arutyunyan <arut@nginx.com>
parents:
8550
diff
changeset
|
261 } |
351d62300832
HTTP/3: rearranged length check when parsing header.
Roman Arutyunyan <arut@nginx.com>
parents:
8550
diff
changeset
|
262 |
8226 | 263 st->state = sw_prefix; |
264 break; | |
265 | |
8549
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
266 case sw_skip: |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
267 |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
268 if (--st->length == 0) { |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
269 st->state = sw_type; |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
270 } |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
271 |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
272 break; |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
273 |
8226 | 274 case sw_prefix: |
275 | |
8552
351d62300832
HTTP/3: rearranged length check when parsing header.
Roman Arutyunyan <arut@nginx.com>
parents:
8550
diff
changeset
|
276 if (--st->length == 0) { |
8460
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
277 return NGX_HTTP_V3_ERR_FRAME_ERROR; |
8226 | 278 } |
279 | |
280 rc = ngx_http_v3_parse_header_block_prefix(c, &st->prefix, ch); | |
281 if (rc != NGX_DONE) { | |
8460
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
282 return rc; |
8226 | 283 } |
284 | |
8456
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
285 st->state = sw_verify; |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
286 break; |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
287 |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
288 case sw_verify: |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
289 |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
290 rc = ngx_http_v3_check_insert_count(c, st->prefix.insert_count); |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
291 if (rc != NGX_OK) { |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
292 return rc; |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
293 } |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
294 |
8226 | 295 st->state = sw_header_rep; |
8456
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
296 |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
297 /* fall through */ |
8226 | 298 |
299 case sw_header_rep: | |
300 | |
301 rc = ngx_http_v3_parse_header_rep(c, &st->header_rep, st->prefix.base, | |
302 ch); | |
303 | |
8467
e02250b55b17
HTTP/3: simplified handling return codes from parse functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8466
diff
changeset
|
304 if (--st->length == 0 && rc == NGX_AGAIN) { |
e02250b55b17
HTTP/3: simplified handling return codes from parse functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8466
diff
changeset
|
305 return NGX_HTTP_V3_ERR_FRAME_ERROR; |
8226 | 306 } |
307 | |
8460
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
308 if (rc != NGX_DONE) { |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
309 return rc; |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
310 } |
8226 | 311 |
8460
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
312 if (st->length == 0) { |
8226 | 313 goto done; |
314 } | |
315 | |
8460
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
316 return NGX_OK; |
8226 | 317 } |
318 | |
319 return NGX_AGAIN; | |
320 | |
321 done: | |
322 | |
323 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse headers done"); | |
324 | |
8456
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
325 if (st->prefix.insert_count > 0) { |
8771
0981329169ea
HTTP/3: renamed ngx_http_v3_client_XXX() functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8765
diff
changeset
|
326 if (ngx_http_v3_send_ack_header(c, c->quic->id) != NGX_OK) { |
8456
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
327 return NGX_ERROR; |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
328 } |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
329 } |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
330 |
8226 | 331 st->state = sw_start; |
332 return NGX_DONE; | |
333 } | |
334 | |
335 | |
8666
ab6aaa8e86b0
HTTP/3: staticize internal parsing functions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8649
diff
changeset
|
336 static ngx_int_t |
8226 | 337 ngx_http_v3_parse_header_block_prefix(ngx_connection_t *c, |
338 ngx_http_v3_parse_header_block_prefix_t *st, u_char ch) | |
339 { | |
8460
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
340 ngx_int_t rc; |
8226 | 341 enum { |
342 sw_start = 0, | |
343 sw_req_insert_count, | |
344 sw_delta_base, | |
345 sw_read_delta_base | |
346 }; | |
347 | |
348 switch (st->state) { | |
349 | |
350 case sw_start: | |
351 | |
352 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
353 "http3 parse header block prefix"); | |
354 | |
355 st->state = sw_req_insert_count; | |
356 | |
357 /* fall through */ | |
358 | |
359 case sw_req_insert_count: | |
360 | |
8464
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
361 rc = ngx_http_v3_parse_prefix_int(c, &st->pint, 8, ch); |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
362 if (rc != NGX_DONE) { |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
363 return rc; |
8226 | 364 } |
365 | |
366 st->insert_count = st->pint.value; | |
367 st->state = sw_delta_base; | |
368 break; | |
369 | |
370 case sw_delta_base: | |
371 | |
372 st->sign = (ch & 0x80) ? 1 : 0; | |
373 st->state = sw_read_delta_base; | |
374 | |
375 /* fall through */ | |
376 | |
377 case sw_read_delta_base: | |
378 | |
8464
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
379 rc = ngx_http_v3_parse_prefix_int(c, &st->pint, 7, ch); |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
380 if (rc != NGX_DONE) { |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
381 return rc; |
8226 | 382 } |
383 | |
384 st->delta_base = st->pint.value; | |
385 goto done; | |
386 } | |
387 | |
388 return NGX_AGAIN; | |
389 | |
390 done: | |
391 | |
8460
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
392 rc = ngx_http_v3_decode_insert_count(c, &st->insert_count); |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
393 if (rc != NGX_OK) { |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
394 return rc; |
8456
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
395 } |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
396 |
8226 | 397 if (st->sign) { |
398 st->base = st->insert_count - st->delta_base - 1; | |
399 } else { | |
400 st->base = st->insert_count + st->delta_base; | |
401 } | |
402 | |
403 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
404 "http3 parse header block prefix done " | |
8478
d2f716e668e8
Fixed format specifiers.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8467
diff
changeset
|
405 "insert_count:%ui, sign:%ui, delta_base:%ui, base:%ui", |
8226 | 406 st->insert_count, st->sign, st->delta_base, st->base); |
407 | |
408 st->state = sw_start; | |
409 return NGX_DONE; | |
410 } | |
411 | |
412 | |
8666
ab6aaa8e86b0
HTTP/3: staticize internal parsing functions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8649
diff
changeset
|
413 static ngx_int_t |
8226 | 414 ngx_http_v3_parse_header_rep(ngx_connection_t *c, |
415 ngx_http_v3_parse_header_rep_t *st, ngx_uint_t base, u_char ch) | |
416 { | |
417 ngx_int_t rc; | |
418 enum { | |
419 sw_start = 0, | |
420 sw_header_ri, | |
421 sw_header_lri, | |
422 sw_header_l, | |
423 sw_header_pbi, | |
424 sw_header_lpbi | |
425 }; | |
426 | |
427 if (st->state == sw_start) { | |
428 | |
429 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
430 "http3 parse header representation"); | |
431 | |
432 ngx_memzero(&st->header, sizeof(ngx_http_v3_parse_header_t)); | |
433 | |
434 st->header.base = base; | |
435 | |
436 if (ch & 0x80) { | |
437 /* Indexed Header Field */ | |
438 | |
439 st->state = sw_header_ri; | |
440 | |
441 } else if (ch & 0x40) { | |
442 /* Literal Header Field With Name Reference */ | |
443 | |
444 st->state = sw_header_lri; | |
445 | |
446 } else if (ch & 0x20) { | |
447 /* Literal Header Field Without Name Reference */ | |
448 | |
449 st->state = sw_header_l; | |
450 | |
451 } else if (ch & 0x10) { | |
452 /* Indexed Header Field With Post-Base Index */ | |
453 | |
454 st->state = sw_header_pbi; | |
455 | |
456 } else { | |
457 /* Literal Header Field With Post-Base Name Reference */ | |
458 | |
459 st->state = sw_header_lpbi; | |
460 } | |
461 } | |
462 | |
463 switch (st->state) { | |
464 | |
465 case sw_header_ri: | |
466 rc = ngx_http_v3_parse_header_ri(c, &st->header, ch); | |
467 break; | |
468 | |
469 case sw_header_lri: | |
470 rc = ngx_http_v3_parse_header_lri(c, &st->header, ch); | |
471 break; | |
472 | |
473 case sw_header_l: | |
474 rc = ngx_http_v3_parse_header_l(c, &st->header, ch); | |
475 break; | |
476 | |
477 case sw_header_pbi: | |
478 rc = ngx_http_v3_parse_header_pbi(c, &st->header, ch); | |
479 break; | |
480 | |
481 case sw_header_lpbi: | |
482 rc = ngx_http_v3_parse_header_lpbi(c, &st->header, ch); | |
483 break; | |
484 | |
485 default: | |
486 rc = NGX_OK; | |
487 } | |
488 | |
8460
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
489 if (rc != NGX_DONE) { |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
490 return rc; |
8226 | 491 } |
492 | |
493 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
494 "http3 parse header representation done"); | |
495 | |
496 st->state = sw_start; | |
497 return NGX_DONE; | |
498 } | |
499 | |
500 | |
8666
ab6aaa8e86b0
HTTP/3: staticize internal parsing functions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8649
diff
changeset
|
501 static ngx_int_t |
8226 | 502 ngx_http_v3_parse_literal(ngx_connection_t *c, ngx_http_v3_parse_literal_t *st, |
503 u_char ch) | |
504 { | |
8705
ae2e68f206f9
HTTP/3: removed http3_max_field_size.
Roman Arutyunyan <arut@nginx.com>
parents:
8666
diff
changeset
|
505 ngx_uint_t n; |
ae2e68f206f9
HTTP/3: removed http3_max_field_size.
Roman Arutyunyan <arut@nginx.com>
parents:
8666
diff
changeset
|
506 ngx_http_core_srv_conf_t *cscf; |
8226 | 507 enum { |
508 sw_start = 0, | |
509 sw_value | |
510 }; | |
511 | |
512 switch (st->state) { | |
513 | |
514 case sw_start: | |
515 | |
516 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
517 "http3 parse literal huff:%ui, len:%ui", | |
518 st->huffman, st->length); | |
519 | |
520 n = st->length; | |
521 | |
8705
ae2e68f206f9
HTTP/3: removed http3_max_field_size.
Roman Arutyunyan <arut@nginx.com>
parents:
8666
diff
changeset
|
522 cscf = ngx_http_v3_get_module_srv_conf(c, ngx_http_core_module); |
8454
032cb35ce758
HTTP/3: http3_max_field_size directive to limit string size.
Roman Arutyunyan <arut@nginx.com>
parents:
8295
diff
changeset
|
523 |
8705
ae2e68f206f9
HTTP/3: removed http3_max_field_size.
Roman Arutyunyan <arut@nginx.com>
parents:
8666
diff
changeset
|
524 if (n > cscf->large_client_header_buffers.size) { |
8457
a7f64438aa3c
HTTP/3: downgraded literal size error level to NGX_LOG_INFO.
Roman Arutyunyan <arut@nginx.com>
parents:
8456
diff
changeset
|
525 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
8705
ae2e68f206f9
HTTP/3: removed http3_max_field_size.
Roman Arutyunyan <arut@nginx.com>
parents:
8666
diff
changeset
|
526 "client sent too large header field"); |
8460
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
527 return NGX_HTTP_V3_ERR_EXCESSIVE_LOAD; |
8454
032cb35ce758
HTTP/3: http3_max_field_size directive to limit string size.
Roman Arutyunyan <arut@nginx.com>
parents:
8295
diff
changeset
|
528 } |
032cb35ce758
HTTP/3: http3_max_field_size directive to limit string size.
Roman Arutyunyan <arut@nginx.com>
parents:
8295
diff
changeset
|
529 |
8226 | 530 if (st->huffman) { |
531 n = n * 8 / 5; | |
532 st->huffstate = 0; | |
533 } | |
534 | |
535 st->last = ngx_pnalloc(c->pool, n + 1); | |
536 if (st->last == NULL) { | |
537 return NGX_ERROR; | |
538 } | |
539 | |
540 st->value.data = st->last; | |
541 st->state = sw_value; | |
542 | |
543 /* fall through */ | |
544 | |
545 case sw_value: | |
546 | |
547 if (st->huffman) { | |
548 if (ngx_http_v2_huff_decode(&st->huffstate, &ch, 1, &st->last, | |
549 st->length == 1, c->log) | |
550 != NGX_OK) | |
551 { | |
552 return NGX_ERROR; | |
553 } | |
554 | |
555 } else { | |
556 *st->last++ = ch; | |
557 } | |
558 | |
559 if (--st->length) { | |
560 break; | |
561 } | |
562 | |
563 st->value.len = st->last - st->value.data; | |
564 *st->last = '\0'; | |
565 goto done; | |
566 } | |
567 | |
568 return NGX_AGAIN; | |
569 | |
570 done: | |
571 | |
572 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
573 "http3 parse literal done \"%V\"", &st->value); | |
574 | |
575 st->state = sw_start; | |
576 return NGX_DONE; | |
577 } | |
578 | |
579 | |
8666
ab6aaa8e86b0
HTTP/3: staticize internal parsing functions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8649
diff
changeset
|
580 static ngx_int_t |
8226 | 581 ngx_http_v3_parse_header_ri(ngx_connection_t *c, ngx_http_v3_parse_header_t *st, |
582 u_char ch) | |
583 { | |
8460
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
584 ngx_int_t rc; |
8226 | 585 enum { |
586 sw_start = 0, | |
587 sw_index | |
588 }; | |
589 | |
590 switch (st->state) { | |
591 | |
592 case sw_start: | |
593 | |
594 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse header ri"); | |
595 | |
596 st->dynamic = (ch & 0x40) ? 0 : 1; | |
597 st->state = sw_index; | |
598 | |
599 /* fall through */ | |
600 | |
601 case sw_index: | |
602 | |
8464
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
603 rc = ngx_http_v3_parse_prefix_int(c, &st->pint, 6, ch); |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
604 if (rc != NGX_DONE) { |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
605 return rc; |
8226 | 606 } |
607 | |
608 st->index = st->pint.value; | |
609 goto done; | |
610 } | |
611 | |
612 return NGX_AGAIN; | |
613 | |
614 done: | |
615 | |
616 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
617 "http3 parse header ri done %s%ui]", | |
618 st->dynamic ? "dynamic[-" : "static[", st->index); | |
619 | |
620 if (st->dynamic) { | |
621 st->index = st->base - st->index - 1; | |
622 } | |
623 | |
8460
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
624 rc = ngx_http_v3_parse_lookup(c, st->dynamic, st->index, &st->name, |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
625 &st->value); |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
626 if (rc != NGX_OK) { |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
627 return rc; |
8226 | 628 } |
629 | |
630 st->state = sw_start; | |
631 return NGX_DONE; | |
632 } | |
633 | |
634 | |
8666
ab6aaa8e86b0
HTTP/3: staticize internal parsing functions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8649
diff
changeset
|
635 static ngx_int_t |
8226 | 636 ngx_http_v3_parse_header_lri(ngx_connection_t *c, |
637 ngx_http_v3_parse_header_t *st, u_char ch) | |
638 { | |
8456
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
639 ngx_int_t rc; |
8226 | 640 enum { |
641 sw_start = 0, | |
642 sw_index, | |
643 sw_value_len, | |
644 sw_read_value_len, | |
645 sw_value | |
646 }; | |
647 | |
648 switch (st->state) { | |
649 | |
650 case sw_start: | |
651 | |
652 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse header lri"); | |
653 | |
654 st->dynamic = (ch & 0x10) ? 0 : 1; | |
655 st->state = sw_index; | |
656 | |
657 /* fall through */ | |
658 | |
659 case sw_index: | |
660 | |
8464
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
661 rc = ngx_http_v3_parse_prefix_int(c, &st->pint, 4, ch); |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
662 if (rc != NGX_DONE) { |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
663 return rc; |
8226 | 664 } |
665 | |
666 st->index = st->pint.value; | |
667 st->state = sw_value_len; | |
668 break; | |
669 | |
670 case sw_value_len: | |
671 | |
672 st->literal.huffman = (ch & 0x80) ? 1 : 0; | |
673 st->state = sw_read_value_len; | |
674 | |
675 /* fall through */ | |
676 | |
677 case sw_read_value_len: | |
678 | |
8464
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
679 rc = ngx_http_v3_parse_prefix_int(c, &st->pint, 7, ch); |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
680 if (rc != NGX_DONE) { |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
681 return rc; |
8226 | 682 } |
683 | |
684 st->literal.length = st->pint.value; | |
685 if (st->literal.length == 0) { | |
686 goto done; | |
687 } | |
688 | |
689 st->state = sw_value; | |
690 break; | |
691 | |
692 case sw_value: | |
693 | |
694 rc = ngx_http_v3_parse_literal(c, &st->literal, ch); | |
8465
5611bbb852ce
HTTP/3: simplifed handling ngx_http_v3_parse_literal() return code.
Roman Arutyunyan <arut@nginx.com>
parents:
8464
diff
changeset
|
695 if (rc != NGX_DONE) { |
8460
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
696 return rc; |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
697 } |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
698 |
8465
5611bbb852ce
HTTP/3: simplifed handling ngx_http_v3_parse_literal() return code.
Roman Arutyunyan <arut@nginx.com>
parents:
8464
diff
changeset
|
699 st->value = st->literal.value; |
5611bbb852ce
HTTP/3: simplifed handling ngx_http_v3_parse_literal() return code.
Roman Arutyunyan <arut@nginx.com>
parents:
8464
diff
changeset
|
700 goto done; |
8226 | 701 } |
702 | |
703 return NGX_AGAIN; | |
704 | |
705 done: | |
706 | |
707 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
708 "http3 parse header lri done %s%ui] \"%V\"", | |
709 st->dynamic ? "dynamic[-" : "static[", | |
710 st->index, &st->value); | |
711 | |
712 if (st->dynamic) { | |
713 st->index = st->base - st->index - 1; | |
714 } | |
715 | |
8460
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
716 rc = ngx_http_v3_parse_lookup(c, st->dynamic, st->index, &st->name, NULL); |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
717 if (rc != NGX_OK) { |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
718 return rc; |
8226 | 719 } |
720 | |
721 st->state = sw_start; | |
722 return NGX_DONE; | |
723 } | |
724 | |
725 | |
8666
ab6aaa8e86b0
HTTP/3: staticize internal parsing functions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8649
diff
changeset
|
726 static ngx_int_t |
8226 | 727 ngx_http_v3_parse_header_l(ngx_connection_t *c, |
728 ngx_http_v3_parse_header_t *st, u_char ch) | |
729 { | |
730 ngx_int_t rc; | |
731 enum { | |
732 sw_start = 0, | |
733 sw_name_len, | |
734 sw_name, | |
735 sw_value_len, | |
736 sw_read_value_len, | |
737 sw_value | |
738 }; | |
739 | |
740 switch (st->state) { | |
741 | |
742 case sw_start: | |
743 | |
744 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse header l"); | |
745 | |
746 st->literal.huffman = (ch & 0x08) ? 1 : 0; | |
747 st->state = sw_name_len; | |
748 | |
749 /* fall through */ | |
750 | |
751 case sw_name_len: | |
752 | |
8464
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
753 rc = ngx_http_v3_parse_prefix_int(c, &st->pint, 3, ch); |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
754 if (rc != NGX_DONE) { |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
755 return rc; |
8226 | 756 } |
757 | |
758 st->literal.length = st->pint.value; | |
759 if (st->literal.length == 0) { | |
760 return NGX_ERROR; | |
761 } | |
762 | |
763 st->state = sw_name; | |
764 break; | |
765 | |
766 case sw_name: | |
767 | |
768 rc = ngx_http_v3_parse_literal(c, &st->literal, ch); | |
8465
5611bbb852ce
HTTP/3: simplifed handling ngx_http_v3_parse_literal() return code.
Roman Arutyunyan <arut@nginx.com>
parents:
8464
diff
changeset
|
769 if (rc != NGX_DONE) { |
8460
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
770 return rc; |
8226 | 771 } |
772 | |
8465
5611bbb852ce
HTTP/3: simplifed handling ngx_http_v3_parse_literal() return code.
Roman Arutyunyan <arut@nginx.com>
parents:
8464
diff
changeset
|
773 st->name = st->literal.value; |
5611bbb852ce
HTTP/3: simplifed handling ngx_http_v3_parse_literal() return code.
Roman Arutyunyan <arut@nginx.com>
parents:
8464
diff
changeset
|
774 st->state = sw_value_len; |
8226 | 775 break; |
776 | |
777 case sw_value_len: | |
778 | |
779 st->literal.huffman = (ch & 0x80) ? 1 : 0; | |
780 st->state = sw_read_value_len; | |
781 | |
782 /* fall through */ | |
783 | |
784 case sw_read_value_len: | |
785 | |
8464
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
786 rc = ngx_http_v3_parse_prefix_int(c, &st->pint, 7, ch); |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
787 if (rc != NGX_DONE) { |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
788 return rc; |
8226 | 789 } |
790 | |
791 st->literal.length = st->pint.value; | |
792 if (st->literal.length == 0) { | |
793 goto done; | |
794 } | |
795 | |
796 st->state = sw_value; | |
797 break; | |
798 | |
799 case sw_value: | |
800 | |
801 rc = ngx_http_v3_parse_literal(c, &st->literal, ch); | |
8465
5611bbb852ce
HTTP/3: simplifed handling ngx_http_v3_parse_literal() return code.
Roman Arutyunyan <arut@nginx.com>
parents:
8464
diff
changeset
|
802 if (rc != NGX_DONE) { |
8460
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
803 return rc; |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
804 } |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
805 |
8465
5611bbb852ce
HTTP/3: simplifed handling ngx_http_v3_parse_literal() return code.
Roman Arutyunyan <arut@nginx.com>
parents:
8464
diff
changeset
|
806 st->value = st->literal.value; |
5611bbb852ce
HTTP/3: simplifed handling ngx_http_v3_parse_literal() return code.
Roman Arutyunyan <arut@nginx.com>
parents:
8464
diff
changeset
|
807 goto done; |
8226 | 808 } |
809 | |
810 return NGX_AGAIN; | |
811 | |
812 done: | |
813 | |
814 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
815 "http3 parse header l done \"%V\" \"%V\"", | |
816 &st->name, &st->value); | |
817 | |
818 st->state = sw_start; | |
819 return NGX_DONE; | |
820 } | |
821 | |
822 | |
8666
ab6aaa8e86b0
HTTP/3: staticize internal parsing functions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8649
diff
changeset
|
823 static ngx_int_t |
8226 | 824 ngx_http_v3_parse_header_pbi(ngx_connection_t *c, |
825 ngx_http_v3_parse_header_t *st, u_char ch) | |
826 { | |
8460
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
827 ngx_int_t rc; |
8226 | 828 enum { |
829 sw_start = 0, | |
830 sw_index | |
831 }; | |
832 | |
833 switch (st->state) { | |
834 | |
835 case sw_start: | |
836 | |
837 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse header pbi"); | |
838 | |
839 st->state = sw_index; | |
840 | |
841 /* fall through */ | |
842 | |
843 case sw_index: | |
844 | |
8464
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
845 rc = ngx_http_v3_parse_prefix_int(c, &st->pint, 4, ch); |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
846 if (rc != NGX_DONE) { |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
847 return rc; |
8226 | 848 } |
849 | |
850 st->index = st->pint.value; | |
851 goto done; | |
852 } | |
853 | |
854 return NGX_AGAIN; | |
855 | |
856 done: | |
857 | |
858 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
859 "http3 parse header pbi done dynamic[+%ui]", st->index); | |
860 | |
8460
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
861 rc = ngx_http_v3_parse_lookup(c, 1, st->base + st->index, &st->name, |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
862 &st->value); |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
863 if (rc != NGX_OK) { |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
864 return rc; |
8226 | 865 } |
866 | |
867 st->state = sw_start; | |
868 return NGX_DONE; | |
869 } | |
870 | |
871 | |
8666
ab6aaa8e86b0
HTTP/3: staticize internal parsing functions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8649
diff
changeset
|
872 static ngx_int_t |
8226 | 873 ngx_http_v3_parse_header_lpbi(ngx_connection_t *c, |
874 ngx_http_v3_parse_header_t *st, u_char ch) | |
875 { | |
8456
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
876 ngx_int_t rc; |
8226 | 877 enum { |
878 sw_start = 0, | |
879 sw_index, | |
880 sw_value_len, | |
881 sw_read_value_len, | |
882 sw_value | |
883 }; | |
884 | |
885 switch (st->state) { | |
886 | |
887 case sw_start: | |
888 | |
889 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
890 "http3 parse header lpbi"); | |
891 | |
892 st->state = sw_index; | |
893 | |
894 /* fall through */ | |
895 | |
896 case sw_index: | |
897 | |
8464
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
898 rc = ngx_http_v3_parse_prefix_int(c, &st->pint, 3, ch); |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
899 if (rc != NGX_DONE) { |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
900 return rc; |
8226 | 901 } |
902 | |
903 st->index = st->pint.value; | |
904 st->state = sw_value_len; | |
905 break; | |
906 | |
907 case sw_value_len: | |
908 | |
909 st->literal.huffman = (ch & 0x80) ? 1 : 0; | |
910 st->state = sw_read_value_len; | |
911 | |
912 /* fall through */ | |
913 | |
914 case sw_read_value_len: | |
915 | |
8464
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
916 rc = ngx_http_v3_parse_prefix_int(c, &st->pint, 7, ch); |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
917 if (rc != NGX_DONE) { |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
918 return rc; |
8226 | 919 } |
920 | |
921 st->literal.length = st->pint.value; | |
922 if (st->literal.length == 0) { | |
923 goto done; | |
924 } | |
925 | |
926 st->state = sw_value; | |
927 break; | |
928 | |
929 case sw_value: | |
930 | |
931 rc = ngx_http_v3_parse_literal(c, &st->literal, ch); | |
8465
5611bbb852ce
HTTP/3: simplifed handling ngx_http_v3_parse_literal() return code.
Roman Arutyunyan <arut@nginx.com>
parents:
8464
diff
changeset
|
932 if (rc != NGX_DONE) { |
8460
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
933 return rc; |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
934 } |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
935 |
8465
5611bbb852ce
HTTP/3: simplifed handling ngx_http_v3_parse_literal() return code.
Roman Arutyunyan <arut@nginx.com>
parents:
8464
diff
changeset
|
936 st->value = st->literal.value; |
5611bbb852ce
HTTP/3: simplifed handling ngx_http_v3_parse_literal() return code.
Roman Arutyunyan <arut@nginx.com>
parents:
8464
diff
changeset
|
937 goto done; |
8226 | 938 } |
939 | |
940 return NGX_AGAIN; | |
941 | |
942 done: | |
943 | |
944 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
945 "http3 parse header lpbi done dynamic[+%ui] \"%V\"", | |
946 st->index, &st->value); | |
947 | |
8460
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
948 rc = ngx_http_v3_parse_lookup(c, 1, st->base + st->index, &st->name, NULL); |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
949 if (rc != NGX_OK) { |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
950 return rc; |
8226 | 951 } |
952 | |
953 st->state = sw_start; | |
954 return NGX_DONE; | |
955 } | |
956 | |
957 | |
8456
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
958 static ngx_int_t |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
959 ngx_http_v3_parse_lookup(ngx_connection_t *c, ngx_uint_t dynamic, |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
960 ngx_uint_t index, ngx_str_t *name, ngx_str_t *value) |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
961 { |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
962 u_char *p; |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
963 |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
964 if (!dynamic) { |
8460
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
965 if (ngx_http_v3_lookup_static(c, index, name, value) != NGX_OK) { |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
966 return NGX_HTTP_V3_ERR_DECOMPRESSION_FAILED; |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
967 } |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
968 |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
969 return NGX_OK; |
8456
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
970 } |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
971 |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
972 if (ngx_http_v3_lookup(c, index, name, value) != NGX_OK) { |
8460
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
973 return NGX_HTTP_V3_ERR_DECOMPRESSION_FAILED; |
8456
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
974 } |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
975 |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
976 if (name) { |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
977 p = ngx_pnalloc(c->pool, name->len + 1); |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
978 if (p == NULL) { |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
979 return NGX_ERROR; |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
980 } |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
981 |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
982 ngx_memcpy(p, name->data, name->len); |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
983 p[name->len] = '\0'; |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
984 name->data = p; |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
985 } |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
986 |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
987 if (value) { |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
988 p = ngx_pnalloc(c->pool, value->len + 1); |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
989 if (p == NULL) { |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
990 return NGX_ERROR; |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
991 } |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
992 |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
993 ngx_memcpy(p, value->data, value->len); |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
994 p[value->len] = '\0'; |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
995 value->data = p; |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
996 } |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
997 |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
998 return NGX_OK; |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
999 } |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
1000 |
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
1001 |
8772
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1002 static ngx_int_t |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1003 ngx_http_v3_parse_control(ngx_connection_t *c, ngx_http_v3_parse_control_t *st, |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1004 u_char ch) |
8226 | 1005 { |
1006 ngx_int_t rc; | |
1007 enum { | |
1008 sw_start = 0, | |
8460
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
1009 sw_first_type, |
8226 | 1010 sw_type, |
1011 sw_length, | |
8497 | 1012 sw_cancel_push, |
8226 | 1013 sw_settings, |
1014 sw_max_push_id, | |
8796
1fec68e322d0
HTTP/3: client GOAWAY support.
Roman Arutyunyan <arut@nginx.com>
parents:
8795
diff
changeset
|
1015 sw_goaway, |
8226 | 1016 sw_skip |
1017 }; | |
1018 | |
1019 switch (st->state) { | |
1020 | |
1021 case sw_start: | |
1022 | |
1023 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse control"); | |
1024 | |
8460
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
1025 st->state = sw_first_type; |
8226 | 1026 |
1027 /* fall through */ | |
1028 | |
8460
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
1029 case sw_first_type: |
8226 | 1030 case sw_type: |
1031 | |
8466
4fd709540daf
HTTP/3: put ngx_http_v3_parse_varlen_int() return code in variable.
Roman Arutyunyan <arut@nginx.com>
parents:
8465
diff
changeset
|
1032 rc = ngx_http_v3_parse_varlen_int(c, &st->vlint, ch); |
4fd709540daf
HTTP/3: put ngx_http_v3_parse_varlen_int() return code in variable.
Roman Arutyunyan <arut@nginx.com>
parents:
8465
diff
changeset
|
1033 if (rc != NGX_DONE) { |
4fd709540daf
HTTP/3: put ngx_http_v3_parse_varlen_int() return code in variable.
Roman Arutyunyan <arut@nginx.com>
parents:
8465
diff
changeset
|
1034 return rc; |
8226 | 1035 } |
1036 | |
1037 st->type = st->vlint.value; | |
1038 | |
1039 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1040 "http3 parse frame type:%ui", st->type); | |
1041 | |
8794
ba5977b38b2e
HTTP/3: reordered H3_MISSING_SETTINGS and H3_FRAME_UNEXPECTED.
Roman Arutyunyan <arut@nginx.com>
parents:
8790
diff
changeset
|
1042 if (st->state == sw_first_type |
ba5977b38b2e
HTTP/3: reordered H3_MISSING_SETTINGS and H3_FRAME_UNEXPECTED.
Roman Arutyunyan <arut@nginx.com>
parents:
8790
diff
changeset
|
1043 && st->type != NGX_HTTP_V3_FRAME_SETTINGS) |
ba5977b38b2e
HTTP/3: reordered H3_MISSING_SETTINGS and H3_FRAME_UNEXPECTED.
Roman Arutyunyan <arut@nginx.com>
parents:
8790
diff
changeset
|
1044 { |
ba5977b38b2e
HTTP/3: reordered H3_MISSING_SETTINGS and H3_FRAME_UNEXPECTED.
Roman Arutyunyan <arut@nginx.com>
parents:
8790
diff
changeset
|
1045 return NGX_HTTP_V3_ERR_MISSING_SETTINGS; |
ba5977b38b2e
HTTP/3: reordered H3_MISSING_SETTINGS and H3_FRAME_UNEXPECTED.
Roman Arutyunyan <arut@nginx.com>
parents:
8790
diff
changeset
|
1046 } |
ba5977b38b2e
HTTP/3: reordered H3_MISSING_SETTINGS and H3_FRAME_UNEXPECTED.
Roman Arutyunyan <arut@nginx.com>
parents:
8790
diff
changeset
|
1047 |
8795
278ab0ed24f2
HTTP/3: generate more H3_FRAME_UNEXPECTED.
Roman Arutyunyan <arut@nginx.com>
parents:
8794
diff
changeset
|
1048 if (st->state != sw_first_type |
278ab0ed24f2
HTTP/3: generate more H3_FRAME_UNEXPECTED.
Roman Arutyunyan <arut@nginx.com>
parents:
8794
diff
changeset
|
1049 && st->type == NGX_HTTP_V3_FRAME_SETTINGS) |
278ab0ed24f2
HTTP/3: generate more H3_FRAME_UNEXPECTED.
Roman Arutyunyan <arut@nginx.com>
parents:
8794
diff
changeset
|
1050 { |
278ab0ed24f2
HTTP/3: generate more H3_FRAME_UNEXPECTED.
Roman Arutyunyan <arut@nginx.com>
parents:
8794
diff
changeset
|
1051 return NGX_HTTP_V3_ERR_FRAME_UNEXPECTED; |
278ab0ed24f2
HTTP/3: generate more H3_FRAME_UNEXPECTED.
Roman Arutyunyan <arut@nginx.com>
parents:
8794
diff
changeset
|
1052 } |
278ab0ed24f2
HTTP/3: generate more H3_FRAME_UNEXPECTED.
Roman Arutyunyan <arut@nginx.com>
parents:
8794
diff
changeset
|
1053 |
8765
687445803d0f
HTTP/3: reject empty DATA and HEADERS frames on control stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8762
diff
changeset
|
1054 if (ngx_http_v3_is_v2_frame(st->type) |
687445803d0f
HTTP/3: reject empty DATA and HEADERS frames on control stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8762
diff
changeset
|
1055 || st->type == NGX_HTTP_V3_FRAME_DATA |
8795
278ab0ed24f2
HTTP/3: generate more H3_FRAME_UNEXPECTED.
Roman Arutyunyan <arut@nginx.com>
parents:
8794
diff
changeset
|
1056 || st->type == NGX_HTTP_V3_FRAME_HEADERS |
278ab0ed24f2
HTTP/3: generate more H3_FRAME_UNEXPECTED.
Roman Arutyunyan <arut@nginx.com>
parents:
8794
diff
changeset
|
1057 || st->type == NGX_HTTP_V3_FRAME_PUSH_PROMISE) |
8765
687445803d0f
HTTP/3: reject empty DATA and HEADERS frames on control stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8762
diff
changeset
|
1058 { |
8550
234e9d89ff7f
HTTP/3: reject HTTP/2 frames.
Roman Arutyunyan <arut@nginx.com>
parents:
8549
diff
changeset
|
1059 return NGX_HTTP_V3_ERR_FRAME_UNEXPECTED; |
234e9d89ff7f
HTTP/3: reject HTTP/2 frames.
Roman Arutyunyan <arut@nginx.com>
parents:
8549
diff
changeset
|
1060 } |
234e9d89ff7f
HTTP/3: reject HTTP/2 frames.
Roman Arutyunyan <arut@nginx.com>
parents:
8549
diff
changeset
|
1061 |
8226 | 1062 st->state = sw_length; |
1063 break; | |
1064 | |
1065 case sw_length: | |
1066 | |
8466
4fd709540daf
HTTP/3: put ngx_http_v3_parse_varlen_int() return code in variable.
Roman Arutyunyan <arut@nginx.com>
parents:
8465
diff
changeset
|
1067 rc = ngx_http_v3_parse_varlen_int(c, &st->vlint, ch); |
4fd709540daf
HTTP/3: put ngx_http_v3_parse_varlen_int() return code in variable.
Roman Arutyunyan <arut@nginx.com>
parents:
8465
diff
changeset
|
1068 if (rc != NGX_DONE) { |
4fd709540daf
HTTP/3: put ngx_http_v3_parse_varlen_int() return code in variable.
Roman Arutyunyan <arut@nginx.com>
parents:
8465
diff
changeset
|
1069 return rc; |
8226 | 1070 } |
1071 | |
1072 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1073 "http3 parse frame len:%uL", st->vlint.value); | |
1074 | |
1075 st->length = st->vlint.value; | |
1076 if (st->length == 0) { | |
1077 st->state = sw_type; | |
1078 break; | |
1079 } | |
1080 | |
1081 switch (st->type) { | |
1082 | |
8497 | 1083 case NGX_HTTP_V3_FRAME_CANCEL_PUSH: |
1084 st->state = sw_cancel_push; | |
1085 break; | |
1086 | |
8226 | 1087 case NGX_HTTP_V3_FRAME_SETTINGS: |
1088 st->state = sw_settings; | |
1089 break; | |
1090 | |
1091 case NGX_HTTP_V3_FRAME_MAX_PUSH_ID: | |
1092 st->state = sw_max_push_id; | |
1093 break; | |
1094 | |
8796
1fec68e322d0
HTTP/3: client GOAWAY support.
Roman Arutyunyan <arut@nginx.com>
parents:
8795
diff
changeset
|
1095 case NGX_HTTP_V3_FRAME_GOAWAY: |
1fec68e322d0
HTTP/3: client GOAWAY support.
Roman Arutyunyan <arut@nginx.com>
parents:
8795
diff
changeset
|
1096 st->state = sw_goaway; |
1fec68e322d0
HTTP/3: client GOAWAY support.
Roman Arutyunyan <arut@nginx.com>
parents:
8795
diff
changeset
|
1097 break; |
1fec68e322d0
HTTP/3: client GOAWAY support.
Roman Arutyunyan <arut@nginx.com>
parents:
8795
diff
changeset
|
1098 |
8226 | 1099 default: |
1100 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1101 "http3 parse skip unknown frame"); | |
1102 st->state = sw_skip; | |
1103 } | |
1104 | |
1105 break; | |
1106 | |
8497 | 1107 case sw_cancel_push: |
1108 | |
1109 rc = ngx_http_v3_parse_varlen_int(c, &st->vlint, ch); | |
1110 | |
1111 if (--st->length == 0 && rc == NGX_AGAIN) { | |
1112 return NGX_HTTP_V3_ERR_FRAME_ERROR; | |
1113 } | |
1114 | |
1115 if (rc != NGX_DONE) { | |
1116 return rc; | |
1117 } | |
1118 | |
1119 rc = ngx_http_v3_cancel_push(c, st->vlint.value); | |
1120 if (rc != NGX_OK) { | |
1121 return rc; | |
1122 } | |
1123 | |
1124 st->state = sw_type; | |
1125 break; | |
1126 | |
8226 | 1127 case sw_settings: |
1128 | |
1129 rc = ngx_http_v3_parse_settings(c, &st->settings, ch); | |
1130 | |
8467
e02250b55b17
HTTP/3: simplified handling return codes from parse functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8466
diff
changeset
|
1131 if (--st->length == 0 && rc == NGX_AGAIN) { |
e02250b55b17
HTTP/3: simplified handling return codes from parse functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8466
diff
changeset
|
1132 return NGX_HTTP_V3_ERR_SETTINGS_ERROR; |
8226 | 1133 } |
1134 | |
1135 if (rc != NGX_DONE) { | |
8460
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
1136 return rc; |
8226 | 1137 } |
1138 | |
8460
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
1139 if (st->length == 0) { |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
1140 st->state = sw_type; |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
1141 } |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
1142 |
8226 | 1143 break; |
1144 | |
1145 case sw_max_push_id: | |
1146 | |
8466
4fd709540daf
HTTP/3: put ngx_http_v3_parse_varlen_int() return code in variable.
Roman Arutyunyan <arut@nginx.com>
parents:
8465
diff
changeset
|
1147 rc = ngx_http_v3_parse_varlen_int(c, &st->vlint, ch); |
8497 | 1148 |
1149 if (--st->length == 0 && rc == NGX_AGAIN) { | |
1150 return NGX_HTTP_V3_ERR_FRAME_ERROR; | |
1151 } | |
1152 | |
8466
4fd709540daf
HTTP/3: put ngx_http_v3_parse_varlen_int() return code in variable.
Roman Arutyunyan <arut@nginx.com>
parents:
8465
diff
changeset
|
1153 if (rc != NGX_DONE) { |
4fd709540daf
HTTP/3: put ngx_http_v3_parse_varlen_int() return code in variable.
Roman Arutyunyan <arut@nginx.com>
parents:
8465
diff
changeset
|
1154 return rc; |
8226 | 1155 } |
1156 | |
8497 | 1157 rc = ngx_http_v3_set_max_push_id(c, st->vlint.value); |
1158 if (rc != NGX_OK) { | |
1159 return rc; | |
1160 } | |
8226 | 1161 |
1162 st->state = sw_type; | |
1163 break; | |
1164 | |
8796
1fec68e322d0
HTTP/3: client GOAWAY support.
Roman Arutyunyan <arut@nginx.com>
parents:
8795
diff
changeset
|
1165 case sw_goaway: |
1fec68e322d0
HTTP/3: client GOAWAY support.
Roman Arutyunyan <arut@nginx.com>
parents:
8795
diff
changeset
|
1166 |
1fec68e322d0
HTTP/3: client GOAWAY support.
Roman Arutyunyan <arut@nginx.com>
parents:
8795
diff
changeset
|
1167 rc = ngx_http_v3_parse_varlen_int(c, &st->vlint, ch); |
1fec68e322d0
HTTP/3: client GOAWAY support.
Roman Arutyunyan <arut@nginx.com>
parents:
8795
diff
changeset
|
1168 |
1fec68e322d0
HTTP/3: client GOAWAY support.
Roman Arutyunyan <arut@nginx.com>
parents:
8795
diff
changeset
|
1169 if (--st->length == 0 && rc == NGX_AGAIN) { |
1fec68e322d0
HTTP/3: client GOAWAY support.
Roman Arutyunyan <arut@nginx.com>
parents:
8795
diff
changeset
|
1170 return NGX_HTTP_V3_ERR_FRAME_ERROR; |
1fec68e322d0
HTTP/3: client GOAWAY support.
Roman Arutyunyan <arut@nginx.com>
parents:
8795
diff
changeset
|
1171 } |
1fec68e322d0
HTTP/3: client GOAWAY support.
Roman Arutyunyan <arut@nginx.com>
parents:
8795
diff
changeset
|
1172 |
1fec68e322d0
HTTP/3: client GOAWAY support.
Roman Arutyunyan <arut@nginx.com>
parents:
8795
diff
changeset
|
1173 if (rc != NGX_DONE) { |
1fec68e322d0
HTTP/3: client GOAWAY support.
Roman Arutyunyan <arut@nginx.com>
parents:
8795
diff
changeset
|
1174 return rc; |
1fec68e322d0
HTTP/3: client GOAWAY support.
Roman Arutyunyan <arut@nginx.com>
parents:
8795
diff
changeset
|
1175 } |
1fec68e322d0
HTTP/3: client GOAWAY support.
Roman Arutyunyan <arut@nginx.com>
parents:
8795
diff
changeset
|
1176 |
1fec68e322d0
HTTP/3: client GOAWAY support.
Roman Arutyunyan <arut@nginx.com>
parents:
8795
diff
changeset
|
1177 rc = ngx_http_v3_goaway(c, st->vlint.value); |
1fec68e322d0
HTTP/3: client GOAWAY support.
Roman Arutyunyan <arut@nginx.com>
parents:
8795
diff
changeset
|
1178 if (rc != NGX_OK) { |
1fec68e322d0
HTTP/3: client GOAWAY support.
Roman Arutyunyan <arut@nginx.com>
parents:
8795
diff
changeset
|
1179 return rc; |
1fec68e322d0
HTTP/3: client GOAWAY support.
Roman Arutyunyan <arut@nginx.com>
parents:
8795
diff
changeset
|
1180 } |
1fec68e322d0
HTTP/3: client GOAWAY support.
Roman Arutyunyan <arut@nginx.com>
parents:
8795
diff
changeset
|
1181 |
1fec68e322d0
HTTP/3: client GOAWAY support.
Roman Arutyunyan <arut@nginx.com>
parents:
8795
diff
changeset
|
1182 st->state = sw_type; |
1fec68e322d0
HTTP/3: client GOAWAY support.
Roman Arutyunyan <arut@nginx.com>
parents:
8795
diff
changeset
|
1183 break; |
1fec68e322d0
HTTP/3: client GOAWAY support.
Roman Arutyunyan <arut@nginx.com>
parents:
8795
diff
changeset
|
1184 |
8226 | 1185 case sw_skip: |
1186 | |
1187 if (--st->length == 0) { | |
1188 st->state = sw_type; | |
1189 } | |
1190 | |
1191 break; | |
1192 } | |
1193 | |
1194 return NGX_AGAIN; | |
1195 } | |
1196 | |
1197 | |
8666
ab6aaa8e86b0
HTTP/3: staticize internal parsing functions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8649
diff
changeset
|
1198 static ngx_int_t |
8226 | 1199 ngx_http_v3_parse_settings(ngx_connection_t *c, |
1200 ngx_http_v3_parse_settings_t *st, u_char ch) | |
1201 { | |
8466
4fd709540daf
HTTP/3: put ngx_http_v3_parse_varlen_int() return code in variable.
Roman Arutyunyan <arut@nginx.com>
parents:
8465
diff
changeset
|
1202 ngx_int_t rc; |
8226 | 1203 enum { |
1204 sw_start = 0, | |
1205 sw_id, | |
1206 sw_value | |
1207 }; | |
1208 | |
1209 switch (st->state) { | |
1210 | |
1211 case sw_start: | |
1212 | |
1213 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse settings"); | |
1214 | |
1215 st->state = sw_id; | |
1216 | |
1217 /* fall through */ | |
1218 | |
1219 case sw_id: | |
1220 | |
8466
4fd709540daf
HTTP/3: put ngx_http_v3_parse_varlen_int() return code in variable.
Roman Arutyunyan <arut@nginx.com>
parents:
8465
diff
changeset
|
1221 rc = ngx_http_v3_parse_varlen_int(c, &st->vlint, ch); |
4fd709540daf
HTTP/3: put ngx_http_v3_parse_varlen_int() return code in variable.
Roman Arutyunyan <arut@nginx.com>
parents:
8465
diff
changeset
|
1222 if (rc != NGX_DONE) { |
4fd709540daf
HTTP/3: put ngx_http_v3_parse_varlen_int() return code in variable.
Roman Arutyunyan <arut@nginx.com>
parents:
8465
diff
changeset
|
1223 return rc; |
8226 | 1224 } |
1225 | |
1226 st->id = st->vlint.value; | |
1227 st->state = sw_value; | |
1228 break; | |
1229 | |
1230 case sw_value: | |
1231 | |
8466
4fd709540daf
HTTP/3: put ngx_http_v3_parse_varlen_int() return code in variable.
Roman Arutyunyan <arut@nginx.com>
parents:
8465
diff
changeset
|
1232 rc = ngx_http_v3_parse_varlen_int(c, &st->vlint, ch); |
4fd709540daf
HTTP/3: put ngx_http_v3_parse_varlen_int() return code in variable.
Roman Arutyunyan <arut@nginx.com>
parents:
8465
diff
changeset
|
1233 if (rc != NGX_DONE) { |
4fd709540daf
HTTP/3: put ngx_http_v3_parse_varlen_int() return code in variable.
Roman Arutyunyan <arut@nginx.com>
parents:
8465
diff
changeset
|
1234 return rc; |
8226 | 1235 } |
1236 | |
1237 if (ngx_http_v3_set_param(c, st->id, st->vlint.value) != NGX_OK) { | |
8460
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
1238 return NGX_HTTP_V3_ERR_SETTINGS_ERROR; |
8226 | 1239 } |
1240 | |
1241 goto done; | |
1242 } | |
1243 | |
1244 return NGX_AGAIN; | |
1245 | |
1246 done: | |
1247 | |
1248 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse settings done"); | |
1249 | |
1250 st->state = sw_start; | |
1251 return NGX_DONE; | |
1252 } | |
1253 | |
1254 | |
8772
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1255 static ngx_int_t |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1256 ngx_http_v3_parse_encoder(ngx_connection_t *c, ngx_http_v3_parse_encoder_t *st, |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1257 u_char ch) |
8226 | 1258 { |
1259 ngx_int_t rc; | |
1260 enum { | |
1261 sw_start = 0, | |
1262 sw_inr, | |
1263 sw_iwnr, | |
1264 sw_capacity, | |
1265 sw_duplicate | |
1266 }; | |
1267 | |
1268 if (st->state == sw_start) { | |
1269 | |
1270 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1271 "http3 parse encoder instruction"); | |
1272 | |
1273 if (ch & 0x80) { | |
1274 /* Insert With Name Reference */ | |
1275 | |
1276 st->state = sw_inr; | |
1277 | |
1278 } else if (ch & 0x40) { | |
1279 /* Insert Without Name Reference */ | |
1280 | |
1281 st->state = sw_iwnr; | |
1282 | |
1283 } else if (ch & 0x20) { | |
1284 /* Set Dynamic Table Capacity */ | |
1285 | |
1286 st->state = sw_capacity; | |
1287 | |
1288 } else { | |
1289 /* Duplicate */ | |
1290 | |
1291 st->state = sw_duplicate; | |
1292 } | |
1293 } | |
1294 | |
1295 switch (st->state) { | |
1296 | |
1297 case sw_inr: | |
1298 | |
1299 rc = ngx_http_v3_parse_header_inr(c, &st->header, ch); | |
1300 if (rc != NGX_DONE) { | |
8460
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
1301 return rc; |
8226 | 1302 } |
1303 | |
1304 goto done; | |
1305 | |
1306 case sw_iwnr: | |
1307 | |
1308 rc = ngx_http_v3_parse_header_iwnr(c, &st->header, ch); | |
1309 if (rc != NGX_DONE) { | |
8460
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
1310 return rc; |
8226 | 1311 } |
1312 | |
1313 goto done; | |
1314 | |
1315 case sw_capacity: | |
1316 | |
8464
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
1317 rc = ngx_http_v3_parse_prefix_int(c, &st->pint, 5, ch); |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
1318 if (rc != NGX_DONE) { |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
1319 return rc; |
8226 | 1320 } |
1321 | |
8460
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
1322 rc = ngx_http_v3_set_capacity(c, st->pint.value); |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
1323 if (rc != NGX_OK) { |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
1324 return rc; |
8226 | 1325 } |
1326 | |
1327 goto done; | |
1328 | |
1329 case sw_duplicate: | |
1330 | |
8464
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
1331 rc = ngx_http_v3_parse_prefix_int(c, &st->pint, 5, ch); |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
1332 if (rc != NGX_DONE) { |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
1333 return rc; |
8226 | 1334 } |
1335 | |
8460
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
1336 rc = ngx_http_v3_duplicate(c, st->pint.value); |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
1337 if (rc != NGX_OK) { |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
1338 return rc; |
8226 | 1339 } |
1340 | |
1341 goto done; | |
1342 } | |
1343 | |
1344 return NGX_AGAIN; | |
1345 | |
1346 done: | |
1347 | |
1348 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1349 "http3 parse encoder instruction done"); | |
1350 | |
1351 st->state = sw_start; | |
8456
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
1352 return NGX_AGAIN; |
8226 | 1353 } |
1354 | |
1355 | |
8666
ab6aaa8e86b0
HTTP/3: staticize internal parsing functions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8649
diff
changeset
|
1356 static ngx_int_t |
8226 | 1357 ngx_http_v3_parse_header_inr(ngx_connection_t *c, |
1358 ngx_http_v3_parse_header_t *st, u_char ch) | |
1359 { | |
1360 ngx_int_t rc; | |
1361 enum { | |
1362 sw_start = 0, | |
1363 sw_name_index, | |
1364 sw_value_len, | |
1365 sw_read_value_len, | |
1366 sw_value | |
1367 }; | |
1368 | |
1369 switch (st->state) { | |
1370 | |
1371 case sw_start: | |
1372 | |
1373 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse header inr"); | |
1374 | |
1375 st->dynamic = (ch & 0x40) ? 0 : 1; | |
1376 st->state = sw_name_index; | |
1377 | |
1378 /* fall through */ | |
1379 | |
1380 case sw_name_index: | |
1381 | |
8464
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
1382 rc = ngx_http_v3_parse_prefix_int(c, &st->pint, 6, ch); |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
1383 if (rc != NGX_DONE) { |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
1384 return rc; |
8226 | 1385 } |
1386 | |
1387 st->index = st->pint.value; | |
1388 st->state = sw_value_len; | |
1389 break; | |
1390 | |
1391 case sw_value_len: | |
1392 | |
1393 st->literal.huffman = (ch & 0x80) ? 1 : 0; | |
1394 st->state = sw_read_value_len; | |
1395 | |
1396 /* fall through */ | |
1397 | |
1398 case sw_read_value_len: | |
1399 | |
8464
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
1400 rc = ngx_http_v3_parse_prefix_int(c, &st->pint, 7, ch); |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
1401 if (rc != NGX_DONE) { |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
1402 return rc; |
8226 | 1403 } |
1404 | |
1405 st->literal.length = st->pint.value; | |
1406 if (st->literal.length == 0) { | |
8789
3509b9dcfb47
HTTP/3: fixed parsing encoder insertions with empty header value.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8772
diff
changeset
|
1407 st->value.len = 0; |
8226 | 1408 goto done; |
1409 } | |
1410 | |
1411 st->state = sw_value; | |
1412 break; | |
1413 | |
1414 case sw_value: | |
1415 | |
1416 rc = ngx_http_v3_parse_literal(c, &st->literal, ch); | |
8465
5611bbb852ce
HTTP/3: simplifed handling ngx_http_v3_parse_literal() return code.
Roman Arutyunyan <arut@nginx.com>
parents:
8464
diff
changeset
|
1417 if (rc != NGX_DONE) { |
8460
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
1418 return rc; |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
1419 } |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
1420 |
8465
5611bbb852ce
HTTP/3: simplifed handling ngx_http_v3_parse_literal() return code.
Roman Arutyunyan <arut@nginx.com>
parents:
8464
diff
changeset
|
1421 st->value = st->literal.value; |
5611bbb852ce
HTTP/3: simplifed handling ngx_http_v3_parse_literal() return code.
Roman Arutyunyan <arut@nginx.com>
parents:
8464
diff
changeset
|
1422 goto done; |
8226 | 1423 } |
1424 | |
1425 return NGX_AGAIN; | |
1426 | |
1427 done: | |
1428 | |
1429 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1430 "http3 parse header inr done %s[%ui] \"%V\"", | |
1431 st->dynamic ? "dynamic" : "static", | |
1432 st->index, &st->value); | |
1433 | |
8460
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
1434 rc = ngx_http_v3_ref_insert(c, st->dynamic, st->index, &st->value); |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
1435 if (rc != NGX_OK) { |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
1436 return rc; |
8226 | 1437 } |
1438 | |
1439 st->state = sw_start; | |
1440 return NGX_DONE; | |
1441 } | |
1442 | |
1443 | |
8666
ab6aaa8e86b0
HTTP/3: staticize internal parsing functions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8649
diff
changeset
|
1444 static ngx_int_t |
8226 | 1445 ngx_http_v3_parse_header_iwnr(ngx_connection_t *c, |
1446 ngx_http_v3_parse_header_t *st, u_char ch) | |
1447 { | |
1448 ngx_int_t rc; | |
1449 enum { | |
1450 sw_start = 0, | |
1451 sw_name_len, | |
1452 sw_name, | |
1453 sw_value_len, | |
1454 sw_read_value_len, | |
1455 sw_value | |
1456 }; | |
1457 | |
1458 switch (st->state) { | |
1459 | |
1460 case sw_start: | |
1461 | |
1462 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1463 "http3 parse header iwnr"); | |
1464 | |
1465 st->literal.huffman = (ch & 0x20) ? 1 : 0; | |
1466 st->state = sw_name_len; | |
1467 | |
1468 /* fall through */ | |
1469 | |
1470 case sw_name_len: | |
1471 | |
8464
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
1472 rc = ngx_http_v3_parse_prefix_int(c, &st->pint, 5, ch); |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
1473 if (rc != NGX_DONE) { |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
1474 return rc; |
8226 | 1475 } |
1476 | |
1477 st->literal.length = st->pint.value; | |
1478 if (st->literal.length == 0) { | |
1479 return NGX_ERROR; | |
1480 } | |
1481 | |
1482 st->state = sw_name; | |
1483 break; | |
1484 | |
1485 case sw_name: | |
1486 | |
1487 rc = ngx_http_v3_parse_literal(c, &st->literal, ch); | |
8465
5611bbb852ce
HTTP/3: simplifed handling ngx_http_v3_parse_literal() return code.
Roman Arutyunyan <arut@nginx.com>
parents:
8464
diff
changeset
|
1488 if (rc != NGX_DONE) { |
8460
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
1489 return rc; |
8226 | 1490 } |
1491 | |
8465
5611bbb852ce
HTTP/3: simplifed handling ngx_http_v3_parse_literal() return code.
Roman Arutyunyan <arut@nginx.com>
parents:
8464
diff
changeset
|
1492 st->name = st->literal.value; |
5611bbb852ce
HTTP/3: simplifed handling ngx_http_v3_parse_literal() return code.
Roman Arutyunyan <arut@nginx.com>
parents:
8464
diff
changeset
|
1493 st->state = sw_value_len; |
8226 | 1494 break; |
1495 | |
1496 case sw_value_len: | |
1497 | |
1498 st->literal.huffman = (ch & 0x80) ? 1 : 0; | |
1499 st->state = sw_read_value_len; | |
1500 | |
1501 /* fall through */ | |
1502 | |
1503 case sw_read_value_len: | |
1504 | |
8464
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
1505 rc = ngx_http_v3_parse_prefix_int(c, &st->pint, 7, ch); |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
1506 if (rc != NGX_DONE) { |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
1507 return rc; |
8226 | 1508 } |
1509 | |
1510 st->literal.length = st->pint.value; | |
1511 if (st->literal.length == 0) { | |
8789
3509b9dcfb47
HTTP/3: fixed parsing encoder insertions with empty header value.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8772
diff
changeset
|
1512 st->value.len = 0; |
8226 | 1513 goto done; |
1514 } | |
1515 | |
1516 st->state = sw_value; | |
1517 break; | |
1518 | |
1519 case sw_value: | |
1520 | |
1521 rc = ngx_http_v3_parse_literal(c, &st->literal, ch); | |
8465
5611bbb852ce
HTTP/3: simplifed handling ngx_http_v3_parse_literal() return code.
Roman Arutyunyan <arut@nginx.com>
parents:
8464
diff
changeset
|
1522 if (rc != NGX_DONE) { |
8460
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
1523 return rc; |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
1524 } |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
1525 |
8465
5611bbb852ce
HTTP/3: simplifed handling ngx_http_v3_parse_literal() return code.
Roman Arutyunyan <arut@nginx.com>
parents:
8464
diff
changeset
|
1526 st->value = st->literal.value; |
5611bbb852ce
HTTP/3: simplifed handling ngx_http_v3_parse_literal() return code.
Roman Arutyunyan <arut@nginx.com>
parents:
8464
diff
changeset
|
1527 goto done; |
8226 | 1528 } |
1529 | |
1530 return NGX_AGAIN; | |
1531 | |
1532 done: | |
1533 | |
1534 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1535 "http3 parse header iwnr done \"%V\":\"%V\"", | |
1536 &st->name, &st->value); | |
1537 | |
8460
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
1538 rc = ngx_http_v3_insert(c, &st->name, &st->value); |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
1539 if (rc != NGX_OK) { |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
1540 return rc; |
8226 | 1541 } |
1542 | |
1543 st->state = sw_start; | |
1544 return NGX_DONE; | |
1545 } | |
1546 | |
1547 | |
8772
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1548 static ngx_int_t |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1549 ngx_http_v3_parse_decoder(ngx_connection_t *c, ngx_http_v3_parse_decoder_t *st, |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1550 u_char ch) |
8226 | 1551 { |
8460
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
1552 ngx_int_t rc; |
8226 | 1553 enum { |
1554 sw_start = 0, | |
1555 sw_ack_header, | |
1556 sw_cancel_stream, | |
1557 sw_inc_insert_count | |
1558 }; | |
1559 | |
1560 if (st->state == sw_start) { | |
1561 | |
1562 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1563 "http3 parse decoder instruction"); | |
1564 | |
1565 if (ch & 0x80) { | |
1566 /* Header Acknowledgement */ | |
1567 | |
1568 st->state = sw_ack_header; | |
1569 | |
1570 } else if (ch & 0x40) { | |
1571 /* Stream Cancellation */ | |
1572 | |
1573 st->state = sw_cancel_stream; | |
1574 | |
1575 } else { | |
1576 /* Insert Count Increment */ | |
1577 | |
1578 st->state = sw_inc_insert_count; | |
1579 } | |
1580 } | |
1581 | |
1582 switch (st->state) { | |
1583 | |
1584 case sw_ack_header: | |
1585 | |
8464
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
1586 rc = ngx_http_v3_parse_prefix_int(c, &st->pint, 7, ch); |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
1587 if (rc != NGX_DONE) { |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
1588 return rc; |
8226 | 1589 } |
1590 | |
8460
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
1591 rc = ngx_http_v3_ack_header(c, st->pint.value); |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
1592 if (rc != NGX_OK) { |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
1593 return rc; |
8226 | 1594 } |
1595 | |
1596 goto done; | |
1597 | |
1598 case sw_cancel_stream: | |
1599 | |
8464
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
1600 rc = ngx_http_v3_parse_prefix_int(c, &st->pint, 6, ch); |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
1601 if (rc != NGX_DONE) { |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
1602 return rc; |
8226 | 1603 } |
1604 | |
8460
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
1605 rc = ngx_http_v3_cancel_stream(c, st->pint.value); |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
1606 if (rc != NGX_OK) { |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
1607 return rc; |
8226 | 1608 } |
1609 | |
1610 goto done; | |
1611 | |
1612 case sw_inc_insert_count: | |
1613 | |
8464
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
1614 rc = ngx_http_v3_parse_prefix_int(c, &st->pint, 6, ch); |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
1615 if (rc != NGX_DONE) { |
fdb8edc8e496
HTTP/3: limited prefixed integer size by 62 bits.
Roman Arutyunyan <arut@nginx.com>
parents:
8463
diff
changeset
|
1616 return rc; |
8226 | 1617 } |
1618 | |
8460
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
1619 rc = ngx_http_v3_inc_insert_count(c, st->pint.value); |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
1620 if (rc != NGX_OK) { |
72f9ff4e0a88
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Roman Arutyunyan <arut@nginx.com>
parents:
8457
diff
changeset
|
1621 return rc; |
8226 | 1622 } |
1623 | |
1624 goto done; | |
1625 } | |
1626 | |
1627 return NGX_AGAIN; | |
1628 | |
1629 done: | |
1630 | |
1631 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1632 "http3 parse decoder instruction done"); | |
1633 | |
1634 st->state = sw_start; | |
8456
c9538aef3211
HTTP/3: refactored dynamic table implementation.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
1635 return NGX_AGAIN; |
8226 | 1636 } |
8295
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1637 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1638 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1639 ngx_int_t |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1640 ngx_http_v3_parse_data(ngx_connection_t *c, ngx_http_v3_parse_data_t *st, |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1641 u_char ch) |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1642 { |
8466
4fd709540daf
HTTP/3: put ngx_http_v3_parse_varlen_int() return code in variable.
Roman Arutyunyan <arut@nginx.com>
parents:
8465
diff
changeset
|
1643 ngx_int_t rc; |
8295
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1644 enum { |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1645 sw_start = 0, |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1646 sw_type, |
8549
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
1647 sw_length, |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
1648 sw_skip |
8295
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1649 }; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1650 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1651 switch (st->state) { |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1652 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1653 case sw_start: |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1654 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1655 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse data"); |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1656 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1657 st->state = sw_type; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1658 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1659 /* fall through */ |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1660 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1661 case sw_type: |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1662 |
8466
4fd709540daf
HTTP/3: put ngx_http_v3_parse_varlen_int() return code in variable.
Roman Arutyunyan <arut@nginx.com>
parents:
8465
diff
changeset
|
1663 rc = ngx_http_v3_parse_varlen_int(c, &st->vlint, ch); |
4fd709540daf
HTTP/3: put ngx_http_v3_parse_varlen_int() return code in variable.
Roman Arutyunyan <arut@nginx.com>
parents:
8465
diff
changeset
|
1664 if (rc != NGX_DONE) { |
4fd709540daf
HTTP/3: put ngx_http_v3_parse_varlen_int() return code in variable.
Roman Arutyunyan <arut@nginx.com>
parents:
8465
diff
changeset
|
1665 return rc; |
8295
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1666 } |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1667 |
8549
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
1668 st->type = st->vlint.value; |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
1669 |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
1670 if (st->type == NGX_HTTP_V3_FRAME_HEADERS) { |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
1671 /* trailers */ |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
1672 goto done; |
8295
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1673 } |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1674 |
8795
278ab0ed24f2
HTTP/3: generate more H3_FRAME_UNEXPECTED.
Roman Arutyunyan <arut@nginx.com>
parents:
8794
diff
changeset
|
1675 if (ngx_http_v3_is_v2_frame(st->type) |
278ab0ed24f2
HTTP/3: generate more H3_FRAME_UNEXPECTED.
Roman Arutyunyan <arut@nginx.com>
parents:
8794
diff
changeset
|
1676 || st->type == NGX_HTTP_V3_FRAME_GOAWAY |
278ab0ed24f2
HTTP/3: generate more H3_FRAME_UNEXPECTED.
Roman Arutyunyan <arut@nginx.com>
parents:
8794
diff
changeset
|
1677 || st->type == NGX_HTTP_V3_FRAME_SETTINGS |
278ab0ed24f2
HTTP/3: generate more H3_FRAME_UNEXPECTED.
Roman Arutyunyan <arut@nginx.com>
parents:
8794
diff
changeset
|
1678 || st->type == NGX_HTTP_V3_FRAME_MAX_PUSH_ID |
278ab0ed24f2
HTTP/3: generate more H3_FRAME_UNEXPECTED.
Roman Arutyunyan <arut@nginx.com>
parents:
8794
diff
changeset
|
1679 || st->type == NGX_HTTP_V3_FRAME_CANCEL_PUSH |
278ab0ed24f2
HTTP/3: generate more H3_FRAME_UNEXPECTED.
Roman Arutyunyan <arut@nginx.com>
parents:
8794
diff
changeset
|
1680 || st->type == NGX_HTTP_V3_FRAME_PUSH_PROMISE) |
278ab0ed24f2
HTTP/3: generate more H3_FRAME_UNEXPECTED.
Roman Arutyunyan <arut@nginx.com>
parents:
8794
diff
changeset
|
1681 { |
8550
234e9d89ff7f
HTTP/3: reject HTTP/2 frames.
Roman Arutyunyan <arut@nginx.com>
parents:
8549
diff
changeset
|
1682 return NGX_HTTP_V3_ERR_FRAME_UNEXPECTED; |
234e9d89ff7f
HTTP/3: reject HTTP/2 frames.
Roman Arutyunyan <arut@nginx.com>
parents:
8549
diff
changeset
|
1683 } |
234e9d89ff7f
HTTP/3: reject HTTP/2 frames.
Roman Arutyunyan <arut@nginx.com>
parents:
8549
diff
changeset
|
1684 |
8295
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1685 st->state = sw_length; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1686 break; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1687 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1688 case sw_length: |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1689 |
8466
4fd709540daf
HTTP/3: put ngx_http_v3_parse_varlen_int() return code in variable.
Roman Arutyunyan <arut@nginx.com>
parents:
8465
diff
changeset
|
1690 rc = ngx_http_v3_parse_varlen_int(c, &st->vlint, ch); |
4fd709540daf
HTTP/3: put ngx_http_v3_parse_varlen_int() return code in variable.
Roman Arutyunyan <arut@nginx.com>
parents:
8465
diff
changeset
|
1691 if (rc != NGX_DONE) { |
4fd709540daf
HTTP/3: put ngx_http_v3_parse_varlen_int() return code in variable.
Roman Arutyunyan <arut@nginx.com>
parents:
8465
diff
changeset
|
1692 return rc; |
8295
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1693 } |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1694 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1695 st->length = st->vlint.value; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1696 |
8549
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
1697 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
1698 "http3 parse data type:%ui, len:%ui", |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
1699 st->type, st->length); |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
1700 |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
1701 if (st->type != NGX_HTTP_V3_FRAME_DATA && st->length > 0) { |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
1702 st->state = sw_skip; |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
1703 break; |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
1704 } |
8295
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1705 |
8549
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
1706 st->state = sw_type; |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
1707 return NGX_OK; |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
1708 |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
1709 case sw_skip: |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
1710 |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
1711 if (--st->length == 0) { |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
1712 st->state = sw_type; |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
1713 } |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
1714 |
d70a38acaea0
HTTP/3: skip unknown frames on request stream.
Roman Arutyunyan <arut@nginx.com>
parents:
8497
diff
changeset
|
1715 break; |
8295
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1716 } |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1717 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1718 return NGX_AGAIN; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1719 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1720 done: |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1721 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1722 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse data done"); |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1723 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1724 st->state = sw_start; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1725 return NGX_DONE; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8227
diff
changeset
|
1726 } |
8772
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1727 |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1728 |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1729 ngx_int_t |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1730 ngx_http_v3_parse_uni(ngx_connection_t *c, ngx_http_v3_parse_uni_t *st, |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1731 u_char ch) |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1732 { |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1733 ngx_int_t rc; |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1734 enum { |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1735 sw_start = 0, |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1736 sw_type, |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1737 sw_control, |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1738 sw_encoder, |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1739 sw_decoder, |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1740 sw_unknown |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1741 }; |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1742 |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1743 switch (st->state) { |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1744 case sw_start: |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1745 |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1746 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse uni"); |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1747 |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1748 st->state = sw_type; |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1749 |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1750 /* fall through */ |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1751 |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1752 case sw_type: |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1753 |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1754 rc = ngx_http_v3_parse_varlen_int(c, &st->vlint, ch); |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1755 if (rc != NGX_DONE) { |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1756 return rc; |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1757 } |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1758 |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1759 rc = ngx_http_v3_register_uni_stream(c, st->vlint.value); |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1760 if (rc != NGX_OK) { |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1761 return rc; |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1762 } |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1763 |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1764 switch (st->vlint.value) { |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1765 case NGX_HTTP_V3_STREAM_CONTROL: |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1766 st->state = sw_control; |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1767 break; |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1768 |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1769 case NGX_HTTP_V3_STREAM_ENCODER: |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1770 st->state = sw_encoder; |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1771 break; |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1772 |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1773 case NGX_HTTP_V3_STREAM_DECODER: |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1774 st->state = sw_decoder; |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1775 break; |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1776 |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1777 default: |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1778 st->state = sw_unknown; |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1779 } |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1780 |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1781 break; |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1782 |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1783 case sw_control: |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1784 |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1785 rc = ngx_http_v3_parse_control(c, &st->u.control, ch); |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1786 if (rc != NGX_OK) { |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1787 return rc; |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1788 } |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1789 |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1790 break; |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1791 |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1792 case sw_encoder: |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1793 |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1794 rc = ngx_http_v3_parse_encoder(c, &st->u.encoder, ch); |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1795 if (rc != NGX_OK) { |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1796 return rc; |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1797 } |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1798 |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1799 break; |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1800 |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1801 case sw_decoder: |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1802 |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1803 rc = ngx_http_v3_parse_decoder(c, &st->u.decoder, ch); |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1804 if (rc != NGX_OK) { |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1805 return rc; |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1806 } |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1807 |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1808 break; |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1809 |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1810 case sw_unknown: |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1811 break; |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1812 } |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1813 |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1814 return NGX_AGAIN; |
345370fdd32d
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Roman Arutyunyan <arut@nginx.com>
parents:
8771
diff
changeset
|
1815 } |