# HG changeset patch # User Igor Sysoev # Date 1195074000 -10800 # Node ID 05693816539c8788ed0060c52a94df2f0975a8bb # Parent 4279bc4cdec6435c32061dea1bcceb0fc182d229 nginx 0.6.17 *) Feature: the "If-Range" request header line support. Thanks to Alexander V. Inyukhin. *) Bugfix: URL double escaping in a redirect of the "msie_refresh" directive; bug appeared in 0.6.4. *) Bugfix: the "autoindex" directive did not work with the "alias /" directive. *) Bugfix: a segmentation fault might occur in worker process if subrequests were used. *) Bugfix: the big responses may be transferred truncated if SSL and gzip were used. *) Bugfix: the $status variable was equal to 0 if a proxied server returned response in HTTP/0.9 version. diff --git a/CHANGES b/CHANGES --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,25 @@ +Changes with nginx 0.6.17 15 Nov 2007 + + *) Feature: the "If-Range" request header line support. + Thanks to Alexander V. Inyukhin. + + *) Bugfix: URL double escaping in a redirect of the "msie_refresh" + directive; bug appeared in 0.6.4. + + *) Bugfix: the "autoindex" directive did not work with the "alias /" + directive. + + *) Bugfix: a segmentation fault might occur in worker process if + subrequests were used. + + *) Bugfix: the big responses may be transferred truncated if SSL and + gzip were used. + + *) Bugfix: the $status variable was equal to 0 if a proxied server + returned response in HTTP/0.9 version. + + Changes with nginx 0.6.16 29 Oct 2007 *) Change: now the uname(2) is used on Linux instead of procfs. diff --git a/CHANGES.ru b/CHANGES.ru --- a/CHANGES.ru +++ b/CHANGES.ru @@ -1,4 +1,25 @@ +Изменения в nginx 0.6.17 15.11.2007 + + *) Добавление: поддержка строки "If-Range" в заголовке запроса. + Спасибо Александру Инюхину. + + *) Исправление: при использовании директивы msie_refresh повторно + экранировались уже экранированные символы; ошибка появилась в 0.6.4. + + *) Исправление: директива autoindex не работала при использовании + "alias /". + + *) Исправление: при использовании подзапросов в рабочем процессе мог + произойти segmentation fault. + + *) Исправление: при использовании SSL и gzip большие ответы могли + передаваться не полностью. + + *) Исправление: если ответ проксированного сервера был версии HTTP/0.9, + то переменная $status была равна 0. + + Изменения в nginx 0.6.16 29.10.2007 *) Изменение: теперь на Linux используется uname(2) вместо procfs. @@ -74,7 +95,7 @@ строке "Connection" в заголовке запроса только, если они были в нижнем регистре; ошибка появилась в 0.6.11. - *) Исправление: sub_filter не работал с пустую строку замены. + *) Исправление: sub_filter не работал с пустой строкой замены. *) Исправление: в парсинге sub_filter. diff --git a/auto/cc/msvc b/auto/cc/msvc --- a/auto/cc/msvc +++ b/auto/cc/msvc @@ -2,7 +2,7 @@ # Copyright (C) Igor Sysoev -# MSVC 6.0 SP2, MSVC Toolkit 2003 (7.1) +# MSVC 6.0 SP2, MSVC Toolkit 2003 (7.1), MSVC 2005 Express Edition SP1 (8.0) # optimizations @@ -91,17 +91,17 @@ CORE_LIBS="$CORE_LIBS kernel32.lib user3 CORE_LINK="$CORE_LINK -subsystem:windows -entry:mainCRTStartup" # debug -CFLAGS="$CFLAGS -Yd" -CORE_LINK="$CORE_LINK -debug -debugtype:coff" +if [ $NGX_CC_NAME != msvc8 ]; then + CFLAGS="$CFLAGS -Zi" + CORE_LINK="$CORE_LINK -debug" +fi # precompiled headers -if [ $NGX_CC_NAME != msvc7 ]; then - CORE_DEPS="$CORE_DEPS $NGX_OBJS/ngx_config.pch" - NGX_PCH="$NGX_OBJS/ngx_config.pch" - NGX_BUILD_PCH="-Ycngx_config.h -Fp$NGX_OBJS/ngx_config.pch" - NGX_USE_PCH="-Yungx_config.h -Fp$NGX_OBJS/ngx_config.pch" -fi +CORE_DEPS="$CORE_DEPS $NGX_OBJS/ngx_config.pch" +NGX_PCH="$NGX_OBJS/ngx_config.pch" +NGX_BUILD_PCH="-Ycngx_config.h -Fp$NGX_OBJS/ngx_config.pch" +NGX_USE_PCH="-Yungx_config.h -Fp$NGX_OBJS/ngx_config.pch" # the resource file diff --git a/auto/cc/name b/auto/cc/name --- a/auto/cc/name +++ b/auto/cc/name @@ -25,6 +25,13 @@ fi if [ "$CC" = cl ]; then if `$NGX_WINE $CC -v 2>&1 \ + | grep '^Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14' \ + >/dev/null 2>&1`; then + + NGX_CC_NAME=msvc8 + echo " + using Microsoft Visual C++ 8 compiler" + + else if `$NGX_WINE $CC -v 2>&1 \ | grep '^Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13' \ >/dev/null 2>&1`; then @@ -35,6 +42,7 @@ if [ "$CC" = cl ]; then NGX_CC_NAME=msvc echo " + using Microsoft Visual C++ compiler" fi + fi else if [ "$CC" = wcl386 ]; then diff --git a/src/core/nginx.h b/src/core/nginx.h --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -8,7 +8,7 @@ #define _NGINX_H_INCLUDED_ -#define NGINX_VERSION "0.6.16" +#define NGINX_VERSION "0.6.17" #define NGINX_VER "nginx/" NGINX_VERSION #define NGINX_VAR "NGINX" diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c --- a/src/core/ngx_string.c +++ b/src/core/ngx_string.c @@ -1147,7 +1147,7 @@ ngx_escape_uri(u_char *dst, u_char *src, 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */ - 0x000000a5, /* 0000 0000 0000 0000 0000 0000 1010 0101 */ + 0x00000085, /* 0000 0000 0000 0000 0000 0000 1000 0101 */ /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */ 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */ diff --git a/src/core/ngx_times.c b/src/core/ngx_times.c --- a/src/core/ngx_times.c +++ b/src/core/ngx_times.c @@ -205,16 +205,16 @@ ngx_gmtime(time_t t, ngx_tm_t *tp) { ngx_int_t sec, min, hour, mday, mon, year, wday, yday, days; - days = t / 86400; + days = (ngx_int_t) (t / 86400); /* Jaunary 1, 1970 was Thursday */ wday = (4 + days) % 7; t %= 86400; - hour = t / 3600; + hour = (ngx_int_t) (t / 3600); t %= 3600; - min = t / 60; - sec = t % 60; + min = (ngx_int_t) (t / 60); + sec = (ngx_int_t) (t % 60); /* the algorithm based on Gauss's formula */ 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 @@ -421,6 +421,7 @@ ngx_event_pipe_write_to_downstream(ngx_e { u_char *prev; size_t bsize; + ngx_int_t rc; ngx_uint_t flush, prev_last_shadow; ngx_chain_t *out, **ll, *cl; ngx_connection_t *downstream; @@ -451,7 +452,13 @@ ngx_event_pipe_write_to_downstream(ngx_e cl->buf->recycled = 0; } - if (p->output_filter(p->output_ctx, p->out) == NGX_ERROR) { + rc = p->output_filter(p->output_ctx, p->out); + + if (downstream->destroyed) { + return NGX_ABORT; + } + + if (rc == NGX_ERROR) { p->downstream_error = 1; return ngx_event_pipe_drain_chains(p); } @@ -467,12 +474,13 @@ ngx_event_pipe_write_to_downstream(ngx_e cl->buf->recycled = 0; } - if (p->output_filter(p->output_ctx, p->in) == NGX_ERROR) { + rc = p->output_filter(p->output_ctx, p->in); - if (downstream->destroyed) { - return NGX_ABORT; - } + if (downstream->destroyed) { + return NGX_ABORT; + } + if (rc == NGX_ERROR) { p->downstream_error = 1; return ngx_event_pipe_drain_chains(p); } @@ -602,7 +610,13 @@ ngx_event_pipe_write_to_downstream(ngx_e break; } - if (p->output_filter(p->output_ctx, out) == NGX_ERROR) { + rc = p->output_filter(p->output_ctx, out); + + if (downstream->destroyed) { + return NGX_ABORT; + } + + if (rc == NGX_ERROR) { p->downstream_error = 1; return ngx_event_pipe_drain_chains(p); } diff --git a/src/http/modules/ngx_http_autoindex_module.c b/src/http/modules/ngx_http_autoindex_module.c --- a/src/http/modules/ngx_http_autoindex_module.c +++ b/src/http/modules/ngx_http_autoindex_module.c @@ -181,7 +181,10 @@ ngx_http_autoindex_handler(ngx_http_requ } allocated = path.len; - path.len = last - path.data - 1; + path.len = last - path.data; + if (path.len > 1) { + path.len--; + } path.data[path.len] = '\0'; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 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 @@ -432,7 +432,7 @@ ngx_http_fastcgi_handler(ngx_http_reques if (r->subrequest_in_memory) { ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, "ngx_http_fastcgi_module does not support " - "subrequest in memeory"); + "subrequest in memory"); return NGX_HTTP_INTERNAL_SERVER_ERROR; } diff --git a/src/http/modules/ngx_http_gzip_filter_module.c b/src/http/modules/ngx_http_gzip_filter_module.c --- a/src/http/modules/ngx_http_gzip_filter_module.c +++ b/src/http/modules/ngx_http_gzip_filter_module.c @@ -837,12 +837,15 @@ ngx_http_gzip_body_filter(ngx_http_reque } } - if (last == NGX_AGAIN && !ctx->done) { - return NGX_AGAIN; - } + if (ctx->out == NULL) { - if (ctx->out == NULL && ctx->busy == NULL) { - return NGX_OK; + if (last == NGX_AGAIN) { + return NGX_AGAIN; + } + + if (ctx->busy == NULL) { + return NGX_OK; + } } last = ngx_http_next_body_filter(r, ctx->out); diff --git a/src/http/modules/ngx_http_index_module.c b/src/http/modules/ngx_http_index_module.c --- a/src/http/modules/ngx_http_index_module.c +++ b/src/http/modules/ngx_http_index_module.c @@ -279,7 +279,7 @@ ngx_http_index_test_dir(ngx_http_request ngx_open_file_info_t of; c = *last; - if (c != '/') { + if (c != '/' || path == last) { /* "alias" without trailing slash */ c = *(++last); } 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 @@ -400,7 +400,8 @@ ngx_http_log_request_time(ngx_http_reque tp = ngx_timeofday(); - ms = (tp->sec - r->start_sec) * 1000 + (tp->msec - r->start_msec); + ms = (ngx_msec_int_t) + ((tp->sec - r->start_sec) * 1000 + (tp->msec - r->start_msec)); ms = (ms >= 0) ? ms : 0; return ngx_sprintf(buf, "%T.%03M", ms / 1000, ms % 1000); 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 @@ -70,7 +70,7 @@ ngx_int_t ngx_http_not_modified_header_f * I think that the equality of the dates is correcter */ - if (ims != NGX_ERROR && ims == r->headers_out.last_modified_time) { + if (ims == r->headers_out.last_modified_time) { r->headers_out.status = NGX_HTTP_NOT_MODIFIED; r->headers_out.content_type.len = 0; ngx_http_clear_content_length(r); diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -860,7 +860,8 @@ ngx_http_proxy_process_status_line(ngx_h #endif r->http_version = NGX_HTTP_VERSION_9; - p->status = NGX_HTTP_OK; + u->headers_in.status_n = NGX_HTTP_OK; + u->state->status = NGX_HTTP_OK; return NGX_OK; } diff --git a/src/http/modules/ngx_http_range_filter_module.c b/src/http/modules/ngx_http_range_filter_module.c --- a/src/http/modules/ngx_http_range_filter_module.c +++ b/src/http/modules/ngx_http_range_filter_module.c @@ -134,6 +134,7 @@ ngx_http_range_header_filter(ngx_http_re u_char *p; size_t len; off_t start, end; + time_t if_range; ngx_int_t rc; ngx_uint_t suffix, i; ngx_atomic_uint_t boundary; @@ -156,18 +157,21 @@ ngx_http_range_header_filter(ngx_http_re (u_char *) "bytes=", 6) != 0) { - r->headers_out.accept_ranges = ngx_list_push(&r->headers_out.headers); - if (r->headers_out.accept_ranges == NULL) { - return NGX_ERROR; - } + goto next_filter; + } + + if (r->headers_in.if_range && r->headers_out.last_modified_time != -1) { + + if_range = ngx_http_parse_time(r->headers_in.if_range->value.data, + r->headers_in.if_range->value.len); - r->headers_out.accept_ranges->hash = 1; - r->headers_out.accept_ranges->key.len = sizeof("Accept-Ranges") - 1; - r->headers_out.accept_ranges->key.data = (u_char *) "Accept-Ranges"; - r->headers_out.accept_ranges->value.len = sizeof("bytes") - 1; - r->headers_out.accept_ranges->value.data = (u_char *) "bytes"; + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "http ir:%d lm:%d", + if_range, r->headers_out.last_modified_time); - return ngx_http_next_header_filter(r); + if (if_range != r->headers_out.last_modified_time) { + goto next_filter; + } } ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_range_filter_ctx_t)); @@ -461,6 +465,21 @@ ngx_http_range_header_filter(ngx_http_re } return ngx_http_next_header_filter(r); + +next_filter: + + r->headers_out.accept_ranges = ngx_list_push(&r->headers_out.headers); + if (r->headers_out.accept_ranges == NULL) { + return NGX_ERROR; + } + + r->headers_out.accept_ranges->hash = 1; + r->headers_out.accept_ranges->key.len = sizeof("Accept-Ranges") - 1; + r->headers_out.accept_ranges->key.data = (u_char *) "Accept-Ranges"; + r->headers_out.accept_ranges->value.len = sizeof("bytes") - 1; + r->headers_out.accept_ranges->value.data = (u_char *) "bytes"; + + return ngx_http_next_header_filter(r); } diff --git a/src/http/modules/ngx_http_userid_filter_module.c b/src/http/modules/ngx_http_userid_filter_module.c --- a/src/http/modules/ngx_http_userid_filter_module.c +++ b/src/http/modules/ngx_http_userid_filter_module.c @@ -318,7 +318,7 @@ ngx_http_userid_set_uid(ngx_http_request } else { ctx->uid_set[0] = conf->service; } - ctx->uid_set[1] = ngx_time(); + ctx->uid_set[1] = (uint32_t) ngx_time(); ctx->uid_set[2] = ngx_pid; ctx->uid_set[3] = sequencer_v1; sequencer_v1 += 0x100; @@ -345,7 +345,7 @@ ngx_http_userid_set_uid(ngx_http_request ctx->uid_set[0] = htonl(conf->service); } - ctx->uid_set[1] = htonl(ngx_time()); + ctx->uid_set[1] = htonl((uint32_t) ngx_time()); ctx->uid_set[2] = htonl(ngx_pid); ctx->uid_set[3] = htonl(sequencer_v2); sequencer_v2 += 0x100; 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.6.16'; +our $VERSION = '0.6.17'; require XSLoader; XSLoader::load('nginx', $VERSION); diff --git a/src/http/ngx_http_parse_time.c b/src/http/ngx_http_parse_time.c --- a/src/http/ngx_http_parse_time.c +++ b/src/http/ngx_http_parse_time.c @@ -11,7 +11,8 @@ static int mday[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; -time_t ngx_http_parse_time(u_char *value, size_t len) +time_t +ngx_http_parse_time(u_char *value, size_t len) { u_char *p, *end; int day, month, year, hour, min, sec; @@ -247,7 +248,7 @@ time_t ngx_http_parse_time(u_char *value year -= 1; } - /* Gauss's formula for Grigorian days from 1 March 1 BC */ + /* Gauss's formula for Grigorian days from March 1, 1 BC */ return (365 * year + year / 4 - year / 100 + year / 400 + 367 * month / 12 - 31 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 @@ -96,6 +96,10 @@ ngx_http_header_t ngx_http_headers_in[] { ngx_string("Range"), offsetof(ngx_http_headers_in_t, range), ngx_http_process_header_line }, + { ngx_string("If-Range"), + offsetof(ngx_http_headers_in_t, if_range), + ngx_http_process_unique_header_line }, + { ngx_string("Transfer-Encoding"), offsetof(ngx_http_headers_in_t, transfer_encoding), ngx_http_process_header_line }, @@ -2337,7 +2341,7 @@ ngx_http_lingering_close_handler(ngx_eve return; } - timer = r->lingering_time - ngx_time(); + timer = (ngx_msec_t) (r->lingering_time - ngx_time()); if (timer <= 0) { ngx_http_close_request(r, 0); return; 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 @@ -168,6 +168,7 @@ typedef struct { ngx_table_elt_t *content_type; ngx_table_elt_t *range; + ngx_table_elt_t *if_range; ngx_table_elt_t *transfer_encoding; diff --git a/src/http/ngx_http_request_body.c b/src/http/ngx_http_request_body.c --- a/src/http/ngx_http_request_body.c +++ b/src/http/ngx_http_request_body.c @@ -493,7 +493,7 @@ ngx_http_read_discarded_request_body_han } if (r->lingering_time) { - timer = r->lingering_time - ngx_time(); + timer = (ngx_msec_t) (r->lingering_time - ngx_time()); if (timer <= 0) { r->discard_body = 0; 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 @@ -2873,7 +2873,8 @@ ngx_http_upstream_response_time_variable for ( ;; ) { if (state[i].status) { - ms = state[i].response_sec * 1000 + state[i].response_msec; + ms = (ngx_msec_int_t) + (state[i].response_sec * 1000 + state[i].response_msec); ms = (ms >= 0) ? ms : 0; p = ngx_sprintf(p, "%d.%03d", ms / 1000, ms % 1000); diff --git a/src/mail/ngx_mail_auth_http_module.c b/src/mail/ngx_mail_auth_http_module.c --- a/src/mail/ngx_mail_auth_http_module.c +++ b/src/mail/ngx_mail_auth_http_module.c @@ -718,7 +718,7 @@ ngx_mail_auth_http_process_headers(ngx_m return; } - ngx_add_timer(s->connection->read, timer * 1000); + ngx_add_timer(s->connection->read, (ngx_msec_t) (timer * 1000)); s->connection->read->handler = ngx_mail_auth_sleep_handler; @@ -735,7 +735,7 @@ ngx_mail_auth_http_process_headers(ngx_m return; } - ngx_add_timer(s->connection->read, timer * 1000); + ngx_add_timer(s->connection->read, (ngx_msec_t) (timer * 1000)); s->connection->read->handler = ngx_mail_auth_sleep_handler;