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