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