From 8d41d17a12509d6f80f51a27046b7a10882892ef Mon Sep 17 00:00:00 2001 From: Roman Arutyunyan Date: Mon, 29 Jun 2020 15:56:14 +0300 Subject: [PATCH] HTTP/3: http3_max_field_size directive to limit string size. Client streams may send literal strings which are now limited in size by the new directive. The default value is 4096. The directive is similar to HTTP/2 directive http2_max_field_size. --- src/http/v3/ngx_http_v3.h | 3 +++ src/http/v3/ngx_http_v3_module.c | 12 ++++++++++++ src/http/v3/ngx_http_v3_parse.c | 11 ++++++++++- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/http/v3/ngx_http_v3.h b/src/http/v3/ngx_http_v3.h index 3c5bb721c..d48f13922 100644 --- a/src/http/v3/ngx_http_v3.h +++ b/src/http/v3/ngx_http_v3.h @@ -47,9 +47,12 @@ #define NGX_HTTP_V3_STREAM_SERVER_DECODER 5 #define NGX_HTTP_V3_MAX_KNOWN_STREAM 6 +#define NGX_HTTP_V3_DEFAULT_MAX_FIELD_SIZE 4096 + typedef struct { ngx_quic_tp_t quic; + size_t max_field_size; } ngx_http_v3_srv_conf_t; diff --git a/src/http/v3/ngx_http_v3_module.c b/src/http/v3/ngx_http_v3_module.c index 550b706da..17029934e 100644 --- a/src/http/v3/ngx_http_v3_module.c +++ b/src/http/v3/ngx_http_v3_module.c @@ -118,6 +118,13 @@ static ngx_command_t ngx_http_v3_commands[] = { offsetof(ngx_http_v3_srv_conf_t, quic.retry), NULL }, + { ngx_string("http3_max_field_size"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, + ngx_conf_set_size_slot, + NGX_HTTP_SRV_CONF_OFFSET, + offsetof(ngx_http_v3_srv_conf_t, max_field_size), + NULL }, + ngx_null_command }; @@ -268,6 +275,8 @@ ngx_http_v3_create_srv_conf(ngx_conf_t *cf) v3cf->quic.retry = NGX_CONF_UNSET; + v3cf->max_field_size = NGX_CONF_UNSET_SIZE; + return v3cf; } @@ -329,6 +338,9 @@ ngx_http_v3_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) } } + ngx_conf_merge_size_value(conf->max_field_size, + prev->max_field_size, + NGX_HTTP_V3_DEFAULT_MAX_FIELD_SIZE); return NGX_CONF_OK; } diff --git a/src/http/v3/ngx_http_v3_parse.c b/src/http/v3/ngx_http_v3_parse.c index 3be3802ed..71a643d70 100644 --- a/src/http/v3/ngx_http_v3_parse.c +++ b/src/http/v3/ngx_http_v3_parse.c @@ -399,7 +399,8 @@ ngx_int_t ngx_http_v3_parse_literal(ngx_connection_t *c, ngx_http_v3_parse_literal_t *st, u_char ch) { - ngx_uint_t n; + ngx_uint_t n; + ngx_http_v3_srv_conf_t *v3cf; enum { sw_start = 0, sw_value @@ -415,6 +416,14 @@ ngx_http_v3_parse_literal(ngx_connection_t *c, ngx_http_v3_parse_literal_t *st, n = st->length; + v3cf = ngx_http_v3_get_module_srv_conf(c, ngx_http_v3_module); + + if (n > v3cf->max_field_size) { + ngx_log_error(NGX_LOG_ERR, c->log, 0, + "client exceeded http3_max_field_size limit"); + return NGX_ERROR; + } + if (st->huffman) { n = n * 8 / 5; st->huffstate = 0;