Mercurial > hg > nginx
comparison src/http/v3/ngx_http_v3_parse.c @ 8549:d70a38acaea0 quic
HTTP/3: skip unknown frames on request stream.
As per HTTP/3 draft 29, section 4.1:
Frames of unknown types (Section 9), including reserved frames
(Section 7.2.8) MAY be sent on a request or push stream before,
after, or interleaved with other frames described in this section.
Also, trailers frame is now used as an indication of the request body end.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Mon, 24 Aug 2020 09:56:36 +0300 |
parents | 0596fe1aee16 |
children | 234e9d89ff7f |
comparison
equal
deleted
inserted
replaced
8548:9ffef6054abf | 8549:d70a38acaea0 |
---|---|
153 u_char ch) | 153 u_char ch) |
154 { | 154 { |
155 ngx_int_t rc; | 155 ngx_int_t rc; |
156 enum { | 156 enum { |
157 sw_start = 0, | 157 sw_start = 0, |
158 sw_type, | |
158 sw_length, | 159 sw_length, |
160 sw_skip, | |
159 sw_prefix, | 161 sw_prefix, |
160 sw_verify, | 162 sw_verify, |
161 sw_header_rep, | 163 sw_header_rep, |
162 sw_done | 164 sw_done |
163 }; | 165 }; |
166 | 168 |
167 case sw_start: | 169 case sw_start: |
168 | 170 |
169 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse headers"); | 171 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse headers"); |
170 | 172 |
171 if (ch != NGX_HTTP_V3_FRAME_HEADERS) { | 173 st->state = sw_type; |
172 return NGX_HTTP_V3_ERR_FRAME_UNEXPECTED; | 174 |
173 } | 175 /* fall through */ |
174 | 176 |
177 case sw_type: | |
178 | |
179 rc = ngx_http_v3_parse_varlen_int(c, &st->vlint, ch); | |
180 if (rc != NGX_DONE) { | |
181 return rc; | |
182 } | |
183 | |
184 st->type = st->vlint.value; | |
175 st->state = sw_length; | 185 st->state = sw_length; |
176 break; | 186 break; |
177 | 187 |
178 case sw_length: | 188 case sw_length: |
179 | 189 |
182 return rc; | 192 return rc; |
183 } | 193 } |
184 | 194 |
185 st->length = st->vlint.value; | 195 st->length = st->vlint.value; |
186 | 196 |
187 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | 197 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, |
188 "http3 parse headers len:%ui", st->length); | 198 "http3 parse headers type:%ui, len:%ui", |
199 st->type, st->length); | |
200 | |
201 if (st->type != NGX_HTTP_V3_FRAME_HEADERS) { | |
202 st->state = st->length > 0 ? sw_skip : sw_type; | |
203 break; | |
204 } | |
189 | 205 |
190 st->state = sw_prefix; | 206 st->state = sw_prefix; |
207 break; | |
208 | |
209 case sw_skip: | |
210 | |
211 if (--st->length == 0) { | |
212 st->state = sw_type; | |
213 } | |
214 | |
191 break; | 215 break; |
192 | 216 |
193 case sw_prefix: | 217 case sw_prefix: |
194 | 218 |
195 if (st->length-- == 0) { | 219 if (st->length-- == 0) { |
1527 { | 1551 { |
1528 ngx_int_t rc; | 1552 ngx_int_t rc; |
1529 enum { | 1553 enum { |
1530 sw_start = 0, | 1554 sw_start = 0, |
1531 sw_type, | 1555 sw_type, |
1532 sw_length | 1556 sw_length, |
1557 sw_skip | |
1533 }; | 1558 }; |
1534 | 1559 |
1535 switch (st->state) { | 1560 switch (st->state) { |
1536 | 1561 |
1537 case sw_start: | 1562 case sw_start: |
1547 rc = ngx_http_v3_parse_varlen_int(c, &st->vlint, ch); | 1572 rc = ngx_http_v3_parse_varlen_int(c, &st->vlint, ch); |
1548 if (rc != NGX_DONE) { | 1573 if (rc != NGX_DONE) { |
1549 return rc; | 1574 return rc; |
1550 } | 1575 } |
1551 | 1576 |
1552 if (st->vlint.value != NGX_HTTP_V3_FRAME_DATA) { | 1577 st->type = st->vlint.value; |
1553 return NGX_HTTP_V3_ERR_FRAME_UNEXPECTED; | 1578 |
1579 if (st->type == NGX_HTTP_V3_FRAME_HEADERS) { | |
1580 /* trailers */ | |
1581 goto done; | |
1554 } | 1582 } |
1555 | 1583 |
1556 st->state = sw_length; | 1584 st->state = sw_length; |
1557 break; | 1585 break; |
1558 | 1586 |
1563 return rc; | 1591 return rc; |
1564 } | 1592 } |
1565 | 1593 |
1566 st->length = st->vlint.value; | 1594 st->length = st->vlint.value; |
1567 | 1595 |
1568 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | 1596 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, |
1569 "http3 parse data frame len:%ui", st->length); | 1597 "http3 parse data type:%ui, len:%ui", |
1570 | 1598 st->type, st->length); |
1571 goto done; | 1599 |
1600 if (st->type != NGX_HTTP_V3_FRAME_DATA && st->length > 0) { | |
1601 st->state = sw_skip; | |
1602 break; | |
1603 } | |
1604 | |
1605 st->state = sw_type; | |
1606 return NGX_OK; | |
1607 | |
1608 case sw_skip: | |
1609 | |
1610 if (--st->length == 0) { | |
1611 st->state = sw_type; | |
1612 } | |
1613 | |
1614 break; | |
1572 } | 1615 } |
1573 | 1616 |
1574 return NGX_AGAIN; | 1617 return NGX_AGAIN; |
1575 | 1618 |
1576 done: | 1619 done: |