changeset 628:83b58b182b76 NGINX_1_0_4

nginx 1.0.4 *) Change: now regular expressions case sensitivity in the "map" directive is given by prefixes "~" or "~*". *) Feature: now shared zones and caches use POSIX semaphores on Linux. Thanks to Denis F. Latypoff. *) Bugfix: "stalled" cache updating" alert. *) Bugfix: nginx could not be built --without-http_auth_basic_module; the bug had appeared in 1.0.3.
author Igor Sysoev <http://sysoev.ru>
date Wed, 01 Jun 2011 00:00:00 +0400
parents a63a292c61af
children 1c167244d2fd
files CHANGES CHANGES.ru auto/os/features auto/threads auto/unix configure src/core/nginx.h src/core/ngx_crypt.c src/core/ngx_md5.c src/core/ngx_md5.h src/http/modules/ngx_http_map_module.c src/http/modules/perl/nginx.pm src/http/ngx_http_upstream.c src/http/ngx_http_variables.c src/http/ngx_http_variables.h
diffstat 15 files changed, 456 insertions(+), 460 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,18 @@
 
+Changes with nginx 1.0.4                                         01 Jun 2011
+
+    *) Change: now regular expressions case sensitivity in the "map" 
+       directive is given by prefixes "~" or "~*".
+
+    *) Feature: now shared zones and caches use POSIX semaphores on Linux. 
+       Thanks to Denis F. Latypoff.
+
+    *) Bugfix: "stalled" cache updating" alert.
+
+    *) Bugfix: nginx could not be built --without-http_auth_basic_module; 
+       the bug had appeared in 1.0.3.
+
+
 Changes with nginx 1.0.3                                         25 May 2011
 
     *) Feature: the "auth_basic_user_file" directive supports "$apr1", 
@@ -15,7 +29,7 @@ Changes with nginx 1.0.3                
        testing IPv4 address mapped to IPv6 address, if access or deny rules 
        were defined only for IPv6; the bug had appeared in 0.8.22.
 
-    *) Bugfix: a cached reponse may be broken if proxy/fastcgi/scgi/ 
+    *) Bugfix: a cached response may be broken if proxy/fastcgi/scgi/ 
        uwsgi_cache_bypass and proxy/fastcgi/scgi/uwsgi_no_cache directive 
        values were different; the bug had appeared in 0.8.46.
 
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,19 @@
 
+Изменения в nginx 1.0.4                                           01.06.2011
+
+    *) Изменение: теперь в регулярных выражениях в директиве map можно 
+       задать чувствительность к регистру с помощью префиксов "~" и "~*".
+
+    *) Добавление: теперь разделяемые зоны и кэши используют семафоры POSIX 
+       на Linux.
+       Спасибо Денису Латыпову.
+
+    *) Исправление: сообщения "stalled cache updating".
+
+    *) Исправление: nginx не собирался с параметром 
+       --without-http_auth_basic_module; ошибка появилась в 1.0.3.
+
+
 Изменения в nginx 1.0.3                                           25.05.2011
 
     *) Добавление: директива auth_basic_user_file поддерживает шифрование 
