Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/http/ngx_http_core_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,13 @@ static ngx_command_t ngx_http_core_commands[] = {
offsetof(ngx_http_core_srv_conf_t, large_client_header_buffers),
NULL },

{ ngx_string("max_headers"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
ngx_conf_set_num_slot,
NGX_HTTP_SRV_CONF_OFFSET,
offsetof(ngx_http_core_srv_conf_t, max_headers),
NULL },

{ ngx_string("ignore_invalid_headers"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
Expand Down Expand Up @@ -3466,6 +3473,7 @@ ngx_http_core_create_srv_conf(ngx_conf_t *cf)
cscf->request_pool_size = NGX_CONF_UNSET_SIZE;
cscf->client_header_timeout = NGX_CONF_UNSET_MSEC;
cscf->client_header_buffer_size = NGX_CONF_UNSET_SIZE;
cscf->max_headers = NGX_CONF_UNSET_UINT;
cscf->ignore_invalid_headers = NGX_CONF_UNSET;
cscf->merge_slashes = NGX_CONF_UNSET;
cscf->underscores_in_headers = NGX_CONF_UNSET;
Expand Down Expand Up @@ -3507,6 +3515,8 @@ ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
return NGX_CONF_ERROR;
}

ngx_conf_merge_uint_value(conf->max_headers, prev->max_headers, 1000);

ngx_conf_merge_value(conf->ignore_invalid_headers,
prev->ignore_invalid_headers, 1);

Expand Down
2 changes: 2 additions & 0 deletions src/http/ngx_http_core_module.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,8 @@ typedef struct {

ngx_msec_t client_header_timeout;

ngx_uint_t max_headers;

ngx_flag_t ignore_invalid_headers;
ngx_flag_t merge_slashes;
ngx_flag_t underscores_in_headers;
Expand Down
9 changes: 9 additions & 0 deletions src/http/ngx_http_request.c
Original file line number Diff line number Diff line change
Expand Up @@ -1433,6 +1433,15 @@ ngx_http_process_request_headers(ngx_event_t *rev)

/* a header line has been parsed successfully */

if (r->headers_in.count++ >= cscf->max_headers) {
r->lingering_close = 1;
ngx_log_error(NGX_LOG_INFO, c->log, 0,
"client sent too many header lines");
ngx_http_finalize_request(r,
NGX_HTTP_REQUEST_HEADER_TOO_LARGE);
break;
}

h = ngx_list_push(&r->headers_in.headers);
if (h == NULL) {
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
Expand Down
1 change: 1 addition & 0 deletions src/http/ngx_http_request.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ typedef struct {

typedef struct {
ngx_list_t headers;
ngx_uint_t count;

ngx_table_elt_t *host;
ngx_table_elt_t *connection;
Expand Down
9 changes: 9 additions & 0 deletions src/http/v2/ngx_http_v2.c
Original file line number Diff line number Diff line change
Expand Up @@ -1841,6 +1841,15 @@ ngx_http_v2_state_process_header(ngx_http_v2_connection_t *h2c, u_char *pos,
}

} else {
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);

if (r->headers_in.count++ >= cscf->max_headers) {
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
"client sent too many header lines");
ngx_http_finalize_request(r, NGX_HTTP_REQUEST_HEADER_TOO_LARGE);
goto error;
}

h = ngx_list_push(&r->headers_in.headers);
if (h == NULL) {
return ngx_http_v2_connection_error(h2c,
Expand Down