# HG changeset patch # User Igor Sysoev # Date 1291582800 -10800 # Node ID 3036c1836a244c5ba1ac6d43d88bd5ab685eb925 # Parent a87726a9033b06f6197a139b056ac2a7a080ff56 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. diff --git a/CHANGES b/CHANGES --- 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. diff --git a/CHANGES.ru b/CHANGES.ru --- 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" не работали; diff --git a/auto/unix b/auto/unix --- 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 + #include ' +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 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 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" diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c --- 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) { 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 @@ -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 */ diff --git a/src/http/modules/ngx_http_not_modified_filter_module.c b/src/http/modules/ngx_http_not_modified_filter_module.c --- 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 - +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); 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 @@ -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); 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 @@ -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 }, diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h --- 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;