# HG changeset patch # User Igor Sysoev # Date 1351540800 -14400 # Node ID b5b7eea22fda3210be431284152d070569fe8035 # Parent 4d942f0d170346f7f4ab612703acf24ac07b127c nginx 1.3.8 *) Feature: the "optional_no_ca" parameter of the "ssl_verify_client" directive. Thanks to Mike Kazantsev and Eric O'Connor. *) Feature: the $bytes_sent, $connection, and $connection_requests variables can now be used not only in the "log_format" directive. Thanks to Benjamin Grössing. *) Feature: the "auto" parameter of the "worker_processes" directive. *) Bugfix: "cache file ... has md5 collision" alert. *) Bugfix: in the ngx_http_gunzip_filter_module. *) Bugfix: in the "ssl_stapling" directive. diff --git a/CHANGES b/CHANGES --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,23 @@ +Changes with nginx 1.3.8 30 Oct 2012 + + *) Feature: the "optional_no_ca" parameter of the "ssl_verify_client" + directive. + Thanks to Mike Kazantsev and Eric O'Connor. + + *) Feature: the $bytes_sent, $connection, and $connection_requests + variables can now be used not only in the "log_format" directive. + Thanks to Benjamin Grössing. + + *) Feature: the "auto" parameter of the "worker_processes" directive. + + *) Bugfix: "cache file ... has md5 collision" alert. + + *) Bugfix: in the ngx_http_gunzip_filter_module. + + *) Bugfix: in the "ssl_stapling" directive. + + Changes with nginx 1.3.7 02 Oct 2012 *) Feature: OCSP stapling support. diff --git a/CHANGES.ru b/CHANGES.ru --- a/CHANGES.ru +++ b/CHANGES.ru @@ -1,4 +1,23 @@ +Изменения в nginx 1.3.8 30.10.2012 + + *) Добавление: параметр optional_no_ca директивы ssl_verify_client. + Спасибо Михаилу Казанцеву и Eric O'Connor. + + *) Добавление: переменные $bytes_sent, $connection и + $connection_requests теперь можно использовать не только в директиве + log_format. + Спасибо Benjamin Grössing. + + *) Добавление: параметр auto директивы worker_processes. + + *) Исправление: сообщения "cache file ... has md5 collision". + + *) Исправление: в модуле ngx_http_gunzip_filter_module. + + *) Исправление: в директиве ssl_stapling. + + Изменения в nginx 1.3.7 02.10.2012 *) Добавление: поддержка OCSP stapling. diff --git a/src/core/nginx.c b/src/core/nginx.c --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -21,6 +21,8 @@ static char *ngx_set_env(ngx_conf_t *cf, static char *ngx_set_priority(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static char *ngx_set_cpu_affinity(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +static char *ngx_set_worker_processes(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf); static ngx_conf_enum_t ngx_debug_points[] = { @@ -69,9 +71,9 @@ static ngx_command_t ngx_core_commands[ { ngx_string("worker_processes"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, - ngx_conf_set_num_slot, + ngx_set_worker_processes, 0, - offsetof(ngx_core_conf_t, worker_processes), + 0, NULL }, { ngx_string("debug_points"), @@ -1329,3 +1331,32 @@ ngx_get_cpu_affinity(ngx_uint_t n) return ccf->cpu_affinity[ccf->cpu_affinity_n - 1]; } + + +static char * +ngx_set_worker_processes(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + ngx_str_t *value; + ngx_core_conf_t *ccf; + + ccf = (ngx_core_conf_t *) conf; + + if (ccf->worker_processes != NGX_CONF_UNSET) { + return "is duplicate"; + } + + value = (ngx_str_t *) cf->args->elts; + + if (ngx_strcmp(value[1].data, "auto") == 0) { + ccf->worker_processes = ngx_ncpu; + return NGX_CONF_OK; + } + + ccf->worker_processes = ngx_atoi(value[1].data, value[1].len); + + if (ccf->worker_processes == NGX_ERROR) { + return "invalid value"; + } + + return NGX_CONF_OK; +} diff --git a/src/core/nginx.h b/src/core/nginx.h --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -9,8 +9,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 1003007 -#define NGINX_VERSION "1.3.7" +#define nginx_version 1003008 +#define NGINX_VERSION "1.3.8" #define NGINX_VER "nginx/" NGINX_VERSION #define NGINX_VAR "NGINX" diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c --- a/src/core/ngx_resolver.c +++ b/src/core/ngx_resolver.c @@ -2144,6 +2144,10 @@ ngx_resolver_rotate(ngx_resolver_t *r, i dst = ngx_resolver_alloc(r, n * sizeof(in_addr_t)); + if (dst == NULL) { + return dst; + } + j = ngx_random() % n; if (j == 0) { diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h --- a/src/event/ngx_event_openssl.h +++ b/src/event/ngx_event_openssl.h @@ -127,6 +127,13 @@ ngx_int_t ngx_ssl_set_session(ngx_connec #define ngx_ssl_get_server_conf(ssl_ctx) \ SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_server_conf_index) +#define ngx_ssl_verify_error_optional(n) \ + (n == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT \ + || n == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN \ + || n == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY \ + || n == X509_V_ERR_CERT_UNTRUSTED \ + || n == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE) + ngx_int_t ngx_ssl_get_protocol(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s); diff --git a/src/event/ngx_event_pipe.c b/src/event/ngx_event_pipe.c --- a/src/event/ngx_event_pipe.c +++ b/src/event/ngx_event_pipe.c @@ -946,8 +946,15 @@ ngx_event_pipe_add_free_buf(ngx_event_pi return NGX_ERROR; } - b->pos = b->start; - b->last = b->start; + if (p->buf_to_file && b->start == p->buf_to_file->start) { + b->pos = p->buf_to_file->last; + b->last = p->buf_to_file->last; + + } else { + b->pos = b->start; + b->last = b->start; + } + b->shadow = NULL; cl->buf = b; diff --git a/src/http/modules/ngx_http_gunzip_filter_module.c b/src/http/modules/ngx_http_gunzip_filter_module.c --- a/src/http/modules/ngx_http_gunzip_filter_module.c +++ b/src/http/modules/ngx_http_gunzip_filter_module.c @@ -145,7 +145,7 @@ ngx_http_gunzip_header_filter(ngx_http_r return ngx_http_next_header_filter(r); } - } else if (!r->gzip_ok) { + } else if (r->gzip_ok) { return ngx_http_next_header_filter(r); } diff --git a/src/http/modules/ngx_http_log_module.c b/src/http/modules/ngx_http_log_module.c --- a/src/http/modules/ngx_http_log_module.c +++ b/src/http/modules/ngx_http_log_module.c @@ -78,10 +78,6 @@ static void ngx_http_log_write(ngx_http_ static ssize_t ngx_http_log_script_write(ngx_http_request_t *r, ngx_http_log_script_t *script, u_char **name, u_char *buf, size_t len); -static u_char *ngx_http_log_connection(ngx_http_request_t *r, u_char *buf, - ngx_http_log_op_t *op); -static u_char *ngx_http_log_connection_requests(ngx_http_request_t *r, - u_char *buf, ngx_http_log_op_t *op); static u_char *ngx_http_log_pipe(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op); static u_char *ngx_http_log_time(ngx_http_request_t *r, u_char *buf, @@ -194,9 +190,6 @@ static ngx_str_t ngx_http_combined_fmt static ngx_http_log_var_t ngx_http_log_vars[] = { - { ngx_string("connection"), NGX_ATOMIC_T_LEN, ngx_http_log_connection }, - { ngx_string("connection_requests"), NGX_INT_T_LEN, - ngx_http_log_connection_requests }, { ngx_string("pipe"), 1, ngx_http_log_pipe }, { ngx_string("time_local"), sizeof("28/Sep/1970:12:00:00 +0600") - 1, ngx_http_log_time }, @@ -209,8 +202,6 @@ static ngx_http_log_var_t ngx_http_log_ { ngx_string("bytes_sent"), NGX_OFF_T_LEN, ngx_http_log_bytes_sent }, { ngx_string("body_bytes_sent"), NGX_OFF_T_LEN, ngx_http_log_body_bytes_sent }, - { ngx_string("apache_bytes_sent"), NGX_OFF_T_LEN, - ngx_http_log_body_bytes_sent }, { ngx_string("request_length"), NGX_SIZE_T_LEN, ngx_http_log_request_length }, @@ -502,22 +493,6 @@ ngx_http_log_copy_long(ngx_http_request_ static u_char * -ngx_http_log_connection(ngx_http_request_t *r, u_char *buf, - ngx_http_log_op_t *op) -{ - return ngx_sprintf(buf, "%uA", r->connection->number); -} - - -static u_char * -ngx_http_log_connection_requests(ngx_http_request_t *r, u_char *buf, - ngx_http_log_op_t *op) -{ - return ngx_sprintf(buf, "%ui", r->connection->requests); -} - - -static u_char * ngx_http_log_pipe(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op) { if (r->pipeline) { @@ -1143,12 +1118,6 @@ ngx_http_log_compile_format(ngx_conf_t * goto invalid; } - if (ngx_strncmp(var.data, "apache_bytes_sent", 17) == 0) { - ngx_conf_log_error(NGX_LOG_WARN, cf, 0, - "use \"$body_bytes_sent\" instead of " - "\"$apache_bytes_sent\""); - } - for (v = ngx_http_log_vars; v->name.len; v++) { if (v->name.len == var.len diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c --- a/src/http/modules/ngx_http_ssl_module.c +++ b/src/http/modules/ngx_http_ssl_module.c @@ -50,6 +50,7 @@ static ngx_conf_enum_t ngx_http_ssl_ver { ngx_string("off"), 0 }, { ngx_string("on"), 1 }, { ngx_string("optional"), 2 }, + { ngx_string("optional_no_ca"), 3 }, { ngx_null_string, 0 } }; @@ -515,7 +516,7 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t * if (conf->verify) { - if (conf->client_certificate.len == 0) { + if (conf->client_certificate.len == 0 && conf->verify != 3) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no ssl_client_certificate for ssl_client_verify"); return NGX_CONF_ERROR; @@ -736,7 +737,7 @@ ngx_http_ssl_init(ngx_conf_t *cf) sscf = cscfp[s]->ctx->srv_conf[ngx_http_ssl_module.ctx_index]; - if (!sscf->stapling) { + if (sscf->ssl.ctx == NULL || !sscf->stapling) { continue; } 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 @@ -50,7 +50,7 @@ our @EXPORT = qw( HTTP_INSUFFICIENT_STORAGE ); -our $VERSION = '1.3.7'; +our $VERSION = '1.3.8'; require XSLoader; XSLoader::load('nginx', $VERSION); 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 @@ -1642,7 +1642,9 @@ ngx_http_process_request(ngx_http_reques if (sscf->verify) { rc = SSL_get_verify_result(c->ssl->connection); - if (rc != X509_V_OK) { + if (rc != X509_V_OK + && (sscf->verify != 3 || !ngx_ssl_verify_error_optional(rc))) + { ngx_log_error(NGX_LOG_INFO, c->log, 0, "client SSL certificate verify error: (%l:%s)", rc, X509_verify_cert_error_string(rc)); @@ -2751,6 +2753,20 @@ ngx_http_keepalive_handler(ngx_event_t * ngx_http_close_connection(c); } + /* + * Like ngx_http_set_keepalive() we are trying to not hold + * c->buffer's memory for a keepalive connection. + */ + + if (ngx_pfree(c->pool, b->start) == NGX_OK) { + + /* + * the special note that c->buffer's memory was freed + */ + + b->pos = NULL; + } + return; } 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 @@ -2287,6 +2287,7 @@ ngx_http_upstream_send_response(ngx_http return; } + p->buf_to_file->start = u->buffer.start; p->buf_to_file->pos = u->buffer.start; p->buf_to_file->last = u->buffer.pos; p->buf_to_file->temporary = 1; diff --git a/src/http/ngx_http_variables.c b/src/http/ngx_http_variables.c --- a/src/http/ngx_http_variables.c +++ b/src/http/ngx_http_variables.c @@ -69,6 +69,8 @@ static ngx_int_t ngx_http_variable_reque ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_variable_remote_user(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); +static ngx_int_t ngx_http_variable_bytes_sent(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_variable_body_bytes_sent(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_variable_request_completion(ngx_http_request_t *r, @@ -95,6 +97,11 @@ static ngx_int_t ngx_http_variable_sent_ static ngx_int_t ngx_http_variable_sent_transfer_encoding(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); +static ngx_int_t ngx_http_variable_connection(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); +static ngx_int_t ngx_http_variable_connection_requests(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); + static ngx_int_t ngx_http_variable_nginx_version(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_variable_hostname(ngx_http_request_t *r, @@ -212,6 +219,9 @@ static ngx_http_variable_t ngx_http_cor { ngx_string("remote_user"), NULL, ngx_http_variable_remote_user, 0, 0, 0 }, + { ngx_string("bytes_sent"), NULL, ngx_http_variable_bytes_sent, + 0, 0, 0 }, + { ngx_string("body_bytes_sent"), NULL, ngx_http_variable_body_bytes_sent, 0, 0, 0 }, @@ -260,6 +270,12 @@ static ngx_http_variable_t ngx_http_cor offsetof(ngx_http_request_t, limit_rate), NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE, 0 }, + { ngx_string("connection"), NULL, + ngx_http_variable_connection, 0, 0, 0 }, + + { ngx_string("connection_requests"), NULL, + ngx_http_variable_connection_requests, 0, 0, 0 }, + { ngx_string("nginx_version"), NULL, ngx_http_variable_nginx_version, 0, 0, 0 }, @@ -1434,6 +1450,27 @@ ngx_http_variable_remote_user(ngx_http_r static ngx_int_t +ngx_http_variable_bytes_sent(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) +{ + u_char *p; + + p = ngx_pnalloc(r->pool, NGX_OFF_T_LEN); + if (p == NULL) { + return NGX_ERROR; + } + + v->len = ngx_sprintf(p, "%O", r->connection->sent) - p; + v->valid = 1; + v->no_cacheable = 0; + v->not_found = 0; + v->data = p; + + return NGX_OK; +} + + +static ngx_int_t ngx_http_variable_body_bytes_sent(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { @@ -1788,6 +1825,48 @@ ngx_http_variable_request_body_file(ngx_ static ngx_int_t +ngx_http_variable_connection(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) +{ + u_char *p; + + p = ngx_pnalloc(r->pool, NGX_ATOMIC_T_LEN); + if (p == NULL) { + return NGX_ERROR; + } + + v->len = ngx_sprintf(p, "%uA", r->connection->number) - p; + v->valid = 1; + v->no_cacheable = 0; + v->not_found = 0; + v->data = p; + + return NGX_OK; +} + + +static ngx_int_t +ngx_http_variable_connection_requests(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) +{ + u_char *p; + + p = ngx_pnalloc(r->pool, NGX_INT_T_LEN); + if (p == NULL) { + return NGX_ERROR; + } + + v->len = ngx_sprintf(p, "%ui", r->connection->requests) - p; + v->valid = 1; + v->no_cacheable = 0; + v->not_found = 0; + v->data = p; + + return NGX_OK; +} + + +static ngx_int_t ngx_http_variable_nginx_version(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { diff --git a/src/os/unix/ngx_process.c b/src/os/unix/ngx_process.c --- a/src/os/unix/ngx_process.c +++ b/src/os/unix/ngx_process.c @@ -474,8 +474,6 @@ ngx_process_get_status(void) return; } -#if (NGX_SOLARIS || NGX_FREEBSD) - /* * Solaris always calls the signal handler for each exited process * despite waitpid() may be already called for this process. @@ -491,8 +489,6 @@ ngx_process_get_status(void) return; } -#endif - ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, err, "waitpid() failed"); return;