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;