deleted file mode 100644
--- a/auto/os/features
+++ /dev/null
@@ -1,363 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-
-
-NGX_USER=${NGX_USER:-nobody}
-
-if [ -z "$NGX_GROUP" ]; then
-    if [ $NGX_USER = nobody ]; then
-        if grep nobody /etc/group 2>&1 >/dev/null; then
-            echo "checking for nobody group ... found"
-            NGX_GROUP=nobody
-        else
-            echo "checking for nobody group ... not found"
-
-            if grep nogroup /etc/group 2>&1 >/dev/null; then
-                echo "checking for nogroup group ... found"
-                NGX_GROUP=nogroup
-            else
-                echo "checking for nogroup group ... not found"
-                NGX_GROUP=nobody
-            fi
-        fi
-    else
-        NGX_GROUP=$NGX_USER
-    fi
-fi
-
-
-ngx_feature="poll()"
-ngx_feature_name=
-ngx_feature_run=no
-ngx_feature_incs="#include <poll.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="int  n, dp; struct pollfd  pl;
-                  dp = 0;
-                  pl.fd = 0;
-                  pl.events = 0;
-                  pl.revents = 0;
-                  n = poll(&pl, 1, 0)"
-. auto/feature
-
-if [ $ngx_found = no ]; then
-    EVENT_POLL=NONE
-fi
-
-
-ngx_feature="/dev/poll"
-ngx_feature_name="NGX_HAVE_DEVPOLL"
-ngx_feature_run=no
-ngx_feature_incs="#include <sys/devpoll.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="int  n, dp; struct dvpoll  dvp;
-                  dp = 0;
-                  dvp.dp_fds = NULL;
-                  dvp.dp_nfds = 0;
-                  dvp.dp_timeout = 0;
-                  n = ioctl(dp, DP_POLL, &dvp)"
-. auto/feature
-
-if [ $ngx_found = yes ]; then
-    CORE_SRCS="$CORE_SRCS $DEVPOLL_SRCS"
-    EVENT_MODULES="$EVENT_MODULES $DEVPOLL_MODULE"
-    EVENT_FOUND=YES
-fi
-
-
-if test -z "$NGX_KQUEUE_CHECKED"; then
-    ngx_feature="kqueue"
-    ngx_feature_name="NGX_HAVE_KQUEUE"
-    ngx_feature_run=no
-    ngx_feature_incs="#include <sys/event.h>"
-    ngx_feature_path=
-    ngx_feature_libs=
-    ngx_feature_test="int kq; kq = kqueue()"
-    . auto/feature
-
-    if [ $ngx_found = yes ]; then
-
-        have=NGX_HAVE_CLEAR_EVENT . auto/have
-        EVENT_MODULES="$EVENT_MODULES $KQUEUE_MODULE"
-        CORE_SRCS="$CORE_SRCS $KQUEUE_SRCS"
-        EVENT_FOUND=YES
-
-        ngx_feature="kqueue's NOTE_LOWAT"
-        ngx_feature_name="NGX_HAVE_LOWAT_EVENT"
-        ngx_feature_run=no
-        ngx_feature_incs="#include <sys/event.h>"
-        ngx_feature_path=
-        ngx_feature_libs=
-        ngx_feature_test="struct kevent  kev;
-                          kev.fflags = NOTE_LOWAT;"
-        . auto/feature
-
-
-        ngx_feature="kqueue's EVFILT_TIMER"
-        ngx_feature_name="NGX_HAVE_TIMER_EVENT"
-        ngx_feature_run=yes
-        ngx_feature_incs="#include <sys/event.h>
-                          #include <sys/time.h>"
-        ngx_feature_path=
-        ngx_feature_libs=
-        ngx_feature_test="int      kq;
-                  struct kevent    kev;
-                  struct timespec  ts;
-
-                  if ((kq = kqueue()) == -1) return 1;
-
-                  kev.ident = 0;
-                  kev.filter = EVFILT_TIMER;
-                  kev.flags = EV_ADD|EV_ENABLE;
-                  kev.fflags = 0;
-                  kev.data = 1000;
-                  kev.udata = 0;
-
-                  ts.tv_sec = 0;
-                  ts.tv_nsec = 0;
-
-                  if (kevent(kq, &kev, 1, &kev, 1, &ts) == -1) return 1;
-
-                  if (kev.flags & EV_ERROR) return 1;"
-
-        . auto/feature
-    fi
-fi
-
-
-if [ "$NGX_SYSTEM" = "NetBSD" ]; then
-
-    # NetBSD 2.0 incompatibly defines kevent.udata as "intptr_t"
-
-    cat << END >> $NGX_AUTO_CONFIG_H
-
-#define NGX_KQUEUE_UDATA_T
-
-END
-
-else
-    cat << END >> $NGX_AUTO_CONFIG_H
-
-#define NGX_KQUEUE_UDATA_T  (void *)
-
-END
-
-fi
-
-
-ngx_feature="crypt()"
-ngx_feature_name=
-ngx_feature_run=no
-ngx_feature_incs=
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="crypt(\"test\", \"salt\");"
-. auto/feature
-
-
-if [ $ngx_found = no ]; then
-
-    ngx_feature="crypt() in libcrypt"
-    ngx_feature_name=
-    ngx_feature_run=no
-    ngx_feature_incs=
-    ngx_feature_path=
-    ngx_feature_libs=-lcrypt
-    . auto/feature
-
-    if [ $ngx_found = yes ]; then
-        CRYPT_LIB="-lcrypt"
-    fi
-fi
-
-
-ngx_feature="F_READAHEAD"
-ngx_feature_name="NGX_HAVE_F_READAHEAD"
-ngx_feature_run=no
-ngx_feature_incs="#include <fcntl.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="fcntl(0, F_READAHEAD, 1);"
-. auto/feature
-
-
-ngx_feature="posix_fadvise()"
-ngx_feature_name="NGX_HAVE_POSIX_FADVISE"
-ngx_feature_run=no
-ngx_feature_incs="#include <fcntl.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="posix_fadvise(0, 0, 0, POSIX_FADV_SEQUENTIAL);"
-. auto/feature
-
-
-ngx_feature="O_DIRECT"
-ngx_feature_name="NGX_HAVE_O_DIRECT"
-ngx_feature_run=no
-ngx_feature_incs="#include <fcntl.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="fcntl(0, F_SETFL, O_DIRECT);"
-. auto/feature
-
-
-if [ $ngx_found = yes -a "$NGX_SYSTEM" = "Linux" ]; then
-    have=NGX_HAVE_ALIGNED_DIRECTIO . auto/have
-fi
-
-ngx_feature="F_NOCACHE"
-ngx_feature_name="NGX_HAVE_F_NOCACHE"
-ngx_feature_run=no
-ngx_feature_incs="#include <fcntl.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="fcntl(0, F_NOCACHE, 1);"
-. auto/feature
-
-
-ngx_feature="directio()"
-ngx_feature_name="NGX_HAVE_DIRECTIO"
-ngx_feature_run=no
-ngx_feature_incs="#include <sys/types.h>
-                  #include <sys/fcntl.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="directio(0, DIRECTIO_ON);"
-. auto/feature
-
-
-ngx_feature="statfs()"
-ngx_feature_name="NGX_HAVE_STATFS"
-ngx_feature_run=no
-ngx_feature_incs="$NGX_INCLUDE_SYS_PARAM_H
-                  $NGX_INCLUDE_SYS_MOUNT_H
-                  $NGX_INCLUDE_SYS_VFS_H"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="struct statfs  fs;
-                  statfs(NULL, &fs);"
-. auto/feature
-
-
-ngx_feature="statvfs()"
-ngx_feature_name="NGX_HAVE_STATVFS"
-ngx_feature_run=no
-ngx_feature_incs="#include <sys/types.h>
-                  #include <sys/statvfs.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="struct statvfs  fs;
-                  statvfs(NULL, &fs);"
-. auto/feature
-
-
-ngx_feature="dlopen()"
-ngx_feature_name=
-ngx_feature_run=no
-ngx_feature_incs="#include <dlfcn.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="dlopen(NULL, 0)"
-. auto/feature
-
-
-if [ $ngx_found != yes ]; then
-
-    ngx_feature="dlopen() in libdl"
-    ngx_feature_libs="-ldl"
-    . auto/feature
-
-    if [ $ngx_found = yes ]; then
-        NGX_LIBDL="-ldl"
-    fi
-fi
-
-
-ngx_feature="sched_yield()"
-ngx_feature_name="NGX_HAVE_SCHED_YIELD"
-ngx_feature_run=no
-ngx_feature_incs="#include <sched.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="sched_yield()"
-. auto/feature
-
-
-if [ $ngx_found != yes ]; then
-
-    ngx_feature="sched_yield() in librt"
-    ngx_feature_libs="-lrt"
-    . auto/feature
-
-    if [ $ngx_found = yes ]; then
-        CORE_LIBS="$CORE_LIBS -lrt"
-    fi
-fi
-
-ngx_feature="SO_SETFIB"
-ngx_feature_name="NGX_HAVE_SETFIB"
-ngx_feature_run=no
-ngx_feature_incs="#include <sys/socket.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="setsockopt(0, SOL_SOCKET, SO_SETFIB, NULL, 4)"
-. auto/feature
-
-
-ngx_feature="accept4()"
-ngx_feature_name="NGX_HAVE_ACCEPT4"
-ngx_feature_run=no
-ngx_feature_incs="#include <sys/socket.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="accept4(0, NULL, NULL, SOCK_NONBLOCK)"
-. auto/feature
-
-if [ $NGX_FILE_AIO = YES ]; then
-
-    ngx_feature="kqueue AIO support"
-    ngx_feature_name="NGX_HAVE_FILE_AIO"
-    ngx_feature_run=no
-    ngx_feature_incs="#include <aio.h>"
-    ngx_feature_path=
-    ngx_feature_libs=
-    ngx_feature_test="int  n; struct aiocb  iocb;
-                      iocb.aio_sigevent.sigev_notify = SIGEV_KEVENT;
-                      n = aio_read(&iocb)"
-    . auto/feature
-
-    if [ $ngx_found = yes ]; then
-        CORE_SRCS="$CORE_SRCS $FILE_AIO_SRCS"
-
-    elif [ $ngx_found = no ]; then
-
-        ngx_feature="Linux AIO support"
-        ngx_feature_name="NGX_HAVE_FILE_AIO"
-        ngx_feature_run=no
-        ngx_feature_incs="#include <linux/aio_abi.h>
-                          #include <sys/syscall.h>"
-        ngx_feature_path=
-        ngx_feature_libs=
-        ngx_feature_test="int  n = SYS_eventfd;
-                          struct iocb  iocb;
-                          iocb.aio_lio_opcode = IOCB_CMD_PREAD;
-                          iocb.aio_flags = IOCB_FLAG_RESFD;
-                          iocb.aio_resfd = -1;"
-        . auto/feature
-
-        if [ $ngx_found = yes ]; then
-            have=NGX_HAVE_EVENTFD . auto/have
-            CORE_SRCS="$CORE_SRCS $LINUX_AIO_SRCS"
-
-        else
-            cat << END
-
-$0: no supported file AIO was found
-Currently file AIO is supported on FreeBSD 4.3+ and Linux 2.6.22+ only
-
-END
-           exit 1
-        fi
-    fi
-fi
deleted file mode 100644
--- a/auto/threads
+++ /dev/null
@@ -1,70 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-
-
-case $USE_THREADS in
-    rfork)
-        have=NGX_THREADS . auto/have
-        have=NGX_USE_RFORK . auto/have
-        CORE_DEPS="$CORE_DEPS $FREEBSD_RFORK_DEPS"
-        CORE_SRCS="$CORE_SRCS $FREEBSD_RFORK_SRCS"
-
-        case "$NGX_PLATFORM" in
-            *:i386)
-                if [ \( $version -gt 500000 -a $version -lt 501000 \) \
-                     -o $version -lt 491000 ]
-                then
-                    CORE_SRCS="$CORE_SRCS $FREEBSD_RFORK_THREAD_SRCS"
-                fi
-            ;;
-        esac
-    ;;
-
-    pthreads)
-        have=NGX_THREADS . auto/have
-        CORE_SRCS="$CORE_SRCS $PTHREAD_SRCS"
-        CORE_LIBS="$CORE_LIBS -lpthread"
-    ;;
-
-    libthr)
-        have=NGX_THREADS . auto/have
-        CORE_SRCS="$CORE_SRCS $PTHREAD_SRCS"
-        CORE_LIBS="$CORE_LIBS -lthr"
-    ;;
-
-    linuxthreads)
-        have=NGX_THREADS . auto/have
-        have=NGX_LINUXTHREADS . auto/have
-        CFLAGS="$CFLAGS -D_THREAD_SAFE"
-        CFLAGS="$CFLAGS -I /usr/local/include/pthread/linuxthreads"
-        CORE_SRCS="$CORE_SRCS $PTHREAD_SRCS"
-        CORE_LIBS="$CORE_LIBS -L /usr/local/lib -llthread -llgcc_r"
-    ;;
-
-    libc_r)
-        case "$NGX_PLATFORM" in
-            FreeBSD:[34]*)
-                have=NGX_THREADS . auto/have
-                CFLAGS="$CFLAGS -pthread"
-                CORE_SRCS="$CORE_SRCS $PTHREAD_SRCS"
-                CORE_LIBS="$CORE_LIBS -pthread"
-            ;;
-
-            FreeBSD:[56]*)
-                have=NGX_THREADS . auto/have
-                CORE_SRCS="$CORE_SRCS $PTHREAD_SRCS"
-                CORE_LIBS="$CORE_LIBS -lc_r"
-            ;;
-        esac
-    ;;
-
-    NO)
-    ;;
-
-    *)
-        have=NGX_THREADS . auto/have
-        CORE_SRCS="$CORE_SRCS $PTHREAD_SRCS"
-        CORE_LIBS="$CORE_LIBS -l$USE_THREADS"
-    ;;
-
-esac
--- a/auto/unix
+++ b/auto/unix
@@ -2,6 +2,367 @@
 # Copyright (C) Igor Sysoev
 
 
