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