changeset 621:3036c1836a24 NGINX_0_9_2

nginx 0.9.2 *) Feature: the "If-Unmodified-Since" client request header line support. *) Workaround: fallback to accept() syscall if accept4() was not implemented; the issue had appeared in 0.9.0. *) Bugfix: nginx could not be built on Cygwin; the issue had appeared in 0.9.0. *) Bugfix: for OpenSSL vulnerability CVE-2010-4180. Thanks to Maxim Dounin.
author Igor Sysoev <http://sysoev.ru>
date Mon, 06 Dec 2010 00:00:00 +0300
parents a87726a9033b
children f6fa6099ee59
files CHANGES CHANGES.ru auto/unix src/core/nginx.h src/event/ngx_event_accept.c src/event/ngx_event_openssl.c src/http/modules/ngx_http_not_modified_filter_module.c src/http/modules/perl/nginx.pm src/http/ngx_http_request.c src/http/ngx_http_request.h
diffstat 10 files changed, 112 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGES
+++ b/CHANGES
@@ -1,7 +1,22 @@
 
+Changes with nginx 0.9.2                                         06 Dec 2010
+
+    *) Feature: the "If-Unmodified-Since" client request header line 
+       support.
+
+    *) Workaround: fallback to accept() syscall if accept4() was not 
+       implemented; the issue had appeared in 0.9.0.
+
+    *) Bugfix: nginx could not be built on Cygwin; the issue had appeared 
+       in 0.9.0.
+
+    *) Bugfix: for OpenSSL vulnerability CVE-2010-4180.
+       Thanks to Maxim Dounin.
+
+
 Changes with nginx 0.9.1                                         30 Nov 2010
 
-    *) Bugfix: "return CODE message" directrives did not work; the bug had 
+    *) Bugfix: "return CODE message" directives did not work; the bug had 
        appeared in 0.9.0.
 
 
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,18 @@
 
+Изменения в nginx 0.9.2                                           06.12.2010
+
+    *) Добавление: поддержка строки "If-Unmodified-Since" в заголовке 
+       запросе клиента.
+
+    *) Изменение: использование accept(), если accept4() не реализован; 
+       ошибка появилась в 0.9.0.
+
+    *) Исправление: nginx не собирался под Cygwin; ошибка появилась в 0.9.0.
+
+    *) Исправление: уязвимости в OpenSSL CVE-2010-4180.
+       Спасибо Максиму Дунину.
+
+
 Изменения в nginx 0.9.1                                           30.11.2010
 
     *) Исправление: директивы вида "return CODE message" не работали; 
--- a/auto/unix
+++ b/auto/unix
@@ -119,6 +119,18 @@ ngx_feature_test='printf("%d", sys_nerr)
 . auto/feature
 
 
+# Cygiwn defines _sys_nerr
+ngx_feature="_sys_nerr"
+ngx_feature_name="NGX_SYS_NERR"
+ngx_feature_run=value
+ngx_feature_incs='#include <errno.h>
+                  #include <stdio.h>'
+ngx_feature_path=
+ngx_feature_libs=
+ngx_feature_test='printf("%d", _sys_nerr);'
+. auto/feature
+
+
 ngx_feature="localtime_r()"
 ngx_feature_name="NGX_HAVE_LOCALTIME_R"
 ngx_feature_run=no
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,8 +8,8 @@
 #define _NGINX_H_INCLUDED_
 
 
-#define nginx_version         9001
-#define NGINX_VERSION      "0.9.1"
+#define nginx_version         9002
+#define NGINX_VERSION      "0.9.2"
 #define NGINX_VER          "nginx/" NGINX_VERSION
 
 #define NGINX_VAR          "NGINX"
--- a/src/event/ngx_event_accept.c
+++ b/src/event/ngx_event_accept.c
@@ -26,6 +26,9 @@ ngx_event_accept(ngx_event_t *ev)
     ngx_connection_t  *c, *lc;
     ngx_event_conf_t  *ecf;
     u_char             sa[NGX_SOCKADDRLEN];
+#if (NGX_HAVE_ACCEPT4)
+    static ngx_uint_t  use_accept4 = 1;
+#endif
 
     ecf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_event_core_module);
 
@@ -47,7 +50,12 @@ ngx_event_accept(ngx_event_t *ev)
         socklen = NGX_SOCKADDRLEN;
 
 #if (NGX_HAVE_ACCEPT4)
-        s = accept4(lc->fd, (struct sockaddr *) sa, &socklen, SOCK_NONBLOCK);
+        if (use_accept4) {
+            s = accept4(lc->fd, (struct sockaddr *) sa, &socklen,
+                        SOCK_NONBLOCK);
+        } else {
+            s = accept(lc->fd, (struct sockaddr *) sa, &socklen);
+        }
 #else
         s = accept(lc->fd, (struct sockaddr *) sa, &socklen);
 #endif
