summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES30
-rw-r--r--CHANGES.ru32
-rw-r--r--src/core/nginx.h4
-rw-r--r--src/core/ngx_cycle.c7
-rw-r--r--src/core/ngx_output_chain.c4
-rw-r--r--src/core/ngx_resolver.c16
-rw-r--r--src/http/modules/ngx_http_addition_filter_module.c2
-rw-r--r--src/http/modules/ngx_http_gzip_static_module.c11
-rw-r--r--src/http/modules/ngx_http_image_filter_module.c65
-rw-r--r--src/http/modules/ngx_http_ssl_module.c7
-rw-r--r--src/http/modules/perl/nginx.pm2
-rw-r--r--src/http/modules/perl/ngx_http_perl_module.c5
-rw-r--r--src/http/ngx_http_file_cache.c8
-rw-r--r--src/http/ngx_http_request.c2
-rw-r--r--src/http/ngx_http_variables.c41
15 files changed, 197 insertions, 39 deletions
diff --git a/CHANGES b/CHANGES
index 59d96eb84..dc55a3957 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,34 @@
+Changes with nginx 0.8.16 22 Sep 2009
+
+ *) Feature: the "image_filter_transparency" directive.
+
+ *) Bugfix: "addition_types" directive was incorrectly named
+ "addtion_types".
+
+ *) Bugfix: resolver cache poisoning.
+ Thanks to Matthew Dempsky.
+
+ *) Bugfix: memory leak in resolver.
+ Thanks to Matthew Dempsky.
+
+ *) Bugfix: invalid request line in $request variable was written in
+ access_log only if error_log was set to "info" or "debug" level.
+
+ *) Bugfix: in PNG alpha-channel support in the
+ ngx_http_image_filter_module.
+
+ *) Bugfix: nginx always added "Vary: Accept-Encoding" response header
+ line, if both "gzip_static" and "gzip_vary" were on.
+
+ *) Bugfix: in UTF-8 encoding support by "try_files" directive in
+ nginx/Windows.
+
+ *) Bugfix: in "post_action" directive usage; the bug had appeared in
+ 0.8.11.
+ Thanks to Igor Artemiev.
+
+
Changes with nginx 0.8.15 14 Sep 2009
*) Security: a segmentation fault might occur in worker process while
diff --git a/CHANGES.ru b/CHANGES.ru
index 53f238749..166777a06 100644
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,36 @@
+Изменения в nginx 0.8.16 22.09.2009
+
+ *) Добавление: директива image_filter_transparency.
+
+ *) Исправление: директива "addition_types" была неверно названа
+ "addtion_types".
+
+ *) Исправление: порчи кэша resolver'а.
+ Спасибо Matthew Dempsky.
+
+ *) Исправление: утечки памяти в resolver'е.
+ Спасибо Matthew Dempsky.
+
+ *) Исправление: неверная строка запроса в переменной $request
+ записывалась в access_log только при использовании error_log на
+ уровне info или debug.
+
+ *) Исправление: в поддержке альфа-канала PNG в модуле
+ ngx_http_image_filter_module.
+
+ *) Исправление: nginx всегда добавлял строку "Vary: Accept-Encoding" в
+ заголовок ответа, если обе директивы gzip_static и gzip_vary были
+ включены.
+
+ *) Исправление: в поддержке кодировки UTF-8 директивой try_files в
+ nginx/Windows.
+
+ *) Исправление: ошибки при использовании post_action; ошибка появилась
+ в 0.8.11.
+ Спасибо Игорю Артемьеву.
+
+
Изменения в nginx 0.8.15 14.09.2009
*) Безопасность: при обработке специально созданного запроса в рабочем
diff --git a/src/core/nginx.h b/src/core/nginx.h
index bfd8f63b9..2aefb7b92 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,8 +8,8 @@
#define _NGINX_H_INCLUDED_
-#define nginx_version 8015
-#define NGINX_VERSION "0.8.15"
+#define nginx_version 8016
+#define NGINX_VERSION "0.8.16"
#define NGINX_VER "nginx/" NGINX_VERSION
#define NGINX_VAR "NGINX"
diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c
index fbfc9c676..cd9efbee7 100644
--- a/src/core/ngx_cycle.c
+++ b/src/core/ngx_cycle.c
@@ -255,11 +255,13 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
#endif
if (ngx_conf_param(&conf) != NGX_CONF_OK) {
+ environ = senv;
ngx_destroy_cycle_pools(&conf);
return NULL;
}
if (ngx_conf_parse(&conf, &cycle->conf_file) != NGX_CONF_OK) {
+ environ = senv;
ngx_destroy_cycle_pools(&conf);
return NULL;
}
@@ -280,6 +282,7 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
if (module->init_conf(cycle, cycle->conf_ctx[ngx_modules[i]->index])
== NGX_CONF_ERROR)
{
+ environ = senv;
ngx_destroy_cycle_pools(&conf);
return NULL;
}
@@ -698,8 +701,8 @@ old_shm_zone_done:
if (ngx_process == NGX_PROCESS_MASTER || ngx_is_init_cycle(old_cycle)) {
/*
- * perl_destruct() frees environ if it is not the same as it was at
- * perl_construct() time. So we have saved an previous cycle
+ * perl_destruct() frees environ, if it is not the same as it was at
+ * perl_construct() time, therefore we save the previous cycle
* environment before ngx_conf_parse() where it will be changed.
*/
diff --git a/src/core/ngx_output_chain.c b/src/core/ngx_output_chain.c
index 01f42a191..590da4f45 100644
--- a/src/core/ngx_output_chain.c
+++ b/src/core/ngx_output_chain.c
@@ -571,9 +571,7 @@ ngx_output_chain_copy_buf(ngx_output_chain_ctx_t *ctx)
ngx_log_error(NGX_LOG_ALERT, ctx->pool->log, 0,
ngx_read_file_n " read only %z of %O from \"%s\"",
n, size, src->file->name.data);
- if (n == 0) {
- return NGX_ERROR;
- }
+ return NGX_ERROR;
}
dst->last += n;
diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c
index 2b53ee07e..d0ba8bc4e 100644
--- a/src/core/ngx_resolver.c
+++ b/src/core/ngx_resolver.c
@@ -1149,6 +1149,8 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
goto failed;
}
+ ngx_resolver_free(r, name.data);
+
if (code == 0 && nan == 0) {
code = 3; /* NXDOMAIN */
}
@@ -1400,6 +1402,8 @@ failed:
/* unlock name mutex */
+ ngx_resolver_free(r, name.data);
+
return;
}
@@ -1595,7 +1599,6 @@ static ngx_resolver_node_t *
ngx_resolver_lookup_name(ngx_resolver_t *r, ngx_str_t *name, uint32_t hash)
{
ngx_int_t rc;
- size_t len;
ngx_rbtree_node_t *node, *sentinel;
ngx_resolver_node_t *rn;
@@ -1619,9 +1622,7 @@ ngx_resolver_lookup_name(ngx_resolver_t *r, ngx_str_t *name, uint32_t hash)
do {
rn = (ngx_resolver_node_t *) node;
- len = (name->len > (size_t) rn->nlen) ? rn->nlen : name->len;
-
- rc = ngx_strncmp(name->data, rn->name, len);
+ rc = ngx_memn2cmp(name->data, rn->name, name->len, rn->nlen);
if (rc == 0) {
return rn;
@@ -1675,7 +1676,6 @@ static void
ngx_resolver_rbtree_insert_value(ngx_rbtree_node_t *temp,
ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel)
{
- size_t len;
ngx_rbtree_node_t **p;
ngx_resolver_node_t *rn, *rn_temp;
@@ -1694,10 +1694,8 @@ ngx_resolver_rbtree_insert_value(ngx_rbtree_node_t *temp,
rn = (ngx_resolver_node_t *) node;
rn_temp = (ngx_resolver_node_t *) temp;
- len = (rn->nlen > rn_temp->nlen) ? rn_temp->nlen : rn->nlen;
-
- p = (ngx_strncmp(rn->name, rn_temp->name, len) < 0)
- ? &temp->left : &temp->right;
+ p = (ngx_memn2cmp(rn->name, rn_temp->name, rn->nlen, rn_temp->nlen)
+ < 0) ? &temp->left : &temp->right;
}
if (*p == sentinel) {
diff --git a/src/http/modules/ngx_http_addition_filter_module.c b/src/http/modules/ngx_http_addition_filter_module.c
index 4076c5374..c78361c66 100644
--- a/src/http/modules/ngx_http_addition_filter_module.c
+++ b/src/http/modules/ngx_http_addition_filter_module.c
@@ -45,7 +45,7 @@ static ngx_command_t ngx_http_addition_commands[] = {
offsetof(ngx_http_addition_conf_t, after_body),
NULL },
- { ngx_string("addtion_types"),
+ { ngx_string("addition_types"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
ngx_http_types_slot,
NGX_HTTP_LOC_CONF_OFFSET,
diff --git a/src/http/modules/ngx_http_gzip_static_module.c b/src/http/modules/ngx_http_gzip_static_module.c
index 19e412841..8080d9cb0 100644
--- a/src/http/modules/ngx_http_gzip_static_module.c
+++ b/src/http/modules/ngx_http_gzip_static_module.c
@@ -95,7 +95,13 @@ ngx_http_gzip_static_handler(ngx_http_request_t *r)
gzcf = ngx_http_get_module_loc_conf(r, ngx_http_gzip_static_module);
- if (!gzcf->enable || ngx_http_gzip_ok(r) != NGX_OK) {
+ if (!gzcf->enable) {
+ return NGX_DECLINED;
+ }
+
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+ if (clcf->gzip_vary && ngx_http_gzip_ok(r) != NGX_OK) {
return NGX_DECLINED;
}
@@ -116,8 +122,6 @@ ngx_http_gzip_static_handler(ngx_http_request_t *r)
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
"http filename: \"%s\"", path.data);
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
ngx_memzero(&of, sizeof(ngx_open_file_info_t));
of.directio = clcf->directio;
@@ -138,6 +142,7 @@ ngx_http_gzip_static_handler(ngx_http_request_t *r)
case NGX_ENOTDIR:
case NGX_ENAMETOOLONG:
+ r->gzip = 0;
return NGX_DECLINED;
case NGX_EACCES:
diff --git a/src/http/modules/ngx_http_image_filter_module.c b/src/http/modules/ngx_http_image_filter_module.c
index 653cc791b..9a4dafe05 100644
--- a/src/http/modules/ngx_http_image_filter_module.c
+++ b/src/http/modules/ngx_http_image_filter_module.c
@@ -40,6 +40,8 @@ typedef struct {
ngx_uint_t height;
ngx_int_t jpeg_quality;
+ ngx_flag_t transparency;
+
ngx_http_complex_value_t *wcv;
ngx_http_complex_value_t *hcv;
@@ -115,6 +117,13 @@ static ngx_command_t ngx_http_image_filter_commands[] = {
offsetof(ngx_http_image_filter_conf_t, jpeg_quality),
NULL },
+ { ngx_string("image_filter_transparency"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+ ngx_conf_set_flag_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_image_filter_conf_t, transparency),
+ NULL },
+
{ ngx_string("image_filter_buffer"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_size_slot,
@@ -678,8 +687,9 @@ ngx_http_image_size(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
static ngx_buf_t *
ngx_http_image_resize(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
{
- int sx, sy, dx, dy, ox, oy,
- colors, transparent, red, green, blue, size;
+ int sx, sy, dx, dy, ox, oy, size,
+ colors, palette, transparent,
+ red, green, blue;
u_char *out;
ngx_buf_t *b;
ngx_uint_t resize;
@@ -706,18 +716,30 @@ ngx_http_image_resize(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
}
colors = gdImageColorsTotal(src);
- transparent = gdImageGetTransparent(src);
- if (transparent != -1 && colors) {
- red = gdImageRed(src, transparent);
- green = gdImageGreen(src, transparent);
- blue = gdImageBlue(src, transparent);
- gdImageColorTransparent(src, -1);
+ if (colors && conf->transparency) {
+ transparent = gdImageGetTransparent(src);
- } else {
- red = 0; green = 0; blue = 0;
+ if (transparent != -1) {
+ palette = colors;
+ red = gdImageRed(src, transparent);
+ green = gdImageGreen(src, transparent);
+ blue = gdImageBlue(src, transparent);
+
+ goto transparent;
+ }
}
+ palette = 0;
+ transparent = -1;
+ red = 0;
+ green = 0;
+ blue = 0;
+
+transparent:
+
+ gdImageColorTransparent(src, -1);
+
dx = sx;
dy = sy;
@@ -762,14 +784,23 @@ ngx_http_image_resize(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
}
if (resize) {
- dst = ngx_http_image_new(r, dx, dy, colors);
+ dst = ngx_http_image_new(r, dx, dy, palette);
if (dst == NULL) {
gdImageDestroy(src);
return NULL;
}
+ if (colors == 0) {
+ gdImageSaveAlpha(dst, 1);
+ gdImageAlphaBlending(dst, 0);
+ }
+
gdImageCopyResampled(dst, src, 0, 0, 0, 0, dx, dy, sx, sy);
+ if (colors) {
+ gdImageTrueColorToPalette(dst, 1, 256);
+ }
+
gdImageDestroy(src);
} else {
@@ -810,8 +841,17 @@ ngx_http_image_resize(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
"image crop: %d x %d @ %d x %d",
dx, dy, ox, oy);
+ if (colors == 0) {
+ gdImageSaveAlpha(dst, 1);
+ gdImageAlphaBlending(dst, 0);
+ }
+
gdImageCopy(dst, src, 0, 0, ox, oy, dx - ox, dy - oy);
+ if (colors) {
+ gdImageTrueColorToPalette(dst, 1, 256);
+ }
+
gdImageDestroy(src);
}
}
@@ -1021,6 +1061,7 @@ ngx_http_image_filter_create_conf(ngx_conf_t *cf)
conf->filter = NGX_CONF_UNSET_UINT;
conf->jpeg_quality = NGX_CONF_UNSET;
+ conf->transparency = NGX_CONF_UNSET;
conf->buffer_size = NGX_CONF_UNSET_SIZE;
return conf;
@@ -1050,6 +1091,8 @@ ngx_http_image_filter_merge_conf(ngx_conf_t *cf, void *parent, void *child)
/* 75 is libjpeg default quality */
ngx_conf_merge_value(conf->jpeg_quality, prev->jpeg_quality, 75);
+ ngx_conf_merge_value(conf->transparency, prev->transparency, 1);
+
ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size,
1 * 1024 * 1024);
diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c
index 42854b479..7729b760e 100644
--- a/src/http/modules/ngx_http_ssl_module.c
+++ b/src/http/modules/ngx_http_ssl_module.c
@@ -406,9 +406,10 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_http_ssl_servername)
== 0)
{
- ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0,
- "SSL_CTX_set_tlsext_servername_callback() failed");
- return NGX_CONF_ERROR;
+ ngx_log_error(NGX_LOG_WARN, cf->log, 0,
+ "nginx was build with SNI support, however, now it is linked "
+ "dynamically to an OpenSSL library which has no tlsext support, "
+ "therefore SNI is not available");
}
#endif
diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm
index f6378445c..7044a5f11 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.15';
+our $VERSION = '0.8.16';
require XSLoader;
XSLoader::load('nginx', $VERSION);
diff --git a/src/http/modules/perl/ngx_http_perl_module.c b/src/http/modules/perl/ngx_http_perl_module.c
index 634801ece..41372ce2d 100644
--- a/src/http/modules/perl/ngx_http_perl_module.c
+++ b/src/http/modules/perl/ngx_http_perl_module.c
@@ -761,7 +761,10 @@ ngx_http_perl_eval_anon_sub(pTHX_ ngx_str_t *handler, SV **sv)
}
}
- if (ngx_strncmp(p, "sub ", 4) == 0 || ngx_strncmp(p, "use ", 4) == 0) {
+ if (ngx_strncmp(p, "sub ", 4) == 0
+ || ngx_strncmp(p, "sub{", 4) == 0
+ || ngx_strncmp(p, "use ", 4) == 0)
+ {
*sv = eval_pv((char *) p, FALSE);
/* eval_pv() does not set ERRSV on failure */
diff --git a/src/http/ngx_http_file_cache.c b/src/http/ngx_http_file_cache.c
index a6271a8e9..ca333fc14 100644
--- a/src/http/ngx_http_file_cache.c
+++ b/src/http/ngx_http_file_cache.c
@@ -767,6 +767,7 @@ ngx_http_file_cache_update(ngx_http_request_t *r, ngx_temp_file_t *tf)
ngx_int_t
ngx_http_cache_send(ngx_http_request_t *r)
{
+ off_t size;
ngx_int_t rc;
ngx_buf_t *b;
ngx_chain_t out;
@@ -795,10 +796,15 @@ ngx_http_cache_send(ngx_http_request_t *r)
return rc;
}
+ size = c->length - c->body_start;
+ if (size == 0) {
+ return rc;
+ }
+
b->file_pos = c->body_start;
b->file_last = c->length;
- b->in_file = (c->length - c->body_start) ? 1: 0;
+ b->in_file = size ? 1: 0;
b->last_buf = (r == r->main) ? 1: 0;
b->last_in_chain = 1;
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index 25b2aff74..07afe676d 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -2820,6 +2820,8 @@ ngx_http_post_action(ngx_http_request_t *r)
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"post action: \"%V\"", &clcf->post_action);
+ r->main->count--;
+
r->http_version = NGX_HTTP_VERSION_9;
r->header_only = 1;
r->post_action = 1;
diff --git a/src/http/ngx_http_variables.c b/src/http/ngx_http_variables.c
index d41b996c6..b25e64889 100644
--- a/src/http/ngx_http_variables.c
+++ b/src/http/ngx_http_variables.c
@@ -25,6 +25,8 @@ static ngx_int_t ngx_http_variable_unknown_header_in(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_variable_unknown_header_out(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_http_variable_request_line(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_variable_cookie(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_variable_argument(ngx_http_request_t *r,
@@ -164,8 +166,7 @@ static ngx_http_variable_t ngx_http_core_variables[] = {
offsetof(ngx_http_request_t, uri),
NGX_HTTP_VAR_NOCACHEABLE, 0 },
- { ngx_string("request"), NULL, ngx_http_variable_request,
- offsetof(ngx_http_request_t, request_line), 0, 0 },
+ { ngx_string("request"), NULL, ngx_http_variable_request_line, 0, 0, 0 },
{ ngx_string("document_root"), NULL,
ngx_http_variable_document_root, 0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
@@ -751,6 +752,42 @@ ngx_http_variable_unknown_header(ngx_http_variable_value_t *v, ngx_str_t *var,
static ngx_int_t
+ngx_http_variable_request_line(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data)
+{
+ u_char *p, *s;
+
+ s = r->request_line.data;
+
+ if (s == NULL) {
+ s = r->request_start;
+
+ if (s == NULL) {
+ v->not_found = 1;
+ return NGX_OK;
+ }
+
+ for (p = s; p < r->header_in->last; p++) {
+ if (*p == CR || *p == LF) {
+ break;
+ }
+ }
+
+ r->request_line.len = p - s;
+ r->request_line.data = s;
+ }
+
+ v->len = r->request_line.len;
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+ v->data = s;
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
ngx_http_variable_cookie(ngx_http_request_t *r, ngx_http_variable_value_t *v,
uintptr_t data)
{