summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/http/v3/ngx_http_v3_parse.c63
-rw-r--r--src/http/v3/ngx_http_v3_parse.h2
-rw-r--r--src/http/v3/ngx_http_v3_request.c6
3 files changed, 60 insertions, 11 deletions
diff --git a/src/http/v3/ngx_http_v3_parse.c b/src/http/v3/ngx_http_v3_parse.c
index 1a7aa17f8..8f47b4d99 100644
--- a/src/http/v3/ngx_http_v3_parse.c
+++ b/src/http/v3/ngx_http_v3_parse.c
@@ -155,7 +155,9 @@ ngx_http_v3_parse_headers(ngx_connection_t *c, ngx_http_v3_parse_headers_t *st,
ngx_int_t rc;
enum {
sw_start = 0,
+ sw_type,
sw_length,
+ sw_skip,
sw_prefix,
sw_verify,
sw_header_rep,
@@ -168,10 +170,18 @@ ngx_http_v3_parse_headers(ngx_connection_t *c, ngx_http_v3_parse_headers_t *st,
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse headers");
- if (ch != NGX_HTTP_V3_FRAME_HEADERS) {
- return NGX_HTTP_V3_ERR_FRAME_UNEXPECTED;
+ st->state = sw_type;
+
+ /* fall through */
+
+ case sw_type:
+
+ rc = ngx_http_v3_parse_varlen_int(c, &st->vlint, ch);
+ if (rc != NGX_DONE) {
+ return rc;
}
+ st->type = st->vlint.value;
st->state = sw_length;
break;
@@ -184,12 +194,26 @@ ngx_http_v3_parse_headers(ngx_connection_t *c, ngx_http_v3_parse_headers_t *st,
st->length = st->vlint.value;
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http3 parse headers len:%ui", st->length);
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
+ "http3 parse headers type:%ui, len:%ui",
+ st->type, st->length);
+
+ if (st->type != NGX_HTTP_V3_FRAME_HEADERS) {
+ st->state = st->length > 0 ? sw_skip : sw_type;
+ break;
+ }
st->state = sw_prefix;
break;
+ case sw_skip:
+
+ if (--st->length == 0) {
+ st->state = sw_type;
+ }
+
+ break;
+
case sw_prefix:
if (st->length-- == 0) {
@@ -1529,7 +1553,8 @@ ngx_http_v3_parse_data(ngx_connection_t *c, ngx_http_v3_parse_data_t *st,
enum {
sw_start = 0,
sw_type,
- sw_length
+ sw_length,
+ sw_skip
};
switch (st->state) {
@@ -1549,8 +1574,11 @@ ngx_http_v3_parse_data(ngx_connection_t *c, ngx_http_v3_parse_data_t *st,
return rc;
}
- if (st->vlint.value != NGX_HTTP_V3_FRAME_DATA) {
- return NGX_HTTP_V3_ERR_FRAME_UNEXPECTED;
+ st->type = st->vlint.value;
+
+ if (st->type == NGX_HTTP_V3_FRAME_HEADERS) {
+ /* trailers */
+ goto done;
}
st->state = sw_length;
@@ -1565,10 +1593,25 @@ ngx_http_v3_parse_data(ngx_connection_t *c, ngx_http_v3_parse_data_t *st,
st->length = st->vlint.value;
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http3 parse data frame len:%ui", st->length);
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
+ "http3 parse data type:%ui, len:%ui",
+ st->type, st->length);
- goto done;
+ if (st->type != NGX_HTTP_V3_FRAME_DATA && st->length > 0) {
+ st->state = sw_skip;
+ break;
+ }
+
+ st->state = sw_type;
+ return NGX_OK;
+
+ case sw_skip:
+
+ if (--st->length == 0) {
+ st->state = sw_type;
+ }
+
+ break;
}
return NGX_AGAIN;
diff --git a/src/http/v3/ngx_http_v3_parse.h b/src/http/v3/ngx_http_v3_parse.h
index 0c0af33b7..856f021bd 100644
--- a/src/http/v3/ngx_http_v3_parse.h
+++ b/src/http/v3/ngx_http_v3_parse.h
@@ -76,6 +76,7 @@ typedef struct {
typedef struct {
ngx_uint_t state;
+ ngx_uint_t type;
ngx_uint_t length;
ngx_http_v3_parse_varlen_int_t vlint;
ngx_http_v3_parse_header_block_prefix_t prefix;
@@ -107,6 +108,7 @@ typedef struct {
typedef struct {
ngx_uint_t state;
+ ngx_uint_t type;
ngx_uint_t length;
ngx_http_v3_parse_varlen_int_t vlint;
} ngx_http_v3_parse_data_t;
diff --git a/src/http/v3/ngx_http_v3_request.c b/src/http/v3/ngx_http_v3_request.c
index fe3c79bf0..d9f4c9d55 100644
--- a/src/http/v3/ngx_http_v3_request.c
+++ b/src/http/v3/ngx_http_v3_request.c
@@ -418,7 +418,11 @@ ngx_http_v3_parse_request_body(ngx_http_request_t *r, ngx_buf_t *b,
continue;
}
- /* rc == NGX_DONE */
+ if (rc == NGX_DONE) {
+ return NGX_DONE;
+ }
+
+ /* rc == NGX_OK */
ctx->size = st->length;
ctx->state = sw_start;