# HG changeset patch # User Igor Sysoev # Date 1155499200 -14400 # Node ID dd6c66b5b0e268c3f03e4c2f61fc767869d00af4 # Parent 52ac9a089ea595ecf8b8eba68ce2bc38c851dfa6 nginx 0.3.58 *) Feature: the "error_page" directive supports the variables. *) Change: now the procfs interface instead of sysctl is used on Linux. *) Change: now the "Content-Type" header line is inherited from first response when the "X-Accel-Redirect" was used. *) Bugfix: the "error_page" directive did not redirect the 413 error. *) Bugfix: the trailing "?" did not remove old arguments if no new arguments were added to a rewritten URI. *) Bugfix: nginx could not run on 64-bit FreeBSD 7.0-CURRENT. diff --git a/CHANGES b/CHANGES --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,21 @@ +Changes with nginx 0.3.58 14 Aug 2006 + + *) Feature: the "error_page" directive supports the variables. + + *) Change: now the procfs interface instead of sysctl is used on Linux. + + *) Change: now the "Content-Type" header line is inherited from first + response when the "X-Accel-Redirect" was used. + + *) Bugfix: the "error_page" directive did not redirect the 413 error. + + *) Bugfix: the trailing "?" did not remove old arguments if no new + arguments were added to a rewritten URI. + + *) Bugfix: nginx could not run on 64-bit FreeBSD 7.0-CURRENT. + + Changes with nginx 0.3.57 09 Aug 2006 *) Feature: the $ssl_client_serial variable. diff --git a/CHANGES.ru b/CHANGES.ru --- a/CHANGES.ru +++ b/CHANGES.ru @@ -1,4 +1,22 @@ +Изменения в nginx 0.3.58 14.08.2006 + + *) Добавление: директива error_page поддерживает переменные. + + *) Изменение: теперь на Linux используется интерфейс procfs вместо + sysctl. + + *) Изменение: теперь при использовании "X-Accel-Redirect" строка + "Content-Type" наследуется из первоначального ответа. + + *) Исправление: директива error_page не перенаправляла ошибку 413. + + *) Исправление: завершающий "?" не удалял старые аргументы, если в + переписанном URI не было новых аргументов. + + *) Исправление: nginx не запускался на 64-битной FreeBSD 7.0-CURRENT. + + Изменения в nginx 0.3.57 09.08.2006 *) Добавление: переменная $ssl_client_serial. diff --git a/src/core/nginx.h b/src/core/nginx.h --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -8,7 +8,7 @@ #define _NGINX_H_INCLUDED_ -#define NGINX_VER "nginx/0.3.57" +#define NGINX_VER "nginx/0.3.58" #define NGINX_VAR "NGINX" #define NGX_OLDPID_EXT ".oldbin" diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c --- a/src/http/modules/ngx_http_fastcgi_module.c +++ b/src/http/modules/ngx_http_fastcgi_module.c @@ -2056,7 +2056,7 @@ ngx_http_fastcgi_lowat_check(ngx_conf_t #if (NGX_FREEBSD) ssize_t *np = data; - if (*np >= ngx_freebsd_net_inet_tcp_sendspace) { + if ((u_long) *np >= ngx_freebsd_net_inet_tcp_sendspace) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"fastcgi_send_lowat\" must be less than %d " "(sysctl net.inet.tcp.sendspace)", diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -2343,7 +2343,7 @@ ngx_http_proxy_lowat_check(ngx_conf_t *c #if (NGX_FREEBSD) ssize_t *np = data; - if (*np >= ngx_freebsd_net_inet_tcp_sendspace) { + if ((u_long) *np >= ngx_freebsd_net_inet_tcp_sendspace) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"proxy_send_lowat\" must be less than %d " "(sysctl net.inet.tcp.sendspace)", diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs --- a/src/http/modules/perl/nginx.xs +++ b/src/http/modules/perl/nginx.xs @@ -116,10 +116,8 @@ send_http_header(r, ...) } } else { - if (r->headers_out.content_type.len == 0) { - if (ngx_http_set_content_type(r) != NGX_OK) { - XSRETURN_EMPTY; - } + if (ngx_http_set_content_type(r) != NGX_OK) { + XSRETURN_EMPTY; } } diff --git a/src/http/modules/perl/ngx_http_perl_module.c b/src/http/modules/perl/ngx_http_perl_module.c --- a/src/http/modules/perl/ngx_http_perl_module.c +++ b/src/http/modules/perl/ngx_http_perl_module.c @@ -226,13 +226,6 @@ ngx_http_perl_handle_request(ngx_http_re ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "perl handler"); - /* mod_perl's content handler assumes that content type was already set */ - - if (ngx_http_set_content_type(r) != NGX_OK) { - ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); - return; - } - ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); if (ctx == NULL) { 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 @@ -700,6 +700,7 @@ ngx_http_find_location_config(ngx_http_r r->headers_in.content_length_n, clcf->client_max_body_size); if (r->headers_in.content_length_n != -1 + && !r->discard_body && clcf->client_max_body_size && clcf->client_max_body_size < r->headers_in.content_length_n) { @@ -929,6 +930,10 @@ ngx_http_set_content_type(ngx_http_reque ngx_uint_t i, hash; ngx_http_core_loc_conf_t *clcf; + if (r->headers_out.content_type.len) { + return NGX_OK; + } + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); if (r->exten.len) { @@ -2688,10 +2693,12 @@ ngx_http_core_error_page(ngx_conf_t *cf, { ngx_http_core_loc_conf_t *lcf = conf; - ngx_int_t overwrite; - ngx_uint_t i, n; - ngx_str_t *value; - ngx_http_err_page_t *err; + ngx_int_t overwrite; + ngx_str_t *value, uri; + ngx_uint_t i, n, nvar; + ngx_array_t *uri_lengths, *uri_values; + ngx_http_err_page_t *err; + ngx_http_script_compile_t sc; if (lcf->error_pages == NULL) { lcf->error_pages = ngx_array_create(cf->pool, 4, @@ -2732,6 +2739,28 @@ ngx_http_core_error_page(ngx_conf_t *cf, n = 1; } + uri = value[cf->args->nelts - 1]; + uri_lengths = NULL; + uri_values = NULL; + + nvar = ngx_http_script_variables_count(&uri); + + if (nvar) { + ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); + + sc.cf = cf; + sc.source = &uri; + sc.lengths = &uri_lengths; + sc.values = &uri_values; + sc.variables = nvar; + sc.complete_lengths = 1; + sc.complete_values = 1; + + if (ngx_http_script_compile(&sc) != NGX_OK) { + return NGX_CONF_ERROR; + } + } + for (i = 1; i < cf->args->nelts - n; i++) { err = ngx_array_push(lcf->error_pages); if (err == NULL) { @@ -2755,7 +2784,9 @@ ngx_http_core_error_page(ngx_conf_t *cf, err->overwrite = (overwrite >= 0) ? overwrite : err->status; - err->uri = value[cf->args->nelts - 1]; + err->uri = uri; + err->uri_lengths = uri_lengths; + err->uri_values = uri_values; } return NGX_CONF_OK; @@ -2838,7 +2869,7 @@ ngx_http_core_lowat_check(ngx_conf_t *cf #if (NGX_FREEBSD) ssize_t *np = data; - if (*np >= ngx_freebsd_net_inet_tcp_sendspace) { + if ((u_long) *np >= ngx_freebsd_net_inet_tcp_sendspace) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"send_lowat\" must be less than %d " "(sysctl net.inet.tcp.sendspace)", 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 @@ -171,9 +171,11 @@ typedef struct { typedef struct { - ngx_int_t status; - ngx_int_t overwrite; - ngx_str_t uri; + ngx_int_t status; + ngx_int_t overwrite; + ngx_str_t uri; + ngx_array_t *uri_lengths; + ngx_array_t *uri_values; } ngx_http_err_page_t; diff --git a/src/http/ngx_http_request_body.c b/src/http/ngx_http_request_body.c --- a/src/http/ngx_http_request_body.c +++ b/src/http/ngx_http_request_body.c @@ -405,7 +405,7 @@ ngx_http_discard_body(ngx_http_request_t ssize_t size; ngx_event_t *rev; - if (r != r->main) { + if (r != r->main || r->discard_body) { return NGX_OK; } diff --git a/src/http/ngx_http_script.c b/src/http/ngx_http_script.c --- a/src/http/ngx_http_script.c +++ b/src/http/ngx_http_script.c @@ -792,6 +792,10 @@ ngx_http_script_regex_end_code(ngx_http_ } else { e->buf.len = e->pos - e->buf.data; + + if (!code->add_args) { + r->args.len = 0; + } } if (e->log) { 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 @@ -295,8 +295,9 @@ ngx_int_t ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error) { ngx_int_t rc; + ngx_buf_t *b; + ngx_str_t *uri; ngx_uint_t i, err, msie_padding; - ngx_buf_t *b; ngx_chain_t *out, *cl; ngx_http_err_page_t *err_page; ngx_http_core_loc_conf_t *clcf; @@ -349,9 +350,20 @@ ngx_http_special_response_handler(ngx_ht r->method = NGX_HTTP_GET; - if (err_page[i].uri.data[0] == '/') { - return ngx_http_internal_redirect(r, &err_page[i].uri, - NULL); + uri = &err_page[i].uri; + + if (err_page[i].uri_lengths) { + if (ngx_http_script_run(r, uri, + err_page[i].uri_lengths->elts, 0, + err_page[i].uri_values->elts) + == NULL) + { + return NGX_ERROR; + } + } + + if (uri->data[0] == '/') { + return ngx_http_internal_redirect(r, uri, NULL); } r->headers_out.location = @@ -364,10 +376,10 @@ ngx_http_special_response_handler(ngx_ht r->headers_out.location->hash = 1; r->headers_out.location->key.len = sizeof("Location") - 1; r->headers_out.location->key.data = (u_char *) "Location"; - r->headers_out.location->value = err_page[i].uri; + r->headers_out.location->value = *uri; } else { - error = NGX_HTTP_INTERNAL_SERVER_ERROR; + return NGX_ERROR; } } } 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 @@ -110,7 +110,7 @@ ngx_http_upstream_header_t ngx_http_ups { ngx_string("Content-Type"), ngx_http_upstream_process_header_line, offsetof(ngx_http_upstream_headers_in_t, content_type), - ngx_http_upstream_copy_content_type, 0, 0 }, + ngx_http_upstream_copy_content_type, 0, 1 }, { ngx_string("Content-Length"), ngx_http_upstream_process_header_line, diff --git a/src/os/unix/ngx_freebsd.h b/src/os/unix/ngx_freebsd.h --- a/src/os/unix/ngx_freebsd.h +++ b/src/os/unix/ngx_freebsd.h @@ -11,10 +11,10 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit); -extern int ngx_freebsd_kern_osreldate; -extern int ngx_freebsd_hw_ncpu; -extern int ngx_freebsd_net_inet_tcp_sendspace; -extern int ngx_freebsd_kern_ipc_zero_copy_send; +extern int ngx_freebsd_kern_osreldate; +extern int ngx_freebsd_hw_ncpu; +extern u_long ngx_freebsd_net_inet_tcp_sendspace; +extern int ngx_freebsd_kern_ipc_zero_copy_send; extern ngx_uint_t ngx_freebsd_sendfile_nbytes_bug; extern ngx_uint_t ngx_freebsd_use_tcp_nopush; diff --git a/src/os/unix/ngx_freebsd_init.c b/src/os/unix/ngx_freebsd_init.c --- a/src/os/unix/ngx_freebsd_init.c +++ b/src/os/unix/ngx_freebsd_init.c @@ -9,18 +9,18 @@ /* FreeBSD 3.0 at least */ -char ngx_freebsd_kern_ostype[16]; -char ngx_freebsd_kern_osrelease[128]; -int ngx_freebsd_kern_osreldate; -int ngx_freebsd_hw_ncpu; -int ngx_freebsd_net_inet_tcp_sendspace; -int ngx_freebsd_kern_ipc_somaxconn; +char ngx_freebsd_kern_ostype[16]; +char ngx_freebsd_kern_osrelease[128]; +int ngx_freebsd_kern_osreldate; +int ngx_freebsd_hw_ncpu; +int ngx_freebsd_kern_ipc_somaxconn; +u_long ngx_freebsd_net_inet_tcp_sendspace; /* FreeBSD 4.9 */ -int ngx_freebsd_machdep_hlt_logical_cpus; +int ngx_freebsd_machdep_hlt_logical_cpus; /* FreeBSD 5.0 */ -int ngx_freebsd_kern_ipc_zero_copy_send; +int ngx_freebsd_kern_ipc_zero_copy_send; ngx_uint_t ngx_freebsd_sendfile_nbytes_bug; @@ -43,7 +43,7 @@ static ngx_os_io_t ngx_freebsd_io = { typedef struct { char *name; - int *value; + void *value; size_t size; ngx_uint_t exists; } sysctl_t; @@ -52,23 +52,23 @@ typedef struct { sysctl_t sysctls[] = { { "hw.ncpu", &ngx_freebsd_hw_ncpu, - sizeof(int), 0 }, + sizeof(ngx_freebsd_hw_ncpu), 0 }, { "machdep.hlt_logical_cpus", &ngx_freebsd_machdep_hlt_logical_cpus, - sizeof(int), 0 }, + sizeof(ngx_freebsd_machdep_hlt_logical_cpus), 0 }, { "net.inet.tcp.sendspace", &ngx_freebsd_net_inet_tcp_sendspace, - sizeof(int), 0 }, + sizeof(ngx_freebsd_net_inet_tcp_sendspace), 0 }, { "kern.ipc.somaxconn", &ngx_freebsd_kern_ipc_somaxconn, - sizeof(int), 0 }, + sizeof(ngx_freebsd_kern_ipc_somaxconn), 0 }, { "kern.ipc.zero_copy.send", &ngx_freebsd_kern_ipc_zero_copy_send, - sizeof(int), 0 }, + sizeof(ngx_freebsd_kern_ipc_zero_copy_send), 0 }, { NULL, NULL, 0, 0 } }; @@ -177,11 +177,10 @@ ngx_os_specific_init(ngx_log_t *log) for (i = 0; sysctls[i].name; i++) { - *sysctls[i].value = 0; size = sysctls[i].size; if (sysctlbyname(sysctls[i].name, sysctls[i].value, &size, NULL, 0) - == 0) + == 0) { sysctls[i].exists = 1; continue; @@ -193,12 +192,6 @@ ngx_os_specific_init(ngx_log_t *log) continue; } -#if 0 - if (sysctls[i].value == &ngx_freebsd_machdep_hlt_logical_cpus) { - continue; - } -#endif - ngx_log_error(NGX_LOG_ALERT, log, err, "sysctlbyname(%s) failed", sysctls[i].name); return NGX_ERROR; @@ -206,15 +199,12 @@ ngx_os_specific_init(ngx_log_t *log) if (ngx_freebsd_machdep_hlt_logical_cpus) { ngx_ncpu = ngx_freebsd_hw_ncpu / 2; + } else { ngx_ncpu = ngx_freebsd_hw_ncpu; } - if (version < 600008) { - somaxconn = 32767; - } else { - somaxconn = 65535; - } + somaxconn = version < 600008 ? 32676 : 65535; if (ngx_freebsd_kern_ipc_somaxconn > somaxconn) { ngx_log_error(NGX_LOG_ALERT, log, 0, @@ -234,6 +224,7 @@ ngx_os_specific_init(ngx_log_t *log) void ngx_os_specific_status(ngx_log_t *log) { + u_long value; ngx_uint_t i; ngx_log_error(NGX_LOG_NOTICE, log, 0, "OS: %s %s", @@ -251,8 +242,15 @@ ngx_os_specific_status(ngx_log_t *log) for (i = 0; sysctls[i].name; i++) { if (sysctls[i].exists) { - ngx_log_error(NGX_LOG_NOTICE, log, 0, "%s: %d", - sysctls[i].name, *sysctls[i].value); + if (sysctls[i].size == sizeof(long)) { + value = *(long *) sysctls[i].value; + + } else { + value = *(int *) sysctls[i].value; + } + + ngx_log_error(NGX_LOG_NOTICE, log, 0, "%s: %l", + sysctls[i].name, value); } } } diff --git a/src/os/unix/ngx_linux_init.c b/src/os/unix/ngx_linux_init.c --- a/src/os/unix/ngx_linux_init.c +++ b/src/os/unix/ngx_linux_init.c @@ -8,10 +8,14 @@ #include -char ngx_linux_kern_ostype[50]; -char ngx_linux_kern_osrelease[20]; +static ngx_int_t ngx_linux_procfs(char *name, char *buf, size_t len, + ngx_log_t *log); + -int ngx_linux_rtsig_max; +char ngx_linux_kern_ostype[50]; +char ngx_linux_kern_osrelease[20]; + +int ngx_linux_rtsig_max; static ngx_os_io_t ngx_linux_io = { @@ -35,35 +39,31 @@ ngx_os_specific_init(ngx_log_t *log) size_t len; ngx_err_t err; - name[0] = CTL_KERN; - name[1] = KERN_OSTYPE; - len = sizeof(ngx_linux_kern_ostype); - - if (sysctl(name, 2, ngx_linux_kern_ostype, &len, NULL, 0) == -1) { - ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, - "sysctl(KERN_OSTYPE) failed"); + if (ngx_linux_procfs("/proc/sys/kernel/ostype", + ngx_linux_kern_ostype, + sizeof(ngx_linux_kern_ostype), log) + == -1) + { return NGX_ERROR; } - /* name[0] = CTL_KERN; */ - name[1] = KERN_OSRELEASE; - len = sizeof(ngx_linux_kern_osrelease); - - if (sysctl(name, 2, ngx_linux_kern_osrelease, &len, NULL, 0) == -1) { - ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, - "sysctl(KERN_OSRELEASE) failed"); + if (ngx_linux_procfs("/proc/sys/kernel/osrelease", + ngx_linux_kern_osrelease, + sizeof(ngx_linux_kern_osrelease), log) + == -1) + { return NGX_ERROR; } - /* name[0] = CTL_KERN; */ + name[0] = CTL_KERN; name[1] = KERN_RTSIGMAX; len = sizeof(ngx_linux_rtsig_max); if (sysctl(name, 2, &ngx_linux_rtsig_max, &len, NULL, 0) == -1) { err = ngx_errno; - if (err != NGX_ENOTDIR) { + if (err != NGX_ENOTDIR && err != NGX_ENOSYS) { ngx_log_error(NGX_LOG_ALERT, log, err, "sysctl(KERN_RTSIGMAX) failed"); @@ -89,3 +89,36 @@ ngx_os_specific_status(ngx_log_t *log) ngx_log_error(NGX_LOG_NOTICE, log, 0, "sysctl(KERN_RTSIGMAX): %d", ngx_linux_rtsig_max); } + + +static ngx_int_t +ngx_linux_procfs(char *name, char *buf, size_t len, ngx_log_t *log) +{ + int n; + ngx_fd_t fd; + + fd = open(name, O_RDONLY); + + if (fd == NGX_INVALID_FILE) { + ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, + "open(\"%s\") failed", name); + + return NGX_ERROR; + } + + n = read(fd, buf, len); + + if (n == -1) { + ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, + "read(\"%s\") failed", name); + + } else { + if (buf[n - 1] == '\n') { + buf[--n] = '\0'; + } + } + + ngx_close_file(fd); + + return n; +}