# HG changeset patch # User Igor Sysoev # Date 1259528400 -10800 # Node ID 5c576ea5dbd969cb73e9c6672723eeb11ddda2ac # Parent 63dde5a94756ec3f5080f078b1b333f66cf433e6 nginx 0.8.29 *) Change: now the "009" status code is written to an access log for proxied HTTP/0.9 responses. *) Feature: the "addition_types", "charset_types", "gzip_types", "ssi_types", "sub_filter_types", and "xslt_types" directives support an "*" parameter. *) Feature: GCC 4.1+ built-in atomic operations usage. Thanks to W-Mark Kubacki. *) Feature: the --with-libatomic[=DIR] option in the configure. Thanks to W-Mark Kubacki. *) Bugfix: listen unix domain socket had limited access rights. *) Bugfix: cached HTTP/0.9 responses were handled incorrectly. *) Bugfix: regular expression named captures given by "?P<...>" did not work in a "server_name" directive. Thanks to Maxim Dounin. diff --git a/CHANGES b/CHANGES --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,28 @@ +Changes with nginx 0.8.29 30 Nov 2009 + + *) Change: now the "009" status code is written to an access log for + proxied HTTP/0.9 responses. + + *) Feature: the "addition_types", "charset_types", "gzip_types", + "ssi_types", "sub_filter_types", and "xslt_types" directives support + an "*" parameter. + + *) Feature: GCC 4.1+ built-in atomic operations usage. + Thanks to W-Mark Kubacki. + + *) Feature: the --with-libatomic[=DIR] option in the configure. + Thanks to W-Mark Kubacki. + + *) Bugfix: listen unix domain socket had limited access rights. + + *) Bugfix: cached HTTP/0.9 responses were handled incorrectly. + + *) Bugfix: regular expression named captures given by "?P<...>" did not + work in a "server_name" directive. + Thanks to Maxim Dounin. + + Changes with nginx 0.8.28 23 Nov 2009 *) Bugfix: nginx could not be built with the --without-pcre parameter; diff --git a/CHANGES.ru b/CHANGES.ru --- a/CHANGES.ru +++ b/CHANGES.ru @@ -1,4 +1,29 @@ +Изменения в nginx 0.8.29 30.11.2009 + + *) Изменение: теперь для проксируемых ответов HTTP/0.9 в лог пишется + код ответа "009". + + *) Добавление: директивы addition_types, charset_types, gzip_types, + ssi_types, sub_filter_types и xslt_types поддерживают параметр "*". + + *) Добавление: использование встроенных атомарных операций GCC 4.1+. + Спасибо W-Mark Kubacki. + + *) Добавление: параметр --with-libatomic[=DIR] в configure. + Спасибо W-Mark Kubacki. + + *) Исправление: listen unix domain сокет имели ограниченные права + доступа. + + *) Исправление: закэшированные ответы ответов HTTP/0.9 неправильно + обрабатывались. + + *) Исправление: именованные выделения в регулярных выражениях, заданные + как "?P<...>", не работали в директиве server_name. + Спасибо Максиму Дунину. + + Изменения в nginx 0.8.28 23.11.2009 *) Исправление: nginx не собирался с параметром --without-pcre; ошибка diff --git a/auto/cc/conf b/auto/cc/conf --- a/auto/cc/conf +++ b/auto/cc/conf @@ -104,7 +104,7 @@ else fi CFLAGS="$CFLAGS $NGX_CC_OPT" - +NGX_TEST_LD_OPT="$NGX_LD_OPT" if [ "$NGX_PLATFORM" != win32 ]; then @@ -125,6 +125,24 @@ if [ "$NGX_PLATFORM" != win32 ]; then fi fi + + ngx_feature="gcc builtin atomic operations" + ngx_feature_name=NGX_HAVE_GCC_ATOMIC + ngx_feature_run=yes + ngx_feature_incs= + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="long n = 0; + if (!__sync_bool_compare_and_swap(&n, 0, 1)) + return 1; + if (__sync_fetch_and_add(&n, 1) != 1) + return 1; + if (n != 2) + return 1; + __sync_synchronize();" + . auto/feature + + ngx_feature="gcc variadic macros" ngx_feature_name="NGX_HAVE_GCC_VARIADIC_MACROS" ngx_feature_run=yes diff --git a/auto/cc/gcc b/auto/cc/gcc --- a/auto/cc/gcc +++ b/auto/cc/gcc @@ -90,7 +90,6 @@ case $CPU in # build 32-bit UltraSparc binary CPU_OPT="-m32" CORE_LINK="$CORE_LINK -m32" - CC_AUX_FLAGS="$CC_AUX_FLAGS -m32" NGX_CPU_CACHE_LINE=64 ;; @@ -98,7 +97,6 @@ case $CPU in # build 64-bit UltraSparc binary CPU_OPT="-m64" CORE_LINK="$CORE_LINK -m64" - CC_AUX_FLAGS="$CC_AUX_FLAGS -m64" NGX_CPU_CACHE_LINE=64 ;; @@ -108,12 +106,12 @@ case $CPU in CPU_OPT="$CPU_OPT -falign-functions=32 -falign-labels=32" CPU_OPT="$CPU_OPT -falign-loops=32 -falign-jumps=32" CORE_LINK="$CORE_LINK -m64" - CC_AUX_FLAGS="$CC_AUX_FLAGS -m64" NGX_CPU_CACHE_LINE=128 ;; esac +CC_AUX_FLAGS="$CC_AUX_FLAGS $CPU_OPT" case "$NGX_GCC_VER" in 2.7*) diff --git a/auto/feature b/auto/feature --- a/auto/feature +++ b/auto/feature @@ -39,7 +39,7 @@ END ngx_test="$CC $CC_TEST_FLAGS $CC_AUX_FLAGS $ngx_feature_inc_path \ - -o $NGX_AUTOTEST $NGX_AUTOTEST.c $NGX_LD_OPT $ngx_feature_libs" + -o $NGX_AUTOTEST $NGX_AUTOTEST.c $NGX_TEST_LD_OPT $ngx_feature_libs" ngx_feature_inc_path= diff --git a/auto/lib/conf b/auto/lib/conf --- a/auto/lib/conf +++ b/auto/lib/conf @@ -70,6 +70,11 @@ fi if [ $HTTP_GEOIP = YES ]; then . auto/lib/geoip/conf fi + if [ $NGX_GOOGLE_PERFTOOLS = YES ]; then . auto/lib/google-perftools/conf fi + +if [ $NGX_LIBATOMIC != NO ]; then + . auto/lib/libatomic/conf +fi diff --git a/auto/lib/libatomic/conf b/auto/lib/libatomic/conf new file mode 100644 --- /dev/null +++ b/auto/lib/libatomic/conf @@ -0,0 +1,41 @@ + +# Copyright (C) Igor Sysoev + + +if [ $NGX_LIBATOMIC != YES ]; then + + have=NGX_HAVE_LIBATOMIC . auto/have + CORE_INCS="$CORE_INCS $NGX_LIBATOMIC/src" + LINK_DEPS="$LINK_DEPS $NGX_LIBATOMIC/src/libatomic_ops.a" + CORE_LIBS="$CORE_LIBS $NGX_LIBATOMIC/src/libatomic_ops.a" + +else + + ngx_feature="atomic_ops library" + ngx_feature_name=NGX_HAVE_LIBATOMIC + ngx_feature_run=yes + ngx_feature_incs="#include " + ngx_feature_path= + ngx_feature_libs="-latomic_ops" + ngx_feature_test="long n = 0; + if (!AO_compare_and_swap(&n, 0, 1)) + return 1; + if (AO_fetch_and_add(&n, 1) != 1) + return 1; + if (n != 2) + return 1; + AO_nop();" + . auto/feature + + if [ $ngx_found = yes ]; then + CORE_LIBS="$CORE_LIBS $ngx_feature_libs" + else + +cat << END + +$0: error: libatomic_ops library was not found. + +END + exit 1 + fi +fi diff --git a/auto/lib/libatomic/make b/auto/lib/libatomic/make new file mode 100644 --- /dev/null +++ b/auto/lib/libatomic/make @@ -0,0 +1,13 @@ + +# Copyright (C) Igor Sysoev + + + cat << END >> $NGX_MAKEFILE + +$NGX_LIBATOMIC/src/libatomic_ops.a: $NGX_LIBATOMIC/Makefile + cd $NGX_LIBATOMIC && make + +$NGX_LIBATOMIC/Makefile: $NGX_MAKEFILE + cd $NGX_LIBATOMIC && ./configure + +END diff --git a/auto/lib/make b/auto/lib/make --- a/auto/lib/make +++ b/auto/lib/make @@ -22,6 +22,10 @@ if [ $ZLIB != NONE -a $ZLIB != NO -a $ZL . auto/lib/zlib/make fi +if [ $NGX_LIBATOMIC != NO -a $NGX_LIBATOMIC != YES ]; then + . auto/lib/libatomic/make +fi + if [ $USE_PERL = YES ]; then . auto/lib/perl/make fi diff --git a/auto/options b/auto/options --- a/auto/options +++ b/auto/options @@ -132,6 +132,8 @@ USE_LIBGD=NO NGX_GOOGLE_PERFTOOLS=NO NGX_CPP_TEST=NO +NGX_LIBATOMIC=NO + NGX_CPU_CACHE_LINE= opt= @@ -266,6 +268,9 @@ do --with-zlib-opt=*) ZLIB_OPT="$value" ;; --with-zlib-asm=*) ZLIB_ASM="$value" ;; + --with-libatomic) NGX_LIBATOMIC=YES ;; + --with-libatomic=*) NGX_LIBATOMIC="$value" ;; + --test-build-devpoll) NGX_TEST_BUILD_DEVPOLL=YES ;; --test-build-eventport) NGX_TEST_BUILD_EVENTPORT=YES ;; --test-build-epoll) NGX_TEST_BUILD_EPOLL=YES ;; @@ -400,6 +405,9 @@ cat << END for specified CPU, the valid values: pentium, pentiumpro + --with-libatomic force libatomic_ops library usage + --with-libatomic=DIR set path to libatomic_ops library sources + --with-openssl=DIR set path to OpenSSL library sources --with-openssl-opt=OPTIONS set additional options for OpenSSL building 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 8028 -#define NGINX_VERSION "0.8.28" +#define nginx_version 8029 +#define NGINX_VERSION "0.8.29" #define NGINX_VER "nginx/" NGINX_VERSION #define NGINX_VAR "NGINX" diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c --- a/src/core/ngx_connection.c +++ b/src/core/ngx_connection.c @@ -374,12 +374,23 @@ ngx_open_listening_sockets(ngx_cycle_t * #if (NGX_HAVE_UNIX_DOMAIN) - if (ngx_test_config && ls[i].sockaddr->sa_family == AF_UNIX) { - u_char *name = ls[i].addr_text.data + sizeof("unix:") - 1; + if (ls[i].sockaddr->sa_family == AF_UNIX) { + mode_t mode; + u_char *name; + + name = ls[i].addr_text.data + sizeof("unix:") - 1; + mode = (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); - if (ngx_delete_file(name) == -1) { - ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno, - ngx_delete_file_n " %s failed", name); + if (chmod((char *) name, mode) == -1) { + ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, + "chmod() \"%s\" failed", name); + } + + if (ngx_test_config) { + if (ngx_delete_file(name) == -1) { + ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, + ngx_delete_file_n " %s failed", name); + } } } #endif diff --git a/src/event/ngx_event_connect.c b/src/event/ngx_event_connect.c --- a/src/event/ngx_event_connect.c +++ b/src/event/ngx_event_connect.c @@ -101,22 +101,17 @@ ngx_event_connect_peer(ngx_peer_connecti pc->connection = c; - /* - * TODO: MT: - ngx_atomic_fetch_add() - * or protection by critical section or mutex - * - * TODO: MP: - allocated in a shared memory - * - ngx_atomic_fetch_add() - * or protection by critical section or mutex - */ - c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1); #if (NGX_THREADS) + + /* TODO: lock event when call completion handler */ + rev->lock = pc->lock; wev->lock = pc->lock; rev->own_lock = &c->lock; wev->own_lock = &c->lock; + #endif if (ngx_add_conn) { diff --git a/src/http/modules/ngx_http_addition_filter_module.c b/src/http/modules/ngx_http_addition_filter_module.c --- a/src/http/modules/ngx_http_addition_filter_module.c +++ b/src/http/modules/ngx_http_addition_filter_module.c @@ -237,8 +237,8 @@ ngx_http_addition_merge_conf(ngx_conf_t ngx_conf_merge_str_value(conf->before_body, prev->before_body, ""); ngx_conf_merge_str_value(conf->after_body, prev->after_body, ""); - if (ngx_http_merge_types(cf, conf->types_keys, &conf->types, - prev->types_keys, &prev->types, + if (ngx_http_merge_types(cf, &conf->types_keys, &conf->types, + &prev->types_keys, &prev->types, ngx_http_html_default_types) != NGX_OK) { diff --git a/src/http/modules/ngx_http_charset_filter_module.c b/src/http/modules/ngx_http_charset_filter_module.c --- a/src/http/modules/ngx_http_charset_filter_module.c +++ b/src/http/modules/ngx_http_charset_filter_module.c @@ -1550,8 +1550,8 @@ ngx_http_charset_merge_loc_conf(ngx_conf ngx_http_charset_recode_t *recode; ngx_http_charset_main_conf_t *mcf; - if (ngx_http_merge_types(cf, conf->types_keys, &conf->types, - prev->types_keys, &prev->types, + if (ngx_http_merge_types(cf, &conf->types_keys, &conf->types, + &prev->types_keys, &prev->types, ngx_http_charset_default_types) != NGX_OK) { 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 @@ -1123,8 +1123,8 @@ ngx_http_gzip_merge_conf(ngx_conf_t *cf, MAX_MEM_LEVEL - 1); ngx_conf_merge_value(conf->min_length, prev->min_length, 20); - if (ngx_http_merge_types(cf, conf->types_keys, &conf->types, - prev->types_keys, &prev->types, + if (ngx_http_merge_types(cf, &conf->types_keys, &conf->types, + &prev->types_keys, &prev->types, ngx_http_html_default_types) != NGX_OK) { 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 @@ -542,8 +542,25 @@ ngx_http_log_request_time(ngx_http_reque static u_char * ngx_http_log_status(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op) { - return ngx_sprintf(buf, "%ui", - r->err_status ? r->err_status : r->headers_out.status); + ngx_uint_t status; + + if (r->err_status) { + status = r->err_status; + + } else if (r->headers_out.status) { + status = r->headers_out.status; + + } else if (r->http_version == NGX_HTTP_VERSION_9) { + *buf++ = '0'; + *buf++ = '0'; + *buf++ = '9'; + return buf; + + } else { + status = 0; + } + + return ngx_sprintf(buf, "%ui", status); } 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 @@ -1230,7 +1230,6 @@ ngx_http_proxy_process_status_line(ngx_h if (r->cache) { r->http_version = NGX_HTTP_VERSION_9; - u->headers_in.status_n = NGX_HTTP_OK; return NGX_OK; } @@ -1246,7 +1245,6 @@ ngx_http_proxy_process_status_line(ngx_h #endif r->http_version = NGX_HTTP_VERSION_9; - 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_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 @@ -2773,8 +2773,8 @@ ngx_http_ssi_merge_loc_conf(ngx_conf_t * ngx_conf_merge_size_value(conf->min_file_chunk, prev->min_file_chunk, 1024); ngx_conf_merge_size_value(conf->value_len, prev->value_len, 256); - if (ngx_http_merge_types(cf, conf->types_keys, &conf->types, - prev->types_keys, &prev->types, + if (ngx_http_merge_types(cf, &conf->types_keys, &conf->types, + &prev->types_keys, &prev->types, ngx_http_html_default_types) != NGX_OK) { diff --git a/src/http/modules/ngx_http_sub_filter_module.c b/src/http/modules/ngx_http_sub_filter_module.c --- a/src/http/modules/ngx_http_sub_filter_module.c +++ b/src/http/modules/ngx_http_sub_filter_module.c @@ -671,8 +671,8 @@ ngx_http_sub_merge_conf(ngx_conf_t *cf, conf->value = prev->value; } - if (ngx_http_merge_types(cf, conf->types_keys, &conf->types, - prev->types_keys, &prev->types, + if (ngx_http_merge_types(cf, &conf->types_keys, &conf->types, + &prev->types_keys, &prev->types, ngx_http_html_default_types) != NGX_OK) { diff --git a/src/http/modules/ngx_http_xslt_filter_module.c b/src/http/modules/ngx_http_xslt_filter_module.c --- a/src/http/modules/ngx_http_xslt_filter_module.c +++ b/src/http/modules/ngx_http_xslt_filter_module.c @@ -1230,8 +1230,8 @@ ngx_http_xslt_filter_merge_conf(ngx_conf conf->sheets = prev->sheets; } - if (ngx_http_merge_types(cf, conf->types_keys, &conf->types, - prev->types_keys, &prev->types, + if (ngx_http_merge_types(cf, &conf->types_keys, &conf->types, + &prev->types_keys, &prev->types, ngx_http_xslt_default_types) != 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.28'; +our $VERSION = '0.8.29'; require XSLoader; XSLoader::load('nginx', $VERSION); diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c --- a/src/http/ngx_http.c +++ b/src/http/ngx_http.c @@ -1854,6 +1854,10 @@ ngx_http_types_slot(ngx_conf_t *cf, ngx_ types = (ngx_array_t **) (p + cmd->offset); + if (*types == (void *) -1) { + return NGX_CONF_OK; + } + default_type = cmd->post; if (*types == NULL) { @@ -1879,6 +1883,11 @@ ngx_http_types_slot(ngx_conf_t *cf, ngx_ for (i = 1; i < cf->args->nelts; i++) { + if (value[i].len == 1 && value[i].data[0] == '*') { + *types = (void *) -1; + return NGX_CONF_OK; + } + hash = ngx_hash_strlow(value[i].data, value[i].data, value[i].len); value[i].data[value[i].len] = '\0'; @@ -1907,13 +1916,17 @@ ngx_http_types_slot(ngx_conf_t *cf, ngx_ char * -ngx_http_merge_types(ngx_conf_t *cf, ngx_array_t *keys, ngx_hash_t *types_hash, - ngx_array_t *prev_keys, ngx_hash_t *prev_types_hash, +ngx_http_merge_types(ngx_conf_t *cf, ngx_array_t **keys, ngx_hash_t *types_hash, + ngx_array_t **prev_keys, ngx_hash_t *prev_types_hash, ngx_str_t *default_types) { ngx_hash_init_t hash; - if (keys) { + if (*keys) { + + if (*keys == (void *) -1) { + return NGX_CONF_OK; + } hash.hash = types_hash; hash.key = NULL; @@ -1923,7 +1936,7 @@ ngx_http_merge_types(ngx_conf_t *cf, ngx hash.pool = cf->pool; hash.temp_pool = NULL; - if (ngx_hash_init(&hash, keys->elts, keys->nelts) != NGX_OK) { + if (ngx_hash_init(&hash, (*keys)->elts, (*keys)->nelts) != NGX_OK) { return NGX_CONF_ERROR; } @@ -1932,13 +1945,17 @@ ngx_http_merge_types(ngx_conf_t *cf, ngx if (prev_types_hash->buckets == NULL) { - if (prev_keys == NULL) { + if (*prev_keys == NULL) { - if (ngx_http_set_default_types(cf, &prev_keys, default_types) + if (ngx_http_set_default_types(cf, prev_keys, default_types) != NGX_OK) { return NGX_CONF_ERROR; } + + } else if (*prev_keys == (void *) -1) { + *keys = *prev_keys; + return NGX_CONF_OK; } hash.hash = prev_types_hash; @@ -1949,7 +1966,9 @@ ngx_http_merge_types(ngx_conf_t *cf, ngx hash.pool = cf->pool; hash.temp_pool = NULL; - if (ngx_hash_init(&hash, prev_keys->elts, prev_keys->nelts) != NGX_OK) { + if (ngx_hash_init(&hash, (*prev_keys)->elts, (*prev_keys)->nelts) + != NGX_OK) + { return NGX_CONF_ERROR; } } diff --git a/src/http/ngx_http.h b/src/http/ngx_http.h --- a/src/http/ngx_http.h +++ b/src/http/ngx_http.h @@ -126,9 +126,9 @@ void ngx_http_test_reading(ngx_http_requ char *ngx_http_types_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); -char *ngx_http_merge_types(ngx_conf_t *cf, ngx_array_t *keys, - ngx_hash_t *types_hash, ngx_array_t *prev_keys, ngx_hash_t *prev_types_hash, - ngx_str_t *default_types); +char *ngx_http_merge_types(ngx_conf_t *cf, ngx_array_t **keys, + ngx_hash_t *types_hash, ngx_array_t **prev_keys, + ngx_hash_t *prev_types_hash, ngx_str_t *default_types); ngx_int_t ngx_http_set_default_types(ngx_conf_t *cf, ngx_array_t **types, ngx_str_t *default_type); 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 @@ -1572,6 +1572,10 @@ ngx_http_test_content_type(ngx_http_requ size_t len; ngx_uint_t i, hash; + if (types_hash->size == 0) { + return (void *) 4; + } + if (r->headers_out.content_type.len == 0) { return NULL; } @@ -3507,16 +3511,16 @@ ngx_http_core_server_name(ngx_conf_t *cf sn->server = cscf; sn->name = value[i]; - ngx_strlow(sn->name.data, sn->name.data, sn->name.len); - if (value[i].data[0] != '~') { + ngx_strlow(sn->name.data, sn->name.data, sn->name.len); continue; } #if (NGX_PCRE) { - ngx_regex_compile_t rc; - u_char errstr[NGX_MAX_CONF_ERRSTR]; + u_char *p; + ngx_regex_compile_t rc; + u_char errstr[NGX_MAX_CONF_ERRSTR]; if (value[i].len == 1) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, @@ -3533,6 +3537,13 @@ ngx_http_core_server_name(ngx_conf_t *cf rc.err.len = NGX_MAX_CONF_ERRSTR; rc.err.data = errstr; + for (p = value[i].data; p < value[i].data + value[i].len; p++) { + if (*p >= 'A' && *p <= 'Z') { + rc.options = NGX_REGEX_CASELESS; + break; + } + } + sn->regex = ngx_http_regex_compile(cf, &rc); if (sn->regex == NULL) { return NGX_CONF_ERROR; 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 @@ -338,7 +338,7 @@ ngx_http_file_cache_read(ngx_http_reques return n; } - if ((size_t) n <= c->header_start) { + if ((size_t) n < c->header_start) { ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0, "cache file \"%s\" is too small", c->file.name.data); return NGX_ERROR; 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 @@ -752,6 +752,11 @@ ngx_http_upstream_cache_send(ngx_http_re r->cached = 1; c = r->cache; + if (c->header_start == c->body_start) { + r->http_version = NGX_HTTP_VERSION_9; + return ngx_http_cache_send(r); + } + /* TODO: cache stack */ u->buffer = *c->buf; diff --git a/src/os/unix/ngx_atomic.h b/src/os/unix/ngx_atomic.h --- a/src/os/unix/ngx_atomic.h +++ b/src/os/unix/ngx_atomic.h @@ -12,7 +12,31 @@ #include -#if (NGX_DARWIN_ATOMIC) +#if (NGX_HAVE_LIBATOMIC) + +#include + +#define NGX_HAVE_ATOMIC_OPS 1 + +typedef long ngx_atomic_int_t; +typedef AO_t ngx_atomic_uint_t; +typedef volatile ngx_atomic_uint_t ngx_atomic_t; + +#if (NGX_PTR_SIZE == 8) +#define NGX_ATOMIC_T_LEN (sizeof("-9223372036854775808") - 1) +#else +#define NGX_ATOMIC_T_LEN (sizeof("-2147483648") - 1) +#endif + +#define ngx_atomic_cmp_set(lock, old, new) \ + AO_compare_and_swap(lock, old, new) +#define ngx_atomic_fetch_add(value, add) \ + AO_fetch_and_add(value, add) +#define ngx_memory_barrier() AO_nop() +#define ngx_cpu_pause() + + +#elif (NGX_DARWIN_ATOMIC) /* * use Darwin 8 atomic(3) and barrier(3) operations @@ -60,10 +84,40 @@ typedef uint32_t ngx_ typedef volatile ngx_atomic_uint_t ngx_atomic_t; -#else /* !(NGX_DARWIN) */ +#elif (NGX_HAVE_GCC_ATOMIC) + +/* GCC 4.1 builtin atomic operations */ + +#define NGX_HAVE_ATOMIC_OPS 1 + +typedef long ngx_atomic_int_t; +typedef unsigned long ngx_atomic_uint_t; + +#if (NGX_PTR_SIZE == 8) +#define NGX_ATOMIC_T_LEN (sizeof("-9223372036854775808") - 1) +#else +#define NGX_ATOMIC_T_LEN (sizeof("-2147483648") - 1) +#endif + +typedef volatile ngx_atomic_uint_t ngx_atomic_t; -#if ( __i386__ || __i386 ) +#define ngx_atomic_cmp_set(lock, old, set) \ + __sync_bool_compare_and_swap(lock, old, set) + +#define ngx_atomic_fetch_add(value, add) \ + __sync_fetch_and_add(value, add) + +#define ngx_memory_barrier() __sync_synchronize() + +#if ( __i386__ || __i386 || __amd64__ || __amd64 ) +#define ngx_cpu_pause() __asm__ ("pause") +#else +#define ngx_cpu_pause() +#endif + + +#elif ( __i386__ || __i386 ) typedef int32_t ngx_atomic_int_t; typedef uint32_t ngx_atomic_uint_t; @@ -203,9 +257,6 @@ typedef volatile ngx_atomic_uint_t ngx_ #include "ngx_gcc_atomic_ppc.h" - -#endif - #endif diff --git a/src/os/unix/ngx_gcc_atomic_x86.h b/src/os/unix/ngx_gcc_atomic_x86.h --- a/src/os/unix/ngx_gcc_atomic_x86.h +++ b/src/os/unix/ngx_gcc_atomic_x86.h @@ -122,5 +122,5 @@ ngx_atomic_fetch_add(ngx_atomic_t *value #define ngx_memory_barrier() __asm__ volatile ("" ::: "memory") -/* old as does not support "pause" opcode */ +/* old "as" does not support "pause" opcode */ #define ngx_cpu_pause() __asm__ (".byte 0xf3, 0x90")