summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2009-01-19 14:03:40 +0000
committerJonathan Kolb <jon@b0g.us>2009-01-19 14:03:40 +0000
commita1ff67ef62e23acd419d67c6991a23d402fd333c (patch)
tree7a06404431e44d8f091eb21d63750387f8733437
parent7f487a0a1befe2003e744b110d2c374dfd294999 (diff)
downloadnginx-0.7.31.tar.gz
Changes with nginx 0.7.31 19 Jan 2009v0.7.31
*) Change: now the "try_files" directive tests files only and ignores directories. *) Feature: the "fastcgi_split_path_info" directive. *) Bugfixes in an "Expect" request header line support. *) Bugfixes in geo ranges. *) Bugfix: in a miss case ngx_http_memcached_module returned the "END" line as response body instead of default 404 page body; the bug had appeared in 0.7.18. Thanks to Maxim Dounin. *) Bugfix: while SMTP proxying nginx issued message "250 2.0.0 OK" instead of "235 2.0.0 OK"; the bug had appeared in 0.7.22. Thanks to Maxim Dounin.
-rw-r--r--CHANGES26
-rw-r--r--CHANGES.ru23
-rw-r--r--LICENSE3
-rw-r--r--src/core/nginx.h2
-rw-r--r--src/core/ngx_cycle.c4
-rw-r--r--src/core/ngx_log.c5
-rw-r--r--src/core/ngx_slab.c2
-rw-r--r--src/http/modules/ngx_http_fastcgi_module.c238
-rw-r--r--src/http/modules/ngx_http_flv_module.c2
-rw-r--r--src/http/modules/ngx_http_geo_module.c125
-rw-r--r--src/http/modules/ngx_http_gzip_static_module.c2
-rw-r--r--src/http/modules/ngx_http_static_module.c2
-rw-r--r--src/http/modules/perl/nginx.pm2
-rw-r--r--src/http/ngx_http_core_module.c56
-rw-r--r--src/http/ngx_http_request_body.c51
-rw-r--r--src/http/ngx_http_special_response.c11
-rw-r--r--src/http/ngx_http_upstream.c42
-rw-r--r--src/mail/ngx_mail_proxy_module.c6
-rw-r--r--src/os/unix/ngx_posix_init.c2
19 files changed, 466 insertions, 138 deletions
diff --git a/CHANGES b/CHANGES
index 1d8dd5d78..8c98dcd59 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,10 +1,30 @@
+Changes with nginx 0.7.31 19 Jan 2009
+
+ *) Change: now the "try_files" directive tests files only and ignores
+ directories.
+
+ *) Feature: the "fastcgi_split_path_info" directive.
+
+ *) Bugfixes in an "Expect" request header line support.
+
+ *) Bugfixes in geo ranges.
+
+ *) Bugfix: in a miss case ngx_http_memcached_module returned the "END"
+ line as response body instead of default 404 page body; the bug had
+ appeared in 0.7.18.
+ Thanks to Maxim Dounin.
+
+ *) Bugfix: while SMTP proxying nginx issued message "250 2.0.0 OK"
+ instead of "235 2.0.0 OK"; the bug had appeared in 0.7.22.
+ Thanks to Maxim Dounin.
+
+
Changes with nginx 0.7.30 24 Dec 2008
*) Bugfix: a segmentation fault occurred in worker process, if
- variables were used in the "fastcgi_pass" and "proxy_pass"
- directives and host name must be resolved; the bug had appeared in
- 0.7.29.
+ variables were used in the "fastcgi_pass" or "proxy_pass" directives
+ and host name must be resolved; the bug had appeared in 0.7.29.
Changes with nginx 0.7.29 24 Dec 2008
diff --git a/CHANGES.ru b/CHANGES.ru
index c74893d1b..524319f1f 100644
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,8 +1,29 @@
+Изменения в nginx 0.7.31 19.01.2009
+
+ *) Изменение: теперь директива try_files проверяет только файлы,
+ игнорируя каталоги.
+
+ *) Добавление: директива fastcgi_split_path_info.
+
+ *) Исправления в поддержке строки "Expect" в заголовке запроса.
+
+ *) Исправления в гео-диапазонах.
+
+ *) Исправление: при отсутствии ответа ngx_http_memcached_module
+ возвращал в теле ответа строку "END" вместо 404-ой страницы по
+ умолчанию; ошибка появилась в 0.7.18.
+ Спасибо Максиму Дунину.
+
+ *) Исправление: при проксировании SMPT nginx выдавал сообщение
+ "250 2.0.0 OK" вместо "235 2.0.0 OK"; ошибка появилась в 0.7.22.
+ Спасибо Максиму Дунину.
+
+
Изменения в nginx 0.7.30 24.12.2008
*) Исправление: в рабочем процессе происходил segmentation fault, если
- в директивах fastcgi_pass и proxy_pass использовались переменные и
+ в директивах fastcgi_pass или proxy_pass использовались переменные и
имя хоста должно было резолвиться; ошибка появилась в 0.7.29.
diff --git a/LICENSE b/LICENSE
index 815d3ccd1..d941ed9fb 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2002-2008 Igor Sysoev
+ * Copyright (C) 2002-2009 Igor Sysoev
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -21,5 +21,4 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
*/
diff --git a/src/core/nginx.h b/src/core/nginx.h
index 55b081856..b38a7b146 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
#define _NGINX_H_INCLUDED_
-#define NGINX_VERSION "0.7.30"
+#define NGINX_VERSION "0.7.31"
#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 aa0d9ce7e..cdebf5645 100644
--- a/src/core/ngx_cycle.c
+++ b/src/core/ngx_cycle.c
@@ -394,10 +394,6 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
cycle->log = cycle->new_log;
pool->log = cycle->new_log;
- if (cycle->log->log_level == 0) {
- cycle->log->log_level = NGX_LOG_ERR;
- }
-
/* create shared memory */
diff --git a/src/core/ngx_log.c b/src/core/ngx_log.c
index cc38b02da..a9221db6e 100644
--- a/src/core/ngx_log.c
+++ b/src/core/ngx_log.c
@@ -302,7 +302,10 @@ ngx_set_error_log_levels(ngx_conf_t *cf, ngx_log_t *log)
}
}
- if (log->log_level == NGX_LOG_DEBUG) {
+ if (log->log_level == 0) {
+ log->log_level = NGX_LOG_ERR;
+
+ } else if (log->log_level == NGX_LOG_DEBUG) {
log->log_level = NGX_LOG_DEBUG_ALL;
}
diff --git a/src/core/ngx_slab.c b/src/core/ngx_slab.c
index b187026d8..233544b22 100644
--- a/src/core/ngx_slab.c
+++ b/src/core/ngx_slab.c
@@ -685,7 +685,7 @@ ngx_slab_alloc_pages(ngx_slab_pool_t *pool, ngx_uint_t pages)
}
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, NGX_ENOMEM,
- "ngx_slab_alloc(): failed");
+ "ngx_slab_alloc(): failed");
return NULL;
}
diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c
index 201ac2a21..f3ea63a74 100644
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -22,6 +22,11 @@ typedef struct {
ngx_array_t *fastcgi_lengths;
ngx_array_t *fastcgi_values;
+
+#if (NGX_PCRE)
+ ngx_regex_t *split_regex;
+ ngx_str_t split_name;
+#endif
} ngx_http_fastcgi_loc_conf_t;
@@ -56,6 +61,9 @@ typedef struct {
ngx_uint_t fastcgi_stdout; /* unsigned :1 */
ngx_array_t *split_parts;
+
+ ngx_str_t script_name;
+ ngx_str_t path_info;
} ngx_http_fastcgi_ctx_t;
@@ -125,9 +133,15 @@ static char *ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf,
void *parent, void *child);
static ngx_int_t ngx_http_fastcgi_script_name_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_http_fastcgi_path_info_variable(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_http_fastcgi_split(ngx_http_request_t *r,
+ ngx_http_fastcgi_ctx_t *f, ngx_http_fastcgi_loc_conf_t *flcf);
static char *ngx_http_fastcgi_pass(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
+static char *ngx_http_fastcgi_split_path_info(ngx_conf_t *cf,
+ ngx_command_t *cmd, void *conf);
static char *ngx_http_fastcgi_store(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static char *ngx_http_fastcgi_lowat_check(ngx_conf_t *cf, void *post,
@@ -171,6 +185,13 @@ static ngx_command_t ngx_http_fastcgi_commands[] = {
offsetof(ngx_http_fastcgi_loc_conf_t, index),
NULL },
+ { ngx_string("fastcgi_split_path_info"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_http_fastcgi_split_path_info,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ 0,
+ NULL },
+
{ ngx_string("fastcgi_store"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_http_fastcgi_store,
@@ -390,8 +411,18 @@ static ngx_http_fastcgi_request_start_t ngx_http_fastcgi_request_start = {
};
-static ngx_str_t ngx_http_fastcgi_script_name =
- ngx_string("fastcgi_script_name");
+static ngx_http_variable_t ngx_http_fastcgi_vars[] = {
+
+ { ngx_string("fastcgi_script_name"), NULL,
+ ngx_http_fastcgi_script_name_variable, 0,
+ NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 },
+
+ { ngx_string("fastcgi_path_info"), NULL,
+ ngx_http_fastcgi_path_info_variable, 0,
+ NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 },
+
+ { ngx_null_string, NULL, NULL, 0, 0, 0 }
+};
static ngx_str_t ngx_http_fastcgi_hide_headers[] = {
@@ -410,6 +441,7 @@ ngx_http_fastcgi_handler(ngx_http_request_t *r)
{
ngx_int_t rc;
ngx_http_upstream_t *u;
+ ngx_http_fastcgi_ctx_t *f;
ngx_http_fastcgi_loc_conf_t *flcf;
if (r->subrequest_in_memory) {
@@ -419,7 +451,12 @@ ngx_http_fastcgi_handler(ngx_http_request_t *r)
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
- ngx_http_set_ctx(r, NULL, ngx_http_fastcgi_module);
+ f = ngx_pcalloc(r->pool, sizeof(ngx_http_fastcgi_ctx_t));
+ if (f == NULL) {
+ return NGX_ERROR;
+ }
+
+ ngx_http_set_ctx(r, f, ngx_http_fastcgi_module);
u = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_t));
if (u == NULL) {
@@ -933,15 +970,6 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module);
- if (f == NULL) {
- f = ngx_pcalloc(r->pool, sizeof(ngx_http_fastcgi_ctx_t));
- if (f == NULL) {
- return NGX_ERROR;
- }
-
- ngx_http_set_ctx(r, f, ngx_http_fastcgi_module);
- }
-
u = r->upstream;
for ( ;; ) {
@@ -1666,15 +1694,17 @@ ngx_http_fastcgi_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
static ngx_int_t
ngx_http_fastcgi_add_variables(ngx_conf_t *cf)
{
- ngx_http_variable_t *var;
+ ngx_http_variable_t *var, *v;
- var = ngx_http_add_variable(cf, &ngx_http_fastcgi_script_name,
- NGX_HTTP_VAR_NOHASH|NGX_HTTP_VAR_NOCACHEABLE);
- if (var == NULL) {
- return NGX_ERROR;
- }
+ for (v = ngx_http_fastcgi_vars; v->name.len; v++) {
+ var = ngx_http_add_variable(cf, &v->name, v->flags);
+ if (var == NULL) {
+ return NGX_ERROR;
+ }
- var->get_handler = ngx_http_fastcgi_script_name_variable;
+ var->get_handler = v->get_handler;
+ var->data = v->data;
+ }
return NGX_OK;
}
@@ -1933,6 +1963,13 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
conf->fastcgi_values = prev->fastcgi_values;
}
+#if (NGX_PCRE)
+ if (conf->split_regex == NULL) {
+ conf->split_regex = prev->split_regex;
+ conf->split_name = prev->split_name;
+ }
+#endif
+
if (conf->params_source == NULL) {
conf->flushes = prev->flushes;
conf->params_len = prev->params_len;
@@ -2071,42 +2108,114 @@ ngx_http_fastcgi_script_name_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
{
u_char *p;
+ ngx_http_fastcgi_ctx_t *f;
ngx_http_fastcgi_loc_conf_t *flcf;
- if (r->uri.len) {
+ f = ngx_http_get_module_ctx(r, ngx_http_fastcgi_module);
+ flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module);
+
+ if (ngx_http_fastcgi_split(r, f, flcf) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ if (f->script_name.len == 0
+ || f->script_name.data[f->script_name.len - 1] != '/')
+ {
+ v->len = f->script_name.len;
v->valid = 1;
v->no_cacheable = 0;
v->not_found = 0;
+ v->data = f->script_name.data;
- flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module);
+ return NGX_OK;
+ }
- if (r->uri.data[r->uri.len - 1] != '/') {
- v->len = r->uri.len;
- v->data = r->uri.data;
- return NGX_OK;
- }
+ v->len = f->script_name.len + flcf->index.len;
- v->len = r->uri.len + flcf->index.len;
+ v->data = ngx_pnalloc(r->pool, v->len);
+ if (v->data == NULL) {
+ return NGX_ERROR;
+ }
- v->data = ngx_pnalloc(r->pool, v->len);
- if (v->data == NULL) {
- return NGX_ERROR;
- }
+ p = ngx_copy(v->data, f->script_name.data, f->script_name.len);
+ ngx_memcpy(p, flcf->index.data, flcf->index.len);
- p = ngx_copy(v->data, r->uri.data, r->uri.len);
- ngx_memcpy(p, flcf->index.data, flcf->index.len);
+ return NGX_OK;
+}
- } else {
- v->len = 0;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = NULL;
+static ngx_int_t
+ngx_http_fastcgi_path_info_variable(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data)
+{
+ ngx_http_fastcgi_ctx_t *f;
+ ngx_http_fastcgi_loc_conf_t *flcf;
+
+ f = ngx_http_get_module_ctx(r, ngx_http_fastcgi_module);
+ flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module);
+
+ if (ngx_http_fastcgi_split(r, f, flcf) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ v->len = f->path_info.len;
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+ v->data = f->path_info.data;
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_fastcgi_split(ngx_http_request_t *r, ngx_http_fastcgi_ctx_t *f,
+ ngx_http_fastcgi_loc_conf_t *flcf)
+{
+#if (NGX_PCRE)
+ ngx_int_t n;
+ int captures[(1 + 2) * 3];
+
+ if (f->script_name.len) {
+ return NGX_OK;
+ }
+
+ if (flcf->split_regex == NULL) {
+ f->script_name = r->uri;
return NGX_OK;
}
+ n = ngx_regex_exec(flcf->split_regex, &r->uri, captures, (1 + 2) * 3);
+
+ if (n == NGX_REGEX_NO_MATCHED) {
+ f->script_name = r->uri;
+ return NGX_OK;
+ }
+
+ if (n < 0) {
+ ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
+ ngx_regex_exec_n " failed: %d on \"%V\" using \"%V\"",
+ n, &r->uri, &flcf->split_name);
+ return NGX_ERROR;
+ }
+
+ /* match */
+
+ f->script_name.len = captures[3] - captures[2];
+ f->script_name.data = r->uri.data;
+
+ f->path_info.len = captures[5] - captures[4];
+ f->path_info.data = r->uri.data + f->script_name.len;
+
return NGX_OK;
+
+#else
+
+ f->script_name = r->uri;
+
+ return NGX_OK;
+
+#endif
}
@@ -2172,6 +2281,57 @@ ngx_http_fastcgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
static char *
+ngx_http_fastcgi_split_path_info(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+#if (NGX_PCRE)
+ ngx_http_fastcgi_loc_conf_t *flcf = conf;
+
+ ngx_int_t n;
+ ngx_str_t *value, err;
+ u_char errstr[NGX_MAX_CONF_ERRSTR];
+
+ value = cf->args->elts;
+
+ flcf->split_name = value[1];
+
+ err.len = NGX_MAX_CONF_ERRSTR;
+ err.data = errstr;
+
+ flcf->split_regex = ngx_regex_compile(&value[1], 0, cf->pool, &err);
+
+ if (flcf->split_regex == NULL) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data);
+ return NGX_CONF_ERROR;
+ }
+
+ n = ngx_regex_capture_count(flcf->split_regex);
+
+ if (n < 0) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ ngx_regex_capture_count_n " failed for "
+ "pattern \"%V\"", &value[1]);
+ return NGX_CONF_ERROR;
+ }
+
+ if (n != 2) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "pattern \"%V\" must have 2 captures", &value[1]);
+ return NGX_CONF_ERROR;
+ }
+
+ return NGX_CONF_OK;
+
+#else
+
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "\"%V\" requires PCRE library", &cmd->name);
+ return NGX_CONF_ERROR;
+
+#endif
+}
+
+
+static char *
ngx_http_fastcgi_store(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_http_fastcgi_loc_conf_t *flcf = conf;
diff --git a/src/http/modules/ngx_http_flv_module.c b/src/http/modules/ngx_http_flv_module.c
index 2197b6c32..948807cca 100644
--- a/src/http/modules/ngx_http_flv_module.c
+++ b/src/http/modules/ngx_http_flv_module.c
@@ -160,7 +160,7 @@ ngx_http_flv_handler(ngx_http_request_t *r)
return NGX_DECLINED;
}
- r->root_tested = 1;
+ r->root_tested = !r->error_page;
start = 0;
len = of.size;
diff --git a/src/http/modules/ngx_http_geo_module.c b/src/http/modules/ngx_http_geo_module.c
index d570e3009..5535eb299 100644
--- a/src/http/modules/ngx_http_geo_module.c
+++ b/src/http/modules/ngx_http_geo_module.c
@@ -518,10 +518,15 @@ ngx_http_geo_add_range(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
ngx_array_t *a;
ngx_http_geo_range_t *range;
- for (n = start; n < end; n += 0x10000) {
+ for (n = start; n <= end; n += 0x10000) {
h = n >> 16;
- s = n & 0xffff;
+
+ if (n == start) {
+ s = n & 0xffff;
+ } else {
+ s = 0;
+ }
if ((n | 0xffff) > end) {
e = end & 0xffff;
@@ -567,7 +572,9 @@ ngx_http_geo_add_range(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
ngx_memcpy(&range[i + 2], &range[i + 1],
(a->nelts - 2 - i) * sizeof(ngx_http_geo_range_t));
- range = &range[i + 1];
+ range[i + 1].start = (u_short) s;
+ range[i + 1].end = (u_short) e;
+ range[i + 1].value = ctx->value;
goto next;
}
@@ -578,11 +585,101 @@ ngx_http_geo_add_range(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
"duplicate range \"%V\", value: \"%v\", old value: \"%v\"",
ctx->net, ctx->value, range[i].value);
- continue;
+
+ range[i].value = ctx->value;
+
+ goto next;
+ }
+
+ if (s > (ngx_uint_t) range[i].start
+ && e < (ngx_uint_t) range[i].end)
+ {
+ /* split the range and insert the new one */
+
+ range = ngx_array_push(a);
+ if (range == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ range = ngx_array_push(a);
+ if (range == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ range = a->elts;
+
+ ngx_memcpy(&range[i + 3], &range[i + 1],
+ (a->nelts - 3 - i) * sizeof(ngx_http_geo_range_t));
+
+ range[i + 2].start = (u_short) (e + 1);
+ range[i + 2].end = range[i].end;
+ range[i + 2].value = range[i].value;
+
+ range[i + 1].start = (u_short) s;
+ range[i + 1].end = (u_short) e;
+ range[i + 1].value = ctx->value;
+
+ range[i].end = (u_short) (s - 1);
+
+ goto next;
}
+ if (s == (ngx_uint_t) range[i].start
+ && e < (ngx_uint_t) range[i].end)
+ {
+ /* shift the range start and insert the new range */
+
+ range = ngx_array_push(a);
+ if (range == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ range = a->elts;
+
+ ngx_memcpy(&range[i + 2], &range[i + 1],
+ (a->nelts - 2 - i) * sizeof(ngx_http_geo_range_t));
+
+ range[i + 1].start = (u_short) (e + 1);
+
+ range[i].start = (u_short) s;
+ range[i].end = (u_short) e;
+ range[i].value = ctx->value;
+
+ goto next;
+ }
+
+ if (s > (ngx_uint_t) range[i].start
+ && e == (ngx_uint_t) range[i].end)
+ {
+ /* shift the range end and insert the new range */
+
+ range = ngx_array_push(a);
+ if (range == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ range = a->elts;
+
+ ngx_memcpy(&range[i + 2], &range[i + 1],
+ (a->nelts - 2 - i) * sizeof(ngx_http_geo_range_t));
+
+ range[i + 1].start = (u_short) s;
+ range[i + 1].end = (u_short) e;
+ range[i + 1].value = ctx->value;
+
+ range[i].end = (u_short) (s - 1);
+
+ goto next;
+ }
+
+ s = (ngx_uint_t) range[i].start;
+ e = (ngx_uint_t) range[i].end;
+
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "overlapped range \"%V\"", ctx->net);
+ "range \"%V\" overlaps \"%d.%d.%d.%d-%d.%d.%d.%d\"",
+ ctx->net,
+ h >> 8, h & 0xff, s >> 8, s & 0xff,
+ h >> 8, h & 0xff, e >> 8, e & 0xff);
return NGX_CONF_ERROR;
}
@@ -594,11 +691,13 @@ ngx_http_geo_add_range(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
return NGX_CONF_ERROR;
}
- next:
-
range->start = (u_short) s;
range->end = (u_short) e;
range->value = ctx->value;
+
+ next:
+
+ continue;
}
return NGX_CONF_OK;
@@ -616,10 +715,15 @@ ngx_http_geo_delete_range(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
warn = 0;
- for (n = start; n < end; n += 0x10000) {
+ for (n = start; n <= end; n += 0x10000) {
h = n >> 16;
- s = n & 0xffff;
+
+ if (n == start) {
+ s = n & 0xffff;
+ } else {
+ s = 0;
+ }
if ((n | 0xffff) > end) {
e = end & 0xffff;
@@ -643,6 +747,9 @@ ngx_http_geo_delete_range(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
{
ngx_memcpy(&range[i], &range[i + 1],
(a->nelts - 1 - i) * sizeof(ngx_http_geo_range_t));
+
+ a->nelts--;
+
break;
}
diff --git a/src/http/modules/ngx_http_gzip_static_module.c b/src/http/modules/ngx_http_gzip_static_module.c
index affb766ac..e7eb2345f 100644
--- a/src/http/modules/ngx_http_gzip_static_module.c
+++ b/src/http/modules/ngx_http_gzip_static_module.c
@@ -176,7 +176,7 @@ ngx_http_gzip_static_handler(ngx_http_request_t *r)
#endif
- r->root_tested = 1;
+ r->root_tested = !r->error_page;
rc = ngx_http_discard_request_body(r);
diff --git a/src/http/modules/ngx_http_static_module.c b/src/http/modules/ngx_http_static_module.c
index 9ff1f817f..5b9a0ebf4 100644
--- a/src/http/modules/ngx_http_static_module.c
+++ b/src/http/modules/ngx_http_static_module.c
@@ -135,7 +135,7 @@ ngx_http_static_handler(ngx_http_request_t *r)
return rc;
}
- r->root_tested = 1;
+ r->root_tested = !r->error_page;
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, "http static fd: %d", of.fd);
diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm
index 49642a997..9117639c4 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.7.30';
+our $VERSION = '0.7.31';
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 a7a5cdb4c..d44933ca3 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -23,7 +23,6 @@ typedef struct {
static ngx_int_t ngx_http_core_find_location(ngx_http_request_t *r);
static ngx_int_t ngx_http_core_find_static_location(ngx_http_request_t *r,
ngx_http_location_tree_node_t *node);
-static ngx_int_t ngx_http_core_send_continue(ngx_http_request_t *r);
static ngx_int_t ngx_http_core_preconfiguration(ngx_conf_t *cf);
static void *ngx_http_core_create_main_conf(ngx_conf_t *cf);
@@ -818,7 +817,7 @@ ngx_http_core_find_config_phase(ngx_http_request_t *r,
{
u_char *p;
size_t len;
- ngx_int_t rc, expect;
+ ngx_int_t rc;
ngx_http_core_loc_conf_t *clcf;
r->content_handler = NULL;
@@ -862,15 +861,6 @@ ngx_http_core_find_config_phase(ngx_http_request_t *r,
return NGX_OK;
}
- if (r->headers_in.expect && r->http_version > NGX_HTTP_VERSION_10) {
- expect = ngx_http_core_send_continue(r);
-
- if (expect != NGX_OK) {
- ngx_http_finalize_request(r, expect);
- return NGX_OK;
- }
- }
-
if (rc == NGX_DONE) {
r->headers_out.location = ngx_list_push(&r->headers_out.headers);
if (r->headers_out.location == NULL) {
@@ -1182,6 +1172,10 @@ ngx_http_core_try_files_phase(ngx_http_request_t *r,
continue;
}
+ if (!of.is_file) {
+ continue;
+ }
+
path.len -= root;
path.data += root;
@@ -1490,45 +1484,6 @@ ngx_http_core_find_static_location(ngx_http_request_t *r,
}
-static ngx_int_t
-ngx_http_core_send_continue(ngx_http_request_t *r)
-{
- ngx_int_t n;
- ngx_str_t *expect;
-
- if (r->expect_tested) {
- return NGX_OK;
- }
-
- r->expect_tested = 1;
-
- expect = &r->headers_in.expect->value;
-
- if (expect->len != sizeof("100-continue") - 1
- || ngx_strncasecmp(expect->data, (u_char *) "100-continue",
- sizeof("100-continue") - 1)
- != 0)
- {
- return NGX_OK;
- }
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "send 100 Continue");
-
- n = r->connection->send(r->connection,
- (u_char *) "HTTP/1.1 100 Continue" CRLF CRLF,
- sizeof("HTTP/1.1 100 Continue" CRLF CRLF) - 1);
-
- if (n == sizeof("HTTP/1.1 100 Continue" CRLF CRLF) - 1) {
- return NGX_OK;
- }
-
- /* we assume that such small packet should be send successfully */
-
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
-}
-
-
void *
ngx_http_test_content_type(ngx_http_request_t *r, ngx_hash_t *types_hash)
{
@@ -2125,6 +2080,7 @@ ngx_http_subrequest(ngx_http_request_t *r,
sr->internal = 1;
sr->discard_body = r->discard_body;
+ sr->expect_tested = 1;
sr->main_filter_need_in_memory = r->main_filter_need_in_memory;
sr->uri_changes = NGX_HTTP_MAX_URI_CHANGES + 1;
diff --git a/src/http/ngx_http_request_body.c b/src/http/ngx_http_request_body.c
index 96f59dd95..9d47300f5 100644
--- a/src/http/ngx_http_request_body.c
+++ b/src/http/ngx_http_request_body.c
@@ -15,6 +15,7 @@ static ngx_int_t ngx_http_write_request_body(ngx_http_request_t *r,
ngx_chain_t *body);
static void ngx_http_read_discarded_request_body_handler(ngx_http_request_t *r);
static ngx_int_t ngx_http_read_discarded_request_body(ngx_http_request_t *r);
+static ngx_int_t ngx_http_test_expect(ngx_http_request_t *r);
/*
@@ -41,6 +42,10 @@ ngx_http_read_client_request_body(ngx_http_request_t *r,
return NGX_OK;
}
+ if (ngx_http_test_expect(r) != NGX_OK) {
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
+
rb = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t));
if (rb == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
@@ -433,6 +438,10 @@ ngx_http_discard_request_body(ngx_http_request_t *r)
return NGX_OK;
}
+ if (ngx_http_test_expect(r) != NGX_OK) {
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
+
rev = r->connection->read;
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "http set discard body");
@@ -581,3 +590,45 @@ ngx_http_read_discarded_request_body(ngx_http_request_t *r)
return NGX_AGAIN;
}
+
+
+static ngx_int_t
+ngx_http_test_expect(ngx_http_request_t *r)
+{
+ ngx_int_t n;
+ ngx_str_t *expect;
+
+ if (r->expect_tested
+ || r->headers_in.expect == NULL
+ || r->http_version < NGX_HTTP_VERSION_11)
+ {
+ return NGX_OK;
+ }
+
+ r->expect_tested = 1;
+
+ expect = &r->headers_in.expect->value;
+
+ if (expect->len != sizeof("100-continue") - 1
+ || ngx_strncasecmp(expect->data, (u_char *) "100-continue",
+ sizeof("100-continue") - 1)
+ != 0)
+ {
+ return NGX_OK;
+ }
+
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "send 100 Continue");
+
+ n = r->connection->send(r->connection,
+ (u_char *) "HTTP/1.1 100 Continue" CRLF CRLF,
+ sizeof("HTTP/1.1 100 Continue" CRLF CRLF) - 1);
+
+ if (n == sizeof("HTTP/1.1 100 Continue" CRLF CRLF) - 1) {
+ return NGX_OK;
+ }
+
+ /* we assume that such small packet should be send successfully */
+
+ return NGX_ERROR;
+}
diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c
index 849326839..50d804307 100644
--- a/src/http/ngx_http_special_response.c
+++ b/src/http/ngx_http_special_response.c
@@ -379,6 +379,8 @@ ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
}
}
+ r->expect_tested = 1;
+
if (ngx_http_discard_request_body(r) != NGX_OK) {
error = NGX_HTTP_INTERNAL_SERVER_ERROR;
}
@@ -431,11 +433,18 @@ static ngx_int_t
ngx_http_send_error_page(ngx_http_request_t *r, ngx_http_err_page_t *err_page)
{
u_char ch, *p, *last;
+ ngx_int_t overwrite;
ngx_str_t *uri, *args, u, a;
ngx_table_elt_t *location;
ngx_http_core_loc_conf_t *clcf;
- r->err_status = err_page->overwrite;
+ overwrite = err_page->overwrite;
+
+ if (overwrite && overwrite != NGX_HTTP_OK) {
+ r->expect_tested = 1;
+ }
+
+ r->err_status = overwrite;
r->zero_in_uri = 0;
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index f567a438e..c6d32877c 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -1441,11 +1441,6 @@ ngx_http_upstream_test_next(ngx_http_request_t *r, ngx_http_upstream_t *u)
return NGX_OK;
}
- if (status == NGX_HTTP_NOT_FOUND && u->conf->intercept_404) {
- ngx_http_upstream_finalize_request(r, u, NGX_HTTP_NOT_FOUND);
- return NGX_OK;
- }
-
#if (NGX_HTTP_CACHE)
if (u->peer.tries == 0 && u->stale && (u->conf->use_stale & un->mask)) {
@@ -1471,6 +1466,13 @@ ngx_http_upstream_intercept_errors(ngx_http_request_t *r,
ngx_http_err_page_t *err_page;
ngx_http_core_loc_conf_t *clcf;
+ status = u->headers_in.status_n;
+
+ if (status == NGX_HTTP_NOT_FOUND && u->conf->intercept_404) {
+ ngx_http_upstream_finalize_request(r, u, NGX_HTTP_NOT_FOUND);
+ return NGX_OK;
+ }
+
if (!u->conf->intercept_errors) {
return NGX_DECLINED;
}
@@ -1481,8 +1483,6 @@ ngx_http_upstream_intercept_errors(ngx_http_request_t *r,
return NGX_DECLINED;
}
- status = u->headers_in.status_n;
-
err_page = clcf->error_pages->elts;
for (i = 0; i < clcf->error_pages->nelts; i++) {
@@ -2201,6 +2201,7 @@ ngx_http_upstream_process_upstream(ngx_http_request_t *r,
static void
ngx_http_upstream_process_request(ngx_http_request_t *r)
{
+ ngx_uint_t del;
ngx_temp_file_t *tf;
ngx_event_pipe_t *p;
ngx_http_upstream_t *u;
@@ -2212,20 +2213,25 @@ ngx_http_upstream_process_request(ngx_http_request_t *r)
if (u->store) {
+ del = p->upstream_error;
+
tf = u->pipe->temp_file;
- if (p->upstream_eof
- && u->headers_in.status_n == NGX_HTTP_OK
- && (u->headers_in.content_length_n == -1
- || (u->headers_in.content_length_n == tf->offset)))
- {
- ngx_http_upstream_store(r, u);
+ if (p->upstream_eof) {
+
+ if (u->headers_in.status_n == NGX_HTTP_OK
+ && (u->headers_in.content_length_n == -1
+ || (u->headers_in.content_length_n == tf->offset)))
+ {
+ ngx_http_upstream_store(r, u);
+
+ } else {
+ del = 1;
+ }
+ }
+
+ if (del && tf->file.fd != NGX_INVALID_FILE) {
- } else if ((p->upstream_error
- || (p->upstream_eof
- && u->headers_in.status_n != NGX_HTTP_OK))
- && tf->file.fd != NGX_INVALID_FILE)
- {
if (ngx_delete_file(tf->file.name.data) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
diff --git a/src/mail/ngx_mail_proxy_module.c b/src/mail/ngx_mail_proxy_module.c
index bd2bcf9ea..a11101e91 100644
--- a/src/mail/ngx_mail_proxy_module.c
+++ b/src/mail/ngx_mail_proxy_module.c
@@ -104,7 +104,7 @@ ngx_module_t ngx_mail_proxy_module = {
};
-static u_char smtp_ok[] = "250 2.0.0 OK" CRLF;
+static u_char smtp_auth_ok[] = "235 2.0.0 OK" CRLF;
void
@@ -614,8 +614,8 @@ ngx_mail_proxy_smtp_handler(ngx_event_t *rev)
b->pos = b->start;
} else {
- ngx_memcpy(b->start, smtp_ok, sizeof(smtp_ok) - 1);
- b->last = b->start + sizeof(smtp_ok) - 1;
+ ngx_memcpy(b->start, smtp_auth_ok, sizeof(smtp_auth_ok) - 1);
+ b->last = b->start + sizeof(smtp_auth_ok) - 1;
}
s->connection->read->handler = ngx_mail_proxy_handler;
diff --git a/src/os/unix/ngx_posix_init.c b/src/os/unix/ngx_posix_init.c
index 78c5d4be9..b38a81009 100644
--- a/src/os/unix/ngx_posix_init.c
+++ b/src/os/unix/ngx_posix_init.c
@@ -22,7 +22,7 @@ ngx_os_io_t ngx_os_io = {
ngx_unix_recv,
ngx_readv_chain,
ngx_udp_unix_recv,
- NULL,
+ ngx_unix_send,
ngx_writev_chain,
0
};