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