# HG changeset patch # User Igor Sysoev # Date 1267563600 -10800 # Node ID da3c99095432591583f4fde189906f6b860002f7 # Parent 66adffc35a4699210362cfa10a2c279732861f41 nginx 0.8.34 *) Bugfix: nginx did not support all ciphers and digests used in client certificates. Thanks to Innocenty Enikeew. *) Bugfix: nginx cached incorrectly FastCGI responses if there was large stderr output before response. *) Bugfix: nginx did not support HTTPS referrers. *) Bugfix: nginx/Windows might not find file if path in configuration was given in other character case; the bug had appeared in 0.8.34. *) Bugfix: the $date_local variable has an incorrect value, if the "%s" format was used. Thanks to Maxim Dounin. *) Bugfix: if ssl_session_cache was not set or was set to "none", then during client certificate verify the error "session id context uninitialized" might occur; the bug had appeared in 0.7.1. *) Bugfix: a geo range returned default value if the range included two or more /16 networks and did not begin at /16 network boundary. *) Bugfix: a block used in a "stub" parameter of an "include" SSI directive was output with "text/plain" MIME type. *) Bugfix: $r->sleep() did not work; the bug had appeared in 0.8.11. diff --git a/CHANGES b/CHANGES --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,35 @@ +Changes with nginx 0.8.34 03 Mar 2010 + + *) Bugfix: nginx did not support all ciphers and digests used in client + certificates. + Thanks to Innocenty Enikeew. + + *) Bugfix: nginx cached incorrectly FastCGI responses if there was + large stderr output before response. + + *) Bugfix: nginx did not support HTTPS referrers. + + *) Bugfix: nginx/Windows might not find file if path in configuration + was given in other character case; the bug had appeared in 0.8.34. + + *) Bugfix: the $date_local variable has an incorrect value, if the "%s" + format was used. + Thanks to Maxim Dounin. + + *) Bugfix: if ssl_session_cache was not set or was set to "none", then + during client certificate verify the error "session id context + uninitialized" might occur; the bug had appeared in 0.7.1. + + *) Bugfix: a geo range returned default value if the range included two + or more /16 networks and did not begin at /16 network boundary. + + *) Bugfix: a block used in a "stub" parameter of an "include" SSI + directive was output with "text/plain" MIME type. + + *) Bugfix: $r->sleep() did not work; the bug had appeared in 0.8.11. + + Changes with nginx 0.8.33 01 Feb 2010 *) Security: now nginx/Windows ignores trailing spaces in URI. @@ -8,9 +39,10 @@ Changes with nginx 0.8.33 Thanks to Dan Crowley, Core Security Technologies. *) Change: now keepalive connections after POST requests are not - disabled for MSIE 7.0+. Thanks to Adam Lounds. - - *) Workaround: now keepalive connections are disabled for Safari. + disabled for MSIE 7.0+. + Thanks to Adam Lounds. + + *) Workaround: now keepalive connections are disabled for Safari. Thanks to Joshua Sierles. *) Bugfix: if a proxied or FastCGI request was internally redirected to @@ -40,8 +72,7 @@ Changes with nginx 0.8.32 Thanks to Julian Reich. *) Bugfix: if the "expires modified" set date in the past, then a - negative number was set in the "Cache-Control" response header - line. + negative number was set in the "Cache-Control" response header line. Thanks to Alex Kapranoff. diff --git a/CHANGES.ru b/CHANGES.ru --- a/CHANGES.ru +++ b/CHANGES.ru @@ -1,19 +1,50 @@ +Изменения в nginx 0.8.34 03.03.2010 + + *) Исправление: nginx не поддерживал все шифры, используемые в + клиентских сертификатах. + Спасибо Иннокентию Еникееву. + + *) Исправление: nginx неправильно кэшировал FastCGI-ответы, если перед + ответом было много вывода в stderr. + + *) Исправление: nginx не поддерживал HTTPS-рефереры. + + *) Исправление: nginx/Windows мог не находить файлы, если путь в + конфигурации был задан в другом регистре; ошибка появилась в 0.8.34. + + *) Исправление: переменная $date_local выдавала неверное время, если + использовался формат "%s". + Спасибо Максиму Дунину. + + *) Исправление: если ssl_session_cache не был установлен или установлен + в none, то при проверке клиентского сертификаты могла происходить + ошибка "session id context uninitialized"; ошибка появилась в 0.7.1. + + *) Исправление: geo-диапазон возвращал значение по умолчанию, если + диапазон включал в себя одну и более сетей размером /16 и не + начинался на границе сети размером /16. + + *) Исправление: блок, используемый в параметре stub в SSI-директиве + include, выводился с MIME-типом "text/plain". + + *) Исправление: $r->sleep() не работал; ошибка появилась в 0.8.11. + + Изменения в nginx 0.8.33 01.02.2010 - *) Безопасность: теперь nginx/Windows игнорирует пробелы в конце - URI. + *) Безопасность: теперь nginx/Windows игнорирует пробелы в конце URI. Спасибо Dan Crowley, Core Security Technologies. - *) Безопасность: теперь nginx/Windows игнорирует короткие имена - файлов. + *) Безопасность: теперь nginx/Windows игнорирует короткие имена файлов. Спасибо Dan Crowley, Core Security Technologies. *) Изменение: теперь keepalive соединения после запросов POST не - запрещаются для MSIE 7.0+. Спасибо Adam Lounds. - - *) Изменение: теперь keepalive соединения запрещены для Safari. Спасибо - Joshua Sierles. + запрещаются для MSIE 7.0+. + Спасибо Adam Lounds. + + *) Изменение: теперь keepalive соединения запрещены для Safari. + Спасибо Joshua Sierles. *) Исправление: если проксированный или FastCGI запрос внутренне перенаправлялся в другой проксированный или FastCGI location, то diff --git a/conf/mime.types b/conf/mime.types --- a/conf/mime.types +++ b/conf/mime.types @@ -35,6 +35,7 @@ types { application/vnd.wap.xhtml+xml xhtml; application/vnd.google-earth.kml+xml kml; application/vnd.google-earth.kmz kmz; + application/x-7z-compressed 7z; application/x-cocoa cco; application/x-java-archive-diff jardiff; application/x-java-jnlp-file jnlp; 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 8033 -#define NGINX_VERSION "0.8.33" +#define nginx_version 8034 +#define NGINX_VERSION "0.8.34" #define NGINX_VER "nginx/" NGINX_VERSION #define NGINX_VAR "NGINX" diff --git a/src/core/ngx_conf_file.c b/src/core/ngx_conf_file.c --- a/src/core/ngx_conf_file.c +++ b/src/core/ngx_conf_file.c @@ -1006,7 +1006,7 @@ ngx_conf_flush_files(ngx_cycle_t *cycle) void ngx_cdecl ngx_conf_log_error(ngx_uint_t level, ngx_conf_t *cf, ngx_err_t err, - char *fmt, ...) + const char *fmt, ...) { u_char errstr[NGX_MAX_CONF_ERRSTR], *p, *last; va_list args; diff --git a/src/core/ngx_conf_file.h b/src/core/ngx_conf_file.h --- a/src/core/ngx_conf_file.h +++ b/src/core/ngx_conf_file.h @@ -322,7 +322,7 @@ ngx_int_t ngx_conf_full_name(ngx_cycle_t ngx_uint_t conf_prefix); ngx_open_file_t *ngx_conf_open_file(ngx_cycle_t *cycle, ngx_str_t *name); void ngx_cdecl ngx_conf_log_error(ngx_uint_t level, ngx_conf_t *cf, - ngx_err_t err, char *fmt, ...); + ngx_err_t err, const char *fmt, ...); char *ngx_conf_set_flag_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -106,6 +106,8 @@ ngx_ssl_init(ngx_log_t *log) ENGINE_load_builtin_engines(); + OpenSSL_add_all_algorithms(); + ngx_ssl_connection_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); if (ngx_ssl_connection_index == -1) { @@ -1308,10 +1310,14 @@ ngx_ssl_connection_error(ngx_connection_ /* handshake failures */ if (n == SSL_R_DIGEST_CHECK_FAILED /* 149 */ + || n == SSL_R_LENGTH_MISMATCH /* 159 */ || n == SSL_R_NO_CIPHERS_PASSED /* 182 */ + || n == SSL_R_NO_CIPHERS_SPECIFIED /* 183 */ || n == SSL_R_NO_SHARED_CIPHER /* 193 */ + || n == SSL_R_RECORD_LENGTH_MISMATCH /* 213 */ || n == SSL_R_UNEXPECTED_MESSAGE /* 244 */ || n == SSL_R_UNEXPECTED_RECORD /* 245 */ + || n == SSL_R_UNKNOWN_ALERT_TYPE /* 246 */ || n == SSL_R_UNKNOWN_PROTOCOL /* 252 */ || n == SSL_R_WRONG_VERSION_NUMBER /* 267 */ || n == SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC /* 281 */ @@ -1424,6 +1430,8 @@ ngx_ssl_session_cache(ngx_ssl_t *ssl, ng return NGX_OK; } + SSL_CTX_set_session_id_context(ssl->ctx, sess_ctx->data, sess_ctx->len); + if (builtin_session_cache == NGX_SSL_NONE_SCACHE) { /* @@ -1455,8 +1463,6 @@ ngx_ssl_session_cache(ngx_ssl_t *ssl, ng SSL_CTX_set_session_cache_mode(ssl->ctx, cache_mode); - SSL_CTX_set_session_id_context(ssl->ctx, sess_ctx->data, sess_ctx->len); - if (builtin_session_cache != NGX_SSL_NO_BUILTIN_SCACHE) { if (builtin_session_cache != NGX_SSL_DFLT_BUILTIN_SCACHE) { @@ -2311,5 +2317,6 @@ ngx_openssl_engine(ngx_conf_t *cf, ngx_c static void ngx_openssl_exit(ngx_cycle_t *cycle) { + EVP_cleanup(); ENGINE_cleanup(); } 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 @@ -15,6 +15,7 @@ #include #include #include +#include #define NGX_SSL_NAME "OpenSSL" 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 @@ -62,7 +62,8 @@ typedef struct { size_t length; size_t padding; - ngx_uint_t fastcgi_stdout; /* unsigned :1 */ + unsigned fastcgi_stdout:1; + unsigned large_stderr:1; ngx_array_t *split_parts; @@ -1081,6 +1082,7 @@ ngx_http_fastcgi_reinit_request(ngx_http f->state = ngx_http_fastcgi_st_version; f->fastcgi_stdout = 0; + f->large_stderr = 0; return NGX_OK; } @@ -1099,6 +1101,7 @@ ngx_http_fastcgi_process_header(ngx_http ngx_table_elt_t *h; ngx_http_upstream_t *u; ngx_http_fastcgi_ctx_t *f; + ngx_http_fastcgi_header_t *fh; ngx_http_upstream_header_t *hh; ngx_http_fastcgi_loc_conf_t *flcf; ngx_http_fastcgi_split_part_t *part; @@ -1223,8 +1226,17 @@ ngx_http_fastcgi_process_header(ngx_http * of the PHP warnings to not allocate memory */ - u->buffer.pos = u->buffer.start; - u->buffer.last = u->buffer.start; +#if (NGX_HTTP_CACHE) + if (r->cache) { + u->buffer.pos = u->buffer.start + + r->cache->header_start; + } else { + u->buffer.pos = u->buffer.start; + } +#endif + + u->buffer.last = u->buffer.pos; + f->large_stderr = 1; } return NGX_AGAIN; @@ -1240,6 +1252,45 @@ ngx_http_fastcgi_process_header(ngx_http /* f->type == NGX_HTTP_FASTCGI_STDOUT */ +#if (NGX_HTTP_CACHE) + + if (f->large_stderr) { + u_char *start; + ssize_t len; + + start = u->buffer.start + r->cache->header_start; + + len = u->buffer.pos - start - 2 * sizeof(ngx_http_fastcgi_header_t); + + /* + * A tail of large stderr output before HTTP header is placed + * in a cache file without a FastCGI record header. + * To workaround it we put a dummy FastCGI record header at the + * start of the stderr output or update r->cache_header_start, + * if there is no enough place for the record header. + */ + + if (len >= 0) { + fh = (ngx_http_fastcgi_header_t *) start; + fh->version = 1; + fh->type = NGX_HTTP_FASTCGI_STDERR; + fh->request_id_hi = 0; + fh->request_id_lo = 1; + fh->content_length_hi = (u_char) ((len >> 8) & 0xff); + fh->content_length_lo = (u_char) (len & 0xff); + fh->padding_length = 0; + fh->reserved = 0; + + } else { + r->cache->header_start += u->buffer.pos - start + - sizeof(ngx_http_fastcgi_header_t); + } + + f->large_stderr = 0; + } + +#endif + f->fastcgi_stdout = 1; start = u->buffer.pos; diff --git a/src/http/modules/ngx_http_geo_module.c b/src/http/modules/ngx_http_geo_module.c --- a/src/http/modules/ngx_http_geo_module.c +++ b/src/http/modules/ngx_http_geo_module.c @@ -589,7 +589,7 @@ ngx_http_geo_add_range(ngx_conf_t *cf, n ngx_array_t *a; ngx_http_geo_range_t *range; - for (n = start; n <= end; n += 0x10000) { + for (n = start; n <= end; n = (n + 0x10000) & 0xffff0000) { h = n >> 16; diff --git a/src/http/modules/ngx_http_referer_module.c b/src/http/modules/ngx_http_referer_module.c --- a/src/http/modules/ngx_http_referer_module.c +++ b/src/http/modules/ngx_http_referer_module.c @@ -124,18 +124,27 @@ ngx_http_referer_variable(ngx_http_reque len = r->headers_in.referer->value.len; ref = r->headers_in.referer->value.data; - if (len < sizeof("http://i.ru") - 1 - || (ngx_strncasecmp(ref, (u_char *) "http://", 7) != 0)) - { - if (rlcf->blocked_referer) { - goto valid; + if (len >= sizeof("http://i.ru") - 1) { + last = ref + len; + + if (ngx_strncasecmp(ref, (u_char *) "http://", 7) == 0) { + ref += 7; + goto valid_scheme; + + } else if (ngx_strncasecmp(ref, (u_char *) "https://", 8) == 0) { + ref += 8; + goto valid_scheme; } - - goto invalid; } - last = ref + len; - ref += 7; + if (rlcf->blocked_referer) { + goto valid; + } + + goto invalid; + +valid_scheme: + i = 0; key = 0; diff --git a/src/http/modules/ngx_http_ssi_filter_module.c b/src/http/modules/ngx_http_ssi_filter_module.c --- a/src/http/modules/ngx_http_ssi_filter_module.c +++ b/src/http/modules/ngx_http_ssi_filter_module.c @@ -2061,9 +2061,9 @@ ngx_http_ssi_stub_output(ngx_http_reques out = data; if (!r->header_sent) { - if (ngx_http_set_content_type(r) != NGX_OK) { - return NGX_ERROR; - } + r->headers_out.content_type_len = + r->parent->headers_out.content_type_len; + r->headers_out.content_type = r->parent->headers_out.content_type; if (ngx_http_send_header(r) == NGX_ERROR) { return NGX_ERROR; @@ -2615,8 +2615,7 @@ ngx_http_ssi_date_gmt_local_variable(ngx return NGX_ERROR; } - v->len = ngx_sprintf(v->data, "%T", tp->sec + (gmt ? 0 : tp->gmtoff)) - - v->data; + v->len = ngx_sprintf(v->data, "%T", tp->sec) - v->data; return NGX_OK; } 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.8.33'; +our $VERSION = '0.8.34'; require XSLoader; XSLoader::load('nginx', $VERSION); 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 @@ -944,6 +944,7 @@ sleep(r, sleep, next) ngx_add_timer(r->connection->write, sleep); r->write_event_handler = ngx_http_perl_sleep_handler; + r->main->count++; void 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 @@ -30,12 +30,6 @@ typedef struct { } ngx_http_perl_variable_t; -typedef struct { - SV *sv; - PerlInterpreter *perl; -} ngx_http_perl_cleanup_t; - - #if (NGX_HTTP_SSI) static ngx_int_t ngx_http_perl_ssi(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ssi_ctx, ngx_str_t **params); 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 @@ -787,11 +787,11 @@ ngx_http_handler(ngx_http_request_t *r) if (r->headers_in.msie6) { if (r->method == NGX_HTTP_POST) { - /* - * MSIE may wait for some time if an response for - * a POST request was sent over a keepalive connection - */ - r->keepalive = 0; + /* + * MSIE may wait for some time if an response for + * a POST request was sent over a keepalive connection + */ + r->keepalive = 0; } } else if (r->headers_in.safari) { 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 @@ -346,7 +346,7 @@ ngx_http_file_cache_read(ngx_http_reques h = (ngx_http_file_cache_header_t *) c->buf->pos; - if (h->crc32 != c->crc32 || (size_t) h->header_start != c->header_start) { + if (h->crc32 != c->crc32) { ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0, "cache file \"%s\" has md5 collision", c->file.name.data); return NGX_DECLINED; @@ -358,6 +358,7 @@ ngx_http_file_cache_read(ngx_http_reques c->last_modified = h->last_modified; c->date = h->date; c->valid_msec = h->valid_msec; + c->header_start = h->header_start; c->body_start = h->body_start; r->cached = 1; 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 @@ -132,10 +132,6 @@ static ngx_str_t ngx_http_status_lines[] ngx_http_header_out_t ngx_http_headers_out[] = { { ngx_string("Server"), offsetof(ngx_http_headers_out_t, server) }, { ngx_string("Date"), offsetof(ngx_http_headers_out_t, date) }, -#if 0 - { ngx_string("Content-Type"), - offsetof(ngx_http_headers_out_t, content_type) }, -#endif { ngx_string("Content-Length"), offsetof(ngx_http_headers_out_t, content_length) }, { ngx_string("Content-Encoding"), @@ -538,8 +534,8 @@ ngx_http_header_filter(ngx_http_request_ r->headers_out.location->value.len = b->last - p; r->headers_out.location->value.data = p; - r->headers_out.location->key.len = sizeof("Location: ") - 1; - r->headers_out.location->key.data = (u_char *) "Location: "; + r->headers_out.location->key.len = sizeof("Location") - 1; + r->headers_out.location->key.data = (u_char *) "Location"; *b->last++ = CR; *b->last++ = LF; } 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 @@ -196,7 +196,8 @@ static ngx_http_variable_t ngx_http_cor { ngx_string("server_name"), NULL, ngx_http_variable_server_name, 0, 0, 0 }, { ngx_string("request_method"), NULL, - ngx_http_variable_request_method, 0, 0, 0 }, + ngx_http_variable_request_method, 0, + NGX_HTTP_VAR_NOCACHEABLE, 0 }, { ngx_string("remote_user"), NULL, ngx_http_variable_remote_user, 0, 0, 0 }, @@ -494,7 +495,7 @@ ngx_http_get_variable(ngx_http_request_t return NULL; } - if (ngx_strncmp(name->data, "upstream_http_", 10) == 0) { + if (ngx_strncmp(name->data, "upstream_http_", 14) == 0) { if (ngx_http_upstream_header_variable(r, vv, (uintptr_t) name) == NGX_OK) diff --git a/src/mail/ngx_mail_pop3_handler.c b/src/mail/ngx_mail_pop3_handler.c --- a/src/mail/ngx_mail_pop3_handler.c +++ b/src/mail/ngx_mail_pop3_handler.c @@ -188,7 +188,6 @@ ngx_mail_pop3_auth_state(ngx_event_t *re default: rc = NGX_MAIL_PARSE_INVALID_COMMAND; - s->mail_state = ngx_pop3_start; break; } @@ -215,7 +214,6 @@ ngx_mail_pop3_auth_state(ngx_event_t *re default: rc = NGX_MAIL_PARSE_INVALID_COMMAND; - s->mail_state = ngx_pop3_start; break; }