+NGX_USER=${NGX_USER:-nobody}
+
+if [ -z "$NGX_GROUP" ]; then
+    if [ $NGX_USER = nobody ]; then
+        if grep nobody /etc/group 2>&1 >/dev/null; then
+            echo "checking for nobody group ... found"
+            NGX_GROUP=nobody
+        else
+            echo "checking for nobody group ... not found"
+
+            if grep nogroup /etc/group 2>&1 >/dev/null; then
+                echo "checking for nogroup group ... found"
+                NGX_GROUP=nogroup
+            else
+                echo "checking for nogroup group ... not found"
+                NGX_GROUP=nobody
+            fi
+        fi
+    else
+        NGX_GROUP=$NGX_USER
+    fi
+fi
+
+
+ngx_feature="poll()"
+ngx_feature_name=
+ngx_feature_run=no
+ngx_feature_incs="#include <poll.h>"
+ngx_feature_path=
+ngx_feature_libs=
+ngx_feature_test="int  n, dp; struct pollfd  pl;
+                  dp = 0;
+                  pl.fd = 0;
+                  pl.events = 0;
+                  pl.revents = 0;
+                  n = poll(&pl, 1, 0)"
+. auto/feature
+
+if [ $ngx_found = no ]; then
+    EVENT_POLL=NONE
+fi
+
+
+ngx_feature="/dev/poll"
+ngx_feature_name="NGX_HAVE_DEVPOLL"
+ngx_feature_run=no
+ngx_feature_incs="#include <sys/devpoll.h>"
+ngx_feature_path=
+ngx_feature_libs=
+ngx_feature_test="int  n, dp; struct dvpoll  dvp;
+                  dp = 0;
+                  dvp.dp_fds = NULL;
+                  dvp.dp_nfds = 0;
+                  dvp.dp_timeout = 0;
+                  n = ioctl(dp, DP_POLL, &dvp)"
+. auto/feature
+
+if [ $ngx_found = yes ]; then
+    CORE_SRCS="$CORE_SRCS $DEVPOLL_SRCS"
+    EVENT_MODULES="$EVENT_MODULES $DEVPOLL_MODULE"
+    EVENT_FOUND=YES
+fi
+
+
+if test -z "$NGX_KQUEUE_CHECKED"; then
+    ngx_feature="kqueue"
+    ngx_feature_name="NGX_HAVE_KQUEUE"
+    ngx_feature_run=no
+    ngx_feature_incs="#include <sys/event.h>"
+    ngx_feature_path=
+    ngx_feature_libs=
+    ngx_feature_test="int kq; kq = kqueue()"
+    . auto/feature
+
+    if [ $ngx_found = yes ]; then
+
+        have=NGX_HAVE_CLEAR_EVENT . auto/have
+        EVENT_MODULES="$EVENT_MODULES $KQUEUE_MODULE"
+        CORE_SRCS="$CORE_SRCS $KQUEUE_SRCS"
+        EVENT_FOUND=YES
+
+        ngx_feature="kqueue's NOTE_LOWAT"
+        ngx_feature_name="NGX_HAVE_LOWAT_EVENT"
+        ngx_feature_run=no
+        ngx_feature_incs="#include <sys/event.h>"
+        ngx_feature_path=
+        ngx_feature_libs=
+        ngx_feature_test="struct kevent  kev;
+                          kev.fflags = NOTE_LOWAT;"
+        . auto/feature
+
+
+        ngx_feature="kqueue's EVFILT_TIMER"
+        ngx_feature_name="NGX_HAVE_TIMER_EVENT"
+        ngx_feature_run=yes
+        ngx_feature_incs="#include <sys/event.h>
+                          #include <sys/time.h>"
+        ngx_feature_path=
+        ngx_feature_libs=
+        ngx_feature_test="int      kq;
+                  struct kevent    kev;
+                  struct timespec  ts;
+
+                  if ((kq = kqueue()) == -1) return 1;
+
+                  kev.ident = 0;
+                  kev.filter = EVFILT_TIMER;
+                  kev.flags = EV_ADD|EV_ENABLE;
+                  kev.fflags = 0;
+                  kev.data = 1000;
+                  kev.udata = 0;
+
+                  ts.tv_sec = 0;
+                  ts.tv_nsec = 0;
+
+                  if (kevent(kq, &kev, 1, &kev, 1, &ts) == -1) return 1;
+
+                  if (kev.flags & EV_ERROR) return 1;"
+
+        . auto/feature
+    fi
+fi
+
+
+if [ "$NGX_SYSTEM" = "NetBSD" ]; then
+
+    # NetBSD 2.0 incompatibly defines kevent.udata as "intptr_t"
+
+    cat << END >> $NGX_AUTO_CONFIG_H
+
+#define NGX_KQUEUE_UDATA_T
+
+END
+
+else
+    cat << END >> $NGX_AUTO_CONFIG_H
+
+#define NGX_KQUEUE_UDATA_T  (void *)
+
+END
+
+fi
+
+
+ngx_feature="crypt()"
+ngx_feature_name=
+ngx_feature_run=no
+ngx_feature_incs=
+ngx_feature_path=
+ngx_feature_libs=
+ngx_feature_test="crypt(\"test\", \"salt\");"
+. auto/feature
+
+
+if [ $ngx_found = no ]; then
+
+    ngx_feature="crypt() in libcrypt"
+    ngx_feature_name=
+    ngx_feature_run=no
+    ngx_feature_incs=
+    ngx_feature_path=
+    ngx_feature_libs=-lcrypt
+    . auto/feature
+
+    if [ $ngx_found = yes ]; then
+        CRYPT_LIB="-lcrypt"
+    fi
+fi
+
+
+ngx_feature="F_READAHEAD"
+ngx_feature_name="NGX_HAVE_F_READAHEAD"
+ngx_feature_run=no
+ngx_feature_incs="#include <fcntl.h>"
+ngx_feature_path=
+ngx_feature_libs=
+ngx_feature_test="fcntl(0, F_READAHEAD, 1);"
+. auto/feature
+
+
+ngx_feature="posix_fadvise()"
+ngx_feature_name="NGX_HAVE_POSIX_FADVISE"
+ngx_feature_run=no
+ngx_feature_incs="#include <fcntl.h>"
+ngx_feature_path=
+ngx_feature_libs=
+ngx_feature_test="posix_fadvise(0, 0, 0, POSIX_FADV_SEQUENTIAL);"
+. auto/feature
+
+
+ngx_feature="O_DIRECT"
+ngx_feature_name="NGX_HAVE_O_DIRECT"
+ngx_feature_run=no
+ngx_feature_incs="#include <fcntl.h>"
+ngx_feature_path=
+ngx_feature_libs=
+ngx_feature_test="fcntl(0, F_SETFL, O_DIRECT);"
+. auto/feature
+
+
+if [ $ngx_found = yes -a "$NGX_SYSTEM" = "Linux" ]; then
+    have=NGX_HAVE_ALIGNED_DIRECTIO . auto/have
+fi
+
+ngx_feature="F_NOCACHE"
+ngx_feature_name="NGX_HAVE_F_NOCACHE"
+ngx_feature_run=no
+ngx_feature_incs="#include <fcntl.h>"
+ngx_feature_path=
+ngx_feature_libs=
+ngx_feature_test="fcntl(0, F_NOCACHE, 1);"
+. auto/feature
+
+
+ngx_feature="directio()"
+ngx_feature_name="NGX_HAVE_DIRECTIO"
+ngx_feature_run=no
+ngx_feature_incs="#include <sys/types.h>
+                  #include <sys/fcntl.h>"
+ngx_feature_path=
+ngx_feature_libs=
+ngx_feature_test="directio(0, DIRECTIO_ON);"
+. auto/feature
+
+
+ngx_feature="statfs()"
+ngx_feature_name="NGX_HAVE_STATFS"
+ngx_feature_run=no
+ngx_feature_incs="$NGX_INCLUDE_SYS_PARAM_H
+                  $NGX_INCLUDE_SYS_MOUNT_H
+                  $NGX_INCLUDE_SYS_VFS_H"
+ngx_feature_path=
+ngx_feature_libs=
+ngx_feature_test="struct statfs  fs;
+                  statfs(NULL, &fs);"
+. auto/feature
+
+
+ngx_feature="statvfs()"
+ngx_feature_name="NGX_HAVE_STATVFS"
+ngx_feature_run=no
+ngx_feature_incs="#include <sys/types.h>
+                  #include <sys/statvfs.h>"
+ngx_feature_path=
+ngx_feature_libs=
+ngx_feature_test="struct statvfs  fs;
+                  statvfs(NULL, &fs);"
+. auto/feature
+
+
+ngx_feature="dlopen()"
+ngx_feature_name=
+ngx_feature_run=no
+ngx_feature_incs="#include <dlfcn.h>"
+ngx_feature_path=
+ngx_feature_libs=
+ngx_feature_test="dlopen(NULL, 0)"
+. auto/feature
+
+
+if [ $ngx_found != yes ]; then
+
+    ngx_feature="dlopen() in libdl"
+    ngx_feature_libs="-ldl"
+    . auto/feature
+
+    if [ $ngx_found = yes ]; then
+        NGX_LIBDL="-ldl"
+    fi
+fi
+
+
+ngx_feature="sched_yield()"
+ngx_feature_name="NGX_HAVE_SCHED_YIELD"
+ngx_feature_run=no
+ngx_feature_incs="#include <sched.h>"
+ngx_feature_path=
+ngx_feature_libs=
+ngx_feature_test="sched_yield()"
+. auto/feature
+
+
+if [ $ngx_found != yes ]; then
+
+    ngx_feature="sched_yield() in librt"
+    ngx_feature_libs="-lrt"
+    . auto/feature
+
+    if [ $ngx_found = yes ]; then
+        CORE_LIBS="$CORE_LIBS -lrt"
+    fi
+fi
+
+ngx_feature="SO_SETFIB"
+ngx_feature_name="NGX_HAVE_SETFIB"
+ngx_feature_run=no
+ngx_feature_incs="#include <sys/socket.h>"
+ngx_feature_path=
+ngx_feature_libs=
+ngx_feature_test="setsockopt(0, SOL_SOCKET, SO_SETFIB, NULL, 4)"
+. auto/feature
+
+
+ngx_feature="accept4()"
+ngx_feature_name="NGX_HAVE_ACCEPT4"
+ngx_feature_run=no
+ngx_feature_incs="#include <sys/socket.h>"
+ngx_feature_path=
+ngx_feature_libs=
+ngx_feature_test="accept4(0, NULL, NULL, SOCK_NONBLOCK)"
+. auto/feature
+
+if [ $NGX_FILE_AIO = YES ]; then
+
+    ngx_feature="kqueue AIO support"
+    ngx_feature_name="NGX_HAVE_FILE_AIO"
+    ngx_feature_run=no
+    ngx_feature_incs="#include <aio.h>"
+    ngx_feature_path=
+    ngx_feature_libs=
+    ngx_feature_test="int  n; struct aiocb  iocb;
+                      iocb.aio_sigevent.sigev_notify = SIGEV_KEVENT;
+                      n = aio_read(&iocb)"
+    . auto/feature
+
+    if [ $ngx_found = yes ]; then
+        CORE_SRCS="$CORE_SRCS $FILE_AIO_SRCS"
+
+    elif [ $ngx_found = no ]; then
+
+        ngx_feature="Linux AIO support"
+        ngx_feature_name="NGX_HAVE_FILE_AIO"
+        ngx_feature_run=no
+        ngx_feature_incs="#include <linux/aio_abi.h>
+                          #include <sys/syscall.h>"
+        ngx_feature_path=
+        ngx_feature_libs=
+        ngx_feature_test="int  n = SYS_eventfd;
+                          struct iocb  iocb;
+                          iocb.aio_lio_opcode = IOCB_CMD_PREAD;
+                          iocb.aio_flags = IOCB_FLAG_RESFD;
+                          iocb.aio_resfd = -1;"
+        . auto/feature
+
+        if [ $ngx_found = yes ]; then
+            have=NGX_HAVE_EVENTFD . auto/have
+            CORE_SRCS="$CORE_SRCS $LINUX_AIO_SRCS"
+
+        else
+            cat << END
+
+$0: no supported file AIO was found
+Currently file AIO is supported on FreeBSD 4.3+ and Linux 2.6.22+ only
+
+END
+           exit 1
+        fi
+    fi
+fi
+
+
 have=NGX_HAVE_UNIX_DOMAIN . auto/have
 
 ngx_feature_libs=
