diff options
| author | Roman Arutyunyan <arut@nginx.com> | 2020-03-27 19:41:06 +0300 |
|---|---|---|
| committer | Roman Arutyunyan <arut@nginx.com> | 2020-03-27 19:41:06 +0300 |
| commit | fa1e1beadca8b1ea900ec654919aea58762ab746 (patch) | |
| tree | 772a9443d24831a11fae49b2493a87fa6f6d4a94 /src/http/v3 | |
| parent | 84a783501590e13ab27277e11f179067c08d38b3 (diff) | |
| download | nginx-fa1e1beadca8b1ea900ec654919aea58762ab746.tar.gz nginx-fa1e1beadca8b1ea900ec654919aea58762ab746.tar.bz2 | |
Parsing HTTP/3 request body.
Diffstat (limited to 'src/http/v3')
| -rw-r--r-- | src/http/v3/ngx_http_v3.h | 2 | ||||
| -rw-r--r-- | src/http/v3/ngx_http_v3_parse.c | 58 | ||||
| -rw-r--r-- | src/http/v3/ngx_http_v3_parse.h | 10 | ||||
| -rw-r--r-- | src/http/v3/ngx_http_v3_request.c | 63 |
4 files changed, 133 insertions, 0 deletions
diff --git a/src/http/v3/ngx_http_v3.h b/src/http/v3/ngx_http_v3.h index d28074d37..3f35e985e 100644 --- a/src/http/v3/ngx_http_v3.h +++ b/src/http/v3/ngx_http_v3.h @@ -68,6 +68,8 @@ typedef struct { ngx_int_t ngx_http_v3_parse_header(ngx_http_request_t *r, ngx_buf_t *b); +ngx_int_t ngx_http_v3_parse_request_body(ngx_http_request_t *r, ngx_buf_t *b, + ngx_http_chunked_t *ctx); ngx_chain_t *ngx_http_v3_create_header(ngx_http_request_t *r); ngx_chain_t *ngx_http_v3_create_trailers(ngx_http_request_t *r); diff --git a/src/http/v3/ngx_http_v3_parse.c b/src/http/v3/ngx_http_v3_parse.c index 0fd44bc40..3be3802ed 100644 --- a/src/http/v3/ngx_http_v3_parse.c +++ b/src/http/v3/ngx_http_v3_parse.c @@ -1421,3 +1421,61 @@ done: st->state = sw_start; return NGX_DONE; } + + +ngx_int_t +ngx_http_v3_parse_data(ngx_connection_t *c, ngx_http_v3_parse_data_t *st, + u_char ch) +{ + enum { + sw_start = 0, + sw_type, + sw_length + }; + + switch (st->state) { + + case sw_start: + + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse data"); + + st->state = sw_type; + + /* fall through */ + + case sw_type: + + if (ngx_http_v3_parse_varlen_int(c, &st->vlint, ch) != NGX_DONE) { + break; + } + + if (st->vlint.value != NGX_HTTP_V3_FRAME_DATA) { + return NGX_ERROR; + } + + st->state = sw_length; + break; + + case sw_length: + + if (ngx_http_v3_parse_varlen_int(c, &st->vlint, ch) != NGX_DONE) { + break; + } + + st->length = st->vlint.value; + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, + "http3 parse data frame len:%ui", st->length); + + goto done; + } + + return NGX_AGAIN; + +done: + + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse data done"); + + st->state = sw_start; + return NGX_DONE; +} diff --git a/src/http/v3/ngx_http_v3_parse.h b/src/http/v3/ngx_http_v3_parse.h index 959da7941..ec78c7c35 100644 --- a/src/http/v3/ngx_http_v3_parse.h +++ b/src/http/v3/ngx_http_v3_parse.h @@ -105,6 +105,13 @@ typedef struct { } ngx_http_v3_parse_control_t; +typedef struct { + ngx_uint_t state; + ngx_uint_t length; + ngx_http_v3_parse_varlen_int_t vlint; +} ngx_http_v3_parse_data_t; + + ngx_int_t ngx_http_v3_parse_varlen_int(ngx_connection_t *c, ngx_http_v3_parse_varlen_int_t *st, u_char ch); ngx_int_t ngx_http_v3_parse_prefix_int(ngx_connection_t *c, @@ -141,5 +148,8 @@ ngx_int_t ngx_http_v3_parse_header_iwnr(ngx_connection_t *c, ngx_int_t ngx_http_v3_parse_decoder(ngx_connection_t *c, void *data, u_char ch); +ngx_int_t ngx_http_v3_parse_data(ngx_connection_t *c, + ngx_http_v3_parse_data_t *st, u_char ch); + #endif /* _NGX_HTTP_V3_PARSE_H_INCLUDED_ */ diff --git a/src/http/v3/ngx_http_v3_request.c b/src/http/v3/ngx_http_v3_request.c index 756a6f90d..911dbab36 100644 --- a/src/http/v3/ngx_http_v3_request.c +++ b/src/http/v3/ngx_http_v3_request.c @@ -241,6 +241,69 @@ ngx_http_v3_process_pseudo_header(ngx_http_request_t *r, ngx_str_t *name, } +ngx_int_t +ngx_http_v3_parse_request_body(ngx_http_request_t *r, ngx_buf_t *b, + ngx_http_chunked_t *ctx) +{ + ngx_int_t rc; + ngx_connection_t *c; + ngx_http_v3_parse_data_t *st; + + c = r->connection; + st = ctx->h3_parse; + + if (st == NULL) { + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, + "http3 parse request body"); + + st = ngx_pcalloc(c->pool, sizeof(ngx_http_v3_parse_data_t)); + if (st == NULL) { + goto failed; + } + + r->h3_parse = st; + } + + if (ctx->size) { + return NGX_OK; + } + + while (b->pos < b->last) { + rc = ngx_http_v3_parse_data(c, st, *b->pos++); + + if (rc == NGX_ERROR) { + goto failed; + } + + if (rc == NGX_AGAIN) { + continue; + } + + /* rc == NGX_DONE */ + + ctx->size = st->length; + return NGX_OK; + } + + if (!b->last_buf) { + ctx->length = 1; + return NGX_AGAIN; + } + + if (st->state) { + goto failed; + } + + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse header done"); + + return NGX_DONE; + +failed: + + return NGX_ERROR; +} + + ngx_chain_t * ngx_http_v3_create_header(ngx_http_request_t *r) { |
