summaryrefslogtreecommitdiff
path: root/src/http/ngx_http_request.c
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2010-02-01 16:09:21 +0000
committerJonathan Kolb <jon@b0g.us>2010-02-01 16:09:21 +0000
commit433704bd188c90b81b2a212ac8c5298583002b32 (patch)
treec5b1e07f4083f2402b2cca38ff6d5fc1688e9672 /src/http/ngx_http_request.c
parente69ffdaddf10c64c8bf1083d437c54e8fde98795 (diff)
downloadnginx-0.7.65.tar.gz
Changes with nginx 0.7.65 01 Feb 2010v0.7.65
*) Security: now nginx/Windows ignores trailing spaces in URI. Thanks to Dan Crowley, Core Security Technologies. *) Security: now nginx/Windows ignores short files names. Thanks to Dan Crowley, Core Security Technologies. *) Change: now the "009" status code is written to an access log for proxied HTTP/0.9 responses. *) Change: now the default buffer size of the "large_client_header_buffers" directive is 8K. Thanks to Andrew Cholakian. *) Change: now default SSL ciphers are "HIGH:!ADH:!MD5". *) Change: now SSLv2 protocol is disabled by default. *) Change: now $host variable value is always low case. *) Feature: the conf/fastcgi.conf for simple FastCGI configurations. *) Feature: now URI part is not required a "proxy_pass" directive if variables are used. *) Feature: the $ssl_session_id variable. *) Bugfix: if a proxied or FastCGI request was internally redirected to another proxied or FastCGI location, then $upstream_response_time variable may have abnormally large value; the bug had appeared in 0.7.63. *) Bugfix: if the "expires modified" set date in the past, then a negative number was set in the "Cache-Control" response header line. Thanks to Alex Kapranoff. *) Bugfix: nginx closed a connection if a cached response had an empty body. Thanks to Piotr Sikora. *) Bugfix: nginx cached a 304 response if there was the "If-None-Match" header line in a proxied request. Thanks to Tim Dettrick and David Kostal. *) Bugfix: nginx did not treat a comma as separator in the "Cache-Control" backend response header line. *) Bugfix: cached HTTP/0.9 responses were handled incorrectly. *) Bugfix: nginx sent gzipped responses to clients those do not support gzip, if "gzip_static on" and "gzip_vary off"; the bug had appeared in 0.8.16. *) Bugfix: nginx always added "Content-Encoding: gzip" response header line in 304 responses sent by ngx_http_gzip_static_module. *) Bugfix: the "!-x" operator did not work. Thanks to Maxim Dounin. *) Bugfix: a segmentation fault might occur in a worker process, if limit_rate was used in HTTPS server. Thanks to Maxim Dounin. *) Bugfix: a segmentation fault might occur in a worker process while $limit_rate logging. Thanks to Maxim Dounin. *) Bugfix: nginx did not support dates in 2038 year on 32-bit platforms; *) Bugfix: nginx/Windows tried to delete a temporary file twice if the file should replace an already existent file. *) Bugfix: nginx/Windows tried to rename a temporary file twice if the file should replace an already existent file. *) Bugfix: nginx/Windows might not create temporary file, a cache file, or "proxy/fastcgi_store"d file if a worker had no enough access rights for top level directories. *) Bugfix: in UTF-8 encoding support by "try_files" directive in nginx/Windows. *) Bugfix: UTF-8 encoding usage in the ngx_http_autoindex_module. Thanks to Maxim Dounin. *) Bugfix: the ngx_http_autoindex_module did not show the trailing slash in links to a directory; the bug had appeared in 0.7.15. *) Bugfix: nginx did not close a log file set by the --error-log-path configuration option; the bug had appeared in 0.7.53. *) Bugfix: "addition_types" directive was incorrectly named "addtion_types". *) Bugfix: invalid request line in $request variable was written in access_log only if error_log was set to "info" or "debug" level.
Diffstat (limited to 'src/http/ngx_http_request.c')
-rw-r--r--src/http/ngx_http_request.c122
1 files changed, 74 insertions, 48 deletions
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index 541d305ec..c239b9d34 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -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 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,
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)
{
size_t len;
+ u_char *host;
const char *servername;
ngx_connection_t *c;
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;
- 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;
}
@@ -666,6 +676,7 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
static void
ngx_http_process_request_line(ngx_event_t *rev)
{
+ u_char *host;
ssize_t n;
ngx_int_t rc, rv;
ngx_connection_t *c;
@@ -773,9 +784,11 @@ ngx_http_process_request_line(ngx_event_t *rev)
p = r->uri.data + r->uri.len - 1;
- if (*p == '.') {
+ if (*p == '.' || *p == ' ') {
- while (--p > r->uri.data && *p == '.') { /* void */ }
+ while (--p > r->uri.data && (*p == '.' || *p == ' ')) {
+ /* void */
+ }
r->uri.len = p + 1 - r->uri.data;
@@ -797,18 +810,25 @@ ngx_http_process_request_line(ngx_event_t *rev)
"http exten: \"%V\"", &r->exten);
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,
"client sent invalid host in request line");
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
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.data = r->host_start;
+ r->headers_in.server.data = host;
}
if (r->http_version < NGX_HTTP_VERSION_10) {
@@ -932,9 +952,17 @@ ngx_http_process_request_headers(ngx_event_t *rev)
}
if (rv == NGX_DECLINED) {
- len = r->header_in->end - 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) {
len = NGX_MAX_ERROR_STR - 300;
p[len++] = '.'; p[len++] = '.'; p[len++] = '.';
@@ -1308,27 +1336,34 @@ static ngx_int_t
ngx_http_process_host(ngx_http_request_t *r, ngx_table_elt_t *h,
ngx_uint_t offset)
{
- ssize_t len;
+ u_char *host;
+ ssize_t len;
if (r->headers_in.host == NULL) {
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,
"client sent invalid host header");
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
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) {
return NGX_OK;
}
r->headers_in.server.len = len;
- r->headers_in.server.data = h->value.data;
+ r->headers_in.server.data = host;
return NGX_OK;
}
@@ -1584,21 +1619,23 @@ ngx_http_process_request(ngx_http_request_t *r)
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;
- size_t i, last;
- ngx_uint_t dot;
+ u_char *h, ch;
+ size_t i, last;
+ ngx_uint_t dot;
last = len;
+ h = *host;
dot = 0;
for (i = 0; i < len; i++) {
- ch = host[i];
+ ch = h[i];
if (ch == '.') {
if (dot) {
- return -1;
+ return 0;
}
dot = 1;
@@ -1613,7 +1650,11 @@ ngx_http_validate_host(u_char *host, size_t len)
}
if (ngx_path_separator(ch) || ch == '\0') {
- return -1;
+ return 0;
+ }
+
+ if (ch >= 'A' || ch < 'Z') {
+ alloc = 1;
}
}
@@ -1621,6 +1662,15 @@ ngx_http_validate_host(u_char *host, size_t len)
last--;
}
+ if (alloc) {
+ *host = ngx_pnalloc(r->pool, last) ;
+ if (*host == NULL) {
+ return -1;
+ }
+
+ ngx_strlow(*host, h, last);
+ }
+
return last;
}
@@ -1628,29 +1678,15 @@ ngx_http_validate_host(u_char *host, size_t len)
static ngx_int_t
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_srv_conf_t *cscf;
- u_char buf[32];
if (r->virtual_names == NULL) {
return NGX_DECLINED;
}
- if (len <= 32) {
- server = buf;
-
- } 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);
+ cscf = ngx_hash_find_combined(&r->virtual_names->names,
+ ngx_hash_key(host, len), host, len);
if (cscf) {
goto found;
@@ -1666,7 +1702,7 @@ ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len)
ngx_http_server_name_t *sn;
name.len = len;
- name.data = server;
+ name.data = host;
ncaptures = 0;
@@ -1682,16 +1718,6 @@ ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len)
if (r->captures == NULL) {
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);
@@ -1713,7 +1739,7 @@ ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len)
cscf = sn[i].core_srv_conf;
r->ncaptures = ncaptures;
- r->captures_data = server;
+ r->captures_data = host;
goto found;
}