@@ -246,6 +607,19 @@ ngx_feature_test="sem_t  sem;
 . auto/feature
 
 
+if [ $ngx_found = no ]; then
+
+    # Linux has POSIX semaphores in libpthread
+    ngx_feature="POSIX semaphores in libpthread"
+    ngx_feature_libs=-lpthread
+    . auto/feature
+
+    if [ $ngx_found = yes ]; then
+        CORE_LIBS="$CORE_LIBS -lpthread"
+    fi
+fi
+
+
 ngx_feature="struct msghdr.msg_control"
 ngx_feature_name="NGX_HAVE_MSGHDR_MSG_CONTROL"
 ngx_feature_run=no
--- a/configure
+++ b/configure
@@ -51,8 +51,7 @@ fi
 . auto/os/conf
 
 if [ "$NGX_PLATFORM" != win32 ]; then
-    . auto/os/features
-    . auto/threads
+    . auto/unix
 fi
 
 . auto/modules
@@ -99,10 +98,6 @@ have=NGX_HTTP_SCGI_TEMP_PATH value="\"$N
 . auto/lib/make
 . auto/install
 
-if [ "$NGX_PLATFORM" != win32 ]; then
-    . auto/unix
-fi
-
 # STUB
 . auto/stubs
 
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,8 +8,8 @@
 #define _NGINX_H_INCLUDED_
 
 