@@ -61,9 +69,22 @@ ngx_event_accept(ngx_event_t *ev)
                 return;
             }
 
+#if (NGX_HAVE_ACCEPT4)
+            ngx_log_error((ngx_uint_t) ((err == NGX_ECONNABORTED) ?
+                                             NGX_LOG_ERR : NGX_LOG_ALERT),
+                          ev->log, err,
+                          use_accept4 ? "accept4() failed" : "accept() failed");
+
+            if (use_accept4 && err == NGX_ENOSYS) {
+                use_accept4 = 0;
+                ngx_inherited_nonblocking = 0;
+                continue;
+            }
+#else
             ngx_log_error((ngx_uint_t) ((err == NGX_ECONNABORTED) ?
                                              NGX_LOG_ERR : NGX_LOG_ALERT),
                           ev->log, err, "accept() failed");
+#endif
 
             if (err == NGX_ECONNABORTED) {
                 if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -155,7 +155,6 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_
 
     SSL_CTX_set_options(ssl->ctx, SSL_OP_MICROSOFT_SESS_ID_BUG);
     SSL_CTX_set_options(ssl->ctx, SSL_OP_NETSCAPE_CHALLENGE_BUG);
-    SSL_CTX_set_options(ssl->ctx, SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG);
 
     /* server side options */
 
--- a/src/http/modules/ngx_http_not_modified_filter_module.c
+++ b/src/http/modules/ngx_http_not_modified_filter_module.c
@@ -9,7 +9,8 @@
 #include <ngx_http.h>
 
 
-
+static ngx_int_t ngx_http_test_precondition(ngx_http_request_t *r);
+static ngx_int_t ngx_http_test_not_modified(ngx_http_request_t *r);
 static ngx_int_t ngx_http_not_modified_filter_init(ngx_conf_t *cf);
 
 
@@ -50,16 +51,50 @@ static ngx_http_output_header_filter_pt 
 static ngx_int_t
 ngx_http_not_modified_header_filter(ngx_http_request_t *r)
 {
-    time_t                     ims;
-    ngx_http_core_loc_conf_t  *clcf;
-
     if (r->headers_out.status != NGX_HTTP_OK
         || r != r->main
-        || r->headers_in.if_modified_since == NULL
         || r->headers_out.last_modified_time == -1)
     {
         return ngx_http_next_header_filter(r);
     }
+ 
+    if (r->headers_in.if_unmodified_since) {
+        return ngx_http_test_precondition(r);
+    }
+ 
+    if (r->headers_in.if_modified_since) {
+        return ngx_http_test_not_modified(r);
+    }
+
+    return ngx_http_next_header_filter(r);
+}
+
+
+static ngx_int_t
+ngx_http_test_precondition(ngx_http_request_t *r)
+{
+    time_t  iums;
+
+    iums = ngx_http_parse_time(r->headers_in.if_unmodified_since->value.data,
+                               r->headers_in.if_unmodified_since->value.len);
+
+    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                 "http iums:%d lm:%d", iums, r->headers_out.last_modified_time);
+
+    if (iums >= r->headers_out.last_modified_time) {
+        return ngx_http_next_header_filter(r);
+    }
+
+    return ngx_http_filter_finalize_request(r, NULL,
+                                            NGX_HTTP_PRECONDITION_FAILED);
+}
+
+
+static ngx_int_t
+ngx_http_test_not_modified(ngx_http_request_t *r)
+{
+    time_t                     ims;
+    ngx_http_core_loc_conf_t  *clcf;
 
     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
 
--- a/src/http/modules/perl/nginx.pm
+++ b/src/http/modules/perl/nginx.pm
@@ -48,7 +48,7 @@ our @EXPORT = qw(
     HTTP_INSUFFICIENT_STORAGE
 );
 
-our $VERSION = '0.9.1';
+our $VERSION = '0.9.2';
 
 require XSLoader;
 XSLoader::load('nginx', $VERSION);
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -88,6 +88,10 @@ ngx_http_header_t  ngx_http_headers_in[]
                  offsetof(ngx_http_headers_in_t, if_modified_since),
                  ngx_http_process_unique_header_line },
 
+    { ngx_string("If-Unmodified-Since"),
+                 offsetof(ngx_http_headers_in_t, if_unmodified_since),
+                 ngx_http_process_unique_header_line },
+
     { ngx_string("User-Agent"), offsetof(ngx_http_headers_in_t, user_agent),
                  ngx_http_process_user_agent },
 
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -167,6 +167,7 @@ typedef struct {
     ngx_table_elt_t                  *host;
     ngx_table_elt_t                  *connection;
     ngx_table_elt_t                  *if_modified_since;
+    ngx_table_elt_t                  *if_unmodified_since;
     ngx_table_elt_t                  *user_agent;
     ngx_table_elt_t                  *referer;
     ngx_table_elt_t                  *content_length;