comparison 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
comparison
equal deleted inserted replaced
8495:ba5977b38b2e 8496:278ab0ed24f2
222 return rc; 222 return rc;
223 } 223 }
224 224
225 st->type = st->vlint.value; 225 st->type = st->vlint.value;
226 226
227 if (ngx_http_v3_is_v2_frame(st->type)) { 227 if (ngx_http_v3_is_v2_frame(st->type)
228 || st->type == NGX_HTTP_V3_FRAME_DATA
229 || st->type == NGX_HTTP_V3_FRAME_GOAWAY
230 || st->type == NGX_HTTP_V3_FRAME_SETTINGS
231 || st->type == NGX_HTTP_V3_FRAME_MAX_PUSH_ID
232 || st->type == NGX_HTTP_V3_FRAME_CANCEL_PUSH
233 || st->type == NGX_HTTP_V3_FRAME_PUSH_PROMISE)
234 {
228 return NGX_HTTP_V3_ERR_FRAME_UNEXPECTED; 235 return NGX_HTTP_V3_ERR_FRAME_UNEXPECTED;
229 } 236 }
230 237
231 st->state = sw_length; 238 st->state = sw_length;
232 break; 239 break;
1035 && st->type != NGX_HTTP_V3_FRAME_SETTINGS) 1042 && st->type != NGX_HTTP_V3_FRAME_SETTINGS)
1036 { 1043 {
1037 return NGX_HTTP_V3_ERR_MISSING_SETTINGS; 1044 return NGX_HTTP_V3_ERR_MISSING_SETTINGS;
1038 } 1045 }
1039 1046
1047 if (st->state != sw_first_type
1048 && st->type == NGX_HTTP_V3_FRAME_SETTINGS)
1049 {
1050 return NGX_HTTP_V3_ERR_FRAME_UNEXPECTED;
1051 }
1052
1040 if (ngx_http_v3_is_v2_frame(st->type) 1053 if (ngx_http_v3_is_v2_frame(st->type)
1041 || st->type == NGX_HTTP_V3_FRAME_DATA 1054 || st->type == NGX_HTTP_V3_FRAME_DATA
1042 || st->type == NGX_HTTP_V3_FRAME_HEADERS) 1055 || st->type == NGX_HTTP_V3_FRAME_HEADERS
1056 || st->type == NGX_HTTP_V3_FRAME_PUSH_PROMISE)
1043 { 1057 {
1044 return NGX_HTTP_V3_ERR_FRAME_UNEXPECTED; 1058 return NGX_HTTP_V3_ERR_FRAME_UNEXPECTED;
1045 } 1059 }
1046 1060
1047 st->state = sw_length; 1061 st->state = sw_length;
1631 if (st->type == NGX_HTTP_V3_FRAME_HEADERS) { 1645 if (st->type == NGX_HTTP_V3_FRAME_HEADERS) {
1632 /* trailers */ 1646 /* trailers */
1633 goto done; 1647 goto done;
1634 } 1648 }
1635 1649
1636 if (ngx_http_v3_is_v2_frame(st->type)) { 1650 if (ngx_http_v3_is_v2_frame(st->type)
1651 || st->type == NGX_HTTP_V3_FRAME_GOAWAY
1652 || st->type == NGX_HTTP_V3_FRAME_SETTINGS
1653 || st->type == NGX_HTTP_V3_FRAME_MAX_PUSH_ID
1654 || st->type == NGX_HTTP_V3_FRAME_CANCEL_PUSH
1655 || st->type == NGX_HTTP_V3_FRAME_PUSH_PROMISE)
1656 {
1637 return NGX_HTTP_V3_ERR_FRAME_UNEXPECTED; 1657 return NGX_HTTP_V3_ERR_FRAME_UNEXPECTED;
1638 } 1658 }
1639 1659
1640 st->state = sw_length; 1660 st->state = sw_length;
1641 break; 1661 break;