-#define nginx_version      1000003
-#define NGINX_VERSION      "1.0.3"
+#define nginx_version      1000004
+#define NGINX_VERSION      "1.0.4"
 #define NGINX_VER          "nginx/" NGINX_VERSION
 
 #define NGINX_VAR          "NGINX"
--- a/src/core/ngx_crypt.c
+++ b/src/core/ngx_crypt.c
@@ -12,6 +12,8 @@
 #endif
 
 
+#if (NGX_CRYPT)
+
 static ngx_int_t ngx_crypt_apr1(ngx_pool_t *pool, u_char *key, u_char *salt,
     u_char **encrypted);
 static ngx_int_t ngx_crypt_plain(ngx_pool_t *pool, u_char *key, u_char *salt,
@@ -73,7 +75,7 @@ ngx_crypt_apr1(ngx_pool_t *pool, u_char 
 
     ngx_md5_init(&md5);
     ngx_md5_update(&md5, key, keylen);
-    ngx_md5_update(&md5, "$apr1$", sizeof("$apr1$") - 1);
+    ngx_md5_update(&md5, (u_char *) "$apr1$", sizeof("$apr1$") - 1);
     ngx_md5_update(&md5, salt, saltlen);
 
     ngx_md5_init(&ctx1);
@@ -232,3 +234,5 @@ ngx_crypt_ssha(ngx_pool_t *pool, u_char 
 }
 
 #endif /* NGX_HAVE_SHA1 */
+
+#endif /* NGX_CRYPT */
--- a/src/core/ngx_md5.c
+++ b/src/core/ngx_md5.c
@@ -32,7 +32,7 @@ ngx_md5_init(ngx_md5_t *ctx)
 
 
 void
-ngx_md5_update(ngx_md5_t *ctx, const u_char *data, size_t size)
+ngx_md5_update(ngx_md5_t *ctx, const void *data, size_t size)
 {
     size_t  used, free;
 
@@ -47,8 +47,7 @@ ngx_md5_update(ngx_md5_t *ctx, const u_c
             return;
         }
 
-        ngx_memcpy(&ctx->buffer[used], data, free);
-        data = (u_char *)data + free;
+        data = ngx_cpymem(&ctx->buffer[used], data, free);
         size -= free;
         (void) ngx_md5_body(ctx, ctx->buffer, 64);
     }
--- a/src/core/ngx_md5.h
+++ b/src/core/ngx_md5.h
@@ -50,7 +50,7 @@ typedef struct {
 
 
 void ngx_md5_init(ngx_md5_t *ctx);
-void ngx_md5_update(ngx_md5_t *ctx, const u_char *data, size_t size);
+void ngx_md5_update(ngx_md5_t *ctx, const void *data, size_t size);
 void ngx_md5_final(u_char result[16], ngx_md5_t *ctx);
 
 
--- a/src/http/modules/ngx_http_map_module.c
+++ b/src/http/modules/ngx_http_map_module.c
@@ -111,7 +111,6 @@ ngx_http_map_variable(ngx_http_request_t
 
     size_t                      len;
     ngx_str_t                   val;
-    ngx_uint_t                  key;
     ngx_http_variable_value_t  *value;
 
     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
@@ -127,9 +126,7 @@ ngx_http_map_variable(ngx_http_request_t
         len--;
     }
 
-    key = ngx_hash_strlow(val.data, val.data, len);
-
-    value = ngx_http_map_find(r, &map->map, key, val.data, len, &val);
+    value = ngx_http_map_find(r, &map->map, &val);
 
     if (value == NULL) {
         value = map->default_value;
@@ -529,6 +526,12 @@ found:
 
         ngx_memzero(&rc, sizeof(ngx_regex_compile_t));
 
+        if (value[0].data[0] == '*') {
+            value[0].len--;
+            value[0].data++;
+            rc.options = NGX_REGEX_CASELESS;
+        }
+
         rc.pattern = value[0];
         rc.err.len = NGX_MAX_CONF_ERRSTR;
         rc.err.data = errstr;
--- 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 = '1.0.3';
+our $VERSION = '1.0.4';
 
 require XSLoader;
 XSLoader::load('nginx', $VERSION);
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -2031,6 +2031,15 @@ ngx_http_upstream_send_response(ngx_http
             c->error = 1;
 
         } else {
+
+#if (NGX_HTTP_CACHE)
+
+            if (r->cache) {
+                ngx_http_file_cache_free(r->cache, u->pipe->temp_file);
+            }
+
+#endif
+
             ngx_http_upstream_finalize_request(r, u, rc);
             return;
         }
--- a/src/http/ngx_http_variables.c
+++ b/src/http/ngx_http_variables.c
@@ -1661,14 +1661,30 @@ ngx_http_variable_pid(ngx_http_request_t
 
 
 void *
-ngx_http_map_find(ngx_http_request_t *r, ngx_http_map_t *map, ngx_uint_t key,
-    u_char *text, size_t len, ngx_str_t *match)
+ngx_http_map_find(ngx_http_request_t *r, ngx_http_map_t *map, ngx_str_t *match)
 {
-    void  *p;
-
-    p = ngx_hash_find_combined(&map->hash, key, text, len);
-    if (p) {
-        return p;
+    void        *value;
+    u_char      *low;
+    size_t       len;
+    ngx_uint_t   key;
+
+    len = match->len;
+
+    if (len) {
+        low = ngx_pnalloc(r->pool, len);
+        if (low == NULL) {
+            return NULL;
+        }
+
+    } else {
+        low = NULL;
+    }
+
+    key = ngx_hash_strlow(low, match->data, len);
+
+    value = ngx_hash_find_combined(&map->hash, key, low, len);
+    if (value) {
+        return value;
     }
 
 #if (NGX_PCRE)
--- a/src/http/ngx_http_variables.h
+++ b/src/http/ngx_http_variables.h
@@ -100,7 +100,7 @@ typedef struct {
 
 
 void *ngx_http_map_find(ngx_http_request_t *r, ngx_http_map_t *map,
-    ngx_uint_t key, u_char *text, size_t len, ngx_str_t *match);
+    ngx_str_t *match);
 
 
 ngx_int_t ngx_http_variables_add_core_vars(ngx_conf_t *cf);