changeset 607:da3c99095432 NGINX_0_8_34

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.
author Igor Sysoev <http://sysoev.ru>
date Wed, 03 Mar 2010 00:00:00 +0300
parents 66adffc35a46
children dd7104f21940
files CHANGES CHANGES.ru conf/mime.types src/core/nginx.h src/core/ngx_conf_file.c src/core/ngx_conf_file.h src/event/ngx_event_openssl.c src/event/ngx_event_openssl.h src/http/modules/ngx_http_fastcgi_module.c src/http/modules/ngx_http_geo_module.c src/http/modules/ngx_http_referer_module.c src/http/modules/ngx_http_ssi_filter_module.c src/http/modules/perl/nginx.pm src/http/modules/perl/nginx.xs src/http/modules/perl/ngx_http_perl_module.c src/http/ngx_http_core_module.c src/http/ngx_http_file_cache.c src/http/ngx_http_header_filter_module.c src/http/ngx_http_variables.c src/mail/ngx_mail_pop3_handler.c
diffstat 20 files changed, 181 insertions(+), 60 deletions(-) [+]
line wrap: on
line diff
--- 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.
 
 
--- 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, то 
--- 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;
--- 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"
--- 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;
--- 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);
--- 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();
 }
--- a/src/event/ngx_event_openssl.h
+++ b/src/event/ngx_event_openssl.h
@@ -15,6 +15,7 @@
 #include <openssl/err.h>
 #include <openssl/conf.h>
 #include <openssl/engine.h>
+#include <openssl/evp.h>
 
 #define NGX_SSL_NAME     "OpenSSL"
 
--- 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;
--- 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;
 
--- 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;
 
--- 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;
     }
--- 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);
--- 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
--- 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);
--- 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) {
--- 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;
--- 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;
     }
--- 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)
--- 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;
             }