mirror of
https://github.com/nginx/nginx.git
synced 2025-02-25 18:55:26 -06:00
merge r3153, r3154, r3288, r3382:
request header processing fixes: *) $host is always in low case: *) move low case convertation from ngx_http_find_virtual_server() to ngx_http_validate_host() *) add in ngx_http_validate_host() capability to copy host name in the pool allocated memory *) fix segfault if there is single large_client_header_buffers and a request line fills it completely *) default large_client_header_buffers' buffer size should be 8K as compatible with Apache's one
This commit is contained in:
parent
13653be34e
commit
12c54b3871
@ -2862,7 +2862,7 @@ ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||||||
prev->client_header_buffer_size, 1024);
|
prev->client_header_buffer_size, 1024);
|
||||||
ngx_conf_merge_bufs_value(conf->large_client_header_buffers,
|
ngx_conf_merge_bufs_value(conf->large_client_header_buffers,
|
||||||
prev->large_client_header_buffers,
|
prev->large_client_header_buffers,
|
||||||
4, ngx_pagesize);
|
4, 8192);
|
||||||
|
|
||||||
if (conf->large_client_header_buffers.size < conf->connection_pool_size) {
|
if (conf->large_client_header_buffers.size < conf->connection_pool_size) {
|
||||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||||
|
@ -31,7 +31,8 @@ static ngx_int_t ngx_http_process_cookie(ngx_http_request_t *r,
|
|||||||
|
|
||||||
static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r);
|
static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r);
|
||||||
static void ngx_http_process_request(ngx_http_request_t *r);
|
static void ngx_http_process_request(ngx_http_request_t *r);
|
||||||
static ssize_t ngx_http_validate_host(u_char *host, size_t len);
|
static ssize_t ngx_http_validate_host(ngx_http_request_t *r, u_char **host,
|
||||||
|
size_t len, ngx_uint_t alloc);
|
||||||
static ngx_int_t ngx_http_find_virtual_server(ngx_http_request_t *r,
|
static ngx_int_t ngx_http_find_virtual_server(ngx_http_request_t *r,
|
||||||
u_char *host, size_t len);
|
u_char *host, size_t len);
|
||||||
|
|
||||||
@ -623,6 +624,7 @@ int
|
|||||||
ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
|
ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
|
||||||
{
|
{
|
||||||
size_t len;
|
size_t len;
|
||||||
|
u_char *host;
|
||||||
const char *servername;
|
const char *servername;
|
||||||
ngx_connection_t *c;
|
ngx_connection_t *c;
|
||||||
ngx_http_request_t *r;
|
ngx_http_request_t *r;
|
||||||
@ -647,7 +649,15 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
|
|||||||
|
|
||||||
r = c->data;
|
r = c->data;
|
||||||
|
|
||||||
if (ngx_http_find_virtual_server(r, (u_char *) servername, len) != NGX_OK) {
|
host = (u_char *) servername;
|
||||||
|
|
||||||
|
len = ngx_http_validate_host(r, &host, len, 1);
|
||||||
|
|
||||||
|
if (len <= 0) {
|
||||||
|
return SSL_TLSEXT_ERR_NOACK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ngx_http_find_virtual_server(r, host, len) != NGX_OK) {
|
||||||
return SSL_TLSEXT_ERR_NOACK;
|
return SSL_TLSEXT_ERR_NOACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -666,6 +676,7 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
|
|||||||
static void
|
static void
|
||||||
ngx_http_process_request_line(ngx_event_t *rev)
|
ngx_http_process_request_line(ngx_event_t *rev)
|
||||||
{
|
{
|
||||||
|
u_char *host;
|
||||||
ssize_t n;
|
ssize_t n;
|
||||||
ngx_int_t rc, rv;
|
ngx_int_t rc, rv;
|
||||||
ngx_connection_t *c;
|
ngx_connection_t *c;
|
||||||
@ -797,18 +808,25 @@ ngx_http_process_request_line(ngx_event_t *rev)
|
|||||||
"http exten: \"%V\"", &r->exten);
|
"http exten: \"%V\"", &r->exten);
|
||||||
|
|
||||||
if (r->host_start && r->host_end) {
|
if (r->host_start && r->host_end) {
|
||||||
n = ngx_http_validate_host(r->host_start,
|
|
||||||
r->host_end - r->host_start);
|
|
||||||
|
|
||||||
if (n <= 0) {
|
host = r->host_start;
|
||||||
|
n = ngx_http_validate_host(r, &host,
|
||||||
|
r->host_end - r->host_start, 0);
|
||||||
|
|
||||||
|
if (n == 0) {
|
||||||
ngx_log_error(NGX_LOG_INFO, c->log, 0,
|
ngx_log_error(NGX_LOG_INFO, c->log, 0,
|
||||||
"client sent invalid host in request line");
|
"client sent invalid host in request line");
|
||||||
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
|
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (n < 0) {
|
||||||
|
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
r->headers_in.server.len = n;
|
r->headers_in.server.len = n;
|
||||||
r->headers_in.server.data = r->host_start;
|
r->headers_in.server.data = host;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r->http_version < NGX_HTTP_VERSION_10) {
|
if (r->http_version < NGX_HTTP_VERSION_10) {
|
||||||
@ -932,9 +950,17 @@ ngx_http_process_request_headers(ngx_event_t *rev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (rv == NGX_DECLINED) {
|
if (rv == NGX_DECLINED) {
|
||||||
len = r->header_in->end - r->header_name_start;
|
|
||||||
p = r->header_name_start;
|
p = r->header_name_start;
|
||||||
|
|
||||||
|
if (p == NULL) {
|
||||||
|
ngx_log_error(NGX_LOG_INFO, c->log, 0,
|
||||||
|
"client sent too large request");
|
||||||
|
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = r->header_in->end - p;
|
||||||
|
|
||||||
if (len > NGX_MAX_ERROR_STR - 300) {
|
if (len > NGX_MAX_ERROR_STR - 300) {
|
||||||
len = NGX_MAX_ERROR_STR - 300;
|
len = NGX_MAX_ERROR_STR - 300;
|
||||||
p[len++] = '.'; p[len++] = '.'; p[len++] = '.';
|
p[len++] = '.'; p[len++] = '.'; p[len++] = '.';
|
||||||
@ -1308,27 +1334,34 @@ static ngx_int_t
|
|||||||
ngx_http_process_host(ngx_http_request_t *r, ngx_table_elt_t *h,
|
ngx_http_process_host(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||||
ngx_uint_t offset)
|
ngx_uint_t offset)
|
||||||
{
|
{
|
||||||
|
u_char *host;
|
||||||
ssize_t len;
|
ssize_t len;
|
||||||
|
|
||||||
if (r->headers_in.host == NULL) {
|
if (r->headers_in.host == NULL) {
|
||||||
r->headers_in.host = h;
|
r->headers_in.host = h;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = ngx_http_validate_host(h->value.data, h->value.len);
|
host = h->value.data;
|
||||||
|
len = ngx_http_validate_host(r, &host, h->value.len, 0);
|
||||||
|
|
||||||
if (len <= 0) {
|
if (len == 0) {
|
||||||
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
||||||
"client sent invalid host header");
|
"client sent invalid host header");
|
||||||
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
|
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (len < 0) {
|
||||||
|
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
if (r->headers_in.server.len) {
|
if (r->headers_in.server.len) {
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
r->headers_in.server.len = len;
|
r->headers_in.server.len = len;
|
||||||
r->headers_in.server.data = h->value.data;
|
r->headers_in.server.data = host;
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
@ -1584,21 +1617,23 @@ ngx_http_process_request(ngx_http_request_t *r)
|
|||||||
|
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
ngx_http_validate_host(u_char *host, size_t len)
|
ngx_http_validate_host(ngx_http_request_t *r, u_char **host, size_t len,
|
||||||
|
ngx_uint_t alloc)
|
||||||
{
|
{
|
||||||
u_char ch;
|
u_char *h, ch;
|
||||||
size_t i, last;
|
size_t i, last;
|
||||||
ngx_uint_t dot;
|
ngx_uint_t dot;
|
||||||
|
|
||||||
last = len;
|
last = len;
|
||||||
|
h = *host;
|
||||||
dot = 0;
|
dot = 0;
|
||||||
|
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
ch = host[i];
|
ch = h[i];
|
||||||
|
|
||||||
if (ch == '.') {
|
if (ch == '.') {
|
||||||
if (dot) {
|
if (dot) {
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
dot = 1;
|
dot = 1;
|
||||||
@ -1613,7 +1648,11 @@ ngx_http_validate_host(u_char *host, size_t len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ngx_path_separator(ch) || ch == '\0') {
|
if (ngx_path_separator(ch) || ch == '\0') {
|
||||||
return -1;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ch >= 'A' || ch < 'Z') {
|
||||||
|
alloc = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1621,6 +1660,15 @@ ngx_http_validate_host(u_char *host, size_t len)
|
|||||||
last--;
|
last--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (alloc) {
|
||||||
|
*host = ngx_pnalloc(r->pool, last) ;
|
||||||
|
if (*host == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_strlow(*host, h, last);
|
||||||
|
}
|
||||||
|
|
||||||
return last;
|
return last;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1628,29 +1676,15 @@ ngx_http_validate_host(u_char *host, size_t len)
|
|||||||
static ngx_int_t
|
static ngx_int_t
|
||||||
ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len)
|
ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len)
|
||||||
{
|
{
|
||||||
u_char *server;
|
|
||||||
ngx_uint_t hash;
|
|
||||||
ngx_http_core_loc_conf_t *clcf;
|
ngx_http_core_loc_conf_t *clcf;
|
||||||
ngx_http_core_srv_conf_t *cscf;
|
ngx_http_core_srv_conf_t *cscf;
|
||||||
u_char buf[32];
|
|
||||||
|
|
||||||
if (r->virtual_names == NULL) {
|
if (r->virtual_names == NULL) {
|
||||||
return NGX_DECLINED;
|
return NGX_DECLINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len <= 32) {
|
cscf = ngx_hash_find_combined(&r->virtual_names->names,
|
||||||
server = buf;
|
ngx_hash_key(host, len), host, len);
|
||||||
|
|
||||||
} else {
|
|
||||||
server = ngx_pnalloc(r->pool, len);
|
|
||||||
if (server == NULL) {
|
|
||||||
return NGX_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hash = ngx_hash_strlow(server, host, len);
|
|
||||||
|
|
||||||
cscf = ngx_hash_find_combined(&r->virtual_names->names, hash, server, len);
|
|
||||||
|
|
||||||
if (cscf) {
|
if (cscf) {
|
||||||
goto found;
|
goto found;
|
||||||
@ -1666,7 +1700,7 @@ ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len)
|
|||||||
ngx_http_server_name_t *sn;
|
ngx_http_server_name_t *sn;
|
||||||
|
|
||||||
name.len = len;
|
name.len = len;
|
||||||
name.data = server;
|
name.data = host;
|
||||||
|
|
||||||
ncaptures = 0;
|
ncaptures = 0;
|
||||||
|
|
||||||
@ -1682,16 +1716,6 @@ ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len)
|
|||||||
if (r->captures == NULL) {
|
if (r->captures == NULL) {
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (server == buf) {
|
|
||||||
server = ngx_pnalloc(r->pool, len);
|
|
||||||
if (server == NULL) {
|
|
||||||
return NGX_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
ngx_memcpy(server, buf, len);
|
|
||||||
name.data = server;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
n = ngx_regex_exec(sn[i].regex, &name, r->captures, ncaptures);
|
n = ngx_regex_exec(sn[i].regex, &name, r->captures, ncaptures);
|
||||||
@ -1713,7 +1737,7 @@ ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len)
|
|||||||
cscf = sn[i].core_srv_conf;
|
cscf = sn[i].core_srv_conf;
|
||||||
|
|
||||||
r->ncaptures = ncaptures;
|
r->ncaptures = ncaptures;
|
||||||
r->captures_data = server;
|
r->captures_data = host;
|
||||||
|
|
||||||
goto found;
|
goto found;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user