# HG changeset patch # User Igor Sysoev # Date 1239480000 -14400 # Node ID f2c6a737327477de6844021269e95333e03eba19 # Parent ba2ea8c4d60f623ab40e1e3d4233566b02d20ffc nginx 0.7.51 *) Feature: the "try_files" directive supports a response code in the fallback parameter. *) Feature: now any response code can be used in the "return" directive. *) Bugfix: the "error_page" directive made an external redirect without query string; the bug had appeared in 0.7.44. *) Bugfix: if servers listened on several defined explicitly addresses, then virtual servers might not work; the bug had appeared in 0.7.39. diff --git a/CHANGES b/CHANGES --- a/CHANGES +++ b/CHANGES @@ -1,13 +1,27 @@ +Changes with nginx 0.7.51 12 Apr 2009 + + *) Feature: the "try_files" directive supports a response code in the + fallback parameter. + + *) Feature: now any response code can be used in the "return" directive. + + *) Bugfix: the "error_page" directive made an external redirect without + query string; the bug had appeared in 0.7.44. + + *) Bugfix: if servers listened on several defined explicitly addresses, + then virtual servers might not work; the bug had appeared in 0.7.39. + + Changes with nginx 0.7.50 06 Apr 2009 - *) Change: a segmentation fault might occur in worker process, if the - $arg_... variables were used; the bug had appeared in 0.7.48. + *) Bugfix: the $arg_... variables did not work; the bug had appeared in + 0.7.49. Changes with nginx 0.7.49 06 Apr 2009 - *) Change: a segmentation fault might occur in worker process, if the + *) Bugfix: a segmentation fault might occur in worker process, if the $arg_... variables were used; the bug had appeared in 0.7.48. @@ -213,7 +227,7 @@ Changes with nginx 0.7.35 original request extension. *) Bugfix: "*domain.tld" names were handled incorrectly in - "server_name", "valid_referers", and "map" directives, if an + "server_name", "valid_referers", and "map" directives, if ".domain.tld" and ".subdomain.domain.tld" wildcards were used; the bug had appeared in 0.7.9. diff --git a/CHANGES.ru b/CHANGES.ru --- a/CHANGES.ru +++ b/CHANGES.ru @@ -1,14 +1,30 @@ +Изменения в nginx 0.7.51 12.04.2009 + + *) Добавление: директива try_files поддерживает код ответа в последнем + параметре. + + *) Добавление: теперь в директиве return можно использовать любой код + ответа. + + *) Исправление: директива error_page делала внешний редирект без строки + запроса; ошибка появилась в 0.7.44. + + *) Исправление: если сервера слушали на нескольких явно описанных + адресах, то виртуальные сервера могли не работать; ошибка появилась + в 0.7.39. + + Изменения в nginx 0.7.50 06.04.2009 - *) Изменение: при использовании переменных $arg_... в рабочем процессе - мог произойти segmentation fault; ошибка появилась в 0.7.48. + *) Исправление: переменные $arg_... не работали; ошибка появилась в + 0.7.49. Изменения в nginx 0.7.49 06.04.2009 - *) Изменение: при использовании переменных $arg_... в рабочем процессе - мог произойти segmentation fault; ошибка появилась в 0.7.48. + *) Исправление: при использовании переменных $arg_... в рабочем + процессе мог произойти segmentation fault; ошибка появилась в 0.7.48. Изменения в nginx 0.7.48 06.04.2009 diff --git a/conf/nginx.conf b/conf/nginx.conf --- a/conf/nginx.conf +++ b/conf/nginx.conf @@ -19,7 +19,7 @@ http { default_type application/octet-stream; #log_format main '$remote_addr - $remote_user [$time_local] "$request" ' - # '"$status" $body_bytes_sent "$http_referer" ' + # '$status $body_bytes_sent "$http_referer" ' # '"$http_user_agent" "$http_x_forwarded_for"'; #access_log logs/access.log main; diff --git a/src/core/nginx.h b/src/core/nginx.h --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -8,8 +8,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 007050 -#define NGINX_VERSION "0.7.50" +#define nginx_version 007051 +#define NGINX_VERSION "0.7.51" #define NGINX_VER "nginx/" NGINX_VERSION #define NGINX_VAR "NGINX" diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c --- a/src/core/ngx_cycle.c +++ b/src/core/ngx_cycle.c @@ -375,14 +375,7 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) goto failed; } -#if (NGX_WIN32) - if (ngx_file_append_mode(file[i].fd) != NGX_OK) { - ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, - ngx_file_append_mode_n " \"%s\" failed", - file[i].name.data); - goto failed; - } -#else +#if !(NGX_WIN32) if (fcntl(file[i].fd, F_SETFD, FD_CLOEXEC) == -1) { ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "fcntl(FD_CLOEXEC) \"%s\" failed", @@ -929,21 +922,20 @@ ngx_cmp_sockaddr(struct sockaddr *sa1, s ngx_int_t ngx_create_pidfile(ngx_str_t *name, ngx_log_t *log) { - size_t len; - ngx_uint_t trunc; - ngx_file_t file; - u_char pid[NGX_INT64_LEN + 2]; + size_t len; + ngx_uint_t create; + ngx_file_t file; + u_char pid[NGX_INT64_LEN + 2]; ngx_memzero(&file, sizeof(ngx_file_t)); file.name = *name; file.log = log; - trunc = ngx_test_config ? 0 : NGX_FILE_TRUNCATE; + create = ngx_test_config ? NGX_FILE_CREATE_OR_OPEN : NGX_FILE_TRUNCATE; file.fd = ngx_open_file(file.name.data, NGX_FILE_RDWR, - NGX_FILE_CREATE_OR_OPEN|trunc, - NGX_FILE_DEFAULT_ACCESS); + create, NGX_FILE_DEFAULT_ACCESS); if (file.fd == NGX_INVALID_FILE) { ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, @@ -1078,21 +1070,7 @@ ngx_reopen_files(ngx_cycle_t *cycle, ngx continue; } -#if (NGX_WIN32) - if (ngx_file_append_mode(fd) == NGX_ERROR) { - ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, - ngx_file_append_mode_n " \"%s\" failed", - file[i].name.data); - - if (ngx_close_file(fd) == NGX_FILE_ERROR) { - ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, - ngx_close_file_n " \"%s\" failed", - file[i].name.data); - } - - continue; - } -#else +#if !(NGX_WIN32) if (user != (ngx_uid_t) NGX_CONF_UNSET_UINT) { ngx_file_info_t fi; diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm --- 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.50'; +our $VERSION = '0.7.51'; require XSLoader; XSLoader::load('nginx', $VERSION); diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c --- a/src/http/ngx_http.c +++ b/src/http/ngx_http.c @@ -1373,10 +1373,10 @@ static ngx_int_t ngx_http_optimize_servers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf, ngx_array_t *ports) { - ngx_uint_t s, p, a; - ngx_http_conf_port_t *port; - ngx_http_conf_addr_t *addr; - ngx_http_server_name_t *name; + ngx_uint_t s, p, a; + ngx_http_conf_port_t *port; + ngx_http_conf_addr_t *addr; + ngx_http_server_name_t *name; port = ports->elts; for (p = 0; p < ports->nelts; p++) { @@ -1425,13 +1425,13 @@ static ngx_int_t ngx_http_server_names(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf, ngx_http_conf_addr_t *addr) { - ngx_int_t rc; - ngx_uint_t s; - ngx_hash_init_t hash; - ngx_http_server_name_t *name; - ngx_hash_keys_arrays_t ha; + ngx_int_t rc; + ngx_uint_t s; + ngx_hash_init_t hash; + ngx_hash_keys_arrays_t ha; + ngx_http_server_name_t *name; #if (NGX_PCRE) - ngx_uint_t regex, i; + ngx_uint_t regex, i; regex = 0; #endif @@ -1825,7 +1825,7 @@ ngx_http_add_addrs(ngx_conf_t *cf, ngx_h return NGX_ERROR; } - addrs[i].conf.core_srv_conf->virtual_names = vn; + addrs[i].conf.virtual_names = vn; vn->names.hash = addr[i].hash; vn->names.wc_head = addr[i].wc_head; @@ -1882,7 +1882,7 @@ ngx_http_add_addrs6(ngx_conf_t *cf, ngx_ return NGX_ERROR; } - addrs6[i].conf.core_srv_conf->virtual_names = vn; + addrs6[i].conf.virtual_names = vn; vn->names.hash = addr[i].hash; vn->names.wc_head = addr[i].wc_head; diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -1144,6 +1144,11 @@ ngx_http_core_try_files_phase(ngx_http_r if (tf->lengths == NULL && tf->name.len == 0) { + if (tf->code) { + ngx_http_finalize_request(r, tf->code); + return NGX_OK; + } + path.len -= root; path.data += root; @@ -3875,7 +3880,7 @@ ngx_http_core_error_page(ngx_conf_t *cf, args.len = 0; args.data = NULL; - if (cv.lengths == NULL) { + if (cv.lengths == NULL && uri.data[0] == '/') { p = (u_char *) ngx_strchr(uri.data, '?'); if (p) { @@ -3939,6 +3944,7 @@ ngx_http_core_try_files(ngx_conf_t *cf, ngx_http_core_loc_conf_t *clcf = conf; ngx_str_t *value; + ngx_int_t code; ngx_uint_t i, n; ngx_http_try_file_t *tf; ngx_http_script_compile_t sc; @@ -3994,6 +4000,20 @@ ngx_http_core_try_files(ngx_conf_t *cf, } } + if (tf[i - 1].name.data[0] == '=') { + + code = ngx_atoi(tf[i - 1].name.data + 1, tf[i - 1].name.len - 2); + + if (code == NGX_ERROR) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid code \"%*s\"", + tf[i - 1].name.len - 1, tf[i - 1].name.data); + return NGX_CONF_ERROR; + } + + tf[i].code = code; + } + return NGX_CONF_OK; } diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h --- a/src/http/ngx_http_core_module.h +++ b/src/http/ngx_http_core_module.h @@ -153,8 +153,6 @@ typedef struct { /* server ctx */ ngx_http_conf_ctx_t *ctx; - ngx_http_virtual_names_t *virtual_names; - ngx_str_t server_name; size_t connection_pool_size; @@ -180,6 +178,8 @@ typedef struct { /* the default server configuration for this address:port */ ngx_http_core_srv_conf_t *core_srv_conf; + ngx_http_virtual_names_t *virtual_names; + #if (NGX_HTTP_SSL) ngx_uint_t ssl; /* unsigned ssl:1; */ #endif @@ -267,7 +267,9 @@ typedef struct { ngx_array_t *lengths; ngx_array_t *values; ngx_str_t name; - ngx_uint_t test_dir; /* unsigned test_dir:1; */ + + unsigned code:10; + unsigned test_dir:1; } ngx_http_try_file_t; diff --git a/src/http/ngx_http_file_cache.c b/src/http/ngx_http_file_cache.c --- a/src/http/ngx_http_file_cache.c +++ b/src/http/ngx_http_file_cache.c @@ -417,7 +417,7 @@ ngx_http_file_cache_exists(ngx_http_file if (fcn == NULL) { ngx_shmtx_unlock(&cache->shpool->mutex); - ngx_http_file_cache_forced_expire(cache); + (void) ngx_http_file_cache_forced_expire(cache); ngx_shmtx_lock(&cache->shpool->mutex); @@ -818,12 +818,12 @@ ngx_http_file_cache_forced_expire(ngx_ht name = ngx_alloc(len + 1, ngx_cycle->log); if (name == NULL) { - return 60; + return 10; } ngx_memcpy(name, path->name.data, path->name.len); - wait = 60; + wait = 10; tries = 0; ngx_shmtx_lock(&cache->shpool->mutex); @@ -891,7 +891,7 @@ ngx_http_file_cache_expire(ngx_http_file name = ngx_alloc(len + 1, ngx_cycle->log); if (name == NULL) { - return 60; + return 10; } ngx_memcpy(name, path->name.data, path->name.len); @@ -903,7 +903,7 @@ ngx_http_file_cache_expire(ngx_http_file for ( ;; ) { if (ngx_queue_empty(cache->queue)) { - wait = 60; + wait = 10; break; } @@ -914,7 +914,7 @@ ngx_http_file_cache_expire(ngx_http_file wait = fcn->expire - now; if (wait > 0) { - wait = wait > 60 ? 60 : wait; + wait = wait > 10 ? 10 : wait; break; } @@ -1042,7 +1042,7 @@ ngx_http_file_cache_manager(void *data) cache->files = 0; if (ngx_walk_tree(&tree, &cache->path->name) == NGX_ABORT) { - return 60; + return 10; } *cache->cold = 0; diff --git a/src/http/ngx_http_header_filter_module.c b/src/http/ngx_http_header_filter_module.c --- a/src/http/ngx_http_header_filter_module.c +++ b/src/http/ngx_http_header_filter_module.c @@ -61,7 +61,8 @@ static ngx_str_t ngx_http_status_lines[] /* ngx_null_string, */ /* "207 Multi-Status" */ -#define NGX_HTTP_LEVEL_200 7 +#define NGX_HTTP_LAST_LEVEL_200 207 +#define NGX_HTTP_LEVEL_200 (NGX_HTTP_LAST_LEVEL_200 - 200) /* ngx_null_string, */ /* "300 Multiple Choices" */ @@ -74,7 +75,8 @@ static ngx_str_t ngx_http_status_lines[] /* ngx_null_string, */ /* "306 unused" */ /* ngx_null_string, */ /* "307 Temporary Redirect" */ -#define NGX_HTTP_LEVEL_300 4 +#define NGX_HTTP_LAST_LEVEL_300 305 +#define NGX_HTTP_LEVEL_300 (NGX_HTTP_LAST_LEVEL_300 - 301) ngx_string("400 Bad Request"), ngx_string("401 Unauthorized"), @@ -106,7 +108,8 @@ static ngx_str_t ngx_http_status_lines[] /* ngx_null_string, */ /* "423 Locked" */ /* ngx_null_string, */ /* "424 Failed Dependency" */ -#define NGX_HTTP_LEVEL_400 17 +#define NGX_HTTP_LAST_LEVEL_400 417 +#define NGX_HTTP_LEVEL_400 (NGX_HTTP_LAST_LEVEL_400 - 400) ngx_string("500 Internal Server Error"), ngx_string("501 Method Not Implemented"), @@ -120,6 +123,9 @@ static ngx_str_t ngx_http_status_lines[] /* ngx_null_string, */ /* "508 unused" */ /* ngx_null_string, */ /* "509 unused" */ /* ngx_null_string, */ /* "510 Not Extended" */ + +#define NGX_HTTP_LAST_LEVEL_500 508 + }; @@ -153,7 +159,7 @@ ngx_http_header_filter(ngx_http_request_ { u_char *p; size_t len; - ngx_str_t host; + ngx_str_t host, *status_line; ngx_buf_t *b; ngx_uint_t status, i, port; ngx_chain_t out; @@ -199,17 +205,21 @@ ngx_http_header_filter(ngx_http_request_ if (r->headers_out.status_line.len) { len += r->headers_out.status_line.len; + status_line = &r->headers_out.status_line; #if (NGX_SUPPRESS_WARN) - status = NGX_INVALID_ARRAY_INDEX; + status = 0; #endif } else { - if (r->headers_out.status < NGX_HTTP_MOVED_PERMANENTLY) { + status = r->headers_out.status; + + if (status >= NGX_HTTP_OK + && status < NGX_HTTP_LAST_LEVEL_200) + { /* 2XX */ - status = r->headers_out.status - NGX_HTTP_OK; - if (r->headers_out.status == NGX_HTTP_NO_CONTENT) { + if (status == NGX_HTTP_NO_CONTENT) { r->header_only = 1; r->headers_out.content_type.len = 0; r->headers_out.content_type.data = NULL; @@ -219,30 +229,50 @@ ngx_http_header_filter(ngx_http_request_ r->headers_out.content_length_n = -1; } - } else if (r->headers_out.status < NGX_HTTP_BAD_REQUEST) { + status -= NGX_HTTP_OK; + status_line = &ngx_http_status_lines[status]; + len += ngx_http_status_lines[status].len; + + } else if (status >= NGX_HTTP_MOVED_PERMANENTLY + && status < NGX_HTTP_LAST_LEVEL_300) + { /* 3XX */ - status = r->headers_out.status - NGX_HTTP_MOVED_PERMANENTLY - + NGX_HTTP_LEVEL_200; - if (r->headers_out.status == NGX_HTTP_NOT_MODIFIED) { + if (status == NGX_HTTP_NOT_MODIFIED) { r->header_only = 1; } - } else if (r->headers_out.status < NGX_HTTP_INTERNAL_SERVER_ERROR) { + status = status - NGX_HTTP_MOVED_PERMANENTLY + NGX_HTTP_LEVEL_200; + status_line = &ngx_http_status_lines[status]; + len += ngx_http_status_lines[status].len; + + } else if (status >= NGX_HTTP_BAD_REQUEST + && status < NGX_HTTP_LAST_LEVEL_400) + { /* 4XX */ - status = r->headers_out.status - NGX_HTTP_BAD_REQUEST - + NGX_HTTP_LEVEL_200 - + NGX_HTTP_LEVEL_300; + status = status - NGX_HTTP_BAD_REQUEST + + NGX_HTTP_LEVEL_200 + + NGX_HTTP_LEVEL_300; + + status_line = &ngx_http_status_lines[status]; + len += ngx_http_status_lines[status].len; + + } else if (status >= NGX_HTTP_INTERNAL_SERVER_ERROR + && status < NGX_HTTP_LAST_LEVEL_500) + { + /* 5XX */ + status = status - NGX_HTTP_INTERNAL_SERVER_ERROR + + NGX_HTTP_LEVEL_200 + + NGX_HTTP_LEVEL_300 + + NGX_HTTP_LEVEL_400; + + status_line = &ngx_http_status_lines[status]; + len += ngx_http_status_lines[status].len; } else { - /* 5XX */ - status = r->headers_out.status - NGX_HTTP_INTERNAL_SERVER_ERROR - + NGX_HTTP_LEVEL_200 - + NGX_HTTP_LEVEL_300 - + NGX_HTTP_LEVEL_400; + len += NGX_INT_T_LEN; + status_line = NULL; } - - len += ngx_http_status_lines[status].len; } clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); @@ -400,13 +430,11 @@ ngx_http_header_filter(ngx_http_request_ b->last = ngx_cpymem(b->last, "HTTP/1.1 ", sizeof("HTTP/1.x ") - 1); /* status line */ - if (r->headers_out.status_line.len) { - b->last = ngx_copy(b->last, r->headers_out.status_line.data, - r->headers_out.status_line.len); + if (status_line) { + b->last = ngx_copy(b->last, status_line->data, status_line->len); } else { - b->last = ngx_copy(b->last, ngx_http_status_lines[status].data, - ngx_http_status_lines[status].len); + b->last = ngx_sprintf(b->last, "%ui", status); } *b->last++ = CR; *b->last++ = LF; diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -372,6 +372,8 @@ ngx_http_init_request(ngx_event_t *rev) } } + r->virtual_names = addr_conf->virtual_names; + /* the default server configuration for the address:port */ cscf = addr_conf->core_srv_conf; @@ -1609,15 +1611,11 @@ ngx_http_find_virtual_server(ngx_http_re { u_char *server; ngx_uint_t hash; - ngx_http_virtual_names_t *vn; ngx_http_core_loc_conf_t *clcf; ngx_http_core_srv_conf_t *cscf; u_char buf[32]; - cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); - vn = cscf->virtual_names; - - if (vn == NULL) { + if (r->virtual_names == NULL) { return NGX_DECLINED; } @@ -1633,7 +1631,7 @@ ngx_http_find_virtual_server(ngx_http_re hash = ngx_hash_strlow(server, host, len); - cscf = ngx_hash_find_combined(&vn->names, hash, server, len); + cscf = ngx_hash_find_combined(&r->virtual_names->names, hash, server, len); if (cscf) { goto found; @@ -1641,7 +1639,7 @@ ngx_http_find_virtual_server(ngx_http_re #if (NGX_PCRE) - if (vn->nregex) { + if (r->virtual_names->nregex) { size_t ncaptures; ngx_int_t n; ngx_uint_t i; @@ -1653,9 +1651,9 @@ ngx_http_find_virtual_server(ngx_http_re ncaptures = 0; - sn = vn->regex; - - for (i = 0; i < vn->nregex; i++) { + sn = r->virtual_names->regex; + + for (i = 0; i < r->virtual_names->nregex; i++) { if (sn[i].captures && r->captures == NULL) { diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h --- a/src/http/ngx_http_request.h +++ b/src/http/ngx_http_request.h @@ -387,6 +387,8 @@ struct ngx_http_request_s { ngx_http_post_subrequest_t *post_subrequest; ngx_http_posted_request_t *posted_requests; + ngx_http_virtual_names_t *virtual_names; + ngx_int_t phase_handler; ngx_http_handler_pt content_handler; ngx_uint_t access_code; diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c --- a/src/http/ngx_http_special_response.c +++ b/src/http/ngx_http_special_response.c @@ -275,14 +275,16 @@ static ngx_str_t ngx_http_error_pages[] ngx_null_string, /* 201, 204 */ -#define NGX_HTTP_LEVEL_200 1 +#define NGX_HTTP_LAST_LEVEL_200 202 +#define NGX_HTTP_LEVEL_200 (NGX_HTTP_LAST_LEVEL_200 - 201) /* ngx_null_string, */ /* 300 */ ngx_string(ngx_http_error_301_page), ngx_string(ngx_http_error_302_page), ngx_null_string, /* 303 */ -#define NGX_HTTP_LEVEL_300 3 +#define NGX_HTTP_LAST_LEVEL_300 304 +#define NGX_HTTP_LEVEL_300 (NGX_HTTP_LAST_LEVEL_300 - 301) ngx_string(ngx_http_error_400_page), ngx_string(ngx_http_error_401_page), @@ -302,7 +304,8 @@ static ngx_str_t ngx_http_error_pages[] ngx_string(ngx_http_error_415_page), ngx_string(ngx_http_error_416_page), -#define NGX_HTTP_LEVEL_400 17 +#define NGX_HTTP_LAST_LEVEL_400 417 +#define NGX_HTTP_LEVEL_400 (NGX_HTTP_LAST_LEVEL_400 - 400) ngx_string(ngx_http_error_495_page), /* 495, https certificate error */ ngx_string(ngx_http_error_496_page), /* 496, https no certificate */ @@ -318,6 +321,9 @@ static ngx_str_t ngx_http_error_pages[] ngx_null_string, /* 505 */ ngx_null_string, /* 506 */ ngx_string(ngx_http_error_507_page) + +#define NGX_HTTP_LAST_LEVEL_500 508 + }; @@ -402,16 +408,22 @@ ngx_http_special_response_handler(ngx_ht /* 204 */ err = 0; - } else if (error < NGX_HTTP_BAD_REQUEST) { + } else if (error >= NGX_HTTP_MOVED_PERMANENTLY + && error < NGX_HTTP_LAST_LEVEL_300) + { /* 3XX */ err = error - NGX_HTTP_MOVED_PERMANENTLY + NGX_HTTP_LEVEL_200; - } else if (error < NGX_HTTP_OWN_CODES) { + } else if (error >= NGX_HTTP_BAD_REQUEST + && error < NGX_HTTP_LAST_LEVEL_400) + { /* 4XX */ err = error - NGX_HTTP_BAD_REQUEST + NGX_HTTP_LEVEL_200 + NGX_HTTP_LEVEL_300; - } else { + } else if (error >= NGX_HTTP_OWN_CODES + && error < NGX_HTTP_LAST_LEVEL_500) + { /* 49X, 5XX */ err = error - NGX_HTTP_OWN_CODES + NGX_HTTP_LEVEL_200 + NGX_HTTP_LEVEL_300 @@ -423,6 +435,10 @@ ngx_http_special_response_handler(ngx_ht r->err_status = NGX_HTTP_BAD_REQUEST; break; } + + } else { + /* unknown code, zero body */ + err = 0; } return ngx_http_send_special_response(r, clcf, err); @@ -451,14 +467,14 @@ ngx_http_send_error_page(ngx_http_reques return NGX_ERROR; } - if (err_page->value.lengths) { - ngx_http_split_args(r, &uri, &args); + if (uri.data[0] == '/') { - } else { - args = err_page->args; - } + if (err_page->value.lengths) { + ngx_http_split_args(r, &uri, &args); - if (uri.data[0] == '/') { + } else { + args = err_page->args; + } if (r->method != NGX_HTTP_HEAD) { r->method = NGX_HTTP_GET; diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -1945,6 +1945,9 @@ ngx_http_upstream_send_response(ngx_http } } + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, + "http cacheable: %d", u->cacheable); + #endif p = u->pipe; @@ -2746,7 +2749,7 @@ ngx_http_upstream_finalize_request(ngx_h #if (NGX_HTTP_CACHE) - if (r->cache) { + if (u->cacheable) { time_t valid; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, @@ -2768,7 +2771,8 @@ ngx_http_upstream_finalize_request(ngx_h #endif - if (u->header_sent && (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE)) + if (u->header_sent + && (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE)) { rc = 0; } diff --git a/src/os/unix/ngx_files.h b/src/os/unix/ngx_files.h --- a/src/os/unix/ngx_files.h +++ b/src/os/unix/ngx_files.h @@ -63,7 +63,7 @@ typedef struct { #define NGX_FILE_RDWR O_RDWR #define NGX_FILE_CREATE_OR_OPEN O_CREAT #define NGX_FILE_OPEN 0 -#define NGX_FILE_TRUNCATE O_TRUNC +#define NGX_FILE_TRUNCATE O_CREAT|O_TRUNC #define NGX_FILE_APPEND O_WRONLY|O_APPEND #define NGX_FILE_DEFAULT_ACCESS 0644