summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2006-08-28 16:57:50 +0000
committerJonathan Kolb <jon@b0g.us>2006-08-28 16:57:50 +0000
commit081a1291e554437fb6147562d8a9b2ed7b4b2d61 (patch)
tree2dc059b1019acda8a7f2f70ee50254f24decd3cc
parentbfb99d562d277020b5fb9617c8b67a91c1866354 (diff)
downloadnginx-0.3.tar.gz
Changes with nginx 0.3.61 28 Aug 2006v0.3.61nginx-0.3
*) Feature: the "msie_refresh" directive. *) Feature: the "recursive_error_pages" directive. *) Bugfix: the "rewrite" directive returned incorrect redirect, if the redirect had the captured escaped symbols from original URI.
-rw-r--r--CHANGES10
-rw-r--r--CHANGES.ru11
-rw-r--r--src/core/nginx.h2
-rw-r--r--src/http/ngx_http_core_module.c30
-rw-r--r--src/http/ngx_http_core_module.h2
-rw-r--r--src/http/ngx_http_request.h1
-rw-r--r--src/http/ngx_http_script.c2
-rw-r--r--src/http/ngx_http_special_response.c136
8 files changed, 150 insertions, 44 deletions
diff --git a/CHANGES b/CHANGES
index f978aa890..77c27a22a 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,14 @@
+Changes with nginx 0.3.61 28 Aug 2006
+
+ *) Feature: the "msie_refresh" directive.
+
+ *) Feature: the "recursive_error_pages" directive.
+
+ *) Bugfix: the "rewrite" directive returned incorrect redirect, if the
+ redirect had the captured escaped symbols from original URI.
+
+
Changes with nginx 0.3.60 18 Aug 2006
*) Bugfix: a worker process may got caught in an endless loop while an
diff --git a/CHANGES.ru b/CHANGES.ru
index 994d7c510..5b9ec4be5 100644
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,15 @@
+Изменения в nginx 0.3.61 28.08.2006
+
+ *) Добавление: директива msie_refresh.
+
+ *) Добавление: директива recursive_error_pages.
+
+ *) Исправление: директива rewrite возвращала неправильный редирект,
+ если редирект включал в себя выделенные закодированные символы из
+ оригинального URI.
+
+
Изменения в nginx 0.3.60 18.08.2006
*) Исправление: во время перенаправления ошибки рабочий процесс мог
diff --git a/src/core/nginx.h b/src/core/nginx.h
index 1d417fed8..1ba97194e 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
#define _NGINX_H_INCLUDED_
-#define NGINX_VER "nginx/0.3.60"
+#define NGINX_VER "nginx/0.3.61"
#define NGINX_VAR "NGINX"
#define NGX_OLDPID_EXT ".oldbin"
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index 5c19167a9..2a5d3da11 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -381,6 +381,13 @@ static ngx_command_t ngx_http_core_commands[] = {
offsetof(ngx_http_core_loc_conf_t, msie_padding),
NULL },
+ { ngx_string("msie_refresh"),
+ 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_core_loc_conf_t, msie_refresh),
+ NULL },
+
{ ngx_string("log_not_found"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
@@ -388,6 +395,13 @@ static ngx_command_t ngx_http_core_commands[] = {
offsetof(ngx_http_core_loc_conf_t, log_not_found),
NULL },
+ { ngx_string("recursive_error_pages"),
+ 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_core_loc_conf_t, recursive_error_pages),
+ NULL },
+
{ ngx_string("error_page"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|NGX_CONF_2MORE,
@@ -547,7 +561,8 @@ ngx_http_core_run_phases(ngx_http_request_t *r)
if (r->uri_changes == 0) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "rewrite or internal redirection cycle");
+ "rewrite or internal redirection cycle "
+ "while processing \"%V\"", &r->uri);
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
return;
}
@@ -1181,7 +1196,7 @@ ngx_http_subrequest(ngx_http_request_t *r,
if (r->main->subrequests == 0) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "subrequests cycle");
+ "subrequests cycle while processing \"%V\"", uri);
return NGX_ERROR;
}
@@ -1328,7 +1343,9 @@ ngx_http_internal_redirect(ngx_http_request_t *r,
if (r->uri_changes == 0) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "rewrite or internal redirection cycle");
+ "rewrite or internal redirection cycle "
+ "while internal redirect to \"%V\"", uri);
+
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
return NGX_DONE;
}
@@ -2052,7 +2069,9 @@ ngx_http_core_create_loc_conf(ngx_conf_t *cf)
lcf->reset_timedout_connection = NGX_CONF_UNSET;
lcf->port_in_redirect = NGX_CONF_UNSET;
lcf->msie_padding = NGX_CONF_UNSET;
+ lcf->msie_refresh = NGX_CONF_UNSET;
lcf->log_not_found = NGX_CONF_UNSET;
+ lcf->recursive_error_pages = NGX_CONF_UNSET;
lcf->types_hash_max_size = NGX_CONF_UNSET_UINT;
lcf->types_hash_bucket_size = NGX_CONF_UNSET_UINT;
@@ -2206,7 +2225,7 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
prev->client_body_in_file_only, 0);
ngx_conf_merge_value(conf->sendfile, prev->sendfile, 0);
ngx_conf_merge_value(conf->tcp_nopush, prev->tcp_nopush, 0);
- ngx_conf_merge_value(conf->tcp_nodelay, prev->tcp_nodelay, 0);
+ ngx_conf_merge_value(conf->tcp_nodelay, prev->tcp_nodelay, 1);
ngx_conf_merge_msec_value(conf->send_timeout, prev->send_timeout, 60000);
ngx_conf_merge_size_value(conf->send_lowat, prev->send_lowat, 0);
@@ -2231,7 +2250,10 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
prev->reset_timedout_connection, 0);
ngx_conf_merge_value(conf->port_in_redirect, prev->port_in_redirect, 1);
ngx_conf_merge_value(conf->msie_padding, prev->msie_padding, 1);
+ ngx_conf_merge_value(conf->msie_refresh, prev->msie_refresh, 0);
ngx_conf_merge_value(conf->log_not_found, prev->log_not_found, 1);
+ ngx_conf_merge_value(conf->recursive_error_pages,
+ prev->recursive_error_pages, 0);
if (conf->open_files == NULL) {
conf->open_files = prev->open_files;
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h
index 35f865827..0f269a123 100644
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -241,7 +241,9 @@ struct ngx_http_core_loc_conf_s {
ngx_flag_t reset_timedout_connection; /* reset_timedout_connection */
ngx_flag_t port_in_redirect; /* port_in_redirect */
ngx_flag_t msie_padding; /* msie_padding */
+ ngx_flag_t msie_refresh; /* msie_refresh */
ngx_flag_t log_not_found; /* log_not_found */
+ ngx_flag_t recursive_error_pages; /* recursive_error_pages */
ngx_array_t *error_pages; /* error_page */
diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h
index 74be0f73d..54666bb34 100644
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -434,6 +434,7 @@ struct ngx_http_request_s {
unsigned lingering_close:1;
unsigned discard_body:1;
unsigned internal:1;
+ unsigned error_page:1;
unsigned post_action:1;
unsigned request_complete:1;
unsigned request_output:1;
diff --git a/src/http/ngx_http_script.c b/src/http/ngx_http_script.c
index 2169c87ed..3a9e2a85b 100644
--- a/src/http/ngx_http_script.c
+++ b/src/http/ngx_http_script.c
@@ -687,9 +687,11 @@ ngx_http_script_regex_start_code(ngx_http_script_engine_t *e)
ngx_memzero(&le, sizeof(ngx_http_script_engine_t));
le.ip = code->lengths->elts;
+ le.line = e->line;
le.request = r;
le.captures = e->captures;
le.ncaptures = e->ncaptures;
+ le.quote = code->redirect;
len = 1; /* reserve 1 byte for possible "?" */
diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c
index a44c51c6a..71428b0c9 100644
--- a/src/http/ngx_http_special_response.c
+++ b/src/http/ngx_http_special_response.c
@@ -27,6 +27,14 @@ static u_char ngx_http_msie_stub[] =
;
+static u_char ngx_http_msie_refresh_head[] =
+"<html><head><meta http-equiv=\"Refresh\" content=\"0; URL=";
+
+
+static u_char ngx_http_msie_refresh_tail[] =
+"\"></head><body></body></html>" CRLF;
+
+
static char error_301_page[] =
"<html>" CRLF
"<head><title>301 Moved Permanently</title></head>" CRLF
@@ -294,9 +302,11 @@ static ngx_str_t error_pages[] = {
ngx_int_t
ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
{
+ u_char *p;
+ size_t msie_refresh;
ngx_int_t rc;
ngx_buf_t *b;
- ngx_str_t *uri;
+ ngx_str_t *uri, *location;
ngx_uint_t i, err, msie_padding;
ngx_chain_t *out, *cl;
ngx_http_err_page_t *err_page;
@@ -311,7 +321,6 @@ ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
error = NGX_HTTP_INTERNAL_SERVER_ERROR;
}
- r->headers_out.status = error;
r->err_status = error;
if (r->keepalive != 0) {
@@ -341,7 +350,11 @@ ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
- if (r->uri_changes && clcf->error_pages) {
+ if (!r->error_page && clcf->error_pages) {
+
+ if (clcf->recursive_error_pages == 0) {
+ r->error_page = 1;
+ }
err_page = clcf->error_pages->elts;
@@ -415,7 +428,7 @@ ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
case NGX_HTTP_TO_HTTPS:
case NGX_HTTPS_CERT_ERROR:
case NGX_HTTPS_NO_CERT:
- r->headers_out.status = NGX_HTTP_BAD_REQUEST;
+ r->err_status = NGX_HTTP_BAD_REQUEST;
error = NGX_HTTP_BAD_REQUEST;
break;
}
@@ -449,6 +462,26 @@ ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
r->headers_out.content_length = NULL;
}
+ msie_refresh = 0;
+ location = NULL;
+
+ if (clcf->msie_refresh
+ && r->headers_in.msie
+ && (error == NGX_HTTP_MOVED_PERMANENTLY
+ || error == NGX_HTTP_MOVED_TEMPORARILY))
+ {
+ location = &r->headers_out.location->value;
+ msie_refresh = sizeof(ngx_http_msie_refresh_head) - 1
+ + location->len
+ + sizeof(ngx_http_msie_refresh_tail) - 1;
+
+ r->err_status = NGX_HTTP_OK;
+ r->headers_out.content_type_len = sizeof("text/html") - 1;
+ r->headers_out.content_length_n = msie_refresh;
+ r->headers_out.location->hash = 0;
+ r->headers_out.location = NULL;
+ }
+
ngx_http_clear_accept_ranges(r);
ngx_http_clear_last_modified(r);
@@ -458,55 +491,39 @@ ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
return rc;
}
- if (error_pages[err].len == 0) {
- return NGX_OK;
- }
-
-
- b = ngx_calloc_buf(r->pool);
- if (b == NULL) {
- return NGX_ERROR;
- }
- b->memory = 1;
- b->pos = error_pages[err].data;
- b->last = error_pages[err].data + error_pages[err].len;
+ if (msie_refresh == 0) {
- cl = ngx_alloc_chain_link(r->pool);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- cl->buf = b;
- out = cl;
+ if (error_pages[err].len == 0) {
+ return NGX_OK;
+ }
+ b = ngx_calloc_buf(r->pool);
+ if (b == NULL) {
+ return NGX_ERROR;
+ }
- b = ngx_calloc_buf(r->pool);
- if (b == NULL) {
- return NGX_ERROR;
- }
+ b->memory = 1;
+ b->pos = error_pages[err].data;
+ b->last = error_pages[err].data + error_pages[err].len;
- b->memory = 1;
- b->pos = error_tail;
- b->last = error_tail + sizeof(error_tail) - 1;
+ cl = ngx_alloc_chain_link(r->pool);
+ if (cl == NULL) {
+ return NGX_ERROR;
+ }
- cl->next = ngx_alloc_chain_link(r->pool);
- if (cl->next == NULL) {
- return NGX_ERROR;
- }
+ cl->buf = b;
+ out = cl;
- cl = cl->next;
- cl->buf = b;
- if (msie_padding) {
b = ngx_calloc_buf(r->pool);
if (b == NULL) {
return NGX_ERROR;
}
b->memory = 1;
- b->pos = ngx_http_msie_stub;
- b->last = ngx_http_msie_stub + sizeof(ngx_http_msie_stub) - 1;
+ b->pos = error_tail;
+ b->last = error_tail + sizeof(error_tail) - 1;
cl->next = ngx_alloc_chain_link(r->pool);
if (cl->next == NULL) {
@@ -515,6 +532,47 @@ ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
cl = cl->next;
cl->buf = b;
+
+ if (msie_padding) {
+ b = ngx_calloc_buf(r->pool);
+ if (b == NULL) {
+ return NGX_ERROR;
+ }
+
+ b->memory = 1;
+ b->pos = ngx_http_msie_stub;
+ b->last = ngx_http_msie_stub + sizeof(ngx_http_msie_stub) - 1;
+
+ cl->next = ngx_alloc_chain_link(r->pool);
+ if (cl->next == NULL) {
+ return NGX_ERROR;
+ }
+
+ cl = cl->next;
+ cl->buf = b;
+ }
+
+ } else {
+ b = ngx_create_temp_buf(r->pool, msie_refresh);
+ if (b == NULL) {
+ return NGX_ERROR;
+ }
+
+ p = ngx_cpymem(b->pos, ngx_http_msie_refresh_head,
+ sizeof(ngx_http_msie_refresh_head) - 1);
+
+ p = ngx_cpymem(p, location->data, location->len);
+
+ b->last = ngx_cpymem(p, ngx_http_msie_refresh_tail,
+ sizeof(ngx_http_msie_refresh_tail) - 1);
+
+ cl = ngx_alloc_chain_link(r->pool);
+ if (cl == NULL) {
+ return NGX_ERROR;
+ }
+
+ cl->buf = b;
+ out = cl;
}
if (r == r->main) {