summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2009-09-28 13:08:15 +0000
committerJonathan Kolb <jon@b0g.us>2009-09-28 13:08:15 +0000
commit49590f7810331a2b33e8a120017f3a01aeab2176 (patch)
tree240d6d750c6fc938e69c2e435f92824dfa87dcf5
parentc1f184e9ab685444d26023e6203754de36c83860 (diff)
downloadnginx-49590f7810331a2b33e8a120017f3a01aeab2176.tar.gz
Changes with nginx 0.8.17 28 Sep 2009v0.8.17
*) Security: now "/../" are disabled in "Destination" request header line. *) Change: now $host variable value is always low case. *) Feature: the $ssl_session_id variable. *) Bugfix: socket leak; the bug had appeared in 0.8.11.
-rw-r--r--CHANGES12
-rw-r--r--CHANGES.ru12
-rw-r--r--auto/lib/openssl/conf8
-rw-r--r--auto/lib/openssl/make6
-rw-r--r--src/core/nginx.h4
-rw-r--r--src/core/ngx_connection.c6
-rw-r--r--src/core/ngx_open_file_cache.c2
-rw-r--r--src/core/ngx_output_chain.c4
-rw-r--r--src/event/ngx_event_openssl.c40
-rw-r--r--src/event/ngx_event_openssl.h2
-rw-r--r--src/http/modules/ngx_http_dav_module.c16
-rw-r--r--src/http/modules/ngx_http_index_module.c5
-rw-r--r--src/http/modules/ngx_http_ssi_filter_module.c2
-rw-r--r--src/http/modules/ngx_http_ssl_module.c3
-rw-r--r--src/http/modules/perl/nginx.pm2
-rw-r--r--src/http/ngx_http_core_module.c6
-rw-r--r--src/http/ngx_http_parse.c6
-rw-r--r--src/http/ngx_http_request.c106
-rw-r--r--src/http/ngx_http_request.h1
-rw-r--r--src/http/ngx_http_request_body.c16
-rw-r--r--src/http/ngx_http_script.c5
-rw-r--r--src/http/ngx_http_upstream.c43
-rw-r--r--src/os/unix/ngx_atomic.h18
-rw-r--r--src/os/unix/ngx_files.c80
24 files changed, 258 insertions, 147 deletions
diff --git a/CHANGES b/CHANGES
index dc55a3957..5b2f7a946 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,16 @@
+Changes with nginx 0.8.17 28 Sep 2009
+
+ *) Security: now "/../" are disabled in "Destination" request header
+ line.
+
+ *) Change: now $host variable value is always low case.
+
+ *) Feature: the $ssl_session_id variable.
+
+ *) Bugfix: socket leak; the bug had appeared in 0.8.11.
+
+
Changes with nginx 0.8.16 22 Sep 2009
*) Feature: the "image_filter_transparency" directive.
diff --git a/CHANGES.ru b/CHANGES.ru
index 166777a06..c7ea14a20 100644
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,16 @@
+Изменения в nginx 0.8.17 28.09.2009
+
+ *) Безопасность: теперь символы "/../" запрещены в строке "Destination"
+ в заголовке запроса.
+
+ *) Изменение: теперь значение переменной $host всегда в нижнем регистре.
+
+ *) Добавление: переменная $ssl_session_id.
+
+ *) Исправление: утечки сокетов; ошибка появилась в 0.8.11.
+
+
Изменения в nginx 0.8.16 22.09.2009
*) Добавление: директива image_filter_transparency.
diff --git a/auto/lib/openssl/conf b/auto/lib/openssl/conf
index 731db80d7..64f2ce02f 100644
--- a/auto/lib/openssl/conf
+++ b/auto/lib/openssl/conf
@@ -25,10 +25,10 @@ if [ $OPENSSL != NONE ]; then
have=NGX_OPENSSL . auto/have
have=NGX_SSL . auto/have
- CORE_INCS="$CORE_INCS $OPENSSL/openssl/include"
- CORE_DEPS="$CORE_DEPS $OPENSSL/openssl/include/openssl/ssl.h"
- CORE_LIBS="$CORE_LIBS $OPENSSL/openssl/lib/libssl.a"
- CORE_LIBS="$CORE_LIBS $OPENSSL/openssl/lib/libcrypto.a"
+ CORE_INCS="$CORE_INCS $OPENSSL/.openssl/include"
+ CORE_DEPS="$CORE_DEPS $OPENSSL/.openssl/include/openssl/ssl.h"
+ CORE_LIBS="$CORE_LIBS $OPENSSL/.openssl/lib/libssl.a"
+ CORE_LIBS="$CORE_LIBS $OPENSSL/.openssl/lib/libcrypto.a"
CORE_LIBS="$CORE_LIBS $NGX_LIBDL"
;;
esac
diff --git a/auto/lib/openssl/make b/auto/lib/openssl/make
index 3c21f436b..d497d88e1 100644
--- a/auto/lib/openssl/make
+++ b/auto/lib/openssl/make
@@ -46,13 +46,13 @@ END
esac
case $OPENSSL in
- /*) ngx_prefix="$OPENSSL/openssl" ;;
- *) ngx_prefix="$PWD/$OPENSSL/openssl" ;;
+ /*) ngx_prefix="$OPENSSL/.openssl" ;;
+ *) ngx_prefix="$PWD/$OPENSSL/.openssl" ;;
esac
cat << END >> $NGX_MAKEFILE
-$OPENSSL/openssl/include/openssl/ssl.h: $NGX_MAKEFILE
+$OPENSSL/.openssl/include/openssl/ssl.h: $NGX_MAKEFILE
cd $OPENSSL \\
&& \$(MAKE) clean \\
&& ./config --prefix=$ngx_prefix no-shared $OPENSSL_OPT \\
diff --git a/src/core/nginx.h b/src/core/nginx.h
index 2aefb7b92..2976408dd 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,8 +8,8 @@
#define _NGINX_H_INCLUDED_
-#define nginx_version 8016
-#define NGINX_VERSION "0.8.16"
+#define nginx_version 8017
+#define NGINX_VERSION "0.8.17"
#define NGINX_VER "nginx/" NGINX_VERSION
#define NGINX_VAR "NGINX"
diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c
index 0a7fe847d..01c205877 100644
--- a/src/core/ngx_connection.c
+++ b/src/core/ngx_connection.c
@@ -917,12 +917,8 @@ ngx_connection_error(ngx_connection_t *c, ngx_err_t err, char *text)
level = NGX_LOG_INFO;
break;
- case NGX_ERROR_ERR:
- level = NGX_LOG_ERR;
- break;
-
default:
- level = NGX_LOG_ALERT;
+ level = NGX_LOG_ERR;
}
} else {
diff --git a/src/core/ngx_open_file_cache.c b/src/core/ngx_open_file_cache.c
index aa87fd22c..5f6e0b263 100644
--- a/src/core/ngx_open_file_cache.c
+++ b/src/core/ngx_open_file_cache.c
@@ -525,7 +525,7 @@ ngx_open_and_stat_file(u_char *name, ngx_open_file_info_t *of, ngx_log_t *log)
of->fd = fd;
if (of->directio <= ngx_file_size(&fi)) {
- if (ngx_directio_on(fd) == -1) {
+ if (ngx_directio_on(fd) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
ngx_directio_on_n " \"%s\" failed", name);
diff --git a/src/core/ngx_output_chain.c b/src/core/ngx_output_chain.c
index 590da4f45..3ff25ff76 100644
--- a/src/core/ngx_output_chain.c
+++ b/src/core/ngx_output_chain.c
@@ -514,7 +514,7 @@ ngx_output_chain_copy_buf(ngx_output_chain_ctx_t *ctx)
#if (NGX_HAVE_ALIGNED_DIRECTIO)
if (ctx->unaligned) {
- if (ngx_directio_off(src->file->fd) == -1) {
+ if (ngx_directio_off(src->file->fd) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_ALERT, ctx->pool->log, ngx_errno,
ngx_directio_off_n " \"%s\" failed",
src->file->name.data);
@@ -550,7 +550,7 @@ ngx_output_chain_copy_buf(ngx_output_chain_ctx_t *ctx)
err = ngx_errno;
- if (ngx_directio_on(src->file->fd) == -1) {
+ if (ngx_directio_on(src->file->fd) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_ALERT, ctx->pool->log, ngx_errno,
ngx_directio_on_n " \"%s\" failed",
src->file->name.data);
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
index 846114077..c46a47d1b 100644
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -1588,7 +1588,7 @@ ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn, ngx_ssl_session_t *sess)
hash = ngx_crc32_short(sess->session_id, sess->session_id_length);
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "http ssl new session: %08XD:%d:%d",
+ "ssl new session: %08XD:%d:%d",
hash, sess->session_id_length, len);
sess_id->node.key = hash;
@@ -1651,7 +1651,7 @@ ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn, u_char *id, int len,
*copy = 0;
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "http ssl get session: %08XD:%d", hash, len);
+ "ssl get session: %08XD:%d", hash, len);
shm_zone = SSL_CTX_get_ex_data(SSL_get_SSL_CTX(ssl_conn),
ngx_ssl_session_cache_index);
@@ -1765,7 +1765,7 @@ ngx_ssl_remove_session(SSL_CTX *ssl, ngx_ssl_session_t *sess)
hash = ngx_crc32_short(id, len);
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0,
- "http ssl remove session: %08XD:%uz", hash, len);
+ "ssl remove session: %08XD:%uz", hash, len);
shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
@@ -1929,6 +1929,40 @@ ngx_ssl_get_cipher_name(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
ngx_int_t
+ngx_ssl_get_session_id(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
+{
+ int len;
+ u_char *p, *buf;
+ SSL_SESSION *sess;
+
+ sess = SSL_get0_session(c->ssl->connection);
+
+ len = i2d_SSL_SESSION(sess, NULL);
+
+ buf = ngx_alloc(len, c->log);
+ if (buf == NULL) {
+ return NGX_ERROR;
+ }
+
+ s->len = 2 * len;
+ s->data = ngx_pnalloc(pool, 2 * len);
+ if (s->data == NULL) {
+ ngx_free(buf);
+ return NGX_ERROR;
+ }
+
+ p = buf;
+ i2d_SSL_SESSION(sess, &p);
+
+ ngx_hex_dump(s->data, buf, len);
+
+ ngx_free(buf);
+
+ return NGX_OK;
+}
+
+
+ngx_int_t
ngx_ssl_get_raw_certificate(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
{
size_t len;
diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h
index 2b9dd284e..deeb57f64 100644
--- a/src/event/ngx_event_openssl.h
+++ b/src/event/ngx_event_openssl.h
@@ -118,6 +118,8 @@ ngx_int_t ngx_ssl_get_protocol(ngx_connection_t *c, ngx_pool_t *pool,
ngx_str_t *s);
ngx_int_t ngx_ssl_get_cipher_name(ngx_connection_t *c, ngx_pool_t *pool,
ngx_str_t *s);
+ngx_int_t ngx_ssl_get_session_id(ngx_connection_t *c, ngx_pool_t *pool,
+ ngx_str_t *s);
ngx_int_t ngx_ssl_get_raw_certificate(ngx_connection_t *c, ngx_pool_t *pool,
ngx_str_t *s);
ngx_int_t ngx_ssl_get_certificate(ngx_connection_t *c, ngx_pool_t *pool,
diff --git a/src/http/modules/ngx_http_dav_module.c b/src/http/modules/ngx_http_dav_module.c
index 38e928c3d..1502fbf25 100644
--- a/src/http/modules/ngx_http_dav_module.c
+++ b/src/http/modules/ngx_http_dav_module.c
@@ -516,8 +516,8 @@ ngx_http_dav_copy_move_handler(ngx_http_request_t *r)
size_t len, root;
ngx_err_t err;
ngx_int_t rc, depth;
- ngx_uint_t overwrite, slash, dir;
- ngx_str_t path, uri;
+ ngx_uint_t overwrite, slash, dir, flags;
+ ngx_str_t path, uri, duri, args;
ngx_tree_ctx_t tree;
ngx_copy_file_t cf;
ngx_file_info_t fi;
@@ -594,6 +594,14 @@ invalid_destination:
destination_done:
+ duri.len = last - p;
+ duri.data = p;
+ flags = 0;
+
+ if (ngx_http_parse_unsafe_uri(r, &duri, &args, &flags) != NGX_OK) {
+ goto invalid_destination;
+ }
+
if ((r->uri.data[r->uri.len - 1] == '/' && *(last - 1) != '/')
|| (r->uri.data[r->uri.len - 1] != '/' && *(last - 1) == '/'))
{
@@ -656,9 +664,7 @@ overwrite_done:
"http copy from: \"%s\"", path.data);
uri = r->uri;
-
- r->uri.len = last - p;
- r->uri.data = p;
+ r->uri = duri;
ngx_http_map_uri_to_path(r, &copy.path, &root, 0);
diff --git a/src/http/modules/ngx_http_index_module.c b/src/http/modules/ngx_http_index_module.c
index d94fc118c..b58aa97c2 100644
--- a/src/http/modules/ngx_http_index_module.c
+++ b/src/http/modules/ngx_http_index_module.c
@@ -222,7 +222,10 @@ ngx_http_index_handler(ngx_http_request_t *r)
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
- if (of.err == NGX_ENOTDIR || of.err == NGX_EACCES) {
+ if (of.err == NGX_ENOTDIR
+ || of.err == NGX_ENAMETOOLONG
+ || of.err == NGX_EACCES)
+ {
return ngx_http_index_error(r, clcf, path.data, of.err);
}
diff --git a/src/http/modules/ngx_http_ssi_filter_module.c b/src/http/modules/ngx_http_ssi_filter_module.c
index 24b30a8fa..d03e58407 100644
--- a/src/http/modules/ngx_http_ssi_filter_module.c
+++ b/src/http/modules/ngx_http_ssi_filter_module.c
@@ -1908,7 +1908,7 @@ ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
args.len = 0;
args.data = NULL;
- flags = 0;
+ flags = NGX_HTTP_LOG_UNSAFE;
if (ngx_http_parse_unsafe_uri(r, uri, &args, &flags) != NGX_OK) {
return NGX_HTTP_SSI_ERROR;
diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c
index 7729b760e..cc0b932d2 100644
--- a/src/http/modules/ngx_http_ssl_module.c
+++ b/src/http/modules/ngx_http_ssl_module.c
@@ -184,6 +184,9 @@ static ngx_http_variable_t ngx_http_ssl_vars[] = {
{ ngx_string("ssl_cipher"), NULL, ngx_http_ssl_static_variable,
(uintptr_t) ngx_ssl_get_cipher_name, NGX_HTTP_VAR_CHANGEABLE, 0 },
+ { ngx_string("ssl_session_id"), NULL, ngx_http_ssl_variable,
+ (uintptr_t) ngx_ssl_get_session_id, NGX_HTTP_VAR_CHANGEABLE, 0 },
+
{ ngx_string("ssl_client_cert"), NULL, ngx_http_ssl_variable,
(uintptr_t) ngx_ssl_get_certificate, NGX_HTTP_VAR_CHANGEABLE, 0 },
diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm
index 7044a5f11..78e99c563 100644
--- a/src/http/modules/perl/nginx.pm
+++ b/src/http/modules/perl/nginx.pm
@@ -47,7 +47,7 @@ our @EXPORT = qw(
HTTP_INSUFFICIENT_STORAGE
);
-our $VERSION = '0.8.16';
+our $VERSION = '0.8.17';
require XSLoader;
XSLoader::load('nginx', $VERSION);
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index 9af59b160..19d088160 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -994,7 +994,6 @@ ngx_http_core_post_rewrite_phase(ngx_http_request_t *r,
"rewrite or internal redirection cycle "
"while processing \"%V\"", &r->uri);
- r->main->count++;
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
return NGX_OK;
}
@@ -1233,7 +1232,10 @@ ngx_http_core_try_files_phase(ngx_http_request_t *r,
if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
!= NGX_OK)
{
- if (of.err != NGX_ENOENT && of.err != NGX_ENOTDIR) {
+ if (of.err != NGX_ENOENT
+ && of.err != NGX_ENOTDIR
+ && of.err != NGX_ENAMETOOLONG)
+ {
ngx_log_error(NGX_LOG_CRIT, r->connection->log, of.err,
"%s \"%s\" failed", of.failed, path.data);
}
diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c
index d2abaa708..b638f86fc 100644
--- a/src/http/ngx_http_parse.c
+++ b/src/http/ngx_http_parse.c
@@ -1322,8 +1322,10 @@ ngx_http_parse_unsafe_uri(ngx_http_request_t *r, ngx_str_t *uri,
unsafe:
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "unsafe URI \"%V\" was detected", uri);
+ if (*flags & NGX_HTTP_LOG_UNSAFE) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "unsafe URI \"%V\" was detected", uri);
+ }
return NGX_ERROR;
}
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index 07afe676d..48b57206b 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);
@@ -627,6 +628,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;
@@ -651,7 +653,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;
}
@@ -670,6 +680,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;
@@ -801,18 +812,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) {
@@ -1312,27 +1330,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;
}
@@ -1588,21 +1613,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;
@@ -1617,7 +1644,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;
}
}
@@ -1625,6 +1656,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;
}
@@ -1632,29 +1672,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;
@@ -1670,7 +1696,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;
@@ -1686,16 +1712,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);
@@ -1717,7 +1733,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;
}
diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h
index 3bd70c33c..8f348154c 100644
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -60,6 +60,7 @@
#define NGX_HTTP_ZERO_IN_URI 1
#define NGX_HTTP_SUBREQUEST_IN_MEMORY 2
#define NGX_HTTP_SUBREQUEST_WAITED 4
+#define NGX_HTTP_LOG_UNSAFE 8
#define NGX_HTTP_OK 200
diff --git a/src/http/ngx_http_request_body.c b/src/http/ngx_http_request_body.c
index d29314747..bc2a14e0d 100644
--- a/src/http/ngx_http_request_body.c
+++ b/src/http/ngx_http_request_body.c
@@ -477,8 +477,9 @@ ngx_http_discard_request_body(ngx_http_request_t *r)
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
- r->count++;
- (void) ngx_http_read_discarded_request_body(r);
+ if (ngx_http_read_discarded_request_body(r) != NGX_OK) {
+ r->count++;
+ }
return NGX_OK;
}
@@ -562,12 +563,16 @@ ngx_http_read_discarded_request_body(ngx_http_request_t *r)
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http read discarded body");
- do {
+ for ( ;; ) {
if (r->headers_in.content_length_n == 0) {
r->read_event_handler = ngx_http_block_reading;
return NGX_OK;
}
+ if (!r->connection->read->ready) {
+ return NGX_AGAIN;
+ }
+
size = (r->headers_in.content_length_n > NGX_HTTP_DISCARD_BUFFER_SIZE) ?
NGX_HTTP_DISCARD_BUFFER_SIZE:
(size_t) r->headers_in.content_length_n;
@@ -588,10 +593,7 @@ ngx_http_read_discarded_request_body(ngx_http_request_t *r)
}
r->headers_in.content_length_n -= n;
-
- } while (r->connection->read->ready);
-
- return NGX_AGAIN;
+ }
}
diff --git a/src/http/ngx_http_script.c b/src/http/ngx_http_script.c
index ad9d88b40..a92b1995a 100644
--- a/src/http/ngx_http_script.c
+++ b/src/http/ngx_http_script.c
@@ -1417,7 +1417,10 @@ ngx_http_script_file_code(ngx_http_script_engine_t *e)
if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
!= NGX_OK)
{
- if (of.err != NGX_ENOENT && of.err != NGX_ENOTDIR) {
+ if (of.err != NGX_ENOENT
+ && of.err != NGX_ENOTDIR
+ && of.err != NGX_ENAMETOOLONG)
+ {
ngx_log_error(NGX_LOG_CRIT, r->connection->log, of.err,
"%s \"%s\" failed", of.failed, value->data);
}
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index 380b3c2f0..1e79a4f10 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -532,7 +532,8 @@ ngx_http_upstream_init_request(ngx_http_request_t *r)
if (ngx_http_upstream_create_round_robin_peer(r, u->resolved)
!= NGX_OK)
{
- ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+ ngx_http_upstream_finalize_request(r, u,
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
return;
}
@@ -564,7 +565,8 @@ ngx_http_upstream_init_request(ngx_http_request_t *r)
ctx = ngx_resolve_start(clcf->resolver, &temp);
if (ctx == NULL) {
- ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+ ngx_http_upstream_finalize_request(r, u,
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
return;
}
@@ -572,7 +574,7 @@ ngx_http_upstream_init_request(ngx_http_request_t *r)
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"no resolver defined to resolve %V", host);
- ngx_http_finalize_request(r, NGX_HTTP_BAD_GATEWAY);
+ ngx_http_upstream_finalize_request(r, u, NGX_HTTP_BAD_GATEWAY);
return;
}
@@ -586,7 +588,8 @@ ngx_http_upstream_init_request(ngx_http_request_t *r)
if (ngx_resolve_name(ctx) != NGX_OK) {
u->resolved->ctx = NULL;
- ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+ ngx_http_upstream_finalize_request(r, u,
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
return;
}
@@ -596,7 +599,8 @@ ngx_http_upstream_init_request(ngx_http_request_t *r)
found:
if (uscf->peer.init(r, uscf) != NGX_OK) {
- ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+ ngx_http_upstream_finalize_request(r, u,
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
return;
}
@@ -789,11 +793,13 @@ static void
ngx_http_upstream_resolve_handler(ngx_resolver_ctx_t *ctx)
{
ngx_http_request_t *r;
+ ngx_http_upstream_t *u;
ngx_http_upstream_resolved_t *ur;
r = ctx->data;
- r->upstream->resolved->ctx = NULL;
+ u = r->upstream;
+ ur = u->resolved;
if (ctx->state) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
@@ -801,12 +807,10 @@ ngx_http_upstream_resolve_handler(ngx_resolver_ctx_t *ctx)
&ctx->name, ctx->state,
ngx_resolver_strerror(ctx->state));
- ngx_resolve_name_done(ctx);
- ngx_http_finalize_request(r, NGX_HTTP_BAD_GATEWAY);
+ ngx_http_upstream_finalize_request(r, u, NGX_HTTP_BAD_GATEWAY);
return;
}
- ur = r->upstream->resolved;
ur->naddrs = ctx->naddrs;
ur->addrs = ctx->addrs;
@@ -827,14 +831,15 @@ ngx_http_upstream_resolve_handler(ngx_resolver_ctx_t *ctx)
#endif
if (ngx_http_upstream_create_round_robin_peer(r, ur) != NGX_OK) {
- ngx_resolve_name_done(ctx);
- ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+ ngx_http_upstream_finalize_request(r, u,
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
return;
}
ngx_resolve_name_done(ctx);
+ ur->ctx = NULL;
- ngx_http_upstream_connect(r, r->upstream);
+ ngx_http_upstream_connect(r, u);
}
@@ -921,10 +926,6 @@ ngx_http_upstream_check_broken_connection(ngx_http_request_t *r,
return;
}
- if (u->peer.connection == NULL) {
- return;
- }
-
#if (NGX_HAVE_KQUEUE)
if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
@@ -956,7 +957,6 @@ ngx_http_upstream_check_broken_connection(ngx_http_request_t *r,
if (u->peer.connection == NULL) {
ngx_http_upstream_finalize_request(r, u,
NGX_HTTP_CLIENT_CLOSED_REQUEST);
- return;
}
return;
@@ -1019,7 +1019,6 @@ ngx_http_upstream_check_broken_connection(ngx_http_request_t *r,
if (u->peer.connection == NULL) {
ngx_http_upstream_finalize_request(r, u,
NGX_HTTP_CLIENT_CLOSED_REQUEST);
- return;
}
}
@@ -1797,7 +1796,7 @@ ngx_http_upstream_process_headers(ngx_http_request_t *r, ngx_http_upstream_t *u)
uri = &u->headers_in.x_accel_redirect->value;
args.len = 0;
args.data = NULL;
- flags = 0;
+ flags = NGX_HTTP_LOG_UNSAFE;
if (ngx_http_parse_unsafe_uri(r, uri, &args, &flags) != NGX_OK) {
ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND);
@@ -2837,6 +2836,7 @@ ngx_http_upstream_cleanup(void *data)
if (u->resolved && u->resolved->ctx) {
ngx_resolve_name_done(u->resolved->ctx);
+ u->resolved->ctx = NULL;
}
ngx_http_upstream_finalize_request(r, u, NGX_DONE);
@@ -2856,6 +2856,11 @@ ngx_http_upstream_finalize_request(ngx_http_request_t *r,
*u->cleanup = NULL;
}
+ if (u->resolved && u->resolved->ctx) {
+ ngx_resolve_name_done(u->resolved->ctx);
+ u->resolved->ctx = NULL;
+ }
+
if (u->state && u->state->response_sec) {
tp = ngx_timeofday();
u->state->response_sec = tp->sec - u->state->response_sec;
diff --git a/src/os/unix/ngx_atomic.h b/src/os/unix/ngx_atomic.h
index e19fddaca..35761b430 100644
--- a/src/os/unix/ngx_atomic.h
+++ b/src/os/unix/ngx_atomic.h
@@ -31,7 +31,7 @@
typedef int64_t ngx_atomic_int_t;
typedef uint64_t ngx_atomic_uint_t;
-#define NGX_ATOMIC_T_LEN sizeof("-9223372036854775808") - 1
+#define NGX_ATOMIC_T_LEN (sizeof("-9223372036854775808") - 1)
#define ngx_atomic_cmp_set(lock, old, new) \
OSAtomicCompareAndSwap64Barrier(old, new, (int64_t *) lock)
@@ -43,7 +43,7 @@ typedef uint64_t ngx_atomic_uint_t;
typedef int32_t ngx_atomic_int_t;
typedef uint32_t ngx_atomic_uint_t;
-#define NGX_ATOMIC_T_LEN sizeof("-2147483648") - 1
+#define NGX_ATOMIC_T_LEN (sizeof("-2147483648") - 1)
#define ngx_atomic_cmp_set(lock, old, new) \
OSAtomicCompareAndSwap32Barrier(old, new, (int32_t *) lock)
@@ -68,7 +68,7 @@ typedef volatile ngx_atomic_uint_t ngx_atomic_t;
typedef int32_t ngx_atomic_int_t;
typedef uint32_t ngx_atomic_uint_t;
typedef volatile ngx_atomic_uint_t ngx_atomic_t;
-#define NGX_ATOMIC_T_LEN sizeof("-2147483648") - 1
+#define NGX_ATOMIC_T_LEN (sizeof("-2147483648") - 1)
#if ( __SUNPRO_C )
@@ -109,7 +109,7 @@ ngx_cpu_pause(void);
typedef int64_t ngx_atomic_int_t;
typedef uint64_t ngx_atomic_uint_t;
typedef volatile ngx_atomic_uint_t ngx_atomic_t;
-#define NGX_ATOMIC_T_LEN sizeof("-9223372036854775808") - 1
+#define NGX_ATOMIC_T_LEN (sizeof("-9223372036854775808") - 1)
#if ( __SUNPRO_C )
@@ -151,13 +151,13 @@ ngx_cpu_pause(void);
typedef int64_t ngx_atomic_int_t;
typedef uint64_t ngx_atomic_uint_t;
-#define NGX_ATOMIC_T_LEN sizeof("-9223372036854775808") - 1
+#define NGX_ATOMIC_T_LEN (sizeof("-9223372036854775808") - 1)
#else
typedef int32_t ngx_atomic_int_t;
typedef uint32_t ngx_atomic_uint_t;
-#define NGX_ATOMIC_T_LEN sizeof("-2147483648") - 1
+#define NGX_ATOMIC_T_LEN (sizeof("-2147483648") - 1)
#endif
@@ -188,13 +188,13 @@ typedef volatile ngx_atomic_uint_t ngx_atomic_t;
typedef int64_t ngx_atomic_int_t;
typedef uint64_t ngx_atomic_uint_t;
-#define NGX_ATOMIC_T_LEN sizeof("-9223372036854775808") - 1
+#define NGX_ATOMIC_T_LEN (sizeof("-9223372036854775808") - 1)
#else
typedef int32_t ngx_atomic_int_t;
typedef uint32_t ngx_atomic_uint_t;
-#define NGX_ATOMIC_T_LEN sizeof("-2147483648") - 1
+#define NGX_ATOMIC_T_LEN (sizeof("-2147483648") - 1)
#endif
@@ -216,7 +216,7 @@ typedef volatile ngx_atomic_uint_t ngx_atomic_t;
typedef int32_t ngx_atomic_int_t;
typedef uint32_t ngx_atomic_uint_t;
typedef volatile ngx_atomic_uint_t ngx_atomic_t;
-#define NGX_ATOMIC_T_LEN sizeof("-2147483648") - 1
+#define NGX_ATOMIC_T_LEN (sizeof("-2147483648") - 1)
static ngx_inline ngx_atomic_uint_t
diff --git a/src/os/unix/ngx_files.c b/src/os/unix/ngx_files.c
index 98ed08229..2154bed49 100644
--- a/src/os/unix/ngx_files.c
+++ b/src/os/unix/ngx_files.c
@@ -22,7 +22,7 @@ ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset)
if (n == -1) {
ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
- "pread() failed, file \"%s\"", file->name.data);
+ "pread() \"%s\" failed", file->name.data);
return NGX_ERROR;
}
@@ -30,7 +30,8 @@ ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset)
if (file->sys_offset != offset) {
if (lseek(file->fd, offset, SEEK_SET) == -1) {
- ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "lseek() failed");
+ ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
+ "lseek() \"%s\" failed", file->name.data);
return NGX_ERROR;
}
@@ -40,7 +41,8 @@ ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset)
n = read(file->fd, buf, size);
if (n == -1) {
- ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "read() failed");
+ ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
+ "read() \"%s\" failed", file->name.data);
return NGX_ERROR;
}
@@ -57,57 +59,66 @@ ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset)
ssize_t
ngx_write_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset)
{
- ssize_t n;
+ ssize_t n, written;
ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0,
"write: %d, %p, %uz, %O", file->fd, buf, size, offset);
+ written = 0;
+
#if (NGX_HAVE_PWRITE)
- n = pwrite(file->fd, buf, size, offset);
+ for ( ;; ) {
+ n = pwrite(file->fd, buf, size, offset);
- if (n == -1) {
- ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "pwrite() failed");
- return NGX_ERROR;
- }
+ if (n == -1) {
+ ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
+ "pwrite() \"%s\" failed", file->name.data);
+ return NGX_ERROR;
+ }
- if ((size_t) n != size) {
- ngx_log_error(NGX_LOG_CRIT, file->log, 0,
- "pwrite() has written only %z of %uz", n, size);
- return NGX_ERROR;
+ file->offset += n;
+ written += n;
+
+ if ((size_t) n == size) {
+ return written;
+ }
+
+ offset += n;
+ size -= n;
}
#else
if (file->sys_offset != offset) {
if (lseek(file->fd, offset, SEEK_SET) == -1) {
- ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "lseek() failed");
+ ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
+ "lseek() \"%s\" failed", file->name.data);
return NGX_ERROR;
}
file->sys_offset = offset;
}
- n = write(file->fd, buf, size);
+ for ( ;; ) {
+ n = write(file->fd, buf, size);
- if (n == -1) {
- ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "write() failed");
- return NGX_ERROR;
- }
+ if (n == -1) {
+ ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
+ "write() \"%s\" failed", file->name.data);
+ return NGX_ERROR;
+ }
- if ((size_t) n != size) {
- ngx_log_error(NGX_LOG_CRIT, file->log, 0,
- "write() has written only %z of %uz", n, size);
- return NGX_ERROR;
- }
+ file->offset += n;
+ written += n;
- file->sys_offset += n;
+ if ((size_t) n == size) {
+ return written;
+ }
+ size -= n;
+ }
#endif
-
- file->offset += n;
-
- return n;
}
@@ -191,7 +202,7 @@ ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl, off_t offset,
if (file->sys_offset != offset) {
if (lseek(file->fd, offset, SEEK_SET) == -1) {
ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
- "lseek() failed");
+ "lseek() \"%s\" failed", file->name.data);
return NGX_ERROR;
}
@@ -202,13 +213,14 @@ ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl, off_t offset,
if (n == -1) {
ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
- "writev() failed");
+ "writev() \"%s\" failed", file->name.data);
return NGX_ERROR;
}
if ((size_t) n != size) {
ngx_log_error(NGX_LOG_CRIT, file->log, 0,
- "writev() has written only %z of %uz", n, size);
+ "writev() \"%s\" has written only %z of %uz",
+ file->name.data, n, size);
return NGX_ERROR;
}
@@ -394,7 +406,7 @@ ngx_directio_on(ngx_fd_t fd)
flags = fcntl(fd, F_GETFL);
if (flags == -1) {
- return -1;
+ return NGX_FILE_ERROR;
}
return fcntl(fd, F_SETFL, flags | O_DIRECT);
@@ -409,7 +421,7 @@ ngx_directio_off(ngx_fd_t fd)
flags = fcntl(fd, F_GETFL);
if (flags == -1) {
- return -1;
+ return NGX_FILE_ERROR;
}
return fcntl(fd, F_SETFL, flags & ~O_DIRECT);