]> git.pld-linux.org Git - packages/lighttpd.git/commitdiff
- branches/lighttpd-1.4.x diff (revision 1664)
authorElan Ruusamäe <glen@pld-linux.org>
Mon, 19 Feb 2007 20:03:06 +0000 (20:03 +0000)
committercvs2git <feedback@pld-linux.org>
Sun, 24 Jun 2012 12:13:13 +0000 (12:13 +0000)
Changed files:
    lighttpd-branch.diff -> 1.12

lighttpd-branch.diff

index 5bd2b12bdf70dc4270f03a6426289a1542f9b178..d4c2eb6104a855be5e3f065f5290178c2c550fde 100644 (file)
---- ../lighttpd-1.4.11/NEWS    2006-03-09 19:34:33.000000000 +0200
-+++ lighttpd-1.5.0/NEWS        2006-07-16 00:26:05.000000000 +0300
-@@ -3,6 +3,23 @@
- NEWS
- ====
-+- 1.4.12 - 2006-..-..
-+
-+  * added handling of Content-Range to PUT requests in mod_webdav
-+  * added handling of ETag and If-Modified-Since to mod_compress if 
-+    cache-dir is not set
-+  * added experimental LOCK support for mod_webdav 
-+  * added support for X-Sendfile as addition to X-LIGHTTPD-send-file.
-+    This allows compatibility with mod_xsendfile for apache
-+    (http://celebnamer.celebworld.ws/stuff/mod_xsendfile/)
-+  * fixed handling of If-Modified-Since if Etag is not set
-+  * fixed hanging fastcgi connections
-+  * fixed stalling SSL POST requests 
-+  * fixed round-robin load-balancing in mod_proxy
-+  * TODO: add fail-over to mod-proxy
-+  * TODO: fix CACHE_HIT/MISS in mod_cml
-+  * TODO: finish LOCK/UNLOCK in mod_webdav
-+
- - 1.4.11 - 2006-03-09
-   * added ability to specify which ip address spawn-fci listens on 
---- ../lighttpd-1.4.11/configure.in    2006-03-04 16:32:38.000000000 +0200
-+++ lighttpd-1.5.0/configure.in        2006-09-07 00:57:05.000000000 +0300
-@@ -1,7 +1,7 @@
- #                                               -*- Autoconf -*-
- # Process this file with autoconf to produce a configure script.
- AC_PREREQ(2.57)
--AC_INIT(lighttpd, 1.4.11, jan@kneschke.de)
-+AC_INIT(lighttpd, 1.5.0, jan@kneschke.de)
- AC_CONFIG_SRCDIR([src/server.c])
- AC_CANONICAL_TARGET
-@@ -66,7 +66,7 @@
- AC_TYPE_PID_T
- AC_TYPE_SIZE_T
--AC_CHECK_MEMBER(struct tm.tm_gmtoff,AC_DEFINE([HAVE_STRUCT_TM_GMTOFF],[1],[gmtoff in struct tm]),,[#include <time.h>])
-+AC_CHECK_MEMBER(struct tm.tm_gmtoff,[AC_DEFINE([HAVE_STRUCT_TM_GMTOFF],[1],[gmtoff in struct tm])],,[#include <time.h>])
- AC_CHECK_TYPES(struct sockaddr_storage,,,[#include <sys/socket.h>])
- AC_CHECK_TYPES(socklen_t,,,[#include <sys/types.h>
- #include <sys/socket.h>])
-@@ -339,6 +339,22 @@
-     AC_DEFINE([HAVE_SQLITE3], [1], [libsqlite3])
-     AC_DEFINE([HAVE_SQLITE3_H], [1], [sqlite3.h])
-  ])
-+
-+ AC_MSG_CHECKING(for locks in mod_webdav)
-+ AC_ARG_WITH(webdav-locks, AC_HELP_STRING([--with-webdav-locks],[locks in mod_webdav]),
-+ [WITH_WEBDAV_LOCKS=$withval],[WITH_WEBDAV_LOCKS=no])
-+ AC_MSG_RESULT([$WITH_WEBDAV_LOCKS])
-+
-+ if test "$WITH_WEBDAV_LOCKS" != "no"; then
-+   AC_CHECK_LIB(uuid, uuid_unparse, [
-+         AC_CHECK_HEADERS([uuid/uuid.h],[
-+                 UUID_LIB=-luuid
-+                 AC_DEFINE([HAVE_UUID], [1], [libuuid])
-+               AC_DEFINE([HAVE_UUID_H], [1], [uuid/uuid.h is available])
-+         ])
-+ ])
-+
-+ fi
- fi
- dnl Check for gdbm
-@@ -381,30 +397,11 @@
- AC_MSG_RESULT($WITH_LUA)
- if test "$WITH_LUA" != "no"; then
-- AC_PATH_PROG(LUACONFIG, lua-config)
--
-- if test x"$LUACONFIG" != x; then
--   LUA_CFLAGS=`$LUACONFIG --include`
--   LUA_LIBS=`$LUACONFIG --libs --extralibs`
-+ # try pkgconfig
-+ PKG_CHECK_MODULES(LUA, lua >= 5.1, [
-    AC_DEFINE([HAVE_LUA], [1], [liblua])
-    AC_DEFINE([HAVE_LUA_H], [1], [lua.h])
-- else
--   AC_CHECK_LIB(lua, lua_open, [
--     AC_CHECK_HEADERS([lua.h],[
--       LUA_LIBS="-llua -llualib"
--       AC_DEFINE([HAVE_LUA], [1], [liblua])
--       AC_DEFINE([HAVE_LUA_H], [1], [lua.h])
--     ])
--   ])
-- fi
--
-- if test x"$LUA_LIBS" = x; then
--   # try pkgconfig
--   PKG_CHECK_MODULES(LUA, lua, [
--     AC_DEFINE([HAVE_LUA], [1], [liblua])
--     AC_DEFINE([HAVE_LUA_H], [1], [lua.h])
--   ])
-- fi
-+ ])
-  AC_SUBST(LUA_CFLAGS)
-  AC_SUBST(LUA_LIBS)
-@@ -440,8 +437,8 @@
- esac
- AC_CHECK_FUNCS([dup2 getcwd inet_ntoa inet_ntop memset mmap munmap strchr \
--                strdup strerror strstr strtol sendfile  getopt socket \
--                gethostbyname poll sigtimedwait epoll_ctl getrlimit chroot \
-+                strdup strerror strstr strtol sendfile  getopt socket lstat \
-+                gethostbyname poll sigtimedwait epoll_ctl getrlimit chroot strptime \
-                 getuid select signal pathconf madvise posix_fadvise posix_madvise \
-                 writev sigaction sendfile64 send_file kqueue port_create localtime_r])
-@@ -519,7 +516,7 @@
- if test "${GCC}" = "yes"; then
--       CFLAGS="${CFLAGS} -Wall -W -Wshadow -pedantic"
-+       CFLAGS="${CFLAGS} -Wall -W -Wshadow -pedantic -std=gnu99"
- fi
- dnl build version-id
-@@ -538,7 +535,7 @@
- AC_OUTPUT
--do_build="mod_cgi mod_fastcgi mod_proxy mod_evhost mod_simple_vhost mod_access mod_alias mod_setenv mod_usertrack mod_auth mod_status mod_accesslog mod_rrdtool mod_secdownload mod_expire mod_compress mod_dirlisting mod_indexfiles mod_userdir mod_webdav mod_staticfile mod_scgi" 
-+do_build="mod_cgi mod_fastcgi mod_proxy mod_evhost mod_simple_vhost mod_access mod_alias mod_setenv mod_usertrack mod_auth mod_status mod_accesslog mod_rrdtool mod_secdownload mod_expire mod_compress mod_dirlisting mod_indexfiles mod_userdir mod_webdav mod_staticfile mod_scgi mod_flv_streaming" 
- plugins="mod_rewrite mod_redirect mod_ssi mod_trigger_b4_dl"
- features="regex-conditionals"
-@@ -642,6 +639,14 @@
-       disable_feature="$disable_feature $features"
- fi
-+features="webdav-locks"
-+if test "x$UUID_LIB" \!= x; then
-+      enable_feature="$enable_feature $features"
-+else
-+      disable_feature="$disable_feature $features"
-+fi
-+
-+
- ## output
- $ECHO
---- ../lighttpd-1.4.11/cygwin/lighttpd.README  2006-03-07 14:22:19.000000000 +0200
-+++ lighttpd-1.5.0/cygwin/lighttpd.README      2006-09-07 01:00:40.000000000 +0300
-@@ -1,114 +1,114 @@
--lighttpd\r
--------------------------------------------\r
--A fast, secure and flexible webserver\r
--\r
--Runtime requirements:\r
--  cygwin-1.5.10 or newer\r
--  crypt-1.1 or newer\r
--  libbz2_1-1.0.2 or newer\r
--  libpcre0-4.5 or newer\r
--  openssl-0.9.7d or newer\r
--  zlib-1.2.1 or newer\r
--\r
--Build requirements:\r
--  cygwin-1.5.10 or newer\r
--  gcc-3.3.1-3 or newer\r
--  binutils-20030901-1 or newer\r
--  crypt\r
--  openssl-devel\r
--  openssl\r
--  openldap\r
--  openldap-devel\r
--  zlib\r
--  bzip2\r
--\r
--Canonical homepage:\r
--  http://jan.kneschke.de/projects/lighttpd/\r
--\r
--Canonical download:\r
--  http://jan.kneschke.de/projects/lighttpd/download\r
--\r
--------------------------------------\r
--\r
--Build instructions:\r
--  unpack lighttpd-1.4.11-<REL>-src.tar.bz2\r
--    if you use setup to install this src package, it will be\r
--       unpacked under /usr/src automatically\r
--  cd /usr/src\r
--  ./lighttpd-1.4.11-<REL>.sh all\r
--\r
--This will create:\r
--  /usr/src/lighttpd-1.4.11-<REL>.tar.bz2\r
--  /usr/src/lighttpd-1.4.11-<REL>-src.tar.bz2\r
--\r
--Or use './lighttpd-1.4.11-<REL>.sh prep' to get a patched source directory\r
--\r
---------------------------------------------\r
--\r
--Files included in the binary distribution:\r
--\r
--  /etc/lighttpd/lighttpd.conf.default\r
--  /usr/lib/cyglightcomp.dll\r
--  /usr/lib/lighttpd/mod_access.dll\r
--  /usr/lib/lighttpd/mod_accesslog.dll\r
--  /usr/lib/lighttpd/mod_auth.dll\r
--  /usr/lib/lighttpd/mod_cgi.dll\r
--  /usr/lib/lighttpd/mod_compress.dll\r
--  /usr/lib/lighttpd/mod_evhost.dll\r
--  /usr/lib/lighttpd/mod_expire.dll\r
--  /usr/lib/lighttpd/mod_fastcgi.dll\r
--  /usr/lib/lighttpd/mod_httptls.dll\r
--  /usr/lib/lighttpd/mod_maps.dll\r
--  /usr/lib/lighttpd/mod_proxy.dll\r
--  /usr/lib/lighttpd/mod_redirect.dll\r
--  /usr/lib/lighttpd/mod_rewrite.dll\r
--  /usr/lib/lighttpd/mod_rrdtool.dll\r
--  /usr/lib/lighttpd/mod_secdownload.dll\r
--  /usr/lib/lighttpd/mod_simple_vhost.dll\r
--  /usr/lib/lighttpd/mod_ssi.dll\r
--  /usr/lib/lighttpd/mod_status.dll\r
--  /usr/lib/lighttpd/mod_usertrack.dll\r
--  /usr/sbin/lighttpd.exe\r
--  /usr/share/doc/Cygwin/lighttpd-1.3.0.README\r
--  /usr/share/doc/lighttpd-1.3.0/accesslog.txt\r
--  /usr/share/doc/lighttpd-1.3.0/authentification.txt\r
--  /usr/share/doc/lighttpd-1.3.0/AUTHORS\r
--  /usr/share/doc/lighttpd-1.3.0/cgi.txt\r
--  /usr/share/doc/lighttpd-1.3.0/ChangeLog\r
--  /usr/share/doc/lighttpd-1.3.0/compress.txt\r
--  /usr/share/doc/lighttpd-1.3.0/configuration.txt\r
--  /usr/share/doc/lighttpd-1.3.0/COPYING\r
--  /usr/share/doc/lighttpd-1.3.0/fastcgi-state.txt\r
--  /usr/share/doc/lighttpd-1.3.0/fastcgi.txt\r
--  /usr/share/doc/lighttpd-1.3.0/features.txt\r
--  /usr/share/doc/lighttpd-1.3.0/INSTALL\r
--  /usr/share/doc/lighttpd-1.3.0/NEWS\r
--  /usr/share/doc/lighttpd-1.3.0/performance.txt\r
--  /usr/share/doc/lighttpd-1.3.0/plugins.txt\r
--  /usr/share/doc/lighttpd-1.3.0/proxy.txt\r
--  /usr/share/doc/lighttpd-1.3.0/README\r
--  /usr/share/doc/lighttpd-1.3.0/redirect.txt\r
--  /usr/share/doc/lighttpd-1.3.0/rewrite.txt\r
--  /usr/share/doc/lighttpd-1.3.0/rrdtool.txt\r
--  /usr/share/doc/lighttpd-1.3.0/secdownload.txt\r
--  /usr/share/doc/lighttpd-1.3.0/security.txt\r
--  /usr/share/doc/lighttpd-1.3.0/simple-vhost.txt\r
--  /usr/share/doc/lighttpd-1.3.0/skeleton.txt\r
--  /usr/share/doc/lighttpd-1.3.0/ssi.txt\r
--  /usr/share/doc/lighttpd-1.3.0/state.txt\r
--  /usr/share/man/man1/lighttpd.1.gz\r
--\r
--------------------\r
--\r
--Port Notes:\r
--\r
------------  lighttpd-1.3.1-1 -----------\r
--\r
--Updated to 1.3.1\r
--\r
------------  lighttpd-1.3.0-1 -----------\r
--Initial release\r
--\r
--Cygwin port maintained by: Jan Kneschke <jan@kneschke.de>\r
--Please address all questions to the Cygwin mailing list at <cygwin@cygwin.com>\r
--\r
-+lighttpd
-+------------------------------------------
-+A fast, secure and flexible webserver
-+
-+Runtime requirements:
-+  cygwin-1.5.10 or newer
-+  crypt-1.1 or newer
-+  libbz2_1-1.0.2 or newer
-+  libpcre0-4.5 or newer
-+  openssl-0.9.7d or newer
-+  zlib-1.2.1 or newer
-+
-+Build requirements:
-+  cygwin-1.5.10 or newer
-+  gcc-3.3.1-3 or newer
-+  binutils-20030901-1 or newer
-+  crypt
-+  openssl-devel
-+  openssl
-+  openldap
-+  openldap-devel
-+  zlib
-+  bzip2
-+
-+Canonical homepage:
-+  http://jan.kneschke.de/projects/lighttpd/
-+
-+Canonical download:
-+  http://jan.kneschke.de/projects/lighttpd/download
-+
-+------------------------------------
-+
-+Build instructions:
-+  unpack lighttpd-1.5.0-<REL>-src.tar.bz2
-+    if you use setup to install this src package, it will be
-+       unpacked under /usr/src automatically
-+  cd /usr/src
-+  ./lighttpd-1.5.0-<REL>.sh all
-+
-+This will create:
-+  /usr/src/lighttpd-1.5.0-<REL>.tar.bz2
-+  /usr/src/lighttpd-1.5.0-<REL>-src.tar.bz2
-+
-+Or use './lighttpd-1.5.0-<REL>.sh prep' to get a patched source directory
-+
-+-------------------------------------------
-+
-+Files included in the binary distribution:
-+
-+  /etc/lighttpd/lighttpd.conf.default
-+  /usr/lib/cyglightcomp.dll
-+  /usr/lib/lighttpd/mod_access.dll
-+  /usr/lib/lighttpd/mod_accesslog.dll
-+  /usr/lib/lighttpd/mod_auth.dll
-+  /usr/lib/lighttpd/mod_cgi.dll
-+  /usr/lib/lighttpd/mod_compress.dll
-+  /usr/lib/lighttpd/mod_evhost.dll
-+  /usr/lib/lighttpd/mod_expire.dll
-+  /usr/lib/lighttpd/mod_fastcgi.dll
-+  /usr/lib/lighttpd/mod_httptls.dll
-+  /usr/lib/lighttpd/mod_maps.dll
-+  /usr/lib/lighttpd/mod_proxy.dll
-+  /usr/lib/lighttpd/mod_redirect.dll
-+  /usr/lib/lighttpd/mod_rewrite.dll
-+  /usr/lib/lighttpd/mod_rrdtool.dll
-+  /usr/lib/lighttpd/mod_secdownload.dll
-+  /usr/lib/lighttpd/mod_simple_vhost.dll
-+  /usr/lib/lighttpd/mod_ssi.dll
-+  /usr/lib/lighttpd/mod_status.dll
-+  /usr/lib/lighttpd/mod_usertrack.dll
-+  /usr/sbin/lighttpd.exe
-+  /usr/share/doc/Cygwin/lighttpd-1.3.0.README
-+  /usr/share/doc/lighttpd-1.3.0/accesslog.txt
-+  /usr/share/doc/lighttpd-1.3.0/authentification.txt
-+  /usr/share/doc/lighttpd-1.3.0/AUTHORS
-+  /usr/share/doc/lighttpd-1.3.0/cgi.txt
-+  /usr/share/doc/lighttpd-1.3.0/ChangeLog
-+  /usr/share/doc/lighttpd-1.3.0/compress.txt
-+  /usr/share/doc/lighttpd-1.3.0/configuration.txt
-+  /usr/share/doc/lighttpd-1.3.0/COPYING
-+  /usr/share/doc/lighttpd-1.3.0/fastcgi-state.txt
-+  /usr/share/doc/lighttpd-1.3.0/fastcgi.txt
-+  /usr/share/doc/lighttpd-1.3.0/features.txt
-+  /usr/share/doc/lighttpd-1.3.0/INSTALL
-+  /usr/share/doc/lighttpd-1.3.0/NEWS
-+  /usr/share/doc/lighttpd-1.3.0/performance.txt
-+  /usr/share/doc/lighttpd-1.3.0/plugins.txt
-+  /usr/share/doc/lighttpd-1.3.0/proxy.txt
-+  /usr/share/doc/lighttpd-1.3.0/README
-+  /usr/share/doc/lighttpd-1.3.0/redirect.txt
-+  /usr/share/doc/lighttpd-1.3.0/rewrite.txt
-+  /usr/share/doc/lighttpd-1.3.0/rrdtool.txt
-+  /usr/share/doc/lighttpd-1.3.0/secdownload.txt
-+  /usr/share/doc/lighttpd-1.3.0/security.txt
-+  /usr/share/doc/lighttpd-1.3.0/simple-vhost.txt
-+  /usr/share/doc/lighttpd-1.3.0/skeleton.txt
-+  /usr/share/doc/lighttpd-1.3.0/ssi.txt
-+  /usr/share/doc/lighttpd-1.3.0/state.txt
-+  /usr/share/man/man1/lighttpd.1.gz
-+
-+------------------
-+
-+Port Notes:
-+
-+----------  lighttpd-1.3.1-1 -----------
-+
-+Updated to 1.3.1
-+
-+----------  lighttpd-1.3.0-1 -----------
-+Initial release
-+
-+Cygwin port maintained by: Jan Kneschke <jan@kneschke.de>
-+Please address all questions to the Cygwin mailing list at <cygwin@cygwin.com>
-+
---- ../lighttpd-1.4.11/cygwin/lighttpd.README.in       2005-08-11 01:26:59.000000000 +0300
-+++ lighttpd-1.5.0/cygwin/lighttpd.README.in   2006-07-16 00:26:04.000000000 +0300
-@@ -1,114 +1,114 @@
--lighttpd\r
--------------------------------------------\r
--A fast, secure and flexible webserver\r
--\r
--Runtime requirements:\r
--  cygwin-1.5.10 or newer\r
--  crypt-1.1 or newer\r
--  libbz2_1-1.0.2 or newer\r
--  libpcre0-4.5 or newer\r
--  openssl-0.9.7d or newer\r
--  zlib-1.2.1 or newer\r
--\r
--Build requirements:\r
--  cygwin-1.5.10 or newer\r
--  gcc-3.3.1-3 or newer\r
--  binutils-20030901-1 or newer\r
--  crypt\r
--  openssl-devel\r
--  openssl\r
--  openldap\r
--  openldap-devel\r
--  zlib\r
--  bzip2\r
--\r
--Canonical homepage:\r
--  http://jan.kneschke.de/projects/lighttpd/\r
--\r
--Canonical download:\r
--  http://jan.kneschke.de/projects/lighttpd/download\r
--\r
--------------------------------------\r
--\r
--Build instructions:\r
--  unpack lighttpd-@VERSION@-<REL>-src.tar.bz2\r
--    if you use setup to install this src package, it will be\r
--       unpacked under /usr/src automatically\r
--  cd /usr/src\r
--  ./lighttpd-@VERSION@-<REL>.sh all\r
--\r
--This will create:\r
--  /usr/src/lighttpd-@VERSION@-<REL>.tar.bz2\r
--  /usr/src/lighttpd-@VERSION@-<REL>-src.tar.bz2\r
--\r
--Or use './lighttpd-@VERSION@-<REL>.sh prep' to get a patched source directory\r
--\r
---------------------------------------------\r
--\r
--Files included in the binary distribution:\r
--\r
--  /etc/lighttpd/lighttpd.conf.default\r
--  /usr/lib/cyglightcomp.dll\r
--  /usr/lib/lighttpd/mod_access.dll\r
--  /usr/lib/lighttpd/mod_accesslog.dll\r
--  /usr/lib/lighttpd/mod_auth.dll\r
--  /usr/lib/lighttpd/mod_cgi.dll\r
--  /usr/lib/lighttpd/mod_compress.dll\r
--  /usr/lib/lighttpd/mod_evhost.dll\r
--  /usr/lib/lighttpd/mod_expire.dll\r
--  /usr/lib/lighttpd/mod_fastcgi.dll\r
--  /usr/lib/lighttpd/mod_httptls.dll\r
--  /usr/lib/lighttpd/mod_maps.dll\r
--  /usr/lib/lighttpd/mod_proxy.dll\r
--  /usr/lib/lighttpd/mod_redirect.dll\r
--  /usr/lib/lighttpd/mod_rewrite.dll\r
--  /usr/lib/lighttpd/mod_rrdtool.dll\r
--  /usr/lib/lighttpd/mod_secdownload.dll\r
--  /usr/lib/lighttpd/mod_simple_vhost.dll\r
--  /usr/lib/lighttpd/mod_ssi.dll\r
--  /usr/lib/lighttpd/mod_status.dll\r
--  /usr/lib/lighttpd/mod_usertrack.dll\r
--  /usr/sbin/lighttpd.exe\r
--  /usr/share/doc/Cygwin/lighttpd-1.3.0.README\r
--  /usr/share/doc/lighttpd-1.3.0/accesslog.txt\r
--  /usr/share/doc/lighttpd-1.3.0/authentification.txt\r
--  /usr/share/doc/lighttpd-1.3.0/AUTHORS\r
--  /usr/share/doc/lighttpd-1.3.0/cgi.txt\r
--  /usr/share/doc/lighttpd-1.3.0/ChangeLog\r
--  /usr/share/doc/lighttpd-1.3.0/compress.txt\r
--  /usr/share/doc/lighttpd-1.3.0/configuration.txt\r
--  /usr/share/doc/lighttpd-1.3.0/COPYING\r
--  /usr/share/doc/lighttpd-1.3.0/fastcgi-state.txt\r
--  /usr/share/doc/lighttpd-1.3.0/fastcgi.txt\r
--  /usr/share/doc/lighttpd-1.3.0/features.txt\r
--  /usr/share/doc/lighttpd-1.3.0/INSTALL\r
--  /usr/share/doc/lighttpd-1.3.0/NEWS\r
--  /usr/share/doc/lighttpd-1.3.0/performance.txt\r
--  /usr/share/doc/lighttpd-1.3.0/plugins.txt\r
--  /usr/share/doc/lighttpd-1.3.0/proxy.txt\r
--  /usr/share/doc/lighttpd-1.3.0/README\r
--  /usr/share/doc/lighttpd-1.3.0/redirect.txt\r
--  /usr/share/doc/lighttpd-1.3.0/rewrite.txt\r
--  /usr/share/doc/lighttpd-1.3.0/rrdtool.txt\r
--  /usr/share/doc/lighttpd-1.3.0/secdownload.txt\r
--  /usr/share/doc/lighttpd-1.3.0/security.txt\r
--  /usr/share/doc/lighttpd-1.3.0/simple-vhost.txt\r
--  /usr/share/doc/lighttpd-1.3.0/skeleton.txt\r
--  /usr/share/doc/lighttpd-1.3.0/ssi.txt\r
--  /usr/share/doc/lighttpd-1.3.0/state.txt\r
--  /usr/share/man/man1/lighttpd.1.gz\r
--\r
--------------------\r
--\r
--Port Notes:\r
--\r
------------  lighttpd-1.3.1-1 -----------\r
--\r
--Updated to 1.3.1\r
--\r
------------  lighttpd-1.3.0-1 -----------\r
--Initial release\r
--\r
--Cygwin port maintained by: Jan Kneschke <jan@kneschke.de>\r
--Please address all questions to the Cygwin mailing list at <cygwin@cygwin.com>\r
--\r
-+lighttpd
-+------------------------------------------
-+A fast, secure and flexible webserver
-+
-+Runtime requirements:
-+  cygwin-1.5.10 or newer
-+  crypt-1.1 or newer
-+  libbz2_1-1.0.2 or newer
-+  libpcre0-4.5 or newer
-+  openssl-0.9.7d or newer
-+  zlib-1.2.1 or newer
-+
-+Build requirements:
-+  cygwin-1.5.10 or newer
-+  gcc-3.3.1-3 or newer
-+  binutils-20030901-1 or newer
-+  crypt
-+  openssl-devel
-+  openssl
-+  openldap
-+  openldap-devel
-+  zlib
-+  bzip2
-+
-+Canonical homepage:
-+  http://jan.kneschke.de/projects/lighttpd/
-+
-+Canonical download:
-+  http://jan.kneschke.de/projects/lighttpd/download
-+
-+------------------------------------
-+
-+Build instructions:
-+  unpack lighttpd-@VERSION@-<REL>-src.tar.bz2
-+    if you use setup to install this src package, it will be
-+       unpacked under /usr/src automatically
-+  cd /usr/src
-+  ./lighttpd-@VERSION@-<REL>.sh all
-+
-+This will create:
-+  /usr/src/lighttpd-@VERSION@-<REL>.tar.bz2
-+  /usr/src/lighttpd-@VERSION@-<REL>-src.tar.bz2
-+
-+Or use './lighttpd-@VERSION@-<REL>.sh prep' to get a patched source directory
-+
-+-------------------------------------------
-+
-+Files included in the binary distribution:
-+
-+  /etc/lighttpd/lighttpd.conf.default
-+  /usr/lib/cyglightcomp.dll
-+  /usr/lib/lighttpd/mod_access.dll
-+  /usr/lib/lighttpd/mod_accesslog.dll
-+  /usr/lib/lighttpd/mod_auth.dll
-+  /usr/lib/lighttpd/mod_cgi.dll
-+  /usr/lib/lighttpd/mod_compress.dll
-+  /usr/lib/lighttpd/mod_evhost.dll
-+  /usr/lib/lighttpd/mod_expire.dll
-+  /usr/lib/lighttpd/mod_fastcgi.dll
-+  /usr/lib/lighttpd/mod_httptls.dll
-+  /usr/lib/lighttpd/mod_maps.dll
-+  /usr/lib/lighttpd/mod_proxy.dll
-+  /usr/lib/lighttpd/mod_redirect.dll
-+  /usr/lib/lighttpd/mod_rewrite.dll
-+  /usr/lib/lighttpd/mod_rrdtool.dll
-+  /usr/lib/lighttpd/mod_secdownload.dll
-+  /usr/lib/lighttpd/mod_simple_vhost.dll
-+  /usr/lib/lighttpd/mod_ssi.dll
-+  /usr/lib/lighttpd/mod_status.dll
-+  /usr/lib/lighttpd/mod_usertrack.dll
-+  /usr/sbin/lighttpd.exe
-+  /usr/share/doc/Cygwin/lighttpd-1.3.0.README
-+  /usr/share/doc/lighttpd-1.3.0/accesslog.txt
-+  /usr/share/doc/lighttpd-1.3.0/authentification.txt
-+  /usr/share/doc/lighttpd-1.3.0/AUTHORS
-+  /usr/share/doc/lighttpd-1.3.0/cgi.txt
-+  /usr/share/doc/lighttpd-1.3.0/ChangeLog
-+  /usr/share/doc/lighttpd-1.3.0/compress.txt
-+  /usr/share/doc/lighttpd-1.3.0/configuration.txt
-+  /usr/share/doc/lighttpd-1.3.0/COPYING
-+  /usr/share/doc/lighttpd-1.3.0/fastcgi-state.txt
-+  /usr/share/doc/lighttpd-1.3.0/fastcgi.txt
-+  /usr/share/doc/lighttpd-1.3.0/features.txt
-+  /usr/share/doc/lighttpd-1.3.0/INSTALL
-+  /usr/share/doc/lighttpd-1.3.0/NEWS
-+  /usr/share/doc/lighttpd-1.3.0/performance.txt
-+  /usr/share/doc/lighttpd-1.3.0/plugins.txt
-+  /usr/share/doc/lighttpd-1.3.0/proxy.txt
-+  /usr/share/doc/lighttpd-1.3.0/README
-+  /usr/share/doc/lighttpd-1.3.0/redirect.txt
-+  /usr/share/doc/lighttpd-1.3.0/rewrite.txt
-+  /usr/share/doc/lighttpd-1.3.0/rrdtool.txt
-+  /usr/share/doc/lighttpd-1.3.0/secdownload.txt
-+  /usr/share/doc/lighttpd-1.3.0/security.txt
-+  /usr/share/doc/lighttpd-1.3.0/simple-vhost.txt
-+  /usr/share/doc/lighttpd-1.3.0/skeleton.txt
-+  /usr/share/doc/lighttpd-1.3.0/ssi.txt
-+  /usr/share/doc/lighttpd-1.3.0/state.txt
-+  /usr/share/man/man1/lighttpd.1.gz
-+
-+------------------
-+
-+Port Notes:
-+
-+----------  lighttpd-1.3.1-1 -----------
-+
-+Updated to 1.3.1
-+
-+----------  lighttpd-1.3.0-1 -----------
-+Initial release
-+
-+Cygwin port maintained by: Jan Kneschke <jan@kneschke.de>
-+Please address all questions to the Cygwin mailing list at <cygwin@cygwin.com>
-+
---- ../lighttpd-1.4.11/doc/authentication.txt  2006-01-12 20:34:26.000000000 +0200
-+++ lighttpd-1.5.0/doc/authentication.txt      2006-07-16 00:26:05.000000000 +0300
-@@ -7,8 +7,8 @@
- ----------------
- :Author: Jan Kneschke
--:Date: $Date$
--:Revision: $Revision$
-+:Date: $Date$
-+:Revision: $Revision$
- :abstract:
-   The auth module provides ...
---- ../lighttpd-1.4.11/doc/compress.txt        2005-08-11 01:26:16.000000000 +0300
-+++ lighttpd-1.5.0/doc/compress.txt    2006-07-16 00:26:05.000000000 +0300
-@@ -22,12 +22,38 @@
- ===========
- Output compression reduces the network load and can improve the overall
--throughput of the webserver. 
-+throughput of the webserver. All major http-clients support compression by
-+announcing it in the Accept-Encoding header. This is used to negotiate the 
-+most suitable compression method. We support deflate, gzip and bzip2.
--Only static content is supported up to now.
-+deflate (RFC1950, RFC1951) and gzip (RFC1952) depend on zlib while bzip2 
-+depends on libbzip2. bzip2 is only supported by lynx and some other console
-+text-browsers.
--The server negotiates automaticly which compression method is used.
--Supported are gzip, deflate, bzip.
-+Currently we limit to compression support to static files.
-+
-+Caching
-+-------
-+
-+mod_compress can stored compressed files on disk to optimized the compression
-+on a second request away. As soon as compress.cache-dir is set the files are
-+compressed. 
-+
-+The names of the cache files are made of the filename, the compression method
-+and the etag associated to the file.
-+
-+Cleaning the cache is left to the user. A cron job deleting files older than
-+10 days should do fine.
-+
-+Limitations
-+-----------
-+
-+The module limits the compression of files to files larger than 128 Byte and
-+smaller than 128 MByte.
-+
-+The lower limit is set as small files tend to become larger by compressing due
-+to the compression headers, the upper limit is set to work sensable with
-+memory and cpu-time.
- Options
- =======
-@@ -47,15 +73,28 @@
-   Default: not set, compress the file for every request
- compress.filetype
--  mimetypes where might get compressed
-+  mimetypes which might get compressed
-   
-   e.g.: ::
-   
-     compress.filetype           = ("text/plain", "text/html")
-+  Keep in mind that compressed JavaScript and CSS files are broken in some
-+  browsers.
-+
-   Default: not set
-+compress.max-file-size 
-+  maximum size of the original file to be compressed kBytes.
-+
-+  This is meant to protect the server against DoSing as compressing large
-+  (let's say 1Gbyte) takes a lot of time and would delay the whole operation
-+  of the server.
-+  There is a hard upper limit of 128Mbyte.
-+
-+  Default: unlimited (== hard-limit of 128MByte)
-+  
- Compressing Dynamic Content
- ===========================
---- ../lighttpd-1.4.11/doc/configuration.txt   2006-03-09 02:10:40.000000000 +0200
-+++ lighttpd-1.5.0/doc/configuration.txt       2006-07-16 00:26:05.000000000 +0300
-@@ -7,8 +7,8 @@
- ------------
+Index: src/base.h
+===================================================================
+--- src/base.h (.../tags/lighttpd-1.4.13)      (revision 1664)
++++ src/base.h (.../branches/lighttpd-1.4.x)   (revision 1664)
+@@ -481,7 +481,9 @@
+       enum { STAT_CACHE_ENGINE_UNSET,
+                       STAT_CACHE_ENGINE_NONE,
+                       STAT_CACHE_ENGINE_SIMPLE,
++#ifdef HAVE_FAM_H
+                       STAT_CACHE_ENGINE_FAM
++#endif
+       } stat_cache_engine;
+       unsigned short enable_cores;
+ } server_config;
+Index: src/connections.c
+===================================================================
+--- src/connections.c  (.../tags/lighttpd-1.4.13)      (revision 1664)
++++ src/connections.c  (.../branches/lighttpd-1.4.x)   (revision 1664)
+@@ -970,7 +970,7 @@
+                                                               }
+                                                       } else {
+                                                               /* a splited \r \n */
+-                                                              return -1;
++                                                              break;
+                                                       }
+                                               }
+                                       }
+Index: src/configfile.c
+===================================================================
+--- src/configfile.c   (.../tags/lighttpd-1.4.13)      (revision 1664)
++++ src/configfile.c   (.../branches/lighttpd-1.4.x)   (revision 1664)
+@@ -218,13 +218,19 @@
+               srv->srvconf.stat_cache_engine = STAT_CACHE_ENGINE_SIMPLE;
+       } else if (buffer_is_equal_string(stat_cache_string, CONST_STR_LEN("simple"))) {
+               srv->srvconf.stat_cache_engine = STAT_CACHE_ENGINE_SIMPLE;
++#ifdef HAVE_FAM_H
+       } else if (buffer_is_equal_string(stat_cache_string, CONST_STR_LEN("fam"))) {
+               srv->srvconf.stat_cache_engine = STAT_CACHE_ENGINE_FAM;
++#endif
+       } else if (buffer_is_equal_string(stat_cache_string, CONST_STR_LEN("disable"))) {
+               srv->srvconf.stat_cache_engine = STAT_CACHE_ENGINE_NONE;
+       } else {
+               log_error_write(srv, __FILE__, __LINE__, "sb",
+-                              "server.stat-cache-engine can be one of \"disable\", \"simple\", \"fam\", but not:", stat_cache_string);
++                              "server.stat-cache-engine can be one of \"disable\", \"simple\","
++#ifdef HAVE_FAM_H
++                              " \"fam\","
++#endif
++                              " but not:", stat_cache_string);
+               ret = HANDLER_ERROR;
+       }
  
- :Author: Jan Kneschke
--:Date: $Date$
--:Revision: $Revision$
-+:Date: $Date$
-+:Revision: $Revision$
+Index: src/mod_scgi.c
+===================================================================
+--- src/mod_scgi.c     (.../tags/lighttpd-1.4.13)      (revision 1664)
++++ src/mod_scgi.c     (.../branches/lighttpd-1.4.x)   (revision 1664)
+@@ -2528,7 +2528,7 @@
+                                   hctx->reconnects < 5) {
+                                       scgi_reconnect(srv, hctx);
  
- :abstract:
-   the layout of the configuration file
-@@ -511,3 +511,10 @@
+-                                      log_error_write(srv, __FILE__, __LINE__, "sdsdsd",
++                                      log_error_write(srv, __FILE__, __LINE__, "ssdsd",
+                                               "response not sent, request not sent, reconnection.",
+                                               "connection-fd:", con->fd,
+                                               "fcgi-fd:", hctx->fd);
+Index: src/request.c
+===================================================================
+--- src/request.c      (.../tags/lighttpd-1.4.13)      (revision 1664)
++++ src/request.c      (.../branches/lighttpd-1.4.x)   (revision 1664)
+@@ -85,6 +85,9 @@
+       /* Host is empty */
+       if (host_len == 0) return -1;
  
- debug.log-request-handling
-   default: disabled 
-+
-+debug.log-condition-handling
-+  default: disabled 
++      /* if the hostname ends in a "." strip it */
++      if (host->ptr[host_len-1] == '.') host_len -= 1;
 +
-+debug.log-condition-cache-handling
-+  for developers only
-+  default: disabled 
---- ../lighttpd-1.4.11/doc/fastcgi.txt 2006-02-16 17:03:52.000000000 +0200
-+++ lighttpd-1.5.0/doc/fastcgi.txt     2006-07-16 00:26:05.000000000 +0300
-@@ -144,8 +144,8 @@
-                 PHP can extract PATH_INFO from it (default: disabled)
-   :"disable-time": time to wait before a disabled backend is checked
-                 again
--  :"allow-x-send-file": controls if X-LIGHTTPD-send-file headers
--                are allowed 
-+  :"allow-x-send-file": controls if X-LIGHTTPD-send-file and X-Sendfile
-+                headers are allowed 
-   If bin-path is set:
---- ../lighttpd-1.4.11/doc/lighttpd.conf       2006-03-04 14:41:12.000000000 +0200
-+++ lighttpd-1.5.0/doc/lighttpd.conf   2006-07-16 00:26:05.000000000 +0300
-@@ -172,10 +172,11 @@
- #dir-listing.activate       = "enable"
- ## enable debugging
--#debug.log-request-header   = "enable"
--#debug.log-response-header  = "enable"
--#debug.log-request-handling = "enable"
--#debug.log-file-not-found   = "enable"
-+#debug.log-request-header     = "enable"
-+#debug.log-response-header    = "enable"
-+#debug.log-request-handling   = "enable"
-+#debug.log-file-not-found     = "enable"
-+#debug.log-condition-handling = "enable"
- ### only root can use these options
- #
---- ../lighttpd-1.4.11/doc/performance.txt     2006-02-02 13:01:08.000000000 +0200
-+++ lighttpd-1.5.0/doc/performance.txt 2006-07-16 00:26:05.000000000 +0300
-@@ -183,6 +183,8 @@
-   server.stat-cache-engine = "fam"   # either fam, simple or disabled
-+See http://oss.sgi.com/projects/fam/faq.html for information about FAM.
-+See http://www.gnome.org/~veillard/gamin/overview.html for information about gamin.
- Platform-Specific Notes
- =======================
---- ../lighttpd-1.4.11/doc/secdownload.txt     2005-12-20 15:58:58.000000000 +0200
-+++ lighttpd-1.5.0/doc/secdownload.txt 2006-07-16 00:26:05.000000000 +0300
-@@ -118,7 +118,7 @@
-   $secret = "verysecret";
-   $uri_prefix = "/dl/";
-   
--  # filename
-+  # filename, make sure it's started with a "/" or you'll get 404 in the browser
-   $f = "/secret-file.txt";
-   
-   # current timestamp
---- ../lighttpd-1.4.11/lighttpd.spec   2006-03-07 14:22:18.000000000 +0200
-+++ lighttpd-1.5.0/lighttpd.spec       2006-09-07 01:00:40.000000000 +0300
-@@ -1,6 +1,6 @@
- Summary: A fast webserver with minimal memory-footprint (lighttpd)
- Name: lighttpd
--Version: 1.4.11
-+Version: 1.5.0
- Release: 1
- Source: http://jan.kneschke.de/projects/lighttpd/download/lighttpd-%version.tar.gz
- Packager: Jan Kneschke <jan@kneschke.de>
---- ../lighttpd-1.4.11/openwrt/control 2006-03-07 14:22:19.000000000 +0200
-+++ lighttpd-1.5.0/openwrt/control     2006-09-07 01:00:41.000000000 +0300
-@@ -1,8 +1,8 @@
- Package: lighttpd
--Version: 1.4.11
-+Version: 1.5.0
- Architecture: mipsel
- Maintainer: Jan Kneschke <jan@kneschke.de>
--Source: http://jan.kneschke.de/projects/lighttpd/download/lighttpd-1.4.11.tar.gz
-+Source: http://jan.kneschke.de/projects/lighttpd/download/lighttpd-1.5.0.tar.gz
- Section: net
- Priority: optional
- Depends:
---- ../lighttpd-1.4.11/openwrt/lighttpd.mk     2006-03-07 14:22:19.000000000 +0200
-+++ lighttpd-1.5.0/openwrt/lighttpd.mk 2006-09-07 01:00:41.000000000 +0300
-@@ -10,7 +10,7 @@
- #  For this example we'll use a fairly simple package that compiles easily
- #  and has sources available for download at sourceforge
--LIGHTTPD=lighttpd-1.4.11
-+LIGHTTPD=lighttpd-1.5.0
- LIGHTTPD_TARGET=.built
- LIGHTTPD_DIR=$(BUILD_DIR)/$(LIGHTTPD)
- LIGHTTPD_IPK=$(BUILD_DIR)/$(LIGHTTPD)_mipsel.ipk
---- ../lighttpd-1.4.11/src/Makefile.am 2006-03-07 14:20:20.000000000 +0200
-+++ lighttpd-1.5.0/src/Makefile.am     2006-09-07 00:57:05.000000000 +0300
-@@ -16,11 +16,26 @@
- else
- configparser.y: lemon
- mod_ssi_exprparser.y: lemon
-+http_resp_parser.y: lemon
-+http_req_parser.y: lemon
-+http_req_range_parser.y: lemon
- configparser.c configparser.h: configparser.y
-       rm -f configparser.h
-       $(LEMON) -q $(srcdir)/configparser.y $(srcdir)/lempar.c
+       /* scan from the right and skip the \0 */
+       for (i = host_len - 1; i + 1 > 0; i--) {
+               const char c = host->ptr[i];
+Index: src/network_backends.h
+===================================================================
+--- src/network_backends.h     (.../tags/lighttpd-1.4.13)      (revision 1664)
++++ src/network_backends.h     (.../branches/lighttpd-1.4.x)   (revision 1664)
+@@ -14,7 +14,7 @@
+ # include <sys/uio.h>
+ #endif
+-#if defined HAVE_SYS_UIO_H && defined HAVE_SENDFILE && defined HAVE_WRITEV && defined(__FreeBSD__)
++#if defined HAVE_SYS_UIO_H && defined HAVE_SENDFILE && defined HAVE_WRITEV && (defined(__FreeBSD__) || defined(__DragonFly__))
+ # define USE_FREEBSD_SENDFILE
+ # include <sys/uio.h>
+ #endif
+Index: src/mod_proxy.c
+===================================================================
+--- src/mod_proxy.c    (.../tags/lighttpd-1.4.13)      (revision 1664)
++++ src/mod_proxy.c    (.../branches/lighttpd-1.4.x)   (revision 1664)
+@@ -656,6 +656,7 @@
+               }
+               if (-1 == (r = read(hctx->fd, hctx->response->ptr + hctx->response->used - 1, b))) {
++                      if (errno == EAGAIN) return 0;
+                       log_error_write(srv, __FILE__, __LINE__, "sds",
+                                       "unexpected end-of-file (perhaps the proxy process died):",
+                                       proxy_fd, strerror(errno));
+Index: src/mod_expire.c
+===================================================================
+--- src/mod_expire.c   (.../tags/lighttpd-1.4.13)      (revision 1664)
++++ src/mod_expire.c   (.../branches/lighttpd-1.4.x)   (revision 1664)
+@@ -85,7 +85,7 @@
+       /*
+        * parse
+        *
+-       * '(access|modification) [plus] {<num> <type>}*'
++       * '(access|now|modification) [plus] {<num> <type>}*'
+        *
+        * e.g. 'access 1 years'
+        */
+@@ -101,6 +101,9 @@
+       if (0 == strncmp(ts, "access ", 7)) {
+               type  = 0;
+               ts   += 7;
++      } else if (0 == strncmp(ts, "now ", 4)) {
++              type  = 0;
++              ts   += 4;
+       } else if (0 == strncmp(ts, "modification ", 13)) {
+               type  = 1;
+               ts   += 13;
+@@ -116,7 +119,7 @@
+               ts   += 5;
+       }
  
-+http_resp_parser.c http_resp_parser.h: http_resp_parser.y
-+      rm -f http_resp_parser.h
-+      $(LEMON) -q $(srcdir)/http_resp_parser.y $(srcdir)/lempar.c
-+
-+http_req_parser.c http_req_parser.h: http_req_parser.y
-+      rm -f http_req_parser.h
-+      $(LEMON) -q $(srcdir)/http_req_parser.y $(srcdir)/lempar.c
-+
-+http_req_range_parser.c http_req_range_parser.h: http_req_range_parser.y
-+      rm -f http_req_parser.h
-+      $(LEMON) -q $(srcdir)/http_req_range_parser.y $(srcdir)/lempar.c
-+
- mod_ssi_exprparser.c mod_ssi_exprparser.h: mod_ssi_exprparser.y 
-       rm -f mod_ssi_exprparser.h
-       $(LEMON) -q $(srcdir)/mod_ssi_exprparser.y $(srcdir)/lempar.c
-@@ -28,10 +43,13 @@
+-      /* the rest is just <number> (years|months|days|hours|minutes|seconds) */
++      /* the rest is just <number> (years|months|weeks|days|hours|minutes|seconds) */
+       while (1) {
+               char *space, *err;
+               int num;
+@@ -148,6 +151,9 @@
+                       } else if (slen == 6 &&
+                                  0 == strncmp(ts, "months", slen)) {
+                               num *= 60 * 60 * 24 * 30;
++                      } else if (slen == 5 &&
++                                 0 == strncmp(ts, "weeks", slen)) {
++                              num *= 60 * 60 * 24 * 7;
+                       } else if (slen == 4 &&
+                                  0 == strncmp(ts, "days", slen)) {
+                               num *= 60 * 60 * 24;
+@@ -174,6 +180,8 @@
+                               num *= 60 * 60 * 24 * 30 * 12;
+                       } else if (0 == strcmp(ts, "months")) {
+                               num *= 60 * 60 * 24 * 30;
++                      } else if (0 == strcmp(ts, "weeks")) {
++                              num *= 60 * 60 * 24 * 7;
+                       } else if (0 == strcmp(ts, "days")) {
+                               num *= 60 * 60 * 24;
+                       } else if (0 == strcmp(ts, "hours")) {
+Index: src/network_freebsd_sendfile.c
+===================================================================
+--- src/network_freebsd_sendfile.c     (.../tags/lighttpd-1.4.13)      (revision 1664)
++++ src/network_freebsd_sendfile.c     (.../branches/lighttpd-1.4.x)   (revision 1664)
+@@ -25,7 +25,7 @@
  
- configfile.c: configparser.h
- mod_ssi_expr.c: mod_ssi_exprparser.h
-+http_resp.c: http_resp_parser.h
-+http_req.c: http_req_parser.h
-+http_req_range.c: http_req_range_parser.h
  
- common_src=buffer.c log.c \
-       keyvalue.c chunk.c  \
--      http_chunk.c stream.c fdevent.c \
-+      stream.c fdevent.c \
-       stat_cache.c plugin.c joblist.c etag.c array.c \
-       data_string.c data_count.c data_array.c \
-       data_integer.c md5.c data_fastcgi.c \
-@@ -40,13 +58,16 @@
-       fdevent_solaris_devpoll.c fdevent_freebsd_kqueue.c \
-       data_config.c bitset.c \
-       inet_ntop_cache.c crc32.c \
--      connections-glue.c \
--      configfile-glue.c \
-+      connections-glue.c iosocket.c \
-+      configfile-glue.c status_counter.c \
-       http-header-glue.c \
-       network_write.c network_linux_sendfile.c \
-       network_freebsd_sendfile.c network_writev.c \
-       network_solaris_sendfilev.c network_openssl.c \
--      splaytree.c 
-+      splaytree.c \
-+      http_resp.c http_resp_parser.c \
-+      http_req.c http_req_parser.c \
-+      http_req_range.c http_req_range_parser.c 
-       
- src = server.c response.c connections.c network.c \
-       configfile.c configparser.c request.c proc_open.c
-@@ -75,6 +96,11 @@
- mod_flv_streaming_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
- mod_flv_streaming_la_LIBADD = $(common_libadd)
+ #ifndef UIO_MAXIOV
+-# ifdef __FreeBSD__
++# if defined(__FreeBSD__) || defined(__DragonFly__)
+ /* FreeBSD 4.7, 4.9 defined it in sys/uio.h only if _KERNEL is specified */
+ #  define UIO_MAXIOV 1024
+ # endif
+Index: src/http_auth.c
+===================================================================
+--- src/http_auth.c    (.../tags/lighttpd-1.4.13)      (revision 1664)
++++ src/http_auth.c    (.../branches/lighttpd-1.4.x)   (revision 1664)
+@@ -733,8 +733,9 @@
+                       }
+               }
  
-+lib_LTLIBRARIES += mod_uploadprogress.la
-+mod_uploadprogress_la_SOURCES = mod_uploadprogress.c 
-+mod_uploadprogress_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
-+mod_uploadprogress_la_LIBADD = $(common_libadd)
-+
- lib_LTLIBRARIES += mod_evasive.la
- mod_evasive_la_SOURCES = mod_evasive.c
- mod_evasive_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
-@@ -82,9 +108,9 @@
++              if (p->conf.auth_ldap_allow_empty_pw != 1 && pw[0] == '\0')
++                      return -1;
  
- lib_LTLIBRARIES += mod_webdav.la
- mod_webdav_la_SOURCES = mod_webdav.c
--mod_webdav_la_CFLAGS = $(AM_CFLAGS) $(XML_CFLAGS) $(SQLITE_CFLAGS)
-+mod_webdav_la_CFLAGS = $(AM_CFLAGS) $(XML_CFLAGS) $(SQLITE_CFLAGS) 
- mod_webdav_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
--mod_webdav_la_LIBADD = $(common_libadd) $(XML_LIBS) $(SQLITE_LIBS)
-+mod_webdav_la_LIBADD = $(common_libadd) $(XML_LIBS) $(SQLITE_LIBS) $(UUID_LIB)
+-
+               /* build filter */
+               buffer_copy_string_buffer(p->ldap_filter, p->conf.ldap_filter_pre);
+               buffer_append_string_buffer(p->ldap_filter, username);
+Index: src/http_auth.h
+===================================================================
+--- src/http_auth.h    (.../tags/lighttpd-1.4.13)      (revision 1664)
++++ src/http_auth.h    (.../branches/lighttpd-1.4.x)   (revision 1664)
+@@ -36,6 +36,7 @@
+       buffer *auth_ldap_filter;
+       buffer *auth_ldap_cafile;
+       unsigned short auth_ldap_starttls;
++      unsigned short auth_ldap_allow_empty_pw;
  
- lib_LTLIBRARIES += mod_cml.la
- mod_cml_la_SOURCES = mod_cml.c mod_cml_lua.c mod_cml_funcs.c
-@@ -103,6 +129,11 @@
- mod_mysql_vhost_la_LIBADD = $(MYSQL_LIBS) $(common_libadd)
- mod_mysql_vhost_la_CPPFLAGS = $(MYSQL_INCLUDE)
+       unsigned short auth_debug;
  
-+lib_LTLIBRARIES += mod_sql_vhost_core.la
-+mod_sql_vhost_core_la_SOURCES = mod_sql_vhost_core.c
-+mod_sql_vhost_core_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
-+mod_sql_vhost_core_la_LIBADD = $(common_libadd)
-+
- lib_LTLIBRARIES += mod_cgi.la
- mod_cgi_la_SOURCES = mod_cgi.c 
- mod_cgi_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
-@@ -158,6 +189,15 @@
- mod_proxy_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
- mod_proxy_la_LIBADD = $(common_libadd)
+Index: src/mod_auth.c
+===================================================================
+--- src/mod_auth.c     (.../tags/lighttpd-1.4.13)      (revision 1664)
++++ src/mod_auth.c     (.../branches/lighttpd-1.4.x)   (revision 1664)
+@@ -113,6 +113,7 @@
+       PATCH(auth_ldap_filter);
+       PATCH(auth_ldap_cafile);
+       PATCH(auth_ldap_starttls);
++      PATCH(auth_ldap_allow_empty_pw);
+ #ifdef USE_LDAP
+       PATCH(ldap);
+       PATCH(ldap_filter_pre);
+@@ -160,6 +161,8 @@
+                               PATCH(auth_ldap_cafile);
+                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.starttls"))) {
+                               PATCH(auth_ldap_starttls);
++                      } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.allow-empty-pw"))) {
++                              PATCH(auth_ldap_allow_empty_pw);
+                       }
+               }
+       }
+@@ -312,6 +315,7 @@
+               { "auth.backend.ldap.starttls",     NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },
+               { "auth.backend.ldap.bind-dn",      NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
+               { "auth.backend.ldap.bind-pw",      NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 10 */
++              { "auth.backend.ldap.allow-empty-pw",     NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },
+               { "auth.backend.htdigest.userfile", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
+               { "auth.backend.htpasswd.userfile", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
+               { "auth.debug",                     NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },  /* 13 */
+@@ -359,11 +363,12 @@
+               cv[6].destination = s->auth_ldap_filter;
+               cv[7].destination = s->auth_ldap_cafile;
+               cv[8].destination = &(s->auth_ldap_starttls);
+-              cv[9].destination = s->auth_ldap_binddn;
+-              cv[10].destination = s->auth_ldap_bindpw;
+-              cv[11].destination = s->auth_htdigest_userfile;
+-              cv[12].destination = s->auth_htpasswd_userfile;
+-              cv[13].destination = &(s->auth_debug);
++              cv[9].destination = s->auth_ldap_binddn;
++              cv[10].destination = s->auth_ldap_bindpw;
++              cv[11].destination = &(s->auth_ldap_allow_empty_pw);
++              cv[12].destination = s->auth_htdigest_userfile;
++              cv[13].destination = s->auth_htpasswd_userfile;
++              cv[14].destination = &(s->auth_debug);
  
-+lib_LTLIBRARIES += mod_proxy_core.la
-+mod_proxy_core_la_SOURCES = mod_proxy_core.c mod_proxy_core_pool.c \
-+                          mod_proxy_core_backend.c mod_proxy_core_address.c \
-+                          mod_proxy_core_backlog.c mod_proxy_core_rewrites.c \
-+                          mod_proxy_backend_http.c mod_proxy_backend_fastcgi.c
-+mod_proxy_core_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
-+mod_proxy_core_la_LIBADD = $(common_libadd) $(PCRE_LIB)
-+
-+
- lib_LTLIBRARIES += mod_ssi.la
- mod_ssi_la_SOURCES = mod_ssi_exprparser.c mod_ssi_expr.c mod_ssi.c 
- mod_ssi_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
-@@ -231,7 +271,7 @@
+               p->config_storage[i] = s;
+               ca = ((data_config *)srv->config_context->data[i])->value;
+Index: src/mod_fastcgi.c
+===================================================================
+--- src/mod_fastcgi.c  (.../tags/lighttpd-1.4.13)      (revision 1664)
++++ src/mod_fastcgi.c  (.../branches/lighttpd-1.4.x)   (revision 1664)
+@@ -275,6 +275,7 @@
+       buffer *key; /* like .php */
  
- hdr = server.h buffer.h network.h log.h keyvalue.h \
-       response.h request.h fastcgi.h chunk.h \
--      settings.h http_chunk.h http_auth_digest.h \
-+      settings.h http_auth_digest.h \
-       md5.h http_auth.h stream.h \
-       fdevent.h connections.h base.h stat_cache.h \
-       plugin.h mod_auth.h \
-@@ -240,7 +280,25 @@
-       mod_ssi.h mod_ssi_expr.h inet_ntop_cache.h \
-       configparser.h mod_ssi_exprparser.h \
-       sys-mmap.h sys-socket.h mod_cml.h mod_cml_funcs.h \
--      splaytree.h proc_open.h
-+      splaytree.h proc_open.h mod_sql_vhost_core.h \
-+      sys-files.h sys-process.h sys-strings.h  \
-+      iosocket.h array-static.h \
-+      mod_proxy_core_address.h \
-+      mod_proxy_core_backend.h \
-+      mod_proxy_core_backlog.h \
-+      mod_proxy_core.h  \
-+      mod_proxy_core_pool.h \
-+      mod_proxy_core_rewrites.h \
-+      mod_proxy_backend_http.h \
-+      mod_proxy_backend_fastcgi.h \
-+      status_counter.h \
-+      http_req.h \
-+      http_req_parser.h \
-+      http_req_range.h \
-+      http_req_range_parser.h \
-+      http_resp.h \
-+      http_resp_parser.h \
-+      http_parser.h
+       int note_is_sent;
++      int last_used_ndx;
  
- DEFS= @DEFS@ -DLIBRARY_DIR="\"$(libdir)\""
+       fcgi_extension_host **hosts;
  
-@@ -267,4 +325,10 @@
- #ajp_SOURCES = ajp.c
+@@ -563,6 +564,7 @@
+               fe = calloc(1, sizeof(*fe));
+               assert(fe);
+               fe->key = buffer_init();
++              fe->last_used_ndx = -1;
+               buffer_copy_string_buffer(fe->key, key);
  
- noinst_HEADERS   = $(hdr)
--EXTRA_DIST = mod_skeleton.c configparser.y mod_ssi_exprparser.y lempar.c
-+EXTRA_DIST = mod_skeleton.c \
-+           configparser.y \
-+           mod_ssi_exprparser.y \
-+           lempar.c  \
-+           http_resp_parser.y \
-+           http_req_parser.y \
-+           http_req_range_parser.y 
---- ../lighttpd-1.4.11/src/array-static.h      1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/array-static.h  2006-07-18 13:03:40.000000000 +0300
-@@ -0,0 +1,33 @@
-+#ifndef _ARRAY_STATIC_H_
-+#define _ARRAY_STATIC_H_
-+
-+/* define a generic array of <type>
-+ * */
-+
-+#define ARRAY_STATIC_DEF(name, type, extra) \
-+typedef struct { \
-+      type **ptr; \
-+      size_t used; \
-+      size_t size; \
-+      extra\
-+} name
-+
-+/* all append operations need a 'resize' for the +1 */
-+
-+#define ARRAY_STATIC_PREPARE_APPEND(a) \
-+        if (a->size == 0) { \
-+              a->size = 16; \
-+              a->ptr = malloc(a->size * sizeof(*(a->ptr))); \
-+      } else if (a->size == a->used) { \
-+              a->size += 16; \
-+              a->ptr = realloc(a->ptr, a->size * sizeof(*(a->ptr))); \
-+      }
-+      
-+#define FOREACH(array, element, func) \
-+do { size_t _i; for (_i = 0; _i < array->used; _i++) { void *element = array->ptr[_i]; func; } } while(0);
-+
-+#define STRUCT_INIT(type, var) \
-+      type *var;\
-+      var = calloc(1, sizeof(*var))
-+
-+#endif
---- ../lighttpd-1.4.11/src/array.c     2005-11-18 13:58:32.000000000 +0200
-+++ lighttpd-1.5.0/src/array.c 2006-07-16 00:26:03.000000000 +0300
-@@ -11,12 +11,12 @@
+               /* */
+@@ -2365,6 +2367,7 @@
+        * check how much we have to read
+        */
+       if (ioctl(hctx->fd, FIONREAD, &toread)) {
++              if( errno == EAGAIN ) return 0;
+               log_error_write(srv, __FILE__, __LINE__, "sd",
+                               "unexpected end-of-file (perhaps the fastcgi process died):",
+                               fcgi_fd);
+@@ -2375,12 +2378,23 @@
  
- array *array_init(void) {
-       array *a;
--      
-+
-       a = calloc(1, sizeof(*a));
-       assert(a);
--      
-+
-       a->next_power_of_2 = 1;
--      
+       if (toread > 0) {
+               buffer *b;
++              chunk *cq_first = hctx->rb->first;
++              chunk *cq_last = hctx->rb->last;
+               b = chunkqueue_get_append_buffer(hctx->rb);
+               buffer_prepare_copy(b, toread + 1);
+               /* append to read-buffer */
+               if (-1 == (r = read(hctx->fd, b->ptr, toread))) {
++                      if( errno == EAGAIN ) {
++                              /* roll back the last chunk allocation,
++                                   and continue on next iteration        */
++                              buffer_free(hctx->rb->last->mem);
++                              free(hctx->rb->last);
++                              hctx->rb->first = cq_first;
++                              hctx->rb->last = cq_last;
++                              return 0;
++                      }
+                       log_error_write(srv, __FILE__, __LINE__, "sds",
+                                       "unexpected end-of-file (perhaps the fastcgi process died):",
+                                       fcgi_fd, strerror(errno));
+@@ -2393,6 +2407,7 @@
+               b->used = r + 1; /* one extra for the fake \0 */
+               b->ptr[b->used - 1] = '\0';
+       } else {
++              if( errno == EAGAIN ) return 0;
+               log_error_write(srv, __FILE__, __LINE__, "ssdsb",
+                               "unexpected end-of-file (perhaps the fastcgi process died):",
+                               "pid:", proc->pid,
+@@ -2499,6 +2514,8 @@
+                       }
+                       break;
+               case FCGI_STDERR:
++                      if (packet.len == 0) break;
 +
-       return a;
- }
+                       log_error_write(srv, __FILE__, __LINE__, "sb",
+                                       "FastCGI-stderr:", packet.b);
  
-@@ -43,29 +43,29 @@
- void array_free(array *a) {
-       size_t i;
-       if (!a) return;
--      
-+
-       if (!a->is_weakref) {
-               for (i = 0; i < a->size; i++) {
-                       if (a->data[i]) a->data[i]->free(a->data[i]);
-               }
-       }
--      
-+
-       if (a->data) free(a->data);
-       if (a->sorted) free(a->sorted);
--      
-+
-       free(a);
- }
+@@ -2979,17 +2996,23 @@
+               size_t k;
+               int ndx, used = -1;
+-              /* get best server */
+-              for (k = 0, ndx = -1; k < hctx->ext->used; k++) {
+-                      host = hctx->ext->hosts[k];
++              /* check if the next server has no load. */
++              ndx = hctx->ext->last_used_ndx + 1;
++              if(ndx >= hctx->ext->used || ndx < 0) ndx = 0;
++              host = hctx->ext->hosts[ndx];
++              if (host->load > 0) {
++                      /* get backend with the least load. */
++                      for (k = 0, ndx = -1; k < hctx->ext->used; k++) {
++                              host = hctx->ext->hosts[k];
+-                      /* we should have at least one proc that can do something */
+-                      if (host->active_procs == 0) continue;
++                              /* we should have at least one proc that can do something */
++                              if (host->active_procs == 0) continue;
+-                      if (used == -1 || host->load < used) {
+-                              used = host->load;
++                              if (used == -1 || host->load < used) {
++                                      used = host->load;
  
- void array_reset(array *a) {
-       size_t i;
-       if (!a) return;
--      
-+
-       if (!a->is_weakref) {
-               for (i = 0; i < a->used; i++) {
-                       a->data[i]->reset(a->data[i]);
+-                              ndx = k;
++                                      ndx = k;
++                              }
+                       }
                }
-       }
--      
-+
-       a->used = 0;
- }
  
-@@ -84,20 +84,20 @@
- static int array_get_index(array *a, const char *key, size_t keylen, int *rndx) {
-       int ndx = -1;
-       int i, pos = 0;
--      
-+
-       if (key == NULL) return -1;
--      
-+
-       /* try to find the string */
-       for (i = pos = a->next_power_of_2 / 2; ; i >>= 1) {
-               int cmp;
--              
-+
-               if (pos < 0) {
-                       pos += i;
-               } else if (pos >= (int)a->used) {
-                       pos -= i;
-               } else {
-                       cmp = buffer_caseless_compare(key, keylen, a->data[a->sorted[pos]]->key->ptr, a->data[a->sorted[pos]]->key->used);
--                      
-+
-                       if (cmp == 0) {
-                               /* found */
-                               ndx = a->sorted[pos];
-@@ -110,46 +110,46 @@
+@@ -3005,6 +3028,7 @@
+                       return HANDLER_FINISHED;
                }
-               if (i == 0) break;
-       }
--      
-+
-       if (rndx) *rndx = pos;
--      
-+
-       return ndx;
- }
- data_unset *array_get_element(array *a, const char *key) {
-       int ndx;
--      
-+
-       if (-1 != (ndx = array_get_index(a, key, strlen(key) + 1, NULL))) {
-               /* found, leave here */
--              
-+
-               return a->data[ndx];
--      } 
--      
-+      }
-+
-       return NULL;
- }
  
- data_unset *array_get_unused_element(array *a, data_type_t t) {
-       data_unset *ds = NULL;
--      
-+
-       UNUSED(t);
++              hctx->ext->last_used_ndx = ndx;
+               host = hctx->ext->hosts[ndx];
  
-       if (a->size == 0) return NULL;
--      
-+
-       if (a->used == a->size) return NULL;
+               /*
+Index: src/server.c
+===================================================================
+--- src/server.c       (.../tags/lighttpd-1.4.13)      (revision 1664)
++++ src/server.c       (.../branches/lighttpd-1.4.x)   (revision 1664)
+@@ -163,6 +163,7 @@
+ #undef CLEAN
  
-       if (a->data[a->used]) {
-               ds = a->data[a->used];
--              
-+
-               a->data[a->used] = NULL;
+       for (i = 0; i < FILE_CACHE_MAX; i++) {
++              srv->mtime_cache[i].mtime = (time_t)-1;
+               srv->mtime_cache[i].str = buffer_init();
        }
--      
-+
-       return ds;
- }
  
- /* replace or insert data, return the old one with the same key */
- data_unset *array_replace(array *a, data_unset *du) {
-       int ndx;
--      
-+
-       if (-1 == (ndx = array_get_index(a, du->key->ptr, du->key->used, NULL))) {
-               array_insert_unique(a, du);
-               return NULL;
-@@ -164,13 +164,13 @@
-       int ndx = -1;
-       int pos = 0;
-       size_t j;
--      
--      /* generate unique index if neccesary */
-+
-+      /* generate unique index if necessary */
-       if (str->key->used == 0 || str->is_index_key) {
-               buffer_copy_long(str->key, a->unique_ndx++);
-               str->is_index_key = 1;
-       }
--      
-+
-       /* try to find the string */
-       if (-1 != (ndx = array_get_index(a, str->key->ptr, str->key->used, &pos))) {
-               /* found, leave here */
-@@ -181,14 +181,14 @@
-               }
-               return 0;
-       }
--      
-+
-       /* insert */
--      
-+
-       if (a->used+1 > INT_MAX) {
-               /* we can't handle more then INT_MAX entries: see array_get_index() */
-               return -1;
-       }
--      
-+
-       if (a->size == 0) {
-               a->size   = 16;
-               a->data   = malloc(sizeof(*a->data)     * a->size);
-@@ -204,27 +204,27 @@
-               assert(a->sorted);
-               for (j = a->used; j < a->size; j++) a->data[j] = NULL;
-       }
--      
-+
-       ndx = (int) a->used;
--      
-+
-       a->data[a->used++] = str;
--      
-+
-       if (pos != ndx &&
--          ((pos < 0) || 
-+          ((pos < 0) ||
-            buffer_caseless_compare(str->key->ptr, str->key->used, a->data[a->sorted[pos]]->key->ptr, a->data[a->sorted[pos]]->key->used) > 0)) {
-               pos++;
--      } 
--      
--      /* move everything on step to the right */
-+      }
-+
-+      /* move everything one step to the right */
-       if (pos != ndx) {
-               memmove(a->sorted + (pos + 1), a->sorted + (pos), (ndx - pos) * sizeof(*a->sorted));
-       }
--      
-+
-       /* insert */
-       a->sorted[pos] = ndx;
--      
-+
-       if (a->next_power_of_2 == (size_t)ndx) a->next_power_of_2 <<= 1;
--      
-+
-       return 0;
- }
+@@ -1231,6 +1232,19 @@
+                                               srv_socket->fd = -1;
  
-@@ -254,7 +254,7 @@
-       size_t i;
-       size_t maxlen;
-       int oneline = 1;
--      
-+
-       if (a->used > 5) {
-               oneline = 0;
-       }
-@@ -314,7 +314,7 @@
-       }
-       array_print_indent(depth);
-       fprintf(stderr, ")");
--      
+                                               /* network_close() will cleanup after us */
 +
-       return 0;
- }
++                                              if (srv->srvconf.pid_file->used &&
++                                                  srv->srvconf.changeroot->used == 0) {
++                                                      if (0 != unlink(srv->srvconf.pid_file->ptr)) {
++                                                              if (errno != EACCES && errno != EPERM) {
++                                                                      log_error_write(srv, __FILE__, __LINE__, "sbds",
++                                                                                      "unlink failed for:",
++                                                                                      srv->srvconf.pid_file,
++                                                                                      errno,
++                                                                                      strerror(errno));
++                                                              }
++                                                      }
++                                              }
+                                       }
+                               }
  
-@@ -323,47 +323,47 @@
-       array *a;
-       data_string *ds;
-       data_count *dc;
--      
-+
-       UNUSED(argc);
-       UNUSED(argv);
+@@ -1335,7 +1349,8 @@
+       }
  
-       a = array_init();
--      
-+
-       ds = data_string_init();
-       buffer_copy_string(ds->key, "abc");
-       buffer_copy_string(ds->value, "alfrag");
--      
-+
-       array_insert_unique(a, (data_unset *)ds);
--      
-+
-       ds = data_string_init();
-       buffer_copy_string(ds->key, "abc");
-       buffer_copy_string(ds->value, "hameplman");
--      
-+
-       array_insert_unique(a, (data_unset *)ds);
--      
-+
-       ds = data_string_init();
-       buffer_copy_string(ds->key, "123");
-       buffer_copy_string(ds->value, "alfrag");
--      
-+
-       array_insert_unique(a, (data_unset *)ds);
--      
-+
-       dc = data_count_init();
-       buffer_copy_string(dc->key, "def");
--      
-+
-       array_insert_unique(a, (data_unset *)dc);
--      
-+
-       dc = data_count_init();
-       buffer_copy_string(dc->key, "def");
--      
-+
-       array_insert_unique(a, (data_unset *)dc);
--      
-+
-       array_print(a, 0);
--      
-+
-       array_free(a);
--      
-+
-       fprintf(stderr, "%d\n",
-              buffer_caseless_compare(CONST_STR_LEN("Content-Type"), CONST_STR_LEN("Content-type")));
--      
-+
-       return 0;
- }
- #endif
---- ../lighttpd-1.4.11/src/array.h     2005-09-23 21:24:18.000000000 +0300
-+++ lighttpd-1.5.0/src/array.h 2006-09-07 00:57:05.000000000 +0300
-@@ -16,7 +16,7 @@
- #define DATA_UNSET \
-       data_type_t type; \
-       buffer *key; \
--      int is_index_key; /* 1 if key is a array index (autogenerated keys) */ \
-+      int is_index_key; /* 1 if key is an array index (auto-generated keys) */ \
-       struct data_unset *(*copy)(const struct data_unset *src); \
-       void (* free)(struct data_unset *p); \
-       void (* reset)(struct data_unset *p); \
-@@ -29,21 +29,21 @@
- typedef struct {
-       data_unset  **data;
--      
-+
-       size_t *sorted;
--      
-+
-       size_t used;
-       size_t size;
--      
-+
-       size_t unique_ndx;
--      
-+
-       size_t next_power_of_2;
-       int is_weakref; /* data is weakref, don't bother the data */
- } array;
- typedef struct {
-       DATA_UNSET;
--      
-+
-       int count;
- } data_count;
-@@ -51,7 +51,7 @@
- typedef struct {
-       DATA_UNSET;
--      
-+
-       buffer *value;
- } data_string;
-@@ -60,21 +60,39 @@
- typedef struct {
-       DATA_UNSET;
--      
-+
-       array *value;
- } data_array;
- data_array *data_array_init(void);
--typedef enum { CONFIG_COND_UNSET, CONFIG_COND_EQ, CONFIG_COND_MATCH, CONFIG_COND_NE, CONFIG_COND_NOMATCH } config_cond_t;
-+/**
-+ * possible compare ops in the configfile parser
-+ */
-+typedef enum { 
-+      CONFIG_COND_UNSET, 
-+      CONFIG_COND_EQ,      /** == */
-+      CONFIG_COND_MATCH,   /** =~ */
-+      CONFIG_COND_NE,      /** != */
-+      CONFIG_COND_NOMATCH  /** !~ */
-+} config_cond_t;
--#define PATCHES NULL, "SERVERsocket", "HTTPurl", "HTTPhost", "HTTPreferer", "HTTPuseragent", "HTTPcookie", "HTTPremoteip"
-+/**
-+ * possible fields to match against
-+ */
- typedef enum {
-       COMP_UNSET,
--      COMP_SERVER_SOCKET, COMP_HTTP_URL, COMP_HTTP_HOST, COMP_HTTP_REFERER, COMP_HTTP_USERAGENT, COMP_HTTP_COOKIE, COMP_HTTP_REMOTEIP
-+      COMP_SERVER_SOCKET, 
-+      COMP_HTTP_URL, 
-+      COMP_HTTP_HOST, 
-+      COMP_HTTP_REFERER, 
-+      COMP_HTTP_USERAGENT, 
-+      COMP_HTTP_COOKIE, 
-+      COMP_HTTP_REMOTEIP,
-+      COMP_HTTP_QUERYSTRING
- } comp_key_t;
--/* $HTTP["host"] ==    "incremental.home.kneschke.de" { ... } 
-+/* $HTTP["host"] ==    "incremental.home.kneschke.de" { ... }
-  * for print:   comp_key      op    string
-  * for compare: comp          cond  string/regex
-  */
-@@ -82,15 +100,15 @@
- typedef struct _data_config data_config;
- struct _data_config {
-       DATA_UNSET;
--      
-+
-       array *value;
--      
-+
-       buffer *comp_key;
-       comp_key_t comp;
--      
-+
-       config_cond_t cond;
-       buffer *op;
--      
-+
-       int context_ndx; /* more or less like an id */
-       array *childs;
-       /* nested */
-@@ -98,7 +116,7 @@
-       /* for chaining only */
-       data_config *prev;
-       data_config *next;
--      
-+
-       buffer *string;
- #ifdef HAVE_PCRE_H
-       pcre   *regex;
-@@ -110,7 +128,7 @@
- typedef struct {
-       DATA_UNSET;
--      
-+
-       int value;
- } data_integer;
-@@ -120,13 +138,13 @@
-       DATA_UNSET;
-       buffer *host;
--      
-+
-       unsigned short port;
-       time_t disable_ts;
-       int is_disabled;
-       size_t balance;
--              
-+
-       int usage; /* fair-balancing needs the no. of connections active on this host */
-       int last_used_ndx; /* round robin */
- } data_fastcgi;
---- ../lighttpd-1.4.11/src/base.h      2006-01-11 16:51:04.000000000 +0200
-+++ lighttpd-1.5.0/src/base.h  2006-09-07 00:57:05.000000000 +0300
-@@ -2,7 +2,6 @@
- #define _BASE_H_
- #include <sys/types.h>
--#include <sys/time.h>
- #include <sys/stat.h>
- #ifdef HAVE_CONFIG_H
-@@ -25,11 +24,11 @@
- #include "fdevent.h"
- #include "sys-socket.h"
- #include "splaytree.h"
--
-+#include "http_req.h"
- #if defined HAVE_LIBSSL && defined HAVE_OPENSSL_SSL_H
- # define USE_OPENSSL
--# include <openssl/ssl.h> 
-+# include <openssl/ssl.h>
- #endif
- #ifdef HAVE_FAM_H
-@@ -40,10 +39,6 @@
- # define O_BINARY 0
- #endif
--#ifndef O_LARGEFILE
--# define O_LARGEFILE 0
--#endif
--
- #ifndef SIZE_MAX
- # ifdef SIZE_T_MAX
- #  define SIZE_MAX SIZE_T_MAX
-@@ -70,7 +65,8 @@
- /* solaris and NetBSD 1.3.x again */
- #if (!defined(HAVE_STDINT_H)) && (!defined(HAVE_INTTYPES_H)) && (!defined(uint32_t))
--# define uint32_t u_int32_t
-+/* # define uint32_t u_int32_t */
-+typedef unsigned __int32 uint32_t;
- #endif
-@@ -80,24 +76,25 @@
- #include "settings.h"
--typedef enum { T_CONFIG_UNSET, 
--              T_CONFIG_STRING, 
--              T_CONFIG_SHORT, 
--              T_CONFIG_BOOLEAN, 
--              T_CONFIG_ARRAY, 
--              T_CONFIG_LOCAL, 
--              T_CONFIG_DEPRECATED
-+typedef enum { T_CONFIG_UNSET,
-+              T_CONFIG_STRING,
-+              T_CONFIG_SHORT,
-+              T_CONFIG_BOOLEAN,
-+              T_CONFIG_ARRAY,
-+              T_CONFIG_LOCAL,
-+              T_CONFIG_DEPRECATED,
-+              T_CONFIG_UNSUPPORTED
- } config_values_type_t;
--typedef enum { T_CONFIG_SCOPE_UNSET, 
--              T_CONFIG_SCOPE_SERVER, 
-+typedef enum { T_CONFIG_SCOPE_UNSET,
-+              T_CONFIG_SCOPE_SERVER,
-               T_CONFIG_SCOPE_CONNECTION
- } config_scope_type_t;
- typedef struct {
-       const char *key;
-       void *destination;
--      
-+
-       config_values_type_t type;
-       config_scope_type_t scope;
- } config_values_t;
-@@ -118,64 +115,38 @@
-       short factor;
- } fcgi_connections;
--
--typedef union {
--#ifdef HAVE_IPV6
--      struct sockaddr_in6 ipv6;
--#endif
--      struct sockaddr_in ipv4;
--#ifdef HAVE_SYS_UN_H
--      struct sockaddr_un un;
--#endif
--      struct sockaddr plain;
--} sock_addr;
--
--/* fcgi_response_header contains ... */
--#define HTTP_STATUS         BV(0)
--#define HTTP_CONNECTION     BV(1)
--#define HTTP_CONTENT_LENGTH BV(2)
--#define HTTP_DATE           BV(3)
--#define HTTP_LOCATION       BV(4)
--
- typedef struct {
-       /** HEADER */
-       /* the request-line */
-       buffer *request;
-       buffer *uri;
--      
-+
-       buffer *orig_uri;
--      
-+
-       http_method_t  http_method;
-       http_version_t http_version;
--      
--      buffer *request_line;
--      
--      /* strings to the header */
--      buffer *http_host; /* not alloced */
--      const char   *http_range;
--      const char   *http_content_type;
--      const char   *http_if_modified_since;
--      const char   *http_if_none_match;
--      
-+
-+      buffer *http_host;
-+
-       array  *headers;
--      
-+
-       /* CONTENT */
--      size_t content_length; /* returned by strtoul() */
--      
-+      off_t   content_length; /* returned by strtoul() */
-+
-       /* internal representation */
-       int     accept_encoding;
--      
-+
-       /* internal */
-       buffer *pathinfo;
- } request;
- typedef struct {
-       off_t   content_length;
--      int     keep_alive;               /* used by  the subrequests in proxy, cgi and fcgi to say the subrequest was keep-alive or not */
--      
-+      int     keep_alive;               /* used by the subrequests in proxy, cgi and fcgi to say whether the subrequest was keep-alive or not */
-+
-       array  *headers;
--      
--      enum { 
-+
-+      enum {
-               HTTP_TRANSFER_ENCODING_IDENTITY, HTTP_TRANSFER_ENCODING_CHUNKED
-       } transfer_encoding;
- } response;
-@@ -191,21 +162,25 @@
- typedef struct {
-       buffer *path;
-       buffer *basedir; /* path = "(basedir)(.*)" */
--      
-+
-       buffer *doc_root; /* path = doc_root + rel_path */
-       buffer *rel_path;
--      
-+
-       buffer *etag;
- } physical;
- typedef struct {
-       buffer *name;
-       buffer *etag;
--      
-+
-       struct stat st;
--      
-+
-       time_t stat_ts;
--      
-+
-+#ifdef HAVE_LSTAT
-+      char is_symlink;
-+#endif
-+
- #ifdef HAVE_FAM_H
-       int    dir_version;
-       int    dir_ndx;
-@@ -215,20 +190,20 @@
- } stat_cache_entry;
- typedef struct {
--      splay_tree *files; /* the nodes of the tree are stat_cache_entry's */
--      
-+      splay_tree *files; /* the nodes of the tree are stat_cache_entries */
-+
-       buffer *dir_name; /* for building the dirname from the filename */
- #ifdef HAVE_FAM_H
-       splay_tree *dirs; /* the nodes of the tree are fam_dir_entry */
-       FAMConnection *fam;
--      int    fam_fcce_ndx;
-+      iosocket *sock;
- #endif
- } stat_cache;
- typedef struct {
-       array *mimetypes;
--      
-+
-       /* virtual-servers */
-       buffer *document_root;
-       buffer *server_name;
-@@ -236,7 +211,7 @@
-       buffer *server_tag;
-       buffer *dirlist_encoding;
-       buffer *errorfile_prefix;
--      
-+
-       unsigned short max_keep_alive_requests;
-       unsigned short max_keep_alive_idle;
-       unsigned short max_read_idle;
-@@ -244,16 +219,17 @@
-       unsigned short use_xattr;
-       unsigned short follow_symlink;
-       unsigned short range_requests;
--      
-+
-       /* debug */
--      
-+
-       unsigned short log_file_not_found;
-       unsigned short log_request_header;
-       unsigned short log_request_handling;
-       unsigned short log_response_header;
-       unsigned short log_condition_handling;
--      
--      
-+      unsigned short log_condition_cache_handling;
-+
-+
-       /* server wide */
-       buffer *ssl_pemfile;
-       buffer *ssl_ca_file;
-@@ -268,22 +244,22 @@
-       /* configside */
-       unsigned short global_kbytes_per_second; /*  */
--      off_t  global_bytes_per_second_cnt; 
-+      off_t  global_bytes_per_second_cnt;
-       /* server-wide traffic-shaper
--       * 
-+       *
-        * each context has the counter which is inited once
--       * a second by the global_kbytes_per_second config-var
-+       * per second by the global_kbytes_per_second config-var
-        *
-        * as soon as global_kbytes_per_second gets below 0
-        * the connected conns are "offline" a little bit
-        *
-        * the problem:
--       * we somehow have to loose our "we are writable" signal 
-+       * we somehow have to lose our "we are writable" signal
-        * on the way.
--       * 
-+       *
-        */
-       off_t *global_bytes_per_second_cnt_ptr; /*  */
--      
-+
- #ifdef USE_OPENSSL
-       SSL_CTX *ssl_ctx;
- #endif
-@@ -291,18 +267,19 @@
- /* the order of the items should be the same as they are processed
-  * read before write as we use this later */
--typedef enum { 
--      CON_STATE_CONNECT, 
--      CON_STATE_REQUEST_START, 
--      CON_STATE_READ, 
--      CON_STATE_REQUEST_END, 
--      CON_STATE_READ_POST, 
--      CON_STATE_HANDLE_REQUEST, 
--      CON_STATE_RESPONSE_START, 
--      CON_STATE_WRITE, 
--      CON_STATE_RESPONSE_END, 
--      CON_STATE_ERROR, 
--      CON_STATE_CLOSE 
-+typedef enum {
-+      CON_STATE_CONNECT,         /** we are wait for a connect */
-+      CON_STATE_REQUEST_START,   /** after the connect, the request is initialized, keep-alive starts here again */
-+      CON_STATE_READ_REQUEST_HEADER,   /** loop in the read-request-header until the full header is received */
-+      CON_STATE_VALIDATE_REQUEST_HEADER,   /** validate the request-header */
-+      CON_STATE_HANDLE_REQUEST_HEADER, /** find a handler for the request */
-+      CON_STATE_READ_REQUEST_CONTENT,  /** forward the request content to the handler */
-+      CON_STATE_HANDLE_RESPONSE_HEADER, /** the backend bounces the response back to the client */
-+      CON_STATE_WRITE_RESPONSE_HEADER,
-+      CON_STATE_WRITE_RESPONSE_CONTENT,
-+      CON_STATE_RESPONSE_END,
-+      CON_STATE_ERROR,
-+      CON_STATE_CLOSE
- } connection_state_t;
- typedef enum { COND_RESULT_UNSET, COND_RESULT_FALSE, COND_RESULT_TRUE } cond_result_t;
-@@ -315,91 +292,87 @@
- typedef struct {
-       connection_state_t state;
--      
-+
-       /* timestamps */
-       time_t read_idle_ts;
-       time_t close_timeout_ts;
-       time_t write_request_ts;
--      
-+
-       time_t connection_start;
-       time_t request_start;
--      
-+
-       struct timeval start_tv;
--      
-+
-       size_t request_count;        /* number of requests handled in this connection */
-       size_t loops_per_request;    /* to catch endless loops in a single request
--                                    * 
-+                                    *
-                                     * used by mod_rewrite, mod_fastcgi, ... and others
-                                     * this is self-protection
-                                     */
--      
--      int fd;                      /* the FD for this connection */
--      int fde_ndx;                 /* index for the fdevent-handler */
-+
-+      iosocket *sock;
-       int ndx;                     /* reverse mapping to server->connection[ndx] */
--      
-+
-       /* fd states */
-       int is_readable;
-       int is_writable;
--      
--      int     keep_alive;           /* only request.c can enable it, all other just disable */
--      
-+
-+      int     keep_alive;          /* only request.c can enable it, all others just disable */
-+
-       int file_started;
--      int file_finished;
--      
--      chunkqueue *write_queue;      /* a large queue for low-level write ( HTTP response ) [ file, mem ] */
--      chunkqueue *read_queue;       /* a small queue for low-level read ( HTTP request ) [ mem ] */
--      chunkqueue *request_content_queue; /* takes request-content into tempfile if necessary [ tempfile, mem ]*/
--      
-+
-+      chunkqueue *send;            /* the response-content without encoding */
-+      chunkqueue *recv;            /* the request-content, without encoding */
-+
-+      chunkqueue *send_raw;        /* the full response (HTTP-Header + compression + chunking ) */
-+      chunkqueue *recv_raw;        /* the full request (HTTP-Header + chunking ) */
-+
-       int traffic_limit_reached;
--      
-+
-       off_t bytes_written;          /* used by mod_accesslog, mod_rrd */
-       off_t bytes_written_cur_second; /* used by mod_accesslog, mod_rrd */
-       off_t bytes_read;             /* used by mod_accesslog, mod_rrd */
-       off_t bytes_header;
--      
-+
-       int http_status;
--      
-+
-       sock_addr dst_addr;
-       buffer *dst_addr_buf;
-       /* request */
-       buffer *parse_request;
--      unsigned int parsed_response; /* bitfield which contains the important header-fields of the parsed response header */
--      
-+
-+      http_req *http_req;
-       request  request;
-       request_uri uri;
--      physical physical; 
-+      physical physical;
-       response response;
--      
-+
-       size_t header_len;
--      
-+
-       buffer *authed_user;
-       array  *environment; /* used to pass lighttpd internal stuff to the FastCGI/CGI apps, setenv does that */
--      
-+
-       /* response */
-       int    got_response;
--      
-+
-       int    in_joblist;
--      
-+
-       connection_type mode;
--      
-+
-       void **plugin_ctx;           /* plugin connection specific config */
--      
-+
-       specific_config conf;        /* global connection specific config */
-       cond_cache_t *cond_cache;
--      
-+
-       buffer *server_name;
--      
-+
-       /* error-handler */
-       buffer *error_handler;
-       int error_handler_saved_status;
-       int in_error_handler;
--      
-+
-       void *srv_socket;   /* reference to the server-socket (typecast to server_socket) */
--      
--#ifdef USE_OPENSSL
--      SSL *ssl;
--#endif
- } connection;
- typedef struct {
-@@ -439,55 +412,63 @@
-       size_t size;
- } buffer_plugin;
-+typedef enum {
-+    NETWORK_STATUS_UNSET,
-+    NETWORK_STATUS_SUCCESS,
-+    NETWORK_STATUS_FATAL_ERROR,
-+    NETWORK_STATUS_CONNECTION_CLOSE,
-+    NETWORK_STATUS_WAIT_FOR_EVENT,
-+    NETWORK_STATUS_INTERRUPTED
-+} network_status_t;
-+
- typedef struct {
-       unsigned short port;
-       buffer *bindhost;
--      
--      buffer *errorlog_file;
--      unsigned short errorlog_use_syslog;
--      
-+
-       unsigned short dont_daemonize;
-       buffer *changeroot;
-       buffer *username;
-       buffer *groupname;
--      
-+
-       buffer *pid_file;
--      
-+
-       buffer *event_handler;
--      
-+
-       buffer *modules_dir;
-       buffer *network_backend;
-       array *modules;
-       array *upload_tempdirs;
--      
-+
-       unsigned short max_worker;
-       unsigned short max_fds;
-       unsigned short max_conns;
-       unsigned short max_request_size;
--      
-+
-       unsigned short log_request_header_on_error;
-       unsigned short log_state_handling;
--      
--      enum { STAT_CACHE_ENGINE_UNSET, 
--                      STAT_CACHE_ENGINE_NONE, 
--                      STAT_CACHE_ENGINE_SIMPLE, 
--                      STAT_CACHE_ENGINE_FAM 
-+
-+      enum { STAT_CACHE_ENGINE_UNSET,
-+                      STAT_CACHE_ENGINE_NONE,
-+                      STAT_CACHE_ENGINE_SIMPLE,
-+                      STAT_CACHE_ENGINE_FAM
-       } stat_cache_engine;
-       unsigned short enable_cores;
-+
-+      buffer *errorlog_file;
-+      unsigned short errorlog_use_syslog;
- } server_config;
- typedef struct {
-       sock_addr addr;
--      int       fd;
--      int       fde_ndx;
--      
-+      iosocket *sock;
-+
-       buffer *ssl_pemfile;
-       buffer *ssl_ca_file;
-       unsigned short use_ipv6;
-       unsigned short is_ssl;
--      
-+
-       buffer *srv_token;
--      
-+
- #ifdef USE_OPENSSL
-       SSL_CTX *ssl_ctx;
- #endif
-@@ -495,37 +476,32 @@
- typedef struct {
-       server_socket **ptr;
--      
-+
-       size_t size;
-       size_t used;
- } server_socket_array;
- typedef struct server {
-       server_socket_array srv_sockets;
--      
--      /* the errorlog */
--      int errorlog_fd;
--      enum { ERRORLOG_STDERR, ERRORLOG_FILE, ERRORLOG_SYSLOG } errorlog_mode;
--      buffer *errorlog_buf;
--      
-+
-       fdevents *ev, *ev_ins;
--      
-+
-       buffer_plugin plugins;
-       void *plugin_slots;
--      
-+
-       /* counters */
-       int con_opened;
-       int con_read;
-       int con_written;
-       int con_closed;
--      
-+
-       int ssl_is_init;
--      
-+
-       int max_fds;    /* max possible fds */
-       int cur_fds;    /* currently used fds */
-       int want_fds;   /* waiting fds */
-       int sockets_disabled;
--      
-+
-       size_t max_conns;
-       /* buffers */
-@@ -533,13 +509,13 @@
-       buffer *response_header;
-       buffer *response_range;
-       buffer *tmp_buf;
--      
-+
-       buffer *tmp_chunk_len;
--      
-+
-       buffer *empty_string; /* is necessary for cond_match */
-       buffer *cond_check_buf;
--      
-+
-       /* caches */
- #ifdef HAVE_IPV6
-       inet_ntop_cache_type inet_ntop_cache[INET_NTOP_CACHE_MAX];
-@@ -547,59 +523,47 @@
-       mtime_cache_type mtime_cache[FILE_CACHE_MAX];
-       array *split_vals;
--      
-+
-       /* Timestamps */
-       time_t cur_ts;
-       time_t last_generated_date_ts;
-       time_t last_generated_debug_ts;
-       time_t startup_ts;
--      
-+
-       buffer *ts_debug_str;
-       buffer *ts_date_str;
--      
-+
-       /* config-file */
-       array *config;
-       array *config_touched;
--      
-+
-       array *config_context;
-       specific_config **config_storage;
--      
-+
-       server_config  srvconf;
--      
--      int config_deprecated;
--      
-+
-+      short unsigned config_deprecated;
-+      short unsigned config_unsupported;
-+
-       connections *conns;
-       connections *joblist;
-       connections *fdwaitqueue;
--      
-+
-       stat_cache  *stat_cache;
--      /**
--       * The status array can carry all the status information you want
--       * the key to the array is <module-prefix>.<name>
--       * and the values are counters
--       *
--       * example:
--       *   fastcgi.backends        = 10
--       *   fastcgi.active-backends = 6
--       *   fastcgi.backend.<key>.load = 24
--       *   fastcgi.backend.<key>....
--       *
--       *   fastcgi.backend.<key>.disconnects = ...
--       */
--      array *status;
--      
-       fdevent_handler_t event_handler;
--      int (* network_backend_write)(struct server *srv, connection *con, int fd, chunkqueue *cq);
--      int (* network_backend_read)(struct server *srv, connection *con, int fd, chunkqueue *cq);
-+      network_status_t (* network_backend_write)(struct server *srv, connection *con, iosocket *sock, chunkqueue *cq);
-+      network_status_t (* network_backend_read)(struct server *srv, connection *con, iosocket *sock, chunkqueue *cq);
- #ifdef USE_OPENSSL
--      int (* network_ssl_backend_write)(struct server *srv, connection *con, SSL *ssl, chunkqueue *cq);
--      int (* network_ssl_backend_read)(struct server *srv, connection *con, SSL *ssl, chunkqueue *cq);
-+      network_status_t (* network_ssl_backend_write)(struct server *srv, connection *con, iosocket *sock, chunkqueue *cq);
-+      network_status_t (* network_ssl_backend_read)(struct server *srv, connection *con, iosocket *sock, chunkqueue *cq);
- #endif
-+#ifdef HAVE_PWD_H
-       uid_t uid;
-       gid_t gid;
-+#endif
- } server;
---- ../lighttpd-1.4.11/src/bitset.c    2005-08-22 01:54:12.000000000 +0300
-+++ lighttpd-1.5.0/src/bitset.c        2006-07-18 13:03:40.000000000 +0300
-@@ -6,6 +6,7 @@
- #include "bitset.h"
- #include "buffer.h"
-+#include "log.h"
- #define BITSET_BITS \
-       ( CHAR_BIT * sizeof(size_t) )
---- ../lighttpd-1.4.11/src/buffer.c    2006-01-13 00:00:45.000000000 +0200
-+++ lighttpd-1.5.0/src/buffer.c        2006-07-18 13:03:40.000000000 +0300
-@@ -12,20 +12,20 @@
- /**
-- * init the buffer 
-- * 
-+ * init the buffer
-+ *
-  */
- buffer* buffer_init(void) {
-       buffer *b;
--      
-+
-       b = malloc(sizeof(*b));
-       assert(b);
--      
-+
-       b->ptr = NULL;
-       b->size = 0;
-       b->used = 0;
--      
-+
-       return b;
- }
-@@ -36,8 +36,8 @@
- }
- /**
-- * free the buffer 
-- * 
-+ * free the buffer
-+ *
-  */
- void buffer_free(buffer *b) {
-@@ -49,39 +49,39 @@
- void buffer_reset(buffer *b) {
-       if (!b) return;
--      
-+
-       /* limit don't reuse buffer larger than ... bytes */
-       if (b->size > BUFFER_MAX_REUSE_SIZE) {
-               free(b->ptr);
-               b->ptr = NULL;
-               b->size = 0;
-       }
--      
-+
-       b->used = 0;
- }
- /**
-- * 
-- * allocate (if neccessary) enough space for 'size' bytes and 
-+ *
-+ * allocate (if necessary) enough space for 'size' bytes and
-  * set the 'used' counter to 0
-- * 
-+ *
-  */
- #define BUFFER_PIECE_SIZE 64
- int buffer_prepare_copy(buffer *b, size_t size) {
-       if (!b) return -1;
--      
--      if ((0 == b->size) || 
-+
-+      if ((0 == b->size) ||
-           (size > b->size)) {
-               if (b->size) free(b->ptr);
--              
-+
-               b->size = size;
--              
--              /* always allocate a multiply of BUFFER_PIECE_SIZE */
-+
-+              /* always allocate a multiple of BUFFER_PIECE_SIZE */
-               b->size += BUFFER_PIECE_SIZE - (b->size % BUFFER_PIECE_SIZE);
--              
-+
-               b->ptr = malloc(b->size);
-               assert(b->ptr);
-       }
-@@ -90,30 +90,30 @@
- }
- /**
-- * 
-- * increase the internal buffer (if neccessary) to append another 'size' byte
-+ *
-+ * increase the internal buffer (if necessary) to append another 'size' byte
-  * ->used isn't changed
-- * 
-+ *
-  */
- int buffer_prepare_append(buffer *b, size_t size) {
-       if (!b) return -1;
--      
-+
-       if (0 == b->size) {
-               b->size = size;
--              
--              /* always allocate a multiply of BUFFER_PIECE_SIZE */
-+
-+              /* always allocate a multiple of BUFFER_PIECE_SIZE */
-               b->size += BUFFER_PIECE_SIZE - (b->size % BUFFER_PIECE_SIZE);
--              
-+
-               b->ptr = malloc(b->size);
-               b->used = 0;
-               assert(b->ptr);
-       } else if (b->used + size > b->size) {
-               b->size += size;
--              
--              /* always allocate a multiply of BUFFER_PIECE_SIZE */
-+
-+              /* always allocate a multiple of BUFFER_PIECE_SIZE */
-               b->size += BUFFER_PIECE_SIZE - (b->size % BUFFER_PIECE_SIZE);
--              
-+
-               b->ptr = realloc(b->ptr, b->size);
-               assert(b->ptr);
-       }
-@@ -122,7 +122,7 @@
- int buffer_copy_string(buffer *b, const char *s) {
-       size_t s_len;
--      
-+
-       if (!s || !b) return -1;
-       s_len = strlen(s) + 1;
-@@ -136,26 +136,26 @@
- int buffer_copy_string_len(buffer *b, const char *s, size_t s_len) {
-       if (!s || !b) return -1;
--#if 0 
--      /* removed optimization as we have to keep the empty string 
-+#if 0
-+      /* removed optimization as we have to keep the empty string
-        * in some cases for the config handling
--       * 
-+       *
-        * url.access-deny = ( "" )
-        */
-       if (s_len == 0) return 0;
--#endif        
-+#endif
-       buffer_prepare_copy(b, s_len + 1);
--      
-+
-       memcpy(b->ptr, s, s_len);
-       b->ptr[s_len] = '\0';
-       b->used = s_len + 1;
--      
-+
-       return 0;
- }
- int buffer_copy_string_buffer(buffer *b, const buffer *src) {
-       if (!src) return -1;
--      
-+
-       if (src->used == 0) {
-               b->used = 0;
-               return 0;
-@@ -201,10 +201,10 @@
- /**
-  * append a string to the end of the buffer
-- * 
-- * the resulting buffer is terminated with a '\0' 
-- * s is treated as a un-terminated string (a \0 is handled a normal character)
-- * 
-+ *
-+ * the resulting buffer is terminated with a '\0'
-+ * s is treated as an un-terminated string (a \0 is handled as a normal character)
-+ *
-  * @param b a buffer
-  * @param s the string
-  * @param s_len size of the string (without the terminating \0)
-@@ -228,7 +228,7 @@
- int buffer_append_string_buffer(buffer *b, const buffer *src) {
-       if (!src) return -1;
-       if (src->used == 0) return 0;
--      
-+
-       return buffer_append_string_len(b, src->ptr, src->used - 1);
- }
-@@ -245,9 +245,9 @@
- int buffer_copy_memory(buffer *b, const char *s, size_t s_len) {
-       if (!s || !b) return -1;
--      
-+
-       b->used = 0;
--      
-+
-       return buffer_append_memory(b, s, s_len);
- }
-@@ -402,46 +402,115 @@
- /**
-- * init the buffer 
-- * 
-+ * init the ptr buffer
-+ *
-+ */
-+buffer_ptr *buffer_ptr_init(buffer_ptr_free_t freer)
-+{
-+      buffer_ptr *l = calloc(1, sizeof(buffer_ptr));
-+      l->free = freer;
-+
-+      return l;
-+}
-+
-+/**
-+ * free the buffer_array
-+ *
-+ */
-+void buffer_ptr_free(buffer_ptr *l)
-+{
-+      if (NULL != l) {
-+              buffer_ptr_clear(l);
-+              free(l);
-+      }
-+}
-+
-+void buffer_ptr_clear(buffer_ptr *l)
-+{
-+      assert(NULL != l);
-+
-+      if (l->free && l->used) {
-+              size_t i;
-+              for (i = 0; i < l->used; i ++) {
-+                      l->free(l->ptr[i]);
-+              }
-+      }
-+
-+      if (l->ptr) {
-+              free(l->ptr);
-+              l->ptr = NULL;
-+      }
-+      l->used = 0;
-+      l->size = 0;
-+}
-+
-+void buffer_ptr_append(buffer_ptr* l, void *item)
-+{
-+      assert(NULL != l);
-+      if (l->ptr == NULL) {
-+              l->size = 16;
-+              l->ptr = (void **)malloc(sizeof(void *) * l->size);
-+      }
-+      else if (l->used == l->size) {
-+              l->size += 16;
-+              l->ptr = realloc(l->ptr, sizeof(void *) * l->size);
-+      }
-+      l->ptr[l->used++] = item;
-+}
-+
-+void *buffer_ptr_pop(buffer_ptr* l)
-+{
-+      assert(NULL != l && l->used > 0);
-+      return l->ptr[--l->used];
-+}
-+
-+void *buffer_ptr_top(buffer_ptr* l)
-+{
-+      assert(NULL != l && l->used > 0);
-+      return l->ptr[l->used-1];
-+}
-+
-+/**
-+ * init the buffer
-+ *
-  */
- buffer_array* buffer_array_init(void) {
-       buffer_array *b;
--      
-+
-       b = malloc(sizeof(*b));
--      
-+
-       assert(b);
-       b->ptr = NULL;
-       b->size = 0;
-       b->used = 0;
--      
-+
-       return b;
- }
- void buffer_array_reset(buffer_array *b) {
-       size_t i;
--      
-+
-       if (!b) return;
--      
-+
-       /* if they are too large, reduce them */
-       for (i = 0; i < b->used; i++) {
-               buffer_reset(b->ptr[i]);
-       }
--      
-+
-       b->used = 0;
- }
- /**
-- * free the buffer_array 
-- * 
-+ * free the buffer_array
-+ *
-  */
- void buffer_array_free(buffer_array *b) {
-       size_t i;
-       if (!b) return;
--      
-+
-       for (i = 0; i < b->size; i++) {
-               if (b->ptr[i]) buffer_free(b->ptr[i]);
-       }
-@@ -451,7 +520,7 @@
- buffer *buffer_array_append_get_buffer(buffer_array *b) {
-       size_t i;
--      
-+
-       if (b->size == 0) {
-               b->size = 16;
-               b->ptr = malloc(sizeof(*b->ptr) * b->size);
-@@ -467,13 +536,13 @@
-                       b->ptr[i] = NULL;
-               }
-       }
--      
-+
-       if (b->ptr[b->used] == NULL) {
-               b->ptr[b->used] = buffer_init();
-       }
--      
-+
-       b->ptr[b->used]->used = 0;
--      
-+
-       return b->ptr[b->used++];
- }
-@@ -482,23 +551,23 @@
-       size_t i;
-       if (len == 0) return NULL;
-       if (needle == NULL) return NULL;
--      
-+
-       if (b->used < len) return NULL;
--      
-+
-       for(i = 0; i < b->used - len; i++) {
-               if (0 == memcmp(b->ptr + i, needle, len)) {
-                       return b->ptr + i;
-               }
-       }
--      
-+
-       return NULL;
- }
- buffer *buffer_init_string(const char *str) {
-       buffer *b = buffer_init();
--      
-+
-       buffer_copy_string(b, str);
--      
-+
-       return b;
- }
-@@ -507,8 +576,8 @@
- }
- /**
-- * check if two buffer contain the same data
-- * 
-+ * check if two buffers contain the same data
-+ *
-  * HISTORY: this function was pretty much optimized, but didn't handled
-  * alignment properly.
-  */
-@@ -517,105 +586,105 @@
-       if (a->used != b->used) return 0;
-       if (a->used == 0) return 1;
--      return (0 == strcmp(a->ptr, b->ptr));
-+      return (0 == strncmp(a->ptr, b->ptr, a->used - 1));
- }
- int buffer_is_equal_string(buffer *a, const char *s, size_t b_len) {
-       buffer b;
--      
-+
-       b.ptr = (char *)s;
-       b.used = b_len + 1;
--      
-+
-       return buffer_is_equal(a, &b);
- }
- /* simple-assumption:
-- * 
-- * most parts are equal and doing a case conversion needs time
-- * 
-+ *
-+ * most parts are equal and doing a case conversion takes time
-+ *
-  */
- int buffer_caseless_compare(const char *a, size_t a_len, const char *b, size_t b_len) {
-       size_t ndx = 0, max_ndx;
-       size_t *al, *bl;
-       size_t mask = sizeof(*al) - 1;
--      
-+
-       al = (size_t *)a;
-       bl = (size_t *)b;
--      
--      /* is the alignment correct ? */
-+
-+      /* is the alignment correct? */
-       if ( ((size_t)al & mask) == 0 &&
-            ((size_t)bl & mask) == 0 ) {
--              
-+
-               max_ndx = ((a_len < b_len) ? a_len : b_len) & ~mask;
--              
-+
-               for (; ndx < max_ndx; ndx += sizeof(*al)) {
-                       if (*al != *bl) break;
-                       al++; bl++;
--                      
-+
-               }
--              
-+
-       }
--      
-+
-       a = (char *)al;
-       b = (char *)bl;
--      
-+
-       max_ndx = ((a_len < b_len) ? a_len : b_len);
--      
-+
-       for (; ndx < max_ndx; ndx++) {
-               char a1 = *a++, b1 = *b++;
--              
-+
-               if (a1 != b1) {
-                       if ((a1 >= 'A' && a1 <= 'Z') && (b1 >= 'a' && b1 <= 'z'))
-                               a1 |= 32;
-                       else if ((a1 >= 'a' && a1 <= 'z') && (b1 >= 'A' && b1 <= 'Z'))
-                               b1 |= 32;
-                       if ((a1 - b1) != 0) return (a1 - b1);
--                      
-+
-               }
-       }
--      
-+
-       return 0;
- }
- /**
-  * check if the rightmost bytes of the string are equal.
-- * 
-- * 
-+ *
-+ *
-  */
- int buffer_is_equal_right_len(buffer *b1, buffer *b2, size_t len) {
-       /* no, len -> equal */
-       if (len == 0) return 1;
--      
-+
-       /* len > 0, but empty buffers -> not equal */
-       if (b1->used == 0 || b2->used == 0) return 0;
--      
-+
-       /* buffers too small -> not equal */
--      if (b1->used - 1 < len || b1->used - 1 < len) return 0;
--      
--      if (0 == strncmp(b1->ptr + b1->used - 1 - len, 
-+      if (b1->used - 1 < len || b2->used - 1 < len) return 0;
-+
-+      if (0 == strncmp(b1->ptr + b1->used - 1 - len,
-                        b2->ptr + b2->used - 1 - len, len)) {
-               return 1;
-       }
--      
-+
-       return 0;
- }
- int buffer_copy_string_hex(buffer *b, const char *in, size_t in_len) {
-       size_t i;
--      
-+
-       /* BO protection */
-       if (in_len * 2 < in_len) return -1;
--      
-+
-       buffer_prepare_copy(b, in_len * 2 + 1);
--      
-+
-       for (i = 0; i < in_len; i++) {
-               b->ptr[b->used++] = hex_chars[(in[i] >> 4) & 0x0F];
-               b->ptr[b->used++] = hex_chars[in[i] & 0x0F];
-       }
-       b->ptr[b->used++] = '\0';
--      
-+
-       return 0;
- }
-@@ -624,7 +693,7 @@
-       0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
-       */
-       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  00 -  0F control chars */
--      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  10 -  1F */ 
-+      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  10 -  1F */
-       1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1,  /*  20 -  2F space " # $ % & ' + , / */
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,  /*  30 -  3F : ; = ? @ < > */
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /*  40 -  4F */
-@@ -646,7 +715,7 @@
-       0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
-       */
-       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  00 -  0F control chars */
--      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  10 -  1F */ 
-+      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  10 -  1F */
-       1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0,  /*  20 -  2F space " # $ % & ' + , / */
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,  /*  30 -  3F : ; = ? @ < > */
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /*  40 -  4F */
-@@ -668,7 +737,7 @@
-       0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
-       */
-       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  00 -  0F control chars */
--      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  10 -  1F */ 
-+      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  10 -  1F */
-       0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /*  20 -  2F & */
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,  /*  30 -  3F < > */
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /*  40 -  4F */
-@@ -690,7 +759,7 @@
-       0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
-       */
-       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  00 -  0F control chars */
--      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  10 -  1F */ 
-+      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  10 -  1F */
-       0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /*  20 -  2F & */
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,  /*  30 -  3F < > */
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /*  40 -  4F */
-@@ -712,12 +781,12 @@
-       0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
-       */
-       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  00 -  0F control chars */
--      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  10 -  1F */ 
--      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  20 -  2F */ 
--      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  30 -  3F */ 
--      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  40 -  4F */ 
--      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  50 -  5F */ 
--      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  60 -  6F */ 
-+      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  10 -  1F */
-+      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  20 -  2F */
-+      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  30 -  3F */
-+      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  40 -  4F */
-+      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  50 -  5F */
-+      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  60 -  6F */
-       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  70 -  7F */
-       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  80 -  8F */
-       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  90 -  9F */
-@@ -734,13 +803,12 @@
-       unsigned char *ds, *d;
-       size_t d_len, ndx;
-       const char *map = NULL;
--      
-+
-       if (!s || !b) return -1;
--      
--      if (b->ptr[b->used - 1] != '\0') {
--              SEGFAULT();
--      }
--      
-+      if (b->used == 0) return -1;
-+
-+      if (b->ptr[b->used - 1] != '\0') return -1;
-+
-       if (s_len == 0) return 0;
-       switch(encoding) {
-@@ -760,12 +828,12 @@
-               map = encoded_chars_hex;
-               break;
-       case ENCODING_UNSET:
--              break;
-+              return buffer_append_string_len(b, s, s_len);
-       }
-       assert(map != NULL);
--      
--      /* count to-be-encoded-characters */
-+
-+      /* count to-be-encoded characters */
-       for (ds = (unsigned char *)s, d_len = 0, ndx = 0; ndx < s_len; ds++, ndx++) {
-               if (map[*ds]) {
-                       switch(encoding) {
-@@ -787,9 +855,9 @@
-                       d_len ++;
-               }
-       }
--      
-+
-       buffer_prepare_append(b, d_len);
--      
-+
-       for (ds = (unsigned char *)s, d = (unsigned char *)b->ptr + b->used - 1, d_len = 0, ndx = 0; ndx < s_len; ds++, ndx++) {
-               if (map[*ds]) {
-                       switch(encoding) {
-@@ -820,16 +888,16 @@
-               }
-       }
--      /* terminate buffer and calculate new length */ 
-+      /* terminate buffer and calculate new length */
-       b->ptr[b->used + d_len - 1] = '\0';
--      
-+
-       b->used += d_len;
-       return 0;
- }
--/* decodes url-special-chars inplace.
-+/* decodes url-special chars in-place.
-  * replaces non-printable characters with '_'
-  */
-@@ -854,10 +922,10 @@
-                               low = hex2int(*(src + 2));
-                               if (low != 0xFF) {
-                                       high = (high << 4) | low;
--                                      
--                                      /* map control-characters out */        
-+
-+                                      /* map out control characters */
-                                       if (high < 32 || high == 127) high = '_';
--                                      
-+
-                                       *dst = high;
-                                       src += 2;
-                               }
-@@ -891,7 +959,7 @@
-  * /abc/./xyz       gets  /abc/xyz
-  * /abc//xyz        gets  /abc/xyz
-  *
-- * NOTE: src and dest can point to the same buffer, in which case,
-+ * NOTE: src and dest can point to the same buffer, in which case
-  *       the operation is performed in-place.
-  */
-@@ -979,7 +1047,7 @@
- int light_isxdigit(int c) {
-       if (light_isdigit(c)) return 1;
--      
-+
-       c |= 32;
-       return (c >= 'a' && c <= 'f');
- }
-@@ -993,31 +1061,56 @@
-       return light_isdigit(c) || light_isalpha(c);
- }
-+#undef BUFFER_CTYPE_FUNC
-+#define BUFFER_CTYPE_FUNC(type) \
-+      int buffer_is##type(buffer *b) { \
-+              size_t i, len; \
-+              if (b->used < 2) return 0; \
-+              /* strlen */ \
-+              len = b->used - 1; \
-+              /* c-string only */ \
-+              if (b->ptr[len] != '\0') { \
-+                      return 0; \
-+              } \
-+              /* check on the whole string */ \
-+              for (i = 0; i < len; i ++) { \
-+                      if (!light_is##type(b->ptr[i])) { \
-+                              return 0; \
-+                      } \
-+              } \
-+              return 1; \
-+      }
-+
-+BUFFER_CTYPE_FUNC(digit)
-+BUFFER_CTYPE_FUNC(xdigit)
-+BUFFER_CTYPE_FUNC(alpha)
-+BUFFER_CTYPE_FUNC(alnum)
-+
- int buffer_to_lower(buffer *b) {
-       char *c;
--      
-+
-       if (b->used == 0) return 0;
--      
-+
-       for (c = b->ptr; *c; c++) {
-               if (*c >= 'A' && *c <= 'Z') {
-                       *c |= 32;
-               }
-       }
--      
-+
-       return 0;
- }
- int buffer_to_upper(buffer *b) {
-       char *c;
--      
-+
-       if (b->used == 0) return 0;
--      
-+
-       for (c = b->ptr; *c; c++) {
-               if (*c >= 'a' && *c <= 'z') {
-                       *c &= ~32;
-               }
-       }
--      
-+
-       return 0;
- }
---- ../lighttpd-1.4.11/src/buffer.h    2006-01-13 00:00:45.000000000 +0200
-+++ lighttpd-1.5.0/src/buffer.h        2006-07-18 13:03:40.000000000 +0300
-@@ -12,27 +12,43 @@
- typedef struct {
-       char *ptr;
--      
-+
-       size_t used;
-       size_t size;
- } buffer;
-+typedef void (*buffer_ptr_free_t)(void *p);
-+
-+typedef struct {
-+      void **ptr;
-+      size_t size;
-+      size_t used;
-+      buffer_ptr_free_t free;
-+} buffer_ptr;
-+
- typedef struct {
-       buffer **ptr;
--      
-+
-       size_t used;
-       size_t size;
- } buffer_array;
- typedef struct {
-       char *ptr;
--      
--      size_t offset; /* input-pointer */
--      
--      size_t used;   /* output-pointer */
-+
-+      size_t offset; /* input pointer */
-+
-+      size_t used;   /* output pointer */
-       size_t size;
- } read_buffer;
-+buffer_ptr *buffer_ptr_init(buffer_ptr_free_t freer);
-+void buffer_ptr_free(buffer_ptr *b);
-+void buffer_ptr_clear(buffer_ptr *b);
-+void buffer_ptr_append(buffer_ptr *b, void *item);
-+void *buffer_ptr_pop(buffer_ptr *b);
-+void *buffer_ptr_top(buffer_ptr *b);
-+
- buffer_array* buffer_array_init(void);
- void buffer_array_free(buffer_array *b);
- void buffer_array_reset(buffer_array *b);
-@@ -43,7 +59,7 @@
- buffer* buffer_init_string(const char *str);
- void buffer_free(buffer *b);
- void buffer_reset(buffer *b);
--      
-+
- int buffer_prepare_copy(buffer *b, size_t size);
- int buffer_prepare_append(buffer *b, size_t size);
-@@ -85,9 +101,9 @@
- typedef enum {
-       ENCODING_UNSET,
--      ENCODING_REL_URI, /* for coding a rel-uri (/with space/and%percent) nicely as part of a href */
--      ENCODING_REL_URI_PART, /* same as ENC_REL_URL plus coding / too as %2F */
--      ENCODING_HTML,    /* & becomes &amp; and so on */
-+      ENCODING_REL_URI, /* for coding a rel-uri (/with space/and%percent) nicely as part of an href */
-+      ENCODING_REL_URI_PART, /* same as ENC_REL_URL plus encoding "/" as "%2F" */
-+      ENCODING_HTML,    /* "&" becomes "&amp;" and so on */
-       ENCODING_MINIMAL_XML, /* minimal encoding for xml */
-       ENCODING_HEX      /* encode string as hex */
- } buffer_encoding_t;
-@@ -111,20 +127,23 @@
- int light_isalpha(int c);
- int light_isalnum(int c);
-+#define BUFFER_CTYPE_FUNC(type) int buffer_is##type(buffer *b);
-+BUFFER_CTYPE_FUNC(digit)
-+BUFFER_CTYPE_FUNC(xdigit)
-+BUFFER_CTYPE_FUNC(alpha)
-+BUFFER_CTYPE_FUNC(alnum)
-+
-+#define BUF_STR(x) x->ptr
- #define BUFFER_APPEND_STRING_CONST(x, y) \
-       buffer_append_string_len(x, y, sizeof(y) - 1)
- #define BUFFER_COPY_STRING_CONST(x, y) \
-       buffer_copy_string_len(x, y, sizeof(y) - 1)
--#define BUFFER_APPEND_SLASH(x) \
--      if (x->used > 1 && x->ptr[x->used - 2] != '/') { BUFFER_APPEND_STRING_CONST(x, "/"); }
--
- #define CONST_STR_LEN(x) x, x ? sizeof(x) - 1 : 0
--#define CONST_BUF_LEN(x) x->ptr, x->used ? x->used - 1 : 0
-+#define CONST_BUF_LEN(x) BUF_STR(x), x->used ? x->used - 1 : 0
--
--#define SEGFAULT() do { fprintf(stderr, "%s.%d: aborted\n", __FILE__, __LINE__); abort(); } while(0)
-+      
- #define UNUSED(x) ( (void)(x) )
- #endif
---- ../lighttpd-1.4.11/src/chunk.c     2005-11-18 15:18:19.000000000 +0200
-+++ lighttpd-1.5.0/src/chunk.c 2006-09-07 00:57:05.000000000 +0300
-@@ -1,16 +1,14 @@
- /**
-  * the network chunk-API
-- * 
-- * 
-+ *
-+ *
-  */
- #include <sys/types.h>
- #include <sys/stat.h>
--#include <sys/mman.h>
- #include <stdlib.h>
- #include <fcntl.h>
--#include <unistd.h>
- #include <stdio.h>
- #include <errno.h>
-@@ -18,36 +16,39 @@
- #include "chunk.h"
-+#include "sys-mmap.h"
-+#include "sys-files.h"
-+
- chunkqueue *chunkqueue_init(void) {
-       chunkqueue *cq;
--      
-+
-       cq = calloc(1, sizeof(*cq));
--      
-+
-       cq->first = NULL;
-       cq->last = NULL;
--      
-+
-       cq->unused = NULL;
--      
-+
-       return cq;
- }
- static chunk *chunk_init(void) {
-       chunk *c;
--      
-+
-       c = calloc(1, sizeof(*c));
--      
-+
-       c->mem = buffer_init();
-       c->file.name = buffer_init();
-       c->file.fd = -1;
-       c->file.mmap.start = MAP_FAILED;
-       c->next = NULL;
--      
-+
-       return c;
- }
- static void chunk_free(chunk *c) {
-       if (!c) return;
--      
-+
-       buffer_free(c->mem);
-       buffer_free(c->file.name);
-@@ -56,13 +57,13 @@
- static void chunk_reset(chunk *c) {
-       if (!c) return;
--      
-+
-       buffer_reset(c->mem);
-       if (c->file.is_temp && !buffer_is_empty(c->file.name)) {
-               unlink(c->file.name->ptr);
-       }
--      
-+
-       buffer_reset(c->file.name);
-       if (c->file.fd != -1) {
-@@ -78,28 +79,28 @@
- void chunkqueue_free(chunkqueue *cq) {
-       chunk *c, *pc;
--      
-+
-       if (!cq) return;
--      
-+
-       for (c = cq->first; c; ) {
-               pc = c;
-               c = c->next;
-               chunk_free(pc);
-       }
--      
-+
-       for (c = cq->unused; c; ) {
-               pc = c;
-               c = c->next;
-               chunk_free(pc);
-       }
--      
-+
-       free(cq);
- }
- static chunk *chunkqueue_get_unused_chunk(chunkqueue *cq) {
-       chunk *c;
--      
--      /* check if we have a unused chunk */
-+
-+      /* check if we have an unused chunk */
-       if (!cq->unused) {
-               c = chunk_init();
-       } else {
-@@ -109,18 +110,18 @@
-               c->next = NULL;
-               cq->unused_chunks--;
-       }
--      
-+
-       return c;
- }
- static int chunkqueue_prepend_chunk(chunkqueue *cq, chunk *c) {
-       c->next = cq->first;
-       cq->first = c;
--      
-+
-       if (cq->last == NULL) {
-               cq->last = c;
-       }
--      
-+
-       return 0;
- }
-@@ -129,19 +130,19 @@
-               cq->last->next = c;
-       }
-       cq->last = c;
--      
-+
-       if (cq->first == NULL) {
-               cq->first = c;
-       }
--      
-+
-       return 0;
- }
- void chunkqueue_reset(chunkqueue *cq) {
-       chunk *c;
-       /* move everything to the unused queue */
--      
--      /* mark all read written */ 
-+
-+      /* mark all read written */
-       for (c = cq->first; c; c = c->next) {
-               switch(c->type) {
-               case MEM_CHUNK:
-@@ -150,7 +151,7 @@
-               case FILE_CHUNK:
-                       c->offset = c->file.length;
-                       break;
--              default: 
-+              default:
-                       break;
-               }
-       }
-@@ -158,97 +159,98 @@
-       chunkqueue_remove_finished_chunks(cq);
-       cq->bytes_in = 0;
-       cq->bytes_out = 0;
-+      cq->is_closed = 0;
- }
- int chunkqueue_append_file(chunkqueue *cq, buffer *fn, off_t offset, off_t len) {
-       chunk *c;
--      
-+
-       if (len == 0) return 0;
--      
-+
-       c = chunkqueue_get_unused_chunk(cq);
--      
-+
-       c->type = FILE_CHUNK;
--      
-+
-       buffer_copy_string_buffer(c->file.name, fn);
-       c->file.start = offset;
-       c->file.length = len;
-       c->offset = 0;
--      
-+
-       chunkqueue_append_chunk(cq, c);
--      
-+
-       return 0;
- }
- int chunkqueue_append_buffer(chunkqueue *cq, buffer *mem) {
-       chunk *c;
--      
-+
-       if (mem->used == 0) return 0;
--      
-+
-       c = chunkqueue_get_unused_chunk(cq);
-       c->type = MEM_CHUNK;
-       c->offset = 0;
-       buffer_copy_string_buffer(c->mem, mem);
--      
-+
-       chunkqueue_append_chunk(cq, c);
--      
-+
-       return 0;
- }
- int chunkqueue_prepend_buffer(chunkqueue *cq, buffer *mem) {
-       chunk *c;
--      
-+
-       if (mem->used == 0) return 0;
--      
-+
-       c = chunkqueue_get_unused_chunk(cq);
-       c->type = MEM_CHUNK;
-       c->offset = 0;
-       buffer_copy_string_buffer(c->mem, mem);
--      
-+
-       chunkqueue_prepend_chunk(cq, c);
--      
-+
-       return 0;
- }
- int chunkqueue_append_mem(chunkqueue *cq, const char * mem, size_t len) {
-       chunk *c;
--      
-+
-       if (len == 0) return 0;
--      
-+
-       c = chunkqueue_get_unused_chunk(cq);
-       c->type = MEM_CHUNK;
-       c->offset = 0;
-       buffer_copy_string_len(c->mem, mem, len - 1);
--      
-+
-       chunkqueue_append_chunk(cq, c);
--      
-+
-       return 0;
- }
- buffer * chunkqueue_get_prepend_buffer(chunkqueue *cq) {
-       chunk *c;
--      
-+
-       c = chunkqueue_get_unused_chunk(cq);
--      
-+
-       c->type = MEM_CHUNK;
-       c->offset = 0;
-       buffer_reset(c->mem);
--      
-+
-       chunkqueue_prepend_chunk(cq, c);
--      
-+
-       return c->mem;
- }
- buffer *chunkqueue_get_append_buffer(chunkqueue *cq) {
-       chunk *c;
--      
-+
-       c = chunkqueue_get_unused_chunk(cq);
--      
-+
-       c->type = MEM_CHUNK;
-       c->offset = 0;
-       buffer_reset(c->mem);
--      
-+
-       chunkqueue_append_chunk(cq, c);
--      
-+
-       return c->mem;
- }
-@@ -263,7 +265,7 @@
- chunk *chunkqueue_get_append_tempfile(chunkqueue *cq) {
-       chunk *c;
-       buffer *template = buffer_init_string("/var/tmp/lighttpd-upload-XXXXXX");
--      
-+
-       c = chunkqueue_get_unused_chunk(cq);
-       c->type = FILE_CHUNK;
-@@ -273,12 +275,12 @@
-               size_t i;
-               /* we have several tempdirs, only if all of them fail we jump out */
--              
-+
-               for (i = 0; i < cq->tempdirs->used; i++) {
-                       data_string *ds = (data_string *)cq->tempdirs->data[i];
-                       buffer_copy_string_buffer(template, ds->value);
--                      BUFFER_APPEND_SLASH(template);
-+                      PATHNAME_APPEND_SLASH(template);
-                       BUFFER_APPEND_STRING_CONST(template, "lighttpd-upload-XXXXXX");
-                       if (-1 != (c->file.fd = mkstemp(template->ptr))) {
-@@ -300,7 +302,7 @@
-       chunkqueue_append_chunk(cq, c);
-       buffer_free(template);
--      
-+
-       return c;
- }
-@@ -308,7 +310,7 @@
- off_t chunkqueue_length(chunkqueue *cq) {
-       off_t len = 0;
-       chunk *c;
--      
-+
-       for (c = cq->first; c; c = c->next) {
-               switch (c->type) {
-               case MEM_CHUNK:
-@@ -321,14 +323,14 @@
-                       break;
-               }
-       }
--      
-+
-       return len;
- }
- off_t chunkqueue_written(chunkqueue *cq) {
-       off_t len = 0;
-       chunk *c;
--      
-+
-       for (c = cq->first; c; c = c->next) {
-               switch (c->type) {
-               case MEM_CHUNK:
-@@ -339,7 +341,7 @@
-                       break;
-               }
-       }
--      
-+
-       return len;
- }
-@@ -355,12 +357,13 @@
-               switch (c->type) {
-               case MEM_CHUNK:
-+                      if (c->mem->used == 0) is_finished = 1;
-                       if (c->offset == (off_t)c->mem->used - 1) is_finished = 1;
-                       break;
-               case FILE_CHUNK:
--                      if (c->offset == c->file.length) is_finished = 1; 
-+                      if (c->offset == c->file.length) is_finished = 1;
-                       break;
--              default: 
-+              default:
-                       break;
-               }
-@@ -383,3 +386,50 @@
-       return 0;
- }
-+
-+void chunkqueue_print(chunkqueue *cq) {
-+      chunk *c;
-+
-+      for (c = cq->first; c; c = c->next) {
-+              fprintf(stderr, "(mem) %s", c->mem->ptr + c->offset);
-+      }
-+      fprintf(stderr, "\r\n");
-+}
-+
-+
-+/**
-+ * remove the last chunk if it is empty
-+ */
-+
-+void chunkqueue_remove_empty_last_chunk(chunkqueue *cq) {
-+      chunk *c;
-+      if (!cq->last) return;
-+      if (!cq->first) return;
-+
-+      if (cq->first == cq->last) {
-+              c = cq->first;
-+
-+              if (c->type != MEM_CHUNK) return;
-+              if (c->mem->used == 0) {
-+                      chunk_free(c);
-+                      cq->first = cq->last = NULL;
-+              }
-+              return;
-+      }
-+
-+      for (c = cq->first; c->next; c = c->next) {
-+              if (c->type != MEM_CHUNK) continue;
-+              if (c->mem->used != 0) continue;
-+
-+              if (c->next == cq->last) {
-+                      cq->last = c;
-+
-+                      chunk_free(c->next);
-+                      c->next = NULL;
-+
-+                      return;
-+              }
-+      }
-+}
-+
-+
---- ../lighttpd-1.4.11/src/chunk.h     2005-11-01 09:32:21.000000000 +0200
-+++ lighttpd-1.5.0/src/chunk.h 2006-09-07 00:57:05.000000000 +0300
-@@ -6,7 +6,7 @@
- typedef struct chunk {
-       enum { UNUSED_CHUNK, MEM_CHUNK, FILE_CHUNK } type;
--      
-+
-       buffer *mem; /* either the storage of the mem-chunk or the read-ahead buffer */
-       struct {
-@@ -16,33 +16,35 @@
-               off_t  length; /* octets to send from the starting offset */
-               int    fd;
--              struct { 
-+              struct {
-                       char   *start; /* the start pointer of the mmap'ed area */
-                       size_t length; /* size of the mmap'ed area */
--                      off_t  offset; /* start is <n> octet away from the start of the file */
-+                      off_t  offset; /* start is <n> octets away from the start of the file */
-               } mmap;
--              int is_temp; /* file is temporary and will be deleted if on cleanup */
-+              int is_temp; /* file is temporary and will be deleted on cleanup */
-       } file;
--      
--      off_t  offset; /* octets sent from this chunk 
--                        the size of the chunk is either 
-+
-+      off_t  offset; /* octets sent from this chunk
-+                        the size of the chunk is either
-                         - mem-chunk: mem->used - 1
-                         - file-chunk: file.length
-                       */
--      
-+
-       struct chunk *next;
- } chunk;
- typedef struct {
-       chunk *first;
-       chunk *last;
--      
-+
-       chunk *unused;
-       size_t unused_chunks;
-       array *tempdirs;
-+      int is_closed;   /* the input to this CQ is closed */
-+
-       off_t  bytes_in, bytes_out;
- } chunkqueue;
-@@ -56,6 +58,7 @@
- buffer * chunkqueue_get_append_buffer(chunkqueue *c);
- buffer * chunkqueue_get_prepend_buffer(chunkqueue *c);
- chunk * chunkqueue_get_append_tempfile(chunkqueue *cq);
-+void chunkqueue_remove_empty_last_chunk(chunkqueue *cq);
- int chunkqueue_remove_finished_chunks(chunkqueue *cq);
-@@ -66,4 +69,6 @@
- int chunkqueue_is_empty(chunkqueue *c);
-+void chunkqueue_print(chunkqueue *cq);
-+
- #endif
---- ../lighttpd-1.4.11/src/configfile-glue.c   2006-03-03 20:14:56.000000000 +0200
-+++ lighttpd-1.5.0/src/configfile-glue.c       2006-09-07 00:57:05.000000000 +0300
-@@ -1,4 +1,5 @@
- #include <string.h>
-+#include <ctype.h>
- #include "base.h"
- #include "buffer.h"
-@@ -11,10 +12,10 @@
-  * are the external interface of lighttpd. The functions
-  * are used by the server itself and the plugins.
-  *
-- * The main-goal is to have a small library in the end 
-- * which is linked against both and which will define 
-+ * The main-goal is to have a small library in the end
-+ * which is linked against both and which will define
-  * the interface itself in the end.
-- * 
-+ *
-  */
-@@ -24,56 +25,60 @@
- int config_insert_values_internal(server *srv, array *ca, const config_values_t cv[]) {
-       size_t i;
-       data_unset *du;
--      
-+
-       for (i = 0; cv[i].key; i++) {
--              
-+
-               if (NULL == (du = array_get_element(ca, cv[i].key))) {
-                       /* no found */
--                      
-+
-                       continue;
-               }
--              
-+
-               switch (cv[i].type) {
-               case T_CONFIG_ARRAY:
-                       if (du->type == TYPE_ARRAY) {
-                               size_t j;
-                               data_array *da = (data_array *)du;
--                              
-+
-                               for (j = 0; j < da->value->used; j++) {
-                                       if (da->value->data[j]->type == TYPE_STRING) {
-                                               data_string *ds = data_string_init();
--                                              
-+
-                                               buffer_copy_string_buffer(ds->value, ((data_string *)(da->value->data[j]))->value);
-                                               if (!da->is_index_key) {
-                                                       /* the id's were generated automaticly, as we copy now we might have to renumber them
--                                                       * this is used to prepend server.modules by mod_indexfiles as it has to be loaded 
-+                                                       * this is used to prepend server.modules by mod_indexfiles as it has to be loaded
-                                                        * before mod_fastcgi and friends */
-                                                       buffer_copy_string_buffer(ds->key, ((data_string *)(da->value->data[j]))->key);
-                                               }
--                                              
-+
-                                               array_insert_unique(cv[i].destination, (data_unset *)ds);
-                                       } else {
--                                              log_error_write(srv, __FILE__, __LINE__, "sssd", 
--                                                              "the key of and array can only be a string or a integer, variable:", 
--                                                              cv[i].key, "type:", da->value->data[j]->type); 
--                                              
-+                                              log_error_write(srv, __FILE__, __LINE__, "sssd",
-+                                                              "the key of and array can only be a string or a integer, variable:",
-+                                                              cv[i].key, "type:", da->value->data[j]->type);
-+
-                                               return -1;
-                                       }
-                               }
-                       } else {
-                               log_error_write(srv, __FILE__, __LINE__, "sss", "unexpected type for key: ", cv[i].key, "array of strings");
--                              
-+
-                               return -1;
-                       }
-                       break;
-               case T_CONFIG_STRING:
-                       if (du->type == TYPE_STRING) {
-                               data_string *ds = (data_string *)du;
--                              
-+
-                               buffer_copy_string_buffer(cv[i].destination, ds->value);
-+                      } else if (du->type == TYPE_INTEGER) {
-+                              data_integer *di = (data_integer *)du;
-+
-+                              buffer_copy_long(cv[i].destination, di->value);
-                       } else {
-                               log_error_write(srv, __FILE__, __LINE__, "ssss", "unexpected type for key: ", cv[i].key, "(string)", "\"...\"");
--                              
-+
-                               return -1;
-                       }
-                       break;
-@@ -81,15 +86,20 @@
-                       switch(du->type) {
-                       case TYPE_INTEGER: {
-                               data_integer *di = (data_integer *)du;
--                              
-+
-                               *((unsigned short *)(cv[i].destination)) = di->value;
-                               break;
-                       }
-                       case TYPE_STRING: {
-                               data_string *ds = (data_string *)du;
--                                      
-+
-+                              if (buffer_isdigit(ds->value)) {
-+                                      *((unsigned short *)(cv[i].destination)) = strtol(ds->value->ptr, NULL, 10);
-+                                      break;
-+                              }
-+
-                               log_error_write(srv, __FILE__, __LINE__, "ssb", "get a string but expected a short:", cv[i].key, ds->value);
--                              
-+
-                               return -1;
-                       }
-                       default:
-@@ -100,30 +110,36 @@
-               case T_CONFIG_BOOLEAN:
-                       if (du->type == TYPE_STRING) {
-                               data_string *ds = (data_string *)du;
--                              
-+
-                               if (buffer_is_equal_string(ds->value, CONST_STR_LEN("enable"))) {
-                                       *((unsigned short *)(cv[i].destination)) = 1;
-                               } else if (buffer_is_equal_string(ds->value, CONST_STR_LEN("disable"))) {
-                                       *((unsigned short *)(cv[i].destination)) = 0;
-                               } else {
-                                       log_error_write(srv, __FILE__, __LINE__, "ssbs", "ERROR: unexpected value for key:", cv[i].key, ds->value, "(enable|disable)");
--                                              
-+
-                                       return -1;
-                               }
-                       } else {
-                               log_error_write(srv, __FILE__, __LINE__, "ssss", "ERROR: unexpected type for key:", cv[i].key, "(string)", "\"(enable|disable)\"");
--                              
-+
-                               return -1;
-                       }
-                       break;
-               case T_CONFIG_LOCAL:
-               case T_CONFIG_UNSET:
-                       break;
-+              case T_CONFIG_UNSUPPORTED:
-+                      log_error_write(srv, __FILE__, __LINE__, "ssss", "ERROR: found unsupported key:", cv[i].key, "-", (char *)(cv[i].destination));
-+                      
-+                      srv->config_unsupported = 1;
-+                      
-+                      break;
-               case T_CONFIG_DEPRECATED:
-                       log_error_write(srv, __FILE__, __LINE__, "ssss", "ERROR: found deprecated key:", cv[i].key, "-", (char *)(cv[i].destination));
--                      
-+
-                       srv->config_deprecated = 1;
--                      
-+
-                       break;
-               }
-       }
-@@ -133,25 +149,25 @@
- int config_insert_values_global(server *srv, array *ca, const config_values_t cv[]) {
-       size_t i;
-       data_unset *du;
--      
-+
-       for (i = 0; cv[i].key; i++) {
-               data_string *touched;
--              
-+
-               if (NULL == (du = array_get_element(ca, cv[i].key))) {
-                       /* no found */
--                      
-+
-                       continue;
-               }
--              
-+
-               /* touched */
-               touched = data_string_init();
--              
-+
-               buffer_copy_string(touched->value, "");
-               buffer_copy_string_buffer(touched->key, du->key);
--              
-+
-               array_insert_unique(srv->config_touched, (data_unset *)touched);
-       }
--      
-+
-       return config_insert_values_internal(srv, ca, cv);
- }
-@@ -191,25 +207,25 @@
-       }
-       /* pass the rules */
--      
-+
-       switch (dc->comp) {
-       case COMP_HTTP_HOST: {
-               char *ck_colon = NULL, *val_colon = NULL;
--              
-+
-               if (!buffer_is_empty(con->uri.authority)) {
--              
--                      /* 
-+
-+                      /*
-                        * append server-port to the HTTP_POST if necessary
-                        */
--                      
-+
-                       l = con->uri.authority;
--                      
-+
-                       switch(dc->cond) {
-                       case CONFIG_COND_NE:
-                       case CONFIG_COND_EQ:
-                               ck_colon = strchr(dc->string->ptr, ':');
-                               val_colon = strchr(l->ptr, ':');
--                              
-+
-                               if (ck_colon == val_colon) {
-                                       /* nothing to do with it */
-                                       break;
-@@ -230,21 +246,21 @@
-                               break;
-                       }
-               } else {
--                      l = NULL;
-+                      l = srv->empty_string;
-               }
-               break;
-       }
-       case COMP_HTTP_REMOTEIP: {
-               char *nm_slash;
--              /* handle remoteip limitations 
--               * 
-+              /* handle remoteip limitations
-+               *
-                * "10.0.0.1" is provided for all comparisions
--               * 
-+               *
-                * only for == and != we support
--               * 
-+               *
-                * "10.0.0.1/24"
-                */
--              
-+
-               if ((dc->cond == CONFIG_COND_EQ ||
-                    dc->cond == CONFIG_COND_NE) &&
-                   (con->dst_addr.plain.sa_family == AF_INET) &&
-@@ -253,41 +269,48 @@
-                       long nm;
-                       char *err;
-                       struct in_addr val_inp;
--                      
-+
-+                      if (con->conf.log_condition_handling) {
-+                              l = srv->empty_string;
-+
-+                              log_error_write(srv, __FILE__, __LINE__,  "bsbsb", dc->comp_key,
-+                                              "(", l, ") compare to", dc->string);
-+                      }
-+
-                       if (*(nm_slash+1) == '\0') {
-                               log_error_write(srv, __FILE__, __LINE__, "sb", "ERROR: no number after / ", dc->string);
--                                      
-+
-                               return COND_RESULT_FALSE;
-                       }
--                      
-+
-                       nm_bits = strtol(nm_slash + 1, &err, 10);
--                      
-+
-                       if (*err) {
-                               log_error_write(srv, __FILE__, __LINE__, "sbs", "ERROR: non-digit found in netmask:", dc->string, *err);
--                              
-+
-                               return COND_RESULT_FALSE;
-                       }
--                      
-+
-                       /* take IP convert to the native */
-                       buffer_copy_string_len(srv->cond_check_buf, dc->string->ptr, nm_slash - dc->string->ptr);
--#ifdef __WIN32                        
-+#ifdef _WIN32
-                       if (INADDR_NONE == (val_inp.s_addr = inet_addr(srv->cond_check_buf->ptr))) {
-                               log_error_write(srv, __FILE__, __LINE__, "sb", "ERROR: ip addr is invalid:", srv->cond_check_buf);
--                              
-+
-                               return COND_RESULT_FALSE;
-                       }
- #else
-                       if (0 == inet_aton(srv->cond_check_buf->ptr, &val_inp)) {
-                               log_error_write(srv, __FILE__, __LINE__, "sb", "ERROR: ip addr is invalid:", srv->cond_check_buf);
--                              
-+
-                               return COND_RESULT_FALSE;
-                       }
- #endif
--                      
-+
-                       /* build netmask */
-                       nm = htonl(~((1 << (32 - nm_bits)) - 1));
--                      
-+
-                       if ((val_inp.s_addr & nm) == (con->dst_addr.ipv4.sin_addr.s_addr & nm)) {
-                               return (dc->cond == CONFIG_COND_EQ) ? COND_RESULT_TRUE : COND_RESULT_FALSE;
-                       } else {
-@@ -302,13 +325,17 @@
-               l = con->uri.path;
-               break;
-+      case COMP_HTTP_QUERYSTRING:
-+              l = con->uri.query;
-+              break;
-+
-       case COMP_SERVER_SOCKET:
-               l = srv_sock->srv_token;
-               break;
-       case COMP_HTTP_REFERER: {
-               data_string *ds;
--              
-+
-               if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Referer"))) {
-                       l = ds->value;
-               } else {
-@@ -338,7 +365,7 @@
-       default:
-               return COND_RESULT_FALSE;
-       }
--      
-+
-       if (NULL == l) {
-               if (con->conf.log_condition_handling) {
-                       log_error_write(srv, __FILE__, __LINE__,  "bsbs", dc->comp_key,
-@@ -346,10 +373,10 @@
-               }
-               return COND_RESULT_FALSE;
-       }
--      
-+
-       if (con->conf.log_condition_handling) {
-               log_error_write(srv, __FILE__, __LINE__,  "bsbsb", dc->comp_key,
--                              "(", l, ") compare to ", dc->string);
-+                              "(", l, ") compare to", dc->string);
-       }
-       switch(dc->cond) {
-       case CONFIG_COND_NE:
-@@ -365,13 +392,13 @@
-       case CONFIG_COND_MATCH: {
-               cond_cache_t *cache = &con->cond_cache[dc->context_ndx];
-               int n;
--              
-+
- #ifndef elementsof
- #define elementsof(x) (sizeof(x) / sizeof(x[0]))
- #endif
-               n = pcre_exec(dc->regex, dc->regex_study, l->ptr, l->used - 1, 0, 0,
-                               cache->matches, elementsof(cache->matches));
--              
-+
-               cache->patterncount = n;
-               if (n > 0) {
-                       cache->comp_value = l;
-@@ -387,7 +414,7 @@
-               /* no way */
-               break;
-       }
--      
-+
-       return COND_RESULT_FALSE;
- }
-@@ -395,6 +422,9 @@
-       cond_cache_t *caches = con->cond_cache;
-       if (COND_RESULT_UNSET == caches[dc->context_ndx].result) {
-+              if (con->conf.log_condition_handling) {
-+                      log_error_write(srv, __FILE__, __LINE__,  "sds",  "=== start of", dc->context_ndx, "condition block ===");
-+              }
-               if (COND_RESULT_TRUE == (caches[dc->context_ndx].result = config_check_cond_nocache(srv, con, dc))) {
-                       if (dc->next) {
-                               data_config *c;
-@@ -409,11 +439,11 @@
-               }
-               if (con->conf.log_condition_handling) {
-                       log_error_write(srv, __FILE__, __LINE__, "dss", dc->context_ndx,
--                                      "(uncached) result:",
-+                                      "result:",
-                                       caches[dc->context_ndx].result == COND_RESULT_TRUE ? "true" : "false");
-               }
-       } else {
--              if (con->conf.log_condition_handling) {
-+              if (con->conf.log_condition_cache_handling) {
-                       log_error_write(srv, __FILE__, __LINE__, "dss", dc->context_ndx,
-                                       "(cached) result:",
-                                       caches[dc->context_ndx].result == COND_RESULT_TRUE ? "true" : "false");
-@@ -422,10 +452,20 @@
-       return caches[dc->context_ndx].result;
- }
--int config_check_cond(server *srv, connection *con, data_config *dc) {
--      if (con->conf.log_condition_handling) {
--              log_error_write(srv, __FILE__, __LINE__,  "s",  "=== start of condition block ===");
-+void config_cond_cache_reset(server *srv, connection *con) {
-+#if COND_RESULT_UNSET
-+      size_t i;
-+
-+      for (i = srv->config_context->used - 1; i >= 0; i --) {
-+              con->cond_cache[i].result = COND_RESULT_UNSET;
-+              con->cond_cache[i].patterncount = 0;
-       }
-+#else 
-+      memset(con->cond_cache, 0, sizeof(cond_cache_t) * srv->config_context->used);
-+#endif
-+}
-+
-+int config_check_cond(server *srv, connection *con, data_config *dc) {
-       return (config_check_cond_cached(srv, con, dc) == COND_RESULT_TRUE);
- }
-@@ -443,3 +483,85 @@
-       return 1;
- }
-+/* return <0 on error
-+ * return 0-x if matched (and replaced)
-+ */
-+int config_exec_pcre_keyvalue_buffer(connection *con, pcre_keyvalue_buffer *kvb, data_config *context, buffer *match_buf, buffer *result)
-+{
-+#ifdef HAVE_PCRE_H
-+      pcre *match;
-+      pcre_extra *extra;
-+      const char *pattern;
-+      size_t pattern_len;
-+      int n;
-+      size_t i;
-+      pcre_keyvalue *kv;
-+# define N 10
-+      int ovec[N * 3];
-+
-+      for (i = 0; i < kvb->used; i++) {
-+              kv = kvb->kv[i];
-+
-+              match       = kv->key;
-+              extra       = kv->key_extra;
-+              pattern     = kv->value->ptr;
-+              pattern_len = kv->value->used - 1;
-+
-+              if ((n = pcre_exec(match, extra, match_buf->ptr, match_buf->used - 1, 0, 0, ovec, 3 * N)) < 0) {
-+                      if (n != PCRE_ERROR_NOMATCH) {
-+                              return n;
-+                      }
-+              } else {
-+                      const char **list;
-+                      size_t start, end;
-+                      size_t k;
-+
-+                      /* it matched */
-+                      pcre_get_substring_list(match_buf->ptr, ovec, n, &list);
-+
-+                      /* search for $[0-9] */
-+
-+                      buffer_reset(result);
-+
-+                      start = 0; end = pattern_len;
-+                      for (k = 0; k < pattern_len; k++) {
-+                              if ((pattern[k] == '$' || pattern[k] == '%') &&
-+                                  isdigit((unsigned char)pattern[k + 1])) {
-+                                      /* got one */
-+
-+                                      size_t num = pattern[k + 1] - '0';
-+
-+                                      end = k;
-+
-+                                      buffer_append_string_len(result, pattern + start, end - start);
-+
-+                                      if (pattern[k] == '$') {
-+                                              /* n is always > 0 */
-+                                              if (num < (size_t)n) {
-+                                                      buffer_append_string(result, list[num]);
-+                                              }
-+                                      } else {
-+                                              config_append_cond_match_buffer(con, context, result, num);
-+                                      }
-+
-+                                      k++;
-+                                      start = k + 1;
-+                              }
-+                      }
-+
-+                      buffer_append_string_len(result, pattern + start, pattern_len - start);
-+
-+                      pcre_free(list);
-+
-+                      return i;
-+              }
-+      }
-+
-+      return PCRE_ERROR_NOMATCH;
-+#undef N
-+#else
-+      UNUSED(kvb);
-+      return -2;
-+#endif
-+}
-+
---- ../lighttpd-1.4.11/src/configfile.c        2006-02-15 14:26:42.000000000 +0200
-+++ lighttpd-1.5.0/src/configfile.c    2006-09-07 00:57:05.000000000 +0300
-@@ -2,7 +2,6 @@
- #include <stdlib.h>
- #include <fcntl.h>
--#include <unistd.h>
- #include <errno.h>
- #include <string.h>
- #include <stdio.h>
-@@ -13,21 +12,24 @@
- #include "log.h"
- #include "stream.h"
- #include "plugin.h"
--#ifdef USE_LICENSE
--#include "license.h"
--#endif
--
- #include "configparser.h"
- #include "configfile.h"
- #include "proc_open.h"
-+#include "sys-files.h"
-+#include "sys-process.h"
-+
-+#ifndef PATH_MAX
-+/* win32 */
-+#define PATH_MAX 64
-+#endif
- static int config_insert(server *srv) {
-       size_t i;
-       int ret = 0;
-       buffer *stat_cache_string;
--      
--      config_values_t cv[] = { 
-+
-+      config_values_t cv[] = {
-               { "server.bind",                 NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER },      /* 0 */
-               { "server.errorlog",             NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER },      /* 1 */
-               { "server.errorfile-prefix",     NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER },      /* 2 */
-@@ -38,7 +40,7 @@
-               { "server.tag",                  NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },  /* 7 */
-               { "server.use-ipv6",             NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 8 */
-               { "server.modules",              NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_SERVER },       /* 9 */
--              
-+
-               { "server.event-handler",        NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER },      /* 10 */
-               { "server.pid-file",             NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER },      /* 11 */
-               { "server.max-request-size",     NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },   /* 12 */
-@@ -49,30 +51,37 @@
-               { "server.max-keep-alive-requests", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 17 */
-               { "server.name",                 NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },  /* 18 */
-               { "server.max-keep-alive-idle",  NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },   /* 19 */
--              
-+
-               { "server.max-read-idle",        NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },   /* 20 */
-               { "server.max-write-idle",       NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },   /* 21 */
-               { "server.error-handler-404",    NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },  /* 22 */
-               { "server.max-fds",              NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_SERVER },       /* 23 */
-+#ifdef HAVE_LSTAT
-               { "server.follow-symlink",       NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 24 */
-+#else
-+              { "server.follow-symlink",
-+                "Your system lacks lstat(). We cant differ symlinks from files."
-+                "Please remove server.follow-symlinks from your config.",
-+                T_CONFIG_UNSUPPORTED, T_CONFIG_SCOPE_UNSET }, /* 24 */
-+#endif
-               { "server.kbytes-per-second",    NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },   /* 25 */
-               { "connection.kbytes-per-second", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },  /* 26 */
-               { "mimetype.use-xattr",          NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 27 */
-               { "mimetype.assign",             NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },   /* 28 */
-               { "ssl.pemfile",                 NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER },      /* 29 */
--              
-+
-               { "ssl.engine",                  NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },     /* 30 */
--              
-+
-               { "debug.log-file-not-found",    NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },     /* 31 */
-               { "debug.log-request-handling",  NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },     /* 32 */
-               { "debug.log-response-header",   NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },     /* 33 */
-               { "debug.log-request-header",    NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },     /* 34 */
--              
-+
-               { "server.protocol-http11",      NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },     /* 35 */
-               { "debug.log-request-header-on-error", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 36 */
-               { "debug.log-state-handling",    NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },     /* 37 */
-               { "ssl.ca-file",                 NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER },      /* 38 */
--              
-+
-               { "server.errorlog-use-syslog",  NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },     /* 39 */
-               { "server.range-requests",       NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 40 */
-               { "server.stat-cache-engine",    NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },  /* 41 */
-@@ -80,7 +89,8 @@
-               { "server.network-backend",      NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },  /* 43 */
-               { "server.upload-dirs",          NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },   /* 44 */
-               { "server.core-files",           NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 45 */
--              
-+              { "debug.log-condition-cache-handling", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },    /* 46 */
-+
-               { "server.host",                 "use server.bind instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET },
-               { "server.docroot",              "use server.document-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET },
-               { "server.virtual-root",         "load mod_simple_vhost and use simple-vhost.server-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET },
-@@ -90,11 +100,11 @@
-               { "server.groupid",              "use server.groupname instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET },
-               { "server.use-keep-alive",       "use server.max-keep-alive-requests = 0 instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET },
-               { "server.force-lower-case-files",       "use server.force-lowercase-filenames instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET },
--              
-+
-               { NULL,                          NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
-       };
--      
-+
-       /* 0 */
-       cv[0].destination = srv->srvconf.bindhost;
-       cv[1].destination = srv->srvconf.errorlog_file;
-@@ -102,33 +112,33 @@
-       cv[4].destination = srv->srvconf.username;
-       cv[5].destination = srv->srvconf.groupname;
-       cv[6].destination = &(srv->srvconf.port);
--      
-+
-       cv[9].destination = srv->srvconf.modules;
-       cv[10].destination = srv->srvconf.event_handler;
-       cv[11].destination = srv->srvconf.pid_file;
--      
-+
-       cv[13].destination = &(srv->srvconf.max_worker);
-       cv[23].destination = &(srv->srvconf.max_fds);
-       cv[36].destination = &(srv->srvconf.log_request_header_on_error);
-       cv[37].destination = &(srv->srvconf.log_state_handling);
--      
-+
-       cv[39].destination = &(srv->srvconf.errorlog_use_syslog);
--      
-+
-       stat_cache_string = buffer_init();
-       cv[41].destination = stat_cache_string;
-       cv[43].destination = srv->srvconf.network_backend;
-       cv[44].destination = srv->srvconf.upload_tempdirs;
-       cv[45].destination = &(srv->srvconf.enable_cores);
--      
-+
-       cv[42].destination = &(srv->srvconf.max_conns);
-       cv[12].destination = &(srv->srvconf.max_request_size);
-       srv->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
-       assert(srv->config_storage);
--      
-+
-       for (i = 0; i < srv->config_context->used; i++) {
-               specific_config *s;
--              
-+
-               s = calloc(1, sizeof(specific_config));
-               assert(s);
-               s->document_root = buffer_init();
-@@ -146,7 +156,9 @@
-               s->use_xattr     = 0;
-               s->is_ssl        = 0;
-               s->use_ipv6      = 0;
-+#ifdef HAVE_LSTAT
-               s->follow_symlink = 1;
-+#endif
-               s->kbytes_per_second = 0;
-               s->allow_http11  = 1;
-               s->range_requests = 1;
-@@ -154,24 +166,27 @@
-               s->global_kbytes_per_second = 0;
-               s->global_bytes_per_second_cnt = 0;
-               s->global_bytes_per_second_cnt_ptr = &s->global_bytes_per_second_cnt;
--              
-+
-               cv[2].destination = s->errorfile_prefix;
--              
-+
-               cv[7].destination = s->server_tag;
-               cv[8].destination = &(s->use_ipv6);
--              
--              
-+
-+
-               /* 13 max-worker */
-               cv[14].destination = s->document_root;
-               cv[15].destination = &(s->force_lowercase_filenames);
-               cv[16].destination = &(s->log_condition_handling);
-+              cv[46].destination = &(s->log_condition_cache_handling);
-               cv[17].destination = &(s->max_keep_alive_requests);
-               cv[18].destination = s->server_name;
-               cv[19].destination = &(s->max_keep_alive_idle);
-               cv[20].destination = &(s->max_read_idle);
-               cv[21].destination = &(s->max_write_idle);
-               cv[22].destination = s->error_handler;
-+#ifdef HAVE_LSTAT
-               cv[24].destination = &(s->follow_symlink);
-+#endif
-               /* 23 -> max-fds */
-               cv[25].destination = &(s->global_kbytes_per_second);
-               cv[26].destination = &(s->kbytes_per_second);
-@@ -179,23 +194,23 @@
-               cv[28].destination = s->mimetypes;
-               cv[29].destination = s->ssl_pemfile;
-               cv[30].destination = &(s->is_ssl);
--              
-+
-               cv[31].destination = &(s->log_file_not_found);
-               cv[32].destination = &(s->log_request_handling);
-               cv[33].destination = &(s->log_response_header);
-               cv[34].destination = &(s->log_request_header);
--              
-+
-               cv[35].destination = &(s->allow_http11);
-               cv[38].destination = s->ssl_ca_file;
-               cv[40].destination = &(s->range_requests);
--              
-+
-               srv->config_storage[i] = s;
--      
-+
-               if (0 != (ret = config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv))) {
-                       break;
-               }
-       }
--      
-+
-       if (buffer_is_empty(stat_cache_string)) {
-               srv->srvconf.stat_cache_engine = STAT_CACHE_ENGINE_SIMPLE;
-       } else if (buffer_is_equal_string(stat_cache_string, CONST_STR_LEN("simple"))) {
-@@ -205,22 +220,22 @@
-       } else if (buffer_is_equal_string(stat_cache_string, CONST_STR_LEN("disable"))) {
-               srv->srvconf.stat_cache_engine = STAT_CACHE_ENGINE_NONE;
-       } else {
--              log_error_write(srv, __FILE__, __LINE__, "sb", 
-+              log_error_write(srv, __FILE__, __LINE__, "sb",
-                               "server.stat-cache-engine can be one of \"disable\", \"simple\", \"fam\", but not:", stat_cache_string);
-               ret = HANDLER_ERROR;
-       }
--      
-+
-       buffer_free(stat_cache_string);
--      
-+
-       return ret;
--                                                               
--}
-+}
--#define PATCH(x) con->conf.x = s->x
-+#define PATCH(x) \
-+      con->conf.x = s->x
- int config_setup_connection(server *srv, connection *con) {
-       specific_config *s = srv->config_storage[0];
--      
-+
-       PATCH(allow_http11);
-       PATCH(mimetypes);
-       PATCH(document_root);
-@@ -231,25 +246,28 @@
-       PATCH(use_xattr);
-       PATCH(error_handler);
-       PATCH(errorfile_prefix);
-+#ifdef HAVE_LSTAT
-       PATCH(follow_symlink);
-+#endif
-       PATCH(server_tag);
-       PATCH(kbytes_per_second);
-       PATCH(global_kbytes_per_second);
-       PATCH(global_bytes_per_second_cnt);
--      
-+
-       con->conf.global_bytes_per_second_cnt_ptr = &s->global_bytes_per_second_cnt;
-       buffer_copy_string_buffer(con->server_name, s->server_name);
--      
-+
-       PATCH(log_request_header);
-       PATCH(log_response_header);
-       PATCH(log_request_handling);
-       PATCH(log_condition_handling);
-+      PATCH(log_condition_cache_handling);
-       PATCH(log_file_not_found);
--      
-+
-       PATCH(range_requests);
-       PATCH(force_lowercase_filenames);
-       PATCH(is_ssl);
--      
-+
-       PATCH(ssl_pemfile);
-       PATCH(ssl_ca_file);
-       return 0;
-@@ -257,22 +275,22 @@
- int config_patch_connection(server *srv, connection *con, comp_key_t comp) {
-       size_t i, j;
--      
-+
-       /* skip the first, the global context */
-       for (i = 1; i < srv->config_context->used; i++) {
-               data_config *dc = (data_config *)srv->config_context->data[i];
-               specific_config *s = srv->config_storage[i];
--              
-+
-               /* not our stage */
-               if (comp != dc->comp) continue;
--              
-+
-               /* condition didn't match */
-               if (!config_check_cond(srv, con, dc)) continue;
--              
-+
-               /* merge config */
-               for (j = 0; j < dc->value->used; j++) {
-                       data_unset *du = dc->value->data[j];
--                      
-+
-                       if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.document-root"))) {
-                               PATCH(document_root);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.range-requests"))) {
-@@ -299,8 +317,10 @@
-                               PATCH(ssl_ca_file);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.engine"))) {
-                               PATCH(is_ssl);
-+#ifdef HAVE_LSTAT
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.follow-symlink"))) {
-                               PATCH(follow_symlink);
-+#endif
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.name"))) {
-                               buffer_copy_string_buffer(con->server_name, s->server_name);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.tag"))) {
-@@ -315,11 +335,13 @@
-                               PATCH(log_response_header);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("debug.log-condition-handling"))) {
-                               PATCH(log_condition_handling);
-+                      } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("debug.log-condition-cache-handling"))) {
-+                              PATCH(log_condition_cache_handling);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("debug.log-file-not-found"))) {
-                               PATCH(log_file_not_found);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.protocol-http11"))) {
-                               PATCH(allow_http11);
--                      } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.force-lowercase-filenames"))) {  
-+                      } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.force-lowercase-filenames"))) {
-                               PATCH(force_lowercase_filenames);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.kbytes-per-second"))) {
-                               PATCH(global_kbytes_per_second);
-@@ -328,7 +350,7 @@
-                       }
-               }
-       }
--      
-+
-       return 0;
- }
- #undef PATCH
-@@ -336,15 +358,15 @@
- typedef struct {
-       int foo;
-       int bar;
--      
-+
-       const buffer *source;
-       const char *input;
-       size_t offset;
-       size_t size;
--      
-+
-       int line_pos;
-       int line;
--      
-+
-       int in_key;
-       int in_brace;
-       int in_cond;
-@@ -362,7 +384,7 @@
-       }
-       if (0 != stream_open(&(t->s), t->file)) {
--              log_error_write(srv, __FILE__, __LINE__, "sbss", 
-+              log_error_write(srv, __FILE__, __LINE__, "sbss",
-                               "opening configfile ", t->file, "failed:", strerror(errno));
-               buffer_free(t->file);
-               return -1;
-@@ -373,7 +395,7 @@
-       t->size = t->s.size;
-       t->line = 1;
-       t->line_pos = 1;
--      
-+
-       t->in_key = 1;
-       t->in_brace = 0;
-       t->in_cond = 0;
-@@ -401,7 +423,7 @@
- static int config_skip_comment(tokenizer_t *t) {
-       int i;
-       assert(t->input[t->offset] == '#');
--      for (i = 1; t->input[t->offset + i] && 
-+      for (i = 1; t->input[t->offset + i] &&
-            (t->input[t->offset + i] != '\n' && t->input[t->offset + i] != '\r');
-            i++);
-       t->offset += i;
-@@ -411,44 +433,44 @@
- static int config_tokenizer(server *srv, tokenizer_t *t, int *token_id, buffer *token) {
-       int tid = 0;
-       size_t i;
--      
-+
-       for (tid = 0; tid == 0 && t->offset < t->size && t->input[t->offset] ; ) {
-               char c = t->input[t->offset];
-               const char *start = NULL;
--              
-+
-               switch (c) {
--              case '=': 
-+              case '=':
-                       if (t->in_brace) {
-                               if (t->input[t->offset + 1] == '>') {
-                                       t->offset += 2;
--                                      
-+
-                                       buffer_copy_string(token, "=>");
--                                      
-+
-                                       tid = TK_ARRAY_ASSIGN;
-                               } else {
--                                      log_error_write(srv, __FILE__, __LINE__, "sbsdsds", 
-+                                      log_error_write(srv, __FILE__, __LINE__, "sbsdsds",
-                                                       "source:", t->source,
--                                                      "line:", t->line, "pos:", t->line_pos, 
-+                                                      "line:", t->line, "pos:", t->line_pos,
-                                                       "use => for assignments in arrays");
-                                       return -1;
-                               }
-                       } else if (t->in_cond) {
-                               if (t->input[t->offset + 1] == '=') {
-                                       t->offset += 2;
--                                      
-+
-                                       buffer_copy_string(token, "==");
--                                      
-+
-                                       tid = TK_EQ;
-                               } else if (t->input[t->offset + 1] == '~') {
-                                       t->offset += 2;
--                                      
-+
-                                       buffer_copy_string(token, "=~");
--                                      
-+
-                                       tid = TK_MATCH;
-                               } else {
--                                      log_error_write(srv, __FILE__, __LINE__, "sbsdsds", 
-+                                      log_error_write(srv, __FILE__, __LINE__, "sbsdsds",
-                                                       "source:", t->source,
--                                                      "line:", t->line, "pos:", t->line_pos, 
-+                                                      "line:", t->line, "pos:", t->line_pos,
-                                                       "only =~ and == are allowed in the condition");
-                                       return -1;
-                               }
-@@ -456,51 +478,51 @@
-                               t->in_cond = 0;
-                       } else if (t->in_key) {
-                               tid = TK_ASSIGN;
--                              
-+
-                               buffer_copy_string_len(token, t->input + t->offset, 1);
--                              
-+
-                               t->offset++;
-                               t->line_pos++;
-                       } else {
--                              log_error_write(srv, __FILE__, __LINE__, "sbsdsds", 
-+                              log_error_write(srv, __FILE__, __LINE__, "sbsdsds",
-                                               "source:", t->source,
--                                              "line:", t->line, "pos:", t->line_pos, 
-+                                              "line:", t->line, "pos:", t->line_pos,
-                                               "unexpected equal-sign: =");
-                               return -1;
-                       }
--                      
-+
-                       break;
--              case '!': 
-+              case '!':
-                       if (t->in_cond) {
-                               if (t->input[t->offset + 1] == '=') {
-                                       t->offset += 2;
--                                      
-+
-                                       buffer_copy_string(token, "!=");
--                                      
-+
-                                       tid = TK_NE;
-                               } else if (t->input[t->offset + 1] == '~') {
-                                       t->offset += 2;
--                                      
-+
-                                       buffer_copy_string(token, "!~");
--                                      
-+
-                                       tid = TK_NOMATCH;
-                               } else {
--                                      log_error_write(srv, __FILE__, __LINE__, "sbsdsds", 
-+                                      log_error_write(srv, __FILE__, __LINE__, "sbsdsds",
-                                                       "source:", t->source,
--                                                      "line:", t->line, "pos:", t->line_pos, 
-+                                                      "line:", t->line, "pos:", t->line_pos,
-                                                       "only !~ and != are allowed in the condition");
-                                       return -1;
-                               }
-                               t->in_key = 1;
-                               t->in_cond = 0;
-                       } else {
--                              log_error_write(srv, __FILE__, __LINE__, "sbsdsds", 
-+                              log_error_write(srv, __FILE__, __LINE__, "sbsdsds",
-                                               "source:", t->source,
--                                              "line:", t->line, "pos:", t->line_pos, 
-+                                              "line:", t->line, "pos:", t->line_pos,
-                                               "unexpected exclamation-marks: !");
-                               return -1;
-                       }
--                      
-+
-                       break;
-               case '\t':
-               case ' ':
-@@ -546,10 +568,10 @@
-               case ',':
-                       if (t->in_brace > 0) {
-                               tid = TK_COMMA;
--                              
-+
-                               buffer_copy_string(token, "(COMMA)");
-                       }
--                      
-+
-                       t->offset++;
-                       t->line_pos++;
-                       break;
-@@ -557,70 +579,70 @@
-                       /* search for the terminating " */
-                       start = t->input + t->offset + 1;
-                       buffer_copy_string(token, "");
--                      
-+
-                       for (i = 1; t->input[t->offset + i]; i++) {
-                               if (t->input[t->offset + i] == '\\' &&
-                                   t->input[t->offset + i + 1] == '"') {
--                                      
-+
-                                       buffer_append_string_len(token, start, t->input + t->offset + i - start);
--                                      
-+
-                                       start = t->input + t->offset + i + 1;
--                                      
-+
-                                       /* skip the " */
-                                       i++;
-                                       continue;
-                               }
--                              
--                              
-+
-+
-                               if (t->input[t->offset + i] == '"') {
-                                       tid = TK_STRING;
--                              
-+
-                                       buffer_append_string_len(token, start, t->input + t->offset + i - start);
--                                      
-+
-                                       break;
-                               }
-                       }
-                       if (t->input[t->offset + i] == '\0') {
-                               /* ERROR */
--                              
--                              log_error_write(srv, __FILE__, __LINE__, "sbsdsds", 
-+
-+                              log_error_write(srv, __FILE__, __LINE__, "sbsdsds",
-                                               "source:", t->source,
--                                              "line:", t->line, "pos:", t->line_pos, 
-+                                              "line:", t->line, "pos:", t->line_pos,
-                                               "missing closing quote");
--                              
-+
-                               return -1;
-                       }
--                      
-+
-                       t->offset += i + 1;
-                       t->line_pos += i + 1;
--                      
-+
-                       break;
-               case '(':
-                       t->offset++;
-                       t->in_brace++;
--                              
-+
-                       tid = TK_LPARAN;
--                              
-+
-                       buffer_copy_string(token, "(");
-                       break;
-               case ')':
-                       t->offset++;
-                       t->in_brace--;
--                              
-+
-                       tid = TK_RPARAN;
--                              
-+
-                       buffer_copy_string(token, ")");
-                       break;
-               case '$':
-                       t->offset++;
--                              
-+
-                       tid = TK_DOLLAR;
-                       t->in_cond = 1;
-                       t->in_key = 0;
--                              
-+
-                       buffer_copy_string(token, "$");
--                      
-+
-                       break;
-               case '+':
-@@ -637,115 +659,107 @@
-               case '{':
-                       t->offset++;
--                              
-+
-                       tid = TK_LCURLY;
--                              
-+
-                       buffer_copy_string(token, "{");
--                      
-+
-                       break;
--                      
-+
-               case '}':
-                       t->offset++;
--                              
-+
-                       tid = TK_RCURLY;
--                              
-+
-                       buffer_copy_string(token, "}");
--                      
-+
-                       break;
-               case '[':
-                       t->offset++;
--                              
-+
-                       tid = TK_LBRACKET;
--                              
-+
-                       buffer_copy_string(token, "[");
--                      
-+
-                       break;
--                      
-+
-               case ']':
-                       t->offset++;
--                              
-+
-                       tid = TK_RBRACKET;
--                              
-+
-                       buffer_copy_string(token, "]");
--                      
-+
-                       break;
-               case '#':
-                       t->line_pos += config_skip_comment(t);
--                      
-+
-                       break;
-               default:
-                       if (t->in_cond) {
--                              for (i = 0; t->input[t->offset + i] && 
-+                              for (i = 0; t->input[t->offset + i] &&
-                                    (isalpha((unsigned char)t->input[t->offset + i])
-                                     ); i++);
--                              
-+
-                               if (i && t->input[t->offset + i]) {
-                                       tid = TK_SRVVARNAME;
-                                       buffer_copy_string_len(token, t->input + t->offset, i);
--                                      
-+
-                                       t->offset += i;
-                                       t->line_pos += i;
-                               } else {
-                                       /* ERROR */
--                                      log_error_write(srv, __FILE__, __LINE__, "sbsdsds", 
-+                                      log_error_write(srv, __FILE__, __LINE__, "sbsdsds",
-                                                       "source:", t->source,
--                                                      "line:", t->line, "pos:", t->line_pos, 
-+                                                      "line:", t->line, "pos:", t->line_pos,
-                                                       "invalid character in condition");
-                                       return -1;
-                               }
-                       } else if (isdigit((unsigned char)c)) {
-                               /* take all digits */
-                               for (i = 0; t->input[t->offset + i] && isdigit((unsigned char)t->input[t->offset + i]);  i++);
--                              
-+
-                               /* was there it least a digit ? */
--                              if (i && t->input[t->offset + i]) {
-+                              if (i) {
-                                       tid = TK_INTEGER;
--                                      
-+
-                                       buffer_copy_string_len(token, t->input + t->offset, i);
--                                      
-+
-                                       t->offset += i;
-                                       t->line_pos += i;
--                              } else {
--                                      /* ERROR */
--                                      log_error_write(srv, __FILE__, __LINE__, "sbsdsds", 
--                                                      "source:", t->source,
--                                                      "line:", t->line, "pos:", t->line_pos, 
--                                                      "unexpected EOF");
--                                      
--                                      return -1;
-                               }
-                       } else {
-                               /* the key might consist of [-.0-9a-z] */
--                              for (i = 0; t->input[t->offset + i] && 
--                                   (isalnum((unsigned char)t->input[t->offset + i]) || 
-+                              for (i = 0; t->input[t->offset + i] &&
-+                                   (isalnum((unsigned char)t->input[t->offset + i]) ||
-                                     t->input[t->offset + i] == '.' ||
-                                     t->input[t->offset + i] == '_' || /* for env.* */
-                                     t->input[t->offset + i] == '-'
-                                     ); i++);
--                              
-+
-                               if (i && t->input[t->offset + i]) {
-                                       buffer_copy_string_len(token, t->input + t->offset, i);
--                                      
--                                      if (strcmp(token->ptr, "include") == 0) {
-+
-+                                      if (buffer_is_equal_string(token, CONST_STR_LEN("include"))) {
-                                               tid = TK_INCLUDE;
--                                      } else if (strcmp(token->ptr, "include_shell") == 0) {
-+                                      } else if (buffer_is_equal_string(token, CONST_STR_LEN("include_shell"))) {
-                                               tid = TK_INCLUDE_SHELL;
--                                      } else if (strcmp(token->ptr, "global") == 0) {
-+                                      } else if (buffer_is_equal_string(token, CONST_STR_LEN("global"))) {
-                                               tid = TK_GLOBAL;
--                                      } else if (strcmp(token->ptr, "else") == 0) {
-+                                      } else if (buffer_is_equal_string(token, CONST_STR_LEN("else"))) {
-                                               tid = TK_ELSE;
-                                       } else {
-                                               tid = TK_LKEY;
-                                       }
--                                      
-+
-                                       t->offset += i;
-                                       t->line_pos += i;
-                               } else {
-                                       /* ERROR */
--                                      log_error_write(srv, __FILE__, __LINE__, "sbsdsds", 
-+                                      log_error_write(srv, __FILE__, __LINE__, "sbsdsds",
-                                                       "source:", t->source,
--                                                      "line:", t->line, "pos:", t->line_pos, 
-+                                                      "line:", t->line, "pos:", t->line_pos,
-                                                       "invalid character in variable name");
-                                       return -1;
-                               }
-@@ -753,16 +767,16 @@
-                       break;
-               }
-       }
--      
-+
-       if (tid) {
-               *token_id = tid;
- #if 0
--              log_error_write(srv, __FILE__, __LINE__, "sbsdsdbdd", 
-+              log_error_write(srv, __FILE__, __LINE__, "sbsdsdbdd",
-                               "source:", t->source,
-                               "line:", t->line, "pos:", t->line_pos,
-                               token, token->used - 1, tid);
- #endif
--              
-+
-               return 1;
-       } else if (t->offset < t->size) {
-               fprintf(stderr, "%s.%d: %d, %s\n",
-@@ -781,10 +795,11 @@
-       pParser = configparserAlloc( malloc );
-       lasttoken = buffer_init();
-       token = buffer_init();
-+
-       while((1 == (ret = config_tokenizer(srv, t, &token_id, token))) && context->ok) {
-               buffer_copy_string_buffer(lasttoken, token);
-               configparser(pParser, token_id, token, context);
--              
-+
-               token = buffer_init();
-       }
-       buffer_free(token);
-@@ -797,14 +812,14 @@
-               }
-       }
-       configparserFree(pParser, free);
--      
-+
-       if (ret == -1) {
--              log_error_write(srv, __FILE__, __LINE__, "sb", 
-+              log_error_write(srv, __FILE__, __LINE__, "sb",
-                               "configfile parser failed:", lasttoken);
-       } else if (context->ok == 0) {
--              log_error_write(srv, __FILE__, __LINE__, "sbsdsdsb", 
-+              log_error_write(srv, __FILE__, __LINE__, "sbsdsdsb",
-                               "source:", t->source,
--                              "line:", t->line, "pos:", t->line_pos, 
-+                              "line:", t->line, "pos:", t->line_pos,
-                               "parser failed somehow near here:", lasttoken);
-               ret = -1;
-       }
-@@ -821,7 +836,7 @@
-       t->offset = 0;
-       t->line = 1;
-       t->line_pos = 1;
--      
-+
-       t->in_key = 1;
-       t->in_brace = 0;
-       t->in_cond = 0;
-@@ -844,7 +859,7 @@
-       }
-       if (0 != stream_open(&s, filename)) {
--              log_error_write(srv, __FILE__, __LINE__, "sbss", 
-+              log_error_write(srv, __FILE__, __LINE__, "sbss",
-                               "opening configfile ", filename, "failed:", strerror(errno));
-               ret = -1;
-       } else {
-@@ -866,7 +881,7 @@
-       char oldpwd[PATH_MAX];
-       if (NULL == getcwd(oldpwd, sizeof(oldpwd))) {
--              log_error_write(srv, __FILE__, __LINE__, "s", 
-+              log_error_write(srv, __FILE__, __LINE__, "s",
-                               "cannot get cwd", strerror(errno));
-               return -1;
-       }
-@@ -879,7 +894,7 @@
-       }
-       if (0 != proc_open_buffer(&proc, cmd, NULL, out, NULL)) {
--              log_error_write(srv, __FILE__, __LINE__, "sbss", 
-+              log_error_write(srv, __FILE__, __LINE__, "sbss",
-                               "opening", source, "failed:", strerror(errno));
-               ret = -1;
-       } else {
-@@ -896,13 +911,12 @@
- static void context_init(server *srv, config_t *context) {
-       context->srv = srv;
-       context->ok = 1;
--      context->configs_stack = array_init();
--      context->configs_stack->is_weakref = 1;
-+      context->configs_stack = buffer_ptr_init(NULL);
-       context->basedir = buffer_init();
- }
- static void context_free(config_t *context) {
--      array_free(context->configs_stack);
-+      buffer_ptr_free(context->configs_stack);
-       buffer_free(context->basedir);
- }
-@@ -918,18 +932,15 @@
-       context_init(srv, &context);
-       context.all_configs = srv->config_context;
--      pos = strrchr(fn,
--#ifdef __WIN32
--                      '\\'
--#else
--                      '/'
--#endif
--                      );
-+    /* use the current dir as basedir for all other includes
-+    */
-+      pos = strrchr(fn, DIR_SEPERATOR);
-+
-       if (pos) {
-               buffer_copy_string_len(context.basedir, fn, pos - fn + 1);
-               fn = pos + 1;
-       }
--      
-+
-       dc = data_config_init();
-       buffer_copy_string(dc->key, "global");
-@@ -944,7 +955,7 @@
-       dpid->value = getpid();
-       buffer_copy_string(dpid->key, "var.PID");
-       array_insert_unique(srv->config, (data_unset *)dpid);
--      
-+
-       dcwd = data_string_init();
-       buffer_prepare_copy(dcwd->value, 1024);
-       if (NULL != getcwd(dcwd->value->ptr, dcwd->value->size - 1)) {
-@@ -968,7 +979,7 @@
-       } else {
-               return -1;
-       }
--      
-+
-       if (NULL != (modules = (data_array *)array_get_element(srv->config, "server.modules"))) {
-               data_string *ds;
-               data_array *prepends;
-@@ -1026,22 +1037,23 @@
-               buffer_copy_string(modules->key, "server.modules");
-               array_insert_unique(srv->config, (data_unset *)modules);
-       }
--      
-+
-       if (0 != config_insert(srv)) {
-               return -1;
-       }
--      
-+
-       return 0;
- }
-+
- int config_set_defaults(server *srv) {
-       size_t i;
-       specific_config *s = srv->config_storage[0];
-       struct stat st1, st2;
--      
--      struct ev_map { fdevent_handler_t et; const char *name; } event_handlers[] = 
--      { 
-+
-+      struct ev_map { fdevent_handler_t et; const char *name; } event_handlers[] =
-+      {
-               /* - poll is most reliable
-                * - select works everywhere
-                * - linux-* are experimental
-@@ -1067,20 +1079,21 @@
- #endif
-               { FDEVENT_HANDLER_UNSET,          NULL }
-       };
--      
--      if (buffer_is_empty(s->document_root)) {  
--              log_error_write(srv, __FILE__, __LINE__, "s",  
--                              "a default document-root has to be set");  
--              
--              return -1;  
--      }  
--      
-+
-+      if (buffer_is_empty(s->document_root)) {
-+              log_error_write(srv, __FILE__, __LINE__, "s",
-+                              "a default document-root has to be set");
-+
-+              return -1;
-+      }
-+
-       if (buffer_is_empty(srv->srvconf.changeroot)) {
--              if (-1 == stat(s->document_root->ptr, &st1)) {  
--                      log_error_write(srv, __FILE__, __LINE__, "sb",  
-+        pathname_unix2local(s->document_root);
-+              if (-1 == stat(s->document_root->ptr, &st1)) {
-+                      log_error_write(srv, __FILE__, __LINE__, "sbs",
-                                       "base-docroot doesn't exist:",
--                                      s->document_root);  
-+                                      s->document_root, strerror(errno));
-                       return -1;
-               }
-@@ -1088,18 +1101,18 @@
-               buffer_copy_string_buffer(srv->tmp_buf, srv->srvconf.changeroot);
-               buffer_append_string_buffer(srv->tmp_buf, s->document_root);
--              if (-1 == stat(srv->tmp_buf->ptr, &st1)) {  
--                      log_error_write(srv, __FILE__, __LINE__, "sb",  
-+              if (-1 == stat(srv->tmp_buf->ptr, &st1)) {
-+                      log_error_write(srv, __FILE__, __LINE__, "sb",
-                                       "base-docroot doesn't exist:",
--                                      srv->tmp_buf);  
-+                                      srv->tmp_buf);
-                       return -1;
-               }
--              
-+
-       }
--      
--      buffer_copy_string_buffer(srv->tmp_buf, s->document_root);  
--      buffer_to_lower(srv->tmp_buf);  
-+      buffer_copy_string_buffer(srv->tmp_buf, s->document_root);
-+
-+      buffer_to_lower(srv->tmp_buf);
-       if (0 == stat(srv->tmp_buf->ptr, &st1)) {
-               int is_lower = 0;
-@@ -1107,68 +1120,68 @@
-               is_lower = buffer_is_equal(srv->tmp_buf, s->document_root);
-               /* lower-case existed, check upper-case */
--              buffer_copy_string_buffer(srv->tmp_buf, s->document_root);  
-+              buffer_copy_string_buffer(srv->tmp_buf, s->document_root);
--              buffer_to_upper(srv->tmp_buf);  
-+              buffer_to_upper(srv->tmp_buf);
-               /* we have to handle the special case that upper and lower-casing results in the same filename
-                * as in server.document-root = "/" or "/12345/" */
-               if (is_lower && buffer_is_equal(srv->tmp_buf, s->document_root)) {
--                      /* lower-casing and upper-casing didn't result in  
--                       * an other filename, no need to stat(), 
-+                      /* lower-casing and upper-casing didn't result in
-+                       * an other filename, no need to stat(),
-                        * just assume it is case-sensitive. */
-                       s->force_lowercase_filenames = 0;
--              } else if (0 == stat(srv->tmp_buf->ptr, &st2)) {  
-+              } else if (0 == stat(srv->tmp_buf->ptr, &st2)) {
-+
-+                      /* upper case exists too, doesn't the FS handle this ? */
-+
-+                      /* upper and lower have the same inode -> case-insensitve FS */
-+
-+                      if (st1.st_ino == st2.st_ino) {
-+                              /* upper and lower have the same inode -> case-insensitve FS */
-+
-+                              s->force_lowercase_filenames = 1;
-+                      }
-+              }
-+      }
--                      /* upper case exists too, doesn't the FS handle this ? */  
--                      
--                      /* upper and lower have the same inode -> case-insensitve FS */  
--                      
--                      if (st1.st_ino == st2.st_ino) {  
--                              /* upper and lower have the same inode -> case-insensitve FS */  
--                              
--                              s->force_lowercase_filenames = 1;  
--                      }  
--              }  
--      }  
--      
-       if (srv->srvconf.port == 0) {
-               srv->srvconf.port = s->is_ssl ? 443 : 80;
-       }
--      
-+
-       if (srv->srvconf.event_handler->used == 0) {
-               /* choose a good default
--               * 
--               * the event_handler list is sorted by 'goodness' 
-+               *
-+               * the event_handler list is sorted by 'goodness'
-                * taking the first available should be the best solution
-                */
-               srv->event_handler = event_handlers[0].et;
--              
-+
-               if (FDEVENT_HANDLER_UNSET == srv->event_handler) {
--                      log_error_write(srv, __FILE__, __LINE__, "s", 
-+                      log_error_write(srv, __FILE__, __LINE__, "s",
-                                       "sorry, there is no event handler for this system");
--                      
-+
-                       return -1;
-               }
-       } else {
-               /*
-                * User override
-                */
--              
-+
-               for (i = 0; event_handlers[i].name; i++) {
-                       if (0 == strcmp(event_handlers[i].name, srv->srvconf.event_handler->ptr)) {
-                               srv->event_handler = event_handlers[i].et;
-                               break;
-                       }
-               }
--              
-+
-               if (FDEVENT_HANDLER_UNSET == srv->event_handler) {
--                      log_error_write(srv, __FILE__, __LINE__, "sb", 
--                                      "the selected event-handler in unknown or not supported:", 
-+                      log_error_write(srv, __FILE__, __LINE__, "sb",
-+                                      "the selected event-handler in unknown or not supported:",
-                                       srv->srvconf.event_handler );
--                      
-+
-                       return -1;
-               }
-       }
-@@ -1176,19 +1189,19 @@
-       if (s->is_ssl) {
-               if (buffer_is_empty(s->ssl_pemfile)) {
-                       /* PEM file is require */
--                      
--                      log_error_write(srv, __FILE__, __LINE__, "s", 
-+
-+                      log_error_write(srv, __FILE__, __LINE__, "s",
-                                       "ssl.pemfile has to be set");
-                       return -1;
-               }
--              
-+
- #ifndef USE_OPENSSL
--              log_error_write(srv, __FILE__, __LINE__, "s", 
-+              log_error_write(srv, __FILE__, __LINE__, "s",
-                               "ssl support is missing, recompile with --with-openssl");
--              
-+
-               return -1;
- #endif
-       }
--      
-+
-       return 0;
- }
---- ../lighttpd-1.4.11/src/configfile.h        2005-08-23 17:36:12.000000000 +0300
-+++ lighttpd-1.5.0/src/configfile.h    2006-09-07 00:57:05.000000000 +0300
-@@ -9,7 +9,7 @@
-       server *srv;
-       int     ok;
-       array  *all_configs;
--      array  *configs_stack; /* to parse nested block */
-+      buffer_ptr  *configs_stack; /* to parse nested block */
-       data_config *current; /* current started with { */
-       buffer *basedir;
- } config_t;
-@@ -20,5 +20,6 @@
- int config_parse_file(server *srv, config_t *context, const char *fn);
- int config_parse_cmd(server *srv, config_t *context, const char *cmd);
- data_unset *configparser_merge_data(data_unset *op1, const data_unset *op2);
-+void config_cond_cache_reset(server *srv, connection *con);
- #endif
---- ../lighttpd-1.4.11/src/configparser.c      2006-02-01 19:51:15.000000000 +0200
-+++ lighttpd-1.5.0/src/configparser.c  2006-09-07 00:57:07.000000000 +0300
-@@ -24,52 +24,34 @@
-     dc->parent = ctx->current;
-     array_insert_unique(dc->parent->childs, (data_unset *)dc);
-   }
--  array_insert_unique(ctx->configs_stack, (data_unset *)ctx->current);
-+  buffer_ptr_append(ctx->configs_stack, (void *)ctx->current);
-   ctx->current = dc;
- }
- static data_config *configparser_pop(config_t *ctx) {
-   data_config *old = ctx->current;
--  ctx->current = (data_config *) array_pop(ctx->configs_stack);
-+  ctx->current = (data_config *) buffer_ptr_pop(ctx->configs_stack);
-   return old;
- }
- /* return a copied variable */
- static data_unset *configparser_get_variable(config_t *ctx, const buffer *key) {
--  if (strncmp(key->ptr, "env.", sizeof("env.") - 1) == 0) {
--    char *env;
--
--    if (NULL != (env = getenv(key->ptr + 4))) {
--      data_string *ds;
--      ds = data_string_init();
--      buffer_append_string(ds->value, env);
--      return (data_unset *)ds;
--    }
--
--    fprintf(stderr, "Undefined env variable: %s\n", key->ptr + 4);
--    ctx->ok = 0;
--
--    return NULL;
--  } else {
--    data_unset *du;
--    data_config *dc;
-+  data_unset *du;
-+  data_config *dc;
- #if 0
--    fprintf(stderr, "get var %s\n", key->ptr);
-+  fprintf(stderr, "get var %s\n", key->ptr);
- #endif
--    for (dc = ctx->current; dc; dc = dc->parent) {
-+  for (dc = ctx->current; dc; dc = dc->parent) {
- #if 0
--      fprintf(stderr, "get var on block: %s\n", dc->key->ptr);
--      array_print(dc->value, 0);
-+    fprintf(stderr, "get var on block: %s\n", dc->key->ptr);
-+    array_print(dc->value, 0);
- #endif
--      if (NULL != (du = array_get_element(dc->value, key->ptr))) {
--        return du->copy(du);
--      }
-+    if (NULL != (du = array_get_element(dc->value, key->ptr))) {
-+      return du->copy(du);
-     }
--    fprintf(stderr, "Undefined config variable: %s\n", key->ptr);
--    ctx->ok = 0;
--    return NULL;
-   }
-+  return NULL;
- }
- /* op1 is to be eat/return by this function, op1->key is not cared
-@@ -124,14 +106,14 @@
- }
--#line 128 "configparser.c"
-+#line 110 "configparser.c"
- /* Next is all token values, in a form suitable for use by makeheaders.
- ** This section will be null unless lemon is run with the -m switch.
- */
--/* 
-+/*
- ** These constants (all generated automatically by the parser generator)
- ** specify the various kinds of tokens (terminals) that the parser
--** understands. 
-+** understands.
- **
- ** Each symbol here is a terminal symbol in the grammar.
- */
-@@ -148,7 +130,7 @@
- **                       and nonterminals.  "int" is used otherwise.
- **    YYNOCODE           is a number of type YYCODETYPE which corresponds
- **                       to no legal terminal or nonterminal number.  This
--**                       number is used to fill in empty slots of the hash 
-+**                       number is used to fill in empty slots of the hash
- **                       table.
- **    YYFALLBACK         If defined, this indicates that one or more tokens
- **                       have fall-back values which should be used if the
-@@ -157,7 +139,7 @@
- **                       and nonterminal numbers.  "unsigned char" is
- **                       used if there are fewer than 250 rules and
- **                       states combined.  "int" is used otherwise.
--**    configparserTOKENTYPE     is the data type used for minor tokens given 
-+**    configparserTOKENTYPE     is the data type used for minor tokens given
- **                       directly to the parser from the tokenizer.
- **    YYMINORTYPE        is the data type used for all minor tokens.
- **                       This is typically a union of many types, one of
-@@ -192,8 +174,8 @@
- #define configparserARG_PDECL ,config_t *ctx
- #define configparserARG_FETCH config_t *ctx = yypParser->ctx
- #define configparserARG_STORE yypParser->ctx = ctx
--#define YYNSTATE 62
--#define YYNRULE 39
-+#define YYNSTATE 63
-+#define YYNRULE 40
- #define YYERRORSYMBOL 26
- #define YYERRSYMDT yy95
- #define YY_NO_ACTION      (YYNSTATE+YYNRULE+2)
-@@ -203,7 +185,7 @@
- /* Next are that tables used to determine what action to take based on the
- ** current state and lookahead token.  These tables are used to implement
- ** functions that take a state number and lookahead value and return an
--** action integer.  
-+** action integer.
- **
- ** Suppose the action integer is N.  Then the action is determined as
- ** follows
-@@ -228,7 +210,7 @@
- ** If the index value yy_shift_ofst[S]+X is out of range or if the value
- ** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S]
- ** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table
--** and that yy_default[S] should be used instead.  
-+** and that yy_default[S] should be used instead.
- **
- ** The formula above is for computing the action when the lookahead is
- ** a terminal symbol.  If the lookahead is a non-terminal (as occurs after
-@@ -248,67 +230,69 @@
- **  yy_default[]       Default action for each state.
- */
- static YYACTIONTYPE yy_action[] = {
-- /*     0 */     2,    3,    4,    5,   13,   14,   62,   15,    7,   44,
-- /*    10 */    20,   86,   16,   45,   28,   48,   40,   10,   39,   25,
-- /*    20 */    22,   49,   45,    8,   15,  102,    1,   20,   28,   18,
-- /*    30 */    57,   59,   19,   25,   22,   39,   19,   61,   98,   45,
-- /*    40 */    20,    6,   23,   24,   26,   28,   35,   57,   59,   12,
-- /*    50 */    25,   22,   28,   27,   36,   87,   29,   25,   22,   33,
-- /*    60 */    15,   30,   31,   20,   28,   38,    9,   17,   37,   25,
-- /*    70 */    22,   39,   42,   43,   10,   45,   11,   53,   54,   55,
-- /*    80 */    56,   28,   52,   57,   59,   34,   25,   22,   28,   27,
-- /*    90 */    32,   88,   41,   25,   22,   33,   28,   48,   46,   28,
-- /*   100 */    48,   25,   22,   58,   25,   22,   60,   21,   19,   47,
-- /*   110 */    51,   50,   25,   22,   88,   88,   93,
-+ /*     0 */     2,    3,    4,    5,   13,   14,   63,   15,    7,   45,
-+ /*    10 */    20,   88,   16,   46,   28,   49,   41,   10,   40,   25,
-+ /*    20 */    22,   50,   46,    8,   15,  104,    1,   20,   28,   18,
-+ /*    30 */    58,   60,    6,   25,   22,   40,   47,   62,   11,   46,
-+ /*    40 */    20,    9,   23,   24,   26,   29,   89,   58,   60,   10,
-+ /*    50 */    17,   38,   28,   27,   37,   19,   30,   25,   22,   34,
-+ /*    60 */    15,  100,   20,   20,   23,   24,   26,   12,   19,   31,
-+ /*    70 */    32,   40,   19,   44,   43,   46,   95,   35,   90,   89,
-+ /*    80 */    28,   49,   42,   58,   60,   25,   22,   59,   28,   27,
-+ /*    90 */    33,   48,   52,   25,   22,   34,   28,   49,   51,   28,
-+ /*   100 */    36,   25,   22,   61,   25,   22,   89,   28,   39,   89,
-+ /*   110 */    89,   89,   25,   22,   54,   55,   56,   57,   89,   28,
-+ /*   120 */    53,   21,   89,   89,   25,   22,   25,   22,
- };
- static YYCODETYPE yy_lookahead[] = {
-  /*     0 */    29,   30,   31,   32,   33,   34,    0,    1,   44,   38,
-  /*    10 */     4,   15,   41,   16,   35,   36,   45,   46,   12,   40,
-  /*    20 */    41,   42,   16,   15,    1,   27,   28,    4,   35,   36,
-- /*    30 */    24,   25,    5,   40,   41,   12,    5,   14,   11,   16,
-- /*    40 */     4,    1,    6,    7,    8,   35,   36,   24,   25,   28,
-- /*    50 */    40,   41,   35,   36,   37,   15,   39,   40,   41,   42,
-- /*    60 */     1,    9,   10,    4,   35,   36,   38,    2,    3,   40,
-- /*    70 */    41,   12,   28,   14,   46,   16,   13,   20,   21,   22,
-- /*    80 */    23,   35,   36,   24,   25,   11,   40,   41,   35,   36,
-- /*    90 */    37,   13,   13,   40,   41,   42,   35,   36,   17,   35,
-- /*   100 */    36,   40,   41,   42,   40,   41,   42,   35,    5,   18,
-- /*   110 */    43,   19,   40,   41,   47,   47,   13,
-+ /*    30 */    24,   25,    1,   40,   41,   12,   17,   14,   13,   16,
-+ /*    40 */     4,   38,    6,    7,    8,    9,   15,   24,   25,   46,
-+ /*    50 */     2,    3,   35,   36,   37,    5,   39,   40,   41,   42,
-+ /*    60 */     1,   11,    4,    4,    6,    7,    8,   28,    5,    9,
-+ /*    70 */    10,   12,    5,   14,   28,   16,   13,   11,   13,   47,
-+ /*    80 */    35,   36,   13,   24,   25,   40,   41,   42,   35,   36,
-+ /*    90 */    37,   18,   43,   40,   41,   42,   35,   36,   19,   35,
-+ /*   100 */    36,   40,   41,   42,   40,   41,   47,   35,   36,   47,
-+ /*   110 */    47,   47,   40,   41,   20,   21,   22,   23,   47,   35,
-+ /*   120 */    36,   35,   47,   47,   40,   41,   40,   41,
- };
- #define YY_SHIFT_USE_DFLT (-5)
- static signed char yy_shift_ofst[] = {
-- /*     0 */    -5,    6,   -5,   -5,   -5,   40,   -4,    8,   -3,   -5,
-- /*    10 */    63,   -5,   23,   -5,   -5,   -5,   65,   36,   31,   36,
-- /*    20 */    -5,   -5,   -5,   -5,   -5,   -5,   36,   27,   -5,   52,
-- /*    30 */    -5,   36,   -5,   74,   36,   31,   -5,   36,   31,   78,
-- /*    40 */    79,   -5,   59,   -5,   -5,   81,   91,   36,   31,   92,
-- /*    50 */    57,   36,  103,   -5,   -5,   -5,   -5,   36,   -5,   36,
-- /*    60 */    -5,   -5,
-+ /*     0 */    -5,    6,   -5,   -5,   -5,   31,   -4,    8,   -3,   -5,
-+ /*    10 */    25,   -5,   23,   -5,   -5,   -5,   48,   58,   67,   58,
-+ /*    20 */    -5,   -5,   -5,   -5,   -5,   -5,   36,   50,   -5,   -5,
-+ /*    30 */    60,   -5,   58,   -5,   66,   58,   67,   -5,   58,   67,
-+ /*    40 */    65,   69,   -5,   59,   -5,   -5,   19,   73,   58,   67,
-+ /*    50 */    79,   94,   58,   63,   -5,   -5,   -5,   -5,   58,   -5,
-+ /*    60 */    58,   -5,   -5,
- };
- #define YY_REDUCE_USE_DFLT (-37)
- static signed char yy_reduce_ofst[] = {
-- /*     0 */    -2,  -29,  -37,  -37,  -37,  -36,  -37,  -37,   28,  -37,
-- /*    10 */   -37,   21,  -29,  -37,  -37,  -37,  -37,   -7,  -37,   72,
-+ /*     0 */    -2,  -29,  -37,  -37,  -37,  -36,  -37,  -37,    3,  -37,
-+ /*    10 */   -37,   39,  -29,  -37,  -37,  -37,  -37,   -7,  -37,   86,
-  /*    20 */   -37,  -37,  -37,  -37,  -37,  -37,   17,  -37,  -37,  -37,
-- /*    30 */   -37,   53,  -37,  -37,   10,  -37,  -37,   29,  -37,  -37,
-- /*    40 */   -37,   44,  -29,  -37,  -37,  -37,  -37,  -21,  -37,  -37,
-- /*    50 */    67,   46,  -37,  -37,  -37,  -37,  -37,   61,  -37,   64,
-- /*    60 */   -37,  -37,
-+ /*    30 */   -37,  -37,   53,  -37,  -37,   64,  -37,  -37,   72,  -37,
-+ /*    40 */   -37,  -37,   46,  -29,  -37,  -37,  -37,  -37,  -21,  -37,
-+ /*    50 */   -37,   49,   84,  -37,  -37,  -37,  -37,  -37,   45,  -37,
-+ /*    60 */    61,  -37,  -37,
- };
- static YYACTIONTYPE yy_default[] = {
-- /*     0 */    64,  101,   63,   65,   66,  101,   67,  101,  101,   90,
-- /*    10 */   101,   64,  101,   68,   69,   70,  101,  101,   71,  101,
-- /*    20 */    73,   74,   76,   77,   78,   79,  101,   84,   75,  101,
-- /*    30 */    80,   82,   81,  101,  101,   85,   83,  101,   72,  101,
-- /*    40 */   101,   64,  101,   89,   91,  101,  101,  101,   98,  101,
-- /*    50 */   101,  101,  101,   94,   95,   96,   97,  101,   99,  101,
-- /*    60 */   100,   92,
-+ /*     0 */    65,  103,   64,   66,   67,  103,   68,  103,  103,   92,
-+ /*    10 */   103,   65,  103,   69,   70,   71,  103,  103,   72,  103,
-+ /*    20 */    74,   75,   77,   78,   79,   80,  103,   86,   76,   81,
-+ /*    30 */   103,   82,   84,   83,  103,  103,   87,   85,  103,   73,
-+ /*    40 */   103,  103,   65,  103,   91,   93,  103,  103,  103,  100,
-+ /*    50 */   103,  103,  103,  103,   96,   97,   98,   99,  103,  101,
-+ /*    60 */   103,  102,   94,
- };
- #define YY_SZ_ACTTAB (sizeof(yy_action)/sizeof(yy_action[0]))
- /* The next table maps tokens into fallback tokens.  If a construct
- ** like the following:
--** 
-+**
- **      %fallback ID X Y Z.
- **
- ** appears in the grammer, then ID becomes a fallback token for X, Y,
-@@ -359,10 +343,10 @@
- #endif /* NDEBUG */
- #ifndef NDEBUG
--/* 
-+/*
- ** Turn parser tracing on by giving a stream to which to write the trace
- ** and a prompt to preface each trace message.  Tracing is turned off
--** by making either argument NULL 
-+** by making either argument NULL
- **
- ** Inputs:
- ** <ul>
-@@ -387,7 +371,7 @@
- #ifndef NDEBUG
- /* For tracing shifts, the names of all terminals and nonterminals
- ** are required.  The following table supplies these names */
--static const char *yyTokenName[] = { 
-+static const char *yyTokenName[] = {
-   "$",             "EOL",           "ASSIGN",        "APPEND",      
-   "LKEY",          "PLUS",          "STRING",        "INTEGER",     
-   "LPARAN",        "RPARAN",        "COMMA",         "ARRAY_ASSIGN",
-@@ -425,27 +409,28 @@
-  /*  15 */ "value ::= STRING",
-  /*  16 */ "value ::= INTEGER",
-  /*  17 */ "value ::= array",
-- /*  18 */ "array ::= LPARAN aelements RPARAN",
-- /*  19 */ "aelements ::= aelements COMMA aelement",
-- /*  20 */ "aelements ::= aelements COMMA",
-- /*  21 */ "aelements ::= aelement",
-- /*  22 */ "aelement ::= expression",
-- /*  23 */ "aelement ::= stringop ARRAY_ASSIGN expression",
-- /*  24 */ "eols ::= EOL",
-- /*  25 */ "eols ::=",
-- /*  26 */ "globalstart ::= GLOBAL",
-- /*  27 */ "global ::= globalstart LCURLY metalines RCURLY",
-- /*  28 */ "condlines ::= condlines eols ELSE condline",
-- /*  29 */ "condlines ::= condline",
-- /*  30 */ "condline ::= context LCURLY metalines RCURLY",
-- /*  31 */ "context ::= DOLLAR SRVVARNAME LBRACKET stringop RBRACKET cond expression",
-- /*  32 */ "cond ::= EQ",
-- /*  33 */ "cond ::= MATCH",
-- /*  34 */ "cond ::= NE",
-- /*  35 */ "cond ::= NOMATCH",
-- /*  36 */ "stringop ::= expression",
-- /*  37 */ "include ::= INCLUDE stringop",
-- /*  38 */ "include_shell ::= INCLUDE_SHELL stringop",
-+ /*  18 */ "array ::= LPARAN RPARAN",
-+ /*  19 */ "array ::= LPARAN aelements RPARAN",
-+ /*  20 */ "aelements ::= aelements COMMA aelement",
-+ /*  21 */ "aelements ::= aelements COMMA",
-+ /*  22 */ "aelements ::= aelement",
-+ /*  23 */ "aelement ::= expression",
-+ /*  24 */ "aelement ::= stringop ARRAY_ASSIGN expression",
-+ /*  25 */ "eols ::= EOL",
-+ /*  26 */ "eols ::=",
-+ /*  27 */ "globalstart ::= GLOBAL",
-+ /*  28 */ "global ::= globalstart LCURLY metalines RCURLY",
-+ /*  29 */ "condlines ::= condlines eols ELSE condline",
-+ /*  30 */ "condlines ::= condline",
-+ /*  31 */ "condline ::= context LCURLY metalines RCURLY",
-+ /*  32 */ "context ::= DOLLAR SRVVARNAME LBRACKET stringop RBRACKET cond expression",
-+ /*  33 */ "cond ::= EQ",
-+ /*  34 */ "cond ::= MATCH",
-+ /*  35 */ "cond ::= NE",
-+ /*  36 */ "cond ::= NOMATCH",
-+ /*  37 */ "stringop ::= expression",
-+ /*  38 */ "include ::= INCLUDE stringop",
-+ /*  39 */ "include_shell ::= INCLUDE_SHELL stringop",
- };
- #endif /* NDEBUG */
-@@ -465,7 +450,7 @@
- #endif
- }
--/* 
-+/*
- ** This function allocates a new parser.
- ** The only argument is a pointer to a function which works like
- ** malloc.
-@@ -496,7 +481,7 @@
-     /* Here is inserted the actions which take place when a
-     ** terminal or non-terminal is destroyed.  This can happen
-     ** when the symbol is popped from the stack during a
--    ** reduce or during error processing or when a parser is 
-+    ** reduce or during error processing or when a parser is
-     ** being destroyed before it is finished parsing.
-     **
-     ** Note: during a reduce, the only symbols destroyed are those
-@@ -528,44 +513,44 @@
-     case 23:
-     case 24:
-     case 25:
--#line 160 "./configparser.y"
-+#line 143 "./configparser.y"
- { buffer_free((yypminor->yy0)); }
--#line 533 "configparser.c"
-+#line 518 "configparser.c"
-       break;
-     case 35:
--#line 151 "./configparser.y"
-+#line 134 "./configparser.y"
- { (yypminor->yy41)->free((yypminor->yy41)); }
--#line 538 "configparser.c"
-+#line 523 "configparser.c"
-       break;
-     case 36:
--#line 152 "./configparser.y"
-+#line 135 "./configparser.y"
- { (yypminor->yy41)->free((yypminor->yy41)); }
--#line 543 "configparser.c"
-+#line 528 "configparser.c"
-       break;
-     case 37:
--#line 153 "./configparser.y"
-+#line 136 "./configparser.y"
- { (yypminor->yy41)->free((yypminor->yy41)); }
--#line 548 "configparser.c"
-+#line 533 "configparser.c"
-       break;
-     case 39:
--#line 154 "./configparser.y"
-+#line 137 "./configparser.y"
- { array_free((yypminor->yy40)); }
--#line 553 "configparser.c"
-+#line 538 "configparser.c"
-       break;
-     case 40:
--#line 155 "./configparser.y"
-+#line 138 "./configparser.y"
- { array_free((yypminor->yy40)); }
--#line 558 "configparser.c"
-+#line 543 "configparser.c"
-       break;
-     case 41:
--#line 156 "./configparser.y"
-+#line 139 "./configparser.y"
- { buffer_free((yypminor->yy43)); }
--#line 563 "configparser.c"
-+#line 548 "configparser.c"
-       break;
-     case 42:
--#line 157 "./configparser.y"
-+#line 140 "./configparser.y"
- { buffer_free((yypminor->yy43)); }
--#line 568 "configparser.c"
-+#line 553 "configparser.c"
-       break;
-     default:  break;   /* If no destructor action specified: do nothing */
-   }
-@@ -597,7 +582,7 @@
-   return yymajor;
- }
--/* 
-+/*
- ** Deallocate and destroy a parser.  Destructors are all called for
- ** all stack elements before shutting the parser down.
- **
-@@ -633,7 +618,7 @@
- ){
-   int i;
-   int stateno = pParser->yystack[pParser->yyidx].stateno;
-- 
-+
-   /* if( pParser->yyidx<0 ) return YY_NO_ACTION;  */
-   i = yy_shift_ofst[stateno];
-   if( i==YY_SHIFT_USE_DFLT ){
-@@ -677,7 +662,7 @@
- ){
-   int i;
-   int stateno = pParser->yystack[pParser->yyidx].stateno;
-- 
-+
-   i = yy_reduce_ofst[stateno];
-   if( i==YY_REDUCE_USE_DFLT ){
-     return yy_default[stateno];
-@@ -759,6 +744,7 @@
-   { 35, 1 },
-   { 35, 1 },
-   { 35, 1 },
-+  { 40, 2 },
-   { 40, 3 },
-   { 39, 3 },
-   { 39, 2 },
-@@ -800,7 +786,7 @@
-   configparserARG_FETCH;
-   yymsp = &yypParser->yystack[yypParser->yyidx];
- #ifndef NDEBUG
--  if( yyTraceFILE && yyruleno>=0 
-+  if( yyTraceFILE && yyruleno>=0
-         && yyruleno<sizeof(yyRuleName)/sizeof(yyRuleName[0]) ){
-     fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt,
-       yyRuleName[yyruleno]);
-@@ -832,9 +818,9 @@
-         /* No destructor defined for global */
-         break;
-       case 5:
--#line 134 "./configparser.y"
-+#line 116 "./configparser.y"
- { yymsp[-1].minor.yy78 = NULL; }
--#line 837 "configparser.c"
-+#line 823 "configparser.c"
-   yy_destructor(1,&yymsp[0].minor);
-         break;
-       case 6:
-@@ -847,10 +833,15 @@
-   yy_destructor(1,&yymsp[0].minor);
-         break;
-       case 9:
--#line 162 "./configparser.y"
-+#line 145 "./configparser.y"
- {
-   buffer_copy_string_buffer(yymsp[0].minor.yy41->key, yymsp[-2].minor.yy43);
--  if (NULL == array_get_element(ctx->current->value, yymsp[0].minor.yy41->key->ptr)) {
-+  if (strncmp(yymsp[-2].minor.yy43->ptr, "env.", sizeof("env.") - 1) == 0) {
-+    fprintf(stderr, "Setting env variable is not supported in conditional %d %s: %s\n",
-+        ctx->current->context_ndx,
-+        ctx->current->key->ptr, yymsp[-2].minor.yy43->ptr);
-+    ctx->ok = 0;
-+  } else if (NULL == array_get_element(ctx->current->value, yymsp[0].minor.yy41->key->ptr)) {
-     array_insert_unique(ctx->current->value, yymsp[0].minor.yy41);
-     yymsp[0].minor.yy41 = NULL;
-   } else {
-@@ -864,16 +855,21 @@
-   buffer_free(yymsp[-2].minor.yy43);
-   yymsp[-2].minor.yy43 = NULL;
- }
--#line 867 "configparser.c"
-+#line 858 "configparser.c"
-   yy_destructor(2,&yymsp[-1].minor);
-         break;
-       case 10:
--#line 179 "./configparser.y"
-+#line 167 "./configparser.y"
- {
-   array *vars = ctx->current->value;
-   data_unset *du;
--  if (NULL != (du = array_get_element(vars, yymsp[-2].minor.yy43->ptr))) {
-+  if (strncmp(yymsp[-2].minor.yy43->ptr, "env.", sizeof("env.") - 1) == 0) {
-+    fprintf(stderr, "Appending env variable is not supported in conditional %d %s: %s\n",
-+        ctx->current->context_ndx,
-+        ctx->current->key->ptr, yymsp[-2].minor.yy43->ptr);
-+    ctx->ok = 0;
-+  } else if (NULL != (du = array_get_element(vars, yymsp[-2].minor.yy43->ptr))) {
-     /* exists in current block */
-     du = configparser_merge_data(du, yymsp[0].minor.yy41);
-     if (NULL == du) {
-@@ -883,6 +879,7 @@
-       buffer_copy_string_buffer(du->key, yymsp[-2].minor.yy43);
-       array_replace(vars, du);
-     }
-+    yymsp[0].minor.yy41->free(yymsp[0].minor.yy41);
-   } else if (NULL != (du = configparser_get_variable(ctx, yymsp[-2].minor.yy43))) {
-     du = configparser_merge_data(du, yymsp[0].minor.yy41);
-     if (NULL == du) {
-@@ -892,22 +889,20 @@
-       buffer_copy_string_buffer(du->key, yymsp[-2].minor.yy43);
-       array_insert_unique(ctx->current->value, du);
-     }
-+    yymsp[0].minor.yy41->free(yymsp[0].minor.yy41);
-   } else {
--    fprintf(stderr, "Undefined config variable in conditional %d %s: %s\n", 
--            ctx->current->context_ndx,
--            ctx->current->key->ptr, yymsp[-2].minor.yy43->ptr);
--    ctx->ok = 0;
-+    buffer_copy_string_buffer(yymsp[0].minor.yy41->key, yymsp[-2].minor.yy43);
-+    array_insert_unique(ctx->current->value, yymsp[0].minor.yy41);
-   }
-   buffer_free(yymsp[-2].minor.yy43);
-   yymsp[-2].minor.yy43 = NULL;
--  yymsp[0].minor.yy41->free(yymsp[0].minor.yy41);
-   yymsp[0].minor.yy41 = NULL;
- }
--#line 906 "configparser.c"
-+#line 901 "configparser.c"
-   yy_destructor(3,&yymsp[-1].minor);
-         break;
-       case 11:
--#line 214 "./configparser.y"
-+#line 206 "./configparser.y"
- {
-   if (strchr(yymsp[0].minor.yy0->ptr, '.') == NULL) {
-     yygotominor.yy43 = buffer_init_string("var.");
-@@ -919,10 +914,10 @@
-     yymsp[0].minor.yy0 = NULL;
-   }
- }
--#line 922 "configparser.c"
-+#line 917 "configparser.c"
-         break;
-       case 12:
--#line 226 "./configparser.y"
-+#line 218 "./configparser.y"
- {
-   yygotominor.yy41 = configparser_merge_data(yymsp[-2].minor.yy41, yymsp[0].minor.yy41);
-   if (NULL == yygotominor.yy41) {
-@@ -932,21 +927,38 @@
-   yymsp[0].minor.yy41->free(yymsp[0].minor.yy41);
-   yymsp[0].minor.yy41 = NULL;
- }
--#line 935 "configparser.c"
-+#line 930 "configparser.c"
-   yy_destructor(5,&yymsp[-1].minor);
-         break;
-       case 13:
--#line 236 "./configparser.y"
-+#line 228 "./configparser.y"
- {
-   yygotominor.yy41 = yymsp[0].minor.yy41;
-   yymsp[0].minor.yy41 = NULL;
- }
--#line 944 "configparser.c"
-+#line 939 "configparser.c"
-         break;
-       case 14:
--#line 241 "./configparser.y"
-+#line 233 "./configparser.y"
- {
--  yygotominor.yy41 = configparser_get_variable(ctx, yymsp[0].minor.yy43);
-+  if (strncmp(yymsp[0].minor.yy43->ptr, "env.", sizeof("env.") - 1) == 0) {
-+    char *env;
-+
-+    if (NULL != (env = getenv(yymsp[0].minor.yy43->ptr + 4))) {
-+      data_string *ds;
-+      ds = data_string_init();
-+      buffer_append_string(ds->value, env);
-+      yygotominor.yy41 = (data_unset *)ds;
-+    }
-+    else {
-+      yygotominor.yy41 = NULL;
-+      fprintf(stderr, "Undefined env variable: %s\n", yymsp[0].minor.yy43->ptr + 4);
-+      ctx->ok = 0;
-+    }
-+  } else if (NULL == (yygotominor.yy41 = configparser_get_variable(ctx, yymsp[0].minor.yy43))) {
-+    fprintf(stderr, "Undefined config variable: %s\n", yymsp[0].minor.yy43->ptr);
-+    ctx->ok = 0;
-+  }
-   if (!yygotominor.yy41) {
-     /* make a dummy so it won't crash */
-     yygotominor.yy41 = (data_unset *)data_string_init();
-@@ -954,50 +966,59 @@
-   buffer_free(yymsp[0].minor.yy43);
-   yymsp[0].minor.yy43 = NULL;
- }
--#line 957 "configparser.c"
-+#line 969 "configparser.c"
-         break;
-       case 15:
--#line 251 "./configparser.y"
-+#line 260 "./configparser.y"
- {
-   yygotominor.yy41 = (data_unset *)data_string_init();
-   buffer_copy_string_buffer(((data_string *)(yygotominor.yy41))->value, yymsp[0].minor.yy0);
-   buffer_free(yymsp[0].minor.yy0);
-   yymsp[0].minor.yy0 = NULL;
- }
--#line 967 "configparser.c"
-+#line 979 "configparser.c"
-         break;
-       case 16:
--#line 258 "./configparser.y"
-+#line 267 "./configparser.y"
- {
-   yygotominor.yy41 = (data_unset *)data_integer_init();
-   ((data_integer *)(yygotominor.yy41))->value = strtol(yymsp[0].minor.yy0->ptr, NULL, 10);
-   buffer_free(yymsp[0].minor.yy0);
-   yymsp[0].minor.yy0 = NULL;
- }
--#line 977 "configparser.c"
-+#line 989 "configparser.c"
-         break;
-       case 17:
--#line 264 "./configparser.y"
-+#line 273 "./configparser.y"
- {
-   yygotominor.yy41 = (data_unset *)data_array_init();
-   array_free(((data_array *)(yygotominor.yy41))->value);
-   ((data_array *)(yygotominor.yy41))->value = yymsp[0].minor.yy40;
-   yymsp[0].minor.yy40 = NULL;
- }
--#line 987 "configparser.c"
-+#line 999 "configparser.c"
-         break;
-       case 18:
--#line 270 "./configparser.y"
-+#line 279 "./configparser.y"
-+{
-+  yygotominor.yy40 = array_init();
-+}
-+#line 1006 "configparser.c"
-+  yy_destructor(8,&yymsp[-1].minor);
-+  yy_destructor(9,&yymsp[0].minor);
-+        break;
-+      case 19:
-+#line 282 "./configparser.y"
- {
-   yygotominor.yy40 = yymsp[-1].minor.yy40;
-   yymsp[-1].minor.yy40 = NULL;
- }
--#line 995 "configparser.c"
-+#line 1016 "configparser.c"
-   yy_destructor(8,&yymsp[-2].minor);
-   yy_destructor(9,&yymsp[0].minor);
-         break;
--      case 19:
--#line 275 "./configparser.y"
-+      case 20:
-+#line 287 "./configparser.y"
- {
-   if (buffer_is_empty(yymsp[0].minor.yy41->key) ||
-       NULL == array_get_element(yymsp[-2].minor.yy40, yymsp[0].minor.yy41->key->ptr)) {
-@@ -1014,37 +1035,37 @@
-   yygotominor.yy40 = yymsp[-2].minor.yy40;
-   yymsp[-2].minor.yy40 = NULL;
- }
--#line 1017 "configparser.c"
-+#line 1038 "configparser.c"
-   yy_destructor(10,&yymsp[-1].minor);
-         break;
--      case 20:
--#line 292 "./configparser.y"
-+      case 21:
-+#line 304 "./configparser.y"
- {
-   yygotominor.yy40 = yymsp[-1].minor.yy40;
-   yymsp[-1].minor.yy40 = NULL;
- }
--#line 1026 "configparser.c"
-+#line 1047 "configparser.c"
-   yy_destructor(10,&yymsp[0].minor);
-         break;
--      case 21:
--#line 297 "./configparser.y"
-+      case 22:
-+#line 309 "./configparser.y"
- {
-   yygotominor.yy40 = array_init();
-   array_insert_unique(yygotominor.yy40, yymsp[0].minor.yy41);
-   yymsp[0].minor.yy41 = NULL;
- }
--#line 1036 "configparser.c"
-+#line 1057 "configparser.c"
-         break;
--      case 22:
--#line 303 "./configparser.y"
-+      case 23:
-+#line 315 "./configparser.y"
- {
-   yygotominor.yy41 = yymsp[0].minor.yy41;
-   yymsp[0].minor.yy41 = NULL;
- }
--#line 1044 "configparser.c"
-+#line 1065 "configparser.c"
-         break;
--      case 23:
--#line 307 "./configparser.y"
-+      case 24:
-+#line 319 "./configparser.y"
- {
-   buffer_copy_string_buffer(yymsp[0].minor.yy41->key, yymsp[-2].minor.yy43);
-   buffer_free(yymsp[-2].minor.yy43);
-@@ -1053,27 +1074,27 @@
-   yygotominor.yy41 = yymsp[0].minor.yy41;
-   yymsp[0].minor.yy41 = NULL;
- }
--#line 1056 "configparser.c"
-+#line 1077 "configparser.c"
-   yy_destructor(11,&yymsp[-1].minor);
-         break;
--      case 24:
--  yy_destructor(1,&yymsp[0].minor);
--        break;
-       case 25:
-+  yy_destructor(1,&yymsp[0].minor);
-         break;
-       case 26:
--#line 319 "./configparser.y"
-+        break;
-+      case 27:
-+#line 331 "./configparser.y"
- {
-   data_config *dc;
-   dc = (data_config *)array_get_element(ctx->srv->config_context, "global");
-   assert(dc);
-   configparser_push(ctx, dc, 0);
- }
--#line 1072 "configparser.c"
-+#line 1093 "configparser.c"
-   yy_destructor(12,&yymsp[0].minor);
-         break;
--      case 27:
--#line 326 "./configparser.y"
-+      case 28:
-+#line 338 "./configparser.y"
- {
-   data_config *cur;
-   
-@@ -1082,16 +1103,16 @@
-   assert(cur && ctx->current);
--  yygotominor.yy0 = cur;
-+  yygotominor.yy78 = cur;
- }
--#line 1087 "configparser.c"
-+#line 1108 "configparser.c"
-         /* No destructor defined for globalstart */
-   yy_destructor(13,&yymsp[-2].minor);
-         /* No destructor defined for metalines */
-   yy_destructor(14,&yymsp[0].minor);
-         break;
--      case 28:
--#line 337 "./configparser.y"
-+      case 29:
-+#line 349 "./configparser.y"
- {
-   assert(yymsp[-3].minor.yy78->context_ndx < yymsp[0].minor.yy78->context_ndx);
-   yymsp[0].minor.yy78->prev = yymsp[-3].minor.yy78;
-@@ -1100,20 +1121,20 @@
-   yymsp[-3].minor.yy78 = NULL;
-   yymsp[0].minor.yy78 = NULL;
- }
--#line 1103 "configparser.c"
-+#line 1124 "configparser.c"
-         /* No destructor defined for eols */
-   yy_destructor(15,&yymsp[-1].minor);
-         break;
--      case 29:
--#line 346 "./configparser.y"
-+      case 30:
-+#line 358 "./configparser.y"
- {
-   yygotominor.yy78 = yymsp[0].minor.yy78;
-   yymsp[0].minor.yy78 = NULL;
- }
--#line 1113 "configparser.c"
-+#line 1134 "configparser.c"
-         break;
--      case 30:
--#line 351 "./configparser.y"
-+      case 31:
-+#line 363 "./configparser.y"
- {
-   data_config *cur;
-   
-@@ -1124,14 +1145,14 @@
-   yygotominor.yy78 = cur;
- }
--#line 1127 "configparser.c"
-+#line 1148 "configparser.c"
-         /* No destructor defined for context */
-   yy_destructor(13,&yymsp[-2].minor);
-         /* No destructor defined for metalines */
-   yy_destructor(14,&yymsp[0].minor);
-         break;
--      case 31:
--#line 362 "./configparser.y"
-+      case 32:
-+#line 374 "./configparser.y"
- {
-   data_config *dc;
-   buffer *b, *rvalue, *op;
-@@ -1183,6 +1204,7 @@
-       { COMP_HTTP_USERAGENT,     CONST_STR_LEN("HTTP[\"useragent\"]"  ) },
-       { COMP_HTTP_COOKIE,        CONST_STR_LEN("HTTP[\"cookie\"]"     ) },
-       { COMP_HTTP_REMOTEIP,      CONST_STR_LEN("HTTP[\"remoteip\"]"   ) },
-+      { COMP_HTTP_QUERYSTRING,   CONST_STR_LEN("HTTP[\"querystring\"]") },
-       { COMP_UNSET, NULL, 0 },
-     };
-     size_t i;
-@@ -1266,45 +1288,45 @@
-   yymsp[0].minor.yy41->free(yymsp[0].minor.yy41);
-   yymsp[0].minor.yy41 = NULL;
- }
--#line 1269 "configparser.c"
-+#line 1291 "configparser.c"
-   yy_destructor(16,&yymsp[-6].minor);
-   yy_destructor(18,&yymsp[-4].minor);
-   yy_destructor(19,&yymsp[-2].minor);
-         break;
--      case 32:
--#line 496 "./configparser.y"
-+      case 33:
-+#line 509 "./configparser.y"
- {
-   yygotominor.yy27 = CONFIG_COND_EQ;
- }
--#line 1279 "configparser.c"
-+#line 1301 "configparser.c"
-   yy_destructor(20,&yymsp[0].minor);
-         break;
--      case 33:
--#line 499 "./configparser.y"
-+      case 34:
-+#line 512 "./configparser.y"
- {
-   yygotominor.yy27 = CONFIG_COND_MATCH;
- }
--#line 1287 "configparser.c"
-+#line 1309 "configparser.c"
-   yy_destructor(21,&yymsp[0].minor);
-         break;
--      case 34:
--#line 502 "./configparser.y"
-+      case 35:
-+#line 515 "./configparser.y"
- {
-   yygotominor.yy27 = CONFIG_COND_NE;
- }
--#line 1295 "configparser.c"
-+#line 1317 "configparser.c"
-   yy_destructor(22,&yymsp[0].minor);
-         break;
--      case 35:
--#line 505 "./configparser.y"
-+      case 36:
-+#line 518 "./configparser.y"
- {
-   yygotominor.yy27 = CONFIG_COND_NOMATCH;
- }
--#line 1303 "configparser.c"
-+#line 1325 "configparser.c"
-   yy_destructor(23,&yymsp[0].minor);
-         break;
--      case 36:
--#line 509 "./configparser.y"
-+      case 37:
-+#line 522 "./configparser.y"
- {
-   yygotominor.yy43 = NULL;
-   if (ctx->ok) {
-@@ -1321,10 +1343,10 @@
-   yymsp[0].minor.yy41->free(yymsp[0].minor.yy41);
-   yymsp[0].minor.yy41 = NULL;
- }
--#line 1324 "configparser.c"
-+#line 1346 "configparser.c"
-         break;
--      case 37:
--#line 526 "./configparser.y"
-+      case 38:
-+#line 539 "./configparser.y"
- {
-   if (ctx->ok) {
-     if (0 != config_parse_file(ctx->srv, ctx, yymsp[0].minor.yy43->ptr)) {
-@@ -1334,11 +1356,11 @@
-     yymsp[0].minor.yy43 = NULL;
-   }
- }
--#line 1337 "configparser.c"
-+#line 1359 "configparser.c"
-   yy_destructor(24,&yymsp[-1].minor);
-         break;
--      case 38:
--#line 536 "./configparser.y"
-+      case 39:
-+#line 549 "./configparser.y"
- {
-   if (ctx->ok) {
-     if (0 != config_parse_cmd(ctx->srv, ctx, yymsp[0].minor.yy43->ptr)) {
-@@ -1348,7 +1370,7 @@
-     yymsp[0].minor.yy43 = NULL;
-   }
- }
--#line 1351 "configparser.c"
-+#line 1373 "configparser.c"
-   yy_destructor(25,&yymsp[-1].minor);
-         break;
-   };
-@@ -1378,11 +1400,11 @@
-   while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
-   /* Here code is inserted which will be executed whenever the
-   ** parser fails */
--#line 125 "./configparser.y"
-+#line 107 "./configparser.y"
-   ctx->ok = 0;
--#line 1385 "configparser.c"
-+#line 1407 "configparser.c"
-   configparserARG_STORE; /* Suppress warning about unused %extra_argument variable */
- }
-@@ -1489,7 +1511,7 @@
- #ifdef YYERRORSYMBOL
-       /* A syntax error has occurred.
-       ** The response to an error depends upon whether or not the
--      ** grammar defines an error token "ERROR".  
-+      ** grammar defines an error token "ERROR".
-       **
-       ** This is what we do if the grammar does define ERROR:
-       **
---- ../lighttpd-1.4.11/src/configparser.y      2006-01-26 18:46:25.000000000 +0200
-+++ lighttpd-1.5.0/src/configparser.y  2006-09-07 00:57:05.000000000 +0300
-@@ -21,52 +21,34 @@
-     dc->parent = ctx->current;
-     array_insert_unique(dc->parent->childs, (data_unset *)dc);
-   }
--  array_insert_unique(ctx->configs_stack, (data_unset *)ctx->current);
-+  buffer_ptr_append(ctx->configs_stack, (void *)ctx->current);
-   ctx->current = dc;
- }
- static data_config *configparser_pop(config_t *ctx) {
-   data_config *old = ctx->current;
--  ctx->current = (data_config *) array_pop(ctx->configs_stack);
-+  ctx->current = (data_config *) buffer_ptr_pop(ctx->configs_stack);
-   return old;
- }
- /* return a copied variable */
- static data_unset *configparser_get_variable(config_t *ctx, const buffer *key) {
--  if (strncmp(key->ptr, "env.", sizeof("env.") - 1) == 0) {
--    char *env;
--
--    if (NULL != (env = getenv(key->ptr + 4))) {
--      data_string *ds;
--      ds = data_string_init();
--      buffer_append_string(ds->value, env);
--      return (data_unset *)ds;
--    }
--
--    fprintf(stderr, "Undefined env variable: %s\n", key->ptr + 4);
--    ctx->ok = 0;
--
--    return NULL;
--  } else {
--    data_unset *du;
--    data_config *dc;
-+  data_unset *du;
-+  data_config *dc;
- #if 0
--    fprintf(stderr, "get var %s\n", key->ptr);
-+  fprintf(stderr, "get var %s\n", key->ptr);
- #endif
--    for (dc = ctx->current; dc; dc = dc->parent) {
-+  for (dc = ctx->current; dc; dc = dc->parent) {
- #if 0
--      fprintf(stderr, "get var on block: %s\n", dc->key->ptr);
--      array_print(dc->value, 0);
-+    fprintf(stderr, "get var on block: %s\n", dc->key->ptr);
-+    array_print(dc->value, 0);
- #endif
--      if (NULL != (du = array_get_element(dc->value, key->ptr))) {
--        return du->copy(du);
--      }
-+    if (NULL != (du = array_get_element(dc->value, key->ptr))) {
-+      return du->copy(du);
-     }
--    fprintf(stderr, "Undefined config variable: %s\n", key->ptr);
--    ctx->ok = 0;
--    return NULL;
-   }
-+  return NULL;
- }
- /* op1 is to be eat/return by this function, op1->key is not cared
-@@ -141,6 +123,7 @@
- %type       aelement               {data_unset *}
- %type       condline               {data_config *}
- %type       condlines              {data_config *}
-+%type       global                 {data_config *}
- %type       aelements              {array *}
- %type       array                  {array *}
- %type       key                    {buffer *}
-@@ -161,7 +144,12 @@
- varline ::= key(A) ASSIGN expression(B). {
-   buffer_copy_string_buffer(B->key, A);
--  if (NULL == array_get_element(ctx->current->value, B->key->ptr)) {
-+  if (strncmp(A->ptr, "env.", sizeof("env.") - 1) == 0) {
-+    fprintf(stderr, "Setting env variable is not supported in conditional %d %s: %s\n",
-+        ctx->current->context_ndx,
-+        ctx->current->key->ptr, A->ptr);
-+    ctx->ok = 0;
-+  } else if (NULL == array_get_element(ctx->current->value, B->key->ptr)) {
-     array_insert_unique(ctx->current->value, B);
-     B = NULL;
-   } else {
-@@ -180,7 +168,12 @@
-   array *vars = ctx->current->value;
-   data_unset *du;
--  if (NULL != (du = array_get_element(vars, A->ptr))) {
-+  if (strncmp(A->ptr, "env.", sizeof("env.") - 1) == 0) {
-+    fprintf(stderr, "Appending env variable is not supported in conditional %d %s: %s\n",
-+        ctx->current->context_ndx,
-+        ctx->current->key->ptr, A->ptr);
-+    ctx->ok = 0;
-+  } else if (NULL != (du = array_get_element(vars, A->ptr))) {
-     /* exists in current block */
-     du = configparser_merge_data(du, B);
-     if (NULL == du) {
-@@ -190,6 +183,7 @@
-       buffer_copy_string_buffer(du->key, A);
-       array_replace(vars, du);
-     }
-+    B->free(B);
-   } else if (NULL != (du = configparser_get_variable(ctx, A))) {
-     du = configparser_merge_data(du, B);
-     if (NULL == du) {
-@@ -199,15 +193,13 @@
-       buffer_copy_string_buffer(du->key, A);
-       array_insert_unique(ctx->current->value, du);
-     }
-+    B->free(B);
-   } else {
--    fprintf(stderr, "Undefined config variable in conditional %d %s: %s\n", 
--            ctx->current->context_ndx,
--            ctx->current->key->ptr, A->ptr);
--    ctx->ok = 0;
-+    buffer_copy_string_buffer(B->key, A);
-+    array_insert_unique(ctx->current->value, B);
-   }
-   buffer_free(A);
-   A = NULL;
--  B->free(B);
-   B = NULL;
- }
-@@ -239,7 +231,24 @@
- }
- value(A) ::= key(B). {
--  A = configparser_get_variable(ctx, B);
-+  if (strncmp(B->ptr, "env.", sizeof("env.") - 1) == 0) {
-+    char *env;
-+
-+    if (NULL != (env = getenv(B->ptr + 4))) {
-+      data_string *ds;
-+      ds = data_string_init();
-+      buffer_append_string(ds->value, env);
-+      A = (data_unset *)ds;
-+    }
-+    else {
-+      A = NULL;
-+      fprintf(stderr, "Undefined env variable: %s\n", B->ptr + 4);
-+      ctx->ok = 0;
-+    }
-+  } else if (NULL == (A = configparser_get_variable(ctx, B))) {
-+    fprintf(stderr, "Undefined config variable: %s\n", B->ptr);
-+    ctx->ok = 0;
-+  }
-   if (!A) {
-     /* make a dummy so it won't crash */
-     A = (data_unset *)data_string_init();
-@@ -267,6 +276,9 @@
-   ((data_array *)(A))->value = B;
-   B = NULL;
- }
-+array(A) ::= LPARAN RPARAN. {
-+  A = array_init();
-+}
- array(A) ::= LPARAN aelements(B) RPARAN. {
-   A = B;
-   B = NULL;
-@@ -410,6 +422,7 @@
-       { COMP_HTTP_USERAGENT,     CONST_STR_LEN("HTTP[\"useragent\"]"  ) },
-       { COMP_HTTP_COOKIE,        CONST_STR_LEN("HTTP[\"cookie\"]"     ) },
-       { COMP_HTTP_REMOTEIP,      CONST_STR_LEN("HTTP[\"remoteip\"]"   ) },
-+      { COMP_HTTP_QUERYSTRING,   CONST_STR_LEN("HTTP[\"querystring\"]") },
-       { COMP_UNSET, NULL, 0 },
-     };
-     size_t i;
---- ../lighttpd-1.4.11/src/connections-glue.c  2005-09-12 10:04:23.000000000 +0300
-+++ lighttpd-1.5.0/src/connections-glue.c      2006-09-07 00:57:05.000000000 +0300
-@@ -3,42 +3,48 @@
- const char *connection_get_state(connection_state_t state) {
-       switch (state) {
-       case CON_STATE_CONNECT: return "connect";
--      case CON_STATE_READ: return "read";
--      case CON_STATE_READ_POST: return "readpost";
--      case CON_STATE_WRITE: return "write";
--      case CON_STATE_CLOSE: return "close";
--      case CON_STATE_ERROR: return "error";
--      case CON_STATE_HANDLE_REQUEST: return "handle-req";
-+
-       case CON_STATE_REQUEST_START: return "req-start";
--      case CON_STATE_REQUEST_END: return "req-end";
--      case CON_STATE_RESPONSE_START: return "resp-start";
-+      case CON_STATE_READ_REQUEST_HEADER: return "read-header";
-+      case CON_STATE_HANDLE_REQUEST_HEADER: return "handle-req";
-+      case CON_STATE_READ_REQUEST_CONTENT: return "read-content";
-+
-+      case CON_STATE_HANDLE_RESPONSE_HEADER: return "resp-start";
-+      case CON_STATE_WRITE_RESPONSE_HEADER: return "write-header";
-+      case CON_STATE_WRITE_RESPONSE_CONTENT: return "write-content";
-       case CON_STATE_RESPONSE_END: return "resp-end";
--      default: return "(unknown)";    
-+
-+      case CON_STATE_CLOSE: return "close";
-+      case CON_STATE_ERROR: return "error";
-+      default: return "(unknown)";
-       }
- }
- const char *connection_get_short_state(connection_state_t state) {
-       switch (state) {
-       case CON_STATE_CONNECT: return ".";
--      case CON_STATE_READ: return "r";
--      case CON_STATE_READ_POST: return "R";
--      case CON_STATE_WRITE: return "W";
--      case CON_STATE_CLOSE: return "C";
--      case CON_STATE_ERROR: return "E";
--      case CON_STATE_HANDLE_REQUEST: return "h";
-       case CON_STATE_REQUEST_START: return "q";
--      case CON_STATE_REQUEST_END: return "Q";
--      case CON_STATE_RESPONSE_START: return "s";
-+
-+      case CON_STATE_READ_REQUEST_HEADER: return "r";
-+      case CON_STATE_HANDLE_REQUEST_HEADER: return "h";
-+      case CON_STATE_READ_REQUEST_CONTENT: return "R";
-+
-+      case CON_STATE_HANDLE_RESPONSE_HEADER: return "s";
-+      case CON_STATE_WRITE_RESPONSE_HEADER: return "w";
-+      case CON_STATE_WRITE_RESPONSE_CONTENT: return "W";
-       case CON_STATE_RESPONSE_END: return "S";
--      default: return "x";    
-+
-+      case CON_STATE_CLOSE: return "C";
-+      case CON_STATE_ERROR: return "E";
-+      default: return "x";
-       }
- }
- int connection_set_state(server *srv, connection *con, connection_state_t state) {
-       UNUSED(srv);
--      
-+
-       con->state = state;
--      
-+
-       return 0;
- }
---- ../lighttpd-1.4.11/src/connections.c       2006-03-05 22:14:53.000000000 +0200
-+++ lighttpd-1.5.0/src/connections.c   2006-09-07 00:57:05.000000000 +0300
-@@ -2,7 +2,6 @@
- #include <stdlib.h>
- #include <stdio.h>
--#include <unistd.h>
- #include <errno.h>
- #include <string.h>
- #include <fcntl.h>
-@@ -17,17 +16,18 @@
- #include "request.h"
- #include "response.h"
- #include "network.h"
--#include "http_chunk.h"
- #include "stat_cache.h"
- #include "joblist.h"
- #include "plugin.h"
- #include "inet_ntop_cache.h"
-+#include "configfile.h"
-+#include "http_req.h"
- #ifdef USE_OPENSSL
--# include <openssl/ssl.h> 
--# include <openssl/err.h> 
-+# include <openssl/ssl.h>
-+# include <openssl/err.h>
- #endif
- #ifdef HAVE_SYS_FILIO_H
-@@ -35,15 +35,16 @@
- #endif
- #include "sys-socket.h"
-+#include "sys-files.h"
- typedef struct {
--              PLUGIN_DATA;
-+      PLUGIN_DATA;
- } plugin_data;
- static connection *connections_get_new_connection(server *srv) {
-       connections *conns = srv->conns;
-       size_t i;
--      
-+
-       if (conns->size == 0) {
-               conns->size = 128;
-               conns->ptr = NULL;
-@@ -54,21 +55,14 @@
-       } else if (conns->size == conns->used) {
-               conns->size += 128;
-               conns->ptr = realloc(conns->ptr, sizeof(*conns->ptr) * conns->size);
--              
-+
-               for (i = conns->used; i < conns->size; i++) {
-                       conns->ptr[i] = connection_init(srv);
-               }
-       }
-       connection_reset(srv, conns->ptr[conns->used]);
--#if 0 
--      fprintf(stderr, "%s.%d: add: ", __FILE__, __LINE__);
--      for (i = 0; i < conns->used + 1; i++) {
--              fprintf(stderr, "%d ", conns->ptr[i]->fd);
--      }
--      fprintf(stderr, "\n");
--#endif        
--      
-+
-       conns->ptr[conns->used]->ndx = conns->used;
-       return conns->ptr[conns->used++];
- }
-@@ -77,272 +71,127 @@
-       size_t i;
-       connections *conns = srv->conns;
-       connection *temp;
--      
-+
-       if (con == NULL) return -1;
--      
-+
-       if (-1 == con->ndx) return -1;
--      
-+
-       i = con->ndx;
--      
-+
-       /* not last element */
--      
-+
-       if (i != conns->used - 1) {
-               temp = conns->ptr[i];
-               conns->ptr[i] = conns->ptr[conns->used - 1];
-               conns->ptr[conns->used - 1] = temp;
--              
-+
-               conns->ptr[i]->ndx = i;
-               conns->ptr[conns->used - 1]->ndx = -1;
-       }
--      
-+
-       conns->used--;
--      
-+
-       con->ndx = -1;
--#if 0
--      fprintf(stderr, "%s.%d: del: (%d)", __FILE__, __LINE__, conns->used);
--      for (i = 0; i < conns->used; i++) {
--              fprintf(stderr, "%d ", conns->ptr[i]->fd);
--      }
--      fprintf(stderr, "\n");
--#endif        
-+
-       return 0;
- }
- int connection_close(server *srv, connection *con) {
- #ifdef USE_OPENSSL
--      server_socket *srv_sock = con->srv_socket;
--#endif
--      
--#ifdef USE_OPENSSL
--      if (srv_sock->is_ssl) {
--              if (con->ssl) SSL_free(con->ssl);
--              con->ssl = NULL;
-+      /* should be in iosocket_close() */
-+
-+      if (con->sock->ssl) {
-+              switch (SSL_shutdown(con->sock->ssl)) {
-+              case 1:
-+                      /* done */
-+                      break;
-+              case 0:
-+                      /* wait for fd-event
-+                       *
-+                       * FIXME: wait for fdevent and call SSL_shutdown again
-+                       *
-+                       */
-+
-+                      break;
-+              default:
-+                      ERROR("SSL_shutdown failed: %s", ERR_error_string(ERR_get_error(), NULL));
-+              }
-+
-+              SSL_free(con->sock->ssl);
-+              con->sock->ssl = NULL;
-       }
- #endif
--      
--      fdevent_event_del(srv->ev, &(con->fde_ndx), con->fd);
--      fdevent_unregister(srv->ev, con->fd);
--#ifdef __WIN32
--      if (closesocket(con->fd)) {
--              log_error_write(srv, __FILE__, __LINE__, "sds",
--                              "(warning) close:", con->fd, strerror(errno));
--      }
--#else
--      if (close(con->fd)) {
-+
-+      fdevent_event_del(srv->ev, con->sock);
-+      fdevent_unregister(srv->ev, con->sock);
-+
-+      if (closesocket(con->sock->fd)) {
-               log_error_write(srv, __FILE__, __LINE__, "sds",
--                              "(warning) close:", con->fd, strerror(errno));
-+                              "(warning) close:", con->sock->fd, strerror(errno));
-       }
--#endif
--      
-+
-       srv->cur_fds--;
--#if 0
--      log_error_write(srv, __FILE__, __LINE__, "sd",
--                      "closed()", con->fd);
--#endif
--      
-+
-       connection_del(srv, con);
-       connection_set_state(srv, con, CON_STATE_CONNECT);
--      
-+
-       return 0;
- }
- #if 0
- static void dump_packet(const unsigned char *data, size_t len) {
-       size_t i, j;
--      
-+
-       if (len == 0) return;
--      
-+
-       for (i = 0; i < len; i++) {
-               if (i % 16 == 0) fprintf(stderr, "  ");
--              
-+
-               fprintf(stderr, "%02x ", data[i]);
--              
-+
-               if ((i + 1) % 16 == 0) {
-                       fprintf(stderr, "  ");
-                       for (j = 0; j <= i % 16; j++) {
-                               unsigned char c;
--                              
-+
-                               if (i-15+j >= len) break;
--                              
-+
-                               c = data[i-15+j];
--                              
-+
-                               fprintf(stderr, "%c", c > 32 && c < 128 ? c : '.');
-                       }
--                      
-+
-                       fprintf(stderr, "\n");
-               }
-       }
--      
-+
-       if (len % 16 != 0) {
-               for (j = i % 16; j < 16; j++) {
-                       fprintf(stderr, "   ");
-               }
--              
-+
-               fprintf(stderr, "  ");
-               for (j = i & ~0xf; j < len; j++) {
-                       unsigned char c;
--                      
-+
-                       c = data[j];
-                       fprintf(stderr, "%c", c > 32 && c < 128 ? c : '.');
-               }
-               fprintf(stderr, "\n");
-       }
- }
--#endif 
--
--static int connection_handle_read(server *srv, connection *con) {
--      int len;
--      buffer *b;
--      int toread;
--#ifdef USE_OPENSSL
--      server_socket *srv_sock = con->srv_socket;
--#endif
--
--      b = chunkqueue_get_append_buffer(con->read_queue);
--      buffer_prepare_copy(b, 4096);
--
--#ifdef USE_OPENSSL
--      if (srv_sock->is_ssl) {
--              len = SSL_read(con->ssl, b->ptr, b->size - 1);
--      } else {
--              if (ioctl(con->fd, FIONREAD, &toread)) {
--                      log_error_write(srv, __FILE__, __LINE__, "sd", 
--                                      "unexpected end-of-file:",
--                                      con->fd);
--                      return -1;
--              }
--              buffer_prepare_copy(b, toread);
--
--              len = read(con->fd, b->ptr, b->size - 1);
--      }
--#elif defined(__WIN32)
--      len = recv(con->fd, b->ptr, b->size - 1, 0);
--#else
--      if (ioctl(con->fd, FIONREAD, &toread)) {
--              log_error_write(srv, __FILE__, __LINE__, "sd", 
--                              "unexpected end-of-file:",
--                              con->fd);
--              return -1;
--      }
--      buffer_prepare_copy(b, toread);
--
--      len = read(con->fd, b->ptr, b->size - 1);
- #endif
--      
--      if (len < 0) {
--              con->is_readable = 0;
--              
--#ifdef USE_OPENSSL
--              if (srv_sock->is_ssl) {
--                      int r, ssl_err;
--                      
--                      switch ((r = SSL_get_error(con->ssl, len))) {
--                      case SSL_ERROR_WANT_READ:
--                              return 0;
--                      case SSL_ERROR_SYSCALL:
--                              /**
--                               * man SSL_get_error()
--                               * 
--                               * SSL_ERROR_SYSCALL
--                               *   Some I/O error occurred.  The OpenSSL error queue may contain more 
--                               *   information on the error.  If the error queue is empty (i.e.
--                               *   ERR_get_error() returns 0), ret can be used to find out more about 
--                               *   the error: If ret == 0, an EOF was observed that violates the
--                               *   protocol.  If ret == -1, the underlying BIO reported an I/O error 
--                               *   (for socket I/O on Unix systems, consult errno for details).
--                               *
--                               */
--                              while((ssl_err = ERR_get_error())) {
--                                      /* get all errors from the error-queue */
--                                      log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:", 
--                                                      r, ERR_error_string(ssl_err, NULL));
--                              }
--                              switch(errno) {
--                              default:
--                                      log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL:", 
--                                                      len, r, errno,
--                                                      strerror(errno));
--                                      break;
--                              }
--                              
--                              break;
--                      case SSL_ERROR_ZERO_RETURN:
--                              /* clean shutdown on the remote side */
--                              
--                              if (r == 0) {
--                                      /* FIXME: later */
--                              }
--                              
--                              /* fall thourgh */
--                      default:
--                              while((ssl_err = ERR_get_error())) {
--                                      /* get all errors from the error-queue */
--                                      log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:", 
--                                                      r, ERR_error_string(ssl_err, NULL));
--                              }
--                              break;
--                      }
--              } else {
--                      if (errno == EAGAIN) return 0;
--                      if (errno == EINTR) {
--                              /* we have been interrupted before we could read */
--                              con->is_readable = 1;
--                              return 0;
--                      }
--              
--                      if (errno != ECONNRESET) {
--                              /* expected for keep-alive */
--                              log_error_write(srv, __FILE__, __LINE__, "ssd", "connection closed - read failed: ", strerror(errno), errno);
--                      }
--              }
--#else
--              if (errno == EAGAIN) return 0;
--              if (errno == EINTR) {
--                      /* we have been interrupted before we could read */
--                      con->is_readable = 1;
--                      return 0;
--              }
--              
--              if (errno != ECONNRESET) {
--                      /* expected for keep-alive */
--                      log_error_write(srv, __FILE__, __LINE__, "ssd", "connection closed - read failed: ", strerror(errno), errno);
--              }
--#endif
--              connection_set_state(srv, con, CON_STATE_ERROR);
--              
--              return -1;
--      } else if (len == 0) {
--              con->is_readable = 0;
--              /* the other end close the connection -> KEEP-ALIVE */
--
--              /* pipelining */
--
--              return -2;
--      } else if ((size_t)len < b->size - 1) {
--              /* we got less then expected, wait for the next fd-event */
--              
--              con->is_readable = 0;
--      }
--      
--      b->used = len;
--      b->ptr[b->used++] = '\0';
--      
--      con->bytes_read += len;
--#if 0
--      dump_packet(b->ptr, len);
--#endif
--      
--      return 0;
--}
-+static int connection_handle_response_header(server *srv, connection *con) {
-+      data_string *cl;
--static int connection_handle_write_prepare(server *srv, connection *con) {
-       if (con->mode == DIRECT) {
-               /* static files */
-               switch(con->request.http_method) {
-               case HTTP_METHOD_GET:
-               case HTTP_METHOD_POST:
-               case HTTP_METHOD_HEAD:
-+                      /* webdav */
-               case HTTP_METHOD_PUT:
-               case HTTP_METHOD_MKCOL:
-               case HTTP_METHOD_DELETE:
-@@ -350,21 +199,25 @@
-               case HTTP_METHOD_MOVE:
-               case HTTP_METHOD_PROPFIND:
-               case HTTP_METHOD_PROPPATCH:
-+              case HTTP_METHOD_LOCK:
-+              case HTTP_METHOD_UNLOCK:
-                       break;
-               case HTTP_METHOD_OPTIONS:
-                       /*
-                        * 400 is coming from the request-parser BEFORE uri.path is set
--                       * 403 is from the response handler when noone else catched it 
--                       * 
-+                       * 403 is from the response handler when noone else catched it
-+                       *
-                        * */
-                       if (con->uri.path->used &&
-                           con->uri.path->ptr[0] != '*') {
-                               response_header_insert(srv, con, CONST_STR_LEN("Allow"), CONST_STR_LEN("OPTIONS, GET, HEAD, POST"));
-+                              /* trash the content */
-+                              chunkqueue_reset(con->send);
-+
-                               con->http_status = 200;
--                              con->file_finished = 1;
-+                              con->send->is_closed = 1;
--                              chunkqueue_reset(con->write_queue);
-                       }
-                       break;
-               default:
-@@ -381,55 +234,61 @@
-                       break;
-               }
-       }
--      
-+
-       if (con->http_status == 0) {
-+              TRACE("%s", "no status, setting 403");
-               con->http_status = 403;
-       }
--      
-+
-       switch(con->http_status) {
-       case 400: /* class: header + custom body */
-       case 401:
-       case 403:
-       case 404:
-       case 408:
-+      case 409:
-+      case 410:
-       case 411:
-       case 416:
-       case 423:
-       case 500:
-       case 501:
-+      case 502:
-       case 503:
--      case 505: 
-+      case 504:
-+      case 505:
-+      case 509:
-               if (con->mode != DIRECT) break;
--              
--              con->file_finished = 0;
--              
-+
-+              con->send->is_closed = 0;
-+
-               buffer_reset(con->physical.path);
--                              
-+
-               /* try to send static errorfile */
-               if (!buffer_is_empty(con->conf.errorfile_prefix)) {
-                       stat_cache_entry *sce = NULL;
--                      
-+
-                       buffer_copy_string_buffer(con->physical.path, con->conf.errorfile_prefix);
-                       buffer_append_string(con->physical.path, get_http_status_body_name(con->http_status));
--                      
-+
-                       if (HANDLER_ERROR != stat_cache_get_entry(srv, con, con->physical.path, &sce)) {
--                              con->file_finished = 1;
--                              
--                              http_chunk_append_file(srv, con, con->physical.path, 0, sce->st.st_size);
-+                              con->send->is_closed = 1;
-+
-+                              chunkqueue_append_file(con->send, con->physical.path, 0, sce->st.st_size);
-                               response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(sce->content_type));
-                       }
-               }
--              
--              if (!con->file_finished) {                      
-+
-+              if (!con->send->is_closed) {
-                       buffer *b;
--                      
-+
-                       buffer_reset(con->physical.path);
--                      
--                      con->file_finished = 1;
--                      b = chunkqueue_get_append_buffer(con->write_queue);
--                              
-+
-+                      con->send->is_closed = 1;
-+                      b = chunkqueue_get_append_buffer(con->send);
-+
-                       /* build default error-page */
--                      buffer_copy_string(b, 
-+                      buffer_copy_string(b,
-                                          "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n"
-                                          "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n"
-                                          "         \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"
-@@ -439,7 +298,7 @@
-                       buffer_append_long(b, con->http_status);
-                       buffer_append_string(b, " - ");
-                       buffer_append_string(b, get_http_status_name(con->http_status));
--                      
-+
-                       buffer_append_string(b,
-                                            "</title>\n"
-                                            " </head>\n"
-@@ -448,12 +307,12 @@
-                       buffer_append_long(b, con->http_status);
-                       buffer_append_string(b, " - ");
-                       buffer_append_string(b, get_http_status_name(con->http_status));
--                      
--                      buffer_append_string(b,"</h1>\n" 
-+
-+                      buffer_append_string(b,"</h1>\n"
-                                            " </body>\n"
-                                            "</html>\n"
-                                            );
--                      
-+
-                       response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html"));
-               }
-               /* fall through */
-@@ -463,109 +322,69 @@
-       case 301:
-       case 302:
-               break;
--              
-+
-       case 206: /* write_queue is already prepared */
--              con->file_finished = 1;
--              
-+              con->send->is_closed = 1;
-+
-               break;
-       case 205: /* class: header only */
-       case 304:
-       default:
-               /* disable chunked encoding again as we have no body */
-               con->response.transfer_encoding &= ~HTTP_TRANSFER_ENCODING_CHUNKED;
--              chunkqueue_reset(con->write_queue);
--              
--              con->file_finished = 1;
-+              chunkqueue_reset(con->send);
-+
-+              con->send->is_closed = 1;
-+
-               break;
-       }
--      
--      if (con->file_finished) {
--              /* we have all the content and chunked encoding is not used, set a content-length */ 
--              
--              if ((!(con->parsed_response & HTTP_CONTENT_LENGTH)) && 
--                  (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) == 0) {
--                      buffer_copy_off_t(srv->tmp_buf, chunkqueue_length(con->write_queue));
--              
-+
-+      if (con->send->is_closed) {
-+              /* we have all the content and chunked encoding is not used, set a content-length */
-+
-+              if ((con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) == 0 &&
-+                  NULL == (cl = (data_string *)array_get_element(con->response.headers, "Content-Length"))) {
-+                      buffer_copy_off_t(srv->tmp_buf, chunkqueue_length(con->send));
-+                      
-                       response_header_overwrite(srv, con, CONST_STR_LEN("Content-Length"), CONST_BUF_LEN(srv->tmp_buf));
-               }
-       } else {
--              /* disable keep-alive if size-info for the body is missing */
--              if ((con->parsed_response & HTTP_CONTENT_LENGTH) &&
--                  ((con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) == 0)) {
--                      con->keep_alive = 0;
--              }
--              
--              if (0 == (con->parsed_response & HTTP_CONNECTION)) {
--                      /* (f)cgi did'nt send Connection: header
--                       *                          
--                       * shall we ?
--                       */
--                      if (((con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) == 0) &&
--                          (con->parsed_response & HTTP_CONTENT_LENGTH) == 0) {
--                              /* without content_length, no keep-alive */
--                              
--                              con->keep_alive = 0;
--                      }
--              } else {
--                      /* a subrequest disable keep-alive although the client wanted it */
--                      if (con->keep_alive && !con->response.keep_alive) {
-+              if (NULL == (cl = (data_string *)array_get_element(con->response.headers, "Content-Length"))) {
-+                      /* we don't know the size of the content yet 
-+                       * - either enable chunking 
-+                       * - or disable keep-alive  */
-+
-+                      if (con->request.http_version == HTTP_VERSION_1_1) {
-+                              /* enable chunk-encoding */
-+                              con->response.transfer_encoding |= HTTP_TRANSFER_ENCODING_CHUNKED;
-+                      } else  {
-                               con->keep_alive = 0;
--                              
--                              /* FIXME: we have to drop the Connection: Header from the subrequest */
-                       }
-               }
-       }
--      
-+
-       if (con->request.http_method == HTTP_METHOD_HEAD) {
--              chunkqueue_reset(con->write_queue);
-+              con->response.transfer_encoding &= ~HTTP_TRANSFER_ENCODING_CHUNKED;
-+              chunkqueue_reset(con->send);
-+
-+              con->send->is_closed = 1;
-       }
--      http_response_write_header(srv, con);
--              
--      return 0;
--}
-+      http_response_write_header(srv, con, con->send_raw);
--static int connection_handle_write(server *srv, connection *con) {
--      switch(network_write_chunkqueue(srv, con, con->write_queue)) {
--      case 0:
--              if (con->file_finished) {
--                      connection_set_state(srv, con, CON_STATE_RESPONSE_END);
--                      joblist_append(srv, con);
--              }
--              break;
--      case -1: /* error on our side */
--              log_error_write(srv, __FILE__, __LINE__, "sd",
--                              "connection closed: write failed on fd", con->fd);
--              connection_set_state(srv, con, CON_STATE_ERROR);
--              joblist_append(srv, con);
--              break;
--      case -2: /* remote close */
--              connection_set_state(srv, con, CON_STATE_ERROR);
--              joblist_append(srv, con);
--              break;
--      case 1:
--              con->is_writable = 0;
--              
--              /* not finished yet -> WRITE */
--              break;
--      }
--      
-       return 0;
- }
--
--
- connection *connection_init(server *srv) {
-       connection *con;
--      
-+
-       UNUSED(srv);
-       con = calloc(1, sizeof(*con));
--              
--      con->fd = 0;
-+
-+      con->sock = iosocket_init();
-       con->ndx = -1;
--      con->fde_ndx = -1;
-       con->bytes_written = 0;
-       con->bytes_read = 0;
-       con->bytes_header = 0;
-@@ -573,91 +392,97 @@
- #define CLEAN(x) \
-       con->x = buffer_init();
--      
-+
-       CLEAN(request.uri);
--      CLEAN(request.request_line);
-       CLEAN(request.request);
-       CLEAN(request.pathinfo);
--      
-+      CLEAN(request.http_host);
-+
-       CLEAN(request.orig_uri);
--      
-+
-       CLEAN(uri.scheme);
-       CLEAN(uri.authority);
-       CLEAN(uri.path);
-       CLEAN(uri.path_raw);
-       CLEAN(uri.query);
--      
-+
-       CLEAN(physical.doc_root);
-       CLEAN(physical.path);
-       CLEAN(physical.basedir);
-       CLEAN(physical.rel_path);
-       CLEAN(physical.etag);
-       CLEAN(parse_request);
--      
-+
-       CLEAN(authed_user);
-       CLEAN(server_name);
-       CLEAN(error_handler);
-       CLEAN(dst_addr_buf);
--      
-+
- #undef CLEAN
--      con->write_queue = chunkqueue_init();
--      con->read_queue = chunkqueue_init();
--      con->request_content_queue = chunkqueue_init();
--      chunkqueue_set_tempdirs(con->request_content_queue, srv->srvconf.upload_tempdirs);
-+      con->send = chunkqueue_init();
-+      con->recv = chunkqueue_init();
-+
-+      con->send_raw = chunkqueue_init();
-+      con->recv_raw = chunkqueue_init();
-+      chunkqueue_set_tempdirs(con->recv_raw, srv->srvconf.upload_tempdirs);
-       con->request.headers      = array_init();
-       con->response.headers     = array_init();
-       con->environment     = array_init();
--      
-+
-+      con->http_req = http_request_init();
-+
-       /* init plugin specific connection structures */
--      
-+
-       con->plugin_ctx = calloc(1, (srv->plugins.used + 1) * sizeof(void *));
--      
-+
-       con->cond_cache = calloc(srv->config_context->used, sizeof(cond_cache_t));
-       config_setup_connection(srv, con);
--      
-+
-       return con;
- }
- void connections_free(server *srv) {
-       connections *conns = srv->conns;
--      size_t i;       
--      
-+      size_t i;
-+
-       for (i = 0; i < conns->size; i++) {
-               connection *con = conns->ptr[i];
--              
-+
-               connection_reset(srv, con);
--              
--              chunkqueue_free(con->write_queue);
--              chunkqueue_free(con->read_queue);
--              chunkqueue_free(con->request_content_queue);
-+              iosocket_free(con->sock);
-+
-+              chunkqueue_free(con->send);
-+              chunkqueue_free(con->recv);
-+              chunkqueue_free(con->send_raw);
-+              chunkqueue_free(con->recv_raw);
-               array_free(con->request.headers);
-               array_free(con->response.headers);
-               array_free(con->environment);
- #define CLEAN(x) \
-       buffer_free(con->x);
--              
-+
-               CLEAN(request.uri);
--              CLEAN(request.request_line);
-               CLEAN(request.request);
-               CLEAN(request.pathinfo);
--              
-+              CLEAN(request.http_host);
-+
-               CLEAN(request.orig_uri);
--              
-+
-               CLEAN(uri.scheme);
-               CLEAN(uri.authority);
-               CLEAN(uri.path);
-               CLEAN(uri.path_raw);
-               CLEAN(uri.query);
--              
-+
-               CLEAN(physical.doc_root);
-               CLEAN(physical.path);
-               CLEAN(physical.basedir);
-               CLEAN(physical.etag);
-               CLEAN(physical.rel_path);
-               CLEAN(parse_request);
--              
-+
-               CLEAN(authed_user);
-               CLEAN(server_name);
-               CLEAN(error_handler);
-@@ -665,97 +490,88 @@
- #undef CLEAN
-               free(con->plugin_ctx);
-               free(con->cond_cache);
--              
-+
-+              http_request_free(con->http_req);
-+
-               free(con);
-       }
--      
-+
-       free(conns->ptr);
- }
- int connection_reset(server *srv, connection *con) {
-       size_t i;
--      
-+
-       plugins_call_connection_reset(srv, con);
--      
-+
-       con->is_readable = 1;
-       con->is_writable = 1;
-       con->http_status = 0;
--      con->file_finished = 0;
-       con->file_started = 0;
-       con->got_response = 0;
--      
--      con->parsed_response = 0;
--      
-+
-       con->bytes_written = 0;
-       con->bytes_written_cur_second = 0;
-       con->bytes_read = 0;
-       con->bytes_header = 0;
-       con->loops_per_request = 0;
--      
-+
-       con->request.http_method = HTTP_METHOD_UNSET;
-       con->request.http_version = HTTP_VERSION_UNSET;
--      
--      con->request.http_if_modified_since = NULL;
--      con->request.http_if_none_match = NULL;
--      
-+      con->request.content_length = -1;
-+
-       con->response.keep_alive = 0;
-       con->response.content_length = -1;
-       con->response.transfer_encoding = 0;
--      
-+
-       con->mode = DIRECT;
--      
-+
- #define CLEAN(x) \
-       if (con->x) buffer_reset(con->x);
--      
-+
-       CLEAN(request.uri);
--      CLEAN(request.request_line);
-       CLEAN(request.pathinfo);
-       CLEAN(request.request);
--      
-+      CLEAN(request.http_host);
-+
-       CLEAN(request.orig_uri);
--      
-+
-       CLEAN(uri.scheme);
-       CLEAN(uri.authority);
-       CLEAN(uri.path);
-       CLEAN(uri.path_raw);
-       CLEAN(uri.query);
--      
-+
-       CLEAN(physical.doc_root);
-       CLEAN(physical.path);
-       CLEAN(physical.basedir);
-       CLEAN(physical.rel_path);
-       CLEAN(physical.etag);
--      
-+
-       CLEAN(parse_request);
--      
-+
-       CLEAN(authed_user);
-       CLEAN(server_name);
-       CLEAN(error_handler);
--#undef CLEAN  
--      
--#define CLEAN(x) \
--      if (con->x) con->x->used = 0;   
--      
- #undef CLEAN
--      
-+
- #define CLEAN(x) \
--              con->request.x = NULL;
--      
--      CLEAN(http_host);
--      CLEAN(http_range);
--      CLEAN(http_content_type);
-+      if (con->x) con->x->used = 0;
-+
- #undef CLEAN
--      con->request.content_length = 0;
--      
-+
-       array_reset(con->request.headers);
-       array_reset(con->response.headers);
-       array_reset(con->environment);
--      
--      chunkqueue_reset(con->write_queue);
--      chunkqueue_reset(con->request_content_queue);
--      /* the plugins should cleanup themself */       
-+      chunkqueue_reset(con->send);
-+      chunkqueue_reset(con->recv);
-+      chunkqueue_reset(con->send_raw);
-+
-+      http_request_reset(con->http_req);
-+
-+      /* the plugins should cleanup themself */
-       for (i = 0; i < srv->plugins.used; i++) {
-               plugin *p = ((plugin **)(srv->plugins.ptr))[i];
-               plugin_data *pd = p->data;
-@@ -768,455 +584,270 @@
-               con->plugin_ctx[pd->id] = NULL;
-       }
--      
--#if COND_RESULT_UNSET
--      for (i = srv->config_context->used - 1; i >= 0; i --) {
--              con->cond_cache[i].result = COND_RESULT_UNSET;
--              con->cond_cache[i].patterncount = 0;
--      }
--#else
--      memset(con->cond_cache, 0, sizeof(cond_cache_t) * srv->config_context->used);
--#endif
--      
-+
-+      config_cond_cache_reset(srv, con);
-+
-       con->header_len = 0;
-       con->in_error_handler = 0;
--      
-+
-       config_setup_connection(srv, con);
--      
-+
-       return 0;
- }
- /**
-- * 
-- * search for \r\n\r\n 
-- * 
-- * this is a special 32bit version which is using a sliding window for
-- * the comparisions 
-- * 
-- * how it works:
-- * 
-- * b:      'abcdefg'
-- * rnrn:   'cdef'
-- * 
-- * cmpbuf: abcd != cdef
-- * cmpbuf: bcde != cdef
-- * cmpbuf: cdef == cdef -> return &c
-- * 
-- * cmpbuf and rnrn are treated as 32bit uint and bit-ops are used to 
-- * maintain cmpbuf and rnrn
-- * 
-- */
--
--char *buffer_search_rnrn(buffer *b) {
--      uint32_t cmpbuf, rnrn;
--      char *cp;
--      size_t i;
--      
--      if (b->used < 4) return NULL;
--      
--      rnrn = ('\r' << 24) | ('\n' << 16) |
--              ('\r' << 8) | ('\n' << 0);
--      
--      cmpbuf = (b->ptr[0] << 24) | (b->ptr[1] << 16) |
--              (b->ptr[2] << 8) | (b->ptr[3] << 0);
--              
--      cp = b->ptr + 4;
--      for (i = 0; i < b->used - 4; i++) {
--              if (cmpbuf == rnrn) return cp - 4;
--                      
--              cmpbuf = (cmpbuf << 8 | *(cp++)) & 0xffffffff;
--      }
--      
--      return NULL;
--}
--/**
-  * handle all header and content read
-  *
-  * we get called by the state-engine and by the fdevent-handler
-  */
--int connection_handle_read_state(server *srv, connection *con)  {
--      int ostate = con->state;
--      char *h_term = NULL;
--      chunk *c;
--      chunkqueue *cq = con->read_queue;
--      chunkqueue *dst_cq = con->request_content_queue;
--      
--      if (con->is_readable) {
--              con->read_idle_ts = srv->cur_ts;
--      
--              switch(connection_handle_read(srv, con)) {
--              case -1:
--                      return -1;
--              case -2:
--                      /* remote side closed the connection
--                       * if we still have content, handle it, if not leave here */
-+handler_t connection_handle_read_request_header(server *srv, connection *con)  {
-+      /* let's see if we need more data later */
-+      fdevent_event_del(srv->ev, con->sock);
-+
-+      con->read_idle_ts = srv->cur_ts;  /* start a read-call() */
-+
-+      /* read from the network */ 
-+      switch (network_read(srv, con, con->sock, con->recv_raw)) {
-+      case NETWORK_STATUS_SUCCESS:
-+              /* we read everything from the socket, do we have a full header ? */
--                      if (cq->first == cq->last &&
--                          cq->first->mem->used == 0) {
-+              break;
-+      case NETWORK_STATUS_WAIT_FOR_EVENT:
-+              fdevent_event_add(srv->ev, con->sock, FDEVENT_IN);
-+              return HANDLER_WAIT_FOR_EVENT;
-+      case NETWORK_STATUS_CONNECTION_CLOSE:
-+              /* the connection went away before we got something back */
-+              connection_set_state(srv, con, CON_STATE_CLOSE);
--                              /* conn-closed, leave here */
--                              connection_set_state(srv, con, CON_STATE_ERROR);
--                      }
--              default:
--                      break;
--              }
-+              return HANDLER_GO_ON;
-+      default:
-+              ERROR("++ %s", "oops, something went wrong while reading");
-+              return HANDLER_ERROR;
-       }
--      /* the last chunk might be empty */
--      for (c = cq->first; c;) {
--              if (cq->first == c && c->mem->used == 0) {
--                      /* the first node is empty */
--                      /* ... and it is empty, move it to unused */
--
--                      cq->first = c->next;
--                      if (cq->first == NULL) cq->last = NULL;
--
--                      c->next = cq->unused;
--                      cq->unused = c;
--                      cq->unused_chunks++;
--
--                      c = cq->first;
--              } else if (c->next && c->next->mem->used == 0) {
--                      chunk *fc;
--                      /* next node is the last one */
--                      /* ... and it is empty, move it to unused */
--
--                      fc = c->next;
--                      c->next = fc->next;
--
--                      fc->next = cq->unused;
--                      cq->unused = fc;
--                      cq->unused_chunks++;
--
--                      /* the last node was empty */
--                      if (c->next == NULL) {
--                              cq->last = c;
--                      } 
--                      c = c->next;
--              } else {
--                      c = c->next;
--              }
-+      switch (http_request_parse_cq(con->recv_raw, con->http_req)) {
-+      case PARSE_ERROR:
-+              con->http_status = 400; /* the header is broken */
-+
-+              chunkqueue_remove_finished_chunks(con->recv_raw);
-+
-+              return HANDLER_FINISHED;
-+      case PARSE_NEED_MORE:
-+              /* we need more */
-+              fdevent_event_add(srv->ev, con->sock, FDEVENT_IN);
-+
-+              return HANDLER_WAIT_FOR_EVENT;
-+      case PARSE_SUCCESS:
-+              chunkqueue_remove_finished_chunks(con->recv_raw);
-+              break;
-+      default:
-+              chunkqueue_remove_finished_chunks(con->recv_raw);
-+              TRACE("%s", "(error)");
-+              return HANDLER_ERROR;
-       }
-+
-+      return HANDLER_GO_ON;
-+}
-+
-+/* decode the HTTP/1.1 chunk encoding */
-+
-+handler_t connection_handle_read_request_content(server *srv, connection *con)  {
-+      /* read data from the socket and push it to the backend */
-+
-+      chunkqueue *in = con->recv_raw;
-+      chunkqueue *out = con->recv; /* the pure content */
-+      chunk *c;
-       
--      /* nothing to handle */
--      if (cq->first == NULL) return 0;
-+      /* let's see if we need more data later */
-+      fdevent_event_del(srv->ev, con->sock);
-+
-+      con->read_idle_ts = srv->cur_ts;  /* start a read-call() */
-+
-+      if (con->request.content_length == -1) return HANDLER_GO_ON;
-+
-+      /* if the content was short enough, it might be read already */
-+      if (in->first &&
-+          chunkqueue_length(in) - in->first->offset > 0) {
--      switch(ostate) {
--      case CON_STATE_READ:
--              /* prepare con->request.request */
--              c = cq->first;
-+              /*  
-+               * looks like the request-header also had some content for us
-+               */
-               
--              /* check if we need the full package */
--              if (con->request.request->used == 0) {
--                      buffer b;
--                      
--                      b.ptr = c->mem->ptr + c->offset;
--                      b.used = c->mem->used - c->offset;
--                      
--                      if (NULL != (h_term = buffer_search_rnrn(&b))) {
--                              /* \r\n\r\n found
--                               * - copy everything incl. the terminator to request.request
--                               */
--                              
--                              buffer_copy_string_len(con->request.request, 
--                                                     b.ptr, 
--                                                     h_term - b.ptr + 4);
--                              
--                              /* the buffer has been read up to the terminator */
--                              c->offset += h_term - b.ptr + 4;
--                      } else {
--                              /* not found, copy everything */
--                              buffer_copy_string_len(con->request.request, c->mem->ptr + c->offset, c->mem->used - c->offset - 1);
--                              c->offset = c->mem->used - 1;
--                      }
--              } else {
--                      /* have to take care of overlapping header terminators */
--                      
--                      size_t l = con->request.request->used - 2;
--                      char *s  = con->request.request->ptr;
--                      buffer b;
--                      
--                      b.ptr = c->mem->ptr + c->offset;
--                      b.used = c->mem->used - c->offset;
--                      
--                      if (con->request.request->used - 1 > 3 &&
--                          c->mem->used > 1 &&
--                          s[l-2] == '\r' &&
--                          s[l-1] == '\n' &&
--                          s[l-0] == '\r' &&
--                          c->mem->ptr[0] == '\n') {
--                              buffer_append_string_len(con->request.request, c->mem->ptr + c->offset, 1);
--                              c->offset += 1;
--                              
--                              h_term = con->request.request->ptr;
--                      } else if (con->request.request->used - 1 > 2 &&
--                                 c->mem->used > 2 &&
--                                 s[l-1] == '\r' &&
--                                 s[l-0] == '\n' &&
--                                 c->mem->ptr[0] == '\r' &&
--                                 c->mem->ptr[1] == '\n') {
--                              buffer_append_string_len(con->request.request, c->mem->ptr + c->offset, 2);
--                              c->offset += 2;
--                              
--                              h_term = con->request.request->ptr;
--                      } else if (con->request.request->used - 1 > 1 &&
--                                 c->mem->used > 3 &&
--                                 s[l-0] == '\r' &&
--                                 c->mem->ptr[0] == '\n' &&
--                                 c->mem->ptr[1] == '\r' &&
--                                 c->mem->ptr[2] == '\n') {
--                              buffer_append_string_len(con->request.request, c->mem->ptr + c->offset, 3);
--                              c->offset += 3;
--                              
--                              h_term = con->request.request->ptr;
--                      } else if (NULL != (h_term = buffer_search_string_len(&b, "\r\n\r\n", 4))) {
--                              /* \r\n\r\n found
--                               * - copy everything incl. the terminator to request.request
--                               */
--                              
--                              buffer_append_string_len(con->request.request, 
--                                                     c->mem->ptr + c->offset, 
--                                                     c->offset + h_term - b.ptr + 4);
--                              
--                              /* the buffer has been read up to the terminator */
--                              c->offset += h_term - b.ptr + 4;
--                      } else {
--                              /* not found, copy everything */
--                              buffer_append_string_len(con->request.request, c->mem->ptr + c->offset, c->mem->used - c->offset - 1);
--                              c->offset = c->mem->used - 1;
--                      }
-+      } else {
-+              /* read from the network */ 
-+              switch (network_read(srv, con, con->sock, in)) {
-+              case NETWORK_STATUS_SUCCESS:
-+                      /* we have data */
-+                      break;
-+              case NETWORK_STATUS_WAIT_FOR_EVENT:
-+                      fdevent_event_add(srv->ev, con->sock, FDEVENT_IN);
-+                      TRACE("%s", "content-read: wait-for-event");
-+                      return HANDLER_WAIT_FOR_EVENT;
-+              case NETWORK_STATUS_CONNECTION_CLOSE:
-+                      /* the connection went away before we got something back */
-+                      connection_set_state(srv, con, CON_STATE_CLOSE);
-+
-+                      return HANDLER_GO_ON;
-+              default:
-+                      ERROR("++ %s", "oops, something went wrong while reading");
-+                      return HANDLER_ERROR;
-               }
-+      }
--              /* con->request.request is setup up */
--              if (h_term) {
--                      connection_set_state(srv, con, CON_STATE_REQUEST_END);
--              } else if (con->request.request->used > 64 * 1024) {
--                      log_error_write(srv, __FILE__, __LINE__, "s", "oversized request-header -> sending Status 414");
-+      /* how much data do we want to extract ? */
-+      for (c = in->first; c && (out->bytes_in != con->request.content_length); c = c->next) {
-+              off_t weWant, weHave, toRead;
--                      con->http_status = 414; /* Request-URI too large */
--                      con->keep_alive = 0;
--                      connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
--              }
--              break;
--      case CON_STATE_READ_POST: 
--              for (c = cq->first; c && (dst_cq->bytes_in != (off_t)con->request.content_length); c = c->next) {
--                      off_t weWant, weHave, toRead;
--                      
--                      weWant = con->request.content_length - dst_cq->bytes_in;
--                      
--                      assert(c->mem->used);
--                      
--                      weHave = c->mem->used - c->offset - 1;
--                              
--                      toRead = weHave > weWant ? weWant : weHave;
--
--                      /* the new way, copy everything into a chunkqueue whcih might use tempfiles */
--                      if (con->request.content_length > 64 * 1024) {
--                              chunk *dst_c = NULL;
--                              /* copy everything to max 1Mb sized tempfiles */
--
--                              /*
--                               * if the last chunk is 
--                               * - smaller than 1Mb (size < 1Mb)
--                               * - not read yet (offset == 0)
--                               * -> append to it
--                               * otherwise
--                               * -> create a new chunk 
--                               * 
--                               * */
--
--                              if (dst_cq->last &&
--                                  dst_cq->last->type == FILE_CHUNK &&
--                                  dst_cq->last->file.is_temp &&
--                                  dst_cq->last->offset == 0) {
--                                      /* ok, take the last chunk for our job */
--
--                                      if (dst_cq->last->file.length < 1 * 1024 * 1024) {
--                                              dst_c = dst_cq->last;
--
--                                              if (dst_c->file.fd == -1) {
--                                                      /* this should not happen as we cache the fd, but you never know */
--                                                      dst_c->file.fd = open(dst_c->file.name->ptr, O_WRONLY | O_APPEND);
--                                              }
--                                      } else {
--                                              /* the chunk is too large now, close it */
--                                              dst_c = dst_cq->last;
-+              weWant = con->request.content_length - out->bytes_in;
-+
-+              if (c->mem->used == 0) continue;
--                                              if (dst_c->file.fd != -1) {
--                                                      close(dst_c->file.fd);
--                                                      dst_c->file.fd = -1;
--                                              }
--                                              dst_c = chunkqueue_get_append_tempfile(dst_cq);
-+              weHave = c->mem->used - c->offset - 1;
-+
-+              toRead = weHave > weWant ? weWant : weHave;
-+
-+              /* the new way, copy everything into a chunkqueue whcih might use tempfiles */
-+              if (con->request.content_length > 64 * 1024) {
-+                      chunk *dst_c = NULL;
-+                      /* copy everything to max 1Mb sized tempfiles */
-+
-+                      /*
-+                       * if the last chunk is
-+                       * - smaller than 1Mb (size < 1Mb)
-+                       * - not read yet (offset == 0)
-+                       * -> append to it
-+                       * otherwise
-+                       * -> create a new chunk
-+                       *
-+                       * */
-+
-+                      if (out->last &&
-+                          out->last->type == FILE_CHUNK &&
-+                          out->last->file.is_temp &&
-+                          out->last->offset == 0) {
-+                              /* ok, take the last chunk for our job */
-+
-+                              if (out->last->file.length < 1 * 1024 * 1024) {
-+                                      dst_c = out->last;
-+
-+                                      if (dst_c->file.fd == -1) {
-+                                              /* this should not happen as we cache the fd, but you never know */
-+                                              dst_c->file.fd = open(dst_c->file.name->ptr, O_WRONLY | O_APPEND);
-                                       }
-                               } else {
--                                      dst_c = chunkqueue_get_append_tempfile(dst_cq);
-+                                      /* the chunk is too large now, close it */
-+                                      dst_c = out->last;
-+
-+                                      if (dst_c->file.fd != -1) {
-+                                              close(dst_c->file.fd);
-+                                              dst_c->file.fd = -1;
-+                                      }
-+                                      dst_c = chunkqueue_get_append_tempfile(out);
-                               }
-+                      } else {
-+                              dst_c = chunkqueue_get_append_tempfile(out);
-+                      }
-+
-+                      /* we have a chunk, let's write to it */
--                              /* we have a chunk, let's write to it */
-+                      if (dst_c->file.fd == -1) {
-+                              /* we don't have file to write to,
-+                               * EACCES might be one reason.
-+                               *
-+                               * Instead of sending 500 we send 413 and say the request is too large
-+                               *  */
--                              if (dst_c->file.fd == -1) {
--                                      /* we don't have file to write to, 
--                                       * EACCES might be one reason.
--                                       *
--                                       * Instead of sending 500 we send 413 and say the request is too large
--                                       *  */
--
--                                      log_error_write(srv, __FILE__, __LINE__, "sbs",
--                                                      "denying upload as opening to temp-file for upload failed:", 
--                                                      dst_c->file.name, strerror(errno));
--
--                                      con->http_status = 413; /* Request-Entity too large */
--                                      con->keep_alive = 0;
--                                      connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
-+                              log_error_write(srv, __FILE__, __LINE__, "sbs",
-+                                              "denying upload as opening to temp-file for upload failed:",
-+                                              dst_c->file.name, strerror(errno));
--                                      break;
--                              }
-+                              con->http_status = 413; /* Request-Entity too large */
-+                              con->keep_alive = 0;
-+                              return HANDLER_FINISHED;
-+                      }
--                              if (toRead != write(dst_c->file.fd, c->mem->ptr + c->offset, toRead)) {
--                                      /* write failed for some reason ... disk full ? */ 
--                                      log_error_write(srv, __FILE__, __LINE__, "sbs",
--                                                      "denying upload as writing to file failed:", 
--                                                      dst_c->file.name, strerror(errno));
--                                      
--                                      con->http_status = 413; /* Request-Entity too large */
--                                      con->keep_alive = 0;
--                                      connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
--                              
--                                      close(dst_c->file.fd);
--                                      dst_c->file.fd = -1;
-+                      if (toRead != write(dst_c->file.fd, c->mem->ptr + c->offset, toRead)) {
-+                              /* write failed for some reason ... disk full ? */
-+                              log_error_write(srv, __FILE__, __LINE__, "sbs",
-+                                              "denying upload as writing to file failed:",
-+                                              dst_c->file.name, strerror(errno));
--                                      break;
--                              }
-+                              con->http_status = 413; /* Request-Entity too large */
-+                              con->keep_alive = 0;
--                              dst_c->file.length += toRead;
--                                      
--                              if (dst_cq->bytes_in + toRead == (off_t)con->request.content_length) {
--                                      /* we read everything, close the chunk */
--                                      close(dst_c->file.fd);
--                                      dst_c->file.fd = -1;
--                              }
--                      } else {
--                              buffer *b;
-+                              close(dst_c->file.fd);
-+                              dst_c->file.fd = -1;
--                              b = chunkqueue_get_append_buffer(dst_cq);
--                              buffer_copy_string_len(b, c->mem->ptr + c->offset, toRead);
-+                              return HANDLER_FINISHED;
-                       }
--                      
--                      c->offset += toRead;
--                      dst_cq->bytes_in += toRead;
--              }
--              /* Content is ready */
--              if (dst_cq->bytes_in == (off_t)con->request.content_length) {
--                      connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
-+                      dst_c->file.length += toRead;
-+
-+                      if (out->bytes_in + toRead == con->request.content_length) {
-+                              /* we read everything, close the chunk */
-+                              close(dst_c->file.fd);
-+                              dst_c->file.fd = -1;
-+                      }
-+              } else {
-+                      buffer *b;
-+
-+                      b = chunkqueue_get_append_buffer(out);
-+                      buffer_copy_string_len(b, c->mem->ptr + c->offset, toRead);
-               }
--                      
--              break;
-+
-+              c->offset += toRead;
-+
-+              out->bytes_in += toRead;
-+              in->bytes_out += toRead;
-       }
--      chunkqueue_remove_finished_chunks(cq);
-+      if (out->bytes_in < con->request.content_length) {
-+              /* we have to read more content */
-+              fdevent_event_add(srv->ev, con->sock, FDEVENT_IN);
-+      }
--      return 0;
-+      return HANDLER_GO_ON;
- }
- handler_t connection_handle_fdevent(void *s, void *context, int revents) {
-       server     *srv = (server *)s;
-       connection *con = context;
--      
--      joblist_append(srv, con);
--      
-+
-       if (revents & FDEVENT_IN) {
--              con->is_readable = 1;
--#if 0
--              log_error_write(srv, __FILE__, __LINE__, "sd", "read-wait - done", con->fd);
--#endif
-+              switch (con->state) {
-+              case CON_STATE_READ_REQUEST_HEADER:
-+              case CON_STATE_READ_REQUEST_CONTENT:
-+                      joblist_append(srv, con);
-+                      break;
-+              case CON_STATE_CLOSE:
-+                      break;
-+              default:
-+                      ERROR("%s", "I thought only READ_REQUEST_* need fdevent-in");
-+                      break;
-+              }
-       }
-+
-       if (revents & FDEVENT_OUT) {
--              con->is_writable = 1;
--              /* we don't need the event twice */
-+              switch (con->state) {
-+              case CON_STATE_WRITE_RESPONSE_HEADER:
-+              case CON_STATE_WRITE_RESPONSE_CONTENT:
-+                      joblist_append(srv, con);
-+                      break;
-+              default:
-+                      ERROR("%s", "I thought only WRITE_RESPONSE_* need fdevent-out");
-+                      break;
-+              }
-       }
--      
--      
-+
-       if (revents & ~(FDEVENT_IN | FDEVENT_OUT)) {
-               /* looks like an error */
--                                              
--              /* FIXME: revents = 0x19 still means that we should read from the queue */
--              if (revents & FDEVENT_HUP) {
--                      if (con->state == CON_STATE_CLOSE) {
--                              con->close_timeout_ts = 0;
--                      } else {
--                              /* sigio reports the wrong event here
--                               * 
--                               * there was no HUP at all 
--                               */
--#ifdef USE_LINUX_SIGIO
--                              if (srv->ev->in_sigio == 1) {
--                                      log_error_write(srv, __FILE__, __LINE__, "sd",
--                                              "connection closed: poll() -> HUP", con->fd);
--                              } else {
--                                      connection_set_state(srv, con, CON_STATE_ERROR);
--                              }
--#else
--                              connection_set_state(srv, con, CON_STATE_ERROR);
--#endif
--                              
--                      }
--              } else if (revents & FDEVENT_ERR) {
--#ifndef USE_LINUX_SIGIO
--                      log_error_write(srv, __FILE__, __LINE__, "sd",
--                                      "connection closed: poll() -> ERR", con->fd);
--#endif        
--                      connection_set_state(srv, con, CON_STATE_ERROR);
--              } else {
--                      log_error_write(srv, __FILE__, __LINE__, "sd",
--                                      "connection closed: poll() -> ???", revents);
--              } 
--      }
--      
--      if (con->state == CON_STATE_READ ||
--          con->state == CON_STATE_READ_POST) {
--              connection_handle_read_state(srv, con);
--      }
--      
--      if (con->state == CON_STATE_WRITE &&
--          !chunkqueue_is_empty(con->write_queue) &&
--          con->is_writable) {
--              
--              if (-1 == connection_handle_write(srv, con)) {
--                      connection_set_state(srv, con, CON_STATE_ERROR);
--                      
--                      log_error_write(srv, __FILE__, __LINE__, "ds",
--                                      con->fd,
--                                      "handle write failed.");
--              } else if (con->state == CON_STATE_WRITE) {
--                      con->write_request_ts = srv->cur_ts;
--              }
--      }
--      
--      if (con->state == CON_STATE_CLOSE) {
--              /* flush the read buffers */
--              int b;
--              
--              if (ioctl(con->fd, FIONREAD, &b)) {
--                      log_error_write(srv, __FILE__, __LINE__, "ss",
--                                      "ioctl() failed", strerror(errno));
--              }
--              
--              if (b > 0) {
--                      char buf[1024];
--                      log_error_write(srv, __FILE__, __LINE__, "sdd",
--                                      "CLOSE-read()", con->fd, b);
--                      
--                      /* */
--                      read(con->fd, buf, sizeof(buf));
--              } else {
--                      /* nothing to read */
--                      
--                      con->close_timeout_ts = 0;
--              }
-+
-+              connection_set_state(srv, con, CON_STATE_ERROR);
-+              joblist_append(srv, con);
-       }
--      
-+
-+
-       return HANDLER_FINISHED;
- }
-@@ -1229,63 +860,78 @@
-       sock_addr cnt_addr;
-       socklen_t cnt_len;
-       /* accept it and register the fd */
--      
-+
-       cnt_len = sizeof(cnt_addr);
--      if (-1 == (cnt = accept(srv_socket->fd, (struct sockaddr *) &cnt_addr, &cnt_len))) {
--              if ((errno != EAGAIN) &&
--                  (errno != EINTR)) {
--                      log_error_write(srv, __FILE__, __LINE__, "ssd", "accept failed:", strerror(errno), errno);
-+      if (-1 == (cnt = accept(srv_socket->sock->fd, (struct sockaddr *) &cnt_addr, &cnt_len))) {
-+#ifdef _WIN32
-+              errno = WSAGetLastError();
-+#endif
-+              switch (errno) {
-+              case EAGAIN:
-+#if EWOULDBLOCK != EAGAIN
-+              case EWOULDBLOCK:
-+#endif
-+              case EINTR: 
-+                      /* we were stopped _before_ we had a connection */
-+              case ECONNABORTED: /* this is a FreeBSD thingy */
-+                      /* we were stopped _after_ we had a connection */
-+                      break;
-+              default:
-+                      ERROR("accept failed on fd=%d with error: (%d) %s", srv_socket->sock->fd, errno, strerror(errno));
-+                      break;
-               }
-               return NULL;
-       } else {
-               connection *con;
--              
-+
-               srv->cur_fds++;
--              
-+
-               /* ok, we have the connection, register it */
- #if 0
-               log_error_write(srv, __FILE__, __LINE__, "sd",
-                               "appected()", cnt);
- #endif
-               srv->con_opened++;
--              
-+
-               con = connections_get_new_connection(srv);
--              
--              con->fd = cnt;
--              con->fde_ndx = -1;
--#if 0         
-+              con->sock->fd = cnt;
-+              con->sock->fde_ndx = -1;
-+#if 0
-               gettimeofday(&(con->start_tv), NULL);
--#endif                
--              fdevent_register(srv->ev, con->fd, connection_handle_fdevent, con);
--              
-+#endif
-+              fdevent_register(srv->ev, con->sock, connection_handle_fdevent, con);
-+
-               connection_set_state(srv, con, CON_STATE_REQUEST_START);
--              
-+
-               con->connection_start = srv->cur_ts;
-               con->dst_addr = cnt_addr;
-               buffer_copy_string(con->dst_addr_buf, inet_ntop_cache_get_ip(srv, &(con->dst_addr)));
-               con->srv_socket = srv_socket;
--              
--              if (-1 == (fdevent_fcntl_set(srv->ev, con->fd))) {
-+
-+              if (-1 == (fdevent_fcntl_set(srv->ev, con->sock))) {
-                       log_error_write(srv, __FILE__, __LINE__, "ss", "fcntl failed: ", strerror(errno));
-+                      connection_close(srv, con);
-                       return NULL;
-               }
-+                      
- #ifdef USE_OPENSSL
-               /* connect FD to SSL */
-               if (srv_socket->is_ssl) {
--                      if (NULL == (con->ssl = SSL_new(srv_socket->ssl_ctx))) {
--                              log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", 
-+                      if (NULL == (con->sock->ssl = SSL_new(srv_socket->ssl_ctx))) {
-+                              log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
-                                               ERR_error_string(ERR_get_error(), NULL));
--                              
-+                              connection_close(srv, con);
-                               return NULL;
-                       }
--                      
--                      SSL_set_accept_state(con->ssl);
-+
-+                      SSL_set_accept_state(con->sock->ssl);
-                       con->conf.is_ssl=1;
--                      
--                      if (1 != (SSL_set_fd(con->ssl, cnt))) {
--                              log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", 
-+
-+                      if (1 != (SSL_set_fd(con->sock->ssl, cnt))) {
-+                              log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
-                                               ERR_error_string(ERR_get_error(), NULL));
-+                              connection_close(srv, con);
-                               return NULL;
-                       }
-               }
-@@ -1294,182 +940,452 @@
-       }
- }
-+static int http_chunk_append_len(chunkqueue *cq, size_t len) {
-+      size_t i, olen = len, j;
-+      buffer *b;
-+
-+      b = buffer_init();
-+
-+      if (len == 0) {
-+              buffer_copy_string(b, "0");
-+      } else {
-+              for (i = 0; i < 8 && len; i++) {
-+                      len >>= 4;
-+              }
-+
-+              /* i is the number of hex digits we have */
-+              buffer_prepare_copy(b, i + 1);
-+
-+              for (j = i-1, len = olen; j+1 > 0; j--) {
-+                      b->ptr[j] = (len & 0xf) + (((len & 0xf) <= 9) ? '0' : 'a' - 10);
-+                      len >>= 4;
-+              }
-+              b->used = i;
-+              b->ptr[b->used++] = '\0';
-+      }
-+
-+      buffer_append_string(b, "\r\n");
-+      chunkqueue_append_buffer(cq, b);
-+
-+      buffer_free(b);
-+
-+      return 0;
-+}
-+
-+
-+/**
-+ * apply chunk encoding if necessary
-+ */
-+int http_stream_encoder(server *srv, connection *con, chunkqueue *in, chunkqueue *out) {
-+      chunk *c;
-+      int is_chunked;
-+
-+      /**/
-+
-+      is_chunked = (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED);
-+
-+      if (is_chunked) {
-+              for (c = in->first; c; c = c->next) {
-+                      switch (c->type) {
-+                      case MEM_CHUNK:
-+                              if (c->mem->used == 0) continue;
-+
-+                              http_chunk_append_len(out, c->mem->used - 1);
-+                              chunkqueue_append_buffer(out, c->mem);
-+                              c->offset = c->mem->used - 1;
-+                              break;
-+                      case FILE_CHUNK:
-+                              if (c->file.length == 0) continue;
-+
-+                              http_chunk_append_len(out, c->file.length);
-+                              chunkqueue_append_file(out, c->file.name, c->file.start, c->file.length);
-+
-+                              c->offset = c->file.length;
-+                              break;
-+                      }
-+                      chunkqueue_append_mem(out, "\r\n", 2 + 1);
-+              }
-+              if (in->is_closed) http_chunk_append_len(out, 0);
-+      } else {
-+              for (c = in->first; c; c = c->next) {
-+                      switch (c->type) {
-+                      case MEM_CHUNK:
-+                              if (c->mem->used == 0) continue;
-+
-+                              chunkqueue_append_buffer(out, c->mem);
-+                              c->offset = c->mem->used - 1;
-+                              break;
-+                      case FILE_CHUNK:
-+                              if (c->file.length == 0) continue;
-+
-+                              chunkqueue_append_file(out, c->file.name, c->file.start, c->file.length);
-+
-+                              c->offset = c->file.length;
-+                              break;
-+                      }
-+              }
-+      }
-+
-+      chunkqueue_remove_finished_chunks(in);
-+
-+      return 0;
-+}
- int connection_state_machine(server *srv, connection *con) {
-       int done = 0, r;
- #ifdef USE_OPENSSL
-       server_socket *srv_sock = con->srv_socket;
- #endif
--      
-+
-       if (srv->srvconf.log_state_handling) {
--              log_error_write(srv, __FILE__, __LINE__, "sds", 
--                              "state at start", 
--                              con->fd,
-+              log_error_write(srv, __FILE__, __LINE__, "sds",
-+                              "state at start",
-+                              con->sock->fd,
-                               connection_get_state(con->state));
-       }
-       while (done == 0) {
-               size_t ostate = con->state;
-               int b;
--              
-+
-               switch (con->state) {
--              case CON_STATE_REQUEST_START: /* transient */
-+              case CON_STATE_CONNECT:
-                       if (srv->srvconf.log_state_handling) {
--                              log_error_write(srv, __FILE__, __LINE__, "sds", 
--                                              "state for fd", con->fd, connection_get_state(con->state));
-+                              log_error_write(srv, __FILE__, __LINE__, "sds",
-+                                              "state for fd", con->sock->fd, connection_get_state(con->state));
-                       }
--                      
--                      con->request_start = srv->cur_ts;
--                      con->read_idle_ts = srv->cur_ts;
--                      
--                      con->request_count++;
--                      con->loops_per_request = 0;
--                      
--                      connection_set_state(srv, con, CON_STATE_READ);
--                      
-+
-+                      chunkqueue_reset(con->recv_raw); /* this is a new connection, trash the pipeline */
-+
-+                      con->request_count = 0;
-+
-                       break;
--              case CON_STATE_REQUEST_END: /* transient */
-+              case CON_STATE_REQUEST_START:
-+                      /* init the request handling */
-                       if (srv->srvconf.log_state_handling) {
--                              log_error_write(srv, __FILE__, __LINE__, "sds", 
--                                              "state for fd", con->fd, connection_get_state(con->state));
-+                              log_error_write(srv, __FILE__, __LINE__, "sds",
-+                                              "state for fd", con->sock->fd, connection_get_state(con->state));
-                       }
--                      
--                      if (http_request_parse(srv, con)) {
--                              /* we have to read some data from the POST request */
--                              
--                              connection_set_state(srv, con, CON_STATE_READ_POST);
-+                      con->request_start = srv->cur_ts; /* start of the request */
-+                      con->read_idle_ts = srv->cur_ts;  /* start a read-call() */
-+
-+                      con->request_count++;             /* max-keepalive requests */
-+                      con->loops_per_request = 0;       /* infinite loops */
-+
-+                      /* if the content was short enough, it might have a header already in the pipe */
-+                      if (con->recv_raw->first &&
-+                          chunkqueue_length(con->recv_raw) - con->recv_raw->first->offset > 0) {
-+                              /* pipelining */
-+
-+                              switch (http_request_parse_cq(con->recv_raw, con->http_req)) {
-+                              case PARSE_ERROR:
-+                                      con->http_status = 400; /* the header is broken */
-+
-+                                      chunkqueue_remove_finished_chunks(con->recv_raw);
-+
-+                                      connection_set_state(srv, con, CON_STATE_HANDLE_RESPONSE_HEADER);
-+                                      break;
-+                              case PARSE_NEED_MORE:
-+                                      /* the read() call is on the way */
-+                                      connection_set_state(srv, con, CON_STATE_READ_REQUEST_HEADER);
-+                                      break;
-+                              case PARSE_SUCCESS:
-+                                      /* pipelining worked, validate the header */
-+                                      chunkqueue_remove_finished_chunks(con->recv_raw);
-+
-+                                      connection_set_state(srv, con, CON_STATE_VALIDATE_REQUEST_HEADER);
-+                                      break;
-+                              default:
-+                                      chunkqueue_remove_finished_chunks(con->recv_raw);
-+                                      TRACE("%s", "(error)");
-+                                      return HANDLER_ERROR;
-+                              }
-+                      } else {
-+                              connection_set_state(srv, con, CON_STATE_READ_REQUEST_HEADER);
-+                      }
-+
-+                      break;
-+              case CON_STATE_READ_REQUEST_HEADER: 
-+                      /* read us much data as needed into the recv_raw-cq for a valid header */
-+                      if (srv->srvconf.log_state_handling) {
-+                              TRACE("state for fd=%d: %s", con->sock->fd, connection_get_state(con->state));
-+                      }
-+
-+                      switch (connection_handle_read_request_header(srv, con)) {
-+                      case HANDLER_GO_ON:
-+                              connection_set_state(srv, con, CON_STATE_VALIDATE_REQUEST_HEADER);
-+                              break;
-+                      case HANDLER_FINISHED:
-+                              connection_set_state(srv, con, CON_STATE_WRITE_RESPONSE_HEADER);
-+                              break;
-+                      case HANDLER_WAIT_FOR_EVENT:
-+                              return HANDLER_WAIT_FOR_EVENT;
-+                      case HANDLER_ERROR:
-+                              TRACE("%s", "(error)");
-+                              connection_set_state(srv, con, CON_STATE_ERROR);
-+                              break;
-+                      default:
-+                              TRACE("%s", "(error)");
-+                              connection_set_state(srv, con, CON_STATE_ERROR);
-                               break;
-                       }
--                      
--                      connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
--                      
-                       break;
--              case CON_STATE_HANDLE_REQUEST:
--                      /* 
--                       * the request is parsed
--                       * 
--                       * decided what to do with the request
--                       * - 
--                       * 
--                       * 
--                       */
--                      
-+              case CON_STATE_VALIDATE_REQUEST_HEADER:
-+                      /* we have the full header, parse it */
-+
-+                      http_request_parse(srv, con, con->http_req);
-+
-+                      if (con->http_status != 0) {
-+                              con->keep_alive = 0;
-+                              con->send->is_closed = 1; /* there is no content */
-+
-+                              connection_set_state(srv, con, CON_STATE_HANDLE_RESPONSE_HEADER);
-+                      } else if (array_get_element(con->request.headers, "Expect")) {
-+                              /* write */
-+                              con->http_status = 100;
-+                              con->send->is_closed = 1;
-+                              TRACE("%s", "setting status 100");
-+
-+                              connection_set_state(srv, con, CON_STATE_WRITE_RESPONSE_HEADER);
-+                      } else {
-+                              /* parsing the request went fine 
-+                               * let's find a handler for this request */
-+                              connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST_HEADER);
-+                      }
-+
-+                      break;
-+              case CON_STATE_HANDLE_REQUEST_HEADER:
-+                      /* the request header is parsed,
-+                       * find someone who wants to handle this request */
-+
-                       if (srv->srvconf.log_state_handling) {
--                              log_error_write(srv, __FILE__, __LINE__, "sds", 
--                                              "state for fd", con->fd, connection_get_state(con->state));
-+                              log_error_write(srv, __FILE__, __LINE__, "sds",
-+                                              "state for fd", con->sock->fd, connection_get_state(con->state));
-                       }
--                      
--                      switch (r = http_response_prepare(srv, con)) {
-+
-+                      switch (r = handle_get_backend(srv, con)) {
-+                      case HANDLER_GO_ON:
-                       case HANDLER_FINISHED:
--                              if (con->http_status == 404 ||
--                                  con->http_status == 403) {
--                                      /* 404 error-handler */
--                                      
--                                      if (con->in_error_handler == 0 && 
--                                          (!buffer_is_empty(con->conf.error_handler) ||
--                                           !buffer_is_empty(con->error_handler))) {
--                                              /* call error-handler */
--                                              
--                                              con->error_handler_saved_status = con->http_status;
--                                              con->http_status = 0;
--                                              
--                                              if (buffer_is_empty(con->error_handler)) {
--                                                      buffer_copy_string_buffer(con->request.uri, con->conf.error_handler);
--                                              } else {
--                                                      buffer_copy_string_buffer(con->request.uri, con->error_handler);
--                                              }
--                                              buffer_reset(con->physical.path);
--                                              
--                                              con->in_error_handler = 1;
--                                              
--                                              connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
--                                              
--                                              done = -1;
--                                              break;
--                                      } else if (con->in_error_handler) {
--                                              /* error-handler is a 404 */
--                                              
--                                              /* continue as normal, status is the same */
--                                              log_error_write(srv, __FILE__, __LINE__, "sb", 
--                                                              "Warning: Either the error-handler returned status 404 or the error-handler itself was not found:", con->request.uri);
--                                              log_error_write(srv, __FILE__, __LINE__, "sd", 
--                                                              "returning the original status", con->error_handler_saved_status);
--                                              log_error_write(srv, __FILE__, __LINE__, "s", 
--                                                              "If this is a rails app: check your production.log");
--                                              con->http_status = con->error_handler_saved_status;
--                                      }
--                              } else if (con->in_error_handler) {
--                                      /* error-handler is back and has generated content */
--                                      /* if Status: was set, take it otherwise use 200 */
--                              }
--                              
--                              if (con->http_status == 0) con->http_status = 200;
--                              
--                              /* we have something to send, go on */
--                              connection_set_state(srv, con, CON_STATE_RESPONSE_START);
-                               break;
-                       case HANDLER_WAIT_FOR_FD:
-                               srv->want_fds++;
--                              
-+
-                               fdwaitqueue_append(srv, con);
--                              
--                              connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
--                              
-+
-+                              connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST_HEADER);
-+
-                               break;
-                       case HANDLER_COMEBACK:
-                               done = -1;
-                       case HANDLER_WAIT_FOR_EVENT:
-                               /* come back here */
--                              connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
--                              
-+                              connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST_HEADER);
-+
-                               break;
-                       case HANDLER_ERROR:
-                               /* something went wrong */
-+                              TRACE("%s", "(error)");
-                               connection_set_state(srv, con, CON_STATE_ERROR);
-                               break;
-                       default:
--                              log_error_write(srv, __FILE__, __LINE__, "sdd", "unknown ret-value: ", con->fd, r);
-+                              TRACE("handle_get_backend returned %d on fd %d", r, con->sock->fd);
-                               break;
-                       }
--                      
-+
-+                      if (r != HANDLER_FINISHED && r != HANDLER_GO_ON) break;
-+
-+                      if (con->http_status == 404 ||
-+                          con->http_status == 403) {
-+                              /* 404 error-handler */
-+
-+                              if (con->in_error_handler == 0 &&
-+                                  (!buffer_is_empty(con->conf.error_handler) ||
-+                                   !buffer_is_empty(con->error_handler))) {
-+                                      /* call error-handler */
-+
-+                                      con->error_handler_saved_status = con->http_status;
-+                                      con->http_status = 0;
-+
-+                                      if (buffer_is_empty(con->error_handler)) {
-+                                              buffer_copy_string_buffer(con->request.uri, con->conf.error_handler);
-+                                      } else {
-+                                              buffer_copy_string_buffer(con->request.uri, con->error_handler);
-+                                      }
-+                                      buffer_reset(con->physical.path);
-+
-+                                      con->in_error_handler = 1;
-+
-+                                      connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST_HEADER);
-+
-+                                      done = -1;
-+                                      break;
-+                              } else if (con->in_error_handler) {
-+                                      /* error-handler is a 404 */
-+
-+                                      /* continue as normal, status is the same */
-+                                      log_error_write(srv, __FILE__, __LINE__, "sb",
-+                                                      "Warning: Either the error-handler returned status 404 or the error-handler itself was not found:", con->request.uri);
-+                                      log_error_write(srv, __FILE__, __LINE__, "sd",
-+                                                      "returning the original status", con->error_handler_saved_status);
-+                                      log_error_write(srv, __FILE__, __LINE__, "s",
-+                                                      "If this is a rails app: check your production.log");
-+                                      con->http_status = con->error_handler_saved_status;
-+                              }
-+                      } else if (con->in_error_handler) {
-+                              /* error-handler is back and has generated content */
-+                              /* if Status: was set, take it otherwise use 200 */
-+                      }
-+
-+                      if (con->http_status == 0) con->http_status = 200;
-+
-+                      /* the backend is prepared, forward the content */
-+                      connection_set_state(srv, con, CON_STATE_READ_REQUEST_CONTENT);
-+
-                       break;
--              case CON_STATE_RESPONSE_START:
-+              case CON_STATE_READ_REQUEST_CONTENT:
-+                      /* the request-handle is setup, read all the data and push it into the request-handler */
-+
-+                      if (con->request.content_length == -1 ||
-+                          con->request.content_length == 0) {
-+                              con->recv->is_closed = 1;
-+                      }
-+
-+                      if (!con->recv->is_closed &&
-+                          con->recv->bytes_in < con->request.content_length) {
-+                              switch (connection_handle_read_request_content(srv, con)) {
-+                              case HANDLER_GO_ON:
-+                                      break;
-+                              case HANDLER_ERROR:
-+                              TRACE("%s", "(error)");
-+                                      connection_set_state(srv, con, CON_STATE_ERROR);
-+                                      break;
-+                              case HANDLER_WAIT_FOR_EVENT:
-+                                      break;
-+                              default:
-+                                      ERROR("%s", "oops, unknown return value: ...");
-+                              }
-+
-+                              if (con->recv->bytes_in == con->request.content_length) {
-+                                      TRACE("%s", "read-content-done");
-+                                      /* we read everything */
-+                                      fdevent_event_del(srv->ev, con->sock);
-+                                      con->recv->is_closed = 1;
-+                              }
-+                              chunkqueue_remove_finished_chunks(con->recv_raw);
-+                      }
-+
-+                      chunkqueue_remove_finished_chunks(con->recv);
-+
-                       /* 
--                       * the decision is done
--                       * - create the HTTP-Response-Header
-+                       * this should call the backend
-+                       * they might build the connection now or stream the content to the upstream server
-+                       * */
-+
-+                      switch(r = plugins_call_handle_send_request_content(srv, con)) {
-+                      case HANDLER_GO_ON:
-+                              /* everything was forwarded */
-+                              break;
-+                      case HANDLER_FINISHED:
-+                              /* oops, we don't want this here */
-+                              break;
-+                      case HANDLER_WAIT_FOR_EVENT:
-+                              return HANDLER_WAIT_FOR_EVENT;
-+                      default:
-+                              /* something strange happened */
-+                              TRACE("%s", "(error)");
-+                              connection_set_state(srv, con, CON_STATE_ERROR);
-+                              break;
-+                      }
-+
-+                      chunkqueue_remove_finished_chunks(con->recv);
-+
-+                      if (con->state == CON_STATE_ERROR) break;
-+
-+                      if (con->recv->is_closed && 
-+                          con->recv->bytes_in == con->recv->bytes_out) {
-+                              /* everything we read is sent */
-+                              connection_set_state(srv, con, CON_STATE_HANDLE_RESPONSE_HEADER);
-+                      }
-+
-+                      break;
-+              case CON_STATE_HANDLE_RESPONSE_HEADER:
-+                      /* we got a response header from the backend
-+                       * call all plugins who want to modify the response header
-+                       * - mod_compress/deflate
-+                       * - HTTP/1.1 chunking
-                        * 
-                        */
-+
-+                      connection_set_state(srv, con, CON_STATE_WRITE_RESPONSE_HEADER);
-+
-+                      break;
-+              case CON_STATE_WRITE_RESPONSE_HEADER:
-+                      /* create the HTTP response header */
-+                      connection_handle_response_header(srv, con);
-+
-+                      connection_set_state(srv, con, CON_STATE_WRITE_RESPONSE_CONTENT);
-                       
--                      if (srv->srvconf.log_state_handling) {
--                              log_error_write(srv, __FILE__, __LINE__, "sds", 
--                                              "state for fd", con->fd, connection_get_state(con->state));
--                      }
--                      
--                      if (-1 == connection_handle_write_prepare(srv, con)) {
-+                      break;
-+              case CON_STATE_WRITE_RESPONSE_CONTENT:
-+                      fdevent_event_del(srv->ev, con->sock);
-+
-+                      /* we might have new content in the con->send buffer 
-+                       * encode it for the network 
-+                       * - chunking
-+                       * - compression
-+                       */
-+
-+                      http_stream_encoder(srv, con, con->send, con->send_raw);
-+
-+                      switch(network_write_chunkqueue(srv, con, con->send_raw)) {
-+                      case NETWORK_STATUS_SUCCESS:
-+                              /* we send everything from the chunkqueue and the chunkqueue-sender signaled it is finished */
-+                              if (con->send->is_closed) {
-+                                      if (con->http_status == 100) {
-+                                              /* send out the 100 Continue header and handle the request as normal afterwards */
-+                                              con->http_status = 0;
-+
-+                                              connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST_HEADER);
-+                                      } else {
-+                                              connection_set_state(srv, con, CON_STATE_RESPONSE_END);
-+                                      }
-+                              }
-+                              break;
-+                      case NETWORK_STATUS_FATAL_ERROR: /* error on our side */
-+                              TRACE("%s", "(error)");
-                               connection_set_state(srv, con, CON_STATE_ERROR);
--                              
-+                              break;
-+                      case NETWORK_STATUS_CONNECTION_CLOSE: /* remote close */
-+                              TRACE("%s", "(error)");
-+                              connection_set_state(srv, con, CON_STATE_ERROR);
-+                              break;
-+                      case NETWORK_STATUS_WAIT_FOR_EVENT:
-+                              fdevent_event_add(srv->ev, con->sock, FDEVENT_OUT);
-+
-+                              return HANDLER_WAIT_FOR_EVENT;
-+                      case NETWORK_STATUS_INTERRUPTED:
-                               break;
-                       }
--                      
--                      connection_set_state(srv, con, CON_STATE_WRITE);
-+
-+
-                       break;
-               case CON_STATE_RESPONSE_END: /* transient */
-                       /* log the request */
--                      
-+
-                       if (srv->srvconf.log_state_handling) {
--                              log_error_write(srv, __FILE__, __LINE__, "sds", 
--                                              "state for fd", con->fd, connection_get_state(con->state));
-+                              log_error_write(srv, __FILE__, __LINE__, "sds",
-+                                              "state for fd", con->sock->fd, connection_get_state(con->state));
-                       }
--                      
--                      plugins_call_handle_request_done(srv, con);
--                      
-+
-+                      plugins_call_handle_response_done(srv, con);
-+
-                       srv->con_written++;
--                      
-+
-                       if (con->keep_alive) {
-                               connection_set_state(srv, con, CON_STATE_REQUEST_START);
--                              
--#if 0                                 
-+
-+#if 0
-                               con->request_start = srv->cur_ts;
-                               con->read_idle_ts = srv->cur_ts;
- #endif
-@@ -1482,150 +1398,83 @@
-                                       log_error_write(srv, __FILE__, __LINE__, "sd", "unhandling return value", r);
-                                       break;
-                               }
--                              
--#ifdef USE_OPENSSL
--                              if (srv_sock->is_ssl) {
--                                      switch (SSL_shutdown(con->ssl)) {
--                                      case 1:
--                                              /* done */
--                                              break;
--                                      case 0:
--                                              /* wait for fd-event 
--                                               * 
--                                               * FIXME: wait for fdevent and call SSL_shutdown again
--                                               * 
--                                               */
--                                              
--                                              break;
--                                      default:
--                                              log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", 
--                                                              ERR_error_string(ERR_get_error(), NULL));
--                                      }
--                              }
--#endif
-+
-                               connection_close(srv, con);
--                              
-+
-                               srv->con_closed++;
-                       }
--                      
-+
-                       connection_reset(srv, con);
--                      
--                      break;
--              case CON_STATE_CONNECT:
--                      if (srv->srvconf.log_state_handling) {
--                              log_error_write(srv, __FILE__, __LINE__, "sds", 
--                                              "state for fd", con->fd, connection_get_state(con->state));
--                      }
--                      
--                      chunkqueue_reset(con->read_queue);
--                      
--                      con->request_count = 0;
--                      
-+
-                       break;
-               case CON_STATE_CLOSE:
-                       if (srv->srvconf.log_state_handling) {
--                              log_error_write(srv, __FILE__, __LINE__, "sds", 
--                                              "state for fd", con->fd, connection_get_state(con->state));
-+                              log_error_write(srv, __FILE__, __LINE__, "sds",
-+                                              "state for fd", con->sock->fd, connection_get_state(con->state));
-                       }
--                      
-+
-                       if (con->keep_alive) {
--                              if (ioctl(con->fd, FIONREAD, &b)) {
-+                              if (ioctl(con->sock->fd, FIONREAD, &b)) {
-                                       log_error_write(srv, __FILE__, __LINE__, "ss",
-                                                       "ioctl() failed", strerror(errno));
-                               }
-                               if (b > 0) {
-                                       char buf[1024];
-                                       log_error_write(srv, __FILE__, __LINE__, "sdd",
--                                                      "CLOSE-read()", con->fd, b);
--                                      
-+                                                      "CLOSE-read()", con->sock->fd, b);
-+
-                                       /* */
--                                      read(con->fd, buf, sizeof(buf));
-+                                      read(con->sock->fd, buf, sizeof(buf));
-                               } else {
-                                       /* nothing to read */
--                                      
-+
-                                       con->close_timeout_ts = 0;
-                               }
-                       } else {
-                               con->close_timeout_ts = 0;
-                       }
--                      
-+
-                       if (srv->cur_ts - con->close_timeout_ts > 1) {
-                               connection_close(srv, con);
--                              
-+
-                               if (srv->srvconf.log_state_handling) {
--                                      log_error_write(srv, __FILE__, __LINE__, "sd", 
--                                                      "connection closed for fd", con->fd);
--                              }
--                      }
--                      
--                      break;
--              case CON_STATE_READ_POST:
--              case CON_STATE_READ:
--                      if (srv->srvconf.log_state_handling) {
--                              log_error_write(srv, __FILE__, __LINE__, "sds", 
--                                              "state for fd", con->fd, connection_get_state(con->state));
--                      }
--                      
--                      connection_handle_read_state(srv, con);
--                      break;
--              case CON_STATE_WRITE:
--                      if (srv->srvconf.log_state_handling) {
--                              log_error_write(srv, __FILE__, __LINE__, "sds", 
--                                              "state for fd", con->fd, connection_get_state(con->state));
--                      }
--                      
--                      /* only try to write if we have something in the queue */
--                      if (!chunkqueue_is_empty(con->write_queue)) {
--#if 0
--                              log_error_write(srv, __FILE__, __LINE__, "dsd",
--                                              con->fd,
--                                              "packets to write:",
--                                              con->write_queue->used);
--#endif
--                      }
--                      if (!chunkqueue_is_empty(con->write_queue) && con->is_writable) {
--                              if (-1 == connection_handle_write(srv, con)) {
--                                      log_error_write(srv, __FILE__, __LINE__, "ds",
--                                                      con->fd,
--                                                      "handle write failed.");
--                                      connection_set_state(srv, con, CON_STATE_ERROR);
--                              } else if (con->state == CON_STATE_WRITE) {
--                                      con->write_request_ts = srv->cur_ts;
-+                                      log_error_write(srv, __FILE__, __LINE__, "sd",
-+                                                      "connection closed for fd", con->sock->fd);
-                               }
-                       }
--                      
-+
-                       break;
-               case CON_STATE_ERROR: /* transient */
--                      
-+
-                       /* even if the connection was drop we still have to write it to the access log */
-                       if (con->http_status) {
--                              plugins_call_handle_request_done(srv, con);
-+                              plugins_call_handle_response_done(srv, con);
-                       }
- #ifdef USE_OPENSSL
-                       if (srv_sock->is_ssl) {
-                               int ret;
--                              switch ((ret = SSL_shutdown(con->ssl))) {
-+                              switch ((ret = SSL_shutdown(con->sock->ssl))) {
-                               case 1:
-                                       /* ok */
-                                       break;
-                               case 0:
--                                      SSL_shutdown(con->ssl);
-+                                      SSL_shutdown(con->sock->ssl);
-                                       break;
-                               default:
--                                      log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:", 
--                                                      SSL_get_error(con->ssl, ret), 
-+                                      log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:",
-+                                                      SSL_get_error(con->sock->ssl, ret),
-                                                       ERR_error_string(ERR_get_error(), NULL));
-                                       return -1;
-                               }
-                       }
- #endif
--                      
-+
-                       switch(con->mode) {
-                       case DIRECT:
- #if 0
--                              log_error_write(srv, __FILE__, __LINE__, "sd", 
--                                              "emergency exit: direct", 
--                                              con->fd);
-+                              log_error_write(srv, __FILE__, __LINE__, "sd",
-+                                              "emergency exit: direct",
-+                                              con->sock->fd);
- #endif
-                               break;
-                       default:
-@@ -1639,35 +1488,35 @@
-                               }
-                               break;
-                       }
--                      
-+
-                       connection_reset(srv, con);
--                      
-+
-                       /* close the connection */
-                       if ((con->keep_alive == 1) &&
--                          (0 == shutdown(con->fd, SHUT_WR))) {
-+                          (0 == shutdown(con->sock->fd, SHUT_WR))) {
-                               con->close_timeout_ts = srv->cur_ts;
-                               connection_set_state(srv, con, CON_STATE_CLOSE);
--                              
-+
-                               if (srv->srvconf.log_state_handling) {
--                                      log_error_write(srv, __FILE__, __LINE__, "sd", 
--                                                      "shutdown for fd", con->fd);
-+                                      log_error_write(srv, __FILE__, __LINE__, "sd",
-+                                                      "shutdown for fd", con->sock->fd);
-                               }
-                       } else {
-                               connection_close(srv, con);
-                       }
--                      
-+
-                       con->keep_alive = 0;
--                      
-+
-                       srv->con_closed++;
--                      
-+
-                       break;
-               default:
--                      log_error_write(srv, __FILE__, __LINE__, "sdd", 
--                                      "unknown state:", con->fd, con->state);
--                      
-+                      log_error_write(srv, __FILE__, __LINE__, "sdd",
-+                                      "unknown state:", con->sock->fd, con->state);
-+
-                       break;
-               }
--              
-+
-               if (done == -1) {
-                       done = 0;
-               } else if (ostate == con->state) {
-@@ -1676,35 +1525,11 @@
-       }
-       if (srv->srvconf.log_state_handling) {
--              log_error_write(srv, __FILE__, __LINE__, "sds", 
--                              "state at exit:", 
--                              con->fd,
-+              log_error_write(srv, __FILE__, __LINE__, "sds",
-+                              "state at exit:",
-+                              con->sock->fd,
-                               connection_get_state(con->state));
-       }
--      
--      switch(con->state) {
--      case CON_STATE_READ_POST:
--      case CON_STATE_READ:
--      case CON_STATE_CLOSE:
--              fdevent_event_add(srv->ev, &(con->fde_ndx), con->fd, FDEVENT_IN);
--              break;
--      case CON_STATE_WRITE:
--              /* request write-fdevent only if we really need it 
--               * - if we have data to write
--               * - if the socket is not writable yet 
--               */
--              if (!chunkqueue_is_empty(con->write_queue) && 
--                  (con->is_writable == 0) &&
--                  (con->traffic_limit_reached == 0)) {
--                      fdevent_event_add(srv->ev, &(con->fde_ndx), con->fd, FDEVENT_OUT);
--              } else {
--                      fdevent_event_del(srv->ev, &(con->fde_ndx), con->fd);
--              }
--              break;
--      default:
--              fdevent_event_del(srv->ev, &(con->fde_ndx), con->fd);
--              break;
--      }
-       return 0;
- }
---- ../lighttpd-1.4.11/src/crc32.h     2005-09-30 20:18:59.000000000 +0300
-+++ lighttpd-1.5.0/src/crc32.h 2006-07-16 00:26:04.000000000 +0300
-@@ -6,6 +6,7 @@
- #endif
- #include <sys/types.h>
-+#include <stdlib.h>
- #if defined HAVE_STDINT_H
- #include <stdint.h>
-@@ -13,6 +14,10 @@
- #include <inttypes.h>
- #endif
-+#ifdef _WIN32
-+#define uint32_t unsigned __int32
-+#endif
-+
- uint32_t generate_crc32c(char *string, size_t length);
- #endif
---- ../lighttpd-1.4.11/src/data_array.c        2005-08-23 17:36:12.000000000 +0300
-+++ lighttpd-1.5.0/src/data_array.c    2006-07-16 00:26:04.000000000 +0300
-@@ -17,16 +17,16 @@
- static void data_array_free(data_unset *d) {
-       data_array *ds = (data_array *)d;
--      
-+
-       buffer_free(ds->key);
-       array_free(ds->value);
--      
-+
-       free(d);
- }
- static void data_array_reset(data_unset *d) {
-       data_array *ds = (data_array *)d;
--      
-+
-       /* reused array elements */
-       buffer_reset(ds->key);
-       array_reset(ds->value);
-@@ -36,7 +36,7 @@
-       UNUSED(dst);
-       src->free(src);
--      
-+
-       return 0;
- }
-@@ -48,18 +48,18 @@
- data_array *data_array_init(void) {
-       data_array *ds;
--      
-+
-       ds = calloc(1, sizeof(*ds));
--      
-+
-       ds->key = buffer_init();
-       ds->value = array_init();
--      
-+
-       ds->copy = data_array_copy;
-       ds->free = data_array_free;
-       ds->reset = data_array_reset;
-       ds->insert_dup = data_array_insert_dup;
-       ds->print = data_array_print;
-       ds->type = TYPE_ARRAY;
--      
-+
-       return ds;
- }
---- ../lighttpd-1.4.11/src/data_config.c       2005-08-17 12:53:19.000000000 +0300
-+++ lighttpd-1.5.0/src/data_config.c   2006-07-16 00:26:03.000000000 +0300
-@@ -17,26 +17,26 @@
- static void data_config_free(data_unset *d) {
-       data_config *ds = (data_config *)d;
--      
-+
-       buffer_free(ds->key);
-       buffer_free(ds->op);
-       buffer_free(ds->comp_key);
--      
-+
-       array_free(ds->value);
-       array_free(ds->childs);
--      
-+
-       if (ds->string) buffer_free(ds->string);
- #ifdef HAVE_PCRE_H
-       if (ds->regex) pcre_free(ds->regex);
-       if (ds->regex_study) pcre_free(ds->regex_study);
- #endif
--      
-+
-       free(d);
- }
- static void data_config_reset(data_unset *d) {
-       data_config *ds = (data_config *)d;
--      
-+
-       /* reused array elements */
-       buffer_reset(ds->key);
-       buffer_reset(ds->comp_key);
-@@ -45,9 +45,9 @@
- static int data_config_insert_dup(data_unset *dst, data_unset *src) {
-       UNUSED(dst);
--      
-+
-       src->free(src);
--      
-+
-       return 0;
- }
-@@ -56,7 +56,7 @@
-       array *a = (array *)ds->value;
-       size_t i;
-       size_t maxlen;
--      
-+
-       if (0 == ds->context_ndx) {
-               fprintf(stderr, "config {\n");
-       }
-@@ -117,22 +117,22 @@
- data_config *data_config_init(void) {
-       data_config *ds;
--      
-+
-       ds = calloc(1, sizeof(*ds));
--      
-+
-       ds->key = buffer_init();
-       ds->op = buffer_init();
-       ds->comp_key = buffer_init();
-       ds->value = array_init();
-       ds->childs = array_init();
-       ds->childs->is_weakref = 1;
--      
-+
-       ds->copy = data_config_copy;
-       ds->free = data_config_free;
-       ds->reset = data_config_reset;
-       ds->insert_dup = data_config_insert_dup;
-       ds->print = data_config_print;
-       ds->type = TYPE_CONFIG;
--      
-+
-       return ds;
- }
---- ../lighttpd-1.4.11/src/data_count.c        2005-08-23 17:36:12.000000000 +0300
-+++ lighttpd-1.5.0/src/data_count.c    2006-07-16 00:26:03.000000000 +0300
-@@ -16,53 +16,53 @@
- static void data_count_free(data_unset *d) {
-       data_count *ds = (data_count *)d;
--      
-+
-       buffer_free(ds->key);
--      
-+
-       free(d);
- }
- static void data_count_reset(data_unset *d) {
-       data_count *ds = (data_count *)d;
--      
-+
-       buffer_reset(ds->key);
--      
-+
-       ds->count = 0;
- }
- static int data_count_insert_dup(data_unset *dst, data_unset *src) {
-       data_count *ds_dst = (data_count *)dst;
-       data_count *ds_src = (data_count *)src;
--      
-+
-       ds_dst->count += ds_src->count;
--      
-+
-       src->free(src);
--      
-+
-       return 0;
- }
- static void data_count_print(const data_unset *d, int depth) {
-       data_count *ds = (data_count *)d;
-       UNUSED(depth);
--      
-+
-       fprintf(stderr, "count(%d)", ds->count);
- }
- data_count *data_count_init(void) {
-       data_count *ds;
--      
-+
-       ds = calloc(1, sizeof(*ds));
--      
-+
-       ds->key = buffer_init();
-       ds->count = 1;
--      
-+
-       ds->copy = data_count_copy;
-       ds->free = data_count_free;
-       ds->reset = data_count_reset;
-       ds->insert_dup = data_count_insert_dup;
-       ds->print = data_count_print;
-       ds->type = TYPE_COUNT;
--      
-+
-       return ds;
- }
---- ../lighttpd-1.4.11/src/data_fastcgi.c      2005-08-23 17:36:12.000000000 +0300
-+++ lighttpd-1.5.0/src/data_fastcgi.c  2006-07-16 00:26:04.000000000 +0300
-@@ -17,53 +17,53 @@
- static void data_fastcgi_free(data_unset *d) {
-       data_fastcgi *ds = (data_fastcgi *)d;
--      
-+
-       buffer_free(ds->key);
-       buffer_free(ds->host);
--      
-+
-       free(d);
- }
- static void data_fastcgi_reset(data_unset *d) {
-       data_fastcgi *ds = (data_fastcgi *)d;
--      
-+
-       buffer_reset(ds->key);
-       buffer_reset(ds->host);
--      
-+
- }
- static int data_fastcgi_insert_dup(data_unset *dst, data_unset *src) {
-       UNUSED(dst);
-       src->free(src);
--      
-+
-       return 0;
- }
- static void data_fastcgi_print(const data_unset *d, int depth) {
-       data_fastcgi *ds = (data_fastcgi *)d;
-       UNUSED(depth);
--      
-+
-       fprintf(stderr, "fastcgi(%s)", ds->host->ptr);
- }
- data_fastcgi *data_fastcgi_init(void) {
-       data_fastcgi *ds;
--      
-+
-       ds = calloc(1, sizeof(*ds));
--      
-+
-       ds->key = buffer_init();
-       ds->host = buffer_init();
-       ds->port = 0;
-       ds->is_disabled = 0;
--      
-+
-       ds->copy = data_fastcgi_copy;
-       ds->free = data_fastcgi_free;
-       ds->reset = data_fastcgi_reset;
-       ds->insert_dup = data_fastcgi_insert_dup;
-       ds->print = data_fastcgi_print;
-       ds->type = TYPE_FASTCGI;
--      
-+
-       return ds;
- }
---- ../lighttpd-1.4.11/src/data_integer.c      2005-08-23 17:36:12.000000000 +0300
-+++ lighttpd-1.5.0/src/data_integer.c  2006-07-16 00:26:03.000000000 +0300
-@@ -16,15 +16,15 @@
- static void data_integer_free(data_unset *d) {
-       data_integer *ds = (data_integer *)d;
--      
-+
-       buffer_free(ds->key);
--      
-+
-       free(d);
- }
- static void data_integer_reset(data_unset *d) {
-       data_integer *ds = (data_integer *)d;
--      
-+
-       /* reused integer elements */
-       buffer_reset(ds->key);
-       ds->value = 0;
-@@ -32,9 +32,9 @@
- static int data_integer_insert_dup(data_unset *dst, data_unset *src) {
-       UNUSED(dst);
--      
-+
-       src->free(src);
--      
-+
-       return 0;
- }
-@@ -48,18 +48,18 @@
- data_integer *data_integer_init(void) {
-       data_integer *ds;
--      
-+
-       ds = calloc(1, sizeof(*ds));
--      
-+
-       ds->key = buffer_init();
-       ds->value = 0;
--      
-+
-       ds->copy = data_integer_copy;
-       ds->free = data_integer_free;
-       ds->reset = data_integer_reset;
-       ds->insert_dup = data_integer_insert_dup;
-       ds->print = data_integer_print;
-       ds->type = TYPE_INTEGER;
--      
-+
-       return ds;
- }
---- ../lighttpd-1.4.11/src/data_string.c       2005-08-23 17:36:12.000000000 +0300
-+++ lighttpd-1.5.0/src/data_string.c   2006-07-16 00:26:04.000000000 +0300
-@@ -17,16 +17,16 @@
- static void data_string_free(data_unset *d) {
-       data_string *ds = (data_string *)d;
--      
-+
-       buffer_free(ds->key);
-       buffer_free(ds->value);
--      
-+
-       free(d);
- }
- static void data_string_reset(data_unset *d) {
-       data_string *ds = (data_string *)d;
--      
-+
-       /* reused array elements */
-       buffer_reset(ds->key);
-       buffer_reset(ds->value);
-@@ -35,23 +35,23 @@
- static int data_string_insert_dup(data_unset *dst, data_unset *src) {
-       data_string *ds_dst = (data_string *)dst;
-       data_string *ds_src = (data_string *)src;
--      
-+
-       if (ds_dst->value->used) {
-               buffer_append_string(ds_dst->value, ", ");
-               buffer_append_string_buffer(ds_dst->value, ds_src->value);
-       } else {
-               buffer_copy_string_buffer(ds_dst->value, ds_src->value);
-       }
--      
-+
-       src->free(src);
--      
-+
-       return 0;
- }
- static int data_response_insert_dup(data_unset *dst, data_unset *src) {
-       data_string *ds_dst = (data_string *)dst;
-       data_string *ds_src = (data_string *)src;
--      
-+
-       if (ds_dst->value->used) {
-               buffer_append_string(ds_dst->value, "\r\n");
-               buffer_append_string_buffer(ds_dst->value, ds_dst->key);
-@@ -60,9 +60,9 @@
-       } else {
-               buffer_copy_string_buffer(ds_dst->value, ds_src->value);
-       }
--      
-+
-       src->free(src);
--      
-+
-       return 0;
- }
-@@ -77,28 +77,28 @@
- data_string *data_string_init(void) {
-       data_string *ds;
--      
-+
-       ds = calloc(1, sizeof(*ds));
-       assert(ds);
--      
-+
-       ds->key = buffer_init();
-       ds->value = buffer_init();
--      
-+
-       ds->copy = data_string_copy;
-       ds->free = data_string_free;
-       ds->reset = data_string_reset;
-       ds->insert_dup = data_string_insert_dup;
-       ds->print = data_string_print;
-       ds->type = TYPE_STRING;
--      
-+
-       return ds;
- }
- data_string *data_response_init(void) {
-       data_string *ds;
--      
-+
-       ds = data_string_init();
-       ds->insert_dup = data_response_insert_dup;
--      
-+
-       return ds;
- }
---- ../lighttpd-1.4.11/src/etag.c      2005-08-11 01:26:40.000000000 +0300
-+++ lighttpd-1.5.0/src/etag.c  2006-07-18 13:03:40.000000000 +0300
-@@ -4,7 +4,7 @@
- #include "etag.h"
- int etag_is_equal(buffer *etag, const char *matches) {
--      if (0 == strcmp(etag->ptr, matches)) return 1;
-+      if (buffer_is_equal_string(etag, matches, strlen(matches))) return 1;
-       return 0;
- }
-@@ -14,19 +14,19 @@
-       buffer_append_off_t(etag, st->st_size);
-       buffer_append_string_len(etag, CONST_STR_LEN("-"));
-       buffer_append_long(etag, st->st_mtime);
--      
-+
-       return 0;
- }
- int etag_mutate(buffer *mut, buffer *etag) {
-       size_t h, i;
--      
-+
-       for (h=0, i=0; i < etag->used; ++i) h = (h<<5)^(h>>27)^(etag->ptr[i]);
--      
-+
-       buffer_reset(mut);
-       buffer_copy_string_len(mut, CONST_STR_LEN("\""));
-       buffer_append_long(mut, h);
-       buffer_append_string_len(mut, CONST_STR_LEN("\""));
--      
-+
-       return 0;
- }
---- ../lighttpd-1.4.11/src/etag.h      2005-08-11 01:26:40.000000000 +0300
-+++ lighttpd-1.5.0/src/etag.h  2006-07-16 00:26:03.000000000 +0300
-@@ -3,13 +3,12 @@
- #include <sys/types.h>
- #include <sys/stat.h>
--#include <unistd.h>
- #include "buffer.h"
- int etag_is_equal(buffer *etag, const char *matches);
- int etag_create(buffer *etag, struct stat *st);
- int etag_mutate(buffer *mut, buffer *etag);
--      
-+
- #endif
---- ../lighttpd-1.4.11/src/fastcgi.h   2005-08-11 01:26:40.000000000 +0300
-+++ lighttpd-1.5.0/src/fastcgi.h       2006-07-16 00:26:03.000000000 +0300
-@@ -1,4 +1,4 @@
--/* 
-+/*
-  * fastcgi.h --
-  *
-  *    Defines for the FastCGI protocol.
-@@ -123,7 +123,7 @@
- typedef struct {
--    unsigned char type;    
-+    unsigned char type;
-     unsigned char reserved[7];
- } FCGI_UnknownTypeBody;
---- ../lighttpd-1.4.11/src/fdevent.c   2005-11-15 10:51:05.000000000 +0200
-+++ lighttpd-1.5.0/src/fdevent.c       2006-07-18 13:03:40.000000000 +0300
-@@ -2,7 +2,6 @@
- #include "settings.h"
--#include <unistd.h>
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
-@@ -11,60 +10,116 @@
- #include "fdevent.h"
- #include "buffer.h"
-+#include "log.h"
-+
-+#include "sys-socket.h"
-+
-+fdevent_revent *fdevent_revent_init(void) {
-+      STRUCT_INIT(fdevent_revent, revent);
-+
-+      return revent;
-+}
-+
-+void fdevent_revent_free(fdevent_revent *revent) {
-+      if (!revent) return;
-+
-+      free(revent);
-+}
-+
-+fdevent_revents *fdevent_revents_init(void) {
-+      STRUCT_INIT(fdevent_revents, revents);
-+
-+      return revents;
-+}
-+
-+void fdevent_revents_reset(fdevent_revents *revents) {
-+      if (!revents) return;
-+
-+      revents->used = 0;
-+}
-+
-+void fdevent_revents_add(fdevent_revents *revents, int fd, int events) {
-+      fdevent_revent *revent;
-+
-+      if (revents->used == revents->size) {
-+              /* resize the events-array */
-+              revents->ptr = realloc(revents->ptr, (revents->size + 1) * sizeof(*(revents->ptr)));
-+              revents->ptr[revents->size++] = fdevent_revent_init();
-+      }
-+
-+      revent = revents->ptr[revents->used++];
-+      revent->fd = fd;
-+      revent->revents = events;
-+}
-+
-+void fdevent_revents_free(fdevent_revents *revents) {
-+      size_t i;
-+      
-+      if (!revents) return;
-+
-+      if (revents->size) {
-+              for (i = 0; i < revents->size; i++) {
-+                      fdevent_revent_free(revents->ptr[i]);
-+              }
-+
-+              free(revents->ptr);
-+      }
-+      free(revents);
-+}
- fdevents *fdevent_init(size_t maxfds, fdevent_handler_t type) {
-       fdevents *ev;
--      
-+
-       ev = calloc(1, sizeof(*ev));
-       ev->fdarray = calloc(maxfds, sizeof(*ev->fdarray));
-       ev->maxfds = maxfds;
--      
-+
-       switch(type) {
-       case FDEVENT_HANDLER_POLL:
-               if (0 != fdevent_poll_init(ev)) {
--                      fprintf(stderr, "%s.%d: event-handler poll failed\n", 
-+                      fprintf(stderr, "%s.%d: event-handler poll failed\n",
-                               __FILE__, __LINE__);
--                      
-+
-                       return NULL;
-               }
-               break;
-       case FDEVENT_HANDLER_SELECT:
-               if (0 != fdevent_select_init(ev)) {
--                      fprintf(stderr, "%s.%d: event-handler select failed\n", 
-+                      fprintf(stderr, "%s.%d: event-handler select failed\n",
-                               __FILE__, __LINE__);
-                       return NULL;
-               }
-               break;
-       case FDEVENT_HANDLER_LINUX_RTSIG:
-               if (0 != fdevent_linux_rtsig_init(ev)) {
--                      fprintf(stderr, "%s.%d: event-handler linux-rtsig failed, try to set server.event-handler = \"poll\" or \"select\"\n", 
-+                      fprintf(stderr, "%s.%d: event-handler linux-rtsig failed, try to set server.event-handler = \"poll\" or \"select\"\n",
-                               __FILE__, __LINE__);
-                       return NULL;
-               }
-               break;
-       case FDEVENT_HANDLER_LINUX_SYSEPOLL:
-               if (0 != fdevent_linux_sysepoll_init(ev)) {
--                      fprintf(stderr, "%s.%d: event-handler linux-sysepoll failed, try to set server.event-handler = \"poll\" or \"select\"\n", 
-+                      fprintf(stderr, "%s.%d: event-handler linux-sysepoll failed, try to set server.event-handler = \"poll\" or \"select\"\n",
-                               __FILE__, __LINE__);
-                       return NULL;
-               }
-               break;
-       case FDEVENT_HANDLER_SOLARIS_DEVPOLL:
-               if (0 != fdevent_solaris_devpoll_init(ev)) {
--                      fprintf(stderr, "%s.%d: event-handler solaris-devpoll failed, try to set server.event-handler = \"poll\" or \"select\"\n", 
-+                      fprintf(stderr, "%s.%d: event-handler solaris-devpoll failed, try to set server.event-handler = \"poll\" or \"select\"\n",
-                               __FILE__, __LINE__);
-                       return NULL;
-               }
-               break;
-       case FDEVENT_HANDLER_FREEBSD_KQUEUE:
-               if (0 != fdevent_freebsd_kqueue_init(ev)) {
--                      fprintf(stderr, "%s.%d: event-handler freebsd-kqueue failed, try to set server.event-handler = \"poll\" or \"select\"\n", 
-+                      fprintf(stderr, "%s.%d: event-handler freebsd-kqueue failed, try to set server.event-handler = \"poll\" or \"select\"\n",
-                               __FILE__, __LINE__);
-                       return NULL;
-               }
-               break;
-       default:
--              fprintf(stderr, "%s.%d: event-handler is unknown, try to set server.event-handler = \"poll\" or \"select\"\n", 
-+              fprintf(stderr, "%s.%d: event-handler is unknown, try to set server.event-handler = \"poll\" or \"select\"\n",
-                       __FILE__, __LINE__);
-               return NULL;
-       }
-@@ -75,28 +130,29 @@
- void fdevent_free(fdevents *ev) {
-       size_t i;
-       if (!ev) return;
--      
-+
-       if (ev->free) ev->free(ev);
--      
-+
-       for (i = 0; i < ev->maxfds; i++) {
-               if (ev->fdarray[i]) free(ev->fdarray[i]);
-       }
--      
-+
-       free(ev->fdarray);
-       free(ev);
- }
- int fdevent_reset(fdevents *ev) {
-       if (ev->reset) return ev->reset(ev);
--      
-+
-       return 0;
- }
- fdnode *fdnode_init() {
-       fdnode *fdn;
--      
-+
-       fdn = calloc(1, sizeof(*fdn));
-       fdn->fd = -1;
-+
-       return fdn;
- }
-@@ -104,48 +160,40 @@
-       free(fdn);
- }
--int fdevent_register(fdevents *ev, int fd, fdevent_handler handler, void *ctx) {
-+int fdevent_register(fdevents *ev, iosocket *sock, fdevent_handler handler, void *ctx) {
-       fdnode *fdn;
--      
-+
-       fdn = fdnode_init();
-       fdn->handler = handler;
--      fdn->fd      = fd;
-+      fdn->fd      = sock->fd;
-       fdn->ctx     = ctx;
--      
--      ev->fdarray[fd] = fdn;
-+
-+      ev->fdarray[sock->fd] = fdn;
-       return 0;
- }
--int fdevent_unregister(fdevents *ev, int fd) {
-+int fdevent_unregister(fdevents *ev, iosocket *sock) {
-       fdnode *fdn;
-         if (!ev) return 0;
--      fdn = ev->fdarray[fd];
--      
-+      fdn = ev->fdarray[sock->fd];
-+
-       fdnode_free(fdn);
--      
--      ev->fdarray[fd] = NULL;
--      
-+
-+      ev->fdarray[sock->fd] = NULL;
-+
-       return 0;
- }
--int fdevent_event_del(fdevents *ev, int *fde_ndx, int fd) {
--      int fde = fde_ndx ? *fde_ndx : -1;
--      
--      if (ev->event_del) fde = ev->event_del(ev, fde, fd);
--      
--      if (fde_ndx) *fde_ndx = fde;
--      
-+int fdevent_event_del(fdevents *ev, iosocket *sock) {
-+      if (ev->event_del) ev->event_del(ev, sock);
-+
-       return 0;
- }
--int fdevent_event_add(fdevents *ev, int *fde_ndx, int fd, int events) {
--      int fde = fde_ndx ? *fde_ndx : -1;
--      
--      if (ev->event_add) fde = ev->event_add(ev, fde, fd, events);
--      
--      if (fde_ndx) *fde_ndx = fde;
--      
-+int fdevent_event_add(fdevents *ev, iosocket *sock, int events) {
-+      if (ev->event_add) ev->event_add(ev, sock, events);
-+
-       return 0;
- }
-@@ -154,49 +202,41 @@
-       return ev->poll(ev, timeout_ms);
- }
--int fdevent_event_get_revent(fdevents *ev, size_t ndx) {
--      if (ev->event_get_revent == NULL) SEGFAULT();
--      
--      return ev->event_get_revent(ev, ndx);
--}
-+int fdevent_get_revents(fdevents *ev, size_t event_count, fdevent_revents *revents) {
-+      size_t i;
--int fdevent_event_get_fd(fdevents *ev, size_t ndx) {
--      if (ev->event_get_fd == NULL) SEGFAULT();
--      
--      return ev->event_get_fd(ev, ndx);
--}
-+      if (ev->get_revents == NULL) SEGFAULT();
--fdevent_handler fdevent_get_handler(fdevents *ev, int fd) {
--      if (ev->fdarray[fd] == NULL) SEGFAULT();
--      if (ev->fdarray[fd]->fd != fd) SEGFAULT();
--      
--      return ev->fdarray[fd]->handler;
--}
-+      fdevent_revents_reset(revents);
--void * fdevent_get_context(fdevents *ev, int fd) {
--      if (ev->fdarray[fd] == NULL) SEGFAULT();
--      if (ev->fdarray[fd]->fd != fd) SEGFAULT();
--      
--      return ev->fdarray[fd]->ctx;
-+      ev->get_revents(ev, event_count, revents);
-+
-+      /* patch the event handlers */
-+      for (i = 0; i < event_count; i++) {
-+              fdevent_revent *r = revents->ptr[i];
-+
-+              r->handler = ev->fdarray[r->fd]->handler;
-+              r->context = ev->fdarray[r->fd]->ctx;
-+      }
-+
-+      return 0;
- }
--int fdevent_fcntl_set(fdevents *ev, int fd) {
-+int fdevent_fcntl_set(fdevents *ev, iosocket *sock) {
-+#ifdef _WIN32
-+      int i = 1;
-+#endif
- #ifdef FD_CLOEXEC
-       /* close fd on exec (cgi) */
--      fcntl(fd, F_SETFD, FD_CLOEXEC);
-+      fcntl(sock->fd, F_SETFD, FD_CLOEXEC);
- #endif
--      if ((ev) && (ev->fcntl_set)) return ev->fcntl_set(ev, fd);
--#ifdef O_NONBLOCK     
--      return fcntl(fd, F_SETFL, O_NONBLOCK | O_RDWR);
-+      if ((ev) && (ev->fcntl_set)) return ev->fcntl_set(ev, sock->fd);
-+#ifdef O_NONBLOCK
-+      return fcntl(sock->fd, F_SETFL, O_NONBLOCK | O_RDWR);
-+#elif defined _WIN32
-+      return ioctlsocket(sock->fd, FIONBIO, &i);
- #else
-       return 0;
- #endif
- }
--
--int fdevent_event_next_fdndx(fdevents *ev, int ndx) {
--      if (ev->event_next_fdndx) return ev->event_next_fdndx(ev, ndx);
--      
--      return -1;
--}
--
---- ../lighttpd-1.4.11/src/fdevent.h   2005-09-27 11:26:33.000000000 +0300
-+++ lighttpd-1.5.0/src/fdevent.h       2006-07-18 13:03:40.000000000 +0300
-@@ -7,6 +7,9 @@
- #include "settings.h"
- #include "bitset.h"
-+#include "iosocket.h"
-+#include "array-static.h"
-+
- /* select event-system */
- #if defined(HAVE_EPOLL_CTL) && defined(HAVE_SYS_EPOLL_H)
-@@ -17,13 +20,13 @@
- # include <sys/epoll.h>
- #endif
--/* MacOS 10.3.x has poll.h under /usr/include/, all other unixes 
-+/* MacOS 10.3.x has poll.h under /usr/include/, all other unixes
-  * under /usr/include/sys/ */
- #if defined HAVE_POLL && (defined(HAVE_SYS_POLL_H) || defined(HAVE_POLL_H))
- # define USE_POLL
- # ifdef HAVE_POLL_H
- #  include <poll.h>
--# else 
-+# else
- #  include <sys/poll.h>
- # endif
- # if defined HAVE_SIGTIMEDWAIT && defined(__linux__)
-@@ -31,9 +34,11 @@
- #  include <signal.h>
- # endif
- #endif
--
-+#ifdef _WIN32
-+# define HAVE_SELECT
-+#endif
- #if defined HAVE_SELECT
--# ifdef __WIN32
-+# ifdef _WIN32
- #  include <winsock2.h>
- # endif
- # define USE_SELECT
-@@ -67,14 +72,14 @@
- #define FDEVENT_HUP    BV(4)
- #define FDEVENT_NVAL   BV(5)
--typedef enum { FD_EVENT_TYPE_UNSET = -1, 
--              FD_EVENT_TYPE_CONNECTION, 
--              FD_EVENT_TYPE_FCGI_CONNECTION, 
--              FD_EVENT_TYPE_DIRWATCH, 
--              FD_EVENT_TYPE_CGI_CONNECTION 
-+typedef enum { FD_EVENT_TYPE_UNSET = -1,
-+              FD_EVENT_TYPE_CONNECTION,
-+              FD_EVENT_TYPE_FCGI_CONNECTION,
-+              FD_EVENT_TYPE_DIRWATCH,
-+              FD_EVENT_TYPE_CGI_CONNECTION
- } fd_event_t;
--typedef enum { FDEVENT_HANDLER_UNSET, 
-+typedef enum { FDEVENT_HANDLER_UNSET,
-               FDEVENT_HANDLER_SELECT,
-               FDEVENT_HANDLER_POLL,
-               FDEVENT_HANDLER_LINUX_RTSIG,
-@@ -86,7 +91,7 @@
- /**
-  * a mapping from fd to connection structure
-- * 
-+ *
-  */
- typedef struct {
-       int fd;                  /**< the fd */
-@@ -96,43 +101,51 @@
-       int revents;
- } fd_conn;
-+ARRAY_STATIC_DEF(fd_conn_buffer, fd_conn, );
-+
-+/**
-+ * revents
-+ */
- typedef struct {
--      fd_conn *ptr;
--      
--      size_t size;
--      size_t used;
--} fd_conn_buffer;
-+      int fd;
-+      int revents;
-+
-+      fdevent_handler handler;
-+      void *context;
-+} fdevent_revent;
-+
-+ARRAY_STATIC_DEF(fdevent_revents, fdevent_revent, );
- /**
-  * array of unused fd's
-- * 
-+ *
-  */
- typedef struct _fdnode {
--      fdevent_handler handler;
--      void *ctx;
--      int fd;
--      
-+      fdevent_handler handler; /* who handles the events for this fd */
-+      void *ctx;               /* opaque pointer which is passed as 3rd parameter to the handler */
-+      int fd;                  /* fd */
-+
-       struct _fdnode *prev, *next;
- } fdnode;
- typedef struct {
-       int *ptr;
--      
-+
-       size_t used;
-       size_t size;
- } buffer_int;
- /**
-  * fd-event handler for select(), poll() and rt-signals on Linux 2.4
-- * 
-+ *
-  */
- typedef struct fdevents {
-       fdevent_handler_t type;
--      
--      fdnode **fdarray;
-+
-+      fdnode **fdarray; /* a list of fdnodes */
-       size_t maxfds;
--      
-+
- #ifdef USE_LINUX_SIGIO
-       int in_sigio;
-       int signum;
-@@ -146,21 +159,21 @@
- #endif
- #ifdef USE_POLL
-       struct pollfd *pollfds;
--      
-+
-       size_t size;
-       size_t used;
--      
-+
-       buffer_int unused;
- #endif
- #ifdef USE_SELECT
-       fd_set select_read;
-       fd_set select_write;
-       fd_set select_error;
--      
-+
-       fd_set select_set_read;
-       fd_set select_set_write;
-       fd_set select_set_error;
--      
-+
-       int select_max_fd;
- #endif
- #ifdef USE_SOLARIS_DEVPOLL
-@@ -177,16 +190,13 @@
- #endif
-       int (*reset)(struct fdevents *ev);
-       void (*free)(struct fdevents *ev);
--      
--      int (*event_add)(struct fdevents *ev, int fde_ndx, int fd, int events);
--      int (*event_del)(struct fdevents *ev, int fde_ndx, int fd);
--      int (*event_get_revent)(struct fdevents *ev, size_t ndx);
--      int (*event_get_fd)(struct fdevents *ev, size_t ndx);
--      
--      int (*event_next_fdndx)(struct fdevents *ev, int ndx);
--      
-+
-+      int (*event_add)(struct fdevents *ev, iosocket *sock, int events);
-+      int (*event_del)(struct fdevents *ev, iosocket *sock);
-+      int (*get_revents)(struct fdevents *ev, size_t event_count, fdevent_revents *revents);
-+
-       int (*poll)(struct fdevents *ev, int timeout_ms);
--      
-+
-       int (*fcntl_set)(struct fdevents *ev, int fd);
- } fdevents;
-@@ -194,22 +204,44 @@
- int fdevent_reset(fdevents *ev);
- void fdevent_free(fdevents *ev);
--int fdevent_event_add(fdevents *ev, int *fde_ndx, int fd, int events);
--int fdevent_event_del(fdevents *ev, int *fde_ndx, int fd);
--int fdevent_event_get_revent(fdevents *ev, size_t ndx);
--int fdevent_event_get_fd(fdevents *ev, size_t ndx);
--fdevent_handler fdevent_get_handler(fdevents *ev, int fd);
--void * fdevent_get_context(fdevents *ev, int fd);
-+/**
-+ * call the plugin for the number of available events
-+ */
-+int fdevent_poll(fdevents *ev, int timeout_ms);
-+/**
-+ * get all available events
-+ */
-+int fdevent_get_revents(fdevents *ev, size_t event_count, fdevent_revents *revents);
--int fdevent_event_next_fdndx(fdevents *ev, int ndx);
-+/**
-+ * add or remove a fd to the handled-pool
-+ */
-+int fdevent_register(fdevents *ev, iosocket *sock, fdevent_handler handler, void *ctx);
-+int fdevent_unregister(fdevents *ev, iosocket *sock);
--int fdevent_poll(fdevents *ev, int timeout_ms);
-+/**
-+ * add a event to a registered fd
-+ */
-+int fdevent_event_add(fdevents *ev, iosocket *sock, int events);
-+int fdevent_event_del(fdevents *ev, iosocket *sock);
-+
-+/**
-+ * set non-blocking
-+ */
-+int fdevent_fcntl_set(fdevents *ev, iosocket *sock);
-+
-+fdevent_revents *fdevent_revents_init(void);
-+void fdevent_revents_reset(fdevent_revents *revents);
-+void fdevent_revents_add(fdevent_revents *revents, int fd, int events);
-+void fdevent_revents_free(fdevent_revents *revents);
--int fdevent_register(fdevents *ev, int fd, fdevent_handler handler, void *ctx);
--int fdevent_unregister(fdevents *ev, int fd);
-+fdevent_revent *fdevent_revent_init(void);
-+void fdevent_revent_free(fdevent_revent *revent);
--int fdevent_fcntl_set(fdevents *ev, int fd);
-+/**
-+ * plugin init
-+ */
- int fdevent_select_init(fdevents *ev);
- int fdevent_poll_init(fdevents *ev);
- int fdevent_linux_rtsig_init(fdevents *ev);
---- ../lighttpd-1.4.11/src/fdevent_freebsd_kqueue.c    2005-09-01 10:46:24.000000000 +0300
-+++ lighttpd-1.5.0/src/fdevent_freebsd_kqueue.c        2006-09-07 00:57:05.000000000 +0300
-@@ -1,6 +1,5 @@
- #include <sys/types.h>
--#include <unistd.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
-@@ -17,22 +16,24 @@
- #include <sys/event.h>
- #include <sys/time.h>
-+#include "sys-files.h"
-+
- static void fdevent_freebsd_kqueue_free(fdevents *ev) {
-       close(ev->kq_fd);
-       free(ev->kq_results);
-       bitset_free(ev->kq_bevents);
- }
--static int fdevent_freebsd_kqueue_event_del(fdevents *ev, int fde_ndx, int fd) {
-+static int fdevent_freebsd_kqueue_event_del(fdevents *ev, iosocket *sock) {
-       int filter, ret;
-       struct kevent kev;
-       struct timespec ts;
--      if (fde_ndx < 0) return -1;
-+      if (sock->fde_ndx < 0) return -1;
--      filter = bitset_test_bit(ev->kq_bevents, fd) ? EVFILT_READ : EVFILT_WRITE;
-+      filter = bitset_test_bit(ev->kq_bevents, sock->fd) ? EVFILT_READ : EVFILT_WRITE;
--      EV_SET(&kev, fd, filter, EV_DELETE, 0, 0, NULL);
-+      EV_SET(&kev, sock->fd, filter, EV_DELETE, 0, 0, NULL);
-       ts.tv_sec  = 0;
-       ts.tv_nsec = 0;
-@@ -42,30 +43,29 @@
-                    NULL, 0,
-                    &ts);
-+      sock->fde_ndx = -1;
-       if (ret == -1) {
-               fprintf(stderr, "%s.%d: kqueue failed polling: %s\n",
-                       __FILE__, __LINE__, strerror(errno));
--              return -1;
-+              return 0;
-       }
--      
--      return -1;
-+
-+      return 0;
- }
--static int fdevent_freebsd_kqueue_event_add(fdevents *ev, int fde_ndx, int fd, int events) {
-+static int fdevent_freebsd_kqueue_event_add(fdevents *ev, iosocket *sock, int events) {
-       int filter, ret;
-       struct kevent kev;
-       struct timespec ts;
--      UNUSED(fde_ndx);
--
-       filter = (events & FDEVENT_IN) ? EVFILT_READ : EVFILT_WRITE;
--      EV_SET(&kev, fd, filter, EV_ADD|EV_CLEAR, 0, 0, NULL);
-+      EV_SET(&kev, sock->fd, filter, EV_ADD|EV_CLEAR, 0, 0, NULL);
-       ts.tv_sec  = 0;
-       ts.tv_nsec = 0;
--      
-+
-       ret = kevent(ev->kq_fd,
-                    &kev, 1,
-                    NULL, 0,
-@@ -77,14 +77,14 @@
-               return -1;
-       }
--      
-+
-       if (filter == EVFILT_READ) {
--              bitset_set_bit(ev->kq_bevents, fd);
-+              bitset_set_bit(ev->kq_bevents, sock->fd);
-       } else {
--              bitset_clear_bit(ev->kq_bevents, fd);
-+              bitset_clear_bit(ev->kq_bevents, sock->fd);
-       }
--      return fd;
-+      return 0;
- }
- static int fdevent_freebsd_kqueue_poll(fdevents *ev, int timeout_ms) {
-@@ -114,48 +114,44 @@
-       return ret;
- }
--static int fdevent_freebsd_kqueue_event_get_revent(fdevents *ev, size_t ndx) {
--      int events = 0, e;
-+static int fdevent_freebsd_kqueue_get_revents(fdevents *ev, size_t event_count, fdevent_revents *revents) {
-+      size_t ndx;
--      e = ev->kq_results[ndx].filter;
--
--      if (e == EVFILT_READ) {
--              events |= FDEVENT_IN;
--      } else if (e == EVFILT_WRITE) {
--              events |= FDEVENT_OUT;
--      }
--      
--      e = ev->kq_results[ndx].flags;
-+      for (ndx = 0; ndx < ev->used; ndx++) {
-+              int events = 0, e;
--      if (e & EV_EOF) {
--              events |= FDEVENT_HUP;
--      }
-+              e = ev->kq_results[ndx].filter;
--      if (e & EV_ERROR) {
--              events |= FDEVENT_ERR;
--      }
-+              if (e == EVFILT_READ) {
-+                      events |= FDEVENT_IN;
-+              } else if (e == EVFILT_WRITE) {
-+                      events |= FDEVENT_OUT;
-+              }
--      return events;
--}
-+              e = ev->kq_results[ndx].flags;
--static int fdevent_freebsd_kqueue_event_get_fd(fdevents *ev, size_t ndx) {
--      return ev->kq_results[ndx].ident;
--}
-+              if (e & EV_EOF) {
-+                      events |= FDEVENT_HUP;
-+              }
-+      
-+              if (e & EV_ERROR) {
-+                      events |= FDEVENT_ERR;
-+              }
--static int fdevent_freebsd_kqueue_event_next_fdndx(fdevents *ev, int ndx) {
--      UNUSED(ev);
-+              fdevent_revents_add(revents, ev->kq_results[ndx].ident, events);
-+      }
--      return (ndx < 0) ? 0 : ndx + 1;
-+      return 0;
- }
- static int fdevent_freebsd_kqueue_reset(fdevents *ev) {
-       if (-1 == (ev->kq_fd = kqueue())) {
-               fprintf(stderr, "%s.%d: kqueue failed (%s), try to set server.event-handler = \"poll\" or \"select\"\n",
-                       __FILE__, __LINE__, strerror(errno));
--              
-+
-               return -1;
-       }
--      
-+
-       return 0;
- }
-@@ -172,9 +168,7 @@
-       SET(event_del);
-       SET(event_add);
--      SET(event_next_fdndx);
--      SET(event_get_fd);
--      SET(event_get_revent);
-+      SET(get_revents);
-       ev->kq_fd = -1;
-@@ -186,7 +180,7 @@
-       if (-1 == (ev->kq_fd = kqueue())) {
-               fprintf(stderr, "%s.%d: kqueue failed (%s), try to set server.event-handler = \"poll\" or \"select\"\n",
-                       __FILE__, __LINE__, strerror(errno));
--              
-+
-               return -1;
-       }
---- ../lighttpd-1.4.11/src/fdevent_linux_rtsig.c       2005-11-21 19:56:11.000000000 +0200
-+++ lighttpd-1.5.0/src/fdevent_linux_rtsig.c   2006-07-18 13:03:40.000000000 +0300
-@@ -1,6 +1,5 @@
- #include <sys/types.h>
--#include <unistd.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
-@@ -14,6 +13,8 @@
- #include "fdevent.h"
- #include "settings.h"
- #include "buffer.h"
-+#include "sys-process.h"
-+#include "log.h"
- #ifdef USE_LINUX_SIGIO
- static void fdevent_linux_rtsig_free(fdevents *ev) {
-@@ -24,21 +25,21 @@
- }
--static int fdevent_linux_rtsig_event_del(fdevents *ev, int fde_ndx, int fd) {
--      if (fde_ndx < 0) return -1;
--      
--      if ((size_t)fde_ndx >= ev->used) {
--              fprintf(stderr, "%s.%d: del! out of range %d %zu\n", __FILE__, __LINE__, fde_ndx, ev->used);
-+static int fdevent_linux_rtsig_event_del(fdevents *ev, iosocket *sock) {
-+      if (sock->fde_ndx < 0) return -1;
-+
-+      if ((size_t)sock->fde_ndx >= ev->used) {
-+              TRACE("del! out of range %d %zu\n", sock->fde_ndx, ev->used);
-               SEGFAULT();
-       }
--      
--      if (ev->pollfds[fde_ndx].fd == fd) {
--              size_t k = fde_ndx;
--              
-+
-+      if (ev->pollfds[sock->fde_ndx].fd == sock->fd) {
-+              size_t k = sock->fde_ndx;
-+
-               ev->pollfds[k].fd = -1;
--              bitset_clear_bit(ev->sigbset, fd);
--              
-+              bitset_clear_bit(ev->sigbset, sock->fd);
-+
-               if (ev->unused.size == 0) {
-                       ev->unused.size = 16;
-                       ev->unused.ptr = malloc(sizeof(*(ev->unused.ptr)) * ev->unused.size);
-@@ -46,53 +47,54 @@
-                       ev->unused.size += 16;
-                       ev->unused.ptr = realloc(ev->unused.ptr, sizeof(*(ev->unused.ptr)) * ev->unused.size);
-               }
--              
-+
-               ev->unused.ptr[ev->unused.used++] = k;
-       } else {
--              fprintf(stderr, "%s.%d: del! %d %d\n", __FILE__, __LINE__, ev->pollfds[fde_ndx].fd, fd);
--              
-+              fprintf(stderr, "%s.%d: del! %d %d\n", __FILE__, __LINE__, ev->pollfds[sock->fde_ndx].fd, sock->fd);
-+
-               SEGFAULT();
-       }
--      
--      return -1;
-+      sock->fde_ndx = -1;
-+
-+      return 0;
- }
- #if 0
- static int fdevent_linux_rtsig_event_compress(fdevents *ev) {
-       size_t j;
--      
-+
-       if (ev->used == 0) return 0;
-       if (ev->unused.used != 0) return 0;
--      
-+
-       for (j = ev->used - 1; j + 1 > 0; j--) {
-               if (ev->pollfds[j].fd == -1) ev->used--;
-       }
--      
--      
-+
-+
-       return 0;
- }
- #endif
--static int fdevent_linux_rtsig_event_add(fdevents *ev, int fde_ndx, int fd, int events) {
-+static int fdevent_linux_rtsig_event_add(fdevents *ev, iosocket *sock, int events) {
-       /* known index */
--      if (fde_ndx != -1) {
--              if (ev->pollfds[fde_ndx].fd == fd) {
--                      ev->pollfds[fde_ndx].events = events;
--                      
--                      return fde_ndx;
-+      if (sock->fde_ndx != -1) {
-+              if (ev->pollfds[sock->fde_ndx].fd == sock->fd) {
-+                      ev->pollfds[sock->fde_ndx].events = events;
-+
-+                      return sock->fde_ndx;
-               }
--              fprintf(stderr, "%s.%d: add: (%d, %d)\n", __FILE__, __LINE__, fde_ndx, ev->pollfds[fde_ndx].fd);
-+              fprintf(stderr, "%s.%d: add: (%d, %d)\n", __FILE__, __LINE__, sock->fde_ndx, ev->pollfds[sock->fde_ndx].fd);
-               SEGFAULT();
-       }
--      
-+
-       if (ev->unused.used > 0) {
-               int k = ev->unused.ptr[--ev->unused.used];
--              
--              ev->pollfds[k].fd = fd;
-+
-+              ev->pollfds[k].fd = sock->fd;
-               ev->pollfds[k].events = events;
--              bitset_set_bit(ev->sigbset, fd);
--              
-+              bitset_set_bit(ev->sigbset, sock->fd);
-+
-               return k;
-       } else {
-               if (ev->size == 0) {
-@@ -102,12 +104,12 @@
-                       ev->size += 16;
-                       ev->pollfds = realloc(ev->pollfds, sizeof(*ev->pollfds) * ev->size);
-               }
--              
--              ev->pollfds[ev->used].fd = fd;
-+
-+              ev->pollfds[ev->used].fd = sock->fd;
-               ev->pollfds[ev->used].events = events;
--              bitset_set_bit(ev->sigbset, fd);
--      
-+              bitset_set_bit(ev->sigbset, sock->fd);
-+
-               return ev->used++;
-       }
- }
-@@ -115,20 +117,20 @@
- static int fdevent_linux_rtsig_poll(fdevents *ev, int timeout_ms) {
-       struct timespec ts;
-       int r;
--      
-+
- #if 0
-       fdevent_linux_rtsig_event_compress(ev);
- #endif
--      
-+
-       ev->in_sigio = 1;
--              
-+
-       ts.tv_sec =  timeout_ms / 1000;
-       ts.tv_nsec = (timeout_ms % 1000) * 1000000;
-       r = sigtimedwait(&(ev->sigset), &(ev->siginfo), &(ts));
--              
--      if (r == -1) { 
-+
-+      if (r == -1) {
-               if (errno == EAGAIN) return 0;
--              return r; 
-+              return r;
-       } else if (r == SIGIO) {
-               struct sigaction act;
-@@ -140,7 +142,7 @@
-               /* re-enable the signal queue */
-               act.sa_handler = SIG_DFL;
-               sigaction(ev->signum, &act, NULL);
--              
-+
-               ev->in_sigio = 0;
-               r = poll(ev->pollfds, ev->used, timeout_ms);
-@@ -156,97 +158,67 @@
-       }
- }
--static int fdevent_linux_rtsig_event_get_revent(fdevents *ev, size_t ndx) {
-+static int fdevent_linux_rtsig_get_revents(fdevents *ev, size_t event_count, fdevent_revents *revents) {
-       if (ev->in_sigio == 1) {
--#  if 0
--              if (ev->siginfo.si_band == POLLERR) {
--                      fprintf(stderr, "event: %d %02lx %02x %s\n", ev->siginfo.si_fd, ev->siginfo.si_band, errno, strerror(errno));
--              }
--#  endif              
--              if (ndx != 0) {
--                      fprintf(stderr, "+\n");
--                      return 0;
--              }
--              
--              return ev->siginfo.si_band & 0x3f;
-+              /* only one event */
-+
-+              fdevent_revents_add(revents, ev->siginfo.si_fd, ev->siginfo.si_band & 0x3f);
-       } else {
--              if (ndx >= ev->used) {
--                      fprintf(stderr, "%s.%d: event: %zu %zu\n", __FILE__, __LINE__, ndx, ev->used);
--                      return 0;
-+              size_t ndx;
-+
-+              for (ndx = 0; ndx < ev->used; ndx++) {
-+                      if (ev->pollfds[ndx].revents) {
-+                              fdevent_revents_add(revents, ev->pollfds[ndx].fd, ev->pollfds[ndx].revents);
-+                      }
-               }
--              return ev->pollfds[ndx].revents;
-       }
--}
--static int fdevent_linux_rtsig_event_get_fd(fdevents *ev, size_t ndx) {
--      if (ev->in_sigio == 1) {
--              return ev->siginfo.si_fd;
--      } else {
--              return ev->pollfds[ndx].fd;
--      }
-+      return 0;
- }
- static int fdevent_linux_rtsig_fcntl_set(fdevents *ev, int fd) {
-       static pid_t pid = 0;
--      
-+
-       if (pid == 0) pid = getpid();
--      
-+
-       if (-1 == fcntl(fd, F_SETSIG, ev->signum)) return -1;
--      
-+
-       if (-1 == fcntl(fd, F_SETOWN, (int) pid)) return -1;
--      
-+
-       return fcntl(fd, F_SETFL, O_ASYNC | O_NONBLOCK | O_RDWR);
- }
--static int fdevent_linux_rtsig_event_next_fdndx(fdevents *ev, int ndx) {
--      if (ev->in_sigio == 1) {
--              if (ndx < 0) return 0;
--              return -1;
--      } else {
--              size_t i;
--              
--              i = (ndx < 0) ? 0 : ndx + 1;
--              for (; i < ev->used; i++) {
--                      if (ev->pollfds[i].revents) break;
--              }
--              
--              return i;
--      }
--}
--
- int fdevent_linux_rtsig_init(fdevents *ev) {
-       ev->type = FDEVENT_HANDLER_LINUX_RTSIG;
- #define SET(x) \
-       ev->x = fdevent_linux_rtsig_##x;
--      
-+
-       SET(free);
-       SET(poll);
--      
-+
-       SET(event_del);
-       SET(event_add);
--      
--      SET(event_next_fdndx);
-+
-       SET(fcntl_set);
--      SET(event_get_fd);
--      SET(event_get_revent);
--      
-+      SET(get_revents);
-+
-       ev->signum = SIGRTMIN + 1;
--      
-+
-       sigemptyset(&(ev->sigset));
-       sigaddset(&(ev->sigset), ev->signum);
-       sigaddset(&(ev->sigset), SIGIO);
-       if (-1 == sigprocmask(SIG_BLOCK, &(ev->sigset), NULL)) {
-               fprintf(stderr, "%s.%d: sigprocmask failed (%s), try to set server.event-handler = \"poll\" or \"select\"\n",
-                       __FILE__, __LINE__, strerror(errno));
--              
-+
-               return -1;
-       }
--      
-+
-       ev->in_sigio = 1;
-       ev->sigbset = bitset_init(ev->maxfds);
--      
-+
-       return 0;
- }
- #else
---- ../lighttpd-1.4.11/src/fdevent_linux_sysepoll.c    2005-09-30 20:29:27.000000000 +0300
-+++ lighttpd-1.5.0/src/fdevent_linux_sysepoll.c        2006-07-18 13:03:40.000000000 +0300
-@@ -1,6 +1,5 @@
- #include <sys/types.h>
--#include <unistd.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
-@@ -11,6 +10,9 @@
- #include "fdevent.h"
- #include "settings.h"
- #include "buffer.h"
-+#include "log.h"
-+
-+#include "sys-files.h"
- #ifdef USE_LINUX_EPOLL
- static void fdevent_linux_sysepoll_free(fdevents *ev) {
-@@ -18,38 +20,40 @@
-       free(ev->epoll_events);
- }
--static int fdevent_linux_sysepoll_event_del(fdevents *ev, int fde_ndx, int fd) {
-+static int fdevent_linux_sysepoll_event_del(fdevents *ev, iosocket *sock) {
-       struct epoll_event ep;
--      
--      if (fde_ndx < 0) return -1;
--      
-+
-+      if (sock->fde_ndx < 0) return -1;
-+
-       memset(&ep, 0, sizeof(ep));
--      
--      ep.data.fd = fd;
-+
-+      ep.data.fd = sock->fd;
-       ep.data.ptr = NULL;
--      
--      if (0 != epoll_ctl(ev->epoll_fd, EPOLL_CTL_DEL, fd, &ep)) {
-+
-+      if (0 != epoll_ctl(ev->epoll_fd, EPOLL_CTL_DEL, sock->fd, &ep)) {
-               fprintf(stderr, "%s.%d: epoll_ctl failed: %s, dying\n", __FILE__, __LINE__, strerror(errno));
--              
-+
-               SEGFAULT();
--              
-+
-               return 0;
-       }
--      
--      
--      return -1;
-+
-+      sock->fde_ndx = -1;
-+
-+      return 0;
- }
--static int fdevent_linux_sysepoll_event_add(fdevents *ev, int fde_ndx, int fd, int events) {
-+static int fdevent_linux_sysepoll_event_add(fdevents *ev, iosocket *sock, int events) {
-       struct epoll_event ep;
-       int add = 0;
--      
--      if (fde_ndx == -1) add = 1;
--      
-+
-+      /* a new fd */
-+      if (sock->fde_ndx == -1) add = 1;
-+
-       memset(&ep, 0, sizeof(ep));
--      
-+
-       ep.events = 0;
--      
-+
-       if (events & FDEVENT_IN)  ep.events |= EPOLLIN;
-       if (events & FDEVENT_OUT) ep.events |= EPOLLOUT;
-@@ -60,73 +64,61 @@
-        * sent.
-        *
-        */
--      
-+
-       ep.events |= EPOLLERR | EPOLLHUP /* | EPOLLET */;
--      
-+
-       ep.data.ptr = NULL;
--      ep.data.fd = fd;
--      
--      if (0 != epoll_ctl(ev->epoll_fd, add ? EPOLL_CTL_ADD : EPOLL_CTL_MOD, fd, &ep)) {
-+      ep.data.fd = sock->fd;
-+
-+      if (0 != epoll_ctl(ev->epoll_fd, add ? EPOLL_CTL_ADD : EPOLL_CTL_MOD, sock->fd, &ep)) {
-               fprintf(stderr, "%s.%d: epoll_ctl failed: %s, dying\n", __FILE__, __LINE__, strerror(errno));
--              
-+
-               SEGFAULT();
--              
-+
-               return 0;
-       }
--      
--      return fd;
-+
-+      sock->fde_ndx = sock->fd;
-+
-+      return 0;
- }
- static int fdevent_linux_sysepoll_poll(fdevents *ev, int timeout_ms) {
-       return epoll_wait(ev->epoll_fd, ev->epoll_events, ev->maxfds, timeout_ms);
- }
--static int fdevent_linux_sysepoll_event_get_revent(fdevents *ev, size_t ndx) {
--      int events = 0, e;
--      
--      e = ev->epoll_events[ndx].events;
--      if (e & EPOLLIN) events |= FDEVENT_IN;
--      if (e & EPOLLOUT) events |= FDEVENT_OUT;
--      if (e & EPOLLERR) events |= FDEVENT_ERR;
--      if (e & EPOLLHUP) events |= FDEVENT_HUP;
--      if (e & EPOLLPRI) events |= FDEVENT_PRI;
--      
--      return e;
--}
--
--static int fdevent_linux_sysepoll_event_get_fd(fdevents *ev, size_t ndx) {
--# if 0
--      fprintf(stderr, "%s.%d: %d, %d\n", __FILE__, __LINE__, ndx, ev->epoll_events[ndx].data.fd);
--# endif
--      
--      return ev->epoll_events[ndx].data.fd;
--}
--
--static int fdevent_linux_sysepoll_event_next_fdndx(fdevents *ev, int ndx) {
--      size_t i;
--      
--      UNUSED(ev);
-+static int fdevent_linux_sysepoll_get_revents(fdevents *ev, size_t event_count, fdevent_revents *revents) {
-+      size_t ndx;
-+
-+      for (ndx = 0; ndx < event_count; ndx++) {
-+              int events = 0, e;
-+
-+              e = ev->epoll_events[ndx].events;
-+              if (e & EPOLLIN) events |= FDEVENT_IN;
-+              if (e & EPOLLOUT) events |= FDEVENT_OUT;
-+              if (e & EPOLLERR) events |= FDEVENT_ERR;
-+              if (e & EPOLLHUP) events |= FDEVENT_HUP;
-+              if (e & EPOLLPRI) events |= FDEVENT_PRI;
--      i = (ndx < 0) ? 0 : ndx + 1;
--      
--      return i;
-+              fdevent_revents_add(revents, ev->epoll_events[ndx].data.fd, e);
-+      }
-+
-+      return 0;
- }
- int fdevent_linux_sysepoll_init(fdevents *ev) {
-       ev->type = FDEVENT_HANDLER_LINUX_SYSEPOLL;
- #define SET(x) \
-       ev->x = fdevent_linux_sysepoll_##x;
--      
-+
-       SET(free);
-       SET(poll);
--      
-+
-       SET(event_del);
-       SET(event_add);
--      
--      SET(event_next_fdndx);
--      SET(event_get_fd);
--      SET(event_get_revent);
--      
-+
-+      SET(get_revents);
-+
-       if (-1 == (ev->epoll_fd = epoll_create(ev->maxfds))) {
-               fprintf(stderr, "%s.%d: epoll_create failed (%s), try to set server.event-handler = \"poll\" or \"select\"\n",
-                       __FILE__, __LINE__, strerror(errno));
-@@ -154,7 +146,7 @@
-       fprintf(stderr, "%s.%d: linux-sysepoll not supported, try to set server.event-handler = \"poll\" or \"select\"\n",
-               __FILE__, __LINE__);
--      
-+
-       return -1;
- }
- #endif
---- ../lighttpd-1.4.11/src/fdevent_poll.c      2005-11-18 13:59:16.000000000 +0200
-+++ lighttpd-1.5.0/src/fdevent_poll.c  2006-09-07 00:57:05.000000000 +0300
-@@ -1,6 +1,5 @@
- #include <sys/types.h>
--#include <unistd.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
-@@ -11,6 +10,7 @@
- #include "fdevent.h"
- #include "settings.h"
- #include "buffer.h"
-+#include "log.h"
- #ifdef USE_POLL
- static void fdevent_poll_free(fdevents *ev) {
-@@ -18,21 +18,21 @@
-       if (ev->unused.ptr) free(ev->unused.ptr);
- }
--static int fdevent_poll_event_del(fdevents *ev, int fde_ndx, int fd) {
--      if (fde_ndx < 0) return -1;
--      
--      if ((size_t)fde_ndx >= ev->used) {
--              fprintf(stderr, "%s.%d: del! out of range %d %zd\n", __FILE__, __LINE__, fde_ndx, ev->used);
-+static int fdevent_poll_event_del(fdevents *ev, iosocket *sock) {
-+      if (sock->fde_ndx < 0) return -1;
-+
-+      if ((size_t)sock->fde_ndx >= ev->used) {
-+              fprintf(stderr, "%s.%d: del! out of range %d %zd\n", __FILE__, __LINE__, sock->fde_ndx, ev->used);
-               SEGFAULT();
-       }
--      
--      if (ev->pollfds[fde_ndx].fd == fd) {
--              size_t k = fde_ndx;
--              
-+
-+      if (ev->pollfds[sock->fde_ndx].fd == sock->fd) {
-+              size_t k = sock->fde_ndx;
-+
-               ev->pollfds[k].fd = -1;
-               /* ev->pollfds[k].events = 0; */
-               /* ev->pollfds[k].revents = 0; */
--              
-+
-               if (ev->unused.size == 0) {
-                       ev->unused.size = 16;
-                       ev->unused.ptr = malloc(sizeof(*(ev->unused.ptr)) * ev->unused.size);
-@@ -40,48 +40,52 @@
-                       ev->unused.size += 16;
-                       ev->unused.ptr = realloc(ev->unused.ptr, sizeof(*(ev->unused.ptr)) * ev->unused.size);
-               }
--              
-+
-               ev->unused.ptr[ev->unused.used++] = k;
-       } else {
-+              TRACE("(fdevent-poll-del) sock->fde_ndx: %d, sock->fd: %d -> stored fd: %d", sock->fde_ndx, sock->fd, ev->pollfds[sock->fde_ndx].fd);
-               SEGFAULT();
-       }
--      
--      return -1;
-+
-+      sock->fde_ndx = -1;
-+
-+      return 0;
- }
- #if 0
- static int fdevent_poll_event_compress(fdevents *ev) {
-       size_t j;
--      
-+
-       if (ev->used == 0) return 0;
-       if (ev->unused.used != 0) return 0;
--      
-+
-       for (j = ev->used - 1; j + 1 > 0 && ev->pollfds[j].fd == -1; j--) ev->used--;
--      
-+
-       return 0;
- }
- #endif
--static int fdevent_poll_event_add(fdevents *ev, int fde_ndx, int fd, int events) {
--      /* known index */
--      
--      if (fde_ndx != -1) {
--              if (ev->pollfds[fde_ndx].fd == fd) {
--                      ev->pollfds[fde_ndx].events = events;
--                      
--                      return fde_ndx;
-+static int fdevent_poll_event_add(fdevents *ev, iosocket *sock, int events) {
-+      if (sock->fde_ndx != -1) {
-+              /* this fd was already added, just change the requested events */
-+
-+              if (ev->pollfds[sock->fde_ndx].fd == sock->fd) {
-+                      ev->pollfds[sock->fde_ndx].events = events;
-+
-+                      return sock->fde_ndx;
-               }
--              fprintf(stderr, "%s.%d: add: (%d, %d)\n", __FILE__, __LINE__, fde_ndx, ev->pollfds[fde_ndx].fd);
-+              fprintf(stderr, "%s.%d: add: (%d, %d)\n", __FILE__, __LINE__, sock->fde_ndx, ev->pollfds[sock->fde_ndx].fd);
-               SEGFAULT();
-       }
--      
-+
-       if (ev->unused.used > 0) {
-               int k = ev->unused.ptr[--ev->unused.used];
--              
--              ev->pollfds[k].fd = fd;
-+
-+              ev->pollfds[k].fd = sock->fd;
-               ev->pollfds[k].events = events;
--              
--              return k;
-+
-+              sock->fde_ndx = k;
-+
-       } else {
-               if (ev->size == 0) {
-                       ev->size = 16;
-@@ -90,12 +94,13 @@
-                       ev->size += 16;
-                       ev->pollfds = realloc(ev->pollfds, sizeof(*ev->pollfds) * ev->size);
-               }
--              
--              ev->pollfds[ev->used].fd = fd;
-+
-+              ev->pollfds[ev->used].fd = sock->fd;
-               ev->pollfds[ev->used].events = events;
--              
--              return ev->used++;
-+
-+              sock->fde_ndx = ev->used++;
-       }
-+      return 0;
- }
- static int fdevent_poll_poll(fdevents *ev, int timeout_ms) {
-@@ -105,71 +110,38 @@
-       return poll(ev->pollfds, ev->used, timeout_ms);
- }
--static int fdevent_poll_event_get_revent(fdevents *ev, size_t ndx) {
--      int r, poll_r;
--      if (ndx >= ev->used) {
--              fprintf(stderr, "%s.%d: dying because: event: %zd >= %zd\n", __FILE__, __LINE__, ndx, ev->used);
--              
--              SEGFAULT();
--              
--              return 0;
--      }
--      
--      if (ev->pollfds[ndx].revents & POLLNVAL) {
--              /* should never happen */
--              SEGFAULT();
--      }
-+static int fdevent_poll_get_revents(fdevents *ev, size_t event_count, fdevent_revents *revents) {
-+      size_t ndx;
--      r = 0;
--      poll_r = ev->pollfds[ndx].revents;
-+      for (ndx = 0; ndx < ev->used; ndx++) {
-+              if (ev->pollfds[ndx].revents) {
-+                      if (ev->pollfds[ndx].revents & POLLNVAL) {
-+                              /* should never happen */
-+                              SEGFAULT();
-+                      }
--      /* map POLL* to FDEVEN_* */
--
--      if (poll_r & POLLIN) r |= FDEVENT_IN;
--      if (poll_r & POLLOUT) r |= FDEVENT_OUT;
--      if (poll_r & POLLERR) r |= FDEVENT_ERR;
--      if (poll_r & POLLHUP) r |= FDEVENT_HUP;
--      if (poll_r & POLLNVAL) r |= FDEVENT_NVAL;
--      if (poll_r & POLLPRI) r |= FDEVENT_PRI;
--      
--      return ev->pollfds[ndx].revents;
--}
--
--static int fdevent_poll_event_get_fd(fdevents *ev, size_t ndx) {
--      return ev->pollfds[ndx].fd;
--}
--
--static int fdevent_poll_event_next_fdndx(fdevents *ev, int ndx) {
--      size_t i;
--      
--      i = (ndx < 0) ? 0 : ndx + 1;
--      for (; i < ev->used; i++) {
--              if (ev->pollfds[i].revents) break;
-+                      fdevent_revents_add(revents, ev->pollfds[ndx].fd, ev->pollfds[ndx].revents);
-+              }
-       }
--      
--      return i;
-+
-+      return 0;
- }
- int fdevent_poll_init(fdevents *ev) {
-       ev->type = FDEVENT_HANDLER_POLL;
- #define SET(x) \
-       ev->x = fdevent_poll_##x;
--      
-+
-       SET(free);
-       SET(poll);
--      
-+
-       SET(event_del);
-       SET(event_add);
--      
--      SET(event_next_fdndx);
--      SET(event_get_fd);
--      SET(event_get_revent);
--      
--      return 0;
--}
--
-+      SET(get_revents);
-+      return 0;
-+}
- #else
- int fdevent_poll_init(fdevents *ev) {
---- ../lighttpd-1.4.11/src/fdevent_select.c    2005-08-31 11:12:46.000000000 +0300
-+++ lighttpd-1.5.0/src/fdevent_select.c        2006-07-18 13:03:40.000000000 +0300
-@@ -1,18 +1,19 @@
--#include <sys/time.h>
- #include <sys/types.h>
--#include <unistd.h>
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
- #include <signal.h>
- #include <fcntl.h>
- #include <assert.h>
-+#include <stdio.h>
- #include "fdevent.h"
- #include "settings.h"
- #include "buffer.h"
-+#include "sys-socket.h"
-+
- #ifdef USE_SELECT
- static int fdevent_select_reset(fdevents *ev) {
-@@ -24,101 +25,98 @@
-       return 0;
- }
--static int fdevent_select_event_del(fdevents *ev, int fde_ndx, int fd) {
--      if (fde_ndx < 0) return -1;
-+static int fdevent_select_event_del(fdevents *ev, iosocket *sock) {
-+      if (sock->fde_ndx < 0) return -1;
--      FD_CLR(fd, &(ev->select_set_read));
--      FD_CLR(fd, &(ev->select_set_write));
--      FD_CLR(fd, &(ev->select_set_error));
-+      FD_CLR(sock->fd, &(ev->select_set_read));
-+      FD_CLR(sock->fd, &(ev->select_set_write));
-+      FD_CLR(sock->fd, &(ev->select_set_error));
--      return -1;
--}
-+      /* mark the fdevent as deleted */
-+      sock->fde_ndx = -1;
--static int fdevent_select_event_add(fdevents *ev, int fde_ndx, int fd, int events) {
--      UNUSED(fde_ndx);
-+      return 0;
-+}
-+static int fdevent_select_event_add(fdevents *ev, iosocket *sock, int events) {
-       /* we should be protected by max-fds, but you never know */
--      assert(fd < FD_SETSIZE);
-+#ifndef _WIN32
-+      assert(sock->fd < FD_SETSIZE);
-+#endif
-       if (events & FDEVENT_IN) {
--              FD_SET(fd, &(ev->select_set_read));
--              FD_CLR(fd, &(ev->select_set_write));
-+              FD_SET(sock->fd, &(ev->select_set_read));
-+              FD_CLR(sock->fd, &(ev->select_set_write));
-       }
-       if (events & FDEVENT_OUT) {
--              FD_CLR(fd, &(ev->select_set_read));
--              FD_SET(fd, &(ev->select_set_write));
-+              FD_CLR(sock->fd, &(ev->select_set_read));
-+              FD_SET(sock->fd, &(ev->select_set_write));
-       }
--      FD_SET(fd, &(ev->select_set_error));
--      
--      if (fd > ev->select_max_fd) ev->select_max_fd = fd;
--      
--      return fd;
-+      FD_SET(sock->fd, &(ev->select_set_error));
-+
-+      /* we need this for the poll */
-+      if (sock->fd > ev->select_max_fd) ev->select_max_fd = sock->fd;
-+
-+      /* mark fd as added */
-+      sock->fde_ndx = sock->fd;
-+
-+      return 0;
- }
- static int fdevent_select_poll(fdevents *ev, int timeout_ms) {
-       struct timeval tv;
--      
-+
-       tv.tv_sec =  timeout_ms / 1000;
-       tv.tv_usec = (timeout_ms % 1000) * 1000;
--      
-+
-       ev->select_read = ev->select_set_read;
-       ev->select_write = ev->select_set_write;
-       ev->select_error = ev->select_set_error;
--      
-+
-       return select(ev->select_max_fd + 1, &(ev->select_read), &(ev->select_write), &(ev->select_error), &tv);
- }
--static int fdevent_select_event_get_revent(fdevents *ev, size_t ndx) {
--      int revents = 0;
--      
--      if (FD_ISSET(ndx, &(ev->select_read))) {
--              revents |= FDEVENT_IN;
-+/**
-+ * scan the fdset for events 
-+ */
-+static int fdevent_select_get_revents(fdevents *ev, size_t event_count, fdevent_revents *revents) {
-+
-+      int ndx = 0;
-+
-+      for (ndx = 0; ndx < ev->select_max_fd; ndx++) {
-+              int events = 0;
-+
-+              if (FD_ISSET(ndx, &(ev->select_read))) {
-+                      events |= FDEVENT_IN;
-+              }
-+              if (FD_ISSET(ndx, &(ev->select_write))) {
-+                      events |= FDEVENT_OUT;
-+              }
-+              if (FD_ISSET(ndx, &(ev->select_error))) {
-+                      events |= FDEVENT_ERR;
-+              }
-+
-+              if (events) {
-+                      fdevent_revents_add(revents, ndx, events);
-+              }
-       }
--      if (FD_ISSET(ndx, &(ev->select_write))) {
--              revents |= FDEVENT_OUT;
--      }
--      if (FD_ISSET(ndx, &(ev->select_error))) {
--              revents |= FDEVENT_ERR;
--      }
--      
--      return revents;
--}
--
--static int fdevent_select_event_get_fd(fdevents *ev, size_t ndx) {
--      UNUSED(ev);
--
--      return ndx;
--}
--static int fdevent_select_event_next_fdndx(fdevents *ev, int ndx) {
--      int i;
--      
--      i = (ndx < 0) ? 0 : ndx + 1;
--      
--      for (; i < ev->select_max_fd + 1; i++) {
--              if (FD_ISSET(i, &(ev->select_read))) break;
--              if (FD_ISSET(i, &(ev->select_write))) break;
--              if (FD_ISSET(i, &(ev->select_error))) break;
--      }
--      
--      return i;
-+      return 0;
- }
- int fdevent_select_init(fdevents *ev) {
-       ev->type = FDEVENT_HANDLER_SELECT;
- #define SET(x) \
-       ev->x = fdevent_select_##x;
--      
-+
-       SET(reset);
-       SET(poll);
--      
-+
-       SET(event_del);
-       SET(event_add);
--      
--      SET(event_next_fdndx);
--      SET(event_get_fd);
--      SET(event_get_revent);
--      
-+
-+      SET(get_revents);
-+
-       return 0;
- }
---- ../lighttpd-1.4.11/src/fdevent_solaris_devpoll.c   2005-09-01 10:45:26.000000000 +0300
-+++ lighttpd-1.5.0/src/fdevent_solaris_devpoll.c       2006-07-16 00:26:03.000000000 +0300
-@@ -1,6 +1,5 @@
- #include <sys/types.h>
--#include <unistd.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
-@@ -23,55 +22,55 @@
- static int fdevent_solaris_devpoll_event_del(fdevents *ev, int fde_ndx, int fd) {
-       struct pollfd pfd;
--              
-+
-       if (fde_ndx < 0) return -1;
--      
-+
-       pfd.fd = fd;
-       pfd.events = POLLREMOVE;
-       pfd.revents = 0;
--      
-+
-       if (-1 == write(ev->devpoll_fd, &pfd, sizeof(pfd))) {
--              fprintf(stderr, "%s.%d: (del) write failed: (%d, %s)\n", 
--                      __FILE__, __LINE__, 
-+              fprintf(stderr, "%s.%d: (del) write failed: (%d, %s)\n",
-+                      __FILE__, __LINE__,
-                       fd, strerror(errno));
--              
-+
-               return -1;
-       }
--      
-+
-       return -1;
- }
- static int fdevent_solaris_devpoll_event_add(fdevents *ev, int fde_ndx, int fd, int events) {
-       struct pollfd pfd;
-       int add = 0;
--              
-+
-       if (fde_ndx == -1) add = 1;
--      
-+
-       pfd.fd = fd;
-       pfd.events = events;
-       pfd.revents = 0;
--      
-+
-       if (-1 == write(ev->devpoll_fd, &pfd, sizeof(pfd))) {
--              fprintf(stderr, "%s.%d: (del) write failed: (%d, %s)\n", 
--                      __FILE__, __LINE__, 
-+              fprintf(stderr, "%s.%d: (del) write failed: (%d, %s)\n",
-+                      __FILE__, __LINE__,
-                       fd, strerror(errno));
--              
-+
-               return -1;
-       }
--      
-+
-       return fd;
- }
- static int fdevent_solaris_devpoll_poll(fdevents *ev, int timeout_ms) {
-       struct dvpoll dopoll;
-       int ret;
--      
-+
-       dopoll.dp_timeout = timeout_ms;
-       dopoll.dp_nfds = ev->maxfds;
-       dopoll.dp_fds = ev->devpollfds;
--      
-+
-       ret = ioctl(ev->devpoll_fd, DP_POLL, &dopoll);
--      
-+
-       return ret;
- }
-@@ -85,11 +84,11 @@
- static int fdevent_solaris_devpoll_event_next_fdndx(fdevents *ev, int last_ndx) {
-       size_t i;
--      
-+
-       UNUSED(ev);
-       i = (last_ndx < 0) ? 0 : last_ndx + 1;
--      
-+
-       return i;
- }
-@@ -117,20 +116,20 @@
-       ev->type = FDEVENT_HANDLER_SOLARIS_DEVPOLL;
- #define SET(x) \
-       ev->x = fdevent_solaris_devpoll_##x;
--      
-+
-       SET(free);
-       SET(poll);
-       SET(reset);
--      
-+
-       SET(event_del);
-       SET(event_add);
--      
-+
-       SET(event_next_fdndx);
-       SET(event_get_fd);
-       SET(event_get_revent);
--      
-+
-       ev->devpollfds = malloc(sizeof(*ev->devpollfds) * ev->maxfds);
--      
-+
-       if ((ev->devpoll_fd = open("/dev/poll", O_RDWR)) < 0) {
-               fprintf(stderr, "%s.%d: opening /dev/poll failed (%s), try to set server.event-handler = \"poll\" or \"select\"\n",
-                       __FILE__, __LINE__, strerror(errno));
-@@ -152,7 +151,7 @@
-       fprintf(stderr, "%s.%d: solaris-devpoll not supported, try to set server.event-handler = \"poll\" or \"select\"\n",
-                       __FILE__, __LINE__);
--      
-+
-       return -1;
- }
- #endif
---- ../lighttpd-1.4.11/src/http-header-glue.c  2006-02-08 15:31:36.000000000 +0200
-+++ lighttpd-1.5.0/src/http-header-glue.c      2006-09-07 00:57:05.000000000 +0300
-@@ -45,20 +45,20 @@
- #   ifdef HAVE_STRUCT_SOCKADDR_STORAGE
- static size_t get_sa_len(const struct sockaddr *addr) {
-       switch (addr->sa_family) {
--              
-+
- #    ifdef AF_INET
-       case AF_INET:
-               return (sizeof (struct sockaddr_in));
- #    endif
--              
-+
- #    ifdef AF_INET6
-       case AF_INET6:
-               return (sizeof (struct sockaddr_in6));
- #    endif
--              
-+
-       default:
-               return (sizeof (struct sockaddr));
--              
-+
-       }
- }
- #    define SA_LEN(addr)   (get_sa_len(addr))
-@@ -74,7 +74,7 @@
- int response_header_insert(server *srv, connection *con, const char *key, size_t keylen, const char *value, size_t vallen) {
-       data_string *ds;
--      
-+
-       UNUSED(srv);
-       if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
-@@ -82,32 +82,32 @@
-       }
-       buffer_copy_string_len(ds->key, key, keylen);
-       buffer_copy_string_len(ds->value, value, vallen);
--      
-+
-       array_insert_unique(con->response.headers, (data_unset *)ds);
--      
-+
-       return 0;
- }
- int response_header_overwrite(server *srv, connection *con, const char *key, size_t keylen, const char *value, size_t vallen) {
-       data_string *ds;
--      
-+
-       UNUSED(srv);
-       /* if there already is a key by this name overwrite the value */
-       if (NULL != (ds = (data_string *)array_get_element(con->response.headers, key))) {
-               buffer_copy_string(ds->value, value);
--              
-+
-               return 0;
-       }
--      
-+
-       return response_header_insert(srv, con, key, keylen, value, vallen);
- }
- int http_response_redirect_to_directory(server *srv, connection *con) {
-       buffer *o;
--      
-+
-       o = buffer_init();
--      
-+
-       if (con->conf.is_ssl) {
-               buffer_copy_string(o, "https://");
-       } else {
-@@ -123,36 +123,36 @@
- #endif
-               sock_addr our_addr;
-               socklen_t our_addr_len;
--              
-+
-               our_addr_len = sizeof(our_addr);
--              
--              if (-1 == getsockname(con->fd, &(our_addr.plain), &our_addr_len)) {
-+
-+              if (-1 == getsockname(con->sock->fd, &(our_addr.plain), &our_addr_len)) {
-                       con->http_status = 500;
--                      
-+
-                       log_error_write(srv, __FILE__, __LINE__, "ss",
-                                       "can't get sockname", strerror(errno));
--                      
-+
-                       buffer_free(o);
-                       return 0;
-               }
--              
--              
-+
-+
-               /* Lookup name: secondly try to get hostname for bind address */
-               switch(our_addr.plain.sa_family) {
- #ifdef HAVE_IPV6
-               case AF_INET6:
--                      if (0 != getnameinfo((const struct sockaddr *)(&our_addr.ipv6), 
--                                           SA_LEN((const struct sockaddr *)&our_addr.ipv6), 
-+                      if (0 != getnameinfo((const struct sockaddr *)(&our_addr.ipv6),
-+                                           SA_LEN((const struct sockaddr *)&our_addr.ipv6),
-                                            hbuf, sizeof(hbuf), NULL, 0, 0)) {
--                              
-+
-                               char dst[INET6_ADDRSTRLEN];
--                              
-+
-                               log_error_write(srv, __FILE__, __LINE__,
-                                               "SSSS", "NOTICE: getnameinfo failed: ",
-                                               strerror(errno), ", using ip-address instead");
--                              
--                              buffer_append_string(o, 
--                                                   inet_ntop(AF_INET6, (char *)&our_addr.ipv6.sin6_addr, 
-+
-+                              buffer_append_string(o,
-+                                                   inet_ntop(AF_INET6, (char *)&our_addr.ipv6.sin6_addr,
-                                                              dst, sizeof(dst)));
-                       } else {
-                               buffer_append_string(o, hbuf);
-@@ -164,7 +164,7 @@
-                               log_error_write(srv, __FILE__, __LINE__,
-                                               "SdSS", "NOTICE: gethostbyaddr failed: ",
-                                               h_errno, ", using ip-address instead");
--                              
-+
-                               buffer_append_string(o, inet_ntoa(our_addr.ipv4.sin_addr));
-                       } else {
-                               buffer_append_string(o, he->h_name);
-@@ -173,12 +173,12 @@
-               default:
-                       log_error_write(srv, __FILE__, __LINE__,
-                                       "S", "ERROR: unsupported address-type");
--                      
-+
-                       buffer_free(o);
-                       return -1;
-               }
--              
--              if (!((con->conf.is_ssl == 0 && srv->srvconf.port == 80) || 
-+
-+              if (!((con->conf.is_ssl == 0 && srv->srvconf.port == 80) ||
-                     (con->conf.is_ssl == 1 && srv->srvconf.port == 443))) {
-                       buffer_append_string(o, ":");
-                       buffer_append_long(o, srv->srvconf.port);
-@@ -190,46 +190,49 @@
-               buffer_append_string(o, "?");
-               buffer_append_string_buffer(o, con->uri.query);
-       }
--      
-+
-       response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(o));
--      
-+
-       con->http_status = 301;
--      con->file_finished = 1;
--      
-+      con->send->is_closed = 1; /* no content */
-+
-       buffer_free(o);
--      
-+
-       return 0;
- }
- buffer * strftime_cache_get(server *srv, time_t last_mod) {
-       struct tm *tm;
-       size_t i;
--              
-+
-       for (i = 0; i < FILE_CACHE_MAX; i++) {
-               /* found cache-entry */
-               if (srv->mtime_cache[i].mtime == last_mod) return srv->mtime_cache[i].str;
--                              
-+
-               /* found empty slot */
-               if (srv->mtime_cache[i].mtime == 0) break;
-       }
--      
-+
-       if (i == FILE_CACHE_MAX) {
-               i = 0;
-       }
--              
-+
-       srv->mtime_cache[i].mtime = last_mod;
-       buffer_prepare_copy(srv->mtime_cache[i].str, 1024);
-       tm = gmtime(&(srv->mtime_cache[i].mtime));
--      srv->mtime_cache[i].str->used = strftime(srv->mtime_cache[i].str->ptr, 
-+      srv->mtime_cache[i].str->used = strftime(srv->mtime_cache[i].str->ptr,
-                                                srv->mtime_cache[i].str->size - 1,
-                                                "%a, %d %b %Y %H:%M:%S GMT", tm);
-       srv->mtime_cache[i].str->used++;
--      
-+
-       return srv->mtime_cache[i].str;
- }
- int http_response_handle_cachable(server *srv, connection *con, buffer *mtime) {
-+      data_string *http_if_none_match;
-+      data_string *http_if_modified_since;
-+
-       /*
-        * 14.26 If-None-Match
-        *    [...]
-@@ -239,56 +242,63 @@
-        *    request. That is, if no entity tags match, then the server MUST NOT
-        *    return a 304 (Not Modified) response.
-        */
--      
-+
-+      http_if_none_match = (data_string *)array_get_element(con->request.headers, "if-none-match");
-+      http_if_modified_since = (data_string *)array_get_element(con->request.headers, "if-modified-since");
-+
-       /* last-modified handling */
--      if (con->request.http_if_none_match) {
--              if (etag_is_equal(con->physical.etag, con->request.http_if_none_match)) {
--                      if (con->request.http_method == HTTP_METHOD_GET || 
-+      if (http_if_none_match) {
-+              if (etag_is_equal(con->physical.etag, BUF_STR(http_if_none_match->value))) {
-+                      if (con->request.http_method == HTTP_METHOD_GET ||
-                           con->request.http_method == HTTP_METHOD_HEAD) {
--                              
-+
-                               /* check if etag + last-modified */
--                              if (con->request.http_if_modified_since) {
-+                              if (http_if_modified_since) {
-                                       size_t used_len;
-                                       char *semicolon;
--                                      
--                                      if (NULL == (semicolon = strchr(con->request.http_if_modified_since, ';'))) {
--                                              used_len = strlen(con->request.http_if_modified_since);
-+
-+                                      if (NULL == (semicolon = strchr(BUF_STR(http_if_modified_since->value), ';'))) {
-+                                              used_len = http_if_modified_since->value->used - 1;
-                                       } else {
--                                              used_len = semicolon - con->request.http_if_modified_since;
-+                                              used_len = semicolon - BUF_STR(http_if_modified_since->value);
-                                       }
--                                      
--                                      if (0 == strncmp(con->request.http_if_modified_since, mtime->ptr, used_len)) {
-+
-+                                      if (0 == strncmp(BUF_STR(http_if_modified_since->value), mtime->ptr, used_len)) {
-                                               con->http_status = 304;
-                                               return HANDLER_FINISHED;
-                                       } else {
-+#ifdef HAVE_STRPTIME
-                                               char buf[sizeof("Sat, 23 Jul 2005 21:20:01 GMT")];
-+                                              time_t t_header, t_file;
-+                                              struct tm tm;
-+
-+                                              /* check if we can safely copy the string */
-+                                              if (used_len >= sizeof(buf)) {
-+                                                      TRACE("last-mod check failed as timestamp was too long: %s: %d, %d", 
-+                                                                      BUF_STR(http_if_modified_since->value), 
-+                                                                      used_len, sizeof(buf) - 1);
--                                              /* convert to timestamp */
--                                              if (used_len < sizeof(buf)) {
--                                                      time_t t_header, t_file;
--                                                      struct tm tm;
--                                                      
--                                                      strncpy(buf, con->request.http_if_modified_since, used_len);
--                                                      buf[used_len] = '\0';
--                                                      
--                                                      strptime(buf, "%a, %d %b %Y %H:%M:%S GMT", &tm);
--                                                      t_header = mktime(&tm);
--                                                      
--                                                      strptime(mtime->ptr, "%a, %d %b %Y %H:%M:%S GMT", &tm);
--                                                      t_file = mktime(&tm);
--
--                                                      if (t_file > t_header) {
--                                                              con->http_status = 304;
--                                                              return HANDLER_FINISHED;
--                                                      }
--                                              } else {
--                                                      log_error_write(srv, __FILE__, __LINE__, "ssdd", 
--                                                                      "DEBUG: Last-Modified check failed as the received timestamp was too long:", 
--                                                                      con->request.http_if_modified_since, used_len, sizeof(buf) - 1);
--                                                      
-                                                       con->http_status = 412;
-                                                       return HANDLER_FINISHED;
-                                               }
-+
-+
-+                                              strncpy(buf, BUF_STR(http_if_modified_since->value), used_len);
-+                                              buf[used_len] = '\0';
-+
-+                                              strptime(buf, "%a, %d %b %Y %H:%M:%S GMT", &tm);
-+                                              t_header = mktime(&tm);
-+
-+                                              strptime(mtime->ptr, "%a, %d %b %Y %H:%M:%S GMT", &tm);
-+                                              t_file = mktime(&tm);
-+
-+                                              if (t_file > t_header) return HANDLER_GO_ON;
-+
-+                                              con->http_status = 304;
-+                                              return HANDLER_FINISHED;
-+#else
-+                                              return HANDLER_GO_ON;
-+#endif
-                                       }
-                               } else {
-                                       con->http_status = 304;
-@@ -299,19 +309,44 @@
-                               return HANDLER_FINISHED;
-                       }
-               }
--      } else if (con->request.http_if_modified_since) {
-+      } else if (http_if_modified_since) {
-               size_t used_len;
-               char *semicolon;
--              
--              if (NULL == (semicolon = strchr(con->request.http_if_modified_since, ';'))) {
--                      used_len = strlen(con->request.http_if_modified_since);
-+
-+              if (NULL == (semicolon = strchr(BUF_STR(http_if_modified_since->value), ';'))) {
-+                      used_len = http_if_modified_since->value->used - 1;
-               } else {
--                      used_len = semicolon - con->request.http_if_modified_since;
-+                      used_len = semicolon - BUF_STR(http_if_modified_since->value);
-               }
--              
--              if (0 == strncmp(con->request.http_if_modified_since, mtime->ptr, used_len)) {
-+
-+              if (0 == strncmp(BUF_STR(http_if_modified_since->value), mtime->ptr, used_len)) {
-                       con->http_status = 304;
-                       return HANDLER_FINISHED;
-+              } else {
-+#ifdef HAVE_STRPTIME
-+                      char buf[sizeof("Sat, 23 Jul 2005 21:20:01 GMT")];
-+                      time_t t_header, t_file;
-+                      struct tm tm;
-+
-+                      /* convert to timestamp */
-+                      if (used_len >= sizeof(buf)) return HANDLER_GO_ON;
-+
-+                      strncpy(buf, BUF_STR(http_if_modified_since->value), used_len);
-+                      buf[used_len] = '\0';
-+
-+                      strptime(buf, "%a, %d %b %Y %H:%M:%S GMT", &tm);
-+                      t_header = mktime(&tm);
-+
-+                      strptime(mtime->ptr, "%a, %d %b %Y %H:%M:%S GMT", &tm);
-+                      t_file = mktime(&tm);
-+
-+                      if (t_file > t_header) return HANDLER_GO_ON;
-+
-+                      con->http_status = 304;
-+                      return HANDLER_FINISHED;
-+#else
-+            return HANDLER_GO_ON;
-+#endif
-               }
-       }
---- ../lighttpd-1.4.11/src/http_auth.c 2006-02-01 13:02:52.000000000 +0200
-+++ lighttpd-1.5.0/src/http_auth.c     2006-09-07 00:57:05.000000000 +0300
-@@ -22,7 +22,6 @@
- #include <string.h>
- #include <time.h>
- #include <errno.h>
--#include <unistd.h>
- #include <ctype.h>
- #include "server.h"
-@@ -31,23 +30,15 @@
- #include "http_auth_digest.h"
- #include "stream.h"
-+#include "sys-strings.h"
-+#include "sys-files.h"
-+
- #ifdef USE_OPENSSL
- # include <openssl/md5.h>
- #else
- # include "md5.h"
- #endif
--
--#ifdef USE_PAM
--#include <security/pam_appl.h>
--#include <security/pam_misc.h>
--
--static struct pam_conv conv = {
--      misc_conv,
--              NULL
--};
--#endif
--
- handler_t auth_ldap_init(server *srv, mod_auth_plugin_config *s);
- static const char base64_pad = '=';
-@@ -75,25 +66,25 @@
-       unsigned char *result;
-       int ch, j = 0, k;
-       size_t i;
--      
-+
-       size_t in_len = strlen(in);
--      
-+
-       buffer_prepare_copy(out, in_len);
--      
-+
-       result = (unsigned char *)out->ptr;
--      
-+
-       ch = in[0];
-       /* run through the whole string, converting as we go */
-       for (i = 0; i < in_len; i++) {
-               ch = in[i];
--              
-+
-               if (ch == '\0') break;
--              
-+
-               if (ch == base64_pad) break;
--              
-+
-               ch = base64_reverse_table[ch];
-               if (ch < 0) continue;
--              
-+
-               switch(i % 4) {
-               case 0:
-                       result[j] = ch << 2;
-@@ -125,168 +116,168 @@
-               }
-       }
-       result[k] = '\0';
--      
-+
-       out->used = k;
--      
-+
-       return result;
- }
- static int http_auth_get_password(server *srv, mod_auth_plugin_data *p, buffer *username, buffer *realm, buffer *password) {
-       int ret = -1;
--      
-+
-       if (!username->used|| !realm->used) return -1;
--      
-+
-       if (p->conf.auth_backend == AUTH_BACKEND_HTDIGEST) {
-               stream f;
-               char * f_line;
--              
-+
-               if (buffer_is_empty(p->conf.auth_htdigest_userfile)) return -1;
--              
-+
-               if (0 != stream_open(&f, p->conf.auth_htdigest_userfile)) {
-                       log_error_write(srv, __FILE__, __LINE__, "sbss", "opening digest-userfile", p->conf.auth_htdigest_userfile, "failed:", strerror(errno));
--                      
-+
-                       return -1;
-               }
--              
-+
-               f_line = f.start;
--              
-+
-               while (f_line - f.start != f.size) {
-                       char *f_user, *f_pwd, *e, *f_realm;
-                       size_t u_len, pwd_len, r_len;
--                      
-+
-                       f_user = f_line;
--                      
--                      /* 
-+
-+                      /*
-                        * htdigest format
--                       * 
--                       * user:realm:md5(user:realm:password) 
-+                       *
-+                       * user:realm:md5(user:realm:password)
-                        */
--                      
-+
-                       if (NULL == (f_realm = memchr(f_user, ':', f.size - (f_user - f.start) ))) {
--                              log_error_write(srv, __FILE__, __LINE__, "sbs", 
--                                              "parsed error in", p->conf.auth_htdigest_userfile, 
-+                              log_error_write(srv, __FILE__, __LINE__, "sbs",
-+                                              "parsed error in", p->conf.auth_htdigest_userfile,
-                                               "expected 'username:realm:hashed password'");
--                              
-+
-                               stream_close(&f);
--                              
-+
-                               return -1;
-                       }
--                      
-+
-                       if (NULL == (f_pwd = memchr(f_realm + 1, ':', f.size - (f_realm + 1 - f.start)))) {
--                              log_error_write(srv, __FILE__, __LINE__, "sbs", 
--                                              "parsed error in", p->conf.auth_plain_userfile, 
-+                              log_error_write(srv, __FILE__, __LINE__, "sbs",
-+                                              "parsed error in", p->conf.auth_plain_userfile,
-                                               "expected 'username:realm:hashed password'");
--                              
-+
-                               stream_close(&f);
--                              
-+
-                               return -1;
-                       }
--                      
-+
-                       /* get pointers to the fields */
--                      u_len = f_realm - f_user; 
-+                      u_len = f_realm - f_user;
-                       f_realm++;
-                       r_len = f_pwd - f_realm;
-                       f_pwd++;
--                      
-+
-                       if (NULL != (e = memchr(f_pwd, '\n', f.size - (f_pwd - f.start)))) {
-                               pwd_len = e - f_pwd;
-                       } else {
-                               pwd_len = f.size - (f_pwd - f.start);
-                       }
--                      
-+
-                       if (username->used - 1 == u_len &&
-                           (realm->used - 1 == r_len) &&
-                           (0 == strncmp(username->ptr, f_user, u_len)) &&
-                           (0 == strncmp(realm->ptr, f_realm, r_len))) {
-                               /* found */
--                              
-+
-                               buffer_copy_string_len(password, f_pwd, pwd_len);
--                              
-+
-                               ret = 0;
-                               break;
-                       }
--                      
-+
-                       /* EOL */
-                       if (!e) break;
--                      
-+
-                       f_line = e + 1;
-               }
--              
-+
-               stream_close(&f);
-       } else if (p->conf.auth_backend == AUTH_BACKEND_HTPASSWD ||
-                  p->conf.auth_backend == AUTH_BACKEND_PLAIN) {
-               stream f;
-               char * f_line;
-               buffer *auth_fn;
--              
-+
-               auth_fn = (p->conf.auth_backend == AUTH_BACKEND_HTPASSWD) ? p->conf.auth_htpasswd_userfile : p->conf.auth_plain_userfile;
--              
-+
-               if (buffer_is_empty(auth_fn)) return -1;
--              
-+
-               if (0 != stream_open(&f, auth_fn)) {
--                      log_error_write(srv, __FILE__, __LINE__, "sbss", 
-+                      log_error_write(srv, __FILE__, __LINE__, "sbss",
-                                       "opening plain-userfile", auth_fn, "failed:", strerror(errno));
--                      
-+
-                       return -1;
-               }
--              
-+
-               f_line = f.start;
--              
-+
-               while (f_line - f.start != f.size) {
-                       char *f_user, *f_pwd, *e;
-                       size_t u_len, pwd_len;
--                      
-+
-                       f_user = f_line;
--                      
--                      /* 
-+
-+                      /*
-                        * htpasswd format
--                       * 
-+                       *
-                        * user:crypted passwd
-                        */
--                      
-+
-                       if (NULL == (f_pwd = memchr(f_user, ':', f.size - (f_user - f.start) ))) {
--                              log_error_write(srv, __FILE__, __LINE__, "sbs", 
--                                              "parsed error in", auth_fn, 
-+                              log_error_write(srv, __FILE__, __LINE__, "sbs",
-+                                              "parsed error in", auth_fn,
-                                               "expected 'username:hashed password'");
--                              
-+
-                               stream_close(&f);
--                              
-+
-                               return -1;
-                       }
--                      
-+
-                       /* get pointers to the fields */
--                      u_len = f_pwd - f_user; 
-+                      u_len = f_pwd - f_user;
-                       f_pwd++;
--                      
-+
-                       if (NULL != (e = memchr(f_pwd, '\n', f.size - (f_pwd - f.start)))) {
-                               pwd_len = e - f_pwd;
-                       } else {
-                               pwd_len = f.size - (f_pwd - f.start);
-                       }
--                      
-+
-                       if (username->used - 1 == u_len &&
-                           (0 == strncmp(username->ptr, f_user, u_len))) {
-                               /* found */
--                              
-+
-                               buffer_copy_string_len(password, f_pwd, pwd_len);
--                              
-+
-                               ret = 0;
-                               break;
-                       }
--                      
-+
-                       /* EOL */
-                       if (!e) break;
--                      
-+
-                       f_line = e + 1;
-               }
--              
-+
-               stream_close(&f);
-       } else if (p->conf.auth_backend == AUTH_BACKEND_LDAP) {
-               ret = 0;
-       } else {
-               return -1;
-       }
--      
-+
-       return ret;
- }
-@@ -296,7 +287,7 @@
-       int username_len;
-       data_string *require;
-       array *req;
--      
-+
-       UNUSED(group);
-       UNUSED(host);
-@@ -304,12 +295,12 @@
-       /* search auth-directives for path */
-       for (i = 0; i < p->conf.auth_require->used; i++) {
-               if (p->conf.auth_require->data[i]->key->used == 0) continue;
--              
-+
-               if (0 == strncmp(url, p->conf.auth_require->data[i]->key->ptr, p->conf.auth_require->data[i]->key->used - 1)) {
-                       break;
-               }
-       }
--      
-+
-       if (i == p->conf.auth_require->used) {
-               return -1;
-       }
-@@ -317,72 +308,72 @@
-       req = ((data_array *)(p->conf.auth_require->data[i]))->value;
-       require = (data_string *)array_get_element(req, "require");
--      
-+
-       /* if we get here, the user we got a authed user */
--      if (0 == strcmp(require->value->ptr, "valid-user")) {
-+      if (buffer_is_equal_string(require->value, CONST_STR_LEN("valid-user"))) {
-               return 0;
-       }
--      
-+
-       /* user=name1|group=name3|host=name4 */
--      
-+
-       /* seperate the string by | */
- #if 0
-       log_error_write(srv, __FILE__, __LINE__, "sb", "rules", require->value);
--#endif        
--      
-+#endif
-+
-       username_len = username ? strlen(username) : 0;
--      
-+
-       r = rules = require->value->ptr;
--      
-+
-       while (1) {
-               const char *eq;
-               const char *k, *v, *e;
-               int k_len, v_len, r_len;
--              
-+
-               e = strchr(r, '|');
--              
-+
-               if (e) {
-                       r_len = e - r;
-               } else {
-                       r_len = strlen(rules) - (r - rules);
-               }
--              
-+
-               /* from r to r + r_len is a rule */
--              
-+
-               if (0 == strncmp(r, "valid-user", r_len)) {
--                      log_error_write(srv, __FILE__, __LINE__, "sb", 
-+                      log_error_write(srv, __FILE__, __LINE__, "sb",
-                                       "parsing the 'require' section in 'auth.require' failed: valid-user cannot be combined with other require rules",
-                                       require->value);
-                       return -1;
-               }
--              
-+
-               /* search for = in the rules */
-               if (NULL == (eq = strchr(r, '='))) {
--                      log_error_write(srv, __FILE__, __LINE__, "sb", 
--                                      "parsing the 'require' section in 'auth.require' failed: a = is missing", 
-+                      log_error_write(srv, __FILE__, __LINE__, "sb",
-+                                      "parsing the 'require' section in 'auth.require' failed: a = is missing",
-                                       require->value);
-                       return -1;
-               }
--              
-+
-               /* = out of range */
-               if (eq > r + r_len) {
--                      log_error_write(srv, __FILE__, __LINE__, "sb", 
-+                      log_error_write(srv, __FILE__, __LINE__, "sb",
-                                       "parsing the 'require' section in 'auth.require' failed: = out of range",
-                                       require->value);
--                      
-+
-                       return -1;
-               }
--              
-+
-               /* the part before the = is user|group|host */
--              
-+
-               k = r;
-               k_len = eq - r;
-               v = eq + 1;
-               v_len = r_len - k_len - 1;
--              
-+
-               if (k_len == 4) {
-                       if (0 == strncmp(k, "user", k_len)) {
--                              if (username && 
-+                              if (username &&
-                                   username_len == v_len &&
-                                   0 == strncmp(username, v, v_len)) {
-                                       return 0;
-@@ -404,19 +395,19 @@
-                       log_error_write(srv, __FILE__, __LINE__, "s", "unknown  key");
-                       return -1;
-               }
--              
-+
-               if (!e) break;
-               r = e + 1;
-       }
--      
-+
-       log_error_write(srv, __FILE__, __LINE__, "s", "nothing matched");
--      
-+
-       return -1;
- }
- /**
-- * 
-- * 
-+ *
-+ *
-  * @param password password-string from the auth-backend
-  * @param pw       password-string from the client
-  */
-@@ -426,16 +417,16 @@
-       UNUSED(req);
-       if (p->conf.auth_backend == AUTH_BACKEND_HTDIGEST) {
--              /* 
-+              /*
-                * htdigest format
--               * 
--               * user:realm:md5(user:realm:password) 
-+               *
-+               * user:realm:md5(user:realm:password)
-                */
--              
-+
-               MD5_CTX Md5Ctx;
-               HASH HA1;
-               char a1[256];
--              
-+
-               MD5_Init(&Md5Ctx);
-               MD5_Update(&Md5Ctx, (unsigned char *)username->ptr, username->used - 1);
-               MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
-@@ -443,24 +434,24 @@
-               MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
-               MD5_Update(&Md5Ctx, (unsigned char *)pw, strlen(pw));
-               MD5_Final(HA1, &Md5Ctx);
--              
-+
-               CvtHex(HA1, a1);
--              
--              if (0 == strcmp(password->ptr, a1)) {
-+
-+              if (buffer_is_equal_string(password, a1, strlen(a1))) {
-                       return 0;
-               }
--      } else if (p->conf.auth_backend == AUTH_BACKEND_HTPASSWD) { 
--#ifdef HAVE_CRYPT     
-+      } else if (p->conf.auth_backend == AUTH_BACKEND_HTPASSWD) {
-+#ifdef HAVE_CRYPT
-               char salt[32];
-               char *crypted;
-               size_t salt_len = 0;
--              /* 
-+              /*
-                * htpasswd format
--               * 
-+               *
-                * user:crypted password
-                */
--              /* 
-+              /*
-                *  Algorithm      Salt
-                *  CRYPT_STD_DES   2-character (Default)
-                *  CRYPT_EXT_DES   9-character
-@@ -478,7 +469,7 @@
-                       salt_len = 2;
-               } else if (password->ptr[0] == '$' && password->ptr[2] == '$') {
-                       char *dollar = NULL;
--              
-+
-                       if (NULL == (dollar = strchr(password->ptr + 3, '$'))) {
-                               fprintf(stderr, "%s.%d\n", __FILE__, __LINE__);
-                               return -1;
-@@ -495,48 +486,21 @@
-               strncpy(salt, password->ptr, salt_len);
-               salt[salt_len] = '\0';
--              
-+
-               crypted = crypt(pw, salt);
--              if (0 == strcmp(password->ptr, crypted)) {
-+              if (buffer_is_equal_string(password, crypted, strlen(crypted))) {
-                       return 0;
-               } else {
-                       fprintf(stderr, "%s.%d\n", __FILE__, __LINE__);
-               }
--      
--#endif        
--      } else if (p->conf.auth_backend == AUTH_BACKEND_PLAIN) { 
--              if (0 == strcmp(password->ptr, pw)) {
--                      return 0;
--              }
--      } else if (p->conf.auth_backend == AUTH_BACKEND_PAM) { 
--#ifdef USE_PAM
--              pam_handle_t *pamh=NULL;
--              int retval;
--              
--              retval = pam_start("lighttpd", username->ptr, &conv, &pamh);
--              
--              if (retval == PAM_SUCCESS)
--                      retval = pam_authenticate(pamh, 0);    /* is user really user? */
--              
--              if (retval == PAM_SUCCESS)
--                      retval = pam_acct_mgmt(pamh, 0);       /* permitted access? */
--              
--              /* This is where we have been authorized or not. */
--              
--              if (pam_end(pamh,retval) != PAM_SUCCESS) {     /* close Linux-PAM */
--                      pamh = NULL;
--                      log_error_write(srv, __FILE__, __LINE__, "s", "failed to release authenticator");
--              }
--              
--              if (retval == PAM_SUCCESS) {
--                      log_error_write(srv, __FILE__, __LINE__, "s", "Authenticated");
-+
-+#endif
-+      } else if (p->conf.auth_backend == AUTH_BACKEND_PLAIN) {
-+              if (buffer_is_equal_string(password, pw, strlen(pw))) {
-                       return 0;
--              } else {
--                      log_error_write(srv, __FILE__, __LINE__, "s", "Not Authenticated");
-               }
--#endif
--      } else if (p->conf.auth_backend == AUTH_BACKEND_LDAP) { 
-+      } else if (p->conf.auth_backend == AUTH_BACKEND_LDAP) {
- #ifdef USE_LDAP
-               LDAP *ldap;
-               LDAPMessage *lm, *first;
-@@ -544,45 +508,45 @@
-               int ret;
-               char *attrs[] = { LDAP_NO_ATTRS, NULL };
-               size_t i;
--              
-+
-               /* for now we stay synchronous */
--              
--              /* 
-+
-+              /*
-                * 1. connect anonymously (done in plugin init)
-                * 2. get DN for uid = username
-                * 3. auth against ldap server
-                * 4. (optional) check a field
-                * 5. disconnect
--               * 
-+               *
-                */
--              
-+
-               /* check username
--               * 
-+               *
-                * we have to protect us againt username which modifies out filter in
-                * a unpleasant way
-                */
--              
-+
-               for (i = 0; i < username->used - 1; i++) {
-                       char c = username->ptr[i];
--                      
-+
-                       if (!isalpha(c) &&
-                           !isdigit(c)) {
--                              
--                              log_error_write(srv, __FILE__, __LINE__, "sbd", 
-+
-+                              log_error_write(srv, __FILE__, __LINE__, "sbd",
-                                       "ldap: invalid character (a-zA-Z0-9 allowed) in username:", username, i);
--                              
-+
-                               return -1;
-                       }
-               }
--              
--              
--              
-+
-+
-+
-               /* build filter */
-               buffer_copy_string_buffer(p->ldap_filter, p->conf.ldap_filter_pre);
-               buffer_append_string_buffer(p->ldap_filter, username);
-               buffer_append_string_buffer(p->ldap_filter, p->conf.ldap_filter_post);
--              
--              
-+
-+
-               /* 2. */
-               if (p->conf.ldap == NULL ||
-                   LDAP_SUCCESS != (ret = ldap_search_s(p->conf.ldap, p->conf.auth_ldap_basedn->ptr, LDAP_SCOPE_SUBTREE, p->ldap_filter->ptr, attrs, 0, &lm))) {
-@@ -590,71 +554,71 @@
-                               return -1;
-                       if (LDAP_SUCCESS != (ret = ldap_search_s(p->conf.ldap, p->conf.auth_ldap_basedn->ptr, LDAP_SCOPE_SUBTREE, p->ldap_filter->ptr, attrs, 0, &lm))) {
--                      log_error_write(srv, __FILE__, __LINE__, "sssb", 
-+                      log_error_write(srv, __FILE__, __LINE__, "sssb",
-                                       "ldap:", ldap_err2string(ret), "filter:", p->ldap_filter);
--                      
-+
-                       return -1;
-                       }
-               }
--              
-+
-               if (NULL == (first = ldap_first_entry(p->conf.ldap, lm))) {
-                       log_error_write(srv, __FILE__, __LINE__, "s", "ldap ...");
--                      
-+
-                       ldap_msgfree(lm);
--                      
-+
-                       return -1;
-               }
--              
-+
-               if (NULL == (dn = ldap_get_dn(p->conf.ldap, first))) {
-                       log_error_write(srv, __FILE__, __LINE__, "s", "ldap ...");
--                      
-+
-                       ldap_msgfree(lm);
--                      
-+
-                       return -1;
-               }
--              
-+
-               ldap_msgfree(lm);
--              
--              
-+
-+
-               /* 3. */
-               if (NULL == (ldap = ldap_init(p->conf.auth_ldap_hostname->ptr, LDAP_PORT))) {
-                       log_error_write(srv, __FILE__, __LINE__, "ss", "ldap ...", strerror(errno));
-                       return -1;
-               }
--              
-+
-               ret = LDAP_VERSION3;
-               if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, &ret))) {
-                       log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));
--                      
-+
-                       ldap_unbind_s(ldap);
--                      
-+
-                       return -1;
-               }
--              
-+
-               if (p->conf.auth_ldap_starttls == 1) {
-                       if (LDAP_OPT_SUCCESS != (ret = ldap_start_tls_s(ldap, NULL,  NULL))) {
-                               log_error_write(srv, __FILE__, __LINE__, "ss", "ldap startTLS failed:", ldap_err2string(ret));
--              
-+
-                               ldap_unbind_s(ldap);
--                              
-+
-                               return -1;
-                       }
-               }
--              
-+
-               if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(ldap, dn, pw))) {
-                       log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));
--                      
-+
-                       ldap_unbind_s(ldap);
--                      
-+
-                       return -1;
-               }
--              
-+
-               /* 5. */
-               ldap_unbind_s(ldap);
--              
-+
-               /* everything worked, good, access granted */
--              
-+
-               return 0;
- #endif
-       }
-@@ -664,65 +628,65 @@
- int http_auth_basic_check(server *srv, connection *con, mod_auth_plugin_data *p, array *req, buffer *url, const char *realm_str) {
-       buffer *username, *password;
-       char *pw;
--      
-+
-       data_string *realm;
--      
-+
-       realm = (data_string *)array_get_element(req, "realm");
--      
-+
-       username = buffer_init();
-       password = buffer_init();
--      
-+
-       base64_decode(username, realm_str);
--      
-+
-       /* r2 == user:password */
-       if (NULL == (pw = strchr(username->ptr, ':'))) {
-               buffer_free(username);
--              
-+
-               log_error_write(srv, __FILE__, __LINE__, "sb", ": is missing in", username);
--              
-+
-               return 0;
-       }
--      
-+
-       *pw++ = '\0';
--      
-+
-       username->used = pw - username->ptr;
--      
-+
-       /* copy password to r1 */
-       if (http_auth_get_password(srv, p, username, realm->value, password)) {
-               buffer_free(username);
-               buffer_free(password);
--              
-+
-               log_error_write(srv, __FILE__, __LINE__, "s", "get_password failed");
--              
-+
-               return 0;
-       }
--      
-+
-       /* password doesn't match */
-       if (http_auth_basic_password_compare(srv, p, req, username, realm->value, password, pw)) {
-               log_error_write(srv, __FILE__, __LINE__, "sbb", "password doesn't match for", con->uri.path, username);
--              
-+
-               buffer_free(username);
-               buffer_free(password);
--              
-+
-               return 0;
-       }
--      
-+
-       /* value is our allow-rules */
-       if (http_auth_match_rules(srv, p, url->ptr, username->ptr, NULL, NULL)) {
-               buffer_free(username);
-               buffer_free(password);
--              
-+
-               log_error_write(srv, __FILE__, __LINE__, "s", "rules didn't match");
--              
-+
-               return 0;
-       }
--      
-+
-       /* remember the username */
-       buffer_copy_string_buffer(p->auth_user, username);
--      
-+
-       buffer_free(username);
-       buffer_free(password);
--      
-+
-       return 1;
- }
-@@ -735,7 +699,7 @@
- int http_auth_digest_check(server *srv, connection *con, mod_auth_plugin_data *p, array *req, buffer *url, const char *realm_str) {
-       char a1[256];
-       char a2[256];
--      
-+
-       char *username;
-       char *realm;
-       char *nonce;
-@@ -745,18 +709,18 @@
-       char *cnonce;
-       char *nc;
-       char *respons;
--      
-+
-       char *e, *c;
-       const char *m = NULL;
-       int i;
-       buffer *password, *b, *username_buf, *realm_buf;
--      
-+
-       MD5_CTX Md5Ctx;
-       HASH HA1;
-       HASH HA2;
-       HASH RespHash;
-       HASHHEX HA2Hex;
--      
-+
-       /* init pointers */
- #define S(x) \
-@@ -771,11 +735,11 @@
-               { S("cnonce=") },
-               { S("nc=") },
-               { S("response=") },
--              
-+
-               { NULL, 0, NULL }
-       };
- #undef S
--      
-+
-       dkv[0].ptr = &username;
-       dkv[1].ptr = &realm;
-       dkv[2].ptr = &nonce;
-@@ -786,24 +750,24 @@
-       dkv[7].ptr = &nc;
-       dkv[8].ptr = &respons;
-       dkv[9].ptr = NULL;
--      
-+
-       UNUSED(req);
--      
-+
-       for (i = 0; dkv[i].key; i++) {
-               *(dkv[i].ptr) = NULL;
-       }
--      
--      
-+
-+
-       if (p->conf.auth_backend != AUTH_BACKEND_HTDIGEST &&
-           p->conf.auth_backend != AUTH_BACKEND_PLAIN) {
--              log_error_write(srv, __FILE__, __LINE__, "s", 
-+              log_error_write(srv, __FILE__, __LINE__, "s",
-                               "digest: unsupported backend (only htdigest or plain)");
--              
-+
-               return -1;
-       }
--      
-+
-       b = buffer_init_string(realm_str);
--      
-+
-       /* parse credentials from client */
-       for (c = b->ptr; *c; c++) {
-               /* skip whitespaces */
-@@ -812,18 +776,18 @@
-               for (i = 0; dkv[i].key; i++) {
-                       if ((0 == strncmp(c, dkv[i].key, dkv[i].key_len))) {
--                              if ((c[dkv[i].key_len] == '"') && 
-+                              if ((c[dkv[i].key_len] == '"') &&
-                                   (NULL != (e = strchr(c + dkv[i].key_len + 1, '"')))) {
-                                       /* value with "..." */
-                                       *(dkv[i].ptr) = c + dkv[i].key_len + 1;
-                                       c = e;
--      
-+
-                                       *e = '\0';
-                               } else if (NULL != (e = strchr(c + dkv[i].key_len, ','))) {
-                                       /* value without "...", terminated by ',' */
-                                       *(dkv[i].ptr) = c + dkv[i].key_len;
-                                       c = e;
--                                      
-+
-                                       *e = '\0';
-                               } else {
-                                       /* value without "...", terminated by EOL */
-@@ -833,7 +797,7 @@
-                       }
-               }
-       }
--      
-+
-       if (p->conf.auth_debug > 1) {
-               log_error_write(srv, __FILE__, __LINE__, "ss", "username", username);
-               log_error_write(srv, __FILE__, __LINE__, "ss", "realm", realm);
-@@ -845,22 +809,22 @@
-               log_error_write(srv, __FILE__, __LINE__, "ss", "nc", nc);
-               log_error_write(srv, __FILE__, __LINE__, "ss", "response", respons);
-       }
--      
-+
-       /* check if everything is transmitted */
--      if (!username || 
-+      if (!username ||
-           !realm ||
-           !nonce ||
-           !uri ||
-           (qop && (!nc || !cnonce)) ||
-           !respons ) {
-               /* missing field */
--              
--              log_error_write(srv, __FILE__, __LINE__, "s", 
-+
-+              log_error_write(srv, __FILE__, __LINE__, "s",
-                               "digest: missing field");
-               return -1;
-       }
--      m = get_http_method_name(con->request.http_method);     
-+      m = get_http_method_name(con->request.http_method);
-       /* password-string == HA1 */
-       password = buffer_init();
-@@ -873,10 +837,10 @@
-               buffer_free(realm_buf);
-               return 0;
-       }
--      
-+
-       buffer_free(username_buf);
-       buffer_free(realm_buf);
--      
-+
-       if (p->conf.auth_backend == AUTH_BACKEND_PLAIN) {
-               /* generate password from plain-text */
-               MD5_Init(&Md5Ctx);
-@@ -890,16 +854,16 @@
-               /* HA1 */
-               /* transform the 32-byte-hex-md5 to a 16-byte-md5 */
-               for (i = 0; i < HASHLEN; i++) {
--                      HA1[i] = hex2int(password->ptr[i*2]) << 4; 
--                      HA1[i] |= hex2int(password->ptr[i*2+1]); 
-+                      HA1[i] = hex2int(password->ptr[i*2]) << 4;
-+                      HA1[i] |= hex2int(password->ptr[i*2+1]);
-               }
-       } else {
-               /* we already check that above */
-               SEGFAULT();
-       }
--      
-+
-       buffer_free(password);
--      
-+
-       if (algorithm &&
-           strcasecmp(algorithm, "md5-sess") == 0) {
-               MD5_Init(&Md5Ctx);
-@@ -910,9 +874,9 @@
-               MD5_Update(&Md5Ctx, (unsigned char *)cnonce, strlen(cnonce));
-               MD5_Final(HA1, &Md5Ctx);
-       }
--      
-+
-       CvtHex(HA1, a1);
--      
-+
-       /* calculate H(A2) */
-       MD5_Init(&Md5Ctx);
-       MD5_Update(&Md5Ctx, (unsigned char *)m, strlen(m));
-@@ -924,7 +888,7 @@
-       }
-       MD5_Final(HA2, &Md5Ctx);
-       CvtHex(HA2, HA2Hex);
--      
-+
-       /* calculate response */
-       MD5_Init(&Md5Ctx);
-       MD5_Update(&Md5Ctx, (unsigned char *)a1, HASHHEXLEN);
-@@ -942,39 +906,39 @@
-       MD5_Update(&Md5Ctx, (unsigned char *)HA2Hex, HASHHEXLEN);
-       MD5_Final(RespHash, &Md5Ctx);
-       CvtHex(RespHash, a2);
--      
-+
-       if (0 != strcmp(a2, respons)) {
-               /* digest not ok */
--              
-+
-               if (p->conf.auth_debug) {
--                      log_error_write(srv, __FILE__, __LINE__, "sss", 
-+                      log_error_write(srv, __FILE__, __LINE__, "sss",
-                               "digest: digest mismatch", a2, respons);
-               }
--              
--              log_error_write(srv, __FILE__, __LINE__, "sss", 
-+
-+              log_error_write(srv, __FILE__, __LINE__, "sss",
-                               "digest: auth failed for", username, "wrong password");
--              
-+
-               buffer_free(b);
-               return 0;
-       }
--      
-+
-       /* value is our allow-rules */
-       if (http_auth_match_rules(srv, p, url->ptr, username, NULL, NULL)) {
-               buffer_free(b);
--              
--              log_error_write(srv, __FILE__, __LINE__, "s", 
-+
-+              log_error_write(srv, __FILE__, __LINE__, "s",
-                               "digest: rules did match");
--              
-+
-               return 0;
-       }
--      
-+
-       /* remember the username */
-       buffer_copy_string(p->auth_user, username);
--      
-+
-       buffer_free(b);
--      
-+
-       if (p->conf.auth_debug) {
--              log_error_write(srv, __FILE__, __LINE__, "s", 
-+              log_error_write(srv, __FILE__, __LINE__, "s",
-                               "digest: auth ok");
-       }
-       return 1;
-@@ -985,23 +949,23 @@
-       HASH h;
-       MD5_CTX Md5Ctx;
-       char hh[32];
--      
-+
-       UNUSED(p);
-       /* generate shared-secret */
-       MD5_Init(&Md5Ctx);
-       MD5_Update(&Md5Ctx, (unsigned char *)fn->ptr, fn->used - 1);
-       MD5_Update(&Md5Ctx, (unsigned char *)"+", 1);
--      
-+
-       /* we assume sizeof(time_t) == 4 here, but if not it ain't a problem at all */
-       ltostr(hh, srv->cur_ts);
-       MD5_Update(&Md5Ctx, (unsigned char *)hh, strlen(hh));
-       ltostr(hh, rand());
-       MD5_Update(&Md5Ctx, (unsigned char *)hh, strlen(hh));
--      
-+
-       MD5_Final(h, &Md5Ctx);
--      
-+
-       CvtHex(h, out);
--      
-+
-       return 0;
- }
---- ../lighttpd-1.4.11/src/http_auth.h 2005-08-14 17:12:31.000000000 +0300
-+++ lighttpd-1.5.0/src/http_auth.h     2006-07-16 00:26:04.000000000 +0300
-@@ -9,22 +9,26 @@
- # include <ldap.h>
- #endif
--typedef enum { AUTH_BACKEND_UNSET, AUTH_BACKEND_PLAIN, 
--              AUTH_BACKEND_LDAP, AUTH_BACKEND_HTPASSWD, 
--              AUTH_BACKEND_HTDIGEST, AUTH_BACKEND_PAM } auth_backend_t;
-+typedef enum {
-+      AUTH_BACKEND_UNSET,
-+      AUTH_BACKEND_PLAIN,
-+      AUTH_BACKEND_LDAP,
-+      AUTH_BACKEND_HTPASSWD,
-+      AUTH_BACKEND_HTDIGEST
-+} auth_backend_t;
- typedef struct {
-       /* auth */
-       array  *auth_require;
--      
-+
-       buffer *auth_plain_groupfile;
-       buffer *auth_plain_userfile;
--      
-+
-       buffer *auth_htdigest_userfile;
-       buffer *auth_htpasswd_userfile;
--      
-+
-       buffer *auth_backend_conf;
--      
-+
-       buffer *auth_ldap_hostname;
-       buffer *auth_ldap_basedn;
-       buffer *auth_ldap_binddn;
-@@ -32,15 +36,15 @@
-       buffer *auth_ldap_filter;
-       buffer *auth_ldap_cafile;
-       unsigned short auth_ldap_starttls;
--      
-+
-       unsigned short auth_debug;
--      
-+
-       /* generated */
-       auth_backend_t auth_backend;
--      
-+
- #ifdef USE_LDAP
-       LDAP *ldap;
--      
-+
-       buffer *ldap_filter_pre;
-       buffer *ldap_filter_post;
- #endif
-@@ -49,15 +53,15 @@
- typedef struct {
-       PLUGIN_DATA;
-       buffer *tmp_buf;
--      
-+
-       buffer *auth_user;
- #ifdef USE_LDAP
-       buffer *ldap_filter;
- #endif
--      
-+
-       mod_auth_plugin_config **config_storage;
--      
-+
-       mod_auth_plugin_config conf; /* this is only used as long as no handler_ctx is setup */
- } mod_auth_plugin_data;
---- ../lighttpd-1.4.11/src/http_auth_digest.h  2006-01-05 00:54:01.000000000 +0200
-+++ lighttpd-1.5.0/src/http_auth_digest.h      2006-07-16 00:26:04.000000000 +0300
-@@ -12,7 +12,7 @@
- #ifdef USE_OPENSSL
- #define IN const
- #else
--#define IN 
-+#define IN
- #endif
- #define OUT
---- ../lighttpd-1.4.11/src/http_chunk.c        2005-08-11 01:26:50.000000000 +0300
-+++ lighttpd-1.5.0/src/http_chunk.c    1970-01-01 03:00:00.000000000 +0300
-@@ -1,133 +0,0 @@
--/**
-- * the HTTP chunk-API
-- * 
-- * 
-- */
--
--#include <sys/types.h>
--#include <sys/stat.h>
--
--#include <stdlib.h>
--#include <fcntl.h>
--#include <unistd.h>
--
--#include <stdio.h>
--#include <errno.h>
--#include <string.h>
--
--#include "server.h"
--#include "chunk.h"
--#include "http_chunk.h"
--#include "log.h"
--
--static int http_chunk_append_len(server *srv, connection *con, size_t len) {
--      size_t i, olen = len, j;
--      buffer *b;
--      
--      b = srv->tmp_chunk_len;
--      
--      if (len == 0) {
--              buffer_copy_string(b, "0");
--      } else {
--              for (i = 0; i < 8 && len; i++) {
--                      len >>= 4;
--              }
--              
--              /* i is the number of hex digits we have */
--              buffer_prepare_copy(b, i + 1);
--              
--              for (j = i-1, len = olen; j+1 > 0; j--) {
--                      b->ptr[j] = (len & 0xf) + (((len & 0xf) <= 9) ? '0' : 'a' - 10);
--                      len >>= 4;
--              }
--              b->used = i;
--              b->ptr[b->used++] = '\0';
--      }
--              
--      buffer_append_string(b, "\r\n");
--      chunkqueue_append_buffer(con->write_queue, b);
--      
--      return 0;
--}
--
--
--int http_chunk_append_file(server *srv, connection *con, buffer *fn, off_t offset, off_t len) {
--      chunkqueue *cq;
--      
--      if (!con) return -1;
--      
--      cq = con->write_queue;
--      
--      if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
--              http_chunk_append_len(srv, con, len);
--      }
--      
--      chunkqueue_append_file(cq, fn, offset, len);
--      
--      if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED && len > 0) {
--              chunkqueue_append_mem(cq, "\r\n", 2 + 1);
--      }
--      
--      return 0;
--}
--
--int http_chunk_append_buffer(server *srv, connection *con, buffer *mem) {
--      chunkqueue *cq;
--      
--      if (!con) return -1;
--      
--      cq = con->write_queue;
--      
--      if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
--              http_chunk_append_len(srv, con, mem->used - 1);
--      }
--      
--      chunkqueue_append_buffer(cq, mem);
--      
--      if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED && mem->used > 0) {
--              chunkqueue_append_mem(cq, "\r\n", 2 + 1);
--      }
--      
--      return 0;
--}
--
--int http_chunk_append_mem(server *srv, connection *con, const char * mem, size_t len) {
--      chunkqueue *cq;
--      
--      if (!con) return -1;
--      
--      cq = con->write_queue;
--      
--      if (len == 0) {
--              if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
--                      http_chunk_append_len(srv, con, 0);
--                      chunkqueue_append_mem(cq, "\r\n", 2 + 1);
--              } else {
--                      chunkqueue_append_mem(cq, "", 1);
--              }
--              return 0;
--      }
--      
--      if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
--              http_chunk_append_len(srv, con, len - 1);
--      }
--      
--      chunkqueue_append_mem(cq, mem, len);
--      
--      if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
--              chunkqueue_append_mem(cq, "\r\n", 2 + 1);
--      }
--      
--      return 0;
--}
--
--
--off_t http_chunkqueue_length(server *srv, connection *con) {
--      if (!con) {
--              log_error_write(srv, __FILE__, __LINE__, "s", "connection is NULL!!");
--              
--              return 0;
--      }
--      
--      return chunkqueue_length(con->write_queue);
--}
---- ../lighttpd-1.4.11/src/http_chunk.h        2005-08-11 01:26:50.000000000 +0300
-+++ lighttpd-1.5.0/src/http_chunk.h    1970-01-01 03:00:00.000000000 +0300
-@@ -1,12 +0,0 @@
--#ifndef _HTTP_CHUNK_H_
--#define _HTTP_CHUNK_H_
--
--#include "server.h"
--#include <sys/types.h>
--
--int http_chunk_append_mem(server *srv, connection *con, const char * mem, size_t len);
--int http_chunk_append_buffer(server *srv, connection *con, buffer *mem);
--int http_chunk_append_file(server *srv, connection *con, buffer *fn, off_t offset, off_t len);
--off_t http_chunkqueue_length(server *srv, connection *con);
--
--#endif
---- ../lighttpd-1.4.11/src/http_parser.h       1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/http_parser.h   2006-09-07 00:57:05.000000000 +0300
-@@ -0,0 +1,11 @@
-+#ifndef _HTTP_PARSER_H_
-+#define _HTTP_PARSER_H_
-+
-+typedef enum {
-+    PARSE_UNSET,
-+    PARSE_SUCCESS,
-+    PARSE_ERROR,
-+    PARSE_NEED_MORE
-+} parse_status_t;
-+
-+#endif
---- ../lighttpd-1.4.11/src/http_req.c  1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/http_req.c      2006-09-07 00:57:05.000000000 +0300
-@@ -0,0 +1,301 @@
-+#include <string.h>
-+#include <stdlib.h>
-+#include <stdio.h>
-+#include <assert.h>
-+
-+#include "log.h"
-+#include "http_req.h"
-+#include "http_req_parser.h"
-+
-+/* declare prototypes for the parser */
-+void *http_req_parserAlloc(void *(*mallocProc)(size_t));
-+void http_req_parserFree(void *p,  void (*freeProc)(void*));
-+void http_req_parserTrace(FILE *TraceFILE, char *zTracePrompt);
-+void http_req_parser(void *, int, buffer *, http_req_ctx_t *);
-+
-+typedef struct {
-+      chunkqueue *cq;
-+
-+      chunk *c; /* current chunk in the chunkqueue */
-+      size_t offset; /* current offset in current chunk */
-+
-+      chunk *lookup_c;
-+      size_t lookup_offset;
-+
-+      int last_token_id;
-+
-+      int is_key;
-+      int is_statusline;
-+} http_req_tokenizer_t;
-+
-+http_req *http_request_init(void) {
-+      http_req *req = calloc(1, sizeof(*req));
-+
-+      req->uri_raw = buffer_init();
-+      req->headers = array_init();
-+
-+      return req;
-+}
-+
-+void http_request_reset(http_req *req) {
-+      if (!req) return;
-+
-+      buffer_reset(req->uri_raw);
-+      array_reset(req->headers);
-+
-+}
-+
-+void http_request_free(http_req *req) {
-+      if (!req) return;
-+
-+      buffer_free(req->uri_raw);
-+      array_free(req->headers);
-+
-+      free(req);
-+}
-+
-+static int http_req_get_next_char(http_req_tokenizer_t *t, unsigned char *c) {
-+      if (t->c->mem->used == 0) {
-+              TRACE("chunk-len: %zd", t->c->mem->used);
-+      }
-+
-+      if (t->offset == t->c->mem->used - 1) {
-+              /* end of chunk, open next chunk */
-+
-+              if (!t->c->next) return -1;
-+
-+              t->c = t->c->next;
-+              /* skip empty chunks */
-+              while (t->c && t->c->mem->used == 0) t->c = t->c->next;
-+              if (!t->c) return -1;
-+
-+              t->offset = 0;
-+      }
-+
-+      *c = t->c->mem->ptr[t->offset++];
-+
-+      t->lookup_offset = t->offset;
-+      t->lookup_c = t->c;
-+
-+#if 0
-+      fprintf(stderr, "%s.%d: get: %c (%d) at offset: %d\r\n", __FILE__, __LINE__, *c > 31 ? *c : ' ', *c, t->offset - 1);
-+#endif
-+
-+      return 0;
-+}
-+
-+static int http_req_lookup_next_char(http_req_tokenizer_t *t, unsigned char *c) {
-+      if (t->lookup_c->mem->used == 0) {
-+              TRACE("chunk-len: %zd", t->lookup_c->mem->used);
-+      }
-+      if (t->lookup_offset == t->lookup_c->mem->used - 1) {
-+              /* end of chunk, open next chunk */
-+
-+              if (!t->lookup_c->next) return -1;
-+
-+              t->lookup_c = t->lookup_c->next;
-+
-+              /* skip empty chunks */
-+              while (t->lookup_c && t->lookup_c->mem->used == 0) t->lookup_c = t->lookup_c->next;
-+              if (!t->lookup_c) return -1;
-+
-+              t->lookup_offset = 0;
-+      }
-+
-+      *c = t->lookup_c->mem->ptr[t->lookup_offset++];
-+#if 0
-+      fprintf(stderr, "%s.%d: lookup: %c (%d) at offset: %d\r\n", __FILE__, __LINE__, *c > 31 ? *c : ' ', *c, t->lookup_offset - 1);
-+#endif
-+
-+      return 0;
-+}
-+
-+
-+static int http_req_tokenizer(
-+      http_req_tokenizer_t *t,
-+      int *token_id,
-+      buffer *token
-+) {
-+      unsigned char c;
-+      int tid = 0;
-+
-+      /* push the token to the parser */
-+
-+      while (tid == 0 && 0 == http_req_get_next_char(t, &c)) {
-+              switch (c) {
-+              case ':':
-+                      tid = TK_COLON;
-+
-+                      t->is_key = 0;
-+
-+                      break;
-+              case ' ':
-+              case '\t':
-+                      if (t->last_token_id == TK_CRLF) {
-+                              /* WS as the start of a line */
-+
-+                              tid = TK_TAB;
-+                              t->is_key = 0;
-+                      }
-+                      /* ignore the rest of the WS-chars */
-+                      break;
-+              case '\r':
-+                      if (0 != http_req_lookup_next_char(t, &c)) return -1;
-+
-+                      if (c == '\n') {
-+                              tid = TK_CRLF;
-+
-+                              t->c = t->lookup_c;
-+                              t->offset = t->lookup_offset;
-+
-+                              t->is_statusline = 0;
-+                              t->is_key = 1;
-+                      } else {
-+                              fprintf(stderr, "%s.%d: CR with out LF\r\n", __FILE__, __LINE__);
-+                              return -1;
-+                      }
-+                      break;
-+              case '\n':
-+                      tid = TK_CRLF;
-+
-+                      t->is_statusline = 0;
-+                      t->is_key = 1;
-+
-+                      break;
-+              default:
-+                      while (c >= 32 && c != 127 && c != 255) {
-+                              if (t->is_statusline) {
-+                                      if (c == 32) break; /* the space is a splitter in the statusline */
-+                              } else {
-+                                      if (t->is_key) {
-+                                              if (c == ':') break; /* the : is the splitter between key and value */
-+                                              if (c == ' ') break; /* no spaces in keys */
-+                                      }
-+                              }
-+                              if (0 != http_req_lookup_next_char(t, &c)) return -1;
-+                      }
-+
-+                      if (t->c == t->lookup_c &&
-+                              t->offset == t->lookup_offset + 1) {
-+
-+                              fprintf(stderr, "%s.%d: invalid char in string\n", __FILE__, __LINE__);
-+                              return -1;
-+                      }
-+
-+                      tid = TK_STRING;
-+
-+                      /* the lookup points to the first invalid char */
-+                      t->lookup_offset--;
-+
-+                      /* no overlapping string */
-+                      if (t->c == t->lookup_c) {
-+                              buffer_copy_string_len(token, t->c->mem->ptr + t->offset - 1, t->lookup_offset - t->offset + 1);
-+                      } else {
-+                              /* first chunk */
-+                              buffer_copy_string_len(token, t->c->mem->ptr + t->offset - 1, t->c->mem->used - t->offset);
-+
-+                              /* chunks in the middle */
-+                              for (t->c = t->c->next; t->c != t->lookup_c; t->c = t->c->next) {
-+                                      buffer_append_string_buffer(token, t->c->mem);
-+                                      t->offset = t->c->mem->used - 1;
-+                              }
-+
-+                              /* last chunk */
-+                              buffer_append_string_len(token, t->c->mem->ptr, t->lookup_offset);
-+                      }
-+
-+                      t->offset = t->lookup_offset;
-+
-+                      break;
-+              }
-+      }
-+
-+      if (tid) {
-+              *token_id = tid;
-+
-+              return 1;
-+      }
-+
-+      return -1;
-+}
-+
-+parse_status_t http_request_parse_cq(chunkqueue *cq, http_req *req) {
-+      http_req_tokenizer_t t;
-+      void *pParser = NULL;
-+      int token_id = 0;
-+      buffer *token = NULL;
-+      http_req_ctx_t context;
-+      parse_status_t ret = PARSE_UNSET;
-+
-+      t.cq = cq;
-+      t.c = cq->first;
-+      t.offset = t.c->offset;
-+      t.is_key = 0;
-+      t.is_statusline = 1;
-+      t.last_token_id = 0;
-+
-+      context.ok = 1;
-+      context.errmsg = buffer_init();
-+      context.req = req;
-+
-+      pParser = http_req_parserAlloc( malloc );
-+      token = buffer_init();
-+
-+#if 0
-+      http_req_parserTrace(stderr, "http-request: "); 
-+#endif
-+
-+      while((1 == http_req_tokenizer(&t, &token_id, token)) && context.ok) {
-+              http_req_parser(pParser, token_id, token, &context);
-+
-+              token = buffer_init();
-+
-+              /* CRLF CRLF ... the header end sequence */
-+              if (t.last_token_id == TK_CRLF &&
-+                  token_id == TK_CRLF) break;
-+
-+              t.last_token_id = token_id;
-+      }
-+
-+      /* oops, the parser failed */
-+      if (context.ok == 0) {
-+              ret = PARSE_ERROR;
-+
-+              if (!buffer_is_empty(context.errmsg)) {
-+                      TRACE("parsing failed: %s", BUF_STR(context.errmsg));
-+              } else {
-+                      TRACE("%s", "parsing failed ... (no error-msg)");
-+              }
-+      }
-+
-+      http_req_parser(pParser, 0, token, &context);
-+      http_req_parserFree(pParser, free);
-+
-+      if (context.ok == 0) {
-+              /* we are missing the some tokens */
-+
-+              if (!buffer_is_empty(context.errmsg)) {
-+                      TRACE("parsing failed: %s", BUF_STR(context.errmsg));
-+              }
-+
-+              if (ret == PARSE_UNSET) {
-+                      ret = buffer_is_empty(context.errmsg) ? PARSE_NEED_MORE : PARSE_ERROR;
-+              }
-+      } else {
-+              chunk *c;
-+
-+              for (c = cq->first; c != t.c; c = c->next) {
-+                      c->offset = c->mem->used - 1;
-+              }
-+
-+              c->offset = t.offset;
-+
-+              ret = PARSE_SUCCESS;
-+      }
-+
-+      buffer_free(token);
-+      buffer_free(context.errmsg);
-+
-+      return ret;
-+}
-+
---- ../lighttpd-1.4.11/src/http_req.h  1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/http_req.h      2006-09-07 00:57:05.000000000 +0300
-@@ -0,0 +1,28 @@
-+#ifndef _HTTP_REQ_H_
-+#define _HTTP_REQ_H_
-+
-+#include "array.h"
-+#include "chunk.h"
-+#include "http_parser.h"
-+
-+typedef struct {
-+    int protocol;   /* http/1.0, http/1.1 */
-+    int method;     /* e.g. GET */
-+    buffer *uri_raw; /* e.g. /foobar/ */
-+    array *headers;
-+} http_req;
-+
-+typedef struct {
-+      int     ok;
-+      buffer *errmsg;
-+
-+      http_req *req;
-+} http_req_ctx_t;
-+
-+http_req *http_request_init(void);
-+void http_request_free(http_req *req);
-+void http_request_reset(http_req *req);
-+
-+parse_status_t http_request_parse_cq(chunkqueue *cq, http_req *http_request);
-+
-+#endif
---- ../lighttpd-1.4.11/src/http_req_parser.c   1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/http_req_parser.c       2006-09-07 01:02:19.000000000 +0300
-@@ -0,0 +1,914 @@
-+/* Driver template for the LEMON parser generator.
-+** The author disclaims copyright to this source code.
-+*/
-+/* First off, code is include which follows the "include" declaration
-+** in the input file. */
-+#include <stdio.h>
-+#line 6 "./http_req_parser.y"
-+
-+#include <assert.h>
-+#include <string.h>
-+#include "http_req.h"
-+#include "keyvalue.h"
-+#include "array.h"
-+#include "log.h"
-+
-+#line 17 "http_req_parser.c"
-+/* Next is all token values, in a form suitable for use by makeheaders.
-+** This section will be null unless lemon is run with the -m switch.
-+*/
-+/*
-+** These constants (all generated automatically by the parser generator)
-+** specify the various kinds of tokens (terminals) that the parser
-+** understands.
-+**
-+** Each symbol here is a terminal symbol in the grammar.
-+*/
-+/* Make sure the INTERFACE macro is defined.
-+*/
-+#ifndef INTERFACE
-+# define INTERFACE 1
-+#endif
-+/* The next thing included is series of defines which control
-+** various aspects of the generated parser.
-+**    YYCODETYPE         is the data type used for storing terminal
-+**                       and nonterminal numbers.  "unsigned char" is
-+**                       used if there are fewer than 250 terminals
-+**                       and nonterminals.  "int" is used otherwise.
-+**    YYNOCODE           is a number of type YYCODETYPE which corresponds
-+**                       to no legal terminal or nonterminal number.  This
-+**                       number is used to fill in empty slots of the hash
-+**                       table.
-+**    YYFALLBACK         If defined, this indicates that one or more tokens
-+**                       have fall-back values which should be used if the
-+**                       original value of the token will not parse.
-+**    YYACTIONTYPE       is the data type used for storing terminal
-+**                       and nonterminal numbers.  "unsigned char" is
-+**                       used if there are fewer than 250 rules and
-+**                       states combined.  "int" is used otherwise.
-+**    http_req_parserTOKENTYPE     is the data type used for minor tokens given
-+**                       directly to the parser from the tokenizer.
-+**    YYMINORTYPE        is the data type used for all minor tokens.
-+**                       This is typically a union of many types, one of
-+**                       which is http_req_parserTOKENTYPE.  The entry in the union
-+**                       for base tokens is called "yy0".
-+**    YYSTACKDEPTH       is the maximum depth of the parser's stack.
-+**    http_req_parserARG_SDECL     A static variable declaration for the %extra_argument
-+**    http_req_parserARG_PDECL     A parameter declaration for the %extra_argument
-+**    http_req_parserARG_STORE     Code to store %extra_argument into yypParser
-+**    http_req_parserARG_FETCH     Code to extract %extra_argument from yypParser
-+**    YYNSTATE           the combined number of states.
-+**    YYNRULE            the number of rules in the grammar
-+**    YYERRORSYMBOL      is the code number of the error symbol.  If not
-+**                       defined, then do no error processing.
-+*/
-+/* \ 1 */
-+#define YYCODETYPE unsigned char
-+#define YYNOCODE 13
-+#define YYACTIONTYPE unsigned char
-+#define http_req_parserTOKENTYPE buffer *
-+typedef union {
-+  http_req_parserTOKENTYPE yy0;
-+  http_req * yy2;
-+  array * yy6;
-+  http_method_t yy8;
-+  data_string * yy15;
-+  buffer * yy17;
-+  http_version_t yy21;
-+  int yy25;
-+} YYMINORTYPE;
-+#define YYSTACKDEPTH 100
-+#define http_req_parserARG_SDECL http_req_ctx_t *ctx;
-+#define http_req_parserARG_PDECL ,http_req_ctx_t *ctx
-+#define http_req_parserARG_FETCH http_req_ctx_t *ctx = yypParser->ctx
-+#define http_req_parserARG_STORE yypParser->ctx = ctx
-+#define YYNSTATE 20
-+#define YYNRULE 10
-+#define YYERRORSYMBOL 5
-+#define YYERRSYMDT yy25
-+#define YY_NO_ACTION      (YYNSTATE+YYNRULE+2)
-+#define YY_ACCEPT_ACTION  (YYNSTATE+YYNRULE+1)
-+#define YY_ERROR_ACTION   (YYNSTATE+YYNRULE)
-+
-+/* Next are that tables used to determine what action to take based on the
-+** current state and lookahead token.  These tables are used to implement
-+** functions that take a state number and lookahead value and return an
-+** action integer.
-+**
-+** Suppose the action integer is N.  Then the action is determined as
-+** follows
-+**
-+**   0 <= N < YYNSTATE                  Shift N.  That is, push the lookahead
-+**                                      token onto the stack and goto state N.
-+**
-+**   YYNSTATE <= N < YYNSTATE+YYNRULE   Reduce by rule N-YYNSTATE.
-+**
-+**   N == YYNSTATE+YYNRULE              A syntax error has occurred.
-+**
-+**   N == YYNSTATE+YYNRULE+1            The parser accepts its input.
-+**
-+**   N == YYNSTATE+YYNRULE+2            No such action.  Denotes unused
-+**                                      slots in the yy_action[] table.
-+**
-+** The action table is constructed as a single large table named yy_action[].
-+** Given state S and lookahead X, the action is computed as
-+**
-+**      yy_action[ yy_shift_ofst[S] + X ]
-+**
-+** If the index value yy_shift_ofst[S]+X is out of range or if the value
-+** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S]
-+** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table
-+** and that yy_default[S] should be used instead.
-+**
-+** The formula above is for computing the action when the lookahead is
-+** a terminal symbol.  If the lookahead is a non-terminal (as occurs after
-+** a reduce action) then the yy_reduce_ofst[] array is used in place of
-+** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of
-+** YY_SHIFT_USE_DFLT.
-+**
-+** The following are the tables generated in this section:
-+**
-+**  yy_action[]        A single table containing all actions.
-+**  yy_lookahead[]     A table containing the lookahead for each entry in
-+**                     yy_action.  Used to detect hash collisions.
-+**  yy_shift_ofst[]    For each state, the offset into yy_action for
-+**                     shifting terminals.
-+**  yy_reduce_ofst[]   For each state, the offset into yy_action for
-+**                     shifting non-terminals after a reduce.
-+**  yy_default[]       Default action for each state.
-+*/
-+static YYACTIONTYPE yy_action[] = {
-+ /*     0 */     1,   31,    8,   16,    5,   17,    8,    6,   12,   11,
-+ /*    10 */    19,    2,   18,    7,    3,    4,   20,    9,   24,   13,
-+ /*    20 */    24,   12,   14,   10,   21,   23,   15,   22,
-+};
-+static YYCODETYPE yy_lookahead[] = {
-+ /*     0 */     7,    8,    1,    2,    9,   10,    1,    2,    1,    2,
-+ /*    10 */     1,    1,    1,   10,    6,    2,    0,    3,   12,    2,
-+ /*    20 */    12,    1,    4,   11,    0,    2,   11,    1,
-+};
-+#define YY_SHIFT_USE_DFLT (-1)
-+static signed char yy_shift_ofst[] = {
-+ /*     0 */     9,   10,   11,   13,    1,    5,   16,   -1,   14,    7,
-+ /*    10 */    -1,   -1,   17,   18,   20,   -1,   24,   -1,   23,   26,
-+};
-+#define YY_REDUCE_USE_DFLT (-8)
-+static signed char yy_reduce_ofst[] = {
-+ /*     0 */    -7,   -8,    8,   -8,   -5,    3,   -8,   -8,   -8,   12,
-+ /*    10 */    -8,   -8,   -8,   -8,   15,   -8,   -8,   -8,   -8,   -8,
-+};
-+static YYACTIONTYPE yy_default[] = {
-+ /*     0 */    30,   30,   30,   30,   30,   30,   30,   24,   30,   30,
-+ /*    10 */    26,   27,   30,   29,   30,   28,   30,   25,   30,   30,
-+};
-+#define YY_SZ_ACTTAB (sizeof(yy_action)/sizeof(yy_action[0]))
-+
-+/* The next table maps tokens into fallback tokens.  If a construct
-+** like the following:
-+**
-+**      %fallback ID X Y Z.
-+**
-+** appears in the grammer, then ID becomes a fallback token for X, Y,
-+** and Z.  Whenever one of the tokens X, Y, or Z is input to the parser
-+** but it does not parse, the type of the token is changed to ID and
-+** the parse is retried before an error is thrown.
-+*/
-+#ifdef YYFALLBACK
-+static const YYCODETYPE yyFallback[] = {
-+};
-+#endif /* YYFALLBACK */
-+
-+/* The following structure represents a single element of the
-+** parser's stack.  Information stored includes:
-+**
-+**   +  The state number for the parser at this level of the stack.
-+**
-+**   +  The value of the token stored at this level of the stack.
-+**      (In other words, the "major" token.)
-+**
-+**   +  The semantic value stored at this level of the stack.  This is
-+**      the information used by the action routines in the grammar.
-+**      It is sometimes called the "minor" token.
-+*/
-+struct yyStackEntry {
-+  int stateno;       /* The state-number */
-+  int major;         /* The major token value.  This is the code
-+                     ** number for the token at this stack level */
-+  YYMINORTYPE minor; /* The user-supplied minor token value.  This
-+                     ** is the value of the token  */
-+};
-+typedef struct yyStackEntry yyStackEntry;
-+
-+/* The state of the parser is completely contained in an instance of
-+** the following structure */
-+struct yyParser {
-+  int yyidx;                    /* Index of top element in stack */
-+  int yyerrcnt;                 /* Shifts left before out of the error */
-+  http_req_parserARG_SDECL                /* A place to hold %extra_argument */
-+  yyStackEntry yystack[YYSTACKDEPTH];  /* The parser's stack */
-+};
-+typedef struct yyParser yyParser;
-+
-+#ifndef NDEBUG
-+#include <stdio.h>
-+static FILE *yyTraceFILE = 0;
-+static char *yyTracePrompt = 0;
-+#endif /* NDEBUG */
-+
-+#ifndef NDEBUG
-+/*
-+** Turn parser tracing on by giving a stream to which to write the trace
-+** and a prompt to preface each trace message.  Tracing is turned off
-+** by making either argument NULL
-+**
-+** Inputs:
-+** <ul>
-+** <li> A FILE* to which trace output should be written.
-+**      If NULL, then tracing is turned off.
-+** <li> A prefix string written at the beginning of every
-+**      line of trace output.  If NULL, then tracing is
-+**      turned off.
-+** </ul>
-+**
-+** Outputs:
-+** None.
-+*/
-+void http_req_parserTrace(FILE *TraceFILE, char *zTracePrompt){
-+  yyTraceFILE = TraceFILE;
-+  yyTracePrompt = zTracePrompt;
-+  if( yyTraceFILE==0 ) yyTracePrompt = 0;
-+  else if( yyTracePrompt==0 ) yyTraceFILE = 0;
-+}
-+#endif /* NDEBUG */
-+
-+#ifndef NDEBUG
-+/* For tracing shifts, the names of all terminals and nonterminals
-+** are required.  The following table supplies these names */
-+static const char *yyTokenName[] = {
-+  "$",             "STRING",        "CRLF",          "COLON",       
-+  "TAB",           "error",         "protocol",      "method",      
-+  "request_hdr",   "headers",       "header",        "multiline",   
-+};
-+#endif /* NDEBUG */
-+
-+#ifndef NDEBUG
-+/* For tracing reduce actions, the names of all rules are required.
-+*/
-+static const char *yyRuleName[] = {
-+ /*   0 */ "request_hdr ::= method STRING protocol CRLF headers CRLF",
-+ /*   1 */ "request_hdr ::= method STRING protocol CRLF CRLF",
-+ /*   2 */ "method ::= STRING",
-+ /*   3 */ "protocol ::= STRING",
-+ /*   4 */ "headers ::= headers header",
-+ /*   5 */ "headers ::= header",
-+ /*   6 */ "header ::= STRING COLON multiline",
-+ /*   7 */ "header ::= STRING COLON CRLF",
-+ /*   8 */ "multiline ::= STRING CRLF TAB multiline",
-+ /*   9 */ "multiline ::= STRING CRLF",
-+};
-+#endif /* NDEBUG */
-+
-+/*
-+** This function returns the symbolic name associated with a token
-+** value.
-+*/
-+const char *http_req_parserTokenName(int tokenType){
-+#ifndef NDEBUG
-+  if( tokenType>0 && tokenType<(sizeof(yyTokenName)/sizeof(yyTokenName[0])) ){
-+    return yyTokenName[tokenType];
-+  }else{
-+    return "Unknown";
-+  }
-+#else
-+  return "";
-+#endif
-+}
-+
-+/*
-+** This function allocates a new parser.
-+** The only argument is a pointer to a function which works like
-+** malloc.
-+**
-+** Inputs:
-+** A pointer to the function used to allocate memory.
-+**
-+** Outputs:
-+** A pointer to a parser.  This pointer is used in subsequent calls
-+** to http_req_parser and http_req_parserFree.
-+*/
-+void *http_req_parserAlloc(void *(*mallocProc)(size_t)){
-+  yyParser *pParser;
-+  pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) );
-+  if( pParser ){
-+    pParser->yyidx = -1;
-+  }
-+  return pParser;
-+}
-+
-+/* The following function deletes the value associated with a
-+** symbol.  The symbol can be either a terminal or nonterminal.
-+** "yymajor" is the symbol code, and "yypminor" is a pointer to
-+** the value.
-+*/
-+static void yy_destructor(YYCODETYPE yymajor, YYMINORTYPE *yypminor){
-+  switch( yymajor ){
-+    /* Here is inserted the actions which take place when a
-+    ** terminal or non-terminal is destroyed.  This can happen
-+    ** when the symbol is popped from the stack during a
-+    ** reduce or during error processing or when a parser is
-+    ** being destroyed before it is finished parsing.
-+    **
-+    ** Note: during a reduce, the only symbols destroyed are those
-+    ** which appear on the RHS of the rule, but which are not used
-+    ** inside the C code.
-+    */
-+    case 1:
-+    case 2:
-+    case 3:
-+    case 4:
-+#line 25 "./http_req_parser.y"
-+{ buffer_free((yypminor->yy0)); }
-+#line 331 "http_req_parser.c"
-+      break;
-+    default:  break;   /* If no destructor action specified: do nothing */
-+  }
-+}
-+
-+/*
-+** Pop the parser's stack once.
-+**
-+** If there is a destructor routine associated with the token which
-+** is popped from the stack, then call it.
-+**
-+** Return the major token number for the symbol popped.
-+*/
-+static int yy_pop_parser_stack(yyParser *pParser){
-+  YYCODETYPE yymajor;
-+  yyStackEntry *yytos = &pParser->yystack[pParser->yyidx];
-+
-+  if( pParser->yyidx<0 ) return 0;
-+#ifndef NDEBUG
-+  if( yyTraceFILE && pParser->yyidx>=0 ){
-+    fprintf(yyTraceFILE,"%sPopping %s\n",
-+      yyTracePrompt,
-+      yyTokenName[yytos->major]);
-+  }
-+#endif
-+  yymajor = yytos->major;
-+  yy_destructor( yymajor, &yytos->minor);
-+  pParser->yyidx--;
-+  return yymajor;
-+}
-+
-+/*
-+** Deallocate and destroy a parser.  Destructors are all called for
-+** all stack elements before shutting the parser down.
-+**
-+** Inputs:
-+** <ul>
-+** <li>  A pointer to the parser.  This should be a pointer
-+**       obtained from http_req_parserAlloc.
-+** <li>  A pointer to a function used to reclaim memory obtained
-+**       from malloc.
-+** </ul>
-+*/
-+void http_req_parserFree(
-+  void *p,                    /* The parser to be deleted */
-+  void (*freeProc)(void*)     /* Function used to reclaim memory */
-+){
-+  yyParser *pParser = (yyParser*)p;
-+  if( pParser==0 ) return;
-+  while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser);
-+  (*freeProc)((void*)pParser);
-+}
-+
-+/*
-+** Find the appropriate action for a parser given the terminal
-+** look-ahead token iLookAhead.
-+**
-+** If the look-ahead token is YYNOCODE, then check to see if the action is
-+** independent of the look-ahead.  If it is, return the action, otherwise
-+** return YY_NO_ACTION.
-+*/
-+static int yy_find_shift_action(
-+  yyParser *pParser,        /* The parser */
-+  int iLookAhead            /* The look-ahead token */
-+){
-+  int i;
-+  int stateno = pParser->yystack[pParser->yyidx].stateno;
-+
-+  /* if( pParser->yyidx<0 ) return YY_NO_ACTION;  */
-+  i = yy_shift_ofst[stateno];
-+  if( i==YY_SHIFT_USE_DFLT ){
-+    return yy_default[stateno];
-+  }
-+  if( iLookAhead==YYNOCODE ){
-+    return YY_NO_ACTION;
-+  }
-+  i += iLookAhead;
-+  if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){
-+#ifdef YYFALLBACK
-+    int iFallback;            /* Fallback token */
-+    if( iLookAhead<sizeof(yyFallback)/sizeof(yyFallback[0])
-+           && (iFallback = yyFallback[iLookAhead])!=0 ){
-+#ifndef NDEBUG
-+      if( yyTraceFILE ){
-+        fprintf(yyTraceFILE, "%sFALLBACK %s => %s\n",
-+           yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]);
-+      }
-+#endif
-+      return yy_find_shift_action(pParser, iFallback);
-+    }
-+#endif
-+    return yy_default[stateno];
-+  }else{
-+    return yy_action[i];
-+  }
-+}
-+
-+/*
-+** Find the appropriate action for a parser given the non-terminal
-+** look-ahead token iLookAhead.
-+**
-+** If the look-ahead token is YYNOCODE, then check to see if the action is
-+** independent of the look-ahead.  If it is, return the action, otherwise
-+** return YY_NO_ACTION.
-+*/
-+static int yy_find_reduce_action(
-+  yyParser *pParser,        /* The parser */
-+  int iLookAhead            /* The look-ahead token */
-+){
-+  int i;
-+  int stateno = pParser->yystack[pParser->yyidx].stateno;
-+
-+  i = yy_reduce_ofst[stateno];
-+  if( i==YY_REDUCE_USE_DFLT ){
-+    return yy_default[stateno];
-+  }
-+  if( iLookAhead==YYNOCODE ){
-+    return YY_NO_ACTION;
-+  }
-+  i += iLookAhead;
-+  if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){
-+    return yy_default[stateno];
-+  }else{
-+    return yy_action[i];
-+  }
-+}
-+
-+/*
-+** Perform a shift action.
-+*/
-+static void yy_shift(
-+  yyParser *yypParser,          /* The parser to be shifted */
-+  int yyNewState,               /* The new state to shift in */
-+  int yyMajor,                  /* The major token to shift in */
-+  YYMINORTYPE *yypMinor         /* Pointer ot the minor token to shift in */
-+){
-+  yyStackEntry *yytos;
-+  yypParser->yyidx++;
-+  if( yypParser->yyidx>=YYSTACKDEPTH ){
-+     http_req_parserARG_FETCH;
-+     yypParser->yyidx--;
-+#ifndef NDEBUG
-+     if( yyTraceFILE ){
-+       fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt);
-+     }
-+#endif
-+     while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
-+     /* Here code is inserted which will execute if the parser
-+     ** stack every overflows */
-+     http_req_parserARG_STORE; /* Suppress warning about unused %extra_argument var */
-+     return;
-+  }
-+  yytos = &yypParser->yystack[yypParser->yyidx];
-+  yytos->stateno = yyNewState;
-+  yytos->major = yyMajor;
-+  yytos->minor = *yypMinor;
-+#ifndef NDEBUG
-+  if( yyTraceFILE && yypParser->yyidx>0 ){
-+    int i;
-+    fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState);
-+    fprintf(yyTraceFILE,"%sStack:",yyTracePrompt);
-+    for(i=1; i<=yypParser->yyidx; i++)
-+      fprintf(yyTraceFILE," %s",yyTokenName[yypParser->yystack[i].major]);
-+    fprintf(yyTraceFILE,"\n");
-+  }
-+#endif
-+}
-+
-+/* The following table contains information about every rule that
-+** is used during the reduce.
-+*/
-+static struct {
-+  YYCODETYPE lhs;         /* Symbol on the left-hand side of the rule */
-+  unsigned char nrhs;     /* Number of right-hand side symbols in the rule */
-+} yyRuleInfo[] = {
-+  { 8, 6 },
-+  { 8, 5 },
-+  { 7, 1 },
-+  { 6, 1 },
-+  { 9, 2 },
-+  { 9, 1 },
-+  { 10, 3 },
-+  { 10, 3 },
-+  { 11, 4 },
-+  { 11, 2 },
-+};
-+
-+static void yy_accept(yyParser*);  /* Forward Declaration */
-+
-+/*
-+** Perform a reduce action and the shift that must immediately
-+** follow the reduce.
-+*/
-+static void yy_reduce(
-+  yyParser *yypParser,         /* The parser */
-+  int yyruleno                 /* Number of the rule by which to reduce */
-+){
-+  int yygoto;                     /* The next state */
-+  int yyact;                      /* The next action */
-+  YYMINORTYPE yygotominor;        /* The LHS of the rule reduced */
-+  yyStackEntry *yymsp;            /* The top of the parser's stack */
-+  int yysize;                     /* Amount to pop the stack */
-+  http_req_parserARG_FETCH;
-+  yymsp = &yypParser->yystack[yypParser->yyidx];
-+#ifndef NDEBUG
-+  if( yyTraceFILE && yyruleno>=0
-+        && yyruleno<sizeof(yyRuleName)/sizeof(yyRuleName[0]) ){
-+    fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt,
-+      yyRuleName[yyruleno]);
-+  }
-+#endif /* NDEBUG */
-+
-+  switch( yyruleno ){
-+  /* Beginning here are the reduction cases.  A typical example
-+  ** follows:
-+  **   case 0:
-+  **  #line <lineno> <grammarfile>
-+  **     { ... }           // User supplied code
-+  **  #line <lineno> <thisfile>
-+  **     break;
-+  */
-+      case 0:
-+#line 28 "./http_req_parser.y"
-+{
-+    http_req *req = ctx->req;
-+    
-+    req->method = yymsp[-5].minor.yy8;
-+    req->protocol = yymsp[-3].minor.yy21;
-+    buffer_copy_string_buffer(req->uri_raw, yymsp[-4].minor.yy0);
-+    buffer_free(yymsp[-4].minor.yy0); 
-+
-+    array_free(req->headers);
-+    
-+    req->headers = yymsp[-1].minor.yy6;
-+}
-+#line 567 "http_req_parser.c"
-+  yy_destructor(2,&yymsp[-2].minor);
-+  yy_destructor(2,&yymsp[0].minor);
-+        break;
-+      case 1:
-+#line 41 "./http_req_parser.y"
-+{
-+    http_req *req = ctx->req;
-+    
-+    req->method = yymsp[-4].minor.yy8;
-+    req->protocol = yymsp[-2].minor.yy21;
-+    buffer_copy_string_buffer(req->uri_raw, yymsp[-3].minor.yy0);
-+    buffer_free(yymsp[-3].minor.yy0); 
-+}
-+#line 581 "http_req_parser.c"
-+  yy_destructor(2,&yymsp[-1].minor);
-+  yy_destructor(2,&yymsp[0].minor);
-+        break;
-+      case 2:
-+#line 51 "./http_req_parser.y"
-+{
-+    yygotominor.yy8 = get_http_method_key(BUF_STR(yymsp[0].minor.yy0));
-+
-+    buffer_free(yymsp[0].minor.yy0);
-+}
-+#line 592 "http_req_parser.c"
-+        break;
-+      case 3:
-+#line 57 "./http_req_parser.y"
-+{
-+    /* the protocol might be HTTP/1.0 or HTTP/1.1
-+    *  the version string is allowed to have leading zeros
-+    */
-+    yygotominor.yy21 = HTTP_VERSION_UNSET;
-+
-+    if (0 == strncmp(BUF_STR(yymsp[0].minor.yy0), "HTTP/", 5)) {
-+       char *err = NULL;
-+       /* is there a dot */
-+       char *major, *minor;
-+       
-+       major = BUF_STR(yymsp[0].minor.yy0) + 5;
-+       minor = strchr(major, '.');
-+       if (minor) {
-+         int hi, lo;
-+         hi = strtol(major, &err, 10);
-+         minor++;
-+         if (*err == '.' && *minor != '\0') {
-+            lo = strtol(minor, &err, 10);
-+            if (*err == '\0') {
-+              if (hi == 1 && lo == 1) {
-+                yygotominor.yy21 = HTTP_VERSION_1_1;
-+              } else if (hi == 1 && lo == 0) {
-+                yygotominor.yy21 = HTTP_VERSION_1_0;
-+              }
-+            }
-+         }
-+       }
-+    }
-+
-+    buffer_free(yymsp[0].minor.yy0);
-+}
-+#line 628 "http_req_parser.c"
-+        break;
-+      case 4:
-+#line 90 "./http_req_parser.y"
-+{
-+    yygotominor.yy6 = yymsp[-1].minor.yy6;
-+   
-+    if (yymsp[0].minor.yy15) { 
-+      array_insert_unique(yygotominor.yy6, (data_unset *)yymsp[0].minor.yy15);
-+    }
-+}
-+#line 639 "http_req_parser.c"
-+        break;
-+      case 5:
-+#line 98 "./http_req_parser.y"
-+{
-+    if (yymsp[0].minor.yy15) {
-+      yygotominor.yy6 = array_init();
-+
-+      array_insert_unique(yygotominor.yy6, (data_unset *)yymsp[0].minor.yy15);
-+    }
-+}
-+#line 650 "http_req_parser.c"
-+        break;
-+      case 6:
-+#line 106 "./http_req_parser.y"
-+{
-+    yygotominor.yy15 = data_string_init();
-+    
-+    buffer_copy_string_buffer(yygotominor.yy15->key, yymsp[-2].minor.yy0);
-+    buffer_copy_string_buffer(yygotominor.yy15->value, yymsp[0].minor.yy17);    
-+    buffer_free(yymsp[-2].minor.yy0);
-+    buffer_free(yymsp[0].minor.yy17);
-+}
-+#line 662 "http_req_parser.c"
-+  yy_destructor(3,&yymsp[-1].minor);
-+        break;
-+      case 7:
-+#line 115 "./http_req_parser.y"
-+{
-+    /* ignore empty header fields */
-+
-+    yygotominor.yy15 = NULL;
-+}
-+#line 672 "http_req_parser.c"
-+  yy_destructor(1,&yymsp[-2].minor);
-+  yy_destructor(3,&yymsp[-1].minor);
-+  yy_destructor(2,&yymsp[0].minor);
-+        break;
-+      case 8:
-+#line 121 "./http_req_parser.y"
-+{
-+   buffer_append_string_buffer(yymsp[-3].minor.yy0, yymsp[0].minor.yy17);
-+   yygotominor.yy17 = yymsp[-3].minor.yy0;
-+
-+   yymsp[-3].minor.yy0 = NULL;
-+   buffer_free(yymsp[0].minor.yy17);
-+}
-+#line 686 "http_req_parser.c"
-+  yy_destructor(2,&yymsp[-2].minor);
-+  yy_destructor(4,&yymsp[-1].minor);
-+        break;
-+      case 9:
-+#line 130 "./http_req_parser.y"
-+{
-+   yygotominor.yy17 = yymsp[-1].minor.yy0;
-+
-+   yymsp[-1].minor.yy0 = NULL;
-+}
-+#line 697 "http_req_parser.c"
-+  yy_destructor(2,&yymsp[0].minor);
-+        break;
-+  };
-+  yygoto = yyRuleInfo[yyruleno].lhs;
-+  yysize = yyRuleInfo[yyruleno].nrhs;
-+  yypParser->yyidx -= yysize;
-+  yyact = yy_find_reduce_action(yypParser,yygoto);
-+  if( yyact < YYNSTATE ){
-+    yy_shift(yypParser,yyact,yygoto,&yygotominor);
-+  }else if( yyact == YYNSTATE + YYNRULE + 1 ){
-+    yy_accept(yypParser);
-+  }
-+}
-+
-+/*
-+** The following code executes when the parse fails
-+*/
-+static void yy_parse_failed(
-+  yyParser *yypParser           /* The parser */
-+){
-+  http_req_parserARG_FETCH;
-+#ifndef NDEBUG
-+  if( yyTraceFILE ){
-+    fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt);
-+  }
-+#endif
-+  while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
-+  /* Here code is inserted which will be executed whenever the
-+  ** parser fails */
-+#line 15 "./http_req_parser.y"
-+
-+  ctx->ok = 0;
-+
-+#line 731 "http_req_parser.c"
-+  http_req_parserARG_STORE; /* Suppress warning about unused %extra_argument variable */
-+}
-+
-+/*
-+** The following code executes when a syntax error first occurs.
-+*/
-+static void yy_syntax_error(
-+  yyParser *yypParser,           /* The parser */
-+  int yymajor,                   /* The major type of the error token */
-+  YYMINORTYPE yyminor            /* The minor type of the error token */
-+){
-+  http_req_parserARG_FETCH;
-+#define TOKEN (yyminor.yy0)
-+  http_req_parserARG_STORE; /* Suppress warning about unused %extra_argument variable */
-+}
-+
-+/*
-+** The following is executed when the parser accepts
-+*/
-+static void yy_accept(
-+  yyParser *yypParser           /* The parser */
-+){
-+  http_req_parserARG_FETCH;
-+#ifndef NDEBUG
-+  if( yyTraceFILE ){
-+    fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt);
-+  }
-+#endif
-+  while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
-+  /* Here code is inserted which will be executed whenever the
-+  ** parser accepts */
-+  http_req_parserARG_STORE; /* Suppress warning about unused %extra_argument variable */
-+}
-+
-+/* The main parser program.
-+** The first argument is a pointer to a structure obtained from
-+** "http_req_parserAlloc" which describes the current state of the parser.
-+** The second argument is the major token number.  The third is
-+** the minor token.  The fourth optional argument is whatever the
-+** user wants (and specified in the grammar) and is available for
-+** use by the action routines.
-+**
-+** Inputs:
-+** <ul>
-+** <li> A pointer to the parser (an opaque structure.)
-+** <li> The major token number.
-+** <li> The minor token number.
-+** <li> An option argument of a grammar-specified type.
-+** </ul>
-+**
-+** Outputs:
-+** None.
-+*/
-+void http_req_parser(
-+  void *yyp,                   /* The parser */
-+  int yymajor,                 /* The major token code number */
-+  http_req_parserTOKENTYPE yyminor       /* The value for the token */
-+  http_req_parserARG_PDECL               /* Optional %extra_argument parameter */
-+){
-+  YYMINORTYPE yyminorunion;
-+  int yyact;            /* The parser action. */
-+  int yyendofinput;     /* True if we are at the end of input */
-+  int yyerrorhit = 0;   /* True if yymajor has invoked an error */
-+  yyParser *yypParser;  /* The parser */
-+
-+  /* (re)initialize the parser, if necessary */
-+  yypParser = (yyParser*)yyp;
-+  if( yypParser->yyidx<0 ){
-+    if( yymajor==0 ) return;
-+    yypParser->yyidx = 0;
-+    yypParser->yyerrcnt = -1;
-+    yypParser->yystack[0].stateno = 0;
-+    yypParser->yystack[0].major = 0;
-+  }
-+  yyminorunion.yy0 = yyminor;
-+  yyendofinput = (yymajor==0);
-+  http_req_parserARG_STORE;
-+
-+#ifndef NDEBUG
-+  if( yyTraceFILE ){
-+    fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]);
-+  }
-+#endif
-+
-+  do{
-+    yyact = yy_find_shift_action(yypParser,yymajor);
-+    if( yyact<YYNSTATE ){
-+      yy_shift(yypParser,yyact,yymajor,&yyminorunion);
-+      yypParser->yyerrcnt--;
-+      if( yyendofinput && yypParser->yyidx>=0 ){
-+        yymajor = 0;
-+      }else{
-+        yymajor = YYNOCODE;
-+      }
-+    }else if( yyact < YYNSTATE + YYNRULE ){
-+      yy_reduce(yypParser,yyact-YYNSTATE);
-+    }else if( yyact == YY_ERROR_ACTION ){
-+      int yymx;
-+#ifndef NDEBUG
-+      if( yyTraceFILE ){
-+        fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt);
-+      }
-+#endif
-+#ifdef YYERRORSYMBOL
-+      /* A syntax error has occurred.
-+      ** The response to an error depends upon whether or not the
-+      ** grammar defines an error token "ERROR".
-+      **
-+      ** This is what we do if the grammar does define ERROR:
-+      **
-+      **  * Call the %syntax_error function.
-+      **
-+      **  * Begin popping the stack until we enter a state where
-+      **    it is legal to shift the error symbol, then shift
-+      **    the error symbol.
-+      **
-+      **  * Set the error count to three.
-+      **
-+      **  * Begin accepting and shifting new tokens.  No new error
-+      **    processing will occur until three tokens have been
-+      **    shifted successfully.
-+      **
-+      */
-+      if( yypParser->yyerrcnt<0 ){
-+        yy_syntax_error(yypParser,yymajor,yyminorunion);
-+      }
-+      yymx = yypParser->yystack[yypParser->yyidx].major;
-+      if( yymx==YYERRORSYMBOL || yyerrorhit ){
-+#ifndef NDEBUG
-+        if( yyTraceFILE ){
-+          fprintf(yyTraceFILE,"%sDiscard input token %s\n",
-+             yyTracePrompt,yyTokenName[yymajor]);
-+        }
-+#endif
-+        yy_destructor(yymajor,&yyminorunion);
-+        yymajor = YYNOCODE;
-+      }else{
-+         while(
-+          yypParser->yyidx >= 0 &&
-+          yymx != YYERRORSYMBOL &&
-+          (yyact = yy_find_shift_action(yypParser,YYERRORSYMBOL)) >= YYNSTATE
-+        ){
-+          yy_pop_parser_stack(yypParser);
-+        }
-+        if( yypParser->yyidx < 0 || yymajor==0 ){
-+          yy_destructor(yymajor,&yyminorunion);
-+          yy_parse_failed(yypParser);
-+          yymajor = YYNOCODE;
-+        }else if( yymx!=YYERRORSYMBOL ){
-+          YYMINORTYPE u2;
-+          u2.YYERRSYMDT = 0;
-+          yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2);
-+        }
-+      }
-+      yypParser->yyerrcnt = 3;
-+      yyerrorhit = 1;
-+#else  /* YYERRORSYMBOL is not defined */
-+      /* This is what we do if the grammar does not define ERROR:
-+      **
-+      **  * Report an error message, and throw away the input token.
-+      **
-+      **  * If the input token is $, then fail the parse.
-+      **
-+      ** As before, subsequent error messages are suppressed until
-+      ** three input tokens have been successfully shifted.
-+      */
-+      if( yypParser->yyerrcnt<=0 ){
-+        yy_syntax_error(yypParser,yymajor,yyminorunion);
-+      }
-+      yypParser->yyerrcnt = 3;
-+      yy_destructor(yymajor,&yyminorunion);
-+      if( yyendofinput ){
-+        yy_parse_failed(yypParser);
-+      }
-+      yymajor = YYNOCODE;
-+#endif
-+    }else{
-+      yy_accept(yypParser);
-+      yymajor = YYNOCODE;
-+    }
-+  }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 );
-+  return;
-+}
---- ../lighttpd-1.4.11/src/http_req_parser.h   1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/http_req_parser.h       2006-09-07 01:02:19.000000000 +0300
-@@ -0,0 +1,4 @@
-+#define TK_STRING                          1
-+#define TK_CRLF                            2
-+#define TK_COLON                           3
-+#define TK_TAB                             4
---- ../lighttpd-1.4.11/src/http_req_parser.y   1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/http_req_parser.y       2006-09-07 00:57:05.000000000 +0300
-@@ -0,0 +1,136 @@
-+%token_prefix TK_
-+%token_type {buffer *}
-+%extra_argument {http_req_ctx_t *ctx}
-+%name http_req_parser
-+
-+%include {
-+#include <assert.h>
-+#include <string.h>
-+#include "http_req.h"
-+#include "keyvalue.h"
-+#include "array.h"
-+#include "log.h"
-+}
-+
-+%parse_failure {
-+  ctx->ok = 0;
-+}
-+
-+%type protocol { http_version_t }
-+%type method { http_method_t }
-+%type request_hdr { http_req * }
-+%type headers { array * }
-+%type header { data_string * }
-+%type multiline { buffer * }
-+%token_destructor { buffer_free($$); }
-+
-+/* GET ... HTTP/1.0 */
-+request_hdr ::= method(B) STRING(C) protocol(D) CRLF headers(HDR) CRLF . {
-+    http_req *req = ctx->req;
-+    
-+    req->method = B;
-+    req->protocol = D;
-+    buffer_copy_string_buffer(req->uri_raw, C);
-+    buffer_free(C); 
-+
-+    array_free(req->headers);
-+    
-+    req->headers = HDR;
-+}
-+
-+request_hdr ::= method(B) STRING(C) protocol(D) CRLF CRLF . {
-+    http_req *req = ctx->req;
-+    
-+    req->method = B;
-+    req->protocol = D;
-+    buffer_copy_string_buffer(req->uri_raw, C);
-+    buffer_free(C); 
-+}
-+
-+
-+method(A) ::= STRING(B) . {
-+    A = get_http_method_key(BUF_STR(B));
-+
-+    buffer_free(B);
-+}
-+
-+protocol(A) ::= STRING(B). {
-+    /* the protocol might be HTTP/1.0 or HTTP/1.1
-+    *  the version string is allowed to have leading zeros
-+    */
-+    A = HTTP_VERSION_UNSET;
-+
-+    if (0 == strncmp(BUF_STR(B), "HTTP/", 5)) {
-+       char *err = NULL;
-+       /* is there a dot */
-+       char *major, *minor;
-+       
-+       major = BUF_STR(B) + 5;
-+       minor = strchr(major, '.');
-+       if (minor) {
-+         int hi, lo;
-+         hi = strtol(major, &err, 10);
-+         minor++;
-+         if (*err == '.' && *minor != '\0') {
-+            lo = strtol(minor, &err, 10);
-+            if (*err == '\0') {
-+              if (hi == 1 && lo == 1) {
-+                A = HTTP_VERSION_1_1;
-+              } else if (hi == 1 && lo == 0) {
-+                A = HTTP_VERSION_1_0;
-+              }
-+            }
-+         }
-+       }
-+    }
-+
-+    buffer_free(B);
-+}
-+
-+headers(HDRS) ::= headers(SRC) header(HDR). {
-+    HDRS = SRC;
-+   
-+    if (HDR) { 
-+      array_insert_unique(HDRS, (data_unset *)HDR);
-+    }
-+}
-+
-+headers(HDRS) ::= header(HDR). {
-+    if (HDR) {
-+      HDRS = array_init();
-+
-+      array_insert_unique(HDRS, (data_unset *)HDR);
-+    }
-+}
-+
-+header(HDR) ::= STRING(A) COLON multiline(B). {
-+    HDR = data_string_init();
-+    
-+    buffer_copy_string_buffer(HDR->key, A);
-+    buffer_copy_string_buffer(HDR->value, B);    
-+    buffer_free(A);
-+    buffer_free(B);
-+}
-+
-+header(HDR) ::= STRING COLON CRLF . {
-+    /* ignore empty header fields */
-+
-+    HDR = NULL;
-+}
-+
-+multiline(A) ::= STRING(B) CRLF TAB multiline(C). {
-+   buffer_append_string_buffer(B, C);
-+   A = B;
-+
-+   B = NULL;
-+   buffer_free(C);
-+}
-+
-+/* the simple form */
-+multiline(A) ::= STRING(B) CRLF. {
-+   A = B;
-+
-+   B = NULL;
-+}
-+
-+
---- ../lighttpd-1.4.11/src/http_req_range.c    1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/http_req_range.c        2006-09-07 00:57:05.000000000 +0300
-@@ -0,0 +1,192 @@
-+#include <string.h>
-+#include <stdlib.h>
-+#include <stdio.h>
-+#include <assert.h>
-+
-+#include "log.h"
-+#include "http_req_range.h"
-+#include "http_req_range_parser.h"
-+
-+/* declare prototypes for the parser */
-+void *http_req_range_parserAlloc(void *(*mallocProc)(size_t));
-+void http_req_range_parserFree(void *p,  void (*freeProc)(void*));
-+void http_req_range_parserTrace(FILE *TraceFILE, char *zTracePrompt);
-+void http_req_range_parser(void *, int, buffer *, http_req_range_ctx_t *);
-+
-+typedef struct {
-+      buffer *hdr;
-+      size_t ndx;
-+
-+      chunk *lookup_c;
-+      size_t lookup_offset;
-+} http_req_range_tokenizer_t;
-+
-+http_req_range *http_request_range_init(void) {
-+      http_req_range *range = calloc(1, sizeof(*range));
-+
-+      range->start = -1;
-+      range->end = -1;
-+
-+      return range;
-+}
-+
-+void http_request_range_reset(http_req_range *range) {
-+      if (!range) return;
-+
-+      http_request_range_free(range->next);
-+
-+      range->next = NULL;
-+
-+      range->start = -1;
-+      range->end = -1;
-+}
-+
-+void http_request_range_free(http_req_range *range) {
-+      if (!range) return;
-+
-+      http_request_range_free(range->next);
-+
-+      free(range);
-+}
-+
-+static int http_req_range_tokenizer(
-+      http_req_range_tokenizer_t *t,
-+      int *token_id,
-+      buffer *token
-+) {
-+      int tid = 0;
-+
-+      /* push the token to the parser */
-+
-+      while (tid == 0) {
-+              char c = t->hdr->ptr[t->ndx];
-+              
-+              switch (c) {
-+              case '-':
-+                      tid = TK_MINUS;
-+                      t->ndx++;
-+
-+                      break;
-+              case '=':
-+                      tid = TK_EQUAL;
-+                      t->ndx++;
-+
-+                      break;
-+              case ',':
-+                      tid = TK_COMMA;
-+                      t->ndx++;
-+
-+                      break;
-+
-+              case ' ':
-+              case '\t':
-+                      /* ignore WS */
-+                      t->ndx++;
-+                      break;
-+              case '\0':
-+                      return 0;
-+              default:
-+                      /* 'bytes' or a number */
-+                      if (0 == strncmp(t->hdr->ptr + t->ndx, "bytes", 5)) {
-+                              tid = TK_BYTES;
-+
-+                              t->ndx += 5;
-+                      } else {
-+                              size_t d;
-+                              /* */
-+                              for (d = t->ndx; d < t->hdr->used; d++) {
-+                                      char dc = t->hdr->ptr[d];
-+                                      if (dc < '0' || dc > '9') {
-+                                              break;
-+                                      }
-+                              }
-+
-+                              if (d == t->ndx) {
-+                                      /* no digit found */
-+
-+                                      TRACE("%s", "no digit found");
-+
-+                                      return -1;
-+                              }
-+
-+                              tid = TK_NUMBER;
-+
-+                              buffer_copy_string_len(token, t->hdr->ptr + t->ndx, d - t->ndx);
-+
-+                              t->ndx = d;
-+                      }
-+
-+                      break;
-+              }
-+      }
-+
-+      if (tid) {
-+              *token_id = tid;
-+
-+              return 1;
-+      }
-+
-+      return -1;
-+}
-+
-+parse_status_t http_request_range_parse(buffer *hdr, http_req_range *ranges) {
-+      http_req_range_tokenizer_t t;
-+      void *pParser = NULL;
-+      int token_id = 0;
-+      buffer *token = NULL;
-+      http_req_range_ctx_t context;
-+      parse_status_t ret = PARSE_UNSET;
-+
-+      t.hdr = hdr;
-+      t.ndx = 0;
-+
-+      context.ok = 1;
-+      context.errmsg = buffer_init();
-+      context.ranges = ranges;
-+
-+      pParser = http_req_range_parserAlloc( malloc );
-+      token = buffer_init();
-+#if 0
-+      http_req_range_parserTrace(stderr, "range: "); 
-+#endif
-+
-+      while((1 == http_req_range_tokenizer(&t, &token_id, token)) && context.ok) {
-+              http_req_range_parser(pParser, token_id, token, &context);
-+
-+              token = buffer_init();
-+      }
-+
-+      /* oops, the parser failed */
-+      if (context.ok == 0) {
-+              ret = PARSE_ERROR;
-+
-+              if (!buffer_is_empty(context.errmsg)) {
-+                      TRACE("parsing failed: %s", BUF_STR(context.errmsg));
-+              } else {
-+                      TRACE("%s", "parsing failed ...");
-+              }
-+      }
-+
-+      http_req_range_parser(pParser, 0, token, &context);
-+      http_req_range_parserFree(pParser, free);
-+
-+      if (context.ok == 0) {
-+              /* we are missing the some tokens */
-+
-+              if (!buffer_is_empty(context.errmsg)) {
-+                      TRACE("parsing failed: %s", BUF_STR(context.errmsg));
-+              }
-+
-+              if (ret == PARSE_UNSET) {
-+                      ret = buffer_is_empty(context.errmsg) ? PARSE_NEED_MORE : PARSE_ERROR;
-+              }
-+      } else {
-+              ret = PARSE_SUCCESS;
-+      }
-+
-+      buffer_free(token);
-+      buffer_free(context.errmsg);
-+
-+      return ret;
-+}
-+
---- ../lighttpd-1.4.11/src/http_req_range.h    1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/http_req_range.h        2006-09-07 00:57:05.000000000 +0300
-@@ -0,0 +1,27 @@
-+#ifndef _HTTP_REQ_RANGE_H_
-+#define _HTTP_REQ_RANGE_H_
-+
-+#include "array.h"
-+#include "chunk.h"
-+#include "http_parser.h"
-+
-+typedef struct _http_req_range {
-+      off_t start;
-+      off_t end;
-+      struct _http_req_range *next;
-+} http_req_range;
-+
-+typedef struct {
-+      int     ok;
-+      buffer *errmsg;
-+
-+      http_req_range *ranges;
-+} http_req_range_ctx_t;
-+
-+http_req_range *http_request_range_init(void);
-+void http_request_range_free(http_req_range *range);
-+void http_request_range_reset(http_req_range *range);
-+
-+parse_status_t http_request_range_parse(buffer *range_hdr, http_req_range *ranges);
-+
-+#endif
---- ../lighttpd-1.4.11/src/http_req_range_parser.c     1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/http_req_range_parser.c 2006-09-07 01:00:42.000000000 +0300
-@@ -0,0 +1,836 @@
-+/* Driver template for the LEMON parser generator.
-+** The author disclaims copyright to this source code.
-+*/
-+/* First off, code is include which follows the "include" declaration
-+** in the input file. */
-+#include <stdio.h>
-+#line 6 "./http_req_range_parser.y"
-+
-+#ifdef HAVE_CONFIG_H
-+#include "config.h"
-+#endif
-+#include <sys/types.h>
-+#include <string.h>
-+#include "http_req_range.h"
-+#include "log.h"
-+
-+#line 18 "http_req_range_parser.c"
-+/* Next is all token values, in a form suitable for use by makeheaders.
-+** This section will be null unless lemon is run with the -m switch.
-+*/
-+/*
-+** These constants (all generated automatically by the parser generator)
-+** specify the various kinds of tokens (terminals) that the parser
-+** understands.
-+**
-+** Each symbol here is a terminal symbol in the grammar.
-+*/
-+/* Make sure the INTERFACE macro is defined.
-+*/
-+#ifndef INTERFACE
-+# define INTERFACE 1
-+#endif
-+/* The next thing included is series of defines which control
-+** various aspects of the generated parser.
-+**    YYCODETYPE         is the data type used for storing terminal
-+**                       and nonterminal numbers.  "unsigned char" is
-+**                       used if there are fewer than 250 terminals
-+**                       and nonterminals.  "int" is used otherwise.
-+**    YYNOCODE           is a number of type YYCODETYPE which corresponds
-+**                       to no legal terminal or nonterminal number.  This
-+**                       number is used to fill in empty slots of the hash
-+**                       table.
-+**    YYFALLBACK         If defined, this indicates that one or more tokens
-+**                       have fall-back values which should be used if the
-+**                       original value of the token will not parse.
-+**    YYACTIONTYPE       is the data type used for storing terminal
-+**                       and nonterminal numbers.  "unsigned char" is
-+**                       used if there are fewer than 250 rules and
-+**                       states combined.  "int" is used otherwise.
-+**    http_req_range_parserTOKENTYPE     is the data type used for minor tokens given
-+**                       directly to the parser from the tokenizer.
-+**    YYMINORTYPE        is the data type used for all minor tokens.
-+**                       This is typically a union of many types, one of
-+**                       which is http_req_range_parserTOKENTYPE.  The entry in the union
-+**                       for base tokens is called "yy0".
-+**    YYSTACKDEPTH       is the maximum depth of the parser's stack.
-+**    http_req_range_parserARG_SDECL     A static variable declaration for the %extra_argument
-+**    http_req_range_parserARG_PDECL     A parameter declaration for the %extra_argument
-+**    http_req_range_parserARG_STORE     Code to store %extra_argument into yypParser
-+**    http_req_range_parserARG_FETCH     Code to extract %extra_argument from yypParser
-+**    YYNSTATE           the combined number of states.
-+**    YYNRULE            the number of rules in the grammar
-+**    YYERRORSYMBOL      is the code number of the error symbol.  If not
-+**                       defined, then do no error processing.
-+*/
-+/* \ 1 */
-+#define YYCODETYPE unsigned char
-+#define YYNOCODE 12
-+#define YYACTIONTYPE unsigned char
-+#define http_req_range_parserTOKENTYPE buffer *
-+typedef union {
-+  http_req_range_parserTOKENTYPE yy0;
-+  http_req_range * yy18;
-+  off_t yy19;
-+  int yy23;
-+} YYMINORTYPE;
-+#define YYSTACKDEPTH 100
-+#define http_req_range_parserARG_SDECL http_req_range_ctx_t *ctx;
-+#define http_req_range_parserARG_PDECL ,http_req_range_ctx_t *ctx
-+#define http_req_range_parserARG_FETCH http_req_range_ctx_t *ctx = yypParser->ctx
-+#define http_req_range_parserARG_STORE yypParser->ctx = ctx
-+#define YYNSTATE 13
-+#define YYNRULE 7
-+#define YYERRORSYMBOL 6
-+#define YYERRSYMDT yy23
-+#define YY_NO_ACTION      (YYNSTATE+YYNRULE+2)
-+#define YY_ACCEPT_ACTION  (YYNSTATE+YYNRULE+1)
-+#define YY_ERROR_ACTION   (YYNSTATE+YYNRULE)
-+
-+/* Next are that tables used to determine what action to take based on the
-+** current state and lookahead token.  These tables are used to implement
-+** functions that take a state number and lookahead value and return an
-+** action integer.
-+**
-+** Suppose the action integer is N.  Then the action is determined as
-+** follows
-+**
-+**   0 <= N < YYNSTATE                  Shift N.  That is, push the lookahead
-+**                                      token onto the stack and goto state N.
-+**
-+**   YYNSTATE <= N < YYNSTATE+YYNRULE   Reduce by rule N-YYNSTATE.
-+**
-+**   N == YYNSTATE+YYNRULE              A syntax error has occurred.
-+**
-+**   N == YYNSTATE+YYNRULE+1            The parser accepts its input.
-+**
-+**   N == YYNSTATE+YYNRULE+2            No such action.  Denotes unused
-+**                                      slots in the yy_action[] table.
-+**
-+** The action table is constructed as a single large table named yy_action[].
-+** Given state S and lookahead X, the action is computed as
-+**
-+**      yy_action[ yy_shift_ofst[S] + X ]
-+**
-+** If the index value yy_shift_ofst[S]+X is out of range or if the value
-+** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S]
-+** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table
-+** and that yy_default[S] should be used instead.
-+**
-+** The formula above is for computing the action when the lookahead is
-+** a terminal symbol.  If the lookahead is a non-terminal (as occurs after
-+** a reduce action) then the yy_reduce_ofst[] array is used in place of
-+** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of
-+** YY_SHIFT_USE_DFLT.
-+**
-+** The following are the tables generated in this section:
-+**
-+**  yy_action[]        A single table containing all actions.
-+**  yy_lookahead[]     A table containing the lookahead for each entry in
-+**                     yy_action.  Used to detect hash collisions.
-+**  yy_shift_ofst[]    For each state, the offset into yy_action for
-+**                     shifting terminals.
-+**  yy_reduce_ofst[]   For each state, the offset into yy_action for
-+**                     shifting non-terminals after a reduce.
-+**  yy_default[]       Default action for each state.
-+*/
-+static YYACTIONTYPE yy_action[] = {
-+ /*     0 */     6,   12,    3,   10,    9,   13,   21,    1,    4,    6,
-+ /*    10 */     5,    2,    7,   20,    8,    9,   20,   20,   11,
-+};
-+static YYCODETYPE yy_lookahead[] = {
-+ /*     0 */     7,    8,    9,    4,    5,    0,   10,    1,    3,    7,
-+ /*    10 */     8,    2,    4,   11,    7,    5,   11,   11,    7,
-+};
-+#define YY_SHIFT_USE_DFLT (-2)
-+static signed char yy_shift_ofst[] = {
-+ /*     0 */     6,    9,   -1,    5,   -1,   -2,    8,   10,   -2,   -2,
-+ /*    10 */    10,   -2,   -2,
-+};
-+#define YY_REDUCE_USE_DFLT (-8)
-+static signed char yy_reduce_ofst[] = {
-+ /*     0 */    -4,   -8,   -7,   -8,    2,   -8,   -8,    7,   -8,   -8,
-+ /*    10 */    11,   -8,   -8,
-+};
-+static YYACTIONTYPE yy_default[] = {
-+ /*     0 */    20,   20,   20,   20,   20,   14,   20,   16,   17,   19,
-+ /*    10 */    20,   18,   15,
-+};
-+#define YY_SZ_ACTTAB (sizeof(yy_action)/sizeof(yy_action[0]))
-+
-+/* The next table maps tokens into fallback tokens.  If a construct
-+** like the following:
-+**
-+**      %fallback ID X Y Z.
-+**
-+** appears in the grammer, then ID becomes a fallback token for X, Y,
-+** and Z.  Whenever one of the tokens X, Y, or Z is input to the parser
-+** but it does not parse, the type of the token is changed to ID and
-+** the parse is retried before an error is thrown.
-+*/
-+#ifdef YYFALLBACK
-+static const YYCODETYPE yyFallback[] = {
-+};
-+#endif /* YYFALLBACK */
-+
-+/* The following structure represents a single element of the
-+** parser's stack.  Information stored includes:
-+**
-+**   +  The state number for the parser at this level of the stack.
-+**
-+**   +  The value of the token stored at this level of the stack.
-+**      (In other words, the "major" token.)
-+**
-+**   +  The semantic value stored at this level of the stack.  This is
-+**      the information used by the action routines in the grammar.
-+**      It is sometimes called the "minor" token.
-+*/
-+struct yyStackEntry {
-+  int stateno;       /* The state-number */
-+  int major;         /* The major token value.  This is the code
-+                     ** number for the token at this stack level */
-+  YYMINORTYPE minor; /* The user-supplied minor token value.  This
-+                     ** is the value of the token  */
-+};
-+typedef struct yyStackEntry yyStackEntry;
-+
-+/* The state of the parser is completely contained in an instance of
-+** the following structure */
-+struct yyParser {
-+  int yyidx;                    /* Index of top element in stack */
-+  int yyerrcnt;                 /* Shifts left before out of the error */
-+  http_req_range_parserARG_SDECL                /* A place to hold %extra_argument */
-+  yyStackEntry yystack[YYSTACKDEPTH];  /* The parser's stack */
-+};
-+typedef struct yyParser yyParser;
-+
-+#ifndef NDEBUG
-+#include <stdio.h>
-+static FILE *yyTraceFILE = 0;
-+static char *yyTracePrompt = 0;
-+#endif /* NDEBUG */
-+
-+#ifndef NDEBUG
-+/*
-+** Turn parser tracing on by giving a stream to which to write the trace
-+** and a prompt to preface each trace message.  Tracing is turned off
-+** by making either argument NULL
-+**
-+** Inputs:
-+** <ul>
-+** <li> A FILE* to which trace output should be written.
-+**      If NULL, then tracing is turned off.
-+** <li> A prefix string written at the beginning of every
-+**      line of trace output.  If NULL, then tracing is
-+**      turned off.
-+** </ul>
-+**
-+** Outputs:
-+** None.
-+*/
-+void http_req_range_parserTrace(FILE *TraceFILE, char *zTracePrompt){
-+  yyTraceFILE = TraceFILE;
-+  yyTracePrompt = zTracePrompt;
-+  if( yyTraceFILE==0 ) yyTracePrompt = 0;
-+  else if( yyTracePrompt==0 ) yyTraceFILE = 0;
-+}
-+#endif /* NDEBUG */
-+
-+#ifndef NDEBUG
-+/* For tracing shifts, the names of all terminals and nonterminals
-+** are required.  The following table supplies these names */
-+static const char *yyTokenName[] = {
-+  "$",             "BYTES",         "EQUAL",         "COMMA",       
-+  "MINUS",         "NUMBER",        "error",         "num",         
-+  "range",         "ranges",        "range_hdr",   
-+};
-+#endif /* NDEBUG */
-+
-+#ifndef NDEBUG
-+/* For tracing reduce actions, the names of all rules are required.
-+*/
-+static const char *yyRuleName[] = {
-+ /*   0 */ "range_hdr ::= BYTES EQUAL ranges",
-+ /*   1 */ "ranges ::= ranges COMMA range",
-+ /*   2 */ "ranges ::= range",
-+ /*   3 */ "range ::= num MINUS",
-+ /*   4 */ "range ::= num MINUS num",
-+ /*   5 */ "range ::= MINUS num",
-+ /*   6 */ "num ::= NUMBER",
-+};
-+#endif /* NDEBUG */
-+
-+/*
-+** This function returns the symbolic name associated with a token
-+** value.
-+*/
-+const char *http_req_range_parserTokenName(int tokenType){
-+#ifndef NDEBUG
-+  if( tokenType>0 && tokenType<(sizeof(yyTokenName)/sizeof(yyTokenName[0])) ){
-+    return yyTokenName[tokenType];
-+  }else{
-+    return "Unknown";
-+  }
-+#else
-+  return "";
-+#endif
-+}
-+
-+/*
-+** This function allocates a new parser.
-+** The only argument is a pointer to a function which works like
-+** malloc.
-+**
-+** Inputs:
-+** A pointer to the function used to allocate memory.
-+**
-+** Outputs:
-+** A pointer to a parser.  This pointer is used in subsequent calls
-+** to http_req_range_parser and http_req_range_parserFree.
-+*/
-+void *http_req_range_parserAlloc(void *(*mallocProc)(size_t)){
-+  yyParser *pParser;
-+  pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) );
-+  if( pParser ){
-+    pParser->yyidx = -1;
-+  }
-+  return pParser;
-+}
-+
-+/* The following function deletes the value associated with a
-+** symbol.  The symbol can be either a terminal or nonterminal.
-+** "yymajor" is the symbol code, and "yypminor" is a pointer to
-+** the value.
-+*/
-+static void yy_destructor(YYCODETYPE yymajor, YYMINORTYPE *yypminor){
-+  switch( yymajor ){
-+    /* Here is inserted the actions which take place when a
-+    ** terminal or non-terminal is destroyed.  This can happen
-+    ** when the symbol is popped from the stack during a
-+    ** reduce or during error processing or when a parser is
-+    ** being destroyed before it is finished parsing.
-+    **
-+    ** Note: during a reduce, the only symbols destroyed are those
-+    ** which appear on the RHS of the rule, but which are not used
-+    ** inside the C code.
-+    */
-+    case 1:
-+    case 2:
-+    case 3:
-+    case 4:
-+    case 5:
-+#line 23 "./http_req_range_parser.y"
-+{ buffer_free((yypminor->yy0)); }
-+#line 324 "http_req_range_parser.c"
-+      break;
-+    default:  break;   /* If no destructor action specified: do nothing */
-+  }
-+}
-+
-+/*
-+** Pop the parser's stack once.
-+**
-+** If there is a destructor routine associated with the token which
-+** is popped from the stack, then call it.
-+**
-+** Return the major token number for the symbol popped.
-+*/
-+static int yy_pop_parser_stack(yyParser *pParser){
-+  YYCODETYPE yymajor;
-+  yyStackEntry *yytos = &pParser->yystack[pParser->yyidx];
-+
-+  if( pParser->yyidx<0 ) return 0;
-+#ifndef NDEBUG
-+  if( yyTraceFILE && pParser->yyidx>=0 ){
-+    fprintf(yyTraceFILE,"%sPopping %s\n",
-+      yyTracePrompt,
-+      yyTokenName[yytos->major]);
-+  }
-+#endif
-+  yymajor = yytos->major;
-+  yy_destructor( yymajor, &yytos->minor);
-+  pParser->yyidx--;
-+  return yymajor;
-+}
-+
-+/*
-+** Deallocate and destroy a parser.  Destructors are all called for
-+** all stack elements before shutting the parser down.
-+**
-+** Inputs:
-+** <ul>
-+** <li>  A pointer to the parser.  This should be a pointer
-+**       obtained from http_req_range_parserAlloc.
-+** <li>  A pointer to a function used to reclaim memory obtained
-+**       from malloc.
-+** </ul>
-+*/
-+void http_req_range_parserFree(
-+  void *p,                    /* The parser to be deleted */
-+  void (*freeProc)(void*)     /* Function used to reclaim memory */
-+){
-+  yyParser *pParser = (yyParser*)p;
-+  if( pParser==0 ) return;
-+  while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser);
-+  (*freeProc)((void*)pParser);
-+}
-+
-+/*
-+** Find the appropriate action for a parser given the terminal
-+** look-ahead token iLookAhead.
-+**
-+** If the look-ahead token is YYNOCODE, then check to see if the action is
-+** independent of the look-ahead.  If it is, return the action, otherwise
-+** return YY_NO_ACTION.
-+*/
-+static int yy_find_shift_action(
-+  yyParser *pParser,        /* The parser */
-+  int iLookAhead            /* The look-ahead token */
-+){
-+  int i;
-+  int stateno = pParser->yystack[pParser->yyidx].stateno;
-+
-+  /* if( pParser->yyidx<0 ) return YY_NO_ACTION;  */
-+  i = yy_shift_ofst[stateno];
-+  if( i==YY_SHIFT_USE_DFLT ){
-+    return yy_default[stateno];
-+  }
-+  if( iLookAhead==YYNOCODE ){
-+    return YY_NO_ACTION;
-+  }
-+  i += iLookAhead;
-+  if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){
-+#ifdef YYFALLBACK
-+    int iFallback;            /* Fallback token */
-+    if( iLookAhead<sizeof(yyFallback)/sizeof(yyFallback[0])
-+           && (iFallback = yyFallback[iLookAhead])!=0 ){
-+#ifndef NDEBUG
-+      if( yyTraceFILE ){
-+        fprintf(yyTraceFILE, "%sFALLBACK %s => %s\n",
-+           yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]);
-+      }
-+#endif
-+      return yy_find_shift_action(pParser, iFallback);
-+    }
-+#endif
-+    return yy_default[stateno];
-+  }else{
-+    return yy_action[i];
-+  }
-+}
-+
-+/*
-+** Find the appropriate action for a parser given the non-terminal
-+** look-ahead token iLookAhead.
-+**
-+** If the look-ahead token is YYNOCODE, then check to see if the action is
-+** independent of the look-ahead.  If it is, return the action, otherwise
-+** return YY_NO_ACTION.
-+*/
-+static int yy_find_reduce_action(
-+  yyParser *pParser,        /* The parser */
-+  int iLookAhead            /* The look-ahead token */
-+){
-+  int i;
-+  int stateno = pParser->yystack[pParser->yyidx].stateno;
-+
-+  i = yy_reduce_ofst[stateno];
-+  if( i==YY_REDUCE_USE_DFLT ){
-+    return yy_default[stateno];
-+  }
-+  if( iLookAhead==YYNOCODE ){
-+    return YY_NO_ACTION;
-+  }
-+  i += iLookAhead;
-+  if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){
-+    return yy_default[stateno];
-+  }else{
-+    return yy_action[i];
-+  }
-+}
-+
-+/*
-+** Perform a shift action.
-+*/
-+static void yy_shift(
-+  yyParser *yypParser,          /* The parser to be shifted */
-+  int yyNewState,               /* The new state to shift in */
-+  int yyMajor,                  /* The major token to shift in */
-+  YYMINORTYPE *yypMinor         /* Pointer ot the minor token to shift in */
-+){
-+  yyStackEntry *yytos;
-+  yypParser->yyidx++;
-+  if( yypParser->yyidx>=YYSTACKDEPTH ){
-+     http_req_range_parserARG_FETCH;
-+     yypParser->yyidx--;
-+#ifndef NDEBUG
-+     if( yyTraceFILE ){
-+       fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt);
-+     }
-+#endif
-+     while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
-+     /* Here code is inserted which will execute if the parser
-+     ** stack every overflows */
-+     http_req_range_parserARG_STORE; /* Suppress warning about unused %extra_argument var */
-+     return;
-+  }
-+  yytos = &yypParser->yystack[yypParser->yyidx];
-+  yytos->stateno = yyNewState;
-+  yytos->major = yyMajor;
-+  yytos->minor = *yypMinor;
-+#ifndef NDEBUG
-+  if( yyTraceFILE && yypParser->yyidx>0 ){
-+    int i;
-+    fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState);
-+    fprintf(yyTraceFILE,"%sStack:",yyTracePrompt);
-+    for(i=1; i<=yypParser->yyidx; i++)
-+      fprintf(yyTraceFILE," %s",yyTokenName[yypParser->yystack[i].major]);
-+    fprintf(yyTraceFILE,"\n");
-+  }
-+#endif
-+}
-+
-+/* The following table contains information about every rule that
-+** is used during the reduce.
-+*/
-+static struct {
-+  YYCODETYPE lhs;         /* Symbol on the left-hand side of the rule */
-+  unsigned char nrhs;     /* Number of right-hand side symbols in the rule */
-+} yyRuleInfo[] = {
-+  { 10, 3 },
-+  { 9, 3 },
-+  { 9, 1 },
-+  { 8, 2 },
-+  { 8, 3 },
-+  { 8, 2 },
-+  { 7, 1 },
-+};
-+
-+static void yy_accept(yyParser*);  /* Forward Declaration */
-+
-+/*
-+** Perform a reduce action and the shift that must immediately
-+** follow the reduce.
-+*/
-+static void yy_reduce(
-+  yyParser *yypParser,         /* The parser */
-+  int yyruleno                 /* Number of the rule by which to reduce */
-+){
-+  int yygoto;                     /* The next state */
-+  int yyact;                      /* The next action */
-+  YYMINORTYPE yygotominor;        /* The LHS of the rule reduced */
-+  yyStackEntry *yymsp;            /* The top of the parser's stack */
-+  int yysize;                     /* Amount to pop the stack */
-+  http_req_range_parserARG_FETCH;
-+  yymsp = &yypParser->yystack[yypParser->yyidx];
-+#ifndef NDEBUG
-+  if( yyTraceFILE && yyruleno>=0
-+        && yyruleno<sizeof(yyRuleName)/sizeof(yyRuleName[0]) ){
-+    fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt,
-+      yyRuleName[yyruleno]);
-+  }
-+#endif /* NDEBUG */
-+
-+  switch( yyruleno ){
-+  /* Beginning here are the reduction cases.  A typical example
-+  ** follows:
-+  **   case 0:
-+  **  #line <lineno> <grammarfile>
-+  **     { ... }           // User supplied code
-+  **  #line <lineno> <thisfile>
-+  **     break;
-+  */
-+      case 0:
-+#line 26 "./http_req_range_parser.y"
-+{
-+  ctx->ranges->start = yymsp[0].minor.yy18->start;
-+  ctx->ranges->end  = yymsp[0].minor.yy18->end;
-+  ctx->ranges->next = yymsp[0].minor.yy18->next;
-+
-+  yymsp[0].minor.yy18->next = NULL;
-+  http_request_range_free(yymsp[0].minor.yy18);
-+}
-+#line 553 "http_req_range_parser.c"
-+  yy_destructor(1,&yymsp[-2].minor);
-+  yy_destructor(2,&yymsp[-1].minor);
-+        break;
-+      case 1:
-+#line 35 "./http_req_range_parser.y"
-+{
-+  for (yygotominor.yy18 = yymsp[-2].minor.yy18; yygotominor.yy18->next; yygotominor.yy18 = yygotominor.yy18->next);
-+
-+  yygotominor.yy18->next = yymsp[0].minor.yy18;
-+
-+  yygotominor.yy18 = yymsp[-2].minor.yy18;
-+}
-+#line 566 "http_req_range_parser.c"
-+  yy_destructor(3,&yymsp[-1].minor);
-+        break;
-+      case 2:
-+#line 42 "./http_req_range_parser.y"
-+{
-+  yygotominor.yy18 = yymsp[0].minor.yy18;
-+}
-+#line 574 "http_req_range_parser.c"
-+        break;
-+      case 3:
-+#line 45 "./http_req_range_parser.y"
-+{
-+  http_req_range *r = http_request_range_init();
-+
-+  r->start = yymsp[-1].minor.yy19;
-+  r->end = -1;
-+
-+  yygotominor.yy18 = r;
-+}
-+#line 586 "http_req_range_parser.c"
-+  yy_destructor(4,&yymsp[0].minor);
-+        break;
-+      case 4:
-+#line 54 "./http_req_range_parser.y"
-+{
-+  http_req_range *r = http_request_range_init();
-+
-+  r->start = yymsp[-2].minor.yy19;
-+  r->end = yymsp[0].minor.yy19;
-+
-+  yygotominor.yy18 = r;
-+}
-+#line 599 "http_req_range_parser.c"
-+  yy_destructor(4,&yymsp[-1].minor);
-+        break;
-+      case 5:
-+#line 63 "./http_req_range_parser.y"
-+{
-+  http_req_range *r = http_request_range_init();
-+
-+  r->start = -1;
-+  r->end = yymsp[0].minor.yy19;
-+
-+  yygotominor.yy18 = r;
-+}
-+#line 612 "http_req_range_parser.c"
-+  yy_destructor(4,&yymsp[-1].minor);
-+        break;
-+      case 6:
-+#line 72 "./http_req_range_parser.y"
-+{
-+  yygotominor.yy19 = strtoull(BUF_STR(yymsp[0].minor.yy0), NULL, 10);
-+}
-+#line 620 "http_req_range_parser.c"
-+        break;
-+  };
-+  yygoto = yyRuleInfo[yyruleno].lhs;
-+  yysize = yyRuleInfo[yyruleno].nrhs;
-+  yypParser->yyidx -= yysize;
-+  yyact = yy_find_reduce_action(yypParser,yygoto);
-+  if( yyact < YYNSTATE ){
-+    yy_shift(yypParser,yyact,yygoto,&yygotominor);
-+  }else if( yyact == YYNSTATE + YYNRULE + 1 ){
-+    yy_accept(yypParser);
-+  }
-+}
-+
-+/*
-+** The following code executes when the parse fails
-+*/
-+static void yy_parse_failed(
-+  yyParser *yypParser           /* The parser */
-+){
-+  http_req_range_parserARG_FETCH;
-+#ifndef NDEBUG
-+  if( yyTraceFILE ){
-+    fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt);
-+  }
-+#endif
-+  while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
-+  /* Here code is inserted which will be executed whenever the
-+  ** parser fails */
-+#line 16 "./http_req_range_parser.y"
-+
-+  ctx->ok = 0;
-+
-+#line 653 "http_req_range_parser.c"
-+  http_req_range_parserARG_STORE; /* Suppress warning about unused %extra_argument variable */
-+}
-+
-+/*
-+** The following code executes when a syntax error first occurs.
-+*/
-+static void yy_syntax_error(
-+  yyParser *yypParser,           /* The parser */
-+  int yymajor,                   /* The major type of the error token */
-+  YYMINORTYPE yyminor            /* The minor type of the error token */
-+){
-+  http_req_range_parserARG_FETCH;
-+#define TOKEN (yyminor.yy0)
-+  http_req_range_parserARG_STORE; /* Suppress warning about unused %extra_argument variable */
-+}
-+
-+/*
-+** The following is executed when the parser accepts
-+*/
-+static void yy_accept(
-+  yyParser *yypParser           /* The parser */
-+){
-+  http_req_range_parserARG_FETCH;
-+#ifndef NDEBUG
-+  if( yyTraceFILE ){
-+    fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt);
-+  }
-+#endif
-+  while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
-+  /* Here code is inserted which will be executed whenever the
-+  ** parser accepts */
-+  http_req_range_parserARG_STORE; /* Suppress warning about unused %extra_argument variable */
-+}
-+
-+/* The main parser program.
-+** The first argument is a pointer to a structure obtained from
-+** "http_req_range_parserAlloc" which describes the current state of the parser.
-+** The second argument is the major token number.  The third is
-+** the minor token.  The fourth optional argument is whatever the
-+** user wants (and specified in the grammar) and is available for
-+** use by the action routines.
-+**
-+** Inputs:
-+** <ul>
-+** <li> A pointer to the parser (an opaque structure.)
-+** <li> The major token number.
-+** <li> The minor token number.
-+** <li> An option argument of a grammar-specified type.
-+** </ul>
-+**
-+** Outputs:
-+** None.
-+*/
-+void http_req_range_parser(
-+  void *yyp,                   /* The parser */
-+  int yymajor,                 /* The major token code number */
-+  http_req_range_parserTOKENTYPE yyminor       /* The value for the token */
-+  http_req_range_parserARG_PDECL               /* Optional %extra_argument parameter */
-+){
-+  YYMINORTYPE yyminorunion;
-+  int yyact;            /* The parser action. */
-+  int yyendofinput;     /* True if we are at the end of input */
-+  int yyerrorhit = 0;   /* True if yymajor has invoked an error */
-+  yyParser *yypParser;  /* The parser */
-+
-+  /* (re)initialize the parser, if necessary */
-+  yypParser = (yyParser*)yyp;
-+  if( yypParser->yyidx<0 ){
-+    if( yymajor==0 ) return;
-+    yypParser->yyidx = 0;
-+    yypParser->yyerrcnt = -1;
-+    yypParser->yystack[0].stateno = 0;
-+    yypParser->yystack[0].major = 0;
-+  }
-+  yyminorunion.yy0 = yyminor;
-+  yyendofinput = (yymajor==0);
-+  http_req_range_parserARG_STORE;
-+
-+#ifndef NDEBUG
-+  if( yyTraceFILE ){
-+    fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]);
-+  }
-+#endif
-+
-+  do{
-+    yyact = yy_find_shift_action(yypParser,yymajor);
-+    if( yyact<YYNSTATE ){
-+      yy_shift(yypParser,yyact,yymajor,&yyminorunion);
-+      yypParser->yyerrcnt--;
-+      if( yyendofinput && yypParser->yyidx>=0 ){
-+        yymajor = 0;
-+      }else{
-+        yymajor = YYNOCODE;
-+      }
-+    }else if( yyact < YYNSTATE + YYNRULE ){
-+      yy_reduce(yypParser,yyact-YYNSTATE);
-+    }else if( yyact == YY_ERROR_ACTION ){
-+      int yymx;
-+#ifndef NDEBUG
-+      if( yyTraceFILE ){
-+        fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt);
-+      }
-+#endif
-+#ifdef YYERRORSYMBOL
-+      /* A syntax error has occurred.
-+      ** The response to an error depends upon whether or not the
-+      ** grammar defines an error token "ERROR".
-+      **
-+      ** This is what we do if the grammar does define ERROR:
-+      **
-+      **  * Call the %syntax_error function.
-+      **
-+      **  * Begin popping the stack until we enter a state where
-+      **    it is legal to shift the error symbol, then shift
-+      **    the error symbol.
-+      **
-+      **  * Set the error count to three.
-+      **
-+      **  * Begin accepting and shifting new tokens.  No new error
-+      **    processing will occur until three tokens have been
-+      **    shifted successfully.
-+      **
-+      */
-+      if( yypParser->yyerrcnt<0 ){
-+        yy_syntax_error(yypParser,yymajor,yyminorunion);
-+      }
-+      yymx = yypParser->yystack[yypParser->yyidx].major;
-+      if( yymx==YYERRORSYMBOL || yyerrorhit ){
-+#ifndef NDEBUG
-+        if( yyTraceFILE ){
-+          fprintf(yyTraceFILE,"%sDiscard input token %s\n",
-+             yyTracePrompt,yyTokenName[yymajor]);
-+        }
-+#endif
-+        yy_destructor(yymajor,&yyminorunion);
-+        yymajor = YYNOCODE;
-+      }else{
-+         while(
-+          yypParser->yyidx >= 0 &&
-+          yymx != YYERRORSYMBOL &&
-+          (yyact = yy_find_shift_action(yypParser,YYERRORSYMBOL)) >= YYNSTATE
-+        ){
-+          yy_pop_parser_stack(yypParser);
-+        }
-+        if( yypParser->yyidx < 0 || yymajor==0 ){
-+          yy_destructor(yymajor,&yyminorunion);
-+          yy_parse_failed(yypParser);
-+          yymajor = YYNOCODE;
-+        }else if( yymx!=YYERRORSYMBOL ){
-+          YYMINORTYPE u2;
-+          u2.YYERRSYMDT = 0;
-+          yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2);
-+        }
-+      }
-+      yypParser->yyerrcnt = 3;
-+      yyerrorhit = 1;
-+#else  /* YYERRORSYMBOL is not defined */
-+      /* This is what we do if the grammar does not define ERROR:
-+      **
-+      **  * Report an error message, and throw away the input token.
-+      **
-+      **  * If the input token is $, then fail the parse.
-+      **
-+      ** As before, subsequent error messages are suppressed until
-+      ** three input tokens have been successfully shifted.
-+      */
-+      if( yypParser->yyerrcnt<=0 ){
-+        yy_syntax_error(yypParser,yymajor,yyminorunion);
-+      }
-+      yypParser->yyerrcnt = 3;
-+      yy_destructor(yymajor,&yyminorunion);
-+      if( yyendofinput ){
-+        yy_parse_failed(yypParser);
-+      }
-+      yymajor = YYNOCODE;
-+#endif
-+    }else{
-+      yy_accept(yypParser);
-+      yymajor = YYNOCODE;
-+    }
-+  }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 );
-+  return;
-+}
---- ../lighttpd-1.4.11/src/http_req_range_parser.h     1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/http_req_range_parser.h 2006-09-07 01:00:42.000000000 +0300
-@@ -0,0 +1,5 @@
-+#define TK_BYTES                           1
-+#define TK_EQUAL                           2
-+#define TK_COMMA                           3
-+#define TK_MINUS                           4
-+#define TK_NUMBER                          5
---- ../lighttpd-1.4.11/src/http_req_range_parser.y     1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/http_req_range_parser.y 2006-09-07 00:57:05.000000000 +0300
-@@ -0,0 +1,74 @@
-+%token_prefix TK_
-+%token_type {buffer *}
-+%extra_argument {http_req_range_ctx_t *ctx}
-+%name http_req_range_parser
-+
-+%include {
-+#ifdef HAVE_CONFIG_H
-+#include "config.h"
-+#endif
-+#include <sys/types.h>
-+#include <string.h>
-+#include "http_req_range.h"
-+#include "log.h"
-+}
-+
-+%parse_failure {
-+  ctx->ok = 0;
-+}
-+
-+%type num { off_t }
-+%type range { http_req_range * }
-+%type ranges { http_req_range * }
-+%token_destructor { buffer_free($$); }
-+
-+
-+range_hdr ::= BYTES EQUAL ranges(A) . {
-+  ctx->ranges->start = A->start;
-+  ctx->ranges->end  = A->end;
-+  ctx->ranges->next = A->next;
-+
-+  A->next = NULL;
-+  http_request_range_free(A);
-+}
-+
-+ranges(A) ::= ranges(B) COMMA range(C) . {
-+  for (A = B; A->next; A = A->next);
-+
-+  A->next = C;
-+
-+  A = B;
-+}
-+ranges(A) ::= range(B) . {
-+  A = B;
-+}
-+range(A) ::= num(B) MINUS . {
-+  http_req_range *r = http_request_range_init();
-+
-+  r->start = B;
-+  r->end = -1;
-+
-+  A = r;
-+}
-+
-+range(A) ::= num(B) MINUS num(C) . {
-+  http_req_range *r = http_request_range_init();
-+
-+  r->start = B;
-+  r->end = C;
-+
-+  A = r;
-+}
-+
-+range(A) ::= MINUS num(B) . {
-+  http_req_range *r = http_request_range_init();
-+
-+  r->start = -1;
-+  r->end = B;
-+
-+  A = r;
-+}
-+
-+num(A) ::= NUMBER(B) . {
-+  A = strtoull(BUF_STR(B), NULL, 10);
-+}
---- ../lighttpd-1.4.11/src/http_resp.c 1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/http_resp.c     2006-07-18 13:03:40.000000000 +0300
-@@ -0,0 +1,277 @@
-+#include <string.h>
-+#include <stdlib.h>
-+#include <stdio.h>
-+#include <assert.h>
-+
-+#include "log.h"
-+#include "http_resp.h"
-+#include "http_resp_parser.h"
-+
-+/* declare prototypes for the parser */
-+void *http_resp_parserAlloc(void *(*mallocProc)(size_t));
-+void http_resp_parserFree(void *p,  void (*freeProc)(void*));
-+void http_resp_parserTrace(FILE *TraceFILE, char *zTracePrompt);
-+void http_resp_parser(void *, int, buffer *, http_resp_ctx_t *);
-+
-+typedef struct {
-+      chunkqueue *cq;
-+
-+      chunk *c; /* current chunk in the chunkqueue */
-+      size_t offset; /* current offset in current chunk */
-+
-+      chunk *lookup_c;
-+      size_t lookup_offset;
-+
-+      int is_key;
-+      int is_statusline;
-+} http_resp_tokenizer_t;
-+
-+http_resp *http_response_init(void) {
-+      http_resp *resp = calloc(1, sizeof(*resp));
-+
-+      resp->reason = buffer_init();
-+      resp->headers = array_init();
-+
-+      return resp;
-+}
-+
-+void http_response_reset(http_resp *resp) {
-+      if (!resp) return;
-+
-+      buffer_reset(resp->reason);
-+      array_reset(resp->headers);
-+
-+}
-+
-+void http_response_free(http_resp *resp) {
-+      if (!resp) return;
-+
-+      buffer_free(resp->reason);
-+      array_free(resp->headers);
-+
-+      free(resp);
-+}
-+
-+static int http_resp_get_next_char(http_resp_tokenizer_t *t, unsigned char *c) {
-+      if (t->offset == t->c->mem->used - 1) {
-+              /* end of chunk, open next chunk */
-+
-+              if (!t->c->next) return -1;
-+
-+              t->c = t->c->next;
-+              t->offset = 0;
-+      }
-+
-+      *c = t->c->mem->ptr[t->offset++];
-+
-+      t->lookup_offset = t->offset;
-+      t->lookup_c = t->c;
-+
-+#if 0
-+      fprintf(stderr, "%s.%d: get: %c (%d) at offset: %d\r\n", __FILE__, __LINE__, *c > 31 ? *c : ' ', *c, t->offset - 1);
-+#endif
-+
-+      return 0;
-+}
-+
-+static int http_resp_lookup_next_char(http_resp_tokenizer_t *t, unsigned char *c) {
-+      if (t->lookup_offset == t->lookup_c->mem->used - 1) {
-+              /* end of chunk, open next chunk */
-+
-+              if (!t->lookup_c->next) return -1;
-+
-+              t->lookup_c = t->lookup_c->next;
-+              t->lookup_offset = 0;
-+      }
-+
-+      *c = t->lookup_c->mem->ptr[t->lookup_offset++];
-+#if 0
-+      fprintf(stderr, "%s.%d: lookup: %c (%d) at offset: %d\r\n", __FILE__, __LINE__, *c > 31 ? *c : ' ', *c, t->lookup_offset - 1);
-+#endif
-+
-+      return 0;
-+}
-+
-+
-+static int http_resp_tokenizer(
-+      http_resp_tokenizer_t *t,
-+      int *token_id,
-+      buffer *token
-+) {
-+      unsigned char c;
-+      int tid = 0;
-+
-+      /* push the token to the parser */
-+
-+      while (tid == 0 && 0 == http_resp_get_next_char(t, &c)) {
-+              switch (c) {
-+              case ':':
-+                      tid = TK_COLON;
-+
-+                      t->is_key = 0;
-+
-+                      break;
-+              case ' ':
-+              case '\t':
-+                      /* ignore WS */
-+
-+                      break;
-+              case '\r':
-+                      if (0 != http_resp_lookup_next_char(t, &c)) return -1;
-+
-+                      if (c == '\n') {
-+                              tid = TK_CRLF;
-+
-+                              t->c = t->lookup_c;
-+                              t->offset = t->lookup_offset;
-+
-+                              t->is_statusline = 0;
-+                              t->is_key = 1;
-+                      } else {
-+                              fprintf(stderr, "%s.%d: CR with out LF\r\n", __FILE__, __LINE__);
-+                              return -1;
-+                      }
-+                      break;
-+              case '\n':
-+                      tid = TK_CRLF;
-+
-+                      t->is_statusline = 0;
-+                      t->is_key = 1;
-+
-+                      break;
-+              default:
-+                      while (c >= 32 && c != 127 && c != 255) {
-+                              if (t->is_statusline) {
-+                                      if (c == ':') { t->is_statusline = 0; break; } /* this is not a status line by a real header */
-+                                      if (c == 32) break; /* the space is a splitter in the statusline */
-+                              } else {
-+                                      if (t->is_key) {
-+                                              if (c == ':') break; /* the : is the splitter between key and value */
-+                                      }
-+                              }
-+                              if (0 != http_resp_lookup_next_char(t, &c)) return -1;
-+                      }
-+
-+                      if (t->c == t->lookup_c &&
-+                              t->offset == t->lookup_offset + 1) {
-+
-+                              fprintf(stderr, "%s.%d: invalid char in string\n", __FILE__, __LINE__);
-+                              return -1;
-+                      }
-+
-+                      tid = TK_STRING;
-+
-+                      /* the lookup points to the first invalid char */
-+                      t->lookup_offset--;
-+
-+                      /* no overlapping string */
-+                      if (t->c == t->lookup_c) {
-+                              buffer_copy_string_len(token, t->c->mem->ptr + t->offset - 1, t->lookup_offset - t->offset + 1);
-+                      } else {
-+                              /* first chunk */
-+                              buffer_copy_string_len(token, t->c->mem->ptr + t->offset - 1, t->c->mem->used - t->offset);
-+
-+                              /* chunks in the middle */
-+                              for (t->c = t->c->next; t->c != t->lookup_c; t->c = t->c->next) {
-+                                      buffer_append_string_buffer(token, t->c->mem);
-+                                      t->offset = t->c->mem->used - 1;
-+                              }
-+
-+                              /* last chunk */
-+                              buffer_append_string_len(token, t->c->mem->ptr, t->lookup_offset);
-+                      }
-+
-+                      t->offset = t->lookup_offset;
-+
-+                      break;
-+              }
-+      }
-+
-+      if (tid) {
-+              *token_id = tid;
-+
-+              return 1;
-+      }
-+
-+      return -1;
-+}
-+
-+parse_status_t http_response_parse_cq(chunkqueue *cq, http_resp *resp) {
-+      http_resp_tokenizer_t t;
-+      void *pParser = NULL;
-+      int token_id = 0;
-+      buffer *token = NULL;
-+      http_resp_ctx_t context;
-+      parse_status_t ret = PARSE_UNSET;
-+      int last_token_id = 0;
-+
-+      t.cq = cq;
-+      t.c = cq->first;
-+      t.offset = t.c->offset;
-+      t.is_key = 0;
-+      t.is_statusline = 1;
-+
-+      context.ok = 1;
-+      context.errmsg = buffer_init();
-+      context.resp = resp;
-+
-+      pParser = http_resp_parserAlloc( malloc );
-+      token = buffer_init();
-+#if 0
-+      http_resp_parserTrace(stderr, "http-response: "); 
-+#endif
-+
-+      while((1 == http_resp_tokenizer(&t, &token_id, token)) && context.ok) {
-+              http_resp_parser(pParser, token_id, token, &context);
-+
-+              token = buffer_init();
-+
-+              /* CRLF CRLF ... the header end sequence */
-+              if (last_token_id == TK_CRLF &&
-+                  token_id == TK_CRLF) break;
-+
-+              last_token_id = token_id;
-+      }
-+
-+      /* oops, the parser failed */
-+      if (context.ok == 0) {
-+              ret = PARSE_ERROR;
-+
-+              if (!buffer_is_empty(context.errmsg)) {
-+                      TRACE("parsing failed: %s", BUF_STR(context.errmsg));
-+              } else {
-+                      TRACE("%s", "parsing failed ...");
-+              }
-+      }
-+
-+      http_resp_parser(pParser, 0, token, &context);
-+      http_resp_parserFree(pParser, free);
-+
-+      if (context.ok == 0) {
-+              /* we are missing the some tokens */
-+
-+              if (!buffer_is_empty(context.errmsg)) {
-+                      TRACE("parsing failed: %s", BUF_STR(context.errmsg));
-+              }
-+
-+              if (ret == PARSE_UNSET) {
-+                      ret = buffer_is_empty(context.errmsg) ? PARSE_NEED_MORE : PARSE_ERROR;
-+              }
-+      } else {
-+              chunk *c;
-+
-+              for (c = cq->first; c != t.c; c = c->next) {
-+                      c->offset = c->mem->used - 1;
-+              }
-+
-+              c->offset = t.offset;
-+
-+              ret = PARSE_SUCCESS;
-+      }
-+
-+      buffer_free(token);
-+      buffer_free(context.errmsg);
-+
-+      return ret;
-+}
-+
---- ../lighttpd-1.4.11/src/http_resp.h 1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/http_resp.h     2006-09-07 00:57:05.000000000 +0300
-@@ -0,0 +1,28 @@
-+#ifndef _HTTP_RESP_H_
-+#define _HTTP_RESP_H_
-+
-+#include "array.h"
-+#include "chunk.h"
-+#include "http_parser.h"
-+
-+typedef struct {
-+    int protocol;   /* http/1.0, http/1.1 */
-+    int status;     /* e.g. 200 */
-+    buffer *reason; /* e.g. Ok */
-+    array *headers;
-+} http_resp;
-+
-+typedef struct {
-+      int     ok;
-+    buffer *errmsg;
-+
-+    http_resp *resp;
-+} http_resp_ctx_t;
-+
-+http_resp *http_response_init(void);
-+void http_response_free(http_resp *resp);
-+void http_response_reset(http_resp *resp);
-+
-+parse_status_t http_response_parse_cq(chunkqueue *cq, http_resp *http_response);
-+
-+#endif
---- ../lighttpd-1.4.11/src/http_resp_parser.c  1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/http_resp_parser.c      2006-09-07 00:57:07.000000000 +0300
-@@ -0,0 +1,901 @@
-+/* Driver template for the LEMON parser generator.
-+** The author disclaims copyright to this source code.
-+*/
-+/* First off, code is include which follows the "include" declaration
-+** in the input file. */
-+#include <stdio.h>
-+#line 6 "./http_resp_parser.y"
-+
-+#include <assert.h>
-+#include <string.h>
-+#include "http_resp.h"
-+#include "keyvalue.h"
-+#include "array.h"
-+#include "log.h"
-+
-+#line 17 "http_resp_parser.c"
-+/* Next is all token values, in a form suitable for use by makeheaders.
-+** This section will be null unless lemon is run with the -m switch.
-+*/
-+/*
-+** These constants (all generated automatically by the parser generator)
-+** specify the various kinds of tokens (terminals) that the parser
-+** understands.
-+**
-+** Each symbol here is a terminal symbol in the grammar.
-+*/
-+/* Make sure the INTERFACE macro is defined.
-+*/
-+#ifndef INTERFACE
-+# define INTERFACE 1
-+#endif
-+/* The next thing included is series of defines which control
-+** various aspects of the generated parser.
-+**    YYCODETYPE         is the data type used for storing terminal
-+**                       and nonterminal numbers.  "unsigned char" is
-+**                       used if there are fewer than 250 terminals
-+**                       and nonterminals.  "int" is used otherwise.
-+**    YYNOCODE           is a number of type YYCODETYPE which corresponds
-+**                       to no legal terminal or nonterminal number.  This
-+**                       number is used to fill in empty slots of the hash
-+**                       table.
-+**    YYFALLBACK         If defined, this indicates that one or more tokens
-+**                       have fall-back values which should be used if the
-+**                       original value of the token will not parse.
-+**    YYACTIONTYPE       is the data type used for storing terminal
-+**                       and nonterminal numbers.  "unsigned char" is
-+**                       used if there are fewer than 250 rules and
-+**                       states combined.  "int" is used otherwise.
-+**    http_resp_parserTOKENTYPE     is the data type used for minor tokens given
-+**                       directly to the parser from the tokenizer.
-+**    YYMINORTYPE        is the data type used for all minor tokens.
-+**                       This is typically a union of many types, one of
-+**                       which is http_resp_parserTOKENTYPE.  The entry in the union
-+**                       for base tokens is called "yy0".
-+**    YYSTACKDEPTH       is the maximum depth of the parser's stack.
-+**    http_resp_parserARG_SDECL     A static variable declaration for the %extra_argument
-+**    http_resp_parserARG_PDECL     A parameter declaration for the %extra_argument
-+**    http_resp_parserARG_STORE     Code to store %extra_argument into yypParser
-+**    http_resp_parserARG_FETCH     Code to extract %extra_argument from yypParser
-+**    YYNSTATE           the combined number of states.
-+**    YYNRULE            the number of rules in the grammar
-+**    YYERRORSYMBOL      is the code number of the error symbol.  If not
-+**                       defined, then do no error processing.
-+*/
-+/* \ 1 */
-+#define YYCODETYPE unsigned char
-+#define YYNOCODE 12
-+#define YYACTIONTYPE unsigned char
-+#define http_resp_parserTOKENTYPE buffer *
-+typedef union {
-+  http_resp_parserTOKENTYPE yy0;
-+  http_resp * yy2;
-+  data_string * yy9;
-+  array * yy12;
-+  int yy20;
-+  int yy23;
-+} YYMINORTYPE;
-+#define YYSTACKDEPTH 100
-+#define http_resp_parserARG_SDECL http_resp_ctx_t *ctx;
-+#define http_resp_parserARG_PDECL ,http_resp_ctx_t *ctx
-+#define http_resp_parserARG_FETCH http_resp_ctx_t *ctx = yypParser->ctx
-+#define http_resp_parserARG_STORE yypParser->ctx = ctx
-+#define YYNSTATE 19
-+#define YYNRULE 9
-+#define YYERRORSYMBOL 4
-+#define YYERRSYMDT yy23
-+#define YY_NO_ACTION      (YYNSTATE+YYNRULE+2)
-+#define YY_ACCEPT_ACTION  (YYNSTATE+YYNRULE+1)
-+#define YY_ERROR_ACTION   (YYNSTATE+YYNRULE)
-+
-+/* Next are that tables used to determine what action to take based on the
-+** current state and lookahead token.  These tables are used to implement
-+** functions that take a state number and lookahead value and return an
-+** action integer.
-+**
-+** Suppose the action integer is N.  Then the action is determined as
-+** follows
-+**
-+**   0 <= N < YYNSTATE                  Shift N.  That is, push the lookahead
-+**                                      token onto the stack and goto state N.
-+**
-+**   YYNSTATE <= N < YYNSTATE+YYNRULE   Reduce by rule N-YYNSTATE.
-+**
-+**   N == YYNSTATE+YYNRULE              A syntax error has occurred.
-+**
-+**   N == YYNSTATE+YYNRULE+1            The parser accepts its input.
-+**
-+**   N == YYNSTATE+YYNRULE+2            No such action.  Denotes unused
-+**                                      slots in the yy_action[] table.
-+**
-+** The action table is constructed as a single large table named yy_action[].
-+** Given state S and lookahead X, the action is computed as
-+**
-+**      yy_action[ yy_shift_ofst[S] + X ]
-+**
-+** If the index value yy_shift_ofst[S]+X is out of range or if the value
-+** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S]
-+** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table
-+** and that yy_default[S] should be used instead.
-+**
-+** The formula above is for computing the action when the lookahead is
-+** a terminal symbol.  If the lookahead is a non-terminal (as occurs after
-+** a reduce action) then the yy_reduce_ofst[] array is used in place of
-+** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of
-+** YY_SHIFT_USE_DFLT.
-+**
-+** The following are the tables generated in this section:
-+**
-+**  yy_action[]        A single table containing all actions.
-+**  yy_lookahead[]     A table containing the lookahead for each entry in
-+**                     yy_action.  Used to detect hash collisions.
-+**  yy_shift_ofst[]    For each state, the offset into yy_action for
-+**                     shifting terminals.
-+**  yy_reduce_ofst[]   For each state, the offset into yy_action for
-+**                     shifting non-terminals after a reduce.
-+**  yy_default[]       Default action for each state.
-+*/
-+static YYACTIONTYPE yy_action[] = {
-+ /*     0 */     8,   29,   18,    1,   14,    2,    4,   11,   15,   12,
-+ /*    10 */    14,   13,    4,   21,    5,   19,    3,    5,    6,    7,
-+ /*    20 */     9,   17,   16,    4,   20,   22,   22,   10,
-+};
-+static YYCODETYPE yy_lookahead[] = {
-+ /*     0 */     5,    6,    2,    8,    9,    1,    2,    1,    2,    8,
-+ /*    10 */     9,    1,    2,    2,    3,    0,    9,    3,    2,    1,
-+ /*    20 */     7,    2,    2,    2,    0,    2,   11,   10,
-+};
-+#define YY_SHIFT_USE_DFLT (-1)
-+static signed char yy_shift_ofst[] = {
-+ /*     0 */     0,    4,   15,   -1,   14,   16,   18,   -1,   19,   20,
-+ /*    10 */     6,   21,   10,   24,   -1,   -1,   -1,   23,   11,
-+};
-+#define YY_REDUCE_USE_DFLT (-6)
-+static signed char yy_reduce_ofst[] = {
-+ /*     0 */    -5,    7,   -6,   -6,   -6,   -6,   -6,   -6,   13,   17,
-+ /*    10 */    -6,    1,    7,   -6,   -6,   -6,   -6,   -6,   -6,
-+};
-+static YYACTIONTYPE yy_default[] = {
-+ /*     0 */    28,   28,   28,   25,   28,   28,   28,   27,   28,   28,
-+ /*    10 */    28,   28,   28,   28,   26,   24,   23,   28,   28,
-+};
-+#define YY_SZ_ACTTAB (sizeof(yy_action)/sizeof(yy_action[0]))
-+
-+/* The next table maps tokens into fallback tokens.  If a construct
-+** like the following:
-+**
-+**      %fallback ID X Y Z.
-+**
-+** appears in the grammer, then ID becomes a fallback token for X, Y,
-+** and Z.  Whenever one of the tokens X, Y, or Z is input to the parser
-+** but it does not parse, the type of the token is changed to ID and
-+** the parse is retried before an error is thrown.
-+*/
-+#ifdef YYFALLBACK
-+static const YYCODETYPE yyFallback[] = {
-+};
-+#endif /* YYFALLBACK */
-+
-+/* The following structure represents a single element of the
-+** parser's stack.  Information stored includes:
-+**
-+**   +  The state number for the parser at this level of the stack.
-+**
-+**   +  The value of the token stored at this level of the stack.
-+**      (In other words, the "major" token.)
-+**
-+**   +  The semantic value stored at this level of the stack.  This is
-+**      the information used by the action routines in the grammar.
-+**      It is sometimes called the "minor" token.
-+*/
-+struct yyStackEntry {
-+  int stateno;       /* The state-number */
-+  int major;         /* The major token value.  This is the code
-+                     ** number for the token at this stack level */
-+  YYMINORTYPE minor; /* The user-supplied minor token value.  This
-+                     ** is the value of the token  */
-+};
-+typedef struct yyStackEntry yyStackEntry;
-+
-+/* The state of the parser is completely contained in an instance of
-+** the following structure */
-+struct yyParser {
-+  int yyidx;                    /* Index of top element in stack */
-+  int yyerrcnt;                 /* Shifts left before out of the error */
-+  http_resp_parserARG_SDECL                /* A place to hold %extra_argument */
-+  yyStackEntry yystack[YYSTACKDEPTH];  /* The parser's stack */
-+};
-+typedef struct yyParser yyParser;
-+
-+#ifndef NDEBUG
-+#include <stdio.h>
-+static FILE *yyTraceFILE = 0;
-+static char *yyTracePrompt = 0;
-+#endif /* NDEBUG */
-+
-+#ifndef NDEBUG
-+/*
-+** Turn parser tracing on by giving a stream to which to write the trace
-+** and a prompt to preface each trace message.  Tracing is turned off
-+** by making either argument NULL
-+**
-+** Inputs:
-+** <ul>
-+** <li> A FILE* to which trace output should be written.
-+**      If NULL, then tracing is turned off.
-+** <li> A prefix string written at the beginning of every
-+**      line of trace output.  If NULL, then tracing is
-+**      turned off.
-+** </ul>
-+**
-+** Outputs:
-+** None.
-+*/
-+void http_resp_parserTrace(FILE *TraceFILE, char *zTracePrompt){
-+  yyTraceFILE = TraceFILE;
-+  yyTracePrompt = zTracePrompt;
-+  if( yyTraceFILE==0 ) yyTracePrompt = 0;
-+  else if( yyTracePrompt==0 ) yyTraceFILE = 0;
-+}
-+#endif /* NDEBUG */
-+
-+#ifndef NDEBUG
-+/* For tracing shifts, the names of all terminals and nonterminals
-+** are required.  The following table supplies these names */
-+static const char *yyTokenName[] = {
-+  "$",             "CRLF",          "STRING",        "COLON",       
-+  "error",         "protocol",      "response_hdr",  "number",      
-+  "headers",       "header",        "reason",      
-+};
-+#endif /* NDEBUG */
-+
-+#ifndef NDEBUG
-+/* For tracing reduce actions, the names of all rules are required.
-+*/
-+static const char *yyRuleName[] = {
-+ /*   0 */ "response_hdr ::= headers CRLF",
-+ /*   1 */ "response_hdr ::= protocol number reason CRLF headers CRLF",
-+ /*   2 */ "protocol ::= STRING",
-+ /*   3 */ "number ::= STRING",
-+ /*   4 */ "reason ::= STRING",
-+ /*   5 */ "reason ::= reason STRING",
-+ /*   6 */ "headers ::= headers header",
-+ /*   7 */ "headers ::= header",
-+ /*   8 */ "header ::= STRING COLON STRING CRLF",
-+};
-+#endif /* NDEBUG */
-+
-+/*
-+** This function returns the symbolic name associated with a token
-+** value.
-+*/
-+const char *http_resp_parserTokenName(int tokenType){
-+#ifndef NDEBUG
-+  if( tokenType>0 && tokenType<(sizeof(yyTokenName)/sizeof(yyTokenName[0])) ){
-+    return yyTokenName[tokenType];
-+  }else{
-+    return "Unknown";
-+  }
-+#else
-+  return "";
-+#endif
-+}
-+
-+/*
-+** This function allocates a new parser.
-+** The only argument is a pointer to a function which works like
-+** malloc.
-+**
-+** Inputs:
-+** A pointer to the function used to allocate memory.
-+**
-+** Outputs:
-+** A pointer to a parser.  This pointer is used in subsequent calls
-+** to http_resp_parser and http_resp_parserFree.
-+*/
-+void *http_resp_parserAlloc(void *(*mallocProc)(size_t)){
-+  yyParser *pParser;
-+  pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) );
-+  if( pParser ){
-+    pParser->yyidx = -1;
-+  }
-+  return pParser;
-+}
-+
-+/* The following function deletes the value associated with a
-+** symbol.  The symbol can be either a terminal or nonterminal.
-+** "yymajor" is the symbol code, and "yypminor" is a pointer to
-+** the value.
-+*/
-+static void yy_destructor(YYCODETYPE yymajor, YYMINORTYPE *yypminor){
-+  switch( yymajor ){
-+    /* Here is inserted the actions which take place when a
-+    ** terminal or non-terminal is destroyed.  This can happen
-+    ** when the symbol is popped from the stack during a
-+    ** reduce or during error processing or when a parser is
-+    ** being destroyed before it is finished parsing.
-+    **
-+    ** Note: during a reduce, the only symbols destroyed are those
-+    ** which appear on the RHS of the rule, but which are not used
-+    ** inside the C code.
-+    */
-+    case 1:
-+    case 2:
-+    case 3:
-+#line 25 "./http_resp_parser.y"
-+{ buffer_free((yypminor->yy0)); }
-+#line 327 "http_resp_parser.c"
-+      break;
-+    case 10:
-+#line 24 "./http_resp_parser.y"
-+{ buffer_free((yypminor->yy0)); }
-+#line 332 "http_resp_parser.c"
-+      break;
-+    default:  break;   /* If no destructor action specified: do nothing */
-+  }
-+}
-+
-+/*
-+** Pop the parser's stack once.
-+**
-+** If there is a destructor routine associated with the token which
-+** is popped from the stack, then call it.
-+**
-+** Return the major token number for the symbol popped.
-+*/
-+static int yy_pop_parser_stack(yyParser *pParser){
-+  YYCODETYPE yymajor;
-+  yyStackEntry *yytos = &pParser->yystack[pParser->yyidx];
-+
-+  if( pParser->yyidx<0 ) return 0;
-+#ifndef NDEBUG
-+  if( yyTraceFILE && pParser->yyidx>=0 ){
-+    fprintf(yyTraceFILE,"%sPopping %s\n",
-+      yyTracePrompt,
-+      yyTokenName[yytos->major]);
-+  }
-+#endif
-+  yymajor = yytos->major;
-+  yy_destructor( yymajor, &yytos->minor);
-+  pParser->yyidx--;
-+  return yymajor;
-+}
-+
-+/*
-+** Deallocate and destroy a parser.  Destructors are all called for
-+** all stack elements before shutting the parser down.
-+**
-+** Inputs:
-+** <ul>
-+** <li>  A pointer to the parser.  This should be a pointer
-+**       obtained from http_resp_parserAlloc.
-+** <li>  A pointer to a function used to reclaim memory obtained
-+**       from malloc.
-+** </ul>
-+*/
-+void http_resp_parserFree(
-+  void *p,                    /* The parser to be deleted */
-+  void (*freeProc)(void*)     /* Function used to reclaim memory */
-+){
-+  yyParser *pParser = (yyParser*)p;
-+  if( pParser==0 ) return;
-+  while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser);
-+  (*freeProc)((void*)pParser);
-+}
-+
-+/*
-+** Find the appropriate action for a parser given the terminal
-+** look-ahead token iLookAhead.
-+**
-+** If the look-ahead token is YYNOCODE, then check to see if the action is
-+** independent of the look-ahead.  If it is, return the action, otherwise
-+** return YY_NO_ACTION.
-+*/
-+static int yy_find_shift_action(
-+  yyParser *pParser,        /* The parser */
-+  int iLookAhead            /* The look-ahead token */
-+){
-+  int i;
-+  int stateno = pParser->yystack[pParser->yyidx].stateno;
-+
-+  /* if( pParser->yyidx<0 ) return YY_NO_ACTION;  */
-+  i = yy_shift_ofst[stateno];
-+  if( i==YY_SHIFT_USE_DFLT ){
-+    return yy_default[stateno];
-+  }
-+  if( iLookAhead==YYNOCODE ){
-+    return YY_NO_ACTION;
-+  }
-+  i += iLookAhead;
-+  if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){
-+#ifdef YYFALLBACK
-+    int iFallback;            /* Fallback token */
-+    if( iLookAhead<sizeof(yyFallback)/sizeof(yyFallback[0])
-+           && (iFallback = yyFallback[iLookAhead])!=0 ){
-+#ifndef NDEBUG
-+      if( yyTraceFILE ){
-+        fprintf(yyTraceFILE, "%sFALLBACK %s => %s\n",
-+           yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]);
-+      }
-+#endif
-+      return yy_find_shift_action(pParser, iFallback);
-+    }
-+#endif
-+    return yy_default[stateno];
-+  }else{
-+    return yy_action[i];
-+  }
-+}
-+
-+/*
-+** Find the appropriate action for a parser given the non-terminal
-+** look-ahead token iLookAhead.
-+**
-+** If the look-ahead token is YYNOCODE, then check to see if the action is
-+** independent of the look-ahead.  If it is, return the action, otherwise
-+** return YY_NO_ACTION.
-+*/
-+static int yy_find_reduce_action(
-+  yyParser *pParser,        /* The parser */
-+  int iLookAhead            /* The look-ahead token */
-+){
-+  int i;
-+  int stateno = pParser->yystack[pParser->yyidx].stateno;
-+
-+  i = yy_reduce_ofst[stateno];
-+  if( i==YY_REDUCE_USE_DFLT ){
-+    return yy_default[stateno];
-+  }
-+  if( iLookAhead==YYNOCODE ){
-+    return YY_NO_ACTION;
-+  }
-+  i += iLookAhead;
-+  if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){
-+    return yy_default[stateno];
-+  }else{
-+    return yy_action[i];
-+  }
-+}
-+
-+/*
-+** Perform a shift action.
-+*/
-+static void yy_shift(
-+  yyParser *yypParser,          /* The parser to be shifted */
-+  int yyNewState,               /* The new state to shift in */
-+  int yyMajor,                  /* The major token to shift in */
-+  YYMINORTYPE *yypMinor         /* Pointer ot the minor token to shift in */
-+){
-+  yyStackEntry *yytos;
-+  yypParser->yyidx++;
-+  if( yypParser->yyidx>=YYSTACKDEPTH ){
-+     http_resp_parserARG_FETCH;
-+     yypParser->yyidx--;
-+#ifndef NDEBUG
-+     if( yyTraceFILE ){
-+       fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt);
-+     }
-+#endif
-+     while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
-+     /* Here code is inserted which will execute if the parser
-+     ** stack every overflows */
-+     http_resp_parserARG_STORE; /* Suppress warning about unused %extra_argument var */
-+     return;
-+  }
-+  yytos = &yypParser->yystack[yypParser->yyidx];
-+  yytos->stateno = yyNewState;
-+  yytos->major = yyMajor;
-+  yytos->minor = *yypMinor;
-+#ifndef NDEBUG
-+  if( yyTraceFILE && yypParser->yyidx>0 ){
-+    int i;
-+    fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState);
-+    fprintf(yyTraceFILE,"%sStack:",yyTracePrompt);
-+    for(i=1; i<=yypParser->yyidx; i++)
-+      fprintf(yyTraceFILE," %s",yyTokenName[yypParser->yystack[i].major]);
-+    fprintf(yyTraceFILE,"\n");
-+  }
-+#endif
-+}
-+
-+/* The following table contains information about every rule that
-+** is used during the reduce.
-+*/
-+static struct {
-+  YYCODETYPE lhs;         /* Symbol on the left-hand side of the rule */
-+  unsigned char nrhs;     /* Number of right-hand side symbols in the rule */
-+} yyRuleInfo[] = {
-+  { 6, 2 },
-+  { 6, 6 },
-+  { 5, 1 },
-+  { 7, 1 },
-+  { 10, 1 },
-+  { 10, 2 },
-+  { 8, 2 },
-+  { 8, 1 },
-+  { 9, 4 },
-+};
-+
-+static void yy_accept(yyParser*);  /* Forward Declaration */
-+
-+/*
-+** Perform a reduce action and the shift that must immediately
-+** follow the reduce.
-+*/
-+static void yy_reduce(
-+  yyParser *yypParser,         /* The parser */
-+  int yyruleno                 /* Number of the rule by which to reduce */
-+){
-+  int yygoto;                     /* The next state */
-+  int yyact;                      /* The next action */
-+  YYMINORTYPE yygotominor;        /* The LHS of the rule reduced */
-+  yyStackEntry *yymsp;            /* The top of the parser's stack */
-+  int yysize;                     /* Amount to pop the stack */
-+  http_resp_parserARG_FETCH;
-+  yymsp = &yypParser->yystack[yypParser->yyidx];
-+#ifndef NDEBUG
-+  if( yyTraceFILE && yyruleno>=0
-+        && yyruleno<sizeof(yyRuleName)/sizeof(yyRuleName[0]) ){
-+    fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt,
-+      yyRuleName[yyruleno]);
-+  }
-+#endif /* NDEBUG */
-+
-+  switch( yyruleno ){
-+  /* Beginning here are the reduction cases.  A typical example
-+  ** follows:
-+  **   case 0:
-+  **  #line <lineno> <grammarfile>
-+  **     { ... }           // User supplied code
-+  **  #line <lineno> <thisfile>
-+  **     break;
-+  */
-+      case 0:
-+#line 28 "./http_resp_parser.y"
-+{
-+    http_resp *resp = ctx->resp;
-+    data_string *ds;
-+ 
-+    resp->protocol = HTTP_VERSION_UNSET;
-+
-+    buffer_copy_string(resp->reason, ""); /* no reason */
-+    array_free(resp->headers);
-+    resp->headers = yymsp[-1].minor.yy12;
-+
-+    if (NULL == (ds = (data_string *)array_get_element(yymsp[-1].minor.yy12, "Status"))) { 
-+        resp->status = 0;
-+    } else {
-+        char *err;
-+        resp->status = strtol(ds->value->ptr, &err, 10);
-+   
-+        if (*err != '\0' && *err != ' ') {
-+            buffer_copy_string(ctx->errmsg, "expected a number: ");
-+            buffer_append_string_buffer(ctx->errmsg, ds->value);
-+            buffer_append_string(ctx->errmsg, err);
-+        
-+            ctx->ok = 0;
-+        }
-+    }
-+
-+    yymsp[-1].minor.yy12 = NULL;
-+}
-+#line 582 "http_resp_parser.c"
-+  yy_destructor(1,&yymsp[0].minor);
-+        break;
-+      case 1:
-+#line 56 "./http_resp_parser.y"
-+{
-+    http_resp *resp = ctx->resp;
-+    
-+    resp->status = yymsp[-4].minor.yy20;
-+    resp->protocol = yymsp[-5].minor.yy20;
-+    buffer_copy_string_buffer(resp->reason, yymsp[-3].minor.yy0);
-+    buffer_free(yymsp[-3].minor.yy0); 
-+
-+    array_free(resp->headers);
-+    
-+    resp->headers = yymsp[-1].minor.yy12;
-+}
-+#line 599 "http_resp_parser.c"
-+  yy_destructor(1,&yymsp[-2].minor);
-+  yy_destructor(1,&yymsp[0].minor);
-+        break;
-+      case 2:
-+#line 69 "./http_resp_parser.y"
-+{
-+    if (buffer_is_equal_string(yymsp[0].minor.yy0, CONST_STR_LEN("HTTP/1.0"))) {
-+        yygotominor.yy20 = HTTP_VERSION_1_0;
-+    } else if (buffer_is_equal_string(yymsp[0].minor.yy0, CONST_STR_LEN("HTTP/1.1"))) {
-+        yygotominor.yy20 = HTTP_VERSION_1_1;
-+    } else {
-+        buffer_copy_string(ctx->errmsg, "unknown protocol: ");
-+        buffer_append_string_buffer(ctx->errmsg, yymsp[0].minor.yy0);
-+        
-+        ctx->ok = 0;
-+    }
-+    buffer_free(yymsp[0].minor.yy0);
-+}
-+#line 618 "http_resp_parser.c"
-+        break;
-+      case 3:
-+#line 83 "./http_resp_parser.y"
-+{
-+    char *err;
-+    yygotominor.yy20 = strtol(yymsp[0].minor.yy0->ptr, &err, 10);
-+    
-+    if (*err != '\0') {
-+        buffer_copy_string(ctx->errmsg, "expected a number, got: ");
-+        buffer_append_string_buffer(ctx->errmsg, yymsp[0].minor.yy0);
-+        
-+        ctx->ok = 0;
-+    }
-+    buffer_free(yymsp[0].minor.yy0);
-+}
-+#line 634 "http_resp_parser.c"
-+        break;
-+      case 4:
-+#line 96 "./http_resp_parser.y"
-+{
-+    yygotominor.yy0 = yymsp[0].minor.yy0;
-+}
-+#line 641 "http_resp_parser.c"
-+        break;
-+      case 5:
-+#line 100 "./http_resp_parser.y"
-+{
-+    yygotominor.yy0 = yymsp[-1].minor.yy0;
-+    
-+    buffer_append_string(yygotominor.yy0, " ");
-+    buffer_append_string_buffer(yygotominor.yy0, yymsp[0].minor.yy0);
-+
-+    buffer_free(yymsp[0].minor.yy0); 
-+}
-+#line 653 "http_resp_parser.c"
-+        break;
-+      case 6:
-+#line 109 "./http_resp_parser.y"
-+{
-+    yygotominor.yy12 = yymsp[-1].minor.yy12;
-+    
-+    array_insert_unique(yygotominor.yy12, (data_unset *)yymsp[0].minor.yy9);
-+}
-+#line 662 "http_resp_parser.c"
-+        break;
-+      case 7:
-+#line 115 "./http_resp_parser.y"
-+{
-+    yygotominor.yy12 = array_init();
-+
-+    array_insert_unique(yygotominor.yy12, (data_unset *)yymsp[0].minor.yy9);
-+}
-+#line 671 "http_resp_parser.c"
-+        break;
-+      case 8:
-+#line 120 "./http_resp_parser.y"
-+{
-+    yygotominor.yy9 = data_response_init();
-+    
-+    buffer_copy_string_buffer(yygotominor.yy9->key, yymsp[-3].minor.yy0);
-+    buffer_copy_string_buffer(yygotominor.yy9->value, yymsp[-1].minor.yy0);    
-+    buffer_free(yymsp[-3].minor.yy0);
-+    buffer_free(yymsp[-1].minor.yy0);
-+}
-+#line 683 "http_resp_parser.c"
-+  yy_destructor(3,&yymsp[-2].minor);
-+  yy_destructor(1,&yymsp[0].minor);
-+        break;
-+  };
-+  yygoto = yyRuleInfo[yyruleno].lhs;
-+  yysize = yyRuleInfo[yyruleno].nrhs;
-+  yypParser->yyidx -= yysize;
-+  yyact = yy_find_reduce_action(yypParser,yygoto);
-+  if( yyact < YYNSTATE ){
-+    yy_shift(yypParser,yyact,yygoto,&yygotominor);
-+  }else if( yyact == YYNSTATE + YYNRULE + 1 ){
-+    yy_accept(yypParser);
-+  }
-+}
-+
-+/*
-+** The following code executes when the parse fails
-+*/
-+static void yy_parse_failed(
-+  yyParser *yypParser           /* The parser */
-+){
-+  http_resp_parserARG_FETCH;
-+#ifndef NDEBUG
-+  if( yyTraceFILE ){
-+    fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt);
-+  }
-+#endif
-+  while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
-+  /* Here code is inserted which will be executed whenever the
-+  ** parser fails */
-+#line 15 "./http_resp_parser.y"
-+
-+  ctx->ok = 0;
-+
-+#line 718 "http_resp_parser.c"
-+  http_resp_parserARG_STORE; /* Suppress warning about unused %extra_argument variable */
-+}
-+
-+/*
-+** The following code executes when a syntax error first occurs.
-+*/
-+static void yy_syntax_error(
-+  yyParser *yypParser,           /* The parser */
-+  int yymajor,                   /* The major type of the error token */
-+  YYMINORTYPE yyminor            /* The minor type of the error token */
-+){
-+  http_resp_parserARG_FETCH;
-+#define TOKEN (yyminor.yy0)
-+  http_resp_parserARG_STORE; /* Suppress warning about unused %extra_argument variable */
-+}
-+
-+/*
-+** The following is executed when the parser accepts
-+*/
-+static void yy_accept(
-+  yyParser *yypParser           /* The parser */
-+){
-+  http_resp_parserARG_FETCH;
-+#ifndef NDEBUG
-+  if( yyTraceFILE ){
-+    fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt);
-+  }
-+#endif
-+  while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
-+  /* Here code is inserted which will be executed whenever the
-+  ** parser accepts */
-+  http_resp_parserARG_STORE; /* Suppress warning about unused %extra_argument variable */
-+}
-+
-+/* The main parser program.
-+** The first argument is a pointer to a structure obtained from
-+** "http_resp_parserAlloc" which describes the current state of the parser.
-+** The second argument is the major token number.  The third is
-+** the minor token.  The fourth optional argument is whatever the
-+** user wants (and specified in the grammar) and is available for
-+** use by the action routines.
-+**
-+** Inputs:
-+** <ul>
-+** <li> A pointer to the parser (an opaque structure.)
-+** <li> The major token number.
-+** <li> The minor token number.
-+** <li> An option argument of a grammar-specified type.
-+** </ul>
-+**
-+** Outputs:
-+** None.
-+*/
-+void http_resp_parser(
-+  void *yyp,                   /* The parser */
-+  int yymajor,                 /* The major token code number */
-+  http_resp_parserTOKENTYPE yyminor       /* The value for the token */
-+  http_resp_parserARG_PDECL               /* Optional %extra_argument parameter */
-+){
-+  YYMINORTYPE yyminorunion;
-+  int yyact;            /* The parser action. */
-+  int yyendofinput;     /* True if we are at the end of input */
-+  int yyerrorhit = 0;   /* True if yymajor has invoked an error */
-+  yyParser *yypParser;  /* The parser */
-+
-+  /* (re)initialize the parser, if necessary */
-+  yypParser = (yyParser*)yyp;
-+  if( yypParser->yyidx<0 ){
-+    if( yymajor==0 ) return;
-+    yypParser->yyidx = 0;
-+    yypParser->yyerrcnt = -1;
-+    yypParser->yystack[0].stateno = 0;
-+    yypParser->yystack[0].major = 0;
-+  }
-+  yyminorunion.yy0 = yyminor;
-+  yyendofinput = (yymajor==0);
-+  http_resp_parserARG_STORE;
-+
-+#ifndef NDEBUG
-+  if( yyTraceFILE ){
-+    fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]);
-+  }
-+#endif
-+
-+  do{
-+    yyact = yy_find_shift_action(yypParser,yymajor);
-+    if( yyact<YYNSTATE ){
-+      yy_shift(yypParser,yyact,yymajor,&yyminorunion);
-+      yypParser->yyerrcnt--;
-+      if( yyendofinput && yypParser->yyidx>=0 ){
-+        yymajor = 0;
-+      }else{
-+        yymajor = YYNOCODE;
-+      }
-+    }else if( yyact < YYNSTATE + YYNRULE ){
-+      yy_reduce(yypParser,yyact-YYNSTATE);
-+    }else if( yyact == YY_ERROR_ACTION ){
-+      int yymx;
-+#ifndef NDEBUG
-+      if( yyTraceFILE ){
-+        fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt);
-+      }
-+#endif
-+#ifdef YYERRORSYMBOL
-+      /* A syntax error has occurred.
-+      ** The response to an error depends upon whether or not the
-+      ** grammar defines an error token "ERROR".
-+      **
-+      ** This is what we do if the grammar does define ERROR:
-+      **
-+      **  * Call the %syntax_error function.
-+      **
-+      **  * Begin popping the stack until we enter a state where
-+      **    it is legal to shift the error symbol, then shift
-+      **    the error symbol.
-+      **
-+      **  * Set the error count to three.
-+      **
-+      **  * Begin accepting and shifting new tokens.  No new error
-+      **    processing will occur until three tokens have been
-+      **    shifted successfully.
-+      **
-+      */
-+      if( yypParser->yyerrcnt<0 ){
-+        yy_syntax_error(yypParser,yymajor,yyminorunion);
-+      }
-+      yymx = yypParser->yystack[yypParser->yyidx].major;
-+      if( yymx==YYERRORSYMBOL || yyerrorhit ){
-+#ifndef NDEBUG
-+        if( yyTraceFILE ){
-+          fprintf(yyTraceFILE,"%sDiscard input token %s\n",
-+             yyTracePrompt,yyTokenName[yymajor]);
-+        }
-+#endif
-+        yy_destructor(yymajor,&yyminorunion);
-+        yymajor = YYNOCODE;
-+      }else{
-+         while(
-+          yypParser->yyidx >= 0 &&
-+          yymx != YYERRORSYMBOL &&
-+          (yyact = yy_find_shift_action(yypParser,YYERRORSYMBOL)) >= YYNSTATE
-+        ){
-+          yy_pop_parser_stack(yypParser);
-+        }
-+        if( yypParser->yyidx < 0 || yymajor==0 ){
-+          yy_destructor(yymajor,&yyminorunion);
-+          yy_parse_failed(yypParser);
-+          yymajor = YYNOCODE;
-+        }else if( yymx!=YYERRORSYMBOL ){
-+          YYMINORTYPE u2;
-+          u2.YYERRSYMDT = 0;
-+          yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2);
-+        }
-+      }
-+      yypParser->yyerrcnt = 3;
-+      yyerrorhit = 1;
-+#else  /* YYERRORSYMBOL is not defined */
-+      /* This is what we do if the grammar does not define ERROR:
-+      **
-+      **  * Report an error message, and throw away the input token.
-+      **
-+      **  * If the input token is $, then fail the parse.
-+      **
-+      ** As before, subsequent error messages are suppressed until
-+      ** three input tokens have been successfully shifted.
-+      */
-+      if( yypParser->yyerrcnt<=0 ){
-+        yy_syntax_error(yypParser,yymajor,yyminorunion);
-+      }
-+      yypParser->yyerrcnt = 3;
-+      yy_destructor(yymajor,&yyminorunion);
-+      if( yyendofinput ){
-+        yy_parse_failed(yypParser);
-+      }
-+      yymajor = YYNOCODE;
-+#endif
-+    }else{
-+      yy_accept(yypParser);
-+      yymajor = YYNOCODE;
-+    }
-+  }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 );
-+  return;
-+}
---- ../lighttpd-1.4.11/src/http_resp_parser.h  1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/http_resp_parser.h      2006-09-07 00:57:07.000000000 +0300
-@@ -0,0 +1,3 @@
-+#define TK_CRLF                            1
-+#define TK_STRING                          2
-+#define TK_COLON                           3
---- ../lighttpd-1.4.11/src/http_resp_parser.y  1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/http_resp_parser.y      2006-09-07 00:57:05.000000000 +0300
-@@ -0,0 +1,127 @@
-+%token_prefix TK_
-+%token_type {buffer *}
-+%extra_argument {http_resp_ctx_t *ctx}
-+%name http_resp_parser
-+
-+%include {
-+#include <assert.h>
-+#include <string.h>
-+#include "http_resp.h"
-+#include "keyvalue.h"
-+#include "array.h"
-+#include "log.h"
-+}
-+
-+%parse_failure {
-+  ctx->ok = 0;
-+}
-+
-+%type protocol { int }
-+%type response_hdr { http_resp * }
-+%type number { int }
-+%type headers { array * }
-+%type header { data_string * }
-+%destructor reason { buffer_free($$); }
-+%token_destructor { buffer_free($$); }
-+
-+/* just headers + Status: ... */
-+response_hdr ::= headers(HDR) CRLF . {
-+    http_resp *resp = ctx->resp;
-+    data_string *ds;
-+ 
-+    resp->protocol = HTTP_VERSION_UNSET;
-+
-+    buffer_copy_string(resp->reason, ""); /* no reason */
-+    array_free(resp->headers);
-+    resp->headers = HDR;
-+
-+    if (NULL == (ds = (data_string *)array_get_element(HDR, "Status"))) { 
-+        resp->status = 0;
-+    } else {
-+        char *err;
-+        resp->status = strtol(ds->value->ptr, &err, 10);
-+   
-+        if (*err != '\0' && *err != ' ') {
-+            buffer_copy_string(ctx->errmsg, "expected a number: ");
-+            buffer_append_string_buffer(ctx->errmsg, ds->value);
-+            buffer_append_string(ctx->errmsg, err);
-+        
-+            ctx->ok = 0;
-+        }
-+    }
-+
-+    HDR = NULL;
-+}
-+/* HTTP/1.0 <status> ... */
-+response_hdr ::= protocol(B) number(C) reason(D) CRLF headers(HDR) CRLF . {
-+    http_resp *resp = ctx->resp;
-+    
-+    resp->status = C;
-+    resp->protocol = B;
-+    buffer_copy_string_buffer(resp->reason, D);
-+    buffer_free(D); 
-+
-+    array_free(resp->headers);
-+    
-+    resp->headers = HDR;
-+}
-+
-+protocol(A) ::= STRING(B). {
-+    if (buffer_is_equal_string(B, CONST_STR_LEN("HTTP/1.0"))) {
-+        A = HTTP_VERSION_1_0;
-+    } else if (buffer_is_equal_string(B, CONST_STR_LEN("HTTP/1.1"))) {
-+        A = HTTP_VERSION_1_1;
-+    } else {
-+        buffer_copy_string(ctx->errmsg, "unknown protocol: ");
-+        buffer_append_string_buffer(ctx->errmsg, B);
-+        
-+        ctx->ok = 0;
-+    }
-+    buffer_free(B);
-+}
-+
-+number(A) ::= STRING(B). {
-+    char *err;
-+    A = strtol(B->ptr, &err, 10);
-+    
-+    if (*err != '\0') {
-+        buffer_copy_string(ctx->errmsg, "expected a number, got: ");
-+        buffer_append_string_buffer(ctx->errmsg, B);
-+        
-+        ctx->ok = 0;
-+    }
-+    buffer_free(B);
-+}
-+
-+reason(A) ::= STRING(B). {
-+    A = B;
-+}
-+
-+reason(A) ::= reason(C) STRING(B). {
-+    A = C;
-+    
-+    buffer_append_string(A, " ");
-+    buffer_append_string_buffer(A, B);
-+
-+    buffer_free(B); 
-+}
-+
-+headers(HDRS) ::= headers(SRC) header(HDR). {
-+    HDRS = SRC;
-+    
-+    array_insert_unique(HDRS, (data_unset *)HDR);
-+}
-+
-+headers(HDRS) ::= header(HDR). {
-+    HDRS = array_init();
-+
-+    array_insert_unique(HDRS, (data_unset *)HDR);
-+}
-+header(HDR) ::= STRING(A) COLON STRING(B) CRLF. {
-+    HDR = data_response_init();
-+    
-+    buffer_copy_string_buffer(HDR->key, A);
-+    buffer_copy_string_buffer(HDR->value, B);    
-+    buffer_free(A);
-+    buffer_free(B);
-+}
---- ../lighttpd-1.4.11/src/inet_ntop_cache.c   2005-08-11 01:26:38.000000000 +0300
-+++ lighttpd-1.5.0/src/inet_ntop_cache.c       2006-07-16 00:26:04.000000000 +0300
-@@ -8,7 +8,7 @@
- #include "sys-socket.h"
- const char * inet_ntop_cache_get_ip(server *srv, sock_addr *addr) {
--#ifdef HAVE_IPV6      
-+#ifdef HAVE_IPV6
-       size_t ndx = 0, i;
-       for (i = 0; i < INET_NTOP_CACHE_MAX; i++) {
-               if (srv->inet_ntop_cache[i].ts != 0) {
-@@ -20,31 +20,31 @@
-                                  srv->inet_ntop_cache[i].addr.ipv4.s_addr == addr->ipv4.sin_addr.s_addr) {
-                               /* IPv4 found in cache */
-                               break;
--                              
-+
-                       }
-               }
-       }
--      
-+
-       if (i == INET_NTOP_CACHE_MAX) {
-               /* not found in cache */
--              
-+
-               i = ndx;
--              inet_ntop(addr->plain.sa_family, 
--                        addr->plain.sa_family == AF_INET6 ? 
-+              inet_ntop(addr->plain.sa_family,
-+                        addr->plain.sa_family == AF_INET6 ?
-                         (const void *) &(addr->ipv6.sin6_addr) :
-                         (const void *) &(addr->ipv4.sin_addr),
-                         srv->inet_ntop_cache[i].b2, INET6_ADDRSTRLEN);
--              
-+
-               srv->inet_ntop_cache[i].ts = srv->cur_ts;
-               srv->inet_ntop_cache[i].family = addr->plain.sa_family;
--              
-+
-               if (srv->inet_ntop_cache[i].family == AF_INET) {
-                       srv->inet_ntop_cache[i].addr.ipv4.s_addr = addr->ipv4.sin_addr.s_addr;
-               } else if (srv->inet_ntop_cache[i].family == AF_INET6) {
-                       memcpy(srv->inet_ntop_cache[i].addr.ipv6.s6_addr, addr->ipv6.sin6_addr.s6_addr, 16);
-               }
-       }
--      
-+
-       return srv->inet_ntop_cache[i].b2;
- #else
-       UNUSED(srv);
---- ../lighttpd-1.4.11/src/iosocket.c  1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/iosocket.c      2006-07-18 13:03:40.000000000 +0300
-@@ -0,0 +1,36 @@
-+#include <stdlib.h>
-+
-+#include "iosocket.h"
-+#include "sys-socket.h"
-+#include "sys-files.h"
-+#include "array-static.h"
-+
-+iosocket *iosocket_init(void) {
-+      STRUCT_INIT(iosocket, sock);
-+
-+      sock->fde_ndx = -1;
-+      sock->fd = -1;
-+
-+      sock->type = IOSOCKET_TYPE_SOCKET;
-+
-+      return sock;
-+}
-+
-+void iosocket_free(iosocket *sock) {
-+      if (!sock) return;
-+
-+      if (sock->fd != -1) {
-+              switch (sock->type) {
-+              case IOSOCKET_TYPE_SOCKET:
-+                      closesocket(sock->fd);
-+                      break;
-+              case IOSOCKET_TYPE_PIPE:
-+                      close(sock->fd);
-+                      break;
-+              default:
-+                      break;
-+              }
-+      }
-+
-+      free(sock);
-+}
---- ../lighttpd-1.4.11/src/iosocket.h  1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/iosocket.h      2006-07-20 01:14:57.000000000 +0300
-@@ -0,0 +1,44 @@
-+#ifndef _IOSOCKET_H_
-+#define _IOSOCKET_H_
-+
-+/**
-+ * make sure we know about OPENSSL all the time
-+ *
-+ * if we don't include config.h here we run into different sizes 
-+ * for the iosocket-struct depending on config.h include before 
-+ * iosocket.h or not
-+ */
-+
-+#ifdef HAVE_CONFIG_H
-+# include "config.h"
-+#endif
-+
-+#if defined HAVE_LIBSSL && defined HAVE_OPENSSL_SSL_H
-+# define USE_OPENSSL
-+# include <openssl/ssl.h>
-+#endif
-+
-+typedef enum {
-+      IOSOCKET_TYPE_UNSET,
-+      IOSOCKET_TYPE_SOCKET,
-+      IOSOCKET_TYPE_PIPE
-+} iosocket_t;
-+
-+/**
-+ * a non-blocking fd
-+ */
-+typedef struct {
-+      int fd;
-+      int fde_ndx;
-+
-+#ifdef USE_OPENSSL
-+      SSL *ssl;
-+#endif
-+
-+      iosocket_t type; /**< sendfile on solaris doesn't work on pipes */
-+} iosocket;
-+
-+iosocket *iosocket_init(void);
-+void iosocket_free(iosocket *sock);
-+
-+#endif
---- ../lighttpd-1.4.11/src/joblist.c   2005-08-11 01:26:41.000000000 +0300
-+++ lighttpd-1.5.0/src/joblist.c       2006-07-16 00:26:03.000000000 +0300
-@@ -7,7 +7,7 @@
- int joblist_append(server *srv, connection *con) {
-       if (con->in_joblist) return 0;
--      
-+
-       if (srv->joblist->size == 0) {
-               srv->joblist->size  = 16;
-               srv->joblist->ptr   = malloc(sizeof(*srv->joblist->ptr) * srv->joblist->size);
-@@ -15,15 +15,15 @@
-               srv->joblist->size += 16;
-               srv->joblist->ptr   = realloc(srv->joblist->ptr, sizeof(*srv->joblist->ptr) * srv->joblist->size);
-       }
--      
-+
-       srv->joblist->ptr[srv->joblist->used++] = con;
--      
-+
-       return 0;
- }
- void joblist_free(server *srv, connections *joblist) {
-       UNUSED(srv);
--              
-+
-       free(joblist->ptr);
-       free(joblist);
- }
-@@ -31,14 +31,14 @@
- connection *fdwaitqueue_unshift(server *srv, connections *fdwaitqueue) {
-       connection *con;
-       UNUSED(srv);
--              
--      
-+
-+
-       if (fdwaitqueue->used == 0) return NULL;
--      
-+
-       con = fdwaitqueue->ptr[0];
--      
-+
-       memmove(fdwaitqueue->ptr, &(fdwaitqueue->ptr[1]), --fdwaitqueue->used * sizeof(*(fdwaitqueue->ptr)));
--      
-+
-       return con;
- }
-@@ -50,9 +50,9 @@
-               srv->fdwaitqueue->size += 16;
-               srv->fdwaitqueue->ptr   = realloc(srv->fdwaitqueue->ptr, sizeof(*(srv->fdwaitqueue->ptr)) * srv->fdwaitqueue->size);
-       }
--      
-+
-       srv->fdwaitqueue->ptr[srv->fdwaitqueue->used++] = con;
--      
-+
-       return 0;
- }
---- ../lighttpd-1.4.11/src/keyvalue.c  2006-03-02 16:08:06.000000000 +0200
-+++ lighttpd-1.5.0/src/keyvalue.c      2006-07-16 00:26:03.000000000 +0300
-@@ -87,7 +87,8 @@
-       { 504, "Gateway Timeout" },
-       { 505, "HTTP Version Not Supported" },
-       { 507, "Insufficient Storage" }, /* WebDAV */
--      
-+      { 509, "Bandwidth Limit exceeded" },
-+
-       { -1, NULL }
- };
-@@ -102,12 +103,12 @@
-       { 501, "501.html" },
-       { 503, "503.html" },
-       { 505, "505.html" },
--      
-+
-       { -1, NULL }
- };
--const char *keyvalue_get_value(keyvalue *kv, int k) { 
-+const char *keyvalue_get_value(keyvalue *kv, int k) {
-       int i;
-       for (i = 0; kv[i].value; i++) {
-               if (kv[i].key == k) return kv[i].value;
-@@ -115,7 +116,7 @@
-       return NULL;
- }
--int keyvalue_get_key(keyvalue *kv, const char *s) { 
-+int keyvalue_get_key(keyvalue *kv, const char *s) {
-       int i;
-       for (i = 0; kv[i].value; i++) {
-               if (0 == strcmp(kv[i].value, s)) return kv[i].key;
-@@ -125,9 +126,9 @@
- keyvalue_buffer *keyvalue_buffer_init(void) {
-       keyvalue_buffer *kvb;
--      
-+
-       kvb = calloc(1, sizeof(*kvb));
--      
-+
-       return kvb;
- }
-@@ -135,49 +136,49 @@
-       size_t i;
-       if (kvb->size == 0) {
-               kvb->size = 4;
--              
-+
-               kvb->kv = malloc(kvb->size * sizeof(*kvb->kv));
--              
-+
-               for(i = 0; i < kvb->size; i++) {
-                       kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
-               }
-       } else if (kvb->used == kvb->size) {
-               kvb->size += 4;
--              
-+
-               kvb->kv = realloc(kvb->kv, kvb->size * sizeof(*kvb->kv));
--              
-+
-               for(i = kvb->used; i < kvb->size; i++) {
-                       kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
-               }
-       }
--      
-+
-       kvb->kv[kvb->used]->key = key;
-       kvb->kv[kvb->used]->value = strdup(value);
--      
-+
-       kvb->used++;
--      
-+
-       return 0;
- }
- void keyvalue_buffer_free(keyvalue_buffer *kvb) {
-       size_t i;
--      
-+
-       for (i = 0; i < kvb->size; i++) {
-               if (kvb->kv[i]->value) free(kvb->kv[i]->value);
-               free(kvb->kv[i]);
-       }
--      
-+
-       if (kvb->kv) free(kvb->kv);
--      
-+
-       free(kvb);
- }
- s_keyvalue_buffer *s_keyvalue_buffer_init(void) {
-       s_keyvalue_buffer *kvb;
--      
-+
-       kvb = calloc(1, sizeof(*kvb));
--      
-+
-       return kvb;
- }
-@@ -186,50 +187,50 @@
-       if (kvb->size == 0) {
-               kvb->size = 4;
-               kvb->used = 0;
--              
-+
-               kvb->kv = malloc(kvb->size * sizeof(*kvb->kv));
--              
-+
-               for(i = 0; i < kvb->size; i++) {
-                       kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
-               }
-       } else if (kvb->used == kvb->size) {
-               kvb->size += 4;
--              
-+
-               kvb->kv = realloc(kvb->kv, kvb->size * sizeof(*kvb->kv));
--              
-+
-               for(i = kvb->used; i < kvb->size; i++) {
-                       kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
-               }
-       }
--      
-+
-       kvb->kv[kvb->used]->key = key ? strdup(key) : NULL;
-       kvb->kv[kvb->used]->value = strdup(value);
--      
-+
-       kvb->used++;
--      
-+
-       return 0;
- }
- void s_keyvalue_buffer_free(s_keyvalue_buffer *kvb) {
-       size_t i;
--      
-+
-       for (i = 0; i < kvb->size; i++) {
-               if (kvb->kv[i]->key) free(kvb->kv[i]->key);
-               if (kvb->kv[i]->value) free(kvb->kv[i]->value);
-               free(kvb->kv[i]);
-       }
--      
-+
-       if (kvb->kv) free(kvb->kv);
--      
-+
-       free(kvb);
- }
- httpauth_keyvalue_buffer *httpauth_keyvalue_buffer_init(void) {
-       httpauth_keyvalue_buffer *kvb;
--      
-+
-       kvb = calloc(1, sizeof(*kvb));
--      
-+
-       return kvb;
- }
-@@ -237,42 +238,42 @@
-       size_t i;
-       if (kvb->size == 0) {
-               kvb->size = 4;
--              
-+
-               kvb->kv = malloc(kvb->size * sizeof(*kvb->kv));
--              
-+
-               for(i = 0; i < kvb->size; i++) {
-                       kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
-               }
-       } else if (kvb->used == kvb->size) {
-               kvb->size += 4;
--              
-+
-               kvb->kv = realloc(kvb->kv, kvb->size * sizeof(*kvb->kv));
--              
-+
-               for(i = kvb->used; i < kvb->size; i++) {
-                       kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
-               }
-       }
--      
-+
-       kvb->kv[kvb->used]->key = strdup(key);
-       kvb->kv[kvb->used]->realm = strdup(realm);
-       kvb->kv[kvb->used]->type = type;
--      
-+
-       kvb->used++;
--      
-+
-       return 0;
- }
- void httpauth_keyvalue_buffer_free(httpauth_keyvalue_buffer *kvb) {
-       size_t i;
--      
-+
-       for (i = 0; i < kvb->size; i++) {
-               if (kvb->kv[i]->key) free(kvb->kv[i]->key);
-               if (kvb->kv[i]->realm) free(kvb->kv[i]->realm);
-               free(kvb->kv[i]);
-       }
--      
-+
-       if (kvb->kv) free(kvb->kv);
--      
-+
-       free(kvb);
- }
-@@ -306,9 +307,9 @@
- pcre_keyvalue_buffer *pcre_keyvalue_buffer_init(void) {
-       pcre_keyvalue_buffer *kvb;
--      
-+
-       kvb = calloc(1, sizeof(*kvb));
--      
-+
-       return kvb;
- }
-@@ -319,46 +320,46 @@
-       int erroff;
-       pcre_keyvalue *kv;
- #endif
--      
-+
-       if (!key) return -1;
- #ifdef HAVE_PCRE_H
-       if (kvb->size == 0) {
-               kvb->size = 4;
-               kvb->used = 0;
--              
-+
-               kvb->kv = malloc(kvb->size * sizeof(*kvb->kv));
--              
-+
-               for(i = 0; i < kvb->size; i++) {
-                       kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
-               }
-       } else if (kvb->used == kvb->size) {
-               kvb->size += 4;
--              
-+
-               kvb->kv = realloc(kvb->kv, kvb->size * sizeof(*kvb->kv));
--              
-+
-               for(i = kvb->used; i < kvb->size; i++) {
-                       kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
-               }
-       }
--      
-+
-       kv = kvb->kv[kvb->used];
-       if (NULL == (kv->key = pcre_compile(key,
-                                         0, &errptr, &erroff, NULL))) {
--              
-+
-               fprintf(stderr, "%s.%d: rexexp compilation error at %s\n", __FILE__, __LINE__, errptr);
-               return -1;
-       }
--      if (NULL == (kv->key_extra = pcre_study(kv->key, 0, &errptr)) &&  
-+      if (NULL == (kv->key_extra = pcre_study(kv->key, 0, &errptr)) &&
-                       errptr != NULL) {
-               return -1;
-       }
--      
-+
-       kv->value = buffer_init_string(value);
--      
-+
-       kvb->used++;
--      
-+
-       return 0;
- #else
-       UNUSED(kvb);
-@@ -380,9 +381,9 @@
-               if (kv->value) buffer_free(kv->value);
-               free(kv);
-       }
--      
-+
-       if (kvb->kv) free(kvb->kv);
- #endif
--      
-+
-       free(kvb);
- }
---- ../lighttpd-1.4.11/src/keyvalue.h  2006-03-02 16:08:06.000000000 +0200
-+++ lighttpd-1.5.0/src/keyvalue.h      2006-09-07 00:57:05.000000000 +0300
-@@ -9,19 +9,19 @@
- # include <pcre.h>
- #endif
--typedef enum { 
--      HTTP_METHOD_UNSET = -1, 
--      HTTP_METHOD_GET, 
--      HTTP_METHOD_POST, 
--      HTTP_METHOD_HEAD, 
--      HTTP_METHOD_OPTIONS, 
-+typedef enum {
-+      HTTP_METHOD_UNSET = -1,
-+      HTTP_METHOD_GET,
-+      HTTP_METHOD_POST,
-+      HTTP_METHOD_HEAD,
-+      HTTP_METHOD_OPTIONS,
-       HTTP_METHOD_PROPFIND,  /* WebDAV */
--      HTTP_METHOD_MKCOL, 
--      HTTP_METHOD_PUT, 
--      HTTP_METHOD_DELETE, 
--      HTTP_METHOD_COPY, 
--      HTTP_METHOD_MOVE, 
--      HTTP_METHOD_PROPPATCH, 
-+      HTTP_METHOD_MKCOL,
-+      HTTP_METHOD_PUT,
-+      HTTP_METHOD_DELETE,
-+      HTTP_METHOD_COPY,
-+      HTTP_METHOD_MOVE,
-+      HTTP_METHOD_PROPPATCH,
-       HTTP_METHOD_REPORT, /* DeltaV */
-       HTTP_METHOD_CHECKOUT,
-       HTTP_METHOD_CHECKIN,
-@@ -35,17 +35,21 @@
-       HTTP_METHOD_CONNECT
- } http_method_t;
--typedef enum { HTTP_VERSION_UNSET = -1, HTTP_VERSION_1_0, HTTP_VERSION_1_1 } http_version_t;
-+typedef enum { 
-+      HTTP_VERSION_UNSET = -1, 
-+      HTTP_VERSION_1_0, 
-+      HTTP_VERSION_1_1
-+} http_version_t;
- typedef struct {
-       int key;
--      
-+
-       char *value;
- } keyvalue;
- typedef struct {
-       char *key;
--      
-+
-       char *value;
- } s_keyvalue;
-@@ -54,7 +58,7 @@
-       pcre *key;
-       pcre_extra *key_extra;
- #endif
--      
-+
-       buffer *value;
- } pcre_keyvalue;
-@@ -62,7 +66,7 @@
- typedef struct {
-       char *key;
--      
-+
-       char *realm;
-       httpauth_type type;
- } httpauth_keyvalue;
---- ../lighttpd-1.4.11/src/lemon.c     2005-09-01 00:21:34.000000000 +0300
-+++ lighttpd-1.5.0/src/lemon.c 2006-07-16 00:26:03.000000000 +0300
-@@ -579,7 +579,7 @@
- */
- /* Find a precedence symbol of every rule in the grammar.
--** 
-+**
- ** Those rules which have a precedence symbol coded in the input
- ** grammar using the "[symbol]" construct will already have the
- ** rp->precsym field filled.  Other rules take as their precedence
-@@ -869,7 +869,7 @@
-       cfp->status = INCOMPLETE;
-     }
-   }
--  
-+
-   do{
-     progress = 0;
-     for(i=0; i<lemp->nstate; i++){
-@@ -900,7 +900,7 @@
-   struct symbol *sp;
-   struct rule *rp;
--  /* Add all of the reduce actions 
-+  /* Add all of the reduce actions
-   ** A reduce action is added for each element of the followset of
-   ** a configuration which has its dot at the extreme right.
-   */
-@@ -1017,7 +1017,7 @@
-       apx->type = RD_RESOLVED;
-     }
-   }else{
--    assert( 
-+    assert(
-       apx->type==SH_RESOLVED ||
-       apx->type==RD_RESOLVED ||
-       apx->type==CONFLICT ||
-@@ -1350,7 +1350,7 @@
-   OptInit(argv,options,stderr);
-   if( version ){
-      printf("Lemon version 1.0\n");
--     exit(0); 
-+     exit(0);
-   }
-   if( OptNArgs() < 1 ){
-     fprintf(stderr,"Exactly one filename argument is required.\n");
-@@ -2031,7 +2031,7 @@
-     case IN_RHS:
-       if( x[0]=='.' ){
-         struct rule *rp;
--        rp = (struct rule *)malloc( sizeof(struct rule) + 
-+        rp = (struct rule *)malloc( sizeof(struct rule) +
-              sizeof(struct symbol*)*psp->nrhs + sizeof(char*)*psp->nrhs );
-         if( rp==0 ){
-           ErrorMsg(psp->filename,psp->tokenlineno,
-@@ -2546,7 +2546,7 @@
-   return fp;
- }
--/* Duplicate the input file without comments and without actions 
-+/* Duplicate the input file without comments and without actions
- ** on rules */
- void Reprint(lemp)
- struct lemon *lemp;
-@@ -2822,7 +2822,7 @@
- PRIVATE FILE *tplt_open(lemp)
- struct lemon *lemp;
- {
--  
-+
-   char buf[1000];
-   FILE *in;
-   char *tpltname;
-@@ -2930,7 +2930,7 @@
-   return ret;
- }
--/* 
-+/*
- ** Generate code which executes when the rule "rp" is reduced.  Write
- ** the code to "out".  Make sure lineno stays up-to-date.
- */
-@@ -3384,7 +3384,7 @@
-   /* Output the yy_shift_ofst[] table */
-   fprintf(out, "#define YY_SHIFT_USE_DFLT (%d)\n", mnTknOfst-1); lineno++;
--  fprintf(out, "static %s yy_shift_ofst[] = {\n", 
-+  fprintf(out, "static %s yy_shift_ofst[] = {\n",
-           minimum_size_type(mnTknOfst-1, mxTknOfst)); lineno++;
-   n = lemp->nstate;
-   for(i=j=0; i<n; i++){
-@@ -3405,7 +3405,7 @@
-   /* Output the yy_reduce_ofst[] table */
-   fprintf(out, "#define YY_REDUCE_USE_DFLT (%d)\n", mnNtOfst-1); lineno++;
--  fprintf(out, "static %s yy_reduce_ofst[] = {\n", 
-+  fprintf(out, "static %s yy_reduce_ofst[] = {\n",
-           minimum_size_type(mnNtOfst-1, mxNtOfst)); lineno++;
-   n = lemp->nstate;
-   for(i=j=0; i<n; i++){
-@@ -3480,7 +3480,7 @@
-   tplt_xfer(lemp->name,in,out,&lineno);
-   /* Generate code which executes every time a symbol is popped from
--  ** the stack while processing errors or while destroying the parser. 
-+  ** the stack while processing errors or while destroying the parser.
-   ** (In other words, generate the %destructor actions)
-   */
-   if( lemp->tokendest ){
-@@ -3522,7 +3522,7 @@
-   tplt_print(out,lemp,lemp->overflow,lemp->overflowln,&lineno);
-   tplt_xfer(lemp->name,in,out,&lineno);
--  /* Generate the table of rule information 
-+  /* Generate the table of rule information
-   **
-   ** Note: This code depends on the fact that rules are number
-   ** sequentually beginning with 0.
-@@ -3589,7 +3589,7 @@
-     for(i=1; i<lemp->nterminal; i++){
-       fprintf(out,"#define %s%-30s %2d\n",prefix,lemp->symbols[i]->name,i);
-     }
--    fclose(out);  
-+    fclose(out);
-   }
-   return;
- }
-@@ -3630,7 +3630,7 @@
-         rbest = rp;
-       }
-     }
-- 
-+
-     /* Do not make a default if the number of rules to default
-     ** is not at least 2 */
-     if( nbest<2 ) continue;
-@@ -3781,7 +3781,7 @@
-   if( x1a ){
-     x1a->size = 1024;
-     x1a->count = 0;
--    x1a->tbl = (x1node*)malloc( 
-+    x1a->tbl = (x1node*)malloc(
-       (sizeof(x1node) + sizeof(x1node*))*1024 );
-     if( x1a->tbl==0 ){
-       free(x1a);
-@@ -3943,7 +3943,7 @@
-   if( x2a ){
-     x2a->size = 128;
-     x2a->count = 0;
--    x2a->tbl = (x2node*)malloc( 
-+    x2a->tbl = (x2node*)malloc(
-       (sizeof(x2node) + sizeof(x2node*))*128 );
-     if( x2a->tbl==0 ){
-       free(x2a);
-@@ -4149,7 +4149,7 @@
-   if( x3a ){
-     x3a->size = 128;
-     x3a->count = 0;
--    x3a->tbl = (x3node*)malloc( 
-+    x3a->tbl = (x3node*)malloc(
-       (sizeof(x3node) + sizeof(x3node*))*128 );
-     if( x3a->tbl==0 ){
-       free(x3a);
-@@ -4295,7 +4295,7 @@
-   if( x4a ){
-     x4a->size = 64;
-     x4a->count = 0;
--    x4a->tbl = (x4node*)malloc( 
-+    x4a->tbl = (x4node*)malloc(
-       (sizeof(x4node) + sizeof(x4node*))*64 );
-     if( x4a->tbl==0 ){
-       free(x4a);
---- ../lighttpd-1.4.11/src/lempar.c    2005-08-11 01:26:40.000000000 +0300
-+++ lighttpd-1.5.0/src/lempar.c        2006-07-16 00:26:03.000000000 +0300
-@@ -8,10 +8,10 @@
- /* Next is all token values, in a form suitable for use by makeheaders.
- ** This section will be null unless lemon is run with the -m switch.
- */
--/* 
-+/*
- ** These constants (all generated automatically by the parser generator)
- ** specify the various kinds of tokens (terminals) that the parser
--** understands. 
-+** understands.
- **
- ** Each symbol here is a terminal symbol in the grammar.
- */
-@@ -29,7 +29,7 @@
- **                       and nonterminals.  "int" is used otherwise.
- **    YYNOCODE           is a number of type YYCODETYPE which corresponds
- **                       to no legal terminal or nonterminal number.  This
--**                       number is used to fill in empty slots of the hash 
-+**                       number is used to fill in empty slots of the hash
- **                       table.
- **    YYFALLBACK         If defined, this indicates that one or more tokens
- **                       have fall-back values which should be used if the
-@@ -38,7 +38,7 @@
- **                       and nonterminal numbers.  "unsigned char" is
- **                       used if there are fewer than 250 rules and
- **                       states combined.  "int" is used otherwise.
--**    ParseTOKENTYPE     is the data type used for minor tokens given 
-+**    ParseTOKENTYPE     is the data type used for minor tokens given
- **                       directly to the parser from the tokenizer.
- **    YYMINORTYPE        is the data type used for all minor tokens.
- **                       This is typically a union of many types, one of
-@@ -62,7 +62,7 @@
- /* Next are that tables used to determine what action to take based on the
- ** current state and lookahead token.  These tables are used to implement
- ** functions that take a state number and lookahead value and return an
--** action integer.  
-+** action integer.
- **
- ** Suppose the action integer is N.  Then the action is determined as
- ** follows
-@@ -87,7 +87,7 @@
- ** If the index value yy_shift_ofst[S]+X is out of range or if the value
- ** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S]
- ** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table
--** and that yy_default[S] should be used instead.  
-+** and that yy_default[S] should be used instead.
- **
- ** The formula above is for computing the action when the lookahead is
- ** a terminal symbol.  If the lookahead is a non-terminal (as occurs after
-@@ -111,7 +111,7 @@
- /* The next table maps tokens into fallback tokens.  If a construct
- ** like the following:
--** 
-+**
- **      %fallback ID X Y Z.
- **
- ** appears in the grammer, then ID becomes a fallback token for X, Y,
-@@ -163,10 +163,10 @@
- #endif /* NDEBUG */
- #ifndef NDEBUG
--/* 
-+/*
- ** Turn parser tracing on by giving a stream to which to write the trace
- ** and a prompt to preface each trace message.  Tracing is turned off
--** by making either argument NULL 
-+** by making either argument NULL
- **
- ** Inputs:
- ** <ul>
-@@ -191,7 +191,7 @@
- #ifndef NDEBUG
- /* For tracing shifts, the names of all terminals and nonterminals
- ** are required.  The following table supplies these names */
--static const char *yyTokenName[] = { 
-+static const char *yyTokenName[] = {
- %%
- };
- #endif /* NDEBUG */
-@@ -220,7 +220,7 @@
- #endif
- }
--/* 
-+/*
- ** This function allocates a new parser.
- ** The only argument is a pointer to a function which works like
- ** malloc.
-@@ -251,7 +251,7 @@
-     /* Here is inserted the actions which take place when a
-     ** terminal or non-terminal is destroyed.  This can happen
-     ** when the symbol is popped from the stack during a
--    ** reduce or during error processing or when a parser is 
-+    ** reduce or during error processing or when a parser is
-     ** being destroyed before it is finished parsing.
-     **
-     ** Note: during a reduce, the only symbols destroyed are those
-@@ -289,7 +289,7 @@
-   return yymajor;
- }
--/* 
-+/*
- ** Deallocate and destroy a parser.  Destructors are all called for
- ** all stack elements before shutting the parser down.
- **
-@@ -325,7 +325,7 @@
- ){
-   int i;
-   int stateno = pParser->yystack[pParser->yyidx].stateno;
-- 
-+
-   /* if( pParser->yyidx<0 ) return YY_NO_ACTION;  */
-   i = yy_shift_ofst[stateno];
-   if( i==YY_SHIFT_USE_DFLT ){
-@@ -369,7 +369,7 @@
- ){
-   int i;
-   int stateno = pParser->yystack[pParser->yyidx].stateno;
-- 
-+
-   i = yy_reduce_ofst[stateno];
-   if( i==YY_REDUCE_USE_DFLT ){
-     return yy_default[stateno];
-@@ -455,7 +455,7 @@
-   ParseARG_FETCH;
-   yymsp = &yypParser->yystack[yypParser->yyidx];
- #ifndef NDEBUG
--  if( yyTraceFILE && yyruleno>=0 
-+  if( yyTraceFILE && yyruleno>=0
-         && yyruleno<sizeof(yyRuleName)/sizeof(yyRuleName[0]) ){
-     fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt,
-       yyRuleName[yyruleno]);
-@@ -608,7 +608,7 @@
- #ifdef YYERRORSYMBOL
-       /* A syntax error has occurred.
-       ** The response to an error depends upon whether or not the
--      ** grammar defines an error token "ERROR".  
-+      ** grammar defines an error token "ERROR".
-       **
-       ** This is what we do if the grammar does define ERROR:
-       **
---- ../lighttpd-1.4.11/src/log.c       2005-11-07 15:01:35.000000000 +0200
-+++ lighttpd-1.5.0/src/log.c   2006-07-18 13:03:40.000000000 +0300
-@@ -5,7 +5,6 @@
- #include <errno.h>
- #include <fcntl.h>
- #include <time.h>
--#include <unistd.h>
- #include <string.h>
- #include <stdlib.h>
-@@ -16,6 +15,10 @@
- #include "config.h"
- #endif
-+#ifdef _WIN32
-+#undef HAVE_SYSLOG_H
-+#endif
-+
- #ifdef HAVE_SYSLOG_H
- #include <syslog.h>
- #endif
-@@ -23,6 +26,8 @@
- #include "log.h"
- #include "array.h"
-+#include "sys-files.h"
-+
- #ifdef HAVE_VALGRIND_VALGRIND_H
- #include <valgrind/valgrind.h>
- #endif
-@@ -31,55 +36,114 @@
- # define O_LARGEFILE 0
- #endif
--/** 
-+/**
-  * open the errorlog
-- * 
-+ *
-  * we have 3 possibilities:
-  * - stderr (default)
-- * - syslog 
-+ * - syslog
-  * - logfile
-- * 
-+ *
-  * if the open failed, report to the user and die
-- * 
-+ *
-  */
--int log_error_open(server *srv) {
-+
-+typedef struct {
-+      buffer *file;
-+      unsigned short use_syslog;
-+
-+      /* the errorlog */
-       int fd;
--      int close_stderr = 1;
-+      enum { ERRORLOG_STDERR, ERRORLOG_FILE, ERRORLOG_SYSLOG } mode;
-+      buffer *buf;
-+
-+      time_t cached_ts;
-+      buffer *cached_ts_str;
-+} errorlog;
-+
-+errorlog *myconfig = NULL;
-+
-+void log_init(void) {
-+      /* use syslog */
-+      errorlog *err;
-+
-+      err = calloc(1, sizeof(*err));
-       
-+      err->fd = -1;
-+      err->mode = ERRORLOG_STDERR;
-+      err->buf = buffer_init();
-+      err->cached_ts_str = buffer_init();
-+
-+      myconfig = err;
-+}
-+
-+void log_free(void) {
-+      errorlog *err = myconfig;
-+
-+      if (!err) return;
-+
-+      TRACE("%s", "server stopped");
-+
-+      switch(err->mode) {
-+      case ERRORLOG_FILE:
-+              close(err->fd);
-+              break;
-+      case ERRORLOG_SYSLOG:
-+#ifdef HAVE_SYSLOG_H
-+              closelog();
-+#endif
-+              break;
-+      case ERRORLOG_STDERR:
-+              break;
-+      }
-+
-+      buffer_free(err->buf);
-+      buffer_free(err->cached_ts_str);
-+      if (err->file) buffer_free(err->file);
-+
-+      free(err);
-+
-+      myconfig = NULL;
-+}
-+
-+int log_error_open(buffer *file, int use_syslog) {
-+      int fd;
-+      int close_stderr = 1;
-+
-+      errorlog *err = myconfig;
-+
- #ifdef HAVE_SYSLOG_H
-       /* perhaps someone wants to use syslog() */
-       openlog("lighttpd", LOG_CONS | LOG_PID, LOG_DAEMON);
- #endif
--      srv->errorlog_mode = ERRORLOG_STDERR;
--      
--      if (srv->srvconf.errorlog_use_syslog) {
--              srv->errorlog_mode = ERRORLOG_SYSLOG;
--      } else if (!buffer_is_empty(srv->srvconf.errorlog_file)) {
--              const char *logfile = srv->srvconf.errorlog_file->ptr;
--              
--              if (-1 == (srv->errorlog_fd = open(logfile, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) {
--                      log_error_write(srv, __FILE__, __LINE__, "SSSS", 
--                                      "opening errorlog '", logfile,
-+      err->mode = ERRORLOG_STDERR;
-+
-+      if (use_syslog) {
-+              err->mode = ERRORLOG_SYSLOG;
-+      } else if (!buffer_is_empty(file)) {
-+              if (-1 == (err->fd = open(file->ptr, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) {
-+                      log_error_write(NULL, __FILE__, __LINE__, "SBSS",
-+                                      "opening errorlog '", file,
-                                       "' failed: ", strerror(errno));
--                      
-+
-                       return -1;
-               }
- #ifdef FD_CLOEXEC
-               /* close fd on exec (cgi) */
--              fcntl(srv->errorlog_fd, F_SETFD, FD_CLOEXEC);
-+              fcntl(err->fd, F_SETFD, FD_CLOEXEC);
- #endif
--              srv->errorlog_mode = ERRORLOG_FILE;
-+              err->mode = ERRORLOG_FILE;
-       }
--      
--      log_error_write(srv, __FILE__, __LINE__, "s", "server started");
--      
-+
-+      TRACE("%s", "server started");
-+
- #ifdef HAVE_VALGRIND_VALGRIND_H
-       /* don't close stderr for debugging purposes if run in valgrind */
-       if (RUNNING_ON_VALGRIND) close_stderr = 0;
- #endif
--      if (srv->errorlog_mode == ERRORLOG_STDERR) close_stderr = 0;
--      
-+      if (err->mode == ERRORLOG_STDERR) close_stderr = 0;
-+
-       /* move stderr to /dev/null */
-       if (close_stderr &&
-           -1 != (fd = open("/dev/null", O_WRONLY))) {
-@@ -90,167 +154,202 @@
-       return 0;
- }
--/** 
-+/**
-  * open the errorlog
-- * 
-+ *
-  * if the open failed, report to the user and die
-  * if no filename is given, use syslog instead
-- * 
-+ *
-  */
--int log_error_cycle(server *srv) {
-+int log_error_cycle(void) {
-       /* only cycle if we are not in syslog-mode */
--      
--      if (srv->errorlog_mode == ERRORLOG_FILE) {
--              const char *logfile = srv->srvconf.errorlog_file->ptr;
-+
-+      errorlog *err = myconfig;
-+
-+      if (err->mode == ERRORLOG_FILE) {
-+              buffer *file = err->file;
-               /* already check of opening time */
--              
-+
-               int new_fd;
--              
--              if (-1 == (new_fd = open(logfile, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) {
-+
-+              if (-1 == (new_fd = open(file->ptr, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) {
-                       /* write to old log */
--                      log_error_write(srv, __FILE__, __LINE__, "SSSSS", 
--                                      "cycling errorlog '", logfile,
-+                      log_error_write(NULL, __FILE__, __LINE__, "SBSSS",
-+                                      "cycling errorlog '", file,
-                                       "' failed: ", strerror(errno),
-                                       ", falling back to syslog()");
--                      
--                      close(srv->errorlog_fd);
--                      srv->errorlog_fd = -1;
--#ifdef HAVE_SYSLOG_H  
--                      srv->errorlog_mode = ERRORLOG_SYSLOG;
-+
-+                      close(err->fd);
-+                      err->fd = -1;
-+#ifdef HAVE_SYSLOG_H
-+                      err->mode = ERRORLOG_SYSLOG;
- #endif
-               } else {
-                       /* ok, new log is open, close the old one */
--                      close(srv->errorlog_fd);
--                      srv->errorlog_fd = new_fd;
-+                      close(err->fd);
-+                      err->fd = new_fd;
-               }
-       }
--      
--      log_error_write(srv, __FILE__, __LINE__, "s", "logfiles cycled");
--      
--      return 0;
--}
--int log_error_close(server *srv) {
--      log_error_write(srv, __FILE__, __LINE__, "s", "server stopped");
--      
--      switch(srv->errorlog_mode) {
--      case ERRORLOG_FILE:
--              close(srv->errorlog_fd);
--              break;
--      case ERRORLOG_SYSLOG:
--#ifdef HAVE_SYSLOG_H
--              closelog();
--#endif
--              break;
--      case ERRORLOG_STDERR:
--              break;
--      }
--      
-+      TRACE("%s", "logfiles cycled");
-+
-       return 0;
- }
--int log_error_write(server *srv, const char *filename, unsigned int line, const char *fmt, ...) {
-+int log_error_write(void *srv, const char *filename, unsigned int line, const char *fmt, ...) {
-       va_list ap;
--      
--      switch(srv->errorlog_mode) {
-+      time_t t;
-+
-+      errorlog *err = myconfig;
-+
-+      switch(err->mode) {
-       case ERRORLOG_FILE:
-       case ERRORLOG_STDERR:
-               /* cache the generated timestamp */
--              if (srv->cur_ts != srv->last_generated_debug_ts) {
--                      buffer_prepare_copy(srv->ts_debug_str, 255);
--                      strftime(srv->ts_debug_str->ptr, srv->ts_debug_str->size - 1, "%Y-%m-%d %H:%M:%S", localtime(&(srv->cur_ts)));
--                      srv->ts_debug_str->used = strlen(srv->ts_debug_str->ptr) + 1;
--                      
--                      srv->last_generated_debug_ts = srv->cur_ts;
-+              t = time(NULL);
-+              
-+              if (t != err->cached_ts) {
-+                      buffer_prepare_copy(err->cached_ts_str, 255);
-+                      strftime(err->cached_ts_str->ptr, err->cached_ts_str->size - 1, "%Y-%m-%d %H:%M:%S", localtime(&(t)));
-+                      err->cached_ts_str->used = strlen(err->cached_ts_str->ptr) + 1;
-+                      err->cached_ts = t;
-               }
--              buffer_copy_string_buffer(srv->errorlog_buf, srv->ts_debug_str);
--              BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, ": (");
-+              buffer_copy_string_buffer(err->buf, err->cached_ts_str);
-+              BUFFER_APPEND_STRING_CONST(err->buf, ": (");
-               break;
-       case ERRORLOG_SYSLOG:
-               /* syslog is generating its own timestamps */
--              BUFFER_COPY_STRING_CONST(srv->errorlog_buf, "(");
-+              BUFFER_COPY_STRING_CONST(err->buf, "(");
-               break;
-       }
--      
--      buffer_append_string(srv->errorlog_buf, filename);
--      BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, ".");
--      buffer_append_long(srv->errorlog_buf, line);
--      BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, ") ");
--      
--      
-+
-+      buffer_append_string(err->buf, filename);
-+      BUFFER_APPEND_STRING_CONST(err->buf, ".");
-+      buffer_append_long(err->buf, line);
-+      BUFFER_APPEND_STRING_CONST(err->buf, ") ");
-+
-       for(va_start(ap, fmt); *fmt; fmt++) {
-               int d;
-               char *s;
-               buffer *b;
-               off_t o;
--              
-+
-               switch(*fmt) {
-               case 's':           /* string */
-                       s = va_arg(ap, char *);
--                      buffer_append_string(srv->errorlog_buf, s);
--                      BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, " ");
-+                      buffer_append_string(err->buf, s);
-+                      BUFFER_APPEND_STRING_CONST(err->buf, " ");
-                       break;
-               case 'b':           /* buffer */
-                       b = va_arg(ap, buffer *);
--                      buffer_append_string_buffer(srv->errorlog_buf, b);
--                      BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, " ");
-+                      buffer_append_string_buffer(err->buf, b);
-+                      BUFFER_APPEND_STRING_CONST(err->buf, " ");
-                       break;
-               case 'd':           /* int */
-                       d = va_arg(ap, int);
--                      buffer_append_long(srv->errorlog_buf, d);
--                      BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, " ");
-+                      buffer_append_long(err->buf, d);
-+                      BUFFER_APPEND_STRING_CONST(err->buf, " ");
-                       break;
-               case 'o':           /* off_t */
-                       o = va_arg(ap, off_t);
--                      buffer_append_off_t(srv->errorlog_buf, o);
--                      BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, " ");
-+                      buffer_append_off_t(err->buf, o);
-+                      BUFFER_APPEND_STRING_CONST(err->buf, " ");
-                       break;
-               case 'x':           /* int (hex) */
-                       d = va_arg(ap, int);
--                      BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, "0x");
--                      buffer_append_long_hex(srv->errorlog_buf, d);
--                      BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, " ");
-+                      BUFFER_APPEND_STRING_CONST(err->buf, "0x");
-+                      buffer_append_long_hex(err->buf, d);
-+                      BUFFER_APPEND_STRING_CONST(err->buf, " ");
-                       break;
-               case 'S':           /* string */
-                       s = va_arg(ap, char *);
--                      buffer_append_string(srv->errorlog_buf, s);
-+                      buffer_append_string(err->buf, s);
-                       break;
-               case 'B':           /* buffer */
-                       b = va_arg(ap, buffer *);
--                      buffer_append_string_buffer(srv->errorlog_buf, b);
-+                      buffer_append_string_buffer(err->buf, b);
-                       break;
-               case 'D':           /* int */
-                       d = va_arg(ap, int);
--                      buffer_append_long(srv->errorlog_buf, d);
-+                      buffer_append_long(err->buf, d);
-                       break;
-               case '(':
-               case ')':
--              case '<':       
-+              case '<':
-               case '>':
-               case ',':
-               case ' ':
--                      buffer_append_string_len(srv->errorlog_buf, fmt, 1);
-+                      buffer_append_string_len(err->buf, fmt, 1);
-                       break;
-               }
-       }
-       va_end(ap);
--      
--      switch(srv->errorlog_mode) {
-+
-+      switch(err->mode) {
-       case ERRORLOG_FILE:
--              BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, "\n");
--              write(srv->errorlog_fd, srv->errorlog_buf->ptr, srv->errorlog_buf->used - 1);
-+              BUFFER_APPEND_STRING_CONST(err->buf, "\n");
-+              write(err->fd, err->buf->ptr, err->buf->used - 1);
-               break;
-       case ERRORLOG_STDERR:
--              BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, "\n");
--              write(STDERR_FILENO, srv->errorlog_buf->ptr, srv->errorlog_buf->used - 1);
-+              BUFFER_APPEND_STRING_CONST(err->buf, "\n");
-+              write(STDERR_FILENO, err->buf->ptr, err->buf->used - 1);
-               break;
-+#ifdef HAVE_SYSLOG_H
-+      case ERRORLOG_SYSLOG:
-+              syslog(LOG_ERR, "%s", err->buf->ptr);
-+              break;
-+#endif
-+      }
-+
-+      return 0;
-+}
-+
-+static int log_trace_write(const char *fmt, va_list ap) {
-+      buffer *b;
-+      int l;
-+      errorlog *err = myconfig;
-+      
-+      b = buffer_init();
-+      buffer_prepare_copy(b, 1024);
-+      l = vsnprintf(b->ptr, b->size - 1, fmt, ap);
-+      if (l > 0) {
-+              b->used = (l > b->size - 1) ? b->size : l + 1;
-+      }
-+
-+      /* write b */
-+      switch(err->mode) {
-+      case ERRORLOG_FILE:
-+              buffer_append_string(b, "\r\n");
-+              write(err->fd, b->ptr, b->used - 1);
-+              break;
-+      case ERRORLOG_STDERR:
-+              buffer_append_string(b, "\r\n");
-+              write(STDERR_FILENO, b->ptr, b->used - 1);
-+              break;
-+#ifdef HAVE_SYSLOG_H
-       case ERRORLOG_SYSLOG:
--              syslog(LOG_ERR, "%s", srv->errorlog_buf->ptr);
-+              syslog(LOG_ERR, "%s", b->ptr);
-               break;
-+#endif
-       }
-       
-+      buffer_free(b);
-+
-+      return 0;
-+}
-+
-+int log_trace(const char *fmt, ...) {
-+      va_list ap;
-+
-+      va_start(ap, fmt);
-+
-+      log_trace_write(fmt, ap);
-+
-+      va_end(ap);
-+
-       return 0;
- }
-+
---- ../lighttpd-1.4.11/src/log.h       2005-08-11 01:26:36.000000000 +0300
-+++ lighttpd-1.5.0/src/log.h   2006-07-18 13:03:40.000000000 +0300
-@@ -1,13 +1,22 @@
- #ifndef _LOG_H_
- #define _LOG_H_
--#include "server.h"
-+#include "buffer.h"
--#define WP() log_error_write(srv, __FILE__, __LINE__, "");
-+void log_init(void); 
-+void log_free(void); 
--int log_error_open(server *srv);
--int log_error_close(server *srv);
--int log_error_write(server *srv, const char *filename, unsigned int line, const char *fmt, ...);
--int log_error_cycle(server *srv);
--      
-+int log_error_open(buffer *file, int use_syslog);
-+int log_error_close();
-+int log_error_write(void *srv, const char *filename, unsigned int line, const char *fmt, ...);
-+int log_error_cycle();
-+
-+#define ERROR(fmt, ...) \
-+      log_trace("%s.%d: (error) "fmt, __FILE__, __LINE__, __VA_ARGS__)
-+
-+#define TRACE(fmt, ...) \
-+      log_trace("%s.%d: (trace) "fmt, __FILE__, __LINE__, __VA_ARGS__)
-+
-+#define SEGFAULT() do { ERROR("%s", "Ooh, Ooh, Ooh. Something is not good ... going down"); abort(); } while(0)
-+int log_trace(const char *fmt, ...);
- #endif
---- ../lighttpd-1.4.11/src/md5.h       2005-11-17 16:20:40.000000000 +0200
-+++ lighttpd-1.5.0/src/md5.h   2006-07-16 00:26:04.000000000 +0300
-@@ -30,9 +30,15 @@
- # include <inttypes.h>
- #endif
-+#ifdef _WIN32
-+#define UINT4 unsigned __int32
-+#define UINT2 unsigned __int16
-+#define POINTER unsigned char *
-+#else
- #define UINT4 uint32_t
- #define UINT2 uint16_t
- #define POINTER unsigned char *
-+#endif
- /* MD5 context. */
- typedef struct {
---- ../lighttpd-1.4.11/src/mod_access.c        2006-01-14 19:44:54.000000000 +0200
-+++ lighttpd-1.5.0/src/mod_access.c    2006-07-16 00:26:04.000000000 +0300
-@@ -8,126 +8,125 @@
- #include "plugin.h"
-+#include "sys-strings.h"
-+
- typedef struct {
-       array *access_deny;
- } plugin_config;
- typedef struct {
-       PLUGIN_DATA;
--      
-+
-       plugin_config **config_storage;
--      
--      plugin_config conf; 
-+
-+      plugin_config conf;
- } plugin_data;
- INIT_FUNC(mod_access_init) {
-       plugin_data *p;
--      
-+
-       p = calloc(1, sizeof(*p));
--      
-+
-       return p;
- }
- FREE_FUNC(mod_access_free) {
-       plugin_data *p = p_d;
--      
-+
-       UNUSED(srv);
-       if (!p) return HANDLER_GO_ON;
--      
-+
-       if (p->config_storage) {
-               size_t i;
-               for (i = 0; i < srv->config_context->used; i++) {
-                       plugin_config *s = p->config_storage[i];
--                      
-+
-                       array_free(s->access_deny);
--                      
-+
-                       free(s);
-               }
-               free(p->config_storage);
-       }
--      
-+
-       free(p);
--      
-+
-       return HANDLER_GO_ON;
- }
- SETDEFAULTS_FUNC(mod_access_set_defaults) {
-       plugin_data *p = p_d;
-       size_t i = 0;
--      
--      config_values_t cv[] = { 
-+
-+      config_values_t cv[] = {
-               { "url.access-deny",             NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },
-               { NULL,                          NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
-       };
--      
-+
-       p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
--      
-+
-       for (i = 0; i < srv->config_context->used; i++) {
-               plugin_config *s;
--              
-+
-               s = calloc(1, sizeof(plugin_config));
-               s->access_deny    = array_init();
--              
-+
-               cv[0].destination = s->access_deny;
--              
-+
-               p->config_storage[i] = s;
--      
-+
-               if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
-                       return HANDLER_ERROR;
-               }
-       }
--      
-+
-       return HANDLER_GO_ON;
- }
--#define PATCH(x) \
--      p->conf.x = s->x;
- static int mod_access_patch_connection(server *srv, connection *con, plugin_data *p) {
-       size_t i, j;
-       plugin_config *s = p->config_storage[0];
--      PATCH(access_deny);
--      
-+      PATCH_OPTION(access_deny);
-+
-       /* skip the first, the global context */
-       for (i = 1; i < srv->config_context->used; i++) {
-               data_config *dc = (data_config *)srv->config_context->data[i];
-               s = p->config_storage[i];
--              
-+
-               /* condition didn't match */
-               if (!config_check_cond(srv, con, dc)) continue;
--              
-+
-               /* merge config */
-               for (j = 0; j < dc->value->used; j++) {
-                       data_unset *du = dc->value->data[j];
--                      
-+
-                       if (buffer_is_equal_string(du->key, CONST_STR_LEN("url.access-deny"))) {
--                              PATCH(access_deny);
-+                              PATCH_OPTION(access_deny);
-                       }
-               }
-       }
--      
-+
-       return 0;
- }
--#undef PATCH
- URIHANDLER_FUNC(mod_access_uri_handler) {
-       plugin_data *p = p_d;
-       int s_len;
-       size_t k;
--      
-+
-       if (con->uri.path->used == 0) return HANDLER_GO_ON;
--      
-+
-       mod_access_patch_connection(srv, con, p);
--      
-+
-       s_len = con->uri.path->used - 1;
--      
-+
-       for (k = 0; k < p->conf.access_deny->used; k++) {
-               data_string *ds = (data_string *)p->conf.access_deny->data[k];
-               int ct_len = ds->value->used - 1;
--              
-+
-               if (ct_len > s_len) continue;
--              
-+
-               if (ds->value->used == 0) continue;
-               /* if we have a case-insensitive FS we have to lower-case the URI here too */
-@@ -135,18 +134,18 @@
-               if (con->conf.force_lowercase_filenames) {
-                       if (0 == strncasecmp(con->uri.path->ptr + s_len - ct_len, ds->value->ptr, ct_len)) {
-                               con->http_status = 403;
--                      
-+
-                               return HANDLER_FINISHED;
-                       }
-               } else {
-                       if (0 == strncmp(con->uri.path->ptr + s_len - ct_len, ds->value->ptr, ct_len)) {
-                               con->http_status = 403;
--                      
-+
-                               return HANDLER_FINISHED;
-                       }
-               }
-       }
--      
-+
-       /* not found */
-       return HANDLER_GO_ON;
- }
-@@ -155,13 +154,13 @@
- int mod_access_plugin_init(plugin *p) {
-       p->version     = LIGHTTPD_VERSION_ID;
-       p->name        = buffer_init_string("access");
--      
-+
-       p->init        = mod_access_init;
-       p->set_defaults = mod_access_set_defaults;
-       p->handle_uri_clean  = mod_access_uri_handler;
-       p->cleanup     = mod_access_free;
--      
-+
-       p->data        = NULL;
--      
-+
-       return 0;
- }
---- ../lighttpd-1.4.11/src/mod_accesslog.c     2006-01-31 14:01:43.000000000 +0200
-+++ lighttpd-1.5.0/src/mod_accesslog.c 2006-09-07 00:57:05.000000000 +0300
-@@ -6,8 +6,7 @@
- #include <ctype.h>
- #include <stdlib.h>
- #include <string.h>
--#include <fcntl.h>
--#include <unistd.h>
-+#include <fcntl.h> /* only the defines on windows */
- #include <errno.h>
- #include <time.h>
-@@ -22,6 +21,7 @@
- #include "inet_ntop_cache.h"
- #include "sys-socket.h"
-+#include "sys-files.h"
- #ifdef HAVE_SYSLOG_H
- # include <syslog.h>
-@@ -29,7 +29,7 @@
- typedef struct {
-       char key;
--      enum { 
-+      enum {
-               FORMAT_UNSET,
-                       FORMAT_UNSUPPORTED,
-                       FORMAT_PERCENT,
-@@ -41,7 +41,7 @@
-                       FORMAT_STATUS,
-                       FORMAT_BYTES_OUT_NO_HEADER,
-                       FORMAT_HEADER,
--                      
-+
-                       FORMAT_REMOTE_ADDR,
-                       FORMAT_LOCAL_ADDR,
-                       FORMAT_COOKIE,
-@@ -59,20 +59,20 @@
-                       FORMAT_CONNECTION_STATUS,
-                       FORMAT_BYTES_IN,
-                       FORMAT_BYTES_OUT,
--                      
-+
-                       FORMAT_RESPONSE_HEADER
-       } type;
- } format_mapping;
- /**
-- * 
-- * 
-+ *
-+ *
-  * "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\""
-- * 
-+ *
-  */
--const format_mapping fmap[] = 
--{ 
-+const format_mapping fmap[] =
-+{
-       { '%', FORMAT_PERCENT },
-       { 'h', FORMAT_REMOTE_HOST },
-       { 'l', FORMAT_REMOTE_IDENT },
-@@ -82,7 +82,7 @@
-       { 's', FORMAT_STATUS },
-       { 'b', FORMAT_BYTES_OUT_NO_HEADER },
-       { 'i', FORMAT_HEADER },
--      
-+
-       { 'a', FORMAT_REMOTE_ADDR },
-       { 'A', FORMAT_LOCAL_ADDR },
-       { 'B', FORMAT_BYTES_OUT_NO_HEADER },
-@@ -103,23 +103,23 @@
-       { 'X', FORMAT_CONNECTION_STATUS },
-       { 'I', FORMAT_BYTES_IN },
-       { 'O', FORMAT_BYTES_OUT },
--      
-+
-       { 'o', FORMAT_RESPONSE_HEADER },
--      
-+
-       { '\0', FORMAT_UNSET }
- };
- typedef struct {
-       enum { FIELD_UNSET, FIELD_STRING, FIELD_FORMAT } type;
--      
-+
-       buffer *string;
-       int field;
- } format_field;
- typedef struct {
-       format_field **ptr;
--      
-+
-       size_t used;
-       size_t size;
- } format_fields;
-@@ -128,39 +128,39 @@
-       buffer *access_logfile;
-       buffer *format;
-       unsigned short use_syslog;
--      
--      
-+
-+
-       int    log_access_fd;
-       time_t last_generated_accesslog_ts;
-       time_t *last_generated_accesslog_ts_ptr;
--      
--      
-+
-+
-       buffer *access_logbuffer;
-       buffer *ts_accesslog_str;
--      
-+
-       format_fields *parsed_format;
- } plugin_config;
- typedef struct {
-       PLUGIN_DATA;
--      
-+
-       plugin_config **config_storage;
--      plugin_config conf; 
-+      plugin_config conf;
- } plugin_data;
- INIT_FUNC(mod_accesslog_init) {
-       plugin_data *p;
--      
-+
-       p = calloc(1, sizeof(*p));
--      
-+
-       return p;
- }
- int accesslog_parse_format(server *srv, format_fields *fields, buffer *format) {
-       size_t i, j, k = 0, start = 0;
--      
-+
-       for (i = 0; i < format->used - 1; i++) {
--              
-+
-               switch(format->ptr[i]) {
-               case '%':
-                       if (start != i) {
-@@ -173,19 +173,19 @@
-                                       fields->size += 16;
-                                       fields->ptr = realloc(fields->ptr, fields->size * sizeof(format_fields * ));
-                               }
--                              
-+
-                               fields->ptr[fields->used] = malloc(sizeof(format_fields));
-                               fields->ptr[fields->used]->type = FIELD_STRING;
-                               fields->ptr[fields->used]->string = buffer_init();
--                              
-+
-                               buffer_copy_string_len(fields->ptr[fields->used]->string, format->ptr + start, i - start);
--                              
-+
-                               fields->used++;
-                       }
--                      
--                      
-+
-+
-                       /* we need a new field */
--                      
-+
-                       if (fields->size == 0) {
-                               fields->size = 16;
-                               fields->used = 0;
-@@ -194,43 +194,43 @@
-                               fields->size += 16;
-                               fields->ptr = realloc(fields->ptr, fields->size * sizeof(format_fields * ));
-                       }
--                      
-+
-                       /* search for the terminating command */
-                       switch (format->ptr[i+1]) {
-                       case '>':
-                       case '<':
-                               /* only for s */
--                              
-+
-                               for (j = 0; fmap[j].key != '\0'; j++) {
-                                       if (fmap[j].key != format->ptr[i+2]) continue;
--                                      
-+
-                                       /* found key */
--                                              
-+
-                                       fields->ptr[fields->used] = malloc(sizeof(format_fields));
-                                       fields->ptr[fields->used]->type = FIELD_FORMAT;
-                                       fields->ptr[fields->used]->field = fmap[j].type;
-                                       fields->ptr[fields->used]->string = NULL;
--                                      
-+
-                                       fields->used++;
--                                      
-+
-                                       break;
-                               }
--                              
-+
-                               if (fmap[j].key == '\0') {
-                                       log_error_write(srv, __FILE__, __LINE__, "ss", "config: ", "failed");
-                                       return -1;
-                               }
--                              
-+
-                               start = i + 3;
--                              
-+
-                               break;
-                       case '{':
-                               /* go forward to } */
--                              
-+
-                               for (k = i+2; k < format->used - 1; k++) {
-                                       if (format->ptr[k] == '}') break;
-                               }
--                              
-+
-                               if (k == format->used - 1) {
-                                       log_error_write(srv, __FILE__, __LINE__, "ss", "config: ", "failed");
-                                       return -1;
-@@ -239,62 +239,62 @@
-                                       log_error_write(srv, __FILE__, __LINE__, "ss", "config: ", "failed");
-                                       return -1;
-                               }
--                              
-+
-                               for (j = 0; fmap[j].key != '\0'; j++) {
-                                       if (fmap[j].key != format->ptr[k+1]) continue;
--                                      
-+
-                                       /* found key */
--                                              
-+
-                                       fields->ptr[fields->used] = malloc(sizeof(format_fields));
-                                       fields->ptr[fields->used]->type = FIELD_FORMAT;
-                                       fields->ptr[fields->used]->field = fmap[j].type;
-                                       fields->ptr[fields->used]->string = buffer_init();
--                                      
-+
-                                       buffer_copy_string_len(fields->ptr[fields->used]->string, format->ptr + i + 2, k - (i + 2));
--                                      
-+
-                                       fields->used++;
--                                      
-+
-                                       break;
-                               }
--                              
-+
-                               if (fmap[j].key == '\0') {
-                                       log_error_write(srv, __FILE__, __LINE__, "ss", "config: ", "failed");
-                                       return -1;
-                               }
--                              
-+
-                               start = k + 2;
--                              
-+
-                               break;
-                       default:
-                               for (j = 0; fmap[j].key != '\0'; j++) {
-                                       if (fmap[j].key != format->ptr[i+1]) continue;
--                                      
-+
-                                       /* found key */
--                                              
-+
-                                       fields->ptr[fields->used] = malloc(sizeof(format_fields));
-                                       fields->ptr[fields->used]->type = FIELD_FORMAT;
-                                       fields->ptr[fields->used]->field = fmap[j].type;
-                                       fields->ptr[fields->used]->string = NULL;
--                                      
-+
-                                       fields->used++;
--                                      
-+
-                                       break;
-                               }
--                              
-+
-                               if (fmap[j].key == '\0') {
-                                       log_error_write(srv, __FILE__, __LINE__, "ss", "config: ", "failed");
-                                       return -1;
-                               }
--                              
-+
-                               start = i + 2;
--                              
-+
-                               break;
-                       }
--                      
-+
-                       break;
-               }
-       }
--      
-+
-       if (start < i) {
-               /* copy the string */
-               if (fields->size == 0) {
-@@ -305,32 +305,32 @@
-                       fields->size += 16;
-                       fields->ptr = realloc(fields->ptr, fields->size * sizeof(format_fields * ));
-               }
--              
-+
-               fields->ptr[fields->used] = malloc(sizeof(format_fields));
-               fields->ptr[fields->used]->type = FIELD_STRING;
-               fields->ptr[fields->used]->string = buffer_init();
--              
-+
-               buffer_copy_string_len(fields->ptr[fields->used]->string, format->ptr + start, i - start);
--              
-+
-               fields->used++;
-       }
--      
-+
-       return 0;
- }
- FREE_FUNC(mod_accesslog_free) {
-       plugin_data *p = p_d;
-       size_t i;
--      
-+
-       if (!p) return HANDLER_GO_ON;
--      
-+
-       if (p->config_storage) {
--              
-+
-               for (i = 0; i < srv->config_context->used; i++) {
-                       plugin_config *s = p->config_storage[i];
-                       if (!s) continue;
--                      
-+
-                       if (s->access_logbuffer->used) {
-                               if (s->use_syslog) {
- # ifdef HAVE_SYSLOG_H
-@@ -342,14 +342,14 @@
-                                       write(s->log_access_fd, s->access_logbuffer->ptr, s->access_logbuffer->used - 1);
-                               }
-                       }
--                      
-+
-                       if (s->log_access_fd != -1) close(s->log_access_fd);
--                      
-+
-                       buffer_free(s->ts_accesslog_str);
-                       buffer_free(s->access_logbuffer);
-                       buffer_free(s->format);
-                       buffer_free(s->access_logfile);
--                      
-+
-                       if (s->parsed_format) {
-                               size_t j;
-                               for (j = 0; j < s->parsed_format->used; j++) {
-@@ -359,36 +359,36 @@
-                               free(s->parsed_format->ptr);
-                               free(s->parsed_format);
-                       }
--                      
-+
-                       free(s);
-               }
--      
-+
-               free(p->config_storage);
-       }
--      
-+
-       free(p);
--      
-+
-       return HANDLER_GO_ON;
- }
- SETDEFAULTS_FUNC(log_access_open) {
-       plugin_data *p = p_d;
-       size_t i = 0;
--      
--      config_values_t cv[] = { 
-+
-+      config_values_t cv[] = {
-               { "accesslog.filename",             NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
-               { "accesslog.use-syslog",           NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },
-               { "accesslog.format",               NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
-               { NULL,                             NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
-       };
--      
-+
-       if (!p) return HANDLER_ERROR;
--      
-+
-       p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
--      
-+
-       for (i = 0; i < srv->config_context->used; i++) {
-               plugin_config *s;
--              
-+
-               s = calloc(1, sizeof(plugin_config));
-               s->access_logfile = buffer_init();
-               s->format = buffer_init();
-@@ -397,44 +397,44 @@
-               s->log_access_fd = -1;
-               s->last_generated_accesslog_ts = 0;
-               s->last_generated_accesslog_ts_ptr = &(s->last_generated_accesslog_ts);
--              
--      
-+
-+
-               cv[0].destination = s->access_logfile;
-               cv[1].destination = &(s->use_syslog);
-               cv[2].destination = s->format;
--      
-+
-               p->config_storage[i] = s;
--              
-+
-               if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
-                       return HANDLER_ERROR;
-               }
--              
-+
-               if (i == 0 && buffer_is_empty(s->format)) {
-                       /* set a default logfile string */
--                      
-+
-                       buffer_copy_string(s->format, "%h %V %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"");
-               }
--              
-+
-               /* parse */
--              
-+
-               if (s->format->used) {
-                       s->parsed_format = calloc(1, sizeof(*(s->parsed_format)));
--                      
-+
-                       if (-1 == accesslog_parse_format(srv, s->parsed_format, s->format)) {
--                              log_error_write(srv, __FILE__, __LINE__, "sb", 
-+                              log_error_write(srv, __FILE__, __LINE__, "sb",
-                                               "parsing accesslog-definition failed:", s->format);
-                               return HANDLER_ERROR;
-                       }
- #if 0
--                      /* debugging */                 
-+                      /* debugging */
-                       for (j = 0; j < s->parsed_format->used; j++) {
-                               switch (s->parsed_format->ptr[j]->type) {
-                               case FIELD_FORMAT:
--                                      log_error_write(srv, __FILE__, __LINE__, "ssds", 
-+                                      log_error_write(srv, __FILE__, __LINE__, "ssds",
-                                                       "config:", "format", s->parsed_format->ptr[j]->field,
--                                                      s->parsed_format->ptr[j]->string ? 
-+                                                      s->parsed_format->ptr[j]->string ?
-                                                       s->parsed_format->ptr[j]->string->ptr : "" );
-                                       break;
-                               case FIELD_STRING:
-@@ -446,52 +446,52 @@
-                       }
- #endif
-               }
--              
-+
-               if (s->use_syslog) {
-                       /* ignore the next checks */
-                       continue;
-               }
--              
-+
-               if (buffer_is_empty(s->access_logfile)) continue;
--              
-+
-               if (s->access_logfile->ptr[0] == '|') {
- #ifdef HAVE_FORK
-                       /* create write pipe and spawn process */
--                      
-+
-                       int to_log_fds[2];
-                       pid_t pid;
--                      
-+
-                       if (pipe(to_log_fds)) {
-                               log_error_write(srv, __FILE__, __LINE__, "ss", "pipe failed: ", strerror(errno));
-                               return HANDLER_ERROR;
-                       }
--                      
-+
-                       /* fork, execve */
-                       switch (pid = fork()) {
--                      case 0: 
-+                      case 0:
-                               /* child */
--                              
-+
-                               close(STDIN_FILENO);
-                               dup2(to_log_fds[0], STDIN_FILENO);
-                               close(to_log_fds[0]);
-                               /* not needed */
-                               close(to_log_fds[1]);
--                              
-+
-                               /* we don't need the client socket */
-                               for (i = 3; i < 256; i++) {
-                                       close(i);
-                               }
--                              
--                              /* exec the log-process (skip the | ) 
--                               * 
-+
-+                              /* exec the log-process (skip the | )
-+                               *
-                                */
--                              
-+
-                               execl("/bin/sh", "sh", "-c", s->access_logfile->ptr + 1, NULL);
--                              log_error_write(srv, __FILE__, __LINE__, "sss", 
--                                              "spawning log-process failed: ", strerror(errno), 
-+                              log_error_write(srv, __FILE__, __LINE__, "sss",
-+                                              "spawning log-process failed: ", strerror(errno),
-                                               s->access_logfile->ptr + 1);
--                              
-+
-                               exit(-1);
-                               break;
-                       case -1:
-@@ -500,27 +500,28 @@
-                               break;
-                       default:
-                               close(to_log_fds[0]);
--                              
-+
-                               s->log_access_fd = to_log_fds[1];
--                              
-+
-                               break;
-                       }
- #else
-                       return -1;
- #endif
--              } else if (-1 == (s->log_access_fd = 
-+              } else if (-1 == (s->log_access_fd =
-                                 open(s->access_logfile->ptr, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) {
--                      
--                      log_error_write(srv, __FILE__, __LINE__, "ssb", 
--                                      "opening access-log failed:", 
-+
-+                      log_error_write(srv, __FILE__, __LINE__, "ssb",
-+                                      "opening access-log failed:",
-                                       strerror(errno), s->access_logfile);
--                      
-+
-                       return HANDLER_ERROR;
-               }
-+#ifndef _WIN32
-               fcntl(s->log_access_fd, F_SETFD, FD_CLOEXEC);
--      
-+#endif
-       }
--      
-+
-       return HANDLER_GO_ON;
- }
-@@ -529,7 +530,7 @@
-       size_t i;
-       if (!p->config_storage) return HANDLER_GO_ON;
--              
-+
-       for (i = 0; i < srv->config_context->used; i++) {
-               plugin_config *s = p->config_storage[i];
-@@ -544,90 +545,87 @@
-                       } else if (s->log_access_fd != -1) {
-                               write(s->log_access_fd, s->access_logbuffer->ptr, s->access_logbuffer->used - 1);
-                       }
--                      
-+
-                       buffer_reset(s->access_logbuffer);
-               }
--              
-+
-               if (s->use_syslog == 0 &&
-                   !buffer_is_empty(s->access_logfile) &&
-                   s->access_logfile->ptr[0] != '|') {
--                      
-+
-                       close(s->log_access_fd);
--                      
--                      if (-1 == (s->log_access_fd = 
-+
-+                      if (-1 == (s->log_access_fd =
-                                  open(s->access_logfile->ptr, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) {
--                              
-+
-                               log_error_write(srv, __FILE__, __LINE__, "ss", "cycling access-log failed:", strerror(errno));
--                              
-+
-                               return HANDLER_ERROR;
-                       }
-               }
-       }
--      
-+
-       return HANDLER_GO_ON;
- }
--#define PATCH(x) \
--      p->conf.x = s->x;
- static int mod_accesslog_patch_connection(server *srv, connection *con, plugin_data *p) {
-       size_t i, j;
-       plugin_config *s = p->config_storage[0];
--      
--      PATCH(access_logfile);
--      PATCH(format);
--      PATCH(log_access_fd);
--      PATCH(last_generated_accesslog_ts_ptr);
--      PATCH(access_logbuffer);
--      PATCH(ts_accesslog_str);
--      PATCH(parsed_format);
--      PATCH(use_syslog);
--      
-+
-+      PATCH_OPTION(access_logfile);
-+      PATCH_OPTION(format);
-+      PATCH_OPTION(log_access_fd);
-+      PATCH_OPTION(last_generated_accesslog_ts_ptr);
-+      PATCH_OPTION(access_logbuffer);
-+      PATCH_OPTION(ts_accesslog_str);
-+      PATCH_OPTION(parsed_format);
-+      PATCH_OPTION(use_syslog);
-+
-       /* skip the first, the global context */
-       for (i = 1; i < srv->config_context->used; i++) {
-               data_config *dc = (data_config *)srv->config_context->data[i];
-               s = p->config_storage[i];
--              
-+
-               /* condition didn't match */
-               if (!config_check_cond(srv, con, dc)) continue;
--              
-+
-               /* merge config */
-               for (j = 0; j < dc->value->used; j++) {
-                       data_unset *du = dc->value->data[j];
--                      
-+
-                       if (buffer_is_equal_string(du->key, CONST_STR_LEN("accesslog.filename"))) {
--                              PATCH(access_logfile);
--                              PATCH(log_access_fd);
--                              PATCH(last_generated_accesslog_ts_ptr);
--                              PATCH(access_logbuffer);
--                              PATCH(ts_accesslog_str);
-+                              PATCH_OPTION(access_logfile);
-+                              PATCH_OPTION(log_access_fd);
-+                              PATCH_OPTION(last_generated_accesslog_ts_ptr);
-+                              PATCH_OPTION(access_logbuffer);
-+                              PATCH_OPTION(ts_accesslog_str);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("accesslog.format"))) {
--                              PATCH(format);
--                              PATCH(parsed_format);
-+                              PATCH_OPTION(format);
-+                              PATCH_OPTION(parsed_format);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("accesslog.use-syslog"))) {
--                              PATCH(use_syslog);
-+                              PATCH_OPTION(use_syslog);
-                       }
-               }
-       }
--      
-+
-       return 0;
- }
--#undef PATCH
- REQUESTDONE_FUNC(log_access_write) {
-       plugin_data *p = p_d;
-       buffer *b;
-       size_t j;
--      
-+
-       int newts = 0;
-       data_string *ds;
--      
-+
-       mod_accesslog_patch_connection(srv, con, p);
--      
-+
-       b = p->conf.access_logbuffer;
-       if (b->used == 0) {
-               buffer_copy_string(b, "");
-       }
--      
-+
-       for (j = 0; j < p->conf.parsed_format->used; j++) {
-               switch(p->conf.parsed_format->ptr[j]->type) {
-               case FIELD_STRING:
-@@ -636,14 +634,14 @@
-               case FIELD_FORMAT:
-                       switch(p->conf.parsed_format->ptr[j]->field) {
-                       case FORMAT_TIMESTAMP:
--                              
-+
-                               /* cache the generated timestamp */
-                               if (srv->cur_ts != *(p->conf.last_generated_accesslog_ts_ptr)) {
-                                       struct tm tm;
- #if defined(HAVE_STRUCT_TM_GMTOFF)
-                                       long scd, hrs, min;
- #endif
--              
-+
-                                       buffer_prepare_copy(p->conf.ts_accesslog_str, 255);
- #if defined(HAVE_STRUCT_TM_GMTOFF)
- # ifdef HAVE_LOCALTIME_R
-@@ -653,17 +651,17 @@
-                                       strftime(p->conf.ts_accesslog_str->ptr, p->conf.ts_accesslog_str->size - 1, "[%d/%b/%Y:%H:%M:%S ", localtime_r(&(srv->cur_ts)));
- # endif
-                                       p->conf.ts_accesslog_str->used = strlen(p->conf.ts_accesslog_str->ptr) + 1;
--                                      
-+
-                                       buffer_append_string(p->conf.ts_accesslog_str, tm.tm_gmtoff >= 0 ? "+" : "-");
--                                      
-+
-                                       scd = abs(tm.tm_gmtoff);
-                                       hrs = scd / 3600;
-                                       min = (scd % 3600) / 60;
--                                      
-+
-                                       /* hours */
-                                       if (hrs < 10) buffer_append_string(p->conf.ts_accesslog_str, "0");
-                                       buffer_append_long(p->conf.ts_accesslog_str, hrs);
--                                      
-+
-                                       if (min < 10) buffer_append_string(p->conf.ts_accesslog_str, "0");
-                                       buffer_append_long(p->conf.ts_accesslog_str, min);
-                                       BUFFER_APPEND_STRING_CONST(p->conf.ts_accesslog_str, "]");
-@@ -676,20 +674,20 @@
- #endif
-                                       p->conf.ts_accesslog_str->used = strlen(p->conf.ts_accesslog_str->ptr) + 1;
- #endif
--                                      
-+
-                                       *(p->conf.last_generated_accesslog_ts_ptr) = srv->cur_ts;
-                                       newts = 1;
-                               }
--                              
-+
-                               buffer_append_string_buffer(b, p->conf.ts_accesslog_str);
--                              
-+
-                               break;
-                       case FORMAT_REMOTE_HOST:
--      
-+
-                               /* handle inet_ntop cache */
--      
-+
-                               buffer_append_string(b, inet_ntop_cache_get_ip(srv, &(con->dst_addr)));
--                              
-+
-                               break;
-                       case FORMAT_REMOTE_IDENT:
-                               /* ident */
-@@ -703,17 +701,20 @@
-                               }
-                               break;
-                       case FORMAT_REQUEST_LINE:
--                              if (con->request.request_line->used) {
--                                      buffer_append_string_buffer(b, con->request.request_line);
--                              }
-+                              buffer_append_string(b, get_http_method_name(con->request.http_method));
-+                              buffer_append_string(b, " ");
-+                              buffer_append_string_buffer(b, con->request.orig_uri);
-+                              buffer_append_string(b, " ");
-+                              buffer_append_string(b, get_http_version_name(con->request.http_version));
-+
-                               break;
-                       case FORMAT_STATUS:
-                               buffer_append_long(b, con->http_status);
-                               break;
--      
-+
-                       case FORMAT_BYTES_OUT_NO_HEADER:
-                               if (con->bytes_written > 0) {
--                                      buffer_append_off_t(b, 
-+                                      buffer_append_off_t(b,
-                                                           con->bytes_written - con->bytes_header <= 0 ? 0 : con->bytes_written - con->bytes_header);
-                               } else {
-                                       BUFFER_APPEND_STRING_CONST(b, "-");
-@@ -772,7 +773,7 @@
-                               }
-                               break;
-                       case FORMAT_REQUEST_PROTOCOL:
--                              buffer_append_string(b, 
-+                              buffer_append_string(b,
-                                                    con->request.http_version == HTTP_VERSION_1_1 ? "HTTP/1.1" : "HTTP/1.0");
-                               break;
-                       case FORMAT_REQUEST_METHOD:
-@@ -801,7 +802,7 @@
-                                { 'D', FORMAT_TIME_USED_MS },
-                                { 'e', FORMAT_ENV },
-                                */
--                              
-+
-                               break;
-                       }
-                       break;
-@@ -809,7 +810,7 @@
-                       break;
-               }
-       }
--      
-+
-       BUFFER_APPEND_STRING_CONST(b, "\n");
-       if (p->conf.use_syslog ||  /* syslog doesn't cache */
-@@ -828,7 +829,7 @@
-               }
-               buffer_reset(b);
-       }
--      
-+
-       return HANDLER_GO_ON;
- }
-@@ -836,15 +837,15 @@
- int mod_accesslog_plugin_init(plugin *p) {
-       p->version     = LIGHTTPD_VERSION_ID;
-       p->name        = buffer_init_string("accesslog");
--      
-+
-       p->init        = mod_accesslog_init;
-       p->set_defaults= log_access_open;
-       p->cleanup     = mod_accesslog_free;
--      
--      p->handle_request_done  = log_access_write;
--      p->handle_sighup        = log_access_cycle;
--      
-+
-+      p->handle_response_done  = log_access_write;
-+      p->handle_sighup         = log_access_cycle;
-+
-       p->data        = NULL;
--      
-+
-       return 0;
- }
---- ../lighttpd-1.4.11/src/mod_alias.c 2006-03-01 23:18:51.000000000 +0200
-+++ lighttpd-1.5.0/src/mod_alias.c     2006-07-16 00:26:03.000000000 +0300
-@@ -8,6 +8,7 @@
- #include "buffer.h"
- #include "plugin.h"
-+#include "sys-strings.h"
- /* plugin config for all request/connections */
- typedef struct {
-@@ -16,44 +17,44 @@
- typedef struct {
-       PLUGIN_DATA;
--      
-+
-       plugin_config **config_storage;
--      
--      plugin_config conf; 
-+
-+      plugin_config conf;
- } plugin_data;
- /* init the plugin data */
- INIT_FUNC(mod_alias_init) {
-       plugin_data *p;
--      
-+
-       p = calloc(1, sizeof(*p));
--      
--      
--      
-+
-+
-+
-       return p;
- }
- /* detroy the plugin data */
- FREE_FUNC(mod_alias_free) {
-       plugin_data *p = p_d;
--      
-+
-       if (!p) return HANDLER_GO_ON;
--      
-+
-       if (p->config_storage) {
-               size_t i;
--              
-+
-               for (i = 0; i < srv->config_context->used; i++) {
-                       plugin_config *s = p->config_storage[i];
--                      
-+
-                       array_free(s->alias);
--                      
-+
-                       free(s);
-               }
-               free(p->config_storage);
-       }
--      
-+
-       free(p);
--      
-+
-       return HANDLER_GO_ON;
- }
-@@ -62,25 +63,25 @@
- SETDEFAULTS_FUNC(mod_alias_set_defaults) {
-       plugin_data *p = p_d;
-       size_t i = 0;
--      
--      config_values_t cv[] = { 
-+
-+      config_values_t cv[] = {
-               { "alias.url",                  NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
-               { NULL,                         NULL, T_CONFIG_UNSET,  T_CONFIG_SCOPE_UNSET }
-       };
--      
-+
-       if (!p) return HANDLER_ERROR;
--      
-+
-       p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
--      
-+
-       for (i = 0; i < srv->config_context->used; i++) {
-               plugin_config *s;
--              
-+
-               s = calloc(1, sizeof(plugin_config));
--              s->alias = array_init();        
-+              s->alias = array_init();
-               cv[0].destination = s->alias;
--              
-+
-               p->config_storage[i] = s;
--              
-+
-               if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
-                       return HANDLER_ERROR;
-               }
-@@ -110,76 +111,73 @@
-                       }
-               }
-       }
--      
-+
-       return HANDLER_GO_ON;
- }
--#define PATCH(x) \
--      p->conf.x = s->x;
- static int mod_alias_patch_connection(server *srv, connection *con, plugin_data *p) {
-       size_t i, j;
-       plugin_config *s = p->config_storage[0];
--      
--      PATCH(alias);
--      
-+
-+      PATCH_OPTION(alias);
-+
-       /* skip the first, the global context */
-       for (i = 1; i < srv->config_context->used; i++) {
-               data_config *dc = (data_config *)srv->config_context->data[i];
-               s = p->config_storage[i];
--              
-+
-               /* condition didn't match */
-               if (!config_check_cond(srv, con, dc)) continue;
--              
-+
-               /* merge config */
-               for (j = 0; j < dc->value->used; j++) {
-                       data_unset *du = dc->value->data[j];
--                      
-+
-                       if (buffer_is_equal_string(du->key, CONST_STR_LEN("alias.url"))) {
--                              PATCH(alias);
-+                              PATCH_OPTION(alias);
-                       }
-               }
-       }
--      
-+
-       return 0;
- }
--#undef PATCH
- PHYSICALPATH_FUNC(mod_alias_physical_handler) {
-       plugin_data *p = p_d;
-       int uri_len, basedir_len;
-       char *uri_ptr;
-       size_t k;
--      
-+
-       if (con->physical.path->used == 0) return HANDLER_GO_ON;
--      
-+
-       mod_alias_patch_connection(srv, con, p);
--      
-+
-       /* not to include the tailing slash */
-       basedir_len = (con->physical.basedir->used - 1) - 1;
-       uri_len = con->physical.path->used - 1 - basedir_len;
-       uri_ptr = con->physical.path->ptr + basedir_len;
--      
-+
-       for (k = 0; k < p->conf.alias->used; k++) {
-               data_string *ds = (data_string *)p->conf.alias->data[k];
-               int alias_len = ds->key->used - 1;
--              
-+
-               if (alias_len > uri_len) continue;
-               if (ds->key->used == 0) continue;
--              
-+
-               if (0 == (con->conf.force_lowercase_filenames ?
-                                       strncasecmp(uri_ptr, ds->key->ptr, alias_len) :
-                                       strncmp(uri_ptr, ds->key->ptr, alias_len))) {
-                       /* matched */
--                      
-+
-                       buffer_copy_string_buffer(con->physical.basedir, ds->value);
-                       buffer_copy_string_buffer(srv->tmp_buf, ds->value);
-                       buffer_append_string(srv->tmp_buf, uri_ptr + alias_len);
-                       buffer_copy_string_buffer(con->physical.path, srv->tmp_buf);
--                      
-+
-                       return HANDLER_GO_ON;
-               }
-       }
--      
-+
-       /* not found */
-       return HANDLER_GO_ON;
- }
-@@ -189,13 +187,13 @@
- int mod_alias_plugin_init(plugin *p) {
-       p->version     = LIGHTTPD_VERSION_ID;
-       p->name        = buffer_init_string("alias");
--      
-+
-       p->init           = mod_alias_init;
-       p->handle_physical= mod_alias_physical_handler;
-       p->set_defaults   = mod_alias_set_defaults;
-       p->cleanup        = mod_alias_free;
--      
-+
-       p->data        = NULL;
--      
-+
-       return 0;
- }
---- ../lighttpd-1.4.11/src/mod_auth.c  2006-02-15 20:01:31.000000000 +0200
-+++ lighttpd-1.5.0/src/mod_auth.c      2006-07-18 13:03:40.000000000 +0300
-@@ -5,168 +5,167 @@
- #include <string.h>
- #include <errno.h>
- #include <fcntl.h>
--#include <unistd.h>
- #include "plugin.h"
- #include "http_auth.h"
- #include "log.h"
- #include "response.h"
-+#include "sys-strings.h"
-+#include "sys-files.h"
-+
- handler_t auth_ldap_init(server *srv, mod_auth_plugin_config *s);
- /**
-  * the basic and digest auth framework
-- * 
-+ *
-  * - config handling
-  * - protocol handling
-- * 
-- * http_auth.c 
-- * http_auth_digest.c 
-- * 
-+ *
-+ * http_auth.c
-+ * http_auth_digest.c
-+ *
-  * do the real work
-  */
- INIT_FUNC(mod_auth_init) {
-       mod_auth_plugin_data *p;
--      
-+
-       p = calloc(1, sizeof(*p));
--      
-+
-       p->tmp_buf = buffer_init();
--      
-+
-       p->auth_user = buffer_init();
- #ifdef USE_LDAP
-       p->ldap_filter = buffer_init();
- #endif
--      
-+
-       return p;
- }
- FREE_FUNC(mod_auth_free) {
-       mod_auth_plugin_data *p = p_d;
--      
-+
-       UNUSED(srv);
-       if (!p) return HANDLER_GO_ON;
--      
-+
-       buffer_free(p->tmp_buf);
-       buffer_free(p->auth_user);
- #ifdef USE_LDAP
-       buffer_free(p->ldap_filter);
- #endif
--      
-+
-       if (p->config_storage) {
-               size_t i;
-               for (i = 0; i < srv->config_context->used; i++) {
-                       mod_auth_plugin_config *s = p->config_storage[i];
--                      
-+
-                       if (!s) continue;
--                      
-+
-                       array_free(s->auth_require);
-                       buffer_free(s->auth_plain_groupfile);
-                       buffer_free(s->auth_plain_userfile);
-                       buffer_free(s->auth_htdigest_userfile);
-                       buffer_free(s->auth_htpasswd_userfile);
-                       buffer_free(s->auth_backend_conf);
--                      
-+
-                       buffer_free(s->auth_ldap_hostname);
-                       buffer_free(s->auth_ldap_basedn);
-                       buffer_free(s->auth_ldap_binddn);
-                       buffer_free(s->auth_ldap_bindpw);
-                       buffer_free(s->auth_ldap_filter);
-                       buffer_free(s->auth_ldap_cafile);
--                      
-+
- #ifdef USE_LDAP
-                       buffer_free(s->ldap_filter_pre);
-                       buffer_free(s->ldap_filter_post);
--                      
-+
-                       if (s->ldap) ldap_unbind_s(s->ldap);
- #endif
--                      
-+
-                       free(s);
-               }
-               free(p->config_storage);
-       }
--      
-+
-       free(p);
--      
-+
-       return HANDLER_GO_ON;
- }
--#define PATCH(x) \
--      p->conf.x = s->x;
- static int mod_auth_patch_connection(server *srv, connection *con, mod_auth_plugin_data *p) {
-       size_t i, j;
-       mod_auth_plugin_config *s = p->config_storage[0];
--      PATCH(auth_backend);
--      PATCH(auth_plain_groupfile);
--      PATCH(auth_plain_userfile);
--      PATCH(auth_htdigest_userfile);
--      PATCH(auth_htpasswd_userfile);
--      PATCH(auth_require);
--      PATCH(auth_debug);
--      PATCH(auth_ldap_hostname);
--      PATCH(auth_ldap_basedn);
--      PATCH(auth_ldap_binddn);
--      PATCH(auth_ldap_bindpw);
--      PATCH(auth_ldap_filter);
--      PATCH(auth_ldap_cafile);
--      PATCH(auth_ldap_starttls);
-+      PATCH_OPTION(auth_backend);
-+      PATCH_OPTION(auth_plain_groupfile);
-+      PATCH_OPTION(auth_plain_userfile);
-+      PATCH_OPTION(auth_htdigest_userfile);
-+      PATCH_OPTION(auth_htpasswd_userfile);
-+      PATCH_OPTION(auth_require);
-+      PATCH_OPTION(auth_debug);
-+      PATCH_OPTION(auth_ldap_hostname);
-+      PATCH_OPTION(auth_ldap_basedn);
-+      PATCH_OPTION(auth_ldap_binddn);
-+      PATCH_OPTION(auth_ldap_bindpw);
-+      PATCH_OPTION(auth_ldap_filter);
-+      PATCH_OPTION(auth_ldap_cafile);
-+      PATCH_OPTION(auth_ldap_starttls);
- #ifdef USE_LDAP
--      PATCH(ldap);
--      PATCH(ldap_filter_pre);
--      PATCH(ldap_filter_post);
-+      PATCH_OPTION(ldap);
-+      PATCH_OPTION(ldap_filter_pre);
-+      PATCH_OPTION(ldap_filter_post);
- #endif
--      
-+
-       /* skip the first, the global context */
-       for (i = 1; i < srv->config_context->used; i++) {
-               data_config *dc = (data_config *)srv->config_context->data[i];
-               s = p->config_storage[i];
--              
-+
-               /* condition didn't match */
-               if (!config_check_cond(srv, con, dc)) continue;
--              
-+
-               /* merge config */
-               for (j = 0; j < dc->value->used; j++) {
-                       data_unset *du = dc->value->data[j];
--                      
-+
-                       if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend"))) {
--                              PATCH(auth_backend);
-+                              PATCH_OPTION(auth_backend);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.plain.groupfile"))) {
--                              PATCH(auth_plain_groupfile);
-+                              PATCH_OPTION(auth_plain_groupfile);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.plain.userfile"))) {
--                              PATCH(auth_plain_userfile);
-+                              PATCH_OPTION(auth_plain_userfile);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.htdigest.userfile"))) {
--                              PATCH(auth_htdigest_userfile);
-+                              PATCH_OPTION(auth_htdigest_userfile);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.htpasswd.userfile"))) {
--                              PATCH(auth_htpasswd_userfile);
-+                              PATCH_OPTION(auth_htpasswd_userfile);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.require"))) {
--                              PATCH(auth_require);
-+                              PATCH_OPTION(auth_require);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.debug"))) {
--                              PATCH(auth_debug);
-+                              PATCH_OPTION(auth_debug);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.hostname"))) {
--                              PATCH(auth_ldap_hostname);
-+                              PATCH_OPTION(auth_ldap_hostname);
- #ifdef USE_LDAP
--                              PATCH(ldap);
--                              PATCH(ldap_filter_pre);
--                              PATCH(ldap_filter_post);
-+                              PATCH_OPTION(ldap);
-+                              PATCH_OPTION(ldap_filter_pre);
-+                              PATCH_OPTION(ldap_filter_post);
- #endif
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.base-dn"))) {
--                              PATCH(auth_ldap_basedn);
-+                              PATCH_OPTION(auth_ldap_basedn);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.filter"))) {
--                              PATCH(auth_ldap_filter);
-+                              PATCH_OPTION(auth_ldap_filter);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.ca-file"))) {
--                              PATCH(auth_ldap_cafile);
-+                              PATCH_OPTION(auth_ldap_cafile);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.starttls"))) {
--                              PATCH(auth_ldap_starttls);
-+                              PATCH_OPTION(auth_ldap_starttls);
-                       }
-               }
-       }
--      
-+
-       return 0;
- }
--#undef PATCH
- static handler_t mod_auth_uri_handler(server *srv, connection *con, void *p_d) {
-       size_t k;
-@@ -175,22 +174,22 @@
-       data_string *ds;
-       mod_auth_plugin_data *p = p_d;
-       array *req;
--      
-+
-       /* select the right config */
-       mod_auth_patch_connection(srv, con, p);
--      
-+
-       if (p->conf.auth_require == NULL) return HANDLER_GO_ON;
--      
-+
-       /*
-        * AUTH
--       *  
-+       *
-        */
--      
-+
-       /* do we have to ask for auth ? */
--      
-+
-       auth_required = 0;
-       auth_satisfied = 0;
--      
-+
-       /* search auth-directives for path */
-       for (k = 0; k < p->conf.auth_require->used; k++) {
-               buffer *req = p->conf.auth_require->data[k]->key;
-@@ -212,76 +211,76 @@
-                       }
-               }
-       }
--      
-+
-       /* nothing to do for us */
-       if (auth_required == 0) return HANDLER_GO_ON;
--      
-+
-       req = ((data_array *)(p->conf.auth_require->data[k]))->value;
--      
-+
-       /* try to get Authorization-header */
--              
-+
-       if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Authorization"))) {
-               http_authorization = ds->value->ptr;
-       }
--      
-+
-       if (ds && ds->value && ds->value->used) {
-               char *auth_realm;
-               data_string *method;
--              
-+
-               method = (data_string *)array_get_element(req, "method");
--              
-+
-               /* parse auth-header */
-               if (NULL != (auth_realm = strchr(http_authorization, ' '))) {
-                       int auth_type_len = auth_realm - http_authorization;
--                      
-+
-                       if ((auth_type_len == 5) &&
-                           (0 == strncmp(http_authorization, "Basic", auth_type_len))) {
--                              
--                              if (0 == strcmp(method->value->ptr, "basic")) {
-+
-+                              if (buffer_is_equal_string(method->value, CONST_STR_LEN("basic"))) {
-                                       auth_satisfied = http_auth_basic_check(srv, con, p, req, con->uri.path, auth_realm+1);
-                               }
-                       } else if ((auth_type_len == 6) &&
-                                  (0 == strncmp(http_authorization, "Digest", auth_type_len))) {
--                              if (0 == strcmp(method->value->ptr, "digest")) {
-+                              if (buffer_is_equal_string(method->value, CONST_STR_LEN("digest"))) {
-                                       if (-1 == (auth_satisfied = http_auth_digest_check(srv, con, p, req, con->uri.path, auth_realm+1))) {
-                                               con->http_status = 400;
--                                              
-+
-                                               /* a field was missing */
--                                              
-+
-                                               return HANDLER_FINISHED;
-                                       }
-                               }
-                       } else {
--                              log_error_write(srv, __FILE__, __LINE__, "ss", 
-+                              log_error_write(srv, __FILE__, __LINE__, "ss",
-                                               "unknown authentification type:",
-                                               http_authorization);
-                       }
-               }
-       }
--      
-+
-       if (!auth_satisfied) {
-               data_string *method, *realm;
-               method = (data_string *)array_get_element(req, "method");
-               realm = (data_string *)array_get_element(req, "realm");
--              
-+
-               con->http_status = 401;
--                      
--              if (0 == strcmp(method->value->ptr, "basic")) {
-+
-+              if (buffer_is_equal_string(method->value, CONST_STR_LEN("basic"))) {
-                       buffer_copy_string(p->tmp_buf, "Basic realm=\"");
-                       buffer_append_string_buffer(p->tmp_buf, realm->value);
-                       buffer_append_string(p->tmp_buf, "\"");
--                      
-+
-                       response_header_insert(srv, con, CONST_STR_LEN("WWW-Authenticate"), CONST_BUF_LEN(p->tmp_buf));
--              } else if (0 == strcmp(method->value->ptr, "digest")) {
-+              } else if (buffer_is_equal_string(method->value, CONST_STR_LEN("digest"))) {
-                       char hh[33];
-                       http_auth_digest_generate_nonce(srv, p, srv->tmp_buf, hh);
--                      
-+
-                       buffer_copy_string(p->tmp_buf, "Digest realm=\"");
-                       buffer_append_string_buffer(p->tmp_buf, realm->value);
-                       buffer_append_string(p->tmp_buf, "\", nonce=\"");
-                       buffer_append_string(p->tmp_buf, hh);
-                       buffer_append_string(p->tmp_buf, "\", qop=\"auth\"");
--                      
-+
-                       response_header_insert(srv, con, CONST_STR_LEN("WWW-Authenticate"), CONST_BUF_LEN(p->tmp_buf));
-               } else {
-                       /* evil */
-@@ -289,18 +288,18 @@
-               return HANDLER_FINISHED;
-       } else {
-               /* the REMOTE_USER header */
--              
-+
-               buffer_copy_string_buffer(con->authed_user, p->auth_user);
-       }
--      
-+
-       return HANDLER_GO_ON;
- }
- SETDEFAULTS_FUNC(mod_auth_set_defaults) {
-       mod_auth_plugin_data *p = p_d;
-       size_t i;
--      
--      config_values_t cv[] = { 
-+
-+      config_values_t cv[] = {
-               { "auth.backend",                   NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
-               { "auth.backend.plain.groupfile",   NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
-               { "auth.backend.plain.userfile",    NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
-@@ -317,7 +316,7 @@
-               { "auth.debug",                     NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },  /* 13 */
-               { NULL,                             NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
-       };
--      
-+
-       p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
-       for (i = 0; i < srv->config_context->used; i++) {
-@@ -325,14 +324,14 @@
-               size_t n;
-               data_array *da;
-               array *ca;
--              
-+
-               s = calloc(1, sizeof(mod_auth_plugin_config));
-               s->auth_plain_groupfile = buffer_init();
-               s->auth_plain_userfile = buffer_init();
-               s->auth_htdigest_userfile = buffer_init();
-               s->auth_htpasswd_userfile = buffer_init();
-               s->auth_backend_conf = buffer_init();
--              
-+
-               s->auth_ldap_hostname = buffer_init();
-               s->auth_ldap_basedn = buffer_init();
-               s->auth_ldap_binddn = buffer_init();
-@@ -341,15 +340,15 @@
-               s->auth_ldap_cafile = buffer_init();
-               s->auth_ldap_starttls = 0;
-               s->auth_debug = 0;
--              
-+
-               s->auth_require = array_init();
--              
-+
- #ifdef USE_LDAP
-               s->ldap_filter_pre = buffer_init();
-               s->ldap_filter_post = buffer_init();
-               s->ldap = NULL;
- #endif
--      
-+
-               cv[0].destination = s->auth_backend_conf;
-               cv[1].destination = s->auth_plain_groupfile;
-               cv[2].destination = s->auth_plain_userfile;
-@@ -364,146 +363,148 @@
-               cv[11].destination = s->auth_htdigest_userfile;
-               cv[12].destination = s->auth_htpasswd_userfile;
-               cv[13].destination = &(s->auth_debug);
--              
-+
-               p->config_storage[i] = s;
-               ca = ((data_config *)srv->config_context->data[i])->value;
--              
-+
-               if (0 != config_insert_values_global(srv, ca, cv)) {
-                       return HANDLER_ERROR;
-               }
--              
--              if (s->auth_backend_conf->used) {
--                      if (0 == strcmp(s->auth_backend_conf->ptr, "htpasswd")) {
-+
-+              if (!buffer_is_empty(s->auth_backend_conf)) {
-+                      if (buffer_is_equal_string(s->auth_backend_conf, CONST_STR_LEN("htpasswd"))) {
-                               s->auth_backend = AUTH_BACKEND_HTPASSWD;
--                      } else if (0 == strcmp(s->auth_backend_conf->ptr, "htdigest")) {
-+                      } else if (buffer_is_equal_string(s->auth_backend_conf, CONST_STR_LEN("htdigest"))) {
-                               s->auth_backend = AUTH_BACKEND_HTDIGEST;
--                      } else if (0 == strcmp(s->auth_backend_conf->ptr, "plain")) {
-+                      } else if (buffer_is_equal_string(s->auth_backend_conf, CONST_STR_LEN("plain"))) {
-                               s->auth_backend = AUTH_BACKEND_PLAIN;
--                      } else if (0 == strcmp(s->auth_backend_conf->ptr, "ldap")) {
-+                      } else if (buffer_is_equal_string(s->auth_backend_conf, CONST_STR_LEN("ldap"))) {
-                               s->auth_backend = AUTH_BACKEND_LDAP;
-                       } else {
-                               log_error_write(srv, __FILE__, __LINE__, "sb", "auth.backend not supported:", s->auth_backend_conf);
--                              
-+
-                               return HANDLER_ERROR;
-                       }
-               }
-               /* no auth.require for this section */
-               if (NULL == (da = (data_array *)array_get_element(ca, "auth.require"))) continue;
--              
-+
-               if (da->type != TYPE_ARRAY) continue;
--              
-+
-               for (n = 0; n < da->value->used; n++) {
-                       size_t m;
-                       data_array *da_file = (data_array *)da->value->data[n];
--                      const char *method, *realm, *require;
--                      
-+                      buffer *method, *realm, *require;
-+
-                       if (da->value->data[n]->type != TYPE_ARRAY) {
--                              log_error_write(srv, __FILE__, __LINE__, "ss", 
--                                              "auth.require should contain an array as in:", 
-+                              log_error_write(srv, __FILE__, __LINE__, "ss",
-+                                              "auth.require should contain an array as in:",
-                                               "auth.require = ( \"...\" => ( ..., ...) )");
-                               return HANDLER_ERROR;
-                       }
--                                      
-+
-                       method = realm = require = NULL;
--                                      
-+
-                       for (m = 0; m < da_file->value->used; m++) {
--                              if (da_file->value->data[m]->type == TYPE_STRING) {
--                                      if (0 == strcmp(da_file->value->data[m]->key->ptr, "method")) {
--                                              method = ((data_string *)(da_file->value->data[m]))->value->ptr;
--                                      } else if (0 == strcmp(da_file->value->data[m]->key->ptr, "realm")) {
--                                              realm = ((data_string *)(da_file->value->data[m]))->value->ptr;
--                                      } else if (0 == strcmp(da_file->value->data[m]->key->ptr, "require")) {
--                                              require = ((data_string *)(da_file->value->data[m]))->value->ptr;
--                                      } else {
--                                              log_error_write(srv, __FILE__, __LINE__, "ssbs", 
--                                                      "the field is unknown in:", 
-+                              data_string *ds_auth_req = (data_string *)da_file->value->data[m];
-+
-+                              if (ds_auth_req->type != TYPE_STRING) {
-+                                      log_error_write(srv, __FILE__, __LINE__, "ssbs",
-+                                              "a string was expected for:",
-+                                              "auth.require = ( \"...\" => ( ..., -> \"",
-+                                              ds_auth_req->key,
-+                                              "\" <- => \"...\" ) )");
-+
-+                                      return HANDLER_ERROR;
-+                              }
-+
-+                              if (buffer_is_equal_string(ds_auth_req->key, CONST_STR_LEN("method"))) {
-+                                      method = ds_auth_req->value;
-+                              } else if (buffer_is_equal_string(ds_auth_req->key, CONST_STR_LEN("realm"))) {
-+                                      realm = ds_auth_req->value;
-+                              } else if (buffer_is_equal_string(ds_auth_req->key, CONST_STR_LEN("require"))) {
-+                                      require = ds_auth_req->value;
-+                              } else {
-+                                      log_error_write(srv, __FILE__, __LINE__, "ssbs",
-+                                                      "the field is unknown in:",
-                                                       "auth.require = ( \"...\" => ( ..., -> \"",
-                                                       da_file->value->data[m]->key,
-                                                       "\" <- => \"...\" ) )");
--                                              return HANDLER_ERROR;
--                                      }
--                              } else {
--                                      log_error_write(srv, __FILE__, __LINE__, "ssbs", 
--                                              "a string was expected for:", 
--                                              "auth.require = ( \"...\" => ( ..., -> \"",
--                                              da_file->value->data[m]->key,
--                                              "\" <- => \"...\" ) )");
--                                      
-                                       return HANDLER_ERROR;
-+
-                               }
-                       }
--                                      
-+
-                       if (method == NULL) {
--                              log_error_write(srv, __FILE__, __LINE__, "ss", 
--                                              "the require field is missing in:", 
-+                              log_error_write(srv, __FILE__, __LINE__, "ss",
-+                                              "the require field is missing in:",
-                                               "auth.require = ( \"...\" => ( ..., \"method\" => \"...\" ) )");
-                               return HANDLER_ERROR;
--                      } else {
--                              if (0 != strcmp(method, "basic") &&
--                                  0 != strcmp(method, "digest")) {
--                                      log_error_write(srv, __FILE__, __LINE__, "ss",
--                                                      "method has to be either \"basic\" or \"digest\" in",
--                                                      "auth.require = ( \"...\" => ( ..., \"method\" => \"...\") )");
--                                      return HANDLER_ERROR;
--                              }
-+                      } 
-+                      if (!buffer_is_equal_string(method, CONST_STR_LEN("basic")) &&
-+                          !buffer_is_equal_string(method, CONST_STR_LEN("digest"))) {
-+                              log_error_write(srv, __FILE__, __LINE__, "ss",
-+                                              "method has to be either \"basic\" or \"digest\" in",
-+                                              "auth.require = ( \"...\" => ( ..., \"method\" => \"...\") )");
-+                              return HANDLER_ERROR;
-                       }
--                      
-+
-                       if (realm == NULL) {
--                              log_error_write(srv, __FILE__, __LINE__, "ss", 
--                                              "the require field is missing in:", 
-+                              log_error_write(srv, __FILE__, __LINE__, "ss",
-+                                              "the require field is missing in:",
-                                               "auth.require = ( \"...\" => ( ..., \"realm\" => \"...\" ) )");
-                               return HANDLER_ERROR;
-                       }
--                      
-+
-                       if (require == NULL) {
--                              log_error_write(srv, __FILE__, __LINE__, "ss", 
--                                              "the require field is missing in:", 
-+                              log_error_write(srv, __FILE__, __LINE__, "ss",
-+                                              "the require field is missing in:",
-                                               "auth.require = ( \"...\" => ( ..., \"require\" => \"...\" ) )");
-                               return HANDLER_ERROR;
-                       }
--                      
-+
-                       if (method && realm && require) {
-                               data_string *ds;
-                               data_array *a;
--                              
-+
-                               a = data_array_init();
-                               buffer_copy_string_buffer(a->key, da_file->key);
--                              
-+
-                               ds = data_string_init();
--                              
-+
-                               buffer_copy_string(ds->key, "method");
--                              buffer_copy_string(ds->value, method);
--                              
-+                              buffer_copy_string_buffer(ds->value, method);
-+
-                               array_insert_unique(a->value, (data_unset *)ds);
--                              
-+
-                               ds = data_string_init();
--                              
-+
-                               buffer_copy_string(ds->key, "realm");
--                              buffer_copy_string(ds->value, realm);
--                              
-+                              buffer_copy_string_buffer(ds->value, realm);
-+
-                               array_insert_unique(a->value, (data_unset *)ds);
--                              
-+
-                               ds = data_string_init();
--                              
-+
-                               buffer_copy_string(ds->key, "require");
--                              buffer_copy_string(ds->value, require);
--                              
-+                              buffer_copy_string_buffer(ds->value, require);
-+
-                               array_insert_unique(a->value, (data_unset *)ds);
--                              
-+
-                               array_insert_unique(s->auth_require, (data_unset *)a);
-                       }
-               }
--      
-+
-               switch(s->auth_backend) {
-               case AUTH_BACKEND_PLAIN:
-                       if (s->auth_plain_userfile->used) {
-                               int fd;
-                               /* try to read */
-                               if (-1 == (fd = open(s->auth_plain_userfile->ptr, O_RDONLY))) {
--                                      log_error_write(srv, __FILE__, __LINE__, "sbss", 
-+                                      log_error_write(srv, __FILE__, __LINE__, "sbss",
-                                                       "opening auth.backend.plain.userfile:", s->auth_plain_userfile,
-                                                       "failed:", strerror(errno));
-                                       return HANDLER_ERROR;
-@@ -516,7 +517,7 @@
-                               int fd;
-                               /* try to read */
-                               if (-1 == (fd = open(s->auth_htpasswd_userfile->ptr, O_RDONLY))) {
--                                      log_error_write(srv, __FILE__, __LINE__, "sbss", 
-+                                      log_error_write(srv, __FILE__, __LINE__, "sbss",
-                                                       "opening auth.backend.htpasswd.userfile:", s->auth_htpasswd_userfile,
-                                                       "failed:", strerror(errno));
-                                       return HANDLER_ERROR;
-@@ -529,7 +530,7 @@
-                               int fd;
-                               /* try to read */
-                               if (-1 == (fd = open(s->auth_htdigest_userfile->ptr, O_RDONLY))) {
--                                      log_error_write(srv, __FILE__, __LINE__, "sbss", 
-+                                      log_error_write(srv, __FILE__, __LINE__, "sbss",
-                                                       "opening auth.backend.htdigest.userfile:", s->auth_htdigest_userfile,
-                                                       "failed:", strerror(errno));
-                                       return HANDLER_ERROR;
-@@ -554,75 +555,75 @@
- handler_t auth_ldap_init(server *srv, mod_auth_plugin_config *s) {
- #ifdef USE_LDAP
-                       int ret;
--#if 0                 
-+#if 0
-                       if (s->auth_ldap_basedn->used == 0) {
-                               log_error_write(srv, __FILE__, __LINE__, "s", "ldap: auth.backend.ldap.base-dn has to be set");
--                              
-+
-                               return HANDLER_ERROR;
-                       }
- #endif
--                      
-+
-                       if (s->auth_ldap_filter->used) {
-                               char *dollar;
--                              
-+
-                               /* parse filter */
--                      
-+
-                               if (NULL == (dollar = strchr(s->auth_ldap_filter->ptr, '$'))) {
-                                       log_error_write(srv, __FILE__, __LINE__, "s", "ldap: auth.backend.ldap.filter is missing a replace-operator '$'");
--                                      
-+
-                                       return HANDLER_ERROR;
-                               }
--                              
-+
-                               buffer_copy_string_len(s->ldap_filter_pre, s->auth_ldap_filter->ptr, dollar - s->auth_ldap_filter->ptr);
-                               buffer_copy_string(s->ldap_filter_post, dollar+1);
-                       }
--                      
-+
-                       if (s->auth_ldap_hostname->used) {
-                               if (NULL == (s->ldap = ldap_init(s->auth_ldap_hostname->ptr, LDAP_PORT))) {
-                                       log_error_write(srv, __FILE__, __LINE__, "ss", "ldap ...", strerror(errno));
--                                      
-+
-                                       return HANDLER_ERROR;
-                               }
--                              
-+
-                               ret = LDAP_VERSION3;
-                               if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(s->ldap, LDAP_OPT_PROTOCOL_VERSION, &ret))) {
-                                       log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));
--                              
-+
-                                       return HANDLER_ERROR;
-                               }
-                               if (s->auth_ldap_starttls) {
--                                      /* if no CA file is given, it is ok, as we will use encryption 
-+                                      /* if no CA file is given, it is ok, as we will use encryption
-                                        * if the server requires a CAfile it will tell us */
-                                       if (!buffer_is_empty(s->auth_ldap_cafile)) {
--                                              if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE, 
-+                                              if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE,
-                                                                               s->auth_ldap_cafile->ptr))) {
--                                                      log_error_write(srv, __FILE__, __LINE__, "ss", 
-+                                                      log_error_write(srv, __FILE__, __LINE__, "ss",
-                                                                       "Loading CA certificate failed:", ldap_err2string(ret));
--                                              
-+
-                                                       return HANDLER_ERROR;
-                                               }
-                                       }
--      
-+
-                                       if (LDAP_OPT_SUCCESS != (ret = ldap_start_tls_s(s->ldap, NULL,  NULL))) {
-                                               log_error_write(srv, __FILE__, __LINE__, "ss", "ldap startTLS failed:", ldap_err2string(ret));
--                                              
-+
-                                               return HANDLER_ERROR;
-                                       }
-                               }
--                              
--                              
-+
-+
-                               /* 1. */
-                               if (s->auth_ldap_binddn->used) {
-                                       if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(s->ldap, s->auth_ldap_binddn->ptr, s->auth_ldap_bindpw->ptr))) {
-                                               log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));
--                                              
-+
-                                               return HANDLER_ERROR;
-                                       }
-                               } else {
-                                       if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(s->ldap, NULL, NULL))) {
-                                               log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));
--                                              
-+
-                                               return HANDLER_ERROR;
-                                       }
-                               }
-@@ -641,8 +642,8 @@
-       p->set_defaults = mod_auth_set_defaults;
-       p->handle_uri_clean = mod_auth_uri_handler;
-       p->cleanup     = mod_auth_free;
--      
-+
-       p->data        = NULL;
--      
-+
-       return 0;
- }
---- ../lighttpd-1.4.11/src/mod_cgi.c   2006-02-22 15:15:10.000000000 +0200
-+++ lighttpd-1.5.0/src/mod_cgi.c       2006-09-07 00:57:05.000000000 +0300
-@@ -1,21 +1,8 @@
- #include <sys/types.h>
--#ifdef __WIN32
--#include <winsock2.h>
--#else
--#include <sys/socket.h>
--#include <sys/wait.h>
--#include <sys/mman.h>
--
--#include <netinet/in.h>
--
--#include <arpa/inet.h>
--#endif
--#include <unistd.h>
- #include <errno.h>
- #include <stdlib.h>
- #include <string.h>
--#include <fdevent.h>
- #include <signal.h>
- #include <ctype.h>
- #include <assert.h>
-@@ -28,9 +15,16 @@
- #include "log.h"
- #include "connections.h"
- #include "joblist.h"
--#include "http_chunk.h"
-+#include "fdevent.h"
- #include "plugin.h"
-+#include "http_resp.h"
-+
-+#include "sys-files.h"
-+#include "sys-mmap.h"
-+#include "sys-socket.h"
-+#include "sys-strings.h"
-+#include "sys-process.h"
- #ifdef HAVE_SYS_FILIO_H
- # include <sys/filio.h>
-@@ -40,11 +34,12 @@
- typedef struct {
-       char **ptr;
--      
-+
-       size_t size;
-       size_t used;
- } char_array;
-+#define pid_t int
- typedef struct {
-       pid_t *ptr;
-       size_t used;
-@@ -58,57 +53,68 @@
- typedef struct {
-       PLUGIN_DATA;
-       buffer_pid_t cgi_pid;
--      
-+
-       buffer *tmp_buf;
--      buffer *parse_response;
--      
-+
-+      http_resp *resp;
-+
-       plugin_config **config_storage;
--      
--      plugin_config conf; 
-+
-+      plugin_config conf;
- } plugin_data;
-+typedef enum {
-+      CGI_STATE_UNSET,
-+      CGI_STATE_CONNECTING,
-+      CGI_STATE_READ_RESPONSE_HEADER,
-+      CGI_STATE_READ_RESPONSE_CONTENT
-+} cgi_state_t;
-+
- typedef struct {
-       pid_t pid;
--      int fd;
--      int fde_ndx; /* index into the fd-event buffer */
--      
--      connection *remote_conn;  /* dumb pointer */
--      plugin_data *plugin_data; /* dumb pointer */
--      
--      buffer *response;
--      buffer *response_header;
--} handler_ctx;
--static handler_ctx * cgi_handler_ctx_init() {
--      handler_ctx *hctx = calloc(1, sizeof(*hctx));
-+      iosocket *sock;
--      assert(hctx);
--      
--      hctx->response = buffer_init();
--      hctx->response_header = buffer_init();
--      
--      return hctx;
--}
-+      chunkqueue *rb;
-+      chunkqueue *wb;
--static void cgi_handler_ctx_free(handler_ctx *hctx) {
--      buffer_free(hctx->response);
--      buffer_free(hctx->response_header);
--      
--      free(hctx);
-+      cgi_state_t state;
-+
-+      connection *remote_con;  /* dumb pointer */
-+} cgi_session;
-+
-+static cgi_session * cgi_session_init() {
-+      cgi_session *sess = calloc(1, sizeof(*sess));
-+      assert(sess);
-+
-+      sess->sock = iosocket_init();
-+      sess->wb = chunkqueue_init();
-+      sess->rb = chunkqueue_init();
-+
-+      return sess;
- }
--enum {FDEVENT_HANDLED_UNSET, FDEVENT_HANDLED_FINISHED, FDEVENT_HANDLED_NOT_FINISHED, FDEVENT_HANDLED_ERROR};
-+static void cgi_session_free(cgi_session *sess) {
-+      if (!sess) return;
-+
-+      iosocket_free(sess->sock);
-+
-+      chunkqueue_free(sess->wb);
-+      chunkqueue_free(sess->rb);
-+
-+      free(sess);
-+}
- INIT_FUNC(mod_cgi_init) {
-       plugin_data *p;
--      
-+
-       p = calloc(1, sizeof(*p));
-       assert(p);
--      
-+
-       p->tmp_buf = buffer_init();
--      p->parse_response = buffer_init();
--      
-+      p->resp = http_response_init();
-+
-       return p;
- }
-@@ -116,62 +122,62 @@
- FREE_FUNC(mod_cgi_free) {
-       plugin_data *p = p_d;
-       buffer_pid_t *r = &(p->cgi_pid);
--      
-+
-       UNUSED(srv);
--      
-+
-       if (p->config_storage) {
-               size_t i;
-               for (i = 0; i < srv->config_context->used; i++) {
-                       plugin_config *s = p->config_storage[i];
--                      
-+
-                       array_free(s->cgi);
--                      
-+
-                       free(s);
-               }
-               free(p->config_storage);
-       }
--      
-+
-       if (r->ptr) free(r->ptr);
--      
-+
-       buffer_free(p->tmp_buf);
--      buffer_free(p->parse_response);
--      
-+      http_response_free(p->resp);
-+
-       free(p);
--      
-+
-       return HANDLER_GO_ON;
- }
- SETDEFAULTS_FUNC(mod_fastcgi_set_defaults) {
-       plugin_data *p = p_d;
-       size_t i = 0;
--      
--      config_values_t cv[] = { 
-+
-+      config_values_t cv[] = {
-               { "cgi.assign",                  NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
-               { NULL,                          NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET}
-       };
-       if (!p) return HANDLER_ERROR;
--      
-+
-       p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
--      
-+
-       for (i = 0; i < srv->config_context->used; i++) {
-               plugin_config *s;
--              
-+
-               s = calloc(1, sizeof(plugin_config));
-               assert(s);
--              
-+
-               s->cgi    = array_init();
--              
-+
-               cv[0].destination = s->cgi;
--              
-+
-               p->config_storage[i] = s;
--      
-+
-               if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
-                       return HANDLER_ERROR;
-               }
-       }
--      
-+
-       return HANDLER_GO_ON;
- }
-@@ -180,13 +186,13 @@
-       int m = -1;
-       size_t i;
-       buffer_pid_t *r = &(p->cgi_pid);
--      
-+
-       UNUSED(srv);
-       for (i = 0; i < r->used; i++) {
-               if (r->ptr[i] > m) m = r->ptr[i];
-       }
--      
-+
-       if (r->size == 0) {
-               r->size = 16;
-               r->ptr = malloc(sizeof(*r->ptr) * r->size);
-@@ -194,321 +200,179 @@
-               r->size += 16;
-               r->ptr = realloc(r->ptr, sizeof(*r->ptr) * r->size);
-       }
--      
-+
-       r->ptr[r->used++] = pid;
--      
-+
-       return m;
- }
- static int cgi_pid_del(server *srv, plugin_data *p, pid_t pid) {
-       size_t i;
-       buffer_pid_t *r = &(p->cgi_pid);
--      
-+
-       UNUSED(srv);
-       for (i = 0; i < r->used; i++) {
-               if (r->ptr[i] == pid) break;
-       }
--      
-+
-       if (i != r->used) {
-               /* found */
--              
-+
-               if (i != r->used - 1) {
-                       r->ptr[i] = r->ptr[r->used - 1];
-               }
-               r->used--;
-       }
--      
-+
-       return 0;
- }
--static int cgi_response_parse(server *srv, connection *con, plugin_data *p, buffer *in, int eol) {
--      char *ns;
--      const char *s;
--      int line = 0;
--      
--      UNUSED(srv);
--      
--      buffer_copy_string_buffer(p->parse_response, in);
--      
--      for (s = p->parse_response->ptr; 
--           NULL != (ns = (eol == EOL_RN ? strstr(s, "\r\n") : strchr(s, '\n'))); 
--           s = ns + (eol == EOL_RN ? 2 : 1), line++) {
--              const char *key, *value;
--              int key_len;
--              data_string *ds;
--              
--              ns[0] = '\0';
--              
--              if (line == 0 && 
--                  0 == strncmp(s, "HTTP/1.", 7)) {
--                      /* non-parsed header ... we parse them anyway */
--                      
--                      if ((s[7] == '1' ||
--                           s[7] == '0') &&
--                          s[8] == ' ') {
--                              int status;
--                              /* after the space should be a status code for us */
--                              
--                              status = strtol(s+9, NULL, 10);
--                              
--                              if (con->http_status >= 100 &&
--                                  con->http_status < 1000) {
--                                      /* we expected 3 digits and didn't got them */
--                                      con->parsed_response |= HTTP_STATUS;
--                                      con->http_status = status;
--                              }
--                      }
--              } else {
--              
--                      key = s;
--                      if (NULL == (value = strchr(s, ':'))) {
--                              /* we expect: "<key>: <value>\r\n" */
--                              continue;
--                      }
--                      
--                      key_len = value - key;
--                      value += 1;
--                      
--                      /* skip LWS */
--                      while (*value == ' ' || *value == '\t') value++;
--                      
--                      if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
--                              ds = data_response_init();
--                      }
--                      buffer_copy_string_len(ds->key, key, key_len);
--                      buffer_copy_string(ds->value, value);
--                      
--                      array_insert_unique(con->response.headers, (data_unset *)ds);
--                      
--                      switch(key_len) {
--                      case 4:
--                              if (0 == strncasecmp(key, "Date", key_len)) {
--                                      con->parsed_response |= HTTP_DATE;
--                              }
--                              break;
--                      case 6:
--                              if (0 == strncasecmp(key, "Status", key_len)) {
--                                      con->http_status = strtol(value, NULL, 10);
--                                      con->parsed_response |= HTTP_STATUS;
--                              }
--                              break;
--                      case 8:
--                              if (0 == strncasecmp(key, "Location", key_len)) {
--                                      con->parsed_response |= HTTP_LOCATION;
--                              }
--                              break;
--                      case 10:
--                              if (0 == strncasecmp(key, "Connection", key_len)) {
--                                      con->response.keep_alive = (0 == strcasecmp(value, "Keep-Alive")) ? 1 : 0;
--                                      con->parsed_response |= HTTP_CONNECTION;
--                              }
--                              break;
--                      case 14:
--                              if (0 == strncasecmp(key, "Content-Length", key_len)) {
--                                      con->response.content_length = strtol(value, NULL, 10);
--                                      con->parsed_response |= HTTP_CONTENT_LENGTH;
--                              }
--                              break;
--                      default:
--                              break;
--                      }
--              }
--      }
--      
--      /* CGI/1.1 rev 03 - 7.2.1.2 */
--      if ((con->parsed_response & HTTP_LOCATION) &&
--          !(con->parsed_response & HTTP_STATUS)) {
--              con->http_status = 302;
-+static int cgi_demux_response(server *srv, connection *con, plugin_data *p) {
-+      cgi_session *sess = con->plugin_ctx[p->id];
-+      chunk *c = NULL;
-+
-+      switch(srv->network_backend_read(srv, con, sess->sock, sess->rb)) {
-+      case NETWORK_STATUS_SUCCESS:
-+              /* we got content */
-+              break;
-+      case NETWORK_STATUS_WAIT_FOR_EVENT:
-+              return 0;
-+      case NETWORK_STATUS_CONNECTION_CLOSE:
-+              /* this is a bit too early */
-+              ERROR("%s", "cgi-connection got closed before we read the response-header (CGI died ?)");
-+              return -1;
-+      default:
-+              /* oops */
-+              ERROR("%s", "oops, read-pipe-read failed and I don't know why");
-+              return -1;
-       }
--      
--      return 0;
--}
-+      /* looks like we got some content
-+      *
-+      * split off the header from the incoming stream
-+      */
--static int cgi_demux_response(server *srv, handler_ctx *hctx) {
--      plugin_data *p    = hctx->plugin_data;
--      connection  *con  = hctx->remote_conn;
--      
--      while(1) {
--              int n;
--              
--              buffer_prepare_copy(hctx->response, 1024);
--              if (-1 == (n = read(hctx->fd, hctx->response->ptr, hctx->response->size - 1))) {
--                      if (errno == EAGAIN || errno == EINTR) {
--                              /* would block, wait for signal */
--                              return FDEVENT_HANDLED_NOT_FINISHED;
--                      }
--                      /* error */
--                      log_error_write(srv, __FILE__, __LINE__, "sdd", strerror(errno), con->fd, hctx->fd);
--                      return FDEVENT_HANDLED_ERROR;
--              }
--              
--              if (n == 0) {
--                      /* read finished */
--                      
--                      con->file_finished = 1;
--                      
--                      /* send final chunk */
--                      http_chunk_append_mem(srv, con, NULL, 0);
--                      joblist_append(srv, con);
--                      
--                      return FDEVENT_HANDLED_FINISHED;
--              }
--              
--              hctx->response->ptr[n] = '\0';
--              hctx->response->used = n+1;
--              
--              /* split header from body */
--              
--              if (con->file_started == 0) {
--                      char *c;
--                      int in_header = 0;
--                      int header_end = 0;
--                      int cp, eol = EOL_UNSET;
--                      size_t used = 0;
--                      
--                      buffer_append_string_buffer(hctx->response_header, hctx->response);
--                      
--                      /* nph (non-parsed headers) */
--                      if (0 == strncmp(hctx->response_header->ptr, "HTTP/1.", 7)) in_header = 1;
--                      
--                      /* search for the \r\n\r\n or \n\n in the string */
--                      for (c = hctx->response_header->ptr, cp = 0, used = hctx->response_header->used - 1; used; c++, cp++, used--) {
--                              if (*c == ':') in_header = 1;
--                              else if (*c == '\n') {
--                                      if (in_header == 0) {
--                                              /* got a response without a response header */
--                                              
--                                              c = NULL;
--                                              header_end = 1;
--                                              break;
--                                      }
--                                      
--                                      if (eol == EOL_UNSET) eol = EOL_N;
--                                      
--                                      if (*(c+1) == '\n') {
--                                              header_end = 1;
--                                              break;
--                                      }
--                                      
--                              } else if (used > 1 && *c == '\r' && *(c+1) == '\n') {
--                                      if (in_header == 0) {
--                                              /* got a response without a response header */
--                                              
--                                              c = NULL;
--                                              header_end = 1;
--                                              break;
--                                      }
--                                      
--                                      if (eol == EOL_UNSET) eol = EOL_RN;
--                                      
--                                      if (used > 3 &&
--                                          *(c+2) == '\r' && 
--                                          *(c+3) == '\n') {
--                                              header_end = 1;
--                                              break;
--                                      }
--                                      
--                                      /* skip the \n */
--                                      c++;
--                                      cp++;
--                                      used--;
-+      if (con->file_started == 0) {
-+              size_t i;
-+              int have_content_length = 0;
-+
-+              http_response_reset(p->resp);
-+
-+              /* the response header is not fully received yet,
-+              *
-+              * extract the http-response header from the rb-cq
-+              */
-+              switch (http_response_parse_cq(sess->rb, p->resp)) {
-+              case PARSE_ERROR:
-+                      /* parsing failed */
-+
-+                      TRACE("%s", "response parser failed");
-+
-+                      con->http_status = 502; /* Bad Gateway */
-+                      return -1;
-+              case PARSE_NEED_MORE:
-+                      return 0;
-+              case PARSE_SUCCESS:
-+                      con->http_status = p->resp->status;
-+
-+                      chunkqueue_remove_finished_chunks(sess->rb);
-+
-+                      /* copy the http-headers */
-+                      for (i = 0; i < p->resp->headers->used; i++) {
-+                              const char *ign[] = { "Status", "Connection", NULL };
-+                              size_t j;
-+                              data_string *ds;
-+
-+                              data_string *header = (data_string *)p->resp->headers->data[i];
-+
-+                              /* some headers are ignored by default */
-+                              for (j = 0; ign[j]; j++) {
-+                                      if (0 == strcasecmp(ign[j], header->key->ptr)) break;
-                               }
--                      }
--                      
--                      if (header_end) {
--                              if (c == NULL) {
--                                      /* no header, but a body */
--                                      
--                                      if (con->request.http_version == HTTP_VERSION_1_1) {
--                                              con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
--                                      }
--                                      
--                                      http_chunk_append_mem(srv, con, hctx->response_header->ptr, hctx->response_header->used);
--                                      joblist_append(srv, con);
--                              } else {
--                                      size_t hlen = c - hctx->response_header->ptr + (eol == EOL_RN ? 4 : 2);
--                                      size_t blen = hctx->response_header->used - hlen - 1;
--                              
--                                      /* a small hack: terminate after at the second \r */
--                                      hctx->response_header->used = hlen + 1 - (eol == EOL_RN ? 2 : 1);
--                                      hctx->response_header->ptr[hlen - (eol == EOL_RN ? 2 : 1)] = '\0';
--                              
--                                      /* parse the response header */
--                                      cgi_response_parse(srv, con, p, hctx->response_header, eol);
--                                      
--                                      /* enable chunked-transfer-encoding */
--                                      if (con->request.http_version == HTTP_VERSION_1_1 &&
--                                          !(con->parsed_response & HTTP_CONTENT_LENGTH)) {
--                                              con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
--                                      }
--                                      
--                                      if ((hctx->response->used != hlen) && blen > 0) {
--                                              http_chunk_append_mem(srv, con, c + (eol == EOL_RN ? 4: 2), blen + 1);
--                                              joblist_append(srv, con);
--                                      }
-+                              if (ign[j]) continue;
-+
-+                              if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("Location"))) {
-+                                      /* CGI/1.1 rev 03 - 7.2.1.2 */
-+                                      if (con->http_status == 0) con->http_status = 302;
-+                              } else if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("Content-Length"))) {
-+                                      have_content_length = 1;
-                               }
-                               
--                              con->file_started = 1;
-+                              if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
-+                                      ds = data_response_init();
-+                              }
-+                              buffer_copy_string_buffer(ds->key, header->key);
-+                              buffer_copy_string_buffer(ds->value, header->value);
-+
-+                              array_insert_unique(con->response.headers, (data_unset *)ds);
-                       }
--              } else {
--                      http_chunk_append_mem(srv, con, hctx->response->ptr, hctx->response->used);
--                      joblist_append(srv, con);
-+
-+                      con->file_started = 1;
-+                      sess->state = CGI_STATE_READ_RESPONSE_CONTENT;
-+
-+                      if (con->request.http_version == HTTP_VERSION_1_1 &&
-+                          !have_content_length) {
-+                              con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
-+                      }
-+
-+                      break;
-               }
--              
--#if 0         
--              log_error_write(srv, __FILE__, __LINE__, "ddss", con->fd, hctx->fd, connection_get_state(con->state), b->ptr);
--#endif
-       }
--      
--      return FDEVENT_HANDLED_NOT_FINISHED;
-+
-+      /* FIXME: pass the response-header to the other plugins to
-+      * setup the filter-queue
-+      *
-+      * - use next-queue instead of con->write_queue
-+      */
-+
-+      /* copy the content to the next cq */
-+      for (c = sess->rb->first; c; c = c->next) {
-+              chunkqueue_append_mem(con->send, c->mem->ptr + c->offset, c->mem->used - c->offset);
-+
-+              c->offset = c->mem->used - 1;
-+      }
-+
-+      chunkqueue_remove_finished_chunks(sess->rb);
-+      joblist_append(srv, con);
-+
-+      return 0;
- }
--static handler_t cgi_connection_close(server *srv, handler_ctx *hctx) {
-+static handler_t cgi_connection_close(server *srv, connection *con, plugin_data *p) {
-+      cgi_session *sess = con->plugin_ctx[p->id];
-       int status;
-       pid_t pid;
--      plugin_data *p;
--      connection  *con;
--      
--      if (NULL == hctx) return HANDLER_GO_ON;
--      
--      p    = hctx->plugin_data;
--      con  = hctx->remote_conn;
--      
-+
-+      if (NULL == sess) return HANDLER_GO_ON;
-       if (con->mode != p->id) return HANDLER_GO_ON;
--#ifndef __WIN32
--      
-+#ifndef _WIN32
-+
-       /* the connection to the browser went away, but we still have a connection
--       * to the CGI script 
-+       * to the CGI script
-        *
-        * close cgi-connection
-        */
--      
--      if (hctx->fd != -1) {
-+
-+      if (sess->sock->fd != -1) {
-               /* close connection to the cgi-script */
--              fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
--              fdevent_unregister(srv->ev, hctx->fd);
--              
--              if (close(hctx->fd)) {
--                      log_error_write(srv, __FILE__, __LINE__, "sds", "cgi close failed ", hctx->fd, strerror(errno));
--              }
--              
--              hctx->fd = -1;
--              hctx->fde_ndx = -1;
-+              fdevent_event_del(srv->ev, sess->sock);
-+              fdevent_unregister(srv->ev, sess->sock);
-       }
--      
--      pid = hctx->pid;
--      
-+
-+      pid = sess->pid;
-+
-       con->plugin_ctx[p->id] = NULL;
--      
-+
-       /* is this a good idea ? */
--      cgi_handler_ctx_free(hctx);
--      
-+      cgi_session_free(sess);
-+      sess = NULL;
-+
-       /* if waitpid hasn't been called by response.c yet, do it here */
-       if (pid) {
-               /* check if the CGI-script is already gone */
-+#ifndef _WIN32
-               switch(waitpid(pid, &status, WNOHANG)) {
-               case 0:
-                       /* not finished yet */
-@@ -519,35 +383,34 @@
-               case -1:
-                       /* */
-                       if (errno == EINTR) break;
--                      
--                      /* 
--                       * errno == ECHILD happens if _subrequest catches the process-status before 
-+
-+                      /*
-+                       * errno == ECHILD happens if _subrequest catches the process-status before
-                        * we have read the response of the cgi process
--                       * 
-+                       *
-                        * -> catch status
-                        * -> WAIT_FOR_EVENT
-                        * -> read response
-                        * -> we get here with waitpid == ECHILD
--                       * 
-+                       *
-                        */
-                       if (errno == ECHILD) return HANDLER_GO_ON;
--                      
-+
-                       log_error_write(srv, __FILE__, __LINE__, "ss", "waitpid failed: ", strerror(errno));
-                       return HANDLER_ERROR;
-               default:
-                       /* Send an error if we haven't sent any data yet */
-                       if (0 == con->file_started) {
--                              connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
--                              con->http_status = 500;
-+                              if (con->http_status == 0) con->http_status = 500;
-                               con->mode = DIRECT;
-                       }
--                              
-+
-                       if (WIFEXITED(status)) {
- #if 0
-                               log_error_write(srv, __FILE__, __LINE__, "sd", "(debug) cgi exited fine, pid:", pid);
- #endif
-                               pid = 0;
--                              
-+
-                               return HANDLER_GO_ON;
-                       } else {
-                               log_error_write(srv, __FILE__, __LINE__, "sd", "cgi died, pid:", pid);
-@@ -555,122 +418,126 @@
-                               return HANDLER_GO_ON;
-                       }
-               }
--              
--      
-+
-+
-               kill(pid, SIGTERM);
--              
-+#endif
-               /* cgi-script is still alive, queue the PID for removal */
-               cgi_pid_add(srv, p, pid);
-       }
--#endif        
-+#endif
-       return HANDLER_GO_ON;
- }
- static handler_t cgi_connection_close_callback(server *srv, connection *con, void *p_d) {
-       plugin_data *p = p_d;
--      
--      return cgi_connection_close(srv, con->plugin_ctx[p->id]);
-+
-+      return cgi_connection_close(srv, con, p);
- }
- static handler_t cgi_handle_fdevent(void *s, void *ctx, int revents) {
-       server      *srv  = (server *)s;
--      handler_ctx *hctx = ctx;
--      connection  *con  = hctx->remote_conn;
--      
--      joblist_append(srv, con);
--      
--      if (hctx->fd == -1) {
--              log_error_write(srv, __FILE__, __LINE__, "ddss", con->fd, hctx->fd, connection_get_state(con->state), "invalid cgi-fd");
--              
--              return HANDLER_ERROR;
--      }
--      
-+      cgi_session *sess = ctx;
-+      connection  *con  = sess->remote_con;
-+      chunk *c;
-+
-       if (revents & FDEVENT_IN) {
--              switch (cgi_demux_response(srv, hctx)) {
--              case FDEVENT_HANDLED_NOT_FINISHED:
-+              switch (sess->state) {
-+              case CGI_STATE_READ_RESPONSE_HEADER:
-+                      /* parse the header and set file-started, the demuxer will care about it */
-+                      joblist_append(srv, con);
-+
-                       break;
--              case FDEVENT_HANDLED_FINISHED:
--                      /* we are done */
--                      
-+              case CGI_STATE_READ_RESPONSE_CONTENT:
-+                      /* just forward the content to the out-going queue */
-+
-+                      chunkqueue_remove_finished_chunks(sess->rb);
-+
-+                      switch (srv->network_backend_read(srv, sess->remote_con, sess->sock, sess->rb)) {
-+                      case NETWORK_STATUS_CONNECTION_CLOSE:
-+                              fdevent_event_del(srv->ev, sess->sock);
-+
-+                              /* the connection is gone
-+                               * make the connect */
-+                              sess->remote_con->send->is_closed = 1;
- #if 0
--                      log_error_write(srv, __FILE__, __LINE__, "ddss", con->fd, hctx->fd, connection_get_state(con->state), "finished");
-+                              fdevent_event_del(srv->ev, sess->sock);
- #endif
--                      cgi_connection_close(srv, hctx);
--                      
--                      /* if we get a IN|HUP and have read everything don't exec the close twice */ 
--                      return HANDLER_FINISHED;
--              case FDEVENT_HANDLED_ERROR:
--                      connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
--                      con->http_status = 500;
--                      con->mode = DIRECT;
--                      
--                      log_error_write(srv, __FILE__, __LINE__, "s", "demuxer failed: ");
-+                      case NETWORK_STATUS_SUCCESS:
-+                              /* read even more, do we have all the content */
-+
-+                              /* how much do we want to read ? */
-+                              
-+                              /* call stream-decoder (HTTP-chunked, FastCGI, ... ) */
-+
-+                              chunkqueue_remove_finished_chunks(sess->rb);
-+
-+                              /* copy the content to the next cq */
-+                              for (c = sess->rb->first; c; c = c->next) {
-+                                      if (c->mem->used == 0) continue;
-+
-+                                      http_chunk_append_mem(srv, sess->remote_con, c->mem->ptr + c->offset, c->mem->used - c->offset);
-+      
-+                                      c->offset = c->mem->used - 1;
-+
-+                              }
-+                              chunkqueue_remove_finished_chunks(sess->rb);
-+
-+                              if (sess->remote_con->send->is_closed) {
-+                                      /* send final HTTP-Chunk packet */
-+                                      http_chunk_append_mem(srv, sess->remote_con, NULL, 0);
-+                              }
-+                              
-+                              break;
-+                      default:
-+                              ERROR("%s", "oops, we failed to read");
-+                              break;
-+                      }
-+
-+                      joblist_append(srv, sess->remote_con);
-+                      break;
-+              default:
-+                      TRACE("unexpected state for a FDEVENT_IN: %d", sess->state);
-                       break;
-               }
-       }
--      
-+
-       if (revents & FDEVENT_OUT) {
-               /* nothing to do */
-       }
--      
-+
-       /* perhaps this issue is already handled */
-       if (revents & FDEVENT_HUP) {
--              /* check if we still have a unfinished header package which is a body in reality */
--              if (con->file_started == 0 &&
--                  hctx->response_header->used) {
--                      con->file_started = 1;
--                      http_chunk_append_mem(srv, con, hctx->response_header->ptr, hctx->response_header->used);
--                      joblist_append(srv, con);
--              }
--              
--              if (con->file_finished == 0) {
--                      http_chunk_append_mem(srv, con, NULL, 0);
--                      joblist_append(srv, con);
--              }
--              
--              con->file_finished = 1;
--              
--              if (chunkqueue_is_empty(con->write_queue)) {
--                      /* there is nothing left to write */
--                      connection_set_state(srv, con, CON_STATE_RESPONSE_END);
--              } else {
--                      /* used the write-handler to finish the request on demand */
--                      
--              }
--              
--# if 0
--              log_error_write(srv, __FILE__, __LINE__, "sddd", "got HUP from cgi", con->fd, hctx->fd, revents);
--# endif
--              
--              /* rtsigs didn't liked the close */
--              cgi_connection_close(srv, hctx);
-+              con->send->is_closed = 1;
-+
-+              fdevent_event_del(srv->ev, sess->sock);
-+
-+              /* someone has to close this socket now :) */
-+              http_chunk_append_mem(srv, sess->remote_con, NULL, 0);
-+              joblist_append(srv, sess->remote_con);
-       } else if (revents & FDEVENT_ERR) {
--              con->file_finished = 1;
--              
-+              con->send->is_closed = 1;
-+
-               /* kill all connections to the cgi process */
--              cgi_connection_close(srv, hctx);
--#if 1
--              log_error_write(srv, __FILE__, __LINE__, "s", "cgi-FDEVENT_ERR");
--#endif                        
--              return HANDLER_ERROR;
-+              fdevent_event_del(srv->ev, sess->sock);
-       }
--      
-+
-       return HANDLER_FINISHED;
- }
- static int cgi_env_add(char_array *env, const char *key, size_t key_len, const char *val, size_t val_len) {
-       char *dst;
--      
-+
-       if (!key || !val) return -1;
--      
-+
-       dst = malloc(key_len + val_len + 3);
-       memcpy(dst, key, key_len);
-       dst[key_len] = '=';
-       /* add the \0 from the value */
-       memcpy(dst + key_len + 1, val, val_len + 1);
--      
-+
-       if (env->size == 0) {
-               env->size = 16;
-               env->ptr = malloc(env->size * sizeof(*env->ptr));
-@@ -678,45 +545,45 @@
-               env->size += 16;
-               env->ptr = realloc(env->ptr, env->size * sizeof(*env->ptr));
-       }
--      
-+
-       env->ptr[env->used++] = dst;
--      
-+
-       return 0;
- }
- static int cgi_create_env(server *srv, connection *con, plugin_data *p, buffer *cgi_handler) {
-       pid_t pid;
--      
-+
- #ifdef HAVE_IPV6
-       char b2[INET6_ADDRSTRLEN + 1];
- #endif
--      
-+
-       int to_cgi_fds[2];
-       int from_cgi_fds[2];
-       struct stat st;
--      
--#ifndef __WIN32       
--      
-+
-+#ifndef _WIN32
-+
-       if (cgi_handler->used > 1) {
-               /* stat the exec file */
-               if (-1 == (stat(cgi_handler->ptr, &st))) {
--                      log_error_write(srv, __FILE__, __LINE__, "sbss", 
-+                      log_error_write(srv, __FILE__, __LINE__, "sbss",
-                                       "stat for cgi-handler", cgi_handler,
-                                       "failed:", strerror(errno));
-                       return -1;
-               }
-       }
--      
-+
-       if (pipe(to_cgi_fds)) {
-               log_error_write(srv, __FILE__, __LINE__, "ss", "pipe failed:", strerror(errno));
-               return -1;
-       }
--      
-+
-       if (pipe(from_cgi_fds)) {
-               log_error_write(srv, __FILE__, __LINE__, "ss", "pipe failed:", strerror(errno));
-               return -1;
-       }
--      
-+
-       /* fork, execve */
-       switch (pid = fork()) {
-       case 0: {
-@@ -730,44 +597,40 @@
-               char *c;
-               const char *s;
-               server_socket *srv_sock = con->srv_socket;
--              
-+
-               /* move stdout to from_cgi_fd[1] */
-               close(STDOUT_FILENO);
-               dup2(from_cgi_fds[1], STDOUT_FILENO);
-               close(from_cgi_fds[1]);
-               /* not needed */
-               close(from_cgi_fds[0]);
--              
-+
-               /* move the stdin to to_cgi_fd[0] */
-               close(STDIN_FILENO);
-               dup2(to_cgi_fds[0], STDIN_FILENO);
-               close(to_cgi_fds[0]);
-               /* not needed */
-               close(to_cgi_fds[1]);
--              
--              /* HACK: 
--               * this is not nice, but it works
--               *
--               * we feed the stderr of the CGI to our errorlog, if possible
-+
-+              /**
-+               * FIXME: add a event-handler for STDERR_FILENO and let it LOG()
-                */
--              if (srv->errorlog_mode == ERRORLOG_FILE) {
--                      close(STDERR_FILENO);
--                      dup2(srv->errorlog_fd, STDERR_FILENO);
--              }
--              
-+
-+              close(STDERR_FILENO);
-+
-               /* create environment */
-               env.ptr = NULL;
-               env.size = 0;
-               env.used = 0;
--              
-+
-               cgi_env_add(&env, CONST_STR_LEN("SERVER_SOFTWARE"), CONST_STR_LEN(PACKAGE_NAME"/"PACKAGE_VERSION));
-               if (!buffer_is_empty(con->server_name)) {
-                       cgi_env_add(&env, CONST_STR_LEN("SERVER_NAME"), CONST_BUF_LEN(con->server_name));
-               } else {
- #ifdef HAVE_IPV6
--                      s = inet_ntop(srv_sock->addr.plain.sa_family, 
--                                    srv_sock->addr.plain.sa_family == AF_INET6 ? 
-+                      s = inet_ntop(srv_sock->addr.plain.sa_family,
-+                                    srv_sock->addr.plain.sa_family == AF_INET6 ?
-                                     (const void *) &(srv_sock->addr.ipv6.sin6_addr) :
-                                     (const void *) &(srv_sock->addr.ipv4.sin_addr),
-                                     b2, sizeof(b2)-1);
-@@ -779,10 +642,10 @@
-               cgi_env_add(&env, CONST_STR_LEN("GATEWAY_INTERFACE"), CONST_STR_LEN("CGI/1.1"));
-               s = get_http_version_name(con->request.http_version);
--              
-+
-               cgi_env_add(&env, CONST_STR_LEN("SERVER_PROTOCOL"), s, strlen(s));
--              
--              ltostr(buf, 
-+
-+              ltostr(buf,
- #ifdef HAVE_IPV6
-                       ntohs(srv_sock->addr.plain.sa_family == AF_INET6 ? srv_sock->addr.ipv6.sin6_port : srv_sock->addr.ipv4.sin_port)
- #else
-@@ -790,10 +653,10 @@
- #endif
-                       );
-               cgi_env_add(&env, CONST_STR_LEN("SERVER_PORT"), buf, strlen(buf));
--              
-+
- #ifdef HAVE_IPV6
--              s = inet_ntop(srv_sock->addr.plain.sa_family, 
--                            srv_sock->addr.plain.sa_family == AF_INET6 ? 
-+              s = inet_ntop(srv_sock->addr.plain.sa_family,
-+                            srv_sock->addr.plain.sa_family == AF_INET6 ?
-                             (const void *) &(srv_sock->addr.ipv6.sin6_addr) :
-                             (const void *) &(srv_sock->addr.ipv4.sin_addr),
-                             b2, sizeof(b2)-1);
-@@ -811,15 +674,18 @@
-               cgi_env_add(&env, CONST_STR_LEN("REDIRECT_STATUS"), CONST_STR_LEN("200"));
-               if (!buffer_is_empty(con->uri.query)) {
-                       cgi_env_add(&env, CONST_STR_LEN("QUERY_STRING"), CONST_BUF_LEN(con->uri.query));
-+              } else {
-+                      /* set a empty QUERY_STRING */
-+                      cgi_env_add(&env, CONST_STR_LEN("QUERY_STRING"), CONST_STR_LEN(""));
-               }
-               if (!buffer_is_empty(con->request.orig_uri)) {
-                       cgi_env_add(&env, CONST_STR_LEN("REQUEST_URI"), CONST_BUF_LEN(con->request.orig_uri));
-               }
--              
--              
-+
-+
- #ifdef HAVE_IPV6
--              s = inet_ntop(con->dst_addr.plain.sa_family, 
--                            con->dst_addr.plain.sa_family == AF_INET6 ? 
-+              s = inet_ntop(con->dst_addr.plain.sa_family,
-+                            con->dst_addr.plain.sa_family == AF_INET6 ?
-                             (const void *) &(con->dst_addr.ipv6.sin6_addr) :
-                             (const void *) &(con->dst_addr.ipv4.sin_addr),
-                             b2, sizeof(b2)-1);
-@@ -828,7 +694,7 @@
- #endif
-               cgi_env_add(&env, CONST_STR_LEN("REMOTE_ADDR"), s, strlen(s));
--              ltostr(buf, 
-+              ltostr(buf,
- #ifdef HAVE_IPV6
-                       ntohs(con->dst_addr.plain.sa_family == AF_INET6 ? con->dst_addr.ipv6.sin6_port : con->dst_addr.ipv4.sin_port)
- #else
-@@ -836,19 +702,19 @@
- #endif
-                       );
-               cgi_env_add(&env, CONST_STR_LEN("REMOTE_PORT"), buf, strlen(buf));
--              
-+
-               if (!buffer_is_empty(con->authed_user)) {
-                       cgi_env_add(&env, CONST_STR_LEN("REMOTE_USER"),
-                                   CONST_BUF_LEN(con->authed_user));
-               }
--              
-+
-               /* request.content_length < SSIZE_MAX, see request.c */
-               ltostr(buf, con->request.content_length);
-               cgi_env_add(&env, CONST_STR_LEN("CONTENT_LENGTH"), buf, strlen(buf));
-               cgi_env_add(&env, CONST_STR_LEN("SCRIPT_FILENAME"), CONST_BUF_LEN(con->physical.path));
-               cgi_env_add(&env, CONST_STR_LEN("SCRIPT_NAME"), CONST_BUF_LEN(con->uri.path));
-               cgi_env_add(&env, CONST_STR_LEN("DOCUMENT_ROOT"), CONST_BUF_LEN(con->physical.doc_root));
--              
-+
-               /* for valgrind */
-               if (NULL != (s = getenv("LD_PRELOAD"))) {
-                       cgi_env_add(&env, CONST_STR_LEN("LD_PRELOAD"), s, strlen(s));
-@@ -863,24 +729,24 @@
-                       cgi_env_add(&env, CONST_STR_LEN("SYSTEMROOT"), s, strlen(s));
-               }
- #endif
--              
-+
-               for (n = 0; n < con->request.headers->used; n++) {
-                       data_string *ds;
--                      
-+
-                       ds = (data_string *)con->request.headers->data[n];
--                      
-+
-                       if (ds->value->used && ds->key->used) {
-                               size_t j;
--                              
-+
-                               buffer_reset(p->tmp_buf);
--                              
-+
-                               if (0 != strcasecmp(ds->key->ptr, "CONTENT-TYPE")) {
-                                       buffer_copy_string(p->tmp_buf, "HTTP_");
-                                       p->tmp_buf->used--; /* strip \0 after HTTP_ */
-                               }
--                              
-+
-                               buffer_prepare_append(p->tmp_buf, ds->key->used + 2);
--                              
-+
-                               for (j = 0; j < ds->key->used - 1; j++) {
-                                       char cr = '_';
-                                       if (light_isalpha(ds->key->ptr[j])) {
-@@ -893,46 +759,46 @@
-                                       p->tmp_buf->ptr[p->tmp_buf->used++] = cr;
-                               }
-                               p->tmp_buf->ptr[p->tmp_buf->used++] = '\0';
--                              
-+
-                               cgi_env_add(&env, CONST_BUF_LEN(p->tmp_buf), CONST_BUF_LEN(ds->value));
-                       }
-               }
--              
-+
-               for (n = 0; n < con->environment->used; n++) {
-                       data_string *ds;
--                      
-+
-                       ds = (data_string *)con->environment->data[n];
--                      
-+
-                       if (ds->value->used && ds->key->used) {
-                               size_t j;
--                              
-+
-                               buffer_reset(p->tmp_buf);
--                              
-+
-                               buffer_prepare_append(p->tmp_buf, ds->key->used + 2);
--                              
-+
-                               for (j = 0; j < ds->key->used - 1; j++) {
--                                      p->tmp_buf->ptr[p->tmp_buf->used++] = 
--                                              isalpha((unsigned char)ds->key->ptr[j]) ? 
-+                                      p->tmp_buf->ptr[p->tmp_buf->used++] =
-+                                              isalpha((unsigned char)ds->key->ptr[j]) ?
-                                               toupper((unsigned char)ds->key->ptr[j]) : '_';
-                               }
-                               p->tmp_buf->ptr[p->tmp_buf->used++] = '\0';
--                              
-+
-                               cgi_env_add(&env, CONST_BUF_LEN(p->tmp_buf), CONST_BUF_LEN(ds->value));
-                       }
-               }
--              
-+
-               if (env.size == env.used) {
-                       env.size += 16;
-                       env.ptr = realloc(env.ptr, env.size * sizeof(*env.ptr));
-               }
--              
-+
-               env.ptr[env.used] = NULL;
--              
-+
-               /* set up args */
-               argc = 3;
-               args = malloc(sizeof(*args) * argc);
-               i = 0;
--              
-+
-               if (cgi_handler->used > 1) {
-                       args[i++] = cgi_handler->ptr;
-               }
-@@ -942,7 +808,7 @@
-               /* search for the last / */
-               if (NULL != (c = strrchr(con->physical.path->ptr, '/'))) {
-                       *c = '\0';
--                      
-+
-                       /* change to the physical directory */
-                       if (-1 == chdir(con->physical.path->ptr)) {
-                               log_error_write(srv, __FILE__, __LINE__, "ssb", "chdir failed:", strerror(errno), con->physical.path);
-@@ -952,14 +818,14 @@
-               /* we don't need the client socket */
-               for (i = 3; i < 256; i++) {
--                      if (i != srv->errorlog_fd) close(i);
-+                      close(i);
-               }
--              
-+
-               /* exec the cgi */
-               execve(args[0], args, env.ptr);
--              
-+
-               log_error_write(srv, __FILE__, __LINE__, "sss", "CGI failed:", strerror(errno), args[0]);
--              
-+
-               /* */
-               SEGFAULT();
-               break;
-@@ -969,16 +835,16 @@
-               log_error_write(srv, __FILE__, __LINE__, "ss", "fork failed:", strerror(errno));
-               break;
-       default: {
--              handler_ctx *hctx;
-+              cgi_session *sess;
-               /* father */
-               close(from_cgi_fds[1]);
-               close(to_cgi_fds[0]);
--              
-+
-               if (con->request.content_length) {
--                      chunkqueue *cq = con->request_content_queue;
-+                      chunkqueue *cq = con->recv;
-                       chunk *c;
--              
-+
-                       assert(chunkqueue_length(cq) == (off_t)con->request.content_length);
-                       /* there is content to send */
-@@ -993,16 +859,16 @@
-                                               if (-1 == c->file.fd &&  /* open the file if not already open */
-                                                   -1 == (c->file.fd = open(c->file.name->ptr, O_RDONLY))) {
-                                                       log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno));
--                                      
-+
-                                                       close(from_cgi_fds[0]);
-                                                       close(to_cgi_fds[1]);
-                                                       return -1;
-                                               }
-                                               c->file.mmap.length = c->file.length;
--                              
-+
-                                               if (MAP_FAILED == (c->file.mmap.start = mmap(0,  c->file.mmap.length, PROT_READ, MAP_SHARED, c->file.fd, 0))) {
--                                                      log_error_write(srv, __FILE__, __LINE__, "ssbd", "mmap failed: ", 
-+                                                      log_error_write(srv, __FILE__, __LINE__, "ssbd", "mmap failed: ",
-                                                                       strerror(errno), c->file.name,  c->file.fd);
-                                                       close(from_cgi_fds[0]);
-@@ -1012,7 +878,7 @@
-                                               close(c->file.fd);
-                                               c->file.fd = -1;
--      
-+
-                                               /* chunk_reset() or chunk_free() will cleanup for us */
-                                       }
-@@ -1020,7 +886,7 @@
-                                               switch(errno) {
-                                               case ENOSPC:
-                                                       con->http_status = 507;
--              
-+
-                                                       break;
-                                               default:
-                                                       con->http_status = 403;
-@@ -1033,7 +899,7 @@
-                                               switch(errno) {
-                                               case ENOSPC:
-                                                       con->http_status = 507;
--              
-+
-                                                       break;
-                                               default:
-                                                       con->http_status = 403;
-@@ -1056,103 +922,95 @@
-               }
-               close(to_cgi_fds[1]);
--                              
-+
-               /* register PID and wait for them asyncronously */
-               con->mode = p->id;
-               buffer_reset(con->physical.path);
--              
--              hctx = cgi_handler_ctx_init();
--              
--              hctx->remote_conn = con;
--              hctx->plugin_data = p;
--              hctx->pid = pid;
--              hctx->fd = from_cgi_fds[0];
--              hctx->fde_ndx = -1;
--              
--              con->plugin_ctx[p->id] = hctx;
--              
--              fdevent_register(srv->ev, hctx->fd, cgi_handle_fdevent, hctx);
--              fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
--              
--              if (-1 == fdevent_fcntl_set(srv->ev, hctx->fd)) {
-+
-+              sess = cgi_session_init();
-+
-+              sess->remote_con = con;
-+              sess->pid = pid;
-+
-+              assert(sess->sock);
-+
-+              sess->sock->fd = from_cgi_fds[0];
-+              sess->sock->type = IOSOCKET_TYPE_PIPE;
-+
-+              if (-1 == fdevent_fcntl_set(srv->ev, sess->sock)) {
-                       log_error_write(srv, __FILE__, __LINE__, "ss", "fcntl failed: ", strerror(errno));
--                      
--                      fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
--                      fdevent_unregister(srv->ev, hctx->fd);
--                      
--                      log_error_write(srv, __FILE__, __LINE__, "sd", "cgi close:", hctx->fd);
--                      
--                      close(hctx->fd);
--                      
--                      cgi_handler_ctx_free(hctx);
--                      
--                      con->plugin_ctx[p->id] = NULL;
--                      
-+
-+                      cgi_session_free(sess);
-+
-                       return -1;
-               }
--              
-+
-+              con->plugin_ctx[p->id] = sess;
-+
-+              fdevent_register(srv->ev, sess->sock, cgi_handle_fdevent, sess);
-+              fdevent_event_add(srv->ev, sess->sock, FDEVENT_IN);
-+
-+              sess->state = CGI_STATE_READ_RESPONSE_HEADER;
-+
-               break;
-       }
-       }
--      
-+
-       return 0;
- #else
-       return -1;
- #endif
- }
--#define PATCH(x) \
--      p->conf.x = s->x;
- static int mod_cgi_patch_connection(server *srv, connection *con, plugin_data *p) {
-       size_t i, j;
-       plugin_config *s = p->config_storage[0];
--      
--      PATCH(cgi);
--      
-+
-+      PATCH_OPTION(cgi);
-+
-       /* skip the first, the global context */
-       for (i = 1; i < srv->config_context->used; i++) {
-               data_config *dc = (data_config *)srv->config_context->data[i];
-               s = p->config_storage[i];
--              
-+
-               /* condition didn't match */
-               if (!config_check_cond(srv, con, dc)) continue;
--              
-+
-               /* merge config */
-               for (j = 0; j < dc->value->used; j++) {
-                       data_unset *du = dc->value->data[j];
--                      
-+
-                       if (buffer_is_equal_string(du->key, CONST_STR_LEN("cgi.assign"))) {
--                              PATCH(cgi);
-+                              PATCH_OPTION(cgi);
-                       }
-               }
-       }
--      
-+
-       return 0;
- }
--#undef PATCH
- URIHANDLER_FUNC(cgi_is_handled) {
-       size_t k, s_len;
-       plugin_data *p = p_d;
-       buffer *fn = con->physical.path;
--      
-+
-       if (fn->used == 0) return HANDLER_GO_ON;
--      
-+
-       mod_cgi_patch_connection(srv, con, p);
--      
-+
-       s_len = fn->used - 1;
--      
-+
-       for (k = 0; k < p->conf.cgi->used; k++) {
-               data_string *ds = (data_string *)p->conf.cgi->data[k];
-               size_t ct_len = ds->key->used - 1;
--              
-+
-               if (ds->key->used == 0) continue;
-               if (s_len < ct_len) continue;
--              
-+
-               if (0 == strncmp(fn->ptr + s_len - ct_len, ds->key->ptr, ct_len)) {
-                       if (cgi_create_env(srv, con, p, ds->value)) {
-                               con->http_status = 500;
--                              
-+
-                               buffer_reset(con->physical.path);
-                               return HANDLER_FINISHED;
-                       }
-@@ -1160,7 +1018,7 @@
-                       break;
-               }
-       }
--      
-+
-       return HANDLER_GO_ON;
- }
-@@ -1168,11 +1026,11 @@
-       plugin_data *p = p_d;
-       size_t ndx;
-       /* the trigger handle only cares about lonely PID which we have to wait for */
--#ifndef __WIN32
-+#ifndef _WIN32
-       for (ndx = 0; ndx < p->cgi_pid.used; ndx++) {
-               int status;
--              
-+
-               switch(waitpid(p->cgi_pid.ptr[ndx], &status, WNOHANG)) {
-               case 0:
-                       /* not finished yet */
-@@ -1182,7 +1040,7 @@
-                       break;
-               case -1:
-                       log_error_write(srv, __FILE__, __LINE__, "ss", "waitpid failed: ", strerror(errno));
--                      
-+
-                       return HANDLER_ERROR;
-               default:
-@@ -1193,96 +1051,104 @@
-                       } else {
-                               log_error_write(srv, __FILE__, __LINE__, "s", "cgi died ?");
-                       }
--                      
-+
-                       cgi_pid_del(srv, p, p->cgi_pid.ptr[ndx]);
--                      /* del modified the buffer structure 
-+                      /* del modified the buffer structure
-                        * and copies the last entry to the current one
-                        * -> recheck the current index
-                        */
-                       ndx--;
-               }
-       }
--#endif        
-+#endif
-       return HANDLER_GO_ON;
- }
- SUBREQUEST_FUNC(mod_cgi_handle_subrequest) {
-       int status;
-       plugin_data *p = p_d;
--      handler_ctx *hctx = con->plugin_ctx[p->id];
--      
-+      cgi_session *sess = con->plugin_ctx[p->id];
-+
-       if (con->mode != p->id) return HANDLER_GO_ON;
--      if (NULL == hctx) return HANDLER_GO_ON;
--      
-+      if (NULL == sess) return HANDLER_GO_ON;
-+
-+      switch (cgi_demux_response(srv, con, p)) {
-+      case 0:
-+              break;
-+      case 1:
-+              cgi_connection_close(srv, con, p);
-+
-+              /* if we get a IN|HUP and have read everything don't exec the close twice */
-+              return HANDLER_FINISHED;
-+      case -1:
-+              cgi_connection_close(srv, con, p);
-+
-+              if (0 == con->http_status) con->http_status = 500;
-+              con->mode = DIRECT;
-+
-+              return HANDLER_FINISHED;
-+      }
-+
- #if 0
--      log_error_write(srv, __FILE__, __LINE__, "sdd", "subrequest, pid =", hctx, hctx->pid);
--#endif        
--      if (hctx->pid == 0) return HANDLER_FINISHED;
--#ifndef __WIN32       
--      switch(waitpid(hctx->pid, &status, WNOHANG)) {
-+      log_error_write(srv, __FILE__, __LINE__, "sdd", "subrequest, pid =", sess, sess->pid);
-+#endif
-+      if (sess->pid == 0) return HANDLER_FINISHED;
-+#ifndef _WIN32
-+      switch(waitpid(sess->pid, &status, WNOHANG)) {
-       case 0:
-               /* we only have for events here if we don't have the header yet,
-                * otherwise the event-handler will send us the incoming data */
--              if (con->file_started) return HANDLER_FINISHED;
--              return HANDLER_WAIT_FOR_EVENT;
-+              if (!con->file_started) return HANDLER_WAIT_FOR_EVENT;
-+              if (con->send->is_closed) return HANDLER_FINISHED;
-+
-+              return HANDLER_GO_ON;
-       case -1:
-               if (errno == EINTR) return HANDLER_WAIT_FOR_EVENT;
--              
-+
-               if (errno == ECHILD && con->file_started == 0) {
-                       /*
--                       * second round but still not response 
-+                       * second round but still not response
-                        */
--                      return HANDLER_WAIT_FOR_EVENT; 
-+                      return HANDLER_WAIT_FOR_EVENT;
-               }
--              
-+
-               log_error_write(srv, __FILE__, __LINE__, "ss", "waitpid failed: ", strerror(errno));
-               con->mode = DIRECT;
-               con->http_status = 500;
--              
--              hctx->pid = 0;
--              
--              fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
--              fdevent_unregister(srv->ev, hctx->fd);
--              
--              if (close(hctx->fd)) {
--                      log_error_write(srv, __FILE__, __LINE__, "sds", "cgi close failed ", hctx->fd, strerror(errno));
--              }
--              
--              cgi_handler_ctx_free(hctx);
--              
-+
-+              sess->pid = 0;
-+
-+              fdevent_event_del(srv->ev, sess->sock);
-+              fdevent_unregister(srv->ev, sess->sock);
-+
-+              cgi_session_free(sess);
-+              sess = NULL;
-+
-               con->plugin_ctx[p->id] = NULL;
--              
-+
-               return HANDLER_FINISHED;
-       default:
--              /* cgi process exited cleanly 
--               * 
--               * check if we already got the response 
--               */
--              
--              if (!con->file_started) return HANDLER_WAIT_FOR_EVENT;
--              
-+              con->send->is_closed = 1;
-+
-               if (WIFEXITED(status)) {
-                       /* nothing */
-               } else {
-                       log_error_write(srv, __FILE__, __LINE__, "s", "cgi died ?");
--                      
-+
-                       con->mode = DIRECT;
-                       con->http_status = 500;
--                      
-+
-               }
--              
--              hctx->pid = 0;
--              
--              fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
--              fdevent_unregister(srv->ev, hctx->fd);
--              
--              if (close(hctx->fd)) {
--                      log_error_write(srv, __FILE__, __LINE__, "sds", "cgi close failed ", hctx->fd, strerror(errno));
--              }
--              
--              cgi_handler_ctx_free(hctx);
--              
-+
-+              sess->pid = 0;
-+
-+              fdevent_event_del(srv->ev, sess->sock);
-+              fdevent_unregister(srv->ev, sess->sock);
-+
-+              cgi_session_free(sess);
-+              sess = NULL;
-+
-               con->plugin_ctx[p->id] = NULL;
-               return HANDLER_FINISHED;
-       }
-@@ -1297,17 +1163,15 @@
-       p->name        = buffer_init_string("cgi");
-       p->connection_reset = cgi_connection_close_callback;
--      p->handle_subrequest_start = cgi_is_handled;
--      p->handle_subrequest = mod_cgi_handle_subrequest;
--#if 0
--      p->handle_fdevent = cgi_handle_fdevent;
--#endif
-+      p->handle_start_backend = cgi_is_handled;
-+      p->handle_send_request_content = mod_cgi_handle_subrequest;
-+
-       p->handle_trigger = cgi_trigger;
-       p->init           = mod_cgi_init;
-       p->cleanup        = mod_cgi_free;
-       p->set_defaults   = mod_fastcgi_set_defaults;
--      
-+
-       p->data        = NULL;
--      
-+
-       return 0;
- }
---- ../lighttpd-1.4.11/src/mod_cml.c   2006-01-30 13:51:48.000000000 +0200
-+++ lighttpd-1.5.0/src/mod_cml.c       2006-09-07 00:57:05.000000000 +0300
-@@ -4,7 +4,6 @@
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
--#include <unistd.h>
- #include <stdio.h>
- #include "buffer.h"
-@@ -20,50 +19,50 @@
- /* init the plugin data */
- INIT_FUNC(mod_cml_init) {
-       plugin_data *p;
--      
-+
-       p = calloc(1, sizeof(*p));
--      
-+
-       p->basedir         = buffer_init();
-       p->baseurl         = buffer_init();
-       p->trigger_handler = buffer_init();
--      
-+
-       return p;
- }
- /* detroy the plugin data */
- FREE_FUNC(mod_cml_free) {
-       plugin_data *p = p_d;
--      
-+
-       UNUSED(srv);
-       if (!p) return HANDLER_GO_ON;
--      
-+
-       if (p->config_storage) {
-               size_t i;
-               for (i = 0; i < srv->config_context->used; i++) {
-                       plugin_config *s = p->config_storage[i];
--                      
-+
-                       buffer_free(s->ext);
--                      
-+
-                       buffer_free(s->mc_namespace);
-                       buffer_free(s->power_magnet);
-                       array_free(s->mc_hosts);
--                      
-+
- #if defined(HAVE_MEMCACHE_H)
-                       if (s->mc) mc_free(s->mc);
- #endif
--                      
-+
-                       free(s);
-               }
-               free(p->config_storage);
-       }
--      
-+
-       buffer_free(p->trigger_handler);
-       buffer_free(p->basedir);
-       buffer_free(p->baseurl);
--      
-+
-       free(p);
--      
-+
-       return HANDLER_GO_ON;
- }
-@@ -72,22 +71,22 @@
- SETDEFAULTS_FUNC(mod_cml_set_defaults) {
-       plugin_data *p = p_d;
-       size_t i = 0;
--      
--      config_values_t cv[] = { 
-+
-+      config_values_t cv[] = {
-               { "cml.extension",              NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
-               { "cml.memcache-hosts",         NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },        /* 1 */
-               { "cml.memcache-namespace",     NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 2 */
-               { "cml.power-magnet",           NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 3 */
-               { NULL,                         NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
-       };
--      
-+
-       if (!p) return HANDLER_ERROR;
--      
-+
-       p->config_storage = malloc(srv->config_context->used * sizeof(specific_config *));
--      
-+
-       for (i = 0; i < srv->config_context->used; i++) {
-               plugin_config *s;
--              
-+
-               s = malloc(sizeof(plugin_config));
-               s->ext    = buffer_init();
-               s->mc_hosts       = array_init();
-@@ -96,87 +95,84 @@
- #if defined(HAVE_MEMCACHE_H)
-               s->mc = NULL;
- #endif
--              
-+
-               cv[0].destination = s->ext;
-               cv[1].destination = s->mc_hosts;
-               cv[2].destination = s->mc_namespace;
-               cv[3].destination = s->power_magnet;
--              
-+
-               p->config_storage[i] = s;
--      
-+
-               if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
-                       return HANDLER_ERROR;
-               }
--              
-+
-               if (s->mc_hosts->used) {
- #if defined(HAVE_MEMCACHE_H)
-                       size_t k;
-                       s->mc = mc_new();
--              
-+
-                       for (k = 0; k < s->mc_hosts->used; k++) {
-                               data_string *ds = (data_string *)s->mc_hosts->data[k];
--                              
-+
-                               if (0 != mc_server_add4(s->mc, ds->value->ptr)) {
--                                      log_error_write(srv, __FILE__, __LINE__, "sb", 
--                                                      "connection to host failed:", 
-+                                      log_error_write(srv, __FILE__, __LINE__, "sb",
-+                                                      "connection to host failed:",
-                                                       ds->value);
--                                      
-+
-                                       return HANDLER_ERROR;
-                               }
-                       }
- #else
--                      log_error_write(srv, __FILE__, __LINE__, "s", 
-+                      log_error_write(srv, __FILE__, __LINE__, "s",
-                                       "memcache support is not compiled in but cml.memcache-hosts is set, aborting");
-                       return HANDLER_ERROR;
- #endif
-               }
-       }
--      
-+
-       return HANDLER_GO_ON;
- }
--#define PATCH(x) \
--      p->conf.x = s->x;
- static int mod_cml_patch_connection(server *srv, connection *con, plugin_data *p) {
-       size_t i, j;
-       plugin_config *s = p->config_storage[0];
--      
--      PATCH(ext);
-+
-+      PATCH_OPTION(ext);
- #if defined(HAVE_MEMCACHE_H)
--      PATCH(mc);
-+      PATCH_OPTION(mc);
- #endif
--      PATCH(mc_namespace);
--      PATCH(power_magnet);
--      
-+      PATCH_OPTION(mc_namespace);
-+      PATCH_OPTION(power_magnet);
-+
-       /* skip the first, the global context */
-       for (i = 1; i < srv->config_context->used; i++) {
-               data_config *dc = (data_config *)srv->config_context->data[i];
-               s = p->config_storage[i];
--              
-+
-               /* condition didn't match */
-               if (!config_check_cond(srv, con, dc)) continue;
--              
-+
-               /* merge config */
-               for (j = 0; j < dc->value->used; j++) {
-                       data_unset *du = dc->value->data[j];
--                      
-+
-                       if (buffer_is_equal_string(du->key, CONST_STR_LEN("cml.extension"))) {
--                              PATCH(ext);
-+                              PATCH_OPTION(ext);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("cml.memcache-hosts"))) {
- #if defined(HAVE_MEMCACHE_H)
--                              PATCH(mc);
-+                              PATCH_OPTION(mc);
- #endif
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("cml.memcache-namespace"))) {
--                              PATCH(mc_namespace);
-+                              PATCH_OPTION(mc_namespace);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("cml.power-magnet"))) {
--                              PATCH(power_magnet);
-+                              PATCH_OPTION(power_magnet);
-                       }
-               }
-       }
--      
-+
-       return 0;
- }
--#undef PATCH
- int cache_call_lua(server *srv, connection *con, plugin_data *p, buffer *cml_file) {
-       buffer *b;
-@@ -187,57 +183,57 @@
-       b = p->baseurl;
-       buffer_copy_string_buffer(b, con->uri.path);
-       for (c = b->ptr + b->used - 1; c > b->ptr && *c != '/'; c--);
--      
-+
-       if (*c == '/') {
-               b->used = c - b->ptr + 2;
-               *(c+1) = '\0';
-       }
--      
-+
-       b = p->basedir;
-       buffer_copy_string_buffer(b, con->physical.path);
-       for (c = b->ptr + b->used - 1; c > b->ptr && *c != '/'; c--);
--      
-+
-       if (*c == '/') {
-               b->used = c - b->ptr + 2;
-               *(c+1) = '\0';
-       }
--      
-+
-       /* prepare variables
-        *   - cookie-based
-        *   - get-param-based
-        */
--      
-+
-       return cache_parse_lua(srv, con, p, cml_file);
--      
-+
- }
- URIHANDLER_FUNC(mod_cml_power_magnet) {
-       plugin_data *p = p_d;
--      
-+
-       mod_cml_patch_connection(srv, con, p);
--      
-+
-       buffer_reset(p->basedir);
-       buffer_reset(p->baseurl);
-       buffer_reset(p->trigger_handler);
-       if (buffer_is_empty(p->conf.power_magnet)) return HANDLER_GO_ON;
--      
--      /* 
-+
-+      /*
-        * power-magnet:
-        * cml.power-magnet = server.docroot + "/rewrite.cml"
-        *
-        * is called on EACH request, take the original REQUEST_URI and modifies the
--       * request header as neccesary. 
-+       * request header as neccesary.
-        *
-        * First use:
-        * if file_exists("/maintainance.html") {
-        *   output_include = ( "/maintainance.html" )
--       *   return CACHE_HIT 
-+       *   return CACHE_HIT
-        * }
-        *
-        * as we only want to rewrite HTML like requests we should cover it in a conditional
--       * 
-+       *
-        * */
-       switch(cache_call_lua(srv, con, p, p->conf.power_magnet)) {
-@@ -266,20 +262,20 @@
- URIHANDLER_FUNC(mod_cml_is_handled) {
-       plugin_data *p = p_d;
--      
-+
-       if (buffer_is_empty(con->physical.path)) return HANDLER_ERROR;
--      
-+
-       mod_cml_patch_connection(srv, con, p);
--      
-+
-       buffer_reset(p->basedir);
-       buffer_reset(p->baseurl);
-       buffer_reset(p->trigger_handler);
-       if (buffer_is_empty(p->conf.ext)) return HANDLER_GO_ON;
--      
-+
-       if (!buffer_is_equal_right_len(con->physical.path, p->conf.ext, p->conf.ext->used - 1)) {
-               return HANDLER_GO_ON;
--      } 
-+      }
-       switch(cache_call_lua(srv, con, p, con->physical.path)) {
-       case -1:
-@@ -311,15 +307,15 @@
- int mod_cml_plugin_init(plugin *p) {
-       p->version     = LIGHTTPD_VERSION_ID;
-       p->name        = buffer_init_string("cache");
--      
-+
-       p->init        = mod_cml_init;
-       p->cleanup     = mod_cml_free;
-       p->set_defaults  = mod_cml_set_defaults;
--      
--      p->handle_subrequest_start = mod_cml_is_handled;
-+
-+      p->handle_start_backend    = mod_cml_is_handled;
-       p->handle_physical         = mod_cml_power_magnet;
--      
-+
-       p->data        = NULL;
--      
-+
-       return 0;
- }
---- ../lighttpd-1.4.11/src/mod_cml.h   2006-01-30 13:51:35.000000000 +0200
-+++ lighttpd-1.5.0/src/mod_cml.h       2006-07-16 00:26:03.000000000 +0300
-@@ -16,10 +16,10 @@
- typedef struct {
-       buffer *ext;
--      
-+
-       array  *mc_hosts;
-       buffer *mc_namespace;
--#if defined(HAVE_MEMCACHE_H) 
-+#if defined(HAVE_MEMCACHE_H)
-       struct memcache *mc;
- #endif
-       buffer *power_magnet;
-@@ -27,15 +27,15 @@
- typedef struct {
-       PLUGIN_DATA;
--      
-+
-       buffer *basedir;
-       buffer *baseurl;
--      
-+
-       buffer *trigger_handler;
--      
-+
-       plugin_config **config_storage;
--      
--      plugin_config conf; 
-+
-+      plugin_config conf;
- } plugin_data;
- int cache_parse_lua(server *srv, connection *con, plugin_data *p, buffer *fn);
---- ../lighttpd-1.4.11/src/mod_cml_funcs.c     2005-11-17 16:15:08.000000000 +0200
-+++ lighttpd-1.5.0/src/mod_cml_funcs.c 2006-07-16 00:26:04.000000000 +0300
-@@ -4,8 +4,7 @@
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
--#include <unistd.h>
--#include <dirent.h>
-+
- #include <stdio.h>
- #include "buffer.h"
-@@ -13,6 +12,7 @@
- #include "log.h"
- #include "plugin.h"
- #include "response.h"
-+#include "sys-files.h"
- #include "mod_cml.h"
- #include "mod_cml_funcs.h"
-@@ -30,7 +30,7 @@
- #ifdef USE_OPENSSL
- #define IN const
- #else
--#define IN 
-+#define IN
- #endif
- #define OUT
-@@ -42,29 +42,29 @@
-       buffer b;
-       char hex[33];
-       int n = lua_gettop(L);
--      
-+
-       b.ptr = hex;
-       b.used = 0;
-       b.size = sizeof(hex);
--      
-+
-       if (n != 1) {
-               lua_pushstring(L, "md5: expected one argument");
-               lua_error(L);
-       }
--      
-+
-       if (!lua_isstring(L, 1)) {
-               lua_pushstring(L, "md5: argument has to be a string");
-               lua_error(L);
-       }
--      
-+
-       MD5_Init(&Md5Ctx);
-       MD5_Update(&Md5Ctx, (unsigned char *)lua_tostring(L, 1), lua_strlen(L, 1));
-       MD5_Final(HA1, &Md5Ctx);
--      
-+
-       buffer_copy_string_hex(&b, (char *)HA1, 16);
--      
-+
-       lua_pushstring(L, b.ptr);
--      
-+
-       return 1;
- }
-@@ -72,37 +72,37 @@
- int f_file_mtime(lua_State *L) {
-       struct stat st;
-       int n = lua_gettop(L);
--      
-+
-       if (n != 1) {
-               lua_pushstring(L, "file_mtime: expected one argument");
-               lua_error(L);
-       }
--      
-+
-       if (!lua_isstring(L, 1)) {
-               lua_pushstring(L, "file_mtime: argument has to be a string");
-               lua_error(L);
-       }
--      
-+
-       if (-1 == stat(lua_tostring(L, 1), &st)) {
-               lua_pushnil(L);
-               return 1;
-       }
--      
-+
-       lua_pushnumber(L, st.st_mtime);
--      
-+
-       return 1;
- }
--
-+#ifndef _WIN32
- int f_dir_files_iter(lua_State *L) {
-       DIR *d;
-       struct dirent *de;
--      
-+
-       d = lua_touserdata(L, lua_upvalueindex(1));
--      
-+
-       if (NULL == (de = readdir(d))) {
-               /* EOF */
-               closedir(d);
--              
-+
-               return 0;
-       } else {
-               lua_pushstring(L, de->d_name);
-@@ -113,75 +113,75 @@
- int f_dir_files(lua_State *L) {
-       DIR *d;
-       int n = lua_gettop(L);
--      
-+
-       if (n != 1) {
-               lua_pushstring(L, "dir_files: expected one argument");
-               lua_error(L);
-       }
--      
-+
-       if (!lua_isstring(L, 1)) {
-               lua_pushstring(L, "dir_files: argument has to be a string");
-               lua_error(L);
-       }
--      
--      /* check if there is a valid DIR handle on the stack */ 
-+
-+      /* check if there is a valid DIR handle on the stack */
-       if (NULL == (d = opendir(lua_tostring(L, 1)))) {
-               lua_pushnil(L);
-               return 1;
-       }
--      
-+
-       /* push d into registry */
-       lua_pushlightuserdata(L, d);
-       lua_pushcclosure(L, f_dir_files_iter, 1);
--      
-+
-       return 1;
- }
--
-+#endif
- int f_file_isreg(lua_State *L) {
-       struct stat st;
-       int n = lua_gettop(L);
--      
-+
-       if (n != 1) {
-               lua_pushstring(L, "file_isreg: expected one argument");
-               lua_error(L);
-       }
--      
-+
-       if (!lua_isstring(L, 1)) {
-               lua_pushstring(L, "file_isreg: argument has to be a string");
-               lua_error(L);
-       }
--      
-+
-       if (-1 == stat(lua_tostring(L, 1), &st)) {
-               lua_pushnil(L);
-               return 1;
-       }
--      
-+
-       lua_pushnumber(L, S_ISREG(st.st_mode));
--      
-+
-       return 1;
- }
- int f_file_isdir(lua_State *L) {
-       struct stat st;
-       int n = lua_gettop(L);
--      
-+
-       if (n != 1) {
-               lua_pushstring(L, "file_isreg: expected one argument");
-               lua_error(L);
-       }
--      
-+
-       if (!lua_isstring(L, 1)) {
-               lua_pushstring(L, "file_isreg: argument has to be a string");
-               lua_error(L);
-       }
--      
-+
-       if (-1 == stat(lua_tostring(L, 1), &st)) {
-               lua_pushnil(L);
-               return 1;
-       }
--      
-+
-       lua_pushnumber(L, S_ISDIR(st.st_mode));
--      
-+
-       return 1;
- }
-@@ -192,33 +192,33 @@
-       char *r;
-       int n = lua_gettop(L);
-       struct memcache *mc;
--      
-+
-       if (!lua_islightuserdata(L, lua_upvalueindex(1))) {
-               lua_pushstring(L, "where is my userdata ?");
-               lua_error(L);
-       }
--      
-+
-       mc = lua_touserdata(L, lua_upvalueindex(1));
--      
-+
-       if (n != 1) {
-               lua_pushstring(L, "expected one argument");
-               lua_error(L);
-       }
--      
-+
-       if (!lua_isstring(L, 1)) {
-               lua_pushstring(L, "argument has to be a string");
-               lua_error(L);
-       }
--      
--      if (NULL == (r = mc_aget(mc, 
-+
-+      if (NULL == (r = mc_aget(mc,
-                                lua_tostring(L, 1), lua_strlen(L, 1)))) {
--                              
-+
-               lua_pushboolean(L, 0);
-               return 1;
-       }
--      
-+
-       free(r);
--      
-+
-       lua_pushboolean(L, 1);
-       return 1;
- }
-@@ -226,74 +226,74 @@
- int f_memcache_get_string(lua_State *L) {
-       char *r;
-       int n = lua_gettop(L);
--      
-+
-       struct memcache *mc;
--      
-+
-       if (!lua_islightuserdata(L, lua_upvalueindex(1))) {
-               lua_pushstring(L, "where is my userdata ?");
-               lua_error(L);
-       }
--      
-+
-       mc = lua_touserdata(L, lua_upvalueindex(1));
--      
--      
-+
-+
-       if (n != 1) {
-               lua_pushstring(L, "expected one argument");
-               lua_error(L);
-       }
--      
-+
-       if (!lua_isstring(L, 1)) {
-               lua_pushstring(L, "argument has to be a string");
-               lua_error(L);
-       }
--      
--      if (NULL == (r = mc_aget(mc, 
-+
-+      if (NULL == (r = mc_aget(mc,
-                                lua_tostring(L, 1), lua_strlen(L, 1)))) {
-               lua_pushnil(L);
-               return 1;
-       }
--      
-+
-       lua_pushstring(L, r);
--      
-+
-       free(r);
--      
-+
-       return 1;
- }
- int f_memcache_get_long(lua_State *L) {
-       char *r;
-       int n = lua_gettop(L);
--      
-+
-       struct memcache *mc;
--      
-+
-       if (!lua_islightuserdata(L, lua_upvalueindex(1))) {
-               lua_pushstring(L, "where is my userdata ?");
-               lua_error(L);
-       }
--      
-+
-       mc = lua_touserdata(L, lua_upvalueindex(1));
--      
--      
-+
-+
-       if (n != 1) {
-               lua_pushstring(L, "expected one argument");
-               lua_error(L);
-       }
--      
-+
-       if (!lua_isstring(L, 1)) {
-               lua_pushstring(L, "argument has to be a string");
-               lua_error(L);
-       }
--      
--      if (NULL == (r = mc_aget(mc, 
-+
-+      if (NULL == (r = mc_aget(mc,
-                                lua_tostring(L, 1), lua_strlen(L, 1)))) {
-               lua_pushnil(L);
-               return 1;
-       }
--      
-+
-       lua_pushnumber(L, strtol(r, NULL, 10));
--      
-+
-       free(r);
--      
-+
-       return 1;
- }
- #endif
---- ../lighttpd-1.4.11/src/mod_cml_lua.c       2006-01-30 13:56:40.000000000 +0200
-+++ lighttpd-1.5.0/src/mod_cml_lua.c   2006-09-07 00:57:05.000000000 +0300
-@@ -23,7 +23,7 @@
- #ifdef USE_OPENSSL
- #define IN const
- #else
--#define IN 
-+#define IN
- #endif
- #define OUT
-@@ -31,6 +31,7 @@
- #include <lua.h>
- #include <lualib.h>
-+#include <lauxlib.h>
- typedef struct {
-       stream st;
-@@ -39,11 +40,11 @@
- static const char * load_file(lua_State *L, void *data, size_t *size) {
-       readme *rm = data;
--      
-+
-       UNUSED(L);
--      
-+
-       if (rm->done) return 0;
--      
-+
-       *size = rm->st.size;
-       rm->done = 1;
-       return rm->st.start;
-@@ -51,47 +52,47 @@
- static int lua_to_c_get_string(lua_State *L, const char *varname, buffer *b) {
-       int curelem;
--      
-+
-       lua_pushstring(L, varname);
--      
-+
-       curelem = lua_gettop(L);
-       lua_gettable(L, LUA_GLOBALSINDEX);
--      
-+
-       /* it should be a table */
-       if (!lua_isstring(L, curelem)) {
-               lua_settop(L, curelem - 1);
--              
-+
-               return -1;
-       }
--      
-+
-       buffer_copy_string(b, lua_tostring(L, curelem));
--      
-+
-       lua_pop(L, 1);
--      
-+
-       assert(curelem - 1 == lua_gettop(L));
--      
-+
-       return 0;
- }
- static int lua_to_c_is_table(lua_State *L, const char *varname) {
-       int curelem;
--      
-+
-       lua_pushstring(L, varname);
--      
-+
-       curelem = lua_gettop(L);
-       lua_gettable(L, LUA_GLOBALSINDEX);
--      
-+
-       /* it should be a table */
-       if (!lua_istable(L, curelem)) {
-               lua_settop(L, curelem - 1);
--              
-+
-               return 0;
-       }
--      
-+
-       lua_settop(L, curelem - 1);
--      
-+
-       assert(curelem - 1 == lua_gettop(L));
--      
-+
-       return 1;
- }
-@@ -99,7 +100,7 @@
-       lua_pushlstring(L, key, key_len);
-       lua_pushlstring(L, val, val_len);
-       lua_settable(L, tbl);
--      
-+
-       return 0;
- }
-@@ -108,21 +109,21 @@
-       size_t is_key = 1;
-       size_t i;
-       char *key = NULL, *val = NULL;
--      
-+
-       key = qrystr->ptr;
--      
-+
-       /* we need the \0 */
-       for (i = 0; i < qrystr->used; i++) {
-               switch(qrystr->ptr[i]) {
-               case '=':
-                       if (is_key) {
-                               val = qrystr->ptr + i + 1;
--                              
-+
-                               qrystr->ptr[i] = '\0';
--                              
-+
-                               is_key = 0;
-                       }
--                      
-+
-                       break;
-               case '&':
-               case '\0': /* fin symbol */
-@@ -131,19 +132,19 @@
-                               /* terminate the value */
-                               qrystr->ptr[i] = '\0';
--                              
--                              c_to_lua_push(L, tbl, 
-+
-+                              c_to_lua_push(L, tbl,
-                                             key, strlen(key),
-                                             val, strlen(val));
-                       }
--                      
-+
-                       key = qrystr->ptr + i + 1;
-                       val = NULL;
-                       is_key = 1;
-                       break;
-               }
-       }
--      
-+
-       return 0;
- }
- #if 0
-@@ -151,21 +152,21 @@
-       data_unset *d;
-       UNUSED(srv);
--      
-+
-       if (NULL != (d = array_get_element(con->request.headers, "Cookie"))) {
-               data_string *ds = (data_string *)d;
-               size_t key = 0, value = 0;
-               size_t is_key = 1, is_sid = 0;
-               size_t i;
--              
-+
-               /* found COOKIE */
-               if (!DATA_IS_STRING(d)) return -1;
-               if (ds->value->used == 0) return -1;
--                      
-+
-               if (ds->value->ptr[0] == '\0' ||
-                   ds->value->ptr[0] == '=' ||
-                   ds->value->ptr[0] == ';') return -1;
--              
-+
-               buffer_reset(p->session_id);
-               for (i = 0; i < ds->value->used; i++) {
-                       switch(ds->value->ptr[i]) {
-@@ -176,16 +177,16 @@
-                                               is_sid = 1;
-                                       }
-                                       value = i + 1;
--                              
-+
-                                       is_key = 0;
-                               }
--                              
-+
-                               break;
-                       case ';':
-                               if (is_sid) {
-                                       buffer_copy_string_len(p->session_id, ds->value->ptr + value, i - value);
-                               }
--                              
-+
-                               is_sid = 0;
-                               key = i + 1;
-                               value = 0;
-@@ -204,48 +205,43 @@
-                       }
-               }
-       }
--      
-+
-       return 0;
- }
- #endif
- int cache_parse_lua(server *srv, connection *con, plugin_data *p, buffer *fn) {
--      lua_State *L; 
-+      lua_State *L;
-       readme rm;
-       int ret = -1;
-       buffer *b = buffer_init();
-       int header_tbl = 0;
--      
-+
-       rm.done = 0;
-       stream_open(&rm.st, fn);
--      
-+
-       /* push the lua file to the interpreter and see what happends */
--      L = lua_open();
--      
--      luaopen_base(L);
--      luaopen_table(L);
--      luaopen_string(L);
--      luaopen_math(L);
--      luaopen_io(L);
--      
-+      L = luaL_newstate();
-+      luaL_openlibs(L);
-+
-       /* register functions */
-       lua_register(L, "md5", f_crypto_md5);
-       lua_register(L, "file_mtime", f_file_mtime);
-       lua_register(L, "file_isreg", f_file_isreg);
-       lua_register(L, "file_isdir", f_file_isreg);
-       lua_register(L, "dir_files", f_dir_files);
--      
-+
- #ifdef HAVE_MEMCACHE_H
-       lua_pushliteral(L, "memcache_get_long");
-       lua_pushlightuserdata(L, p->conf.mc);
-       lua_pushcclosure(L, f_memcache_get_long, 1);
-       lua_settable(L, LUA_GLOBALSINDEX);
--      
-+
-       lua_pushliteral(L, "memcache_get_string");
-       lua_pushlightuserdata(L, p->conf.mc);
-       lua_pushcclosure(L, f_memcache_get_string, 1);
-       lua_settable(L, LUA_GLOBALSINDEX);
--      
-+
-       lua_pushliteral(L, "memcache_exists");
-       lua_pushlightuserdata(L, p->conf.mc);
-       lua_pushcclosure(L, f_memcache_exists, 1);
-@@ -255,11 +251,11 @@
-       lua_pushliteral(L, "request");
-       lua_newtable(L);
-       lua_settable(L, LUA_GLOBALSINDEX);
--      
-+
-       lua_pushliteral(L, "request");
-       header_tbl = lua_gettop(L);
-       lua_gettable(L, LUA_GLOBALSINDEX);
--      
-+
-       c_to_lua_push(L, header_tbl, CONST_STR_LEN("REQUEST_URI"), CONST_BUF_LEN(con->request.orig_uri));
-       c_to_lua_push(L, header_tbl, CONST_STR_LEN("SCRIPT_NAME"), CONST_BUF_LEN(con->uri.path));
-       c_to_lua_push(L, header_tbl, CONST_STR_LEN("SCRIPT_FILENAME"), CONST_BUF_LEN(con->physical.path));
-@@ -267,84 +263,84 @@
-       if (!buffer_is_empty(con->request.pathinfo)) {
-               c_to_lua_push(L, header_tbl, CONST_STR_LEN("PATH_INFO"), CONST_BUF_LEN(con->request.pathinfo));
-       }
--      
-+
-       c_to_lua_push(L, header_tbl, CONST_STR_LEN("CWD"), CONST_BUF_LEN(p->basedir));
-       c_to_lua_push(L, header_tbl, CONST_STR_LEN("BASEURL"), CONST_BUF_LEN(p->baseurl));
--      
-+
-       /* register GET parameter */
-       lua_pushliteral(L, "get");
-       lua_newtable(L);
-       lua_settable(L, LUA_GLOBALSINDEX);
--      
-+
-       lua_pushliteral(L, "get");
-       header_tbl = lua_gettop(L);
-       lua_gettable(L, LUA_GLOBALSINDEX);
--      
-+
-       buffer_copy_string_buffer(b, con->uri.query);
-       cache_export_get_params(L, header_tbl, b);
-       buffer_reset(b);
--      /* 2 default constants */       
-+      /* 2 default constants */
-       lua_pushliteral(L, "CACHE_HIT");
-       lua_pushboolean(L, 0);
-       lua_settable(L, LUA_GLOBALSINDEX);
--      
-+
-       lua_pushliteral(L, "CACHE_MISS");
-       lua_pushboolean(L, 1);
-       lua_settable(L, LUA_GLOBALSINDEX);
--      
-+
-       /* load lua program */
-       if (lua_load(L, load_file, &rm, fn->ptr) || lua_pcall(L,0,1,0)) {
-               log_error_write(srv, __FILE__, __LINE__, "s",
-                               lua_tostring(L,-1));
--              
-+
-               goto error;
-       }
--      
-+
-       /* get return value */
-       ret = (int)lua_tonumber(L, -1);
-       lua_pop(L, 1);
--      
--      /* fetch the data from lua */ 
-+
-+      /* fetch the data from lua */
-       lua_to_c_get_string(L, "trigger_handler", p->trigger_handler);
--      
-+
-       if (0 == lua_to_c_get_string(L, "output_contenttype", b)) {
-               response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(b));
-       }
--      
-+
-       if (ret == 0) {
-               /* up to now it is a cache-hit, check if all files exist */
--              
-+
-               int curelem;
-               time_t mtime = 0;
--      
-+
-               if (!lua_to_c_is_table(L, "output_include")) {
-                       log_error_write(srv, __FILE__, __LINE__, "s",
-                               "output_include is missing or not a table");
-                       ret = -1;
--              
-+
-                       goto error;
-               }
--              
-+
-               lua_pushstring(L, "output_include");
--              
-+
-               curelem = lua_gettop(L);
-               lua_gettable(L, LUA_GLOBALSINDEX);
-               /* HOW-TO build a etag ?
--               * as we don't just have one file we have to take the stat() 
-+               * as we don't just have one file we have to take the stat()
-                * from all base files, merge them and build the etag from
-                * it later.
--               * 
-+               *
-                * The mtime of the content is the mtime of the freshest base file
--               * 
-+               *
-                * */
--              
-+
-               lua_pushnil(L);  /* first key */
-               while (lua_next(L, curelem) != 0) {
-                       stat_cache_entry *sce = NULL;
-                       /* key' is at index -2 and value' at index -1 */
--                      
-+
-                       if (lua_isstring(L, -1)) {
-                               const char *s = lua_tostring(L, -1);
-@@ -364,18 +360,18 @@
-                                               /* a file is missing, call the handler to generate it */
-                                               if (!buffer_is_empty(p->trigger_handler)) {
-                                                       ret = 1; /* cache-miss */
--                                                      
-+
-                                                       log_error_write(srv, __FILE__, __LINE__, "s",
-                                                                       "a file is missing, calling handler");
--                                                      
-+
-                                                       break;
-                                               } else {
-                                                       /* handler not set -> 500 */
-                                                       ret = -1;
--                                                      
-+
-                                                       log_error_write(srv, __FILE__, __LINE__, "s",
-                                                                       "a file missing and no handler set");
--                                                      
-+
-                                                       break;
-                                               }
-                                               break;
-@@ -383,7 +379,7 @@
-                                               break;
-                                       }
-                               } else {
--                                      chunkqueue_append_file(con->write_queue, b, 0, sce->st.st_size);
-+                                      chunkqueue_append_file(con->send, b, 0, sce->st.st_size);
-                                       if (sce->st.st_mtime > mtime) mtime = sce->st.st_mtime;
-                               }
-                       } else {
-@@ -393,26 +389,26 @@
-                                               "not a string");
-                               break;
-                       }
--              
-+
-                       lua_pop(L, 1);  /* removes value'; keeps key' for next iteration */
-               }
--              
-+
-               lua_settop(L, curelem - 1);
--              
-+
-               if (ret == 0) {
-                       data_string *ds;
-                       char timebuf[sizeof("Sat, 23 Jul 2005 21:20:01 GMT")];
-                       buffer tbuf;
--                      con->file_finished = 1;
-+                      con->send->is_closed = 1;
-                       ds = (data_string *)array_get_element(con->response.headers, "Last-Modified");
-                       /* no Last-Modified specified */
-                       if ((mtime) && (NULL == ds)) {
--              
-+
-                               strftime(timebuf, sizeof(timebuf), "%a, %d %b %Y %H:%M:%S GMT", gmtime(&mtime));
--                              
-+
-                               response_header_overwrite(srv, con, CONST_STR_LEN("Last-Modified"), timebuf, sizeof(timebuf) - 1);
-@@ -428,36 +424,36 @@
-                               tbuf.used = 0;
-                               tbuf.ptr = NULL;
-                       }
--                      
-+
-                       if (HANDLER_FINISHED == http_response_handle_cachable(srv, con, &tbuf)) {
--                              /* ok, the client already has our content, 
-+                              /* ok, the client already has our content,
-                                * no need to send it again */
--                              chunkqueue_reset(con->write_queue);
-+                              chunkqueue_reset(con->send);
-                               ret = 0; /* cache-hit */
-                       }
-               } else {
--                      chunkqueue_reset(con->write_queue);
-+                      chunkqueue_reset(con->send);
-               }
-       }
--      
-+
-       if (ret == 1 && !buffer_is_empty(p->trigger_handler)) {
-               /* cache-miss */
-               buffer_copy_string_buffer(con->uri.path, p->baseurl);
-               buffer_append_string_buffer(con->uri.path, p->trigger_handler);
--      
-+
-               buffer_copy_string_buffer(con->physical.path, p->basedir);
-               buffer_append_string_buffer(con->physical.path, p->trigger_handler);
--              
--              chunkqueue_reset(con->write_queue);
-+
-+              chunkqueue_reset(con->send);
-       }
--      
-+
- error:
-       lua_close(L);
--      
-+
-       stream_close(&rm.st);
-       buffer_free(b);
--      
-+
-       return ret /* cache-error */;
- }
- #else
---- ../lighttpd-1.4.11/src/mod_compress.c      2005-11-18 13:49:14.000000000 +0200
-+++ lighttpd-1.5.0/src/mod_compress.c  2006-09-07 00:57:05.000000000 +0300
-@@ -2,7 +2,6 @@
- #include <sys/stat.h>
- #include <fcntl.h>
--#include <unistd.h>
- #include <ctype.h>
- #include <stdlib.h>
- #include <string.h>
-@@ -33,6 +32,7 @@
- #endif
- #include "sys-mmap.h"
-+#include "sys-files.h"
- /* request: accept-encoding */
- #define HTTP_ACCEPT_ENCODING_IDENTITY BV(0)
-@@ -55,97 +55,127 @@
-       PLUGIN_DATA;
-       buffer *ofn;
-       buffer *b;
--      
-+
-       plugin_config **config_storage;
--      plugin_config conf; 
-+      plugin_config conf;
- } plugin_data;
- INIT_FUNC(mod_compress_init) {
-       plugin_data *p;
--      
-+
-       p = calloc(1, sizeof(*p));
--      
-+
-       p->ofn = buffer_init();
-       p->b = buffer_init();
--      
-+
-       return p;
- }
- FREE_FUNC(mod_compress_free) {
-       plugin_data *p = p_d;
--      
-+
-       UNUSED(srv);
-       if (!p) return HANDLER_GO_ON;
--      
-+
-       buffer_free(p->ofn);
-       buffer_free(p->b);
--      
-+
-       if (p->config_storage) {
-               size_t i;
-               for (i = 0; i < srv->config_context->used; i++) {
-                       plugin_config *s = p->config_storage[i];
-                       if (!s) continue;
--                      
-+
-                       array_free(s->compress);
-                       buffer_free(s->compress_cache_dir);
--                      
-+
-                       free(s);
-               }
-               free(p->config_storage);
-       }
--      
--      
-+
-+
-       free(p);
--      
-+
-       return HANDLER_GO_ON;
- }
-+void mkdir_recursive(const char *dir) {
-+
-+      char dir_copy[256];
-+      char *p = dir_copy;
-+
-+      if (!dir || !dir[0])
-+              return;
-+
-+      strncpy(dir_copy, dir, sizeof(dir_copy) / sizeof(dir_copy[0]));
-+
-+      while ((p = strchr(p + 1, '/')) != NULL) {
-+
-+              *p = '\0';
-+              if ((mkdir(dir_copy, 0700) != 0) && (errno != EEXIST))
-+                      return;
-+
-+              *p++ = '/';
-+      }
-+
-+      mkdir(dir, 0700);
-+}
-+
- SETDEFAULTS_FUNC(mod_compress_setdefaults) {
-       plugin_data *p = p_d;
-       size_t i = 0;
--      
--      config_values_t cv[] = { 
-+
-+      config_values_t cv[] = {
-               { "compress.cache-dir",             NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
-               { "compress.filetype",              NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },
-               { "compress.max-filesize",          NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },
-               { NULL,                             NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
-       };
--      
-+
-       p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
--      
-+
-       for (i = 0; i < srv->config_context->used; i++) {
-               plugin_config *s;
--              
-+
-               s = calloc(1, sizeof(plugin_config));
-               s->compress_cache_dir = buffer_init();
-               s->compress = array_init();
-               s->compress_max_filesize = 0;
--              
-+
-               cv[0].destination = s->compress_cache_dir;
-               cv[1].destination = s->compress;
-               cv[2].destination = &(s->compress_max_filesize);
--              
-+
-               p->config_storage[i] = s;
--      
-+
-               if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
-                       return HANDLER_ERROR;
-               }
--              
-+
-               if (!buffer_is_empty(s->compress_cache_dir)) {
-                       struct stat st;
-                       if (0 != stat(s->compress_cache_dir->ptr, &st)) {
--                              log_error_write(srv, __FILE__, __LINE__, "sbs", "can't stat compress.cache-dir", 
-+
-+                              log_error_write(srv, __FILE__, __LINE__, "sbs", "can't stat compress.cache-dir, attempting to create",
-                                               s->compress_cache_dir, strerror(errno));
--                              
--                              return HANDLER_ERROR;
-+                              mkdir_recursive(s->compress_cache_dir->ptr);
-+
-+                              if (0 != stat(s->compress_cache_dir->ptr, &st)) {
-+
-+                                      log_error_write(srv, __FILE__, __LINE__, "sbs", "can't stat compress.cache-dir, create failed",
-+                                                                      s->compress_cache_dir, strerror(errno));
-+
-+                                      return HANDLER_ERROR;
-+                              }
-                       }
-               }
-       }
--      
-+
-       return HANDLER_GO_ON;
--      
-+
- }
- #ifdef USE_ZLIB
-@@ -153,32 +183,32 @@
-       unsigned char *c;
-       unsigned long crc;
-       z_stream z;
--      
-+
-       UNUSED(srv);
-       UNUSED(con);
-       z.zalloc = Z_NULL;
-       z.zfree = Z_NULL;
-       z.opaque = Z_NULL;
--      
--      if (Z_OK != deflateInit2(&z, 
-+
-+      if (Z_OK != deflateInit2(&z,
-                                Z_DEFAULT_COMPRESSION,
--                               Z_DEFLATED, 
-+                               Z_DEFLATED,
-                                -MAX_WBITS,  /* supress zlib-header */
-                                8,
-                                Z_DEFAULT_STRATEGY)) {
-               return -1;
-       }
--              
-+
-       z.next_in = (unsigned char *)start;
-       z.avail_in = st_size;
-       z.total_in = 0;
--              
--                      
-+
-+
-       buffer_prepare_copy(p->b, (z.avail_in * 1.1) + 12 + 18);
--              
-+
-       /* write gzip header */
--              
-+
-       c = (unsigned char *)p->b->ptr;
-       c[0] = 0x1f;
-       c[1] = 0x8b;
-@@ -190,24 +220,24 @@
-       c[7] = (mtime >> 24) & 0xff;
-       c[8] = 0x00; /* extra flags */
-       c[9] = 0x03; /* UNIX */
--      
-+
-       p->b->used = 10;
-       z.next_out = (unsigned char *)p->b->ptr + p->b->used;
-       z.avail_out = p->b->size - p->b->used - 8;
-       z.total_out = 0;
--      
-+
-       if (Z_STREAM_END != deflate(&z, Z_FINISH)) {
-               deflateEnd(&z);
-               return -1;
-       }
--      
-+
-       /* trailer */
-       p->b->used += z.total_out;
--      
-+
-       crc = generate_crc32c(start, st_size);
--              
-+
-       c = (unsigned char *)p->b->ptr + p->b->used;
--              
-+
-       c[0] = (crc >>  0) & 0xff;
-       c[1] = (crc >>  8) & 0xff;
-       c[2] = (crc >> 16) & 0xff;
-@@ -221,51 +251,51 @@
-       if (Z_OK != deflateEnd(&z)) {
-               return -1;
-       }
--      
-+
-       return 0;
- }
- static int deflate_file_to_buffer_deflate(server *srv, connection *con, plugin_data *p, unsigned char *start, off_t st_size) {
-       z_stream z;
--      
-+
-       UNUSED(srv);
-       UNUSED(con);
-       z.zalloc = Z_NULL;
-       z.zfree = Z_NULL;
-       z.opaque = Z_NULL;
--      
--      if (Z_OK != deflateInit2(&z, 
-+
-+      if (Z_OK != deflateInit2(&z,
-                                Z_DEFAULT_COMPRESSION,
--                               Z_DEFLATED, 
-+                               Z_DEFLATED,
-                                -MAX_WBITS,  /* supress zlib-header */
-                                8,
-                                Z_DEFAULT_STRATEGY)) {
-               return -1;
-       }
--              
-+
-       z.next_in = start;
-       z.avail_in = st_size;
-       z.total_in = 0;
--              
-+
-       buffer_prepare_copy(p->b, (z.avail_in * 1.1) + 12);
--      
-+
-       z.next_out = (unsigned char *)p->b->ptr;
-       z.avail_out = p->b->size;
-       z.total_out = 0;
--      
-+
-       if (Z_STREAM_END != deflate(&z, Z_FINISH)) {
-               deflateEnd(&z);
-               return -1;
-       }
--      
-+
-       /* trailer */
-       p->b->used += z.total_out;
--      
-+
-       if (Z_OK != deflateEnd(&z)) {
-               return -1;
-       }
--      
-+
-       return 0;
- }
-@@ -274,48 +304,48 @@
- #ifdef USE_BZ2LIB
- static int deflate_file_to_buffer_bzip2(server *srv, connection *con, plugin_data *p, unsigned char *start, off_t st_size) {
-       bz_stream bz;
--      
-+
-       UNUSED(srv);
-       UNUSED(con);
-       bz.bzalloc = NULL;
-       bz.bzfree = NULL;
-       bz.opaque = NULL;
--      
--      if (BZ_OK != BZ2_bzCompressInit(&bz, 
-+
-+      if (BZ_OK != BZ2_bzCompressInit(&bz,
-                                       9, /* blocksize = 900k */
-                                       0, /* no output */
-                                       0)) { /* workFactor: default */
-               return -1;
-       }
--              
-+
-       bz.next_in = (char *)start;
-       bz.avail_in = st_size;
-       bz.total_in_lo32 = 0;
-       bz.total_in_hi32 = 0;
--              
-+
-       buffer_prepare_copy(p->b, (bz.avail_in * 1.1) + 12);
--      
-+
-       bz.next_out = p->b->ptr;
-       bz.avail_out = p->b->size;
-       bz.total_out_lo32 = 0;
-       bz.total_out_hi32 = 0;
--      
-+
-       if (BZ_STREAM_END != BZ2_bzCompress(&bz, BZ_FINISH)) {
-               BZ2_bzCompressEnd(&bz);
-               return -1;
-       }
--      
-+
-       /* file is too large for now */
-       if (bz.total_out_hi32) return -1;
--      
-+
-       /* trailer */
-       p->b->used = bz.total_out_lo32;
--      
-+
-       if (BZ_OK != BZ2_bzCompressEnd(&bz)) {
-               return -1;
-       }
--      
-+
-       return 0;
- }
- #endif
-@@ -326,47 +356,50 @@
-       void *start;
-       const char *filename = fn->ptr;
-       ssize_t r;
--      
-+      stat_cache_entry *compressed_sce = NULL;
-+
-+      if (buffer_is_empty(p->conf.compress_cache_dir)) return -1;
-+
-       /* overflow */
-       if ((off_t)(sce->st.st_size * 1.1) < sce->st.st_size) return -1;
--      
--      /* don't mmap files > 128Mb 
--       * 
-+
-+      /* don't mmap files > 128Mb
-+       *
-        * we could use a sliding window, but currently there is no need for it
-        */
--      
-+
-       if (sce->st.st_size > 128 * 1024 * 1024) return -1;
--      
-+
-       buffer_reset(p->ofn);
-       buffer_copy_string_buffer(p->ofn, p->conf.compress_cache_dir);
--      BUFFER_APPEND_SLASH(p->ofn);
--      
-+      PATHNAME_APPEND_SLASH(p->ofn);
-+
-       if (0 == strncmp(con->physical.path->ptr, con->physical.doc_root->ptr, con->physical.doc_root->used-1)) {
-               size_t offset = p->ofn->used - 1;
-               char *dir, *nextdir;
--              
-+
-               buffer_append_string(p->ofn, con->physical.path->ptr + con->physical.doc_root->used - 1);
--              
-+
-               buffer_copy_string_buffer(p->b, p->ofn);
--              
-+
-               /* mkdir -p ... */
-               for (dir = p->b->ptr + offset; NULL != (nextdir = strchr(dir, '/')); dir = nextdir + 1) {
-                       *nextdir = '\0';
--                      
-+
-                       if (-1 == mkdir(p->b->ptr, 0700)) {
-                               if (errno != EEXIST) {
-                                       log_error_write(srv, __FILE__, __LINE__, "sbss", "creating cache-directory", p->b, "failed", strerror(errno));
--                                      
-+
-                                       return -1;
-                               }
-                       }
--                      
-+
-                       *nextdir = '/';
-               }
-       } else {
-               buffer_append_string_buffer(p->ofn, con->uri.path);
-       }
--      
-+
-       switch(type) {
-       case HTTP_ACCEPT_ENCODING_GZIP:
-               buffer_append_string(p->ofn, "-gzip-");
-@@ -381,55 +414,64 @@
-               log_error_write(srv, __FILE__, __LINE__, "sd", "unknown compression type", type);
-               return -1;
-       }
--      
-+
-       buffer_append_string_buffer(p->ofn, sce->etag);
--      
-+
-+
-+      if (HANDLER_ERROR != stat_cache_get_entry(srv, con, p->ofn, &compressed_sce)) {
-+              /* file exists */
-+
-+              chunkqueue_append_file(con->send_raw, p->ofn, 0, compressed_sce->st.st_size);
-+              con->send->is_closed = 1;
-+
-+              return 0;
-+      }
-+
-       if (-1 == (ofd = open(p->ofn->ptr, O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0600))) {
-               if (errno == EEXIST) {
-                       /* cache-entry exists */
--#if 0
--                      log_error_write(srv, __FILE__, __LINE__, "bs", p->ofn, "compress-cache hit");
--#endif
--                      buffer_copy_string_buffer(con->physical.path, p->ofn);
--                      
--                      return 0;
-+
-               }
--              
--              log_error_write(srv, __FILE__, __LINE__, "sbss", "creating cachefile", p->ofn, "failed", strerror(errno));
--              
-+
-+              log_error_write(srv, __FILE__, __LINE__, "sbss",
-+                              "creating cachefile", p->ofn,
-+                              "failed", strerror(errno));
-+
-               return -1;
-       }
--#if 0
--      log_error_write(srv, __FILE__, __LINE__, "bs", p->ofn, "compress-cache miss");
--#endif        
-+
-       if (-1 == (ifd = open(filename, O_RDONLY | O_BINARY))) {
--              log_error_write(srv, __FILE__, __LINE__, "sbss", "opening plain-file", fn, "failed", strerror(errno));
--              
-+              log_error_write(srv, __FILE__, __LINE__, "sbss",
-+                              "opening plain-file", fn,
-+                              "failed", strerror(errno));
-+
-               close(ofd);
--              
-+
-               return -1;
-       }
--      
--      
-+
-+
-       if (MAP_FAILED == (start = mmap(NULL, sce->st.st_size, PROT_READ, MAP_SHARED, ifd, 0))) {
--              log_error_write(srv, __FILE__, __LINE__, "sbss", "mmaping", fn, "failed", strerror(errno));
--              
-+              log_error_write(srv, __FILE__, __LINE__, "sbss",
-+                              "mmaping", fn,
-+                              "failed", strerror(errno));
-+
-               close(ofd);
-               close(ifd);
-               return -1;
-       }
--      
-+
-       switch(type) {
- #ifdef USE_ZLIB
--      case HTTP_ACCEPT_ENCODING_GZIP: 
-+      case HTTP_ACCEPT_ENCODING_GZIP:
-               ret = deflate_file_to_buffer_gzip(srv, con, p, start, sce->st.st_size, sce->st.st_mtime);
-               break;
--      case HTTP_ACCEPT_ENCODING_DEFLATE: 
-+      case HTTP_ACCEPT_ENCODING_DEFLATE:
-               ret = deflate_file_to_buffer_deflate(srv, con, p, start, sce->st.st_size);
-               break;
- #endif
- #ifdef USE_BZ2LIB
--      case HTTP_ACCEPT_ENCODING_BZIP2: 
-+      case HTTP_ACCEPT_ENCODING_BZIP2:
-               ret = deflate_file_to_buffer_bzip2(srv, con, p, start, sce->st.st_size);
-               break;
- #endif
-@@ -437,26 +479,27 @@
-               ret = -1;
-               break;
-       }
--      
-+
-       if (-1 == (r = write(ofd, p->b->ptr, p->b->used))) {
--              munmap(start, sce->st.st_size); 
-+              munmap(start, sce->st.st_size);
-               close(ofd);
-               close(ifd);
-               return -1;
-       }
--      
-+
-       if ((size_t)r != p->b->used) {
--              
-+
-       }
--              
-+
-       munmap(start, sce->st.st_size);
-       close(ofd);
-       close(ifd);
--      
-+
-       if (ret != 0) return -1;
--      
--      buffer_copy_string_buffer(con->physical.path, p->ofn);
--      
-+
-+      chunkqueue_append_file(con->send_raw, p->ofn, 0, r);
-+      con->send->is_closed = 1;
-+
-       return 0;
- }
-@@ -465,43 +508,44 @@
-       int ret = -1;
-       void *start;
-       buffer *b;
--      
-+
-       /* overflow */
-       if ((off_t)(sce->st.st_size * 1.1) < sce->st.st_size) return -1;
--      
-+
-       /* don't mmap files > 128M
--       * 
-+       *
-        * we could use a sliding window, but currently there is no need for it
-        */
--      
-+
-       if (sce->st.st_size > 128 * 1024 * 1024) return -1;
--      
--      
-+
-       if (-1 == (ifd = open(fn->ptr, O_RDONLY | O_BINARY))) {
-               log_error_write(srv, __FILE__, __LINE__, "sbss", "opening plain-file", fn, "failed", strerror(errno));
--              
-+
-               return -1;
-       }
--      
--      
--      if (MAP_FAILED == (start = mmap(NULL, sce->st.st_size, PROT_READ, MAP_SHARED, ifd, 0))) {
-+
-+      start = mmap(NULL, sce->st.st_size, PROT_READ, MAP_SHARED, ifd, 0);
-+
-+      close(ifd);
-+
-+      if (MAP_FAILED == start) {
-               log_error_write(srv, __FILE__, __LINE__, "sbss", "mmaping", fn, "failed", strerror(errno));
--              
--              close(ifd);
-+
-               return -1;
-       }
--      
-+
-       switch(type) {
- #ifdef USE_ZLIB
--      case HTTP_ACCEPT_ENCODING_GZIP: 
-+      case HTTP_ACCEPT_ENCODING_GZIP:
-               ret = deflate_file_to_buffer_gzip(srv, con, p, start, sce->st.st_size, sce->st.st_mtime);
-               break;
--      case HTTP_ACCEPT_ENCODING_DEFLATE: 
-+      case HTTP_ACCEPT_ENCODING_DEFLATE:
-               ret = deflate_file_to_buffer_deflate(srv, con, p, start, sce->st.st_size);
-               break;
- #endif
- #ifdef USE_BZ2LIB
--      case HTTP_ACCEPT_ENCODING_BZIP2: 
-+      case HTTP_ACCEPT_ENCODING_BZIP2:
-               ret = deflate_file_to_buffer_bzip2(srv, con, p, start, sce->st.st_size);
-               break;
- #endif
-@@ -509,69 +553,64 @@
-               ret = -1;
-               break;
-       }
--              
-+
-       munmap(start, sce->st.st_size);
--      close(ifd);
--      
-+
-       if (ret != 0) return -1;
--      
--      chunkqueue_reset(con->write_queue);
--      b = chunkqueue_get_append_buffer(con->write_queue);
-+
-+      chunkqueue_reset(con->send);
-+      b = chunkqueue_get_append_buffer(con->send);
-       buffer_copy_memory(b, p->b->ptr, p->b->used + 1);
--      
-+
-       buffer_reset(con->physical.path);
--      
--      con->file_finished = 1;
-+
-+      con->send->is_closed = 1;
-       con->file_started  = 1;
--      
-+
-       return 0;
- }
--
--#define PATCH(x) \
--      p->conf.x = s->x;
- static int mod_compress_patch_connection(server *srv, connection *con, plugin_data *p) {
-       size_t i, j;
-       plugin_config *s = p->config_storage[0];
--      PATCH(compress_cache_dir);
--      PATCH(compress);
--      PATCH(compress_max_filesize);
--      
-+      PATCH_OPTION(compress_cache_dir);
-+      PATCH_OPTION(compress);
-+      PATCH_OPTION(compress_max_filesize);
-+
-       /* skip the first, the global context */
-       for (i = 1; i < srv->config_context->used; i++) {
-               data_config *dc = (data_config *)srv->config_context->data[i];
-               s = p->config_storage[i];
--              
-+
-               /* condition didn't match */
-               if (!config_check_cond(srv, con, dc)) continue;
--              
-+
-               /* merge config */
-               for (j = 0; j < dc->value->used; j++) {
-                       data_unset *du = dc->value->data[j];
--                      
-+
-                       if (buffer_is_equal_string(du->key, CONST_STR_LEN("compress.cache-dir"))) {
--                              PATCH(compress_cache_dir);
-+                              PATCH_OPTION(compress_cache_dir);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("compress.filetype"))) {
--                              PATCH(compress);
-+                              PATCH_OPTION(compress);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("compress.max-filesize"))) {
--                              PATCH(compress_max_filesize);
-+                              PATCH_OPTION(compress_max_filesize);
-                       }
-               }
-       }
--      
-+
-       return 0;
- }
--#undef PATCH
- PHYSICALPATH_FUNC(mod_compress_physical) {
-       plugin_data *p = p_d;
-       size_t m;
-       off_t max_fsize;
-       stat_cache_entry *sce = NULL;
--      
-+
-       /* only GET and POST can get compressed */
--      if (con->request.http_method != HTTP_METHOD_GET && 
-+      if (con->request.http_method != HTTP_METHOD_GET &&
-           con->request.http_method != HTTP_METHOD_POST) {
-               return HANDLER_GO_ON;
-       }
-@@ -579,46 +618,49 @@
-       if (buffer_is_empty(con->physical.path)) {
-               return HANDLER_GO_ON;
-       }
--      
-+
-       mod_compress_patch_connection(srv, con, p);
--      
-+
-       max_fsize = p->conf.compress_max_filesize;
-       stat_cache_get_entry(srv, con, con->physical.path, &sce);
-       /* don't compress files that are too large as we need to much time to handle them */
-       if (max_fsize && (sce->st.st_size >> 10) > max_fsize) return HANDLER_GO_ON;
--              
-+
-+      /* compressing the file might lead to larger files instead */
-+      if (sce->st.st_size < 128) return HANDLER_GO_ON;
-+
-       /* check if mimetype is in compress-config */
-       for (m = 0; m < p->conf.compress->used; m++) {
-               data_string *compress_ds = (data_string *)p->conf.compress->data[m];
--                      
-+
-               if (!compress_ds) {
-                       log_error_write(srv, __FILE__, __LINE__, "sbb", "evil", con->physical.path, con->uri.path);
--                      
-+
-                       return HANDLER_GO_ON;
-               }
--              
-+
-               if (buffer_is_equal(compress_ds->value, sce->content_type)) {
-                       /* mimetype found */
-                       data_string *ds;
--                              
-+
-                       /* the response might change according to Accept-Encoding */
-                       response_header_insert(srv, con, CONST_STR_LEN("Vary"), CONST_STR_LEN("Accept-Encoding"));
--                              
-+
-                       if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Accept-Encoding"))) {
-                               int accept_encoding = 0;
-                               char *value = ds->value->ptr;
-                               int srv_encodings = 0;
-                               int matched_encodings = 0;
--                              
-+
-                               /* get client side support encodings */
-                               if (NULL != strstr(value, "gzip")) accept_encoding |= HTTP_ACCEPT_ENCODING_GZIP;
-                               if (NULL != strstr(value, "deflate")) accept_encoding |= HTTP_ACCEPT_ENCODING_DEFLATE;
-                               if (NULL != strstr(value, "compress")) accept_encoding |= HTTP_ACCEPT_ENCODING_COMPRESS;
-                               if (NULL != strstr(value, "bzip2")) accept_encoding |= HTTP_ACCEPT_ENCODING_BZIP2;
-                               if (NULL != strstr(value, "identity")) accept_encoding |= HTTP_ACCEPT_ENCODING_IDENTITY;
--                              
-+
-                               /* get server side supported ones */
- #ifdef USE_BZ2LIB
-                               srv_encodings |= HTTP_ACCEPT_ENCODING_BZIP2;
-@@ -627,18 +669,31 @@
-                               srv_encodings |= HTTP_ACCEPT_ENCODING_GZIP;
-                               srv_encodings |= HTTP_ACCEPT_ENCODING_DEFLATE;
- #endif
--                              
-+
-                               /* find matching entries */
-                               matched_encodings = accept_encoding & srv_encodings;
--                              
-+
-                               if (matched_encodings) {
-                                       const char *dflt_gzip = "gzip";
-                                       const char *dflt_deflate = "deflate";
-                                       const char *dflt_bzip2 = "bzip2";
--                                      
-+
-                                       const char *compression_name = NULL;
-                                       int compression_type = 0;
--                                      
-+                                      buffer *mtime;
-+
-+                                      mtime = strftime_cache_get(srv, sce->st.st_mtime);
-+                                      etag_mutate(con->physical.etag, sce->etag);
-+
-+                                      response_header_overwrite(srv, con, CONST_STR_LEN("Last-Modified"), CONST_BUF_LEN(mtime));
-+                                      response_header_overwrite(srv, con, CONST_STR_LEN("ETag"), CONST_BUF_LEN(con->physical.etag));
-+
-+                                      /* perhaps we don't even have to compress the file as the browser still has the
-+                                       * current version */
-+                                      if (HANDLER_FINISHED == http_response_handle_cachable(srv, con, mtime)) {
-+                                              return HANDLER_FINISHED;
-+                                      }
-+
-                                       /* select best matching encoding */
-                                       if (matched_encodings & HTTP_ACCEPT_ENCODING_BZIP2) {
-                                               compression_type = HTTP_ACCEPT_ENCODING_BZIP2;
-@@ -650,31 +705,21 @@
-                                               compression_type = HTTP_ACCEPT_ENCODING_DEFLATE;
-                                               compression_name = dflt_deflate;
-                                       }
--                                      
--                                      /* deflate it */
--                                      if (p->conf.compress_cache_dir->used) {
--                                              if (0 == deflate_file_to_file(srv, con, p,
--                                                                            con->physical.path, sce, compression_type)) {
--                                                      buffer *mtime;
--                                                      
--                                                      response_header_overwrite(srv, con, CONST_STR_LEN("Content-Encoding"), compression_name, strlen(compression_name));
--                                                      
--                                                      mtime = strftime_cache_get(srv, sce->st.st_mtime);
--                                                      response_header_overwrite(srv, con, CONST_STR_LEN("Last-Modified"), CONST_BUF_LEN(mtime));
--
--                                                      etag_mutate(con->physical.etag, sce->etag);
--                                                      response_header_overwrite(srv, con, CONST_STR_LEN("ETag"), CONST_BUF_LEN(con->physical.etag));
--
--                                                      response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(sce->content_type));
--
--                                                      return HANDLER_GO_ON;
--                                              }
--                                      } else if (0 == deflate_file_to_buffer(srv, con, p,
--                                                                             con->physical.path, sce, compression_type)) {
--                                                      
--                                              response_header_overwrite(srv, con, CONST_STR_LEN("Content-Encoding"), compression_name, strlen(compression_name));
--                                              response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(sce->content_type));
--                                              
-+
-+                                      /* deflate it to file (cached) or to memory */
-+                                      if (0 == deflate_file_to_file(srv, con, p,
-+                                                      con->physical.path, sce, compression_type) ||
-+                                          0 == deflate_file_to_buffer(srv, con, p,
-+                                                      con->physical.path, sce, compression_type)) {
-+
-+                                              response_header_overwrite(srv, con,
-+                                                              CONST_STR_LEN("Content-Encoding"),
-+                                                              compression_name, strlen(compression_name));
-+
-+                                              response_header_overwrite(srv, con,
-+                                                              CONST_STR_LEN("Content-Type"),
-+                                                              CONST_BUF_LEN(sce->content_type));
-+
-                                               return HANDLER_FINISHED;
-                                       }
-                                       break;
-@@ -682,20 +727,23 @@
-                       }
-               }
-       }
--      
-+
-       return HANDLER_GO_ON;
- }
- int mod_compress_plugin_init(plugin *p) {
-       p->version     = LIGHTTPD_VERSION_ID;
-       p->name        = buffer_init_string("compress");
--      
-+
-       p->init        = mod_compress_init;
-       p->set_defaults = mod_compress_setdefaults;
--      p->handle_subrequest_start  = mod_compress_physical;
-+
-+      /* we have to hook into the response-header settings */
-+      p->handle_response_header  = mod_compress_physical;
-+
-       p->cleanup     = mod_compress_free;
--      
-+
-       p->data        = NULL;
--      
-+
-       return 0;
- }
---- ../lighttpd-1.4.11/src/mod_dirlisting.c    2006-01-13 00:00:45.000000000 +0200
-+++ lighttpd-1.5.0/src/mod_dirlisting.c        2006-09-07 00:57:05.000000000 +0300
-@@ -1,11 +1,9 @@
- #include <ctype.h>
- #include <stdlib.h>
- #include <string.h>
--#include <dirent.h>
- #include <assert.h>
- #include <errno.h>
- #include <stdio.h>
--#include <unistd.h>
- #include <time.h>
- #include "base.h"
-@@ -17,6 +15,9 @@
- #include "response.h"
- #include "stat_cache.h"
- #include "stream.h"
-+#include "etag.h"
-+
-+#include "sys-strings.h"
- /**
-  * this is a dirlisting for a lighttpd plugin
-@@ -27,10 +28,13 @@
- #include <sys/syslimits.h>
- #endif
--#ifdef HAVE_ATTR_ATTRIBUTES_H
-+#ifdef HAVE_XATTR
- #include <attr/attributes.h>
- #endif
-+#include "sys-files.h"
-+#include "sys-strings.h"
-+
- /* plugin config for all request/connections */
- typedef struct {
-@@ -54,7 +58,7 @@
-       unsigned short hide_readme_file;
-       unsigned short show_header;
-       unsigned short hide_header_file;
--      
-+
-       excludes_buffer *excludes;
-       buffer *external_css;
-@@ -63,13 +67,14 @@
- typedef struct {
-       PLUGIN_DATA;
--      
-+
-       buffer *tmp_buf;
-       buffer *content_charset;
--      
-+      buffer *path;
-+
-       plugin_config **config_storage;
--      
--      plugin_config conf; 
-+
-+      plugin_config conf;
- } plugin_data;
- excludes_buffer *excludes_buffer_init(void) {
-@@ -146,44 +151,46 @@
- /* init the plugin data */
- INIT_FUNC(mod_dirlisting_init) {
-       plugin_data *p;
--      
-+
-       p = calloc(1, sizeof(*p));
-       p->tmp_buf = buffer_init();
-       p->content_charset = buffer_init();
--      
-+      p->path = buffer_init();
-+
-       return p;
- }
- /* detroy the plugin data */
- FREE_FUNC(mod_dirlisting_free) {
-       plugin_data *p = p_d;
--      
-+
-       UNUSED(srv);
-       if (!p) return HANDLER_GO_ON;
--      
-+
-       if (p->config_storage) {
-               size_t i;
-               for (i = 0; i < srv->config_context->used; i++) {
-                       plugin_config *s = p->config_storage[i];
--                      
-+
-                       if (!s) continue;
--                      
-+
-                       excludes_buffer_free(s->excludes);
-                       buffer_free(s->external_css);
-                       buffer_free(s->encoding);
--                      
-+
-                       free(s);
-               }
-               free(p->config_storage);
-       }
--      
-+
-       buffer_free(p->tmp_buf);
-+      buffer_free(p->path);
-       buffer_free(p->content_charset);
--      
-+
-       free(p);
--      
-+
-       return HANDLER_GO_ON;
- }
-@@ -215,10 +222,10 @@
-                       if (0 != excludes_buffer_append(s->excludes,
-                                   ((data_string *)(da->value->data[j]))->value)) {
- #ifdef HAVE_PCRE_H
--                              log_error_write(srv, __FILE__, __LINE__, "sb", 
-+                              log_error_write(srv, __FILE__, __LINE__, "sb",
-                                               "pcre-compile failed for", ((data_string *)(da->value->data[j]))->value);
- #else
--                              log_error_write(srv, __FILE__, __LINE__, "s", 
-+                              log_error_write(srv, __FILE__, __LINE__, "s",
-                                               "pcre support is missing, please install libpcre and the headers");
- #endif
-                       }
-@@ -233,8 +240,8 @@
- SETDEFAULTS_FUNC(mod_dirlisting_set_defaults) {
-       plugin_data *p = p_d;
-       size_t i = 0;
--      
--      config_values_t cv[] = { 
-+
-+      config_values_t cv[] = {
-               { "dir-listing.exclude",          NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION },   /* 0 */
-               { "dir-listing.activate",         NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
-               { "dir-listing.hide-dotfiles",    NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 2 */
-@@ -245,18 +252,18 @@
-               { "dir-listing.show-header",      NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 7 */
-               { "dir-listing.hide-header-file", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 8 */
-               { "server.dir-listing",           NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 9 */
--              
-+
-               { NULL,                          NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
-       };
--      
-+
-       if (!p) return HANDLER_ERROR;
--      
-+
-       p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
--      
-+
-       for (i = 0; i < srv->config_context->used; i++) {
-               plugin_config *s;
-               array *ca;
--              
-+
-               s = calloc(1, sizeof(plugin_config));
-               s->excludes = excludes_buffer_init();
-               s->dir_listing = 0;
-@@ -267,7 +274,7 @@
-               s->show_header = 0;
-               s->hide_header_file = 0;
-               s->encoding = buffer_init();
--              
-+
-               cv[0].destination = s->excludes;
-               cv[1].destination = &(s->dir_listing);
-               cv[2].destination = &(s->hide_dot_files);
-@@ -292,60 +299,57 @@
-       return HANDLER_GO_ON;
- }
--#define PATCH(x) \
--      p->conf.x = s->x;
- static int mod_dirlisting_patch_connection(server *srv, connection *con, plugin_data *p) {
-       size_t i, j;
-       plugin_config *s = p->config_storage[0];
--      PATCH(dir_listing);
--      PATCH(external_css);
--      PATCH(hide_dot_files);
--      PATCH(encoding);
--      PATCH(show_readme);
--      PATCH(hide_readme_file);
--      PATCH(show_header);
--      PATCH(hide_header_file);
--      PATCH(excludes);
--      
-+      PATCH_OPTION(dir_listing);
-+      PATCH_OPTION(external_css);
-+      PATCH_OPTION(hide_dot_files);
-+      PATCH_OPTION(encoding);
-+      PATCH_OPTION(show_readme);
-+      PATCH_OPTION(hide_readme_file);
-+      PATCH_OPTION(show_header);
-+      PATCH_OPTION(hide_header_file);
-+      PATCH_OPTION(excludes);
-+
-       /* skip the first, the global context */
-       for (i = 1; i < srv->config_context->used; i++) {
-               data_config *dc = (data_config *)srv->config_context->data[i];
-               s = p->config_storage[i];
--              
-+
-               /* condition didn't match */
-               if (!config_check_cond(srv, con, dc)) continue;
--              
-+
-               /* merge config */
-               for (j = 0; j < dc->value->used; j++) {
-                       data_unset *du = dc->value->data[j];
--                      
-+
-                       if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.activate")) ||
-                           buffer_is_equal_string(du->key, CONST_STR_LEN("server.dir-listing"))) {
--                              PATCH(dir_listing);
-+                              PATCH_OPTION(dir_listing);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.hide-dotfiles"))) {
--                              PATCH(hide_dot_files);
-+                              PATCH_OPTION(hide_dot_files);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.external-css"))) {
--                              PATCH(external_css);
-+                              PATCH_OPTION(external_css);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.encoding"))) {
--                              PATCH(encoding);
-+                              PATCH_OPTION(encoding);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.show-readme"))) {
--                              PATCH(show_readme);
-+                              PATCH_OPTION(show_readme);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.hide-readme-file"))) {
--                              PATCH(hide_readme_file);
-+                              PATCH_OPTION(hide_readme_file);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.show-header"))) {
--                              PATCH(show_header);
-+                              PATCH_OPTION(show_header);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.hide-header-file"))) {
--                              PATCH(hide_header_file);
-+                              PATCH_OPTION(hide_header_file);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.excludes"))) {
--                              PATCH(excludes);
-+                              PATCH_OPTION(excludes);
-                       }
-               }
-       }
--      
-+
-       return 0;
- }
--#undef PATCH
- typedef struct {
-       size_t  namelen;
-@@ -432,7 +436,7 @@
- static void http_list_directory_header(server *srv, connection *con, plugin_data *p, buffer *out) {
-       UNUSED(srv);
--      
-+
-       BUFFER_APPEND_STRING_CONST(out,
-               "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n"
-               "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\">\n"
-@@ -492,11 +496,11 @@
-       if (p->conf.show_header) {
-               stream s;
-               /* if we have a HEADER file, display it in <pre class="header"></pre> */
--              
-+
-               buffer_copy_string_buffer(p->tmp_buf, con->physical.path);
--              BUFFER_APPEND_SLASH(p->tmp_buf);
-+              PATHNAME_APPEND_SLASH(p->tmp_buf);
-               BUFFER_APPEND_STRING_CONST(p->tmp_buf, "HEADER.txt");
--              
-+
-               if (-1 != stream_open(&s, p->tmp_buf)) {
-                       BUFFER_APPEND_STRING_CONST(out, "<pre class=\"header\">");
-                       buffer_append_string_encoded(out, s.start, s.size, ENCODING_MINIMAL_XML);
-@@ -531,21 +535,21 @@
- static void http_list_directory_footer(server *srv, connection *con, plugin_data *p, buffer *out) {
-       UNUSED(srv);
--      
-+
-       BUFFER_APPEND_STRING_CONST(out,
-               "</tbody>\n"
-               "</table>\n"
-               "</div>\n"
-       );
--      
-+
-       if (p->conf.show_readme) {
-               stream s;
-               /* if we have a README file, display it in <pre class="readme"></pre> */
--              
-+
-               buffer_copy_string_buffer(p->tmp_buf,  con->physical.path);
--              BUFFER_APPEND_SLASH(p->tmp_buf);
-+              PATHNAME_APPEND_SLASH(p->tmp_buf);
-               BUFFER_APPEND_STRING_CONST(p->tmp_buf, "README.txt");
--              
-+
-               if (-1 != stream_open(&s, p->tmp_buf)) {
-                       BUFFER_APPEND_STRING_CONST(out, "<pre class=\"readme\">");
-                       buffer_append_string_encoded(out, s.start, s.size, ENCODING_MINIMAL_XML);
-@@ -553,7 +557,7 @@
-               }
-               stream_close(&s);
-       }
--      
-+
-       BUFFER_APPEND_STRING_CONST(out,
-               "<div class=\"foot\">"
-       );
-@@ -576,7 +580,6 @@
-       buffer *out;
-       struct dirent *dent;
-       struct stat st;
--      char *path, *path_file;
-       size_t i;
-       int hide_dotfiles = p->conf.hide_dot_files;
-       dirls_list_t dirs, files, *list;
-@@ -586,6 +589,7 @@
-       size_t k;
-       const char *content_type;
-       long name_max;
-+
- #ifdef HAVE_XATTR
-       char attrval[128];
-       int attrlen;
-@@ -594,10 +598,10 @@
-       struct tm tm;
- #endif
--      if (dir->used == 0) return -1;
--      
--      i = dir->used - 1;
-+      /* empty pathname, never ... */
-+      if (buffer_is_empty(dir)) return -1;
-+      /* max-length for the opendir */
- #ifdef HAVE_PATHCONF
-       if (-1 == (name_max = pathconf(dir->ptr, _PC_NAME_MAX))) {
- #ifdef NAME_MAX
-@@ -606,22 +610,24 @@
-               name_max = 256; /* stupid default */
- #endif
-       }
--#elif defined __WIN32
-+#elif defined _WIN32
-       name_max = FILENAME_MAX;
- #else
-       name_max = NAME_MAX;
- #endif
--      
--      path = malloc(dir->used + name_max);
--      assert(path);
--      strcpy(path, dir->ptr);
--      path_file = path + i;
--      if (NULL == (dp = opendir(path))) {
--              log_error_write(srv, __FILE__, __LINE__, "sbs", 
-+      buffer_copy_string_buffer(p->path, dir);
-+      PATHNAME_APPEND_SLASH(p->path);
-+
-+#ifdef _WIN32
-+      /* append *.* to the path */
-+      buffer_append_string(path, "*.*");
-+#endif
-+
-+      if (NULL == (dp = opendir(p->path->ptr))) {
-+              log_error_write(srv, __FILE__, __LINE__, "sbs",
-                       "opendir failed:", dir, strerror(errno));
--              free(path);
-               return -1;
-       }
-@@ -633,7 +639,7 @@
-       assert(files.ent);
-       files.size = DIRLIST_BLOB_SIZE;
-       files.used = 0;
--      
-+
-       while ((dent = readdir(dp)) != NULL) {
-               unsigned short exclude_match = 0;
-@@ -686,15 +692,21 @@
- #endif
-               i = strlen(dent->d_name);
--              
-+
-               /* NOTE: the manual says, d_name is never more than NAME_MAX
-                *       so this should actually not be a buffer-overflow-risk
-                */
-               if (i > (size_t)name_max) continue;
--              
--              memcpy(path_file, dent->d_name, i + 1);
--              if (stat(path, &st) != 0)
-+
-+              /* build the dirname */
-+              buffer_copy_string_buffer(p->path, dir);
-+              PATHNAME_APPEND_SLASH(p->path);
-+              buffer_append_string(p->path, dent->d_name);
-+
-+              if (stat(p->path->ptr, &st) != 0) {
-+                      fprintf(stderr, "%s.%d: %s, %s\r\n", __FILE__, __LINE__, p->path->ptr, strerror(errno));
-                       continue;
-+              }
-               list = &files;
-               if (S_ISDIR(st.st_mode))
-@@ -720,7 +732,7 @@
-       if (files.used) http_dirls_sort(files.ent, files.used);
--      out = chunkqueue_get_append_buffer(con->write_queue);
-+      out = chunkqueue_get_append_buffer(con->send);
-       BUFFER_COPY_STRING_CONST(out, "<?xml version=\"1.0\" encoding=\"");
-       if (buffer_is_empty(p->conf.encoding)) {
-               BUFFER_APPEND_STRING_CONST(out, "iso-8859-1");
-@@ -740,7 +752,7 @@
- #else
-               strftime(datebuf, sizeof(datebuf), "%Y-%b-%d %H:%M:%S", localtime(&(tmp->mtime)));
- #endif
--              
-+
-               BUFFER_APPEND_STRING_CONST(out, "<tr><td class=\"n\"><a href=\"");
-               buffer_append_string_encoded(out, DIRLIST_ENT_NAME(tmp), tmp->namelen, ENCODING_REL_URI_PART);
-               BUFFER_APPEND_STRING_CONST(out, "/\">");
-@@ -757,18 +769,22 @@
-               tmp = files.ent[i];
-               content_type = NULL;
-+
- #ifdef HAVE_XATTR
--              
-               if (con->conf.use_xattr) {
--                      memcpy(path_file, DIRLIST_ENT_NAME(tmp), tmp->namelen + 1);
-+                      /* build the dirname */
-+                      buffer_copy_string_buffer(p->path, dir);
-+                      PATHNAME_APPEND_SLASH(p->path);
-+                      buffer_append_string_len(p->path, DIRLIST_ENT_NAME(tmp), tmp->namelen);
-+
-                       attrlen = sizeof(attrval) - 1;
--                      if (attr_get(path, "Content-Type", attrval, &attrlen, 0) == 0) {
-+                      if (attr_get(p->path->ptr, "Content-Type", attrval, &attrlen, 0) == 0) {
-                               attrval[attrlen] = '\0';
-                               content_type = attrval;
-                       }
-               }
- #endif
--              
-+
-               if (content_type == NULL) {
-                       content_type = "application/octet-stream";
-                       for (k = 0; k < con->conf.mimetypes->used; k++) {
-@@ -788,7 +804,7 @@
-                               }
-                       }
-               }
--                      
-+
- #ifdef HAVE_LOCALTIME_R
-               localtime_r(&(tmp->mtime), &tm);
-               strftime(datebuf, sizeof(datebuf), "%Y-%b-%d %H:%M:%S", &tm);
-@@ -814,7 +830,6 @@
-       free(files.ent);
-       free(dirs.ent);
--      free(path);
-       http_list_directory_footer(srv, con, p, out);
-@@ -827,7 +842,7 @@
-               response_header_insert(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(p->content_charset));
-       }
--      con->file_finished = 1;
-+      con->send->is_closed = 1;
-       return 0;
- }
-@@ -837,36 +852,55 @@
- URIHANDLER_FUNC(mod_dirlisting_subrequest) {
-       plugin_data *p = p_d;
-       stat_cache_entry *sce = NULL;
--      
--      UNUSED(srv);
--      
--      if (con->physical.path->used == 0) return HANDLER_GO_ON;
--      if (con->uri.path->used == 0) return HANDLER_GO_ON;
-+      buffer *mtime;
-+      data_string *ds;
-+
-+      if (con->uri.path->used < 2) return HANDLER_GO_ON;
-       if (con->uri.path->ptr[con->uri.path->used - 2] != '/') return HANDLER_GO_ON;
--      
-+      if (con->physical.path->used == 0) return HANDLER_GO_ON;
-+
-       mod_dirlisting_patch_connection(srv, con, p);
-       if (!p->conf.dir_listing) return HANDLER_GO_ON;
--      
-+
-+      if (HANDLER_ERROR == stat_cache_get_entry(srv, con, con->physical.path, &sce)) {
-+              /* just a second ago the file was still there */
-+              return HANDLER_GO_ON;
-+      }
-+
-+      if (!S_ISDIR(sce->st.st_mode)) return HANDLER_GO_ON;
-+
-       if (con->conf.log_request_handling) {
-               log_error_write(srv, __FILE__, __LINE__,  "s",  "-- handling the request as Dir-Listing");
-               log_error_write(srv, __FILE__, __LINE__,  "sb", "URI          :", con->uri.path);
-       }
--      
--      if (HANDLER_ERROR == stat_cache_get_entry(srv, con, con->physical.path, &sce)) {
--              fprintf(stderr, "%s.%d: %s\n", __FILE__, __LINE__, con->physical.path->ptr);
--              SEGFAULT();
-+
-+      /* perhaps this a cachable request
-+       * - we use the etag of the directory
-+       * */
-+
-+      etag_mutate(con->physical.etag, sce->etag);
-+      response_header_overwrite(srv, con, CONST_STR_LEN("ETag"), CONST_BUF_LEN(con->physical.etag));
-+
-+      /* prepare header */
-+      if (NULL == (ds = (data_string *)array_get_element(con->response.headers, "Last-Modified"))) {
-+              mtime = strftime_cache_get(srv, sce->st.st_mtime);
-+              response_header_overwrite(srv, con, CONST_STR_LEN("Last-Modified"), CONST_BUF_LEN(mtime));
-+      } else {
-+              mtime = ds->value;
-       }
--      
--      if (!S_ISDIR(sce->st.st_mode)) return HANDLER_GO_ON;
--      
-+
-+      if (HANDLER_FINISHED == http_response_handle_cachable(srv, con, mtime)) {
-+              return HANDLER_FINISHED;
-+      }
-+
-       if (http_list_directory(srv, con, p, con->physical.path)) {
-               /* dirlisting failed */
-               con->http_status = 403;
-       }
--      
-+
-       buffer_reset(con->physical.path);
--      
-+
-       /* not found */
-       return HANDLER_FINISHED;
- }
-@@ -876,13 +910,13 @@
- int mod_dirlisting_plugin_init(plugin *p) {
-       p->version     = LIGHTTPD_VERSION_ID;
-       p->name        = buffer_init_string("dirlisting");
--      
-+
-       p->init        = mod_dirlisting_init;
--      p->handle_subrequest_start  = mod_dirlisting_subrequest;
-+      p->handle_start_backend  = mod_dirlisting_subrequest;
-       p->set_defaults  = mod_dirlisting_set_defaults;
-       p->cleanup     = mod_dirlisting_free;
--      
-+
-       p->data        = NULL;
--      
-+
-       return 0;
- }
---- ../lighttpd-1.4.11/src/mod_evasive.c       2006-01-04 15:24:51.000000000 +0200
-+++ lighttpd-1.5.0/src/mod_evasive.c   2006-09-07 00:57:05.000000000 +0300
-@@ -31,100 +31,97 @@
- typedef struct {
-       PLUGIN_DATA;
--      
-+
-       plugin_config **config_storage;
--      
--      plugin_config conf; 
-+
-+      plugin_config conf;
- } plugin_data;
- INIT_FUNC(mod_evasive_init) {
-       plugin_data *p;
--      
-+
-       p = calloc(1, sizeof(*p));
--      
-+
-       return p;
- }
- FREE_FUNC(mod_evasive_free) {
-       plugin_data *p = p_d;
--      
-+
-       UNUSED(srv);
-       if (!p) return HANDLER_GO_ON;
--      
-+
-       if (p->config_storage) {
-               size_t i;
-               for (i = 0; i < srv->config_context->used; i++) {
-                       plugin_config *s = p->config_storage[i];
--                                              
-+
-                       free(s);
-               }
-               free(p->config_storage);
-       }
--      
-+
-       free(p);
--      
-+
-       return HANDLER_GO_ON;
- }
- SETDEFAULTS_FUNC(mod_evasive_set_defaults) {
-       plugin_data *p = p_d;
-       size_t i = 0;
--      
--      config_values_t cv[] = { 
-+
-+      config_values_t cv[] = {
-               { "evasive.max-conns-per-ip",    NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },
-               { NULL,                          NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
-       };
--      
-+
-       p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
--      
-+
-       for (i = 0; i < srv->config_context->used; i++) {
-               plugin_config *s;
--              
-+
-               s = calloc(1, sizeof(plugin_config));
-               s->max_conns       = 0;
--              
-+
-               cv[0].destination = &(s->max_conns);
--              
-+
-               p->config_storage[i] = s;
--      
-+
-               if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
-                       return HANDLER_ERROR;
-               }
-       }
--      
-+
-       return HANDLER_GO_ON;
- }
--#define PATCH(x) \
--      p->conf.x = s->x;
- static int mod_evasive_patch_connection(server *srv, connection *con, plugin_data *p) {
-       size_t i, j;
-       plugin_config *s = p->config_storage[0];
--      PATCH(max_conns);
--      
-+      PATCH_OPTION(max_conns);
-+
-       /* skip the first, the global context */
-       for (i = 1; i < srv->config_context->used; i++) {
-               data_config *dc = (data_config *)srv->config_context->data[i];
-               s = p->config_storage[i];
--              
-+
-               /* condition didn't match */
-               if (!config_check_cond(srv, con, dc)) continue;
--              
-+
-               /* merge config */
-               for (j = 0; j < dc->value->used; j++) {
-                       data_unset *du = dc->value->data[j];
--                      
-+
-                       if (buffer_is_equal_string(du->key, CONST_STR_LEN("evasive.max-conns-per-ip"))) {
--                              PATCH(max_conns);
-+                              PATCH_OPTION(max_conns);
-                       }
-               }
-       }
--      
-+
-       return 0;
- }
--#undef PATCH
- URIHANDLER_FUNC(mod_evasive_uri_handler) {
-       plugin_data *p = p_d;
-@@ -132,10 +129,10 @@
-       size_t j;
-       if (con->uri.path->used == 0) return HANDLER_GO_ON;
--      
-+
-       mod_evasive_patch_connection(srv, con, p);
--      
--      /* no limit set, nothing to block */    
-+
-+      /* no limit set, nothing to block */
-       if (p->conf.max_conns == 0) return HANDLER_GO_ON;
-       for (j = 0; j < srv->conns->used; j++) {
-@@ -145,9 +142,9 @@
-                * we can only ban connections which are already behind the 'read request' state
-                * */
-               if (c->dst_addr.ipv4.sin_addr.s_addr == con->dst_addr.ipv4.sin_addr.s_addr &&
--                  c->state > CON_STATE_REQUEST_END) {
-+                  c->state > CON_STATE_HANDLE_REQUEST_HEADER) {
-                       conns_by_ip++;
--      
-+
-                       if (conns_by_ip > p->conf.max_conns) {
-                               log_error_write(srv, __FILE__, __LINE__, "ss",
-                                       inet_ntop_cache_get_ip(srv, &(con->dst_addr)),
-@@ -158,7 +155,7 @@
-                       }
-               }
-       }
--      
-+
-       return HANDLER_GO_ON;
- }
-@@ -166,13 +163,13 @@
- int mod_evasive_plugin_init(plugin *p) {
-       p->version     = LIGHTTPD_VERSION_ID;
-       p->name        = buffer_init_string("evasive");
--      
-+
-       p->init        = mod_evasive_init;
-       p->set_defaults = mod_evasive_set_defaults;
-       p->handle_uri_clean  = mod_evasive_uri_handler;
-       p->cleanup     = mod_evasive_free;
--      
-+
-       p->data        = NULL;
--      
-+
-       return 0;
- }
---- ../lighttpd-1.4.11/src/mod_evhost.c        2005-08-17 10:42:03.000000000 +0300
-+++ lighttpd-1.5.0/src/mod_evhost.c    2006-07-16 00:26:03.000000000 +0300
-@@ -7,10 +7,12 @@
- #include "response.h"
- #include "stat_cache.h"
-+#include "sys-files.h"
-+
- typedef struct {
-       /* unparsed pieces */
-       buffer *path_pieces_raw;
--      
-+
-       /* pieces for path creation */
-       size_t len;
-       buffer **path_pieces;
-@@ -21,14 +23,14 @@
-       buffer *tmp_buf;
-       plugin_config **config_storage;
--      plugin_config conf; 
-+      plugin_config conf;
- } plugin_data;
- INIT_FUNC(mod_evhost_init) {
-       plugin_data *p;
--      
-+
-       p = calloc(1, sizeof(*p));
--      
-+
-       p->tmp_buf = buffer_init();
-       return p;
-@@ -36,34 +38,34 @@
- FREE_FUNC(mod_evhost_free) {
-       plugin_data *p = p_d;
--      
-+
-       UNUSED(srv);
-       if (!p) return HANDLER_GO_ON;
--      
-+
-       if (p->config_storage) {
-               size_t i;
-               for (i = 0; i < srv->config_context->used; i++) {
-                       plugin_config *s = p->config_storage[i];
-                       if (!s) continue;
--                      
-+
-                       if(s->path_pieces) {
-                               size_t j;
-                               for (j = 0; j < s->len; j++) {
-                                       buffer_free(s->path_pieces[j]);
-                               }
--                              
-+
-                               free(s->path_pieces);
-                       }
--                      
-+
-                       buffer_free(s->path_pieces_raw);
--                      
-+
-                       free(s);
-               }
-               free(p->config_storage);
-       }
--      
-+
-       buffer_free(p->tmp_buf);
-       free(p);
-@@ -73,30 +75,30 @@
- static void mod_evhost_parse_pattern(plugin_config *s) {
-       char *ptr = s->path_pieces_raw->ptr,*pos;
--      
-+
-       s->path_pieces = NULL;
--      
-+
-       for(pos=ptr;*ptr;ptr++) {
-               if(*ptr == '%') {
-                       s->path_pieces = realloc(s->path_pieces,(s->len+2) * sizeof(*s->path_pieces));
-                       s->path_pieces[s->len] = buffer_init();
-                       s->path_pieces[s->len+1] = buffer_init();
--                      
-+
-                       buffer_copy_string_len(s->path_pieces[s->len],pos,ptr-pos);
-                       pos = ptr + 2;
--                      
-+
-                       buffer_copy_string_len(s->path_pieces[s->len+1],ptr++,2);
--                      
-+
-                       s->len += 2;
-               }
-       }
--      
-+
-       if(*pos != '\0') {
-               s->path_pieces = realloc(s->path_pieces,(s->len+1) * sizeof(*s->path_pieces));
-               s->path_pieces[s->len] = buffer_init();
--              
-+
-               buffer_append_memory(s->path_pieces[s->len],pos,ptr-pos);
--              
-+
-               s->len += 1;
-       }
- }
-@@ -104,9 +106,9 @@
- SETDEFAULTS_FUNC(mod_evhost_set_defaults) {
-       plugin_data *p = p_d;
-       size_t i;
--      
-+
-       /**
--       * 
-+       *
-        * #
-        * # define a pattern for the host url finding
-        * # %% => % sign
-@@ -117,39 +119,39 @@
-        * # %4 => subdomain 2 name
-        * #
-        * evhost.path-pattern = "/home/ckruse/dev/www/%3/htdocs/"
--       * 
-+       *
-        */
--      
--      config_values_t cv[] = { 
-+
-+      config_values_t cv[] = {
-               { "evhost.path-pattern",            NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
-               { NULL,                             NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
-       };
--      
-+
-       if (!p) return HANDLER_ERROR;
--      
-+
-       p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
--      
-+
-       for (i = 0; i < srv->config_context->used; i++) {
-               plugin_config *s;
--              
-+
-               s = calloc(1, sizeof(plugin_config));
-               s->path_pieces_raw = buffer_init();
-               s->path_pieces     = NULL;
-               s->len             = 0;
--      
-+
-               cv[0].destination = s->path_pieces_raw;
--              
-+
-               p->config_storage[i] = s;
--              
-+
-               if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value,  cv)) {
-                       return HANDLER_ERROR;
-               }
--              
-+
-               if (s->path_pieces_raw->used != 0) {
-                       mod_evhost_parse_pattern(s);
-               }
-       }
--      
-+
-       return HANDLER_GO_ON;
- }
-@@ -158,7 +160,7 @@
-  * - %0 - full hostname (authority w/o port)
-  * - %1 - tld
-  * - %2 - domain.tld
-- * - %3 - 
-+ * - %3 -
-  */
- static int mod_evhost_parse_host(connection *con,array *host) {
-@@ -168,7 +170,7 @@
-       int first = 1;
-       data_string *ds;
-       int i;
--      
-+
-       /* first, find the domain + tld */
-       for(;ptr > con->uri.authority->ptr;ptr--) {
-               if(*ptr == '.') {
-@@ -179,18 +181,18 @@
-                       first = 1;
-               }
-       }
--      
-+
-       ds = data_string_init();
-       buffer_copy_string(ds->key,"%0");
--      
-+
-       /* if we stopped at a dot, skip the dot */
-       if (*ptr == '.') ptr++;
-       buffer_copy_string_len(ds->value, ptr, colon-ptr);
--      
-+
-       array_insert_unique(host,(data_unset *)ds);
--      
-+
-       /* if the : is not the start of the authority, go on parsing the hostname */
--      
-+
-       if (colon != con->uri.authority->ptr) {
-               for(ptr = colon - 1, i = 1; ptr > con->uri.authority->ptr; ptr--) {
-                       if(*ptr == '.') {
-@@ -200,59 +202,55 @@
-                                       buffer_copy_string(ds->key,"%");
-                                       buffer_append_long(ds->key, i++);
-                                       buffer_copy_string_len(ds->value,ptr+1,colon-ptr-1);
--                                      
-+
-                                       array_insert_unique(host,(data_unset *)ds);
-                               }
-                               colon = ptr;
-                       }
-               }
--              
-+
-               /* if the . is not the first charactor of the hostname */
-               if (colon != ptr) {
-                       ds = data_string_init();
-                       buffer_copy_string(ds->key,"%");
-                       buffer_append_long(ds->key, i++);
-                       buffer_copy_string_len(ds->value,ptr,colon-ptr);
--                      
-+
-                       array_insert_unique(host,(data_unset *)ds);
-               }
-       }
--      
-+
-       return 0;
- }
--#define PATCH(x) \
--      p->conf.x = s->x;
- static int mod_evhost_patch_connection(server *srv, connection *con, plugin_data *p) {
-       size_t i, j;
-       plugin_config *s = p->config_storage[0];
--      
--      PATCH(path_pieces);
--      PATCH(len);
--      
-+
-+      PATCH_OPTION(path_pieces);
-+      PATCH_OPTION(len);
-+
-       /* skip the first, the global context */
-       for (i = 1; i < srv->config_context->used; i++) {
-               data_config *dc = (data_config *)srv->config_context->data[i];
-               s = p->config_storage[i];
--              
-+
-               /* condition didn't match */
-               if (!config_check_cond(srv, con, dc)) continue;
--              
-+
-               /* merge config */
-               for (j = 0; j < dc->value->used; j++) {
-                       data_unset *du = dc->value->data[j];
--                      
-+
-                       if (buffer_is_equal_string(du->key, CONST_STR_LEN("evhost.path-pattern"))) {
--                              PATCH(path_pieces);
--                              PATCH(len);
-+                              PATCH_OPTION(path_pieces);
-+                              PATCH_OPTION(len);
-                       }
-               }
-       }
--      
-+
-       return 0;
- }
--#undef PATCH
--
- static handler_t mod_evhost_uri_handler(server *srv, connection *con, void *p_d) {
-       plugin_data *p = p_d;
-@@ -261,29 +259,29 @@
-       register char *ptr;
-       int not_good = 0;
-       stat_cache_entry *sce = NULL;
--      
-+
-       /* not authority set */
-       if (con->uri.authority->used == 0) return HANDLER_GO_ON;
--      
-+
-       mod_evhost_patch_connection(srv, con, p);
--      
-+
-       /* missing even default(global) conf */
-       if (0 == p->conf.len) {
-               return HANDLER_GO_ON;
-       }
-       parsed_host = array_init();
--      
-+
-       mod_evhost_parse_host(con, parsed_host);
--      
-+
-       /* build document-root */
-       buffer_reset(p->tmp_buf);
--      
-+
-       for (i = 0; i < p->conf.len; i++) {
-               ptr = p->conf.path_pieces[i]->ptr;
-               if (*ptr == '%') {
-                       data_string *ds;
--                      
-+
-                       if (*(ptr+1) == '%') {
-                               /* %% */
-                               BUFFER_APPEND_STRING_CONST(p->tmp_buf,"%");
-@@ -298,11 +296,11 @@
-                       buffer_append_string_buffer(p->tmp_buf,p->conf.path_pieces[i]);
-               }
-       }
--      
--      BUFFER_APPEND_SLASH(p->tmp_buf);
--      
-+
-+      PATHNAME_APPEND_SLASH(p->tmp_buf);
-+
-       array_free(parsed_host);
--      
-+
-       if (HANDLER_ERROR == stat_cache_get_entry(srv, con, p->tmp_buf, &sce)) {
-               log_error_write(srv, __FILE__, __LINE__, "sb", strerror(errno), p->tmp_buf);
-               not_good = 1;
-@@ -310,11 +308,11 @@
-               log_error_write(srv, __FILE__, __LINE__, "sb", "not a directory:", p->tmp_buf);
-               not_good = 1;
-       }
--      
-+
-       if (!not_good) {
-               buffer_copy_string_buffer(con->physical.doc_root, p->tmp_buf);
-       }
--      
-+
-       return HANDLER_GO_ON;
- }
-@@ -325,9 +323,9 @@
-       p->set_defaults            = mod_evhost_set_defaults;
-       p->handle_docroot          = mod_evhost_uri_handler;
-       p->cleanup                 = mod_evhost_free;
--      
-+
-       p->data                    = NULL;
--      
-+
-       return 0;
- }
---- ../lighttpd-1.4.11/src/mod_expire.c        2005-11-03 09:52:13.000000000 +0200
-+++ lighttpd-1.5.0/src/mod_expire.c    2006-09-07 00:57:05.000000000 +0300
-@@ -12,8 +12,8 @@
- #include "stat_cache.h"
- /**
-- * this is a expire module for a lighttpd 
-- * 
-+ * this is a expire module for a lighttpd
-+ *
-  * set 'Expires:' HTTP Headers on demand
-  */
-@@ -27,51 +27,51 @@
- typedef struct {
-       PLUGIN_DATA;
--      
-+
-       buffer *expire_tstmp;
--      
-+
-       plugin_config **config_storage;
--      
--      plugin_config conf; 
-+
-+      plugin_config conf;
- } plugin_data;
- /* init the plugin data */
- INIT_FUNC(mod_expire_init) {
-       plugin_data *p;
--      
-+
-       p = calloc(1, sizeof(*p));
--      
-+
-       p->expire_tstmp = buffer_init();
--      
-+
-       buffer_prepare_copy(p->expire_tstmp, 255);
--      
-+
-       return p;
- }
- /* detroy the plugin data */
- FREE_FUNC(mod_expire_free) {
-       plugin_data *p = p_d;
--      
-+
-       UNUSED(srv);
-       if (!p) return HANDLER_GO_ON;
--      
-+
-       buffer_free(p->expire_tstmp);
--      
-+
-       if (p->config_storage) {
-               size_t i;
-               for (i = 0; i < srv->config_context->used; i++) {
-                       plugin_config *s = p->config_storage[i];
--                      
-+
-                       array_free(s->expire_url);
--                      
-+
-                       free(s);
-               }
-               free(p->config_storage);
-       }
--      
-+
-       free(p);
--      
-+
-       return HANDLER_GO_ON;
- }
-@@ -79,25 +79,25 @@
-       char *ts;
-       int type = -1;
-       int retts = 0;
--              
-+
-       UNUSED(p);
--      /* 
-+      /*
-        * parse
--       * 
-+       *
-        * '(access|modification) [plus] {<num> <type>}*'
--       * 
-+       *
-        * e.g. 'access 1 years'
-        */
--      
-+
-       if (expire->used == 0) {
--              log_error_write(srv, __FILE__, __LINE__, "s", 
-+              log_error_write(srv, __FILE__, __LINE__, "s",
-                               "empty:");
-               return -1;
-       }
--      
-+
-       ts = expire->ptr;
--      
-+
-       if (0 == strncmp(ts, "access ", 7)) {
-               type  = 0;
-               ts   += 7;
-@@ -110,39 +110,39 @@
-                               "invalid <base>:", ts);
-               return -1;
-       }
--      
-+
-       if (0 == strncmp(ts, "plus ", 5)) {
-               /* skip the optional plus */
-               ts   += 5;
-       }
--      
-+
-       /* the rest is just <number> (years|months|days|hours|minutes|seconds) */
-       while (1) {
-               char *space, *err;
-               int num;
--              
-+
-               if (NULL == (space = strchr(ts, ' '))) {
--                      log_error_write(srv, __FILE__, __LINE__, "ss", 
-+                      log_error_write(srv, __FILE__, __LINE__, "ss",
-                                       "missing space after <num>:", ts);
-                       return -1;
-               }
--              
-+
-               num = strtol(ts, &err, 10);
-               if (*err != ' ') {
--                      log_error_write(srv, __FILE__, __LINE__, "ss", 
-+                      log_error_write(srv, __FILE__, __LINE__, "ss",
-                                       "missing <type> after <num>:", ts);
-                       return -1;
-               }
--              
-+
-               ts = space + 1;
--              
-+
-               if (NULL != (space = strchr(ts, ' '))) {
-                       int slen;
-                       /* */
--                      
-+
-                       slen = space - ts;
--                      
--                      if (slen == 5 && 
-+
-+                      if (slen == 5 &&
-                           0 == strncmp(ts, "years", slen)) {
-                               num *= 60 * 60 * 24 * 30 * 12;
-                       } else if (slen == 6 &&
-@@ -161,13 +161,13 @@
-                                  0 == strncmp(ts, "seconds", slen)) {
-                               num *= 1;
-                       } else {
--                              log_error_write(srv, __FILE__, __LINE__, "ss", 
-+                              log_error_write(srv, __FILE__, __LINE__, "ss",
-                                               "unknown type:", ts);
-                               return -1;
-                       }
--                      
-+
-                       retts += num;
--                      
-+
-                       ts = space + 1;
-               } else {
-                       if (0 == strcmp(ts, "years")) {
-@@ -183,19 +183,19 @@
-                       } else if (0 == strcmp(ts, "seconds")) {
-                               num *= 1;
-                       } else {
--                              log_error_write(srv, __FILE__, __LINE__, "ss", 
-+                              log_error_write(srv, __FILE__, __LINE__, "ss",
-                                               "unknown type:", ts);
-                               return -1;
-                       }
--                      
-+
-                       retts += num;
--                      
-+
-                       break;
-               }
-       }
--      
-+
-       if (offset != NULL) *offset = retts;
--      
-+
-       return type;
- }
-@@ -205,102 +205,99 @@
- SETDEFAULTS_FUNC(mod_expire_set_defaults) {
-       plugin_data *p = p_d;
-       size_t i = 0, k;
--      
--      config_values_t cv[] = { 
-+
-+      config_values_t cv[] = {
-               { "expire.url",                 NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
-               { NULL,                         NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
-       };
--      
-+
-       if (!p) return HANDLER_ERROR;
--      
-+
-       p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
--      
-+
-       for (i = 0; i < srv->config_context->used; i++) {
-               plugin_config *s;
--              
-+
-               s = calloc(1, sizeof(plugin_config));
-               s->expire_url    = array_init();
--              
-+
-               cv[0].destination = s->expire_url;
--              
-+
-               p->config_storage[i] = s;
--      
-+
-               if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
-                       return HANDLER_ERROR;
-               }
--      
-+
-               for (k = 0; k < s->expire_url->used; k++) {
-                       data_string *ds = (data_string *)s->expire_url->data[k];
--                      
-+
-                       /* parse lines */
-                       if (-1 == mod_expire_get_offset(srv, p, ds->value, NULL)) {
--                              log_error_write(srv, __FILE__, __LINE__, "sb", 
-+                              log_error_write(srv, __FILE__, __LINE__, "sb",
-                                               "parsing expire.url failed:", ds->value);
-                               return HANDLER_ERROR;
-                       }
-               }
-       }
--      
--      
-+
-+
-       return HANDLER_GO_ON;
- }
--#define PATCH(x) \
--      p->conf.x = s->x;
- static int mod_expire_patch_connection(server *srv, connection *con, plugin_data *p) {
-       size_t i, j;
-       plugin_config *s = p->config_storage[0];
--      
--      PATCH(expire_url);
--      
-+
-+      PATCH_OPTION(expire_url);
-+
-       /* skip the first, the global context */
-       for (i = 1; i < srv->config_context->used; i++) {
-               data_config *dc = (data_config *)srv->config_context->data[i];
-               s = p->config_storage[i];
--              
-+
-               /* condition didn't match */
-               if (!config_check_cond(srv, con, dc)) continue;
--              
-+
-               /* merge config */
-               for (j = 0; j < dc->value->used; j++) {
-                       data_unset *du = dc->value->data[j];
--                      
-+
-                       if (buffer_is_equal_string(du->key, CONST_STR_LEN("expire.url"))) {
--                              PATCH(expire_url);
-+                              PATCH_OPTION(expire_url);
-                       }
-               }
-       }
--      
-+
-       return 0;
- }
--#undef PATCH
- URIHANDLER_FUNC(mod_expire_path_handler) {
-       plugin_data *p = p_d;
-       int s_len;
-       size_t k;
--      
-+
-       if (con->uri.path->used == 0) return HANDLER_GO_ON;
--      
-+
-       mod_expire_patch_connection(srv, con, p);
--      
-+
-       s_len = con->uri.path->used - 1;
--      
-+
-       for (k = 0; k < p->conf.expire_url->used; k++) {
-               data_string *ds = (data_string *)p->conf.expire_url->data[k];
-               int ct_len = ds->key->used - 1;
--              
-+
-               if (ct_len > s_len) continue;
-               if (ds->key->used == 0) continue;
--              
-+
-               if (0 == strncmp(con->uri.path->ptr, ds->key->ptr, ct_len)) {
-                       int ts;
-                       time_t t;
-                       size_t len;
-                       stat_cache_entry *sce = NULL;
--              
-+
-                       stat_cache_get_entry(srv, con, con->physical.path, &sce);
--                      
-+
-                       switch(mod_expire_get_offset(srv, p, ds->value, &ts)) {
-                       case 0:
-                               /* access */
-@@ -308,38 +305,38 @@
-                               break;
-                       case 1:
-                               /* modification */
--                              
-+
-                               t = (ts + sce->st.st_mtime);
-                               break;
-                       default:
-                               /* -1 is handled at parse-time */
-                               break;
-                       }
--                      
--                      
--                      if (0 == (len = strftime(p->expire_tstmp->ptr, p->expire_tstmp->size - 1, 
-+
-+
-+                      if (0 == (len = strftime(p->expire_tstmp->ptr, p->expire_tstmp->size - 1,
-                                          "%a, %d %b %Y %H:%M:%S GMT", gmtime(&(t))))) {
-                               /* could not set expire header, out of mem */
--                              
-+
-                               return HANDLER_GO_ON;
--                              
-+
-                       }
--                          
-+
-                       p->expire_tstmp->used = len + 1;
--              
--                      /* HTTP/1.0 */  
-+
-+                      /* HTTP/1.0 */
-                       response_header_overwrite(srv, con, CONST_STR_LEN("Expires"), CONST_BUF_LEN(p->expire_tstmp));
--                      /* HTTP/1.1 */  
-+                      /* HTTP/1.1 */
-                       buffer_copy_string(p->expire_tstmp, "max-age=");
-                       buffer_append_long(p->expire_tstmp, ts);
--                      
-+
-                       response_header_overwrite(srv, con, CONST_STR_LEN("Cache-Control"), CONST_BUF_LEN(p->expire_tstmp));
--                      
-+
-                       return HANDLER_GO_ON;
-               }
-       }
--      
-+
-       /* not found */
-       return HANDLER_GO_ON;
- }
-@@ -349,13 +346,13 @@
- int mod_expire_plugin_init(plugin *p) {
-       p->version     = LIGHTTPD_VERSION_ID;
-       p->name        = buffer_init_string("expire");
--      
-+
-       p->init        = mod_expire_init;
--      p->handle_subrequest_start = mod_expire_path_handler;
-+      p->handle_response_header = mod_expire_path_handler;
-       p->set_defaults  = mod_expire_set_defaults;
-       p->cleanup     = mod_expire_free;
--      
-+
-       p->data        = NULL;
--      
-+
-       return 0;
- }
---- ../lighttpd-1.4.11/src/mod_fastcgi.c       2006-03-09 13:18:39.000000000 +0200
-+++ lighttpd-1.5.0/src/mod_fastcgi.c   2006-09-07 00:57:05.000000000 +0300
-@@ -1,5 +1,4 @@
- #include <sys/types.h>
--#include <unistd.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <string.h>
-@@ -13,18 +12,18 @@
- #include "keyvalue.h"
- #include "log.h"
--#include "http_chunk.h"
- #include "fdevent.h"
- #include "connections.h"
- #include "response.h"
- #include "joblist.h"
-+#include "status_counter.h"
- #include "plugin.h"
- #include "inet_ntop_cache.h"
- #include "stat_cache.h"
--#include <fastcgi.h>
-+#include "fastcgi.h"
- #include <stdio.h>
- #ifdef HAVE_SYS_FILIO_H
-@@ -32,7 +31,11 @@
- #endif
- #include "sys-socket.h"
-+#include "sys-files.h"
-+#include "sys-strings.h"
-+#include "sys-process.h"
-+#include "http_resp.h"
- #ifndef UNIX_PATH_MAX
- # define UNIX_PATH_MAX 108
-@@ -45,14 +48,13 @@
- #include <sys/wait.h>
- #endif
--
- /*
-- * 
-+ *
-  * TODO:
-- * 
-+ *
-  * - add timeout for a connect to a non-fastcgi process
-  *   (use state_timestamp + state)
-- * 
-+ *
-  */
- typedef struct fcgi_proc {
-@@ -61,7 +63,7 @@
-       unsigned port;  /* config.port + pno */
-       buffer *connection_name; /* either tcp:<host>:<port> or unix:<socket> for debuggin purposes */
--      
-+
-       pid_t pid;   /* PID of the spawned process (0 if not spawned locally) */
-@@ -70,20 +72,20 @@
-       time_t last_used; /* see idle_timeout */
-       size_t requests;  /* see max_requests */
-       struct fcgi_proc *prev, *next; /* see first */
--      
-+
-       time_t disabled_until; /* this proc is disabled until, use something else until than */
--      
-+
-       int is_local;
--      enum { 
-+      enum {
-               PROC_STATE_UNSET,    /* init-phase */
-               PROC_STATE_RUNNING,  /* alive */
--              PROC_STATE_OVERLOADED, /* listen-queue is full, 
-+              PROC_STATE_OVERLOADED, /* listen-queue is full,
-                                         don't send something to this proc for the next 2 seconds */
-               PROC_STATE_DIED_WAIT_FOR_PID, /* */
-               PROC_STATE_DIED,     /* marked as dead, should be restarted */
-               PROC_STATE_KILLED    /* was killed as we don't have the load anymore */
--      } state; 
-+      } state;
- } fcgi_proc;
- typedef struct {
-@@ -94,20 +96,20 @@
-        * sorted by lowest load
-        *
-        * whenever a job is done move it up in the list
--       * until it is sorted, move it down as soon as the 
-+       * until it is sorted, move it down as soon as the
-        * job is started
-        */
--      fcgi_proc *first; 
--      fcgi_proc *unused_procs; 
-+      fcgi_proc *first;
-+      fcgi_proc *unused_procs;
--      /* 
-+      /*
-        * spawn at least min_procs, at max_procs.
-        *
--       * as soon as the load of the first entry 
-+       * as soon as the load of the first entry
-        * is max_load_per_proc we spawn a new one
--       * and add it to the first entry and give it 
-+       * and add it to the first entry and give it
-        * the load
--       * 
-+       *
-        */
-       unsigned short min_procs;
-@@ -119,44 +121,44 @@
-       /*
-        * kick the process from the list if it was not
--       * used for idle_timeout until min_procs is 
-+       * used for idle_timeout until min_procs is
-        * reached. this helps to get the processlist
-        * small again we had a small peak load.
-        *
-        */
--      
-+
-       unsigned short idle_timeout;
--      
-+
-       /*
-        * time after a disabled remote connection is tried to be re-enabled
--       * 
--       * 
-+       *
-+       *
-        */
--      
-+
-       unsigned short disable_time;
-       /*
-        * same fastcgi processes get a little bit larger
--       * than wanted. max_requests_per_proc kills a 
-+       * than wanted. max_requests_per_proc kills a
-        * process after a number of handled requests.
-        *
-        */
-       size_t max_requests_per_proc;
--      
-+
-       /* config */
--      /* 
--       * host:port 
-+      /*
-+       * host:port
-        *
--       * if host is one of the local IP adresses the 
-+       * if host is one of the local IP adresses the
-        * whole connection is local
-        *
-        * if tcp/ip should be used host AND port have
--       * to be specified 
--       * 
--       */ 
--      buffer *host; 
-+       * to be specified
-+       *
-+       */
-+      buffer *host;
-       unsigned short port;
-       /*
-@@ -169,7 +171,7 @@
-        */
-       buffer *unixsocket;
--      /* if socket is local we can start the fastcgi 
-+      /* if socket is local we can start the fastcgi
-        * process ourself
-        *
-        * bin-path is the path to the binary
-@@ -177,19 +179,19 @@
-        * check min_procs and max_procs for the number
-        * of process to start-up
-        */
--      buffer *bin_path; 
--      
--      /* bin-path is set bin-environment is taken to 
-+      buffer *bin_path;
-+
-+      /* bin-path is set bin-environment is taken to
-        * create the environement before starting the
-        * FastCGI process
--       * 
-+       *
-        */
-       array *bin_env;
--      
-+
-       array *bin_env_copy;
--      
-+
-       /*
--       * docroot-translation between URL->phys and the 
-+       * docroot-translation between URL->phys and the
-        * remote host
-        *
-        * reasons:
-@@ -208,7 +210,7 @@
-       unsigned short mode;
-       /*
--       * check_local tell you if the phys file is stat()ed 
-+       * check_local tell you if the phys file is stat()ed
-        * or not. FastCGI doesn't care if the service is
-        * remote. If the web-server side doesn't contain
-        * the fastcgi-files we should not stat() for them
-@@ -218,11 +220,11 @@
-       /*
-        * append PATH_INFO to SCRIPT_FILENAME
--       * 
-+       *
-        * php needs this if cgi.fix_pathinfo is provied
--       * 
-+       *
-        */
--      
-+
-       unsigned short break_scriptfilename_for_php;
-       /*
-@@ -231,12 +233,12 @@
-        *
-        */
-       unsigned short allow_xsendfile;
--              
-+
-       ssize_t load; /* replace by host->load */
-       size_t max_id; /* corresponds most of the time to
-       num_procs.
--      
-+
-       only if a process is killed max_id waits for the process itself
-       to die and decrements its afterwards */
-@@ -245,17 +247,17 @@
- /*
-  * one extension can have multiple hosts assigned
-- * one host can spawn additional processes on the same 
-+ * one host can spawn additional processes on the same
-  *   socket (if we control it)
-  *
-  * ext -> host -> procs
-  *    1:n     1:n
-  *
-- * if the fastcgi process is remote that whole goes down 
-+ * if the fastcgi process is remote that whole goes down
-  * to
-  *
-  * ext -> host -> procs
-- *    1:n     1:1 
-+ *    1:n     1:1
-  *
-  * in case of PHP and FCGI_CHILDREN we have again a procs
-  * but we don't control it directly.
-@@ -268,7 +270,7 @@
-       int note_is_sent;
-       fcgi_extension_host **hosts;
--      
-+
-       size_t used;
-       size_t size;
- } fcgi_extension;
-@@ -282,10 +284,10 @@
- typedef struct {
--      fcgi_exts *exts; 
-+      fcgi_exts *exts;
-       array *ext_mapping;
--      
-+
-       int debug;
- } plugin_config;
-@@ -297,7 +299,7 @@
- typedef struct {
-       char **ptr;
--      
-+
-       size_t size;
-       size_t used;
- } char_array;
-@@ -306,55 +308,54 @@
- typedef struct {
-       PLUGIN_DATA;
-       buffer_uint fcgi_request_id;
--      
-+
-       buffer *fcgi_env;
--      
-+
-       buffer *path;
--      buffer *parse_response;
-       buffer *statuskey;
--      
-+
-+      http_resp *resp;
-+
-       plugin_config **config_storage;
--      
-+
-       plugin_config conf; /* this is only used as long as no handler_ctx is setup */
- } plugin_data;
- /* connection specific data */
--typedef enum { 
-+typedef enum {
-       FCGI_STATE_UNSET,
--      FCGI_STATE_INIT, 
--      FCGI_STATE_CONNECT_DELAYED, 
--      FCGI_STATE_PREPARE_WRITE, 
--      FCGI_STATE_WRITE, 
--      FCGI_STATE_READ 
-+      FCGI_STATE_INIT,
-+      FCGI_STATE_CONNECT_DELAYED,
-+      FCGI_STATE_PREPARE_WRITE,
-+      FCGI_STATE_WRITE,
-+      FCGI_STATE_READ
- } fcgi_connection_state_t;
- typedef struct {
-       fcgi_proc *proc;
-       fcgi_extension_host *host;
-       fcgi_extension *ext;
--      
-+
-       fcgi_connection_state_t state;
-       time_t   state_timestamp;
--      
-+
-       int      reconnects; /* number of reconnect attempts */
--      
--      chunkqueue *rb; /* read queue */
-+
-+      chunkqueue *rb; /* the raw fcgi read-queue */
-+      chunkqueue *http_rb; /* the decoded read-queue for http-parsing */
-       chunkqueue *wb; /* write queue */
--      
--      buffer   *response_header;
--      
-+
-       size_t    request_id;
--      int       fd;        /* fd to the fastcgi process */
--      int       fde_ndx;   /* index into the fd-event buffer */
-+      iosocket *sock;
-       pid_t     pid;
-       int       got_proc;
-       int       send_content_body;
--      
-+
-       plugin_config conf;
--      
-+
-       connection *remote_conn;  /* dumb pointer */
-       plugin_data *plugin_data; /* dumb pointer */
- } handler_ctx;
-@@ -363,49 +364,6 @@
- /* ok, we need a prototype */
- static handler_t fcgi_handle_fdevent(void *s, void *ctx, int revents);
--data_integer *status_counter_get_counter(server *srv, const char *s, size_t len) {
--      data_integer *di;
--
--      if (NULL == (di = (data_integer *)array_get_element(srv->status, s))) {
--              /* not found, create it */
--
--              if (NULL == (di = (data_integer *)array_get_unused_element(srv->status, TYPE_INTEGER))) {
--                      di = data_integer_init();
--              }
--              buffer_copy_string_len(di->key, s, len);
--              di->value = 0;
--
--              array_insert_unique(srv->status, (data_unset *)di);
--      }
--      return di;
--}
--
--/* dummies of the statistic framework functions 
-- * they will be moved to a statistics.c later */
--int status_counter_inc(server *srv, const char *s, size_t len) {
--      data_integer *di = status_counter_get_counter(srv, s, len);
--
--      di->value++;
--
--      return 0;
--}
--
--int status_counter_dec(server *srv, const char *s, size_t len) {
--      data_integer *di = status_counter_get_counter(srv, s, len);
--
--      if (di->value > 0) di->value--;
--
--      return 0;
--}
--
--int status_counter_set(server *srv, const char *s, size_t len, int val) {
--      data_integer *di = status_counter_get_counter(srv, s, len);
--
--      di->value = val;
--
--      return 0;
--}
--
- int fastcgi_status_copy_procname(buffer *b, fcgi_extension_host *host, fcgi_proc *proc) {
-       buffer_copy_string(b, "fastcgi.backend.");
-       buffer_append_string_buffer(b, host->id);
-@@ -421,7 +379,7 @@
- #define CLEAN(x) \
-       fastcgi_status_copy_procname(b, host, proc); \
-       buffer_append_string(b, x); \
--      status_counter_set(srv, CONST_BUF_LEN(b), 0);
-+      status_counter_set(CONST_BUF_LEN(b), 0);
-       CLEAN(".disabled");
-       CLEAN(".died");
-@@ -429,42 +387,39 @@
-       CLEAN(".connected");
-       CLEAN(".load");
--#undef CLEAN  
-+#undef CLEAN
- #define CLEAN(x) \
-       fastcgi_status_copy_procname(b, host, NULL); \
-       buffer_append_string(b, x); \
--      status_counter_set(srv, CONST_BUF_LEN(b), 0);
-+      status_counter_set(CONST_BUF_LEN(b), 0);
-       CLEAN(".load");
--#undef CLEAN  
-+#undef CLEAN
-       return 0;
- }
- static handler_ctx * handler_ctx_init() {
-       handler_ctx * hctx;
--      
-+
-       hctx = calloc(1, sizeof(*hctx));
-       assert(hctx);
--      
--      hctx->fde_ndx = -1;
--      
--      hctx->response_header = buffer_init();
--      
-+
-       hctx->request_id = 0;
-       hctx->state = FCGI_STATE_INIT;
-       hctx->proc = NULL;
--      
--      hctx->fd = -1;
--      
-+
-+      hctx->sock = iosocket_init();
-+
-       hctx->reconnects = 0;
-       hctx->send_content_body = 1;
-       hctx->rb = chunkqueue_init();
-+      hctx->http_rb = chunkqueue_init();
-       hctx->wb = chunkqueue_init();
--      
-+
-       return hctx;
- }
-@@ -473,12 +428,13 @@
-               hctx->host->load--;
-               hctx->host = NULL;
-       }
--      
--      buffer_free(hctx->response_header);
-       chunkqueue_free(hctx->rb);
-+      chunkqueue_free(hctx->http_rb);
-       chunkqueue_free(hctx->wb);
-+      iosocket_free(hctx->sock);
-+
-       free(hctx);
- }
-@@ -488,21 +444,21 @@
-       f = calloc(1, sizeof(*f));
-       f->unixsocket = buffer_init();
-       f->connection_name = buffer_init();
--      
-+
-       f->prev = NULL;
-       f->next = NULL;
--      
-+
-       return f;
- }
- void fastcgi_process_free(fcgi_proc *f) {
-       if (!f) return;
--      
-+
-       fastcgi_process_free(f->next);
--      
-+
-       buffer_free(f->unixsocket);
-       buffer_free(f->connection_name);
--      
-+
-       free(f);
- }
-@@ -519,13 +475,13 @@
-       f->bin_env = array_init();
-       f->bin_env_copy = array_init();
-       f->strip_request_uri = buffer_init();
--      
-+
-       return f;
- }
- void fastcgi_host_free(fcgi_extension_host *h) {
-       if (!h) return;
--      
-+
-       buffer_free(h->id);
-       buffer_free(h->host);
-       buffer_free(h->unixsocket);
-@@ -534,49 +490,49 @@
-       buffer_free(h->strip_request_uri);
-       array_free(h->bin_env);
-       array_free(h->bin_env_copy);
--      
-+
-       fastcgi_process_free(h->first);
-       fastcgi_process_free(h->unused_procs);
--      
-+
-       free(h);
--      
-+
- }
- fcgi_exts *fastcgi_extensions_init() {
-       fcgi_exts *f;
-       f = calloc(1, sizeof(*f));
--      
-+
-       return f;
- }
- void fastcgi_extensions_free(fcgi_exts *f) {
-       size_t i;
--      
-+
-       if (!f) return;
--      
-+
-       for (i = 0; i < f->used; i++) {
-               fcgi_extension *fe;
-               size_t j;
--              
-+
-               fe = f->exts[i];
--              
-+
-               for (j = 0; j < fe->used; j++) {
-                       fcgi_extension_host *h;
--                      
-+
-                       h = fe->hosts[j];
--                      
-+
-                       fastcgi_host_free(h);
-               }
--              
-+
-               buffer_free(fe->key);
-               free(fe->hosts);
--              
-+
-               free(fe);
-       }
--      
-+
-       free(f->exts);
--      
-+
-       free(f);
- }
-@@ -625,24 +581,25 @@
-               assert(fe->hosts);
-       }
--      fe->hosts[fe->used++] = fh; 
-+      fe->hosts[fe->used++] = fh;
-       return 0;
--      
-+
- }
- INIT_FUNC(mod_fastcgi_init) {
-       plugin_data *p;
--      
-+
-       p = calloc(1, sizeof(*p));
--      
-+
-       p->fcgi_env = buffer_init();
--      
-+
-       p->path = buffer_init();
--      p->parse_response = buffer_init();
-+
-+      p->resp = http_response_init();
-       p->statuskey = buffer_init();
--      
-+
-       return p;
- }
-@@ -650,81 +607,82 @@
- FREE_FUNC(mod_fastcgi_free) {
-       plugin_data *p = p_d;
-       buffer_uint *r = &(p->fcgi_request_id);
--      
-+
-       UNUSED(srv);
-       if (r->ptr) free(r->ptr);
--      
-+
-       buffer_free(p->fcgi_env);
-       buffer_free(p->path);
--      buffer_free(p->parse_response);
-       buffer_free(p->statuskey);
--      
-+
-+      http_response_free(p->resp);
-+
-       if (p->config_storage) {
-               size_t i, j, n;
-               for (i = 0; i < srv->config_context->used; i++) {
-                       plugin_config *s = p->config_storage[i];
-                       fcgi_exts *exts;
--                      
-+
-                       if (!s) continue;
--                      
-+
-                       exts = s->exts;
-                       for (j = 0; j < exts->used; j++) {
-                               fcgi_extension *ex;
--                              
-+
-                               ex = exts->exts[j];
--                              
-+
-                               for (n = 0; n < ex->used; n++) {
-                                       fcgi_proc *proc;
-                                       fcgi_extension_host *host;
--                                      
-+
-                                       host = ex->hosts[n];
--                                      
-+
-                                       for (proc = host->first; proc; proc = proc->next) {
-                                               if (proc->pid != 0) kill(proc->pid, SIGTERM);
--                                              
--                                              if (proc->is_local && 
-+
-+                                              if (proc->is_local &&
-                                                   !buffer_is_empty(proc->unixsocket)) {
-                                                       unlink(proc->unixsocket->ptr);
-                                               }
-                                       }
--                                      
-+
-                                       for (proc = host->unused_procs; proc; proc = proc->next) {
-                                               if (proc->pid != 0) kill(proc->pid, SIGTERM);
--                                              
--                                              if (proc->is_local && 
-+
-+                                              if (proc->is_local &&
-                                                   !buffer_is_empty(proc->unixsocket)) {
-                                                       unlink(proc->unixsocket->ptr);
-                                               }
-                                       }
-                               }
-                       }
--                      
-+
-                       fastcgi_extensions_free(s->exts);
-                       array_free(s->ext_mapping);
--                      
-+
-                       free(s);
-               }
-               free(p->config_storage);
-       }
--      
-+
-       free(p);
--      
-+
-       return HANDLER_GO_ON;
- }
- static int env_add(char_array *env, const char *key, size_t key_len, const char *val, size_t val_len) {
-       char *dst;
--      
-+
-       if (!key || !val) return -1;
--      
-+
-       dst = malloc(key_len + val_len + 3);
-       memcpy(dst, key, key_len);
-       dst[key_len] = '=';
-       /* add the \0 from the value */
-       memcpy(dst + key_len + 1, val, val_len + 1);
--      
-+
-       if (env->size == 0) {
-               env->size = 16;
-               env->ptr = malloc(env->size * sizeof(*env->ptr));
-@@ -732,9 +690,9 @@
-               env->size += 16;
-               env->ptr = realloc(env->ptr, env->size * sizeof(*env->ptr));
-       }
--      
-+
-       env->ptr[env->used++] = dst;
--      
-+
-       return 0;
- }
-@@ -753,15 +711,15 @@
-                       if (env->size == 0) {
-                               env->size = 16;
-                               env->ptr = malloc(env->size * sizeof(*env->ptr));
--                      } else if (env->size == env->used) { 
-+                      } else if (env->size == env->used) {
-                               env->size += 16;
-                               env->ptr = realloc(env->ptr, env->size * sizeof(*env->ptr));
-                       }
--                      
-+
-                       b->ptr[i] = '\0';
-                       env->ptr[env->used++] = start;
--                      
-+
-                       start = b->ptr + i + 1;
-                       break;
-               default:
-@@ -794,7 +752,7 @@
-       return 0;
- }
--static int fcgi_spawn_connection(server *srv, 
-+static int fcgi_spawn_connection(server *srv,
-                                plugin_data *p,
-                                fcgi_extension_host *host,
-                                fcgi_proc *proc) {
-@@ -806,31 +764,27 @@
- #endif
-       struct sockaddr_in fcgi_addr_in;
-       struct sockaddr *fcgi_addr;
--      
-+
-       socklen_t servlen;
--      
-+
- #ifndef HAVE_FORK
-       return -1;
- #endif
--      
-+
-       if (p->conf.debug) {
-               log_error_write(srv, __FILE__, __LINE__, "sdb",
-                               "new proc, socket:", proc->port, proc->unixsocket);
-       }
--              
-+
-       if (!buffer_is_empty(proc->unixsocket)) {
-               memset(&fcgi_addr, 0, sizeof(fcgi_addr));
--              
-+
- #ifdef HAVE_SYS_UN_H
-               fcgi_addr_un.sun_family = AF_UNIX;
-               strcpy(fcgi_addr_un.sun_path, proc->unixsocket->ptr);
--              
--#ifdef SUN_LEN
-+
-               servlen = SUN_LEN(&fcgi_addr_un);
--#else
--              /* stevens says: */
--              servlen = proc->unixsocket->used + sizeof(fcgi_addr_un.sun_family);
--#endif
-+
-               socket_type = AF_UNIX;
-               fcgi_addr = (struct sockaddr *) &fcgi_addr_un;
-@@ -844,108 +798,108 @@
- #endif
-       } else {
-               fcgi_addr_in.sin_family = AF_INET;
--              
-+
-               if (buffer_is_empty(host->host)) {
-                       fcgi_addr_in.sin_addr.s_addr = htonl(INADDR_ANY);
-               } else {
-                       struct hostent *he;
--                      
-+
-                       /* set a usefull default */
-                       fcgi_addr_in.sin_addr.s_addr = htonl(INADDR_ANY);
--                      
--                      
-+
-+
-                       if (NULL == (he = gethostbyname(host->host->ptr))) {
--                              log_error_write(srv, __FILE__, __LINE__, 
--                                              "sdb", "gethostbyname failed: ", 
-+                              log_error_write(srv, __FILE__, __LINE__,
-+                                              "sdb", "gethostbyname failed: ",
-                                               h_errno, host->host);
-                               return -1;
-                       }
--                      
-+
-                       if (he->h_addrtype != AF_INET) {
-                               log_error_write(srv, __FILE__, __LINE__, "sd", "addr-type != AF_INET: ", he->h_addrtype);
-                               return -1;
-                       }
--                      
-+
-                       if (he->h_length != sizeof(struct in_addr)) {
-                               log_error_write(srv, __FILE__, __LINE__, "sd", "addr-length != sizeof(in_addr): ", he->h_length);
-                               return -1;
-                       }
--                      
-+
-                       memcpy(&(fcgi_addr_in.sin_addr.s_addr), he->h_addr_list[0], he->h_length);
--                      
-+
-               }
-               fcgi_addr_in.sin_port = htons(proc->port);
-               servlen = sizeof(fcgi_addr_in);
--              
-+
-               socket_type = AF_INET;
-               fcgi_addr = (struct sockaddr *) &fcgi_addr_in;
--              
-+
-               buffer_copy_string(proc->connection_name, "tcp:");
-               buffer_append_string_buffer(proc->connection_name, host->host);
-               buffer_append_string(proc->connection_name, ":");
-               buffer_append_long(proc->connection_name, proc->port);
-       }
--      
-+
-       if (-1 == (fcgi_fd = socket(socket_type, SOCK_STREAM, 0))) {
--              log_error_write(srv, __FILE__, __LINE__, "ss", 
-+              log_error_write(srv, __FILE__, __LINE__, "ss",
-                               "failed:", strerror(errno));
-               return -1;
-       }
--      
-+
-       if (-1 == connect(fcgi_fd, fcgi_addr, servlen)) {
-               /* server is not up, spawn in  */
-               pid_t child;
-               int val;
--              
--              if (errno != ENOENT && 
-+
-+              if (errno != ENOENT &&
-                   !buffer_is_empty(proc->unixsocket)) {
-                       unlink(proc->unixsocket->ptr);
-               }
--              
-+
-               close(fcgi_fd);
--              
-+
-               /* reopen socket */
-               if (-1 == (fcgi_fd = socket(socket_type, SOCK_STREAM, 0))) {
--                      log_error_write(srv, __FILE__, __LINE__, "ss", 
-+                      log_error_write(srv, __FILE__, __LINE__, "ss",
-                               "socket failed:", strerror(errno));
-                       return -1;
-               }
--              
-+
-               val = 1;
-               if (setsockopt(fcgi_fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) {
--                      log_error_write(srv, __FILE__, __LINE__, "ss", 
-+                      log_error_write(srv, __FILE__, __LINE__, "ss",
-                                       "socketsockopt failed:", strerror(errno));
-                       return -1;
-               }
--              
-+
-               /* create socket */
-               if (-1 == bind(fcgi_fd, fcgi_addr, servlen)) {
--                      log_error_write(srv, __FILE__, __LINE__, "sbs", 
--                              "bind failed for:", 
-+                      log_error_write(srv, __FILE__, __LINE__, "sbs",
-+                              "bind failed for:",
-                               proc->connection_name,
-                               strerror(errno));
-                       return -1;
-               }
--              
-+
-               if (-1 == listen(fcgi_fd, 1024)) {
--                      log_error_write(srv, __FILE__, __LINE__, "ss", 
-+                      log_error_write(srv, __FILE__, __LINE__, "ss",
-                               "listen failed:", strerror(errno));
-                       return -1;
-               }
--              
--#ifdef HAVE_FORK      
-+
-+#ifndef _WIN32
-               switch ((child = fork())) {
-               case 0: {
-                       size_t i = 0;
-                       char *c;
-                       char_array env;
-                       char_array arg;
--                      
-+
-                       /* create environment */
-                       env.ptr = NULL;
-                       env.size = 0;
-                       env.used = 0;
--                      
-+
-                       arg.ptr = NULL;
-                       arg.size = 0;
-                       arg.used = 0;
-@@ -955,18 +909,18 @@
-                               dup2(fcgi_fd, FCGI_LISTENSOCK_FILENO);
-                               close(fcgi_fd);
-                       }
--                      
-+
-                       /* we don't need the client socket */
-                       for (i = 3; i < 256; i++) {
-                               close(i);
-                       }
--                      
-+
-                       /* build clean environment */
-                       if (host->bin_env_copy->used) {
-                               for (i = 0; i < host->bin_env_copy->used; i++) {
-                                       data_string *ds = (data_string *)host->bin_env_copy->data[i];
-                                       char *ge;
--                                      
-+
-                                       if (NULL != (ge = getenv(ds->value->ptr))) {
-                                               env_add(&env, CONST_BUF_LEN(ds->value), ge, strlen(ge));
-                                       }
-@@ -974,39 +928,39 @@
-                       } else {
-                               for (i = 0; environ[i]; i++) {
-                                       char *eq;
--                                      
-+
-                                       if (NULL != (eq = strchr(environ[i], '='))) {
-                                               env_add(&env, environ[i], eq - environ[i], eq+1, strlen(eq+1));
-                                       }
-                               }
-                       }
--                      
-+
-                       /* create environment */
-                       for (i = 0; i < host->bin_env->used; i++) {
-                               data_string *ds = (data_string *)host->bin_env->data[i];
--                              
-+
-                               env_add(&env, CONST_BUF_LEN(ds->key), CONST_BUF_LEN(ds->value));
-                       }
--                      
-+
-                       for (i = 0; i < env.used; i++) {
-                               /* search for PHP_FCGI_CHILDREN */
-                               if (0 == strncmp(env.ptr[i], "PHP_FCGI_CHILDREN=", sizeof("PHP_FCGI_CHILDREN=") - 1)) break;
-                       }
--                      
-+
-                       /* not found, add a default */
-                       if (i == env.used) {
-                               env_add(&env, CONST_STR_LEN("PHP_FCGI_CHILDREN"), CONST_STR_LEN("1"));
-                       }
--                      
-+
-                       env.ptr[env.used] = NULL;
-                       parse_binpath(&arg, host->bin_path);
--                      
-+
-                       /* chdir into the base of the bin-path,
-                        * search for the last / */
-                       if (NULL != (c = strrchr(arg.ptr[0], '/'))) {
-                               *c = '\0';
--                      
-+
-                               /* change to the physical directory */
-                               if (-1 == chdir(arg.ptr[0])) {
-                                       *c = '/';
-@@ -1018,12 +972,12 @@
-                       /* exec the cgi */
-                       execve(arg.ptr[0], arg.ptr, env.ptr);
--                      
--                      log_error_write(srv, __FILE__, __LINE__, "sbs", 
-+
-+                      log_error_write(srv, __FILE__, __LINE__, "sbs",
-                                       "execve failed for:", host->bin_path, strerror(errno));
--                      
-+
-                       exit(errno);
--                      
-+
-                       break;
-               }
-               case -1:
-@@ -1031,17 +985,17 @@
-                       break;
-               default:
-                       /* father */
--                      
-+
-                       /* wait */
-                       select(0, NULL, NULL, NULL, &tv);
--                      
-+
-                       switch (waitpid(child, &status, WNOHANG)) {
-                       case 0:
-                               /* child still running after timeout, good */
-                               break;
-                       case -1:
-                               /* no PID found ? should never happen */
--                              log_error_write(srv, __FILE__, __LINE__, "ss", 
-+                              log_error_write(srv, __FILE__, __LINE__, "ss",
-                                               "pid not found:", strerror(errno));
-                               return -1;
-                       default:
-@@ -1049,10 +1003,10 @@
-                                               "the fastcgi-backend", host->bin_path, "failed to start:");
-                               /* the child should not terminate at all */
-                               if (WIFEXITED(status)) {
--                                      log_error_write(srv, __FILE__, __LINE__, "sdb", 
--                                                      "child exited with status", 
-+                                      log_error_write(srv, __FILE__, __LINE__, "sdb",
-+                                                      "child exited with status",
-                                                       WEXITSTATUS(status), host->bin_path);
--                                      log_error_write(srv, __FILE__, __LINE__, "s", 
-+                                      log_error_write(srv, __FILE__, __LINE__, "s",
-                                                       "if you try do run PHP as FastCGI backend make sure you use the FastCGI enabled version.\n"
-                                                       "You can find out if it is the right one by executing 'php -v' and it should display '(cgi-fcgi)' "
-                                                       "in the output, NOT (cgi) NOR (cli)\n"
-@@ -1060,8 +1014,8 @@
-                                       log_error_write(srv, __FILE__, __LINE__, "s",
-                                                       "If this is PHP on Gentoo add fastcgi to the USE flags");
-                               } else if (WIFSIGNALED(status)) {
--                                      log_error_write(srv, __FILE__, __LINE__, "sd", 
--                                                      "terminated by signal:", 
-+                                      log_error_write(srv, __FILE__, __LINE__, "sd",
-+                                                      "terminated by signal:",
-                                                       WTERMSIG(status));
-                                       if (WTERMSIG(status) == 11) {
-@@ -1071,8 +1025,8 @@
-                                                               "If this is PHP try to remove the byte-code caches for now and try again.");
-                                       }
-                               } else {
--                                      log_error_write(srv, __FILE__, __LINE__, "sd", 
--                                                      "child died somehow:", 
-+                                      log_error_write(srv, __FILE__, __LINE__, "sd",
-+                                                      "child died somehow:",
-                                                       status);
-                               }
-                               return -1;
-@@ -1082,26 +1036,26 @@
-                       proc->pid = child;
-                       proc->last_used = srv->cur_ts;
-                       proc->is_local = 1;
--                                              
-+
-                       break;
-               }
- #endif
-       } else {
-               proc->is_local = 0;
-               proc->pid = 0;
--              
-+
-               if (p->conf.debug) {
-                       log_error_write(srv, __FILE__, __LINE__, "sb",
-                                       "(debug) socket is already used, won't spawn:",
-                                       proc->connection_name);
-               }
-       }
--      
-+
-       proc->state = PROC_STATE_RUNNING;
-       host->active_procs++;
--      
-+
-       close(fcgi_fd);
--      
-+
-       return 0;
- }
-@@ -1111,93 +1065,93 @@
-       data_unset *du;
-       size_t i = 0;
-       buffer *fcgi_mode = buffer_init();
--      
--      config_values_t cv[] = { 
-+
-+      config_values_t cv[] = {
-               { "fastcgi.server",              NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
-               { "fastcgi.debug",               NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },       /* 1 */
-               { "fastcgi.map-extensions",      NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 2 */
-               { NULL,                          NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
-       };
--      
-+
-       p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
--      
-+
-       for (i = 0; i < srv->config_context->used; i++) {
-               plugin_config *s;
-               array *ca;
--              
-+
-               s = malloc(sizeof(plugin_config));
-               s->exts          = fastcgi_extensions_init();
-               s->debug         = 0;
-               s->ext_mapping   = array_init();
--              
-+
-               cv[0].destination = s->exts;
-               cv[1].destination = &(s->debug);
-               cv[2].destination = s->ext_mapping;
--              
-+
-               p->config_storage[i] = s;
-               ca = ((data_config *)srv->config_context->data[i])->value;
--      
-+
-               if (0 != config_insert_values_global(srv, ca, cv)) {
-                       return HANDLER_ERROR;
-               }
--              
--              /* 
-+
-+              /*
-                * <key> = ( ... )
-                */
--              
-+
-               if (NULL != (du = array_get_element(ca, "fastcgi.server"))) {
-                       size_t j;
-                       data_array *da = (data_array *)du;
--                      
-+
-                       if (du->type != TYPE_ARRAY) {
--                              log_error_write(srv, __FILE__, __LINE__, "sss", 
-+                              log_error_write(srv, __FILE__, __LINE__, "sss",
-                                               "unexpected type for key: ", "fastcgi.server", "array of strings");
--                              
-+
-                               return HANDLER_ERROR;
-                       }
--                      
--                      
--                      /* 
--                       * fastcgi.server = ( "<ext>" => ( ... ), 
-+
-+
-+                      /*
-+                       * fastcgi.server = ( "<ext>" => ( ... ),
-                        *                    "<ext>" => ( ... ) )
-                        */
--                      
-+
-                       for (j = 0; j < da->value->used; j++) {
-                               size_t n;
-                               data_array *da_ext = (data_array *)da->value->data[j];
--                              
-+
-                               if (da->value->data[j]->type != TYPE_ARRAY) {
--                                      log_error_write(srv, __FILE__, __LINE__, "sssbs", 
--                                                      "unexpected type for key: ", "fastcgi.server", 
-+                                      log_error_write(srv, __FILE__, __LINE__, "sssbs",
-+                                                      "unexpected type for key: ", "fastcgi.server",
-                                                       "[", da->value->data[j]->key, "](string)");
--                                      
-+
-                                       return HANDLER_ERROR;
-                               }
--                              
--                              /* 
--                               * da_ext->key == name of the extension 
-+
-+                              /*
-+                               * da_ext->key == name of the extension
-                                */
--                              
--                              /* 
--                               * fastcgi.server = ( "<ext>" => 
--                               *                     ( "<host>" => ( ... ), 
-+
-+                              /*
-+                               * fastcgi.server = ( "<ext>" =>
-+                               *                     ( "<host>" => ( ... ),
-                                *                       "<host>" => ( ... )
--                               *                     ), 
-+                               *                     ),
-                                *                    "<ext>" => ... )
-                                */
--                                      
-+
-                               for (n = 0; n < da_ext->value->used; n++) {
-                                       data_array *da_host = (data_array *)da_ext->value->data[n];
--                                      
-+
-                                       fcgi_extension_host *host;
--                                      
--                                      config_values_t fcv[] = { 
-+
-+                                      config_values_t fcv[] = {
-                                               { "host",              NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
-                                               { "docroot",           NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 1 */
-                                               { "mode",              NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 2 */
-                                               { "socket",            NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 3 */
-                                               { "bin-path",          NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 4 */
--                                              
-+
-                                               { "check-local",       NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },      /* 5 */
-                                               { "port",              NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },        /* 6 */
-                                               { "min-procs-not-working",         NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },        /* 7 this is broken for now */
-@@ -1205,28 +1159,28 @@
-                                               { "max-load-per-proc", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },        /* 9 */
-                                               { "idle-timeout",      NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },        /* 10 */
-                                               { "disable-time",      NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },        /* 11 */
--                                              
-+
-                                               { "bin-environment",   NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },        /* 12 */
-                                               { "bin-copy-environment", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },     /* 13 */
--                                              
-+
-                                               { "broken-scriptfilename", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },  /* 14 */
-                                               { "allow-x-send-file", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },      /* 15 */
-                                               { "strip-request-uri",  NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },      /* 16 */
--                                              
-+
-                                               { NULL,                NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
-                                       };
--                                      
-+
-                                       if (da_host->type != TYPE_ARRAY) {
--                                              log_error_write(srv, __FILE__, __LINE__, "ssSBS", 
--                                                              "unexpected type for key:", 
--                                                              "fastcgi.server", 
-+                                              log_error_write(srv, __FILE__, __LINE__, "ssSBS",
-+                                                              "unexpected type for key:",
-+                                                              "fastcgi.server",
-                                                               "[", da_host->key, "](string)");
--                                              
-+
-                                               return HANDLER_ERROR;
-                                       }
--                                      
-+
-                                       host = fastcgi_host_init();
--                                      
-+
-                                       buffer_copy_string_buffer(host->id, da_host->key);
-                                       host->check_local  = 1;
-@@ -1238,13 +1192,13 @@
-                                       host->disable_time = 60;
-                                       host->break_scriptfilename_for_php = 0;
-                                       host->allow_xsendfile = 0; /* handle X-LIGHTTPD-send-file */
--                                      
-+
-                                       fcv[0].destination = host->host;
-                                       fcv[1].destination = host->docroot;
-                                       fcv[2].destination = fcgi_mode;
-                                       fcv[3].destination = host->unixsocket;
-                                       fcv[4].destination = host->bin_path;
--                                      
-+
-                                       fcv[5].destination = &(host->check_local);
-                                       fcv[6].destination = &(host->port);
-                                       fcv[7].destination = &(host->min_procs);
-@@ -1252,35 +1206,35 @@
-                                       fcv[9].destination = &(host->max_load_per_proc);
-                                       fcv[10].destination = &(host->idle_timeout);
-                                       fcv[11].destination = &(host->disable_time);
--                                      
-+
-                                       fcv[12].destination = host->bin_env;
-                                       fcv[13].destination = host->bin_env_copy;
-                                       fcv[14].destination = &(host->break_scriptfilename_for_php);
-                                       fcv[15].destination = &(host->allow_xsendfile);
-                                       fcv[16].destination = host->strip_request_uri;
--                                      
-+
-                                       if (0 != config_insert_values_internal(srv, da_host->value, fcv)) {
-                                               return HANDLER_ERROR;
-                                       }
--                                                      
--                                      if ((!buffer_is_empty(host->host) || host->port) && 
-+
-+                                      if ((!buffer_is_empty(host->host) || host->port) &&
-                                           !buffer_is_empty(host->unixsocket)) {
--                                              log_error_write(srv, __FILE__, __LINE__, "sbsbsbs", 
-+                                              log_error_write(srv, __FILE__, __LINE__, "sbsbsbs",
-                                                               "either host/port or socket have to be set in:",
--                                                              da->key, "= (", 
-+                                                              da->key, "= (",
-                                                               da_ext->key, " => (",
-                                                               da_host->key, " ( ...");
-                                               return HANDLER_ERROR;
-                                       }
--                                      
-+
-                                       if (!buffer_is_empty(host->unixsocket)) {
-                                               /* unix domain socket */
--                                              
-+
-                                               if (host->unixsocket->used > UNIX_PATH_MAX - 2) {
--                                                      log_error_write(srv, __FILE__, __LINE__, "sbsbsbs", 
-+                                                      log_error_write(srv, __FILE__, __LINE__, "sbsbsbs",
-                                                                       "unixsocket is too long in:",
--                                                                      da->key, "= (", 
-+                                                                      da->key, "= (",
-                                                                       da_ext->key, " => (",
-                                                                       da_host->key, " ( ...");
-@@ -1288,37 +1242,37 @@
-                                               }
-                                       } else {
-                                               /* tcp/ip */
--                                              
--                                              if (buffer_is_empty(host->host) && 
-+
-+                                              if (buffer_is_empty(host->host) &&
-                                                   buffer_is_empty(host->bin_path)) {
--                                                      log_error_write(srv, __FILE__, __LINE__, "sbsbsbs", 
-+                                                      log_error_write(srv, __FILE__, __LINE__, "sbsbsbs",
-                                                                       "host or binpath have to be set in:",
--                                                                      da->key, "= (", 
-+                                                                      da->key, "= (",
-                                                                       da_ext->key, " => (",
-                                                                       da_host->key, " ( ...");
--                                                      
-+
-                                                       return HANDLER_ERROR;
-                                               } else if (host->port == 0) {
--                                                      log_error_write(srv, __FILE__, __LINE__, "sbsbsbs", 
-+                                                      log_error_write(srv, __FILE__, __LINE__, "sbsbsbs",
-                                                                       "port has to be set in:",
--                                                                      da->key, "= (", 
-+                                                                      da->key, "= (",
-                                                                       da_ext->key, " => (",
-                                                                       da_host->key, " ( ...");
-                                                       return HANDLER_ERROR;
-                                               }
-                                       }
--                                              
--                                      if (!buffer_is_empty(host->bin_path)) { 
-+
-+                                      if (!buffer_is_empty(host->bin_path)) {
-                                               /* a local socket + self spawning */
-                                               size_t pno;
-                                               /* HACK:  just to make sure the adaptive spawing is disabled */
-                                               host->min_procs = host->max_procs;
--                                              
-+
-                                               if (host->min_procs > host->max_procs) host->max_procs = host->min_procs;
-                                               if (host->max_load_per_proc < 1) host->max_load_per_proc = 0;
--                                              
-+
-                                               if (s->debug) {
-                                                       log_error_write(srv, __FILE__, __LINE__, "ssbsdsbsdsd",
-                                                                       "--- fastcgi spawning local",
-@@ -1328,7 +1282,7 @@
-                                                                       "\n\tmin-procs:", host->min_procs,
-                                                                       "\n\tmax-procs:", host->max_procs);
-                                               }
--                                              
-+
-                                               for (pno = 0; pno < host->min_procs; pno++) {
-                                                       fcgi_proc *proc;
-@@ -1343,7 +1297,7 @@
-                                                               buffer_append_string(proc->unixsocket, "-");
-                                                               buffer_append_long(proc->unixsocket, pno);
-                                                       }
--                                                      
-+
-                                                       if (s->debug) {
-                                                               log_error_write(srv, __FILE__, __LINE__, "ssdsbsdsd",
-                                                                               "--- fastcgi spawning",
-@@ -1351,7 +1305,7 @@
-                                                                               "\n\tsocket", host->unixsocket,
-                                                                               "\n\tcurrent:", pno, "/", host->min_procs);
-                                                       }
--                                                      
-+
-                                                       if (fcgi_spawn_connection(srv, p, host, proc)) {
-                                                               log_error_write(srv, __FILE__, __LINE__, "s",
-                                                                               "[ERROR]: spawning fcgi failed.");
-@@ -1359,35 +1313,35 @@
-                                                       }
-                                                       fastcgi_status_init(srv, p->statuskey, host, proc);
--                                                      
-+
-                                                       proc->next = host->first;
-                                                       if (host->first)        host->first->prev = proc;
--                                                      
-+
-                                                       host->first = proc;
-                                               }
-                                       } else {
-                                               fcgi_proc *proc;
--                                              
-+
-                                               proc = fastcgi_process_init();
-                                               proc->id = host->num_procs++;
-                                               host->max_id++;
-                                               host->active_procs++;
-                                               proc->state = PROC_STATE_RUNNING;
--                                              
-+
-                                               if (buffer_is_empty(host->unixsocket)) {
-                                                       proc->port = host->port;
-                                               } else {
-                                                       buffer_copy_string_buffer(proc->unixsocket, host->unixsocket);
-                                               }
--                                              
-+
-                                               fastcgi_status_init(srv, p->statuskey, host, proc);
-                                               host->first = proc;
--                                              
-+
-                                               host->min_procs = 1;
-                                               host->max_procs = 1;
-                                       }
--                                      
-+
-                                       if (!buffer_is_empty(fcgi_mode)) {
-                                               if (strcmp(fcgi_mode->ptr, "responder") == 0) {
-                                                       host->mode = FCGI_RESPONDER;
-@@ -1411,16 +1365,16 @@
-                       }
-               }
-       }
--      
-+
-       buffer_free(fcgi_mode);
--      
-+
-       return HANDLER_GO_ON;
- }
- static int fcgi_set_state(server *srv, handler_ctx *hctx, fcgi_connection_state_t state) {
-       hctx->state = state;
-       hctx->state_timestamp = srv->cur_ts;
--      
-+
-       return 0;
- }
-@@ -1429,13 +1383,13 @@
-       size_t m = 0;
-       size_t i;
-       buffer_uint *r = &(p->fcgi_request_id);
--      
-+
-       UNUSED(srv);
-       for (i = 0; i < r->used; i++) {
-               if (r->ptr[i] > m) m = r->ptr[i];
-       }
--      
-+
-       if (r->size == 0) {
-               r->size = 16;
-               r->ptr = malloc(sizeof(*r->ptr) * r->size);
-@@ -1443,54 +1397,55 @@
-               r->size += 16;
-               r->ptr = realloc(r->ptr, sizeof(*r->ptr) * r->size);
-       }
--      
-+
-       r->ptr[r->used++] = ++m;
--      
-+
-       return m;
- }
- static int fcgi_requestid_del(server *srv, plugin_data *p, size_t request_id) {
-       size_t i;
-       buffer_uint *r = &(p->fcgi_request_id);
--      
-+
-       UNUSED(srv);
-       for (i = 0; i < r->used; i++) {
-               if (r->ptr[i] == request_id) break;
-       }
--      
-+
-       if (i != r->used) {
-               /* found */
--              
-+
-               if (i != r->used - 1) {
-                       r->ptr[i] = r->ptr[r->used - 1];
-               }
-               r->used--;
-       }
--      
-+
-       return 0;
- }
- void fcgi_connection_close(server *srv, handler_ctx *hctx) {
-       plugin_data *p;
-       connection  *con;
--      
-+
-       if (NULL == hctx) return;
--      
-+
-       p    = hctx->plugin_data;
-       con  = hctx->remote_conn;
--      
-+
-       if (con->mode != p->id) {
--              WP();
-               return;
-       }
--      
--      if (hctx->fd != -1) {
--              fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
--              fdevent_unregister(srv->ev, hctx->fd);
--              close(hctx->fd);
-+
-+      if (hctx->sock->fd != -1) {
-+              fdevent_event_del(srv->ev, hctx->sock);
-+              fdevent_unregister(srv->ev, hctx->sock);
-+              closesocket(hctx->sock->fd);
-+              hctx->sock->fd = -1;
-+
-               srv->cur_fds--;
-       }
--      
-+
-       if (hctx->request_id != 0) {
-               fcgi_requestid_del(srv, p, hctx->request_id);
-       }
-@@ -1499,111 +1454,111 @@
-               if (hctx->got_proc) {
-                       /* after the connect the process gets a load */
-                       hctx->proc->load--;
--                      
--                      status_counter_dec(srv, CONST_STR_LEN("fastcgi.active-requests"));
-+
-+                      status_counter_dec(CONST_STR_LEN("fastcgi.active-requests"));
-                       fastcgi_status_copy_procname(p->statuskey, hctx->host, hctx->proc);
-                       buffer_append_string(p->statuskey, ".load");
--                      status_counter_set(srv, CONST_BUF_LEN(p->statuskey), hctx->proc->load);
-+                      status_counter_set(CONST_BUF_LEN(p->statuskey), hctx->proc->load);
-                       if (p->conf.debug) {
-                               log_error_write(srv, __FILE__, __LINE__, "ssdsbsd",
--                                              "released proc:", 
--                                              "pid:", hctx->proc->pid, 
--                                              "socket:", hctx->proc->connection_name, 
-+                                              "released proc:",
-+                                              "pid:", hctx->proc->pid,
-+                                              "socket:", hctx->proc->connection_name,
-                                               "load:", hctx->proc->load);
-                       }
-               }
-       }
--      
-+
-       handler_ctx_free(hctx);
--      con->plugin_ctx[p->id] = NULL;  
-+      con->plugin_ctx[p->id] = NULL;
- }
- static int fcgi_reconnect(server *srv, handler_ctx *hctx) {
-       plugin_data *p    = hctx->plugin_data;
--      
--      /* child died 
--       * 
--       * 1. 
--       * 
-+
-+      /* child died
-+       *
-+       * 1.
-+       *
-        * connect was ok, connection was accepted
-        * but the php accept loop checks after the accept if it should die or not.
--       * 
--       * if yes we can only detect it at a write() 
--       * 
-+       *
-+       * if yes we can only detect it at a write()
-+       *
-        * next step is resetting this attemp and setup a connection again
--       * 
-+       *
-        * if we have more then 5 reconnects for the same request, die
--       * 
--       * 2. 
--       * 
-+       *
-+       * 2.
-+       *
-        * we have a connection but the child died by some other reason
--       * 
-+       *
-        */
--      if (hctx->fd != -1) {
--              fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
--              fdevent_unregister(srv->ev, hctx->fd);
--              close(hctx->fd);
-+      if (hctx->sock->fd != -1) {
-+              fdevent_event_del(srv->ev, hctx->sock);
-+              fdevent_unregister(srv->ev, hctx->sock);
-+              close(hctx->sock->fd);
-               srv->cur_fds--;
--              hctx->fd = -1;
-+              hctx->sock->fd = -1;
-       }
--      
-+
-       fcgi_requestid_del(srv, p, hctx->request_id);
--      
-+
-       fcgi_set_state(srv, hctx, FCGI_STATE_INIT);
--      
-+
-       hctx->request_id = 0;
-       hctx->reconnects++;
--      
-+
-       if (p->conf.debug > 2) {
-               if (hctx->proc) {
-                       log_error_write(srv, __FILE__, __LINE__, "sdb",
--                                      "release proc for reconnect:", 
-+                                      "release proc for reconnect:",
-                                       hctx->proc->pid, hctx->proc->connection_name);
-               } else {
-                       log_error_write(srv, __FILE__, __LINE__, "sb",
--                                      "release proc for reconnect:", 
-+                                      "release proc for reconnect:",
-                                       hctx->host->unixsocket);
-               }
-       }
--      if (hctx->proc && hctx->got_proc) {     
-+      if (hctx->proc && hctx->got_proc) {
-               hctx->proc->load--;
-       }
-       /* perhaps another host gives us more luck */
-       hctx->host->load--;
-       hctx->host = NULL;
--      
-+
-       return 0;
- }
- static handler_t fcgi_connection_reset(server *srv, connection *con, void *p_d) {
-       plugin_data *p = p_d;
--      
-+
-       fcgi_connection_close(srv, con->plugin_ctx[p->id]);
--      
-+
-       return HANDLER_GO_ON;
- }
- static int fcgi_env_add(buffer *env, const char *key, size_t key_len, const char *val, size_t val_len) {
-       size_t len;
--      
-+
-       if (!key || !val) return -1;
--      
-+
-       len = key_len + val_len;
--      
-+
-       len += key_len > 127 ? 4 : 1;
-       len += val_len > 127 ? 4 : 1;
--      
-+
-       buffer_prepare_append(env, len);
--      
-+
-       if (key_len > 127) {
-               env->ptr[env->used++] = ((key_len >> 24) & 0xff) | 0x80;
-               env->ptr[env->used++] = (key_len >> 16) & 0xff;
-@@ -1612,7 +1567,7 @@
-       } else {
-               env->ptr[env->used++] = (key_len >> 0) & 0xff;
-       }
--      
-+
-       if (val_len > 127) {
-               env->ptr[env->used++] = ((val_len >> 24) & 0xff) | 0x80;
-               env->ptr[env->used++] = (val_len >> 16) & 0xff;
-@@ -1621,12 +1576,12 @@
-       } else {
-               env->ptr[env->used++] = (val_len >> 0) & 0xff;
-       }
--      
-+
-       memcpy(env->ptr + env->used, key, key_len);
-       env->used += key_len;
-       memcpy(env->ptr + env->used, val, val_len);
-       env->used += val_len;
--      
-+
-       return 0;
- }
-@@ -1639,11 +1594,11 @@
-       header->contentLengthB1 = (contentLength >> 8) & 0xff;
-       header->paddingLength = paddingLength;
-       header->reserved = 0;
--      
-+
-       return 0;
- }
- /**
-- * 
-+ *
-  * returns
-  *   -1 error
-  *    0 connected
-@@ -1665,26 +1620,23 @@
-       struct sockaddr_un fcgi_addr_un;
- #endif
-       socklen_t servlen;
--      
-+
-       fcgi_extension_host *host = hctx->host;
-       fcgi_proc *proc   = hctx->proc;
--      int fcgi_fd       = hctx->fd;
--      
-+      int fcgi_fd       = hctx->sock->fd;
-+
-       memset(&fcgi_addr, 0, sizeof(fcgi_addr));
--      
-+
-       if (!buffer_is_empty(proc->unixsocket)) {
- #ifdef HAVE_SYS_UN_H
-               /* use the unix domain socket */
-               fcgi_addr_un.sun_family = AF_UNIX;
-               strcpy(fcgi_addr_un.sun_path, proc->unixsocket->ptr);
--#ifdef SUN_LEN
-+
-               servlen = SUN_LEN(&fcgi_addr_un);
--#else
--              /* stevens says: */
--              servlen = proc->unixsocket->used + sizeof(fcgi_addr_un.sun_family);
--#endif
-+
-               fcgi_addr = (struct sockaddr *) &fcgi_addr_un;
--      
-+
-               if (buffer_is_empty(proc->connection_name)) {
-                       /* on remote spawing we have to set the connection-name now */
-                       buffer_copy_string(proc->connection_name, "unix:");
-@@ -1695,16 +1647,18 @@
- #endif
-       } else {
-               fcgi_addr_in.sin_family = AF_INET;
-+
-               if (0 == inet_aton(host->host->ptr, &(fcgi_addr_in.sin_addr))) {
--                      log_error_write(srv, __FILE__, __LINE__, "sbs", 
--                                      "converting IP-adress failed for", host->host, 
-+                      log_error_write(srv, __FILE__, __LINE__, "sbs",
-+                                      "converting IP-adress failed for", host->host,
-                                       "\nBe sure to specify an IP address here");
--                      
-+
-                       return -1;
-               }
-+
-               fcgi_addr_in.sin_port = htons(proc->port);
-               servlen = sizeof(fcgi_addr_in);
--              
-+
-               fcgi_addr = (struct sockaddr *) &fcgi_addr_in;
-               if (buffer_is_empty(proc->connection_name)) {
-@@ -1715,20 +1669,20 @@
-                       buffer_append_long(proc->connection_name, proc->port);
-               }
-       }
--      
-+
-       if (-1 == connect(fcgi_fd, fcgi_addr, servlen)) {
--              if (errno == EINPROGRESS || 
-+              if (errno == EINPROGRESS ||
-                   errno == EALREADY ||
-                   errno == EINTR) {
-                       if (hctx->conf.debug > 2) {
--                              log_error_write(srv, __FILE__, __LINE__, "sb", 
-+                              log_error_write(srv, __FILE__, __LINE__, "sb",
-                                       "connect delayed, will continue later:", proc->connection_name);
-                       }
--                      
-+
-                       return CONNECTION_DELAYED;
-               } else if (errno == EAGAIN) {
-                       if (hctx->conf.debug) {
--                              log_error_write(srv, __FILE__, __LINE__, "sbsd", 
-+                              log_error_write(srv, __FILE__, __LINE__, "sbsd",
-                                       "This means that the you have more incoming requests than your fastcgi-backend can handle in parallel. "
-                                       "Perhaps it helps to spawn more fastcgi backend or php-children, if not decrease server.max-connections."
-                                       "The load for this fastcgi backend", proc->connection_name, "is", proc->load);
-@@ -1736,8 +1690,8 @@
-                       return CONNECTION_OVERLOADED;
-               } else {
--                      log_error_write(srv, __FILE__, __LINE__, "sssb", 
--                                      "connect failed:", 
-+                      log_error_write(srv, __FILE__, __LINE__, "sssb",
-+                                      "connect failed:",
-                                       strerror(errno), "on",
-                                       proc->connection_name);
-@@ -1747,7 +1701,7 @@
-       hctx->reconnects = 0;
-       if (hctx->conf.debug > 1) {
--              log_error_write(srv, __FILE__, __LINE__, "sd", 
-+              log_error_write(srv, __FILE__, __LINE__, "sd",
-                               "connect succeeded: ", fcgi_fd);
-       }
-@@ -1756,21 +1710,21 @@
- static int fcgi_env_add_request_headers(server *srv, connection *con, plugin_data *p) {
-       size_t i;
--      
-+
-       for (i = 0; i < con->request.headers->used; i++) {
-               data_string *ds;
--              
-+
-               ds = (data_string *)con->request.headers->data[i];
--              
-+
-               if (ds->value->used && ds->key->used) {
-                       size_t j;
-                       buffer_reset(srv->tmp_buf);
--                      
-+
-                       if (0 != strcasecmp(ds->key->ptr, "CONTENT-TYPE")) {
-                               BUFFER_COPY_STRING_CONST(srv->tmp_buf, "HTTP_");
-                               srv->tmp_buf->used--;
-                       }
--                      
-+
-                       buffer_prepare_append(srv->tmp_buf, ds->key->used + 2);
-                       for (j = 0; j < ds->key->used - 1; j++) {
-                               char c = '_';
-@@ -1784,20 +1738,20 @@
-                               srv->tmp_buf->ptr[srv->tmp_buf->used++] = c;
-                       }
-                       srv->tmp_buf->ptr[srv->tmp_buf->used++] = '\0';
--                      
-+
-                       fcgi_env_add(p->fcgi_env, CONST_BUF_LEN(srv->tmp_buf), CONST_BUF_LEN(ds->value));
-               }
-       }
--      
-+
-       for (i = 0; i < con->environment->used; i++) {
-               data_string *ds;
--              
-+
-               ds = (data_string *)con->environment->data[i];
--              
-+
-               if (ds->value->used && ds->key->used) {
-                       size_t j;
-                       buffer_reset(srv->tmp_buf);
--                      
-+
-                       buffer_prepare_append(srv->tmp_buf, ds->key->used + 2);
-                       for (j = 0; j < ds->key->used - 1; j++) {
-                               char c = '_';
-@@ -1811,11 +1765,11 @@
-                               srv->tmp_buf->ptr[srv->tmp_buf->used++] = c;
-                       }
-                       srv->tmp_buf->ptr[srv->tmp_buf->used++] = '\0';
--                      
-+
-                       fcgi_env_add(p->fcgi_env, CONST_BUF_LEN(srv->tmp_buf), CONST_BUF_LEN(ds->value));
-               }
-       }
--      
-+
-       return 0;
- }
-@@ -1824,24 +1778,24 @@
-       FCGI_BeginRequestRecord beginRecord;
-       FCGI_Header header;
-       buffer *b;
--      
-+
-       char buf[32];
-       const char *s;
- #ifdef HAVE_IPV6
-       char b2[INET6_ADDRSTRLEN + 1];
- #endif
--      
-+
-       plugin_data *p    = hctx->plugin_data;
-       fcgi_extension_host *host= hctx->host;
-       connection *con   = hctx->remote_conn;
-       server_socket *srv_sock = con->srv_socket;
--      
-+
-       sock_addr our_addr;
-       socklen_t our_addr_len;
--      
-+
-       /* send FCGI_BEGIN_REQUEST */
--      
-+
-       fcgi_header(&(beginRecord.header), FCGI_BEGIN_REQUEST, request_id, sizeof(beginRecord.body), 0);
-       beginRecord.body.roleB0 = host->mode;
-       beginRecord.body.roleB1 = 0;
-@@ -1849,21 +1803,21 @@
-       memset(beginRecord.body.reserved, 0, sizeof(beginRecord.body.reserved));
-       b = chunkqueue_get_append_buffer(hctx->wb);
--      
-+
-       buffer_copy_memory(b, (const char *)&beginRecord, sizeof(beginRecord));
--      
-+
-       /* send FCGI_PARAMS */
-       buffer_prepare_copy(p->fcgi_env, 1024);
-       fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_SOFTWARE"), CONST_STR_LEN(PACKAGE_NAME"/"PACKAGE_VERSION));
--      
-+
-       if (con->server_name->used) {
-               fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_NAME"), CONST_BUF_LEN(con->server_name));
-       } else {
- #ifdef HAVE_IPV6
--              s = inet_ntop(srv_sock->addr.plain.sa_family, 
--                            srv_sock->addr.plain.sa_family == AF_INET6 ? 
-+              s = inet_ntop(srv_sock->addr.plain.sa_family,
-+                            srv_sock->addr.plain.sa_family == AF_INET6 ?
-                             (const void *) &(srv_sock->addr.ipv6.sin6_addr) :
-                             (const void *) &(srv_sock->addr.ipv4.sin_addr),
-                             b2, sizeof(b2)-1);
-@@ -1872,50 +1826,50 @@
- #endif
-               fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_NAME"), s, strlen(s));
-       }
--      
-+
-       fcgi_env_add(p->fcgi_env, CONST_STR_LEN("GATEWAY_INTERFACE"), CONST_STR_LEN("CGI/1.1"));
--      
--      ltostr(buf, 
-+
-+      ltostr(buf,
- #ifdef HAVE_IPV6
-              ntohs(srv_sock->addr.plain.sa_family ? srv_sock->addr.ipv6.sin6_port : srv_sock->addr.ipv4.sin_port)
- #else
-              ntohs(srv_sock->addr.ipv4.sin_port)
- #endif
-              );
--      
-+
-       fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_PORT"), buf, strlen(buf));
--      
-+
-       /* get the server-side of the connection to the client */
-       our_addr_len = sizeof(our_addr);
--      
--      if (-1 == getsockname(con->fd, &(our_addr.plain), &our_addr_len)) {
-+
-+      if (-1 == getsockname(con->sock->fd, &(our_addr.plain), &our_addr_len)) {
-               s = inet_ntop_cache_get_ip(srv, &(srv_sock->addr));
-       } else {
-               s = inet_ntop_cache_get_ip(srv, &(our_addr));
-       }
-       fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_ADDR"), s, strlen(s));
--      
--      ltostr(buf, 
-+
-+      ltostr(buf,
- #ifdef HAVE_IPV6
-              ntohs(con->dst_addr.plain.sa_family ? con->dst_addr.ipv6.sin6_port : con->dst_addr.ipv4.sin_port)
- #else
-              ntohs(con->dst_addr.ipv4.sin_port)
- #endif
-              );
--      
-+
-       fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REMOTE_PORT"), buf, strlen(buf));
--      
-+
-       s = inet_ntop_cache_get_ip(srv, &(con->dst_addr));
-       fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REMOTE_ADDR"), s, strlen(s));
--      
-+
-       if (!buffer_is_empty(con->authed_user)) {
-               fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REMOTE_USER"),
-                            CONST_BUF_LEN(con->authed_user));
-       }
--      
-+
-       if (con->request.content_length > 0 && host->mode != FCGI_AUTHORIZER) {
-               /* CGI-SPEC 6.1.2 and FastCGI spec 6.3 */
--              
-+
-               /* request.content_length < SSIZE_MAX, see request.c */
-               ltostr(buf, con->request.content_length);
-               fcgi_env_add(p->fcgi_env, CONST_STR_LEN("CONTENT_LENGTH"), buf, strlen(buf));
-@@ -1930,12 +1884,12 @@
-                */
-               fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SCRIPT_NAME"), CONST_BUF_LEN(con->uri.path));
--              
-+
-               if (!buffer_is_empty(con->request.pathinfo)) {
-                       fcgi_env_add(p->fcgi_env, CONST_STR_LEN("PATH_INFO"), CONST_BUF_LEN(con->request.pathinfo));
--                      
-+
-                       /* PATH_TRANSLATED is only defined if PATH_INFO is set */
--                      
-+
-                       if (!buffer_is_empty(host->docroot)) {
-                               buffer_copy_string_buffer(p->path, host->docroot);
-                       } else {
-@@ -1957,27 +1911,27 @@
-        */
-       if (!buffer_is_empty(host->docroot)) {
--              /* 
--               * rewrite SCRIPT_FILENAME 
--               * 
-+              /*
-+               * rewrite SCRIPT_FILENAME
-+               *
-                */
--              
-+
-               buffer_copy_string_buffer(p->path, host->docroot);
-               buffer_append_string_buffer(p->path, con->uri.path);
--              
-+
-               fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SCRIPT_FILENAME"), CONST_BUF_LEN(p->path));
-               fcgi_env_add(p->fcgi_env, CONST_STR_LEN("DOCUMENT_ROOT"), CONST_BUF_LEN(host->docroot));
-       } else {
-               buffer_copy_string_buffer(p->path, con->physical.path);
--              
--              /* cgi.fix_pathinfo need a broken SCRIPT_FILENAME to find out what PATH_INFO is itself 
--               * 
-+
-+              /* cgi.fix_pathinfo need a broken SCRIPT_FILENAME to find out what PATH_INFO is itself
-+               *
-                * see src/sapi/cgi_main.c, init_request_info()
-                */
-               if (host->break_scriptfilename_for_php) {
-                       buffer_append_string_buffer(p->path, con->request.pathinfo);
-               }
--              
-+
-               fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SCRIPT_FILENAME"), CONST_BUF_LEN(p->path));
-               fcgi_env_add(p->fcgi_env, CONST_STR_LEN("DOCUMENT_ROOT"), CONST_BUF_LEN(con->physical.doc_root));
-       }
-@@ -1987,7 +1941,7 @@
-               /**
-                * /app1/index/list
-                *
--               * stripping /app1 or /app1/ should lead to 
-+               * stripping /app1 or /app1/ should lead to
-                *
-                * /index/list
-                *
-@@ -2001,7 +1955,7 @@
-                   0 == strncmp(con->request.orig_uri->ptr, host->strip_request_uri->ptr, host->strip_request_uri->used - 1)) {
-                       /* the left is the same */
--                      fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REQUEST_URI"), 
-+                      fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REQUEST_URI"),
-                                       con->request.orig_uri->ptr + (host->strip_request_uri->used - 2),
-                                       con->request.orig_uri->used - (host->strip_request_uri->used - 2));
-               } else {
-@@ -2018,26 +1972,26 @@
-       } else {
-               fcgi_env_add(p->fcgi_env, CONST_STR_LEN("QUERY_STRING"), CONST_STR_LEN(""));
-       }
--      
-+
-       s = get_http_method_name(con->request.http_method);
-       fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REQUEST_METHOD"), s, strlen(s));
-       fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REDIRECT_STATUS"), CONST_STR_LEN("200")); /* if php is compiled with --force-redirect */
-       s = get_http_version_name(con->request.http_version);
-       fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_PROTOCOL"), s, strlen(s));
--      
-+
- #ifdef USE_OPENSSL
-       if (srv_sock->is_ssl) {
-               fcgi_env_add(p->fcgi_env, CONST_STR_LEN("HTTPS"), CONST_STR_LEN("on"));
-       }
- #endif
--      
--      
-+
-+
-       fcgi_env_add_request_headers(srv, con, p);
--      
-+
-       fcgi_header(&(header), FCGI_PARAMS, request_id, p->fcgi_env->used, 0);
-       buffer_append_memory(b, (const char *)&header, sizeof(header));
-       buffer_append_memory(b, (const char *)p->fcgi_env->ptr, p->fcgi_env->used);
--      
-+
-       fcgi_header(&(header), FCGI_PARAMS, request_id, 0, 0);
-       buffer_append_memory(b, (const char *)&header, sizeof(header));
-@@ -2045,7 +1999,7 @@
-       hctx->wb->bytes_in += b->used - 1;
-       if (con->request.content_length) {
--              chunkqueue *req_cq = con->request_content_queue;
-+              chunkqueue *req_cq = con->recv;
-               chunk *req_c;
-               off_t offset;
-@@ -2057,7 +2011,7 @@
-                       /* we announce toWrite octects
-                        * now take all the request_content chunk that we need to fill this request
--                       * */   
-+                       * */
-                       b = chunkqueue_get_append_buffer(hctx->wb);
-                       fcgi_header(&(header), FCGI_STDIN, request_id, weWant, 0);
-@@ -2080,16 +2034,16 @@
-                                       if (weHave > weWant - written) weHave = weWant - written;
-                                       if (p->conf.debug > 10) {
--                                              fprintf(stderr, "%s.%d: sending %lld bytes from (%lld / %lld) %s\n", 
--                                                              __FILE__, __LINE__, 
--                                                              weHave, 
--                                                              req_c->offset, 
--                                                              req_c->file.length, 
-+                                              fprintf(stderr, "%s.%d: sending %lld bytes from (%lld / %lld) %s\n",
-+                                                              __FILE__, __LINE__,
-+                                                              weHave,
-+                                                              req_c->offset,
-+                                                              req_c->file.length,
-                                                               req_c->file.name->ptr);
-                                       }
-                                       assert(weHave != 0);
--                                      
-+
-                                       chunkqueue_append_file(hctx->wb, req_c->file.name, req_c->offset, weHave);
-                                       req_c->offset += weHave;
-@@ -2104,7 +2058,7 @@
-                                        * - we reference the tempfile from the request-content-queue several times
-                                        *   if the req_c is larger than FCGI_MAX_LENGTH
-                                        * - we can't simply cleanup the request-content-queue as soon as possible
--                                       *   as it would remove the tempfiles 
-+                                       *   as it would remove the tempfiles
-                                        * - the idea is to 'steal' the tempfiles and attach the is_temp flag to the last
-                                        *   referencing chunk of the fastcgi-write-queue
-                                        *
-@@ -2141,7 +2095,7 @@
-                                       req_c->offset += weHave;
-                                       req_cq->bytes_out += weHave;
-                                       written += weHave;
--                                      
-+
-                                       hctx->wb->bytes_in += weHave;
-                                       if (req_c->offset == req_c->mem->used - 1) {
-@@ -2155,12 +2109,12 @@
-                                       break;
-                               }
-                       }
--                      
-+
-                       b->used++; /* add virtual \0 */
-                       offset += weWant;
-               }
-       }
--      
-+
-       b = chunkqueue_get_append_buffer(hctx->wb);
-       /* terminate STDIN */
-       fcgi_header(&(header), FCGI_STDIN, request_id, 0, 0);
-@@ -2175,118 +2129,19 @@
-               if ((i+1) % 16 == 0) {
-                       size_t j;
-                       for (j = i-15; j <= i; j++) {
--                              fprintf(stderr, "%c", 
-+                              fprintf(stderr, "%c",
-                                       isprint((unsigned char)hctx->write_buffer->ptr[j]) ? hctx->write_buffer->ptr[j] : '.');
-                       }
-                       fprintf(stderr, "\n");
-               }
-       }
- #endif
--      
--      return 0;
--}
--static int fcgi_response_parse(server *srv, connection *con, plugin_data *p, buffer *in) {
--      char *s, *ns;
--      
--      handler_ctx *hctx = con->plugin_ctx[p->id];
--      fcgi_extension_host *host= hctx->host;
--      
--      UNUSED(srv);
--
--      buffer_copy_string_buffer(p->parse_response, in);
--      
--      /* search for \n */
--      for (s = p->parse_response->ptr; NULL != (ns = strchr(s, '\n')); s = ns + 1) {
--              char *key, *value;
--              int key_len;
--              data_string *ds;
--              
--              /* a good day. Someone has read the specs and is sending a \r\n to us */
--              
--              if (ns > p->parse_response->ptr &&
--                  *(ns-1) == '\r') {
--                      *(ns-1) = '\0';
--              }
--              
--              ns[0] = '\0';
--              
--              key = s;
--              if (NULL == (value = strchr(s, ':'))) {
--                      /* we expect: "<key>: <value>\n" */
--                      continue;
--              }
--              
--              key_len = value - key;
--              
--              value++;
--              /* strip WS */
--              while (*value == ' ' || *value == '\t') value++;
--              
--              if (host->mode != FCGI_AUTHORIZER ||
--                  !(con->http_status == 0 ||
--                    con->http_status == 200)) {
--                      /* authorizers shouldn't affect the response headers sent back to the client */
--                      
--                      /* don't forward Status: */
--                      if (0 != strncasecmp(key, "Status", key_len)) {
--                              if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
--                                      ds = data_response_init();
--                              }
--                              buffer_copy_string_len(ds->key, key, key_len);
--                              buffer_copy_string(ds->value, value);
--                              
--                              array_insert_unique(con->response.headers, (data_unset *)ds);
--                      }
--              }
--              
--              switch(key_len) {
--              case 4:
--                      if (0 == strncasecmp(key, "Date", key_len)) {
--                              con->parsed_response |= HTTP_DATE;
--                      }
--                      break;
--              case 6:
--                      if (0 == strncasecmp(key, "Status", key_len)) {
--                              con->http_status = strtol(value, NULL, 10);
--                              con->parsed_response |= HTTP_STATUS;
--                      }
--                      break;
--              case 8:
--                      if (0 == strncasecmp(key, "Location", key_len)) {
--                              con->parsed_response |= HTTP_LOCATION;
--                      }
--                      break;
--              case 10:
--                      if (0 == strncasecmp(key, "Connection", key_len)) {
--                              con->response.keep_alive = (0 == strcasecmp(value, "Keep-Alive")) ? 1 : 0;
--                              con->parsed_response |= HTTP_CONNECTION;
--                      }
--                      break;
--              case 14:
--                      if (0 == strncasecmp(key, "Content-Length", key_len)) {
--                              con->response.content_length = strtol(value, NULL, 10);
--                              con->parsed_response |= HTTP_CONTENT_LENGTH;
--                              
--                              if (con->response.content_length < 0) con->response.content_length = 0;
--                      }
--                      break;
--              default:
--                      break;
--              }
--      }
--      
--      /* CGI/1.1 rev 03 - 7.2.1.2 */
--      if ((con->parsed_response & HTTP_LOCATION) &&
--          !(con->parsed_response & HTTP_STATUS)) {
--              con->http_status = 302;
--      }
--      
-       return 0;
- }
- typedef struct {
--      buffer  *b; 
-+      buffer  *b;
-       size_t   len;
-       int      type;
-       int      padding;
-@@ -2327,9 +2182,9 @@
-               return -1;
-       }
--      /* we have at least a header, now check how much me have to fetch */ 
-+      /* we have at least a header, now check how much me have to fetch */
-       header = (FCGI_Header *)(packet->b->ptr);
--                      
-+
-       packet->len = (header->contentLengthB0 | (header->contentLengthB1 << 8)) + header->paddingLength;
-       packet->request_id = (header->requestIdB0 | (header->requestIdB1 << 8));
-       packet->type = header->type;
-@@ -2348,7 +2203,7 @@
-                       size_t weHave = c->mem->used - c->offset - offset - 1;
-                       if (weHave > weWant) weHave = weWant;
--                                              
-+
-                       buffer_append_string_len(packet->b, c->mem->ptr + c->offset + offset, weHave);
-                       /* we only skipped the first 8 bytes as they are the fcgi header */
-@@ -2380,65 +2235,42 @@
-       }
-       chunkqueue_remove_finished_chunks(hctx->rb);
--      
-+
-       return 0;
- }
- static int fcgi_demux_response(server *srv, handler_ctx *hctx) {
-       int fin = 0;
--      int toread;
--      ssize_t r;
--      
-+
-       plugin_data *p    = hctx->plugin_data;
-       connection *con   = hctx->remote_conn;
--      int fcgi_fd       = hctx->fd;
-       fcgi_extension_host *host= hctx->host;
-       fcgi_proc *proc   = hctx->proc;
--      
--      /* 
--       * check how much we have to read 
--       */
--      if (ioctl(hctx->fd, FIONREAD, &toread)) {
--              log_error_write(srv, __FILE__, __LINE__, "sd", 
--                              "unexpected end-of-file (perhaps the fastcgi process died):",
--                              fcgi_fd);
--              return -1;
--      }
--      
--      /* init read-buffer */
--      
--      if (toread > 0) {
--              buffer *b;
--
--              b = chunkqueue_get_append_buffer(hctx->rb);
--              buffer_prepare_copy(b, toread + 1);
--
--              /* append to read-buffer */
--              if (-1 == (r = read(hctx->fd, b->ptr, toread))) {
--                      log_error_write(srv, __FILE__, __LINE__, "sds", 
--                                      "unexpected end-of-file (perhaps the fastcgi process died):",
--                                      fcgi_fd, strerror(errno));
--                      return -1;
--              }
--              
--              /* this should be catched by the b > 0 above */
--              assert(r);
-+      handler_t ret;
--              b->used = r + 1; /* one extra for the fake \0 */
--              b->ptr[b->used - 1] = '\0';
--      } else {
--              log_error_write(srv, __FILE__, __LINE__, "ssdsb", 
--                              "unexpected end-of-file (perhaps the fastcgi process died):",
--                              "pid:", proc->pid,
--                              "socket:", proc->connection_name);
--              
-+      /* in case we read nothing, check the return code
-+       * if we got something, be happy :)
-+       *
-+       * Ok, to be honest:
-+       * - it is fine to receive a EAGAIN on a second read() call
-+       * - it might be fine they we get a con-close on a second read() call */
-+      switch(srv->network_backend_read(srv, con, hctx->sock, hctx->rb)) {
-+      case NETWORK_STATUS_WAIT_FOR_EVENT:
-+              /* a EAGAIN after we read exactly the chunk-size */
-+
-+              ERROR("%s", "oops, got a EAGAIN even if we just got call for the event, wired");
-+              return -1;
-+      case NETWORK_STATUS_SUCCESS:
-+              break;
-+      default:
-+              ERROR("reading from fastcgi socket failed (fd=%d)", hctx->sock->fd);
-               return -1;
-       }
-       /*
-        * parse the fastcgi packets and forward the content to the write-queue
-        *
--       */     
-+       */
-       while (fin == 0) {
-               fastcgi_response_packet packet;
-@@ -2454,132 +2286,165 @@
-                       /* is the header already finished */
-                       if (0 == con->file_started) {
--                              char *c;
--                              size_t blen;
--                              data_string *ds;
--                                      
--                              /* search for header terminator 
--                               * 
--                               * if we start with \r\n check if last packet terminated with \r\n
--                               * if we start with \n check if last packet terminated with \n
--                               * search for \r\n\r\n
--                               * search for \n\n
--                               */
--
--                              if (hctx->response_header->used == 0) {
--                                      buffer_copy_string_buffer(hctx->response_header, packet.b);
--                              } else {
--                                      buffer_append_string_buffer(hctx->response_header, packet.b);
--                              }
--
--                              if (NULL != (c = buffer_search_string_len(hctx->response_header, CONST_STR_LEN("\r\n\r\n")))) {
--                                      blen = hctx->response_header->used - (c - hctx->response_header->ptr) - 4;
--                                      hctx->response_header->used = (c - hctx->response_header->ptr) + 3;
--                                      c += 4; /* point the the start of the response */
--                              } else if (NULL != (c = buffer_search_string_len(hctx->response_header, CONST_STR_LEN("\n\n")))) {
--                                      blen = hctx->response_header->used - (c - hctx->response_header->ptr) - 2;
--                                      hctx->response_header->used = c - hctx->response_header->ptr + 2;
--                                      c += 2; /* point the the start of the response */
--                              } else {
--                                      /* no luck, no header found */
-+                              int have_content_length = 0;
-+                              int need_more = 0;
-+                              size_t i;
-+
-+                              /* append the current packet to the chunk queue */
-+                              chunkqueue_append_buffer(hctx->http_rb, packet.b);
-+                              http_response_reset(p->resp);
-+
-+                              switch(http_response_parse_cq(hctx->http_rb, p->resp)) {
-+                              case PARSE_ERROR:
-+                                      /* parsing the response header failed */
-+
-+                                      con->http_status = 502; /* Bad Gateway */
-+
-+                                      return 1;
-+                              case PARSE_NEED_MORE:
-+                                      need_more = 1;
-+                                      break; /* leave the loop */
-+                              case PARSE_SUCCESS:
-                                       break;
-+                              default:
-+                                      /* should not happen */
-+                                      SEGFAULT();
-                               }
--                              /* parse the response header */
--                              fcgi_response_parse(srv, con, p, hctx->response_header);
-+                              if (need_more) break;
--                              con->file_started = 1;
-+                              chunkqueue_remove_finished_chunks(hctx->http_rb);
--                              if (host->mode == FCGI_AUTHORIZER &&
--                                  (con->http_status == 0 ||
--                                   con->http_status == 200)) {
--                                      /* a authorizer with approved the static request, ignore the content here */
--                                      hctx->send_content_body = 0;
--                              }
--
--                              if (host->allow_xsendfile &&
--                                  NULL != (ds = (data_string *) array_get_element(con->response.headers, "X-LIGHTTPD-send-file"))) {
--                                      stat_cache_entry *sce;
--
--                                      if (HANDLER_ERROR != stat_cache_get_entry(srv, con, ds->value, &sce)) {
--                                              /* found */
--
--                                              http_chunk_append_file(srv, con, ds->value, 0, sce->st.st_size);
--                                              hctx->send_content_body = 0; /* ignore the content */
--                                              joblist_append(srv, con);
-+                              con->http_status = p->resp->status;
-+                              hctx->send_content_body = 1;
-+
-+                              /* handle the header fields */
-+                              if (host->mode == FCGI_AUTHORIZER) {
-+                                      /* auth mode is a bit different */
-+
-+                                      if (con->http_status == 0 ||
-+                                          con->http_status == 200) {
-+                                              /* a authorizer with approved the static request, ignore the content here */
-+                                              hctx->send_content_body = 0;
-                                       }
-                               }
-+                              /* copy the http-headers */
-+                              for (i = 0; i < p->resp->headers->used; i++) {
-+                                      const char *ign[] = { "Status", NULL };
-+                                      size_t j;
-+                                      data_string *ds;
-+
-+                                      data_string *header = (data_string *)p->resp->headers->data[i];
-+
-+                                      /* ignore all headers in AUTHORIZER mode */
-+                                      if (host->mode == FCGI_AUTHORIZER) continue;
-+
-+                                      /* some headers are ignored by default */
-+                                      for (j = 0; ign[j]; j++) {
-+                                              if (0 == strcasecmp(ign[j], header->key->ptr)) break;
-+                                      }
-+                                      if (ign[j]) continue;
-+
-+                                      if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("Location"))) {
-+                                              /* CGI/1.1 rev 03 - 7.2.1.2 */
-+                                              con->http_status = 302;
-+                                      } else if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("Content-Length"))) {
-+                                              have_content_length = 1;
-+                                      } else if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("X-Sendfile")) || 
-+                                                 0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("X-LIGHTTPD-send-file"))) {
-                                               
--                              if (hctx->send_content_body && blen > 1) {                                              
--                                      /* enable chunked-transfer-encoding */
--                                      if (con->request.http_version == HTTP_VERSION_1_1 &&
--                                          !(con->parsed_response & HTTP_CONTENT_LENGTH)) {
--                                              con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
-+                                              stat_cache_entry *sce;
-+                                              
-+                                              if (host->allow_xsendfile &&
-+                                                  HANDLER_ERROR != stat_cache_get_entry(srv, con, header->value, &sce)) {
-+                                                      chunkqueue_append_file(con->send, header->value, 0, sce->st.st_size);
-+                                                      hctx->send_content_body = 0; /* ignore the content */
-+                                      
-+                                                      joblist_append(srv, con);
-+                                              }
-+
-+                                              continue; /* ignore header */
-                                       }
-+                                      
-+                                      if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
-+                                              ds = data_response_init();
-+                                      }
-+                                      buffer_copy_string_buffer(ds->key, header->key);
-+                                      buffer_copy_string_buffer(ds->value, header->value);
--                                      http_chunk_append_mem(srv, con, c, blen);
-+                                      array_insert_unique(con->response.headers, (data_unset *)ds);
-+                              }
-+
-+                              /* header is complete ... go on with the body */
-+
-+                              con->file_started = 1;
-+
-+                              if (hctx->send_content_body) {
-+                                      chunk *c = hctx->http_rb->first;
-+
-+                                      /* copy the rest of the data */
-+                                      for (c = hctx->http_rb->first; c; c = c->next) {
-+                                              if (c->mem->used > 1) {
-+                                                      chunkqueue_append_mem(con->send, c->mem->ptr + c->offset, c->mem->used - c->offset);
-+                                                      c->offset = c->mem->used - 1;
-+                                              }
-+                                      }
-+                                      chunkqueue_remove_finished_chunks(hctx->http_rb);
-                                       joblist_append(srv, con);
-                               }
-                       } else if (hctx->send_content_body && packet.b->used > 1) {
--                              if (con->request.http_version == HTTP_VERSION_1_1 &&
--                                  !(con->parsed_response & HTTP_CONTENT_LENGTH)) {
--                                      /* enable chunked-transfer-encoding */
--                                      con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
--                              }
--
--                              http_chunk_append_mem(srv, con, packet.b->ptr, packet.b->used);
-+                              chunkqueue_append_mem(con->send, packet.b->ptr, packet.b->used);
-                               joblist_append(srv, con);
-                       }
-                       break;
-               case FCGI_STDERR:
--                      log_error_write(srv, __FILE__, __LINE__, "sb", 
-+                      log_error_write(srv, __FILE__, __LINE__, "sb",
-                                       "FastCGI-stderr:", packet.b);
--                      
-+
-                       break;
-               case FCGI_END_REQUEST:
--                      con->file_finished = 1;
--                      
-+                      con->send->is_closed = 1;
-+
-                       if (host->mode != FCGI_AUTHORIZER ||
-                           !(con->http_status == 0 ||
-                             con->http_status == 200)) {
-                               /* send chunk-end if nesseary */
--                              http_chunk_append_mem(srv, con, NULL, 0);
-                               joblist_append(srv, con);
-                       }
--                      
-+
-                       fin = 1;
-                       break;
-               default:
--                      log_error_write(srv, __FILE__, __LINE__, "sd", 
-+                      log_error_write(srv, __FILE__, __LINE__, "sd",
-                                       "FastCGI: header.type not handled: ", packet.type);
-                       break;
-               }
-               buffer_free(packet.b);
-       }
--      
-+
-       return fin;
- }
- static int fcgi_restart_dead_procs(server *srv, plugin_data *p, fcgi_extension_host *host) {
-       fcgi_proc *proc;
--      
-+
-       for (proc = host->first; proc; proc = proc->next) {
-               int status;
-               if (p->conf.debug > 2) {
--                      log_error_write(srv, __FILE__, __LINE__,  "sbdddd", 
--                                      "proc:", 
-+                      log_error_write(srv, __FILE__, __LINE__,  "sbdddd",
-+                                      "proc:",
-                                       proc->connection_name,
-                                       proc->state,
-                                       proc->is_local,
-                                       proc->load,
-                                       proc->pid);
-               }
--              
--              /* 
-+
-+              /*
-                * if the remote side is overloaded, we check back after <n> seconds
--               * 
-+               *
-                */
-               switch (proc->state) {
-               case PROC_STATE_KILLED:
-@@ -2592,13 +2457,13 @@
-                       break;
-               case PROC_STATE_OVERLOADED:
-                       if (srv->cur_ts <= proc->disabled_until) break;
--                      
-+
-                       proc->state = PROC_STATE_RUNNING;
-                       host->active_procs++;
--                      
--                      log_error_write(srv, __FILE__, __LINE__,  "sbdb", 
--                                      "fcgi-server re-enabled:", 
--                                      host->host, host->port, 
-+
-+                      log_error_write(srv, __FILE__, __LINE__,  "sbdb",
-+                                      "fcgi-server re-enabled:",
-+                                      host->host, host->port,
-                                       host->unixsocket);
-                       break;
-               case PROC_STATE_DIED_WAIT_FOR_PID:
-@@ -2606,7 +2471,7 @@
-                       if (!proc->is_local) break;
-                       /* the child should not terminate at all */
--                      
-+#ifndef _WIN32
-                       switch(waitpid(proc->pid, &status, WNOHANG)) {
-                       case 0:
-                               /* child is still alive */
-@@ -2616,45 +2481,45 @@
-                       default:
-                               if (WIFEXITED(status)) {
- #if 0
--                                      log_error_write(srv, __FILE__, __LINE__, "sdsd", 
-+                                      log_error_write(srv, __FILE__, __LINE__, "sdsd",
-                                                       "child exited, pid:", proc->pid,
-                                                       "status:", WEXITSTATUS(status));
- #endif
-                               } else if (WIFSIGNALED(status)) {
--                                      log_error_write(srv, __FILE__, __LINE__, "sd", 
--                                                      "child signaled:", 
-+                                      log_error_write(srv, __FILE__, __LINE__, "sd",
-+                                                      "child signaled:",
-                                                       WTERMSIG(status));
-                               } else {
--                                      log_error_write(srv, __FILE__, __LINE__, "sd", 
--                                                      "child died somehow:", 
-+                                      log_error_write(srv, __FILE__, __LINE__, "sd",
-+                                                      "child died somehow:",
-                                                       status);
-                               }
--                              
-+
-                               proc->state = PROC_STATE_DIED;
-                               break;
-                       }
--
-+#endif
-                       /* fall through if we have a dead proc now */
-                       if (proc->state != PROC_STATE_DIED) break;
-               case PROC_STATE_DIED:
--                      /* local proc get restarted by us, 
-+                      /* local proc get restarted by us,
-                        * remote ones hopefully by the admin */
--                      
-+
-                       if (proc->is_local) {
-                               /* we still have connections bound to this proc,
-                                * let them terminate first */
-                               if (proc->load != 0) break;
--                      
-+
-                               /* restart the child */
--                              
-+
-                               if (p->conf.debug) {
-                                       log_error_write(srv, __FILE__, __LINE__, "ssbsdsd",
-                                                       "--- fastcgi spawning",
-                                                       "\n\tsocket", proc->connection_name,
-                                                       "\n\tcurrent:", 1, "/", host->min_procs);
-                               }
--                              
-+
-                               if (fcgi_spawn_connection(srv, p, host, proc)) {
-                                       log_error_write(srv, __FILE__, __LINE__, "s",
-                                                       "ERROR: spawning fcgi failed.");
-@@ -2662,18 +2527,18 @@
-                               }
-                       } else {
-                               if (srv->cur_ts <= proc->disabled_until) break;
--                      
-+
-                               proc->state = PROC_STATE_RUNNING;
-                               host->active_procs++;
--                      
--                              log_error_write(srv, __FILE__, __LINE__,  "sb", 
--                                              "fcgi-server re-enabled:", 
-+
-+                              log_error_write(srv, __FILE__, __LINE__,  "sb",
-+                                              "fcgi-server re-enabled:",
-                                               proc->connection_name);
-                       }
-                       break;
-               }
-       }
--      
-+
-       return 0;
- }
-@@ -2682,19 +2547,19 @@
-       fcgi_extension_host *host= hctx->host;
-       connection *con   = hctx->remote_conn;
-       fcgi_proc  *proc;
--      
-+
-       int ret;
--      /* sanity check */      
-+      /* sanity check */
-       if (!host ||
-           ((!host->host->used || !host->port) && !host->unixsocket->used)) {
--              log_error_write(srv, __FILE__, __LINE__, "sxddd", 
-+              log_error_write(srv, __FILE__, __LINE__, "sxddd",
-                               "write-req: error",
-                               host,
-                               host->host->used,
-                               host->port,
-                               host->unixsocket->used);
--                      
-+
-               hctx->proc->disabled_until = srv->cur_ts + 10;
-               hctx->proc->state = PROC_STATE_DIED;
-@@ -2705,12 +2570,12 @@
-       if (hctx->state == FCGI_STATE_CONNECT_DELAYED) {
-               int socket_error;
-               socklen_t socket_error_len = sizeof(socket_error);
--                      
-+
-               /* try to finish the connect() */
--              if (0 != getsockopt(hctx->fd, SOL_SOCKET, SO_ERROR, &socket_error, &socket_error_len)) {
--                      log_error_write(srv, __FILE__, __LINE__, "ss", 
-+              if (0 != getsockopt(hctx->sock->fd, SOL_SOCKET, SO_ERROR, &socket_error, &socket_error_len)) {
-+                      log_error_write(srv, __FILE__, __LINE__, "ss",
-                                       "getsockopt failed:", strerror(errno));
--                      
-+
-                       hctx->proc->disabled_until = srv->cur_ts + 10;
-                       hctx->proc->state = PROC_STATE_DIED;
-@@ -2719,12 +2584,12 @@
-               if (socket_error != 0) {
-                       if (!hctx->proc->is_local || p->conf.debug) {
-                               /* local procs get restarted */
--                              
-+
-                               log_error_write(srv, __FILE__, __LINE__, "sssb",
--                                              "establishing connection failed:", strerror(socket_error), 
-+                                              "establishing connection failed:", strerror(socket_error),
-                                               "socket:", hctx->proc->connection_name);
-                       }
--      
-+
-                       hctx->proc->disabled_until = srv->cur_ts + 5;
-                       if (hctx->proc->is_local) {
-@@ -2732,17 +2597,17 @@
-                       } else {
-                               hctx->proc->state = PROC_STATE_DIED;
-                       }
--      
-+
-                       hctx->proc->state = PROC_STATE_DIED;
--              
-+
-                       fastcgi_status_copy_procname(p->statuskey, hctx->host, hctx->proc);
-                       buffer_append_string(p->statuskey, ".died");
--                      status_counter_inc(srv, CONST_BUF_LEN(p->statuskey));
--              
-+                      status_counter_inc(CONST_BUF_LEN(p->statuskey));
-+
-                       return HANDLER_ERROR;
-               }
--              /* go on with preparing the request */ 
-+              /* go on with preparing the request */
-               hctx->state = FCGI_STATE_PREPARE_WRITE;
-       }
-@@ -2755,14 +2620,14 @@
-               /* do we have a running process for this host (max-procs) ? */
-               hctx->proc = NULL;
--              for (proc = hctx->host->first; 
--                   proc && proc->state != PROC_STATE_RUNNING; 
-+              for (proc = hctx->host->first;
-+                   proc && proc->state != PROC_STATE_RUNNING;
-                    proc = proc->next);
--                      
-+
-               /* all childs are dead */
-               if (proc == NULL) {
--                      hctx->fde_ndx = -1;
--              
-+                      hctx->sock->fde_ndx = -1;
-+
-                       return HANDLER_ERROR;
-               }
-@@ -2775,50 +2640,50 @@
-               }
-               ret = host->unixsocket->used ? AF_UNIX : AF_INET;
--              
--              if (-1 == (hctx->fd = socket(ret, SOCK_STREAM, 0))) {
-+
-+              if (-1 == (hctx->sock->fd = socket(ret, SOCK_STREAM, 0))) {
-                       if (errno == EMFILE ||
-                           errno == EINTR) {
--                              log_error_write(srv, __FILE__, __LINE__, "sd", 
--                                              "wait for fd at connection:", con->fd);
--                              
-+                              log_error_write(srv, __FILE__, __LINE__, "sd",
-+                                              "wait for fd at connection:", con->sock->fd);
-+
-                               return HANDLER_WAIT_FOR_FD;
-                       }
--                      
--                      log_error_write(srv, __FILE__, __LINE__, "ssdd", 
-+
-+                      log_error_write(srv, __FILE__, __LINE__, "ssdd",
-                                       "socket failed:", strerror(errno), srv->cur_fds, srv->max_fds);
-                       return HANDLER_ERROR;
-               }
--              hctx->fde_ndx = -1;
--              
-+              hctx->sock->fde_ndx = -1;
-+
-               srv->cur_fds++;
--              
--              fdevent_register(srv->ev, hctx->fd, fcgi_handle_fdevent, hctx);
--              
--              if (-1 == fdevent_fcntl_set(srv->ev, hctx->fd)) {
--                      log_error_write(srv, __FILE__, __LINE__, "ss", 
-+
-+              fdevent_register(srv->ev, hctx->sock, fcgi_handle_fdevent, hctx);
-+
-+              if (-1 == fdevent_fcntl_set(srv->ev, hctx->sock)) {
-+                      log_error_write(srv, __FILE__, __LINE__, "ss",
-                                       "fcntl failed:", strerror(errno));
--                      
-+
-                       return HANDLER_ERROR;
-               }
--                      
-+
-               if (hctx->proc->is_local) {
-                       hctx->pid = hctx->proc->pid;
-               }
--                      
-+
-               switch (fcgi_establish_connection(srv, hctx)) {
-               case CONNECTION_DELAYED:
-                       /* connection is in progress, wait for an event and call getsockopt() below */
--                      
--                      fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
--                      
-+
-+                      fdevent_event_add(srv->ev, hctx->sock, FDEVENT_OUT);
-+
-                       fcgi_set_state(srv, hctx, FCGI_STATE_CONNECT_DELAYED);
-                       return HANDLER_WAIT_FOR_EVENT;
-               case CONNECTION_OVERLOADED:
-                       /* cool down the backend, it is overloaded
-                        * -> EAGAIN */
--                      log_error_write(srv, __FILE__, __LINE__, "ssdsd", 
-+                      log_error_write(srv, __FILE__, __LINE__, "ssdsd",
-                               "backend is overloaded, we disable it for a 2 seconds and send the request to another backend instead:",
-                               "reconnects:", hctx->reconnects,
-                               "load:", host->load);
-@@ -2830,8 +2695,8 @@
-                       fastcgi_status_copy_procname(p->statuskey, hctx->host, hctx->proc);
-                       buffer_append_string(p->statuskey, ".overloaded");
--                      status_counter_inc(srv, CONST_BUF_LEN(p->statuskey));
--                      
-+                      status_counter_inc(CONST_BUF_LEN(p->statuskey));
-+
-                       return HANDLER_ERROR;
-               case CONNECTION_DEAD:
-                       /* we got a hard error from the backend like
-@@ -2840,67 +2705,67 @@
-                        *
-                        * for check if the host is back in 5 seconds
-                        *  */
--                      
-+
-                       hctx->proc->disabled_until = srv->cur_ts + 5;
-                       if (hctx->proc->is_local) {
-                               hctx->proc->state = PROC_STATE_DIED_WAIT_FOR_PID;
-                       } else {
-                               hctx->proc->state = PROC_STATE_DIED;
-                       }
--      
--                      log_error_write(srv, __FILE__, __LINE__, "ssdsd", 
-+
-+                      log_error_write(srv, __FILE__, __LINE__, "ssdsd",
-                               "backend died, we disable it for a 5 seconds and send the request to another backend instead:",
-                               "reconnects:", hctx->reconnects,
-                               "load:", host->load);
--      
-+
-                       fastcgi_status_copy_procname(p->statuskey, hctx->host, hctx->proc);
-                       buffer_append_string(p->statuskey, ".died");
--                      status_counter_inc(srv, CONST_BUF_LEN(p->statuskey));
-+                      status_counter_inc(CONST_BUF_LEN(p->statuskey));
-                       return HANDLER_ERROR;
-               case CONNECTION_OK:
-                       /* everything is ok, go on */
-                       fcgi_set_state(srv, hctx, FCGI_STATE_PREPARE_WRITE);
--                      
-+
-                       break;
-               case CONNECTION_UNSET:
-                       break;
-               }
--              
-+
-       case FCGI_STATE_PREPARE_WRITE:
-               /* ok, we have the connection */
--              
-+
-               hctx->proc->load++;
-               hctx->proc->last_used = srv->cur_ts;
-               hctx->got_proc = 1;
--      
--              status_counter_inc(srv, CONST_STR_LEN("fastcgi.requests"));
--              status_counter_inc(srv, CONST_STR_LEN("fastcgi.active-requests"));
-+
-+              status_counter_inc(CONST_STR_LEN("fastcgi.requests"));
-+              status_counter_inc(CONST_STR_LEN("fastcgi.active-requests"));
-               fastcgi_status_copy_procname(p->statuskey, hctx->host, hctx->proc);
-               buffer_append_string(p->statuskey, ".connected");
--              status_counter_inc(srv, CONST_BUF_LEN(p->statuskey));
-+              status_counter_inc(CONST_BUF_LEN(p->statuskey));
-               /* the proc-load */
-               fastcgi_status_copy_procname(p->statuskey, hctx->host, hctx->proc);
-               buffer_append_string(p->statuskey, ".load");
--              status_counter_set(srv, CONST_BUF_LEN(p->statuskey), hctx->proc->load);
-+              status_counter_set(CONST_BUF_LEN(p->statuskey), hctx->proc->load);
-               /* the host-load */
-               fastcgi_status_copy_procname(p->statuskey, hctx->host, NULL);
-               buffer_append_string(p->statuskey, ".load");
--              status_counter_set(srv, CONST_BUF_LEN(p->statuskey), hctx->host->load);
-+              status_counter_set(CONST_BUF_LEN(p->statuskey), hctx->host->load);
-               if (p->conf.debug) {
-                       log_error_write(srv, __FILE__, __LINE__, "ssdsbsd",
--                                      "got proc:", 
--                                      "pid:", hctx->proc->pid, 
--                                      "socket:", hctx->proc->connection_name, 
-+                                      "got proc:",
-+                                      "pid:", hctx->proc->pid,
-+                                      "socket:", hctx->proc->connection_name,
-                                       "load:", hctx->proc->load);
-               }
-@@ -2908,74 +2773,75 @@
-               if (hctx->request_id == 0) {
-                       hctx->request_id = fcgi_requestid_new(srv, p);
-               } else {
--                      log_error_write(srv, __FILE__, __LINE__, "sd", 
-+                      log_error_write(srv, __FILE__, __LINE__, "sd",
-                                       "fcgi-request is already in use:", hctx->request_id);
-               }
--              
-+
-               /* fall through */
-               fcgi_create_env(srv, hctx, hctx->request_id);
--              
-+
-               fcgi_set_state(srv, hctx, FCGI_STATE_WRITE);
--              
-+
-               /* fall through */
-       case FCGI_STATE_WRITE:
--              ret = srv->network_backend_write(srv, con, hctx->fd, hctx->wb); 
-+              ret = srv->network_backend_write(srv, con, hctx->sock, hctx->wb);
-               chunkqueue_remove_finished_chunks(hctx->wb);
--              
-+
-               if (ret < 0) {
-                       switch(errno) {
-                       case ENOTCONN:
--                              /* the connection got dropped after accept() 
--                               * 
--                               * this is most of the time a PHP which dies 
-+                              /* the connection got dropped after accept()
-+                               *
-+                               * this is most of the time a PHP which dies
-                                * after PHP_FCGI_MAX_REQUESTS
--                               * 
--                               */ 
-+                               *
-+                               */
-                               if (hctx->wb->bytes_out == 0 &&
-                                   hctx->reconnects < 5) {
--                                      usleep(10000); /* take away the load of the webserver 
--                                                      * to let the php a chance to restart 
-+#ifndef _WIN32
-+                                      usleep(10000); /* take away the load of the webserver
-+                                                      * to let the php a chance to restart
-                                                       */
--                                      
-+#endif
-                                       fcgi_reconnect(srv, hctx);
--                              
-+
-                                       return HANDLER_WAIT_FOR_FD;
-                               }
--                              
-+
-                               /* not reconnected ... why
--                               * 
-+                               *
-                                * far@#lighttpd report this for FreeBSD
--                               * 
-+                               *
-                                */
--                              
--                              log_error_write(srv, __FILE__, __LINE__, "ssdsd", 
-+
-+                              log_error_write(srv, __FILE__, __LINE__, "ssosd",
-                                               "[REPORT ME] connection was dropped after accept(). reconnect() denied:",
-                                               "write-offset:", hctx->wb->bytes_out,
-                                               "reconnect attempts:", hctx->reconnects);
--                              
-+
-                               return HANDLER_ERROR;
-                       case EAGAIN:
-                       case EINTR:
--                              fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
--                              
-+                              fdevent_event_add(srv->ev, hctx->sock, FDEVENT_OUT);
-+
-                               return HANDLER_WAIT_FOR_EVENT;
-                       default:
--                              log_error_write(srv, __FILE__, __LINE__, "ssd", 
-+                              log_error_write(srv, __FILE__, __LINE__, "ssd",
-                                               "write failed:", strerror(errno), errno);
--                              
-+
-                               return HANDLER_ERROR;
-                       }
-               }
-               if (hctx->wb->bytes_out == hctx->wb->bytes_in) {
-                       /* we don't need the out event anymore */
--                      fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
--                      fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
-+                      fdevent_event_del(srv->ev, hctx->sock);
-+                      fdevent_event_add(srv->ev, hctx->sock, FDEVENT_IN);
-                       fcgi_set_state(srv, hctx, FCGI_STATE_READ);
-               } else {
--                      fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
--                              
-+                      fdevent_event_add(srv->ev, hctx->sock, FDEVENT_OUT);
-+
-                       return HANDLER_WAIT_FOR_EVENT;
-               }
-@@ -2987,7 +2853,7 @@
-               log_error_write(srv, __FILE__, __LINE__, "s", "(debug) unknown state");
-               return HANDLER_ERROR;
-       }
--      
-+
-       return HANDLER_WAIT_FOR_EVENT;
- }
-@@ -2996,18 +2862,18 @@
-  * */
- SUBREQUEST_FUNC(mod_fastcgi_handle_subrequest) {
-       plugin_data *p = p_d;
--      
-+
-       handler_ctx *hctx = con->plugin_ctx[p->id];
-       fcgi_proc *proc;
-       fcgi_extension_host *host;
--      
-+
-       if (NULL == hctx) return HANDLER_GO_ON;
--      
-+
-       /* not my job */
-       if (con->mode != p->id) return HANDLER_GO_ON;
-       /* we don't have a host yet, choose one
--       * -> this happens in the first round 
-+       * -> this happens in the first round
-        *    and when the host died and we have to select a new one */
-       if (hctx->host == NULL) {
-               size_t k;
-@@ -3016,23 +2882,23 @@
-               /* get best server */
-               for (k = 0, ndx = -1; k < hctx->ext->used; k++) {
-                       host = hctx->ext->hosts[k];
--              
-+
-                       /* we should have at least one proc that can do something */
-                       if (host->active_procs == 0) continue;
-                       if (used == -1 || host->load < used) {
-                               used = host->load;
--                      
-+
-                               ndx = k;
-                       }
-               }
--      
-+
-               /* found a server */
-               if (ndx == -1) {
-                       /* all hosts are down */
-                       fcgi_connection_close(srv, hctx);
--                      
-+
-                       con->http_status = 500;
-                       con->mode = DIRECT;
-@@ -3040,16 +2906,16 @@
-               }
-               host = hctx->ext->hosts[ndx];
--              
--              /* 
--               * if check-local is disabled, use the uri.path handler 
--               * 
-+
-+              /*
-+               * if check-local is disabled, use the uri.path handler
-+               *
-                */
--              
-+
-               /* init handler-context */
-               hctx->host = host;
--              /* we put a connection on this host, move the other new connections to other hosts 
-+              /* we put a connection on this host, move the other new connections to other hosts
-                *
-                * as soon as hctx->host is unassigned, decrease the load again */
-               hctx->host->load++;
-@@ -3063,7 +2929,7 @@
-       case HANDLER_ERROR:
-               proc = hctx->proc;
-               host = hctx->host;
--              
-+
-               if (hctx->state == FCGI_STATE_INIT ||
-                   hctx->state == FCGI_STATE_CONNECT_DELAYED) {
-                       if (proc) host->active_procs--;
-@@ -3078,7 +2944,7 @@
-                               return HANDLER_WAIT_FOR_FD;
-                       } else {
-                               fcgi_connection_close(srv, hctx);
--                      
-+
-                               buffer_reset(con->physical.path);
-                               con->mode = DIRECT;
-                               con->http_status = 500;
-@@ -3088,12 +2954,12 @@
-                       }
-               } else {
-                       fcgi_connection_close(srv, hctx);
--                      
-+
-                       buffer_reset(con->physical.path);
-                       con->mode = DIRECT;
-                       con->http_status = 503;
-                       joblist_append(srv, con); /* really ? */
--                      
-+
-                       return HANDLER_FINISHED;
-               }
-       case HANDLER_WAIT_FOR_EVENT:
-@@ -3115,7 +2981,7 @@
-       handler_ctx *hctx = ctx;
-       connection  *con  = hctx->remote_conn;
-       plugin_data *p    = hctx->plugin_data;
--      
-+
-       fcgi_proc *proc   = hctx->proc;
-       fcgi_extension_host *host= hctx->host;
-@@ -3125,8 +2991,8 @@
-               case 0:
-                       break;
-               case 1:
--                      
--                      if (host->mode == FCGI_AUTHORIZER && 
-+
-+                      if (host->mode == FCGI_AUTHORIZER &&
-                           (con->http_status == 200 ||
-                            con->http_status == 0)) {
-                               /*
-@@ -3136,26 +3002,26 @@
-                                */
-                               buffer_copy_string_buffer(con->physical.doc_root, host->docroot);
--                              
-+
-                               buffer_copy_string_buffer(con->physical.path, host->docroot);
-                               buffer_append_string_buffer(con->physical.path, con->uri.path);
-                               fcgi_connection_close(srv, hctx);
--                              
-+
-                               con->mode = DIRECT;
-                               con->file_started = 1; /* fcgi_extension won't touch the request afterwards */
-                       } else {
-                               /* we are done */
-                               fcgi_connection_close(srv, hctx);
-                       }
--                      
-+
-                       joblist_append(srv, con);
-                       return HANDLER_FINISHED;
-               case -1:
-                       if (proc->pid && proc->state != PROC_STATE_DIED) {
-                               int status;
--                              
-+
-                               /* only fetch the zombie if it is not already done */
--                              
-+#ifndef _WIN32
-                               switch(waitpid(proc->pid, &status, WNOHANG)) {
-                               case 0:
-                                       /* child is still alive */
-@@ -3165,137 +3031,137 @@
-                               default:
-                                       /* the child should not terminate at all */
-                                       if (WIFEXITED(status)) {
--                                              log_error_write(srv, __FILE__, __LINE__, "sdsd", 
-+                                              log_error_write(srv, __FILE__, __LINE__, "sdsd",
-                                                               "child exited, pid:", proc->pid,
-                                                               "status:", WEXITSTATUS(status));
-                                       } else if (WIFSIGNALED(status)) {
--                                              log_error_write(srv, __FILE__, __LINE__, "sd", 
--                                                              "child signaled:", 
-+                                              log_error_write(srv, __FILE__, __LINE__, "sd",
-+                                                              "child signaled:",
-                                                               WTERMSIG(status));
-                                       } else {
--                                              log_error_write(srv, __FILE__, __LINE__, "sd", 
--                                                              "child died somehow:", 
-+                                              log_error_write(srv, __FILE__, __LINE__, "sd",
-+                                                              "child died somehow:",
-                                                               status);
-                                       }
--                                      
-+
-                                       if (p->conf.debug) {
-                                               log_error_write(srv, __FILE__, __LINE__, "ssbsdsd",
-                                                               "--- fastcgi spawning",
-                                                               "\n\tsocket", proc->connection_name,
-                                                               "\n\tcurrent:", 1, "/", host->min_procs);
-                                       }
--                                      
-+
-                                       if (fcgi_spawn_connection(srv, p, host, proc)) {
-                                               /* respawning failed, retry later */
-                                               proc->state = PROC_STATE_DIED;
--                                              log_error_write(srv, __FILE__, __LINE__, "s", 
-+                                              log_error_write(srv, __FILE__, __LINE__, "s",
-                                                               "respawning failed, will retry later");
-                                       }
--                                      
-+
-                                       break;
-                               }
-+#endif
-                       }
-                       if (con->file_started == 0) {
-                               /* nothing has been send out yet, try to use another child */
--                              
-+
-                               if (hctx->wb->bytes_out == 0 &&
-                                   hctx->reconnects < 5) {
-                                       fcgi_reconnect(srv, hctx);
--                                      
--                                      log_error_write(srv, __FILE__, __LINE__, "ssbsbs", 
-+
-+                                      log_error_write(srv, __FILE__, __LINE__, "ssbsbs",
-                                               "response not received, request not sent",
--                                              "on socket:", proc->connection_name, 
-+                                              "on socket:", proc->connection_name,
-                                               "for", con->uri.path, ", reconnecting");
--                                      
-+
-                                       return HANDLER_WAIT_FOR_FD;
-                               }
--                      
--                              log_error_write(srv, __FILE__, __LINE__, "sosbsbs", 
-+
-+                              log_error_write(srv, __FILE__, __LINE__, "sosbsbs",
-                                               "response not received, request sent:", hctx->wb->bytes_out,
--                                              "on socket:", proc->connection_name, 
-+                                              "on socket:", proc->connection_name,
-                                               "for", con->uri.path, ", closing connection");
--                              
-+
-                               fcgi_connection_close(srv, hctx);
--                              
--                              connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
-+
-                               buffer_reset(con->physical.path);
-                               con->http_status = 500;
-                               con->mode = DIRECT;
-                       } else {
-                               /* response might have been already started, kill the connection */
-                               fcgi_connection_close(srv, hctx);
--                              
--                              log_error_write(srv, __FILE__, __LINE__, "ssbsbs", 
-+
-+                              log_error_write(srv, __FILE__, __LINE__, "ssbsbs",
-                                               "response already sent out, but backend returned error",
--                                              "on socket:", proc->connection_name, 
-+                                              "on socket:", proc->connection_name,
-                                               "for", con->uri.path, ", terminating connection");
--                              
-+
-                               connection_set_state(srv, con, CON_STATE_ERROR);
-                       }
-                       /* */
--                      
--                      
-+
-+
-                       joblist_append(srv, con);
-                       return HANDLER_FINISHED;
-               }
-       }
--      
-+
-       if (revents & FDEVENT_OUT) {
-               if (hctx->state == FCGI_STATE_CONNECT_DELAYED ||
-                   hctx->state == FCGI_STATE_WRITE) {
-                       /* we are allowed to send something out
--                       * 
-+                       *
-                        * 1. in a unfinished connect() call
-                        * 2. in a unfinished write() call (long POST request)
-                        */
-                       return mod_fastcgi_handle_subrequest(srv, con, p);
-               } else {
--                      log_error_write(srv, __FILE__, __LINE__, "sd", 
--                                      "got a FDEVENT_OUT and didn't know why:", 
-+                      log_error_write(srv, __FILE__, __LINE__, "sd",
-+                                      "got a FDEVENT_OUT and didn't know why:",
-                                       hctx->state);
-               }
-       }
--      
-+
-       /* perhaps this issue is already handled */
-       if (revents & FDEVENT_HUP) {
-               if (hctx->state == FCGI_STATE_CONNECT_DELAYED) {
-                       /* getoptsock will catch this one (right ?)
--                       * 
--                       * if we are in connect we might get a EINPROGRESS 
--                       * in the first call and a FDEVENT_HUP in the 
-+                       *
-+                       * if we are in connect we might get a EINPROGRESS
-+                       * in the first call and a FDEVENT_HUP in the
-                        * second round
--                       * 
-+                       *
-                        * FIXME: as it is a bit ugly.
--                       * 
-+                       *
-                        */
-                       return mod_fastcgi_handle_subrequest(srv, con, p);
-               } else if (hctx->state == FCGI_STATE_READ &&
-                          hctx->proc->port == 0) {
-                       /* FIXME:
--                       * 
-+                       *
-                        * ioctl says 8192 bytes to read from PHP and we receive directly a HUP for the socket
-                        * even if the FCGI_FIN packet is not received yet
-                        */
-               } else {
--                      log_error_write(srv, __FILE__, __LINE__, "sbSBSDSd", 
--                                      "error: unexpected close of fastcgi connection for", 
-+                      log_error_write(srv, __FILE__, __LINE__, "sbSBSDSd",
-+                                      "error: unexpected close of fastcgi connection for",
-                                       con->uri.path,
--                                      "(no fastcgi process on host:", 
-+                                      "(no fastcgi process on host:",
-                                       host->host,
--                                      ", port: ", 
-+                                      ", port: ",
-                                       host->port,
-                                       " ?)",
-                                       hctx->state);
--                      
-+
-                       connection_set_state(srv, con, CON_STATE_ERROR);
-                       fcgi_connection_close(srv, hctx);
-                       joblist_append(srv, con);
-               }
-       } else if (revents & FDEVENT_ERR) {
--              log_error_write(srv, __FILE__, __LINE__, "s", 
-+              log_error_write(srv, __FILE__, __LINE__, "s",
-                               "fcgi: got a FDEVENT_ERR. Don't know why.");
-               /* kill all connections to the fastcgi process */
-@@ -3304,45 +3170,42 @@
-               fcgi_connection_close(srv, hctx);
-               joblist_append(srv, con);
-       }
--      
-+
-       return HANDLER_FINISHED;
- }
--#define PATCH(x) \
--      p->conf.x = s->x;
-+
- static int fcgi_patch_connection(server *srv, connection *con, plugin_data *p) {
-       size_t i, j;
-       plugin_config *s = p->config_storage[0];
--      
--      PATCH(exts);
--      PATCH(debug);
--      PATCH(ext_mapping);
--      
-+
-+      PATCH_OPTION(exts);
-+      PATCH_OPTION(debug);
-+      PATCH_OPTION(ext_mapping);
-+
-       /* skip the first, the global context */
-       for (i = 1; i < srv->config_context->used; i++) {
-               data_config *dc = (data_config *)srv->config_context->data[i];
-               s = p->config_storage[i];
--              
-+
-               /* condition didn't match */
-               if (!config_check_cond(srv, con, dc)) continue;
--              
-+
-               /* merge config */
-               for (j = 0; j < dc->value->used; j++) {
-                       data_unset *du = dc->value->data[j];
--                      
-+
-                       if (buffer_is_equal_string(du->key, CONST_STR_LEN("fastcgi.server"))) {
--                              PATCH(exts);
-+                              PATCH_OPTION(exts);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("fastcgi.debug"))) {
--                              PATCH(debug);
-+                              PATCH_OPTION(debug);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("fastcgi.map-extensions"))) {
--                              PATCH(ext_mapping);
-+                              PATCH_OPTION(ext_mapping);
-                       }
-               }
-       }
--      
-+
-       return 0;
- }
--#undef PATCH
--
- static handler_t fcgi_check_extension(server *srv, connection *con, void *p_d, int uri_path_handler) {
-       plugin_data *p = p_d;
-@@ -3351,16 +3214,16 @@
-       buffer *fn;
-       fcgi_extension *extension = NULL;
-       fcgi_extension_host *host = NULL;
--      
-+
-       /* Possibly, we processed already this request */
-       if (con->file_started == 1) return HANDLER_GO_ON;
-       fn = uri_path_handler ? con->uri.path : con->physical.path;
-       if (buffer_is_empty(fn)) return HANDLER_GO_ON;
--      
-+
-       s_len = fn->used - 1;
--      
-+
-       fcgi_patch_connection(srv, con, p);
-       /* fastcgi.map-extensions maps extensions to existing fastcgi.server entries
-@@ -3368,24 +3231,24 @@
-        * fastcgi.map-extensions = ( ".php3" => ".php" )
-        *
-        * fastcgi.server = ( ".php" => ... )
--       * 
-+       *
-        * */
-       /* check if extension-mapping matches */
-       for (k = 0; k < p->conf.ext_mapping->used; k++) {
-               data_string *ds = (data_string *)p->conf.ext_mapping->data[k];
-               size_t ct_len; /* length of the config entry */
--              
-+
-               if (ds->key->used == 0) continue;
--              
-+
-               ct_len = ds->key->used - 1;
--              
-+
-               if (s_len < ct_len) continue;
--              
-+
-               /* found a mapping */
-               if (0 == strncmp(fn->ptr + s_len - ct_len, ds->key->ptr, ct_len)) {
-                       /* check if we know the extension */
--                      
-+
-                       /* we can reuse k here */
-                       for (k = 0; k < p->conf.exts->used; k++) {
-                               extension = p->conf.exts->exts[k];
-@@ -3407,15 +3270,15 @@
-               /* check if extension matches */
-               for (k = 0; k < p->conf.exts->used; k++) {
-                       size_t ct_len; /* length of the config entry */
--              
-+
-                       extension = p->conf.exts->exts[k];
--              
-+
-                       if (extension->key->used == 0) continue;
--              
-+
-                       ct_len = extension->key->used - 1;
--              
-+
-                       if (s_len < ct_len) continue;
--              
-+
-                       /* check extension in the form "/fcgi_pattern" */
-                       if (*(extension->key->ptr) == '/' && strncmp(fn->ptr, extension->key->ptr, ct_len) == 0) {
-                               break;
-@@ -3441,10 +3304,10 @@
-                       continue;
-               }
--              /* we found one host that is alive */ 
-+              /* we found one host that is alive */
-               break;
-       }
--      
-+
-       if (!host) {
-               /* sorry, we don't have a server alive for this ext */
-               buffer_reset(con->physical.path);
-@@ -3459,72 +3322,72 @@
-                                       "on", extension->key,
-                                       "are down.");
-               }
--              
-+
-               return HANDLER_FINISHED;
-       }
-       /* a note about no handler is not sent yey */
-       extension->note_is_sent = 0;
--      /* 
--       * if check-local is disabled, use the uri.path handler 
--       * 
-+      /*
-+       * if check-local is disabled, use the uri.path handler
-+       *
-        */
--      
-+
-       /* init handler-context */
-       if (uri_path_handler) {
-               if (host->check_local == 0) {
-                       handler_ctx *hctx;
-                       char *pathinfo;
--                      
-+
-                       hctx = handler_ctx_init();
--                      
-+
-                       hctx->remote_conn      = con;
-                       hctx->plugin_data      = p;
-                       hctx->proc             = NULL;
-                       hctx->ext              = extension;
--      
-+
-                       hctx->conf.exts        = p->conf.exts;
-                       hctx->conf.debug       = p->conf.debug;
--                              
-+
-                       con->plugin_ctx[p->id] = hctx;
--                              
-+
-                       con->mode = p->id;
--                              
-+
-                       if (con->conf.log_request_handling) {
--                              log_error_write(srv, __FILE__, __LINE__, "s", 
-+                              log_error_write(srv, __FILE__, __LINE__, "s",
-                               "handling it in mod_fastcgi");
-                       }
--                              
--                      /* the prefix is the SCRIPT_NAME, 
-+
-+                      /* the prefix is the SCRIPT_NAME,
-                        * everthing from start to the next slash
-                        * this is important for check-local = "disable"
--                       * 
-+                       *
-                        * if prefix = /admin.fcgi
--                       * 
-+                       *
-                        * /admin.fcgi/foo/bar
--                       * 
-+                       *
-                        * SCRIPT_NAME = /admin.fcgi
-                        * PATH_INFO   = /foo/bar
--                       * 
-+                       *
-                        * if prefix = /fcgi-bin/
--                       * 
-+                       *
-                        * /fcgi-bin/foo/bar
--                       * 
-+                       *
-                        * SCRIPT_NAME = /fcgi-bin/foo
-                        * PATH_INFO   = /bar
--                       * 
-+                       *
-                        */
--                      
-+
-                       /* the rewrite is only done for /prefix/? matches */
-                       if (extension->key->ptr[0] == '/' &&
-                           con->uri.path->used > extension->key->used &&
-                           NULL != (pathinfo = strchr(con->uri.path->ptr + extension->key->used - 1, '/'))) {
--                              /* rewrite uri.path and pathinfo */ 
--                              
-+                              /* rewrite uri.path and pathinfo */
-+
-                               buffer_copy_string(con->request.pathinfo, pathinfo);
--                              
-+
-                               con->uri.path->used -= con->request.pathinfo->used - 1;
-                               con->uri.path->ptr[con->uri.path->used - 1] = '\0';
-                       }
-@@ -3532,19 +3395,19 @@
-       } else {
-               handler_ctx *hctx;
-               hctx = handler_ctx_init();
--              
-+
-               hctx->remote_conn      = con;
-               hctx->plugin_data      = p;
-               hctx->proc             = NULL;
-               hctx->ext              = extension;
--              
-+
-               hctx->conf.exts        = p->conf.exts;
-               hctx->conf.debug       = p->conf.debug;
--              
-+
-               con->plugin_ctx[p->id] = hctx;
--              
-+
-               con->mode = p->id;
--              
-+
-               if (con->conf.log_request_handling) {
-                       log_error_write(srv, __FILE__, __LINE__, "s", "handling it in mod_fastcgi");
-               }
-@@ -3566,19 +3429,19 @@
- JOBLIST_FUNC(mod_fastcgi_handle_joblist) {
-       plugin_data *p = p_d;
-       handler_ctx *hctx = con->plugin_ctx[p->id];
--      
-+
-       if (hctx == NULL) return HANDLER_GO_ON;
--      if (hctx->fd != -1) {
-+      if (hctx->sock->fd != -1) {
-               switch (hctx->state) {
-               case FCGI_STATE_READ:
--                      fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
--                      
-+                      fdevent_event_add(srv->ev, hctx->sock, FDEVENT_IN);
-+
-                       break;
-               case FCGI_STATE_CONNECT_DELAYED:
-               case FCGI_STATE_WRITE:
--                      fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
--                      
-+                      fdevent_event_add(srv->ev, hctx->sock, FDEVENT_OUT);
-+
-                       break;
-               case FCGI_STATE_INIT:
-                       /* at reconnect */
-@@ -3595,7 +3458,7 @@
- static handler_t fcgi_connection_close_callback(server *srv, connection *con, void *p_d) {
-       plugin_data *p = p_d;
--      
-+
-       fcgi_connection_close(srv, con->plugin_ctx[p->id]);
-       return HANDLER_GO_ON;
-@@ -3604,16 +3467,38 @@
- TRIGGER_FUNC(mod_fastcgi_handle_trigger) {
-       plugin_data *p = p_d;
-       size_t i, j, n;
--      
--      
-+
-+
-       /* perhaps we should kill a connect attempt after 10-15 seconds
--       * 
-+       *
-        * currently we wait for the TCP timeout which is on Linux 180 seconds
--       * 
--       * 
--       * 
-+       *
-        */
-+      for (i = 0; i < srv->conns->used; i++) {
-+              connection *con = srv->conns->ptr[i];
-+              handler_ctx *hctx = con->plugin_ctx[p->id];
-+
-+              /* if a connection is ours and is in handle-req for more than max-request-time
-+               * kill the connection */
-+
-+              if (con->mode != p->id) continue;
-+              if (srv->cur_ts < con->request_start + 60) continue;
-+
-+              /* the request is waiting for a FCGI_STDOUT since 60 seconds */
-+
-+              /* kill the connection */
-+
-+              log_error_write(srv, __FILE__, __LINE__, "s", "fastcgi backend didn't responded after 60 seconds");
-+
-+              fcgi_connection_close(srv, hctx);
-+
-+              con->mode = DIRECT;
-+              con->http_status = 500;
-+
-+              joblist_append(srv, con);
-+      }
-+
-       /* check all childs if they are still up */
-       for (i = 0; i < srv->config_context->used; i++) {
-@@ -3628,45 +3513,45 @@
-                       fcgi_extension *ex;
-                       ex = exts->exts[j];
--                      
-+
-                       for (n = 0; n < ex->used; n++) {
--                              
-+
-                               fcgi_proc *proc;
-                               unsigned long sum_load = 0;
-                               fcgi_extension_host *host;
--                              
-+
-                               host = ex->hosts[n];
--                              
-+
-                               fcgi_restart_dead_procs(srv, p, host);
--                              
-+
-                               for (proc = host->first; proc; proc = proc->next) {
-                                       sum_load += proc->load;
-                               }
--                              
-+
-                               if (host->num_procs &&
-                                   host->num_procs < host->max_procs &&
-                                   (sum_load / host->num_procs) > host->max_load_per_proc) {
-                                       /* overload, spawn new child */
-                                       if (p->conf.debug) {
--                                              log_error_write(srv, __FILE__, __LINE__, "s", 
-+                                              log_error_write(srv, __FILE__, __LINE__, "s",
-                                                               "overload detected, spawning a new child");
-                                       }
--                                      
-+
-                                       for (proc = host->unused_procs; proc && proc->pid != 0; proc = proc->next);
--                                      
-+
-                                       if (proc) {
-                                               if (proc == host->unused_procs) host->unused_procs = proc->next;
--                                              
-+
-                                               if (proc->next) proc->next->prev = NULL;
--                                              
-+
-                                               host->max_id++;
-                                       } else {
-                                               proc = fastcgi_process_init();
-                                               proc->id = host->max_id++;
-                                       }
--                                      
-+
-                                       host->num_procs++;
--                                      
-+
-                                       if (buffer_is_empty(host->unixsocket)) {
-                                               proc->port = host->port + proc->id;
-                                       } else {
-@@ -3674,13 +3559,13 @@
-                                               buffer_append_string(proc->unixsocket, "-");
-                                               buffer_append_long(proc->unixsocket, proc->id);
-                                       }
--                                      
-+
-                                       if (fcgi_spawn_connection(srv, p, host, proc)) {
-                                               log_error_write(srv, __FILE__, __LINE__, "s",
-                                                               "ERROR: spawning fcgi failed.");
-                                               return HANDLER_ERROR;
-                                       }
--                                      
-+
-                                       proc->prev = NULL;
-                                       proc->next = host->first;
-                                       if (host->first) {
-@@ -3688,56 +3573,56 @@
-                                       }
-                                       host->first = proc;
-                               }
--                              
-+
-                               for (proc = host->first; proc; proc = proc->next) {
-                                       if (proc->load != 0) break;
-                                       if (host->num_procs <= host->min_procs) break;
-                                       if (proc->pid == 0) continue;
--                                      
-+
-                                       if (srv->cur_ts - proc->last_used > host->idle_timeout) {
-                                               /* a proc is idling for a long time now,
-                                                * terminated it */
--                                              
-+
-                                               if (p->conf.debug) {
--                                                      log_error_write(srv, __FILE__, __LINE__, "ssbsd", 
--                                                                      "idle-timeout reached, terminating child:", 
--                                                                      "socket:", proc->connection_name, 
-+                                                      log_error_write(srv, __FILE__, __LINE__, "ssbsd",
-+                                                                      "idle-timeout reached, terminating child:",
-+                                                                      "socket:", proc->connection_name,
-                                                                       "pid", proc->pid);
-                                               }
--                                              
--                                              
-+
-+
-                                               if (proc->next) proc->next->prev = proc->prev;
-                                               if (proc->prev) proc->prev->next = proc->next;
--                                              
-+
-                                               if (proc->prev == NULL) host->first = proc->next;
--                                              
-+
-                                               proc->prev = NULL;
-                                               proc->next = host->unused_procs;
--                                              
-+
-                                               if (host->unused_procs) host->unused_procs->prev = proc;
-                                               host->unused_procs = proc;
--                                              
-+
-                                               kill(proc->pid, SIGTERM);
--                                              
-+
-                                               proc->state = PROC_STATE_KILLED;
--                                              
--                                              log_error_write(srv, __FILE__, __LINE__, "ssbsd", 
--                                                                      "killed:", 
--                                                                      "socket:", proc->connection_name, 
-+
-+                                              log_error_write(srv, __FILE__, __LINE__, "ssbsd",
-+                                                                      "killed:",
-+                                                                      "socket:", proc->connection_name,
-                                                                       "pid", proc->pid);
--                                              
-+
-                                               host->num_procs--;
--                                              
-+
-                                               /* proc is now in unused, let the next second handle the next process */
-                                               break;
--                                      }       
-+                                      }
-                               }
--                              
-+
-                               for (proc = host->unused_procs; proc; proc = proc->next) {
-                                       int status;
--                                      
-+
-                                       if (proc->pid == 0) continue;
--                                      
-+#ifndef _WIN32
-                                       switch (waitpid(proc->pid, &status, WNOHANG)) {
-                                       case 0:
-                                               /* child still running after timeout, good */
-@@ -3745,10 +3630,10 @@
-                                       case -1:
-                                               if (errno != EINTR) {
-                                                       /* no PID found ? should never happen */
--                                                      log_error_write(srv, __FILE__, __LINE__, "sddss", 
-+                                                      log_error_write(srv, __FILE__, __LINE__, "sddss",
-                                                                       "pid ", proc->pid, proc->state,
-                                                                       "not found:", strerror(errno));
--                                                      
-+
- #if 0
-                                                       if (errno == ECHILD) {
-                                                               /* someone else has cleaned up for us */
-@@ -3762,25 +3647,26 @@
-                                               /* the child should not terminate at all */
-                                               if (WIFEXITED(status)) {
-                                                       if (proc->state != PROC_STATE_KILLED) {
--                                                              log_error_write(srv, __FILE__, __LINE__, "sdb", 
--                                                                              "child exited:", 
-+                                                              log_error_write(srv, __FILE__, __LINE__, "sdb",
-+                                                                              "child exited:",
-                                                                               WEXITSTATUS(status), proc->connection_name);
-                                                       }
-                                               } else if (WIFSIGNALED(status)) {
-                                                       if (WTERMSIG(status) != SIGTERM) {
--                                                              log_error_write(srv, __FILE__, __LINE__, "sd", 
--                                                                              "child signaled:", 
-+                                                              log_error_write(srv, __FILE__, __LINE__, "sd",
-+                                                                              "child signaled:",
-                                                                               WTERMSIG(status));
-                                                       }
-                                               } else {
--                                                      log_error_write(srv, __FILE__, __LINE__, "sd", 
--                                                                      "child died somehow:", 
-+                                                      log_error_write(srv, __FILE__, __LINE__, "sd",
-+                                                                      "child died somehow:",
-                                                                       status);
-                                               }
-                                               proc->pid = 0;
-                                               proc->state = PROC_STATE_UNSET;
-                                               host->max_id--;
-                                       }
-+#endif
-                               }
-                       }
-               }
-@@ -3800,12 +3686,12 @@
-       p->connection_reset        = fcgi_connection_reset;
-       p->handle_connection_close = fcgi_connection_close_callback;
-       p->handle_uri_clean        = fcgi_check_extension_1;
--      p->handle_subrequest_start = fcgi_check_extension_2;
--      p->handle_subrequest       = mod_fastcgi_handle_subrequest;
-+      p->handle_start_backend    = fcgi_check_extension_2;
-+      p->handle_send_request_content = mod_fastcgi_handle_subrequest;
-       p->handle_joblist          = mod_fastcgi_handle_joblist;
-       p->handle_trigger          = mod_fastcgi_handle_trigger;
--      
-+
-       p->data         = NULL;
--      
-+
-       return 0;
- }
---- ../lighttpd-1.4.11/src/mod_flv_streaming.c 2006-03-07 14:06:26.000000000 +0200
-+++ lighttpd-1.5.0/src/mod_flv_streaming.c     2006-09-07 00:57:05.000000000 +0300
-@@ -6,7 +6,6 @@
- #include "log.h"
- #include "buffer.h"
- #include "response.h"
--#include "http_chunk.h"
- #include "stat_cache.h"
- #include "plugin.h"
-@@ -23,35 +22,35 @@
- typedef struct {
-       PLUGIN_DATA;
--      
-+
-       buffer *query_str;
-       array *get_params;
--      
-+
-       plugin_config **config_storage;
--      
--      plugin_config conf; 
-+
-+      plugin_config conf;
- } plugin_data;
- /* init the plugin data */
- INIT_FUNC(mod_flv_streaming_init) {
-       plugin_data *p;
--      
-+
-       p = calloc(1, sizeof(*p));
--      
-+
-       p->query_str = buffer_init();
-       p->get_params = array_init();
--      
-+
-       return p;
- }
- /* detroy the plugin data */
- FREE_FUNC(mod_flv_streaming_free) {
-       plugin_data *p = p_d;
--      
-+
-       UNUSED(srv);
-       if (!p) return HANDLER_GO_ON;
--      
-+
-       if (p->config_storage) {
-               size_t i;
-@@ -59,19 +58,19 @@
-                       plugin_config *s = p->config_storage[i];
-                       if (!s) continue;
--                      
-+
-                       array_free(s->extensions);
--                      
-+
-                       free(s);
-               }
-               free(p->config_storage);
-       }
--      
-+
-       buffer_free(p->query_str);
-       array_free(p->get_params);
--      
-+
-       free(p);
--      
-+
-       return HANDLER_GO_ON;
- }
-@@ -80,83 +79,80 @@
- SETDEFAULTS_FUNC(mod_flv_streaming_set_defaults) {
-       plugin_data *p = p_d;
-       size_t i = 0;
--      
--      config_values_t cv[] = { 
-+
-+      config_values_t cv[] = {
-               { "flv-streaming.extensions",   NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
-               { NULL,                         NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
-       };
--      
-+
-       if (!p) return HANDLER_ERROR;
--      
-+
-       p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
--      
-+
-       for (i = 0; i < srv->config_context->used; i++) {
-               plugin_config *s;
--              
-+
-               s = calloc(1, sizeof(plugin_config));
-               s->extensions     = array_init();
--              
-+
-               cv[0].destination = s->extensions;
--              
-+
-               p->config_storage[i] = s;
--      
-+
-               if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
-                       return HANDLER_ERROR;
-               }
-       }
--      
-+
-       return HANDLER_GO_ON;
- }
--#define PATCH(x) \
--      p->conf.x = s->x;
- static int mod_flv_streaming_patch_connection(server *srv, connection *con, plugin_data *p) {
-       size_t i, j;
-       plugin_config *s = p->config_storage[0];
--      
--      PATCH(extensions);
--      
-+
-+      PATCH_OPTION(extensions);
-+
-       /* skip the first, the global context */
-       for (i = 1; i < srv->config_context->used; i++) {
-               data_config *dc = (data_config *)srv->config_context->data[i];
-               s = p->config_storage[i];
--              
-+
-               /* condition didn't match */
-               if (!config_check_cond(srv, con, dc)) continue;
--              
-+
-               /* merge config */
-               for (j = 0; j < dc->value->used; j++) {
-                       data_unset *du = dc->value->data[j];
--                      
-+
-                       if (buffer_is_equal_string(du->key, CONST_STR_LEN("flv-streaming.extensions"))) {
--                              PATCH(extensions);
-+                              PATCH_OPTION(extensions);
-                       }
-               }
-       }
--      
-+
-       return 0;
- }
--#undef PATCH
--static int split_get_params(server *srv, connection *con, array *get_params, buffer *qrystr) {
-+static int split_get_params(array *get_params, buffer *qrystr) {
-       size_t is_key = 1;
-       size_t i;
-       char *key = NULL, *val = NULL;
--      
-+
-       key = qrystr->ptr;
--      
-+
-       /* we need the \0 */
-       for (i = 0; i < qrystr->used; i++) {
-               switch(qrystr->ptr[i]) {
-               case '=':
-                       if (is_key) {
-                               val = qrystr->ptr + i + 1;
--                              
-+
-                               qrystr->ptr[i] = '\0';
--                              
-+
-                               is_key = 0;
-                       }
--                      
-+
-                       break;
-               case '&':
-               case '\0': /* fin symbol */
-@@ -167,7 +163,7 @@
-                               /* terminate the value */
-                               qrystr->ptr[i] = '\0';
--                              if (NULL == (ds = (data_string *)array_get_unused_element(con->request.headers, TYPE_STRING))) {
-+                              if (NULL == (ds = (data_string *)array_get_unused_element(get_params, TYPE_STRING))) {
-                                       ds = data_string_init();
-                               }
-                               buffer_copy_string_len(ds->key, key, strlen(key));
-@@ -175,14 +171,14 @@
-                               array_insert_unique(get_params, (data_unset *)ds);
-                       }
--                      
-+
-                       key = qrystr->ptr + i + 1;
-                       val = NULL;
-                       is_key = 1;
-                       break;
-               }
-       }
--      
-+
-       return 0;
- }
-@@ -190,34 +186,34 @@
-       plugin_data *p = p_d;
-       int s_len;
-       size_t k;
--      
-+
-       UNUSED(srv);
-       if (buffer_is_empty(con->physical.path)) return HANDLER_GO_ON;
--      
-+
-       mod_flv_streaming_patch_connection(srv, con, p);
-       s_len = con->physical.path->used - 1;
--      
-+
-       for (k = 0; k < p->conf.extensions->used; k++) {
-               data_string *ds = (data_string *)p->conf.extensions->data[k];
-               int ct_len = ds->value->used - 1;
--              
-+
-               if (ct_len > s_len) continue;
-               if (ds->value->used == 0) continue;
--              
-+
-               if (0 == strncmp(con->physical.path->ptr + s_len - ct_len, ds->value->ptr, ct_len)) {
-                       data_string *get_param;
-                       stat_cache_entry *sce = NULL;
-                       buffer *b;
-                       int start;
-                       char *err = NULL;
--                      /* if there is a start=[0-9]+ in the header use it as start, 
-+                      /* if there is a start=[0-9]+ in the header use it as start,
-                        * otherwise send the full file */
-                       array_reset(p->get_params);
-                       buffer_copy_string_buffer(p->query_str, con->uri.query);
--                      split_get_params(srv, con, p->get_params, p->query_str);
-+                      split_get_params(p->get_params, p->query_str);
-                       if (NULL == (get_param = (data_string *)array_get_element(p->get_params, "start"))) {
-                               return HANDLER_GO_ON;
-@@ -244,19 +240,19 @@
-                       }
-                       /* we are safe now, let's build a flv header */
--                      b = chunkqueue_get_append_buffer(con->write_queue);
-+                      b = chunkqueue_get_append_buffer(con->send);
-                       BUFFER_COPY_STRING_CONST(b, "FLV\x1\x1\0\0\0\x9\0\0\0\x9");
--                      http_chunk_append_file(srv, con, con->physical.path, start, sce->st.st_size - start);
-+                      chunkqueue_append_file(con->send, con->physical.path, start, sce->st.st_size - start);
-                       response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("video/x-flv"));
--                      con->file_finished = 1;
-+                      con->send->is_closed = 1;
-                       return HANDLER_FINISHED;
-               }
-       }
--      
-+
-       /* not found */
-       return HANDLER_GO_ON;
- }
-@@ -266,13 +262,13 @@
- int mod_flv_streaming_plugin_init(plugin *p) {
-       p->version     = LIGHTTPD_VERSION_ID;
-       p->name        = buffer_init_string("flv_streaming");
--      
-+
-       p->init        = mod_flv_streaming_init;
-       p->handle_physical = mod_flv_streaming_path_handler;
-       p->set_defaults  = mod_flv_streaming_set_defaults;
-       p->cleanup     = mod_flv_streaming_free;
--      
-+
-       p->data        = NULL;
--      
-+
-       return 0;
- }
---- ../lighttpd-1.4.11/src/mod_indexfile.c     2005-09-30 01:08:53.000000000 +0300
-+++ lighttpd-1.5.0/src/mod_indexfile.c 2006-09-07 00:57:05.000000000 +0300
-@@ -12,6 +12,8 @@
- #include "stat_cache.h"
-+#include "sys-strings.h"
-+#include "sys-files.h"
- /* plugin config for all request/connections */
- typedef struct {
-@@ -20,51 +22,51 @@
- typedef struct {
-       PLUGIN_DATA;
--      
-+
-       buffer *tmp_buf;
--      
-+
-       plugin_config **config_storage;
--      
--      plugin_config conf; 
-+
-+      plugin_config conf;
- } plugin_data;
- /* init the plugin data */
- INIT_FUNC(mod_indexfile_init) {
-       plugin_data *p;
--      
-+
-       p = calloc(1, sizeof(*p));
--      
-+
-       p->tmp_buf = buffer_init();
--      
-+
-       return p;
- }
- /* detroy the plugin data */
- FREE_FUNC(mod_indexfile_free) {
-       plugin_data *p = p_d;
--      
-+
-       UNUSED(srv);
-       if (!p) return HANDLER_GO_ON;
--      
-+
-       if (p->config_storage) {
-               size_t i;
-               for (i = 0; i < srv->config_context->used; i++) {
-                       plugin_config *s = p->config_storage[i];
-                       if (!s) continue;
--                      
-+
-                       array_free(s->indexfiles);
--                      
-+
-                       free(s);
-               }
-               free(p->config_storage);
-       }
--      
-+
-       buffer_free(p->tmp_buf);
--      
-+
-       free(p);
--      
-+
-       return HANDLER_GO_ON;
- }
-@@ -73,131 +75,139 @@
- SETDEFAULTS_FUNC(mod_indexfile_set_defaults) {
-       plugin_data *p = p_d;
-       size_t i = 0;
--      
--      config_values_t cv[] = { 
-+
-+      config_values_t cv[] = {
-               { "index-file.names",           NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
-               { "server.indexfiles",          NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 1 */
-               { NULL,                         NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
-       };
--      
-+
-       if (!p) return HANDLER_ERROR;
--      
-+
-       p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
--      
-+
-       for (i = 0; i < srv->config_context->used; i++) {
-               plugin_config *s;
--              
-+
-               s = calloc(1, sizeof(plugin_config));
-               s->indexfiles    = array_init();
--              
-+
-               cv[0].destination = s->indexfiles;
-               cv[1].destination = s->indexfiles; /* old name for [0] */
--              
-+
-               p->config_storage[i] = s;
--      
-+
-               if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
-                       return HANDLER_ERROR;
-               }
-       }
--      
-+
-       return HANDLER_GO_ON;
- }
--#define PATCH(x) \
--      p->conf.x = s->x;
- static int mod_indexfile_patch_connection(server *srv, connection *con, plugin_data *p) {
-       size_t i, j;
-       plugin_config *s = p->config_storage[0];
--      
--      PATCH(indexfiles);
--      
-+
-+      PATCH_OPTION(indexfiles);
-+
-       /* skip the first, the global context */
-       for (i = 1; i < srv->config_context->used; i++) {
-               data_config *dc = (data_config *)srv->config_context->data[i];
-               s = p->config_storage[i];
--              
-+
-               /* condition didn't match */
-               if (!config_check_cond(srv, con, dc)) continue;
--              
-+
-               /* merge config */
-               for (j = 0; j < dc->value->used; j++) {
-                       data_unset *du = dc->value->data[j];
--                      
-+
-                       if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.indexfiles"))) {
--                              PATCH(indexfiles);
-+                              PATCH_OPTION(indexfiles);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("index-file.names"))) {
--                              PATCH(indexfiles);
-+                              PATCH_OPTION(indexfiles);
-                       }
-               }
-       }
--      
-+
-       return 0;
- }
--#undef PATCH
- URIHANDLER_FUNC(mod_indexfile_subrequest) {
-       plugin_data *p = p_d;
-       size_t k;
-       stat_cache_entry *sce = NULL;
--      
-+
-       if (con->uri.path->used == 0) return HANDLER_GO_ON;
-       if (con->uri.path->ptr[con->uri.path->used - 2] != '/') return HANDLER_GO_ON;
--      
-+
-       mod_indexfile_patch_connection(srv, con, p);
--      
-+
-+      /* is the physical-path really a dir ? */
-+      if (HANDLER_ERROR == stat_cache_get_entry(srv, con, con->physical.path, &sce)) {
-+              return HANDLER_GO_ON;
-+      }
-+
-+      if (!S_ISDIR(sce->st.st_mode)) {
-+              return HANDLER_GO_ON;
-+      }
-+
-       if (con->conf.log_request_handling) {
-               log_error_write(srv, __FILE__, __LINE__,  "s",  "-- handling the request as Indexfile");
-               log_error_write(srv, __FILE__, __LINE__,  "sb", "URI          :", con->uri.path);
-       }
--      
-+
-+
-       /* indexfile */
-       for (k = 0; k < p->conf.indexfiles->used; k++) {
-               data_string *ds = (data_string *)p->conf.indexfiles->data[k];
--              
-+
-               if (ds->value && ds->value->ptr[0] == '/') {
--                      /* if the index-file starts with a prefix as use this file as 
-+                      /* if the index-file starts with a prefix as use this file as
-                        * index-generator */
-                       buffer_copy_string_buffer(p->tmp_buf, con->physical.doc_root);
-               } else {
-                       buffer_copy_string_buffer(p->tmp_buf, con->physical.path);
-+                      PATHNAME_APPEND_SLASH(p->tmp_buf);
-               }
-               buffer_append_string_buffer(p->tmp_buf, ds->value);
--              
-+
-               if (HANDLER_ERROR == stat_cache_get_entry(srv, con, p->tmp_buf, &sce)) {
-                       if (errno == EACCES) {
-                               con->http_status = 403;
-                               buffer_reset(con->physical.path);
--                              
-+
-                               return HANDLER_FINISHED;
-                       }
--                      
-+
-                       if (errno != ENOENT &&
-                           errno != ENOTDIR) {
-                               /* we have no idea what happend. let's tell the user so. */
--                              
-+
-                               con->http_status = 500;
--                              
-+
-                               log_error_write(srv, __FILE__, __LINE__, "ssbsb",
-                                               "file not found ... or so: ", strerror(errno),
-                                               con->uri.path,
-                                               "->", con->physical.path);
--                              
-+
-                               buffer_reset(con->physical.path);
--                              
-+
-                               return HANDLER_FINISHED;
-                       }
-                       continue;
-               }
--                      
-+
-               /* rewrite uri.path to the real path (/ -> /index.php) */
-               buffer_append_string_buffer(con->uri.path, ds->value);
-               buffer_copy_string_buffer(con->physical.path, p->tmp_buf);
--              
-+
-               /* fce is already set up a few lines above */
--              
-+
-               return HANDLER_GO_ON;
-       }
--      
-+
-       /* not found */
-       return HANDLER_GO_ON;
- }
-@@ -207,13 +217,13 @@
- int mod_indexfile_plugin_init(plugin *p) {
-       p->version     = LIGHTTPD_VERSION_ID;
-       p->name        = buffer_init_string("indexfile");
--      
-+
-       p->init        = mod_indexfile_init;
--      p->handle_subrequest_start = mod_indexfile_subrequest;
-+      p->handle_start_backend = mod_indexfile_subrequest;
-       p->set_defaults  = mod_indexfile_set_defaults;
-       p->cleanup     = mod_indexfile_free;
--      
-+
-       p->data        = NULL;
--      
-+
-       return 0;
- }
---- ../lighttpd-1.4.11/src/mod_mysql_vhost.c   2006-01-14 20:35:10.000000000 +0200
-+++ lighttpd-1.5.0/src/mod_mysql_vhost.c       2006-07-20 00:57:19.000000000 +0300
-@@ -1,13 +1,18 @@
--#include <unistd.h>
- #include <stdio.h>
- #include <errno.h>
- #include <fcntl.h>
--#include <strings.h>
-+#include <string.h>
- #ifdef HAVE_CONFIG_H
- #include "config.h"
- #endif
-+#ifdef HAVE_MYSQL_H 
-+# ifdef HAVE_LIBMYSQL
-+#  define HAVE_MYSQL
-+# endif
-+#endif
-+
- #ifdef HAVE_MYSQL
- #include <mysql.h>
- #endif
-@@ -16,61 +21,40 @@
- #include "log.h"
- #include "stat_cache.h"
--#ifdef DEBUG_MOD_MYSQL_VHOST
--#define DEBUG
--#endif
-+#include "sys-files.h"
--/*
-- * Plugin for lighttpd to use MySQL 
-- *   for domain to directory lookups,
-- *   i.e virtual hosts (vhosts).
-- *   
-- * Optionally sets fcgi_offset and fcgi_arg 
-- *   in preparation for fcgi.c to handle 
-- *   per-user fcgi chroot jails.
-- *
-- * /ada@riksnet.se 2004-12-06
-- */
-+#include "mod_sql_vhost_core.h"
- #ifdef HAVE_MYSQL
-+
-+#define CORE_PLUGIN "mod_sql_vhost_core"
-+
- typedef struct {
-       MYSQL   *mysql;
--      
--      buffer  *mydb;
--      buffer  *myuser;
--      buffer  *mypass;
--      buffer  *mysock;
--      
--      buffer  *hostname;
--      unsigned short port;
--      
-+
-       buffer  *mysql_pre;
-       buffer  *mysql_post;
-+
-+      mod_sql_vhost_core_plugin_config *core;
- } plugin_config;
- /* global plugin data */
- typedef struct {
-       PLUGIN_DATA;
--      
-+
-       buffer  *tmp_buf;
--      
-+
-       plugin_config **config_storage;
--      
--      plugin_config conf; 
-+
-+      plugin_config conf;
- } plugin_data;
--/* per connection plugin data */
--typedef struct {
--      buffer  *server_name;
--      buffer  *document_root;
--      buffer  *fcgi_arg;
--      unsigned fcgi_offset;
--} plugin_connection_data;
-+SQLVHOST_BACKEND_GETVHOST(mod_mysql_vhost_get_vhost); 
- /* init the plugin data */
- INIT_FUNC(mod_mysql_vhost_init) {
-       plugin_data *p;
--      
-+
-       p = calloc(1, sizeof(*p));
-       p->tmp_buf = buffer_init();
-@@ -83,144 +67,77 @@
-       plugin_data *p = p_d;
-       UNUSED(srv);
--      
--#ifdef DEBUG
--      log_error_write(srv, __FILE__, __LINE__, "ss", 
--              "mod_mysql_vhost_cleanup", p ? "yes" : "NO");
--#endif
-+
-       if (!p) return HANDLER_GO_ON;
--      
-+
-       if (p->config_storage) {
-               size_t i;
-               for (i = 0; i < srv->config_context->used; i++) {
-                       plugin_config *s = p->config_storage[i];
-                       if (!s) continue;
--                      
-+
-                       mysql_close(s->mysql);
--                      
--                      buffer_free(s->mydb);
--                      buffer_free(s->myuser);
--                      buffer_free(s->mypass);
--                      buffer_free(s->mysock);
-+
-                       buffer_free(s->mysql_pre);
-                       buffer_free(s->mysql_post);
--                      
-+
-                       free(s);
-               }
-               free(p->config_storage);
-       }
-       buffer_free(p->tmp_buf);
--      
--      free(p);
--      return HANDLER_GO_ON;
--}
--
--/* handle the plugin per connection data */
--static void* mod_mysql_vhost_connection_data(server *srv, connection *con, void *p_d)
--{
--      plugin_data *p = p_d;
--      plugin_connection_data *c = con->plugin_ctx[p->id];
--
--      UNUSED(srv);
--
--#ifdef DEBUG
--        log_error_write(srv, __FILE__, __LINE__, "ss", 
--              "mod_mysql_connection_data", c ? "old" : "NEW");
--#endif
--
--      if (c) return c;
--      c = calloc(1, sizeof(*c));
--
--      c->server_name = buffer_init();
--      c->document_root = buffer_init();
--      c->fcgi_arg = buffer_init();
--      c->fcgi_offset = 0;
--
--      return con->plugin_ctx[p->id] = c;
--}
--
--/* destroy the plugin per connection data */
--CONNECTION_FUNC(mod_mysql_vhost_handle_connection_close) {
--      plugin_data *p = p_d;
--      plugin_connection_data *c = con->plugin_ctx[p->id];
--
--      UNUSED(srv);
--
--#ifdef DEBUG
--      log_error_write(srv, __FILE__, __LINE__, "ss", 
--              "mod_mysql_vhost_handle_connection_close", c ? "yes" : "NO");
--#endif
--      
--      if (!c) return HANDLER_GO_ON;
--
--      buffer_free(c->server_name);
--      buffer_free(c->document_root);
--      buffer_free(c->fcgi_arg);
--      c->fcgi_offset = 0;
--
--      free(c);
-+      free(p);
--      con->plugin_ctx[p->id] = NULL;
-       return HANDLER_GO_ON;
- }
- /* set configuration values */
- SERVER_FUNC(mod_mysql_vhost_set_defaults) {
-       plugin_data *p = p_d;
-+      mod_sql_vhost_core_plugin_data *core_config;
--      char *qmark;
-       size_t i = 0;
--      config_values_t cv[] = {
--              { "mysql-vhost.db",     NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER },
--              { "mysql-vhost.user",   NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER },
--              { "mysql-vhost.pass",   NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER },
--              { "mysql-vhost.sock",   NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER },
--              { "mysql-vhost.sql",    NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER },
--              { "mysql-vhost.hostname", NULL, T_CONFIG_STRING,T_CONFIG_SCOPE_SERVER },
--              { "mysql-vhost.port",   NULL, T_CONFIG_SHORT,   T_CONFIG_SCOPE_SERVER },
--                { NULL,                       NULL, T_CONFIG_UNSET,   T_CONFIG_SCOPE_UNSET }
--        };
--      
-+      /* our very own plugin storage, one entry for each conditional
-+       * 
-+       * srv->config_context->used is the number of conditionals
-+       * */
-       p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
--      
-+
-+      /* get the config of the core-plugin */
-+      core_config = plugin_get_config(srv, CORE_PLUGIN);
-+
-+
-+      /* walk through all conditionals and check for assignments */
-       for (i = 0; i < srv->config_context->used; i++) {
-               plugin_config *s;
-               buffer *sel;
--              
--              
-+              char *qmark;
-+
-+              /* get the config from the core plugin for this conditional-context */
-               s = calloc(1, sizeof(plugin_config));
--              s->mydb = buffer_init();
--              s->myuser = buffer_init();
--              s->mypass = buffer_init();
--              s->mysock = buffer_init();
--              s->hostname = buffer_init();
--              s->port   = 0;               /* default port for mysql */
--              sel = buffer_init();
--              s->mysql = NULL;
-+
-+              s->core = core_config->config_storage[i];
-               
-+              s->mysql = NULL;
-+
-               s->mysql_pre = buffer_init();
-               s->mysql_post = buffer_init();
--              
--              cv[0].destination = s->mydb;
--              cv[1].destination = s->myuser;
--              cv[2].destination = s->mypass;
--              cv[3].destination = s->mysock;
--              cv[4].destination = sel;
--              cv[5].destination = s->hostname;
--              cv[6].destination = &(s->port);
--              
-+
-               p->config_storage[i] = s;
--              
--              if (config_insert_values_global(srv, 
--                      ((data_config *)srv->config_context->data[i])->value,
--                      cv)) return HANDLER_ERROR;
--              
--              s->mysql_pre = buffer_init();
--              s->mysql_post = buffer_init();
--              
-+
-+              /* check if we are the plugin for this backend */
-+              if (!buffer_is_equal_string(s->core->backend, CONST_STR_LEN("mysql"))) continue;
-+
-+              /* attach us to the core-plugin */
-+              s->core->backend_data = p;
-+              s->core->get_vhost = mod_mysql_vhost_get_vhost;
-+
-+              sel = buffer_init();
-+              buffer_copy_string_buffer(sel, s->core->select_vhost);
-+
-               if (sel->used && (qmark = index(sel->ptr, '?'))) {
-                       *qmark = '\0';
-                       buffer_copy_string(s->mysql_pre, sel->ptr);
-@@ -228,35 +145,38 @@
-               } else {
-                       buffer_copy_string_buffer(s->mysql_pre, sel);
-               }
--              
-+              buffer_free(sel);
-+
-               /* required:
-                * - username
--               * - database 
--               * 
-+               * - database
-+               *
-                * optional:
-                * - password, default: empty
-                * - socket, default: mysql default
-                * - hostname, if set overrides socket
-                * - port, default: 3306
-                */
--              
-+
-               /* all have to be set */
--              if (!(buffer_is_empty(s->myuser) ||
--                    buffer_is_empty(s->mydb))) {
-+              if (!(buffer_is_empty(s->core->user) ||
-+                    buffer_is_empty(s->core->db))) {
-                       int fd;
--              
-+
-                       if (NULL == (s->mysql = mysql_init(NULL))) {
-                               log_error_write(srv, __FILE__, __LINE__, "s", "mysql_init() failed, exiting...");
--                              
-+
-                               return HANDLER_ERROR;
-                       }
--#define FOO(x) (s->x->used ? s->x->ptr : NULL)
--                      
--                      if (!mysql_real_connect(s->mysql, FOO(hostname), FOO(myuser), FOO(mypass), 
--                                              FOO(mydb), s->port, FOO(mysock), 0)) {
-+#define FOO(x) (s->core->x->used ? s->core->x->ptr : NULL)
-+
-+                      s->mysql->free_me = 1;
-+
-+                      if (!mysql_real_connect(s->mysql, FOO(hostname), FOO(user), FOO(pass),
-+                                              FOO(db), s->core->port, FOO(sock), 0)) {
-                               log_error_write(srv, __FILE__, __LINE__, "s", mysql_error(s->mysql));
--                              
-+
-                               return HANDLER_ERROR;
-                       }
- #undef FOO
-@@ -265,61 +185,47 @@
-                       /* otherwise we cannot be sure that mysql is fd i-1 */
-                       if (-1 == (fd = open("/dev/null", 0))) {
-                               close(fd);
--                              fcntl(fd-1, F_SETFD, FD_CLOEXEC); 
-+                              fcntl(fd-1, F_SETFD, FD_CLOEXEC);
-                       }
-               }
-       }
--      
--      
-+
-+
-         return HANDLER_GO_ON;
- }
--#define PATCH(x) \
--      p->conf.x = s->x;
- static int mod_mysql_vhost_patch_connection(server *srv, connection *con, plugin_data *p) {
--      size_t i, j;
-+      size_t i;
-       plugin_config *s = p->config_storage[0];
--      
--      PATCH(mysql_pre);
--      PATCH(mysql_post);
--#ifdef HAVE_MYSQL
--      PATCH(mysql);
--#endif
--      
-+
-+      PATCH_OPTION(mysql_pre);
-+      PATCH_OPTION(mysql_post);
-+      PATCH_OPTION(mysql);
-+
-       /* skip the first, the global context */
-       for (i = 1; i < srv->config_context->used; i++) {
-               data_config *dc = (data_config *)srv->config_context->data[i];
-               s = p->config_storage[i];
--              
-+
-               /* condition didn't match */
-               if (!config_check_cond(srv, con, dc)) continue;
--              
--              /* merge config */
--              for (j = 0; j < dc->value->used; j++) {
--                      data_unset *du = dc->value->data[j];
--                      
--                      if (buffer_is_equal_string(du->key, CONST_STR_LEN("mysql-vhost.sql"))) {
--                              PATCH(mysql_pre);
--                              PATCH(mysql_post);
--                      }
--              }
--              
-+
-               if (s->mysql) {
--                      PATCH(mysql);
-+                      PATCH_OPTION(mysql);
-+                      PATCH_OPTION(mysql_pre);
-+                      PATCH_OPTION(mysql_post);
-               }
-       }
--      
-+
-       return 0;
- }
--#undef PATCH
--
--/* handle document root request */
--CONNECTION_FUNC(mod_mysql_vhost_handle_docroot) {
-+/**
-+ * get the vhost info from the database 
-+ */
-+SQLVHOST_BACKEND_GETVHOST(mod_mysql_vhost_get_vhost) {
-       plugin_data *p = p_d;
--      plugin_connection_data *c;
--      stat_cache_entry *sce;
-       unsigned  cols;
-       MYSQL_ROW row;
-@@ -332,13 +238,6 @@
-       if (!p->conf.mysql) return HANDLER_GO_ON;
--      /* sets up connection data if not done yet */
--      c = mod_mysql_vhost_connection_data(srv, con, p_d);
--
--      /* check if cached this connection */
--      if (c->server_name->used && /* con->uri.authority->used && */
--            buffer_is_equal(c->server_name, con->uri.authority)) goto GO_ON;
--
-       /* build and run SQL query */
-       buffer_copy_string_buffer(p->tmp_buf, p->conf.mysql_pre);
-       if (p->conf.mysql_post->used) {
-@@ -347,77 +246,43 @@
-       }
-       if (mysql_query(p->conf.mysql, p->tmp_buf->ptr)) {
-               log_error_write(srv, __FILE__, __LINE__, "s", mysql_error(p->conf.mysql));
--              goto ERR500;
-+
-+              mysql_free_result(result);
-+              return HANDLER_GO_ON;
-       }
-       result = mysql_store_result(p->conf.mysql);
-       cols = mysql_num_fields(result);
-       row = mysql_fetch_row(result);
-+
-       if (!row || cols < 1) {
-               /* no such virtual host */
-               mysql_free_result(result);
-               return HANDLER_GO_ON;
-       }
--      /* sanity check that really is a directory */
--      buffer_copy_string(p->tmp_buf, row[0]);
--      BUFFER_APPEND_SLASH(p->tmp_buf);
--
--      if (HANDLER_ERROR == stat_cache_get_entry(srv, con, p->tmp_buf, &sce)) {
--              log_error_write(srv, __FILE__, __LINE__, "sb", strerror(errno), p->tmp_buf);
--              goto ERR500;
--      }
--        if (!S_ISDIR(sce->st.st_mode)) {
--              log_error_write(srv, __FILE__, __LINE__, "sb", "Not a directory", p->tmp_buf);
--              goto ERR500;
--      }
-+      buffer_copy_string(docroot, row[0]);
--      /* cache the data */
--      buffer_copy_string_buffer(c->server_name, con->uri.authority);
--      buffer_copy_string_buffer(c->document_root, p->tmp_buf);
--
--      /* fcgi_offset and fcgi_arg are optional */
--      if (cols > 1 && row[1]) {
--              c->fcgi_offset = atoi(row[1]);
--              
--              if (cols > 2 && row[2]) {
--                      buffer_copy_string(c->fcgi_arg, row[2]);
--              } else {
--                      c->fcgi_arg->used = 0;
--              }
--      } else {
--              c->fcgi_offset = c->fcgi_arg->used = 0;
--      }
-       mysql_free_result(result);
--      /* fix virtual server and docroot */
--GO_ON:        buffer_copy_string_buffer(con->server_name, c->server_name);
--      buffer_copy_string_buffer(con->physical.doc_root, c->document_root);
--
--#ifdef DEBUG
--      log_error_write(srv, __FILE__, __LINE__, "sbbdb", 
--              result ? "NOT CACHED" : "cached", 
--              con->server_name, con->physical.doc_root,
--              c->fcgi_offset, c->fcgi_arg);
--#endif
--      return HANDLER_GO_ON;   
--
--ERR500:       if (result) mysql_free_result(result);
--      con->http_status = 500; /* Internal Error */
--      return HANDLER_FINISHED;
-+      return HANDLER_GO_ON;
- }
- /* this function is called at dlopen() time and inits the callbacks */
- int mod_mysql_vhost_plugin_init(plugin *p) {
-+      data_string *ds;
-+      
-       p->version     = LIGHTTPD_VERSION_ID;
-       p->name                         = buffer_init_string("mysql_vhost");
-       p->init                         = mod_mysql_vhost_init;
-       p->cleanup                      = mod_mysql_vhost_cleanup;
--      p->handle_request_done          = mod_mysql_vhost_handle_connection_close;
-       p->set_defaults                 = mod_mysql_vhost_set_defaults;
--      p->handle_docroot               = mod_mysql_vhost_handle_docroot;
-       
-+      ds = data_string_init();
-+      buffer_copy_string(ds->value, CORE_PLUGIN);
-+      array_insert_unique(p->required_plugins, (data_unset *)ds);
-+
-       return 0;
- }
- #else
---- ../lighttpd-1.4.11/src/mod_proxy.c 2006-01-31 13:01:22.000000000 +0200
-+++ lighttpd-1.5.0/src/mod_proxy.c     2006-09-07 00:57:05.000000000 +0300
-@@ -1,6 +1,5 @@
- #include <sys/types.h>
--#include <unistd.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <string.h>
-@@ -13,7 +12,6 @@
- #include "keyvalue.h"
- #include "log.h"
--#include "http_chunk.h"
- #include "fdevent.h"
- #include "connections.h"
- #include "response.h"
-@@ -23,6 +21,9 @@
- #include "inet_ntop_cache.h"
- #include "crc32.h"
-+#include "network.h"
-+
-+#include "http_resp.h"
- #include <stdio.h>
-@@ -31,6 +32,8 @@
- #endif
- #include "sys-socket.h"
-+#include "sys-files.h"
-+#include "sys-strings.h"
- #define data_proxy data_fastcgi
- #define data_proxy_init data_fastcgi_init
-@@ -38,22 +41,25 @@
- #define PROXY_RETRY_TIMEOUT 60
- /**
-- * 
-- * the proxy module is based on the fastcgi module 
-- * 
-+ *
-+ * the proxy module is based on the fastcgi module
-+ *
-  * 28.06.2004 Jan Kneschke     The first release
-  * 01.07.2004 Evgeny Rodichev  Several bugfixes and cleanups
-  *            - co-ordinate up- and downstream flows correctly (proxy_demux_response
-  *              and proxy_handle_fdevent)
-  *            - correctly transfer upstream http_response_status;
-  *            - some unused structures removed.
-- * 
-+ *
-  * TODO:      - delay upstream read if write_queue is too large
-  *              (to prevent memory eating, like in apache). Shoud be
-  *              configurable).
-  *            - persistent connection with upstream servers
-  *            - HTTP/1.1
-  */
-+
-+
-+
- typedef enum {
-       PROXY_BALANCE_UNSET,
-       PROXY_BALANCE_FAIR,
-@@ -66,26 +72,33 @@
-       int debug;
-       proxy_balance_t balance;
-+
-+      array *last_used_backends; /* "extension" : last_used_backend */
- } plugin_config;
- typedef struct {
-       PLUGIN_DATA;
--      
-+
-       buffer *parse_response;
-       buffer *balance_buf;
--      
-+
-+      http_resp *resp;
-+
-+      array *ignore_headers;
-+
-       plugin_config **config_storage;
--      
-+
-       plugin_config conf;
- } plugin_data;
--typedef enum { 
--      PROXY_STATE_INIT, 
--      PROXY_STATE_CONNECT, 
--      PROXY_STATE_PREPARE_WRITE, 
--      PROXY_STATE_WRITE, 
--      PROXY_STATE_READ, 
--      PROXY_STATE_ERROR 
-+typedef enum {
-+      PROXY_STATE_INIT,
-+      PROXY_STATE_CONNECT,
-+      PROXY_STATE_PREPARE_WRITE,
-+      PROXY_STATE_WRITE,
-+      PROXY_STATE_RESPONSE_HEADER,
-+      PROXY_STATE_RESPONSE_CONTENT,
-+      PROXY_STATE_ERROR
- } proxy_connection_state_t;
- enum { PROXY_STDOUT, PROXY_END_REQUEST };
-@@ -93,19 +106,16 @@
- typedef struct {
-       proxy_connection_state_t state;
-       time_t state_timestamp;
--      
-+
-       data_proxy *host;
--      
--      buffer *response;
--      buffer *response_header;
-       chunkqueue *wb;
--      
--      int fd; /* fd to the proxy process */
--      int fde_ndx; /* index into the fd-event buffer */
-+      chunkqueue *rb;
-+
-+      iosocket *sock; /* fd to the proxy process */
-       size_t path_info_offset; /* start of path_info in uri.path */
--      
-+
-       connection *remote_conn;  /* dump pointer */
-       plugin_data *plugin_data; /* dump pointer */
- } handler_ctx;
-@@ -116,69 +126,89 @@
- static handler_ctx * handler_ctx_init() {
-       handler_ctx * hctx;
--      
-+
-       hctx = calloc(1, sizeof(*hctx));
--      
-+
-       hctx->state = PROXY_STATE_INIT;
-       hctx->host = NULL;
--      
--      hctx->response = buffer_init();
--      hctx->response_header = buffer_init();
-       hctx->wb = chunkqueue_init();
-+      hctx->rb = chunkqueue_init();
-+
-+      hctx->sock = iosocket_init();
--      hctx->fd = -1;
--      hctx->fde_ndx = -1;
--      
-       return hctx;
- }
- static void handler_ctx_free(handler_ctx *hctx) {
--      buffer_free(hctx->response);
--      buffer_free(hctx->response_header);
-       chunkqueue_free(hctx->wb);
--      
-+      chunkqueue_free(hctx->rb);
-+
-+      iosocket_free(hctx->sock);
-+
-       free(hctx);
- }
- INIT_FUNC(mod_proxy_init) {
-       plugin_data *p;
--      
-+      size_t i;
-+
-+      char *hop2hop_headers[] = {
-+              "Connection",
-+              "Keep-Alive",
-+              "Host",
-+              NULL
-+      };
-+
-       p = calloc(1, sizeof(*p));
--      
--      p->parse_response = buffer_init();
-+
-       p->balance_buf = buffer_init();
--      
-+      p->ignore_headers = array_init();
-+      p->resp = http_response_init();
-+
-+      for (i = 0; hop2hop_headers[i]; i++) {
-+              data_string *ds;
-+
-+              if (NULL == (ds = (data_string *)array_get_unused_element(p->ignore_headers, TYPE_STRING))) {
-+                      ds = data_string_init();
-+              }
-+
-+              buffer_copy_string(ds->key, hop2hop_headers[i]);
-+              buffer_copy_string(ds->value, hop2hop_headers[i]);
-+              array_insert_unique(p->ignore_headers, (data_unset *)ds);
-+      }
-+
-       return p;
- }
- FREE_FUNC(mod_proxy_free) {
-       plugin_data *p = p_d;
--      
-+
-       UNUSED(srv);
--      buffer_free(p->parse_response);
--      buffer_free(p->balance_buf);
--      
-       if (p->config_storage) {
-               size_t i;
-               for (i = 0; i < srv->config_context->used; i++) {
-                       plugin_config *s = p->config_storage[i];
--                      
-+
-                       if (s) {
--                      
-                               array_free(s->extensions);
--                      
-+                              array_free(s->last_used_backends);
-+
-                               free(s);
-                       }
-               }
-               free(p->config_storage);
-       }
--      
-+
-+      array_free(p->ignore_headers);
-+      buffer_free(p->balance_buf);
-+      http_response_free(p->resp);
-+
-       free(p);
--      
-+
-       return HANDLER_GO_ON;
- }
-@@ -186,37 +216,38 @@
-       plugin_data *p = p_d;
-       data_unset *du;
-       size_t i = 0;
--      
--      config_values_t cv[] = { 
-+
-+      config_values_t cv[] = {
-               { "proxy.server",              NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
-               { "proxy.debug",               NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },       /* 1 */
-               { "proxy.balance",             NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },      /* 2 */
-               { NULL,                        NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
-       };
--      
-+
-       p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
--      
-+
-       for (i = 0; i < srv->config_context->used; i++) {
-               plugin_config *s;
-               array *ca;
--              
-+
-               s = malloc(sizeof(plugin_config));
--              s->extensions    = array_init();
-+              s->extensions         = array_init();
-+              s->last_used_backends = array_init();
-               s->debug         = 0;
--              
-+
-               cv[0].destination = s->extensions;
-               cv[1].destination = &(s->debug);
-               cv[2].destination = p->balance_buf;
-               buffer_reset(p->balance_buf);
--              
-+
-               p->config_storage[i] = s;
-               ca = ((data_config *)srv->config_context->data[i])->value;
--      
-+
-               if (0 != config_insert_values_global(srv, ca, cv)) {
-                       return HANDLER_ERROR;
-               }
--      
-+
-               if (buffer_is_empty(p->balance_buf)) {
-                       s->balance = PROXY_BALANCE_FAIR;
-               } else if (buffer_is_equal_string(p->balance_buf, CONST_STR_LEN("fair"))) {
-@@ -226,99 +257,99 @@
-               } else if (buffer_is_equal_string(p->balance_buf, CONST_STR_LEN("hash"))) {
-                       s->balance = PROXY_BALANCE_HASH;
-               } else {
--                      log_error_write(srv, __FILE__, __LINE__, "sb", 
--                                      "proxy.balance has to be one of: fair, round-robin, hash, but not:", p->balance_buf);
-+                      log_error_write(srv, __FILE__, __LINE__, "sb",
-+                              "proxy.balance has to be one of: fair, round-robin, hash, but not:", p->balance_buf);
-                       return HANDLER_ERROR;
-               }
-               if (NULL != (du = array_get_element(ca, "proxy.server"))) {
-                       size_t j;
-                       data_array *da = (data_array *)du;
--                      
-+
-                       if (du->type != TYPE_ARRAY) {
--                              log_error_write(srv, __FILE__, __LINE__, "sss", 
-+                              log_error_write(srv, __FILE__, __LINE__, "sss",
-                                               "unexpected type for key: ", "proxy.server", "array of strings");
--                              
-+
-                               return HANDLER_ERROR;
-                       }
--                      
--                      /* 
-+
-+                      /*
-                        * proxy.server = ( "<ext>" => ...,
-                        *                  "<ext>" => ... )
-                        */
--                      
-+
-                       for (j = 0; j < da->value->used; j++) {
-                               data_array *da_ext = (data_array *)da->value->data[j];
-                               size_t n;
--                              
-+
-                               if (da_ext->type != TYPE_ARRAY) {
--                                      log_error_write(srv, __FILE__, __LINE__, "sssbs", 
--                                                      "unexpected type for key: ", "proxy.server", 
-+                                      log_error_write(srv, __FILE__, __LINE__, "sssbs",
-+                                                      "unexpected type for key: ", "proxy.server",
-                                                       "[", da->value->data[j]->key, "](string)");
--                                      
-+
-                                       return HANDLER_ERROR;
-                               }
--                              
--                              /* 
--                               * proxy.server = ( "<ext>" => 
--                               *                     ( "<host>" => ( ... ), 
-+
-+                              /*
-+                               * proxy.server = ( "<ext>" =>
-+                               *                     ( "<host>" => ( ... ),
-                                *                       "<host>" => ( ... )
--                               *                     ), 
-+                               *                     ),
-                                *                    "<ext>" => ... )
-                                */
--                              
-+
-                               for (n = 0; n < da_ext->value->used; n++) {
-                                       data_array *da_host = (data_array *)da_ext->value->data[n];
--                                      
-+
-                                       data_proxy *df;
-                                       data_array *dfa;
--                                      
--                                      config_values_t pcv[] = { 
-+
-+                                      config_values_t pcv[] = {
-                                               { "host",              NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },      /* 0 */
-                                               { "port",              NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },       /* 1 */
-                                               { NULL,                NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
-                                       };
--                                      
-+
-                                       if (da_host->type != TYPE_ARRAY) {
--                                              log_error_write(srv, __FILE__, __LINE__, "ssSBS", 
--                                                              "unexpected type for key:", 
--                                                              "proxy.server", 
-+                                              log_error_write(srv, __FILE__, __LINE__, "ssSBS",
-+                                                              "unexpected type for key:",
-+                                                              "proxy.server",
-                                                               "[", da_ext->value->data[n]->key, "](string)");
--                                              
-+
-                                               return HANDLER_ERROR;
-                                       }
--                                      
-+
-                                       df = data_proxy_init();
--                                      
-+
-                                       df->port = 80;
--                                      
-+
-                                       buffer_copy_string_buffer(df->key, da_host->key);
--                                      
-+
-                                       pcv[0].destination = df->host;
-                                       pcv[1].destination = &(df->port);
--                                      
-+
-                                       if (0 != config_insert_values_internal(srv, da_host->value, pcv)) {
-                                               return HANDLER_ERROR;
-                                       }
--                                      
-+
-                                       if (buffer_is_empty(df->host)) {
--                                              log_error_write(srv, __FILE__, __LINE__, "sbbbs", 
--                                                              "missing key (string):", 
-+                                              log_error_write(srv, __FILE__, __LINE__, "sbbbs",
-+                                                              "missing key (string):",
-                                                               da->key,
-                                                               da_ext->key,
-                                                               da_host->key,
-                                                               "host");
--                                              
-+
-                                               return HANDLER_ERROR;
-                                       }
--                                      
-+
-                                       /* if extension already exists, take it */
--                                      
-+
-                                       if (NULL == (dfa = (data_array *)array_get_element(s->extensions, da_ext->key->ptr))) {
-                                               dfa = data_array_init();
--                                              
-+
-                                               buffer_copy_string_buffer(dfa->key, da_ext->key);
--                                              
-+
-                                               array_insert_unique(dfa->value, (data_unset *)df);
-                                               array_insert_unique(s->extensions, (data_unset *)dfa);
-                                       } else {
-@@ -328,67 +359,76 @@
-                       }
-               }
-       }
--      
-+
-       return HANDLER_GO_ON;
- }
- void proxy_connection_close(server *srv, handler_ctx *hctx) {
-       plugin_data *p;
-       connection *con;
--      
-+
-       if (NULL == hctx) return;
--      
-+
-       p    = hctx->plugin_data;
-       con  = hctx->remote_conn;
--      
--      if (hctx->fd != -1) {
--              fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
--              fdevent_unregister(srv->ev, hctx->fd);
--              close(hctx->fd);
-+      if (hctx->sock->fd != -1) {
-+              fdevent_event_del(srv->ev, hctx->sock);
-+              fdevent_unregister(srv->ev, hctx->sock);
-+
-+              close(hctx->sock->fd);
-               srv->cur_fds--;
-       }
--      
-+
-       handler_ctx_free(hctx);
--      con->plugin_ctx[p->id] = NULL;  
-+      con->plugin_ctx[p->id] = NULL;
- }
- static int proxy_establish_connection(server *srv, handler_ctx *hctx) {
-       struct sockaddr *proxy_addr;
-       struct sockaddr_in proxy_addr_in;
-       socklen_t servlen;
--      
-+
-       plugin_data *p    = hctx->plugin_data;
-       data_proxy *host= hctx->host;
--      int proxy_fd       = hctx->fd;
--      
-+      int proxy_fd       = hctx->sock->fd;
-+
-       memset(&proxy_addr, 0, sizeof(proxy_addr));
--      
-+
-       proxy_addr_in.sin_family = AF_INET;
-       proxy_addr_in.sin_addr.s_addr = inet_addr(host->host->ptr);
-       proxy_addr_in.sin_port = htons(host->port);
-       servlen = sizeof(proxy_addr_in);
--              
-+
-       proxy_addr = (struct sockaddr *) &proxy_addr_in;
--      
-+
-       if (-1 == connect(proxy_fd, proxy_addr, servlen)) {
--              if (errno == EINPROGRESS || errno == EALREADY) {
-+#ifdef _WIN32
-+      errno = WSAGetLastError();
-+#endif
-+      switch(errno) {
-+#ifdef _WIN32
-+      case WSAEWOULDBLOCK:
-+#endif
-+      case EINPROGRESS:
-+      case EALREADY:
-                       if (p->conf.debug) {
--                              log_error_write(srv, __FILE__, __LINE__, "sd", 
-+                              log_error_write(srv, __FILE__, __LINE__, "sd",
-                                               "connect delayed:", proxy_fd);
-                       }
--                      
-+
-                       return 1;
--              } else {
--                      
--                      log_error_write(srv, __FILE__, __LINE__, "sdsd", 
-+              default:
-+
-+                      log_error_write(srv, __FILE__, __LINE__, "sdsd",
-                                       "connect failed:", proxy_fd, strerror(errno), errno);
--                      
-+
-                       return -1;
-               }
-       }
-+      fprintf(stderr, "%s.%d: connected fd = %d\r\n", __FILE__, __LINE__, proxy_fd);
-       if (p->conf.debug) {
--              log_error_write(srv, __FILE__, __LINE__, "sd", 
-+              log_error_write(srv, __FILE__, __LINE__, "sd",
-                               "connect succeeded: ", proxy_fd);
-       }
-@@ -396,51 +436,52 @@
- }
- void proxy_set_header(connection *con, const char *key, const char *value) {
--    data_string *ds_dst;
-+      data_string *ds_dst;
-+
-+      if (NULL == (ds_dst = (data_string *)array_get_unused_element(con->request.headers, TYPE_STRING))) {
-+              ds_dst = data_string_init();
-+      }
--    if (NULL == (ds_dst = (data_string *)array_get_unused_element(con->request.headers, TYPE_STRING))) {
--          ds_dst = data_string_init();
--    }
--
--    buffer_copy_string(ds_dst->key, key);
--    buffer_copy_string(ds_dst->value, value);
--    array_insert_unique(con->request.headers, (data_unset *)ds_dst);
-+      buffer_copy_string(ds_dst->key, key);
-+      buffer_copy_string(ds_dst->value, value);
-+      array_insert_unique(con->request.headers, (data_unset *)ds_dst);
- }
- void proxy_append_header(connection *con, const char *key, const char *value) {
--    data_string *ds_dst;
-+      data_string *ds_dst;
-+
-+      if (NULL == (ds_dst = (data_string *)array_get_unused_element(con->request.headers, TYPE_STRING))) {
-+              ds_dst = data_string_init();
-+      }
--    if (NULL == (ds_dst = (data_string *)array_get_unused_element(con->request.headers, TYPE_STRING))) {
--          ds_dst = data_string_init();
--    }
--
--    buffer_copy_string(ds_dst->key, key);
--    buffer_append_string(ds_dst->value, value);
--    array_insert_unique(con->request.headers, (data_unset *)ds_dst);
-+      buffer_copy_string(ds_dst->key, key);
-+      buffer_append_string(ds_dst->value, value);
-+      array_insert_unique(con->request.headers, (data_unset *)ds_dst);
- }
- static int proxy_create_env(server *srv, handler_ctx *hctx) {
-       size_t i;
--      
-+
-       connection *con   = hctx->remote_conn;
-+      plugin_data *p    = hctx->plugin_data;
-       buffer *b;
--      
-+
-       /* build header */
-       b = chunkqueue_get_append_buffer(hctx->wb);
--      
-+
-       /* request line */
-       buffer_copy_string(b, get_http_method_name(con->request.http_method));
-       BUFFER_APPEND_STRING_CONST(b, " ");
--      
-+
-       buffer_append_string_buffer(b, con->request.uri);
-       BUFFER_APPEND_STRING_CONST(b, " HTTP/1.0\r\n");
-       proxy_append_header(con, "X-Forwarded-For", (char *)inet_ntop_cache_get_ip(srv, &(con->dst_addr)));
--      /* http_host is NOT is just a pointer to a buffer 
-+      /* http_host is NOT is just a pointer to a buffer
-        * which is NULL if it is not set */
--      if (con->request.http_host && 
-+      if (con->request.http_host &&
-           !buffer_is_empty(con->request.http_host)) {
-               proxy_set_header(con, "X-Host", con->request.http_host->ptr);
-       }
-@@ -449,26 +490,27 @@
-       /* request header */
-       for (i = 0; i < con->request.headers->used; i++) {
-               data_string *ds;
--              
-+
-               ds = (data_string *)con->request.headers->data[i];
--              
--              if (ds->value->used && ds->key->used) {
--                      if (buffer_is_equal_string(ds->key, CONST_STR_LEN("Connection"))) continue;
--                      
--                      buffer_append_string_buffer(b, ds->key);
--                      BUFFER_APPEND_STRING_CONST(b, ": ");
--                      buffer_append_string_buffer(b, ds->value);
--                      BUFFER_APPEND_STRING_CONST(b, "\r\n");
--              }
-+
-+              if (buffer_is_empty(ds->value) || buffer_is_empty(ds->key)) continue;
-+
-+              if (buffer_is_equal_string(ds->key, CONST_STR_LEN("Connection"))) continue;
-+              if (buffer_is_equal_string(ds->key, CONST_STR_LEN("Keep-Alive"))) continue;
-+
-+              buffer_append_string_buffer(b, ds->key);
-+              BUFFER_APPEND_STRING_CONST(b, ": ");
-+              buffer_append_string_buffer(b, ds->value);
-+              BUFFER_APPEND_STRING_CONST(b, "\r\n");
-       }
--      
-+
-       BUFFER_APPEND_STRING_CONST(b, "\r\n");
--      
-+
-       hctx->wb->bytes_in += b->used - 1;
-       /* body */
--      
-+
-       if (con->request.content_length) {
--              chunkqueue *req_cq = con->request_content_queue;
-+              chunkqueue *req_cq = con->recv;
-               chunk *req_c;
-               off_t offset;
-@@ -479,7 +521,7 @@
-                       /* we announce toWrite octects
-                        * now take all the request_content chunk that we need to fill this request
--                       * */   
-+                       * */
-                       switch (req_c->type) {
-                       case FILE_CHUNK:
-@@ -507,223 +549,145 @@
-                               req_c->offset += weHave;
-                               req_cq->bytes_out += weHave;
--                              
-+
-                               hctx->wb->bytes_in += weHave;
-                               break;
-                       default:
-                               break;
-                       }
--                      
-+
-                       offset += weHave;
-               }
-       }
--      
-+
-       return 0;
- }
- static int proxy_set_state(server *srv, handler_ctx *hctx, proxy_connection_state_t state) {
-       hctx->state = state;
-       hctx->state_timestamp = srv->cur_ts;
--      
--      return 0;
--}
--
--static int proxy_response_parse(server *srv, connection *con, plugin_data *p, buffer *in) {
--      char *s, *ns;
--      int http_response_status = -1;
--      
--      UNUSED(srv);
--
--      /* \r\n -> \0\0 */
--      
--      buffer_copy_string_buffer(p->parse_response, in);
--      
--      for (s = p->parse_response->ptr; NULL != (ns = strstr(s, "\r\n")); s = ns + 2) {
--              char *key, *value;
--              int key_len;
--              data_string *ds;
--              int copy_header;
--              
--              ns[0] = '\0';
--              ns[1] = '\0';
--
--              if (-1 == http_response_status) {
--                      /* The first line of a Response message is the Status-Line */
--
--                      for (key=s; *key && *key != ' '; key++);
--
--                      if (*key) {
--                              http_response_status = (int) strtol(key, NULL, 10);
--                              if (http_response_status <= 0) http_response_status = 502;
--                      } else {
--                              http_response_status = 502;
--                      }
--
--                      con->http_status = http_response_status;
--                      con->parsed_response |= HTTP_STATUS;
--                      continue;
--              }
--              
--              if (NULL == (value = strchr(s, ':'))) {
--                      /* now we expect: "<key>: <value>\n" */
--
--                      continue;
--              }
--
--              key = s;
--              key_len = value - key;
--              
--              value++;
--              /* strip WS */
--              while (*value == ' ' || *value == '\t') value++;
--              
--              copy_header = 1;
--              
--              switch(key_len) {
--              case 4:
--                      if (0 == strncasecmp(key, "Date", key_len)) {
--                              con->parsed_response |= HTTP_DATE;
--                      }
--                      break;
--              case 8:
--                      if (0 == strncasecmp(key, "Location", key_len)) {
--                              con->parsed_response |= HTTP_LOCATION;
--                      }
--                      break;
--              case 10:
--                      if (0 == strncasecmp(key, "Connection", key_len)) {
--                              copy_header = 0;
--                      }
--                      break;
--              case 14:
--                      if (0 == strncasecmp(key, "Content-Length", key_len)) {
--                              con->response.content_length = strtol(value, NULL, 10);
--                              con->parsed_response |= HTTP_CONTENT_LENGTH;
--                      }
--                      break;
--              default:
--                      break;
--              }
--
--              if (copy_header) {
--                      if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
--                              ds = data_response_init();
--                      }
--                      buffer_copy_string_len(ds->key, key, key_len);
--                      buffer_copy_string(ds->value, value);
--                      
--                      array_insert_unique(con->response.headers, (data_unset *)ds);
--              }
--      }
--      
-       return 0;
- }
- static int proxy_demux_response(server *srv, handler_ctx *hctx) {
--      int fin = 0;
--      int b;
--      ssize_t r;
--      
-       plugin_data *p    = hctx->plugin_data;
-       connection *con   = hctx->remote_conn;
--      int proxy_fd       = hctx->fd;
--      
--      /* check how much we have to read */
--      if (ioctl(hctx->fd, FIONREAD, &b)) {
--              log_error_write(srv, __FILE__, __LINE__, "sd", 
--                              "ioctl failed: ",
--                              proxy_fd);
-+      chunkqueue *next_queue = NULL;
-+      chunk *c = NULL;
-+
-+      switch(srv->network_backend_read(srv, con, hctx->sock, hctx->rb)) {
-+      case NETWORK_STATUS_SUCCESS:
-+              /* we got content */
-+              break;
-+      case NETWORK_STATUS_WAIT_FOR_EVENT:
-+              return 0;
-+      case NETWORK_STATUS_CONNECTION_CLOSE:
-+              /* we are done, get out of here */
-+              con->send->is_closed = 1;
-+
-+              /* close the chunk-queue with a empty chunk */
-+
-+              return 1;
-+      default:
-+              /* oops */
-               return -1;
-       }
-+      /* looks like we got some content
-+      *
-+      * split off the header from the incoming stream
-+      */
--      if (p->conf.debug) {
--              log_error_write(srv, __FILE__, __LINE__, "sd",
--                             "proxy - have to read:", b);
--      }
-+      if (hctx->state == PROXY_STATE_RESPONSE_HEADER) {
-+              size_t i;
-+              int have_content_length = 0;
--      if (b > 0) {
--              if (hctx->response->used == 0) {
--                      /* avoid too small buffer */
--                      buffer_prepare_append(hctx->response, b + 1);
--                      hctx->response->used = 1;
--              } else {
--                      buffer_prepare_append(hctx->response, hctx->response->used + b);
--              }
--              
--              if (-1 == (r = read(hctx->fd, hctx->response->ptr + hctx->response->used - 1, b))) {
--                      log_error_write(srv, __FILE__, __LINE__, "sds", 
--                                      "unexpected end-of-file (perhaps the proxy process died):",
--                                      proxy_fd, strerror(errno));
--                      return -1;
--              }
--              
--              /* this should be catched by the b > 0 above */
--              assert(r);
--              
--              hctx->response->used += r;
--              hctx->response->ptr[hctx->response->used - 1] = '\0';
--
--#if 0
--              log_error_write(srv, __FILE__, __LINE__, "sdsbs", 
--                              "demux: Response buffer len", hctx->response->used, ":", hctx->response, ":");
--#endif
-+              http_response_reset(p->resp);
--              if (0 == con->got_response) {
--                      con->got_response = 1;
--                      buffer_prepare_copy(hctx->response_header, 128);
--              }
--                              
--              if (0 == con->file_started) {
--                      char *c;
--                              
--                      /* search for the \r\n\r\n in the string */
--                      if (NULL != (c = buffer_search_string_len(hctx->response, "\r\n\r\n", 4))) {
--                              size_t hlen = c - hctx->response->ptr + 4;
--                              size_t blen = hctx->response->used - hlen - 1;
--                              /* found */
--                              
--                              buffer_append_string_len(hctx->response_header, hctx->response->ptr, c - hctx->response->ptr + 4);
--#if 0
--                              log_error_write(srv, __FILE__, __LINE__, "sb", "Header:", hctx->response_header);
--#endif
--                              /* parse the response header */
--                              proxy_response_parse(srv, con, p, hctx->response_header);
--                                      
--                              /* enable chunked-transfer-encoding */
--                              if (con->request.http_version == HTTP_VERSION_1_1 &&
--                                  !(con->parsed_response & HTTP_CONTENT_LENGTH)) {
--                                      con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
-+              /* the response header is not fully received yet,
-+              *
-+              * extract the http-response header from the rb-cq
-+              */
-+              switch (http_response_parse_cq(hctx->rb, p->resp)) {
-+              case PARSE_ERROR:
-+                      /* parsing failed */
-+
-+                      con->http_status = 502; /* Bad Gateway */
-+                      return 1;
-+              case PARSE_NEED_MORE:
-+                      return 0;
-+              case PARSE_SUCCESS:
-+                      con->http_status = p->resp->status;
-+
-+                      chunkqueue_remove_finished_chunks(hctx->rb);
-+
-+                      /* copy the http-headers */
-+                      for (i = 0; i < p->resp->headers->used; i++) {
-+                              const char *ign[] = { "Status", "Connection", NULL };
-+                              size_t j;
-+                              data_string *ds;
-+
-+                              data_string *header = (data_string *)p->resp->headers->data[i];
-+
-+                              /* some headers are ignored by default */
-+                              for (j = 0; ign[j]; j++) {
-+                                      if (0 == strcasecmp(ign[j], header->key->ptr)) break;
-+                              }
-+                              if (ign[j]) continue;
-+
-+                              if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("Location"))) {
-+                                      /* CGI/1.1 rev 03 - 7.2.1.2 */
-+                                      if (con->http_status == 0) con->http_status = 302;
-+                              } else if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("Content-Length"))) {
-+                                      have_content_length = 1;
-                               }
--                                      
--                              con->file_started = 1;
--                              if (blen) {
--                                      http_chunk_append_mem(srv, con, c + 4, blen + 1);
--                                      joblist_append(srv, con);
-+                              
-+                              if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
-+                                      ds = data_response_init();
-                               }
--                              hctx->response->used = 0;
-+                              buffer_copy_string_buffer(ds->key, header->key);
-+                              buffer_copy_string_buffer(ds->value, header->value);
-+
-+                              array_insert_unique(con->response.headers, (data_unset *)ds);
-                       }
--              } else {
--                      http_chunk_append_mem(srv, con, hctx->response->ptr, hctx->response->used);
--                      joblist_append(srv, con);
--                      hctx->response->used = 0;
-+
-+                      con->file_started = 1;
-+
-+                      hctx->state = PROXY_STATE_RESPONSE_CONTENT;
-+                      break;
-               }
--              
--      } else {
--              /* reading from upstream done */
--              con->file_finished = 1;
--              
--              http_chunk_append_mem(srv, con, NULL, 0);
--              joblist_append(srv, con);
--              
--              fin = 1;
-       }
--      
--      return fin;
-+
-+      /* FIXME: pass the response-header to the other plugins to
-+      * setup the filter-queue
-+      *
-+      * - use next-queue instead of con->write_queue
-+      */
-+
-+      next_queue = con->send;
-+
-+      assert(hctx->state == PROXY_STATE_RESPONSE_CONTENT);
-+
-+      /* FIXME: if we have a content-length or chunked-encoding
-+      * handle it.
-+      *
-+      * for now we wait for EOF on the socket */
-+
-+      /* copy the content to the next cq */
-+      for (c = hctx->rb->first; c; c = c->next) {
-+              chunkqueue_append_mem(con->send, c->mem->ptr + c->offset, c->mem->used - c->offset);
-+
-+              c->offset = c->mem->used - 1;
-+      }
-+
-+      chunkqueue_remove_finished_chunks(hctx->rb);
-+      joblist_append(srv, con);
-+
-+      return 0;
- }
-@@ -731,32 +695,32 @@
-       data_proxy *host= hctx->host;
-       plugin_data *p    = hctx->plugin_data;
-       connection *con   = hctx->remote_conn;
--      
-+
-       int ret;
--      
--      if (!host || 
--          (!host->host->used || !host->port)) return -1;
--      
-+
-+      if (!host ||
-+              (!host->host->used || !host->port)) return -1;
-+
-       switch(hctx->state) {
-       case PROXY_STATE_INIT:
--              if (-1 == (hctx->fd = socket(AF_INET, SOCK_STREAM, 0))) {
-+              if (-1 == (hctx->sock->fd = socket(AF_INET, SOCK_STREAM, 0))) {
-                       log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed: ", strerror(errno));
-                       return HANDLER_ERROR;
-               }
--              hctx->fde_ndx = -1;
--              
-+              hctx->sock->fde_ndx = -1;
-+
-               srv->cur_fds++;
--              
--              fdevent_register(srv->ev, hctx->fd, proxy_handle_fdevent, hctx);
--              
--              if (-1 == fdevent_fcntl_set(srv->ev, hctx->fd)) {
-+
-+              fdevent_register(srv->ev, hctx->sock, proxy_handle_fdevent, hctx);
-+
-+              if (-1 == fdevent_fcntl_set(srv->ev, hctx->sock)) {
-                       log_error_write(srv, __FILE__, __LINE__, "ss", "fcntl failed: ", strerror(errno));
--                      
-+
-                       return HANDLER_ERROR;
-               }
--              
-+
-               /* fall through */
--              
-+
-       case PROXY_STATE_CONNECT:
-               /* try to finish the connect() */
-               if (hctx->state == PROXY_STATE_INIT) {
-@@ -764,16 +728,16 @@
-                       switch (proxy_establish_connection(srv, hctx)) {
-                       case 1:
-                               proxy_set_state(srv, hctx, PROXY_STATE_CONNECT);
--                              
-+
-                               /* connection is in progress, wait for an event and call getsockopt() below */
--                              
--                              fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
--                              
-+
-+                              fdevent_event_add(srv->ev, hctx->sock, FDEVENT_OUT);
-+
-                               return HANDLER_WAIT_FOR_EVENT;
-                       case -1:
-                               /* if ECONNREFUSED choose another connection -> FIXME */
--                              hctx->fde_ndx = -1;
--                              
-+                              hctx->sock->fde_ndx = -1;
-+
-                               return HANDLER_ERROR;
-                       default:
-                               /* everything is ok, go on */
-@@ -782,152 +746,152 @@
-               } else {
-                       int socket_error;
-                       socklen_t socket_error_len = sizeof(socket_error);
--              
--                      /* we don't need it anymore */  
--                      fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
-+
-+                      /* we don't need it anymore */
-+                      fdevent_event_del(srv->ev, hctx->sock);
-                       /* try to finish the connect() */
--                      if (0 != getsockopt(hctx->fd, SOL_SOCKET, SO_ERROR, &socket_error, &socket_error_len)) {
--                              log_error_write(srv, __FILE__, __LINE__, "ss", 
-+                      if (0 != getsockopt(hctx->sock->fd, SOL_SOCKET, SO_ERROR, &socket_error, &socket_error_len)) {
-+                              log_error_write(srv, __FILE__, __LINE__, "ss",
-                                               "getsockopt failed:", strerror(errno));
--                              
-+
-                               return HANDLER_ERROR;
-                       }
-                       if (socket_error != 0) {
-                               log_error_write(srv, __FILE__, __LINE__, "ss",
--                                              "establishing connection failed:", strerror(socket_error), 
-+                                              "establishing connection failed:", strerror(socket_error),
-                                               "port:", hctx->host->port);
--                              
-+
-                               return HANDLER_ERROR;
-                       }
-                       if (p->conf.debug) {
--                              log_error_write(srv, __FILE__, __LINE__,  "s", "proxy - connect - delayed success"); 
-+                              log_error_write(srv, __FILE__, __LINE__,  "s", "proxy - connect - delayed success");
-                       }
-               }
--              
-+
-               proxy_set_state(srv, hctx, PROXY_STATE_PREPARE_WRITE);
-               /* fall through */
-       case PROXY_STATE_PREPARE_WRITE:
-               proxy_create_env(srv, hctx);
--              
-+
-               proxy_set_state(srv, hctx, PROXY_STATE_WRITE);
--              
-+
-               /* fall through */
-       case PROXY_STATE_WRITE:;
--              ret = srv->network_backend_write(srv, con, hctx->fd, hctx->wb); 
-+              ret = srv->network_backend_write(srv, con, hctx->sock, hctx->wb);
-               chunkqueue_remove_finished_chunks(hctx->wb);
--              if (-1 == ret) {
--                      if (errno != EAGAIN &&
--                          errno != EINTR) {
--                              log_error_write(srv, __FILE__, __LINE__, "ssd", "write failed:", strerror(errno), errno);
--                              
--                              return HANDLER_ERROR;
--                      } else {
--                              fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
-+              switch(ret) {
-+              case NETWORK_STATUS_FATAL_ERROR:
-+                      log_error_write(srv, __FILE__, __LINE__, "ssd", "write failed:", strerror(errno), errno);
--                              return HANDLER_WAIT_FOR_EVENT;
--                      }
-+                      return HANDLER_ERROR;
-+              case NETWORK_STATUS_WAIT_FOR_EVENT:
-+
-+                      fdevent_event_add(srv->ev, hctx->sock, FDEVENT_OUT);
-+
-+                      return HANDLER_WAIT_FOR_EVENT;
-               }
-               if (hctx->wb->bytes_out == hctx->wb->bytes_in) {
--                      proxy_set_state(srv, hctx, PROXY_STATE_READ);
-+                      proxy_set_state(srv, hctx, PROXY_STATE_RESPONSE_HEADER);
--                      fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
--                      fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
-+                      fdevent_event_del(srv->ev, hctx->sock);
-+                      fdevent_event_add(srv->ev, hctx->sock, FDEVENT_IN);
-               } else {
--                      fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
--                              
-+                      fdevent_event_add(srv->ev, hctx->sock, FDEVENT_OUT);
-+
-                       return HANDLER_WAIT_FOR_EVENT;
-               }
--              
-+
-               return HANDLER_WAIT_FOR_EVENT;
--      case PROXY_STATE_READ:
-+      case PROXY_STATE_RESPONSE_CONTENT:
-+      case PROXY_STATE_RESPONSE_HEADER:
-               /* waiting for a response */
-+
-               return HANDLER_WAIT_FOR_EVENT;
-       default:
-               log_error_write(srv, __FILE__, __LINE__, "s", "(debug) unknown state");
-               return HANDLER_ERROR;
-       }
--      
-+
-       return HANDLER_GO_ON;
- }
--#define PATCH(x) \
--      p->conf.x = s->x;
- static int mod_proxy_patch_connection(server *srv, connection *con, plugin_data *p) {
-       size_t i, j;
-       plugin_config *s = p->config_storage[0];
--      
--      PATCH(extensions);
--      PATCH(debug);
--      PATCH(balance);
--      
-+
-+      PATCH_OPTION(extensions);
-+      PATCH_OPTION(debug);
-+      PATCH_OPTION(balance);
-+      PATCH_OPTION(last_used_backends);
-+
-       /* skip the first, the global context */
-       for (i = 1; i < srv->config_context->used; i++) {
-               data_config *dc = (data_config *)srv->config_context->data[i];
-               s = p->config_storage[i];
--              
-+
-               /* condition didn't match */
-               if (!config_check_cond(srv, con, dc)) continue;
--              
-+
-               /* merge config */
-               for (j = 0; j < dc->value->used; j++) {
-                       data_unset *du = dc->value->data[j];
--                      
-+
-                       if (buffer_is_equal_string(du->key, CONST_STR_LEN("proxy.server"))) {
--                              PATCH(extensions);
-+                              PATCH_OPTION(extensions);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("proxy.debug"))) {
--                              PATCH(debug);
-+                              PATCH_OPTION(debug);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("proxy.balance"))) {
--                              PATCH(balance);
-+                              PATCH_OPTION(balance);
-+                              PATCH_OPTION(last_used_backends);
-                       }
-               }
-       }
--      
-+
-       return 0;
- }
--#undef PATCH
- SUBREQUEST_FUNC(mod_proxy_handle_subrequest) {
-       plugin_data *p = p_d;
--      
-+
-       handler_ctx *hctx = con->plugin_ctx[p->id];
-       data_proxy *host;
--      
-+
-       if (NULL == hctx) return HANDLER_GO_ON;
-       mod_proxy_patch_connection(srv, con, p);
--      
-+
-       host = hctx->host;
--      
-+
-       /* not my job */
-       if (con->mode != p->id) return HANDLER_GO_ON;
--      
-+
-       /* ok, create the request */
-       switch(proxy_write_request(srv, hctx)) {
-       case HANDLER_ERROR:
--              log_error_write(srv, __FILE__, __LINE__,  "sbdd", "proxy-server disabled:", 
-+              log_error_write(srv, __FILE__, __LINE__,  "sbdd", "proxy-server disabled:",
-                               host->host,
-                               host->port,
--                              hctx->fd);
--              
-+                              hctx->sock->fd);
-+
-               /* disable this server */
-               host->is_disabled = 1;
-               host->disable_ts = srv->cur_ts;
--              
-+
-               proxy_connection_close(srv, hctx);
--      
--              /* reset the enviroment and restart the sub-request */  
-+
-+              /* reset the enviroment and restart the sub-request */
-               buffer_reset(con->physical.path);
-               con->mode = DIRECT;
-               joblist_append(srv, con);
--              /* mis-using HANDLER_WAIT_FOR_FD to break out of the loop 
--               * and hope that the childs will be restarted 
--               * 
-+              /* mis-using HANDLER_WAIT_FOR_FD to break out of the loop
-+               * and hope that the childs will be restarted
-+               *
-                */
-               return HANDLER_WAIT_FOR_FD;
-@@ -938,7 +902,7 @@
-       default:
-               break;
-       }
--      
-+
-       if (con->file_started == 1) {
-               return HANDLER_FINISHED;
-       } else {
-@@ -951,13 +915,14 @@
-       handler_ctx *hctx = ctx;
-       connection  *con  = hctx->remote_conn;
-       plugin_data *p    = hctx->plugin_data;
--      
--      
-+
-+
-       if ((revents & FDEVENT_IN) &&
--          hctx->state == PROXY_STATE_READ) {
-+          (hctx->state == PROXY_STATE_RESPONSE_HEADER ||
-+           hctx->state == PROXY_STATE_RESPONSE_CONTENT)) {
-               if (p->conf.debug) {
--                      log_error_write(srv, __FILE__, __LINE__, "sd", 
-+                      log_error_write(srv, __FILE__, __LINE__, "sd",
-                                       "proxy: fdevent-in", hctx->state);
-               }
-@@ -965,86 +930,87 @@
-               case 0:
-                       break;
-               case 1:
-+                      log_error_write(srv, __FILE__, __LINE__, "sd",
-+                                      "proxy: request done", hctx->sock->fd);
-                       hctx->host->usage--;
--                      
-+
-                       /* we are done */
-                       proxy_connection_close(srv, hctx);
--                      
-+
-                       joblist_append(srv, con);
-                       return HANDLER_FINISHED;
-               case -1:
-                       if (con->file_started == 0) {
-                               /* nothing has been send out yet, send a 500 */
--                              connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
-                               con->http_status = 500;
-                               con->mode = DIRECT;
-                       } else {
-                               /* response might have been already started, kill the connection */
-                               connection_set_state(srv, con, CON_STATE_ERROR);
-                       }
--                      
-+
-                       joblist_append(srv, con);
-                       return HANDLER_FINISHED;
-               }
-       }
--      
-+
-       if (revents & FDEVENT_OUT) {
-               if (p->conf.debug) {
--                      log_error_write(srv, __FILE__, __LINE__, "sd", 
-+                      log_error_write(srv, __FILE__, __LINE__, "sd",
-                                       "proxy: fdevent-out", hctx->state);
-               }
-               if (hctx->state == PROXY_STATE_CONNECT ||
-                   hctx->state == PROXY_STATE_WRITE) {
-                       /* we are allowed to send something out
--                       * 
-+                       *
-                        * 1. in a unfinished connect() call
-                        * 2. in a unfinished write() call (long POST request)
-                        */
-                       return mod_proxy_handle_subrequest(srv, con, p);
-               } else {
--                      log_error_write(srv, __FILE__, __LINE__, "sd", 
-+                      log_error_write(srv, __FILE__, __LINE__, "sd",
-                                       "proxy: out", hctx->state);
-               }
-       }
--      
-+
-       /* perhaps this issue is already handled */
-       if (revents & FDEVENT_HUP) {
-               if (p->conf.debug) {
--                      log_error_write(srv, __FILE__, __LINE__, "sd", 
-+                      log_error_write(srv, __FILE__, __LINE__, "sd",
-                                       "proxy: fdevent-hup", hctx->state);
-               }
--              
-+
-               if (hctx->state == PROXY_STATE_CONNECT) {
-                       /* connect() -> EINPROGRESS -> HUP */
--                      
-+
-                       /**
--                       * what is proxy is doing if it can't reach the next hop ? 
--                       * 
-+                       * what is proxy is doing if it can't reach the next hop ?
-+                       *
-                        */
--                      
-+
-                       proxy_connection_close(srv, hctx);
-                       joblist_append(srv, con);
--                      
-+
-                       con->http_status = 503;
-                       con->mode = DIRECT;
--                      
-+
-                       return HANDLER_FINISHED;
-               }
--              con->file_finished = 1;
-+              con->send->is_closed = 1;
-               proxy_connection_close(srv, hctx);
-               joblist_append(srv, con);
-       } else if (revents & FDEVENT_ERR) {
-               /* kill all connections to the proxy process */
--              
-+
-               log_error_write(srv, __FILE__, __LINE__, "sd", "proxy-FDEVENT_ERR, but no HUP", revents);
-               joblist_append(srv, con);
-               proxy_connection_close(srv, hctx);
-       }
--      
-+
-       return HANDLER_FINISHED;
- }
-@@ -1058,44 +1024,48 @@
-       buffer *fn;
-       data_array *extension = NULL;
-       size_t path_info_offset;
--      
-+      data_integer *last_used_backend;
-+      data_proxy *host = NULL;
-+      handler_ctx *hctx = NULL;
-+
-+      array *backends = NULL;
-+
-       /* Possibly, we processed already this request */
-       if (con->file_started == 1) return HANDLER_GO_ON;
--      
-+
-       mod_proxy_patch_connection(srv, con, p);
--      
-+
-       fn = con->uri.path;
-       if (fn->used == 0) {
-               return HANDLER_ERROR;
-       }
--      
-+
-       s_len = fn->used - 1;
--      
--      
-+
-       path_info_offset = 0;
--      if (p->conf.debug) {    
-+      if (p->conf.debug) {
-               log_error_write(srv, __FILE__, __LINE__,  "s", "proxy - start");
-       }
-       /* check if extension matches */
-       for (k = 0; k < p->conf.extensions->used; k++) {
-               size_t ct_len;
--              
-+
-               extension = (data_array *)p->conf.extensions->data[k];
--              
-+
-               if (extension->key->used == 0) continue;
--              
-+
-               ct_len = extension->key->used - 1;
--              
-+
-               if (s_len < ct_len) continue;
--              
-+
-               /* check extension in the form "/proxy_pattern" */
-               if (*(extension->key->ptr) == '/' && strncmp(fn->ptr, extension->key->ptr, ct_len) == 0) {
-                       if (s_len > ct_len + 1) {
-                               char *pi_offset;
--                              
-+
-                               if (0 != (pi_offset = strchr(fn->ptr + ct_len + 1, '/'))) {
-                                       path_info_offset = pi_offset - fn->ptr;
-                               }
-@@ -1106,12 +1076,14 @@
-                       break;
-               }
-       }
--      
-+
-       if (k == p->conf.extensions->used) {
-               return HANDLER_GO_ON;
-       }
--      if (p->conf.debug) {    
-+      backends = extension->value;
-+
-+      if (p->conf.debug) {
-               log_error_write(srv, __FILE__, __LINE__,  "s", "proxy - ext found");
-       }
-@@ -1120,34 +1092,34 @@
-               /* hash balancing */
-               if (p->conf.debug) {
--                      log_error_write(srv, __FILE__, __LINE__,  "sd", 
--                                      "proxy - used hash balancing, hosts:", extension->value->used);
-+                      log_error_write(srv, __FILE__, __LINE__,  "sd",
-+                                      "proxy - used hash balancing, hosts:", backends->used);
-               }
--              for (k = 0, ndx = -1, last_max = ULONG_MAX; k < extension->value->used; k++) {
--                      data_proxy *host = (data_proxy *)extension->value->data[k];
-+              for (k = 0, ndx = -1, last_max = ULONG_MAX; k < backends->used; k++) {
-                       unsigned long cur_max;
--                      if (host->is_disabled) continue;
--                      
-+                      data_proxy *cur = (data_proxy *)backends->data[k];
-+
-+                      if (cur->is_disabled) continue;
-+
-                       cur_max = generate_crc32c(CONST_BUF_LEN(con->uri.path)) +
--                              generate_crc32c(CONST_BUF_LEN(host->host)) + /* we can cache this */
-+                              generate_crc32c(CONST_BUF_LEN(cur->host)) + /* we can cache this */
-                               generate_crc32c(CONST_BUF_LEN(con->uri.authority));
--                      
-+
-                       if (p->conf.debug) {
--                              log_error_write(srv, __FILE__, __LINE__,  "sbbbd", 
-+                              log_error_write(srv, __FILE__, __LINE__,  "sbbbd",
-                                               "proxy - election:",
-                                               con->uri.path,
--                                              host->host,
-+                                              cur->host,
-                                               con->uri.authority,
-                                               cur_max);
-                       }
--                      if ((last_max == ULONG_MAX) || /* first round */
--                          (cur_max > last_max)) {
-+                      if (host == NULL || (cur_max > last_max)) {
-                               last_max = cur_max;
--                              ndx = k;
-+                              host = cur;
-                       }
-               }
-@@ -1155,19 +1127,20 @@
-       case PROXY_BALANCE_FAIR:
-               /* fair balancing */
-               if (p->conf.debug) {
--                      log_error_write(srv, __FILE__, __LINE__,  "s", 
-+                      log_error_write(srv, __FILE__, __LINE__,  "s",
-                                       "proxy - used fair balancing");
-               }
--              for (k = 0, ndx = -1, max_usage = INT_MAX; k < extension->value->used; k++) {
--                      data_proxy *host = (data_proxy *)extension->value->data[k];
--              
--                      if (host->is_disabled) continue;
--
--                      if (host->usage < max_usage) {
--                              max_usage = host->usage;
--                      
--                              ndx = k;
-+              /* try to find the host with the lowest load */
-+              for (k = 0, max_usage = 0; k < backends->used; k++) {
-+                      data_proxy *cur = (data_proxy *)backends->data[k];
-+
-+                      if (cur->is_disabled) continue;
-+
-+                      if (NULL == host || cur->usage < max_usage) {
-+                              max_usage = cur->usage;
-+
-+                              host = cur;
-                       }
-               }
-@@ -1175,89 +1148,100 @@
-       case PROXY_BALANCE_RR:
-               /* round robin */
-               if (p->conf.debug) {
--                      log_error_write(srv, __FILE__, __LINE__,  "s", 
-+                      log_error_write(srv, __FILE__, __LINE__,  "s",
-                                       "proxy - used round-robin balancing");
-               }
-               /* just to be sure */
--              assert(extension->value->used < INT_MAX);
--              
--              for (k = 0, ndx = -1, max_usage = INT_MAX; k < extension->value->used; k++) {
--                      data_proxy *host = (data_proxy *)extension->value->data[k];
--              
--                      if (host->is_disabled) continue;
--
--                      /* first usable ndx */
--                      if (max_usage == INT_MAX) {
--                              max_usage = k;
--                      }
-+              assert(backends->used < INT_MAX);
--                      /* get next ndx */
--                      if ((int)k > host->last_used_ndx) {
--                              ndx = k;
--                              host->last_used_ndx = k;
-+              /* send each request to another host:
-+               *
-+               * e.g.:
-+               *
-+               * if we have three hosts it is
-+               *
-+               * 1 .. 2 .. 3 .. 1 .. 2 .. 3
-+               *
-+               **/
--                              break;
--                      }
-+              /* walk through the list */
-+              last_used_backend = (data_integer *)array_get_element(p->conf.last_used_backends, extension->key->ptr);
-+
-+              if (NULL == last_used_backend) {
-+                      last_used_backend = data_integer_init();
-+
-+                      buffer_copy_string_buffer(last_used_backend->key, extension->key);
-+                      last_used_backend->value = 0;
-+
-+                      array_insert_unique(p->conf.last_used_backends, (data_unset *)last_used_backend);
-+              }
-+
-+              /* scan all but the last host to see if they are up
-+               * take the first running host */
-+              for (k = last_used_backend->value + 1; (int)(k % backends->used) != last_used_backend->value; k++) {
-+                      data_proxy *cur = (data_proxy *)backends->data[k % backends->used];
-+
-+                      if (cur->is_disabled) continue;
-+
-+                      host = cur;
-+
-+                      last_used_backend->value = k;
-+
-+                      break;
-               }
--              
--              /* didn't found a higher id, wrap to the start */
--              if (ndx != -1 && max_usage != INT_MAX) {
--                      ndx = max_usage;
-+
-+              if (NULL == host) {
-+                      /* we found nothing better, fallback to the last used backend
-+                       * and check if it is still up */
-+                      host = (data_proxy *)backends->data[last_used_backend->value];
-+
-+                      if (host->is_disabled) host = NULL;
-               }
-               break;
-       default:
-               break;
-       }
--      
--      /* found a server */
--      if (ndx != -1) {
--              data_proxy *host = (data_proxy *)extension->value->data[ndx];
--              
--              /* 
--               * if check-local is disabled, use the uri.path handler 
--               * 
--               */
--              
--              /* init handler-context */
--              handler_ctx *hctx;
--              hctx = handler_ctx_init();
--                              
--              hctx->path_info_offset = path_info_offset;
--              hctx->remote_conn      = con;
--              hctx->plugin_data      = p;
--              hctx->host             = host;
--                              
--              con->plugin_ctx[p->id] = hctx;
--              
--              host->usage++;
--              
--              con->mode = p->id;
--              
--              if (p->conf.debug) {
--                      log_error_write(srv, __FILE__, __LINE__,  "sbd", 
--                                      "proxy - found a host",
--                                      host->host, host->port);
--              }
--              return HANDLER_GO_ON;
--      } else {
--              /* no handler found */
-+      /* we havn't found a host */
-+      if (NULL == host) {
-               con->http_status = 500;
--              
--              log_error_write(srv, __FILE__, __LINE__,  "sb", 
--                              "no proxy-handler found for:", 
-+
-+              log_error_write(srv, __FILE__, __LINE__,  "sb",
-+                              "no proxy-handler found for:",
-                               fn);
--              
-+
-               return HANDLER_FINISHED;
-       }
-+
-+      /* init handler-context */
-+      hctx = handler_ctx_init();
-+
-+      hctx->path_info_offset = path_info_offset;
-+      hctx->remote_conn      = con;
-+      hctx->plugin_data      = p;
-+      hctx->host             = host;
-+
-+      con->plugin_ctx[p->id] = hctx;
-+
-+      host->usage++;
-+
-+      /* we handle this request */
-+      con->mode = p->id;
-+
-+      if (p->conf.debug) {
-+              log_error_write(srv, __FILE__, __LINE__,  "sbd",
-+                              "proxy - found a host",
-+                              host->host, host->port);
-+      }
-+
-       return HANDLER_GO_ON;
- }
- static handler_t mod_proxy_connection_close_callback(server *srv, connection *con, void *p_d) {
-       plugin_data *p = p_d;
--      
-+
-       proxy_connection_close(srv, con->plugin_ctx[p->id]);
-       return HANDLER_GO_ON;
-@@ -1276,11 +1260,11 @@
-               size_t i, n, k;
-               for (i = 0; i < srv->config_context->used; i++) {
-                       plugin_config *s = p->config_storage[i];
--                      
--                      if (!s) continue; 
-+
-+                      if (!s) continue;
-                       /* get the extensions for all configs */
--                      
-+
-                       for (k = 0; k < s->extensions->used; k++) {
-                               data_array *extension = (data_array *)s->extensions->data[k];
-@@ -1290,8 +1274,8 @@
-                                       if (!host->is_disabled ||
-                                           srv->cur_ts - host->disable_ts < 5) continue;
--                      
--                                      log_error_write(srv, __FILE__, __LINE__,  "sbd", 
-+
-+                                      log_error_write(srv, __FILE__, __LINE__,  "sbd",
-                                                       "proxy - re-enabled:",
-                                                       host->host, host->port);
-@@ -1315,10 +1299,10 @@
-       p->connection_reset        = mod_proxy_connection_close_callback; /* end of req-resp cycle */
-       p->handle_connection_close = mod_proxy_connection_close_callback; /* end of client connection */
-       p->handle_uri_clean        = mod_proxy_check_extension;
--      p->handle_subrequest       = mod_proxy_handle_subrequest;
-+      p->handle_start_backend    = mod_proxy_handle_subrequest;
-       p->handle_trigger          = mod_proxy_trigger;
--      
-+
-       p->data         = NULL;
--      
-+
-       return 0;
- }
---- ../lighttpd-1.4.11/src/mod_proxy_backend_fastcgi.c 1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/mod_proxy_backend_fastcgi.c     2006-09-07 00:57:05.000000000 +0300
-@@ -0,0 +1,656 @@
-+#include <stdlib.h>
-+#include <string.h>
-+#include <assert.h>
-+
-+#include "inet_ntop_cache.h"
-+#include "mod_proxy_core.h"
-+#include "buffer.h"
-+#include "log.h"
-+#include "fastcgi.h"
-+
-+int proxy_fastcgi_get_env_fastcgi(server *srv, connection *con, plugin_data *p, proxy_session *sess) {
-+      buffer *b;
-+
-+      char buf[32];
-+      const char *s;
-+      server_socket *srv_sock = con->srv_socket;
-+#ifdef HAVE_IPV6
-+      char b2[INET6_ADDRSTRLEN + 1];
-+#endif
-+
-+      sock_addr our_addr;
-+      socklen_t our_addr_len;
-+
-+      proxy_set_header(sess->env_headers, CONST_STR_LEN("SERVER_SOFTWARE"), CONST_STR_LEN(PACKAGE_NAME"/"PACKAGE_VERSION));
-+
-+      if (con->server_name->used) {
-+              proxy_set_header(sess->env_headers, CONST_STR_LEN("SERVER_NAME"), CONST_BUF_LEN(con->server_name));
-+      } else {
-+#ifdef HAVE_IPV6
-+              s = inet_ntop(srv_sock->addr.plain.sa_family,
-+                            srv_sock->addr.plain.sa_family == AF_INET6 ?
-+                            (const void *) &(srv_sock->addr.ipv6.sin6_addr) :
-+                            (const void *) &(srv_sock->addr.ipv4.sin_addr),
-+                            b2, sizeof(b2)-1);
-+#else
-+              s = inet_ntoa(srv_sock->addr.ipv4.sin_addr);
-+#endif
-+              proxy_set_header(sess->env_headers, CONST_STR_LEN("SERVER_NAME"), s, strlen(s));
-+      }
-+
-+      proxy_set_header(sess->env_headers, CONST_STR_LEN("GATEWAY_INTERFACE"), CONST_STR_LEN("CGI/1.1"));
-+
-+      ltostr(buf,
-+#ifdef HAVE_IPV6
-+             ntohs(srv_sock->addr.plain.sa_family ? srv_sock->addr.ipv6.sin6_port : srv_sock->addr.ipv4.sin_port)
-+#else
-+             ntohs(srv_sock->addr.ipv4.sin_port)
-+#endif
-+             );
-+
-+      proxy_set_header(sess->env_headers, CONST_STR_LEN("SERVER_PORT"), buf, strlen(buf));
-+
-+      /* get the server-side of the connection to the client */
-+      our_addr_len = sizeof(our_addr);
-+
-+      if (-1 == getsockname(con->sock->fd, &(our_addr.plain), &our_addr_len)) {
-+              s = inet_ntop_cache_get_ip(srv, &(srv_sock->addr));
-+      } else {
-+              s = inet_ntop_cache_get_ip(srv, &(our_addr));
-+      }
-+      proxy_set_header(sess->env_headers, CONST_STR_LEN("SERVER_ADDR"), s, strlen(s));
-+
-+      ltostr(buf,
-+#ifdef HAVE_IPV6
-+             ntohs(con->dst_addr.plain.sa_family ? con->dst_addr.ipv6.sin6_port : con->dst_addr.ipv4.sin_port)
-+#else
-+             ntohs(con->dst_addr.ipv4.sin_port)
-+#endif
-+             );
-+
-+      proxy_set_header(sess->env_headers, CONST_STR_LEN("REMOTE_PORT"), buf, strlen(buf));
-+
-+      s = inet_ntop_cache_get_ip(srv, &(con->dst_addr));
-+      proxy_set_header(sess->env_headers, CONST_STR_LEN("REMOTE_ADDR"), s, strlen(s));
-+
-+      if (!buffer_is_empty(con->authed_user)) {
-+              proxy_set_header(sess->env_headers, CONST_STR_LEN("REMOTE_USER"),
-+                           CONST_BUF_LEN(con->authed_user));
-+      }
-+
-+      if (con->request.content_length > 0) {
-+              /* CGI-SPEC 6.1.2 and FastCGI spec 6.3 */
-+
-+              /* request.content_length < SSIZE_MAX, see request.c */
-+              ltostr(buf, con->request.content_length);
-+              proxy_set_header(sess->env_headers, CONST_STR_LEN("CONTENT_LENGTH"), buf, strlen(buf));
-+      }
-+
-+      
-+      /*
-+       * SCRIPT_NAME, PATH_INFO and PATH_TRANSLATED according to
-+       * http://cgi-spec.golux.com/draft-coar-cgi-v11-03-clean.html
-+       * (6.1.14, 6.1.6, 6.1.7)
-+       * For AUTHORIZER mode these headers should be omitted.
-+       */
-+
-+      proxy_set_header(sess->env_headers, CONST_STR_LEN("SCRIPT_NAME"), CONST_BUF_LEN(con->uri.path));
-+
-+      if (!buffer_is_empty(con->request.pathinfo)) {
-+              proxy_set_header(sess->env_headers, CONST_STR_LEN("PATH_INFO"), CONST_BUF_LEN(con->request.pathinfo));
-+
-+              /* PATH_TRANSLATED is only defined if PATH_INFO is set */
-+
-+              buffer_copy_string_buffer(p->tmp_buf, con->physical.doc_root);
-+              buffer_append_string_buffer(p->tmp_buf, con->request.pathinfo);
-+              proxy_set_header(sess->env_headers, CONST_STR_LEN("PATH_TRANSLATED"), CONST_BUF_LEN(p->tmp_buf));
-+      } else {
-+              proxy_set_header(sess->env_headers, CONST_STR_LEN("PATH_INFO"), CONST_STR_LEN(""));
-+      }
-+
-+      /*
-+       * SCRIPT_FILENAME and DOCUMENT_ROOT for php. The PHP manual
-+       * http://www.php.net/manual/en/reserved.variables.php
-+       * treatment of PATH_TRANSLATED is different from the one of CGI specs.
-+       * TODO: this code should be checked against cgi.fix_pathinfo php
-+       * parameter.
-+       */
-+
-+      if (1) {
-+              proxy_set_header(sess->env_headers, CONST_STR_LEN("SCRIPT_FILENAME"), CONST_BUF_LEN(con->physical.path));
-+              proxy_set_header(sess->env_headers, CONST_STR_LEN("DOCUMENT_ROOT"), CONST_BUF_LEN(con->physical.doc_root));
-+      }
-+
-+      proxy_set_header(sess->env_headers, CONST_STR_LEN("REQUEST_URI"), CONST_BUF_LEN(con->request.orig_uri));
-+
-+      if (!buffer_is_equal(con->request.uri, con->request.orig_uri)) {
-+              proxy_set_header(sess->env_headers, CONST_STR_LEN("REDIRECT_URI"), CONST_BUF_LEN(con->request.uri));
-+      }
-+      if (!buffer_is_empty(con->uri.query)) {
-+              proxy_set_header(sess->env_headers, CONST_STR_LEN("QUERY_STRING"), CONST_BUF_LEN(con->uri.query));
-+      } else {
-+              proxy_set_header(sess->env_headers, CONST_STR_LEN("QUERY_STRING"), CONST_STR_LEN(""));
-+      }
-+
-+      s = get_http_method_name(con->request.http_method);
-+      proxy_set_header(sess->env_headers, CONST_STR_LEN("REQUEST_METHOD"), s, strlen(s));
-+      proxy_set_header(sess->env_headers, CONST_STR_LEN("REDIRECT_STATUS"), CONST_STR_LEN("200")); /* if php is compiled with --force-redirect */
-+      s = get_http_version_name(con->request.http_version);
-+      proxy_set_header(sess->env_headers, CONST_STR_LEN("SERVER_PROTOCOL"), s, strlen(s));
-+
-+#ifdef USE_OPENSSL
-+      if (srv_sock->is_ssl) {
-+              proxy_set_header(sess->env_headers, CONST_STR_LEN("HTTPS"), CONST_STR_LEN("on"));
-+      }
-+#endif
-+
-+      return 0;
-+}
-+
-+/**
-+ * transform the HTTP-Request headers into CGI notation
-+ */
-+int proxy_fastcgi_get_env_request(server *srv, connection *con, plugin_data *p, proxy_session *sess) {
-+      size_t i;
-+      /* the request header got already copied into the sess->request_headers for us
-+       * no extra filter is needed
-+       *
-+       * prepend a HTTP_ and uppercase the keys
-+       */
-+      for (i = 0; i < sess->request_headers->used; i++) {
-+              data_string *ds;
-+              size_t j;
-+
-+              ds = (data_string *)sess->request_headers->data[i];
-+
-+              buffer_reset(p->tmp_buf);
-+
-+              if (0 != strcasecmp(ds->key->ptr, "CONTENT-TYPE")) {
-+                      BUFFER_COPY_STRING_CONST(p->tmp_buf, "HTTP_");
-+                      p->tmp_buf->used--;
-+              }
-+
-+              buffer_prepare_append(p->tmp_buf, ds->key->used + 2);
-+              for (j = 0; j < ds->key->used - 1; j++) {
-+                      char c = '_';
-+                      if (light_isalpha(ds->key->ptr[j])) {
-+                              /* upper-case */
-+                              c = ds->key->ptr[j] & ~32;
-+                      } else if (light_isdigit(ds->key->ptr[j])) {
-+                              /* copy */
-+                              c = ds->key->ptr[j];
-+                      }
-+                      p->tmp_buf->ptr[p->tmp_buf->used++] = c;
-+              }
-+              p->tmp_buf->ptr[p->tmp_buf->used++] = '\0';
-+
-+              proxy_set_header(sess->env_headers, CONST_BUF_LEN(p->tmp_buf), CONST_BUF_LEN(ds->value));
-+      }
-+
-+      return 0;
-+}
-+
-+
-+/**
-+ * add a key-value pair to the fastcgi-buffer
-+ */
-+
-+static int fcgi_env_add(buffer *env, const char *key, size_t key_len, const char *val, size_t val_len) {
-+      size_t len;
-+
-+      if (!key || !val) return -1;
-+
-+      len = key_len + val_len;
-+
-+      len += key_len > 127 ? 4 : 1;
-+      len += val_len > 127 ? 4 : 1;
-+
-+      buffer_prepare_append(env, len);
-+
-+      if (key_len > 127) {
-+              env->ptr[env->used++] = ((key_len >> 24) & 0xff) | 0x80;
-+              env->ptr[env->used++] = (key_len >> 16) & 0xff;
-+              env->ptr[env->used++] = (key_len >> 8) & 0xff;
-+              env->ptr[env->used++] = (key_len >> 0) & 0xff;
-+      } else {
-+              env->ptr[env->used++] = (key_len >> 0) & 0xff;
-+      }
-+
-+      if (val_len > 127) {
-+              env->ptr[env->used++] = ((val_len >> 24) & 0xff) | 0x80;
-+              env->ptr[env->used++] = (val_len >> 16) & 0xff;
-+              env->ptr[env->used++] = (val_len >> 8) & 0xff;
-+              env->ptr[env->used++] = (val_len >> 0) & 0xff;
-+      } else {
-+              env->ptr[env->used++] = (val_len >> 0) & 0xff;
-+      }
-+
-+      memcpy(env->ptr + env->used, key, key_len);
-+      env->used += key_len;
-+      memcpy(env->ptr + env->used, val, val_len);
-+      env->used += val_len;
-+
-+      return 0;
-+}
-+
-+/**
-+ * init the FCGI_header 
-+ */
-+static int fcgi_header(FCGI_Header * header, unsigned char type, size_t request_id, int contentLength, unsigned char paddingLength) {
-+      header->version = FCGI_VERSION_1;
-+      header->type = type;
-+      header->requestIdB0 = request_id & 0xff;
-+      header->requestIdB1 = (request_id >> 8) & 0xff;
-+      header->contentLengthB0 = contentLength & 0xff;
-+      header->contentLengthB1 = (contentLength >> 8) & 0xff;
-+      header->paddingLength = paddingLength;
-+      header->reserved = 0;
-+
-+      return 0;
-+}
-+
-+
-+int proxy_fastcgi_get_request_chunk(server *srv, connection *con, plugin_data *p, proxy_session *sess, chunkqueue *out) {
-+      buffer *b, *packet;
-+      size_t i;
-+      FCGI_BeginRequestRecord beginRecord;
-+      FCGI_Header header;
-+      int request_id = 1;
-+
-+      b = chunkqueue_get_append_buffer(out);
-+      /* send FCGI_BEGIN_REQUEST */
-+
-+      fcgi_header(&(beginRecord.header), FCGI_BEGIN_REQUEST, FCGI_NULL_REQUEST_ID, sizeof(beginRecord.body), 0);
-+      beginRecord.body.roleB0 = FCGI_RESPONDER;
-+      beginRecord.body.roleB1 = 0;
-+      beginRecord.body.flags = 0;
-+      memset(beginRecord.body.reserved, 0, sizeof(beginRecord.body.reserved));
-+
-+      buffer_copy_string_len(b, (const char *)&beginRecord, sizeof(beginRecord));
-+      out->bytes_in += sizeof(beginRecord);
-+
-+      /* send FCGI_PARAMS */
-+      b = chunkqueue_get_append_buffer(out);
-+      buffer_prepare_copy(b, 1024);
-+
-+      /* fill the sess->env_headers */
-+      array_reset(sess->env_headers);
-+      proxy_fastcgi_get_env_request(srv, con, p, sess);
-+      proxy_fastcgi_get_env_fastcgi(srv, con, p, sess);
-+
-+      packet = buffer_init();
-+
-+      for (i = 0; i < sess->env_headers->used; i++) {
-+              data_string *ds;
-+
-+              ds = (data_string *)sess->env_headers->data[i];
-+              fcgi_env_add(packet, CONST_BUF_LEN(ds->key), CONST_BUF_LEN(ds->value));
-+      }
-+
-+      fcgi_header(&(header), FCGI_PARAMS, FCGI_NULL_REQUEST_ID, packet->used, 0);
-+      buffer_append_memory(b, (const char *)&header, sizeof(header));
-+      buffer_append_memory(b, (const char *)packet->ptr, packet->used);
-+      out->bytes_in += sizeof(header);
-+      out->bytes_in += packet->used - 1;
-+
-+      buffer_free(packet);
-+
-+      fcgi_header(&(header), FCGI_PARAMS, FCGI_NULL_REQUEST_ID, 0, 0);
-+      buffer_append_memory(b, (const char *)&header, sizeof(header));
-+      out->bytes_in += sizeof(header);
-+
-+      return 0;
-+}
-+
-+
-+typedef struct {
-+      buffer  *b;
-+      size_t   len;
-+      int      type;
-+      int      padding;
-+      size_t   request_id;
-+} fastcgi_response_packet;
-+
-+int proxy_fastcgi_stream_decoder(server *srv, proxy_session *sess, chunkqueue *raw, chunkqueue *decoded) {
-+      chunk * c;
-+      size_t offset = 0;
-+      size_t toread = 0;
-+      FCGI_Header *header;
-+      fastcgi_response_packet packet;
-+      buffer *b;
-+
-+      if (!raw->first) return 0;
-+
-+      packet.b = buffer_init();
-+      packet.len = 0;
-+      packet.type = 0;
-+      packet.padding = 0;
-+      packet.request_id = 0;
-+
-+      /* get at least the FastCGI header */
-+      for (c = raw->first; c; c = c->next) {
-+              if (packet.b->used == 0) {
-+                      buffer_copy_string_len(packet.b, c->mem->ptr + c->offset, c->mem->used - c->offset - 1);
-+              } else {
-+                      buffer_append_string_len(packet.b, c->mem->ptr + c->offset, c->mem->used - c->offset - 1);
-+              }
-+
-+              if (packet.b->used >= sizeof(*header) + 1) break;
-+      }
-+
-+      if ((packet.b->used == 0) ||
-+          (packet.b->used - 1 < sizeof(FCGI_Header))) {
-+              /* no header */
-+              buffer_free(packet.b);
-+
-+              ERROR("%s", "FastCGI: header too small");
-+              return -1;
-+      }
-+
-+      /* we have at least a header, now check how much me have to fetch */
-+      header = (FCGI_Header *)(packet.b->ptr);
-+
-+      packet.len = (header->contentLengthB0 | (header->contentLengthB1 << 8)) + header->paddingLength;
-+      packet.request_id = (header->requestIdB0 | (header->requestIdB1 << 8));
-+      packet.type = header->type;
-+      packet.padding = header->paddingLength;
-+
-+      /* the first bytes in packet->b are the header */
-+      offset = sizeof(*header);
-+
-+      buffer_copy_string(packet.b, "");
-+
-+      if (packet.len) {
-+              /* copy the content */
-+              for (; c && (packet.b->used < packet.len + 1); c = c->next) {
-+                      size_t weWant = packet.len - (packet.b->used - 1);
-+                      size_t weHave = c->mem->used - c->offset - offset - 1;
-+
-+                      if (weHave > weWant) weHave = weWant;
-+
-+                      buffer_append_string_len(packet.b, c->mem->ptr + c->offset + offset, weHave);
-+
-+                      /* we only skipped the first 8 bytes as they are the fcgi header */
-+                      offset = 0;
-+              }
-+
-+              if (packet.b->used < packet.len + 1) {
-+                      /* we didn't got the full packet */
-+
-+                      buffer_free(packet.b);
-+
-+                      TRACE("%s", "need more");
-+
-+                      return 0;
-+              }
-+
-+              packet.b->used -= packet.padding;
-+              packet.b->ptr[packet.b->used - 1] = '\0';
-+      }
-+
-+      /* tag the chunks as read */
-+      toread = packet.len + sizeof(FCGI_Header);
-+      for (c = raw->first; c && toread; c = c->next) {
-+              if (c->mem->used - c->offset - 1 <= toread) {
-+                      /* we read this whole buffer, move it to unused */
-+                      toread -= c->mem->used - c->offset - 1;
-+                      c->offset = c->mem->used - 1; /* everthing has been written */
-+              } else {
-+                      c->offset += toread;
-+                      toread = 0;
-+              }
-+      }
-+
-+      chunkqueue_remove_finished_chunks(raw);
-+
-+      /* we are still here ? */
-+
-+      switch (packet.type) {
-+      case FCGI_STDOUT:
-+              b = chunkqueue_get_append_buffer(decoded);
-+              buffer_copy_string_buffer(b, packet.b);
-+              buffer_free(packet.b);
-+              return 0;
-+      case FCGI_STDERR:
-+              if (!buffer_is_empty(packet.b)) {
-+                      TRACE("(fastcgi-stderr) %s", BUF_STR(packet.b));
-+              }
-+              buffer_free(packet.b);
-+              return 0;
-+      case FCGI_END_REQUEST:
-+              buffer_free(packet.b);
-+              return 1;
-+      default:
-+              buffer_free(packet.b);
-+
-+              TRACE("unknown packet.type: %d", packet.type);
-+              return -1;
-+      }
-+}
-+
-+/**
-+ * transform the content-stream into a valid HTTP-content-stream
-+ *
-+ * as we don't apply chunked-encoding here, pass it on AS IS
-+ */
-+int proxy_fastcgi_stream_encoder(server *srv, proxy_session *sess, chunkqueue *in, chunkqueue *out) {
-+      chunk *c;
-+      buffer *b;
-+      FCGI_Header header;
-+
-+      /* there is nothing that we have to send out anymore */
-+      for (c = in->first; in->bytes_out < in->bytes_in; ) {
-+              off_t weWant = in->bytes_in - in->bytes_out > FCGI_MAX_LENGTH ? FCGI_MAX_LENGTH : in->bytes_in - in->bytes_out;
-+              off_t weHave = 0;
-+
-+              /* we announce toWrite octects
-+               * now take all the request_content chunk that we need to fill this request
-+               */
-+              b = chunkqueue_get_append_buffer(out);
-+              fcgi_header(&(header), FCGI_STDIN, FCGI_NULL_REQUEST_ID, weWant, 0);
-+              buffer_copy_memory(b, (const char *)&header, sizeof(header) + 1);
-+              out->bytes_in += sizeof(header);
-+
-+              switch (c->type) {
-+              case FILE_CHUNK:
-+                      weHave = c->file.length - c->offset;
-+
-+                      if (weHave > weWant) weHave = weWant;
-+
-+                      chunkqueue_append_file(out, c->file.name, c->offset, weHave);
-+
-+                      c->offset += weHave;
-+                      in->bytes_out += weHave;
-+
-+                      out->bytes_in += weHave;
-+
-+                      /* steal the tempfile
-+                       *
-+                       * This is tricky:
-+                       * - we reference the tempfile from the in-queue several times
-+                       *   if the chunk is larger than FCGI_MAX_LENGTH
-+                       * - we can't simply cleanup the in-queue as soon as possible
-+                       *   as it would remove the tempfiles
-+                       * - the idea is to 'steal' the tempfiles and attach the is_temp flag to the last
-+                       *   referencing chunk of the fastcgi-write-queue
-+                       *
-+                       */
-+
-+                      if (c->offset == c->file.length) {
-+                              chunk *out_c;
-+
-+                              out_c = out->last;
-+
-+                              /* the last of the out-queue should be a FILE_CHUNK (we just created it)
-+                               * and the incoming side should have given use a temp-file-chunk */
-+                              assert(out_c->type == FILE_CHUNK);
-+                              assert(c->file.is_temp == 1);
-+
-+                              out_c->file.is_temp = 1;
-+                              c->file.is_temp = 0;
-+
-+                              c = c->next;
-+                      }
-+
-+                      break;
-+              case MEM_CHUNK:
-+                      /* append to the buffer */
-+                      weHave = c->mem->used - 1 - c->offset;
-+
-+                      if (weHave > weWant) weHave = weWant;
-+
-+                      b = chunkqueue_get_append_buffer(out);
-+                      buffer_append_memory(b, c->mem->ptr + c->offset, weHave);
-+                      b->used++; /* add virtual \0 */
-+
-+                      c->offset += weHave;
-+                      in->bytes_out += weHave;
-+
-+                      out->bytes_in += weHave;
-+
-+                      if (c->offset == c->mem->used - 1) {
-+                              c = c->next;
-+                      }
-+
-+                      break;
-+              default:
-+                      break;
-+              }
-+      }
-+
-+      if (in->bytes_in == in->bytes_out && in->is_closed && !out->is_closed) {
-+              /* send the closing packet */
-+              b = chunkqueue_get_append_buffer(out);
-+              /* terminate STDIN */
-+              fcgi_header(&(header), FCGI_STDIN, FCGI_NULL_REQUEST_ID, 0, 0);
-+              buffer_copy_memory(b, (const char *)&header, sizeof(header) + 1);
-+
-+              out->bytes_in += sizeof(header);
-+              out->is_closed = 1;
-+      }
-+
-+      return 0;
-+
-+}
-+
-+/**
-+ * parse the response header
-+ *
-+ * NOTE: this can be used by all backends as they all send a HTTP-Response a clean block
-+ * - fastcgi needs some decoding for the protocol
-+ */
-+parse_status_t proxy_fastcgi_parse_response_header(server *srv, connection *con, plugin_data *p, proxy_session *sess, chunkqueue *cq) {
-+      int have_content_length = 0;
-+      size_t i;
-+      off_t old_len;
-+
-+      http_response_reset(p->resp);
-+
-+      /* decode the whole packet stream */
-+      do {
-+              old_len = chunkqueue_length(sess->recv);
-+              /* decode the packet */
-+              switch (proxy_fastcgi_stream_decoder(srv, sess, cq, sess->recv)) {
-+              case 0:
-+                      /* STDERR + STDOUT */
-+                      break;
-+              case 1:
-+                      /* the FIN packet was catched, why ever */
-+                      return PARSE_ERROR;
-+              case -1:
-+                      return PARSE_ERROR;
-+              }
-+      } while (chunkqueue_length(sess->recv) == old_len);
-+      
-+      switch (http_response_parse_cq(sess->recv, p->resp)) {
-+      case PARSE_ERROR:
-+              /* parsing failed */
-+
-+              return PARSE_ERROR;
-+      case PARSE_NEED_MORE:
-+              return PARSE_NEED_MORE;
-+      case PARSE_SUCCESS:
-+              con->http_status = p->resp->status;
-+
-+              chunkqueue_remove_finished_chunks(cq);
-+
-+              sess->content_length = -1;
-+
-+              /* copy the http-headers */
-+              for (i = 0; i < p->resp->headers->used; i++) {
-+                      const char *ign[] = { "Status", "Connection", NULL };
-+                      size_t j, k;
-+                      data_string *ds;
-+
-+                      data_string *header = (data_string *)p->resp->headers->data[i];
-+
-+                      /* some headers are ignored by default */
-+                      for (j = 0; ign[j]; j++) {
-+                              if (0 == strcasecmp(ign[j], header->key->ptr)) break;
-+                      }
-+                      if (ign[j]) continue;
-+
-+                      if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("Location"))) {
-+                              /* CGI/1.1 rev 03 - 7.2.1.2 */
-+                              if (con->http_status == 0) con->http_status = 302;
-+                      } else if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("Content-Length"))) {
-+                              have_content_length = 1;
-+
-+                              sess->content_length = strtol(header->value->ptr, NULL, 10);
-+
-+                              if (sess->content_length < 0) {
-+                                      return PARSE_ERROR;
-+                              }
-+                      } else if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("Transfer-Encoding"))) {
-+                              if (strstr(header->value->ptr, "chunked")) {
-+                                      sess->is_chunked = 1;
-+                              }
-+                              /* ignore the header */
-+                              continue;
-+                      }
-+                      
-+                      if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
-+                              ds = data_response_init();
-+                      }
-+
-+
-+                      buffer_copy_string_buffer(ds->key, header->key);
-+
-+                      for (k = 0; k < p->conf.response_rewrites->used; k++) {
-+                              proxy_rewrite *rw = p->conf.response_rewrites->ptr[k];
-+
-+                              if (buffer_is_equal(rw->header, header->key)) {
-+                                      int ret;
-+      
-+                                      if ((ret = pcre_replace(rw->regex, rw->replace, header->value, p->replace_buf)) < 0) {
-+                                              switch (ret) {
-+                                              case PCRE_ERROR_NOMATCH:
-+                                                      /* hmm, ok. no problem */
-+                                                      buffer_append_string_buffer(ds->value, header->value);
-+                                                      break;
-+                                              default:
-+                                                      TRACE("oops, pcre_replace failed with: %d", ret);
-+                                                      break;
-+                                              }
-+                                      } else {
-+                                              buffer_append_string_buffer(ds->value, p->replace_buf);
-+                                      }
-+
-+                                      break;
-+                              }
-+                      }
-+
-+                      if (k == p->conf.response_rewrites->used) {
-+                              buffer_copy_string_buffer(ds->value, header->value);
-+                      }
-+
-+                      array_insert_unique(con->response.headers, (data_unset *)ds);
-+              }
-+
-+              break;
-+      }
-+
-+      return PARSE_SUCCESS; /* we have a full header */
-+}
-+
-+
---- ../lighttpd-1.4.11/src/mod_proxy_backend_fastcgi.h 1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/mod_proxy_backend_fastcgi.h     2006-09-07 00:57:05.000000000 +0300
-@@ -0,0 +1,13 @@
-+#ifndef _MOD_PROXY_BACKEND_FASTCGI_H_
-+#define _MOD_PROXY_BACKEND_FASTCGI_H_
-+
-+#include "mod_proxy_core.h"
-+#include "base.h"
-+
-+int proxy_fastcgi_stream_decoder(server *srv, proxy_session *sess, chunkqueue *in, chunkqueue *out);
-+int proxy_fastcgi_stream_encoder(server *srv, proxy_session *sess, chunkqueue *in, chunkqueue *out);
-+
-+parse_status_t proxy_fastcgi_parse_response_header(server *srv, connection *con, plugin_data *p, proxy_session *sess, chunkqueue *cq);
-+int proxy_fastcgi_get_request_chunk(server *srv, connection *con, plugin_data *p, proxy_session *sess, chunkqueue *cq);
-+
-+#endif
---- ../lighttpd-1.4.11/src/mod_proxy_backend_http.c    1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/mod_proxy_backend_http.c        2006-09-07 00:57:05.000000000 +0300
-@@ -0,0 +1,436 @@
-+#include <stdlib.h>
-+#include <string.h>
-+
-+#include "mod_proxy_core.h"
-+#include "configfile.h"
-+#include "buffer.h"
-+#include "log.h"
-+#include "sys-strings.h"
-+
-+void chunkqueue_skip(chunkqueue *cq, off_t skip) {
-+      chunk *c;
-+
-+      for (c = cq->first; c && skip; c = c->next) {
-+              if (skip > c->mem->used - c->offset - 1) {
-+                      skip -= c->mem->used - c->offset - 1;
-+              } else {
-+                      c->offset += skip;
-+                      skip = 0;
-+              }
-+      }
-+
-+      return;
-+}
-+
-+int proxy_http_stream_decoder(server *srv, proxy_session *sess, chunkqueue *raw, chunkqueue *decoded) {
-+      chunk *c;
-+
-+      if (raw->first == NULL) return 0;
-+
-+      if (sess->is_chunked) {
-+              do {
-+                      /* the start should always be a chunk-length */
-+                      off_t chunk_len = 0;
-+                      char *err = NULL;
-+                      int chunklen_strlen = 0;
-+                      char ch;
-+                      off_t we_have = 0, we_need = 0;
-+
-+                      c = raw->first;
-+
-+                      if (c->mem->used == 0) return 0;
-+
-+                      chunk_len = strtol(BUF_STR(c->mem) + c->offset, &err, 16);
-+                      if (!(*err == ' ' || *err == '\r' || *err == ';')) {
-+                              if (*err == '\0') {
-+                                      /* we just need more data */
-+                                      return 0;
-+                              }
-+                              return -1;
-+                      }
-+
-+                      if (chunk_len < 0) {
-+                              ERROR("chunk_len is negative: %Ld", chunk_len);
-+                              return -1;
-+                      }
-+
-+                      chunklen_strlen = err - (BUF_STR(c->mem) + c->offset);
-+                      chunklen_strlen++; /* skip the err-char */ 
-+                      
-+                      do {
-+                              ch = BUF_STR(c->mem)[c->offset + chunklen_strlen];
-+      
-+                              switch (ch) {
-+                              case '\n':
-+                              case '\0':
-+                                      /* bingo, chunk-header is finished */
-+                                      break;
-+                              default:
-+                                      break;
-+                              }
-+                              chunklen_strlen++;
-+                      } while (ch != '\n' && c != '\0');
-+
-+                      if (ch != '\n') {
-+                              ERROR("%s", "missing the CRLF");
-+                              return 0;
-+                      }
-+
-+                      we_need = chunk_len + chunklen_strlen + 2;
-+                      /* do we have the full chunk ? */
-+                      for (c = raw->first; c; c = c->next) {
-+                              we_have += c->mem->used - 1 - c->offset;
-+
-+                              /* we have enough, jump out */
-+                              if (we_have > we_need) break;
-+                      }
-+
-+                      /* get more data */
-+                      if (we_have < we_need) {
-+                              return 0;
-+                      }
-+
-+                      /* skip the chunk-header */
-+                      chunkqueue_skip(raw, chunklen_strlen);
-+
-+                      /* final chunk */
-+                      if (chunk_len == 0) {
-+                              chunkqueue_skip(raw, 2);
-+
-+                              return 1;
-+                      }
-+
-+                      /* we have enough, copy the data */     
-+                      for (c = raw->first; c && chunk_len; c = c->next) {
-+                              off_t we_want = 0;
-+                              buffer *b = chunkqueue_get_append_buffer(decoded);
-+
-+                              we_want = chunk_len > (c->mem->used - c->offset - 1) ? c->mem->used - c->offset - 1: chunk_len;
-+
-+                              buffer_copy_string_len(b, c->mem->ptr + c->offset, we_want);
-+
-+                              c->offset += we_want;
-+                              chunk_len -= we_want;
-+                      }
-+
-+                      /* skip the \r\n */
-+                      chunkqueue_skip(raw, 2);
-+
-+                      /* we are done, give the connection to someone else */
-+                      chunkqueue_remove_finished_chunks(raw);
-+              } while (1);
-+      } else {
-+              /* no chunked encoding, ok, perhaps a content-length ? */
-+
-+              chunkqueue_remove_finished_chunks(raw);
-+              for (c = raw->first; c; c = c->next) {
-+                      buffer *b;
-+
-+                      if (c->mem->used == 0) continue;
-+                     
-+                      b = chunkqueue_get_append_buffer(decoded);
-+
-+                      sess->bytes_read += c->mem->used - c->offset - 1;
-+
-+                      buffer_copy_string_len(b, c->mem->ptr + c->offset, c->mem->used - c->offset - 1);
-+
-+                      c->offset = c->mem->used - 1;
-+
-+                      if (sess->bytes_read == sess->content_length) {
-+                              break;
-+                      }
-+
-+              }
-+              if (sess->bytes_read == sess->content_length) {
-+                      return 1; /* finished */
-+              }
-+      }
-+
-+      return 0;
-+}
-+
-+/**
-+ * transform the content-stream into a valid HTTP-content-stream
-+ *
-+ * as we don't apply chunked-encoding here, pass it on AS IS
-+ */
-+int proxy_http_stream_encoder(server *srv, proxy_session *sess, chunkqueue *in, chunkqueue *out) {
-+      chunk *c;
-+
-+      /* there is nothing that we have to send out anymore */
-+      if (in->bytes_in == in->bytes_out && 
-+          in->is_closed) return 0;
-+
-+      for (c = in->first; in->bytes_out < in->bytes_in; c = c->next) {
-+              buffer *b;
-+              off_t weWant = in->bytes_in - in->bytes_out;
-+              off_t weHave = 0;
-+
-+              /* we announce toWrite octects
-+               * now take all the request_content chunk that we need to fill this request
-+               */
-+
-+              switch (c->type) {
-+              case FILE_CHUNK:
-+                      weHave = c->file.length - c->offset;
-+
-+                      if (weHave > weWant) weHave = weWant;
-+
-+                      chunkqueue_append_file(out, c->file.name, c->offset, weHave);
-+
-+                      c->offset += weHave;
-+                      in->bytes_out += weHave;
-+
-+                      out->bytes_in += weHave;
-+
-+                      break;
-+              case MEM_CHUNK:
-+                      /* append to the buffer */
-+                      weHave = c->mem->used - 1 - c->offset;
-+
-+                      if (weHave > weWant) weHave = weWant;
-+
-+                      b = chunkqueue_get_append_buffer(out);
-+                      buffer_append_memory(b, c->mem->ptr + c->offset, weHave);
-+                      b->used++; /* add virtual \0 */
-+
-+                      c->offset += weHave;
-+                      in->bytes_out += weHave;
-+
-+                      out->bytes_in += weHave;
-+
-+                      break;
-+              default:
-+                      break;
-+              }
-+      }
-+
-+      return 0;
-+
-+}
-+/**
-+ * generate a HTTP/1.1 proxy request from the set of request-headers
-+ *
-+ * TODO: this is HTTP-proxy specific and will be moved moved into a separate backed
-+ *
-+ */
-+int proxy_http_get_request_chunk(server *srv, connection *con, plugin_data *p, proxy_session *sess, chunkqueue *cq) {
-+      buffer *b;
-+      size_t i;
-+      
-+      b = chunkqueue_get_append_buffer(cq);
-+
-+      /* request line */
-+      buffer_copy_string(b, get_http_method_name(con->request.http_method));
-+      BUFFER_APPEND_STRING_CONST(b, " ");
-+
-+      /* check if we want to rewrite the uri */
-+
-+      for (i = 0; i < p->conf.request_rewrites->used; i++) {
-+              proxy_rewrite *rw = p->conf.request_rewrites->ptr[i];
-+
-+              if (buffer_is_equal_string(rw->header, CONST_STR_LEN("_uri"))) {
-+                      int ret;
-+
-+                      if ((ret = pcre_replace(rw->regex, rw->replace, con->request.uri, p->replace_buf)) < 0) {
-+                              switch (ret) {
-+                              case PCRE_ERROR_NOMATCH:
-+                                      /* hmm, ok. no problem */
-+                                      buffer_append_string_buffer(b, con->request.uri);
-+                                      break;
-+                              default:
-+                                      TRACE("oops, pcre_replace failed with: %d", ret);
-+                                      break;
-+                              }
-+                      } else {
-+                              buffer_append_string_buffer(b, p->replace_buf);
-+                      }
-+
-+                      break;
-+              }
-+      }
-+
-+      if (i == p->conf.request_rewrites->used) {
-+              /* not found */
-+              buffer_append_string_buffer(b, con->request.uri);
-+      }
-+
-+      if (con->request.http_version == HTTP_VERSION_1_1) {
-+              BUFFER_APPEND_STRING_CONST(b, " HTTP/1.1\r\n");
-+      } else {
-+              BUFFER_APPEND_STRING_CONST(b, " HTTP/1.0\r\n");
-+      }
-+
-+      for (i = 0; i < sess->request_headers->used; i++) {
-+              data_string *ds;
-+
-+              ds = (data_string *)sess->request_headers->data[i];
-+
-+              buffer_append_string_buffer(b, ds->key);
-+              BUFFER_APPEND_STRING_CONST(b, ": ");
-+              buffer_append_string_buffer(b, ds->value);
-+              BUFFER_APPEND_STRING_CONST(b, "\r\n");
-+      }
-+
-+      BUFFER_APPEND_STRING_CONST(b, "\r\n");
-+      
-+      return 0;
-+}
-+
-+/**
-+ * parse the response header
-+ *
-+ * NOTE: this can be used by all backends as they all send a HTTP-Response a clean block
-+ * - fastcgi needs some decoding for the protocol
-+ */
-+parse_status_t proxy_http_parse_response_header(server *srv, connection *con, plugin_data *p, proxy_session *sess, chunkqueue *cq) {
-+      int have_content_length = 0;
-+      size_t i;
-+
-+      http_response_reset(p->resp);
-+      
-+      switch (http_response_parse_cq(cq, p->resp)) {
-+      case PARSE_ERROR:
-+              /* parsing failed */
-+
-+              return PARSE_ERROR;
-+      case PARSE_NEED_MORE:
-+              return PARSE_NEED_MORE;
-+      case PARSE_SUCCESS:
-+              con->http_status = p->resp->status;
-+
-+              chunkqueue_remove_finished_chunks(cq);
-+
-+              sess->content_length = -1;
-+
-+              /* copy the http-headers */
-+              for (i = 0; i < p->resp->headers->used; i++) {
-+                      const char *ign[] = { "Status", NULL };
-+                      size_t j, k;
-+                      data_string *ds;
-+
-+                      data_string *header = (data_string *)p->resp->headers->data[i];
-+
-+                      /* some headers are ignored by default */
-+                      for (j = 0; ign[j]; j++) {
-+                              if (0 == strcasecmp(ign[j], header->key->ptr)) break;
-+                      }
-+                      if (ign[j]) continue;
-+
-+                      if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("Location"))) {
-+                              /* CGI/1.1 rev 03 - 7.2.1.2 */
-+                              if (con->http_status == 0) con->http_status = 302;
-+                      } else if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("Content-Length"))) {
-+                              have_content_length = 1;
-+
-+                              sess->content_length = strtol(header->value->ptr, NULL, 10);
-+
-+                              if (sess->content_length < 0) {
-+                                      return PARSE_ERROR;
-+                              }
-+                      } else if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("X-Sendfile")) ||
-+                                 0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("X-LIGHTTPD-Sendfile"))) {
-+                              if (p->conf.allow_x_sendfile) {
-+                                      sess->send_response_content = 0;
-+                                      sess->do_internal_redirect = 1;
-+                                      
-+                                      /* don't try to rewrite this request through mod_proxy_core again */
-+                                      sess->internal_redirect_count = MAX_INTERNAL_REDIRECTS; 
-+
-+                                      buffer_copy_string_buffer(con->physical.path, header->value);
-+
-+                                      /* as we want to support ETag and friends we set the physical path for the file
-+                                       * and hope mod_staticfile catches up */
-+                              }
-+
-+                              continue;
-+                      } else if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("X-Rewrite-URI"))) { 
-+                              if (p->conf.allow_x_rewrite) {
-+                                      sess->send_response_content = 0;
-+                                      sess->do_internal_redirect = 1;
-+
-+                                      buffer_copy_string_buffer(con->request.uri, header->value);
-+                                      buffer_reset(con->physical.path);
-+
-+                                      config_cond_cache_reset(srv, con);
-+                              }
-+
-+                              continue;
-+                      } else if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("X-Rewrite-Host"))) { 
-+                              if (p->conf.allow_x_rewrite) {
-+                                      sess->send_response_content = 0;
-+                                      sess->do_internal_redirect = 1;
-+
-+                                      buffer_copy_string_buffer(con->request.http_host, header->value);
-+                                      buffer_reset(con->physical.path);
-+
-+                                      config_cond_cache_reset(srv, con);
-+                              }
-+
-+                              continue;
-+                      } else if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("Transfer-Encoding"))) {
-+                              if (strstr(header->value->ptr, "chunked")) {
-+                                      sess->is_chunked = 1;
-+                              }
-+                              /* ignore the header */
-+                              continue;
-+                      } else if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("Connection"))) {
-+                              if (strstr(header->value->ptr, "close")) {
-+                                      sess->is_closing = 1;
-+                              }
-+                              /* ignore the header */
-+                              continue;
-+
-+                      }
-+                      
-+                      if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
-+                              ds = data_response_init();
-+                      }
-+
-+
-+                      buffer_copy_string_buffer(ds->key, header->key);
-+
-+                      for (k = 0; k < p->conf.response_rewrites->used; k++) {
-+                              proxy_rewrite *rw = p->conf.response_rewrites->ptr[k];
-+
-+                              if (buffer_is_equal(rw->header, header->key)) {
-+                                      int ret;
-+      
-+                                      if ((ret = pcre_replace(rw->regex, rw->replace, header->value, p->replace_buf)) < 0) {
-+                                              switch (ret) {
-+                                              case PCRE_ERROR_NOMATCH:
-+                                                      /* hmm, ok. no problem */
-+                                                      buffer_append_string_buffer(ds->value, header->value);
-+                                                      break;
-+                                              default:
-+                                                      TRACE("oops, pcre_replace failed with: %d", ret);
-+                                                      break;
-+                                              }
-+                                      } else {
-+                                              buffer_append_string_buffer(ds->value, p->replace_buf);
-+                                      }
-+
-+                                      break;
-+                              }
-+                      }
-+
-+                      if (k == p->conf.response_rewrites->used) {
-+                              buffer_copy_string_buffer(ds->value, header->value);
-+                      }
-+
-+                      array_insert_unique(con->response.headers, (data_unset *)ds);
-+              }
-+
-+              /* does the client allow us to send chunked encoding ? */
-+              if (con->request.http_version == HTTP_VERSION_1_1 &&
-+                  !have_content_length) {
-+                      con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
-+              }
-+
-+              break;
-+      }
-+
-+      return PARSE_SUCCESS; /* we have a full header */
-+}
-+
-+
---- ../lighttpd-1.4.11/src/mod_proxy_backend_http.h    1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/mod_proxy_backend_http.h        2006-09-07 00:57:05.000000000 +0300
-@@ -0,0 +1,13 @@
-+#ifndef _MOD_PROXY_BACKEND_HTTP_H_
-+#define _MOD_PROXY_BACKEND_HTTP_H_
-+
-+#include "mod_proxy_core.h"
-+#include "base.h"
-+
-+int proxy_http_stream_decoder(server *srv, proxy_session *sess, chunkqueue *in, chunkqueue *out);
-+int proxy_http_stream_encoder(server *srv, proxy_session *sess, chunkqueue *in, chunkqueue *out);
-+
-+parse_status_t proxy_http_parse_response_header(server *srv, connection *con, plugin_data *p, proxy_session *sess, chunkqueue *cq);
-+int proxy_http_get_request_chunk(server *srv, connection *con, plugin_data *p, proxy_session *sess, chunkqueue *cq);
-+
-+#endif
---- ../lighttpd-1.4.11/src/mod_proxy_core.c    1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/mod_proxy_core.c        2006-09-07 00:57:05.000000000 +0300
-@@ -0,0 +1,1471 @@
-+#include <string.h>
-+#include <stdlib.h>
-+#include <fcntl.h>
-+#include <errno.h>
-+#include <ctype.h>
-+#include <assert.h>
-+
-+#include "buffer.h"
-+#include "array.h"
-+#include "log.h"
-+
-+#include "base.h"
-+#include "plugin.h"
-+#include "joblist.h"
-+#include "sys-files.h"
-+#include "inet_ntop_cache.h"
-+#include "crc32.h"
-+#include "configfile.h"
-+
-+#include "mod_proxy_core.h"
-+#include "mod_proxy_backend_http.h"
-+#include "mod_proxy_backend_fastcgi.h"
-+
-+#define CONFIG_PROXY_CORE_BALANCER "proxy-core.balancer"
-+#define CONFIG_PROXY_CORE_PROTOCOL "proxy-core.protocol"
-+#define CONFIG_PROXY_CORE_DEBUG "proxy-core.debug"
-+#define CONFIG_PROXY_CORE_BACKENDS "proxy-core.backends"
-+#define CONFIG_PROXY_CORE_REWRITE_REQUEST "proxy-core.rewrite-request"
-+#define CONFIG_PROXY_CORE_REWRITE_RESPONSE "proxy-core.rewrite-response"
-+#define CONFIG_PROXY_CORE_ALLOW_X_SENDFILE "proxy-core.allow-x-sendfile"
-+#define CONFIG_PROXY_CORE_ALLOW_X_REWRITE "proxy-core.allow-x-rewrite"
-+#define CONFIG_PROXY_CORE_MAX_POOL_SIZE "proxy-core.max-pool-size"
-+
-+int array_insert_int(array *a, const char *key, int val) {
-+      data_integer *di;
-+
-+      if (NULL == (di = (data_integer *)array_get_unused_element(a, TYPE_INTEGER))) {
-+              di = data_integer_init();
-+      }
-+
-+      buffer_copy_string(di->key, key);
-+      di->value = val;
-+      array_insert_unique(a, (data_unset *)di);
-+
-+      return 0;
-+}
-+
-+INIT_FUNC(mod_proxy_core_init) {
-+      plugin_data *p;
-+
-+      p = calloc(1, sizeof(*p));
-+
-+      /* create some backends as long as we don't have the config-parser */
-+
-+      p->possible_balancers = array_init();
-+      array_insert_int(p->possible_balancers, "fair", PROXY_BALANCE_FAIR);
-+      array_insert_int(p->possible_balancers, "hash", PROXY_BALANCE_HASH);
-+      array_insert_int(p->possible_balancers, "round-robin", PROXY_BALANCE_RR);
-+
-+      p->possible_protocols = array_init();
-+      array_insert_int(p->possible_protocols, "http", PROXY_PROTOCOL_HTTP);
-+      array_insert_int(p->possible_protocols, "fastcgi", PROXY_PROTOCOL_FASTCGI);
-+      array_insert_int(p->possible_protocols, "scgi", PROXY_PROTOCOL_SCGI);
-+      array_insert_int(p->possible_protocols, "https", PROXY_PROTOCOL_HTTPS);
-+
-+      p->balance_buf = buffer_init();
-+      p->protocol_buf = buffer_init();
-+      p->replace_buf = buffer_init();
-+      p->backends_arr = array_init();
-+
-+      p->tmp_buf = buffer_init();
-+
-+      p->resp = http_response_init();
-+
-+      return p;
-+}
-+
-+FREE_FUNC(mod_proxy_core_free) {
-+      plugin_data *p = p_d;
-+
-+      if (!p) return HANDLER_GO_ON;
-+
-+      if (p->config_storage) {
-+              size_t i;
-+              for (i = 0; i < srv->config_context->used; i++) {
-+                      plugin_config *s = p->config_storage[i];
-+
-+                      if (!s) continue;
-+
-+                      proxy_backends_free(s->backends);
-+                      proxy_backlog_free(s->backlog);
-+
-+                      proxy_rewrites_free(s->request_rewrites);
-+                      proxy_rewrites_free(s->response_rewrites);
-+
-+                      free(s);
-+              }
-+              free(p->config_storage);
-+      }
-+
-+      array_free(p->possible_protocols);
-+      array_free(p->possible_balancers);
-+      array_free(p->backends_arr);
-+
-+      buffer_free(p->balance_buf);
-+      buffer_free(p->protocol_buf);
-+      buffer_free(p->replace_buf);
-+      buffer_free(p->tmp_buf);
-+      
-+      http_response_free(p->resp);
-+
-+      free(p);
-+
-+      return HANDLER_GO_ON;
-+}
-+
-+static handler_t mod_proxy_core_config_parse_rewrites(proxy_rewrites *dest, array *src, const char *config_key) {
-+      data_unset *du;
-+      size_t j;
-+
-+      if (NULL != (du = array_get_element(src, config_key))) {
-+              data_array *keys = (data_array *)du;
-+
-+              if (keys->type != TYPE_ARRAY) {
-+                      ERROR("%s = <...>", 
-+                              config_key);
-+
-+                      return HANDLER_ERROR;
-+              }
-+
-+              /*
-+               * proxy-core.rewrite-request = (
-+               *   "_uri" => ( ... ) 
-+               * )
-+               */
-+
-+              for (j = 0; j < keys->value->used; j++) {
-+                      size_t k;
-+                      data_array *headers = (data_array *)keys->value->data[j];
-+
-+                      /* keys->key should be "_uri" and the value a array of rewrite */
-+                      if (headers->type != TYPE_ARRAY) {
-+                              ERROR("%s = ( %s => <...> ) has to a array", 
-+                                      config_key,
-+                                      BUF_STR(headers->key));
-+
-+                              return HANDLER_ERROR;
-+                      }
-+
-+                      if (headers->value->used > 1) {
-+                              ERROR("%s = ( %s => <...> ) has to a array with only one element", 
-+                                      config_key,
-+                                      BUF_STR(headers->key));
-+
-+                              return HANDLER_ERROR;
-+
-+                      }
-+
-+                      for (k = 0; k < headers->value->used; k++) {
-+                              data_string *rewrites = (data_string *)headers->value->data[k];
-+                              proxy_rewrite *rw;
-+
-+                              /* keys->key should be "_uri" and the value a array of rewrite */
-+                              if (rewrites->type != TYPE_STRING) {
-+                                      ERROR("%s = ( \"%s\" => ( \"%s\" => <value> ) ) has to a string", 
-+                                              config_key,
-+                                              BUF_STR(headers->key),
-+                                              BUF_STR(rewrites->key));
-+
-+                                      return HANDLER_ERROR;
-+                              }
-+                      
-+                              rw = proxy_rewrite_init();
-+
-+                              if (0 != proxy_rewrite_set_regex(rw, rewrites->key)) {
-+                                      return HANDLER_ERROR;
-+                              }
-+                              buffer_copy_string_buffer(rw->replace, rewrites->value);
-+                              buffer_copy_string_buffer(rw->match, rewrites->key);
-+                              buffer_copy_string_buffer(rw->header, headers->key);
-+
-+                              proxy_rewrites_add(dest, rw);
-+                      }
-+              }
-+      }
-+
-+      return HANDLER_GO_ON;
-+}
-+
-+
-+SETDEFAULTS_FUNC(mod_proxy_core_set_defaults) {
-+      plugin_data *p = p_d;
-+      size_t i, j;
-+
-+      config_values_t cv[] = {
-+              { CONFIG_PROXY_CORE_BACKENDS,       NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
-+              { CONFIG_PROXY_CORE_DEBUG,          NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },       /* 1 */
-+              { CONFIG_PROXY_CORE_BALANCER,       NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },      /* 2 */
-+              { CONFIG_PROXY_CORE_PROTOCOL,       NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },      /* 3 */
-+              { CONFIG_PROXY_CORE_REWRITE_REQUEST, NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION },      /* 4 */
-+              { CONFIG_PROXY_CORE_REWRITE_RESPONSE, NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION },     /* 5 */
-+              { CONFIG_PROXY_CORE_ALLOW_X_SENDFILE, NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },   /* 6 */
-+              { CONFIG_PROXY_CORE_ALLOW_X_REWRITE, NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },    /* 7 */
-+              { CONFIG_PROXY_CORE_MAX_POOL_SIZE, NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },        /* 8 */
-+              { NULL,                        NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
-+      };
-+
-+      p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
-+
-+      for (i = 0; i < srv->config_context->used; i++) {
-+              plugin_config *s;
-+              array *ca;
-+              proxy_backend *backend;
-+
-+              array_reset(p->backends_arr);
-+              buffer_reset(p->balance_buf);
-+              buffer_reset(p->protocol_buf);
-+
-+              s = calloc(1, sizeof(plugin_config));
-+              s->debug     = 0;
-+              s->balancer  = PROXY_BALANCE_UNSET;
-+              s->protocol  = PROXY_PROTOCOL_UNSET;
-+              s->backends  = proxy_backends_init();
-+              s->backlog   = proxy_backlog_init();
-+              s->response_rewrites   = proxy_rewrites_init();
-+              s->request_rewrites   = proxy_rewrites_init();
-+
-+              cv[0].destination = p->backends_arr;
-+              cv[1].destination = &(s->debug);
-+              cv[2].destination = p->balance_buf;         /* parse into a constant */
-+              cv[3].destination = p->protocol_buf;        /* parse into a constant */
-+              cv[6].destination = &(s->allow_x_sendfile);
-+              cv[7].destination = &(s->allow_x_rewrite);
-+              cv[8].destination = &(s->max_pool_size);
-+
-+              buffer_reset(p->balance_buf);
-+
-+              p->config_storage[i] = s;
-+              ca = ((data_config *)srv->config_context->data[i])->value;
-+
-+              if (0 != config_insert_values_global(srv, ca, cv)) {
-+                      return HANDLER_ERROR;
-+              }
-+
-+              if (!buffer_is_empty(p->balance_buf)) {
-+                      data_integer *di;
-+                      
-+                      if (NULL == (di = (data_integer *)array_get_element(p->possible_balancers, BUF_STR(p->balance_buf)))) {
-+                              ERROR("proxy.balance has to be on of 'fair', 'round-robin', 'hash', got %s", BUF_STR(p->balance_buf));
-+
-+                              return HANDLER_ERROR;
-+                      }
-+
-+                      s->balancer = di->value;
-+              }
-+
-+              if (!buffer_is_empty(p->protocol_buf)) {
-+                      data_integer *di;
-+                      
-+                      if (NULL == (di = (data_integer *)array_get_element(p->possible_protocols, BUF_STR(p->protocol_buf)))) {
-+                              ERROR("proxy.balance has to be on of 'fair', 'round-robin', 'hash', got %s", BUF_STR(p->protocol_buf));
-+
-+                              return HANDLER_ERROR;
-+                      }
-+
-+                      s->protocol = di->value;
-+              }
-+
-+              if (p->backends_arr->used) {
-+                      backend = proxy_backend_init();
-+
-+                      /* check if the backends have a valid host-name */
-+                      for (j = 0; j < p->backends_arr->used; j++) {
-+                              data_string *ds = (data_string *)p->backends_arr->data[j];
-+
-+                              /* the values should be ips or hostnames */
-+                              if (0 != proxy_address_pool_add_string(backend->address_pool, ds->value)) {
-+                                      return HANDLER_ERROR;
-+                              }
-+                      }
-+
-+                      if (s->max_pool_size) {
-+                              backend->pool->max_size = s->max_pool_size;
-+                      }
-+
-+                      proxy_backends_add(s->backends, backend);
-+              }
-+
-+              if (HANDLER_GO_ON != mod_proxy_core_config_parse_rewrites(s->request_rewrites, ca, CONFIG_PROXY_CORE_REWRITE_REQUEST)) {
-+                      return HANDLER_ERROR;
-+              }
-+              
-+              if (HANDLER_GO_ON != mod_proxy_core_config_parse_rewrites(s->response_rewrites, ca, CONFIG_PROXY_CORE_REWRITE_RESPONSE)) {
-+                      return HANDLER_ERROR;
-+              }
-+      }
-+
-+      return HANDLER_GO_ON;
-+}
-+
-+
-+proxy_session *proxy_session_init(void) {
-+      proxy_session *sess;
-+
-+      sess = calloc(1, sizeof(*sess));
-+
-+      sess->state = PROXY_STATE_UNSET;
-+      sess->request_headers = array_init();
-+      sess->env_headers = array_init();
-+
-+      sess->recv = chunkqueue_init();
-+      sess->recv_raw = chunkqueue_init();
-+      sess->send_raw = chunkqueue_init();
-+      sess->send = chunkqueue_init();
-+
-+      sess->is_chunked = 0;
-+      sess->send_response_content = 1;
-+
-+      return sess;
-+}
-+
-+void proxy_session_free(proxy_session *sess) {
-+      if (!sess) return;
-+
-+      array_free(sess->request_headers);
-+      array_free(sess->env_headers);
-+
-+      chunkqueue_free(sess->recv);
-+      chunkqueue_free(sess->recv_raw);
-+      chunkqueue_free(sess->send_raw);
-+      chunkqueue_free(sess->send);
-+
-+      free(sess);
-+}
-+
-+/**
-+ * decode the content for the protocol
-+ *
-+ * http might have chunk-encoding 
-+ * fastcgi has the fastcgi wrapper code
-+ *
-+ * @param in chunkqueue for the encoded, protocol specific data
-+ * @param out chunkqueue for the plain content
-+ */
-+
-+int proxy_stream_decoder(server *srv, proxy_session *sess, chunkqueue *in, chunkqueue *out) {
-+      switch (sess->proxy_backend->protocol) {
-+      case PROXY_PROTOCOL_HTTP:
-+              return proxy_http_stream_decoder(srv, sess, in, out);
-+      case PROXY_PROTOCOL_FASTCGI:
-+              return proxy_fastcgi_stream_decoder(srv, sess, in, out);
-+      default:
-+              ERROR("protocol %d is not supported yet", sess->proxy_backend->protocol);
-+              return -1;
-+      }
-+}
-+/**
-+ * encode the content for the protocol
-+ *
-+ * @param in chunkqueue with the content to (no encoding)
-+ * @param out chunkqueue for the encoded, protocol specific data
-+ */
-+int proxy_stream_encoder(server *srv, proxy_session *sess, chunkqueue *in, chunkqueue *out) {
-+      switch (sess->proxy_backend->protocol) {
-+      case PROXY_PROTOCOL_HTTP:
-+              return proxy_http_stream_encoder(srv, sess, in, out);
-+      case PROXY_PROTOCOL_FASTCGI:
-+              return proxy_fastcgi_stream_encoder(srv, sess, in, out);
-+      default:
-+              ERROR("protocol %d is not supported yet", sess->proxy_backend->protocol);
-+              return -1;
-+      }
-+}
-+
-+int proxy_get_request_chunk(server *srv, connection *con, plugin_data *p, proxy_session *sess, chunkqueue *cq) {
-+      switch (sess->proxy_backend->protocol) {
-+      case PROXY_PROTOCOL_HTTP:
-+              return proxy_http_get_request_chunk(srv, con, p, sess, cq);
-+      case PROXY_PROTOCOL_FASTCGI:
-+              return proxy_fastcgi_get_request_chunk(srv, con, p, sess, cq);
-+      default:
-+              ERROR("protocol %d is not supported yet", sess->proxy_backend->protocol);
-+              return -1;
-+      }
-+}
-+
-+
-+parse_status_t proxy_parse_response_header(server *srv, connection *con, plugin_data *p, proxy_session *sess, chunkqueue *cq) {
-+      switch (sess->proxy_backend->protocol) {
-+      case PROXY_PROTOCOL_HTTP:
-+              return proxy_http_parse_response_header(srv, con, p, sess, cq);
-+      case PROXY_PROTOCOL_FASTCGI:
-+              return proxy_fastcgi_parse_response_header(srv, con, p, sess, cq);
-+      default:
-+              ERROR("protocol %d is not supported yet", sess->proxy_backend->protocol);
-+              return PARSE_ERROR;
-+      }
-+}
-+
-+
-+handler_t proxy_connection_connect(proxy_connection *con) {
-+      int fd;
-+
-+      if (-1 == (fd = socket(con->address->addr.plain.sa_family, SOCK_STREAM, 0))) {
-+      }
-+
-+      fcntl(fd, F_SETFL, O_NONBLOCK | O_RDWR);
-+
-+      con->sock->fd = fd;
-+      con->sock->fde_ndx = -1;
-+      con->sock->type = IOSOCKET_TYPE_SOCKET;
-+
-+      if (-1 == connect(fd, &(con->address->addr.plain), sizeof(con->address->addr))) {
-+              switch(errno) {
-+              case EINPROGRESS:
-+              case EALREADY:
-+              case EINTR:
-+                      return HANDLER_WAIT_FOR_EVENT;
-+              default:
-+                      close(fd);
-+                      con->sock->fd = -1;
-+
-+                      return HANDLER_ERROR;
-+              }
-+      }
-+
-+      return HANDLER_GO_ON;
-+}
-+
-+/**
-+ * event-handler for idling connections
-+ *
-+ * unused (idling) keep-alive connections are not bound to a session
-+ * and need their own event-handler 
-+ *
-+ * if the connection closes (we get a FDEVENT_IN), close our side too and 
-+ * let the trigger-func handle the cleanup
-+ *
-+ * @see proxy_trigger
-+ */
-+
-+
-+static handler_t proxy_handle_fdevent_idle(void *s, void *ctx, int revents) {
-+      server      *srv  = (server *)s;
-+      proxy_connection *proxy_con = ctx;
-+
-+      if (revents & FDEVENT_IN) {
-+              switch (proxy_con->state) {
-+              case PROXY_CONNECTION_STATE_IDLE:
-+                      proxy_con->state = PROXY_CONNECTION_STATE_CLOSED;
-+
-+                      /* close + unregister have to be in the same call,
-+                       * otherwise we get a events for a re-opened fd */
-+
-+                      fdevent_event_del(srv->ev, proxy_con->sock);
-+
-+                      break;
-+              case PROXY_CONNECTION_STATE_CLOSED:
-+                      /* poll() is state-driven, we will get events as long as it isn't disabled
-+                       * the close() above should disable the events too */
-+                      ERROR("%s", "hurry up buddy, I got another event for a closed idle-connection");
-+                      break;
-+              default:
-+                      ERROR("invalid connection state: %d, should be idle", proxy_con->state);
-+                      break;
-+              }
-+      }
-+
-+      return HANDLER_GO_ON;
-+}
-+
-+
-+/* don't call any proxy functions directly */
-+static handler_t proxy_handle_fdevent(void *s, void *ctx, int revents) {
-+      server      *srv  = (server *)s;
-+      proxy_session *sess = ctx;
-+      connection  *con  = sess->remote_con;
-+
-+      if (revents & FDEVENT_OUT) {
-+              switch (sess->state) {
-+              case PROXY_STATE_CONNECTING: /* delayed connect */
-+              case PROXY_STATE_WRITE_REQUEST_HEADER:
-+              case PROXY_STATE_WRITE_REQUEST_BODY:
-+                      /* we are still connection */
-+
-+                      joblist_append(srv, con);
-+                      break;
-+              default:
-+                      ERROR("oops, unexpected state for fdevent-out %d", sess->state);
-+                      break;
-+              }
-+      } else if (revents & FDEVENT_IN) {
-+              chunk *c;
-+
-+              switch (sess->state) {
-+              case PROXY_STATE_READ_RESPONSE_HEADER:
-+                      /* call our header parser */
-+                      joblist_append(srv, con);
-+                      break;
-+              case PROXY_STATE_READ_RESPONSE_BODY:
-+                      /* we should be in the WRITE state now, 
-+                       * just read in the content and forward it to the outgoing connection
-+                       * */
-+
-+                      chunkqueue_remove_finished_chunks(sess->recv_raw);
-+                      switch (srv->network_backend_read(srv, con, sess->proxy_con->sock, sess->recv_raw)) {
-+                      case NETWORK_STATUS_CONNECTION_CLOSE:
-+                              fdevent_event_del(srv->ev,sess->proxy_con->sock);
-+
-+                              /* the connection is gone
-+                               * make the connect */
-+                              con->send->is_closed = 1;
-+                              sess->proxy_con->state = PROXY_CONNECTION_STATE_CLOSED;
-+
-+                      case NETWORK_STATUS_SUCCESS:
-+                              /* read even more, do we have all the content */
-+
-+                              /* how much do we want to read ? */
-+                              
-+                              /* call stream-decoder (HTTP-chunked, FastCGI, ... ) */
-+
-+                              switch (proxy_stream_decoder(srv, sess, sess->recv_raw, sess->recv)) {
-+                              case 0:
-+                                      /* need more */
-+                                      break;
-+                              case -1:
-+                                      /* error */
-+                                      break;
-+                              case 1:
-+                                      /* we are done */
-+                                      con->send->is_closed = 1;
-+
-+                                      break;
-+                              }
-+                              chunkqueue_remove_finished_chunks(sess->recv_raw);
-+
-+
-+                              /* copy the content to the next cq */
-+                              for (c = sess->recv->first; c; c = c->next) {
-+                                      if (c->mem->used == 0) continue;
-+
-+                                      if (sess->send_response_content) {
-+                                              /* X-Sendfile ignores the content-body */
-+                                              chunkqueue_append_mem(con->send, c->mem->ptr + c->offset, c->mem->used - c->offset);
-+                                      }
-+      
-+                                      c->offset = c->mem->used - 1;
-+
-+                              }
-+                              chunkqueue_remove_finished_chunks(sess->recv);
-+                              
-+                              break;
-+                      default:
-+                              ERROR("%s", "oops, we failed to read");
-+                              break;
-+                      }
-+
-+                      /* we wrote something into the the send-buffers, 
-+                       * call the connection-handler to push it to the client */
-+                      joblist_append(srv, con);
-+                      break;
-+              default:
-+                      ERROR("oops, unexpected state for fdevent-in %d", sess->state);
-+                      break;
-+              }
-+      }
-+
-+      if (revents & FDEVENT_HUP) {
-+              /* someone closed our connection */
-+              switch (sess->state) {
-+              case PROXY_STATE_CONNECTING:
-+                      /* let the getsockopt() catch this */
-+                      joblist_append(srv, con);
-+                      break;
-+              case PROXY_STATE_READ_RESPONSE_BODY:
-+                      /* the keep-alive race-condition */
-+                      break;
-+              default:
-+                      ERROR("oops, unexpected state for fdevent-hup %d", sess->state);
-+                      break;
-+              }
-+      }
-+
-+      return HANDLER_GO_ON;
-+}
-+void proxy_set_header(array *hdrs, const char *key, size_t key_len, const char *value, size_t val_len) {
-+      data_string *ds_dst;
-+
-+      if (NULL != (ds_dst = (data_string *)array_get_element(hdrs, key))) {
-+              buffer_copy_string_len(ds_dst->value, value, val_len);
-+              return;
-+      }
-+
-+      if (NULL == (ds_dst = (data_string *)array_get_unused_element(hdrs, TYPE_STRING))) {
-+              ds_dst = data_string_init();
-+      }
-+
-+      buffer_copy_string_len(ds_dst->key, key, key_len);
-+      buffer_copy_string_len(ds_dst->value, value, val_len);
-+      array_insert_unique(hdrs, (data_unset *)ds_dst);
-+}
-+
-+void proxy_append_header(array *hdrs, const char *key, size_t key_len, const char *value, size_t val_len) {
-+      data_string *ds_dst;
-+
-+      if (NULL == (ds_dst = (data_string *)array_get_unused_element(hdrs, TYPE_STRING))) {
-+              ds_dst = data_string_init();
-+      }
-+
-+      buffer_copy_string_len(ds_dst->key, key, key_len);
-+      buffer_copy_string_len(ds_dst->value, value, val_len);
-+      array_insert_unique(hdrs, (data_unset *)ds_dst);
-+}
-+
-+
-+/**
-+ * build the request-header array and call the backend specific request formater
-+ * to fill the chunkqueue
-+ */
-+int proxy_get_request_header(server *srv, connection *con, plugin_data *p, proxy_session *sess) {
-+      /* request line */
-+      const char *remote_ip;
-+      size_t i;
-+
-+      remote_ip = inet_ntop_cache_get_ip(srv, &(con->dst_addr));
-+      proxy_append_header(sess->request_headers, CONST_STR_LEN("X-Forwarded-For"), remote_ip, strlen(remote_ip));
-+
-+      /* http_host is NOT is just a pointer to a buffer
-+       * which is NULL if it is not set */
-+      if (con->request.http_host &&
-+          !buffer_is_empty(con->request.http_host)) {
-+              proxy_set_header(sess->request_headers, CONST_STR_LEN("X-Host"), CONST_BUF_LEN(con->request.http_host));
-+      }
-+      if (con->conf.is_ssl) {
-+              proxy_set_header(sess->request_headers, CONST_STR_LEN("X-Forwarded-Proto"), CONST_STR_LEN("https"));
-+      } else {
-+              proxy_set_header(sess->request_headers, CONST_STR_LEN("X-Forwarded-Proto"), CONST_STR_LEN("http"));
-+      }
-+
-+      /* request header */
-+      for (i = 0; i < con->request.headers->used; i++) {
-+              data_string *ds;
-+              size_t k;
-+
-+              ds = (data_string *)con->request.headers->data[i];
-+
-+              if (buffer_is_empty(ds->value) || buffer_is_empty(ds->key)) continue;
-+
-+              if (buffer_is_equal_string(ds->key, CONST_STR_LEN("Connection"))) continue;
-+              if (buffer_is_equal_string(ds->key, CONST_STR_LEN("Keep-Alive"))) continue;
-+
-+              for (k = 0; k < p->conf.request_rewrites->used; k++) {
-+                      proxy_rewrite *rw = p->conf.request_rewrites->ptr[k];
-+
-+                      if (buffer_is_equal(rw->header, ds->key)) {
-+                              int ret;
-+
-+                              if ((ret = pcre_replace(rw->regex, rw->replace, ds->value, p->replace_buf)) < 0) {
-+                                      switch (ret) {
-+                                      case PCRE_ERROR_NOMATCH:
-+                                              /* hmm, ok. no problem */
-+                                              proxy_set_header(sess->request_headers, CONST_BUF_LEN(ds->key), CONST_BUF_LEN(ds->value));
-+                                              break;
-+                                      default:
-+                                              TRACE("oops, pcre_replace failed with: %d", ret);
-+                                              break;
-+                                      }
-+                              } else {
-+                                      proxy_set_header(sess->request_headers, CONST_BUF_LEN(ds->key), CONST_BUF_LEN(p->replace_buf));
-+                              }
-+
-+                              break;
-+                      }
-+              }
-+
-+              if (k == p->conf.request_rewrites->used) {
-+                      proxy_set_header(sess->request_headers, CONST_BUF_LEN(ds->key), CONST_BUF_LEN(ds->value));
-+              }
-+      }
-+
-+      proxy_get_request_chunk(srv, con, p, sess, sess->send_raw);
-+
-+      return 0;
-+}
-+
-+
-+/* we are event-driven
-+ * 
-+ * the first entry is connect() call, if the doesn't need a event 
-+ *
-+ * a bit boring
-+ * - connect (+ delayed connect)
-+ * - write header + content
-+ * - read header + content
-+ *
-+ * as soon as have read the response header we switch con->file_started and return HANDLER_GO_ON to
-+ * tell the core we are ready to stream out the content.
-+ *  */
-+handler_t proxy_state_engine(server *srv, connection *con, plugin_data *p, proxy_session *sess) {
-+      /* do we have a connection ? */
-+
-+      if (sess->state == PROXY_STATE_UNSET) {
-+              /* we are not started yet */
-+              sess->connect_start_ts = srv->cur_ts;
-+              switch(proxy_connection_connect(sess->proxy_con)) {
-+              case HANDLER_WAIT_FOR_EVENT:
-+                      /* waiting on the connect call */
-+
-+                      fdevent_register(srv->ev, sess->proxy_con->sock, proxy_handle_fdevent, sess);
-+                      fdevent_event_add(srv->ev, sess->proxy_con->sock, FDEVENT_OUT);
-+
-+                      sess->state = PROXY_STATE_CONNECTING;
-+                      sess->proxy_con->state = PROXY_CONNECTION_STATE_CONNECTING;
-+                      
-+                      return HANDLER_WAIT_FOR_EVENT;
-+              case HANDLER_GO_ON:
-+                      /* we are connected */
-+                      sess->state = PROXY_STATE_CONNECTED;
-+                      sess->proxy_con->state = PROXY_CONNECTION_STATE_CONNECTED;
-+                      fdevent_register(srv->ev, sess->proxy_con->sock, proxy_handle_fdevent, sess);
-+
-+                      break;
-+              case HANDLER_ERROR:
-+              default:
-+                      /* not good, something failed */
-+                      return HANDLER_ERROR;
-+              
-+              }
-+      } else if (sess->state == PROXY_STATE_CONNECTING) {
-+              int socket_error;
-+              socklen_t socket_error_len = sizeof(socket_error);
-+
-+              fdevent_event_del(srv->ev, sess->proxy_con->sock);
-+
-+              if (0 != getsockopt(sess->proxy_con->sock->fd, SOL_SOCKET, SO_ERROR, &socket_error, &socket_error_len)) {
-+                      ERROR("getsockopt failed:", strerror(errno));
-+
-+                      return HANDLER_ERROR;
-+              }
-+              if (socket_error != 0) {
-+                      switch (socket_error) {
-+                      case ECONNREFUSED:
-+                              /* there is no-one on the other side */
-+                              sess->proxy_con->address->disabled_until = srv->cur_ts + 2;
-+
-+                              TRACE("address %s refused us, disabling for 2 sec", sess->proxy_con->address->name->ptr);
-+                              break;
-+                      case EHOSTUNREACH:
-+                              /* there is no-one on the other side */
-+                              sess->proxy_con->address->disabled_until = srv->cur_ts + 60;
-+
-+                              TRACE("host %s is unreachable, disabling for 60 sec", sess->proxy_con->address->name->ptr);
-+                              break;
-+                      default:
-+                              sess->proxy_con->address->disabled_until = srv->cur_ts + 60;
-+
-+                              TRACE("connected finally failed: %s (%d)", strerror(socket_error), socket_error);
-+
-+                              TRACE("connect to address %s failed and I don't know why, disabling for 10 sec", sess->proxy_con->address->name->ptr);
-+
-+                              break;
-+                      }
-+
-+                      sess->proxy_con->address->state = PROXY_ADDRESS_STATE_DISABLED;
-+
-+                      sess->proxy_con->state = PROXY_CONNECTION_STATE_CLOSED;
-+                      return HANDLER_COMEBACK;
-+              }
-+
-+              sess->state = PROXY_STATE_CONNECTED;
-+              sess->proxy_con->state = PROXY_CONNECTION_STATE_CONNECTED;
-+      }
-+
-+      if (sess->state == PROXY_STATE_CONNECTED) {
-+              /* build the header */
-+              proxy_get_request_header(srv, con, p, sess);
-+
-+              sess->state = PROXY_STATE_WRITE_REQUEST_HEADER;
-+      }
-+
-+      switch (sess->state) {
-+      case PROXY_STATE_WRITE_REQUEST_HEADER:
-+              /* create the request-packet */ 
-+              fdevent_event_del(srv->ev, sess->proxy_con->sock);
-+
-+              switch (srv->network_backend_write(srv, con, sess->proxy_con->sock, sess->send_raw)) {
-+              case NETWORK_STATUS_SUCCESS:
-+                      sess->state = PROXY_STATE_WRITE_REQUEST_BODY;
-+                      break;
-+              case NETWORK_STATUS_WAIT_FOR_EVENT:
-+                      fdevent_event_add(srv->ev, sess->proxy_con->sock, FDEVENT_OUT);
-+
-+                      return HANDLER_WAIT_FOR_EVENT;
-+              case NETWORK_STATUS_CONNECTION_CLOSE:
-+                      sess->proxy_con->state = PROXY_CONNECTION_STATE_CLOSED;
-+
-+                      /* this connection is closed, restart the request with a new connection */
-+
-+                      return HANDLER_COMEBACK;
-+              default:
-+                      return HANDLER_ERROR;
-+              }
-+
-+              chunkqueue_remove_finished_chunks(sess->send_raw);
-+              
-+              /* fall through */
-+      case PROXY_STATE_WRITE_REQUEST_BODY:
-+              /* do we have a content-body to send up to the backend ? */
-+
-+              fdevent_event_del(srv->ev, sess->proxy_con->sock);
-+
-+              proxy_stream_encoder(srv, sess, con->recv, sess->send_raw);
-+
-+              chunkqueue_remove_finished_chunks(con->recv);
-+
-+              switch (srv->network_backend_write(srv, con, sess->proxy_con->sock, sess->send_raw)) {
-+              case NETWORK_STATUS_SUCCESS:
-+                      if (con->recv->is_closed && /* no further input */
-+                          con->recv->bytes_in == con->recv->bytes_out &&  /* everything is encoded */
-+                          sess->send_raw->bytes_in == sess->send_raw->bytes_out) { /* everything is sent */
-+                              sess->state = PROXY_STATE_READ_RESPONSE_HEADER;
-+                      }
-+                      break;
-+              case NETWORK_STATUS_WAIT_FOR_EVENT:
-+                      fdevent_event_add(srv->ev, sess->proxy_con->sock, FDEVENT_OUT);
-+
-+                      chunkqueue_remove_finished_chunks(sess->send_raw);
-+
-+                      return HANDLER_WAIT_FOR_EVENT;
-+              case NETWORK_STATUS_CONNECTION_CLOSE:
-+                      /* the connection got close while sending the request content up 
-+                       * to the backend, for now handle this as error */
-+
-+                      TRACE("%s", "(con-close)");
-+                      return HANDLER_ERROR;
-+              default:
-+                      TRACE("%s", "(error)");
-+                      return HANDLER_ERROR;
-+              }
-+              chunkqueue_remove_finished_chunks(sess->send_raw);
-+
-+              /* fall through */
-+      case PROXY_STATE_READ_RESPONSE_HEADER:
-+              fdevent_event_del(srv->ev, sess->proxy_con->sock);
-+
-+              chunkqueue_remove_finished_chunks(sess->recv_raw);
-+
-+              switch (srv->network_backend_read(srv, con, sess->proxy_con->sock, sess->recv_raw)) {
-+              case NETWORK_STATUS_SUCCESS:
-+                      /* we read everything from the socket, do we have a full header ? */
-+
-+                      switch (proxy_parse_response_header(srv, con, p, sess, sess->recv_raw)) {
-+                      case PARSE_ERROR:
-+                              con->http_status = 502; /* bad gateway */
-+
-+                              return HANDLER_FINISHED;
-+                      case PARSE_NEED_MORE:
-+                              /* we need more */
-+                              fdevent_event_add(srv->ev, sess->proxy_con->sock, FDEVENT_IN);
-+
-+                              return HANDLER_WAIT_FOR_EVENT;
-+                      case PARSE_SUCCESS:
-+                              break;
-+                      default:
-+                              return HANDLER_ERROR;
-+                      }
-+
-+                      if (sess->do_internal_redirect) {
-+                              /* now it becomes tricky
-+                               * 
-+                               * mod_staticfile should handle this file for us
-+                               * con->mode = DIRECT is taking us out of the loop */
-+
-+                              return HANDLER_COMEBACK;
-+                      }
-+
-+                      con->file_started = 1;
-+                      /* if Status: ... is not set, 200 is our default status-code */
-+                      if (con->http_status == 0) con->http_status = 200;
-+
-+                      sess->state = PROXY_STATE_READ_RESPONSE_BODY;
-+
-+                      /**
-+                       * set the event to pass the content through to the server
-+                       *
-+                       * this triggers the event-handler
-+                       * @see proxy_handle_fdevent
-+                       */
-+                      fdevent_event_add(srv->ev, sess->proxy_con->sock, FDEVENT_IN);
-+
-+                      return HANDLER_GO_ON; /* tell http_response_prepare that we are done with the header */
-+              case NETWORK_STATUS_WAIT_FOR_EVENT:
-+                      fdevent_event_add(srv->ev, sess->proxy_con->sock, FDEVENT_IN);
-+                      return HANDLER_WAIT_FOR_EVENT;
-+              case NETWORK_STATUS_CONNECTION_CLOSE:
-+                      if (chunkqueue_length(sess->recv_raw) == 0) {
-+                              /* the connection went away before we got something back */
-+                              sess->proxy_con->state = PROXY_CONNECTION_STATE_CLOSED;
-+
-+                              /**
-+                               * we might run into a 'race-condition' 
-+                               *
-+                               * 1. proxy-con is keep-alive, idling and just being closed (FDEVENT_IN) [fd=27]
-+                               * 2. new connection comes in, we use the idling connection [fd=14]
-+                               * 3. we write(), successful [to fd=27]
-+                               * 3. we read() ... and finally receive the close-event for the connection
-+                               */
-+
-+                              ERROR("%s", "++ oops, connection closed while waiting to read a response, restarting");
-+
-+                              return HANDLER_COMEBACK;
-+                      }
-+
-+                      ERROR("%s", "conn-close after header-read");
-+                              
-+                      break;
-+              default:
-+                      ERROR("++ %s", "oops, something went wrong while reading");
-+                      return HANDLER_ERROR;
-+              }
-+      case PROXY_STATE_READ_RESPONSE_BODY:
-+              /* if we do everything right, we won't get call for this state-anymore */
-+
-+              ERROR("%s", "PROXY_STATE_READ_RESPONSE_BODY");
-+              
-+              break;
-+      }
-+
-+      return HANDLER_GO_ON;
-+}
-+
-+proxy_backend *proxy_get_backend(server *srv, connection *con, plugin_data *p) {
-+      size_t i;
-+
-+      for (i = 0; i < p->conf.backends->used; i++) {
-+              proxy_backend *backend = p->conf.backends->ptr[i];
-+
-+              return backend;
-+      }
-+
-+      return NULL;
-+}
-+
-+/**
-+ * choose a available address from the address-pool
-+ *
-+ * the backend has different balancers 
-+ */
-+proxy_address *proxy_backend_balance(server *srv, connection *con, proxy_backend *backend) {
-+      size_t i;
-+      proxy_address_pool *address_pool = backend->address_pool;
-+      unsigned long last_max; /* for the HASH balancer */
-+      proxy_address *address = NULL, *cur_address = NULL;
-+      int active_addresses = 0, rand_ndx;
-+
-+      switch(backend->balancer) {
-+      case PROXY_BALANCE_HASH:
-+              /* hash balancing */
-+
-+              for (i = 0, last_max = ULONG_MAX; i < address_pool->used; i++) {
-+                      unsigned long cur_max;
-+
-+                      cur_address = address_pool->ptr[i];
-+
-+                      if (cur_address->state != PROXY_ADDRESS_STATE_ACTIVE) continue;
-+
-+                      cur_max = generate_crc32c(CONST_BUF_LEN(con->uri.path)) +
-+                              generate_crc32c(CONST_BUF_LEN(cur_address->name)) + /* we can cache this */
-+                              generate_crc32c(CONST_BUF_LEN(con->uri.authority));
-+#if 0
-+                      TRACE("hash-election: %s - %s - %s: %ld", 
-+                                      con->uri.path->ptr,
-+                                      cur_address->name->ptr,
-+                                      con->uri.authority->ptr,
-+                                      cur_max);
-+#endif
-+                      if (address == NULL || (cur_max > last_max)) {
-+                              last_max = cur_max;
-+
-+                              address = cur_address;
-+                      }
-+              }
-+
-+              break;
-+      case PROXY_BALANCE_FAIR:
-+              /* fair balancing */
-+
-+              for (i = 0; i < address_pool->used; i++) {
-+                      cur_address = address_pool->ptr[i];
-+
-+                      if (cur_address->state != PROXY_ADDRESS_STATE_ACTIVE) continue;
-+
-+                      /* the address is up, use it */
-+
-+                      address = cur_address;
-+
-+                      break;
-+              }
-+
-+              break;
-+      case PROXY_BALANCE_RR:
-+              /* round robin */
-+
-+              /**
-+               * instead of real RoundRobin we just do a RandomSelect
-+               *
-+               * it is state-less and has the same distribution
-+               */
-+
-+              active_addresses = 0;
-+              
-+              for (i = 0; i < address_pool->used; i++) {
-+                      cur_address = address_pool->ptr[i];
-+
-+                      if (cur_address->state != PROXY_ADDRESS_STATE_ACTIVE) continue;
-+
-+                      active_addresses++;
-+              }
-+
-+              rand_ndx = (int) (1.0 * active_addresses * rand()/(RAND_MAX));
-+      
-+              active_addresses = 0;
-+              for (i = 0; i < address_pool->used; i++) {
-+                      cur_address = address_pool->ptr[i];
-+
-+                      if (cur_address->state != PROXY_ADDRESS_STATE_ACTIVE) continue;
-+
-+                      address = cur_address;
-+
-+                      if (rand_ndx == active_addresses++) break;
-+              }
-+
-+              break;
-+      default:
-+              break;
-+      }
-+
-+      return address;
-+}
-+
-+static int mod_proxy_core_patch_connection(server *srv, connection *con, plugin_data *p) {
-+      size_t i, j;
-+      plugin_config *s = p->config_storage[0];
-+
-+      /* global defaults */
-+      PATCH_OPTION(balancer);
-+      PATCH_OPTION(debug);
-+      PATCH_OPTION(backends);
-+      PATCH_OPTION(backlog);
-+      PATCH_OPTION(protocol);
-+      PATCH_OPTION(request_rewrites);
-+      PATCH_OPTION(response_rewrites);
-+      PATCH_OPTION(allow_x_sendfile);
-+      PATCH_OPTION(allow_x_rewrite);
-+
-+      /* skip the first, the global context */
-+      for (i = 1; i < srv->config_context->used; i++) {
-+              data_config *dc = (data_config *)srv->config_context->data[i];
-+              s = p->config_storage[i];
-+
-+              /* condition didn't match */
-+              if (!config_check_cond(srv, con, dc)) continue;
-+
-+              /* merge config */
-+              for (j = 0; j < dc->value->used; j++) {
-+                      data_unset *du = dc->value->data[j];
-+
-+                      if (buffer_is_equal_string(du->key, CONST_STR_LEN(CONFIG_PROXY_CORE_BACKENDS))) {
-+                              PATCH_OPTION(backends);
-+                              PATCH_OPTION(backlog);
-+                      } else if (buffer_is_equal_string(du->key, CONST_STR_LEN(CONFIG_PROXY_CORE_DEBUG))) {
-+                              PATCH_OPTION(debug);
-+                      } else if (buffer_is_equal_string(du->key, CONST_STR_LEN(CONFIG_PROXY_CORE_BALANCER))) {
-+                              PATCH_OPTION(balancer);
-+                      } else if (buffer_is_equal_string(du->key, CONST_STR_LEN(CONFIG_PROXY_CORE_PROTOCOL))) {
-+                              PATCH_OPTION(protocol);
-+                      } else if (buffer_is_equal_string(du->key, CONST_STR_LEN(CONFIG_PROXY_CORE_REWRITE_REQUEST))) {
-+                              PATCH_OPTION(request_rewrites);
-+                      } else if (buffer_is_equal_string(du->key, CONST_STR_LEN(CONFIG_PROXY_CORE_REWRITE_RESPONSE))) {
-+                              PATCH_OPTION(response_rewrites);
-+                      } else if (buffer_is_equal_string(du->key, CONST_STR_LEN(CONFIG_PROXY_CORE_ALLOW_X_SENDFILE))) {
-+                              PATCH_OPTION(allow_x_sendfile);
-+                      } else if (buffer_is_equal_string(du->key, CONST_STR_LEN(CONFIG_PROXY_CORE_ALLOW_X_REWRITE))) {
-+                              PATCH_OPTION(allow_x_rewrite);
-+                      }
-+              }
-+      }
-+
-+      return 0;
-+}
-+
-+SUBREQUEST_FUNC(mod_proxy_core_check_extension) {
-+      plugin_data *p = p_d;
-+      proxy_session *sess = con->plugin_ctx[p->id]; /* if this is the second round, sess is already prepared */
-+
-+      /* check if we have a matching conditional for this request */
-+
-+      if (buffer_is_empty(con->uri.path)) return HANDLER_GO_ON;
-+
-+      mod_proxy_core_patch_connection(srv, con, p);
-+
-+      if (p->conf.backends->used == 0) return HANDLER_GO_ON;
-+
-+      if (!sess) {
-+              /* a session lives for a single request */
-+              sess = proxy_session_init();
-+
-+              con->plugin_ctx[p->id] = sess;
-+              con->mode = p->id;
-+
-+              sess->remote_con = con;
-+      }
-+
-+      return HANDLER_GO_ON;
-+}
-+
-+CONNECTION_FUNC(mod_proxy_core_start_backend) {
-+      plugin_data *p = p_d;
-+      proxy_session *sess = con->plugin_ctx[p->id];
-+
-+      if (p->id != con->mode) return HANDLER_GO_ON;
-+
-+      /* 
-+       * 0. build session
-+       * 1. get a proxy connection
-+       * 2. create the http-request header
-+       * 3. stream the content to the backend 
-+       * 4. wait for http-response header 
-+       * 5. decode the response + parse the response
-+       * 6. stream the response-content to the client 
-+       * 7. kill session
-+       * */
-+
-+
-+      assert(sess);
-+
-+      if (sess->do_internal_redirect) {
-+             if (sess->internal_redirect_count > MAX_INTERNAL_REDIRECTS) {
-+                      /* we already handled this request and sent it to the static file handling */
-+
-+                      return HANDLER_GO_ON;
-+              }
-+      }
-+
-+      switch (sess->state) {
-+      case PROXY_STATE_CONNECTING:
-+              /* this connections is waited 10 seconds to connect to the backend
-+               * and didn't got a successful connection yet, sending timeout */
-+              if (srv->cur_ts - sess->connect_start_ts > 10) {
-+                      con->http_status = 504; /* gateway timeout */
-+                      con->send->is_closed = 1;
-+
-+                      if (sess->proxy_con) {
-+                              /* if we are waiting for a proxy-connection right now, close it */
-+                              proxy_connection_pool_remove_connection(sess->proxy_backend->pool, sess->proxy_con);
-+      
-+                              fdevent_event_del(srv->ev, sess->proxy_con->sock);
-+                              fdevent_unregister(srv->ev, sess->proxy_con->sock);
-+
-+                              proxy_connection_free(sess->proxy_con);
-+                      
-+                              sess->proxy_con = NULL;
-+                      }
-+
-+                      TRACE("%s", "connect to backend timed out");
-+                      
-+                      return HANDLER_FINISHED;
-+              }
-+      default:
-+              /* handle-request-timeout,  */
-+#if 0
-+              if (srv->cur_ts - con->request_start > 60) {
-+                      TRACE("request runs longer than 60sec: current state: %d", sess->state);
-+              }
-+#endif
-+              break;
-+      }
-+
-+      /* if the WRITE fails from the start, restart the connection */
-+      while (1) {
-+              if (sess->proxy_con == NULL) {
-+                      proxy_address *address = NULL;
-+                      if (NULL == (sess->proxy_backend = proxy_get_backend(srv, con, p))) {
-+                              /* no connection pool for this location */
-+                              SEGFAULT();
-+                      }
-+
-+                      sess->proxy_backend->balancer = p->conf.balancer;
-+                      sess->proxy_backend->protocol = p->conf.protocol;
-+
-+                      /**
-+                       * ask the balancer for the next address and
-+                       * check the connection pool if we have a connection open
-+                       * for that address
-+                       */
-+                      if (NULL == (address = proxy_backend_balance(srv, con, sess->proxy_backend))) {
-+                              /* we don't have any backends to connect to */
-+                              proxy_request *req;
-+
-+                              /* connection pool is full, queue the request for now */
-+                              req = proxy_request_init();
-+                              req->added_ts = srv->cur_ts;
-+                              req->con = con;
-+                              
-+                              TRACE("backlog: all backends are down, putting %s (%d) into the backlog", BUF_STR(con->uri.path), con->sock->fd);
-+                              proxy_backlog_push(p->conf.backlog, req);
-+
-+                              /* no, not really a event, 
-+                               * we just want to block the outer loop from stepping forward
-+                               *
-+                               * the trigger will bring this connection back into the game
-+                               * */
-+                              return HANDLER_WAIT_FOR_EVENT;
-+                      }
-+
-+                      if (PROXY_CONNECTIONPOOL_FULL == proxy_connection_pool_get_connection(
-+                                              sess->proxy_backend->pool, 
-+                                              address,
-+                                              &(sess->proxy_con))) {
-+                              proxy_request *req;
-+
-+                              /* connection pool is full, queue the request for now */
-+                              req = proxy_request_init();
-+                              req->added_ts = srv->cur_ts;
-+                              req->con = con;
-+                      
-+#if 0 
-+                              TRACE("backlog: the con-pool is full, putting %s (%d) into the backlog", BUF_STR(con->uri.path), con->sock->fd);
-+#endif
-+                              proxy_backlog_push(p->conf.backlog, req);
-+
-+                              /* no, not really a event, 
-+                               * we just want to block the outer loop from stepping forward
-+                               *
-+                               * the trigger will bring this connection back into the game
-+                               * */
-+                              return HANDLER_WAIT_FOR_EVENT;
-+                      }
-+
-+                      /* a fresh connection, we need address for it */
-+                      if (sess->proxy_con->state == PROXY_CONNECTION_STATE_CONNECTING) {
-+                              sess->state = PROXY_STATE_UNSET;
-+                              sess->bytes_read = 0;
-+                      } else {
-+                              /* we are already connected */
-+                              sess->state = PROXY_STATE_CONNECTED;
-+                              
-+                              /* the connection was idling and using the fdevent_idle-handler 
-+                               * switch it back to the normal proxy-event-handler */
-+                              fdevent_event_del(srv->ev, sess->proxy_con->sock);
-+                              fdevent_unregister(srv->ev, sess->proxy_con->sock);
-+
-+                              fdevent_register(srv->ev, sess->proxy_con->sock, proxy_handle_fdevent, sess);
-+                              fdevent_event_add(srv->ev, sess->proxy_con->sock, FDEVENT_IN);
-+                      }
-+              }
-+
-+              switch (proxy_state_engine(srv, con, p, sess)) {
-+              case HANDLER_WAIT_FOR_EVENT:
-+                      return HANDLER_WAIT_FOR_EVENT;
-+              case HANDLER_COMEBACK:
-+                      proxy_connection_pool_remove_connection(sess->proxy_backend->pool, sess->proxy_con);
-+      
-+                      fdevent_event_del(srv->ev, sess->proxy_con->sock);
-+                      fdevent_unregister(srv->ev, sess->proxy_con->sock);
-+
-+                      proxy_connection_free(sess->proxy_con);
-+
-+                      sess->proxy_con = NULL;
-+
-+                      if (sess->do_internal_redirect) {
-+                              con->mode = DIRECT;
-+                              con->http_status = 0;
-+
-+                              return HANDLER_COMEBACK;
-+                      }
-+                      /* restart the connection to the backend */
-+                      TRACE("%s", "write failed, restarting request");
-+                      break;
-+              case HANDLER_GO_ON:
-+                      return HANDLER_GO_ON;
-+              default:
-+                      TRACE("state: %d (error)", sess->state);
-+                      return HANDLER_ERROR;
-+              }
-+      }
-+
-+      TRACE("state: %d", sess->state);
-+      /* should not be reached */
-+      return HANDLER_ERROR;
-+}
-+
-+CONNECTION_FUNC(mod_proxy_send_request_content) {
-+      plugin_data *p = p_d;
-+      proxy_session *sess = con->plugin_ctx[p->id]; 
-+
-+      if (p->id != con->mode) return HANDLER_GO_ON;
-+
-+      /* read all the content before we start our backend */
-+      if (!con->recv->is_closed) {
-+              return HANDLER_GO_ON;
-+      }
-+
-+      /* copy the chunks to our queue and call the state-engine to send it out */
-+      return mod_proxy_core_start_backend(srv, con, p_d);
-+}
-+/**
-+ * end of the connection to the client
-+ */
-+REQUESTDONE_FUNC(mod_proxy_connection_close_callback) {
-+      plugin_data *p = p_d;
-+      
-+      if (con->mode != p->id) return HANDLER_GO_ON;
-+
-+      return HANDLER_GO_ON;
-+}
-+
-+/**
-+ * end of a request
-+ */
-+CONNECTION_FUNC(mod_proxy_connection_reset) {
-+      plugin_data *p = p_d;
-+      proxy_session *sess = con->plugin_ctx[p->id]; 
-+      proxy_request *req;
-+
-+      if (!sess) return HANDLER_GO_ON;
-+
-+      if (sess->proxy_con) {
-+              switch (sess->proxy_con->state) {
-+              case PROXY_CONNECTION_STATE_CONNECTED:
-+                      if (!sess->is_closing) {
-+                              sess->proxy_con->state = PROXY_CONNECTION_STATE_IDLE;
-+
-+                              /* don't ignore events as the FD is idle
-+                               * we might get a HUP as the remote connection might close */
-+                              fdevent_event_del(srv->ev, sess->proxy_con->sock);
-+                              fdevent_unregister(srv->ev, sess->proxy_con->sock);
-+
-+                              fdevent_register(srv->ev, sess->proxy_con->sock, proxy_handle_fdevent_idle, sess->proxy_con);
-+                              fdevent_event_add(srv->ev, sess->proxy_con->sock, FDEVENT_IN);
-+
-+                              break;
-+                      }
-+
-+                      /* fall-through for non-keep-alive */
-+
-+              case PROXY_CONNECTION_STATE_CLOSED:
-+                      proxy_connection_pool_remove_connection(sess->proxy_backend->pool, sess->proxy_con);
-+      
-+                      fdevent_event_del(srv->ev, sess->proxy_con->sock);
-+                      fdevent_unregister(srv->ev, sess->proxy_con->sock);
-+
-+                      proxy_connection_free(sess->proxy_con);
-+                      break;
-+              case PROXY_CONNECTION_STATE_IDLE:
-+                      TRACE("%s", "... connection is already back in the pool");
-+                      break;
-+              default:
-+                      ERROR("connection is in a unexpected state at close-time: %d", sess->proxy_con->state);
-+                      break;
-+              }
-+      } else {
-+              /* if we have the connection in the backlog, remove it */
-+              proxy_backlog_remove_connection(p->conf.backlog, con);
-+      }
-+      
-+
-+      proxy_session_free(sess);
-+
-+      con->plugin_ctx[p->id] = NULL;
-+
-+      /* wake up a connection from the backlog */
-+      if ((req = proxy_backlog_shift(p->conf.backlog))) {
-+              connection *next_con = req->con;
-+
-+              joblist_append(srv, next_con);
-+
-+              proxy_request_free(req);
-+      }
-+
-+      
-+      return HANDLER_GO_ON;
-+}
-+
-+
-+
-+/**
-+ * cleanup dead connections once a second
-+ *
-+ * the idling event-handler can't cleanup connections itself and has to wait until the 
-+ * trigger cleans up
-+ */
-+handler_t mod_proxy_trigger_context(server *srv, plugin_config *p) {
-+      size_t i, j;
-+      proxy_request *req;
-+
-+      for (i = 0; i < p->backends->used; i++) {
-+              proxy_backend *backend = p->backends->ptr[i];
-+              proxy_connection_pool *pool = backend->pool;
-+              proxy_address_pool *address_pool = backend->address_pool;
-+
-+              for (j = 0; j < pool->used; ) {
-+                      proxy_connection *proxy_con = pool->ptr[j];
-+
-+                      /* remove-con is removing the current con and moves the good connections to the left
-+                       * no need to increment i */
-+                      if (proxy_con->state == PROXY_CONNECTION_STATE_CLOSED) {
-+                              proxy_connection_pool_remove_connection(backend->pool, proxy_con);
-+      
-+                              fdevent_event_del(srv->ev, proxy_con->sock);
-+                              fdevent_unregister(srv->ev, proxy_con->sock);
-+
-+                              proxy_connection_free(proxy_con);
-+                      } else {
-+                              j++;
-+                      }
-+              }
-+
-+              /* active the disabled addresses again */
-+              for (j = 0; j < address_pool->used; j++) {
-+                      proxy_address *address = address_pool->ptr[j];
-+
-+                      if (address->state != PROXY_ADDRESS_STATE_DISABLED) continue;
-+
-+                      if (srv->cur_ts > address->disabled_until) {
-+                              address->disabled_until = 0;
-+                              address->state = PROXY_ADDRESS_STATE_ACTIVE;
-+                      }
-+              }
-+      }
-+
-+      /* wake up the connections from the backlog */
-+      while ((req = proxy_backlog_shift(p->backlog))) {
-+              connection *con = req->con;
-+
-+              joblist_append(srv, con);
-+
-+              proxy_request_free(req);
-+      }
-+      
-+      return HANDLER_GO_ON;
-+}
-+
-+TRIGGER_FUNC(mod_proxy_trigger) {
-+      plugin_data *p = p_d;
-+      size_t i;
-+      
-+      for (i = 0; i < srv->config_context->used; i++) {
-+              mod_proxy_trigger_context(srv, p->config_storage[i]);
-+      }
-+
-+      return HANDLER_GO_ON;
-+}
-+
-+int mod_proxy_core_plugin_init(plugin *p) {
-+      p->version      = LIGHTTPD_VERSION_ID;
-+      p->name         = buffer_init_string("mod_proxy_core");
-+
-+      p->init         = mod_proxy_core_init;
-+      p->cleanup      = mod_proxy_core_free;
-+      p->set_defaults = mod_proxy_core_set_defaults;
-+      p->handle_physical         = mod_proxy_core_check_extension;
-+      p->handle_send_request_content = mod_proxy_send_request_content;
-+      p->connection_reset        = mod_proxy_connection_reset;
-+      p->handle_connection_close = mod_proxy_connection_close_callback;
-+      p->handle_trigger          = mod_proxy_trigger;
-+
-+      p->data         = NULL;
-+
-+      return 0;
-+}
---- ../lighttpd-1.4.11/src/mod_proxy_core.h    1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/mod_proxy_core.h        2006-09-07 00:57:05.000000000 +0300
-@@ -0,0 +1,104 @@
-+#ifndef _MOD_PROXY_CORE_H_
-+#define _MOD_PROXY_CORE_H_
-+
-+#include "buffer.h"
-+#include "plugin.h"
-+#include "http_resp.h"
-+#include "array.h"
-+
-+#include "mod_proxy_core_pool.h"      
-+#include "mod_proxy_core_backend.h"
-+#include "mod_proxy_core_backlog.h"
-+#include "mod_proxy_core_rewrites.h"
-+
-+#define MAX_INTERNAL_REDIRECTS 8
-+
-+typedef struct {
-+      proxy_backends *backends;
-+
-+      proxy_backlog *backlog;
-+
-+      proxy_rewrites *request_rewrites;
-+      proxy_rewrites *response_rewrites;
-+
-+      unsigned short allow_x_sendfile;
-+      unsigned short allow_x_rewrite;
-+      unsigned short debug;
-+      unsigned short max_pool_size;
-+
-+      proxy_balance_t balancer;
-+      proxy_protocol_t protocol;
-+} plugin_config;
-+
-+typedef struct {
-+      PLUGIN_DATA;
-+
-+      http_resp *resp;
-+
-+      array *possible_balancers;
-+      array *possible_protocols;
-+
-+      /* for parsing only */
-+      array *backends_arr;
-+      buffer *protocol_buf;
-+      buffer *balance_buf;
-+
-+      buffer *replace_buf;
-+
-+      buffer *tmp_buf;     /** a temporary buffer, used by mod_proxy_backend_fastcgi */
-+
-+      plugin_config **config_storage;
-+
-+      plugin_config conf;
-+} plugin_data;
-+
-+
-+typedef enum {
-+      PROXY_STATE_UNSET,
-+      PROXY_STATE_CONNECTING,
-+      PROXY_STATE_CONNECTED,
-+      PROXY_STATE_WRITE_REQUEST_HEADER,
-+      PROXY_STATE_WRITE_REQUEST_BODY,
-+      PROXY_STATE_READ_RESPONSE_HEADER,
-+      PROXY_STATE_READ_RESPONSE_BODY
-+} proxy_state_t;
-+
-+typedef struct {
-+      proxy_connection *proxy_con;
-+      proxy_backend *proxy_backend;
-+
-+      connection *remote_con;
-+
-+      array *request_headers;    /** the con->request.headers without the hop-to-hop headers */
-+      array *env_headers;        /** transformed request-headers for the backend */
-+
-+      int is_chunked;            /** is the incoming content chunked (for HTTP) */
-+      int is_closing;            /** our connection will close when we are done */
-+      int send_response_content; /** 0 if we have to ignore the content-body */
-+      int do_internal_redirect;  /** 1 if we do a internal redirect to the ->mode = DIRECT */
-+      int internal_redirect_count;  /** protection against infinite loops */
-+      
-+      /**
-+       * chunkqueues
-+       * - the encoded_rb is the raw network stuff
-+       * - the rb is filtered through the stream decoder
-+       *
-+       * - wb is the normal bytes stream
-+       * - encoded_wb is encoded for the network by the stream encoder
-+       */
-+      chunkqueue *recv;
-+      chunkqueue *recv_raw;
-+      chunkqueue *send_raw;
-+      chunkqueue *send;
-+      
-+      off_t bytes_read;
-+      off_t content_length;
-+
-+      proxy_state_t state;
-+
-+      time_t connect_start_ts;
-+} proxy_session;
-+
-+void proxy_set_header(array *hdrs, const char *key, size_t key_len, const char *value, size_t val_len);
-+
-+#endif
---- ../lighttpd-1.4.11/src/mod_proxy_core_address.c    1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/mod_proxy_core_address.c        2006-07-20 00:57:20.000000000 +0300
-@@ -0,0 +1,186 @@
-+#include <stdlib.h>
-+#include <string.h>
-+
-+#include "log.h"
-+#include "sys-socket.h"
-+#include "mod_proxy_core_address.h"
-+
-+proxy_address *proxy_address_init(void) {
-+      proxy_address *address;
-+
-+      address = calloc(1, sizeof(*address));
-+
-+      address->name = buffer_init();
-+
-+      return address;
-+}
-+
-+void proxy_address_free(proxy_address *address) {
-+      if (!address) return;
-+
-+      buffer_free(address->name);
-+
-+      free(address);
-+}
-+
-+
-+proxy_address_pool *proxy_address_pool_init(void) {
-+      proxy_address_pool *address_pool;
-+
-+      address_pool = calloc(1, sizeof(*address_pool));
-+
-+      return address_pool;
-+}
-+
-+void proxy_address_pool_free(proxy_address_pool *address_pool) {
-+      if (!address_pool) return;
-+
-+      FOREACH(address_pool, element, proxy_address_free(element));
-+
-+      if (address_pool->ptr) free(address_pool->ptr);
-+
-+      free(address_pool);
-+}
-+
-+void proxy_address_pool_add(proxy_address_pool *address_pool, proxy_address *address) {
-+      size_t i;
-+
-+      /* check if this address is already known */
-+
-+      for (i = 0; i < address_pool->used; i++) {
-+              proxy_address *pool_address = address_pool->ptr[i];
-+
-+              if (buffer_is_equal(address->name, pool_address->name)) {
-+                      TRACE("%s is already in the address-pool", BUF_STR(address->name));
-+
-+                      proxy_address_free(address);
-+
-+                      return;
-+              }       
-+      }
-+
-+      TRACE("adding %s to the address-pool", BUF_STR(address->name));
-+
-+      ARRAY_STATIC_PREPARE_APPEND(address_pool);
-+
-+      address_pool->ptr[address_pool->used++] = address;
-+}
-+
-+int  proxy_address_pool_add_string(proxy_address_pool *address_pool, buffer *name) {
-+      struct addrinfo *res = NULL, pref, *cur;
-+      int ret;
-+      buffer *hostname = NULL, *port = NULL;
-+      char *colon;
-+
-+      pref.ai_flags = 0;
-+      pref.ai_family = PF_UNSPEC;
-+      pref.ai_socktype = SOCK_STREAM;
-+      pref.ai_protocol = 0;
-+      pref.ai_addrlen = 0;
-+      pref.ai_addr = NULL;
-+      pref.ai_canonname = NULL;
-+      pref.ai_next = NULL;
-+
-+      /* check the address style
-+       *
-+       * unix:/tmp/socket
-+       * www.example.org
-+       * www.example.org:80
-+       * 127.0.0.1
-+       * 127.0.0.1:80
-+       * [::1]:80
-+       * [::1]
-+       */
-+
-+      if (buffer_is_empty(name)) return -1;
-+
-+      if (0 == strncmp(BUF_STR(name), "unix:", 5)) {
-+              /* a unix domain socket */
-+              ERROR("unix: scheme is not supported for %s", BUF_STR(name));
-+              return -1;
-+      } else if (name->ptr[0] == '[') {
-+              if (name->ptr[name->used - 1] == ']') {
-+                      /* no port-number attached */
-+              
-+                      hostname = buffer_init();
-+                      buffer_copy_string_len(hostname, BUF_STR(name) + 1, name->used - 3);
-+                      port = buffer_init_string("80");
-+              } else if (NULL != (colon = strrchr(BUF_STR(name), ':'))) {
-+                      /* with port number */
-+
-+                      hostname = buffer_init();
-+                      buffer_copy_string_len(hostname, BUF_STR(name) + 1, colon - BUF_STR(name) - 2);
-+                      port = buffer_init();
-+                      buffer_copy_string(port, colon + 1);
-+
-+              } else {
-+                      ERROR("this is neither [<ipv6-address>] nor [<ipv6-address>]:<port>: %s", BUF_STR(name));
-+
-+                      return -1;
-+              }
-+      } else if (name->ptr[name->used - 1] != ']' &&
-+                 NULL != (colon = strrchr(BUF_STR(name), ':'))) {
-+
-+              hostname = buffer_init();
-+              buffer_copy_string_len(hostname, BUF_STR(name), colon - BUF_STR(name));
-+              port = buffer_init();
-+              buffer_copy_string(port, colon + 1);
-+      } else {
-+              /* no colon, just a IPv4 address or a domain name */
-+
-+              hostname = buffer_init_string(BUF_STR(name));
-+              port = buffer_init_string("80");
-+      }
-+
-+      TRACE("resolving %s on port %s", BUF_STR(hostname), BUF_STR(port));
-+      
-+      if (0 != (ret = getaddrinfo(BUF_STR(hostname), BUF_STR(port), &pref, &res))) {
-+              ERROR("getaddrinfo failed: %s", gai_strerror(ret));
-+
-+              buffer_free(hostname);
-+              buffer_free(port);
-+
-+              return -1;
-+      }
-+
-+      buffer_free(hostname);
-+      buffer_free(port);
-+
-+      for (cur = res; cur; cur = cur->ai_next) {
-+              proxy_address *a = proxy_address_init();
-+
-+              memcpy(&(a->addr), cur->ai_addr, cur->ai_addrlen);
-+
-+              a->state = PROXY_ADDRESS_STATE_ACTIVE;
-+              buffer_prepare_copy(a->name, 128);
-+
-+              switch (cur->ai_family) {
-+              case AF_INET6:
-+                      a->name->ptr[0] = '[';
-+                      inet_ntop(cur->ai_family, &(a->addr.ipv6.sin6_addr), a->name->ptr + 1, a->name->size - 2);
-+                      a->name->used = strlen(a->name->ptr) + 1;
-+                      buffer_append_string(a->name, "]:");
-+                      buffer_append_long(a->name, ntohs(a->addr.ipv6.sin6_port));
-+                      break;
-+              case AF_INET:
-+                      inet_ntop(cur->ai_family, &(a->addr.ipv4.sin_addr), a->name->ptr, a->name->size - 1);
-+                      a->name->used = strlen(a->name->ptr) + 1;
-+
-+                      buffer_append_string(a->name, ":");
-+                      buffer_append_long(a->name, ntohs(a->addr.ipv4.sin_port));
-+                      break;
-+              default:
-+                      ERROR("unknown address-family: %d", cur->ai_family);
-+                      return -1;
-+              }
-+
-+
-+              proxy_address_pool_add(address_pool, a);
-+      }
-+
-+      freeaddrinfo(res);
-+
-+      return 0;
-+}
-+
-+
---- ../lighttpd-1.4.11/src/mod_proxy_core_address.h    1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/mod_proxy_core_address.h        2006-07-18 13:03:40.000000000 +0300
-@@ -0,0 +1,33 @@
-+#ifndef _MOD_PROXY_CORE_ADDRESS_H_
-+#define _MOD_PROXY_CORE_ADDRESS_H_
-+
-+#include <time.h>
-+#include "buffer.h"
-+#include "sys-socket.h"
-+#include "array-static.h"
-+
-+typedef enum {
-+      PROXY_ADDRESS_STATE_UNSET,
-+      PROXY_ADDRESS_STATE_ACTIVE,
-+      PROXY_ADDRESS_STATE_DISABLED,
-+} proxy_address_state_t;
-+
-+typedef struct {
-+      sock_addr addr;
-+
-+      buffer *name; /* a inet_ntoa() prepresentation of the address */
-+
-+      time_t last_used;
-+      time_t disabled_until;
-+
-+      proxy_address_state_t state;
-+} proxy_address;
-+
-+ARRAY_STATIC_DEF(proxy_address_pool, proxy_address, );
-+
-+proxy_address_pool *proxy_address_pool_init(void); 
-+void proxy_address_pool_free(proxy_address_pool *address_pool); 
-+void proxy_address_pool_add(proxy_address_pool *address_pool, proxy_address *address);
-+int proxy_address_pool_add_string(proxy_address_pool *address_pool, buffer *address);
-+
-+#endif
---- ../lighttpd-1.4.11/src/mod_proxy_core_backend.c    1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/mod_proxy_core_backend.c        2006-07-20 00:57:19.000000000 +0300
-@@ -0,0 +1,47 @@
-+#include <stdlib.h>
-+
-+#include "mod_proxy_core_backend.h"
-+#include "mod_proxy_core_pool.h"
-+#include "mod_proxy_core_address.h"
-+
-+proxy_backend *proxy_backend_init(void) {
-+      proxy_backend *backend;
-+
-+      backend = calloc(1, sizeof(*backend));
-+      backend->pool = proxy_connection_pool_init();
-+      backend->address_pool = proxy_address_pool_init();
-+      backend->balancer = PROXY_BALANCE_RR;
-+
-+      return backend;
-+}
-+
-+void proxy_backend_free(proxy_backend *backend) {
-+      if (!backend) return;
-+
-+      proxy_address_pool_free(backend->address_pool);
-+      proxy_connection_pool_free(backend->pool);
-+      
-+      free(backend);
-+}
-+
-+proxy_backends *proxy_backends_init(void) {
-+      proxy_backends *backends;
-+
-+      backends = calloc(1, sizeof(*backends));
-+
-+      return backends;
-+}
-+
-+void proxy_backends_free(proxy_backends *backends) {
-+      FOREACH(backends, element, proxy_backend_free(element))
-+
-+      if (backends->ptr) free(backends->ptr);
-+
-+      free(backends);
-+}
-+
-+void proxy_backends_add(proxy_backends *backends, proxy_backend *backend) {
-+      ARRAY_STATIC_PREPARE_APPEND(backends);
-+
-+      backends->ptr[backends->used++] = backend;
-+}
---- ../lighttpd-1.4.11/src/mod_proxy_core_backend.h    1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/mod_proxy_core_backend.h        2006-09-07 00:57:05.000000000 +0300
-@@ -0,0 +1,63 @@
-+#ifndef _MOD_PROXY_CORE_BACKEND_H_
-+#define _MOD_PROXY_CORE_BACKEND_H_
-+
-+#include "array-static.h"
-+#include "buffer.h"
-+#include "mod_proxy_core_address.h"
-+#include "mod_proxy_core_pool.h"
-+#include "sys-socket.h"
-+
-+/**
-+ * a single DNS name might explode to several IP addresses 
-+ * 
-+ * url: 
-+ * - http://foo.bar/suburl/
-+ * - https://foo.bar/suburl/
-+ * - unix:/tmp/socket
-+ * - tcp://foobar:1025/
-+ *
-+ * backend:
-+ * - scgi
-+ * - http
-+ * - fastcgi
-+ *
-+ * request-url-rewrite
-+ * response-url-rewrite
-+ */ 
-+typedef enum {
-+      PROXY_BALANCE_UNSET,
-+      PROXY_BALANCE_FAIR,
-+      PROXY_BALANCE_HASH,
-+      PROXY_BALANCE_RR
-+} proxy_balance_t;
-+
-+typedef enum {
-+      PROXY_PROTOCOL_UNSET,
-+      PROXY_PROTOCOL_HTTP,
-+      PROXY_PROTOCOL_HTTPS,
-+      PROXY_PROTOCOL_FASTCGI,
-+      PROXY_PROTOCOL_SCGI
-+} proxy_protocol_t;
-+
-+typedef struct {
-+      buffer *url;
-+
-+      proxy_connection_pool *pool;  /* pool of active connections */
-+      int use_keepalive;
-+
-+      proxy_address_pool *address_pool; /* possible destination-addresses, disabling is done here */
-+      proxy_balance_t balancer; /* how to choose a address from the address-pool */
-+      proxy_protocol_t protocol; /* how to choose a address from the address-pool */
-+} proxy_backend;
-+
-+ARRAY_STATIC_DEF(proxy_backends, proxy_backend, );
-+
-+proxy_backend *proxy_backend_init(void);
-+void proxy_backend_free(proxy_backend *backend);
-+
-+proxy_backends *proxy_backends_init(void);
-+void proxy_backends_free(proxy_backends *backends);
-+void proxy_backends_add(proxy_backends *backends, proxy_backend *backend);
-+
-+#endif
-+
---- ../lighttpd-1.4.11/src/mod_proxy_core_backlog.c    1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/mod_proxy_core_backlog.c        2006-07-18 13:03:40.000000000 +0300
-@@ -0,0 +1,109 @@
-+#include <stdlib.h>
-+
-+#include "mod_proxy_core_backlog.h"
-+#include "array-static.h"
-+
-+proxy_backlog *proxy_backlog_init(void) {
-+      STRUCT_INIT(proxy_backlog, backlog);
-+
-+      return backlog;
-+}
-+
-+void proxy_backlog_free(proxy_backlog *backlog) {
-+      if (!backlog) return;
-+
-+      free(backlog);
-+}
-+
-+int proxy_backlog_push(proxy_backlog *backlog, proxy_request *req) {
-+      /* first entry */
-+      if (NULL == backlog->first) {
-+              backlog->first = backlog->last = req;
-+      } else {
-+              backlog->last->next = req;
-+              backlog->last = req;
-+      }
-+      backlog->length++;
-+
-+      return 0;
-+}
-+
-+/**
-+ * remove the first element from the backlog
-+ */
-+proxy_request *proxy_backlog_shift(proxy_backlog *backlog) {
-+      proxy_request *req = NULL;
-+
-+      if (!backlog->first) return req;
-+
-+      backlog->length--;
-+
-+      req = backlog->first;
-+
-+      backlog->first = req->next;
-+
-+      /* the backlog is empty */
-+      if (backlog->first == NULL) backlog->last = NULL;
-+
-+      return req;
-+}
-+
-+int proxy_backlog_remove_connection(proxy_backlog *backlog, void *con) {
-+      proxy_request *req = NULL;
-+
-+      if (!backlog->first) return -1;
-+      if (!con) return -1;
-+
-+      /* the first element is what we look for */
-+      if (backlog->first->con == con) {
-+              req = backlog->first;
-+              
-+              backlog->first = req->next;
-+              if (backlog->first == NULL) backlog->last = NULL;
-+
-+              backlog->length--;
-+              
-+              proxy_request_free(req);
-+
-+              return 0;
-+      }
-+
-+
-+      for (req = backlog->first; req && req->next; req = req->next) {
-+              proxy_request *cur;
-+
-+              if (req->next->con != con) continue;
-+
-+              backlog->length--;
-+              /* the next node is our searched connection */
-+
-+              cur = req->next;
-+              req->next = cur->next;
-+
-+              /* the next node is the last one, make the current the new last */
-+              if (cur == backlog->last) {
-+                      backlog->last = req;
-+              }
-+              cur->next = NULL;
-+
-+              proxy_request_free(req);
-+
-+              return 0;
-+      }
-+
-+      return -1;
-+}
-+
-+proxy_request *proxy_request_init(void) {
-+      STRUCT_INIT(proxy_request, request);
-+
-+      return request;
-+}
-+
-+void proxy_request_free(proxy_request *request) {
-+      if (!request) return;
-+
-+      free(request);
-+}
-+
-+
---- ../lighttpd-1.4.11/src/mod_proxy_core_backlog.h    1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/mod_proxy_core_backlog.h        2006-07-18 13:03:40.000000000 +0300
-@@ -0,0 +1,56 @@
-+#ifndef _MOD_PROXY_CORE_BACKLOG_H_
-+#define _MOD_PROXY_CORE_BACKLOG_H_
-+
-+#include <sys/types.h>
-+#include <sys/time.h>
-+
-+typedef struct _proxy_request {
-+      void *con; /* a pointer to the client-connection, (type: connection) */
-+
-+      time_t added_ts; /* when was the entry added (for timeout handling) */
-+
-+      struct _proxy_request *next;
-+} proxy_request;
-+
-+/**
-+ * a we can't get a connection from the pool, queue the request in the
-+ * request queue (FIFO)
-+ *
-+ * - the queue is infinite
-+ * - entries are removed after a timeout (status 504)
-+ */
-+typedef struct {
-+      proxy_request *first; /* pull() does q->first = q->first->next */
-+      proxy_request *last; /* push() does q->last = r */
-+
-+      size_t length;
-+} proxy_backlog;
-+
-+proxy_backlog *proxy_backlog_init(void);
-+void proxy_backlog_free(proxy_backlog *backlog);
-+
-+/**
-+ * append a request to the end
-+ * 
-+ * @return 0 in success, -1 if full
-+ */ 
-+int proxy_backlog_push(proxy_backlog *backlog, proxy_request *req);
-+
-+/**
-+ * remove the first request from the backlog
-+ *
-+ * @return NULL if backlog is empty, the request otherwise
-+ */
-+proxy_request *proxy_backlog_shift(proxy_backlog *backlog);
-+/**
-+ * remove the request with the connection 'con' from the backlog
-+ *
-+ * @return -1 if not found, 0 otherwise
-+ */
-+int proxy_backlog_remove_connection(proxy_backlog *backlog, void *con);
-+
-+proxy_request *proxy_request_init(void);
-+void proxy_request_free(proxy_request *req);
-+
-+#endif
-+
---- ../lighttpd-1.4.11/src/mod_proxy_core_pool.c       1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/mod_proxy_core_pool.c   2006-07-18 13:03:40.000000000 +0300
-@@ -0,0 +1,127 @@
-+
-+#include <stdlib.h>
-+
-+#include "array-static.h"
-+#include "sys-files.h"
-+#include "log.h"
-+#include "mod_proxy_core_pool.h"
-+
-+proxy_connection * proxy_connection_init(void) {
-+      proxy_connection *con;
-+
-+      con = calloc(1, sizeof(*con));
-+
-+      con->sock = iosocket_init();
-+
-+      return con;
-+}
-+
-+void proxy_connection_free(proxy_connection *con) {
-+      if (!con) return;
-+
-+      iosocket_free(con->sock);
-+
-+      free(con);
-+}
-+
-+proxy_connection_pool *proxy_connection_pool_init(void) {
-+      proxy_connection_pool *pool;
-+
-+      pool = calloc(1, sizeof(*pool));
-+
-+              /* default: max parallel connections to the backend
-+       * 
-+       * this should match max-procs if we manage the procs ourself
-+               */
-+
-+      pool->max_size = 8;
-+
-+      return pool;
-+}
-+
-+void proxy_connection_pool_free(proxy_connection_pool *pool) {
-+      size_t i;
-+
-+      if (!pool) return;
-+
-+      for (i = 0; i < pool->used; i++) {
-+              proxy_connection_free(pool->ptr[i]);
-+      }
-+
-+      if (pool->size) free(pool->ptr);
-+
-+      free(pool);
-+}
-+
-+void proxy_connection_pool_add_connection(proxy_connection_pool *pool, proxy_connection *c) {
-+      ARRAY_STATIC_PREPARE_APPEND(pool);
-+
-+      pool->ptr[pool->used++] = c;
-+}
-+/**
-+ * remove the connection from the pool
-+ *
-+ * usually called on conn-shutdown
-+ */
-+int proxy_connection_pool_remove_connection(proxy_connection_pool *pool, proxy_connection *c) {
-+      size_t i;
-+
-+      if (pool->used == 0) return -1; /* empty */
-+
-+      for (i = 0; i < pool->used; i++) {
-+              if (pool->ptr[i] == c) {
-+                      break;
-+              }
-+      }
-+
-+      if (i == pool->used) return -1; /* not found */
-+
-+      /**
-+       * move all elements one to the left
-+       *
-+       * if the last element is going to be removed, skip the loop
-+       */
-+      for (; i < pool->used - 1; i++) {
-+              pool->ptr[i] = pool->ptr[i + 1];
-+      }
-+
-+      pool->used--;
-+
-+      return 0;
-+}
-+
-+proxy_connection_pool_t proxy_connection_pool_get_connection(proxy_connection_pool *pool, proxy_address *address, proxy_connection **rcon) {
-+      proxy_connection *proxy_con = NULL;
-+      size_t i;
-+
-+      /* search for a idling proxy connection with the given address */
-+      for (i = 0; i < pool->used; i++) {
-+              proxy_con = pool->ptr[i];
-+
-+              if (proxy_con->address == address &&
-+                  proxy_con->state == PROXY_CONNECTION_STATE_IDLE) {
-+                      break;
-+              }
-+      }
-+
-+      if (i == pool->used) {
-+              /* no idling connection found */
-+
-+              if (pool->used == pool->max_size) return PROXY_CONNECTIONPOOL_FULL;
-+              
-+              proxy_con = proxy_connection_init();
-+
-+              proxy_con->state = PROXY_CONNECTION_STATE_CONNECTING;
-+              proxy_con->address = address;
-+
-+              proxy_connection_pool_add_connection(pool, proxy_con);
-+      } else {
-+              proxy_con->state = PROXY_CONNECTION_STATE_CONNECTED;
-+      }
-+
-+      *rcon = proxy_con;
-+
-+      return PROXY_CONNECTIONPOOL_GOT_CONNECTION;
-+}
-+
-+
---- ../lighttpd-1.4.11/src/mod_proxy_core_pool.h       1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/mod_proxy_core_pool.h   2006-07-18 13:03:40.000000000 +0300
-@@ -0,0 +1,52 @@
-+#ifndef _MOD_PROXY_CORE_POOL_H_
-+#define _MOD_PROXY_CORE_POOL_H_
-+
-+#include <sys/time.h>
-+
-+#include "iosocket.h"
-+#include "array-static.h"
-+#include "mod_proxy_core_address.h"
-+
-+typedef enum {
-+      PROXY_CONNECTION_STATE_UNSET,
-+      PROXY_CONNECTION_STATE_CONNECTING,
-+      PROXY_CONNECTION_STATE_CONNECTED,
-+      PROXY_CONNECTION_STATE_IDLE,
-+      PROXY_CONNECTION_STATE_CLOSED,
-+} proxy_connection_state_t;
-+
-+/**
-+ * a connection to a proxy backend
-+ * 
-+ * the connection is independent of the incoming request to allow keep-alive
-+ */
-+typedef struct { 
-+      iosocket *sock;
-+
-+      time_t last_read; /* timeout handling for keep-alive connections */
-+      time_t last_write;
-+
-+      proxy_address *address; /* the struct sock_addr for the sock */
-+
-+      proxy_connection_state_t state;
-+} proxy_connection;
-+
-+ARRAY_STATIC_DEF(proxy_connection_pool, proxy_connection, size_t max_size;);
-+
-+typedef enum {
-+      PROXY_CONNECTIONPOOL_UNSET,
-+      PROXY_CONNECTIONPOOL_FULL,
-+      PROXY_CONNECTIONPOOL_GOT_CONNECTION,
-+} proxy_connection_pool_t;
-+
-+proxy_connection_pool *proxy_connection_pool_init(void); 
-+void proxy_connection_pool_free(proxy_connection_pool *pool); 
-+
-+proxy_connection_pool_t proxy_connection_pool_get_connection(proxy_connection_pool *pool, proxy_address *address, proxy_connection **rcon);
-+int proxy_connection_pool_remove_connection(proxy_connection_pool *pool, proxy_connection *c);
-+
-+proxy_connection * proxy_connection_init(void);
-+void proxy_connection_free(proxy_connection *pool);
-+
-+#endif
-+
---- ../lighttpd-1.4.11/src/mod_proxy_core_rewrites.c   1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/mod_proxy_core_rewrites.c       2006-09-07 00:57:05.000000000 +0300
-@@ -0,0 +1,122 @@
-+#include <stdlib.h>
-+#include <string.h>
-+#include <ctype.h>
-+
-+#include "mod_proxy_core_rewrites.h"
-+#include "log.h"
-+
-+proxy_rewrite *proxy_rewrite_init(void) {
-+      STRUCT_INIT(proxy_rewrite, rewrite);
-+
-+      rewrite->header = buffer_init();
-+      rewrite->match = buffer_init();
-+      rewrite->replace = buffer_init();
-+
-+      return rewrite;
-+
-+}
-+void proxy_rewrite_free(proxy_rewrite *rewrite) {
-+      if (!rewrite) return;
-+
-+      if (rewrite->regex) pcre_free(rewrite->regex);
-+
-+      buffer_free(rewrite->header);
-+      buffer_free(rewrite->match);
-+      buffer_free(rewrite->replace);
-+
-+      free(rewrite);
-+}
-+
-+int proxy_rewrite_set_regex(proxy_rewrite *rewrite, buffer *regex) {
-+      const char *errptr;
-+      int erroff;
-+
-+      if (NULL == (rewrite->regex = pcre_compile(BUF_STR(regex),
-+                0, &errptr, &erroff, NULL))) {
-+              
-+              TRACE("regex compilation for %s failed at %s", BUF_STR(regex), errptr);
-+
-+              return -1;
-+      }
-+
-+      return 0;
-+}
-+
-+
-+proxy_rewrites *proxy_rewrites_init(void) {
-+      STRUCT_INIT(proxy_rewrites, rewrites);
-+
-+      return rewrites;
-+}
-+
-+void proxy_rewrites_add(proxy_rewrites *rewrites, proxy_rewrite *rewrite) {
-+      ARRAY_STATIC_PREPARE_APPEND(rewrites);
-+
-+      rewrites->ptr[rewrites->used++] = rewrite;
-+}
-+
-+void proxy_rewrites_free(proxy_rewrites *rewrites) {
-+      if (!rewrites) return;
-+
-+      FOREACH(rewrites, rewrite, proxy_rewrite_free(rewrite))
-+
-+      if (rewrites->ptr) free(rewrites->ptr);
-+
-+      free(rewrites);
-+}
-+
-+int pcre_replace(pcre *match, buffer *replace, buffer *match_buf, buffer *result) {
-+      const char *pattern = replace->ptr;
-+      size_t pattern_len = replace->used - 1;
-+
-+# define N 10
-+      int ovec[N * 3];
-+      int n;
-+
-+      if ((n = pcre_exec(match, NULL, match_buf->ptr, match_buf->used - 1, 0, 0, ovec, 3 * N)) < 0) {
-+              if (n != PCRE_ERROR_NOMATCH) {
-+                      return n;
-+              }
-+      } else {
-+              const char **list;
-+              size_t start, end;
-+              size_t k;
-+
-+              /* it matched */
-+              pcre_get_substring_list(match_buf->ptr, ovec, n, &list);
-+
-+              /* search for $[0-9] */
-+
-+              buffer_reset(result);
-+
-+              start = 0; end = pattern_len;
-+              for (k = 0; k < pattern_len; k++) {
-+                      if ((pattern[k] == '$') &&
-+                          isdigit((unsigned char)pattern[k + 1])) {
-+                              /* got one */
-+
-+                              size_t num = pattern[k + 1] - '0';
-+
-+                              end = k;
-+
-+                              buffer_append_string_len(result, pattern + start, end - start);
-+
-+                              /* n is always > 0 */
-+                              if (num < (size_t)n) {
-+                                      buffer_append_string(result, list[num]);
-+                              }
-+
-+                              k++;
-+                              start = k + 1;
-+                      }
-+              }
-+
-+              buffer_append_string_len(result, pattern + start, pattern_len - start);
-+
-+              pcre_free(list);
-+      }
-+
-+      return n;
-+}
-+
-+
---- ../lighttpd-1.4.11/src/mod_proxy_core_rewrites.h   1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/mod_proxy_core_rewrites.h       2006-09-07 00:57:05.000000000 +0300
-@@ -0,0 +1,30 @@
-+#ifndef _MOD_PROXY_CORE_REWRITES_H_
-+#define _MOD_PROXY_CORE_REWRITES_H_
-+
-+#include <pcre.h>
-+#include "array-static.h"
-+#include "buffer.h"
-+
-+typedef struct {
-+      buffer *header;
-+
-+      pcre *regex; /* regex compiled from the <match> */
-+
-+      buffer *match;
-+      buffer *replace;
-+} proxy_rewrite;
-+
-+ARRAY_STATIC_DEF(proxy_rewrites, proxy_rewrite,);
-+
-+proxy_rewrite *proxy_rewrite_init(void);
-+void proxy_rewrite_free(proxy_rewrite *rewrite);
-+int proxy_rewrite_set_regex(proxy_rewrite *rewrite, buffer *regex);
-+
-+proxy_rewrites *proxy_rewrites_init(void);
-+void proxy_rewrites_add(proxy_rewrites *rewrites, proxy_rewrite *rewrite);
-+void proxy_rewrites_free(proxy_rewrites *rewrites);
-+
-+int pcre_replace(pcre *match, buffer *replace, buffer *match_buf, buffer *result);
-+
-+#endif
-+
---- ../lighttpd-1.4.11/src/mod_redirect.c      2006-02-08 15:38:06.000000000 +0200
-+++ lighttpd-1.5.0/src/mod_redirect.c  2006-09-07 00:57:05.000000000 +0300
-@@ -22,35 +22,35 @@
-       PLUGIN_DATA;
-       buffer *match_buf;
-       buffer *location;
--      
-+
-       plugin_config **config_storage;
--      
--      plugin_config conf; 
-+
-+      plugin_config conf;
- } plugin_data;
- INIT_FUNC(mod_redirect_init) {
-       plugin_data *p;
--      
-+
-       p = calloc(1, sizeof(*p));
--      
-+
-       p->match_buf = buffer_init();
-       p->location = buffer_init();
--      
-+
-       return p;
- }
- FREE_FUNC(mod_redirect_free) {
-       plugin_data *p = p_d;
--      
-+
-       if (!p) return HANDLER_GO_ON;
-       if (p->config_storage) {
-               size_t i;
-               for (i = 0; i < srv->config_context->used; i++) {
-                       plugin_config *s = p->config_storage[i];
--                      
-+
-                       pcre_keyvalue_buffer_free(s->redirect);
--                      
-+
-                       free(s);
-               }
-               free(p->config_storage);
-@@ -59,9 +59,9 @@
-       buffer_free(p->match_buf);
-       buffer_free(p->location);
--      
-+
-       free(p);
--      
-+
-       return HANDLER_GO_ON;
- }
-@@ -69,195 +69,137 @@
-       plugin_data *p = p_d;
-       data_unset *du;
-       size_t i = 0;
--      
--      config_values_t cv[] = { 
-+
-+      config_values_t cv[] = {
-               { "url.redirect",               NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
-               { NULL,                         NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
-       };
--      
-+
-       if (!p) return HANDLER_ERROR;
--      
-+
-       /* 0 */
-       p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
--      
-+
-       for (i = 0; i < srv->config_context->used; i++) {
-               plugin_config *s;
-               size_t j;
-               array *ca;
-               data_array *da = (data_array *)du;
--              
-+
-               s = calloc(1, sizeof(plugin_config));
-               s->redirect   = pcre_keyvalue_buffer_init();
--              
-+
-               cv[0].destination = s->redirect;
--              
-+
-               p->config_storage[i] = s;
-               ca = ((data_config *)srv->config_context->data[i])->value;
--      
-+
-               if (0 != config_insert_values_global(srv, ca, cv)) {
-                       return HANDLER_ERROR;
-               }
--              
-+
-               if (NULL == (du = array_get_element(ca, "url.redirect"))) {
-                       /* no url.redirect defined */
-                       continue;
-               }
--              
-+
-               if (du->type != TYPE_ARRAY) {
--                      log_error_write(srv, __FILE__, __LINE__, "sss", 
-+                      log_error_write(srv, __FILE__, __LINE__, "sss",
-                                       "unexpected type for key: ", "url.redirect", "array of strings");
--                      
-+
-                       return HANDLER_ERROR;
-               }
--              
-+
-               da = (data_array *)du;
--                              
-+
-               for (j = 0; j < da->value->used; j++) {
-                       if (da->value->data[j]->type != TYPE_STRING) {
--                              log_error_write(srv, __FILE__, __LINE__, "sssbs", 
--                                              "unexpected type for key: ", 
--                                              "url.redirect", 
-+                              log_error_write(srv, __FILE__, __LINE__, "sssbs",
-+                                              "unexpected type for key: ",
-+                                              "url.redirect",
-                                               "[", da->value->data[j]->key, "](string)");
--                              
-+
-                               return HANDLER_ERROR;
-                       }
--                              
--                      if (0 != pcre_keyvalue_buffer_append(s->redirect, 
-+
-+                      if (0 != pcre_keyvalue_buffer_append(s->redirect,
-                                                            ((data_string *)(da->value->data[j]))->key->ptr,
-                                                            ((data_string *)(da->value->data[j]))->value->ptr)) {
--                                      
--                              log_error_write(srv, __FILE__, __LINE__, "sb", 
-+
-+                              log_error_write(srv, __FILE__, __LINE__, "sb",
-                                               "pcre-compile failed for", da->value->data[j]->key);
-                       }
-               }
-       }
--      
-+
-       return HANDLER_GO_ON;
- }
- #ifdef HAVE_PCRE_H
- static int mod_redirect_patch_connection(server *srv, connection *con, plugin_data *p) {
-       size_t i, j;
-       plugin_config *s = p->config_storage[0];
--      
-+
-       p->conf.redirect = s->redirect;
--      
-+
-       /* skip the first, the global context */
-       for (i = 1; i < srv->config_context->used; i++) {
-               data_config *dc = (data_config *)srv->config_context->data[i];
-               s = p->config_storage[i];
--              
-+
-               /* condition didn't match */
-               if (!config_check_cond(srv, con, dc)) continue;
--              
-+
-               /* merge config */
-               for (j = 0; j < dc->value->used; j++) {
-                       data_unset *du = dc->value->data[j];
--                      
-+
-                       if (0 == strcmp(du->key->ptr, "url.redirect")) {
-                               p->conf.redirect = s->redirect;
-                               p->conf.context = dc;
-                       }
-               }
-       }
--      
-+
-       return 0;
- }
- #endif
- static handler_t mod_redirect_uri_handler(server *srv, connection *con, void *p_data) {
- #ifdef HAVE_PCRE_H
-       plugin_data *p = p_data;
--      size_t i;
-+      int i;
--      /* 
-+      /*
-        * REWRITE URL
--       * 
-+       *
-        * e.g. redirect /base/ to /index.php?section=base
--       * 
-+       *
-        */
--      
-+
-       mod_redirect_patch_connection(srv, con, p);
--      
-+
-       buffer_copy_string_buffer(p->match_buf, con->request.uri);
--      
--      for (i = 0; i < p->conf.redirect->used; i++) {
--              pcre *match;
--              pcre_extra *extra;
--              const char *pattern;
--              size_t pattern_len;
--              int n;
--              pcre_keyvalue *kv = p->conf.redirect->kv[i];
--# define N 10
--              int ovec[N * 3];
--              
--              match       = kv->key;
--              extra       = kv->key_extra;
--              pattern     = kv->value->ptr;
--              pattern_len = kv->value->used - 1;
--              
--              if ((n = pcre_exec(match, extra, p->match_buf->ptr, p->match_buf->used - 1, 0, 0, ovec, 3 * N)) < 0) {
--                      if (n != PCRE_ERROR_NOMATCH) {
--                              log_error_write(srv, __FILE__, __LINE__, "sd",
--                                              "execution error while matching: ", n);
--                              return HANDLER_ERROR;
--                      }
--              } else {
--                      const char **list;
--                      size_t start, end;
--                      size_t k;
--                      
--                      /* it matched */
--                      pcre_get_substring_list(p->match_buf->ptr, ovec, n, &list);
--                      
--                      /* search for $[0-9] */
--                      
--                      buffer_reset(p->location);
--                      
--                      start = 0; end = pattern_len;
--                      for (k = 0; k < pattern_len; k++) {
--                              if ((pattern[k] == '$' || pattern[k] == '%') &&
--                                  isdigit((unsigned char)pattern[k + 1])) {
--                                      /* got one */
--                                      
--                                      size_t num = pattern[k + 1] - '0';
--                                      
--                                      end = k;
--                                      
--                                      buffer_append_string_len(p->location, pattern + start, end - start);
--                                      
--                                      if (pattern[k] == '$') {
--                                              /* n is always > 0 */
--                                              if (num < (size_t)n) {
--                                                      buffer_append_string(p->location, list[num]);
--                                              }
--                                      } else {
--                                              config_append_cond_match_buffer(con, p->conf.context, p->location, num);
--                                      }
--                                      
--                                      k++;
--                                      start = k + 1;
--                              } 
--                      }
--                      
--                      buffer_append_string_len(p->location, pattern + start, pattern_len - start);
--                      
--                      pcre_free(list);
--                      
--                      response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(p->location));
--                      
--                      con->http_status = 301;
--                      con->file_finished = 1;
--                      
--                      return HANDLER_FINISHED;
--              }
-+      i = config_exec_pcre_keyvalue_buffer(con, p->conf.redirect, p->conf.context, p->match_buf, p->location);
-+
-+      if (i >= 0) {
-+              response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(p->location));
-+
-+              con->http_status = 301;
-+              con->send->is_closed = 1;
-+
-+              return HANDLER_FINISHED;
-+      }
-+      else if (i != PCRE_ERROR_NOMATCH) {
-+              log_error_write(srv, __FILE__, __LINE__, "s",
-+                              "execution error while matching", i);
-       }
- #undef N
--              
-+
- #else
-       UNUSED(srv);
-       UNUSED(con);
-       UNUSED(p_data);
- #endif
--      
-+
-       return HANDLER_GO_ON;
- }
-@@ -265,13 +207,13 @@
- int mod_redirect_plugin_init(plugin *p) {
-       p->version     = LIGHTTPD_VERSION_ID;
-       p->name        = buffer_init_string("redirect");
--      
-+
-       p->init        = mod_redirect_init;
-       p->handle_uri_clean  = mod_redirect_uri_handler;
-       p->set_defaults  = mod_redirect_set_defaults;
-       p->cleanup     = mod_redirect_free;
--      
-+
-       p->data        = NULL;
--      
-+
-       return 0;
- }
---- ../lighttpd-1.4.11/src/mod_rewrite.c       2005-09-29 20:59:10.000000000 +0300
-+++ lighttpd-1.5.0/src/mod_rewrite.c   2006-07-16 00:26:03.000000000 +0300
-@@ -13,24 +13,8 @@
- #endif
- typedef struct {
--#ifdef HAVE_PCRE_H
--      pcre *key;
--#endif
--      
--      buffer *value;
--      
--      int once;
--} rewrite_rule;
--
--typedef struct {
--      rewrite_rule **ptr;
--      
--      size_t used;
--      size_t size;
--} rewrite_rule_buffer;
--
--typedef struct {
--      rewrite_rule_buffer *rewrite;
-+      pcre_keyvalue_buffer *rewrite;
-+      buffer *once;
-       data_config *context; /* to which apply me */
- } plugin_config;
-@@ -42,20 +26,20 @@
- typedef struct {
-       PLUGIN_DATA;
-       buffer *match_buf;
--      
-+
-       plugin_config **config_storage;
--      
--      plugin_config conf; 
-+
-+      plugin_config conf;
- } plugin_data;
- static handler_ctx * handler_ctx_init() {
-       handler_ctx * hctx;
--      
-+
-       hctx = calloc(1, sizeof(*hctx));
--      
-+
-       hctx->state = REWRITE_STATE_UNSET;
-       hctx->loops = 0;
--      
-+
-       return hctx;
- }
-@@ -63,207 +47,136 @@
-       free(hctx);
- }
--rewrite_rule_buffer *rewrite_rule_buffer_init(void) {
--      rewrite_rule_buffer *kvb;
--      
--      kvb = calloc(1, sizeof(*kvb));
--      
--      return kvb;
--}
--
--int rewrite_rule_buffer_append(rewrite_rule_buffer *kvb, buffer *key, buffer *value, int once) {
--#ifdef HAVE_PCRE_H
--      size_t i;
--      const char *errptr;
--      int erroff;
--      
--      if (!key) return -1;
--
--      if (kvb->size == 0) {
--              kvb->size = 4;
--              kvb->used = 0;
--              
--              kvb->ptr = malloc(kvb->size * sizeof(*kvb->ptr));
--              
--              for(i = 0; i < kvb->size; i++) {
--                      kvb->ptr[i] = calloc(1, sizeof(**kvb->ptr));
--              }
--      } else if (kvb->used == kvb->size) {
--              kvb->size += 4;
--              
--              kvb->ptr = realloc(kvb->ptr, kvb->size * sizeof(*kvb->ptr));
--              
--              for(i = kvb->used; i < kvb->size; i++) {
--                      kvb->ptr[i] = calloc(1, sizeof(**kvb->ptr));
--              }
--      }
--      
--      if (NULL == (kvb->ptr[kvb->used]->key = pcre_compile(key->ptr,
--                                                          0, &errptr, &erroff, NULL))) {
--              
--              return -1;
--      }
--      
--      kvb->ptr[kvb->used]->value = buffer_init();
--      buffer_copy_string_buffer(kvb->ptr[kvb->used]->value, value);
--      kvb->ptr[kvb->used]->once = once;
--      
--      kvb->used++;
--      
--      return 0;
--#else
--      UNUSED(kvb);
--      UNUSED(value);
--      UNUSED(once);
--      UNUSED(key);
--
--      return -1;
--#endif
--}
--
--void rewrite_rule_buffer_free(rewrite_rule_buffer *kvb) {
--#ifdef HAVE_PCRE_H
--      size_t i;
--
--      for (i = 0; i < kvb->size; i++) {
--              if (kvb->ptr[i]->key) pcre_free(kvb->ptr[i]->key);
--              if (kvb->ptr[i]->value) buffer_free(kvb->ptr[i]->value);
--              free(kvb->ptr[i]);
--      }
--      
--      if (kvb->ptr) free(kvb->ptr);
--#endif
--      
--      free(kvb);
--}
--
- INIT_FUNC(mod_rewrite_init) {
-       plugin_data *p;
--      
-+
-       p = calloc(1, sizeof(*p));
--      
-+
-       p->match_buf = buffer_init();
--      
-+
-       return p;
- }
- FREE_FUNC(mod_rewrite_free) {
-       plugin_data *p = p_d;
--      
-+
-       UNUSED(srv);
-       if (!p) return HANDLER_GO_ON;
--      
-+
-       buffer_free(p->match_buf);
-       if (p->config_storage) {
-               size_t i;
-               for (i = 0; i < srv->config_context->used; i++) {
-                       plugin_config *s = p->config_storage[i];
--                      rewrite_rule_buffer_free(s->rewrite);
--                      
-+                      pcre_keyvalue_buffer_free(s->rewrite);
-+                      buffer_free(s->once);
-+
-                       free(s);
-               }
-               free(p->config_storage);
-       }
--      
-+
-       free(p);
--      
-+
-       return HANDLER_GO_ON;
- }
- static int parse_config_entry(server *srv, plugin_config *s, array *ca, const char *option, int once) {
-       data_unset *du;
--      
-+
-       if (NULL != (du = array_get_element(ca, option))) {
-               data_array *da = (data_array *)du;
-               size_t j;
--              
-+
-               if (du->type != TYPE_ARRAY) {
--                      log_error_write(srv, __FILE__, __LINE__, "sss", 
-+                      log_error_write(srv, __FILE__, __LINE__, "sss",
-                                       "unexpected type for key: ", option, "array of strings");
--                      
-+
-                       return HANDLER_ERROR;
-               }
--              
-+
-               da = (data_array *)du;
--              
-+
-               for (j = 0; j < da->value->used; j++) {
-                       if (da->value->data[j]->type != TYPE_STRING) {
--                              log_error_write(srv, __FILE__, __LINE__, "sssbs", 
--                                              "unexpected type for key: ", 
--                                              option, 
-+                              log_error_write(srv, __FILE__, __LINE__, "sssbs",
-+                                              "unexpected type for key: ",
-+                                              option,
-                                               "[", da->value->data[j]->key, "](string)");
--                              
-+
-                               return HANDLER_ERROR;
-                       }
--                      
--                      if (0 != rewrite_rule_buffer_append(s->rewrite, 
--                                                          ((data_string *)(da->value->data[j]))->key,
--                                                          ((data_string *)(da->value->data[j]))->value,
--                                                          once)) {
-+
-+                      if (0 != pcre_keyvalue_buffer_append(s->rewrite,
-+                                                          ((data_string *)(da->value->data[j]))->key->ptr,
-+                                                          ((data_string *)(da->value->data[j]))->value->ptr)) {
- #ifdef HAVE_PCRE_H
--                              log_error_write(srv, __FILE__, __LINE__, "sb", 
-+                              log_error_write(srv, __FILE__, __LINE__, "sb",
-                                               "pcre-compile failed for", da->value->data[j]->key);
- #else
--                              log_error_write(srv, __FILE__, __LINE__, "s", 
-+                              log_error_write(srv, __FILE__, __LINE__, "s",
-                                               "pcre support is missing, please install libpcre and the headers");
- #endif
-                       }
-+
-+                      if (once) {
-+                              buffer_append_string_len(s->once, CONST_STR_LEN("1"));
-+                      } else {
-+                              buffer_append_string_len(s->once, CONST_STR_LEN("0"));
-+                      }
-               }
-       }
--      
-+
-       return 0;
- }
- SETDEFAULTS_FUNC(mod_rewrite_set_defaults) {
-       plugin_data *p = p_d;
-       size_t i = 0;
--      
--      config_values_t cv[] = { 
-+
-+      config_values_t cv[] = {
-               { "url.rewrite-repeat",        NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
-               { "url.rewrite-once",          NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
--              
--              /* old names, still supported 
--               * 
-+
-+              /* old names, still supported
-+               *
-                * url.rewrite remapped to url.rewrite-once
-                * url.rewrite-final    is url.rewrite-once
--               * 
-+               *
-                */
-               { "url.rewrite",               NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 2 */
-               { "url.rewrite-final",         NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 3 */
-               { NULL,                        NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
-       };
--      
-+
-       if (!p) return HANDLER_ERROR;
--      
-+
-       /* 0 */
-       p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
--      
-+
-       for (i = 0; i < srv->config_context->used; i++) {
-               plugin_config *s;
-               array *ca;
--              
-+
-               s = calloc(1, sizeof(plugin_config));
--              s->rewrite   = rewrite_rule_buffer_init();
--              
--              cv[0].destination = s->rewrite;
--              cv[1].destination = s->rewrite;
--              cv[2].destination = s->rewrite;
--              
-+              s->rewrite   = pcre_keyvalue_buffer_init();
-+              s->once      = buffer_init();
-+
-               p->config_storage[i] = s;
-               ca = ((data_config *)srv->config_context->data[i])->value;
--      
-+
-               if (0 != config_insert_values_global(srv, ca, cv)) {
-                       return HANDLER_ERROR;
-               }
--              
-+
-               parse_config_entry(srv, s, ca, "url.rewrite-once",   1);
-               parse_config_entry(srv, s, ca, "url.rewrite-final",  1);
-               parse_config_entry(srv, s, ca, "url.rewrite",        1);
-               parse_config_entry(srv, s, ca, "url.rewrite-repeat", 0);
-       }
--      
-+
-       return HANDLER_GO_ON;
- }
- #ifdef HAVE_PCRE_H
-@@ -271,157 +184,107 @@
-       size_t i, j;
-       plugin_config *s = p->config_storage[0];
-       p->conf.rewrite = s->rewrite;
--      
-+      p->conf.once    = s->once;
-+
-       /* skip the first, the global context */
-       for (i = 1; i < srv->config_context->used; i++) {
-               data_config *dc = (data_config *)srv->config_context->data[i];
-               s = p->config_storage[i];
--              
-+
-               if (COMP_HTTP_URL == dc->comp) continue;
--              
-+
-               /* condition didn't match */
-               if (!config_check_cond(srv, con, dc)) continue;
--              
-+
-               /* merge config */
-               for (j = 0; j < dc->value->used; j++) {
-                       data_unset *du = dc->value->data[j];
--                      
-+
-                       if (buffer_is_equal_string(du->key, CONST_STR_LEN("url.rewrite"))) {
-                               p->conf.rewrite = s->rewrite;
-+                              p->conf.once    = s->once;
-                               p->conf.context = dc;
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("url.rewrite-once"))) {
-                               p->conf.rewrite = s->rewrite;
-+                              p->conf.once    = s->once;
-                               p->conf.context = dc;
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("url.rewrite-repeat"))) {
-                               p->conf.rewrite = s->rewrite;
-+                              p->conf.once    = s->once;
-                               p->conf.context = dc;
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("url.rewrite-final"))) {
-                               p->conf.rewrite = s->rewrite;
-+                              p->conf.once    = s->once;
-                               p->conf.context = dc;
-                       }
-               }
-       }
--      
-+
-       return 0;
- }
- #endif
- URIHANDLER_FUNC(mod_rewrite_con_reset) {
-       plugin_data *p = p_d;
--      
-+
-       UNUSED(srv);
--      
-+
-       if (con->plugin_ctx[p->id]) {
-               handler_ctx_free(con->plugin_ctx[p->id]);
-               con->plugin_ctx[p->id] = NULL;
-       }
--      
-+
-       return HANDLER_GO_ON;
- }
- URIHANDLER_FUNC(mod_rewrite_uri_handler) {
- #ifdef HAVE_PCRE_H
-       plugin_data *p = p_d;
--      size_t i;
-+      int i;
-       handler_ctx *hctx;
--      /* 
-+      /*
-        * REWRITE URL
--       * 
-+       *
-        * e.g. rewrite /base/ to /index.php?section=base
--       * 
-+       *
-        */
--      
-+
-       if (con->plugin_ctx[p->id]) {
-               hctx = con->plugin_ctx[p->id];
--              
-+
-               if (hctx->loops++ > 100) {
--                      log_error_write(srv, __FILE__, __LINE__,  "s",  
-+                      log_error_write(srv, __FILE__, __LINE__,  "s",
-                                       "ENDLESS LOOP IN rewrite-rule DETECTED ... aborting request, perhaps you want to use url.rewrite-once instead of url.rewrite-repeat");
--                      
-+
-                       return HANDLER_ERROR;
-               }
--              
-+
-               if (hctx->state == REWRITE_STATE_FINISHED) return HANDLER_GO_ON;
-       }
--      
-+
-       mod_rewrite_patch_connection(srv, con, p);
-       if (!p->conf.rewrite) return HANDLER_GO_ON;
--      
-+
-       buffer_copy_string_buffer(p->match_buf, con->request.uri);
--      
--      for (i = 0; i < p->conf.rewrite->used; i++) {
--              pcre *match;
--              const char *pattern;
--              size_t pattern_len;
--              int n;
--              rewrite_rule *rule = p->conf.rewrite->ptr[i];
--# define N 10
--              int ovec[N * 3];
--              
--              match       = rule->key;
--              pattern     = rule->value->ptr;
--              pattern_len = rule->value->used - 1;
--              
--              if ((n = pcre_exec(match, NULL, p->match_buf->ptr, p->match_buf->used - 1, 0, 0, ovec, 3 * N)) < 0) {
--                      if (n != PCRE_ERROR_NOMATCH) {
--                              log_error_write(srv, __FILE__, __LINE__, "sd",
--                                              "execution error while matching: ", n);
--                              return HANDLER_ERROR;
--                      }
--              } else {
--                      const char **list;
--                      size_t start, end;
--                      size_t k;
--                      
--                      /* it matched */
--                      pcre_get_substring_list(p->match_buf->ptr, ovec, n, &list);
--                      
--                      /* search for $[0-9] */
--                      
--                      buffer_reset(con->request.uri);
--                      
--                      start = 0; end = pattern_len;
--                      for (k = 0; k < pattern_len; k++) {
--                              if ((pattern[k] == '$' || pattern[k] == '%') &&
--                                  isdigit((unsigned char)pattern[k + 1])) {
--                                      /* got one */
--                                      
--                                      size_t num = pattern[k + 1] - '0';
--                                      
--                                      end = k;
--                                      
--                                      buffer_append_string_len(con->request.uri, pattern + start, end - start);
--                                      
--                                      if (pattern[k] == '$') {
--                                              /* n is always > 0 */
--                                              if (num < (size_t)n) {
--                                                      buffer_append_string(con->request.uri, list[num]);
--                                              }
--                                      } else {
--                                              config_append_cond_match_buffer(con, p->conf.context, con->request.uri, num);
--                                      }
--                                      
--                                      k++;
--                                      start = k + 1;
--                              } 
--                      }
--                      
--                      buffer_append_string_len(con->request.uri, pattern + start, pattern_len - start);
--                      
--                      pcre_free(list);
--                      
--                      hctx = handler_ctx_init();
--                              
--                      con->plugin_ctx[p->id] = hctx;
--                      
--                      if (rule->once) hctx->state = REWRITE_STATE_FINISHED;
--                      
--                      return HANDLER_COMEBACK;
--              }
-+      i = config_exec_pcre_keyvalue_buffer(con, p->conf.rewrite, p->conf.context, p->match_buf, con->request.uri);
-+
-+      if (i >= 0) {
-+              hctx = handler_ctx_init();
-+
-+              con->plugin_ctx[p->id] = hctx;
-+
-+              if (p->conf.once->ptr[i] == '1')
-+                      hctx->state = REWRITE_STATE_FINISHED;
-+
-+              return HANDLER_COMEBACK;
-+      }
-+      else if (i != PCRE_ERROR_NOMATCH) {
-+              log_error_write(srv, __FILE__, __LINE__, "s",
-+                              "execution error while matching", i);
-       }
- #undef N
--              
-+
- #else
-       UNUSED(srv);
-       UNUSED(con);
-@@ -434,17 +297,17 @@
- int mod_rewrite_plugin_init(plugin *p) {
-       p->version     = LIGHTTPD_VERSION_ID;
-       p->name        = buffer_init_string("rewrite");
--      
-+
-       p->init        = mod_rewrite_init;
-       /* it has to stay _raw as we are matching on uri + querystring
-        */
--      
-+
-       p->handle_uri_raw = mod_rewrite_uri_handler;
-       p->set_defaults = mod_rewrite_set_defaults;
-       p->cleanup     = mod_rewrite_free;
-       p->connection_reset = mod_rewrite_con_reset;
--      
-+
-       p->data        = NULL;
--      
-+
-       return 0;
- }
---- ../lighttpd-1.4.11/src/mod_rrdtool.c       2005-08-22 01:52:24.000000000 +0300
-+++ lighttpd-1.5.0/src/mod_rrdtool.c   2006-09-07 00:57:05.000000000 +0300
-@@ -5,7 +5,6 @@
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
--#include <unistd.h>
- #include <errno.h>
- #include <time.h>
-@@ -20,10 +19,14 @@
- /* no need for waitpid if we don't have fork */
- #include <sys/wait.h>
- #endif
-+
-+#include "sys-files.h"
-+#include "sys-process.h"
-+
- typedef struct {
-       buffer *path_rrdtool_bin;
-       buffer *path_rrd;
--      
-+
-       double requests, *requests_ptr;
-       double bytes_written, *bytes_written_ptr;
-       double bytes_read, *bytes_read_ptr;
-@@ -31,84 +34,84 @@
- typedef struct {
-       PLUGIN_DATA;
--      
-+
-       buffer *cmd;
-       buffer *resp;
--      
-+
-       int read_fd, write_fd;
-       pid_t rrdtool_pid;
--      
-+
-       int rrdtool_running;
--      
-+
-       plugin_config **config_storage;
-       plugin_config conf;
- } plugin_data;
- INIT_FUNC(mod_rrd_init) {
-       plugin_data *p;
--      
-+
-       p = calloc(1, sizeof(*p));
--      
-+
-       p->resp = buffer_init();
-       p->cmd = buffer_init();
--      
-+
-       return p;
- }
- FREE_FUNC(mod_rrd_free) {
-       plugin_data *p = p_d;
-       size_t i;
--      
-+
-       if (!p) return HANDLER_GO_ON;
--      
-+
-       if (p->config_storage) {
-               for (i = 0; i < srv->config_context->used; i++) {
-                       plugin_config *s = p->config_storage[i];
--                      
-+
-                       buffer_free(s->path_rrdtool_bin);
-                       buffer_free(s->path_rrd);
--                      
-+
-                       free(s);
-               }
-       }
-       buffer_free(p->cmd);
-       buffer_free(p->resp);
--      
-+
-       free(p->config_storage);
--      
-+
-       if (p->rrdtool_pid) {
-               int status;
-               close(p->read_fd);
-               close(p->write_fd);
--#ifdef HAVE_FORK      
-+#ifdef HAVE_FORK
-               /* collect status */
-               waitpid(p->rrdtool_pid, &status, 0);
- #endif
-       }
--      
-+
-       free(p);
--      
-+
-       return HANDLER_GO_ON;
- }
- int mod_rrd_create_pipe(server *srv, plugin_data *p) {
-       pid_t pid;
--      
-+
-       int to_rrdtool_fds[2];
-       int from_rrdtool_fds[2];
--#ifdef HAVE_FORK      
-+#ifdef HAVE_FORK
-       if (pipe(to_rrdtool_fds)) {
--              log_error_write(srv, __FILE__, __LINE__, "ss", 
-+              log_error_write(srv, __FILE__, __LINE__, "ss",
-                               "pipe failed: ", strerror(errno));
-               return -1;
-       }
--      
-+
-       if (pipe(from_rrdtool_fds)) {
--              log_error_write(srv, __FILE__, __LINE__, "ss", 
-+              log_error_write(srv, __FILE__, __LINE__, "ss",
-                               "pipe failed: ", strerror(errno));
-               return -1;
-       }
--      
-+
-       /* fork, execve */
-       switch (pid = fork()) {
-       case 0: {
-@@ -117,33 +120,28 @@
-               int argc;
-               int i = 0;
-               char *dash = "-";
--              
-+
-               /* move stdout to from_rrdtool_fd[1] */
-               close(STDOUT_FILENO);
-               dup2(from_rrdtool_fds[1], STDOUT_FILENO);
-               close(from_rrdtool_fds[1]);
-               /* not needed */
-               close(from_rrdtool_fds[0]);
--              
-+
-               /* move the stdin to to_rrdtool_fd[0] */
-               close(STDIN_FILENO);
-               dup2(to_rrdtool_fds[0], STDIN_FILENO);
-               close(to_rrdtool_fds[0]);
-               /* not needed */
-               close(to_rrdtool_fds[1]);
--              
-+
-               close(STDERR_FILENO);
--              
--              if (srv->errorlog_mode == ERRORLOG_FILE) {
--                      dup2(srv->errorlog_fd, STDERR_FILENO);
--                      close(srv->errorlog_fd);
--              }
--              
-+
-               /* set up args */
-               argc = 3;
-               args = malloc(sizeof(*args) * argc);
-               i = 0;
--              
-+
-               args[i++] = p->conf.path_rrdtool_bin->ptr;
-               args[i++] = dash;
-               args[i++] = NULL;
-@@ -152,12 +150,12 @@
-               for (i = 3; i < 256; i++) {
-                       close(i);
-               }
--              
-+
-               /* exec the cgi */
-               execv(args[0], args);
--              
-+
-               log_error_write(srv, __FILE__, __LINE__, "sss", "spawing rrdtool failed: ", strerror(errno), args[0]);
--              
-+
-               /* */
-               SEGFAULT();
-               break;
-@@ -168,19 +166,19 @@
-               break;
-       default: {
-               /* father */
--              
-+
-               close(from_rrdtool_fds[1]);
-               close(to_rrdtool_fds[0]);
--              
-+
-               /* register PID and wait for them asyncronously */
-               p->write_fd = to_rrdtool_fds[1];
-               p->read_fd = from_rrdtool_fds[0];
-               p->rrdtool_pid = pid;
--              
-+
-               break;
-       }
-       }
--      
-+
-       return 0;
- #else
-       return -1;
-@@ -189,19 +187,19 @@
- static int mod_rrdtool_create_rrd(server *srv, plugin_data *p, plugin_config *s) {
-       struct stat st;
--      
-+
-       /* check if DB already exists */
-       if (0 == stat(s->path_rrd->ptr, &st)) {
-               /* check if it is plain file */
-               if (!S_ISREG(st.st_mode)) {
--                      log_error_write(srv, __FILE__, __LINE__, "sb", 
-+                      log_error_write(srv, __FILE__, __LINE__, "sb",
-                                       "not a regular file:", s->path_rrd);
-                       return HANDLER_ERROR;
-               }
-       } else {
-               int r ;
-               /* create a new one */
--              
-+
-               BUFFER_COPY_STRING_CONST(p->cmd, "create ");
-               buffer_append_string_buffer(p->cmd, s->path_rrd);
-               buffer_append_string(p->cmd, " --step 60 ");
-@@ -220,158 +218,155 @@
-               buffer_append_string(p->cmd, "RRA:MIN:0.5:6:700 ");
-               buffer_append_string(p->cmd, "RRA:MIN:0.5:24:775 ");
-               buffer_append_string(p->cmd, "RRA:MIN:0.5:288:797\n");
--              
-+
-               if (-1 == (r = write(p->write_fd, p->cmd->ptr, p->cmd->used - 1))) {
--                      log_error_write(srv, __FILE__, __LINE__, "ss", 
-+                      log_error_write(srv, __FILE__, __LINE__, "ss",
-                               "rrdtool-write: failed", strerror(errno));
--                      
-+
-                       return HANDLER_ERROR;
-               }
--              
-+
-               buffer_prepare_copy(p->resp, 4096);
-               if (-1 == (r = read(p->read_fd, p->resp->ptr, p->resp->size))) {
--                      log_error_write(srv, __FILE__, __LINE__, "ss", 
-+                      log_error_write(srv, __FILE__, __LINE__, "ss",
-                               "rrdtool-read: failed", strerror(errno));
--                      
-+
-                       return HANDLER_ERROR;
-               }
--              
-+
-               p->resp->used = r;
--              
-+
-               if (p->resp->ptr[0] != 'O' ||
-                   p->resp->ptr[1] != 'K') {
--                      log_error_write(srv, __FILE__, __LINE__, "sbb", 
-+                      log_error_write(srv, __FILE__, __LINE__, "sbb",
-                               "rrdtool-response:", p->cmd, p->resp);
--                      
-+
-                       return HANDLER_ERROR;
-               }
-       }
--      
-+
-       return HANDLER_GO_ON;
- }
--#define PATCH(x) \
--      p->conf.x = s->x;
- static int mod_rrd_patch_connection(server *srv, connection *con, plugin_data *p) {
-       size_t i, j;
-       plugin_config *s = p->config_storage[0];
--      
--      PATCH(path_rrdtool_bin);
--      PATCH(path_rrd);
--      
-+
-+      PATCH_OPTION(path_rrdtool_bin);
-+      PATCH_OPTION(path_rrd);
-+
-       p->conf.bytes_written_ptr = &(s->bytes_written);
-       p->conf.bytes_read_ptr = &(s->bytes_read);
-       p->conf.requests_ptr = &(s->requests);
--      
-+
-       /* skip the first, the global context */
-       for (i = 1; i < srv->config_context->used; i++) {
-               data_config *dc = (data_config *)srv->config_context->data[i];
-               s = p->config_storage[i];
--              
-+
-               /* condition didn't match */
-               if (!config_check_cond(srv, con, dc)) continue;
--              
-+
-               /* merge config */
-               for (j = 0; j < dc->value->used; j++) {
-                       data_unset *du = dc->value->data[j];
--                      
-+
-                       if (buffer_is_equal_string(du->key, CONST_STR_LEN("rrdtool.db-name"))) {
--                              PATCH(path_rrd);
-+                              PATCH_OPTION(path_rrd);
-                               /* get pointers to double values */
--                              
-+
-                               p->conf.bytes_written_ptr = &(s->bytes_written);
-                               p->conf.bytes_read_ptr = &(s->bytes_read);
-                               p->conf.requests_ptr = &(s->requests);
-                       }
-               }
-       }
--      
-+
-       return 0;
- }
--#undef PATCH
- SETDEFAULTS_FUNC(mod_rrd_set_defaults) {
-       plugin_data *p = p_d;
-       size_t i;
--      
--      config_values_t cv[] = { 
-+
-+      config_values_t cv[] = {
-               { "rrdtool.binary",              NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER },
-               { "rrdtool.db-name",             NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
-               { NULL,                          NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
-       };
--      
-+
-       if (!p) return HANDLER_ERROR;
--      
-+
-       p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
--      
-+
-       for (i = 0; i < srv->config_context->used; i++) {
-               plugin_config *s;
--              
-+
-               s = calloc(1, sizeof(plugin_config));
-               s->path_rrdtool_bin = buffer_init();
-               s->path_rrd = buffer_init();
-               s->requests = 0;
-               s->bytes_written = 0;
-               s->bytes_read = 0;
--              
-+
-               cv[0].destination = s->path_rrdtool_bin;
-               cv[1].destination = s->path_rrd;
--              
-+
-               p->config_storage[i] = s;
--      
-+
-               if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
-                       return HANDLER_ERROR;
-               }
--              
-+
-               if (i > 0 && !buffer_is_empty(s->path_rrdtool_bin)) {
-                       /* path_rrdtool_bin is a global option */
--                      
--                      log_error_write(srv, __FILE__, __LINE__, "s", 
-+
-+                      log_error_write(srv, __FILE__, __LINE__, "s",
-                                       "rrdtool.binary can only be set as a global option.");
--                      
-+
-                       return HANDLER_ERROR;
-               }
--              
-+
-       }
--      
-+
-       p->conf.path_rrdtool_bin = p->config_storage[0]->path_rrdtool_bin;
-       p->rrdtool_running = 0;
--      
-+
-       /* check for dir */
--      
-+
-       if (buffer_is_empty(p->conf.path_rrdtool_bin)) {
--              log_error_write(srv, __FILE__, __LINE__, "s", 
-+              log_error_write(srv, __FILE__, __LINE__, "s",
-                               "rrdtool.binary has to be set");
-               return HANDLER_ERROR;
-       }
--      
-+
-       /* open the pipe to rrdtool */
-       if (mod_rrd_create_pipe(srv, p)) {
-               return HANDLER_ERROR;
-       }
--      
-+
-       p->rrdtool_running = 1;
--              
-+
-       return HANDLER_GO_ON;
- }
- TRIGGER_FUNC(mod_rrd_trigger) {
-       plugin_data *p = p_d;
-       size_t i;
--      
-+
-       if (!p->rrdtool_running) return HANDLER_GO_ON;
-       if ((srv->cur_ts % 60) != 0) return HANDLER_GO_ON;
--      
-+
-       for (i = 0; i < srv->config_context->used; i++) {
-               plugin_config *s = p->config_storage[i];
-               int r;
--              
-+
-               if (buffer_is_empty(s->path_rrd)) continue;
--      
-+
-               /* write the data down every minute */
--              
-+
-               if (HANDLER_GO_ON != mod_rrdtool_create_rrd(srv, p, s)) return HANDLER_ERROR;
--              
-+
-               BUFFER_COPY_STRING_CONST(p->cmd, "update ");
-               buffer_append_string_buffer(p->cmd, s->path_rrd);
-               BUFFER_APPEND_STRING_CONST(p->cmd, " N:");
-@@ -381,69 +376,69 @@
-               BUFFER_APPEND_STRING_CONST(p->cmd, ":");
-               buffer_append_long(p->cmd, s->requests);
-               BUFFER_APPEND_STRING_CONST(p->cmd, "\n");
--              
-+
-               if (-1 == (r = write(p->write_fd, p->cmd->ptr, p->cmd->used - 1))) {
-                       p->rrdtool_running = 0;
--                      
--                      log_error_write(srv, __FILE__, __LINE__, "ss", 
-+
-+                      log_error_write(srv, __FILE__, __LINE__, "ss",
-                                       "rrdtool-write: failed", strerror(errno));
--                      
-+
-                       return HANDLER_ERROR;
-               }
--              
-+
-               buffer_prepare_copy(p->resp, 4096);
-               if (-1 == (r = read(p->read_fd, p->resp->ptr, p->resp->size))) {
-                       p->rrdtool_running = 0;
--                      
--                      log_error_write(srv, __FILE__, __LINE__, "ss", 
-+
-+                      log_error_write(srv, __FILE__, __LINE__, "ss",
-                                       "rrdtool-read: failed", strerror(errno));
--                      
-+
-                       return HANDLER_ERROR;
-               }
--              
-+
-               p->resp->used = r;
--              
-+
-               if (p->resp->ptr[0] != 'O' ||
-                   p->resp->ptr[1] != 'K') {
-                       p->rrdtool_running = 0;
--                      
--                      log_error_write(srv, __FILE__, __LINE__, "sbb", 
-+
-+                      log_error_write(srv, __FILE__, __LINE__, "sbb",
-                                       "rrdtool-response:", p->cmd, p->resp);
--                      
-+
-                       return HANDLER_ERROR;
-               }
-               s->requests = 0;
-               s->bytes_written = 0;
-               s->bytes_read = 0;
-       }
--      
-+
-       return HANDLER_GO_ON;
- }
- REQUESTDONE_FUNC(mod_rrd_account) {
-       plugin_data *p = p_d;
--      
-+
-       mod_rrd_patch_connection(srv, con, p);
--      
-+
-       *(p->conf.requests_ptr)      += 1;
-       *(p->conf.bytes_written_ptr) += con->bytes_written;
-       *(p->conf.bytes_read_ptr)    += con->bytes_read;
--      
-+
-       return HANDLER_GO_ON;
- }
- int mod_rrdtool_plugin_init(plugin *p) {
-       p->version     = LIGHTTPD_VERSION_ID;
-       p->name        = buffer_init_string("rrd");
--      
-+
-       p->init        = mod_rrd_init;
-       p->cleanup     = mod_rrd_free;
-       p->set_defaults= mod_rrd_set_defaults;
--      
-+
-       p->handle_trigger      = mod_rrd_trigger;
--      p->handle_request_done = mod_rrd_account;
--      
-+      p->handle_response_done = mod_rrd_account;
-+
-       p->data        = NULL;
--      
-+
-       return 0;
- }
---- ../lighttpd-1.4.11/src/mod_scgi.c  2006-03-04 17:15:26.000000000 +0200
-+++ lighttpd-1.5.0/src/mod_scgi.c      2006-09-07 00:57:05.000000000 +0300
-@@ -1,5 +1,4 @@
- #include <sys/types.h>
--#include <unistd.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <string.h>
-@@ -13,11 +12,11 @@
- #include "keyvalue.h"
- #include "log.h"
--#include "http_chunk.h"
- #include "fdevent.h"
- #include "connections.h"
- #include "response.h"
- #include "joblist.h"
-+#include "http_resp.h"
- #include "plugin.h"
-@@ -30,7 +29,9 @@
- #endif
- #include "sys-socket.h"
--
-+#include "sys-files.h"
-+#include "sys-strings.h"
-+#include "sys-process.h"
- #ifndef UNIX_PATH_MAX
- # define UNIX_PATH_MAX 108
-@@ -46,30 +47,29 @@
- enum {EOL_UNSET, EOL_N, EOL_RN};
- /*
-- * 
-+ *
-  * TODO:
-- * 
-+ *
-  * - add timeout for a connect to a non-scgi process
-  *   (use state_timestamp + state)
-- * 
-+ *
-  */
- typedef struct scgi_proc {
-       size_t id; /* id will be between 1 and max_procs */
-       buffer *socket; /* config.socket + "-" + id */
-       unsigned port;  /* config.port + pno */
--      
--      pid_t pid;   /* PID of the spawned process (0 if not spawned locally) */
-+      pid_t pid;   /* PID of the spawned process (0 if not spawned locally) */
-       size_t load; /* number of requests waiting on this process */
-       time_t last_used; /* see idle_timeout */
-       size_t requests;  /* see max_requests */
-       struct scgi_proc *prev, *next; /* see first */
--      
-+
-       time_t disable_ts; /* replace by host->something */
--      
-+
-       int is_local;
-       enum { PROC_STATE_UNSET,            /* init-phase */
-@@ -78,7 +78,7 @@
-                       PROC_STATE_KILLED,  /* was killed as we don't have the load anymore */
-                       PROC_STATE_DIED,    /* marked as dead, should be restarted */
-                       PROC_STATE_DISABLED /* proc disabled as it resulted in an error */
--      } state; 
-+      } state;
- } scgi_proc;
- typedef struct {
-@@ -86,20 +86,20 @@
-        * sorted by lowest load
-        *
-        * whenever a job is done move it up in the list
--       * until it is sorted, move it down as soon as the 
-+       * until it is sorted, move it down as soon as the
-        * job is started
-        */
--      scgi_proc *first; 
--      scgi_proc *unused_procs; 
-+      scgi_proc *first;
-+      scgi_proc *unused_procs;
--      /* 
-+      /*
-        * spawn at least min_procs, at max_procs.
-        *
--       * as soon as the load of the first entry 
-+       * as soon as the load of the first entry
-        * is max_load_per_proc we spawn a new one
--       * and add it to the first entry and give it 
-+       * and add it to the first entry and give it
-        * the load
--       * 
-+       *
-        */
-       unsigned short min_procs;
-@@ -111,44 +111,44 @@
-       /*
-        * kick the process from the list if it was not
--       * used for idle_timeout until min_procs is 
-+       * used for idle_timeout until min_procs is
-        * reached. this helps to get the processlist
-        * small again we had a small peak load.
-        *
-        */
--      
-+
-       unsigned short idle_timeout;
--      
-+
-       /*
-        * time after a disabled remote connection is tried to be re-enabled
--       * 
--       * 
-+       *
-+       *
-        */
--      
-+
-       unsigned short disable_time;
-       /*
-        * same scgi processes get a little bit larger
--       * than wanted. max_requests_per_proc kills a 
-+       * than wanted. max_requests_per_proc kills a
-        * process after a number of handled requests.
-        *
-        */
-       size_t max_requests_per_proc;
--      
-+
-       /* config */
--      /* 
--       * host:port 
-+      /*
-+       * host:port
-        *
--       * if host is one of the local IP adresses the 
-+       * if host is one of the local IP adresses the
-        * whole connection is local
-        *
-        * if tcp/ip should be used host AND port have
--       * to be specified 
--       * 
--       */ 
--      buffer *host; 
-+       * to be specified
-+       *
-+       */
-+      buffer *host;
-       unsigned short port;
-       /*
-@@ -161,7 +161,7 @@
-        */
-       buffer *unixsocket;
--      /* if socket is local we can start the scgi 
-+      /* if socket is local we can start the scgi
-        * process ourself
-        *
-        * bin-path is the path to the binary
-@@ -169,19 +169,19 @@
-        * check min_procs and max_procs for the number
-        * of process to start-up
-        */
--      buffer *bin_path; 
--      
--      /* bin-path is set bin-environment is taken to 
-+      buffer *bin_path;
-+
-+      /* bin-path is set bin-environment is taken to
-        * create the environement before starting the
-        * FastCGI process
--       * 
-+       *
-        */
-       array *bin_env;
--      
-+
-       array *bin_env_copy;
--      
-+
-       /*
--       * docroot-translation between URL->phys and the 
-+       * docroot-translation between URL->phys and the
-        * remote host
-        *
-        * reasons:
-@@ -192,7 +192,7 @@
-       buffer *docroot;
-       /*
--       * check_local tell you if the phys file is stat()ed 
-+       * check_local tell you if the phys file is stat()ed
-        * or not. FastCGI doesn't care if the service is
-        * remote. If the web-server side doesn't contain
-        * the scgi-files we should not stat() for them
-@@ -202,33 +202,33 @@
-       /*
-        * append PATH_INFO to SCRIPT_FILENAME
--       * 
-+       *
-        * php needs this if cgi.fix_pathinfo is provied
--       * 
-+       *
-        */
--      
-+
-       ssize_t load; /* replace by host->load */
-       size_t max_id; /* corresponds most of the time to
-       num_procs.
--      
-+
-       only if a process is killed max_id waits for the process itself
-       to die and decrements its afterwards */
- } scgi_extension_host;
- /*
-  * one extension can have multiple hosts assigned
-- * one host can spawn additional processes on the same 
-+ * one host can spawn additional processes on the same
-  *   socket (if we control it)
-  *
-  * ext -> host -> procs
-  *    1:n     1:n
-  *
-- * if the scgi process is remote that whole goes down 
-+ * if the scgi process is remote that whole goes down
-  * to
-  *
-  * ext -> host -> procs
-- *    1:n     1:1 
-+ *    1:n     1:1
-  *
-  * in case of PHP and FCGI_CHILDREN we have again a procs
-  * but we don't control it directly.
-@@ -239,7 +239,7 @@
-       buffer *key; /* like .php */
-       scgi_extension_host **hosts;
--      
-+
-       size_t used;
-       size_t size;
- } scgi_extension;
-@@ -253,14 +253,14 @@
- typedef struct {
--      scgi_exts *exts; 
--      
-+      scgi_exts *exts;
-+
-       int debug;
- } plugin_config;
- typedef struct {
-       char **ptr;
--      
-+
-       size_t size;
-       size_t used;
- } char_array;
-@@ -268,52 +268,51 @@
- /* generic plugin data, shared between all connections */
- typedef struct {
-       PLUGIN_DATA;
--      
-+
-       buffer *scgi_env;
--      
-+
-       buffer *path;
--      buffer *parse_response;
--      
-+
-+      http_resp *resp;
-+
-       plugin_config **config_storage;
--      
-+
-       plugin_config conf; /* this is only used as long as no handler_ctx is setup */
- } plugin_data;
- /* connection specific data */
--typedef enum { FCGI_STATE_INIT, FCGI_STATE_CONNECT, FCGI_STATE_PREPARE_WRITE, 
--              FCGI_STATE_WRITE, FCGI_STATE_READ 
-+typedef enum {
-+      SCGI_STATE_INIT,
-+      SCGI_STATE_CONNECT,
-+      SCGI_STATE_PREPARE_WRITE,
-+      SCGI_STATE_WRITE,
-+      SCGI_STATE_RESPONSE_HEADER,
-+      SCGI_STATE_RESPONSE_CONTENT,
-+      SCGI_STATE_ERROR
- } scgi_connection_state_t;
- typedef struct {
--      buffer  *response; 
--      size_t   response_len;
--      int      response_type;
--      int      response_padding;
--      
-       scgi_proc *proc;
-       scgi_extension_host *host;
--      
-+
-       scgi_connection_state_t state;
-       time_t   state_timestamp;
--      
-+
-       int      reconnects; /* number of reconnect attempts */
--      
--      read_buffer *rb;
-+
-+      chunkqueue *rb;
-       chunkqueue *wb;
--      
--      buffer   *response_header;
--      
-+
-       int       delayed;   /* flag to mark that the connect() is delayed */
--      
-+
-       size_t    request_id;
--      int       fd;        /* fd to the scgi process */
--      int       fde_ndx;   /* index into the fd-event buffer */
-+      iosocket  *sock;        /* fd to the scgi process */
-       pid_t     pid;
-       int       got_proc;
--      
-+
-       plugin_config conf;
--      
-+
-       connection *remote_conn;  /* dumb pointer */
-       plugin_data *plugin_data; /* dumb pointer */
- } handler_ctx;
-@@ -328,42 +327,30 @@
- static handler_ctx * handler_ctx_init() {
-       handler_ctx * hctx;
--      
-+
-       hctx = calloc(1, sizeof(*hctx));
-       assert(hctx);
--      
--      hctx->fde_ndx = -1;
--      
--      hctx->response = buffer_init();
--      hctx->response_header = buffer_init();
--      
-+
-+      hctx->sock = iosocket_init();;
-+
-       hctx->request_id = 0;
--      hctx->state = FCGI_STATE_INIT;
-+      hctx->state = SCGI_STATE_INIT;
-       hctx->proc = NULL;
--      
--      hctx->response_len = 0;
--      hctx->response_type = 0;
--      hctx->response_padding = 0;
--      hctx->fd = -1;
--      
-+
-       hctx->reconnects = 0;
-       hctx->wb = chunkqueue_init();
--      
-+      hctx->rb = chunkqueue_init();
-+
-       return hctx;
- }
- static void handler_ctx_free(handler_ctx *hctx) {
--      buffer_free(hctx->response);
--      buffer_free(hctx->response_header);
--
-       chunkqueue_free(hctx->wb);
--      
--      if (hctx->rb) {
--              if (hctx->rb->ptr) free(hctx->rb->ptr);
--              free(hctx->rb);
--      }
--      
-+      chunkqueue_free(hctx->rb);
-+
-+      iosocket_free(hctx->sock);
-+
-       free(hctx);
- }
-@@ -372,20 +359,20 @@
-       f = calloc(1, sizeof(*f));
-       f->socket = buffer_init();
--      
-+
-       f->prev = NULL;
-       f->next = NULL;
--      
-+
-       return f;
- }
- void scgi_process_free(scgi_proc *f) {
-       if (!f) return;
--      
-+
-       scgi_process_free(f->next);
--      
-+
-       buffer_free(f->socket);
--      
-+
-       free(f);
- }
-@@ -400,62 +387,62 @@
-       f->bin_path = buffer_init();
-       f->bin_env = array_init();
-       f->bin_env_copy = array_init();
--      
-+
-       return f;
- }
- void scgi_host_free(scgi_extension_host *h) {
-       if (!h) return;
--      
-+
-       buffer_free(h->host);
-       buffer_free(h->unixsocket);
-       buffer_free(h->docroot);
-       buffer_free(h->bin_path);
-       array_free(h->bin_env);
-       array_free(h->bin_env_copy);
--      
-+
-       scgi_process_free(h->first);
-       scgi_process_free(h->unused_procs);
--      
-+
-       free(h);
--      
-+
- }
- scgi_exts *scgi_extensions_init() {
-       scgi_exts *f;
-       f = calloc(1, sizeof(*f));
--      
-+
-       return f;
- }
- void scgi_extensions_free(scgi_exts *f) {
-       size_t i;
--      
-+
-       if (!f) return;
--      
-+
-       for (i = 0; i < f->used; i++) {
-               scgi_extension *fe;
-               size_t j;
--              
-+
-               fe = f->exts[i];
--              
-+
-               for (j = 0; j < fe->used; j++) {
-                       scgi_extension_host *h;
--                      
-+
-                       h = fe->hosts[j];
--                      
-+
-                       scgi_host_free(h);
-               }
--              
-+
-               buffer_free(fe->key);
-               free(fe->hosts);
--              
-+
-               free(fe);
-       }
--      
-+
-       free(f->exts);
--      
-+
-       free(f);
- }
-@@ -504,99 +491,103 @@
-               assert(fe->hosts);
-       }
--      fe->hosts[fe->used++] = fh; 
-+      fe->hosts[fe->used++] = fh;
-       return 0;
--      
-+
- }
- INIT_FUNC(mod_scgi_init) {
-       plugin_data *p;
--      
-+
-       p = calloc(1, sizeof(*p));
--      
-+
-       p->scgi_env = buffer_init();
--      
-+
-       p->path = buffer_init();
--      p->parse_response = buffer_init();
--      
-+      p->resp = http_response_init();
-+
-       return p;
- }
- FREE_FUNC(mod_scgi_free) {
-       plugin_data *p = p_d;
--      
-+
-       UNUSED(srv);
-       buffer_free(p->scgi_env);
-       buffer_free(p->path);
--      buffer_free(p->parse_response);
--      
-+      http_response_free(p->resp);
-+
-       if (p->config_storage) {
-               size_t i, j, n;
-               for (i = 0; i < srv->config_context->used; i++) {
-                       plugin_config *s = p->config_storage[i];
-                       scgi_exts *exts;
--                      
-+
-                       if (!s) continue;
--                      
-+
-                       exts = s->exts;
-                       for (j = 0; j < exts->used; j++) {
-                               scgi_extension *ex;
--                              
-+
-                               ex = exts->exts[j];
--                              
-+
-                               for (n = 0; n < ex->used; n++) {
-                                       scgi_proc *proc;
-                                       scgi_extension_host *host;
--                                      
-+
-                                       host = ex->hosts[n];
--                                      
-+
-                                       for (proc = host->first; proc; proc = proc->next) {
-+#ifndef _WIN32
-                                               if (proc->pid != 0) kill(proc->pid, SIGTERM);
--                                              
--                                              if (proc->is_local && 
-+#endif
-+
-+                                              if (proc->is_local &&
-                                                   !buffer_is_empty(proc->socket)) {
-                                                       unlink(proc->socket->ptr);
-                                               }
-                                       }
--                                      
-+
-                                       for (proc = host->unused_procs; proc; proc = proc->next) {
-+#ifndef _WIN32
-                                               if (proc->pid != 0) kill(proc->pid, SIGTERM);
--                                              
--                                              if (proc->is_local && 
-+#endif
-+
-+                                              if (proc->is_local &&
-                                                   !buffer_is_empty(proc->socket)) {
-                                                       unlink(proc->socket->ptr);
-                                               }
-                                       }
-                               }
-                       }
--                      
-+
-                       scgi_extensions_free(s->exts);
--                      
-+
-                       free(s);
-               }
-               free(p->config_storage);
-       }
--      
-+
-       free(p);
--      
-+
-       return HANDLER_GO_ON;
- }
- static int env_add(char_array *env, const char *key, size_t key_len, const char *val, size_t val_len) {
-       char *dst;
--      
-+
-       if (!key || !val) return -1;
--      
-+
-       dst = malloc(key_len + val_len + 3);
-       memcpy(dst, key, key_len);
-       dst[key_len] = '=';
-       /* add the \0 from the value */
-       memcpy(dst + key_len + 1, val, val_len + 1);
--      
-+
-       if (env->size == 0) {
-               env->size = 16;
-               env->ptr = malloc(env->size * sizeof(*env->ptr));
-@@ -604,13 +595,13 @@
-               env->size += 16;
-               env->ptr = realloc(env->ptr, env->size * sizeof(*env->ptr));
-       }
--      
-+
-       env->ptr[env->used++] = dst;
--      
-+
-       return 0;
- }
--static int scgi_spawn_connection(server *srv, 
-+static int scgi_spawn_connection(server *srv,
-                                plugin_data *p,
-                                scgi_extension_host *host,
-                                scgi_proc *proc) {
-@@ -622,31 +613,27 @@
- #endif
-       struct sockaddr_in scgi_addr_in;
-       struct sockaddr *scgi_addr;
--      
-+
-       socklen_t servlen;
--      
-+
- #ifndef HAVE_FORK
-       return -1;
- #endif
--      
-+
-       if (p->conf.debug) {
-               log_error_write(srv, __FILE__, __LINE__, "sdb",
-                               "new proc, socket:", proc->port, proc->socket);
-       }
--              
-+
-       if (!buffer_is_empty(proc->socket)) {
-               memset(&scgi_addr, 0, sizeof(scgi_addr));
--              
-+
- #ifdef HAVE_SYS_UN_H
-               scgi_addr_un.sun_family = AF_UNIX;
-               strcpy(scgi_addr_un.sun_path, proc->socket->ptr);
--              
--#ifdef SUN_LEN
-+
-               servlen = SUN_LEN(&scgi_addr_un);
--#else
--              /* stevens says: */
--              servlen = proc->socket->used + sizeof(scgi_addr_un.sun_family);
--#endif
-+
-               socket_type = AF_UNIX;
-               scgi_addr = (struct sockaddr *) &scgi_addr_un;
- #else
-@@ -656,115 +643,115 @@
- #endif
-       } else {
-               scgi_addr_in.sin_family = AF_INET;
--              
-+
-               if (buffer_is_empty(host->host)) {
-                       scgi_addr_in.sin_addr.s_addr = htonl(INADDR_ANY);
-               } else {
-                       struct hostent *he;
--                      
-+
-                       /* set a usefull default */
-                       scgi_addr_in.sin_addr.s_addr = htonl(INADDR_ANY);
--                      
--                      
-+
-+
-                       if (NULL == (he = gethostbyname(host->host->ptr))) {
--                              log_error_write(srv, __FILE__, __LINE__, 
--                                              "sdb", "gethostbyname failed: ", 
-+                              log_error_write(srv, __FILE__, __LINE__,
-+                                              "sdb", "gethostbyname failed: ",
-                                               h_errno, host->host);
-                               return -1;
-                       }
--                      
-+
-                       if (he->h_addrtype != AF_INET) {
-                               log_error_write(srv, __FILE__, __LINE__, "sd", "addr-type != AF_INET: ", he->h_addrtype);
-                               return -1;
-                       }
--                      
-+
-                       if (he->h_length != sizeof(struct in_addr)) {
-                               log_error_write(srv, __FILE__, __LINE__, "sd", "addr-length != sizeof(in_addr): ", he->h_length);
-                               return -1;
-                       }
--                      
-+
-                       memcpy(&(scgi_addr_in.sin_addr.s_addr), he->h_addr_list[0], he->h_length);
--                      
-+
-               }
-               scgi_addr_in.sin_port = htons(proc->port);
-               servlen = sizeof(scgi_addr_in);
--              
-+
-               socket_type = AF_INET;
-               scgi_addr = (struct sockaddr *) &scgi_addr_in;
-       }
--      
-+
-       if (-1 == (scgi_fd = socket(socket_type, SOCK_STREAM, 0))) {
--              log_error_write(srv, __FILE__, __LINE__, "ss", 
-+              log_error_write(srv, __FILE__, __LINE__, "ss",
-                               "failed:", strerror(errno));
-               return -1;
-       }
--      
-+
-       if (-1 == connect(scgi_fd, scgi_addr, servlen)) {
-               /* server is not up, spawn in  */
-               pid_t child;
-               int val;
--              
-+
-               if (!buffer_is_empty(proc->socket)) {
-                       unlink(proc->socket->ptr);
-               }
--              
-+
-               close(scgi_fd);
--              
-+
-               /* reopen socket */
-               if (-1 == (scgi_fd = socket(socket_type, SOCK_STREAM, 0))) {
--                      log_error_write(srv, __FILE__, __LINE__, "ss", 
-+                      log_error_write(srv, __FILE__, __LINE__, "ss",
-                               "socket failed:", strerror(errno));
-                       return -1;
-               }
--              
-+
-               val = 1;
-               if (setsockopt(scgi_fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) {
--                      log_error_write(srv, __FILE__, __LINE__, "ss", 
-+                      log_error_write(srv, __FILE__, __LINE__, "ss",
-                                       "socketsockopt failed:", strerror(errno));
-                       return -1;
-               }
--              
-+
-               /* create socket */
-               if (-1 == bind(scgi_fd, scgi_addr, servlen)) {
--                      log_error_write(srv, __FILE__, __LINE__, "sbds", 
--                              "bind failed for:", 
--                              proc->socket, 
--                              proc->port, 
-+                      log_error_write(srv, __FILE__, __LINE__, "sbds",
-+                              "bind failed for:",
-+                              proc->socket,
-+                              proc->port,
-                               strerror(errno));
-                       return -1;
-               }
--              
-+
-               if (-1 == listen(scgi_fd, 1024)) {
--                      log_error_write(srv, __FILE__, __LINE__, "ss", 
-+                      log_error_write(srv, __FILE__, __LINE__, "ss",
-                               "listen failed:", strerror(errno));
-                       return -1;
-               }
--              
--#ifdef HAVE_FORK      
-+
-+#ifdef HAVE_FORK
-               switch ((child = fork())) {
-               case 0: {
-                       buffer *b;
-                       size_t i = 0;
-                       int fd = 0;
-                       char_array env;
--                      
--                      
-+
-+
-                       /* create environment */
-                       env.ptr = NULL;
-                       env.size = 0;
-                       env.used = 0;
--                      
-+
-                       /* we don't need the client socket */
-                       for (fd = 3; fd < 256; fd++) {
-                               if (fd != 2 && fd != scgi_fd) close(fd);
-                       }
--                      
-+
-                       /* build clean environment */
-                       if (host->bin_env_copy->used) {
-                               for (i = 0; i < host->bin_env_copy->used; i++) {
-                                       data_string *ds = (data_string *)host->bin_env_copy->data[i];
-                                       char *ge;
--                                      
-+
-                                       if (NULL != (ge = getenv(ds->value->ptr))) {
-                                               env_add(&env, CONST_BUF_LEN(ds->value), ge, strlen(ge));
-                                       }
-@@ -772,44 +759,44 @@
-                       } else {
-                               for (i = 0; environ[i]; i++) {
-                                       char *eq;
--                                      
-+
-                                       if (NULL != (eq = strchr(environ[i], '='))) {
-                                               env_add(&env, environ[i], eq - environ[i], eq+1, strlen(eq+1));
-                                       }
-                               }
-                       }
--                      
-+
-                       /* create environment */
-                       for (i = 0; i < host->bin_env->used; i++) {
-                               data_string *ds = (data_string *)host->bin_env->data[i];
--                              
-+
-                               env_add(&env, CONST_BUF_LEN(ds->key), CONST_BUF_LEN(ds->value));
-                       }
--                      
-+
-                       for (i = 0; i < env.used; i++) {
-                               /* search for PHP_FCGI_CHILDREN */
-                               if (0 == strncmp(env.ptr[i], "PHP_FCGI_CHILDREN=", sizeof("PHP_FCGI_CHILDREN=") - 1)) break;
-                       }
--                      
-+
-                       /* not found, add a default */
-                       if (i == env.used) {
-                               env_add(&env, CONST_STR_LEN("PHP_FCGI_CHILDREN"), CONST_STR_LEN("1"));
-                       }
--                      
-+
-                       env.ptr[env.used] = NULL;
--                      
-+
-                       b = buffer_init();
-                       buffer_copy_string(b, "exec ");
-                       buffer_append_string_buffer(b, host->bin_path);
--                      
-+
-                       /* exec the cgi */
-                       execle("/bin/sh", "sh", "-c", b->ptr, NULL, env.ptr);
--                      
--                      log_error_write(srv, __FILE__, __LINE__, "sbs", 
-+
-+                      log_error_write(srv, __FILE__, __LINE__, "sbs",
-                                       "execl failed for:", host->bin_path, strerror(errno));
--                      
-+
-                       exit(errno);
--                      
-+
-                       break;
-               }
-               case -1:
-@@ -817,32 +804,32 @@
-                       break;
-               default:
-                       /* father */
--                      
-+
-                       /* wait */
-                       select(0, NULL, NULL, NULL, &tv);
--                      
-+
-                       switch (waitpid(child, &status, WNOHANG)) {
-                       case 0:
-                               /* child still running after timeout, good */
-                               break;
-                       case -1:
-                               /* no PID found ? should never happen */
--                              log_error_write(srv, __FILE__, __LINE__, "ss", 
-+                              log_error_write(srv, __FILE__, __LINE__, "ss",
-                                               "pid not found:", strerror(errno));
-                               return -1;
-                       default:
-                               /* the child should not terminate at all */
-                               if (WIFEXITED(status)) {
--                                      log_error_write(srv, __FILE__, __LINE__, "sd", 
--                                                      "child exited (is this a SCGI binary ?):", 
-+                                      log_error_write(srv, __FILE__, __LINE__, "sd",
-+                                                      "child exited (is this a SCGI binary ?):",
-                                                       WEXITSTATUS(status));
-                               } else if (WIFSIGNALED(status)) {
--                                      log_error_write(srv, __FILE__, __LINE__, "sd", 
--                                                      "child signaled:", 
-+                                      log_error_write(srv, __FILE__, __LINE__, "sd",
-+                                                      "child signaled:",
-                                                       WTERMSIG(status));
-                               } else {
--                                      log_error_write(srv, __FILE__, __LINE__, "sd", 
--                                                      "child died somehow:", 
-+                                      log_error_write(srv, __FILE__, __LINE__, "sd",
-+                                                      "child died somehow:",
-                                                       status);
-                               }
-                               return -1;
-@@ -852,26 +839,26 @@
-                       proc->pid = child;
-                       proc->last_used = srv->cur_ts;
-                       proc->is_local = 1;
--                                              
-+
-                       break;
-               }
- #endif
-       } else {
-               proc->is_local = 0;
-               proc->pid = 0;
--              
-+
-               if (p->conf.debug) {
-                       log_error_write(srv, __FILE__, __LINE__, "sb",
-                                       "(debug) socket is already used, won't spawn:",
-                                       proc->socket);
-               }
-       }
--      
-+
-       proc->state = PROC_STATE_RUNNING;
-       host->active_procs++;
--      
-+
-       close(scgi_fd);
--      
-+
-       return 0;
- }
-@@ -880,89 +867,89 @@
-       plugin_data *p = p_d;
-       data_unset *du;
-       size_t i = 0;
--      
--      config_values_t cv[] = { 
-+
-+      config_values_t cv[] = {
-               { "scgi.server",              NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
-               { "scgi.debug",               NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },       /* 1 */
-               { NULL,                          NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
-       };
--      
-+
-       p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
--      
-+
-       for (i = 0; i < srv->config_context->used; i++) {
-               plugin_config *s;
-               array *ca;
--              
-+
-               s = malloc(sizeof(plugin_config));
-               s->exts          = scgi_extensions_init();
-               s->debug         = 0;
--              
-+
-               cv[0].destination = s->exts;
-               cv[1].destination = &(s->debug);
--              
-+
-               p->config_storage[i] = s;
-               ca = ((data_config *)srv->config_context->data[i])->value;
--      
-+
-               if (0 != config_insert_values_global(srv, ca, cv)) {
-                       return HANDLER_ERROR;
-               }
--              
--              /* 
-+
-+              /*
-                * <key> = ( ... )
-                */
--              
-+
-               if (NULL != (du = array_get_element(ca, "scgi.server"))) {
-                       size_t j;
-                       data_array *da = (data_array *)du;
--                      
-+
-                       if (du->type != TYPE_ARRAY) {
--                              log_error_write(srv, __FILE__, __LINE__, "sss", 
-+                              log_error_write(srv, __FILE__, __LINE__, "sss",
-                                               "unexpected type for key: ", "scgi.server", "array of strings");
--                              
-+
-                               return HANDLER_ERROR;
-                       }
--                      
--                      
--                      /* 
--                       * scgi.server = ( "<ext>" => ( ... ), 
-+
-+
-+                      /*
-+                       * scgi.server = ( "<ext>" => ( ... ),
-                        *                    "<ext>" => ( ... ) )
-                        */
--                      
-+
-                       for (j = 0; j < da->value->used; j++) {
-                               size_t n;
-                               data_array *da_ext = (data_array *)da->value->data[j];
--                              
-+
-                               if (da->value->data[j]->type != TYPE_ARRAY) {
--                                      log_error_write(srv, __FILE__, __LINE__, "sssbs", 
--                                                      "unexpected type for key: ", "scgi.server", 
-+                                      log_error_write(srv, __FILE__, __LINE__, "sssbs",
-+                                                      "unexpected type for key: ", "scgi.server",
-                                                       "[", da->value->data[j]->key, "](string)");
--                                      
-+
-                                       return HANDLER_ERROR;
-                               }
--                              
--                              /* 
--                               * da_ext->key == name of the extension 
-+
-+                              /*
-+                               * da_ext->key == name of the extension
-                                */
--                              
--                              /* 
--                               * scgi.server = ( "<ext>" => 
--                               *                     ( "<host>" => ( ... ), 
-+
-+                              /*
-+                               * scgi.server = ( "<ext>" =>
-+                               *                     ( "<host>" => ( ... ),
-                                *                       "<host>" => ( ... )
--                               *                     ), 
-+                               *                     ),
-                                *                    "<ext>" => ... )
-                                */
--                                      
-+
-                               for (n = 0; n < da_ext->value->used; n++) {
-                                       data_array *da_host = (data_array *)da_ext->value->data[n];
--                                      
-+
-                                       scgi_extension_host *df;
--                                      
--                                      config_values_t fcv[] = { 
-+
-+                                      config_values_t fcv[] = {
-                                               { "host",              NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
-                                               { "docroot",           NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 1 */
-                                               { "socket",            NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 2 */
-                                               { "bin-path",          NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 3 */
--                                              
-+
-                                               { "check-local",       NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },      /* 4 */
-                                               { "port",              NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },        /* 5 */
-                                               { "min-procs-not-working",         NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },        /* 7 this is broken for now */
-@@ -970,37 +957,37 @@
-                                               { "max-load-per-proc", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },        /* 8 */
-                                               { "idle-timeout",      NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },        /* 9 */
-                                               { "disable-time",      NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },        /* 10 */
--                                              
-+
-                                               { "bin-environment",   NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },        /* 11 */
-                                               { "bin-copy-environment", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },     /* 12 */
--                                              
--                                              
-+
-+
-                                               { NULL,                NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
-                                       };
--                                      
-+
-                                       if (da_host->type != TYPE_ARRAY) {
--                                              log_error_write(srv, __FILE__, __LINE__, "ssSBS", 
--                                                              "unexpected type for key:", 
--                                                              "scgi.server", 
-+                                              log_error_write(srv, __FILE__, __LINE__, "ssSBS",
-+                                                              "unexpected type for key:",
-+                                                              "scgi.server",
-                                                               "[", da_host->key, "](string)");
--                                              
-+
-                                               return HANDLER_ERROR;
-                                       }
--                                      
-+
-                                       df = scgi_host_init();
--                                      
-+
-                                       df->check_local  = 1;
-                                       df->min_procs    = 4;
-                                       df->max_procs    = 4;
-                                       df->max_load_per_proc = 1;
-                                       df->idle_timeout = 60;
-                                       df->disable_time = 60;
--                                      
-+
-                                       fcv[0].destination = df->host;
-                                       fcv[1].destination = df->docroot;
-                                       fcv[2].destination = df->unixsocket;
-                                       fcv[3].destination = df->bin_path;
--                                      
-+
-                                       fcv[4].destination = &(df->check_local);
-                                       fcv[5].destination = &(df->port);
-                                       fcv[6].destination = &(df->min_procs);
-@@ -1008,47 +995,47 @@
-                                       fcv[8].destination = &(df->max_load_per_proc);
-                                       fcv[9].destination = &(df->idle_timeout);
-                                       fcv[10].destination = &(df->disable_time);
--                                      
-+
-                                       fcv[11].destination = df->bin_env;
-                                       fcv[12].destination = df->bin_env_copy;
--                                      
--                                      
-+
-+
-                                       if (0 != config_insert_values_internal(srv, da_host->value, fcv)) {
-                                               return HANDLER_ERROR;
-                                       }
--                                                      
--                                      if ((!buffer_is_empty(df->host) || df->port) && 
-+
-+                                      if ((!buffer_is_empty(df->host) || df->port) &&
-                                           !buffer_is_empty(df->unixsocket)) {
--                                              log_error_write(srv, __FILE__, __LINE__, "s", 
-+                                              log_error_write(srv, __FILE__, __LINE__, "s",
-                                                               "either host+port or socket");
--                                              
-+
-                                               return HANDLER_ERROR;
-                                       }
--                                      
-+
-                                       if (!buffer_is_empty(df->unixsocket)) {
-                                               /* unix domain socket */
--                                              
-+
-                                               if (df->unixsocket->used > UNIX_PATH_MAX - 2) {
--                                                      log_error_write(srv, __FILE__, __LINE__, "s", 
-+                                                      log_error_write(srv, __FILE__, __LINE__, "s",
-                                                                       "path of the unixdomain socket is too large");
-                                                       return HANDLER_ERROR;
-                                               }
-                                       } else {
-                                               /* tcp/ip */
--                                              
--                                              if (buffer_is_empty(df->host) && 
-+
-+                                              if (buffer_is_empty(df->host) &&
-                                                   buffer_is_empty(df->bin_path)) {
--                                                      log_error_write(srv, __FILE__, __LINE__, "sbbbs", 
--                                                                      "missing key (string):", 
-+                                                      log_error_write(srv, __FILE__, __LINE__, "sbbbs",
-+                                                                      "missing key (string):",
-                                                                       da->key,
-                                                                       da_ext->key,
-                                                                       da_host->key,
-                                                                       "host");
--                                                      
-+
-                                                       return HANDLER_ERROR;
-                                               } else if (df->port == 0) {
--                                                      log_error_write(srv, __FILE__, __LINE__, "sbbbs", 
--                                                                      "missing key (short):", 
-+                                                      log_error_write(srv, __FILE__, __LINE__, "sbbbs",
-+                                                                      "missing key (short):",
-                                                                       da->key,
-                                                                       da_ext->key,
-                                                                       da_host->key,
-@@ -1056,14 +1043,14 @@
-                                                       return HANDLER_ERROR;
-                                               }
-                                       }
--                                              
--                                      if (!buffer_is_empty(df->bin_path)) { 
-+
-+                                      if (!buffer_is_empty(df->bin_path)) {
-                                               /* a local socket + self spawning */
-                                               size_t pno;
--                                              
-+
-                                               if (df->min_procs > df->max_procs) df->max_procs = df->min_procs;
-                                               if (df->max_load_per_proc < 1) df->max_load_per_proc = 0;
--                                              
-+
-                                               if (s->debug) {
-                                                       log_error_write(srv, __FILE__, __LINE__, "ssbsdsbsdsd",
-                                                                       "--- scgi spawning local",
-@@ -1073,7 +1060,7 @@
-                                                                       "\n\tmin-procs:", df->min_procs,
-                                                                       "\n\tmax-procs:", df->max_procs);
-                                               }
--                                              
-+
-                                               for (pno = 0; pno < df->min_procs; pno++) {
-                                                       scgi_proc *proc;
-@@ -1088,7 +1075,7 @@
-                                                               buffer_append_string(proc->socket, "-");
-                                                               buffer_append_long(proc->socket, pno);
-                                                       }
--                                                      
-+
-                                                       if (s->debug) {
-                                                               log_error_write(srv, __FILE__, __LINE__, "ssdsbsdsd",
-                                                                               "--- scgi spawning",
-@@ -1096,53 +1083,53 @@
-                                                                               "\n\tsocket", df->unixsocket,
-                                                                               "\n\tcurrent:", pno, "/", df->min_procs);
-                                                       }
--                                                      
-+
-                                                       if (scgi_spawn_connection(srv, p, df, proc)) {
-                                                               log_error_write(srv, __FILE__, __LINE__, "s",
-                                                                               "[ERROR]: spawning fcgi failed.");
-                                                               return HANDLER_ERROR;
-                                                       }
--                                                      
-+
-                                                       proc->next = df->first;
-                                                       if (df->first)  df->first->prev = proc;
--                                                      
-+
-                                                       df->first = proc;
-                                               }
-                                       } else {
-                                               scgi_proc *fp;
--                                              
-+
-                                               fp = scgi_process_init();
-                                               fp->id = df->num_procs++;
-                                               df->max_id++;
-                                               df->active_procs++;
-                                               fp->state = PROC_STATE_RUNNING;
--                                              
-+
-                                               if (buffer_is_empty(df->unixsocket)) {
-                                                       fp->port = df->port;
-                                               } else {
-                                                       buffer_copy_string_buffer(fp->socket, df->unixsocket);
-                                               }
--                                              
-+
-                                               df->first = fp;
--                                              
-+
-                                               df->min_procs = 1;
-                                               df->max_procs = 1;
-                                       }
--                                      
-+
-                                       /* if extension already exists, take it */
-                                       scgi_extension_insert(s->exts, da_ext->key, df);
-                               }
-                       }
-               }
-       }
--      
-+
-       return HANDLER_GO_ON;
- }
- static int scgi_set_state(server *srv, handler_ctx *hctx, scgi_connection_state_t state) {
-       hctx->state = state;
-       hctx->state_timestamp = srv->cur_ts;
--      
-+
-       return 0;
- }
-@@ -1150,35 +1137,35 @@
- void scgi_connection_cleanup(server *srv, handler_ctx *hctx) {
-       plugin_data *p;
-       connection  *con;
--      
-+
-       if (NULL == hctx) return;
--      
-+
-       p    = hctx->plugin_data;
-       con  = hctx->remote_conn;
--      
-+
-       if (con->mode != p->id) {
--              WP();
-               return;
-       }
--      
--      if (hctx->fd != -1) {
--              fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
--              fdevent_unregister(srv->ev, hctx->fd);
--              close(hctx->fd);
-+
-+      if (hctx->sock->fd != -1) {
-+              fdevent_event_del(srv->ev, hctx->sock);
-+              fdevent_unregister(srv->ev, hctx->sock);
-+              closesocket(hctx->sock->fd);
-+              hctx->sock->fd = -1;
-               srv->cur_fds--;
-       }
--      
-+
-       if (hctx->host && hctx->proc) {
-               hctx->host->load--;
--              
-+
-               if (hctx->got_proc) {
-                       /* after the connect the process gets a load */
-                       hctx->proc->load--;
--                      
-+
-                       if (p->conf.debug) {
-                               log_error_write(srv, __FILE__, __LINE__, "sddb",
--                                              "release proc:", 
--                                              hctx->fd,
-+                                              "release proc:",
-+                                              hctx->sock->fd,
-                                               hctx->proc->pid, hctx->proc->socket);
-                       }
-               }
-@@ -1186,87 +1173,87 @@
-               scgi_proclist_sort_down(srv, hctx->host, hctx->proc);
-       }
--      
-+
-       handler_ctx_free(hctx);
--      con->plugin_ctx[p->id] = NULL;  
-+      con->plugin_ctx[p->id] = NULL;
- }
- static int scgi_reconnect(server *srv, handler_ctx *hctx) {
-       plugin_data *p    = hctx->plugin_data;
--      
--      /* child died 
--       * 
--       * 1. 
--       * 
-+
-+      /* child died
-+       *
-+       * 1.
-+       *
-        * connect was ok, connection was accepted
-        * but the php accept loop checks after the accept if it should die or not.
--       * 
--       * if yes we can only detect it at a write() 
--       * 
-+       *
-+       * if yes we can only detect it at a write()
-+       *
-        * next step is resetting this attemp and setup a connection again
--       * 
-+       *
-        * if we have more then 5 reconnects for the same request, die
--       * 
--       * 2. 
--       * 
-+       *
-+       * 2.
-+       *
-        * we have a connection but the child died by some other reason
--       * 
-+       *
-        */
--      
--      fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
--      fdevent_unregister(srv->ev, hctx->fd);
--      close(hctx->fd);
-+
-+      fdevent_event_del(srv->ev, hctx->sock);
-+      fdevent_unregister(srv->ev, hctx->sock);
-+      closesocket(hctx->sock->fd);
-       srv->cur_fds--;
--      
--      scgi_set_state(srv, hctx, FCGI_STATE_INIT);
--      
-+
-+      scgi_set_state(srv, hctx, SCGI_STATE_INIT);
-+
-       hctx->request_id = 0;
-       hctx->reconnects++;
--      
-+
-       if (p->conf.debug) {
-               log_error_write(srv, __FILE__, __LINE__, "sddb",
--                              "release proc:", 
--                              hctx->fd,
-+                              "release proc:",
-+                              hctx->sock->fd,
-                               hctx->proc->pid, hctx->proc->socket);
-       }
--      
-+
-       hctx->proc->load--;
-       scgi_proclist_sort_down(srv, hctx->host, hctx->proc);
--      
-+
-       return 0;
- }
- static handler_t scgi_connection_reset(server *srv, connection *con, void *p_d) {
-       plugin_data *p = p_d;
--      
-+
-       scgi_connection_cleanup(srv, con->plugin_ctx[p->id]);
--      
-+
-       return HANDLER_GO_ON;
- }
- static int scgi_env_add(buffer *env, const char *key, size_t key_len, const char *val, size_t val_len) {
-       size_t len;
--      
-+
-       if (!key || !val) return -1;
--      
-+
-       len = key_len + val_len + 2;
--      
-+
-       buffer_prepare_append(env, len);
--      /* include the NUL */   
-+      /* include the NUL */
-       memcpy(env->ptr + env->used, key, key_len + 1);
-       env->used += key_len + 1;
-       memcpy(env->ptr + env->used, val, val_len + 1);
-       env->used += val_len + 1;
--      
-+
-       return 0;
- }
- /**
-- * 
-+ *
-  * returns
-  *   -1 error
-  *    0 connected
-@@ -1280,24 +1267,21 @@
-       struct sockaddr_un scgi_addr_un;
- #endif
-       socklen_t servlen;
--      
-+
-       scgi_extension_host *host = hctx->host;
-       scgi_proc *proc   = hctx->proc;
--      int scgi_fd       = hctx->fd;
--      
-+      int scgi_fd       = hctx->sock->fd;
-+
-       memset(&scgi_addr, 0, sizeof(scgi_addr));
--      
-+
-       if (!buffer_is_empty(proc->socket)) {
- #ifdef HAVE_SYS_UN_H
-               /* use the unix domain socket */
-               scgi_addr_un.sun_family = AF_UNIX;
-               strcpy(scgi_addr_un.sun_path, proc->socket->ptr);
--#ifdef SUN_LEN
-+              
-               servlen = SUN_LEN(&scgi_addr_un);
--#else
--              /* stevens says: */
--              servlen = proc->socket->used + sizeof(scgi_addr_un.sun_family);
--#endif
-+
-               scgi_addr = (struct sockaddr *) &scgi_addr_un;
- #else
-               return -1;
-@@ -1305,105 +1289,105 @@
-       } else {
-               scgi_addr_in.sin_family = AF_INET;
-               if (0 == inet_aton(host->host->ptr, &(scgi_addr_in.sin_addr))) {
--                      log_error_write(srv, __FILE__, __LINE__, "sbs", 
--                                      "converting IP-adress failed for", host->host, 
-+                      log_error_write(srv, __FILE__, __LINE__, "sbs",
-+                                      "converting IP-adress failed for", host->host,
-                                       "\nBe sure to specify an IP address here");
--                      
-+
-                       return -1;
-               }
-               scgi_addr_in.sin_port = htons(proc->port);
-               servlen = sizeof(scgi_addr_in);
--              
-+
-               scgi_addr = (struct sockaddr *) &scgi_addr_in;
-       }
--      
-+
-       if (-1 == connect(scgi_fd, scgi_addr, servlen)) {
--              if (errno == EINPROGRESS || 
-+              if (errno == EINPROGRESS ||
-                   errno == EALREADY ||
-                   errno == EINTR) {
-                       if (hctx->conf.debug) {
--                              log_error_write(srv, __FILE__, __LINE__, "sd", 
-+                              log_error_write(srv, __FILE__, __LINE__, "sd",
-                                               "connect delayed, will continue later:", scgi_fd);
-                       }
--                      
-+
-                       return 1;
-               } else {
--                      log_error_write(srv, __FILE__, __LINE__, "sdsddb", 
--                                      "connect failed:", scgi_fd, 
-+                      log_error_write(srv, __FILE__, __LINE__, "sdsddb",
-+                                      "connect failed:", scgi_fd,
-                                       strerror(errno), errno,
-                                       proc->port, proc->socket);
-                       if (errno == EAGAIN) {
-                               /* this is Linux only */
--                              
--                              log_error_write(srv, __FILE__, __LINE__, "s", 
-+
-+                              log_error_write(srv, __FILE__, __LINE__, "s",
-                                               "If this happend on Linux: You have been run out of local ports. "
-                                               "Check the manual, section Performance how to handle this.");
--                      } 
--                      
-+                      }
-+
-                       return -1;
-               }
-       }
-       if (hctx->conf.debug > 1) {
--              log_error_write(srv, __FILE__, __LINE__, "sd", 
-+              log_error_write(srv, __FILE__, __LINE__, "sd",
-                               "connect succeeded: ", scgi_fd);
-       }
--      
-+
-       return 0;
- }
- static int scgi_env_add_request_headers(server *srv, connection *con, plugin_data *p) {
-       size_t i;
--      
-+
-       for (i = 0; i < con->request.headers->used; i++) {
-               data_string *ds;
--              
-+
-               ds = (data_string *)con->request.headers->data[i];
--              
-+
-               if (ds->value->used && ds->key->used) {
-                       size_t j;
-                       buffer_reset(srv->tmp_buf);
--                      
-+
-                       if (0 != strcasecmp(ds->key->ptr, "CONTENT-TYPE")) {
-                               BUFFER_COPY_STRING_CONST(srv->tmp_buf, "HTTP_");
-                               srv->tmp_buf->used--;
-                       }
--                      
-+
-                       buffer_prepare_append(srv->tmp_buf, ds->key->used + 2);
-                       for (j = 0; j < ds->key->used - 1; j++) {
--                              srv->tmp_buf->ptr[srv->tmp_buf->used++] = 
--                                      light_isalpha(ds->key->ptr[j]) ? 
-+                              srv->tmp_buf->ptr[srv->tmp_buf->used++] =
-+                                      light_isalpha(ds->key->ptr[j]) ?
-                                       ds->key->ptr[j] & ~32 : '_';
-                       }
-                       srv->tmp_buf->ptr[srv->tmp_buf->used++] = '\0';
--                      
-+
-                       scgi_env_add(p->scgi_env, CONST_BUF_LEN(srv->tmp_buf), CONST_BUF_LEN(ds->value));
-               }
-       }
--      
-+
-       for (i = 0; i < con->environment->used; i++) {
-               data_string *ds;
--              
-+
-               ds = (data_string *)con->environment->data[i];
--              
-+
-               if (ds->value->used && ds->key->used) {
-                       size_t j;
-                       buffer_reset(srv->tmp_buf);
--                      
-+
-                       buffer_prepare_append(srv->tmp_buf, ds->key->used + 2);
-                       for (j = 0; j < ds->key->used - 1; j++) {
--                              srv->tmp_buf->ptr[srv->tmp_buf->used++] = 
--                                      isalpha((unsigned char)ds->key->ptr[j]) ? 
-+                              srv->tmp_buf->ptr[srv->tmp_buf->used++] =
-+                                      isalpha((unsigned char)ds->key->ptr[j]) ?
-                                       toupper((unsigned char)ds->key->ptr[j]) : '_';
-                       }
-                       srv->tmp_buf->ptr[srv->tmp_buf->used++] = '\0';
--                      
-+
-                       scgi_env_add(p->scgi_env, CONST_BUF_LEN(srv->tmp_buf), CONST_BUF_LEN(ds->value));
-               }
-       }
--      
-+
-       return 0;
- }
-@@ -1415,20 +1399,20 @@
-       char b2[INET6_ADDRSTRLEN + 1];
- #endif
-       buffer *b;
--      
-+
-       plugin_data *p    = hctx->plugin_data;
-       scgi_extension_host *host= hctx->host;
-       connection *con   = hctx->remote_conn;
-       server_socket *srv_sock = con->srv_socket;
--      
-+
-       sock_addr our_addr;
-       socklen_t our_addr_len;
--      
-+
-       buffer_prepare_copy(p->scgi_env, 1024);
-       /* CGI-SPEC 6.1.2, FastCGI spec 6.3 and SCGI spec */
--              
-+
-       /* request.content_length < SSIZE_MAX, see request.c */
-       ltostr(buf, con->request.content_length);
-       scgi_env_add(p->scgi_env, CONST_STR_LEN("CONTENT_LENGTH"), buf, strlen(buf));
-@@ -1436,13 +1420,13 @@
-       scgi_env_add(p->scgi_env, CONST_STR_LEN("SERVER_SOFTWARE"), CONST_STR_LEN(PACKAGE_NAME"/"PACKAGE_VERSION));
--      
-+
-       if (con->server_name->used) {
-               scgi_env_add(p->scgi_env, CONST_STR_LEN("SERVER_NAME"), CONST_BUF_LEN(con->server_name));
-       } else {
- #ifdef HAVE_IPV6
--              s = inet_ntop(srv_sock->addr.plain.sa_family, 
--                            srv_sock->addr.plain.sa_family == AF_INET6 ? 
-+              s = inet_ntop(srv_sock->addr.plain.sa_family,
-+                            srv_sock->addr.plain.sa_family == AF_INET6 ?
-                             (const void *) &(srv_sock->addr.ipv6.sin6_addr) :
-                             (const void *) &(srv_sock->addr.ipv4.sin_addr),
-                             b2, sizeof(b2)-1);
-@@ -1451,47 +1435,47 @@
- #endif
-               scgi_env_add(p->scgi_env, CONST_STR_LEN("SERVER_NAME"), s, strlen(s));
-       }
--      
-+
-       scgi_env_add(p->scgi_env, CONST_STR_LEN("GATEWAY_INTERFACE"), CONST_STR_LEN("CGI/1.1"));
--      
--      ltostr(buf, 
-+
-+      ltostr(buf,
- #ifdef HAVE_IPV6
-              ntohs(srv_sock->addr.plain.sa_family ? srv_sock->addr.ipv6.sin6_port : srv_sock->addr.ipv4.sin_port)
- #else
-              ntohs(srv_sock->addr.ipv4.sin_port)
- #endif
-              );
--      
-+
-       scgi_env_add(p->scgi_env, CONST_STR_LEN("SERVER_PORT"), buf, strlen(buf));
--      
-+
-       /* get the server-side of the connection to the client */
-       our_addr_len = sizeof(our_addr);
--      
--      if (-1 == getsockname(con->fd, &(our_addr.plain), &our_addr_len)) {
-+
-+      if (-1 == getsockname(con->sock->fd, &(our_addr.plain), &our_addr_len)) {
-               s = inet_ntop_cache_get_ip(srv, &(srv_sock->addr));
-       } else {
-               s = inet_ntop_cache_get_ip(srv, &(our_addr));
-       }
-       scgi_env_add(p->scgi_env, CONST_STR_LEN("SERVER_ADDR"), s, strlen(s));
--      
--      ltostr(buf, 
-+
-+      ltostr(buf,
- #ifdef HAVE_IPV6
-              ntohs(con->dst_addr.plain.sa_family ? con->dst_addr.ipv6.sin6_port : con->dst_addr.ipv4.sin_port)
- #else
-              ntohs(con->dst_addr.ipv4.sin_port)
- #endif
-              );
--      
-+
-       scgi_env_add(p->scgi_env, CONST_STR_LEN("REMOTE_PORT"), buf, strlen(buf));
--      
-+
-       s = inet_ntop_cache_get_ip(srv, &(con->dst_addr));
-       scgi_env_add(p->scgi_env, CONST_STR_LEN("REMOTE_ADDR"), s, strlen(s));
--      
-+
-       if (!buffer_is_empty(con->authed_user)) {
-               scgi_env_add(p->scgi_env, CONST_STR_LEN("REMOTE_USER"),
-                            CONST_BUF_LEN(con->authed_user));
-       }
--      
-+
-       /*
-        * SCRIPT_NAME, PATH_INFO and PATH_TRANSLATED according to
-@@ -1500,12 +1484,12 @@
-        */
-       scgi_env_add(p->scgi_env, CONST_STR_LEN("SCRIPT_NAME"), CONST_BUF_LEN(con->uri.path));
--              
-+
-       if (!buffer_is_empty(con->request.pathinfo)) {
-               scgi_env_add(p->scgi_env, CONST_STR_LEN("PATH_INFO"), CONST_BUF_LEN(con->request.pathinfo));
--              
-+
-               /* PATH_TRANSLATED is only defined if PATH_INFO is set */
--              
-+
-               if (!buffer_is_empty(host->docroot)) {
-                       buffer_copy_string_buffer(p->path, host->docroot);
-               } else {
-@@ -1526,19 +1510,19 @@
-        */
-       if (!buffer_is_empty(host->docroot)) {
--              /* 
--               * rewrite SCRIPT_FILENAME 
--               * 
-+              /*
-+               * rewrite SCRIPT_FILENAME
-+               *
-                */
--              
-+
-               buffer_copy_string_buffer(p->path, host->docroot);
-               buffer_append_string_buffer(p->path, con->uri.path);
--              
-+
-               scgi_env_add(p->scgi_env, CONST_STR_LEN("SCRIPT_FILENAME"), CONST_BUF_LEN(p->path));
-               scgi_env_add(p->scgi_env, CONST_STR_LEN("DOCUMENT_ROOT"), CONST_BUF_LEN(host->docroot));
-       } else {
-               buffer_copy_string_buffer(p->path, con->physical.path);
--              
-+
-               scgi_env_add(p->scgi_env, CONST_STR_LEN("SCRIPT_FILENAME"), CONST_BUF_LEN(p->path));
-               scgi_env_add(p->scgi_env, CONST_STR_LEN("DOCUMENT_ROOT"), CONST_BUF_LEN(con->physical.doc_root));
-       }
-@@ -1551,32 +1535,32 @@
-       } else {
-               scgi_env_add(p->scgi_env, CONST_STR_LEN("QUERY_STRING"), CONST_STR_LEN(""));
-       }
--      
-+
-       s = get_http_method_name(con->request.http_method);
-       scgi_env_add(p->scgi_env, CONST_STR_LEN("REQUEST_METHOD"), s, strlen(s));
-       scgi_env_add(p->scgi_env, CONST_STR_LEN("REDIRECT_STATUS"), CONST_STR_LEN("200")); /* if php is compiled with --force-redirect */
-       s = get_http_version_name(con->request.http_version);
-       scgi_env_add(p->scgi_env, CONST_STR_LEN("SERVER_PROTOCOL"), s, strlen(s));
--      
-+
- #ifdef USE_OPENSSL
-       if (srv_sock->is_ssl) {
-               scgi_env_add(p->scgi_env, CONST_STR_LEN("HTTPS"), CONST_STR_LEN("on"));
-       }
- #endif
--      
-+
-       scgi_env_add_request_headers(srv, con, p);
-       b = chunkqueue_get_append_buffer(hctx->wb);
--      
-+
-       buffer_append_long(b, p->scgi_env->used);
-       buffer_append_string_len(b, CONST_STR_LEN(":"));
-       buffer_append_string_len(b, (const char *)p->scgi_env->ptr, p->scgi_env->used);
-       buffer_append_string_len(b, CONST_STR_LEN(","));
-       hctx->wb->bytes_in += b->used - 1;
--      
-+
-       if (con->request.content_length) {
--              chunkqueue *req_cq = con->request_content_queue;
-+              chunkqueue *req_cq = con->recv;
-               chunk *req_c;
-               off_t offset;
-@@ -1587,7 +1571,7 @@
-                       /* we announce toWrite octects
-                        * now take all the request_content chunk that we need to fill this request
--                       * */   
-+                       * */
-                       switch (req_c->type) {
-                       case FILE_CHUNK:
-@@ -1615,293 +1599,170 @@
-                               req_c->offset += weHave;
-                               req_cq->bytes_out += weHave;
--                              
-+
-                               hctx->wb->bytes_in += weHave;
-                               break;
-                       default:
-                               break;
-                       }
--                      
-+
-                       offset += weHave;
-               }
-       }
--      
-+
- #if 0
-       for (i = 0; i < hctx->write_buffer->used; i++) {
-               fprintf(stderr, "%02x ", hctx->write_buffer->ptr[i]);
-               if ((i+1) % 16 == 0) {
-                       size_t j;
-                       for (j = i-15; j <= i; j++) {
--                              fprintf(stderr, "%c", 
-+                              fprintf(stderr, "%c",
-                                       isprint((unsigned char)hctx->write_buffer->ptr[j]) ? hctx->write_buffer->ptr[j] : '.');
-                       }
-                       fprintf(stderr, "\n");
-               }
-       }
- #endif
--      
--      return 0;
--}
--static int scgi_response_parse(server *srv, connection *con, plugin_data *p, buffer *in, int eol) {
--      char *ns;
--      const char *s;
--      int line = 0;
--      
--      UNUSED(srv);
--      
--      buffer_copy_string_buffer(p->parse_response, in);
--      
--      for (s = p->parse_response->ptr; 
--           NULL != (ns = (eol == EOL_RN ? strstr(s, "\r\n") : strchr(s, '\n'))); 
--           s = ns + (eol == EOL_RN ? 2 : 1), line++) {
--              const char *key, *value;
--              int key_len;
--              data_string *ds;
--              
--              ns[0] = '\0';
--              
--              if (line == 0 && 
--                  0 == strncmp(s, "HTTP/1.", 7)) {
--                      /* non-parsed header ... we parse them anyway */
--                      
--                      if ((s[7] == '1' ||
--                           s[7] == '0') &&
--                          s[8] == ' ') {
--                              int status;
--                              /* after the space should be a status code for us */
--                              
--                              status = strtol(s+9, NULL, 10);
--                              
--                              if (con->http_status >= 100 &&
--                                  con->http_status < 1000) {
--                                      /* we expected 3 digits and didn't got them */
--                                      con->parsed_response |= HTTP_STATUS;
--                                      con->http_status = status;
--                              }
--                      }
--              } else {
--              
--                      key = s;
--                      if (NULL == (value = strchr(s, ':'))) {
--                              /* we expect: "<key>: <value>\r\n" */
--                              continue;
--                      }
--                      
--                      key_len = value - key;
--                      value += 1;
--                      
--                      /* skip LWS */
--                      while (*value == ' ' || *value == '\t') value++;
--                      
--                      if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
--                              ds = data_response_init();
--                      }
--                      buffer_copy_string_len(ds->key, key, key_len);
--                      buffer_copy_string(ds->value, value);
--                      
--                      array_insert_unique(con->response.headers, (data_unset *)ds);
--                      
--                      switch(key_len) {
--                      case 4:
--                              if (0 == strncasecmp(key, "Date", key_len)) {
--                                      con->parsed_response |= HTTP_DATE;
--                              }
--                              break;
--                      case 6:
--                              if (0 == strncasecmp(key, "Status", key_len)) {
--                                      con->http_status = strtol(value, NULL, 10);
--                                      con->parsed_response |= HTTP_STATUS;
--                              }
--                              break;
--                      case 8:
--                              if (0 == strncasecmp(key, "Location", key_len)) {
--                                      con->parsed_response |= HTTP_LOCATION;
--                              }
--                              break;
--                      case 10:
--                              if (0 == strncasecmp(key, "Connection", key_len)) {
--                                      con->response.keep_alive = (0 == strcasecmp(value, "Keep-Alive")) ? 1 : 0;
--                                      con->parsed_response |= HTTP_CONNECTION;
--                              }
--                              break;
--                      case 14:
--                              if (0 == strncasecmp(key, "Content-Length", key_len)) {
--                                      con->response.content_length = strtol(value, NULL, 10);
--                                      con->parsed_response |= HTTP_CONTENT_LENGTH;
--                              }
--                              break;
--                      default:
--                              break;
--                      }
--              }
--      }
--      
--      /* CGI/1.1 rev 03 - 7.2.1.2 */
--      if ((con->parsed_response & HTTP_LOCATION) &&
--          !(con->parsed_response & HTTP_STATUS)) {
--              con->http_status = 302;
--      }
--      
-       return 0;
- }
--
- static int scgi_demux_response(server *srv, handler_ctx *hctx) {
-       plugin_data *p    = hctx->plugin_data;
-       connection  *con  = hctx->remote_conn;
--      
--      while(1) {
--              int n;
--              
--              buffer_prepare_copy(hctx->response, 1024);
--              if (-1 == (n = read(hctx->fd, hctx->response->ptr, hctx->response->size - 1))) {
--                      if (errno == EAGAIN || errno == EINTR) {
--                              /* would block, wait for signal */
--                              return 0;
--                      }
--                      /* error */
--                      log_error_write(srv, __FILE__, __LINE__, "sdd", strerror(errno), con->fd, hctx->fd);
--                      return -1;
--              }
--              
--              if (n == 0) {
--                      /* read finished */
--                      
--                      con->file_finished = 1;
--                      
--                      /* send final chunk */
--                      http_chunk_append_mem(srv, con, NULL, 0);
--                      joblist_append(srv, con);
--                      
-+      chunk *c;
-+
-+      switch(srv->network_backend_read(srv, con, hctx->sock, hctx->rb)) {
-+      case NETWORK_STATUS_SUCCESS:
-+              /* we got content */
-+              break;
-+      case NETWORK_STATUS_WAIT_FOR_EVENT:
-+              /* the ioctl will return WAIT_FOR_EVENT on a read */
-+              if (0 == con->file_started) return -1;
-+      case NETWORK_STATUS_CONNECTION_CLOSE:
-+              /* we are done, get out of here */
-+              con->send->is_closed = 1;
-+
-+              /* close the chunk-queue with a empty chunk */
-+
-+              return 1;
-+      default:
-+              /* oops */
-+              return -1;
-+      }
-+
-+      /* looks like we got some content
-+      *
-+      * split off the header from the incoming stream
-+      */
-+
-+      if (hctx->state == SCGI_STATE_RESPONSE_HEADER) {
-+              size_t i;
-+              int have_content_length = 0;
-+
-+              http_response_reset(p->resp);
-+
-+              /* the response header is not fully received yet,
-+              *
-+              * extract the http-response header from the rb-cq
-+              */
-+              switch (http_response_parse_cq(hctx->rb, p->resp)) {
-+              case PARSE_ERROR:
-+                      /* parsing failed */
-+
-+                      con->http_status = 502; /* Bad Gateway */
-                       return 1;
--              }
--              
--              hctx->response->ptr[n] = '\0';
--              hctx->response->used = n+1;
--              
--              /* split header from body */
--              
--              if (con->file_started == 0) {
--                      char *c;
--                      int in_header = 0;
--                      int header_end = 0;
--                      int cp, eol = EOL_UNSET;
--                      size_t used = 0;
--                      
--                      buffer_append_string_buffer(hctx->response_header, hctx->response);
--                      
--                      /* nph (non-parsed headers) */
--                      if (0 == strncmp(hctx->response_header->ptr, "HTTP/1.", 7)) in_header = 1;
--                      
--                      /* search for the \r\n\r\n or \n\n in the string */
--                      for (c = hctx->response_header->ptr, cp = 0, used = hctx->response_header->used - 1; used; c++, cp++, used--) {
--                              if (*c == ':') in_header = 1;
--                              else if (*c == '\n') {
--                                      if (in_header == 0) {
--                                              /* got a response without a response header */
--                                              
--                                              c = NULL;
--                                              header_end = 1;
--                                              break;
--                                      }
--                                      
--                                      if (eol == EOL_UNSET) eol = EOL_N;
--                                      
--                                      if (*(c+1) == '\n') {
--                                              header_end = 1;
--                                              break;
--                                      }
--                                      
--                              } else if (used > 1 && *c == '\r' && *(c+1) == '\n') {
--                                      if (in_header == 0) {
--                                              /* got a response without a response header */
--                                              
--                                              c = NULL;
--                                              header_end = 1;
--                                              break;
--                                      }
--                                      
--                                      if (eol == EOL_UNSET) eol = EOL_RN;
--                                      
--                                      if (used > 3 &&
--                                          *(c+2) == '\r' && 
--                                          *(c+3) == '\n') {
--                                              header_end = 1;
--                                              break;
--                                      }
--                                      
--                                      /* skip the \n */
--                                      c++;
--                                      cp++;
--                                      used--;
-+              case PARSE_NEED_MORE:
-+                      return 0;
-+              case PARSE_SUCCESS:
-+                      con->http_status = p->resp->status;
-+
-+                      chunkqueue_remove_finished_chunks(hctx->rb);
-+
-+                      /* copy the http-headers */
-+                      for (i = 0; i < p->resp->headers->used; i++) {
-+                              const char *ign[] = { "Status", "Connection", NULL };
-+                              size_t j;
-+                              data_string *ds;
-+
-+                              data_string *header = (data_string *)p->resp->headers->data[i];
-+
-+                              /* some headers are ignored by default */
-+                              for (j = 0; ign[j]; j++) {
-+                                      if (0 == strcasecmp(ign[j], header->key->ptr)) break;
-                               }
--                      }
--                      
--                      if (header_end) {
--                              if (c == NULL) {
--                                      /* no header, but a body */
--                                      
--                                      if (con->request.http_version == HTTP_VERSION_1_1) {
--                                              con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
--                                      }
--                                      
--                                      http_chunk_append_mem(srv, con, hctx->response_header->ptr, hctx->response_header->used);
--                                      joblist_append(srv, con);
--                              } else {
--                                      size_t hlen = c - hctx->response_header->ptr + (eol == EOL_RN ? 4 : 2);
--                                      size_t blen = hctx->response_header->used - hlen - 1;
--                              
--                                      /* a small hack: terminate after at the second \r */
--                                      hctx->response_header->used = hlen + 1 - (eol == EOL_RN ? 2 : 1);
--                                      hctx->response_header->ptr[hlen - (eol == EOL_RN ? 2 : 1)] = '\0';
--                              
--                                      /* parse the response header */
--                                      scgi_response_parse(srv, con, p, hctx->response_header, eol);
--                                      
--                                      /* enable chunked-transfer-encoding */
--                                      if (con->request.http_version == HTTP_VERSION_1_1 &&
--                                          !(con->parsed_response & HTTP_CONTENT_LENGTH)) {
--                                              con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
--                                      }
--                                      
--                                      if ((hctx->response->used != hlen) && blen > 0) {
--                                              http_chunk_append_mem(srv, con, c + (eol == EOL_RN ? 4: 2), blen + 1);
--                                              joblist_append(srv, con);
--                                      }
-+                              if (ign[j]) continue;
-+
-+                              if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("Location"))) {
-+                                      /* CGI/1.1 rev 03 - 7.2.1.2 */
-+                                      if (con->http_status == 0) con->http_status = 302;
-+                              } else if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("Content-Length"))) {
-+                                      have_content_length = 1;
-                               }
-                               
--                              con->file_started = 1;
-+                              if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
-+                                      ds = data_response_init();
-+                              }
-+                              buffer_copy_string_buffer(ds->key, header->key);
-+                              buffer_copy_string_buffer(ds->value, header->value);
-+
-+                              array_insert_unique(con->response.headers, (data_unset *)ds);
-                       }
--              } else {
--                      http_chunk_append_mem(srv, con, hctx->response->ptr, hctx->response->used);
--                      joblist_append(srv, con);
-+
-+                      con->file_started = 1;
-+
-+                      if (con->request.http_version == HTTP_VERSION_1_1 &&
-+                          !have_content_length) {
-+                              con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
-+                      }
-+
-+                      hctx->state = SCGI_STATE_RESPONSE_CONTENT;
-+                      break;
-               }
--              
--#if 0         
--              log_error_write(srv, __FILE__, __LINE__, "ddss", con->fd, hctx->fd, connection_get_state(con->state), b->ptr);
--#endif
-       }
--      
-+
-+      /* FIXME: pass the response-header to the other plugins to
-+      * setup the filter-queue
-+      *
-+      * - use next-queue instead of con->write_queue
-+      */
-+
-+      assert(hctx->state == SCGI_STATE_RESPONSE_CONTENT);
-+
-+      /* FIXME: if we have a content-length or chunked-encoding
-+      * handle it.
-+      *
-+      * for now we wait for EOF on the socket */
-+
-+      /* copy the content to the next cq */
-+      for (c = hctx->rb->first; c; c = c->next) {
-+              chunkqueue_append_mem(con->send, c->mem->ptr + c->offset, c->mem->used - c->offset);
-+
-+              c->offset = c->mem->used - 1;
-+      }
-+
-+      chunkqueue_remove_finished_chunks(hctx->rb);
-+      joblist_append(srv, con);
-+
-       return 0;
- }
- int scgi_proclist_sort_up(server *srv, scgi_extension_host *host, scgi_proc *proc) {
-       scgi_proc *p;
--      
-+
-       UNUSED(srv);
--      
--      /* we have been the smallest of the current list 
--       * and we want to insert the node sorted as soon 
-+
-+      /* we have been the smallest of the current list
-+       * and we want to insert the node sorted as soon
-        * possible
-        *
--       * 1 0 0 0 1 1 1 
--       * |      ^ 
-+       * 1 0 0 0 1 1 1
-+       * |      ^
-        * |      |
-        * +------+
--       * 
-+       *
-        */
-       /* nothing to sort, only one element */
-@@ -1909,9 +1770,9 @@
-       for (p = proc; p->next && p->next->load < proc->load; p = p->next);
--      /* no need to move something 
-+      /* no need to move something
-        *
--       * 1 2 2 2 3 3 3 
-+       * 1 2 2 2 3 3 3
-        * ^
-        * |
-        * +
-@@ -1930,16 +1791,16 @@
-       if (proc->prev) proc->prev->next = proc->next;
-       if (proc->next) proc->next->prev = proc->prev;
--      
-+
-       /* proc should be right of p */
--      
-+
-       proc->next = p->next;
-       proc->prev = p;
-       if (p->next) p->next->prev = proc;
-       p->next = proc;
- #if 0
-       for(p = host->first; p; p = p->next) {
--              log_error_write(srv, __FILE__, __LINE__, "dd", 
-+              log_error_write(srv, __FILE__, __LINE__, "dd",
-                               p->pid, p->load);
-       }
- #else
-@@ -1951,21 +1812,21 @@
- int scgi_proclist_sort_down(server *srv, scgi_extension_host *host, scgi_proc *proc) {
-       scgi_proc *p;
--      
-+
-       UNUSED(srv);
--      
--      /* we have been the smallest of the current list 
--       * and we want to insert the node sorted as soon 
-+
-+      /* we have been the smallest of the current list
-+       * and we want to insert the node sorted as soon
-        * possible
-        *
--       *  0 0 0 0 1 0 1 
-+       *  0 0 0 0 1 0 1
-        * ^          |
-        * |          |
-        * +----------+
-        *
-        *
-        * the basic is idea is:
--       * - the last active scgi process should be still 
-+       * - the last active scgi process should be still
-        *   in ram and is not swapped out yet
-        * - processes that are not reused will be killed
-        *   after some time by the trigger-handler
-@@ -1975,7 +1836,7 @@
-        *   ice-cold processes are propably unused since more
-        *   than 'unused-timeout', are swaped out and won't be
-        *   reused in the next seconds anyway.
--       * 
-+       *
-        */
-       /* nothing to sort, only one element */
-@@ -1984,16 +1845,16 @@
-       for (p = host->first; p != proc && p->load < proc->load; p = p->next);
--      /* no need to move something 
-+      /* no need to move something
-        *
--       * 1 2 2 2 3 3 3 
-+       * 1 2 2 2 3 3 3
-        * ^
-        * |
-        * +
-        *
-        */
-       if (p == proc) return 0;
--      
-+
-       /* we have to move left. If we are already the first element
-        * we are done */
-       if (host->first == proc) return 0;
-@@ -2009,9 +1870,9 @@
-       p->prev = proc;
-       if (proc->prev == NULL) host->first = proc;
--#if 0 
-+#if 0
-       for(p = host->first; p; p = p->next) {
--              log_error_write(srv, __FILE__, __LINE__, "dd", 
-+              log_error_write(srv, __FILE__, __LINE__, "dd",
-                               p->pid, p->load);
-       }
- #else
-@@ -2023,41 +1884,42 @@
- static int scgi_restart_dead_procs(server *srv, plugin_data *p, scgi_extension_host *host) {
-       scgi_proc *proc;
--      
-+
-       for (proc = host->first; proc; proc = proc->next) {
-               if (p->conf.debug) {
--                      log_error_write(srv, __FILE__, __LINE__,  "sbdbdddd", 
--                                      "proc:", 
--                                      host->host, proc->port, 
-+                      log_error_write(srv, __FILE__, __LINE__,  "sbdbdddd",
-+                                      "proc:",
-+                                      host->host, proc->port,
-                                       proc->socket,
-                                       proc->state,
-                                       proc->is_local,
-                                       proc->load,
-                                       proc->pid);
-               }
--              
-+
-               if (0 == proc->is_local) {
--                      /* 
--                       * external servers might get disabled 
--                       * 
--                       * enable the server again, perhaps it is back again 
-+                      /*
-+                       * external servers might get disabled
-+                       *
-+                       * enable the server again, perhaps it is back again
-                        */
--                      
-+
-                       if ((proc->state == PROC_STATE_DISABLED) &&
-                           (srv->cur_ts - proc->disable_ts > host->disable_time)) {
-                               proc->state = PROC_STATE_RUNNING;
-                               host->active_procs++;
--                              
--                              log_error_write(srv, __FILE__, __LINE__,  "sbdb", 
--                                              "fcgi-server re-enabled:", 
--                                              host->host, host->port, 
-+
-+                              log_error_write(srv, __FILE__, __LINE__,  "sbdb",
-+                                              "fcgi-server re-enabled:",
-+                                              host->host, host->port,
-                                               host->unixsocket);
-                       }
-               } else {
-                       /* the child should not terminate at all */
-                       int status;
--                      
-+
-                       if (proc->state == PROC_STATE_DIED_WAIT_FOR_PID) {
-+#ifndef _WIN32
-                               switch(waitpid(proc->pid, &status, WNOHANG)) {
-                               case 0:
-                                       /* child is still alive */
-@@ -2067,33 +1929,34 @@
-                               default:
-                                       if (WIFEXITED(status)) {
- #if 0
--                                              log_error_write(srv, __FILE__, __LINE__, "sdsd", 
-+                                              log_error_write(srv, __FILE__, __LINE__, "sdsd",
-                                                               "child exited, pid:", proc->pid,
-                                                               "status:", WEXITSTATUS(status));
- #endif
-                                       } else if (WIFSIGNALED(status)) {
--                                              log_error_write(srv, __FILE__, __LINE__, "sd", 
--                                                              "child signaled:", 
-+                                              log_error_write(srv, __FILE__, __LINE__, "sd",
-+                                                              "child signaled:",
-                                                               WTERMSIG(status));
-                                       } else {
--                                              log_error_write(srv, __FILE__, __LINE__, "sd", 
--                                                              "child died somehow:", 
-+                                              log_error_write(srv, __FILE__, __LINE__, "sd",
-+                                                              "child died somehow:",
-                                                               status);
-                                       }
--                                      
-+
-                                       proc->state = PROC_STATE_DIED;
-                                       break;
-                               }
-+#endif
-                       }
--                      
--                      /* 
-+
-+                      /*
-                        * local servers might died, but we restart them
--                       * 
-+                       *
-                        */
-                       if (proc->state == PROC_STATE_DIED &&
-                           proc->load == 0) {
-                               /* restart the child */
--                              
-+
-                               if (p->conf.debug) {
-                                       log_error_write(srv, __FILE__, __LINE__, "ssdsbsdsd",
-                                                       "--- scgi spawning",
-@@ -2101,18 +1964,18 @@
-                                                       "\n\tsocket", host->unixsocket,
-                                                       "\n\tcurrent:", 1, "/", host->min_procs);
-                               }
--                              
-+
-                               if (scgi_spawn_connection(srv, p, host, proc)) {
-                                       log_error_write(srv, __FILE__, __LINE__, "s",
-                                                       "ERROR: spawning fcgi failed.");
-                                       return HANDLER_ERROR;
-                               }
--                              
-+
-                               scgi_proclist_sort_down(srv, host, proc);
-                       }
-               }
-       }
--      
-+
-       return 0;
- }
-@@ -2121,13 +1984,13 @@
-       plugin_data *p    = hctx->plugin_data;
-       scgi_extension_host *host= hctx->host;
-       connection *con   = hctx->remote_conn;
--      
-+
-       int ret;
--      /* sanity check */      
-+      /* sanity check */
-       if (!host ||
-           ((!host->host->used || !host->port) && !host->unixsocket->used)) {
--              log_error_write(srv, __FILE__, __LINE__, "sxddd", 
-+              log_error_write(srv, __FILE__, __LINE__, "sxddd",
-                               "write-req: error",
-                               host,
-                               host->host->used,
-@@ -2135,259 +1998,260 @@
-                               host->unixsocket->used);
-               return HANDLER_ERROR;
-       }
--      
-+
-       switch(hctx->state) {
--      case FCGI_STATE_INIT:
-+      case SCGI_STATE_INIT:
-               ret = host->unixsocket->used ? AF_UNIX : AF_INET;
--              
--              if (-1 == (hctx->fd = socket(ret, SOCK_STREAM, 0))) {
-+
-+              if (-1 == (hctx->sock->fd = socket(ret, SOCK_STREAM, 0))) {
-                       if (errno == EMFILE ||
-                           errno == EINTR) {
--                              log_error_write(srv, __FILE__, __LINE__, "sd", 
--                                              "wait for fd at connection:", con->fd);
--                              
-+                              log_error_write(srv, __FILE__, __LINE__, "sd",
-+                                              "wait for fd at connection:", con->sock->fd);
-+
-                               return HANDLER_WAIT_FOR_FD;
-                       }
--                      
--                      log_error_write(srv, __FILE__, __LINE__, "ssdd", 
-+
-+                      log_error_write(srv, __FILE__, __LINE__, "ssdd",
-                                       "socket failed:", strerror(errno), srv->cur_fds, srv->max_fds);
-                       return HANDLER_ERROR;
-               }
--              hctx->fde_ndx = -1;
--              
-+              hctx->sock->fde_ndx = -1;
-+
-               srv->cur_fds++;
--              
--              fdevent_register(srv->ev, hctx->fd, scgi_handle_fdevent, hctx);
--              
--              if (-1 == fdevent_fcntl_set(srv->ev, hctx->fd)) {
--                      log_error_write(srv, __FILE__, __LINE__, "ss", 
-+
-+              fdevent_register(srv->ev, hctx->sock, scgi_handle_fdevent, hctx);
-+
-+              if (-1 == fdevent_fcntl_set(srv->ev, hctx->sock)) {
-+                      log_error_write(srv, __FILE__, __LINE__, "ss",
-                                       "fcntl failed: ", strerror(errno));
--                      
-+
-                       return HANDLER_ERROR;
-               }
--              
-+
-               /* fall through */
--      case FCGI_STATE_CONNECT:
--              if (hctx->state == FCGI_STATE_INIT) {
--                      for (hctx->proc = hctx->host->first; 
--                           hctx->proc && hctx->proc->state != PROC_STATE_RUNNING; 
-+      case SCGI_STATE_CONNECT:
-+              if (hctx->state == SCGI_STATE_INIT) {
-+                      for (hctx->proc = hctx->host->first;
-+                           hctx->proc && hctx->proc->state != PROC_STATE_RUNNING;
-                            hctx->proc = hctx->proc->next);
--                      
-+
-                       /* all childs are dead */
-                       if (hctx->proc == NULL) {
--                              hctx->fde_ndx = -1;
--                              
-+                              hctx->sock->fde_ndx = -1;
-+
-                               return HANDLER_ERROR;
-                       }
--                      
-+
-                       if (hctx->proc->is_local) {
-                               hctx->pid = hctx->proc->pid;
-                       }
--                      
-+
-                       switch (scgi_establish_connection(srv, hctx)) {
-                       case 1:
--                              scgi_set_state(srv, hctx, FCGI_STATE_CONNECT);
--                              
-+                              scgi_set_state(srv, hctx, SCGI_STATE_CONNECT);
-+
-                               /* connection is in progress, wait for an event and call getsockopt() below */
--                              
--                              fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
--                              
-+
-+                              fdevent_event_add(srv->ev, hctx->sock, FDEVENT_OUT);
-+
-                               return HANDLER_WAIT_FOR_EVENT;
-                       case -1:
-                               /* if ECONNREFUSED choose another connection -> FIXME */
--                              hctx->fde_ndx = -1;
--                              
-+                              hctx->sock->fde_ndx = -1;
-+
-                               return HANDLER_ERROR;
-                       default:
-                               /* everything is ok, go on */
-                               break;
-                       }
--                      
-+
-               } else {
-                       int socket_error;
-                       socklen_t socket_error_len = sizeof(socket_error);
--                      
-+
-                       /* try to finish the connect() */
--                      if (0 != getsockopt(hctx->fd, SOL_SOCKET, SO_ERROR, &socket_error, &socket_error_len)) {
--                              log_error_write(srv, __FILE__, __LINE__, "ss", 
-+                      if (0 != getsockopt(hctx->sock->fd, SOL_SOCKET, SO_ERROR, &socket_error, &socket_error_len)) {
-+                              log_error_write(srv, __FILE__, __LINE__, "ss",
-                                               "getsockopt failed:", strerror(errno));
--                              
-+
-                               return HANDLER_ERROR;
-                       }
-                       if (socket_error != 0) {
-                               if (!hctx->proc->is_local || p->conf.debug) {
-                                       /* local procs get restarted */
--                                      
-+
-                                       log_error_write(srv, __FILE__, __LINE__, "ss",
--                                                      "establishing connection failed:", strerror(socket_error), 
-+                                                      "establishing connection failed:", strerror(socket_error),
-                                                       "port:", hctx->proc->port);
-                               }
--                              
-+
-                               return HANDLER_ERROR;
-                       }
-               }
--              
-+
-               /* ok, we have the connection */
--              
-+
-               hctx->proc->load++;
-               hctx->proc->last_used = srv->cur_ts;
-               hctx->got_proc = 1;
--              
-+
-               if (p->conf.debug) {
-                       log_error_write(srv, __FILE__, __LINE__, "sddbdd",
--                                      "got proc:", 
--                                      hctx->fd,
--                                      hctx->proc->pid, 
--                                      hctx->proc->socket, 
-+                                      "got proc:",
-+                                      hctx->sock->fd,
-+                                      hctx->proc->pid,
-+                                      hctx->proc->socket,
-                                       hctx->proc->port,
-                                       hctx->proc->load);
-               }
-               /* move the proc-list entry down the list */
-               scgi_proclist_sort_up(srv, hctx->host, hctx->proc);
--              
--              scgi_set_state(srv, hctx, FCGI_STATE_PREPARE_WRITE);
-+
-+              scgi_set_state(srv, hctx, SCGI_STATE_PREPARE_WRITE);
-               /* fall through */
--      case FCGI_STATE_PREPARE_WRITE:
-+      case SCGI_STATE_PREPARE_WRITE:
-               scgi_create_env(srv, hctx);
--              
--              scgi_set_state(srv, hctx, FCGI_STATE_WRITE);
--              
-+
-+              scgi_set_state(srv, hctx, SCGI_STATE_WRITE);
-+
-               /* fall through */
--      case FCGI_STATE_WRITE:
--              ret = srv->network_backend_write(srv, con, hctx->fd, hctx->wb); 
-+      case SCGI_STATE_WRITE:
-+              ret = srv->network_backend_write(srv, con, hctx->sock, hctx->wb);
-               chunkqueue_remove_finished_chunks(hctx->wb);
--      
-+
-               if (-1 == ret) {
-                       if (errno == ENOTCONN) {
--                              /* the connection got dropped after accept() 
--                               * 
--                               * this is most of the time a PHP which dies 
-+                              /* the connection got dropped after accept()
-+                               *
-+                               * this is most of the time a PHP which dies
-                                * after PHP_FCGI_MAX_REQUESTS
--                               * 
--                               */ 
-+                               *
-+                               */
-                               if (hctx->wb->bytes_out == 0 &&
-                                   hctx->reconnects < 5) {
--                                      usleep(10000); /* take away the load of the webserver 
--                                                      * to let the php a chance to restart 
-+#ifndef _WIN32
-+                                      usleep(10000); /* take away the load of the webserver
-+                                                      * to let the php a chance to restart
-                                                       */
--                                      
-+#endif
-                                       scgi_reconnect(srv, hctx);
--                              
-+
-                                       return HANDLER_WAIT_FOR_FD;
-                               }
--                              
-+
-                               /* not reconnected ... why
--                               * 
-+                               *
-                                * far@#lighttpd report this for FreeBSD
--                               * 
-+                               *
-                                */
--                              
--                              log_error_write(srv, __FILE__, __LINE__, "ssdsd", 
-+
-+                              log_error_write(srv, __FILE__, __LINE__, "ssosd",
-                                               "[REPORT ME] connection was dropped after accept(). reconnect() denied:",
-                                               "write-offset:", hctx->wb->bytes_out,
-                                               "reconnect attempts:", hctx->reconnects);
--                              
-+
-                               return HANDLER_ERROR;
-                       }
--                      
-+
-                       if ((errno != EAGAIN) &&
-                           (errno != EINTR)) {
--                              
--                              log_error_write(srv, __FILE__, __LINE__, "ssd", 
-+
-+                              log_error_write(srv, __FILE__, __LINE__, "ssd",
-                                               "write failed:", strerror(errno), errno);
--                              
-+
-                               return HANDLER_ERROR;
-                       } else {
--                              fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
--                              
-+                              fdevent_event_add(srv->ev, hctx->sock, FDEVENT_OUT);
-+
-                               return HANDLER_WAIT_FOR_EVENT;
-                       }
-               }
--              
-+
-               if (hctx->wb->bytes_out == hctx->wb->bytes_in) {
-                       /* we don't need the out event anymore */
--                      fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
--                      fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
--                      scgi_set_state(srv, hctx, FCGI_STATE_READ);
-+                      fdevent_event_del(srv->ev, hctx->sock);
-+                      fdevent_event_add(srv->ev, hctx->sock, FDEVENT_IN);
-+                      scgi_set_state(srv, hctx, SCGI_STATE_RESPONSE_HEADER);
-               } else {
--                      fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
--                      
-+                      fdevent_event_add(srv->ev, hctx->sock, FDEVENT_OUT);
-+
-                       return HANDLER_WAIT_FOR_EVENT;
-               }
--              
-+
-               break;
--      case FCGI_STATE_READ:
-+      case SCGI_STATE_RESPONSE_HEADER:
-               /* waiting for a response */
-               break;
-       default:
-               log_error_write(srv, __FILE__, __LINE__, "s", "(debug) unknown state");
-               return HANDLER_ERROR;
-       }
--      
-+
-       return HANDLER_WAIT_FOR_EVENT;
- }
- SUBREQUEST_FUNC(mod_scgi_handle_subrequest) {
-       plugin_data *p = p_d;
--      
-+
-       handler_ctx *hctx = con->plugin_ctx[p->id];
-       scgi_proc *proc;
-       scgi_extension_host *host;
--      
-+
-       if (NULL == hctx) return HANDLER_GO_ON;
--      
-+
-       /* not my job */
-       if (con->mode != p->id) return HANDLER_GO_ON;
--      
-+
-       /* ok, create the request */
-       switch(scgi_write_request(srv, hctx)) {
-       case HANDLER_ERROR:
-               proc = hctx->proc;
-               host = hctx->host;
--              
--              if (proc && 
-+
-+              if (proc &&
-                   0 == proc->is_local &&
-                   proc->state != PROC_STATE_DISABLED) {
-                       /* only disable remote servers as we don't manage them*/
--                      
--                      log_error_write(srv, __FILE__, __LINE__,  "sbdb", "fcgi-server disabled:", 
-+
-+                      log_error_write(srv, __FILE__, __LINE__,  "sbdb", "fcgi-server disabled:",
-                                       host->host,
-                                       proc->port,
-                                       proc->socket);
--                      
-+
-                       /* disable this server */
-                       proc->disable_ts = srv->cur_ts;
-                       proc->state = PROC_STATE_DISABLED;
-                       host->active_procs--;
-               }
--              
--              if (hctx->state == FCGI_STATE_INIT ||
--                  hctx->state == FCGI_STATE_CONNECT) {
--                      /* connect() or getsockopt() failed, 
--                       * restart the request-handling 
-+
-+              if (hctx->state == SCGI_STATE_INIT ||
-+                  hctx->state == SCGI_STATE_CONNECT) {
-+                      /* connect() or getsockopt() failed,
-+                       * restart the request-handling
-                        */
-                       if (proc && proc->is_local) {
-                               if (p->conf.debug) {
--                                      log_error_write(srv, __FILE__, __LINE__,  "sbdb", "connect() to scgi failed, restarting the request-handling:", 
-+                                      log_error_write(srv, __FILE__, __LINE__,  "sbdb", "connect() to scgi failed, restarting the request-handling:",
-                                                       host->host,
-                                                       proc->port,
-                                                       proc->socket);
-                               }
--                              /* 
-+                              /*
-                                * several hctx might reference the same proc
--                               * 
-+                               *
-                                * Only one of them should mark the proc as dead all the other
-                                * ones should just take a new one.
--                               * 
-+                               *
-                                * If a new proc was started with the old struct this might lead
-                                * the mark a perfect proc as dead otherwise
--                               * 
-+                               *
-                                */
-                               if (proc->state == PROC_STATE_RUNNING &&
-                                   hctx->pid == proc->pid) {
-@@ -2395,25 +2259,25 @@
-                               }
-                       }
-                       scgi_restart_dead_procs(srv, p, host);
--                      
-+
-                       scgi_connection_cleanup(srv, hctx);
--                      
-+
-                       buffer_reset(con->physical.path);
-                       con->mode = DIRECT;
-                       joblist_append(srv, con);
--                      
--                      /* mis-using HANDLER_WAIT_FOR_FD to break out of the loop 
--                       * and hope that the childs will be restarted 
--                       * 
-+
-+                      /* mis-using HANDLER_WAIT_FOR_FD to break out of the loop
-+                       * and hope that the childs will be restarted
-+                       *
-                        */
-                       return HANDLER_WAIT_FOR_FD;
-               } else {
-                       scgi_connection_cleanup(srv, hctx);
--                      
-+
-                       buffer_reset(con->physical.path);
-                       con->mode = DIRECT;
-                       con->http_status = 503;
--                      
-+
-                       return HANDLER_FINISHED;
-               }
-       case HANDLER_WAIT_FOR_EVENT:
-@@ -2433,23 +2297,23 @@
- static handler_t scgi_connection_close(server *srv, handler_ctx *hctx) {
-       plugin_data *p;
-       connection  *con;
--      
-+
-       if (NULL == hctx) return HANDLER_GO_ON;
--      
-+
-       p    = hctx->plugin_data;
-       con  = hctx->remote_conn;
--      
-+
-       if (con->mode != p->id) return HANDLER_GO_ON;
--      
--      log_error_write(srv, __FILE__, __LINE__, "ssdsd", 
--                      "emergency exit: scgi:", 
--                      "connection-fd:", con->fd,
--                      "fcgi-fd:", hctx->fd);
--      
--      
--      
-+
-+      log_error_write(srv, __FILE__, __LINE__, "ssdsd",
-+                      "emergency exit: scgi:",
-+                      "connection-fd:", con->sock->fd,
-+                      "fcgi-fd:", hctx->sock->fd);
-+
-+
-+
-       scgi_connection_cleanup(srv, hctx);
--      
-+
-       return HANDLER_FINISHED;
- }
-@@ -2459,27 +2323,28 @@
-       handler_ctx *hctx = ctx;
-       connection  *con  = hctx->remote_conn;
-       plugin_data *p    = hctx->plugin_data;
--      
-+
-       scgi_proc *proc   = hctx->proc;
-       scgi_extension_host *host= hctx->host;
-       if ((revents & FDEVENT_IN) &&
--          hctx->state == FCGI_STATE_READ) {
-+          (hctx->state == SCGI_STATE_RESPONSE_HEADER ||
-+           hctx->state == SCGI_STATE_RESPONSE_CONTENT)) {
-               switch (scgi_demux_response(srv, hctx)) {
-               case 0:
-                       break;
-               case 1:
-                       /* we are done */
-                       scgi_connection_cleanup(srv, hctx);
--                      
-+
-                       joblist_append(srv, con);
-                       return HANDLER_FINISHED;
-               case -1:
-                       if (proc->pid && proc->state != PROC_STATE_DIED) {
-                               int status;
--                              
-+
-                               /* only fetch the zombie if it is not already done */
--                              
-+#ifndef _WIN32
-                               switch(waitpid(proc->pid, &status, WNOHANG)) {
-                               case 0:
-                                       /* child is still alive */
-@@ -2489,19 +2354,19 @@
-                               default:
-                                       /* the child should not terminate at all */
-                                       if (WIFEXITED(status)) {
--                                              log_error_write(srv, __FILE__, __LINE__, "sdsd", 
-+                                              log_error_write(srv, __FILE__, __LINE__, "sdsd",
-                                                               "child exited, pid:", proc->pid,
-                                                               "status:", WEXITSTATUS(status));
-                                       } else if (WIFSIGNALED(status)) {
--                                              log_error_write(srv, __FILE__, __LINE__, "sd", 
--                                                              "child signaled:", 
-+                                              log_error_write(srv, __FILE__, __LINE__, "sd",
-+                                                              "child signaled:",
-                                                               WTERMSIG(status));
-                                       } else {
--                                              log_error_write(srv, __FILE__, __LINE__, "sd", 
--                                                              "child died somehow:", 
-+                                              log_error_write(srv, __FILE__, __LINE__, "sd",
-+                                                              "child died somehow:",
-                                                               status);
-                                       }
--                                      
-+
-                                       if (p->conf.debug) {
-                                               log_error_write(srv, __FILE__, __LINE__, "ssdsbsdsd",
-                                                               "--- scgi spawning",
-@@ -2509,117 +2374,118 @@
-                                                               "\n\tsocket", host->unixsocket,
-                                                               "\n\tcurrent:", 1, "/", host->min_procs);
-                                       }
--                                      
-+
-                                       if (scgi_spawn_connection(srv, p, host, proc)) {
-                                               /* child died */
-                                               proc->state = PROC_STATE_DIED;
-                                       } else {
-                                               scgi_proclist_sort_down(srv, host, proc);
-                                       }
--                                      
-+
-                                       break;
-                               }
-+#endif
-                       }
-                       if (con->file_started == 0) {
-                               /* nothing has been send out yet, try to use another child */
--                              
-+
-                               if (hctx->wb->bytes_out == 0 &&
-                                   hctx->reconnects < 5) {
-                                       scgi_reconnect(srv, hctx);
--                                      
--                                      log_error_write(srv, __FILE__, __LINE__, "sdsdsd", 
-+
-+                                      log_error_write(srv, __FILE__, __LINE__, "sdsdsd",
-                                               "response not sent, request not sent, reconnection.",
--                                              "connection-fd:", con->fd,
--                                              "fcgi-fd:", hctx->fd);
--                                      
-+                                              "connection-fd:", con->sock->fd,
-+                                              "fcgi-fd:", hctx->sock->fd);
-+
-                                       return HANDLER_WAIT_FOR_FD;
-                               }
--                              
--                              log_error_write(srv, __FILE__, __LINE__, "sdsdsd", 
-+
-+                              log_error_write(srv, __FILE__, __LINE__, "sosdsd",
-                                               "response not sent, request sent:", hctx->wb->bytes_out,
--                                              "connection-fd:", con->fd,
--                                              "fcgi-fd:", hctx->fd);
--                              
-+                                              "connection-fd:", con->sock->fd,
-+                                              "fcgi-fd:", hctx->sock->fd);
-+
-                               scgi_connection_cleanup(srv, hctx);
--                              
--                              connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
-+
-                               buffer_reset(con->physical.path);
-                               con->http_status = 500;
-                               con->mode = DIRECT;
-                       } else {
-                               /* response might have been already started, kill the connection */
-                               scgi_connection_cleanup(srv, hctx);
--                              
--                              log_error_write(srv, __FILE__, __LINE__, "ssdsd", 
-+
-+                              log_error_write(srv, __FILE__, __LINE__, "ssdsd",
-                                               "response already sent out, termination connection",
--                                              "connection-fd:", con->fd,
--                                              "fcgi-fd:", hctx->fd);
--                              
-+                                              "connection-fd:", con->sock->fd,
-+                                              "fcgi-fd:", hctx->sock->fd);
-+
-                               connection_set_state(srv, con, CON_STATE_ERROR);
-                       }
-                       /* */
--                      
--                      
-+
-+
-                       joblist_append(srv, con);
-                       return HANDLER_FINISHED;
-               }
-       }
--      
-+
-       if (revents & FDEVENT_OUT) {
--              if (hctx->state == FCGI_STATE_CONNECT ||
--                  hctx->state == FCGI_STATE_WRITE) {
-+              if (hctx->state == SCGI_STATE_CONNECT ||
-+                  hctx->state == SCGI_STATE_WRITE) {
-                       /* we are allowed to send something out
--                       * 
-+                       *
-                        * 1. in a unfinished connect() call
-                        * 2. in a unfinished write() call (long POST request)
-                        */
-                       return mod_scgi_handle_subrequest(srv, con, p);
-               } else {
--                      log_error_write(srv, __FILE__, __LINE__, "sd", 
--                                      "got a FDEVENT_OUT and didn't know why:", 
-+                      log_error_write(srv, __FILE__, __LINE__, "sd",
-+                                      "got a FDEVENT_OUT and didn't know why:",
-                                       hctx->state);
-               }
-       }
--      
-+
-       /* perhaps this issue is already handled */
-       if (revents & FDEVENT_HUP) {
--              if (hctx->state == FCGI_STATE_CONNECT) {
-+              if (hctx->state == SCGI_STATE_CONNECT) {
-                       /* getoptsock will catch this one (right ?)
--                       * 
--                       * if we are in connect we might get a EINPROGRESS 
--                       * in the first call and a FDEVENT_HUP in the 
-+                       *
-+                       * if we are in connect we might get a EINPROGRESS
-+                       * in the first call and a FDEVENT_HUP in the
-                        * second round
--                       * 
-+                       *
-                        * FIXME: as it is a bit ugly.
--                       * 
-+                       *
-                        */
-                       return mod_scgi_handle_subrequest(srv, con, p);
--              } else if (hctx->state == FCGI_STATE_READ &&
-+              } else if ((hctx->state == SCGI_STATE_RESPONSE_HEADER ||
-+                          hctx->state == SCGI_STATE_RESPONSE_CONTENT ) &&
-                          hctx->proc->port == 0) {
-                       /* FIXME:
--                       * 
-+                       *
-                        * ioctl says 8192 bytes to read from PHP and we receive directly a HUP for the socket
-                        * even if the FCGI_FIN packet is not received yet
-                        */
-               } else {
--                      log_error_write(srv, __FILE__, __LINE__, "sbSBSDSd", 
--                                      "error: unexpected close of scgi connection for", 
-+                      log_error_write(srv, __FILE__, __LINE__, "sbSBSDSd",
-+                                      "error: unexpected close of scgi connection for",
-                                       con->uri.path,
--                                      "(no scgi process on host: ", 
-+                                      "(no scgi process on host: ",
-                                       host->host,
--                                      ", port: ", 
-+                                      ", port: ",
-                                       host->port,
-                                       " ?)",
-                                       hctx->state);
--                      
-+
-                       connection_set_state(srv, con, CON_STATE_ERROR);
-                       scgi_connection_close(srv, hctx);
-                       joblist_append(srv, con);
-               }
-       } else if (revents & FDEVENT_ERR) {
--              log_error_write(srv, __FILE__, __LINE__, "s", 
-+              log_error_write(srv, __FILE__, __LINE__, "s",
-                               "fcgi: got a FDEVENT_ERR. Don't know why.");
-               /* kill all connections to the scgi process */
-@@ -2628,42 +2494,39 @@
-               scgi_connection_close(srv, hctx);
-               joblist_append(srv, con);
-       }
--      
-+
-       return HANDLER_FINISHED;
- }
--#define PATCH(x) \
--      p->conf.x = s->x;
-+
- static int scgi_patch_connection(server *srv, connection *con, plugin_data *p) {
-       size_t i, j;
-       plugin_config *s = p->config_storage[0];
--      
--      PATCH(exts);
--      PATCH(debug);
--      
-+
-+      PATCH_OPTION(exts);
-+      PATCH_OPTION(debug);
-+
-       /* skip the first, the global context */
-       for (i = 1; i < srv->config_context->used; i++) {
-               data_config *dc = (data_config *)srv->config_context->data[i];
-               s = p->config_storage[i];
--              
-+
-               /* condition didn't match */
-               if (!config_check_cond(srv, con, dc)) continue;
--              
-+
-               /* merge config */
-               for (j = 0; j < dc->value->used; j++) {
-                       data_unset *du = dc->value->data[j];
--                      
-+
-                       if (buffer_is_equal_string(du->key, CONST_STR_LEN("scgi.server"))) {
--                              PATCH(exts);
-+                              PATCH_OPTION(exts);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("scgi.debug"))) {
--                              PATCH(debug);
-+                              PATCH_OPTION(debug);
-                       }
-               }
-       }
--      
-+
-       return 0;
- }
--#undef PATCH
--
- static handler_t scgi_check_extension(server *srv, connection *con, void *p_d, int uri_path_handler) {
-       plugin_data *p = p_d;
-@@ -2673,30 +2536,30 @@
-       size_t k;
-       buffer *fn;
-       scgi_extension *extension = NULL;
--      
-+
-       /* Possibly, we processed already this request */
-       if (con->file_started == 1) return HANDLER_GO_ON;
--      
-+
-       fn = uri_path_handler ? con->uri.path : con->physical.path;
-       if (buffer_is_empty(fn)) return HANDLER_GO_ON;
-       s_len = fn->used - 1;
--      
-+
-       scgi_patch_connection(srv, con, p);
-       /* check if extension matches */
-       for (k = 0; k < p->conf.exts->used; k++) {
-               size_t ct_len;
--              
-+
-               extension = p->conf.exts->exts[k];
--              
-+
-               if (extension->key->used == 0) continue;
--              
-+
-               ct_len = extension->key->used - 1;
--              
-+
-               if (s_len < ct_len) continue;
--              
-+
-               /* check extension in the form "/scgi_pattern" */
-               if (*(extension->key->ptr) == '/' && strncmp(fn->ptr, extension->key->ptr, ct_len) == 0) {
-                       break;
-@@ -2710,17 +2573,17 @@
-       if (k == p->conf.exts->used) {
-               return HANDLER_GO_ON;
-       }
--      
-+
-       /* get best server */
-       for (k = 0, ndx = -1; k < extension->used; k++) {
-               scgi_extension_host *host = extension->hosts[k];
--              
-+
-               /* we should have at least one proc that can do somthing */
-               if (host->active_procs == 0) continue;
-               if (used == -1 || host->load < used) {
-                       used = host->load;
--                      
-+
-                       ndx = k;
-               }
-       }
-@@ -2728,12 +2591,12 @@
-       /* found a server */
-       if (ndx != -1) {
-               scgi_extension_host *host = extension->hosts[ndx];
--              
--              /* 
--               * if check-local is disabled, use the uri.path handler 
--               * 
-+
-+              /*
-+               * if check-local is disabled, use the uri.path handler
-+               *
-                */
--              
-+
-               /* init handler-context */
-               if (uri_path_handler) {
-                       if (host->check_local == 0) {
-@@ -2741,7 +2604,7 @@
-                               char *pathinfo;
-                               hctx = handler_ctx_init();
--                              
-+
-                               hctx->remote_conn      = con;
-                               hctx->plugin_data      = p;
-                               hctx->host             = host;
-@@ -2749,45 +2612,45 @@
-                               hctx->conf.exts        = p->conf.exts;
-                               hctx->conf.debug       = p->conf.debug;
--                              
-+
-                               con->plugin_ctx[p->id] = hctx;
--                              
-+
-                               host->load++;
--                              
-+
-                               con->mode = p->id;
-                               if (con->conf.log_request_handling) {
-                                       log_error_write(srv, __FILE__, __LINE__, "s", "handling it in mod_scgi");
-                               }
--                              /* the prefix is the SCRIPT_NAME, 
-+                              /* the prefix is the SCRIPT_NAME,
-                                * everthing from start to the next slash
-                                * this is important for check-local = "disable"
--                               * 
-+                               *
-                                * if prefix = /admin.fcgi
--                               * 
-+                               *
-                                * /admin.fcgi/foo/bar
--                               * 
-+                               *
-                                * SCRIPT_NAME = /admin.fcgi
-                                * PATH_INFO   = /foo/bar
--                               * 
-+                               *
-                                * if prefix = /fcgi-bin/
--                               * 
-+                               *
-                                * /fcgi-bin/foo/bar
--                               * 
-+                               *
-                                * SCRIPT_NAME = /fcgi-bin/foo
-                                * PATH_INFO   = /bar
--                               * 
-+                               *
-                                */
--                              
-+
-                               /* the rewrite is only done for /prefix/? matches */
-                               if (extension->key->ptr[0] == '/' &&
-                                   con->uri.path->used > extension->key->used &&
-                                   NULL != (pathinfo = strchr(con->uri.path->ptr + extension->key->used - 1, '/'))) {
--                                      /* rewrite uri.path and pathinfo */ 
--                                      
-+                                      /* rewrite uri.path and pathinfo */
-+
-                                       buffer_copy_string(con->request.pathinfo, pathinfo);
--                                      
-+
-                                       con->uri.path->used -= con->request.pathinfo->used - 1;
-                                       con->uri.path->ptr[con->uri.path->used - 1] = '\0';
-                               }
-@@ -2796,21 +2659,21 @@
-               } else {
-                       handler_ctx *hctx;
-                       hctx = handler_ctx_init();
--                      
-+
-                       hctx->remote_conn      = con;
-                       hctx->plugin_data      = p;
-                       hctx->host             = host;
-                       hctx->proc             = NULL;
--                      
-+
-                       hctx->conf.exts        = p->conf.exts;
-                       hctx->conf.debug       = p->conf.debug;
--                      
-+
-                       con->plugin_ctx[p->id] = hctx;
--                      
-+
-                       host->load++;
--                      
-+
-                       con->mode = p->id;
--                      
-+
-                       if (con->conf.log_request_handling) {
-                               log_error_write(srv, __FILE__, __LINE__, "s", "handling it in mod_fastcgi");
-                       }
-@@ -2821,11 +2684,11 @@
-               /* no handler found */
-               buffer_reset(con->physical.path);
-               con->http_status = 500;
--              
--              log_error_write(srv, __FILE__, __LINE__,  "sb", 
--                              "no fcgi-handler found for:", 
-+
-+              log_error_write(srv, __FILE__, __LINE__,  "sb",
-+                              "no fcgi-handler found for:",
-                               fn);
--              
-+
-               return HANDLER_FINISHED;
-       }
-       return HANDLER_GO_ON;
-@@ -2844,21 +2707,22 @@
- JOBLIST_FUNC(mod_scgi_handle_joblist) {
-       plugin_data *p = p_d;
-       handler_ctx *hctx = con->plugin_ctx[p->id];
--      
-+
-       if (hctx == NULL) return HANDLER_GO_ON;
--      if (hctx->fd != -1) {
-+      if (hctx->sock->fd != -1) {
-               switch (hctx->state) {
--              case FCGI_STATE_READ:
--                      fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
--                      
-+              case SCGI_STATE_RESPONSE_HEADER:
-+              case SCGI_STATE_RESPONSE_CONTENT:
-+                      fdevent_event_add(srv->ev, hctx->sock, FDEVENT_IN);
-+
-                       break;
--              case FCGI_STATE_CONNECT:
--              case FCGI_STATE_WRITE:
--                      fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
--                      
-+              case SCGI_STATE_CONNECT:
-+              case SCGI_STATE_WRITE:
-+                      fdevent_event_add(srv->ev, hctx->sock, FDEVENT_OUT);
-+
-                       break;
--              case FCGI_STATE_INIT:
-+              case SCGI_STATE_INIT:
-                       /* at reconnect */
-                       break;
-               default:
-@@ -2873,21 +2737,21 @@
- static handler_t scgi_connection_close_callback(server *srv, connection *con, void *p_d) {
-       plugin_data *p = p_d;
--      
-+
-       return scgi_connection_close(srv, con->plugin_ctx[p->id]);
- }
- TRIGGER_FUNC(mod_scgi_handle_trigger) {
-       plugin_data *p = p_d;
-       size_t i, j, n;
--      
--      
-+
-+
-       /* perhaps we should kill a connect attempt after 10-15 seconds
--       * 
-+       *
-        * currently we wait for the TCP timeout which is on Linux 180 seconds
--       * 
--       * 
--       * 
-+       *
-+       *
-+       *
-        */
-       /* check all childs if they are still up */
-@@ -2904,47 +2768,47 @@
-                       scgi_extension *ex;
-                       ex = exts->exts[j];
--                      
-+
-                       for (n = 0; n < ex->used; n++) {
--                              
-+
-                               scgi_proc *proc;
-                               unsigned long sum_load = 0;
-                               scgi_extension_host *host;
--                              
-+
-                               host = ex->hosts[n];
--                              
-+
-                               scgi_restart_dead_procs(srv, p, host);
--                              
-+
-                               for (proc = host->first; proc; proc = proc->next) {
-                                       sum_load += proc->load;
-                               }
--                              
-+
-                               if (host->num_procs &&
-                                   host->num_procs < host->max_procs &&
-                                   (sum_load / host->num_procs) > host->max_load_per_proc) {
-                                       /* overload, spawn new child */
-                                       scgi_proc *fp = NULL;
--                                      
-+
-                                       if (p->conf.debug) {
--                                              log_error_write(srv, __FILE__, __LINE__, "s", 
-+                                              log_error_write(srv, __FILE__, __LINE__, "s",
-                                                               "overload detected, spawning a new child");
-                                       }
--                                      
-+
-                                       for (fp = host->unused_procs; fp && fp->pid != 0; fp = fp->next);
--                                      
-+
-                                       if (fp) {
-                                               if (fp == host->unused_procs) host->unused_procs = fp->next;
--                                              
-+
-                                               if (fp->next) fp->next->prev = NULL;
--                                              
-+
-                                               host->max_id++;
-                                       } else {
-                                               fp = scgi_process_init();
-                                               fp->id = host->max_id++;
-                                       }
--                                      
-+
-                                       host->num_procs++;
--                                      
-+
-                                       if (buffer_is_empty(host->unixsocket)) {
-                                               fp->port = host->port + fp->id;
-                                       } else {
-@@ -2952,13 +2816,13 @@
-                                               buffer_append_string(fp->socket, "-");
-                                               buffer_append_long(fp->socket, fp->id);
-                                       }
--                                      
-+
-                                       if (scgi_spawn_connection(srv, p, host, fp)) {
-                                               log_error_write(srv, __FILE__, __LINE__, "s",
-                                                               "ERROR: spawning fcgi failed.");
-                                               return HANDLER_ERROR;
-                                       }
--                                      
-+
-                                       fp->prev = NULL;
-                                       fp->next = host->first;
-                                       if (host->first) {
-@@ -2966,56 +2830,57 @@
-                                       }
-                                       host->first = fp;
-                               }
--                              
-+
-                               for (proc = host->first; proc; proc = proc->next) {
-                                       if (proc->load != 0) break;
-                                       if (host->num_procs <= host->min_procs) break;
-                                       if (proc->pid == 0) continue;
--                                      
-+#ifndef _WIN32
-                                       if (srv->cur_ts - proc->last_used > host->idle_timeout) {
-                                               /* a proc is idling for a long time now,
-                                                * terminated it */
--                                              
-+
-                                               if (p->conf.debug) {
--                                                      log_error_write(srv, __FILE__, __LINE__, "ssbsd", 
--                                                                      "idle-timeout reached, terminating child:", 
--                                                                      "socket:", proc->socket, 
-+                                                      log_error_write(srv, __FILE__, __LINE__, "ssbsd",
-+                                                                      "idle-timeout reached, terminating child:",
-+                                                                      "socket:", proc->socket,
-                                                                       "pid", proc->pid);
-                                               }
--                                              
--                                              
-+
-+
-                                               if (proc->next) proc->next->prev = proc->prev;
-                                               if (proc->prev) proc->prev->next = proc->next;
--                                              
-+
-                                               if (proc->prev == NULL) host->first = proc->next;
--                                              
-+
-                                               proc->prev = NULL;
-                                               proc->next = host->unused_procs;
--                                              
-+
-                                               if (host->unused_procs) host->unused_procs->prev = proc;
-                                               host->unused_procs = proc;
--                                              
-+
-                                               kill(proc->pid, SIGTERM);
--                                              
-+
-                                               proc->state = PROC_STATE_KILLED;
--                                              
--                                              log_error_write(srv, __FILE__, __LINE__, "ssbsd", 
--                                                                      "killed:", 
--                                                                      "socket:", proc->socket, 
-+
-+                                              log_error_write(srv, __FILE__, __LINE__, "ssbsd",
-+                                                                      "killed:",
-+                                                                      "socket:", proc->socket,
-                                                                       "pid", proc->pid);
--                                              
-+
-                                               host->num_procs--;
--                                              
-+
-                                               /* proc is now in unused, let the next second handle the next process */
-                                               break;
--                                      }       
-+                                      }
-+#endif
-                               }
--                              
-+
-                               for (proc = host->unused_procs; proc; proc = proc->next) {
-                                       int status;
--                                      
-+
-                                       if (proc->pid == 0) continue;
--                                      
-+#ifndef _WIN32
-                                       switch (waitpid(proc->pid, &status, WNOHANG)) {
-                                       case 0:
-                                               /* child still running after timeout, good */
-@@ -3023,10 +2888,10 @@
-                                       case -1:
-                                               if (errno != EINTR) {
-                                                       /* no PID found ? should never happen */
--                                                      log_error_write(srv, __FILE__, __LINE__, "sddss", 
-+                                                      log_error_write(srv, __FILE__, __LINE__, "sddss",
-                                                                       "pid ", proc->pid, proc->state,
-                                                                       "not found:", strerror(errno));
--                                                      
-+
- #if 0
-                                                       if (errno == ECHILD) {
-                                                               /* someone else has cleaned up for us */
-@@ -3040,25 +2905,26 @@
-                                               /* the child should not terminate at all */
-                                               if (WIFEXITED(status)) {
-                                                       if (proc->state != PROC_STATE_KILLED) {
--                                                              log_error_write(srv, __FILE__, __LINE__, "sdb", 
--                                                                              "child exited:", 
-+                                                              log_error_write(srv, __FILE__, __LINE__, "sdb",
-+                                                                              "child exited:",
-                                                                               WEXITSTATUS(status), proc->socket);
-                                                       }
-                                               } else if (WIFSIGNALED(status)) {
-                                                       if (WTERMSIG(status) != SIGTERM) {
--                                                              log_error_write(srv, __FILE__, __LINE__, "sd", 
--                                                                              "child signaled:", 
-+                                                              log_error_write(srv, __FILE__, __LINE__, "sd",
-+                                                                              "child signaled:",
-                                                                               WTERMSIG(status));
-                                                       }
-                                               } else {
--                                                      log_error_write(srv, __FILE__, __LINE__, "sd", 
--                                                                      "child died somehow:", 
-+                                                      log_error_write(srv, __FILE__, __LINE__, "sd",
-+                                                                      "child died somehow:",
-                                                                       status);
-                                               }
-                                               proc->pid = 0;
-                                               proc->state = PROC_STATE_UNSET;
-                                               host->max_id--;
-                                       }
-+#endif
-                               }
-                       }
-               }
-@@ -3078,12 +2944,14 @@
-       p->connection_reset        = scgi_connection_reset;
-       p->handle_connection_close = scgi_connection_close_callback;
-       p->handle_uri_clean        = scgi_check_extension_1;
--      p->handle_subrequest_start = scgi_check_extension_2;
-+      p->handle_start_backend    = scgi_check_extension_2;
-+#if 0
-       p->handle_subrequest       = mod_scgi_handle_subrequest;
-+#endif
-       p->handle_joblist          = mod_scgi_handle_joblist;
-       p->handle_trigger          = mod_scgi_handle_trigger;
--      
-+
-       p->data         = NULL;
--      
-+
-       return 0;
- }
---- ../lighttpd-1.4.11/src/mod_secure_download.c       2005-12-14 14:37:29.000000000 +0200
-+++ lighttpd-1.5.0/src/mod_secure_download.c   2006-07-16 00:26:03.000000000 +0300
-@@ -25,7 +25,7 @@
- #ifdef USE_OPENSSL
- #define IN const
- #else
--#define IN 
-+#define IN
- #endif
- #define OUT
-@@ -36,28 +36,28 @@
-       buffer *doc_root;
-       buffer *secret;
-       buffer *uri_prefix;
--      
-+
-       unsigned short timeout;
- } plugin_config;
- typedef struct {
-       PLUGIN_DATA;
--      
-+
-       buffer *md5;
--      
-+
-       plugin_config **config_storage;
--      
--      plugin_config conf; 
-+
-+      plugin_config conf;
- } plugin_data;
- /* init the plugin data */
- INIT_FUNC(mod_secdownload_init) {
-       plugin_data *p;
--      
-+
-       p = calloc(1, sizeof(*p));
--      
-+
-       p->md5 = buffer_init();
--      
-+
-       return p;
- }
-@@ -65,27 +65,27 @@
- FREE_FUNC(mod_secdownload_free) {
-       plugin_data *p = p_d;
-       UNUSED(srv);
--      
-+
-       if (!p) return HANDLER_GO_ON;
--      
-+
-       if (p->config_storage) {
-               size_t i;
-               for (i = 0; i < srv->config_context->used; i++) {
-                       plugin_config *s = p->config_storage[i];
--                      
-+
-                       buffer_free(s->secret);
-                       buffer_free(s->doc_root);
-                       buffer_free(s->uri_prefix);
--                      
-+
-                       free(s);
-               }
-               free(p->config_storage);
-       }
--      
-+
-       buffer_free(p->md5);
--      
-+
-       free(p);
--      
-+
-       return HANDLER_GO_ON;
- }
-@@ -94,107 +94,103 @@
- SETDEFAULTS_FUNC(mod_secdownload_set_defaults) {
-       plugin_data *p = p_d;
-       size_t i = 0;
--      
--      config_values_t cv[] = { 
-+
-+      config_values_t cv[] = {
-               { "secdownload.secret",            NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
-               { "secdownload.document-root",     NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 1 */
-               { "secdownload.uri-prefix",        NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 2 */
-               { "secdownload.timeout",           NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },        /* 3 */
-               { NULL,                            NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
-       };
--      
-+
-       if (!p) return HANDLER_ERROR;
--      
-+
-       p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
--      
-+
-       for (i = 0; i < srv->config_context->used; i++) {
-               plugin_config *s;
--              
-+
-               s = calloc(1, sizeof(plugin_config));
-               s->secret        = buffer_init();
-               s->doc_root      = buffer_init();
-               s->uri_prefix    = buffer_init();
-               s->timeout       = 60;
--              
-+
-               cv[0].destination = s->secret;
-               cv[1].destination = s->doc_root;
-               cv[2].destination = s->uri_prefix;
-               cv[3].destination = &(s->timeout);
--              
-+
-               p->config_storage[i] = s;
--      
-+
-               if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
-                       return HANDLER_ERROR;
-               }
-       }
--      
-+
-       return HANDLER_GO_ON;
- }
- /**
-  * checks if the supplied string is a MD5 string
-- * 
-+ *
-  * @param str a possible MD5 string
-  * @return if the supplied string is a valid MD5 string 1 is returned otherwise 0
-  */
- int is_hex_len(const char *str, size_t len) {
-       size_t i;
--      
-+
-       if (NULL == str) return 0;
--      
-+
-       for (i = 0; i < len && *str; i++, str++) {
-               /* illegal characters */
-               if (!((*str >= '0' && *str <= '9') ||
-                     (*str >= 'a' && *str <= 'f') ||
--                    (*str >= 'A' && *str <= 'F')) 
-+                    (*str >= 'A' && *str <= 'F'))
-                   ) {
-                       return 0;
-               }
-       }
--      
-+
-       return i == len;
- }
--#define PATCH(x) \
--      p->conf.x = s->x;
- static int mod_secdownload_patch_connection(server *srv, connection *con, plugin_data *p) {
-       size_t i, j;
-       plugin_config *s = p->config_storage[0];
--      
--      PATCH(secret);
--      PATCH(doc_root);
--      PATCH(uri_prefix);
--      PATCH(timeout);
--      
-+
-+      PATCH_OPTION(secret);
-+      PATCH_OPTION(doc_root);
-+      PATCH_OPTION(uri_prefix);
-+      PATCH_OPTION(timeout);
-+
-       /* skip the first, the global context */
-       for (i = 1; i < srv->config_context->used; i++) {
-               data_config *dc = (data_config *)srv->config_context->data[i];
-               s = p->config_storage[i];
--              
-+
-               /* condition didn't match */
-               if (!config_check_cond(srv, con, dc)) continue;
--              
-+
-               /* merge config */
-               for (j = 0; j < dc->value->used; j++) {
-                       data_unset *du = dc->value->data[j];
--                      
-+
-                       if (buffer_is_equal_string(du->key, CONST_STR_LEN("secdownload.secret"))) {
--                              PATCH(secret);
-+                              PATCH_OPTION(secret);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("secdownload.document-root"))) {
--                              PATCH(doc_root);
-+                              PATCH_OPTION(doc_root);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("secdownload.uri-prefix"))) {
--                              PATCH(uri_prefix);
-+                              PATCH_OPTION(uri_prefix);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("secdownload.timeout"))) {
--                              PATCH(timeout);
-+                              PATCH_OPTION(timeout);
-                       }
-               }
-       }
--      
-+
-       return 0;
- }
--#undef PATCH
--
- URIHANDLER_FUNC(mod_secdownload_uri_handler) {
-       plugin_data *p = p_d;
-@@ -203,88 +199,88 @@
-       const char *rel_uri, *ts_str, *md5_str;
-       time_t ts = 0;
-       size_t i;
--      
-+
-       if (con->uri.path->used == 0) return HANDLER_GO_ON;
--      
-+
-       mod_secdownload_patch_connection(srv, con, p);
-       if (buffer_is_empty(p->conf.uri_prefix)) return HANDLER_GO_ON;
--      
-+
-       if (buffer_is_empty(p->conf.secret)) {
-               log_error_write(srv, __FILE__, __LINE__, "s",
-                               "secdownload.secret has to be set");
-               return HANDLER_ERROR;
-       }
--      
-+
-       if (buffer_is_empty(p->conf.doc_root)) {
-               log_error_write(srv, __FILE__, __LINE__, "s",
-                               "secdownload.document-root has to be set");
-               return HANDLER_ERROR;
-       }
--      
--      /* 
-+
-+      /*
-        *  /<uri-prefix>[a-f0-9]{32}/[a-f0-9]{8}/<rel-path>
-        */
--      
-+
-       if (0 != strncmp(con->uri.path->ptr, p->conf.uri_prefix->ptr, p->conf.uri_prefix->used - 1)) return HANDLER_GO_ON;
--      
-+
-       md5_str = con->uri.path->ptr + p->conf.uri_prefix->used - 1;
--      
-+
-       if (!is_hex_len(md5_str, 32)) return HANDLER_GO_ON;
-       if (*(md5_str + 32) != '/') return HANDLER_GO_ON;
--      
-+
-       ts_str = md5_str + 32 + 1;
--      
-+
-       if (!is_hex_len(ts_str, 8)) return HANDLER_GO_ON;
-       if (*(ts_str + 8) != '/') return HANDLER_GO_ON;
--      
-+
-       for (i = 0; i < 8; i++) {
-               ts = (ts << 4) + hex2int(*(ts_str + i));
-       }
--      
-+
-       /* timed-out */
--      if (srv->cur_ts - ts > p->conf.timeout || 
-+      if (srv->cur_ts - ts > p->conf.timeout ||
-           srv->cur_ts - ts < -p->conf.timeout) {
-               con->http_status = 408;
--              
-+
-               return HANDLER_FINISHED;
-       }
--      
-+
-       rel_uri = ts_str + 8;
--      
--      /* checking MD5 
--       * 
-+
-+      /* checking MD5
-+       *
-        * <secret><rel-path><timestamp-hex>
-        */
--      
-+
-       buffer_copy_string_buffer(p->md5, p->conf.secret);
-       buffer_append_string(p->md5, rel_uri);
-       buffer_append_string_len(p->md5, ts_str, 8);
--      
-+
-       MD5_Init(&Md5Ctx);
-       MD5_Update(&Md5Ctx, (unsigned char *)p->md5->ptr, p->md5->used - 1);
-       MD5_Final(HA1, &Md5Ctx);
--      
-+
-       buffer_copy_string_hex(p->md5, (char *)HA1, 16);
--      
-+
-       if (0 != strncmp(md5_str, p->md5->ptr, 32)) {
-               con->http_status = 403;
--              
--              log_error_write(srv, __FILE__, __LINE__, "sss", 
-+
-+              log_error_write(srv, __FILE__, __LINE__, "sss",
-                               "md5 invalid:",
-                               md5_str, p->md5->ptr);
--              
-+
-               return HANDLER_FINISHED;
-       }
--      
-+
-       /* starting with the last / we should have relative-path to the docroot
-        */
--      
-+
-       buffer_copy_string_buffer(con->physical.doc_root, p->conf.doc_root);
-       buffer_copy_string(con->physical.rel_path, rel_uri);
-       buffer_copy_string_buffer(con->physical.path, con->physical.doc_root);
-       buffer_append_string_buffer(con->physical.path, con->physical.rel_path);
--      
-+
-       return HANDLER_GO_ON;
- }
-@@ -293,13 +289,13 @@
- int mod_secdownload_plugin_init(plugin *p) {
-       p->version     = LIGHTTPD_VERSION_ID;
-       p->name        = buffer_init_string("secdownload");
--      
-+
-       p->init        = mod_secdownload_init;
-       p->handle_physical  = mod_secdownload_uri_handler;
-       p->set_defaults  = mod_secdownload_set_defaults;
-       p->cleanup     = mod_secdownload_free;
--      
-+
-       p->data        = NULL;
--      
-+
-       return 0;
- }
---- ../lighttpd-1.4.11/src/mod_setenv.c        2006-01-14 20:33:12.000000000 +0200
-+++ lighttpd-1.5.0/src/mod_setenv.c    2006-09-07 00:57:05.000000000 +0300
-@@ -18,25 +18,25 @@
- typedef struct {
-       array *request_header;
-       array *response_header;
--      
-+
-       array *environment;
- } plugin_config;
- typedef struct {
-       PLUGIN_DATA;
--      
-+
-       plugin_config **config_storage;
--      
--      plugin_config conf; 
-+
-+      plugin_config conf;
- } plugin_data;
- static handler_ctx * handler_ctx_init() {
-       handler_ctx * hctx;
--      
-+
-       hctx = calloc(1, sizeof(*hctx));
--      
-+
-       hctx->handled = 0;
--      
-+
-       return hctx;
- }
-@@ -48,36 +48,36 @@
- /* init the plugin data */
- INIT_FUNC(mod_setenv_init) {
-       plugin_data *p;
--      
-+
-       p = calloc(1, sizeof(*p));
--      
-+
-       return p;
- }
- /* detroy the plugin data */
- FREE_FUNC(mod_setenv_free) {
-       plugin_data *p = p_d;
--      
-+
-       UNUSED(srv);
-       if (!p) return HANDLER_GO_ON;
--      
-+
-       if (p->config_storage) {
-               size_t i;
-               for (i = 0; i < srv->config_context->used; i++) {
-                       plugin_config *s = p->config_storage[i];
--                      
-+
-                       array_free(s->request_header);
-                       array_free(s->response_header);
-                       array_free(s->environment);
--                      
-+
-                       free(s);
-               }
-               free(p->config_storage);
-       }
--      
-+
-       free(p);
--      
-+
-       return HANDLER_GO_ON;
- }
-@@ -86,86 +86,83 @@
- SETDEFAULTS_FUNC(mod_setenv_set_defaults) {
-       plugin_data *p = p_d;
-       size_t i = 0;
--      
--      config_values_t cv[] = { 
-+
-+      config_values_t cv[] = {
-               { "setenv.add-request-header",  NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
-               { "setenv.add-response-header", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 1 */
-               { "setenv.add-environment",     NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 2 */
-               { NULL,                         NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
-       };
--      
-+
-       if (!p) return HANDLER_ERROR;
--      
-+
-       p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
--      
-+
-       for (i = 0; i < srv->config_context->used; i++) {
-               plugin_config *s;
--              
-+
-               s = calloc(1, sizeof(plugin_config));
-               s->request_header   = array_init();
-               s->response_header  = array_init();
-               s->environment      = array_init();
--              
-+
-               cv[0].destination = s->request_header;
-               cv[1].destination = s->response_header;
-               cv[2].destination = s->environment;
--              
-+
-               p->config_storage[i] = s;
--      
-+
-               if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
-                       return HANDLER_ERROR;
-               }
-       }
--      
-+
-       return HANDLER_GO_ON;
- }
--#define PATCH(x) \
--      p->conf.x = s->x;
- static int mod_setenv_patch_connection(server *srv, connection *con, plugin_data *p) {
-       size_t i, j;
-       plugin_config *s = p->config_storage[0];
--      
--      PATCH(request_header);
--      PATCH(response_header);
--      PATCH(environment);
--      
-+
-+      PATCH_OPTION(request_header);
-+      PATCH_OPTION(response_header);
-+      PATCH_OPTION(environment);
-+
-       /* skip the first, the global context */
-       for (i = 1; i < srv->config_context->used; i++) {
-               data_config *dc = (data_config *)srv->config_context->data[i];
-               s = p->config_storage[i];
--              
-+
-               /* condition didn't match */
-               if (!config_check_cond(srv, con, dc)) continue;
--              
-+
-               /* merge config */
-               for (j = 0; j < dc->value->used; j++) {
-                       data_unset *du = dc->value->data[j];
--                      
-+
-                       if (buffer_is_equal_string(du->key, CONST_STR_LEN("setenv.add-request-header"))) {
--                              PATCH(request_header);
-+                              PATCH_OPTION(request_header);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("setenv.add-response-header"))) {
--                              PATCH(response_header);
-+                              PATCH_OPTION(response_header);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("setenv.add-environment"))) {
--                              PATCH(environment);
-+                              PATCH_OPTION(environment);
-                       }
-               }
-       }
--      
-+
-       return 0;
- }
--#undef PATCH
- URIHANDLER_FUNC(mod_setenv_uri_handler) {
-       plugin_data *p = p_d;
-       size_t k;
-       handler_ctx *hctx;
--      
-+
-       if (con->plugin_ctx[p->id]) {
-               hctx = con->plugin_ctx[p->id];
-       } else {
-               hctx = handler_ctx_init();
--                              
-+
-               con->plugin_ctx[p->id] = hctx;
-       }
-@@ -180,52 +177,52 @@
-       for (k = 0; k < p->conf.request_header->used; k++) {
-               data_string *ds = (data_string *)p->conf.request_header->data[k];
-               data_string *ds_dst;
--              
-+
-               if (NULL == (ds_dst = (data_string *)array_get_unused_element(con->request.headers, TYPE_STRING))) {
-                       ds_dst = data_string_init();
-               }
--              
-+
-               buffer_copy_string_buffer(ds_dst->key, ds->key);
-               buffer_copy_string_buffer(ds_dst->value, ds->value);
--              
-+
-               array_insert_unique(con->request.headers, (data_unset *)ds_dst);
-       }
--      
-+
-       for (k = 0; k < p->conf.environment->used; k++) {
-               data_string *ds = (data_string *)p->conf.environment->data[k];
-               data_string *ds_dst;
--              
-+
-               if (NULL == (ds_dst = (data_string *)array_get_unused_element(con->environment, TYPE_STRING))) {
-                       ds_dst = data_string_init();
-               }
--              
-+
-               buffer_copy_string_buffer(ds_dst->key, ds->key);
-               buffer_copy_string_buffer(ds_dst->value, ds->value);
--              
-+
-               array_insert_unique(con->environment, (data_unset *)ds_dst);
-       }
--      
-+
-       for (k = 0; k < p->conf.response_header->used; k++) {
-               data_string *ds = (data_string *)p->conf.response_header->data[k];
--              
-+
-               response_header_insert(srv, con, CONST_BUF_LEN(ds->key), CONST_BUF_LEN(ds->value));
-       }
--      
-+
-       /* not found */
-       return HANDLER_GO_ON;
- }
- REQUESTDONE_FUNC(mod_setenv_reset) {
-       plugin_data *p = p_d;
--      
-+
-       UNUSED(srv);
--      
-+
-       if (con->plugin_ctx[p->id]) {
-               handler_ctx_free(con->plugin_ctx[p->id]);
-               con->plugin_ctx[p->id] = NULL;
-       }
--      return HANDLER_GO_ON;   
-+      return HANDLER_GO_ON;
- }
- /* this function is called at dlopen() time and inits the callbacks */
-@@ -233,15 +230,15 @@
- int mod_setenv_plugin_init(plugin *p) {
-       p->version     = LIGHTTPD_VERSION_ID;
-       p->name        = buffer_init_string("setenv");
--      
-+
-       p->init        = mod_setenv_init;
-       p->handle_uri_clean  = mod_setenv_uri_handler;
-       p->set_defaults  = mod_setenv_set_defaults;
-       p->cleanup     = mod_setenv_free;
--      
--      p->handle_request_done  = mod_setenv_reset;
-+
-+      p->connection_reset  = mod_setenv_reset;
-       p->data        = NULL;
--      
-+
-       return 0;
- }
---- ../lighttpd-1.4.11/src/mod_simple_vhost.c  2005-11-18 15:16:13.000000000 +0200
-+++ lighttpd-1.5.0/src/mod_simple_vhost.c      2006-07-16 00:26:04.000000000 +0300
-@@ -10,6 +10,8 @@
- #include "plugin.h"
-+#include "sys-files.h"
-+
- #ifdef HAVE_CONFIG_H
- #include "config.h"
- #endif
-@@ -18,7 +20,7 @@
-       buffer *server_root;
-       buffer *default_host;
-       buffer *document_root;
--      
-+
-       buffer *docroot_cache_key;
-       buffer *docroot_cache_value;
-       buffer *docroot_cache_servername;
-@@ -28,138 +30,138 @@
- typedef struct {
-       PLUGIN_DATA;
--      
-+
-       buffer *doc_root;
--      
-+
-       plugin_config **config_storage;
--      plugin_config conf; 
-+      plugin_config conf;
- } plugin_data;
- INIT_FUNC(mod_simple_vhost_init) {
-       plugin_data *p;
--      
-+
-       p = calloc(1, sizeof(*p));
--      
-+
-       p->doc_root = buffer_init();
--      
-+
-       return p;
- }
- FREE_FUNC(mod_simple_vhost_free) {
-       plugin_data *p = p_d;
--      
-+
-       UNUSED(srv);
-       if (!p) return HANDLER_GO_ON;
--      
-+
-       if (p->config_storage) {
-               size_t i;
-               for (i = 0; i < srv->config_context->used; i++) {
-                       plugin_config *s = p->config_storage[i];
--                      
-+
-                       buffer_free(s->document_root);
-                       buffer_free(s->default_host);
-                       buffer_free(s->server_root);
--                      
-+
-                       buffer_free(s->docroot_cache_key);
-                       buffer_free(s->docroot_cache_value);
-                       buffer_free(s->docroot_cache_servername);
--                      
-+
-                       free(s);
-               }
--      
-+
-               free(p->config_storage);
-       }
--      
-+
-       buffer_free(p->doc_root);
--      
-+
-       free(p);
--      
-+
-       return HANDLER_GO_ON;
- }
- SETDEFAULTS_FUNC(mod_simple_vhost_set_defaults) {
-       plugin_data *p = p_d;
-       size_t i;
--      
--      config_values_t cv[] = { 
-+
-+      config_values_t cv[] = {
-               { "simple-vhost.server-root",       NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
-               { "simple-vhost.default-host",      NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
-               { "simple-vhost.document-root",     NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
-               { "simple-vhost.debug",             NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },
-               { NULL,                             NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
-       };
--      
-+
-       if (!p) return HANDLER_ERROR;
--      
-+
-       p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
--      
-+
-       for (i = 0; i < srv->config_context->used; i++) {
-               plugin_config *s;
--              
-+
-               s = calloc(1, sizeof(plugin_config));
--              
-+
-               s->server_root = buffer_init();
-               s->default_host = buffer_init();
-               s->document_root = buffer_init();
--              
-+
-               s->docroot_cache_key = buffer_init();
-               s->docroot_cache_value = buffer_init();
-               s->docroot_cache_servername = buffer_init();
-               s->debug = 0;
--              
-+
-               cv[0].destination = s->server_root;
-               cv[1].destination = s->default_host;
-               cv[2].destination = s->document_root;
-               cv[3].destination = &(s->debug);
--              
--              
-+
-+
-               p->config_storage[i] = s;
--              
-+
-               if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
-                       return HANDLER_ERROR;
-               }
-       }
--      
-+
-       return HANDLER_GO_ON;
- }
- static int build_doc_root(server *srv, connection *con, plugin_data *p, buffer *out, buffer *host) {
-       stat_cache_entry *sce = NULL;
--      
-+
-       buffer_prepare_copy(out, 128);
-       if (p->conf.server_root->used) {
-               buffer_copy_string_buffer(out, p->conf.server_root);
--              
-+
-               if (host->used) {
-                       /* a hostname has to start with a alpha-numerical character
-                        * and must not contain a slash "/"
-                        */
-                       char *dp;
--                      
--                      BUFFER_APPEND_SLASH(out);
--                      
-+
-+                      PATHNAME_APPEND_SLASH(out);
-+
-                       if (NULL == (dp = strchr(host->ptr, ':'))) {
-                               buffer_append_string_buffer(out, host);
-                       } else {
-                               buffer_append_string_len(out, host->ptr, dp - host->ptr);
-                       }
-               }
--              BUFFER_APPEND_SLASH(out);
--              
-+              PATHNAME_APPEND_SLASH(out);
-+
-               if (p->conf.document_root->used > 2 && p->conf.document_root->ptr[0] == '/') {
-                       buffer_append_string_len(out, p->conf.document_root->ptr + 1, p->conf.document_root->used - 2);
-               } else {
-                       buffer_append_string_buffer(out, p->conf.document_root);
--                      BUFFER_APPEND_SLASH(out);
-+                      PATHNAME_APPEND_SLASH(out);
-               }
-       } else {
-               buffer_copy_string_buffer(out, con->conf.document_root);
--              BUFFER_APPEND_SLASH(out);
-+              PATHNAME_APPEND_SLASH(out);
-       }
--      
-+
-       if (HANDLER_ERROR == stat_cache_get_entry(srv, con, out, &sce)) {
-               if (p->conf.debug) {
-                       log_error_write(srv, __FILE__, __LINE__, "sb",
-@@ -169,57 +171,53 @@
-       } else if (!S_ISDIR(sce->st.st_mode)) {
-               return -1;
-       }
--      
-+
-       return 0;
- }
--
--#define PATCH(x) \
--      p->conf.x = s->x;
- static int mod_simple_vhost_patch_connection(server *srv, connection *con, plugin_data *p) {
-       size_t i, j;
-       plugin_config *s = p->config_storage[0];
--      
--      PATCH(server_root);
--      PATCH(default_host);
--      PATCH(document_root);
--      
--      PATCH(docroot_cache_key);
--      PATCH(docroot_cache_value);
--      PATCH(docroot_cache_servername);
--      PATCH(debug);
--      
-+      PATCH_OPTION(server_root);
-+      PATCH_OPTION(default_host);
-+      PATCH_OPTION(document_root);
-+
-+      PATCH_OPTION(docroot_cache_key);
-+      PATCH_OPTION(docroot_cache_value);
-+      PATCH_OPTION(docroot_cache_servername);
-+
-+      PATCH_OPTION(debug);
-+
-       /* skip the first, the global context */
-       for (i = 1; i < srv->config_context->used; i++) {
-               data_config *dc = (data_config *)srv->config_context->data[i];
-               s = p->config_storage[i];
--              
-+
-               /* condition didn't match */
-               if (!config_check_cond(srv, con, dc)) continue;
--              
-+
-               /* merge config */
-               for (j = 0; j < dc->value->used; j++) {
-                       data_unset *du = dc->value->data[j];
--                      
-+
-                       if (buffer_is_equal_string(du->key, CONST_STR_LEN("simple-vhost.server-root"))) {
--                              PATCH(server_root);
--                              PATCH(docroot_cache_key);
--                              PATCH(docroot_cache_value);
--                              PATCH(docroot_cache_servername);
-+                              PATCH_OPTION(server_root);
-+                              PATCH_OPTION(docroot_cache_key);
-+                              PATCH_OPTION(docroot_cache_value);
-+                              PATCH_OPTION(docroot_cache_servername);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("simple-vhost.default-host"))) {
--                              PATCH(default_host);
-+                              PATCH_OPTION(default_host);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("simple-vhost.document-root"))) {
--                              PATCH(document_root);
-+                              PATCH_OPTION(document_root);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("simple-vhost.debug"))) {
--                              PATCH(debug);
-+                              PATCH_OPTION(debug);
-                       }
-               }
-       }
--      
-+
-       return 0;
- }
--#undef PATCH
- static handler_t mod_simple_vhost_docroot(server *srv, connection *con, void *p_data) {
-       plugin_data *p = p_data;
-@@ -227,12 +225,12 @@
-       /*
-        * cache the last successfull translation from hostname (authority) to docroot
-        * - this saves us a stat() call
--       * 
-+       *
-        */
--      
-+
-       mod_simple_vhost_patch_connection(srv, con, p);
--      
--      if (p->conf.docroot_cache_key->used && 
-+
-+      if (p->conf.docroot_cache_key->used &&
-           con->uri.authority->used &&
-           buffer_is_equal(p->conf.docroot_cache_key, con->uri.authority)) {
-               /* cache hit */
-@@ -243,8 +241,8 @@
-               if ((con->uri.authority->used == 0) ||
-                   build_doc_root(srv, con, p, p->doc_root, con->uri.authority)) {
-                       /* not found, fallback the default-host */
--                      if (build_doc_root(srv, con, p, 
--                                         p->doc_root, 
-+                      if (build_doc_root(srv, con, p,
-+                                         p->doc_root,
-                                          p->conf.default_host)) {
-                               return HANDLER_GO_ON;
-                       } else {
-@@ -253,15 +251,15 @@
-               } else {
-                       buffer_copy_string_buffer(con->server_name, con->uri.authority);
-               }
--              
-+
-               /* copy to cache */
-               buffer_copy_string_buffer(p->conf.docroot_cache_key,        con->uri.authority);
-               buffer_copy_string_buffer(p->conf.docroot_cache_value,      p->doc_root);
-               buffer_copy_string_buffer(p->conf.docroot_cache_servername, con->server_name);
--              
-+
-               buffer_copy_string_buffer(con->physical.doc_root, p->doc_root);
-       }
--      
-+
-       return HANDLER_GO_ON;
- }
-@@ -269,13 +267,13 @@
- int mod_simple_vhost_plugin_init(plugin *p) {
-       p->version     = LIGHTTPD_VERSION_ID;
-       p->name        = buffer_init_string("simple_vhost");
--      
-+
-       p->init        = mod_simple_vhost_init;
-       p->set_defaults = mod_simple_vhost_set_defaults;
-       p->handle_docroot  = mod_simple_vhost_docroot;
-       p->cleanup     = mod_simple_vhost_free;
--      
-+
-       p->data        = NULL;
--      
-+
-       return 0;
- }
---- ../lighttpd-1.4.11/src/mod_skeleton.c      2005-10-02 18:30:51.000000000 +0300
-+++ lighttpd-1.5.0/src/mod_skeleton.c  2006-07-16 00:26:03.000000000 +0300
-@@ -14,13 +14,13 @@
- /**
-  * this is a skeleton for a lighttpd plugin
-- * 
-+ *
-  * just replaces every occurance of 'skeleton' by your plugin name
-- * 
-+ *
-  * e.g. in vim:
-- * 
-+ *
-  *   :%s/skeleton/myhandler/
-- * 
-+ *
-  */
-@@ -33,12 +33,12 @@
- typedef struct {
-       PLUGIN_DATA;
--      
-+
-       buffer *match_buf;
--      
-+
-       plugin_config **config_storage;
--      
--      plugin_config conf; 
-+
-+      plugin_config conf;
- } plugin_data;
- typedef struct {
-@@ -47,36 +47,36 @@
- static handler_ctx * handler_ctx_init() {
-       handler_ctx * hctx;
--      
-+
-       hctx = calloc(1, sizeof(*hctx));
--      
-+
-       return hctx;
- }
- static void handler_ctx_free(handler_ctx *hctx) {
--      
-+
-       free(hctx);
- }
- /* init the plugin data */
- INIT_FUNC(mod_skeleton_init) {
-       plugin_data *p;
--      
-+
-       p = calloc(1, sizeof(*p));
--      
-+
-       p->match_buf = buffer_init();
--      
-+
-       return p;
- }
- /* detroy the plugin data */
- FREE_FUNC(mod_skeleton_free) {
-       plugin_data *p = p_d;
--      
-+
-       UNUSED(srv);
-       if (!p) return HANDLER_GO_ON;
--      
-+
-       if (p->config_storage) {
-               size_t i;
-@@ -84,18 +84,18 @@
-                       plugin_config *s = p->config_storage[i];
-                       if (!s) continue;
--                      
-+
-                       array_free(s->match);
--                      
-+
-                       free(s);
-               }
-               free(p->config_storage);
-       }
--      
-+
-       buffer_free(p->match_buf);
--      
-+
-       free(p);
--      
-+
-       return HANDLER_GO_ON;
- }
-@@ -104,91 +104,88 @@
- SETDEFAULTS_FUNC(mod_skeleton_set_defaults) {
-       plugin_data *p = p_d;
-       size_t i = 0;
--      
--      config_values_t cv[] = { 
-+
-+      config_values_t cv[] = {
-               { "skeleton.array",             NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
-               { NULL,                         NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
-       };
--      
-+
-       if (!p) return HANDLER_ERROR;
--      
-+
-       p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
--      
-+
-       for (i = 0; i < srv->config_context->used; i++) {
-               plugin_config *s;
--              
-+
-               s = calloc(1, sizeof(plugin_config));
-               s->match    = array_init();
--              
-+
-               cv[0].destination = s->match;
--              
-+
-               p->config_storage[i] = s;
--      
-+
-               if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
-                       return HANDLER_ERROR;
-               }
-       }
--      
-+
-       return HANDLER_GO_ON;
- }
--#define PATCH(x) \
--      p->conf.x = s->x;
- static int mod_skeleton_patch_connection(server *srv, connection *con, plugin_data *p) {
-       size_t i, j;
-       plugin_config *s = p->config_storage[0];
--      
--      PATCH(match);
--      
-+
-+      PATCH_OPTION(match);
-+
-       /* skip the first, the global context */
-       for (i = 1; i < srv->config_context->used; i++) {
-               data_config *dc = (data_config *)srv->config_context->data[i];
-               s = p->config_storage[i];
--              
-+
-               /* condition didn't match */
-               if (!config_check_cond(srv, con, dc)) continue;
--              
-+
-               /* merge config */
-               for (j = 0; j < dc->value->used; j++) {
-                       data_unset *du = dc->value->data[j];
--                      
-+
-                       if (buffer_is_equal_string(du->key, CONST_STR_LEN("skeleton.array"))) {
--                              PATCH(match);
-+                              PATCH_OPTION(match);
-                       }
-               }
-       }
--      
-+
-       return 0;
- }
--#undef PATCH
- URIHANDLER_FUNC(mod_skeleton_uri_handler) {
-       plugin_data *p = p_d;
-       int s_len;
-       size_t k, i;
--      
-+
-       UNUSED(srv);
-       if (con->uri.path->used == 0) return HANDLER_GO_ON;
--      
-+
-       mod_skeleton_patch_connection(srv, con, p);
-       s_len = con->uri.path->used - 1;
--      
-+
-       for (k = 0; k < p->conf.match->used; k++) {
-               data_string *ds = (data_string *)p->conf.match->data[k];
-               int ct_len = ds->value->used - 1;
--              
-+
-               if (ct_len > s_len) continue;
-               if (ds->value->used == 0) continue;
--              
-+
-               if (0 == strncmp(con->uri.path->ptr + s_len - ct_len, ds->value->ptr, ct_len)) {
-                       con->http_status = 403;
--      
-+
-                       return HANDLER_FINISHED;
-               }
-       }
--      
-+
-       /* not found */
-       return HANDLER_GO_ON;
- }
-@@ -198,13 +195,13 @@
- int mod_skeleton_plugin_init(plugin *p) {
-       p->version     = LIGHTTPD_VERSION_ID;
-       p->name        = buffer_init_string("skeleton");
--      
-+
-       p->init        = mod_skeleton_init;
-       p->handle_uri_clean  = mod_skeleton_uri_handler;
-       p->set_defaults  = mod_skeleton_set_defaults;
-       p->cleanup     = mod_skeleton_free;
--      
-+
-       p->data        = NULL;
--      
-+
-       return 0;
- }
---- ../lighttpd-1.4.11/src/mod_sql_vhost_core.c        1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/mod_sql_vhost_core.c    2006-07-20 00:57:20.000000000 +0300
-@@ -0,0 +1,211 @@
-+#include <stdio.h>
-+#include <errno.h>
-+#include <fcntl.h>
-+#include <string.h>
-+
-+#ifdef HAVE_CONFIG_H
-+#include "config.h"
-+#endif
-+
-+#include "plugin.h"
-+#include "log.h"
-+
-+#include "stat_cache.h"
-+
-+#include "mod_sql_vhost_core.h"
-+
-+#define plugin_data mod_sql_vhost_core_plugin_data
-+#define plugin_config mod_sql_vhost_core_plugin_config
-+
-+/* init the plugin data */
-+INIT_FUNC(mod_sql_vhost_core_init) {
-+      plugin_data *p;
-+
-+      p = calloc(1, sizeof(*p));
-+
-+      p->docroot = buffer_init();
-+      p->host = buffer_init();
-+
-+      return p;
-+}
-+
-+/* cleanup the plugin data */
-+SERVER_FUNC(mod_sql_vhost_core_cleanup) {
-+      plugin_data *p = p_d;
-+
-+      UNUSED(srv);
-+
-+      if (!p) return HANDLER_GO_ON;
-+
-+      if (p->config_storage) {
-+              size_t i;
-+              for (i = 0; i < srv->config_context->used; i++) {
-+                      plugin_config *s = p->config_storage[i];
-+
-+                      if (!s) continue;
-+
-+                      buffer_free(s->db);
-+                      buffer_free(s->user);
-+                      buffer_free(s->pass);
-+                      buffer_free(s->sock);
-+                      buffer_free(s->backend);
-+                      buffer_free(s->hostname);
-+                      buffer_free(s->select_vhost);
-+
-+                      free(s);
-+              }
-+              free(p->config_storage);
-+      }
-+      buffer_free(p->docroot);
-+      buffer_free(p->host);
-+
-+      free(p);
-+
-+      return HANDLER_GO_ON;
-+}
-+
-+/* set configuration values */
-+SERVER_FUNC(mod_sql_vhost_core_set_defaults) {
-+      plugin_data *p = p_d;
-+
-+      size_t i = 0;
-+
-+      config_values_t cv[] = {
-+              { "sql-vhost.db",       NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER }, /* 0 * e.g. vhost */
-+              { "sql-vhost.user",     NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER }, /* 1 * lighty */
-+              { "sql-vhost.pass",     NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER }, /* 2 * secrect */
-+              { "sql-vhost.sock",     NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER }, /* 3 * /tmp/mysql.sock */
-+              { "sql-vhost.select-vhost", NULL, T_CONFIG_STRING,      T_CONFIG_SCOPE_SERVER }, /* 4 * SELECT ... FROM hosts WHERE hostname = ? */
-+              { "sql-vhost.hostname", NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER }, /* 5 * 127.0.0.1 */
-+              { "sql-vhost.port",     NULL, T_CONFIG_SHORT,   T_CONFIG_SCOPE_SERVER }, /* 6 * 3306 */
-+              { "sql-vhost.backend",  NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER }, /* 7 * mysql */
-+
-+              /* backward compat */
-+              { "mysql-vhost.db",     NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER }, /* 8 == 0 */
-+              { "mysql-vhost.user",   NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER }, /* 9 == 1 */
-+              { "mysql-vhost.pass",   NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER }, /* 10 == 2 */
-+              { "mysql-vhost.sock",   NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER }, /* 11 == 3 */
-+              { "mysql-vhost.sql",    NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER }, /* 12 == 4 */
-+              { "mysql-vhost.hostname", NULL, T_CONFIG_STRING,T_CONFIG_SCOPE_SERVER }, /* 13 == 5 */
-+              { "mysql-vhost.port",   NULL, T_CONFIG_SHORT,   T_CONFIG_SCOPE_SERVER }, /* 14 == 6 */
-+
-+                { NULL,                       NULL, T_CONFIG_UNSET,   T_CONFIG_SCOPE_UNSET }
-+        };
-+
-+      p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
-+
-+      for (i = 0; i < srv->config_context->used; i++) {
-+              plugin_config *s;
-+
-+              s = calloc(1, sizeof(plugin_config));
-+              s->db = buffer_init();
-+              s->user = buffer_init();
-+              s->pass = buffer_init();
-+              s->sock = buffer_init();
-+              s->hostname = buffer_init();
-+              s->backend = buffer_init();
-+              s->port   = 0;               /* default port for mysql */
-+              s->select_vhost = buffer_init();
-+              s->backend_data = NULL;
-+
-+              cv[0].destination = s->db;
-+              cv[1].destination = s->user;
-+              cv[2].destination = s->pass;
-+              cv[3].destination = s->sock;
-+              cv[4].destination = s->select_vhost;
-+              cv[5].destination = s->hostname;
-+              cv[6].destination = &(s->port);
-+              cv[7].destination = s->backend;
-+
-+              /* backend compat */
-+              cv[8].destination = cv[0].destination;
-+              cv[9].destination = cv[1].destination;
-+              cv[10].destination = cv[2].destination;
-+              cv[11].destination = cv[3].destination;
-+              cv[12].destination = cv[4].destination;
-+              cv[13].destination = cv[5].destination;
-+              cv[14].destination = cv[6].destination;
-+
-+              p->config_storage[i] = s;
-+
-+              if (config_insert_values_global(srv,
-+                      ((data_config *)srv->config_context->data[i])->value,
-+                      cv)) return HANDLER_ERROR;
-+
-+              /* we only parse the config, the backend plugin will patch itself into the plugin-struct */
-+      }
-+
-+        return HANDLER_GO_ON;
-+}
-+
-+static int mod_sql_vhost_core_patch_connection(server *srv, connection *con, plugin_data *p) {
-+      size_t i;
-+      plugin_config *s = p->config_storage[0];
-+
-+      PATCH_OPTION(backend_data);
-+      PATCH_OPTION(get_vhost);
-+
-+      /* skip the first, the global context */
-+      for (i = 1; i < srv->config_context->used; i++) {
-+              data_config *dc = (data_config *)srv->config_context->data[i];
-+              s = p->config_storage[i];
-+
-+              /* condition didn't match */
-+              if (!config_check_cond(srv, con, dc)) continue;
-+
-+              if (s->backend_data) {
-+                      PATCH_OPTION(backend_data);
-+                      PATCH_OPTION(get_vhost);
-+              }
-+      }
-+
-+      return 0;
-+}
-+
-+/* handle document root request */
-+CONNECTION_FUNC(mod_sql_vhost_core_handle_docroot) {
-+      plugin_data *p = p_d;
-+      stat_cache_entry *sce;
-+
-+      /* no host specified? */
-+      if (!con->uri.authority->used) return HANDLER_GO_ON;
-+
-+      mod_sql_vhost_core_patch_connection(srv, con, p);
-+
-+      /* do we have backend ? */
-+      if (!p->conf.get_vhost) return HANDLER_GO_ON;
-+
-+      /* ask the backend for the data */
-+      if (0 != p->conf.get_vhost(srv, con, p->conf.backend_data, p->docroot, p->host)) {
-+              return HANDLER_GO_ON;
-+      }
-+
-+      if (HANDLER_ERROR == stat_cache_get_entry(srv, con, p->docroot, &sce)) {
-+              log_error_write(srv, __FILE__, __LINE__, "sb", strerror(errno), p->docroot);
-+              return HANDLER_GO_ON;
-+      }
-+        if (!S_ISDIR(sce->st.st_mode)) {
-+              log_error_write(srv, __FILE__, __LINE__, "sb", "Not a directory", p->docroot);
-+              return HANDLER_GO_ON;
-+      }
-+
-+      buffer_copy_string_buffer(con->server_name, p->host);
-+      buffer_copy_string_buffer(con->physical.doc_root, p->docroot);
-+
-+      return HANDLER_GO_ON;
-+}
-+
-+/* this function is called at dlopen() time and inits the callbacks */
-+int mod_sql_vhost_core_plugin_init(plugin *p) {
-+      p->version     = LIGHTTPD_VERSION_ID;
-+      p->name                         = buffer_init_string("mod_sql_vhost_core");
-+
-+      p->init                         = mod_sql_vhost_core_init;
-+      p->cleanup                      = mod_sql_vhost_core_cleanup;
-+
-+      p->set_defaults                 = mod_sql_vhost_core_set_defaults;
-+      p->handle_docroot               = mod_sql_vhost_core_handle_docroot;
-+
-+      return 0;
-+}
-+
---- ../lighttpd-1.4.11/src/mod_sql_vhost_core.h        1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/mod_sql_vhost_core.h    2006-07-16 00:26:04.000000000 +0300
-@@ -0,0 +1,49 @@
-+#ifndef _MOD_SQL_VHOST_CORE_H_
-+#define _MOD_SQL_VHOST_CORE_H_
-+
-+#include "buffer.h"
-+#include "plugin.h"
-+
-+#define SQLVHOST_BACKEND_GETVHOST_PARAMS \
-+      (server *srv, connection *con, void *p_d, buffer *docroot, buffer *host)
-+
-+#define SQLVHOST_BACKEND_GETVHOST_RETVAL handler_t
-+
-+#define SQLVHOST_BACKEND_GETVHOST(name) \
-+      SQLVHOST_BACKEND_GETVHOST_RETVAL name SQLVHOST_BACKEND_GETVHOST_PARAMS
-+
-+#define SQLVHOST_BACKEND_GETVHOST_PTR(name) \
-+      SQLVHOST_BACKEND_GETVHOST_RETVAL (* name)SQLVHOST_BACKEND_GETVHOST_PARAMS
-+
-+typedef struct {
-+      buffer  *db;
-+      buffer  *user;
-+      buffer  *pass;
-+      buffer  *sock;
-+
-+      buffer  *hostname;
-+      unsigned short port;
-+
-+      buffer  *backend;
-+      void *backend_data;
-+
-+      buffer *select_vhost;
-+
-+      SQLVHOST_BACKEND_GETVHOST_PTR(get_vhost);
-+} mod_sql_vhost_core_plugin_config;
-+
-+/* global plugin data */
-+typedef struct {
-+      PLUGIN_DATA;
-+
-+      buffer  *docroot;
-+      buffer  *host;
-+
-+      mod_sql_vhost_core_plugin_config **config_storage;
-+
-+      mod_sql_vhost_core_plugin_config conf;
-+} mod_sql_vhost_core_plugin_data;
-+
-+
-+
-+#endif
---- ../lighttpd-1.4.11/src/mod_ssi.c   2006-03-04 17:09:48.000000000 +0200
-+++ lighttpd-1.5.0/src/mod_ssi.c       2006-09-07 00:57:05.000000000 +0300
-@@ -6,7 +6,6 @@
- #include <string.h>
- #include <errno.h>
- #include <time.h>
--#include <unistd.h>
- #include "base.h"
- #include "log.h"
-@@ -23,6 +22,8 @@
- #include "inet_ntop_cache.h"
- #include "sys-socket.h"
-+#include "sys-strings.h"
-+#include "sys-files.h"
- #ifdef HAVE_PWD_H
- #include <pwd.h>
-@@ -39,15 +40,15 @@
- /* init the plugin data */
- INIT_FUNC(mod_ssi_init) {
-       plugin_data *p;
--      
-+
-       p = calloc(1, sizeof(*p));
--      
-+
-       p->timefmt = buffer_init();
-       p->stat_fn = buffer_init();
--      
-+
-       p->ssi_vars = array_init();
-       p->ssi_cgi_env = array_init();
--      
-+
-       return p;
- }
-@@ -55,21 +56,21 @@
- FREE_FUNC(mod_ssi_free) {
-       plugin_data *p = p_d;
-       UNUSED(srv);
--      
-+
-       if (!p) return HANDLER_GO_ON;
--      
-+
-       if (p->config_storage) {
-               size_t i;
-               for (i = 0; i < srv->config_context->used; i++) {
-                       plugin_config *s = p->config_storage[i];
--                      
-+
-                       array_free(s->ssi_extension);
--                      
-+
-                       free(s);
-               }
-               free(p->config_storage);
-       }
--      
-+
-       array_free(p->ssi_vars);
-       array_free(p->ssi_cgi_env);
- #ifdef HAVE_PCRE_H
-@@ -77,9 +78,9 @@
- #endif
-       buffer_free(p->timefmt);
-       buffer_free(p->stat_fn);
--      
-+
-       free(p);
--      
-+
-       return HANDLER_GO_ON;
- }
-@@ -92,36 +93,36 @@
-       const char *errptr;
-       int erroff;
- #endif
--      
--      config_values_t cv[] = { 
-+
-+      config_values_t cv[] = {
-               { "ssi.extension",              NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
-               { NULL,                         NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
-       };
--      
-+
-       if (!p) return HANDLER_ERROR;
--      
-+
-       p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
--      
-+
-       for (i = 0; i < srv->config_context->used; i++) {
-               plugin_config *s;
--              
-+
-               s = calloc(1, sizeof(plugin_config));
-               s->ssi_extension  = array_init();
--              
-+
-               cv[0].destination = s->ssi_extension;
--              
-+
-               p->config_storage[i] = s;
--      
-+
-               if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
-                       return HANDLER_ERROR;
-               }
-       }
--      
-+
- #ifdef HAVE_PCRE_H
-       /* allow 2 params */
-       if (NULL == (p->ssi_regex = pcre_compile("<!--#([a-z]+)\\s+(?:([a-z]+)=\"(.*?)(?<!\\\\)\"\\s*)?(?:([a-z]+)=\"(.*?)(?<!\\\\)\"\\s*)?-->", 0, &errptr, &erroff, NULL))) {
-               log_error_write(srv, __FILE__, __LINE__, "sds",
--                              "ssi: pcre ", 
-+                              "ssi: pcre ",
-                               erroff, errptr);
-               return HANDLER_ERROR;
-       }
-@@ -130,52 +131,52 @@
-                       "mod_ssi: pcre support is missing, please recompile with pcre support or remove mod_ssi from the list of modules");
-       return HANDLER_ERROR;
- #endif
--      
-+
-       return HANDLER_GO_ON;
- }
- int ssi_env_add(array *env, const char *key, const char *val) {
-       data_string *ds;
--                      
-+
-       if (NULL == (ds = (data_string *)array_get_unused_element(env, TYPE_STRING))) {
-               ds = data_string_init();
-       }
-       buffer_copy_string(ds->key,   key);
-       buffer_copy_string(ds->value, val);
--      
-+
-       array_insert_unique(env, (data_unset *)ds);
--      
-+
-       return 0;
- }
- /**
-  *
-  *  the next two functions are take from fcgi.c
-- * 
-+ *
-  */
- static int ssi_env_add_request_headers(server *srv, connection *con, plugin_data *p) {
-       size_t i;
--      
-+
-       for (i = 0; i < con->request.headers->used; i++) {
-               data_string *ds;
--              
-+
-               ds = (data_string *)con->request.headers->data[i];
--              
-+
-               if (ds->value->used && ds->key->used) {
-                       size_t j;
-                       buffer_reset(srv->tmp_buf);
--                      
-+
-                       /* don't forward the Authorization: Header */
-                       if (0 == strcasecmp(ds->key->ptr, "AUTHORIZATION")) {
-                               continue;
-                       }
--                      
-+
-                       if (0 != strcasecmp(ds->key->ptr, "CONTENT-TYPE")) {
-                               buffer_copy_string(srv->tmp_buf, "HTTP_");
-                               srv->tmp_buf->used--;
-                       }
--                      
-+
-                       buffer_prepare_append(srv->tmp_buf, ds->key->used + 2);
-                       for (j = 0; j < ds->key->used - 1; j++) {
-                               char c = '_';
-@@ -189,33 +190,33 @@
-                               srv->tmp_buf->ptr[srv->tmp_buf->used++] = c;
-                       }
-                       srv->tmp_buf->ptr[srv->tmp_buf->used] = '\0';
--                      
-+
-                       ssi_env_add(p->ssi_cgi_env, srv->tmp_buf->ptr, ds->value->ptr);
-               }
-       }
--      
-+
-       return 0;
- }
- static int build_ssi_cgi_vars(server *srv, connection *con, plugin_data *p) {
-       char buf[32];
--      
-+
-       server_socket *srv_sock = con->srv_socket;
--      
-+
- #ifdef HAVE_IPV6
-       char b2[INET6_ADDRSTRLEN + 1];
- #endif
- #define CONST_STRING(x) \
-               x
--      
-+
-       array_reset(p->ssi_cgi_env);
--      
-+
-       ssi_env_add(p->ssi_cgi_env, CONST_STRING("SERVER_SOFTWARE"), PACKAGE_NAME"/"PACKAGE_VERSION);
-       ssi_env_add(p->ssi_cgi_env, CONST_STRING("SERVER_NAME"),
- #ifdef HAVE_IPV6
--                   inet_ntop(srv_sock->addr.plain.sa_family, 
--                             srv_sock->addr.plain.sa_family == AF_INET6 ? 
-+                   inet_ntop(srv_sock->addr.plain.sa_family,
-+                             srv_sock->addr.plain.sa_family == AF_INET6 ?
-                              (const void *) &(srv_sock->addr.ipv6.sin6_addr) :
-                              (const void *) &(srv_sock->addr.ipv4.sin_addr),
-                              b2, sizeof(b2)-1)
-@@ -224,28 +225,28 @@
- #endif
-                    );
-       ssi_env_add(p->ssi_cgi_env, CONST_STRING("GATEWAY_INTERFACE"), "CGI/1.1");
--              
--      ltostr(buf, 
-+
-+      ltostr(buf,
- #ifdef HAVE_IPV6
-              ntohs(srv_sock->addr.plain.sa_family ? srv_sock->addr.ipv6.sin6_port : srv_sock->addr.ipv4.sin_port)
- #else
-              ntohs(srv_sock->addr.ipv4.sin_port)
- #endif
-              );
--      
-+
-       ssi_env_add(p->ssi_cgi_env, CONST_STRING("SERVER_PORT"), buf);
--      
-+
-       ssi_env_add(p->ssi_cgi_env, CONST_STRING("REMOTE_ADDR"),
-                   inet_ntop_cache_get_ip(srv, &(con->dst_addr)));
--      
-+
-       if (con->authed_user->used) {
-               ssi_env_add(p->ssi_cgi_env, CONST_STRING("REMOTE_USER"),
-                            con->authed_user->ptr);
-       }
--      
-+
-       if (con->request.content_length > 0) {
-               /* CGI-SPEC 6.1.2 and FastCGI spec 6.3 */
--              
-+
-               /* request.content_length < SSIZE_MAX, see request.c */
-               ltostr(buf, con->request.content_length);
-               ssi_env_add(p->ssi_cgi_env, CONST_STRING("CONTENT_LENGTH"), buf);
-@@ -271,30 +272,30 @@
-       if (con->request.pathinfo->used) {
-               ssi_env_add(p->ssi_cgi_env, CONST_STRING("PATH_INFO"), con->request.pathinfo->ptr);
-       }
--              
-+
-       ssi_env_add(p->ssi_cgi_env, CONST_STRING("SCRIPT_FILENAME"), con->physical.path->ptr);
-       ssi_env_add(p->ssi_cgi_env, CONST_STRING("DOCUMENT_ROOT"), con->physical.doc_root->ptr);
--      
-+
-       ssi_env_add(p->ssi_cgi_env, CONST_STRING("REQUEST_URI"), con->request.uri->ptr);
-       ssi_env_add(p->ssi_cgi_env, CONST_STRING("QUERY_STRING"), con->uri.query->used ? con->uri.query->ptr : "");
-       ssi_env_add(p->ssi_cgi_env, CONST_STRING("REQUEST_METHOD"), get_http_method_name(con->request.http_method));
-       ssi_env_add(p->ssi_cgi_env, CONST_STRING("REDIRECT_STATUS"), "200");
-       ssi_env_add(p->ssi_cgi_env, CONST_STRING("SERVER_PROTOCOL"), get_http_version_name(con->request.http_version));
--      
-+
-       ssi_env_add_request_headers(srv, con, p);
--      
-+
-       return 0;
- }
--static int process_ssi_stmt(server *srv, connection *con, plugin_data *p, 
-+static int process_ssi_stmt(server *srv, connection *con, plugin_data *p,
-                           const char **l, size_t n) {
-       size_t i, ssicmd = 0;
-       char buf[255];
-       buffer *b = NULL;
--      
--      struct { 
-+
-+      struct {
-               const char *var;
--              enum { SSI_UNSET, SSI_ECHO, SSI_FSIZE, SSI_INCLUDE, SSI_FLASTMOD, 
-+              enum { SSI_UNSET, SSI_ECHO, SSI_FSIZE, SSI_INCLUDE, SSI_FLASTMOD,
-                               SSI_CONFIG, SSI_PRINTENV, SSI_SET, SSI_IF, SSI_ELIF,
-                               SSI_ELSE, SSI_ENDIF, SSI_EXEC } type;
-       } ssicmds[] = {
-@@ -310,27 +311,27 @@
-               { "endif",    SSI_ENDIF },
-               { "else",     SSI_ELSE },
-               { "exec",     SSI_EXEC },
--              
-+
-               { NULL, SSI_UNSET }
-       };
--      
-+
-       for (i = 0; ssicmds[i].var; i++) {
-               if (0 == strcmp(l[1], ssicmds[i].var)) {
-                       ssicmd = ssicmds[i].type;
-                       break;
-               }
-       }
--      
-+
-       switch(ssicmd) {
-       case SSI_ECHO: {
-               /* echo */
-               int var = 0, enc = 0;
-               const char *var_val = NULL;
-               stat_cache_entry *sce = NULL;
--              
--              struct { 
-+
-+              struct {
-                       const char *var;
--                      enum { SSI_ECHO_UNSET, SSI_ECHO_DATE_GMT, SSI_ECHO_DATE_LOCAL, SSI_ECHO_DOCUMENT_NAME, SSI_ECHO_DOCUMENT_URI, 
-+                      enum { SSI_ECHO_UNSET, SSI_ECHO_DATE_GMT, SSI_ECHO_DATE_LOCAL, SSI_ECHO_DOCUMENT_NAME, SSI_ECHO_DOCUMENT_URI,
-                                       SSI_ECHO_LAST_MODIFIED, SSI_ECHO_USER_NAME } type;
-               } echovars[] = {
-                       { "DATE_GMT",      SSI_ECHO_DATE_GMT },
-@@ -339,27 +340,27 @@
-                       { "DOCUMENT_URI",  SSI_ECHO_DOCUMENT_URI },
-                       { "LAST_MODIFIED", SSI_ECHO_LAST_MODIFIED },
-                       { "USER_NAME",     SSI_ECHO_USER_NAME },
--                      
-+
-                       { NULL, SSI_ECHO_UNSET }
-               };
--              
--              struct { 
-+
-+              struct {
-                       const char *var;
-                       enum { SSI_ENC_UNSET, SSI_ENC_URL, SSI_ENC_NONE, SSI_ENC_ENTITY } type;
-               } encvars[] = {
-                       { "url",          SSI_ENC_URL },
-                       { "none",         SSI_ENC_NONE },
-                       { "entity",       SSI_ENC_ENTITY },
--                      
-+
-                       { NULL, SSI_ENC_UNSET }
-               };
--              
-+
-               for (i = 2; i < n; i += 2) {
-                       if (0 == strcmp(l[i], "var")) {
-                               int j;
--                              
-+
-                               var_val = l[i+1];
--                              
-+
-                               for (j = 0; echovars[j].var; j++) {
-                                       if (0 == strcmp(l[i+1], echovars[j].var)) {
-                                               var = echovars[j].type;
-@@ -368,7 +369,7 @@
-                               }
-                       } else if (0 == strcmp(l[i], "encoding")) {
-                               int j;
--                              
-+
-                               for (j = 0; encvars[j].var; j++) {
-                                       if (0 == strcmp(l[i+1], encvars[j].var)) {
-                                               enc = encvars[j].type;
-@@ -377,27 +378,27 @@
-                               }
-                       } else {
-                               log_error_write(srv, __FILE__, __LINE__, "sss",
--                                              "ssi: unknow attribute for ", 
-+                                              "ssi: unknow attribute for ",
-                                               l[1], l[i]);
-                       }
-               }
--              
-+
-               if (p->if_is_false) break;
--              
-+
-               if (!var_val) {
-                       log_error_write(srv, __FILE__, __LINE__, "sss",
--                                      "ssi: ", 
-+                                      "ssi: ",
-                                       l[1], "var is missing");
-                       break;
-               }
-               stat_cache_get_entry(srv, con, con->physical.path, &sce);
--              
-+
-               switch(var) {
-               case SSI_ECHO_USER_NAME: {
-                       struct passwd *pw;
--                      
--                      b = chunkqueue_get_append_buffer(con->write_queue);
-+
-+                      b = chunkqueue_get_append_buffer(con->send);
- #ifdef HAVE_PWD_H
-                       if (NULL == (pw = getpwuid(sce->st.st_uid))) {
-                               buffer_copy_long(b, sce->st.st_uid);
-@@ -411,8 +412,8 @@
-               }
-               case SSI_ECHO_LAST_MODIFIED:    {
-                       time_t t = sce->st.st_mtime;
--                      
--                      b = chunkqueue_get_append_buffer(con->write_queue);
-+
-+                      b = chunkqueue_get_append_buffer(con->send);
-                       if (0 == strftime(buf, sizeof(buf), p->timefmt->ptr, localtime(&t))) {
-                               buffer_copy_string(b, "(none)");
-                       } else {
-@@ -422,8 +423,8 @@
-               }
-               case SSI_ECHO_DATE_LOCAL: {
-                       time_t t = time(NULL);
--                      
--                      b = chunkqueue_get_append_buffer(con->write_queue);
-+
-+                      b = chunkqueue_get_append_buffer(con->send);
-                       if (0 == strftime(buf, sizeof(buf), p->timefmt->ptr, localtime(&t))) {
-                               buffer_copy_string(b, "(none)");
-                       } else {
-@@ -433,8 +434,8 @@
-               }
-               case SSI_ECHO_DATE_GMT: {
-                       time_t t = time(NULL);
--                      
--                      b = chunkqueue_get_append_buffer(con->write_queue);
-+
-+                      b = chunkqueue_get_append_buffer(con->send);
-                       if (0 == strftime(buf, sizeof(buf), p->timefmt->ptr, gmtime(&t))) {
-                               buffer_copy_string(b, "(none)");
-                       } else {
-@@ -444,8 +445,8 @@
-               }
-               case SSI_ECHO_DOCUMENT_NAME: {
-                       char *sl;
--                      
--                      b = chunkqueue_get_append_buffer(con->write_queue);
-+
-+                      b = chunkqueue_get_append_buffer(con->send);
-                       if (NULL == (sl = strrchr(con->physical.path->ptr, '/'))) {
-                               buffer_copy_string_buffer(b, con->physical.path);
-                       } else {
-@@ -454,22 +455,22 @@
-                       break;
-               }
-               case SSI_ECHO_DOCUMENT_URI: {
--                      b = chunkqueue_get_append_buffer(con->write_queue);
-+                      b = chunkqueue_get_append_buffer(con->send);
-                       buffer_copy_string_buffer(b, con->uri.path);
-                       break;
-               }
-               default: {
-                       data_string *ds;
-                       /* check if it is a cgi-var */
--                      
--                      b = chunkqueue_get_append_buffer(con->write_queue);
--                      
-+
-+                      b = chunkqueue_get_append_buffer(con->send);
-+
-                       if (NULL != (ds = (data_string *)array_get_element(p->ssi_cgi_env, var_val))) {
-                               buffer_copy_string_buffer(b, ds->value);
-                       } else {
-                               buffer_copy_string(b, "(none)");
-                       }
--                      
-+
-                       break;
-               }
-               }
-@@ -481,7 +482,7 @@
-               const char * file_path = NULL, *virt_path = NULL;
-               struct stat st;
-               char *sl;
--              
-+
-               for (i = 2; i < n; i += 2) {
-                       if (0 == strcmp(l[i], "file")) {
-                               file_path = l[i+1];
-@@ -489,28 +490,28 @@
-                               virt_path = l[i+1];
-                       } else {
-                               log_error_write(srv, __FILE__, __LINE__, "sss",
--                                              "ssi: unknow attribute for ", 
-+                                              "ssi: unknow attribute for ",
-                                               l[1], l[i]);
-                       }
-               }
--              
-+
-               if (!file_path && !virt_path) {
-                       log_error_write(srv, __FILE__, __LINE__, "sss",
--                                      "ssi: ", 
-+                                      "ssi: ",
-                                       l[1], "file or virtual are missing");
-                       break;
-               }
--              
-+
-               if (file_path && virt_path) {
-                       log_error_write(srv, __FILE__, __LINE__, "sss",
--                                      "ssi: ", 
-+                                      "ssi: ",
-                                       l[1], "only one of file and virtual is allowed here");
-                       break;
-               }
--              
--              
-+
-+
-               if (p->if_is_false) break;
--              
-+
-               if (file_path) {
-                       /* current doc-root */
-                       if (NULL == (sl = strrchr(con->physical.path->ptr, '/'))) {
-@@ -519,46 +520,46 @@
-                               buffer_copy_string_len(p->stat_fn, con->physical.path->ptr, sl - con->physical.path->ptr + 1);
-                       }
--                      buffer_copy_string(srv->tmp_buf, file_path); 
-+                      buffer_copy_string(srv->tmp_buf, file_path);
-                       buffer_urldecode_path(srv->tmp_buf);
--                      buffer_path_simplify(srv->tmp_buf, srv->tmp_buf); 
--                      buffer_append_string_buffer(p->stat_fn, srv->tmp_buf); 
-+                      buffer_path_simplify(srv->tmp_buf, srv->tmp_buf);
-+                      buffer_append_string_buffer(p->stat_fn, srv->tmp_buf);
-               } else {
-                       /* virtual */
--                      
-+
-                       if (virt_path[0] == '/') {
-                               buffer_copy_string(p->stat_fn, virt_path);
-                       } else {
-                               /* there is always a / */
-                               sl = strrchr(con->uri.path->ptr, '/');
--                              
-+
-                               buffer_copy_string_len(p->stat_fn, con->uri.path->ptr, sl - con->uri.path->ptr + 1);
-                               buffer_append_string(p->stat_fn, virt_path);
-                       }
--                      
-+
-                       buffer_urldecode_path(p->stat_fn);
-                       buffer_path_simplify(srv->tmp_buf, p->stat_fn);
--                      
-+
-                       /* we have an uri */
--                      
-+
-                       buffer_copy_string_buffer(p->stat_fn, con->physical.doc_root);
-                       buffer_append_string_buffer(p->stat_fn, srv->tmp_buf);
-               }
--              
-+
-               if (0 == stat(p->stat_fn->ptr, &st)) {
-                       time_t t = st.st_mtime;
--                      
-+
-                       switch (ssicmd) {
-                       case SSI_FSIZE:
--                              b = chunkqueue_get_append_buffer(con->write_queue);
-+                              b = chunkqueue_get_append_buffer(con->send);
-                               if (p->sizefmt) {
-                                       int j = 0;
-                                       const char *abr[] = { " B", " kB", " MB", " GB", " TB", NULL };
--                                      
-+
-                                       off_t s = st.st_size;
--                                      
-+
-                                       for (j = 0; s > 1024 && abr[j+1]; s /= 1024, j++);
--                                      
-+
-                                       buffer_copy_off_t(b, s);
-                                       buffer_append_string(b, abr[j]);
-                               } else {
-@@ -566,7 +567,7 @@
-                               }
-                               break;
-                       case SSI_FLASTMOD:
--                              b = chunkqueue_get_append_buffer(con->write_queue);
-+                              b = chunkqueue_get_append_buffer(con->send);
-                               if (0 == strftime(buf, sizeof(buf), p->timefmt->ptr, localtime(&t))) {
-                                       buffer_copy_string(b, "(none)");
-                               } else {
-@@ -574,12 +575,12 @@
-                               }
-                               break;
-                       case SSI_INCLUDE:
--                              chunkqueue_append_file(con->write_queue, p->stat_fn, 0, st.st_size);
-+                              chunkqueue_append_file(con->send, p->stat_fn, 0, st.st_size);
-                               break;
-                       }
-               } else {
-                       log_error_write(srv, __FILE__, __LINE__, "sbs",
--                                      "ssi: stating failed ", 
-+                                      "ssi: stating failed ",
-                                       p->stat_fn, strerror(errno));
-               }
-               break;
-@@ -593,33 +594,33 @@
-                               val = l[i+1];
-                       } else {
-                               log_error_write(srv, __FILE__, __LINE__, "sss",
--                                              "ssi: unknow attribute for ", 
-+                                              "ssi: unknow attribute for ",
-                                               l[1], l[i]);
-                       }
-               }
--              
-+
-               if (p->if_is_false) break;
--              
-+
-               if (key && val) {
-                       data_string *ds;
--                      
-+
-                       if (NULL == (ds = (data_string *)array_get_unused_element(p->ssi_vars, TYPE_STRING))) {
-                               ds = data_string_init();
-                       }
-                       buffer_copy_string(ds->key,   key);
-                       buffer_copy_string(ds->value, val);
--                      
-+
-                       array_insert_unique(p->ssi_vars, (data_unset *)ds);
-               } else {
-                       log_error_write(srv, __FILE__, __LINE__, "sss",
--                                      "ssi: var and value have to be set in", 
-+                                      "ssi: var and value have to be set in",
-                                       l[0], l[1]);
-               }
-               break;
-       }
--      case SSI_CONFIG: 
-+      case SSI_CONFIG:
-               if (p->if_is_false) break;
--              
-+
-               for (i = 2; i < n; i += 2) {
-                       if (0 == strcmp(l[i], "timefmt")) {
-                               buffer_copy_string(p->timefmt, l[i+1]);
-@@ -632,63 +633,65 @@
-                                       log_error_write(srv, __FILE__, __LINE__, "sssss",
-                                                       "ssi: unknow value for attribute '",
-                                                       l[i],
--                                                      "' for ", 
-+                                                      "' for ",
-                                                       l[1], l[i+1]);
-                               }
-                       } else {
-                               log_error_write(srv, __FILE__, __LINE__, "sss",
--                                              "ssi: unknow attribute for ", 
-+                                              "ssi: unknow attribute for ",
-                                               l[1], l[i]);
-                       }
-               }
-               break;
-       case SSI_PRINTENV:
-               if (p->if_is_false) break;
--              
--              b = chunkqueue_get_append_buffer(con->write_queue);
-+
-+              b = chunkqueue_get_append_buffer(con->send);
-               buffer_copy_string(b, "<pre>");
-               for (i = 0; i < p->ssi_vars->used; i++) {
-                       data_string *ds = (data_string *)p->ssi_vars->data[p->ssi_vars->sorted[i]];
--                      
-+
-                       buffer_append_string_buffer(b, ds->key);
-                       buffer_append_string(b, ": ");
-                       buffer_append_string_buffer(b, ds->value);
-                       buffer_append_string(b, "<br />");
--                                      
-+
-               }
-               buffer_append_string(b, "</pre>");
--              
-+
-               break;
-       case SSI_EXEC: {
-+#ifndef _WIN32
-+
-               const char *cmd = NULL;
-               pid_t pid;
-               int from_exec_fds[2];
--              
-+
-               for (i = 2; i < n; i += 2) {
-                       if (0 == strcmp(l[i], "cmd")) {
-                               cmd = l[i+1];
-                       } else {
-                               log_error_write(srv, __FILE__, __LINE__, "sss",
--                                              "ssi: unknow attribute for ", 
-+                                              "ssi: unknow attribute for ",
-                                               l[1], l[i]);
-                       }
-               }
--              
-+
-               if (p->if_is_false) break;
--              
-+
-               /* create a return pipe and send output to the html-page
--               * 
--               * as exec is assumed evil it is implemented synchronously 
-+               *
-+               * as exec is assumed evil it is implemented synchronously
-                */
--              
-+
-               if (!cmd) break;
--#ifdef HAVE_FORK      
-+
-               if (pipe(from_exec_fds)) {
--                      log_error_write(srv, __FILE__, __LINE__, "ss", 
-+                      log_error_write(srv, __FILE__, __LINE__, "ss",
-                                       "pipe failed: ", strerror(errno));
-                       return -1;
-               }
--      
-+
-               /* fork, execve */
-               switch (pid = fork()) {
-               case 0: {
-@@ -698,14 +701,14 @@
-                       close(from_exec_fds[1]);
-                       /* not needed */
-                       close(from_exec_fds[0]);
--                      
-+
-                       /* close stdin */
-                       close(STDIN_FILENO);
--              
-+
-                       execl("/bin/sh", "sh", "-c", cmd, NULL);
--                      
-+
-                       log_error_write(srv, __FILE__, __LINE__, "sss", "spawing exec failed:", strerror(errno), cmd);
--              
-+
-                       /* */
-                       SEGFAULT();
-                       break;
-@@ -718,9 +721,9 @@
-                       /* father */
-                       int status;
-                       ssize_t r;
--                      
-+
-                       close(from_exec_fds[1]);
--                      
-+
-                       /* wait for the client to end */
-                       if (-1 == waitpid(pid, &status, 0)) {
-                               log_error_write(srv, __FILE__, __LINE__, "ss", "waitpid failed:", strerror(errno));
-@@ -730,18 +733,18 @@
-                               while(1) {
-                                       if (ioctl(from_exec_fds[0], FIONREAD, &toread)) {
--                                              log_error_write(srv, __FILE__, __LINE__, "s", 
-+                                              log_error_write(srv, __FILE__, __LINE__, "s",
-                                                       "unexpected end-of-file (perhaps the ssi-exec process died)");
-                                               return -1;
-                                       }
-                                       if (toread > 0) {
--                                              b = chunkqueue_get_append_buffer(con->write_queue);
-+                                              b = chunkqueue_get_append_buffer(con->send);
--                                              buffer_prepare_copy(b, toread + 1); 
-+                                              buffer_prepare_copy(b, toread + 1);
-                                               if ((r = read(from_exec_fds[0], b->ptr, b->size - 1)) < 0) {
--                                                      /* read failed */ 
-+                                                      /* read failed */
-                                                       break;
-                                               } else {
-                                                       b->used = r;
-@@ -755,59 +758,58 @@
-                               log_error_write(srv, __FILE__, __LINE__, "s", "process exited abnormally");
-                       }
-                       close(from_exec_fds[0]);
--                      
-+
-                       break;
-               }
-               }
- #else
--
-               return -1;
- #endif
--              
-+
-               break;
-       }
-       case SSI_IF: {
-               const char *expr = NULL;
--              
-+
-               for (i = 2; i < n; i += 2) {
-                       if (0 == strcmp(l[i], "expr")) {
-                               expr = l[i+1];
-                       } else {
-                               log_error_write(srv, __FILE__, __LINE__, "sss",
--                                              "ssi: unknow attribute for ", 
-+                                              "ssi: unknow attribute for ",
-                                               l[1], l[i]);
-                       }
-               }
--              
-+
-               if (!expr) {
-                       log_error_write(srv, __FILE__, __LINE__, "sss",
--                                      "ssi: ", 
-+                                      "ssi: ",
-                                       l[1], "expr missing");
-                       break;
-               }
--              
-+
-               if ((!p->if_is_false) &&
--                  ((p->if_is_false_level == 0) || 
-+                  ((p->if_is_false_level == 0) ||
-                    (p->if_level < p->if_is_false_level))) {
-                       switch (ssi_eval_expr(srv, con, p, expr)) {
-                       case -1:
--                      case 0: 
--                              p->if_is_false = 1; 
-+                      case 0:
-+                              p->if_is_false = 1;
-                               p->if_is_false_level = p->if_level;
-                               break;
--                      case 1: 
--                              p->if_is_false = 0; 
-+                      case 1:
-+                              p->if_is_false = 0;
-                               break;
-                       }
-               }
--              
-+
-               p->if_level++;
--              
-+
-               break;
-       }
-       case SSI_ELSE:
-               p->if_level--;
--              
-+
-               if (p->if_is_false) {
-                       if ((p->if_level == p->if_is_false_level) &&
-                           (p->if_is_false_endif == 0)) {
-@@ -815,11 +817,11 @@
-                       }
-               } else {
-                       p->if_is_false = 1;
--                      
-+
-                       p->if_is_false_level = p->if_level;
-               }
-               p->if_level++;
--              
-+
-               break;
-       case SSI_ELIF: {
-               const char *expr = NULL;
-@@ -828,52 +830,52 @@
-                               expr = l[i+1];
-                       } else {
-                               log_error_write(srv, __FILE__, __LINE__, "sss",
--                                              "ssi: unknow attribute for ", 
-+                                              "ssi: unknow attribute for ",
-                                               l[1], l[i]);
-                       }
-               }
--              
-+
-               if (!expr) {
-                       log_error_write(srv, __FILE__, __LINE__, "sss",
--                                      "ssi: ", 
-+                                      "ssi: ",
-                                       l[1], "expr missing");
-                       break;
-               }
--              
-+
-               p->if_level--;
--              
-+
-               if (p->if_level == p->if_is_false_level) {
-                       if ((p->if_is_false) &&
-                           (p->if_is_false_endif == 0)) {
-                               switch (ssi_eval_expr(srv, con, p, expr)) {
-                               case -1:
--                              case 0: 
--                                      p->if_is_false = 1; 
-+                              case 0:
-+                                      p->if_is_false = 1;
-                                       p->if_is_false_level = p->if_level;
-                                       break;
--                              case 1: 
--                                      p->if_is_false = 0; 
-+                              case 1:
-+                                      p->if_is_false = 0;
-                                       break;
-                               }
-                       } else {
--                              p->if_is_false = 1; 
-+                              p->if_is_false = 1;
-                               p->if_is_false_level = p->if_level;
-                               p->if_is_false_endif = 1;
-                       }
-               }
--              
-+
-               p->if_level++;
--              
-+
-               break;
-       }
-       case SSI_ENDIF:
-               p->if_level--;
--              
-+
-               if (p->if_level == p->if_is_false_level) {
-                       p->if_is_false = 0;
-                       p->if_is_false_endif = 0;
-               }
--                      
-+
-               break;
-       default:
-               log_error_write(srv, __FILE__, __LINE__, "ss",
-@@ -881,41 +883,41 @@
-                               l[1]);
-               break;
-       }
--      
-+
-       return 0;
--      
-+
- }
- static int mod_ssi_handle_request(server *srv, connection *con, plugin_data *p) {
-       stream s;
- #ifdef  HAVE_PCRE_H
-       int i, n;
--      
-+
- #define N 10
-       int ovec[N * 3];
- #endif
--      
-+
-       /* get a stream to the file */
--      
-+
-       array_reset(p->ssi_vars);
-       array_reset(p->ssi_cgi_env);
-       buffer_copy_string(p->timefmt, "%a, %d %b %Y %H:%M:%S %Z");
-       p->sizefmt = 0;
-       build_ssi_cgi_vars(srv, con, p);
-       p->if_is_false = 0;
--      
-+
-       if (-1 == stream_open(&s, con->physical.path)) {
-               log_error_write(srv, __FILE__, __LINE__, "sb",
-                               "stream-open: ", con->physical.path);
-               return -1;
-       }
--      
--      
-+
-+
-       /**
--       * <!--#element attribute=value attribute=value ... --> 
--       * 
-+       * <!--#element attribute=value attribute=value ... -->
-+       *
-        * config       DONE
--       *   errmsg     -- missing 
-+       *   errmsg     -- missing
-        *   sizefmt    DONE
-        *   timefmt    DONE
-        * echo         DONE
-@@ -937,13 +939,13 @@
-        * set          DONE
-        *   var        DONE
-        *   value      DONE
--       * 
-+       *
-        * if           DONE
-        * elif         DONE
-        * else         DONE
-        * endif        DONE
--       * 
--       * 
-+       *
-+       *
-        * expressions
-        * AND, OR      DONE
-        * comp         DONE
-@@ -951,118 +953,115 @@
-        * $...         DONE
-        * '...'        DONE
-        * ( ... )      DONE
--       * 
--       * 
--       * 
-+       *
-+       *
-+       *
-        * ** all DONE **
--       * DATE_GMT 
--       *   The current date in Greenwich Mean Time. 
--       * DATE_LOCAL 
--       *   The current date in the local time zone. 
--       * DOCUMENT_NAME 
--       *   The filename (excluding directories) of the document requested by the user. 
--       * DOCUMENT_URI 
--       *   The (%-decoded) URL path of the document requested by the user. Note that in the case of nested include files, this is not then URL for the current document. 
--       * LAST_MODIFIED 
--       *   The last modification date of the document requested by the user. 
--       * USER_NAME 
-+       * DATE_GMT
-+       *   The current date in Greenwich Mean Time.
-+       * DATE_LOCAL
-+       *   The current date in the local time zone.
-+       * DOCUMENT_NAME
-+       *   The filename (excluding directories) of the document requested by the user.
-+       * DOCUMENT_URI
-+       *   The (%-decoded) URL path of the document requested by the user. Note that in the case of nested include files, this is not then URL for the current document.
-+       * LAST_MODIFIED
-+       *   The last modification date of the document requested by the user.
-+       * USER_NAME
-        *   Contains the owner of the file which included it.
--       * 
-+       *
-        */
--#ifdef HAVE_PCRE_H    
-+#ifdef HAVE_PCRE_H
-       for (i = 0; (n = pcre_exec(p->ssi_regex, NULL, s.start, s.size, i, 0, ovec, N * 3)) > 0; i = ovec[1]) {
-               const char **l;
-               /* take everything from last offset to current match pos */
--              
--              if (!p->if_is_false) chunkqueue_append_file(con->write_queue, con->physical.path, i, ovec[0] - i);
--              
-+
-+              if (!p->if_is_false) chunkqueue_append_file(con->send, con->physical.path, i, ovec[0] - i);
-+
-               pcre_get_substring_list(s.start, ovec, n, &l);
-               process_ssi_stmt(srv, con, p, l, n);
-               pcre_free_substring_list(l);
-       }
--      
-+
-       switch(n) {
-       case PCRE_ERROR_NOMATCH:
-               /* copy everything/the rest */
--              chunkqueue_append_file(con->write_queue, con->physical.path, i, s.size - i);
--              
-+              chunkqueue_append_file(con->send, con->physical.path, i, s.size - i);
-+
-               break;
-       default:
-               log_error_write(srv, __FILE__, __LINE__, "sd",
-                               "execution error while matching: ", n);
-               break;
-       }
--#endif        
--      
--      
-+#endif
-+
-+
-       stream_close(&s);
--      
-+
-       con->file_started  = 1;
--      con->file_finished = 1;
--      
-+      con->send->is_closed = 1;
-+
-       response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html"));
--      
-+
-       /* reset physical.path */
-       buffer_reset(con->physical.path);
--      
-+
-       return 0;
- }
--#define PATCH(x) \
--      p->conf.x = s->x;
- static int mod_ssi_patch_connection(server *srv, connection *con, plugin_data *p) {
-       size_t i, j;
-       plugin_config *s = p->config_storage[0];
--      
--      PATCH(ssi_extension);
--      
-+
-+      PATCH_OPTION(ssi_extension);
-+
-       /* skip the first, the global context */
-       for (i = 1; i < srv->config_context->used; i++) {
-               data_config *dc = (data_config *)srv->config_context->data[i];
-               s = p->config_storage[i];
--              
-+
-               /* condition didn't match */
-               if (!config_check_cond(srv, con, dc)) continue;
--              
-+
-               /* merge config */
-               for (j = 0; j < dc->value->used; j++) {
-                       data_unset *du = dc->value->data[j];
--                      
-+
-                       if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssi.extension"))) {
--                              PATCH(ssi_extension);
-+                              PATCH_OPTION(ssi_extension);
-                       }
-               }
-       }
--      
-+
-       return 0;
- }
--#undef PATCH
- URIHANDLER_FUNC(mod_ssi_physical_path) {
-       plugin_data *p = p_d;
-       size_t k;
--      
-+
-       if (con->physical.path->used == 0) return HANDLER_GO_ON;
--      
-+
-       mod_ssi_patch_connection(srv, con, p);
--      
-+
-       for (k = 0; k < p->conf.ssi_extension->used; k++) {
-               data_string *ds = (data_string *)p->conf.ssi_extension->data[k];
--              
-+
-               if (ds->value->used == 0) continue;
--              
-+
-               if (buffer_is_equal_right_len(con->physical.path, ds->value, ds->value->used - 1)) {
-                       /* handle ssi-request */
--                      
-+
-                       if (mod_ssi_handle_request(srv, con, p)) {
-                               /* on error */
-                               con->http_status = 500;
-                       }
--                      
-+
-                       return HANDLER_FINISHED;
-               }
-       }
--      
-+
-       /* not found */
-       return HANDLER_GO_ON;
- }
-@@ -1072,13 +1071,13 @@
- int mod_ssi_plugin_init(plugin *p) {
-       p->version     = LIGHTTPD_VERSION_ID;
-       p->name        = buffer_init_string("ssi");
--      
-+
-       p->init        = mod_ssi_init;
--      p->handle_subrequest_start = mod_ssi_physical_path;
-+      p->handle_start_backend = mod_ssi_physical_path;
-       p->set_defaults  = mod_ssi_set_defaults;
-       p->cleanup     = mod_ssi_free;
--      
-+
-       p->data        = NULL;
--      
-+
-       return 0;
- }
---- ../lighttpd-1.4.11/src/mod_ssi.h   2005-08-11 01:26:39.000000000 +0300
-+++ lighttpd-1.5.0/src/mod_ssi.h       2006-07-16 00:26:04.000000000 +0300
-@@ -19,23 +19,23 @@
- typedef struct {
-       PLUGIN_DATA;
--      
--#ifdef HAVE_PCRE_H    
-+
-+#ifdef HAVE_PCRE_H
-       pcre *ssi_regex;
--#endif        
-+#endif
-       buffer *timefmt;
-       int sizefmt;
--      
-+
-       buffer *stat_fn;
--      
-+
-       array *ssi_vars;
-       array *ssi_cgi_env;
--      
-+
-       int if_level, if_is_false_level, if_is_false, if_is_false_endif;
--      
-+
-       plugin_config **config_storage;
--      
--      plugin_config conf; 
-+
-+      plugin_config conf;
- } plugin_data;
- int ssi_eval_expr(server *srv, connection *con, plugin_data *p, const char *expr);
---- ../lighttpd-1.4.11/src/mod_ssi_expr.c      2005-08-11 01:26:48.000000000 +0300
-+++ lighttpd-1.5.0/src/mod_ssi_expr.c  2006-07-16 00:26:04.000000000 +0300
-@@ -11,9 +11,9 @@
-       const char *input;
-       size_t offset;
-       size_t size;
--      
-+
-       int line_pos;
--      
-+
-       int in_key;
-       int in_brace;
-       int in_cond;
-@@ -21,15 +21,15 @@
- ssi_val_t *ssi_val_init() {
-       ssi_val_t *s;
--      
-+
-       s = calloc(1, sizeof(*s));
--      
-+
-       return s;
- }
- void ssi_val_free(ssi_val_t *s) {
-       if (s->str) buffer_free(s->str);
--      
-+
-       free(s);
- }
-@@ -45,175 +45,175 @@
-                             ssi_tokenizer_t *t, int *token_id, buffer *token) {
-       int tid = 0;
-       size_t i;
--      
-+
-       UNUSED(con);
-       for (tid = 0; tid == 0 && t->offset < t->size && t->input[t->offset] ; ) {
-               char c = t->input[t->offset];
-               data_string *ds;
--              
-+
-               switch (c) {
--              case '=': 
-+              case '=':
-                       tid = TK_EQ;
--                      
-+
-                       t->offset++;
-                       t->line_pos++;
--                      
-+
-                       buffer_copy_string(token, "(=)");
--                      
-+
-                       break;
-               case '>':
-                       if (t->input[t->offset + 1] == '=') {
-                               t->offset += 2;
-                               t->line_pos += 2;
--                              
-+
-                               tid = TK_GE;
--                              
-+
-                               buffer_copy_string(token, "(>=)");
-                       } else {
-                               t->offset += 1;
-                               t->line_pos += 1;
--                              
-+
-                               tid = TK_GT;
--                              
-+
-                               buffer_copy_string(token, "(>)");
-                       }
--                      
-+
-                       break;
-               case '<':
-                       if (t->input[t->offset + 1] == '=') {
-                               t->offset += 2;
-                               t->line_pos += 2;
--                              
-+
-                               tid = TK_LE;
--                              
-+
-                               buffer_copy_string(token, "(<=)");
-                       } else {
-                               t->offset += 1;
-                               t->line_pos += 1;
--                              
-+
-                               tid = TK_LT;
--                              
-+
-                               buffer_copy_string(token, "(<)");
-                       }
--                      
-+
-                       break;
--                      
-+
-               case '!':
-                       if (t->input[t->offset + 1] == '=') {
-                               t->offset += 2;
-                               t->line_pos += 2;
--                              
-+
-                               tid = TK_NE;
--                              
-+
-                               buffer_copy_string(token, "(!=)");
-                       } else {
-                               t->offset += 1;
-                               t->line_pos += 1;
--                              
-+
-                               tid = TK_NOT;
--                              
-+
-                               buffer_copy_string(token, "(!)");
-                       }
--                      
-+
-                       break;
-               case '&':
-                       if (t->input[t->offset + 1] == '&') {
-                               t->offset += 2;
-                               t->line_pos += 2;
--                              
-+
-                               tid = TK_AND;
--                              
-+
-                               buffer_copy_string(token, "(&&)");
-                       } else {
--                              log_error_write(srv, __FILE__, __LINE__, "sds", 
--                                              "pos:", t->line_pos, 
-+                              log_error_write(srv, __FILE__, __LINE__, "sds",
-+                                              "pos:", t->line_pos,
-                                               "missing second &");
-                               return -1;
-                       }
--                      
-+
-                       break;
-               case '|':
-                       if (t->input[t->offset + 1] == '|') {
-                               t->offset += 2;
-                               t->line_pos += 2;
--                              
-+
-                               tid = TK_OR;
--                              
-+
-                               buffer_copy_string(token, "(||)");
-                       } else {
--                              log_error_write(srv, __FILE__, __LINE__, "sds", 
--                                              "pos:", t->line_pos, 
-+                              log_error_write(srv, __FILE__, __LINE__, "sds",
-+                                              "pos:", t->line_pos,
-                                               "missing second |");
-                               return -1;
-                       }
--                      
-+
-                       break;
-               case '\t':
-               case ' ':
-                       t->offset++;
-                       t->line_pos++;
-                       break;
--                      
-+
-               case '\'':
-                       /* search for the terminating " */
-                       for (i = 1; t->input[t->offset + i] && t->input[t->offset + i] != '\'';  i++);
--                      
-+
-                       if (t->input[t->offset + i]) {
-                               tid = TK_VALUE;
--                              
-+
-                               buffer_copy_string_len(token, t->input + t->offset + 1, i-1);
--                              
-+
-                               t->offset += i + 1;
-                               t->line_pos += i + 1;
-                       } else {
-                               /* ERROR */
--                              
--                              log_error_write(srv, __FILE__, __LINE__, "sds", 
--                                              "pos:", t->line_pos, 
-+
-+                              log_error_write(srv, __FILE__, __LINE__, "sds",
-+                                              "pos:", t->line_pos,
-                                               "missing closing quote");
--                              
-+
-                               return -1;
-                       }
--                      
-+
-                       break;
-               case '(':
-                       t->offset++;
-                       t->in_brace++;
--                              
-+
-                       tid = TK_LPARAN;
--                              
-+
-                       buffer_copy_string(token, "(");
-                       break;
-               case ')':
-                       t->offset++;
-                       t->in_brace--;
--                              
-+
-                       tid = TK_RPARAN;
--                              
-+
-                       buffer_copy_string(token, ")");
-                       break;
-               case '$':
-                       if (t->input[t->offset + 1] == '{') {
-                               for (i = 2; t->input[t->offset + i] && t->input[t->offset + i] != '}';  i++);
--                              
-+
-                               if (t->input[t->offset + i] != '}') {
--                                      log_error_write(srv, __FILE__, __LINE__, "sds", 
--                                                      "pos:", t->line_pos, 
-+                                      log_error_write(srv, __FILE__, __LINE__, "sds",
-+                                                      "pos:", t->line_pos,
-                                                       "missing closing quote");
--                                      
-+
-                                       return -1;
-                               }
--                              
-+
-                               buffer_copy_string_len(token, t->input + t->offset + 2, i-3);
-                       } else {
-                               for (i = 1; isalpha(t->input[t->offset + i]) || t->input[t->offset + i] == '_';  i++);
--                              
-+
-                               buffer_copy_string_len(token, t->input + t->offset + 1, i-1);
-                       }
--                      
-+
-                       tid = TK_VALUE;
--                      
-+
-                       if (NULL != (ds = (data_string *)array_get_element(p->ssi_cgi_env, token->ptr))) {
-                               buffer_copy_string_buffer(token, ds->value);
-                       } else if (NULL != (ds = (data_string *)array_get_element(p->ssi_vars, token->ptr))) {
-@@ -221,16 +221,16 @@
-                       } else {
-                               buffer_copy_string(token, "");
-                       }
--                              
-+
-                       t->offset += i;
-                       t->line_pos += i;
--                      
-+
-                       break;
-               default:
-                       for (i = 0; isgraph(t->input[t->offset + i]);  i++) {
-                               char d = t->input[t->offset + i];
-                               switch(d) {
--                              case ' ': 
-+                              case ' ':
-                               case '\t':
-                               case ')':
-                               case '(':
-@@ -244,25 +244,25 @@
-                                       break;
-                               }
-                       }
--                      
-+
-                       tid = TK_VALUE;
--                              
-+
-                       buffer_copy_string_len(token, t->input + t->offset, i);
--                              
-+
-                       t->offset += i;
-                       t->line_pos += i;
--                      
-+
-                       break;
-               }
-       }
--                      
-+
-       if (tid) {
-               *token_id = tid;
--              
-+
-               return 1;
-       } else if (t->offset < t->size) {
--              log_error_write(srv, __FILE__, __LINE__, "sds", 
--                              "pos:", t->line_pos, 
-+              log_error_write(srv, __FILE__, __LINE__, "sds",
-+                              "pos:", t->line_pos,
-                               "foobar");
-       }
-       return 0;
-@@ -275,50 +275,50 @@
-       buffer *token;
-       ssi_ctx_t context;
-       int ret;
--      
-+
-       t.input = expr;
-       t.offset = 0;
-       t.size = strlen(expr);
-       t.line_pos = 1;
--      
-+
-       t.in_key = 1;
-       t.in_brace = 0;
-       t.in_cond = 0;
--      
-+
-       context.ok = 1;
-       context.srv = srv;
--      
-+
-       /* default context */
--      
-+
-       pParser = ssiexprparserAlloc( malloc );
-       token = buffer_init();
-       while((1 == (ret = ssi_expr_tokenizer(srv, con, p, &t, &token_id, token))) && context.ok) {
-               ssiexprparser(pParser, token_id, token, &context);
--              
-+
-               token = buffer_init();
-       }
-       ssiexprparser(pParser, 0, token, &context);
-       ssiexprparserFree(pParser, free );
--      
-+
-       buffer_free(token);
--      
-+
-       if (ret == -1) {
--              log_error_write(srv, __FILE__, __LINE__, "s", 
-+              log_error_write(srv, __FILE__, __LINE__, "s",
-                               "expr parser failed");
-               return -1;
-       }
--      
-+
-       if (context.ok == 0) {
--              log_error_write(srv, __FILE__, __LINE__, "sds", 
--                              "pos:", t.line_pos, 
-+              log_error_write(srv, __FILE__, __LINE__, "sds",
-+                              "pos:", t.line_pos,
-                               "parser failed somehow near here");
-               return -1;
-       }
- #if 0
--      log_error_write(srv, __FILE__, __LINE__, "ssd", 
-+      log_error_write(srv, __FILE__, __LINE__, "ssd",
-                       "expr: ",
-                       expr,
-                       context.val.bo);
--#endif        
-+#endif
-       return context.val.bo;
- }
---- ../lighttpd-1.4.11/src/mod_ssi_expr.h      2005-08-11 01:26:48.000000000 +0300
-+++ lighttpd-1.5.0/src/mod_ssi_expr.h  2006-07-16 00:26:04.000000000 +0300
-@@ -5,16 +5,16 @@
- typedef struct {
-       enum { SSI_TYPE_UNSET, SSI_TYPE_BOOL, SSI_TYPE_STRING } type;
--      
-+
-       buffer *str;
-       int     bo;
- } ssi_val_t;
- typedef struct {
-       int     ok;
--      
-+
-       ssi_val_t val;
--      
-+
-       void   *srv;
- } ssi_ctx_t;
---- ../lighttpd-1.4.11/src/mod_ssi_exprparser.c        2005-10-03 00:40:25.000000000 +0300
-+++ lighttpd-1.5.0/src/mod_ssi_exprparser.c    2006-07-17 22:02:23.000000000 +0300
-@@ -18,10 +18,10 @@
- /* Next is all token values, in a form suitable for use by makeheaders.
- ** This section will be null unless lemon is run with the -m switch.
- */
--/* 
-+/*
- ** These constants (all generated automatically by the parser generator)
- ** specify the various kinds of tokens (terminals) that the parser
--** understands. 
-+** understands.
- **
- ** Each symbol here is a terminal symbol in the grammar.
- */
-@@ -38,7 +38,7 @@
- **                       and nonterminals.  "int" is used otherwise.
- **    YYNOCODE           is a number of type YYCODETYPE which corresponds
- **                       to no legal terminal or nonterminal number.  This
--**                       number is used to fill in empty slots of the hash 
-+**                       number is used to fill in empty slots of the hash
- **                       table.
- **    YYFALLBACK         If defined, this indicates that one or more tokens
- **                       have fall-back values which should be used if the
-@@ -47,7 +47,7 @@
- **                       and nonterminal numbers.  "unsigned char" is
- **                       used if there are fewer than 250 rules and
- **                       states combined.  "int" is used otherwise.
--**    ssiexprparserTOKENTYPE     is the data type used for minor tokens given 
-+**    ssiexprparserTOKENTYPE     is the data type used for minor tokens given
- **                       directly to the parser from the tokenizer.
- **    YYMINORTYPE        is the data type used for all minor tokens.
- **                       This is typically a union of many types, one of
-@@ -91,7 +91,7 @@
- /* Next are that tables used to determine what action to take based on the
- ** current state and lookahead token.  These tables are used to implement
- ** functions that take a state number and lookahead value and return an
--** action integer.  
-+** action integer.
- **
- ** Suppose the action integer is N.  Then the action is determined as
- ** follows
-@@ -116,7 +116,7 @@
- ** If the index value yy_shift_ofst[S]+X is out of range or if the value
- ** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S]
- ** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table
--** and that yy_default[S] should be used instead.  
-+** and that yy_default[S] should be used instead.
- **
- ** The formula above is for computing the action when the lookahead is
- ** a terminal symbol.  If the lookahead is a non-terminal (as occurs after
-@@ -168,7 +168,7 @@
- /* The next table maps tokens into fallback tokens.  If a construct
- ** like the following:
--** 
-+**
- **      %fallback ID X Y Z.
- **
- ** appears in the grammer, then ID becomes a fallback token for X, Y,
-@@ -219,10 +219,10 @@
- #endif /* NDEBUG */
- #ifndef NDEBUG
--/* 
-+/*
- ** Turn parser tracing on by giving a stream to which to write the trace
- ** and a prompt to preface each trace message.  Tracing is turned off
--** by making either argument NULL 
-+** by making either argument NULL
- **
- ** Inputs:
- ** <ul>
-@@ -247,7 +247,7 @@
- #ifndef NDEBUG
- /* For tracing shifts, the names of all terminals and nonterminals
- ** are required.  The following table supplies these names */
--static const char *yyTokenName[] = { 
-+static const char *yyTokenName[] = {
-   "$",             "AND",           "OR",            "EQ",          
-   "NE",            "GT",            "GE",            "LT",          
-   "LE",            "NOT",           "LPARAN",        "RPARAN",      
-@@ -295,7 +295,7 @@
- #endif
- }
--/* 
-+/*
- ** This function allocates a new parser.
- ** The only argument is a pointer to a function which works like
- ** malloc.
-@@ -326,7 +326,7 @@
-     /* Here is inserted the actions which take place when a
-     ** terminal or non-terminal is destroyed.  This can happen
-     ** when the symbol is popped from the stack during a
--    ** reduce or during error processing or when a parser is 
-+    ** reduce or during error processing or when a parser is
-     ** being destroyed before it is finished parsing.
-     **
-     ** Note: during a reduce, the only symbols destroyed are those
-@@ -379,7 +379,7 @@
-   return yymajor;
- }
--/* 
-+/*
- ** Deallocate and destroy a parser.  Destructors are all called for
- ** all stack elements before shutting the parser down.
- **
-@@ -415,7 +415,7 @@
- ){
-   int i;
-   int stateno = pParser->yystack[pParser->yyidx].stateno;
-- 
-+
-   /* if( pParser->yyidx<0 ) return YY_NO_ACTION;  */
-   i = yy_shift_ofst[stateno];
-   if( i==YY_SHIFT_USE_DFLT ){
-@@ -459,7 +459,7 @@
- ){
-   int i;
-   int stateno = pParser->yystack[pParser->yyidx].stateno;
-- 
-+
-   i = yy_reduce_ofst[stateno];
-   if( i==YY_REDUCE_USE_DFLT ){
-     return yy_default[stateno];
-@@ -559,7 +559,7 @@
-   ssiexprparserARG_FETCH;
-   yymsp = &yypParser->yystack[yypParser->yyidx];
- #ifndef NDEBUG
--  if( yyTraceFILE && yyruleno>=0 
-+  if( yyTraceFILE && yyruleno>=0
-         && yyruleno<sizeof(yyRuleName)/sizeof(yyRuleName[0]) ){
-     fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt,
-       yyRuleName[yyruleno]);
-@@ -872,7 +872,7 @@
- #ifdef YYERRORSYMBOL
-       /* A syntax error has occurred.
-       ** The response to an error depends upon whether or not the
--      ** grammar defines an error token "ERROR".  
-+      ** grammar defines an error token "ERROR".
-       **
-       ** This is what we do if the grammar does define ERROR:
-       **
---- ../lighttpd-1.4.11/src/mod_staticfile.c    2006-02-15 14:31:14.000000000 +0200
-+++ lighttpd-1.5.0/src/mod_staticfile.c        2006-09-07 00:57:05.000000000 +0300
-@@ -11,12 +11,15 @@
- #include "stat_cache.h"
- #include "etag.h"
--#include "http_chunk.h"
- #include "response.h"
-+#include "sys-files.h"
-+#include "sys-strings.h"
-+
-+#include "http_req_range.h"
- /**
-  * this is a staticfile for a lighttpd plugin
-- * 
-+ *
-  */
-@@ -29,48 +32,48 @@
- typedef struct {
-       PLUGIN_DATA;
--      
-+
-       buffer *range_buf;
--      
-+
-       plugin_config **config_storage;
--      
--      plugin_config conf; 
-+
-+      plugin_config conf;
- } plugin_data;
- /* init the plugin data */
- INIT_FUNC(mod_staticfile_init) {
-       plugin_data *p;
--      
-+
-       p = calloc(1, sizeof(*p));
--      
-+
-       p->range_buf = buffer_init();
--      
-+
-       return p;
- }
--/* detroy the plugin data */
-+/* destroy the plugin data */
- FREE_FUNC(mod_staticfile_free) {
-       plugin_data *p = p_d;
--      
-+
-       UNUSED(srv);
-       if (!p) return HANDLER_GO_ON;
--      
-+
-       if (p->config_storage) {
-               size_t i;
-               for (i = 0; i < srv->config_context->used; i++) {
-                       plugin_config *s = p->config_storage[i];
--                      
-+
-                       array_free(s->exclude_ext);
--                      
-+
-                       free(s);
-               }
-               free(p->config_storage);
-       }
-       buffer_free(p->range_buf);
--      
-+
-       free(p);
--      
-+
-       return HANDLER_GO_ON;
- }
-@@ -79,263 +82,222 @@
- SETDEFAULTS_FUNC(mod_staticfile_set_defaults) {
-       plugin_data *p = p_d;
-       size_t i = 0;
--      
--      config_values_t cv[] = { 
-+
-+      config_values_t cv[] = {
-               { "static-file.exclude-extensions", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
-               { NULL,                         NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
-       };
--      
-+
-       if (!p) return HANDLER_ERROR;
--      
-+
-       p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
--      
-+
-       for (i = 0; i < srv->config_context->used; i++) {
-               plugin_config *s;
--              
-+
-               s = calloc(1, sizeof(plugin_config));
-               s->exclude_ext    = array_init();
--              
-+
-               cv[0].destination = s->exclude_ext;
--              
-+
-               p->config_storage[i] = s;
--      
-+
-               if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
-                       return HANDLER_ERROR;
-               }
-       }
--      
-+
-       return HANDLER_GO_ON;
- }
--#define PATCH(x) \
--      p->conf.x = s->x;
- static int mod_staticfile_patch_connection(server *srv, connection *con, plugin_data *p) {
-       size_t i, j;
-       plugin_config *s = p->config_storage[0];
--      
--      PATCH(exclude_ext);
--      
-+
-+      PATCH_OPTION(exclude_ext);
-+
-       /* skip the first, the global context */
-       for (i = 1; i < srv->config_context->used; i++) {
-               data_config *dc = (data_config *)srv->config_context->data[i];
-               s = p->config_storage[i];
--              
-+
-               /* condition didn't match */
-               if (!config_check_cond(srv, con, dc)) continue;
--              
-+
-               /* merge config */
-               for (j = 0; j < dc->value->used; j++) {
-                       data_unset *du = dc->value->data[j];
--                      
-+
-                       if (buffer_is_equal_string(du->key, CONST_STR_LEN("static-file.exclude-extensions"))) {
--                              PATCH(exclude_ext);
-+                              PATCH_OPTION(exclude_ext);
-                       }
-               }
-       }
--      
-+
-       return 0;
- }
--#undef PATCH
- static int http_response_parse_range(server *srv, connection *con, plugin_data *p) {
-       int multipart = 0;
--      int error;
--      off_t start, end;
--      const char *s, *minus;
-       char *boundary = "fkj49sn38dcn3";
-       data_string *ds;
-       stat_cache_entry *sce = NULL;
-       buffer *content_type = NULL;
--      
-+      buffer *range = NULL;
-+      http_req_range *ranges, *r;
-+
-+      if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Range"))) {
-+              range = ds->value;
-+      } else {
-+              /* we don't have a Range header */
-+
-+              return -1;
-+      }
-+
-       if (HANDLER_ERROR == stat_cache_get_entry(srv, con, con->physical.path, &sce)) {
-               SEGFAULT();
-       }
--      
--      start = 0;
--      end = sce->st.st_size - 1;
--      
-+
-       con->response.content_length = 0;
--      
-+
-       if (NULL != (ds = (data_string *)array_get_element(con->response.headers, "Content-Type"))) {
-               content_type = ds->value;
-       }
--      
--      for (s = con->request.http_range, error = 0;
--           !error && *s && NULL != (minus = strchr(s, '-')); ) {
--              char *err;
--              off_t la, le;
--              
--              if (s == minus) {
--                      /* -<stop> */
--                      
--                      le = strtoll(s, &err, 10);
--                      
--                      if (le == 0) {
--                              /* RFC 2616 - 14.35.1 */
--                              
--                              con->http_status = 416;
--                              error = 1;
--                      } else if (*err == '\0') {
--                              /* end */
--                              s = err;
--                              
--                              end = sce->st.st_size - 1;
--                              start = sce->st.st_size + le;
--                      } else if (*err == ',') {
--                              multipart = 1;
--                              s = err + 1;
--                              
--                              end = sce->st.st_size - 1;
--                              start = sce->st.st_size + le;
--                      } else {
--                              error = 1;
--                      }
--                      
--              } else if (*(minus+1) == '\0' || *(minus+1) == ',') {
--                      /* <start>- */
--                      
--                      la = strtoll(s, &err, 10);
--                      
--                      if (err == minus) {
--                              /* ok */
--                              
--                              if (*(err + 1) == '\0') {
--                                      s = err + 1;
--                                      
--                                      end = sce->st.st_size - 1;
--                                      start = la;
--                                      
--                              } else if (*(err + 1) == ',') {
--                                      multipart = 1;
--                                      s = err + 2;
--                                      
--                                      end = sce->st.st_size - 1;
--                                      start = la;
--                              } else {
--                                      error = 1;
--                              }
--                      } else {
--                              /* error */
--                              error = 1;
--                      }
--              } else {
--                      /* <start>-<stop> */
--                      
--                      la = strtoll(s, &err, 10);
--                      
--                      if (err == minus) {
--                              le = strtoll(minus+1, &err, 10);
--                              
--                              /* RFC 2616 - 14.35.1 */
--                              if (la > le) {
--                                      error = 1;
--                              }
--                                      
--                              if (*err == '\0') {
--                                      /* ok, end*/
--                                      s = err;
--                                      
--                                      end = le;
--                                      start = la;
--                              } else if (*err == ',') {
--                                      multipart = 1;
--                                      s = err + 1;
--                                      
--                                      end = le;
--                                      start = la;
--                              } else {
--                                      /* error */
-+
-+      /* start the range-header parser
-+       * bytes=<num>  */
-+
-+      ranges = http_request_range_init();
-+      switch (http_request_range_parse(range, ranges)) {
-+      case PARSE_ERROR:
-+              return -1; /* no range valid Range Header */
-+      case PARSE_SUCCESS:
-+              break;
-+      default:
-+              TRACE("%s", "foobar");
-+              return -1;
-+      }
-+
-+      if (ranges->next) {
-+              multipart = 1;
-+      }
-+
-+      /* patch the '-1' */
-+      for (r = ranges; r; r = r->next) {
-+              if (r->start == -1) {
-+                      /* -<end>
-+                       *
-+                       * the last <end> bytes  */
-+                      r->start = sce->st.st_size - r->end;
-+                      r->end = sce->st.st_size - 1;
-+              } 
-+              if (r->end == -1) {
-+                      /* <start>-
-+                       * all but the first <start> bytes */
-                                       
--                                      error = 1;
--                              }
--                      } else {
--                              /* error */
--                              
--                              error = 1;
--                      }
-+                      r->end = sce->st.st_size - 1;
-               }
--              
--              if (!error) {
--                      if (start < 0) start = 0;
--                      
--                      /* RFC 2616 - 14.35.1 */
--                      if (end > sce->st.st_size - 1) end = sce->st.st_size - 1;
--                      
--                      if (start > sce->st.st_size - 1) {
--                              error = 1;
--                              
--                              con->http_status = 416;
--                      }
-+
-+              if (r->end > sce->st.st_size - 1) {
-+                      /* RFC 2616 - 14.35.1
-+                       *
-+                       * if last-byte-pos not present or > size-of-file 
-+                       * take the size-of-file
-+                       *
-+                       *  */
-+                      r->end = sce->st.st_size - 1;
-               }
--              
--              if (!error) {
--                      if (multipart) {
--                              /* write boundary-header */
--                              buffer *b;
--                              
--                              b = chunkqueue_get_append_buffer(con->write_queue);
--                              
--                              buffer_copy_string(b, "\r\n--");
--                              buffer_append_string(b, boundary);
--                              
--                              /* write Content-Range */
--                              buffer_append_string(b, "\r\nContent-Range: bytes ");
--                              buffer_append_off_t(b, start);
--                              buffer_append_string(b, "-");
--                              buffer_append_off_t(b, end);
--                              buffer_append_string(b, "/");
--                              buffer_append_off_t(b, sce->st.st_size);
--                              
--                              buffer_append_string(b, "\r\nContent-Type: ");
--                              buffer_append_string_buffer(b, content_type);
--                              
--                              /* write END-OF-HEADER */
--                              buffer_append_string(b, "\r\n\r\n");
--                              
--                              con->response.content_length += b->used - 1;
--                              
--                      }
--                      
--                      chunkqueue_append_file(con->write_queue, con->physical.path, start, end - start + 1);
--                      con->response.content_length += end - start + 1;
-+
-+              if (r->start > sce->st.st_size - 1) {
-+                      /* RFC 2616 - 14.35.1
-+                       *
-+                       * if first-byte-pos > file-size, 416
-+                       */
-+
-+                      con->http_status = 416;
-+                      return -1;
-+              }
-+
-+              if (r->start > r->end) {
-+                      /* RFC 2616 - 14.35.1
-+                       *
-+                       * if last-byte-pos is present, it has to be >= first-byte-pos
-+                       * 
-+                       * invalid ranges have to be handle as no Range specified
-+                       *  */
-+
-+                      return -1;
-               }
-       }
--      
--      /* something went wrong */
--      if (error) return -1;
--      
-+
-+      if (r) {
-+              /* we ran into an range violation */
-+              return -1;
-+      }
-+
-       if (multipart) {
--              /* add boundary end */
-               buffer *b;
--              
--              b = chunkqueue_get_append_buffer(con->write_queue);
--              
-+              for (r = ranges; r; r = r->next) {
-+                      /* write boundary-header */
-+
-+                      b = chunkqueue_get_append_buffer(con->send);
-+
-+                      buffer_copy_string(b, "\r\n--");
-+                      buffer_append_string(b, boundary);
-+
-+                      /* write Content-Range */
-+                      buffer_append_string(b, "\r\nContent-Range: bytes ");
-+                      buffer_append_off_t(b, r->start);
-+                      buffer_append_string(b, "-");
-+                      buffer_append_off_t(b, r->end);
-+                      buffer_append_string(b, "/");
-+                      buffer_append_off_t(b, sce->st.st_size);
-+
-+                      buffer_append_string(b, "\r\nContent-Type: ");
-+                      buffer_append_string_buffer(b, content_type);
-+
-+                      /* write END-OF-HEADER */
-+                      buffer_append_string(b, "\r\n\r\n");
-+
-+                      con->response.content_length += b->used - 1;
-+
-+                      chunkqueue_append_file(con->send, con->physical.path, r->start, r->end - r->start + 1);
-+                      con->response.content_length += r->end - r->start + 1;
-+              }
-+
-+              /* add boundary end */
-+              b = chunkqueue_get_append_buffer(con->send);
-+
-               buffer_copy_string_len(b, "\r\n--", 4);
-               buffer_append_string(b, boundary);
-               buffer_append_string_len(b, "--\r\n", 4);
--              
-+
-               con->response.content_length += b->used - 1;
--              
-+
-               /* set header-fields */
--              
-+
-               buffer_copy_string(p->range_buf, "multipart/byteranges; boundary=");
-               buffer_append_string(p->range_buf, boundary);
--              
-+
-               /* overwrite content-type */
-               response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(p->range_buf));
-+
-       } else {
--              /* add Content-Range-header */
--              
-+              r = ranges;
-+
-+              chunkqueue_append_file(con->send, con->physical.path, r->start, r->end - r->start + 1);
-+              con->response.content_length += r->end - r->start + 1;
-+
-               buffer_copy_string(p->range_buf, "bytes ");
--              buffer_append_off_t(p->range_buf, start);
-+              buffer_append_off_t(p->range_buf, r->start);
-               buffer_append_string(p->range_buf, "-");
--              buffer_append_off_t(p->range_buf, end);
-+              buffer_append_off_t(p->range_buf, r->end);
-               buffer_append_string(p->range_buf, "/");
-               buffer_append_off_t(p->range_buf, sce->st.st_size);
--              
-+
-               response_header_insert(srv, con, CONST_STR_LEN("Content-Range"), CONST_BUF_LEN(p->range_buf));
-       }
--
-+      
-       /* ok, the file is set-up */
-       return 0;
- }
-@@ -347,12 +309,12 @@
-       stat_cache_entry *sce = NULL;
-       buffer *mtime;
-       data_string *ds;
--      
-+
-       /* someone else has done a decision for us */
-       if (con->http_status != 0) return HANDLER_GO_ON;
-       if (con->uri.path->used == 0) return HANDLER_GO_ON;
-       if (con->physical.path->used == 0) return HANDLER_GO_ON;
--      
-+
-       /* someone else has handled this request */
-       if (con->mode != DIRECT) return HANDLER_GO_ON;
-@@ -365,52 +327,67 @@
-       default:
-               return HANDLER_GO_ON;
-       }
--      
-+
-       mod_staticfile_patch_connection(srv, con, p);
--      
-+
-       s_len = con->uri.path->used - 1;
--      
-+
-       /* ignore certain extensions */
-       for (k = 0; k < p->conf.exclude_ext->used; k++) {
--              ds = (data_string *)p->conf.exclude_ext->data[k]; 
--              
-+              ds = (data_string *)p->conf.exclude_ext->data[k];
-+
-               if (ds->value->used == 0) continue;
-               if (buffer_is_equal_right_len(con->physical.path, ds->value, ds->value->used - 1)) {
--                      return HANDLER_GO_ON;
-+                      con->http_status = 403;
-+
-+                      return HANDLER_FINISHED;
-               }
-       }
--      
-+
-       if (con->conf.log_request_handling) {
-               log_error_write(srv, __FILE__, __LINE__,  "s",  "-- handling file as static file");
-       }
--      
-+
-       if (HANDLER_ERROR == stat_cache_get_entry(srv, con, con->physical.path, &sce)) {
-               con->http_status = 403;
--              
-+
-               log_error_write(srv, __FILE__, __LINE__, "sbsb",
-                               "not a regular file:", con->uri.path,
-                               "->", con->physical.path);
--              
-+
-               return HANDLER_FINISHED;
-       }
--      
--      /* we only handline regular files */
-+
-+      /* we only handle regular files */
-+#ifdef HAVE_LSTAT
-+      if ((sce->is_symlink == 1) && !con->conf.follow_symlink) {
-+              con->http_status = 403;
-+
-+              if (con->conf.log_request_handling) {
-+                      log_error_write(srv, __FILE__, __LINE__,  "s",  "-- access denied due symlink restriction");
-+                      log_error_write(srv, __FILE__, __LINE__,  "sb", "Path         :", con->physical.path);
-+              }
-+
-+              buffer_reset(con->physical.path);
-+              return HANDLER_FINISHED;
-+      }
-+#endif
-       if (!S_ISREG(sce->st.st_mode)) {
-               con->http_status = 404;
--              
-+
-               if (con->conf.log_file_not_found) {
-                       log_error_write(srv, __FILE__, __LINE__, "sbsb",
-                                       "not a regular file:", con->uri.path,
-                                       "->", sce->name);
-               }
--              
-+
-               return HANDLER_FINISHED;
-       }
--      /* mod_compress might set several data directly, don't overwrite them */
--      
-+      /* mod_compress might set several parameters directly; don't overwrite them */
-+
-       /* set response content-type, if not set already */
-       if (NULL == array_get_element(con->response.headers, "Content-Type")) {
-@@ -420,15 +397,15 @@
-                       response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(sce->content_type));
-               }
-       }
--      
-+
-       if (NULL == array_get_element(con->response.headers, "ETag")) {
-               /* generate e-tag */
-               etag_mutate(con->physical.etag, sce->etag);
--      
-+
-               response_header_overwrite(srv, con, CONST_STR_LEN("ETag"), CONST_BUF_LEN(con->physical.etag));
-       }
-       response_header_overwrite(srv, con, CONST_STR_LEN("Accept-Ranges"), CONST_STR_LEN("bytes"));
--      
-+
-       /* prepare header */
-       if (NULL == (ds = (data_string *)array_get_element(con->response.headers, "Last-Modified"))) {
-               mtime = strftime_cache_get(srv, sce->st.st_mtime);
-@@ -439,54 +416,104 @@
-       if (HANDLER_FINISHED == http_response_handle_cachable(srv, con, mtime)) {
-               return HANDLER_FINISHED;
--      } else if (con->request.http_range && con->conf.range_requests) {
-+      } else if (con->conf.range_requests && 
-+                 NULL != array_get_element(con->request.headers, "Range")) {
-               int do_range_request = 1;
-               /* check if we have a conditional GET */
-               if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "If-Range"))) {
--                      /* if the value is the same as our ETag, we do a Range-request, 
-+                      /* if the value is the same as our ETag, we do a Range-request,
-                        * otherwise a full 200 */
-                       if (!buffer_is_equal(ds->value, con->physical.etag)) {
-                               do_range_request = 0;
-                       }
-               }
--      
-+
-               if (do_range_request) {
-                       /* content prepared, I'm done */
--                      con->file_finished = 1;
--              
-+                      con->send->is_closed = 1;
-+
-                       if (0 == http_response_parse_range(srv, con, p)) {
-                               con->http_status = 206;
-                       }
-                       return HANDLER_FINISHED;
-               }
-       }
--      
-+
-       /* if we are still here, prepare body */
--      
--      /* we add it here for all requests 
--       * the HEAD request will drop it afterwards again 
-+
-+      /* we add it here for all requests
-+       * the HEAD request will drop it afterwards again
-        */
--      http_chunk_append_file(srv, con, con->physical.path, 0, sce->st.st_size);
--      
--      con->file_finished = 1;
--      
-+      chunkqueue_append_file(con->send, con->physical.path, 0, sce->st.st_size);
-+
-+      con->send->is_closed = 1;
-+
-       return HANDLER_FINISHED;
- }
-+/**
-+ * mark all the content as read
-+ */
-+CONNECTION_FUNC(mod_staticfile_dev_null) {
-+      chunk *c;
-+      off_t offset;
-+      chunkqueue *in = con->recv;
-+
-+      /* there is nothing that we have to send out anymore */
-+      if (in->bytes_in == in->bytes_out && 
-+          in->is_closed) return HANDLER_GO_ON;
-+
-+      for (c = in->first; in->bytes_out < in->bytes_in; c = c->next) {
-+              off_t weWant = in->bytes_in - in->bytes_out;
-+              off_t weHave = 0;
-+
-+              /* we announce toWrite octects
-+               * now take all the request_content chunk that we need to fill this request
-+               */
-+
-+              switch (c->type) {
-+              case FILE_CHUNK:
-+                      weHave = c->file.length - c->offset;
-+
-+                      if (weHave > weWant) weHave = weWant;
-+
-+                      c->offset += weHave;
-+                      in->bytes_out += weHave;
-+
-+                      break;
-+              case MEM_CHUNK:
-+                      /* append to the buffer */
-+                      weHave = c->mem->used - 1 - c->offset;
-+
-+                      if (weHave > weWant) weHave = weWant;
-+
-+                      c->offset += weHave;
-+                      in->bytes_out += weHave;
-+
-+                      break;
-+              default:
-+                      break;
-+              }
-+      }
-+
-+      return HANDLER_GO_ON;
-+
-+}
- /* this function is called at dlopen() time and inits the callbacks */
- int mod_staticfile_plugin_init(plugin *p) {
-       p->version     = LIGHTTPD_VERSION_ID;
-       p->name        = buffer_init_string("staticfile");
--      
-+
-       p->init        = mod_staticfile_init;
--      p->handle_subrequest_start = mod_staticfile_subrequest;
-+      p->handle_start_backend = mod_staticfile_subrequest;
-+      p->handle_send_request_content = mod_staticfile_dev_null;
-       p->set_defaults  = mod_staticfile_set_defaults;
-       p->cleanup     = mod_staticfile_free;
--      
-+
-       p->data        = NULL;
--      
-+
-       return 0;
- }
---- ../lighttpd-1.4.11/src/mod_status.c        2006-01-10 21:45:32.000000000 +0200
-+++ lighttpd-1.5.0/src/mod_status.c    2006-09-07 00:57:05.000000000 +0300
-@@ -4,7 +4,6 @@
- #include <fcntl.h>
- #include <stdlib.h>
- #include <string.h>
--#include <unistd.h>
- #include <errno.h>
- #include <time.h>
- #include <stdio.h>
-@@ -14,6 +13,7 @@
- #include "response.h"
- #include "connections.h"
- #include "log.h"
-+#include "status_counter.h"
- #include "plugin.h"
-@@ -29,114 +29,114 @@
- typedef struct {
-       PLUGIN_DATA;
--      
-+
-       double traffic_out;
-       double requests;
--      
-+
-       double mod_5s_traffic_out[5];
-       double mod_5s_requests[5];
-       size_t mod_5s_ndx;
--      
-+
-       double rel_traffic_out;
-       double rel_requests;
--      
-+
-       double abs_traffic_out;
-       double abs_requests;
--      
-+
-       double bytes_written;
--      
-+
-       buffer *module_list;
--      
-+
-       plugin_config **config_storage;
--      
--      plugin_config conf; 
-+
-+      plugin_config conf;
- } plugin_data;
- INIT_FUNC(mod_status_init) {
-       plugin_data *p;
-       size_t i;
--      
-+
-       p = calloc(1, sizeof(*p));
--      
-+
-       p->traffic_out = p->requests = 0;
-       p->rel_traffic_out = p->rel_requests = 0;
-       p->abs_traffic_out = p->abs_requests = 0;
-       p->bytes_written = 0;
-       p->module_list = buffer_init();
--      
-+
-       for (i = 0; i < 5; i++) {
-               p->mod_5s_traffic_out[i] = p->mod_5s_requests[i] = 0;
-       }
--      
-+
-       return p;
- }
- FREE_FUNC(mod_status_free) {
-       plugin_data *p = p_d;
--      
-+
-       UNUSED(srv);
-       if (!p) return HANDLER_GO_ON;
--      
-+
-       buffer_free(p->module_list);
--      
-+
-       if (p->config_storage) {
-               size_t i;
-               for (i = 0; i < srv->config_context->used; i++) {
-                       plugin_config *s = p->config_storage[i];
--                      
-+
-                       buffer_free(s->status_url);
-                       buffer_free(s->statistics_url);
-                       buffer_free(s->config_url);
--                      
-+
-                       free(s);
-               }
-               free(p->config_storage);
-       }
--      
--      
-+
-+
-       free(p);
--      
-+
-       return HANDLER_GO_ON;
- }
- SETDEFAULTS_FUNC(mod_status_set_defaults) {
-       plugin_data *p = p_d;
-       size_t i;
--      
--      config_values_t cv[] = { 
-+
-+      config_values_t cv[] = {
-               { "status.status-url",           NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
-               { "status.config-url",           NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
-               { "status.enable-sort",          NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },
-               { "status.statistics-url",       NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
-               { NULL,                          NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
-       };
--      
-+
-       if (!p) return HANDLER_ERROR;
--      
-+
-       p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
--      
-+
-       for (i = 0; i < srv->config_context->used; i++) {
-               plugin_config *s;
--              
-+
-               s = calloc(1, sizeof(plugin_config));
-               s->config_url    = buffer_init();
-               s->status_url    = buffer_init();
-               s->sort          = 1;
-               s->statistics_url    = buffer_init();
--              
-+
-               cv[0].destination = s->status_url;
-               cv[1].destination = s->config_url;
-               cv[2].destination = &(s->sort);
-               cv[3].destination = s->statistics_url;
--              
-+
-               p->config_storage[i] = s;
--      
-+
-               if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
-                       return HANDLER_ERROR;
-               }
-       }
--      
-+
-       return HANDLER_GO_ON;
- }
-@@ -151,7 +151,7 @@
-       buffer_append_string(b, value);
-       BUFFER_APPEND_STRING_CONST(b, "</td>\n");
-       BUFFER_APPEND_STRING_CONST(b, "   </tr>\n");
--      
-+
-       return 0;
- }
-@@ -161,13 +161,13 @@
-       buffer_append_string(b, key);
-       BUFFER_APPEND_STRING_CONST(b, "</th>\n");
-       BUFFER_APPEND_STRING_CONST(b, "   </tr>\n");
--      
-+
-       return 0;
- }
- static int mod_status_header_append_sort(buffer *b, void *p_d, const char* key) {
-       plugin_data *p = p_d;
--      
-+
-       if (p->conf.sort) {
-               BUFFER_APPEND_STRING_CONST(b, "<th class=\"status\"><a href=\"#\" class=\"sortheader\" onclick=\"resort(this);return false;\">");
-               buffer_append_string(b, key);
-@@ -177,13 +177,13 @@
-               buffer_append_string(b, key);
-               BUFFER_APPEND_STRING_CONST(b, "</th>\n");
-       }
--      
-+
-       return 0;
- }
- static int mod_status_get_multiplier(double *avg, char *multiplier, int size) {
-       *multiplier = ' ';
--      
-+
-       if (*avg > size) { *avg /= size; *multiplier = 'k'; }
-       if (*avg > size) { *avg /= size; *multiplier = 'M'; }
-       if (*avg > size) { *avg /= size; *multiplier = 'G'; }
-@@ -202,21 +202,21 @@
-       size_t j;
-       double avg;
-       char multiplier = '\0';
--      char buf[32];
-+      char buf[128];
-       time_t ts;
--      
-+
-       int days, hours, mins, seconds;
--      
--      b = chunkqueue_get_append_buffer(con->write_queue);
--      BUFFER_COPY_STRING_CONST(b, 
-+      b = chunkqueue_get_append_buffer(con->send);
-+
-+      BUFFER_COPY_STRING_CONST(b,
-                                "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n"
-                                "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n"
-                                "         \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"
-                                "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n"
-                                " <head>\n"
-                                "  <title>Status</title>\n");
--      
-+
-       BUFFER_APPEND_STRING_CONST(b,
-                                  "  <style type=\"text/css\">\n"
-                                  "    table.status { border: black solid thin; }\n"
-@@ -226,14 +226,14 @@
-                                  "    a.sortheader { background-color: black; color: white; font-weight: bold; text-decoration: none; display: block; }\n"
-                                  "    span.sortarrow { color: white; text-decoration: none; }\n"
-                                  "  </style>\n");
--      
-+
-       if (p->conf.sort) {
-               BUFFER_APPEND_STRING_CONST(b,
-                                          "<script type=\"text/javascript\">\n"
-                                          "// <!--\n"
-                                          "var sort_column;\n"
-                                          "var prev_span = null;\n");
--              
-+
-               BUFFER_APPEND_STRING_CONST(b,
-                                          "function get_inner_text(el) {\n"
-                                          " if((typeof el == 'string')||(typeof el == 'undefined'))\n"
-@@ -251,7 +251,7 @@
-                                          " }\n"
-                                          " return str;\n"
-                                          "}\n");
--              
-+
-               BUFFER_APPEND_STRING_CONST(b,
-                                          "function sortfn(a,b) {\n"
-                                          " var at = get_inner_text(a.cells[sort_column]);\n"
-@@ -266,7 +266,7 @@
-                                          "  else return 1;\n"
-                                          " }\n"
-                                          "}\n");
--              
-+
-               BUFFER_APPEND_STRING_CONST(b,
-                                          "function resort(lnk) {\n"
-                                          " var span = lnk.childNodes[1];\n"
-@@ -276,7 +276,7 @@
-                                          "  rows[j-1] = table.rows[j];\n"
-                                          " sort_column = lnk.parentNode.cellIndex;\n"
-                                          " rows.sort(sortfn);\n");
--              
-+
-               BUFFER_APPEND_STRING_CONST(b,
-                                          " if (prev_span != null) prev_span.innerHTML = '';\n"
-                                          " if (span.getAttribute('sortdir')=='down') {\n"
-@@ -294,175 +294,175 @@
-                                          "// -->\n"
-                                          "</script>\n");
-       }
--      
--      BUFFER_APPEND_STRING_CONST(b, 
-+
-+      BUFFER_APPEND_STRING_CONST(b,
-                                " </head>\n"
-                                " <body>\n");
--      
--      
--      
-+
-+
-+
-       /* connection listing */
-       BUFFER_APPEND_STRING_CONST(b, "<h1>Server-Status</h1>");
--      
--      BUFFER_APPEND_STRING_CONST(b, "<table class=\"status\">");
--      BUFFER_APPEND_STRING_CONST(b, "<tr><td>Hostname</td><td class=\"string\">");
-+
-+      BUFFER_APPEND_STRING_CONST(b, "<table class=\"status\" id=\"status\" summary=\"Server Status\">");
-+      BUFFER_APPEND_STRING_CONST(b, "<tr><td>Hostname</td><td class=\"string\"><span id=\"host_addr\">");
-       buffer_append_string_buffer(b, con->uri.authority);
--      BUFFER_APPEND_STRING_CONST(b, " (");
-+      BUFFER_APPEND_STRING_CONST(b, "</span> (<span id=\"host_name\">");
-       buffer_append_string_buffer(b, con->server_name);
--      BUFFER_APPEND_STRING_CONST(b, ")</td></tr>\n");
--      BUFFER_APPEND_STRING_CONST(b, "<tr><td>Uptime</td><td class=\"string\">");
--      
-+      BUFFER_APPEND_STRING_CONST(b, "</span>)</td></tr>\n");
-+      BUFFER_APPEND_STRING_CONST(b, "<tr><td>Uptime</td><td class=\"string\" id=\"uptime\">");
-+
-       ts = srv->cur_ts - srv->startup_ts;
--      
-+
-       days = ts / (60 * 60 * 24);
-       ts %= (60 * 60 * 24);
--      
-+
-       hours = ts / (60 * 60);
-       ts %= (60 * 60);
--      
-+
-       mins = ts / (60);
-       ts %= (60);
--      
-+
-       seconds = ts;
--      
-+
-       if (days) {
-               buffer_append_long(b, days);
-               BUFFER_APPEND_STRING_CONST(b, " days ");
-       }
--      
-+
-       if (hours) {
-               buffer_append_long(b, hours);
-               BUFFER_APPEND_STRING_CONST(b, " hours ");
-       }
--      
-+
-       if (mins) {
-               buffer_append_long(b, mins);
-               BUFFER_APPEND_STRING_CONST(b, " min ");
-       }
--      
-+
-       buffer_append_long(b, seconds);
-       BUFFER_APPEND_STRING_CONST(b, " s");
--      
-+
-       BUFFER_APPEND_STRING_CONST(b, "</td></tr>\n");
-       BUFFER_APPEND_STRING_CONST(b, "<tr><td>Started at</td><td class=\"string\">");
--      
-+
-       ts = srv->startup_ts;
--      
--      strftime(buf, sizeof(buf) - 1, "%Y-%m-%d %H:%M:%S", localtime(&ts));
-+
-+      strftime(buf, sizeof(buf) - 1, "<span id=\"start_date\">%Y-%m-%d</span> <span id=\"start_time\">%H:%M:%S</span>", localtime(&ts));
-       buffer_append_string(b, buf);
-       BUFFER_APPEND_STRING_CONST(b, "</td></tr>\n");
--      
--      
-+
-+
-       BUFFER_APPEND_STRING_CONST(b, "<tr><th colspan=\"2\">absolute (since start)</th></tr>\n");
--      
--      BUFFER_APPEND_STRING_CONST(b, "<tr><td>Requests</td><td class=\"string\">");
-+
-+      BUFFER_APPEND_STRING_CONST(b, "<tr><td>Requests</td><td class=\"string\" ><span id=\"requests\">");
-       avg = p->abs_requests;
-       mod_status_get_multiplier(&avg, &multiplier, 1000);
--      
-+
-       buffer_append_long(b, avg);
--      BUFFER_APPEND_STRING_CONST(b, " ");
-+      BUFFER_APPEND_STRING_CONST(b, "</span> <span id=\"requests_mult\">");
-       if (multiplier) buffer_append_string_len(b, &multiplier, 1);
--      BUFFER_APPEND_STRING_CONST(b, "req</td></tr>\n");
--      
--      BUFFER_APPEND_STRING_CONST(b, "<tr><td>Traffic</td><td class=\"string\">");
-+      BUFFER_APPEND_STRING_CONST(b, "</span>req</td></tr>\n");
-+
-+      BUFFER_APPEND_STRING_CONST(b, "<tr><td>Traffic</td><td class=\"string\"><span id=\"traffic\">");
-       avg = p->abs_traffic_out;
-       mod_status_get_multiplier(&avg, &multiplier, 1024);
-       sprintf(buf, "%.2f", avg);
-       buffer_append_string(b, buf);
--      BUFFER_APPEND_STRING_CONST(b, " ");
-+      BUFFER_APPEND_STRING_CONST(b, "</span>  <span id=\"traffic_mult\">");
-       if (multiplier) buffer_append_string_len(b, &multiplier, 1);
--      BUFFER_APPEND_STRING_CONST(b, "byte</td></tr>\n");
-+      BUFFER_APPEND_STRING_CONST(b, "</span>byte</td></tr>\n");
-       BUFFER_APPEND_STRING_CONST(b, "<tr><th colspan=\"2\">average (since start)</th></tr>\n");
--      
--      BUFFER_APPEND_STRING_CONST(b, "<tr><td>Requests</td><td class=\"string\">");
-+
-+      BUFFER_APPEND_STRING_CONST(b, "<tr><td>Requests</td><td class=\"string\"><span id=\"requests_avg\">");
-       avg = p->abs_requests / (srv->cur_ts - srv->startup_ts);
-       mod_status_get_multiplier(&avg, &multiplier, 1000);
-       buffer_append_long(b, avg);
--      BUFFER_APPEND_STRING_CONST(b, " ");
-+      BUFFER_APPEND_STRING_CONST(b, "</span> <span id=\"requests_avg_mult\">");
-       if (multiplier) buffer_append_string_len(b, &multiplier, 1);
--      BUFFER_APPEND_STRING_CONST(b, "req/s</td></tr>\n");
--      
--      BUFFER_APPEND_STRING_CONST(b, "<tr><td>Traffic</td><td class=\"string\">");
-+      BUFFER_APPEND_STRING_CONST(b, "</span>req/s</td></tr>\n");
-+
-+      BUFFER_APPEND_STRING_CONST(b, "<tr><td>Traffic</td><td class=\"string\"><span id=\"traffic_avg\">");
-       avg = p->abs_traffic_out / (srv->cur_ts - srv->startup_ts);
-       mod_status_get_multiplier(&avg, &multiplier, 1024);
-       sprintf(buf, "%.2f", avg);
-       buffer_append_string(b, buf);
--      BUFFER_APPEND_STRING_CONST(b, " ");
-+      BUFFER_APPEND_STRING_CONST(b, "</span> <span id=\"traffic_avg_mult\">");
-       if (multiplier) buffer_append_string_len(b, &multiplier, 1);
--      BUFFER_APPEND_STRING_CONST(b, "byte/s</td></tr>\n");
-+      BUFFER_APPEND_STRING_CONST(b, "</span>byte/s</td></tr>\n");
-+
-+
--      
--      
-       BUFFER_APPEND_STRING_CONST(b, "<tr><th colspan=\"2\">average (5s sliding average)</th></tr>\n");
-       for (j = 0, avg = 0; j < 5; j++) {
-               avg += p->mod_5s_requests[j];
-       }
--      
-+
-       avg /= 5;
--      
--      BUFFER_APPEND_STRING_CONST(b, "<tr><td>Requests</td><td class=\"string\">");
-+
-+      BUFFER_APPEND_STRING_CONST(b, "<tr><td>Requests</td><td class=\"string\"><span id=\"requests_sliding_avg\">");
-       mod_status_get_multiplier(&avg, &multiplier, 1000);
-       buffer_append_long(b, avg);
--      BUFFER_APPEND_STRING_CONST(b, " ");
-+      BUFFER_APPEND_STRING_CONST(b, "</span> <span id=\"requests_sliding_avg_mult\">");
-       if (multiplier) buffer_append_string_len(b, &multiplier, 1);
--      
--      BUFFER_APPEND_STRING_CONST(b, "req/s</td></tr>\n");
--      
-+
-+      BUFFER_APPEND_STRING_CONST(b, "</span>req/s</td></tr>\n");
-+
-       for (j = 0, avg = 0; j < 5; j++) {
-               avg += p->mod_5s_traffic_out[j];
-       }
--      
-+
-       avg /= 5;
--      
--      BUFFER_APPEND_STRING_CONST(b, "<tr><td>Traffic</td><td class=\"string\">");
-+
-+      BUFFER_APPEND_STRING_CONST(b, "<tr><td>Traffic</td><td class=\"string\"><span id=\"requests_sliding_traffic\">");
-       mod_status_get_multiplier(&avg, &multiplier, 1024);
-       sprintf(buf, "%.2f", avg);
-       buffer_append_string(b, buf);
--      BUFFER_APPEND_STRING_CONST(b, " ");
-+      BUFFER_APPEND_STRING_CONST(b, "</span> <span id=\"requests_sliding_traffic_mult\">");
-       if (multiplier) buffer_append_string_len(b, &multiplier, 1);
--      BUFFER_APPEND_STRING_CONST(b, "byte/s</td></tr>\n");
--      
-+      BUFFER_APPEND_STRING_CONST(b, "</span>byte/s</td></tr>\n");
-+
-       BUFFER_APPEND_STRING_CONST(b, "</table>\n");
--      
--      
-+
-+
-       BUFFER_APPEND_STRING_CONST(b, "<hr />\n<pre><b>legend</b>\n");
-       BUFFER_APPEND_STRING_CONST(b, ". = connect, C = close, E = hard error\n");
-       BUFFER_APPEND_STRING_CONST(b, "r = read, R = read-POST, W = write, h = handle-request\n");
-       BUFFER_APPEND_STRING_CONST(b, "q = request-start,  Q = request-end\n");
-       BUFFER_APPEND_STRING_CONST(b, "s = response-start, S = response-end\n");
--      
--      BUFFER_APPEND_STRING_CONST(b, "<b>");
-+
-+      BUFFER_APPEND_STRING_CONST(b, "<strong><span id=\"connections\">");
-       buffer_append_long(b, srv->conns->used);
--      BUFFER_APPEND_STRING_CONST(b, " connections</b>\n");
--      
-+      BUFFER_APPEND_STRING_CONST(b, "</span> connections</strong>\n");
-+
-       for (j = 0; j < srv->conns->used; j++) {
-               connection *c = srv->conns->ptr[j];
-               const char *state = connection_get_short_state(c->state);
--              
-+
-               buffer_append_string_len(b, state, 1);
--              
-+
-               if (((j + 1) % 50) == 0) {
-                       BUFFER_APPEND_STRING_CONST(b, "\n");
-               }
-       }
--      
-+
-       BUFFER_APPEND_STRING_CONST(b, "\n</pre><hr />\n<h2>Connections</h2>\n");
--      
--      BUFFER_APPEND_STRING_CONST(b, "<table class=\"status\">\n");
-+
-+      BUFFER_APPEND_STRING_CONST(b, "<table class=\"status\" summary=\"Current connections\" id=\"clients\">\n");
-       BUFFER_APPEND_STRING_CONST(b, "<tr>");
-       mod_status_header_append_sort(b, p_d, "Client IP");
-       mod_status_header_append_sort(b, p_d, "Read");
-@@ -473,72 +473,72 @@
-       mod_status_header_append_sort(b, p_d, "URI");
-       mod_status_header_append_sort(b, p_d, "File");
-       BUFFER_APPEND_STRING_CONST(b, "</tr>\n");
--      
-+
-       for (j = 0; j < srv->conns->used; j++) {
-               connection *c = srv->conns->ptr[j];
--              
--              BUFFER_APPEND_STRING_CONST(b, "<tr><td class=\"string\">");
--              
-+
-+              BUFFER_APPEND_STRING_CONST(b, "<tr><td class=\"string ip\">");
-+
-               buffer_append_string(b, inet_ntop_cache_get_ip(srv, &(c->dst_addr)));
--              
--              BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"int\">");
--              
--              if (con->request.content_length) {
--                      buffer_append_long(b, c->request_content_queue->bytes_in);
-+
-+              BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"int bytes_read\">");
-+
-+              if (c->request.content_length != -1) {
-+                      buffer_append_long(b, c->recv->bytes_in);
-                       BUFFER_APPEND_STRING_CONST(b, "/");
-                       buffer_append_long(b, c->request.content_length);
-               } else {
-                       BUFFER_APPEND_STRING_CONST(b, "0/0");
-               }
--      
--              BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"int\">");
--              
--              buffer_append_off_t(b, chunkqueue_written(c->write_queue));
-+
-+              BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"int bytes_written\">");
-+
-+              buffer_append_off_t(b, chunkqueue_written(c->send_raw));
-               BUFFER_APPEND_STRING_CONST(b, "/");
--              buffer_append_off_t(b, chunkqueue_length(c->write_queue));
--              
--              BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string\">");
--              
-+              buffer_append_off_t(b, chunkqueue_length(c->send_raw));
-+
-+              BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string state\">");
-+
-               buffer_append_string(b, connection_get_state(c->state));
--              
--              BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"int\">");
--              
-+
-+              BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"int time\">");
-+
-               buffer_append_long(b, srv->cur_ts - c->request_start);
--              
--              BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string\">");
--              
-+
-+              BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string host\">");
-+
-               if (buffer_is_empty(c->server_name)) {
-                       buffer_append_string_buffer(b, c->uri.authority);
-               }
-               else {
-                       buffer_append_string_buffer(b, c->server_name);
-               }
--              
--              BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string\">");
--              
-+
-+              BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string uri\">");
-+
-               if (!buffer_is_empty(c->uri.path)) {
-                       buffer_append_string_encoded(b, CONST_BUF_LEN(c->uri.path), ENCODING_HTML);
-               }
--              
--              BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string\">");
--              
-+
-+              BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string file\">");
-+
-               buffer_append_string_buffer(b, c->physical.path);
--              
-+
-               BUFFER_APPEND_STRING_CONST(b, "</td></tr>\n");
-       }
--      
--      
--      BUFFER_APPEND_STRING_CONST(b, 
-+
-+
-+      BUFFER_APPEND_STRING_CONST(b,
-                     "</table>\n");
--      
--      
--      BUFFER_APPEND_STRING_CONST(b, 
-+
-+
-+      BUFFER_APPEND_STRING_CONST(b,
-                     " </body>\n"
-                     "</html>\n"
-                     );
--      
-+
-       response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html"));
--      
-+
-       return 0;
- }
-@@ -548,27 +548,27 @@
-       buffer *b;
-       double avg;
-       time_t ts;
--      
--      b = chunkqueue_get_append_buffer(con->write_queue);
-+
-+      b = chunkqueue_get_append_buffer(con->send);
-       /* output total number of requests */
-       BUFFER_APPEND_STRING_CONST(b, "Total Accesses: ");
-       avg = p->abs_requests;
-       buffer_append_long(b, avg);
-       BUFFER_APPEND_STRING_CONST(b, "\n");
--      
-+
-       /* output total traffic out in kbytes */
-       BUFFER_APPEND_STRING_CONST(b, "Total kBytes: ");
-       avg = p->abs_traffic_out / 1024;
-       buffer_append_long(b, avg);
-       BUFFER_APPEND_STRING_CONST(b, "\n");
--      
-+
-       /* output uptime */
-       BUFFER_APPEND_STRING_CONST(b, "Uptime: ");
-       ts = srv->cur_ts - srv->startup_ts;
-       buffer_append_long(b, ts);
-       BUFFER_APPEND_STRING_CONST(b, "\n");
--      
-+
-       /* output busy servers */
-       BUFFER_APPEND_STRING_CONST(b, "BusyServers: ");
-       buffer_append_long(b, srv->conns->used);
-@@ -577,7 +577,7 @@
-       /* set text/plain output */
-       response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/plain"));
--      
-+
-       return 0;
- }
-@@ -585,17 +585,17 @@
-       plugin_data *p = p_d;
-       buffer *b, *m = p->module_list;
-       size_t i;
--      array *st = srv->status;
-+      array *st = status_counter_get_array();
-       if (0 == st->used) {
-               /* we have nothing to send */
-               con->http_status = 204;
--              con->file_finished = 1;
--      
-+              con->send->is_closed = 1;
-+
-               return HANDLER_FINISHED;
-       }
--      
--      b = chunkqueue_get_append_buffer(con->write_queue);
-+
-+      b = chunkqueue_get_append_buffer(con->send);
-       for (i = 0; i < st->used; i++) {
-               size_t ndx = st->sorted[i];
-@@ -605,27 +605,27 @@
-               buffer_append_long(b, ((data_integer *)(st->data[ndx]))->value);
-               buffer_append_string(b, "\n");
-       }
--      
-+
-       response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/plain"));
--      
-+
-       con->http_status = 200;
--      con->file_finished = 1;
--      
-+      con->send->is_closed = 1;
-+
-       return HANDLER_FINISHED;
- }
- static handler_t mod_status_handle_server_status(server *srv, connection *con, void *p_d) {
--      
-+
-       if (buffer_is_equal_string(con->uri.query, CONST_STR_LEN("auto"))) {
-               mod_status_handle_server_status_text(srv, con, p_d);
-       } else {
-               mod_status_handle_server_status_html(srv, con, p_d);
-       }
--      
-+
-       con->http_status = 200;
--      con->file_finished = 1;
--      
-+      con->send->is_closed = 1;
-+
-       return HANDLER_FINISHED;
- }
-@@ -634,9 +634,9 @@
-       plugin_data *p = p_d;
-       buffer *b, *m = p->module_list;
-       size_t i;
--      
--      struct ev_map { fdevent_handler_t et; const char *name; } event_handlers[] = 
--      { 
-+
-+      struct ev_map { fdevent_handler_t et; const char *name; } event_handlers[] =
-+      {
-               /* - poll is most reliable
-                * - select works everywhere
-                * - linux-* are experimental
-@@ -661,10 +661,10 @@
- #endif
-               { FDEVENT_HANDLER_UNSET,          NULL }
-       };
--      
--      b = chunkqueue_get_append_buffer(con->write_queue);
--      
--      BUFFER_COPY_STRING_CONST(b, 
-+
-+      b = chunkqueue_get_append_buffer(con->send);
-+
-+      BUFFER_COPY_STRING_CONST(b,
-                          "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n"
-                          "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n"
-                          "         \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"
-@@ -675,7 +675,7 @@
-                          " <body>\n"
-                          "  <h1>" PACKAGE_NAME " " PACKAGE_VERSION "</h1>\n"
-                          "  <table border=\"1\">\n");
--      
-+
-       mod_status_header_append(b, "Server-Features");
- #ifdef HAVE_PCRE_H
-       mod_status_row_append(b, "RegEx Conditionals", "enabled");
-@@ -683,21 +683,21 @@
-       mod_status_row_append(b, "RegEx Conditionals", "disabled - pcre missing");
- #endif
-       mod_status_header_append(b, "Network Engine");
--      
-+
-       for (i = 0; event_handlers[i].name; i++) {
-               if (event_handlers[i].et == srv->event_handler) {
-                       mod_status_row_append(b, "fd-Event-Handler", event_handlers[i].name);
-                       break;
-               }
-       }
--      
-+
-       mod_status_header_append(b, "Config-File-Settings");
--      
-+
-       for (i = 0; i < srv->plugins.used; i++) {
-               plugin **ps = srv->plugins.ptr;
--              
-+
-               plugin *pl = ps[i];
--      
-+
-               if (i == 0) {
-                       buffer_copy_string_buffer(m, pl->name);
-               } else {
-@@ -705,137 +705,135 @@
-                       buffer_append_string_buffer(m, pl->name);
-               }
-       }
--      
-+
-       mod_status_row_append(b, "Loaded Modules", m->ptr);
--      
-+
-       BUFFER_APPEND_STRING_CONST(b, "  </table>\n");
--      
--      BUFFER_APPEND_STRING_CONST(b, 
-+
-+      BUFFER_APPEND_STRING_CONST(b,
-                     " </body>\n"
-                     "</html>\n"
-                     );
--      
-+
-       response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html"));
--      
-+
-       con->http_status = 200;
--      con->file_finished = 1;
--      
-+      con->send->is_closed = 1;
-+
-       return HANDLER_FINISHED;
- }
--#define PATCH(x) \
--      p->conf.x = s->x;
- static int mod_status_patch_connection(server *srv, connection *con, plugin_data *p) {
-       size_t i, j;
-       plugin_config *s = p->config_storage[0];
--      
--      PATCH(status_url);
--      PATCH(config_url);
--      PATCH(sort);
--      PATCH(statistics_url);
--      
-+
-+      PATCH_OPTION(status_url);
-+      PATCH_OPTION(config_url);
-+      PATCH_OPTION(sort);
-+      PATCH_OPTION(statistics_url);
-+
-       /* skip the first, the global context */
-       for (i = 1; i < srv->config_context->used; i++) {
-               data_config *dc = (data_config *)srv->config_context->data[i];
-               s = p->config_storage[i];
--              
-+
-               /* condition didn't match */
-               if (!config_check_cond(srv, con, dc)) continue;
--              
-+
-               /* merge config */
-               for (j = 0; j < dc->value->used; j++) {
-                       data_unset *du = dc->value->data[j];
--                      
-+
-                       if (buffer_is_equal_string(du->key, CONST_STR_LEN("status.status-url"))) {
--                              PATCH(status_url);
-+                              PATCH_OPTION(status_url);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("status.config-url"))) {
--                              PATCH(config_url);
-+                              PATCH_OPTION(config_url);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("status.enable-sort"))) {
--                              PATCH(sort);
-+                              PATCH_OPTION(sort);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("status.statistics-url"))) {
--                              PATCH(statistics_url);
--                      } 
-+                              PATCH_OPTION(statistics_url);
-+                      }
-               }
-       }
--      
-+
-       return 0;
- }
- static handler_t mod_status_handler(server *srv, connection *con, void *p_d) {
-       plugin_data *p = p_d;
--      
-+
-       mod_status_patch_connection(srv, con, p);
--      
--      if (!buffer_is_empty(p->conf.status_url) && 
-+
-+      if (!buffer_is_empty(p->conf.status_url) &&
-           buffer_is_equal(p->conf.status_url, con->uri.path)) {
-               return mod_status_handle_server_status(srv, con, p_d);
--      } else if (!buffer_is_empty(p->conf.config_url) && 
-+      } else if (!buffer_is_empty(p->conf.config_url) &&
-           buffer_is_equal(p->conf.config_url, con->uri.path)) {
-               return mod_status_handle_server_config(srv, con, p_d);
--      } else if (!buffer_is_empty(p->conf.statistics_url) && 
-+      } else if (!buffer_is_empty(p->conf.statistics_url) &&
-           buffer_is_equal(p->conf.statistics_url, con->uri.path)) {
-               return mod_status_handle_server_statistics(srv, con, p_d);
-       }
--      
-+
-       return HANDLER_GO_ON;
- }
- TRIGGER_FUNC(mod_status_trigger) {
-       plugin_data *p = p_d;
-       size_t i;
--      
-+
-       /* check all connections */
-       for (i = 0; i < srv->conns->used; i++) {
-               connection *c = srv->conns->ptr[i];
--              
-+
-               p->bytes_written += c->bytes_written_cur_second;
-       }
--      
-+
-       /* a sliding average */
-       p->mod_5s_traffic_out[p->mod_5s_ndx] = p->bytes_written;
-       p->mod_5s_requests   [p->mod_5s_ndx] = p->requests;
--      
-+
-       p->mod_5s_ndx = (p->mod_5s_ndx+1) % 5;
--      
-+
-       p->abs_traffic_out += p->bytes_written;
-       p->rel_traffic_out += p->bytes_written;
--      
-+
-       p->bytes_written = 0;
--      
-+
-       /* reset storage - second */
-       p->traffic_out = 0;
-       p->requests    = 0;
--      
-+
-       return HANDLER_GO_ON;
- }
- REQUESTDONE_FUNC(mod_status_account) {
-       plugin_data *p = p_d;
--      
-+
-       UNUSED(srv);
-       p->requests++;
-       p->rel_requests++;
-       p->abs_requests++;
--      
-+
-       p->bytes_written += con->bytes_written_cur_second;
--      
-+
-       return HANDLER_GO_ON;
- }
- int mod_status_plugin_init(plugin *p) {
-       p->version     = LIGHTTPD_VERSION_ID;
-       p->name        = buffer_init_string("status");
--      
-+
-       p->init        = mod_status_init;
-       p->cleanup     = mod_status_free;
-       p->set_defaults= mod_status_set_defaults;
--      
-+
-       p->handle_uri_clean    = mod_status_handler;
-       p->handle_trigger      = mod_status_trigger;
--      p->handle_request_done = mod_status_account;
--      
-+      p->handle_response_done = mod_status_account;
-+
-       p->data        = NULL;
--      
-+
-       return 0;
- }
---- ../lighttpd-1.4.11/src/mod_trigger_b4_dl.c 2005-09-23 22:53:55.000000000 +0300
-+++ lighttpd-1.5.0/src/mod_trigger_b4_dl.c     2006-07-16 00:26:03.000000000 +0300
-@@ -24,18 +24,18 @@
- /**
-  * this is a trigger_b4_dl for a lighttpd plugin
-- * 
-+ *
-  */
- /* plugin config for all request/connections */
- typedef struct {
-       buffer *db_filename;
--      
-+
-       buffer *trigger_url;
-       buffer *download_url;
-       buffer *deny_url;
--      
-+
-       array  *mc_hosts;
-       buffer *mc_namespace;
- #if defined(HAVE_PCRE_H)
-@@ -46,58 +46,58 @@
-       GDBM_FILE db;
- #endif
--#if defined(HAVE_MEMCACHE_H) 
-+#if defined(HAVE_MEMCACHE_H)
-       struct memcache *mc;
- #endif
--      
-+
-       unsigned short trigger_timeout;
-       unsigned short debug;
- } plugin_config;
- typedef struct {
-       PLUGIN_DATA;
--      
-+
-       buffer *tmp_buf;
--      
-+
-       plugin_config **config_storage;
--      
--      plugin_config conf; 
-+
-+      plugin_config conf;
- } plugin_data;
- /* init the plugin data */
- INIT_FUNC(mod_trigger_b4_dl_init) {
-       plugin_data *p;
--      
-+
-       p = calloc(1, sizeof(*p));
--      
-+
-       p->tmp_buf = buffer_init();
--      
-+
-       return p;
- }
- /* detroy the plugin data */
- FREE_FUNC(mod_trigger_b4_dl_free) {
-       plugin_data *p = p_d;
--      
-+
-       UNUSED(srv);
-       if (!p) return HANDLER_GO_ON;
--      
-+
-       if (p->config_storage) {
-               size_t i;
-               for (i = 0; i < srv->config_context->used; i++) {
-                       plugin_config *s = p->config_storage[i];
-                       if (!s) continue;
--                      
-+
-                       buffer_free(s->db_filename);
-                       buffer_free(s->download_url);
-                       buffer_free(s->trigger_url);
-                       buffer_free(s->deny_url);
--                      
-+
-                       buffer_free(s->mc_namespace);
-                       array_free(s->mc_hosts);
--                      
-+
- #if defined(HAVE_PCRE_H)
-                       if (s->trigger_regex) pcre_free(s->trigger_regex);
-                       if (s->download_regex) pcre_free(s->download_regex);
-@@ -108,16 +108,16 @@
- #if defined(HAVE_MEMCACHE_H)
-                       if (s->mc) mc_free(s->mc);
- #endif
--                      
-+
-                       free(s);
-               }
-               free(p->config_storage);
-       }
--      
-+
-       buffer_free(p->tmp_buf);
--      
-+
-       free(p);
--      
-+
-       return HANDLER_GO_ON;
- }
-@@ -126,9 +126,9 @@
- SETDEFAULTS_FUNC(mod_trigger_b4_dl_set_defaults) {
-       plugin_data *p = p_d;
-       size_t i = 0;
--      
--      
--      config_values_t cv[] = { 
-+
-+
-+      config_values_t cv[] = {
-               { "trigger-before-download.gdbm-filename",   NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
-               { "trigger-before-download.trigger-url",     NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 1 */
-               { "trigger-before-download.download-url",    NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 2 */
-@@ -139,18 +139,18 @@
-               { "trigger-before-download.debug",           NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },      /* 7 */
-               { NULL,                        NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
-       };
--      
-+
-       if (!p) return HANDLER_ERROR;
--      
-+
-       p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
--      
-+
-       for (i = 0; i < srv->config_context->used; i++) {
-               plugin_config *s;
- #if defined(HAVE_PCRE_H)
-               const char *errptr;
-               int erroff;
- #endif
--              
-+
-               s = calloc(1, sizeof(plugin_config));
-               s->db_filename    = buffer_init();
-               s->download_url   = buffer_init();
-@@ -158,7 +158,7 @@
-               s->deny_url       = buffer_init();
-               s->mc_hosts       = array_init();
-               s->mc_namespace   = buffer_init();
--              
-+
-               cv[0].destination = s->db_filename;
-               cv[1].destination = s->trigger_url;
-               cv[2].destination = s->download_url;
-@@ -167,41 +167,41 @@
-               cv[5].destination = s->mc_hosts;
-               cv[6].destination = s->mc_namespace;
-               cv[7].destination = &(s->debug);
--              
-+
-               p->config_storage[i] = s;
--      
-+
-               if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
-                       return HANDLER_ERROR;
-               }
- #if defined(HAVE_GDBM_H)
-               if (!buffer_is_empty(s->db_filename)) {
-                       if (NULL == (s->db = gdbm_open(s->db_filename->ptr, 4096, GDBM_WRCREAT | GDBM_NOLOCK, S_IRUSR | S_IWUSR, 0))) {
--                              log_error_write(srv, __FILE__, __LINE__, "s", 
-+                              log_error_write(srv, __FILE__, __LINE__, "s",
-                                               "gdbm-open failed");
-                               return HANDLER_ERROR;
-                       }
-               }
- #endif
--#if defined(HAVE_PCRE_H)              
-+#if defined(HAVE_PCRE_H)
-               if (!buffer_is_empty(s->download_url)) {
-                       if (NULL == (s->download_regex = pcre_compile(s->download_url->ptr,
-                                                                     0, &errptr, &erroff, NULL))) {
--                              
--                              log_error_write(srv, __FILE__, __LINE__, "sbss", 
--                                              "compiling regex for download-url failed:", 
-+
-+                              log_error_write(srv, __FILE__, __LINE__, "sbss",
-+                                              "compiling regex for download-url failed:",
-                                               s->download_url, "pos:", erroff);
-                               return HANDLER_ERROR;
-                       }
-               }
--              
-+
-               if (!buffer_is_empty(s->trigger_url)) {
-                       if (NULL == (s->trigger_regex = pcre_compile(s->trigger_url->ptr,
-                                                                    0, &errptr, &erroff, NULL))) {
--                              
--                              log_error_write(srv, __FILE__, __LINE__, "sbss", 
--                                              "compiling regex for trigger-url failed:", 
-+
-+                              log_error_write(srv, __FILE__, __LINE__, "sbss",
-+                                              "compiling regex for trigger-url failed:",
-                                               s->trigger_url, "pos:", erroff);
--                              
-+
-                               return HANDLER_ERROR;
-                       }
-               }
-@@ -211,100 +211,97 @@
- #if defined(HAVE_MEMCACHE_H)
-                       size_t k;
-                       s->mc = mc_new();
--              
-+
-                       for (k = 0; k < s->mc_hosts->used; k++) {
-                               data_string *ds = (data_string *)s->mc_hosts->data[k];
--                              
-+
-                               if (0 != mc_server_add4(s->mc, ds->value->ptr)) {
--                                      log_error_write(srv, __FILE__, __LINE__, "sb", 
--                                                      "connection to host failed:", 
-+                                      log_error_write(srv, __FILE__, __LINE__, "sb",
-+                                                      "connection to host failed:",
-                                                       ds->value);
--                                      
-+
-                                       return HANDLER_ERROR;
-                               }
-                       }
- #else
--                      log_error_write(srv, __FILE__, __LINE__, "s", 
-+                      log_error_write(srv, __FILE__, __LINE__, "s",
-                                       "memcache support is not compiled in but trigger-before-download.memcache-hosts is set, aborting");
-                       return HANDLER_ERROR;
- #endif
-               }
--              
-+
- #if (!defined(HAVE_GDBM_H) && !defined(HAVE_MEMCACHE_H)) || !defined(HAVE_PCRE_H)
--              log_error_write(srv, __FILE__, __LINE__, "s", 
-+              log_error_write(srv, __FILE__, __LINE__, "s",
-                               "(either gdbm or libmemcache) and pcre are require, but were not found, aborting");
-               return HANDLER_ERROR;
- #endif
-       }
--      
-+
-       return HANDLER_GO_ON;
- }
--#define PATCH(x) \
--      p->conf.x = s->x;
- static int mod_trigger_b4_dl_patch_connection(server *srv, connection *con, plugin_data *p) {
-       size_t i, j;
-       plugin_config *s = p->config_storage[0];
--      
-+
- #if defined(HAVE_GDBM)
--      PATCH(db);
--#endif        
-+      PATCH_OPTION(db);
-+#endif
- #if defined(HAVE_PCRE_H)
--      PATCH(download_regex);
--      PATCH(trigger_regex);
--#endif        
--      PATCH(trigger_timeout);
--      PATCH(deny_url);
--      PATCH(mc_namespace);
--      PATCH(debug);
-+      PATCH_OPTION(download_regex);
-+      PATCH_OPTION(trigger_regex);
-+#endif
-+      PATCH_OPTION(trigger_timeout);
-+      PATCH_OPTION(deny_url);
-+      PATCH_OPTION(mc_namespace);
-+      PATCH_OPTION(debug);
- #if defined(HAVE_MEMCACHE_H)
--      PATCH(mc);
-+      PATCH_OPTION(mc);
- #endif
--      
-+
-       /* skip the first, the global context */
-       for (i = 1; i < srv->config_context->used; i++) {
-               data_config *dc = (data_config *)srv->config_context->data[i];
-               s = p->config_storage[i];
--              
-+
-               /* condition didn't match */
-               if (!config_check_cond(srv, con, dc)) continue;
--              
-+
-               /* merge config */
-               for (j = 0; j < dc->value->used; j++) {
-                       data_unset *du = dc->value->data[j];
-                       if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.download-url"))) {
- #if defined(HAVE_PCRE_H)
--                              PATCH(download_regex);
-+                              PATCH_OPTION(download_regex);
- #endif
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.trigger-url"))) {
- # if defined(HAVE_PCRE_H)
--                              PATCH(trigger_regex);
-+                              PATCH_OPTION(trigger_regex);
- # endif
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.gdbm-filename"))) {
- #if defined(HAVE_GDBM_H)
--                              PATCH(db);
-+                              PATCH_OPTION(db);
- #endif
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.trigger-timeout"))) {
--                              PATCH(trigger_timeout);
-+                              PATCH_OPTION(trigger_timeout);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.debug"))) {
--                              PATCH(debug);
-+                              PATCH_OPTION(debug);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.deny-url"))) {
--                              PATCH(deny_url);
-+                              PATCH_OPTION(deny_url);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.memcache-namespace"))) {
--                              PATCH(mc_namespace);
-+                              PATCH_OPTION(mc_namespace);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.memcache-hosts"))) {
- #if defined(HAVE_MEMCACHE_H)
--                              PATCH(mc);
-+                              PATCH_OPTION(mc);
- #endif
-                       }
-               }
-       }
--      
-+
-       return 0;
- }
--#undef PATCH
- URIHANDLER_FUNC(mod_trigger_b4_dl_uri_handler) {
-       plugin_data *p = p_d;
-@@ -315,20 +312,20 @@
-       int n;
- # define N 10
-       int ovec[N * 3];
--      
-+
-       if (con->uri.path->used == 0) return HANDLER_GO_ON;
--      
-+
-       mod_trigger_b4_dl_patch_connection(srv, con, p);
--      
-+
-       if (!p->conf.trigger_regex || !p->conf.download_regex) return HANDLER_GO_ON;
--      
-+
- # if !defined(HAVE_GDBM_H) && !defined(HAVE_MEMCACHE_H)
-       return HANDLER_GO_ON;
- # elif defined(HAVE_GDBM_H) && defined(HAVE_MEMCACHE_H)
-       if (!p->conf.db && !p->conf.mc) return HANDLER_GO_ON;
-       if (p->conf.db && p->conf.mc) {
-               /* can't decide which one */
--              
-+
-               return HANDLER_GO_ON;
-       }
- # elif defined(HAVE_GDBM_H)
-@@ -336,12 +333,12 @@
- # else
-       if (!p->conf.mc) return HANDLER_GO_ON;
- # endif
--      
-+
-       if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "X-Forwarded-For"))) {
-               /* X-Forwarded-For contains the ip behind the proxy */
--              
-+
-               remote_ip = ds->value->ptr;
--              
-+
-               /* memcache can't handle spaces */
-       } else {
-               remote_ip = inet_ntop_cache_get_ip(srv, &(con->dst_addr));
-@@ -350,13 +347,13 @@
-       if (p->conf.debug) {
-               log_error_write(srv, __FILE__, __LINE__, "ss", "(debug) remote-ip:", remote_ip);
-       }
--              
-+
-       /* check if URL is a trigger -> insert IP into DB */
-       if ((n = pcre_exec(p->conf.trigger_regex, NULL, con->uri.path->ptr, con->uri.path->used - 1, 0, 0, ovec, 3 * N)) < 0) {
-               if (n != PCRE_ERROR_NOMATCH) {
-                       log_error_write(srv, __FILE__, __LINE__, "sd",
-                                       "execution error while matching:", n);
--                      
-+
-                       return HANDLER_ERROR;
-               }
-       } else {
-@@ -364,34 +361,34 @@
-               if (p->conf.db) {
-                       /* the trigger matched */
-                       datum key, val;
--                      
-+
-                       key.dptr = (char *)remote_ip;
-                       key.dsize = strlen(remote_ip);
--                      
-+
-                       val.dptr = (char *)&(srv->cur_ts);
-                       val.dsize = sizeof(srv->cur_ts);
--                      
-+
-                       if (0 != gdbm_store(p->conf.db, key, val, GDBM_REPLACE)) {
-                               log_error_write(srv, __FILE__, __LINE__, "s",
-                                               "insert failed");
-                       }
-               }
- # endif
--# if defined(HAVE_MEMCACHE_H)         
-+# if defined(HAVE_MEMCACHE_H)
-               if (p->conf.mc) {
-                       size_t i;
-                       buffer_copy_string_buffer(p->tmp_buf, p->conf.mc_namespace);
-                       buffer_append_string(p->tmp_buf, remote_ip);
--                      
-+
-                       for (i = 0; i < p->tmp_buf->used - 1; i++) {
-                               if (p->tmp_buf->ptr[i] == ' ') p->tmp_buf->ptr[i] = '-';
-                       }
--                      
-+
-                       if (p->conf.debug) {
-                               log_error_write(srv, __FILE__, __LINE__, "sb", "(debug) triggered IP:", p->tmp_buf);
-                       }
--                      if (0 != mc_set(p->conf.mc, 
-+                      if (0 != mc_set(p->conf.mc,
-                                       CONST_BUF_LEN(p->tmp_buf),
-                                       (char *)&(srv->cur_ts), sizeof(srv->cur_ts),
-                                       p->conf.trigger_timeout, 0)) {
-@@ -401,7 +398,7 @@
-               }
- # endif
-       }
--              
-+
-       /* check if URL is a download -> check IP in DB, update timestamp */
-       if ((n = pcre_exec(p->conf.download_regex, NULL, con->uri.path->ptr, con->uri.path->used - 1, 0, 0, ovec, 3 * N)) < 0) {
-               if (n != PCRE_ERROR_NOMATCH) {
-@@ -411,93 +408,93 @@
-               }
-       } else {
-               /* the download uri matched */
--# if defined(HAVE_GDBM_H)             
-+# if defined(HAVE_GDBM_H)
-               if (p->conf.db) {
-                       datum key, val;
-                       time_t last_hit;
--              
-+
-                       key.dptr = (char *)remote_ip;
-                       key.dsize = strlen(remote_ip);
--                      
-+
-                       val = gdbm_fetch(p->conf.db, key);
--              
-+
-                       if (val.dptr == NULL) {
-                               /* not found, redirect */
--                              
-+
-                               response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(p->conf.deny_url));
--                              
-+
-                               con->http_status = 307;
--                              
-+
-                               return HANDLER_FINISHED;
-                       }
--                      
-+
-                       last_hit = *(time_t *)(val.dptr);
--                      
-+
-                       free(val.dptr);
--                      
-+
-                       if (srv->cur_ts - last_hit > p->conf.trigger_timeout) {
-                               /* found, but timeout, redirect */
--                              
-+
-                               response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(p->conf.deny_url));
-                               con->http_status = 307;
--                              
-+
-                               if (p->conf.db) {
-                                       if (0 != gdbm_delete(p->conf.db, key)) {
-                                               log_error_write(srv, __FILE__, __LINE__, "s",
-                                                               "delete failed");
-                                       }
-                               }
--                              
-+
-                               return HANDLER_FINISHED;
-                       }
--                      
-+
-                       val.dptr = (char *)&(srv->cur_ts);
-                       val.dsize = sizeof(srv->cur_ts);
--                      
-+
-                       if (0 != gdbm_store(p->conf.db, key, val, GDBM_REPLACE)) {
-                               log_error_write(srv, __FILE__, __LINE__, "s",
-                                               "insert failed");
-                       }
-               }
- # endif
--              
--# if defined(HAVE_MEMCACHE_H)         
-+
-+# if defined(HAVE_MEMCACHE_H)
-               if (p->conf.mc) {
-                       void *r;
-                       size_t i;
--                      
-+
-                       buffer_copy_string_buffer(p->tmp_buf, p->conf.mc_namespace);
-                       buffer_append_string(p->tmp_buf, remote_ip);
--                      
-+
-                       for (i = 0; i < p->tmp_buf->used - 1; i++) {
-                               if (p->tmp_buf->ptr[i] == ' ') p->tmp_buf->ptr[i] = '-';
-                       }
--                      
-+
-                       if (p->conf.debug) {
-                               log_error_write(srv, __FILE__, __LINE__, "sb", "(debug) checking IP:", p->tmp_buf);
-                       }
-                       /**
--                       * 
-+                       *
-                        * memcached is do expiration for us, as long as we can fetch it every thing is ok
--                       * and the timestamp is updated 
--                       * 
-+                       * and the timestamp is updated
-+                       *
-                        */
--                      if (NULL == (r = mc_aget(p->conf.mc, 
-+                      if (NULL == (r = mc_aget(p->conf.mc,
-                                                CONST_BUF_LEN(p->tmp_buf)
-                                                ))) {
--                              
-+
-                               response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(p->conf.deny_url));
--                              
-+
-                               con->http_status = 307;
--                              
-+
-                               return HANDLER_FINISHED;
-                       }
--                      
-+
-                       free(r);
--                      
-+
-                       /* set a new timeout */
--                      if (0 != mc_set(p->conf.mc, 
-+                      if (0 != mc_set(p->conf.mc,
-                                       CONST_BUF_LEN(p->tmp_buf),
-                                       (char *)&(srv->cur_ts), sizeof(srv->cur_ts),
-                                       p->conf.trigger_timeout, 0)) {
-@@ -507,13 +504,13 @@
-               }
- # endif
-       }
--      
-+
- #else
-       UNUSED(srv);
-       UNUSED(con);
-       UNUSED(p_d);
- #endif
--      
-+
-       return HANDLER_GO_ON;
- }
-@@ -521,21 +518,21 @@
- TRIGGER_FUNC(mod_trigger_b4_dl_handle_trigger) {
-       plugin_data *p = p_d;
-       size_t i;
--      
-+
-       /* check DB each minute */
-       if (srv->cur_ts % 60 != 0) return HANDLER_GO_ON;
--      
-+
-       /* cleanup */
-       for (i = 0; i < srv->config_context->used; i++) {
-               plugin_config *s = p->config_storage[i];
-               datum key, val, okey;
--              
-+
-               if (!s->db) continue;
--              
-+
-               okey.dptr = NULL;
--              
--              /* according to the manual this loop + delete does delete all entries on its way 
--               * 
-+
-+              /* according to the manual this loop + delete does delete all entries on its way
-+               *
-                * we don't care as the next round will remove them. We don't have to perfect here.
-                */
-               for (key = gdbm_firstkey(s->db); key.dptr; key = gdbm_nextkey(s->db, okey)) {
-@@ -544,21 +541,21 @@
-                               free(okey.dptr);
-                               okey.dptr = NULL;
-                       }
--                      
-+
-                       val = gdbm_fetch(s->db, key);
--                      
-+
-                       last_hit = *(time_t *)(val.dptr);
--                      
-+
-                       free(val.dptr);
--                      
-+
-                       if (srv->cur_ts - last_hit > s->trigger_timeout) {
-                               gdbm_delete(s->db, key);
-                       }
--                      
-+
-                       okey = key;
-               }
-               if (okey.dptr) free(okey.dptr);
--              
-+
-               /* reorg once a day */
-               if ((srv->cur_ts % (60 * 60 * 24) != 0)) gdbm_reorganize(s->db);
-       }
-@@ -571,7 +568,7 @@
- int mod_trigger_b4_dl_plugin_init(plugin *p) {
-       p->version     = LIGHTTPD_VERSION_ID;
-       p->name        = buffer_init_string("trigger_b4_dl");
--      
-+
-       p->init        = mod_trigger_b4_dl_init;
-       p->handle_uri_clean  = mod_trigger_b4_dl_uri_handler;
-       p->set_defaults  = mod_trigger_b4_dl_set_defaults;
-@@ -579,8 +576,8 @@
-       p->handle_trigger  = mod_trigger_b4_dl_handle_trigger;
- #endif
-       p->cleanup     = mod_trigger_b4_dl_free;
--      
-+
-       p->data        = NULL;
--      
-+
-       return 0;
- }
---- ../lighttpd-1.4.11/src/mod_uploadprogress.c        1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/mod_uploadprogress.c    2006-09-07 00:57:05.000000000 +0300
-@@ -0,0 +1,420 @@
-+#include <ctype.h>
-+#include <stdlib.h>
-+#include <string.h>
-+
-+#include "base.h"
-+#include "log.h"
-+#include "buffer.h"
-+
-+#include "plugin.h"
-+
-+#include "response.h"
-+#include "stat_cache.h"
-+
-+/**
-+ * this is a uploadprogress for a lighttpd plugin
-+ *
-+ */
-+
-+typedef struct {
-+      buffer     *con_id;
-+      connection *con;
-+} connection_map_entry;
-+
-+typedef struct {
-+      connection_map_entry **ptr;
-+
-+      size_t used;
-+      size_t size;
-+} connection_map;
-+
-+/* plugin config for all request/connections */
-+
-+typedef struct {
-+      buffer *progress_url;
-+} plugin_config;
-+
-+typedef struct {
-+      PLUGIN_DATA;
-+
-+      connection_map *con_map;
-+
-+      plugin_config **config_storage;
-+
-+      plugin_config conf;
-+} plugin_data;
-+
-+/**
-+ *
-+ * connection maps
-+ *
-+ */
-+
-+/* init the plugin data */
-+connection_map *connection_map_init() {
-+      connection_map *cm;
-+
-+      cm = calloc(1, sizeof(*cm));
-+
-+      return cm;
-+}
-+
-+void connection_map_free(connection_map *cm) {
-+      size_t i;
-+      for (i = 0; i < cm->size; i++) {
-+              connection_map_entry *cme = cm->ptr[i];
-+
-+              if (!cme) break;
-+
-+              if (cme->con_id) {
-+                      buffer_free(cme->con_id);
-+              }
-+              free(cme);
-+      }
-+
-+      free(cm);
-+}
-+
-+int connection_map_insert(connection_map *cm, connection *con, buffer *con_id) {
-+      connection_map_entry *cme;
-+      size_t i;
-+
-+      if (cm->size == 0) {
-+              cm->size = 16;
-+              cm->ptr = malloc(cm->size * sizeof(*(cm->ptr)));
-+              for (i = 0; i < cm->size; i++) {
-+                      cm->ptr[i] = NULL;
-+              }
-+      } else if (cm->used == cm->size) {
-+              cm->size += 16;
-+              cm->ptr = realloc(cm->ptr, cm->size * sizeof(*(cm->ptr)));
-+              for (i = cm->used; i < cm->size; i++) {
-+                      cm->ptr[i] = NULL;
-+              }
-+      }
-+
-+      if (cm->ptr[cm->used]) {
-+              /* is already alloced, just reuse it */
-+              cme = cm->ptr[cm->used];
-+      } else {
-+              cme = malloc(sizeof(*cme));
-+      }
-+      cme->con_id = buffer_init();
-+      buffer_copy_string_buffer(cme->con_id, con_id);
-+      cme->con = con;
-+
-+      cm->ptr[cm->used++] = cme;
-+
-+      return 0;
-+}
-+
-+connection *connection_map_get_connection(connection_map *cm, buffer *con_id) {
-+      size_t i;
-+
-+      for (i = 0; i < cm->used; i++) {
-+              connection_map_entry *cme = cm->ptr[i];
-+
-+              if (buffer_is_equal(cme->con_id, con_id)) {
-+                      /* found connection */
-+
-+                      return cme->con;
-+              }
-+      }
-+      return NULL;
-+}
-+
-+int connection_map_remove_connection(connection_map *cm, connection *con) {
-+      size_t i;
-+
-+      for (i = 0; i < cm->used; i++) {
-+              connection_map_entry *cme = cm->ptr[i];
-+
-+              if (cme->con == con) {
-+                      /* found connection */
-+
-+                      buffer_reset(cme->con_id);
-+                      cme->con = NULL;
-+
-+                      cm->used--;
-+
-+                      /* swap positions with the last entry */
-+                      if (cm->used) {
-+                              cm->ptr[i] = cm->ptr[cm->used];
-+                              cm->ptr[cm->used] = cme;
-+                      }
-+
-+                      return 1;
-+              }
-+      }
-+
-+      return 0;
-+}
-+
-+/* init the plugin data */
-+INIT_FUNC(mod_uploadprogress_init) {
-+      plugin_data *p;
-+
-+      p = calloc(1, sizeof(*p));
-+
-+      p->con_map = connection_map_init();
-+
-+      return p;
-+}
-+
-+/* detroy the plugin data */
-+FREE_FUNC(mod_uploadprogress_free) {
-+      plugin_data *p = p_d;
-+
-+      UNUSED(srv);
-+
-+      if (!p) return HANDLER_GO_ON;
-+
-+      if (p->config_storage) {
-+              size_t i;
-+              for (i = 0; i < srv->config_context->used; i++) {
-+                      plugin_config *s = p->config_storage[i];
-+
-+                      buffer_free(s->progress_url);
-+
-+                      free(s);
-+              }
-+              free(p->config_storage);
-+      }
-+
-+      connection_map_free(p->con_map);
-+
-+      free(p);
-+
-+      return HANDLER_GO_ON;
-+}
-+
-+/* handle plugin config and check values */
-+
-+SETDEFAULTS_FUNC(mod_uploadprogress_set_defaults) {
-+      plugin_data *p = p_d;
-+      size_t i = 0;
-+
-+      config_values_t cv[] = {
-+              { "upload-progress.progress-url", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
-+              { NULL,                         NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
-+      };
-+
-+      if (!p) return HANDLER_ERROR;
-+
-+      p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
-+
-+      for (i = 0; i < srv->config_context->used; i++) {
-+              plugin_config *s;
-+
-+              s = calloc(1, sizeof(plugin_config));
-+              s->progress_url    = buffer_init();
-+
-+              cv[0].destination = s->progress_url;
-+
-+              p->config_storage[i] = s;
-+
-+              if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
-+                      return HANDLER_ERROR;
-+              }
-+      }
-+
-+      return HANDLER_GO_ON;
-+}
-+
-+static int mod_uploadprogress_patch_connection(server *srv, connection *con, plugin_data *p) {
-+      size_t i, j;
-+      plugin_config *s = p->config_storage[0];
-+
-+      PATCH_OPTION(progress_url);
-+
-+      /* skip the first, the global context */
-+      for (i = 1; i < srv->config_context->used; i++) {
-+              data_config *dc = (data_config *)srv->config_context->data[i];
-+              s = p->config_storage[i];
-+
-+              /* condition didn't match */
-+              if (!config_check_cond(srv, con, dc)) continue;
-+
-+              /* merge config */
-+              for (j = 0; j < dc->value->used; j++) {
-+                      data_unset *du = dc->value->data[j];
-+
-+                      if (buffer_is_equal_string(du->key, CONST_STR_LEN("upload-progress.progress-url"))) {
-+                              PATCH_OPTION(progress_url);
-+                      }
-+              }
-+      }
-+
-+      return 0;
-+}
-+
-+/**
-+ *
-+ * the idea:
-+ *
-+ * for the first request we check if it is a post-request
-+ *
-+ * if no, move out, don't care about them
-+ *
-+ * if yes, take the connection structure and register it locally
-+ * in the progress-struct together with an session-id (md5 ... )
-+ *
-+ * if the connections closes, cleanup the entry in the progress-struct
-+ *
-+ * a second request can now get the info about the size of the upload,
-+ * the received bytes
-+ *
-+ */
-+
-+URIHANDLER_FUNC(mod_uploadprogress_uri_handler) {
-+      plugin_data *p = p_d;
-+      size_t i;
-+      data_string *ds;
-+      buffer *b, *tracking_id;
-+      connection *post_con = NULL;
-+
-+      UNUSED(srv);
-+
-+      if (con->uri.path->used == 0) return HANDLER_GO_ON;
-+
-+      mod_uploadprogress_patch_connection(srv, con, p);
-+
-+      /* check if this is a POST request */
-+      switch(con->request.http_method) {
-+      case HTTP_METHOD_POST:
-+              /* the request has to contain a 32byte ID */
-+
-+              if (NULL == (ds = (data_string *)array_get_element(con->request.headers, "X-Progress-ID"))) {
-+                      if (!buffer_is_empty(con->uri.query)) {
-+                              /* perhaps the POST request is using the querystring to pass the X-Progress-ID */
-+                              b = con->uri.query;
-+                      } else {
-+                              return HANDLER_GO_ON;
-+                      }
-+              } else {
-+                      b = ds->value;
-+              }
-+
-+              if (b->used != 32 + 1) {
-+                      ERROR("the Progress-ID has to be 32 characters long, got %d characters", b->used - 1);
-+
-+                      return HANDLER_GO_ON;
-+              }
-+
-+              for (i = 0; i < b->used - 1; i++) {
-+                      char c = b->ptr[i];
-+
-+                      if (!light_isxdigit(c)) {
-+                              ERROR("only hex-digits are allowed (0-9 + a-f): (ascii: %d)", c);
-+
-+                              return HANDLER_GO_ON;
-+                      }
-+              }
-+
-+              connection_map_insert(p->con_map, con, b);
-+
-+              return HANDLER_GO_ON;
-+      case HTTP_METHOD_GET:
-+              if (!buffer_is_equal(con->uri.path, p->conf.progress_url)) {
-+                      return HANDLER_GO_ON;
-+              }
-+
-+              if (NULL == (ds = (data_string *)array_get_element(con->request.headers, "X-Progress-ID"))) {
-+                      if (!buffer_is_empty(con->uri.query)) {
-+                              /* perhaps the GET request is using the querystring to pass the X-Progress-ID */
-+                              tracking_id = con->uri.query;
-+                      } else {
-+                              return HANDLER_GO_ON;
-+                      }
-+              } else {
-+                      tracking_id = ds->value;
-+              }
-+
-+              if (tracking_id->used != 32 + 1) {
-+                      ERROR("the Progress-ID has to be 32 characters long, got %d characters", tracking_id->used - 1);
-+
-+                      return HANDLER_GO_ON;
-+              }
-+
-+              for (i = 0; i < tracking_id->used - 1; i++) {
-+                      char c = tracking_id->ptr[i];
-+
-+                      if (!light_isxdigit(c)) {
-+                              ERROR("only hex-digits are allowed (0-9 + a-f): (ascii: %d)", c);
-+
-+                              return HANDLER_GO_ON;
-+                      }
-+              }
-+
-+              buffer_reset(con->physical.path);
-+
-+              con->file_started = 1;
-+              con->http_status = 200;
-+              con->send->is_closed = 1;
-+
-+              /* send JSON content */
-+
-+              response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/javascript"));
-+
-+              /* just an attempt the force the IE/proxies to NOT cache the request */
-+              response_header_overwrite(srv, con, CONST_STR_LEN("Pragma"), CONST_STR_LEN("no-cache"));
-+              response_header_overwrite(srv, con, CONST_STR_LEN("Expires"), CONST_STR_LEN("Thu, 19 Nov 1981 08:52:00 GMT"));
-+              response_header_overwrite(srv, con, CONST_STR_LEN("Cache-Control"), 
-+                              CONST_STR_LEN("no-store, no-cache, must-revalidate, post-check=0, pre-check=0"));
-+
-+              b = chunkqueue_get_append_buffer(con->send);
-+
-+              /* get the connection */
-+              if (NULL == (post_con = connection_map_get_connection(p->con_map, tracking_id))) {
-+                      BUFFER_APPEND_STRING_CONST(b, "new Object({ 'status' : 'starting' })\r\n");
-+
-+                      return HANDLER_FINISHED;
-+              }
-+
-+              /* prepare XML */
-+              BUFFER_COPY_STRING_CONST(b, "new Object({ 'state' : ");
-+              buffer_append_string(b, post_con->recv->is_closed ? "'done'" : "'uploading'");
-+              BUFFER_APPEND_STRING_CONST(b, ", 'size' : ");
-+              buffer_append_off_t(b, post_con->request.content_length == -1 ? 0 : post_con->request.content_length);
-+              BUFFER_APPEND_STRING_CONST(b, ", 'received' : ");
-+              buffer_append_off_t(b, post_con->recv->bytes_in);
-+              BUFFER_APPEND_STRING_CONST(b, "})\r\n");
-+
-+              return HANDLER_FINISHED;
-+      default:
-+              break;
-+      }
-+
-+      return HANDLER_GO_ON;
-+}
-+
-+REQUESTDONE_FUNC(mod_uploadprogress_request_done) {
-+      plugin_data *p = p_d;
-+
-+      UNUSED(srv);
-+
-+      if (con->uri.path->used == 0) return HANDLER_GO_ON;
-+
-+      if (connection_map_remove_connection(p->con_map, con)) {
-+              /* removed */
-+      }
-+
-+      return HANDLER_GO_ON;
-+}
-+
-+/* this function is called at dlopen() time and inits the callbacks */
-+
-+int mod_uploadprogress_plugin_init(plugin *p) {
-+      p->version     = LIGHTTPD_VERSION_ID;
-+      p->name        = buffer_init_string("uploadprogress");
-+
-+      p->init        = mod_uploadprogress_init;
-+      p->handle_uri_clean = mod_uploadprogress_uri_handler;
-+      p->handle_response_done  = mod_uploadprogress_request_done;
-+      p->set_defaults  = mod_uploadprogress_set_defaults;
-+      p->cleanup     = mod_uploadprogress_free;
-+
-+      p->data        = NULL;
-+
-+      return 0;
-+}
---- ../lighttpd-1.4.11/src/mod_userdir.c       2005-10-28 16:48:28.000000000 +0300
-+++ lighttpd-1.5.0/src/mod_userdir.c   2006-07-16 00:26:04.000000000 +0300
-@@ -10,6 +10,7 @@
- #include "response.h"
- #include "plugin.h"
-+#include "sys-files.h"
- #ifdef HAVE_PWD_H
- #include <pwd.h>
-@@ -25,54 +26,54 @@
- typedef struct {
-       PLUGIN_DATA;
--      
-+
-       buffer *username;
-       buffer *temp_path;
--      
-+
-       plugin_config **config_storage;
--      
--      plugin_config conf; 
-+
-+      plugin_config conf;
- } plugin_data;
- /* init the plugin data */
- INIT_FUNC(mod_userdir_init) {
-       plugin_data *p;
--      
-+
-       p = calloc(1, sizeof(*p));
--      
-+
-       p->username = buffer_init();
-       p->temp_path = buffer_init();
--      
-+
-       return p;
- }
- /* detroy the plugin data */
- FREE_FUNC(mod_userdir_free) {
-       plugin_data *p = p_d;
--      
-+
-       if (!p) return HANDLER_GO_ON;
--      
-+
-       if (p->config_storage) {
-               size_t i;
--              
-+
-               for (i = 0; i < srv->config_context->used; i++) {
-                       plugin_config *s = p->config_storage[i];
--                      
-+
-                       array_free(s->include_user);
-                       array_free(s->exclude_user);
-                       buffer_free(s->path);
-                       buffer_free(s->basepath);
--                      
-+
-                       free(s);
-               }
-               free(p->config_storage);
-       }
--      
-+
-       buffer_free(p->username);
-       buffer_free(p->temp_path);
--      
-+
-       free(p);
--      
-+
-       return HANDLER_GO_ON;
- }
-@@ -81,81 +82,78 @@
- SETDEFAULTS_FUNC(mod_userdir_set_defaults) {
-       plugin_data *p = p_d;
-       size_t i;
--      
--      config_values_t cv[] = { 
-+
-+      config_values_t cv[] = {
-               { "userdir.path",               NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
-               { "userdir.exclude-user",       NULL, T_CONFIG_ARRAY,  T_CONFIG_SCOPE_CONNECTION },       /* 1 */
-               { "userdir.include-user",       NULL, T_CONFIG_ARRAY,  T_CONFIG_SCOPE_CONNECTION },       /* 2 */
-               { "userdir.basepath",           NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 3 */
-               { NULL,                         NULL, T_CONFIG_UNSET,  T_CONFIG_SCOPE_UNSET }
-       };
--      
-+
-       if (!p) return HANDLER_ERROR;
--      
-+
-       p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
--      
-+
-       for (i = 0; i < srv->config_context->used; i++) {
-               plugin_config *s;
--              
-+
-               s = calloc(1, sizeof(plugin_config));
-               s->exclude_user = array_init();
-               s->include_user = array_init();
-               s->path = buffer_init();
-               s->basepath = buffer_init();
--      
-+
-               cv[0].destination = s->path;
-               cv[1].destination = s->exclude_user;
-               cv[2].destination = s->include_user;
-               cv[3].destination = s->basepath;
--              
-+
-               p->config_storage[i] = s;
--      
-+
-               if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
-                       return HANDLER_ERROR;
-               }
-       }
--      
-+
-       return HANDLER_GO_ON;
- }
--#define PATCH(x) \
--      p->conf.x = s->x;
- static int mod_userdir_patch_connection(server *srv, connection *con, plugin_data *p) {
-       size_t i, j;
-       plugin_config *s = p->config_storage[0];
--      
--      PATCH(path);
--      PATCH(exclude_user);
--      PATCH(include_user);
--      PATCH(basepath);
--      
-+
-+      PATCH_OPTION(path);
-+      PATCH_OPTION(exclude_user);
-+      PATCH_OPTION(include_user);
-+      PATCH_OPTION(basepath);
-+
-       /* skip the first, the global context */
-       for (i = 1; i < srv->config_context->used; i++) {
-               data_config *dc = (data_config *)srv->config_context->data[i];
-               s = p->config_storage[i];
--              
-+
-               /* condition didn't match */
-               if (!config_check_cond(srv, con, dc)) continue;
--              
-+
-               /* merge config */
-               for (j = 0; j < dc->value->used; j++) {
-                       data_unset *du = dc->value->data[j];
--                      
-+
-                       if (buffer_is_equal_string(du->key, CONST_STR_LEN("userdir.path"))) {
--                              PATCH(path);
-+                              PATCH_OPTION(path);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("userdir.exclude-user"))) {
--                              PATCH(exclude_user);
-+                              PATCH_OPTION(exclude_user);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("userdir.include-user"))) {
--                              PATCH(include_user);
-+                              PATCH_OPTION(include_user);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("userdir.basepath"))) {
--                              PATCH(basepath);
-+                              PATCH_OPTION(basepath);
-                       }
-               }
-       }
--      
-+
-       return 0;
- }
--#undef PATCH
- URIHANDLER_FUNC(mod_userdir_docroot_handler) {
-       plugin_data *p = p_d;
-@@ -169,18 +167,18 @@
-       if (con->uri.path->used == 0) return HANDLER_GO_ON;
-       mod_userdir_patch_connection(srv, con, p);
--      
-+
-       uri_len = con->uri.path->used - 1;
--      
-+
-       /* /~user/foo.html -> /home/user/public_html/foo.html */
--      
-+
-       if (con->uri.path->ptr[0] != '/' ||
-           con->uri.path->ptr[1] != '~') return HANDLER_GO_ON;
--      
-+
-       if (NULL == (rel_url = strchr(con->uri.path->ptr + 2, '/'))) {
-               /* / is missing -> redirect to .../ as we are a user - DIRECTORY ! :) */
-               http_response_redirect_to_directory(srv, con);
--              
-+
-               return HANDLER_FINISHED;
-       }
-@@ -188,10 +186,10 @@
-       if (0 == rel_url - (con->uri.path->ptr + 2)) {
-               return HANDLER_GO_ON;
-       }
--      
-+
-       buffer_copy_string_len(p->username, con->uri.path->ptr + 2, rel_url - (con->uri.path->ptr + 2));
--      
--      if (buffer_is_empty(p->conf.basepath) 
-+
-+      if (buffer_is_empty(p->conf.basepath)
- #ifdef HAVE_PWD_H
-           && NULL == (pwd = getpwnam(p->username->ptr))
- #endif
-@@ -200,31 +198,31 @@
-               return HANDLER_GO_ON;
-       }
--      
-+
-       for (k = 0; k < p->conf.exclude_user->used; k++) {
-               data_string *ds = (data_string *)p->conf.exclude_user->data[k];
--              
-+
-               if (buffer_is_equal(ds->value, p->username)) {
-                       /* user in exclude list */
-                       return HANDLER_GO_ON;
-               }
-       }
--      
-+
-       if (p->conf.include_user->used) {
-               int found_user = 0;
-               for (k = 0; k < p->conf.include_user->used; k++) {
-                       data_string *ds = (data_string *)p->conf.include_user->data[k];
--                      
-+
-                       if (buffer_is_equal(ds->value, p->username)) {
-                               /* user in include list */
-                               found_user = 1;
-                               break;
-                       }
-               }
--              
-+
-               if (!found_user) return HANDLER_GO_ON;
-       }
--      
-+
-       /* we build the physical path */
-       if (buffer_is_empty(p->conf.basepath)) {
-@@ -252,23 +250,23 @@
-               }
-               buffer_copy_string_buffer(p->temp_path, p->conf.basepath);
--              BUFFER_APPEND_SLASH(p->temp_path);
-+              PATHNAME_APPEND_SLASH(p->temp_path);
-               buffer_append_string_buffer(p->temp_path, p->username);
-       }
--      BUFFER_APPEND_SLASH(p->temp_path);
--      buffer_append_string_buffer(p->temp_path, p->conf.path); 
-+      PATHNAME_APPEND_SLASH(p->temp_path);
-+      buffer_append_string_buffer(p->temp_path, p->conf.path);
-       if (buffer_is_empty(p->conf.basepath)) {
-               struct stat st;
-               int ret;
--              
-+
-               ret = stat(p->temp_path->ptr, &st);
-               if (ret < 0 || S_ISDIR(st.st_mode) != 1) {
-                       return HANDLER_GO_ON;
--              } 
-+              }
-       }
--      BUFFER_APPEND_SLASH(p->temp_path);
-+      PATHNAME_APPEND_SLASH(p->temp_path);
-       buffer_append_string(p->temp_path, rel_url + 1); /* skip the / */
-       buffer_copy_string_buffer(con->physical.path, p->temp_path);
-@@ -282,13 +280,13 @@
- int mod_userdir_plugin_init(plugin *p) {
-       p->version     = LIGHTTPD_VERSION_ID;
-       p->name        = buffer_init_string("userdir");
--      
-+
-       p->init           = mod_userdir_init;
-       p->handle_physical = mod_userdir_docroot_handler;
-       p->set_defaults   = mod_userdir_set_defaults;
-       p->cleanup        = mod_userdir_free;
--      
-+
-       p->data        = NULL;
--      
-+
-       return 0;
- }
---- ../lighttpd-1.4.11/src/mod_usertrack.c     2006-01-31 15:01:20.000000000 +0200
-+++ lighttpd-1.5.0/src/mod_usertrack.c 2006-07-16 00:26:04.000000000 +0300
-@@ -24,44 +24,44 @@
- typedef struct {
-       PLUGIN_DATA;
--      
-+
-       plugin_config **config_storage;
--      
--      plugin_config conf; 
-+
-+      plugin_config conf;
- } plugin_data;
- /* init the plugin data */
- INIT_FUNC(mod_usertrack_init) {
-       plugin_data *p;
--      
-+
-       p = calloc(1, sizeof(*p));
--      
-+
-       return p;
- }
- /* detroy the plugin data */
- FREE_FUNC(mod_usertrack_free) {
-       plugin_data *p = p_d;
--      
-+
-       UNUSED(srv);
--      
-+
-       if (!p) return HANDLER_GO_ON;
--      
-+
-       if (p->config_storage) {
-               size_t i;
-               for (i = 0; i < srv->config_context->used; i++) {
-                       plugin_config *s = p->config_storage[i];
--                      
-+
-                       buffer_free(s->cookie_name);
-                       buffer_free(s->cookie_domain);
--                      
-+
-                       free(s);
-               }
-               free(p->config_storage);
-       }
--      
-+
-       free(p);
--      
-+
-       return HANDLER_GO_ON;
- }
-@@ -70,38 +70,38 @@
- SETDEFAULTS_FUNC(mod_usertrack_set_defaults) {
-       plugin_data *p = p_d;
-       size_t i = 0;
--      
--      config_values_t cv[] = { 
-+
-+      config_values_t cv[] = {
-               { "usertrack.cookie-name",       NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
-               { "usertrack.cookie-max-age",    NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },        /* 1 */
-               { "usertrack.cookie-domain",     NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 2 */
--              
--              { "usertrack.cookiename",        NULL, T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_CONNECTION },   
-+
-+              { "usertrack.cookiename",        NULL, T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_CONNECTION },
-               { NULL,                          NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
-       };
--      
-+
-       if (!p) return HANDLER_ERROR;
--      
-+
-       p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
--      
-+
-       for (i = 0; i < srv->config_context->used; i++) {
-               plugin_config *s;
--              
-+
-               s = calloc(1, sizeof(plugin_config));
-               s->cookie_name    = buffer_init();
-               s->cookie_domain  = buffer_init();
-               s->cookie_max_age = 0;
--              
-+
-               cv[0].destination = s->cookie_name;
-               cv[1].destination = &(s->cookie_max_age);
-               cv[2].destination = s->cookie_domain;
--              
-+
-               p->config_storage[i] = s;
--      
-+
-               if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
-                       return HANDLER_ERROR;
-               }
--      
-+
-               if (buffer_is_empty(s->cookie_name)) {
-                       buffer_copy_string(s->cookie_name, "TRACKID");
-               } else {
-@@ -109,68 +109,65 @@
-                       for (j = 0; j < s->cookie_name->used - 1; j++) {
-                               char c = s->cookie_name->ptr[j] | 32;
-                               if (c < 'a' || c > 'z') {
--                                      log_error_write(srv, __FILE__, __LINE__, "sb", 
--                                                      "invalid character in usertrack.cookie-name:", 
-+                                      log_error_write(srv, __FILE__, __LINE__, "sb",
-+                                                      "invalid character in usertrack.cookie-name:",
-                                                       s->cookie_name);
--                                      
-+
-                                       return HANDLER_ERROR;
-                               }
-                       }
-               }
--              
-+
-               if (!buffer_is_empty(s->cookie_domain)) {
-                       size_t j;
-                       for (j = 0; j < s->cookie_domain->used - 1; j++) {
-                               char c = s->cookie_domain->ptr[j];
-                               if (c <= 32 || c >= 127 || c == '"' || c == '\\') {
--                                      log_error_write(srv, __FILE__, __LINE__, "sb", 
--                                                      "invalid character in usertrack.cookie-domain:", 
-+                                      log_error_write(srv, __FILE__, __LINE__, "sb",
-+                                                      "invalid character in usertrack.cookie-domain:",
-                                                       s->cookie_domain);
--                                      
-+
-                                       return HANDLER_ERROR;
-                               }
-                       }
-               }
-       }
--              
-+
-       return HANDLER_GO_ON;
- }
--#define PATCH(x) \
--      p->conf.x = s->x;
- static int mod_usertrack_patch_connection(server *srv, connection *con, plugin_data *p) {
-       size_t i, j;
-       plugin_config *s = p->config_storage[0];
--      
--      PATCH(cookie_name);
--      PATCH(cookie_domain);
--      PATCH(cookie_max_age);
--      
-+
-+      PATCH_OPTION(cookie_name);
-+      PATCH_OPTION(cookie_domain);
-+      PATCH_OPTION(cookie_max_age);
-+
-       /* skip the first, the global context */
-       for (i = 1; i < srv->config_context->used; i++) {
-               data_config *dc = (data_config *)srv->config_context->data[i];
-               s = p->config_storage[i];
--              
-+
-               /* condition didn't match */
-               if (!config_check_cond(srv, con, dc)) continue;
--              
-+
-               /* merge config */
-               for (j = 0; j < dc->value->used; j++) {
-                       data_unset *du = dc->value->data[j];
--                      
-+
-                       if (buffer_is_equal_string(du->key, CONST_STR_LEN("usertrack.cookie-name"))) {
--                              PATCH(cookie_name);
-+                              PATCH_OPTION(cookie_name);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("usertrack.cookie-max-age"))) {
--                              PATCH(cookie_max_age);
-+                              PATCH_OPTION(cookie_max_age);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("usertrack.cookie-domain"))) {
--                              PATCH(cookie_domain);
-+                              PATCH_OPTION(cookie_domain);
-                       }
-               }
-       }
--      
-+
-       return 0;
- }
--#undef PATCH
- URIHANDLER_FUNC(mod_usertrack_uri_handler) {
-       plugin_data *p = p_d;
-@@ -178,38 +175,38 @@
-       unsigned char h[16];
-       MD5_CTX Md5Ctx;
-       char hh[32];
--      
-+
-       if (con->uri.path->used == 0) return HANDLER_GO_ON;
--      
-+
-       mod_usertrack_patch_connection(srv, con, p);
--      
-+
-       if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Cookie"))) {
-               char *g;
-               /* we have a cookie, does it contain a valid name ? */
--              
--              /* parse the cookie 
--               * 
-+
-+              /* parse the cookie
-+               *
-                * check for cookiename + (WS | '=')
--               * 
-+               *
-                */
--              
-+
-               if (NULL != (g = strstr(ds->value->ptr, p->conf.cookie_name->ptr))) {
-                       char *nc;
--                      
-+
-                       /* skip WS */
-                       for (nc = g + p->conf.cookie_name->used-1; *nc == ' ' || *nc == '\t'; nc++);
--                      
-+
-                       if (*nc == '=') {
-                               /* ok, found the key of our own cookie */
--                              
-+
-                               if (strlen(nc) > 32) {
-                                       /* i'm lazy */
-                                       return HANDLER_GO_ON;
-                               }
-                       }
-               }
--      } 
--      
-+      }
-+
-       /* set a cookie */
-       if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
-               ds = data_response_init();
-@@ -217,39 +214,39 @@
-       buffer_copy_string(ds->key, "Set-Cookie");
-       buffer_copy_string_buffer(ds->value, p->conf.cookie_name);
-       buffer_append_string(ds->value, "=");
--      
-+
-       /* taken from mod_auth.c */
--      
-+
-       /* generate shared-secret */
-       MD5_Init(&Md5Ctx);
-       MD5_Update(&Md5Ctx, (unsigned char *)con->uri.path->ptr, con->uri.path->used - 1);
-       MD5_Update(&Md5Ctx, (unsigned char *)"+", 1);
--      
-+
-       /* we assume sizeof(time_t) == 4 here, but if not it ain't a problem at all */
-       ltostr(hh, srv->cur_ts);
-       MD5_Update(&Md5Ctx, (unsigned char *)hh, strlen(hh));
-       ltostr(hh, rand());
-       MD5_Update(&Md5Ctx, (unsigned char *)hh, strlen(hh));
--      
-+
-       MD5_Final(h, &Md5Ctx);
--      
-+
-       buffer_append_string_encoded(ds->value, (char *)h, 16, ENCODING_HEX);
-       buffer_append_string(ds->value, "; Path=/");
-       buffer_append_string(ds->value, "; Version=1");
--      
-+
-       if (!buffer_is_empty(p->conf.cookie_domain)) {
-               buffer_append_string(ds->value, "; Domain=");
-               buffer_append_string_encoded(ds->value, CONST_BUF_LEN(p->conf.cookie_domain), ENCODING_REL_URI);
-       }
--      
-+
-       if (p->conf.cookie_max_age) {
-               buffer_append_string(ds->value, "; max-age=");
-               buffer_append_long(ds->value, p->conf.cookie_max_age);
-       }
--      
-+
-       array_insert_unique(con->response.headers, (data_unset *)ds);
--      
-+
-       return HANDLER_GO_ON;
- }
-@@ -258,13 +255,13 @@
- int mod_usertrack_plugin_init(plugin *p) {
-       p->version     = LIGHTTPD_VERSION_ID;
-       p->name        = buffer_init_string("usertrack");
--      
-+
-       p->init        = mod_usertrack_init;
-       p->handle_uri_clean  = mod_usertrack_uri_handler;
-       p->set_defaults  = mod_usertrack_set_defaults;
-       p->cleanup     = mod_usertrack_free;
--      
-+
-       p->data        = NULL;
--      
-+
-       return 0;
- }
---- ../lighttpd-1.4.11/src/mod_webdav.c        2006-03-03 01:28:58.000000000 +0200
-+++ lighttpd-1.5.0/src/mod_webdav.c    2006-09-07 00:57:05.000000000 +0300
-@@ -3,13 +3,10 @@
- #include <ctype.h>
- #include <stdlib.h>
- #include <string.h>
--#include <dirent.h>
- #include <errno.h>
--#include <unistd.h>
- #include <fcntl.h>
- #include <stdio.h>
- #include <assert.h>
--#include <sys/mman.h>
- #ifdef HAVE_CONFIG_H
- #include "config.h"
-@@ -23,6 +20,11 @@
- #include <sqlite3.h>
- #endif
-+#if defined(HAVE_LIBXML_H) && defined(HAVE_SQLITE3_H) && defined(HAVE_UUID_H)
-+#define USE_LOCKS
-+#include <uuid/uuid.h>
-+#endif
-+
- #include "base.h"
- #include "log.h"
- #include "buffer.h"
-@@ -33,13 +35,16 @@
- #include "stream.h"
- #include "stat_cache.h"
-+#include "sys-files.h"
-+#include "sys-mmap.h"
-+#include "sys-strings.h"
- /**
-  * this is a webdav for a lighttpd plugin
-  *
-- * at least a very basic one. 
-+ * at least a very basic one.
-  * - for now it is read-only and we only support PROPFIND
-- * 
-+ *
-  */
-@@ -58,64 +63,70 @@
-       sqlite3_stmt *stmt_delete_prop;
-       sqlite3_stmt *stmt_select_prop;
-       sqlite3_stmt *stmt_select_propnames;
--      
-+
-       sqlite3_stmt *stmt_delete_uri;
-       sqlite3_stmt *stmt_move_uri;
-       sqlite3_stmt *stmt_copy_uri;
-+
-+      sqlite3_stmt *stmt_remove_lock;
-+      sqlite3_stmt *stmt_create_lock;
-+      sqlite3_stmt *stmt_read_lock;
-+      sqlite3_stmt *stmt_read_lock_by_uri;
-+      sqlite3_stmt *stmt_refresh_lock;
- #endif
- } plugin_config;
- typedef struct {
-       PLUGIN_DATA;
--      
-+
-       buffer *tmp_buf;
-       request_uri uri;
-       physical physical;
-       plugin_config **config_storage;
--      
--      plugin_config conf; 
-+
-+      plugin_config conf;
- } plugin_data;
- /* init the plugin data */
- INIT_FUNC(mod_webdav_init) {
-       plugin_data *p;
--      
-+
-       p = calloc(1, sizeof(*p));
--      
-+
-       p->tmp_buf = buffer_init();
-       p->uri.scheme = buffer_init();
-       p->uri.path_raw = buffer_init();
-       p->uri.path = buffer_init();
-       p->uri.authority = buffer_init();
--      
-+
-       p->physical.path = buffer_init();
-       p->physical.rel_path = buffer_init();
-       p->physical.doc_root = buffer_init();
-       p->physical.basedir = buffer_init();
--      
-+
-       return p;
- }
- /* detroy the plugin data */
- FREE_FUNC(mod_webdav_free) {
-       plugin_data *p = p_d;
--      
-+
-       UNUSED(srv);
-       if (!p) return HANDLER_GO_ON;
--      
-+
-       if (p->config_storage) {
-               size_t i;
-               for (i = 0; i < srv->config_context->used; i++) {
-                       plugin_config *s = p->config_storage[i];
-                       if (!s) continue;
--      
-+
-                       buffer_free(s->sqlite_db_name);
- #ifdef USE_PROPPATCH
--                      if (s->sql) {   
-+                      if (s->sql) {
-                               sqlite3_finalize(s->stmt_delete_prop);
-                               sqlite3_finalize(s->stmt_delete_uri);
-                               sqlite3_finalize(s->stmt_copy_uri);
-@@ -123,9 +134,15 @@
-                               sqlite3_finalize(s->stmt_update_prop);
-                               sqlite3_finalize(s->stmt_select_prop);
-                               sqlite3_finalize(s->stmt_select_propnames);
-+
-+                              sqlite3_finalize(s->stmt_read_lock);
-+                              sqlite3_finalize(s->stmt_read_lock_by_uri);
-+                              sqlite3_finalize(s->stmt_create_lock);
-+                              sqlite3_finalize(s->stmt_remove_lock);
-+                              sqlite3_finalize(s->stmt_refresh_lock);
-                               sqlite3_close(s->sql);
-                       }
--#endif        
-+#endif
-                       free(s);
-               }
-               free(p->config_storage);
-@@ -135,16 +152,16 @@
-       buffer_free(p->uri.path_raw);
-       buffer_free(p->uri.path);
-       buffer_free(p->uri.authority);
--      
-+
-       buffer_free(p->physical.path);
-       buffer_free(p->physical.rel_path);
-       buffer_free(p->physical.doc_root);
-       buffer_free(p->physical.basedir);
--      
-+
-       buffer_free(p->tmp_buf);
--      
-+
-       free(p);
--      
-+
-       return HANDLER_GO_ON;
- }
-@@ -153,32 +170,32 @@
- SETDEFAULTS_FUNC(mod_webdav_set_defaults) {
-       plugin_data *p = p_d;
-       size_t i = 0;
--      
--      config_values_t cv[] = { 
-+
-+      config_values_t cv[] = {
-               { "webdav.activate",            NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
-               { "webdav.is-readonly",         NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },       /* 1 */
-               { "webdav.sqlite-db-name",      NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_CONNECTION },       /* 2 */
-               { "webdav.log-xml",             NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },       /* 3 */
-               { NULL,                         NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
-       };
--      
-+
-       if (!p) return HANDLER_ERROR;
--      
-+
-       p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
--      
-+
-       for (i = 0; i < srv->config_context->used; i++) {
-               plugin_config *s;
--              
-+
-               s = calloc(1, sizeof(plugin_config));
-               s->sqlite_db_name = buffer_init();
--              
-+
-               cv[0].destination = &(s->enabled);
-               cv[1].destination = &(s->is_readonly);
-               cv[2].destination = s->sqlite_db_name;
-               cv[3].destination = &(s->log_xml);
--              
-+
-               p->config_storage[i] = s;
--      
-+
-               if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
-                       return HANDLER_ERROR;
-               }
-@@ -193,8 +210,26 @@
-                               return HANDLER_ERROR;
-                       }
--                      if (SQLITE_OK != sqlite3_prepare(s->sql, 
--                              CONST_STR_LEN("SELECT value FROM properties WHERE resource = ? AND prop = ? AND ns = ?"), 
-+                      if (SQLITE_OK != sqlite3_exec(s->sql,
-+                                      "CREATE TABLE properties ("
-+                                      "  resource TEXT NOT NULL,"
-+                                      "  prop TEXT NOT NULL,"
-+                                      "  ns TEXT NOT NULL,"
-+                                      "  value TEXT NOT NULL,"
-+                                      "  PRIMARY KEY(resource, prop, ns))",
-+                                      NULL, NULL, &err)) {
-+
-+                              if (0 != strcmp(err, "table properties already exists")) {
-+                                      log_error_write(srv, __FILE__, __LINE__, "ss", "can't open transaction:", err);
-+                                      sqlite3_free(err);
-+
-+                                      return HANDLER_ERROR;
-+                              }
-+                              sqlite3_free(err);
-+                      }
-+
-+                      if (SQLITE_OK != sqlite3_prepare(s->sql,
-+                              CONST_STR_LEN("SELECT value FROM properties WHERE resource = ? AND prop = ? AND ns = ?"),
-                               &(s->stmt_select_prop), &next_stmt)) {
-                               /* prepare failed */
-@@ -202,8 +237,8 @@
-                               return HANDLER_ERROR;
-                       }
--                      if (SQLITE_OK != sqlite3_prepare(s->sql, 
--                              CONST_STR_LEN("SELECT ns, prop FROM properties WHERE resource = ?"), 
-+                      if (SQLITE_OK != sqlite3_prepare(s->sql,
-+                              CONST_STR_LEN("SELECT ns, prop FROM properties WHERE resource = ?"),
-                               &(s->stmt_select_propnames), &next_stmt)) {
-                               /* prepare failed */
-@@ -211,16 +246,67 @@
-                               return HANDLER_ERROR;
-                       }
--                      if (SQLITE_OK != sqlite3_exec(s->sql, 
--                                      "CREATE TABLE properties ("
-+
-+                      if (SQLITE_OK != sqlite3_prepare(s->sql,
-+                              CONST_STR_LEN("REPLACE INTO properties (resource, prop, ns, value) VALUES (?, ?, ?, ?)"),
-+                              &(s->stmt_update_prop), &next_stmt)) {
-+                              /* prepare failed */
-+
-+                              log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed:", sqlite3_errmsg(s->sql));
-+                              return HANDLER_ERROR;
-+                      }
-+
-+                      if (SQLITE_OK != sqlite3_prepare(s->sql,
-+                              CONST_STR_LEN("DELETE FROM properties WHERE resource = ? AND prop = ? AND ns = ?"),
-+                              &(s->stmt_delete_prop), &next_stmt)) {
-+                              /* prepare failed */
-+                              log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
-+
-+                              return HANDLER_ERROR;
-+                      }
-+
-+                      if (SQLITE_OK != sqlite3_prepare(s->sql,
-+                              CONST_STR_LEN("DELETE FROM properties WHERE resource = ?"),
-+                              &(s->stmt_delete_uri), &next_stmt)) {
-+                              /* prepare failed */
-+                              log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
-+
-+                              return HANDLER_ERROR;
-+                      }
-+
-+                      if (SQLITE_OK != sqlite3_prepare(s->sql,
-+                              CONST_STR_LEN("INSERT INTO properties SELECT ?, prop, ns, value FROM properties WHERE resource = ?"),
-+                              &(s->stmt_copy_uri), &next_stmt)) {
-+                              /* prepare failed */
-+                              log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
-+
-+                              return HANDLER_ERROR;
-+                      }
-+
-+                      if (SQLITE_OK != sqlite3_prepare(s->sql,
-+                              CONST_STR_LEN("UPDATE properties SET resource = ? WHERE resource = ?"),
-+                              &(s->stmt_move_uri), &next_stmt)) {
-+                              /* prepare failed */
-+                              log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
-+
-+                              return HANDLER_ERROR;
-+                      }
-+
-+                      /* LOCKS */
-+
-+                      if (SQLITE_OK != sqlite3_exec(s->sql,
-+                                      "CREATE TABLE locks ("
-+                                      "  locktoken TEXT NOT NULL,"
-                                       "  resource TEXT NOT NULL,"
--                                      "  prop TEXT NOT NULL,"
--                                      "  ns TEXT NOT NULL,"
--                                      "  value TEXT NOT NULL,"
--                                      "  PRIMARY KEY(resource, prop, ns))",
-+                                      "  lockscope TEXT NOT NULL,"
-+                                      "  locktype TEXT NOT NULL,"
-+                                      "  owner TEXT NOT NULL,"
-+                                      "  depth INT NOT NULL,"
-+                                      "  timeout TIMESTAMP NOT NULL,"
-+                                      "  PRIMARY KEY(locktoken))",
-                                       NULL, NULL, &err)) {
--                              if (0 != strcmp(err, "table properties already exists")) {
-+                              if (0 != strcmp(err, "table locks already exists")) {
-                                       log_error_write(srv, __FILE__, __LINE__, "ss", "can't open transaction:", err);
-                                       sqlite3_free(err);
-@@ -228,127 +314,138 @@
-                               }
-                               sqlite3_free(err);
-                       }
--      
--                      if (SQLITE_OK != sqlite3_prepare(s->sql, 
--                              CONST_STR_LEN("REPLACE INTO properties (resource, prop, ns, value) VALUES (?, ?, ?, ?)"), 
--                              &(s->stmt_update_prop), &next_stmt)) {
-+
-+                      if (SQLITE_OK != sqlite3_prepare(s->sql,
-+                              CONST_STR_LEN("INSERT INTO locks (locktoken, resource, lockscope, locktype, owner, depth, timeout) VALUES (?,?,?,?,?,?, CURRENT_TIME + 600)"),
-+                              &(s->stmt_create_lock), &next_stmt)) {
-                               /* prepare failed */
-+                              log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
--                              log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed:", sqlite3_errmsg(s->sql));
-                               return HANDLER_ERROR;
-                       }
--                      if (SQLITE_OK != sqlite3_prepare(s->sql, 
--                              CONST_STR_LEN("DELETE FROM properties WHERE resource = ? AND prop = ? AND ns = ?"), 
--                              &(s->stmt_delete_prop), &next_stmt)) {
-+                      if (SQLITE_OK != sqlite3_prepare(s->sql,
-+                              CONST_STR_LEN("DELETE FROM locks WHERE locktoken = ?"),
-+                              &(s->stmt_remove_lock), &next_stmt)) {
-                               /* prepare failed */
-                               log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
-                               return HANDLER_ERROR;
-                       }
--                      if (SQLITE_OK != sqlite3_prepare(s->sql, 
--                              CONST_STR_LEN("DELETE FROM properties WHERE resource = ?"), 
--                              &(s->stmt_delete_uri), &next_stmt)) {
-+                      if (SQLITE_OK != sqlite3_prepare(s->sql,
-+                              CONST_STR_LEN("SELECT locktoken, resource, lockscope, locktype, owner, depth, timeout FROM locks WHERE locktoken = ?"),
-+                              &(s->stmt_read_lock), &next_stmt)) {
-                               /* prepare failed */
-                               log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
-                               return HANDLER_ERROR;
-                       }
--                      if (SQLITE_OK != sqlite3_prepare(s->sql, 
--                              CONST_STR_LEN("INSERT INTO properties SELECT ?, prop, ns, value FROM properties WHERE resource = ?"), 
--                              &(s->stmt_copy_uri), &next_stmt)) {
-+                      if (SQLITE_OK != sqlite3_prepare(s->sql,
-+                              CONST_STR_LEN("SELECT locktoken, resource, lockscope, locktype, owner, depth, timeout FROM locks WHERE resource = ?"),
-+                              &(s->stmt_read_lock_by_uri), &next_stmt)) {
-                               /* prepare failed */
-                               log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
-                               return HANDLER_ERROR;
-                       }
--                      if (SQLITE_OK != sqlite3_prepare(s->sql, 
--                              CONST_STR_LEN("UPDATE properties SET resource = ? WHERE resource = ?"), 
--                              &(s->stmt_move_uri), &next_stmt)) {
-+                      if (SQLITE_OK != sqlite3_prepare(s->sql,
-+                              CONST_STR_LEN("UPDATE locks SET timeout = CURRENT_TIME + 600 WHERE locktoken = ?"),
-+                              &(s->stmt_refresh_lock), &next_stmt)) {
-                               /* prepare failed */
-                               log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
-                               return HANDLER_ERROR;
-                       }
-+
-+
- #else
-                       log_error_write(srv, __FILE__, __LINE__, "s", "Sorry, no sqlite3 and libxml2 support include, compile with --with-webdav-props");
-                       return HANDLER_ERROR;
- #endif
-               }
-       }
--      
-+
-       return HANDLER_GO_ON;
- }
--#define PATCH(x) \
--      p->conf.x = s->x;
- static int mod_webdav_patch_connection(server *srv, connection *con, plugin_data *p) {
-       size_t i, j;
-       plugin_config *s = p->config_storage[0];
--      
--      PATCH(enabled);
--      PATCH(is_readonly);
--      PATCH(log_xml);
--      
-+
-+      PATCH_OPTION(enabled);
-+      PATCH_OPTION(is_readonly);
-+      PATCH_OPTION(log_xml);
-+
- #ifdef USE_PROPPATCH
--      PATCH(sql);
--      PATCH(stmt_update_prop);
--      PATCH(stmt_delete_prop);
--      PATCH(stmt_select_prop);
--      PATCH(stmt_select_propnames);
--
--      PATCH(stmt_delete_uri);
--      PATCH(stmt_move_uri);
--      PATCH(stmt_copy_uri);
-+      PATCH_OPTION(sql);
-+      PATCH_OPTION(stmt_update_prop);
-+      PATCH_OPTION(stmt_delete_prop);
-+      PATCH_OPTION(stmt_select_prop);
-+      PATCH_OPTION(stmt_select_propnames);
-+
-+      PATCH_OPTION(stmt_delete_uri);
-+      PATCH_OPTION(stmt_move_uri);
-+      PATCH_OPTION(stmt_copy_uri);
-+
-+      PATCH_OPTION(stmt_remove_lock);
-+      PATCH_OPTION(stmt_refresh_lock);
-+      PATCH_OPTION(stmt_create_lock);
-+      PATCH_OPTION(stmt_read_lock);
-+      PATCH_OPTION(stmt_read_lock_by_uri);
- #endif
-       /* skip the first, the global context */
-       for (i = 1; i < srv->config_context->used; i++) {
-               data_config *dc = (data_config *)srv->config_context->data[i];
-               s = p->config_storage[i];
--              
-+
-               /* condition didn't match */
-               if (!config_check_cond(srv, con, dc)) continue;
--              
-+
-               /* merge config */
-               for (j = 0; j < dc->value->used; j++) {
-                       data_unset *du = dc->value->data[j];
--                      
-+
-                       if (buffer_is_equal_string(du->key, CONST_STR_LEN("webdav.activate"))) {
--                              PATCH(enabled);
-+                              PATCH_OPTION(enabled);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("webdav.is-readonly"))) {
--                              PATCH(is_readonly);
-+                              PATCH_OPTION(is_readonly);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("webdav.log-xml"))) {
--                              PATCH(log_xml);
-+                              PATCH_OPTION(log_xml);
-                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("webdav.sqlite-db-name"))) {
- #ifdef USE_PROPPATCH
--                              PATCH(sql);
--                              PATCH(stmt_update_prop);
--                              PATCH(stmt_delete_prop);
--                              PATCH(stmt_select_prop);
--                              PATCH(stmt_select_propnames);
--                              
--                              PATCH(stmt_delete_uri);
--                              PATCH(stmt_move_uri);
--                              PATCH(stmt_copy_uri);
-+                              PATCH_OPTION(sql);
-+                              PATCH_OPTION(stmt_update_prop);
-+                              PATCH_OPTION(stmt_delete_prop);
-+                              PATCH_OPTION(stmt_select_prop);
-+                              PATCH_OPTION(stmt_select_propnames);
-+
-+                              PATCH_OPTION(stmt_delete_uri);
-+                              PATCH_OPTION(stmt_move_uri);
-+                              PATCH_OPTION(stmt_copy_uri);
-+
-+                              PATCH_OPTION(stmt_remove_lock);
-+                              PATCH_OPTION(stmt_refresh_lock);
-+                              PATCH_OPTION(stmt_create_lock);
-+                              PATCH_OPTION(stmt_read_lock);
-+                              PATCH_OPTION(stmt_read_lock_by_uri);
- #endif
-                       }
-               }
-       }
--      
-+
-       return 0;
- }
--#undef PATCH
- URIHANDLER_FUNC(mod_webdav_uri_handler) {
-       plugin_data *p = p_d;
--      
-+
-       UNUSED(srv);
-       if (con->uri.path->used == 0) return HANDLER_GO_ON;
--      
-+
-       mod_webdav_patch_connection(srv, con, p);
-       if (!p->conf.enabled) return HANDLER_GO_ON;
-@@ -362,20 +459,20 @@
-               if (p->conf.is_readonly) {
-                       response_header_insert(srv, con, CONST_STR_LEN("Allow"), CONST_STR_LEN("PROPFIND"));
-               } else {
--                      response_header_insert(srv, con, CONST_STR_LEN("Allow"), CONST_STR_LEN("PROPFIND, DELETE, MKCOL, PUT, MOVE, COPY, PROPPATCH"));
-+                      response_header_insert(srv, con, CONST_STR_LEN("Allow"), CONST_STR_LEN("PROPFIND, DELETE, MKCOL, PUT, MOVE, COPY, PROPPATCH, LOCK, UNLOCK"));
-               }
-               break;
-       default:
-               break;
-       }
--      
-+
-       /* not found */
-       return HANDLER_GO_ON;
- }
--static int webdav_gen_prop_tag(server *srv, connection *con, 
--              char *prop_name, 
--              char *prop_ns, 
--              char *value, 
-+static int webdav_gen_prop_tag(server *srv, connection *con,
-+              char *prop_name,
-+              char *prop_ns,
-+              char *value,
-               buffer *b) {
-       UNUSED(srv);
-@@ -414,7 +511,7 @@
-       buffer_append_string_buffer(b, dst->rel_path);
-       buffer_append_string(b,"</D:href>\n");
-       buffer_append_string(b,"<D:status>\n");
--      
-+
-       if (con->request.http_version == HTTP_VERSION_1_1) {
-               BUFFER_COPY_STRING_CONST(b, "HTTP/1.1 ");
-       } else {
-@@ -458,14 +555,13 @@
-                       /* bind the values to the insert */
--                      sqlite3_bind_text(stmt, 1, 
--                                        dst->rel_path->ptr, 
-+                      sqlite3_bind_text(stmt, 1,
-+                                        dst->rel_path->ptr,
-                                         dst->rel_path->used - 1,
-                                         SQLITE_TRANSIENT);
--                                                                      
-+
-                       if (SQLITE_DONE != sqlite3_step(stmt)) {
-                               /* */
--                              WP();
-                       }
-               }
- #endif
-@@ -493,14 +589,14 @@
-                           (de->d_name[0] == '.' && de->d_name[1] == '.' && de->d_name[2] == '\0')) {
-                               continue;
-                               /* ignore the parent dir */
--                      } 
-+                      }
-                       buffer_copy_string_buffer(d.path, dst->path);
--                      BUFFER_APPEND_SLASH(d.path);
-+                      PATHNAME_APPEND_SLASH(d.path);
-                       buffer_append_string(d.path, de->d_name);
--                      
-+
-                       buffer_copy_string_buffer(d.rel_path, dst->rel_path);
--                      BUFFER_APPEND_SLASH(d.rel_path);
-+                      PATHNAME_APPEND_SLASH(d.rel_path);
-                       buffer_append_string(d.rel_path, de->d_name);
-                       /* stat and unlink afterwards */
-@@ -508,7 +604,7 @@
-                               /* don't about it yet, rmdir will fail too */
-                       } else if (S_ISDIR(st.st_mode)) {
-                               have_multi_status = webdav_delete_dir(srv, con, p, &d, b);
--                                      
-+
-                               /* try to unlink it */
-                               if (-1 == rmdir(d.path->ptr)) {
-                                       switch(errno) {
-@@ -535,14 +631,13 @@
-                                               /* bind the values to the insert */
--                                              sqlite3_bind_text(stmt, 1, 
--                                                                d.rel_path->ptr, 
-+                                              sqlite3_bind_text(stmt, 1,
-+                                                                d.rel_path->ptr,
-                                                                 d.rel_path->used - 1,
-                                                                 SQLITE_TRANSIENT);
--                                                                                                      
-+
-                                               if (SQLITE_DONE != sqlite3_step(stmt)) {
-                                                       /* */
--                                                      WP();
-                                               }
-                                       }
- #endif
-@@ -569,7 +664,7 @@
-       if (stream_open(&s, src->path)) {
-               return 403;
-       }
--                      
-+
-       if (-1 == (ofd = open(dst->path->ptr, O_WRONLY|O_TRUNC|O_CREAT|(overwrite ? 0 : O_EXCL), 0600))) {
-               /* opening the destination failed for some reason */
-               switch(errno) {
-@@ -601,7 +696,7 @@
-                       break;
-               }
-       }
--      
-+
-       stream_close(&s);
-       close(ofd);
-@@ -614,19 +709,18 @@
-                       sqlite3_reset(stmt);
-                       /* bind the values to the insert */
--                      sqlite3_bind_text(stmt, 1, 
--                                        dst->rel_path->ptr, 
-+                      sqlite3_bind_text(stmt, 1,
-+                                        dst->rel_path->ptr,
-                                         dst->rel_path->used - 1,
-                                         SQLITE_TRANSIENT);
--                      sqlite3_bind_text(stmt, 2, 
--                                        src->rel_path->ptr, 
-+                      sqlite3_bind_text(stmt, 2,
-+                                        src->rel_path->ptr,
-                                         src->rel_path->used - 1,
-                                         SQLITE_TRANSIENT);
--                                                                                                      
-+
-                       if (SQLITE_DONE != sqlite3_step(stmt)) {
-                               /* */
--                              WP();
-                       }
-               }
-       }
-@@ -655,21 +749,21 @@
-                           (de->d_name[0] == '.' && de->d_name[1] == '.' && de->d_name[2] == '\0')) {
-                               continue;
-                       }
--                      
-+
-                       buffer_copy_string_buffer(s.path, src->path);
--                      BUFFER_APPEND_SLASH(s.path);
-+                      PATHNAME_APPEND_SLASH(s.path);
-                       buffer_append_string(s.path, de->d_name);
-                       buffer_copy_string_buffer(d.path, dst->path);
--                      BUFFER_APPEND_SLASH(d.path);
-+                      PATHNAME_APPEND_SLASH(d.path);
-                       buffer_append_string(d.path, de->d_name);
-                       buffer_copy_string_buffer(s.rel_path, src->rel_path);
--                      BUFFER_APPEND_SLASH(s.rel_path);
-+                      PATHNAME_APPEND_SLASH(s.rel_path);
-                       buffer_append_string(s.rel_path, de->d_name);
-                       buffer_copy_string_buffer(d.rel_path, dst->rel_path);
--                      BUFFER_APPEND_SLASH(d.rel_path);
-+                      PATHNAME_APPEND_SLASH(d.rel_path);
-                       buffer_append_string(d.rel_path, de->d_name);
-                       if (-1 == stat(s.path->ptr, &st)) {
-@@ -692,19 +786,18 @@
-                                               sqlite3_reset(stmt);
-                                               /* bind the values to the insert */
--                                              sqlite3_bind_text(stmt, 1, 
--                                                        dst->rel_path->ptr, 
-+                                              sqlite3_bind_text(stmt, 1,
-+                                                        dst->rel_path->ptr,
-                                                         dst->rel_path->used - 1,
-                                                         SQLITE_TRANSIENT);
--                                              sqlite3_bind_text(stmt, 2, 
--                                                        src->rel_path->ptr, 
-+                                              sqlite3_bind_text(stmt, 2,
-+                                                        src->rel_path->ptr,
-                                                         src->rel_path->used - 1,
-                                                         SQLITE_TRANSIENT);
--                                                                                                      
-+
-                                               if (SQLITE_DONE != sqlite3_step(stmt)) {
-                                                       /* */
--                                                      WP();
-                                               }
-                                       }
- #endif
-@@ -721,7 +814,7 @@
-               buffer_free(s.rel_path);
-               buffer_free(d.path);
-               buffer_free(d.rel_path);
--              
-+
-               closedir(srcdir);
-       }
-@@ -748,12 +841,12 @@
-                       if (S_ISDIR(sce->st.st_mode)) {
-                               buffer_append_string(b, "<D:getcontenttype>httpd/unix-directory</D:getcontenttype>");
-                               found = 1;
--                      } else if(S_ISREG(sce->st.st_mode)) { 
-+                      } else if(S_ISREG(sce->st.st_mode)) {
-                               for (k = 0; k < con->conf.mimetypes->used; k++) {
-                                       data_string *ds = (data_string *)con->conf.mimetypes->data[k];
--              
-+
-                                       if (ds->key->used == 0) continue;
--                              
-+
-                                       if (buffer_is_equal_right_len(dst->path, ds->key, ds->key->used - 1)) {
-                                               buffer_append_string(b,"<D:getcontenttype>");
-                                               buffer_append_string_buffer(b, ds->value);
-@@ -807,23 +900,23 @@
-                       /* bind the values to the insert */
--                      sqlite3_bind_text(stmt, 1, 
--                                        dst->rel_path->ptr, 
-+                      sqlite3_bind_text(stmt, 1,
-+                                        dst->rel_path->ptr,
-                                         dst->rel_path->used - 1,
-                                         SQLITE_TRANSIENT);
--                      sqlite3_bind_text(stmt, 2, 
-+                      sqlite3_bind_text(stmt, 2,
-                                         prop_name,
-                                         strlen(prop_name),
-                                         SQLITE_TRANSIENT);
--                      sqlite3_bind_text(stmt, 3, 
-+                      sqlite3_bind_text(stmt, 3,
-                                         prop_ns,
-                                         strlen(prop_ns),
-                                         SQLITE_TRANSIENT);
-                       /* it is the PK */
--                      while (SQLITE_ROW == sqlite3_step(p->conf.stmt_select_prop)) {
-+                      while (SQLITE_ROW == sqlite3_step(stmt)) {
-                               /* there is a row for us, we only expect a single col 'value' */
--                              webdav_gen_prop_tag(srv, con, prop_name, prop_ns, (char *)sqlite3_column_text(p->conf.stmt_select_prop, 0), b);
-+                              webdav_gen_prop_tag(srv, con, prop_name, prop_ns, (char *)sqlite3_column_text(stmt, 0), b);
-                               found = 1;
-                       }
-               }
-@@ -840,7 +933,7 @@
-       char *prop;
- } webdav_property;
--webdav_property live_properties[] = { 
-+webdav_property live_properties[] = {
-       { "DAV:", "creationdate" },
-       { "DAV:", "displayname" },
-       { "DAV:", "getcontentlanguage" },
-@@ -871,8 +964,8 @@
-                       webdav_property *prop;
-                       prop = props->ptr[i];
--                      
--                      if (0 != webdav_get_property(srv, con, p, 
-+
-+                      if (0 != webdav_get_property(srv, con, p,
-                               dst, prop->prop, prop->ns, b_200)) {
-                               webdav_gen_prop_tag(srv, con, prop->prop, prop->ns, NULL, b_404);
-                       }
-@@ -916,12 +1009,12 @@
-                               if (-1 == c->file.fd &&  /* open the file if not already open */
-                                   -1 == (c->file.fd = open(c->file.name->ptr, O_RDONLY))) {
-                                       log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno));
--              
-+
-                                       return -1;
-                               }
--      
-+
-                               if (MAP_FAILED == (c->file.mmap.start = mmap(0, c->file.length, PROT_READ, MAP_SHARED, c->file.fd, 0))) {
--                                      log_error_write(srv, __FILE__, __LINE__, "ssbd", "mmap failed: ", 
-+                                      log_error_write(srv, __FILE__, __LINE__, "ssbd", "mmap failed: ",
-                                                       strerror(errno), c->file.name,  c->file.fd);
-                                       return -1;
-@@ -938,7 +1031,7 @@
-                       if (XML_ERR_OK != (err = xmlParseChunk(ctxt, c->file.mmap.start + c->offset, weHave, 0))) {
-                               log_error_write(srv, __FILE__, __LINE__, "sddd", "xmlParseChunk failed at:", cq->bytes_out, weHave, err);
-                       }
--                      
-+
-                       c->offset += weHave;
-                       cq->bytes_out += weHave;
-@@ -956,7 +1049,7 @@
-                       if (XML_ERR_OK != (err = xmlParseChunk(ctxt, c->mem->ptr + c->offset, weHave, 0))) {
-                               log_error_write(srv, __FILE__, __LINE__, "sddd", "xmlParseChunk failed at:", cq->bytes_out, weHave, err);
-                       }
--                      
-+
-                       c->offset += weHave;
-                       cq->bytes_out += weHave;
-@@ -991,6 +1084,113 @@
- }
- #endif
-+int webdav_lockdiscovery(server *srv, connection *con,
-+              buffer *locktoken, const char *lockscope, const char *locktype, int depth) {
-+
-+      buffer *b;
-+
-+      response_header_overwrite(srv, con, CONST_STR_LEN("Lock-Token"), CONST_BUF_LEN(locktoken));
-+
-+      response_header_overwrite(srv, con,
-+              CONST_STR_LEN("Content-Type"),
-+              CONST_STR_LEN("text/xml; charset=\"utf-8\""));
-+
-+      b = chunkqueue_get_append_buffer(con->send);
-+
-+      buffer_copy_string(b, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
-+
-+      buffer_append_string(b,"<D:prop xmlns:D=\"DAV:\" xmlns:ns0=\"urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/\">\n");
-+      buffer_append_string(b,"<D:lockdiscovery>\n");
-+      buffer_append_string(b,"<D:activelock>\n");
-+
-+      buffer_append_string(b,"<D:lockscope>");
-+      buffer_append_string(b,"<D:");
-+      buffer_append_string(b, lockscope);
-+      buffer_append_string(b, "/>");
-+      buffer_append_string(b,"</D:lockscope>\n");
-+
-+      buffer_append_string(b,"<D:locktype>");
-+      buffer_append_string(b,"<D:");
-+      buffer_append_string(b, locktype);
-+      buffer_append_string(b, "/>");
-+      buffer_append_string(b,"</D:locktype>\n");
-+
-+      buffer_append_string(b,"<D:depth>");
-+      buffer_append_string(b, depth == 0 ? "0" : "infinity");
-+      buffer_append_string(b,"</D:depth>\n");
-+
-+      buffer_append_string(b,"<D:timeout>");
-+      buffer_append_string(b, "Second-600");
-+      buffer_append_string(b,"</D:timeout>\n");
-+
-+      buffer_append_string(b,"<D:owner>");
-+      buffer_append_string(b,"</D:owner>\n");
-+
-+      buffer_append_string(b,"<D:locktoken>");
-+      buffer_append_string(b, "<D:href>");
-+      buffer_append_string_buffer(b, locktoken);
-+      buffer_append_string(b, "</D:href>");
-+      buffer_append_string(b,"</D:locktoken>\n");
-+
-+      buffer_append_string(b,"</D:activelock>\n");
-+      buffer_append_string(b,"</D:lockdiscovery>\n");
-+      buffer_append_string(b,"</D:prop>\n");
-+
-+      return 0;
-+}
-+/**
-+ * check if resource is having the right locks to access to resource
-+ *
-+ *
-+ *
-+ */
-+int webdav_has_lock(server *srv, connection *con, plugin_data *p, buffer *uri) {
-+      int has_lock = 1;
-+
-+#ifdef USE_LOCKS
-+      data_string *ds;
-+
-+      /**
-+       * If can have
-+       * - <lock-token>
-+       * - [etag]
-+       *
-+       * there is NOT, AND and OR
-+       * and a list can be tagged
-+       *
-+       * (<lock-token>) is untagged
-+       * <tag> (<lock-token>) is tagged
-+       *
-+       * as long as we don't handle collections it is simple. :)
-+       *
-+       * X-Litmus: locks: 11 (owner_modify)
-+       * If: <http://127.0.0.1:1025/dav/litmus/lockme> (<opaquelocktoken:2165478d-0611-49c4-be92-e790d68a38f1>)
-+       *
-+       * X-Litmus: locks: 16 (fail_cond_put)
-+       * If: (<DAV:no-lock> ["-1622396671"])
-+       */
-+      if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "If"))) {
-+      } else {
-+              /* we didn't provided a lock-token -> */
-+              /* if the resource is locked -> 423 */
-+
-+              sqlite3_stmt *stmt = p->conf.stmt_read_lock_by_uri;
-+
-+              sqlite3_reset(stmt);
-+
-+              sqlite3_bind_text(stmt, 1,
-+                        CONST_BUF_LEN(uri),
-+                        SQLITE_TRANSIENT);
-+
-+              while (SQLITE_ROW == sqlite3_step(stmt)) {
-+                      has_lock = 0;
-+              }
-+      }
-+#endif
-+
-+      return has_lock;
-+}
-+
- URIHANDLER_FUNC(mod_webdav_subrequest_handler) {
-       plugin_data *p = p_d;
-       buffer *b;
-@@ -1001,7 +1201,8 @@
-       buffer *prop_200;
-       buffer *prop_404;
-       webdav_properties *req_props;
--      
-+      stat_cache_entry *sce = NULL;
-+
-       UNUSED(srv);
-       if (!p->conf.enabled) return HANDLER_GO_ON;
-@@ -1019,13 +1220,25 @@
-               req_props = NULL;
-               /* is there a content-body ? */
--      
-+
-+              switch (stat_cache_get_entry(srv, con, con->physical.path, &sce)) {
-+              case HANDLER_ERROR:
-+                      if (errno == ENOENT) {
-+                              con->http_status = 404;
-+                              return HANDLER_FINISHED;
-+                      }
-+                      break;
-+              default:
-+                      break;
-+              }
-+
-+
- #ifdef USE_PROPPATCH
-               /* any special requests or just allprop ? */
-               if (con->request.content_length) {
-                       xmlDocPtr xml;
--                      if (1 == webdav_parse_chunkqueue(srv, con, p, con->request_content_queue, &xml)) {
-+                      if (1 == webdav_parse_chunkqueue(srv, con, p, con->recv, &xml)) {
-                               xmlNode *rootnode = xmlDocGetRootElement(xml);
-                               assert(rootnode);
-@@ -1087,14 +1300,13 @@
-                                                               /* get all property names (EMPTY) */
-                                                               sqlite3_reset(stmt);
-                                                               /* bind the values to the insert */
--      
--                                                              sqlite3_bind_text(stmt, 1, 
--                                                                                con->uri.path->ptr, 
-+
-+                                                              sqlite3_bind_text(stmt, 1,
-+                                                                                con->uri.path->ptr,
-                                                                                 con->uri.path->used - 1,
-                                                                                 SQLITE_TRANSIENT);
--                                              
-+
-                                                               if (SQLITE_DONE != sqlite3_step(stmt)) {
--                                                                      WP();
-                                                               }
-                                                       }
-                                               } else if (0 == xmlStrcmp(cmd->name, BAD_CAST "allprop")) {
-@@ -1114,14 +1326,14 @@
-               response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml; charset=\"utf-8\""));
--              b = chunkqueue_get_append_buffer(con->write_queue);
--                              
-+              b = chunkqueue_get_append_buffer(con->send);
-+
-               buffer_copy_string(b, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
-               buffer_append_string(b,"<D:multistatus xmlns:D=\"DAV:\" xmlns:ns0=\"urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/\">\n");
-               /* allprop */
--              
-+
-               prop_200 = buffer_init();
-               prop_404 = buffer_init();
-@@ -1129,7 +1341,7 @@
-               case 0:
-                       /* Depth: 0 */
-                       webdav_get_props(srv, con, p, &(con->physical), req_props, prop_200, prop_404);
--      
-+
-                       buffer_append_string(b,"<D:response>\n");
-                       buffer_append_string(b,"<D:href>");
-                       buffer_append_string_buffer(b, con->uri.scheme);
-@@ -1145,9 +1357,9 @@
-                               buffer_append_string_buffer(b, prop_200);
-                               buffer_append_string(b,"</D:prop>\n");
--      
-+
-                               buffer_append_string(b,"<D:status>HTTP/1.1 200 OK</D:status>\n");
--      
-+
-                               buffer_append_string(b,"</D:propstat>\n");
-                       }
-                       if (!buffer_is_empty(prop_404)) {
-@@ -1157,16 +1369,16 @@
-                               buffer_append_string_buffer(b, prop_404);
-                               buffer_append_string(b,"</D:prop>\n");
--      
-+
-                               buffer_append_string(b,"<D:status>HTTP/1.1 404 Not Found</D:status>\n");
--      
-+
-                               buffer_append_string(b,"</D:propstat>\n");
-                       }
-                       buffer_append_string(b,"</D:response>\n");
-                       break;
--              case 1: 
-+              case 1:
-                       if (NULL != (dir = opendir(con->physical.path->ptr))) {
-                               struct dirent *de;
-                               physical d;
-@@ -1179,16 +1391,16 @@
-                                       if (de->d_name[0] == '.' && de->d_name[1] == '.' && de->d_name[2] == '\0') {
-                                               continue;
-                                               /* ignore the parent dir */
--                                      } 
-+                                      }
-                                       buffer_copy_string_buffer(d.path, dst->path);
--                                      BUFFER_APPEND_SLASH(d.path);
-+                                      PATHNAME_APPEND_SLASH(d.path);
-                                       buffer_copy_string_buffer(d.rel_path, dst->rel_path);
--                                      BUFFER_APPEND_SLASH(d.rel_path);
-+                                      PATHNAME_APPEND_SLASH(d.rel_path);
-                                       if (de->d_name[0] == '.' && de->d_name[1] == '\0') {
--                                              /* don't append the . */ 
-+                                              /* don't append the . */
-                                       } else {
-                                               buffer_append_string(d.path, de->d_name);
-                                               buffer_append_string(d.rel_path, de->d_name);
-@@ -1198,7 +1410,7 @@
-                                       buffer_reset(prop_404);
-                                       webdav_get_props(srv, con, p, &d, req_props, prop_200, prop_404);
--                                      
-+
-                                       buffer_append_string(b,"<D:response>\n");
-                                       buffer_append_string(b,"<D:href>");
-                                       buffer_append_string_buffer(b, con->uri.scheme);
-@@ -1214,9 +1426,9 @@
-                                               buffer_append_string_buffer(b, prop_200);
-                                               buffer_append_string(b,"</D:prop>\n");
--                      
-+
-                                               buffer_append_string(b,"<D:status>HTTP/1.1 200 OK</D:status>\n");
--                      
-+
-                                               buffer_append_string(b,"</D:propstat>\n");
-                                       }
-                                       if (!buffer_is_empty(prop_404)) {
-@@ -1226,9 +1438,9 @@
-                                               buffer_append_string_buffer(b, prop_404);
-                                               buffer_append_string(b,"</D:prop>\n");
--      
-+
-                                               buffer_append_string(b,"<D:status>HTTP/1.1 404 Not Found</D:status>\n");
--      
-+
-                                               buffer_append_string(b,"</D:propstat>\n");
-                                       }
-@@ -1260,7 +1472,7 @@
-               if (p->conf.log_xml) {
-                       log_error_write(srv, __FILE__, __LINE__, "sb", "XML-response-body:", b);
-               }
--              con->file_finished = 1;
-+              con->send->is_closed = 1;
-               return HANDLER_FINISHED;
-       case HTTP_METHOD_MKCOL:
-@@ -1275,7 +1487,7 @@
-                       return HANDLER_FINISHED;
-               }
--      
-+
-               /* let's create the directory */
-               if (-1 == mkdir(con->physical.path->ptr, 0700)) {
-@@ -1294,7 +1506,7 @@
-                       }
-               } else {
-                       con->http_status = 201;
--                      con->file_finished = 1;
-+                      con->send->is_closed = 1;
-               }
-               return HANDLER_FINISHED;
-@@ -1303,7 +1515,13 @@
-                       con->http_status = 403;
-                       return HANDLER_FINISHED;
-               }
--              
-+
-+              /* does the client have a lock for this connection ? */
-+              if (!webdav_has_lock(srv, con, p, con->uri.path)) {
-+                      con->http_status = 423;
-+                      return HANDLER_FINISHED;
-+              }
-+
-               /* stat and unlink afterwards */
-               if (-1 == stat(con->physical.path->ptr, &st)) {
-                       /* don't about it yet, unlink will fail too */
-@@ -1322,8 +1540,8 @@
-                               /* we got an error somewhere in between, build a 207 */
-                               response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml; charset=\"utf-8\""));
--                              b = chunkqueue_get_append_buffer(con->write_queue);
--                      
-+                              b = chunkqueue_get_append_buffer(con->send);
-+
-                               buffer_copy_string(b, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
-                               buffer_append_string(b,"<D:multistatus xmlns:D=\"DAV:\">\n");
-@@ -1331,16 +1549,16 @@
-                               buffer_append_string_buffer(b, multi_status_resp);
-                               buffer_append_string(b,"</D:multistatus>\n");
--                      
-+
-                               if (p->conf.log_xml) {
-                                       log_error_write(srv, __FILE__, __LINE__, "sb", "XML-response-body:", b);
-                               }
-                               con->http_status = 207;
--                              con->file_finished = 1;
-+                              con->send->is_closed = 1;
-                       } else {
-                               /* everything went fine, remove the directory */
--      
-+
-                               if (-1 == rmdir(con->physical.path->ptr)) {
-                                       switch(errno) {
-                                       case ENOENT:
-@@ -1374,98 +1592,175 @@
-               return HANDLER_FINISHED;
-       case HTTP_METHOD_PUT: {
-               int fd;
--              chunkqueue *cq = con->request_content_queue;
-+              chunkqueue *cq = con->recv;
-+              chunk *c;
-+              data_string *ds_range;
-               if (p->conf.is_readonly) {
-                       con->http_status = 403;
-                       return HANDLER_FINISHED;
-               }
-+              /* is a exclusive lock set on the source */
-+              if (!webdav_has_lock(srv, con, p, con->uri.path)) {
-+                      con->http_status = 423;
-+                      return HANDLER_FINISHED;
-+              }
-+
-+
-               assert(chunkqueue_length(cq) == (off_t)con->request.content_length);
--              /* taken what we have in the request-body and write it to a file */
--              if (-1 == (fd = open(con->physical.path->ptr, O_WRONLY|O_CREAT|O_TRUNC, 0600))) {
--                      /* we can't open the file */
--                      con->http_status = 403;
--              } else {
--                      chunk *c;
-+              /* RFC2616 Section 9.6 PUT requires us to send 501 on all Content-* we don't support
-+               * - most important Content-Range
-+               *
-+               *
-+               * Example: Content-Range: bytes 100-1037/1038 */
--                      con->http_status = 201; /* created */
--                      con->file_finished = 1;
-+              if (NULL != (ds_range = (data_string *)array_get_element(con->request.headers, "Content-Range"))) {
-+                      const char *num = ds_range->value->ptr;
-+                      off_t offset;
-+                      char *err = NULL;
--                      for (c = cq->first; c; c = cq->first) {
--                              int r = 0; 
-+                      if (0 != strncmp(num, "bytes ", 6)) {
-+                              con->http_status = 501; /* not implemented */
--                              /* copy all chunks */
--                              switch(c->type) {
--                              case FILE_CHUNK:
--
--                                      if (c->file.mmap.start == MAP_FAILED) {
--                                              if (-1 == c->file.fd &&  /* open the file if not already open */
--                                                  -1 == (c->file.fd = open(c->file.name->ptr, O_RDONLY))) {
--                                                      log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno));
--                                      
--                                                      return -1;
--                                              }
--                              
--                                              if (MAP_FAILED == (c->file.mmap.start = mmap(0, c->file.length, PROT_READ, MAP_SHARED, c->file.fd, 0))) {
--                                                      log_error_write(srv, __FILE__, __LINE__, "ssbd", "mmap failed: ", 
--                                                                      strerror(errno), c->file.name,  c->file.fd);
-+                              return HANDLER_FINISHED;
-+                      }
--                                                      return -1;
--                                              }
-+                      /* we only support <num>- ... */
--                                              c->file.mmap.length = c->file.length;
-+                      num += 6;
--                                              close(c->file.fd);
--                                              c->file.fd = -1;
--      
--                                              /* chunk_reset() or chunk_free() will cleanup for us */
--                                      }
--
--                                      if ((r = write(fd, c->file.mmap.start + c->offset, c->file.length - c->offset)) < 0) {
--                                              switch(errno) {
--                                              case ENOSPC:
--                                                      con->http_status = 507;
--              
--                                                      break;
--                                              default:
--                                                      con->http_status = 403;
--                                                      break;
--                                              }
--                                      }
--                                      break;
--                              case MEM_CHUNK:
--                                      if ((r = write(fd, c->mem->ptr + c->offset, c->mem->used - c->offset - 1)) < 0) {
--                                              switch(errno) {
--                                              case ENOSPC:
--                                                      con->http_status = 507;
--              
--                                                      break;
--                                              default:
--                                                      con->http_status = 403;
--                                                      break;
--                                              }
--                                      }
-+                      /* skip WS */
-+                      while (*num == ' ' || *num == '\t') num++;
-+
-+                      if (*num == '\0') {
-+                              con->http_status = 501; /* not implemented */
-+
-+                              return HANDLER_FINISHED;
-+                      }
-+
-+                      offset = strtoll(num, &err, 10);
-+
-+                      if (*err != '-' || offset < 0) {
-+                              con->http_status = 501; /* not implemented */
-+
-+                              return HANDLER_FINISHED;
-+                      }
-+
-+                      if (-1 == (fd = open(con->physical.path->ptr, O_WRONLY, 0600))) {
-+                              switch (errno) {
-+                              case ENOENT:
-+                                      con->http_status = 404; /* not found */
-                                       break;
--                              case UNUSED_CHUNK:
-+                              default:
-+                                      con->http_status = 403; /* not found */
-                                       break;
-                               }
-+                              return HANDLER_FINISHED;
-+                      }
-+
-+                      if (-1 == lseek(fd, offset, SEEK_SET)) {
-+                              con->http_status = 501; /* not implemented */
-+
-+                              close(fd);
-+
-+                              return HANDLER_FINISHED;
-+                      }
-+                      con->http_status = 200; /* modified */
-+              } else {
-+                      /* take what we have in the request-body and write it to a file */
--                              if (r > 0) {
--                                      c->offset += r;
--                                      cq->bytes_out += r;
-+                      /* if the file doesn't exist, create it */
-+                      if (-1 == (fd = open(con->physical.path->ptr, O_WRONLY|O_TRUNC, 0600))) {
-+                              if (errno == ENOENT &&
-+                                  -1 == (fd = open(con->physical.path->ptr, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0600))) {
-+                                      /* we can't open the file */
-+                                      con->http_status = 403;
-+
-+                                      return HANDLER_FINISHED;
-                               } else {
--                                      break;
-+                                      con->http_status = 201; /* created */
-                               }
--                              chunkqueue_remove_finished_chunks(cq);
-+                      } else {
-+                              con->http_status = 200; /* modified */
-                       }
--                      close(fd);
-+              }
-+
-+              con->send->is_closed = 1;
-+
-+              for (c = cq->first; c; c = cq->first) {
-+                      int r = 0;
-+
-+                      /* copy all chunks */
-+                      switch(c->type) {
-+                      case FILE_CHUNK:
-+
-+                              if (c->file.mmap.start == MAP_FAILED) {
-+                                      if (-1 == c->file.fd &&  /* open the file if not already open */
-+                                          -1 == (c->file.fd = open(c->file.name->ptr, O_RDONLY))) {
-+                                              log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno));
-+
-+                                              return -1;
-+                                      }
-+
-+                                      if (MAP_FAILED == (c->file.mmap.start = mmap(0, c->file.length, PROT_READ, MAP_SHARED, c->file.fd, 0))) {
-+                                              log_error_write(srv, __FILE__, __LINE__, "ssbd", "mmap failed: ",
-+                                                              strerror(errno), c->file.name,  c->file.fd);
-+                                              return -1;
-+                                      }
-+
-+                                      c->file.mmap.length = c->file.length;
-+
-+                                      close(c->file.fd);
-+                                      c->file.fd = -1;
-+
-+                                      /* chunk_reset() or chunk_free() will cleanup for us */
-+                              }
-+
-+                              if ((r = write(fd, c->file.mmap.start + c->offset, c->file.length - c->offset)) < 0) {
-+                                      switch(errno) {
-+                                      case ENOSPC:
-+                                              con->http_status = 507;
-+
-+                                              break;
-+                                      default:
-+                                              con->http_status = 403;
-+                                              break;
-+                                      }
-+                              }
-+                              break;
-+                      case MEM_CHUNK:
-+                              if ((r = write(fd, c->mem->ptr + c->offset, c->mem->used - c->offset - 1)) < 0) {
-+                                      switch(errno) {
-+                                      case ENOSPC:
-+                                              con->http_status = 507;
-+
-+                                              break;
-+                                      default:
-+                                              con->http_status = 403;
-+                                              break;
-+                                      }
-+                              }
-+                              break;
-+                      case UNUSED_CHUNK:
-+                              break;
-+                      }
-+
-+                      if (r > 0) {
-+                              c->offset += r;
-+                              cq->bytes_out += r;
-+                      } else {
-+                              break;
-+                      }
-+                      chunkqueue_remove_finished_chunks(cq);
-               }
-+              close(fd);
-+
-               return HANDLER_FINISHED;
-       }
--      case HTTP_METHOD_MOVE: 
-+      case HTTP_METHOD_MOVE:
-       case HTTP_METHOD_COPY: {
-               buffer *destination = NULL;
-               char *sep, *start;
-@@ -1475,7 +1770,15 @@
-                       con->http_status = 403;
-                       return HANDLER_FINISHED;
-               }
--              
-+
-+              /* is a exclusive lock set on the source */
-+              if (con->request.http_method == HTTP_METHOD_MOVE) {
-+                      if (!webdav_has_lock(srv, con, p, con->uri.path)) {
-+                              con->http_status = 423;
-+                              return HANDLER_FINISHED;
-+                      }
-+              }
-+
-               if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Destination"))) {
-                       destination = ds->value;
-               } else {
-@@ -1549,10 +1852,10 @@
-               }
-               buffer_copy_string_buffer(p->physical.path, p->physical.doc_root);
--              BUFFER_APPEND_SLASH(p->physical.path);
-+              PATHNAME_APPEND_SLASH(p->physical.path);
-               buffer_copy_string_buffer(p->physical.basedir, p->physical.path);
--              /* don't add a second / */ 
-+              /* don't add a second / */
-               if (p->physical.rel_path->ptr[0] == '/') {
-                       buffer_append_string_len(p->physical.path, p->physical.rel_path->ptr + 1, p->physical.rel_path->used - 2);
-               } else {
-@@ -1608,11 +1911,17 @@
-                               rmdir(con->physical.path->ptr);
-                       }
-                       con->http_status = 201;
--                      con->file_finished = 1;
-+                      con->send->is_closed = 1;
-               } else {
-                       /* it is just a file, good */
-                       int r;
-+                      /* does the client have a lock for this connection ? */
-+                      if (!webdav_has_lock(srv, con, p, p->uri.path)) {
-+                              con->http_status = 423;
-+                              return HANDLER_FINISHED;
-+                      }
-+
-                       /* destination exists */
-                       if (0 == (r = stat(p->physical.path->ptr, &st))) {
-                               if (S_ISDIR(st.st_mode)) {
-@@ -1628,7 +1937,7 @@
-                       if (-1 == r) {
-                               con->http_status = 201; /* we will create a new one */
--                              con->file_finished = 1;
-+                              con->send->is_closed = 1;
-                               switch(errno) {
-                               case ENOTDIR:
-@@ -1636,7 +1945,7 @@
-                                       return HANDLER_FINISHED;
-                               }
-                       } else if (overwrite == 0) {
--                              /* destination exists, but overwrite is not set */ 
-+                              /* destination exists, but overwrite is not set */
-                               con->http_status = 412;
-                               return HANDLER_FINISHED;
-                       } else {
-@@ -1655,16 +1964,16 @@
-                                               sqlite3_reset(stmt);
-                                               /* bind the values to the insert */
--                                              sqlite3_bind_text(stmt, 1, 
--                                                                p->uri.path->ptr, 
-+                                              sqlite3_bind_text(stmt, 1,
-+                                                                p->uri.path->ptr,
-                                                                 p->uri.path->used - 1,
-                                                                 SQLITE_TRANSIENT);
--                                              sqlite3_bind_text(stmt, 2, 
--                                                                con->uri.path->ptr, 
-+                                              sqlite3_bind_text(stmt, 2,
-+                                                                con->uri.path->ptr,
-                                                                 con->uri.path->used - 1,
-                                                                 SQLITE_TRANSIENT);
--                                              
-+
-                                               if (SQLITE_DONE != sqlite3_step(stmt)) {
-                                                       log_error_write(srv, __FILE__, __LINE__, "ss", "sql-move failed:", sqlite3_errmsg(p->conf.sql));
-                                               }
-@@ -1691,12 +2000,17 @@
-               return HANDLER_FINISHED;
-       }
--      case HTTP_METHOD_PROPPATCH: {
-+      case HTTP_METHOD_PROPPATCH:
-               if (p->conf.is_readonly) {
-                       con->http_status = 403;
-                       return HANDLER_FINISHED;
-               }
-+              if (!webdav_has_lock(srv, con, p, con->uri.path)) {
-+                      con->http_status = 423;
-+                      return HANDLER_FINISHED;
-+              }
-+
-               /* check if destination exists */
-               if (-1 == stat(con->physical.path->ptr, &st)) {
-                       switch(errno) {
-@@ -1710,7 +2024,7 @@
-               if (con->request.content_length) {
-                       xmlDocPtr xml;
--                      if (1 == webdav_parse_chunkqueue(srv, con, p, con->request_content_queue, &xml)) {
-+                      if (1 == webdav_parse_chunkqueue(srv, con, p, con->recv, &xml)) {
-                               xmlNode *rootnode = xmlDocGetRootElement(xml);
-                               if (0 == xmlStrcmp(rootnode->name, BAD_CAST "propertyupdate")) {
-@@ -1737,7 +2051,7 @@
-                                                       sqlite3_stmt *stmt;
--                                                      stmt = (0 == xmlStrcmp(cmd->name, BAD_CAST "remove")) ? 
-+                                                      stmt = (0 == xmlStrcmp(cmd->name, BAD_CAST "remove")) ?
-                                                               p->conf.stmt_delete_prop : p->conf.stmt_update_prop;
-                                                       for (props = cmd->children; props; props = props->next) {
-@@ -1762,34 +2076,35 @@
-                                                                       /* bind the values to the insert */
--                                                                      sqlite3_bind_text(stmt, 1, 
--                                                                                        con->uri.path->ptr, 
-+                                                                      sqlite3_bind_text(stmt, 1,
-+                                                                                        con->uri.path->ptr,
-                                                                                         con->uri.path->used - 1,
-                                                                                         SQLITE_TRANSIENT);
--                                                                      sqlite3_bind_text(stmt, 2, 
-+                                                                      sqlite3_bind_text(stmt, 2,
-                                                                                         (char *)prop->name,
-                                                                                         strlen((char *)prop->name),
-                                                                                         SQLITE_TRANSIENT);
-                                                                       if (prop->ns) {
--                                                                              sqlite3_bind_text(stmt, 3, 
-+                                                                              sqlite3_bind_text(stmt, 3,
-                                                                                                 (char *)prop->ns->href,
-                                                                                                 strlen((char *)prop->ns->href),
-                                                                                                 SQLITE_TRANSIENT);
-                                                                       } else {
--                                                                              sqlite3_bind_text(stmt, 3, 
-+                                                                              sqlite3_bind_text(stmt, 3,
-                                                                                                 "",
-                                                                                                 0,
-                                                                                                 SQLITE_TRANSIENT);
-                                                                       }
-                                                                       if (stmt == p->conf.stmt_update_prop) {
--                                                                              sqlite3_bind_text(stmt, 4, 
-+                                                                              sqlite3_bind_text(stmt, 4,
-                                                                                         (char *)xmlNodeGetContent(prop),
-                                                                                         strlen((char *)xmlNodeGetContent(prop)),
-                                                                                         SQLITE_TRANSIENT);
-                                                                       }
--                                                              
-+
-                                                                       if (SQLITE_DONE != (r = sqlite3_step(stmt))) {
--                                                                              log_error_write(srv, __FILE__, __LINE__, "ss", "sql-set failed:", sqlite3_errmsg(p->conf.sql));
-+                                                                              log_error_write(srv, __FILE__, __LINE__, "ss",
-+                                                                                              "sql-set failed:", sqlite3_errmsg(p->conf.sql));
-                                                                       }
-                                                               }
-                                                       }
-@@ -1804,7 +2119,7 @@
-                                                       goto propmatch_cleanup;
-                                               }
--      
-+
-                                               con->http_status = 400;
-                                       } else {
-                                               if (SQLITE_OK != sqlite3_exec(p->conf.sql, "COMMIT", NULL, NULL, &err)) {
-@@ -1815,12 +2130,13 @@
-                                               }
-                                               con->http_status = 200;
-                                       }
--                                      con->file_finished = 1;
-+                                      con->send->is_closed = 1;
-                                       return HANDLER_FINISHED;
-                               }
- propmatch_cleanup:
-+
-                               xmlFreeDoc(xml);
-                       } else {
-                               con->http_status = 400;
-@@ -1830,11 +2146,307 @@
- #endif
-               con->http_status = 501;
-               return HANDLER_FINISHED;
--      }
-+      case HTTP_METHOD_LOCK:
-+              /**
-+               * a mac wants to write
-+               *
-+               * LOCK /dav/expire.txt HTTP/1.1\r\n
-+               * User-Agent: WebDAVFS/1.3 (01308000) Darwin/8.1.0 (Power Macintosh)\r\n
-+               * Accept: * / *\r\n
-+               * Depth: 0\r\n
-+               * Timeout: Second-600\r\n
-+               * Content-Type: text/xml; charset=\"utf-8\"\r\n
-+               * Content-Length: 229\r\n
-+               * Connection: keep-alive\r\n
-+               * Host: 192.168.178.23:1025\r\n
-+               * \r\n
-+               * <?xml version=\"1.0\" encoding=\"utf-8\"?>\n
-+               * <D:lockinfo xmlns:D=\"DAV:\">\n
-+               *  <D:lockscope><D:exclusive/></D:lockscope>\n
-+               *  <D:locktype><D:write/></D:locktype>\n
-+               *  <D:owner>\n
-+               *   <D:href>http://www.apple.com/webdav_fs/</D:href>\n
-+               *  </D:owner>\n
-+               * </D:lockinfo>\n
-+               */
-+
-+              if (depth != 0 && depth != -1) {
-+                      con->http_status = 400;
-+
-+                      return HANDLER_FINISHED;
-+              }
-+
-+#ifdef USE_LOCKS
-+              if (con->request.content_length) {
-+                      xmlDocPtr xml;
-+                      buffer *hdr_if = NULL;
-+
-+                      if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "If"))) {
-+                              hdr_if = ds->value;
-+                      }
-+
-+                      /* we don't support Depth: Infinity on locks */
-+                      if (hdr_if == NULL && depth == -1) {
-+                              con->http_status = 409; /* Conflict */
-+
-+                              return HANDLER_FINISHED;
-+                      }
-+
-+                      if (1 == webdav_parse_chunkqueue(srv, con, p, con->recv, &xml)) {
-+                              xmlNode *rootnode = xmlDocGetRootElement(xml);
-+
-+                              assert(rootnode);
-+
-+                              if (0 == xmlStrcmp(rootnode->name, BAD_CAST "lockinfo")) {
-+                                      xmlNode *lockinfo;
-+                                      const xmlChar *lockscope = NULL, *locktype = NULL, *owner = NULL;
-+
-+                                      for (lockinfo = rootnode->children; lockinfo; lockinfo = lockinfo->next) {
-+                                              if (0 == xmlStrcmp(lockinfo->name, BAD_CAST "lockscope")) {
-+                                                      xmlNode *value;
-+                                                      for (value = lockinfo->children; value; value = value->next) {
-+                                                              if ((0 == xmlStrcmp(value->name, BAD_CAST "exclusive")) ||
-+                                                                  (0 == xmlStrcmp(value->name, BAD_CAST "shared"))) {
-+                                                                      lockscope = value->name;
-+                                                              } else {
-+                                                                      con->http_status = 400;
-+
-+                                                                      xmlFreeDoc(xml);
-+                                                                      return HANDLER_FINISHED;
-+                                                              }
-+                                                      }
-+                                              } else if (0 == xmlStrcmp(lockinfo->name, BAD_CAST "locktype")) {
-+                                                      xmlNode *value;
-+                                                      for (value = lockinfo->children; value; value = value->next) {
-+                                                              if ((0 == xmlStrcmp(value->name, BAD_CAST "write"))) {
-+                                                                      locktype = value->name;
-+                                                              } else {
-+                                                                      con->http_status = 400;
-+
-+                                                                      xmlFreeDoc(xml);
-+                                                                      return HANDLER_FINISHED;
-+                                                              }
-+                                                      }
-+
-+                                              } else if (0 == xmlStrcmp(lockinfo->name, BAD_CAST "owner")) {
-+                                              }
-+                                      }
-+
-+                                      if (lockscope && locktype) {
-+                                              sqlite3_stmt *stmt = p->conf.stmt_read_lock_by_uri;
-+
-+                                              /* is this resourse already locked ? */
-+
-+                                              /* SELECT locktoken, resource, lockscope, locktype, owner, depth, timeout
-+                                               *   FROM locks
-+                                               *  WHERE resource = ? */
-+
-+                                              if (stmt) {
-+
-+                                                      sqlite3_reset(stmt);
-+
-+                                                      sqlite3_bind_text(stmt, 1,
-+                                                                        p->uri.path->ptr,
-+                                                                        p->uri.path->used - 1,
-+                                                                        SQLITE_TRANSIENT);
-+
-+                                                      /* it is the PK */
-+                                                      while (SQLITE_ROW == sqlite3_step(stmt)) {
-+                                                              /* we found a lock
-+                                                               * 1. is it compatible ?
-+                                                               * 2. is it ours */
-+                                                              char *sql_lockscope = (char *)sqlite3_column_text(stmt, 2);
-+
-+                                                              if (strcmp(sql_lockscope, "exclusive")) {
-+                                                                      con->http_status = 423;
-+                                                              } else if (0 == xmlStrcmp(lockscope, BAD_CAST "exclusive")) {
-+                                                                      /* resourse is locked with a shared lock
-+                                                                       * client wants exclusive */
-+                                                                      con->http_status = 423;
-+                                                              }
-+                                                      }
-+                                                      if (con->http_status == 423) {
-+                                                              xmlFreeDoc(xml);
-+                                                              return HANDLER_FINISHED;
-+                                                      }
-+                                              }
-+
-+                                              stmt = p->conf.stmt_create_lock;
-+                                              if (stmt) {
-+                                                      /* create a lock-token */
-+                                                      uuid_t id;
-+                                                      char uuid[37] /* 36 + \0 */;
-+
-+                                                      uuid_generate(id);
-+                                                      uuid_unparse(id, uuid);
-+
-+                                                      buffer_copy_string(p->tmp_buf, "opaquelocktoken:");
-+                                                      buffer_append_string(p->tmp_buf, uuid);
-+
-+                                                      /* "CREATE TABLE locks ("
-+                                                       * "  locktoken TEXT NOT NULL,"
-+                                                       * "  resource TEXT NOT NULL,"
-+                                                       * "  lockscope TEXT NOT NULL,"
-+                                                       * "  locktype TEXT NOT NULL,"
-+                                                       * "  owner TEXT NOT NULL,"
-+                                                       * "  depth INT NOT NULL,"
-+                                                       */
-+
-+                                                      sqlite3_reset(stmt);
-+
-+                                                      sqlite3_bind_text(stmt, 1,
-+                                                                        CONST_BUF_LEN(p->tmp_buf),
-+                                                                        SQLITE_TRANSIENT);
-+
-+                                                      sqlite3_bind_text(stmt, 2,
-+                                                                        CONST_BUF_LEN(con->uri.path),
-+                                                                        SQLITE_TRANSIENT);
-+
-+                                                      sqlite3_bind_text(stmt, 3,
-+                                                                        lockscope,
-+                                                                        xmlStrlen(lockscope),
-+                                                                        SQLITE_TRANSIENT);
-+
-+                                                      sqlite3_bind_text(stmt, 4,
-+                                                                        locktype,
-+                                                                        xmlStrlen(locktype),
-+                                                                        SQLITE_TRANSIENT);
-+
-+                                                      /* owner */
-+                                                      sqlite3_bind_text(stmt, 5,
-+                                                                        "",
-+                                                                        0,
-+                                                                        SQLITE_TRANSIENT);
-+
-+                                                      /* depth */
-+                                                      sqlite3_bind_int(stmt, 6,
-+                                                                       depth);
-+
-+
-+                                                      if (SQLITE_DONE != sqlite3_step(stmt)) {
-+                                                              log_error_write(srv, __FILE__, __LINE__, "ss",
-+                                                                              "create lock:", sqlite3_errmsg(p->conf.sql));
-+                                                      }
-+
-+                                                      /* looks like we survived */
-+                                                      webdav_lockdiscovery(srv, con, p->tmp_buf, lockscope, locktype, depth);
-+
-+                                                      con->http_status = 201;
-+                                                      con->send->is_closed = 1;
-+                                              }
-+                                      }
-+                              }
-+
-+                              xmlFreeDoc(xml);
-+                              return HANDLER_FINISHED;
-+                      } else {
-+                              con->http_status = 400;
-+                              return HANDLER_FINISHED;
-+                      }
-+              } else {
-+
-+                      if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "If"))) {
-+                              buffer *locktoken = ds->value;
-+                              sqlite3_stmt *stmt = p->conf.stmt_refresh_lock;
-+
-+                              /* remove the < > around the token */
-+                              if (locktoken->used < 6) {
-+                                      con->http_status = 400;
-+
-+                                      return HANDLER_FINISHED;
-+                              }
-+
-+                              buffer_copy_string_len(p->tmp_buf, locktoken->ptr + 2, locktoken->used - 5);
-+
-+                              sqlite3_reset(stmt);
-+
-+                              sqlite3_bind_text(stmt, 1,
-+                                        CONST_BUF_LEN(p->tmp_buf),
-+                                        SQLITE_TRANSIENT);
-+
-+                              if (SQLITE_DONE != sqlite3_step(stmt)) {
-+                                      log_error_write(srv, __FILE__, __LINE__, "ss",
-+                                              "refresh lock:", sqlite3_errmsg(p->conf.sql));
-+                              }
-+
-+                              webdav_lockdiscovery(srv, con, p->tmp_buf, "exclusive", "write", 0);
-+
-+                              con->http_status = 200;
-+                              con->send->is_closed = 1;
-+                              return HANDLER_FINISHED;
-+                      } else {
-+                              /* we need a lock-token to refresh */
-+                              con->http_status = 400;
-+
-+                              return HANDLER_FINISHED;
-+                      }
-+              }
-+              break;
-+#else
-+              con->http_status = 501;
-+              return HANDLER_FINISHED;
-+#endif
-+      case HTTP_METHOD_UNLOCK:
-+#ifdef USE_LOCKS
-+              if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Lock-Token"))) {
-+                      buffer *locktoken = ds->value;
-+                      sqlite3_stmt *stmt = p->conf.stmt_remove_lock;
-+
-+                      /* remove the < > around the token */
-+                      if (locktoken->used < 4) {
-+                              con->http_status = 400;
-+
-+                              return HANDLER_FINISHED;
-+                      }
-+
-+                      /**
-+                       * FIXME:
-+                       *
-+                       * if the resourse is locked:
-+                       * - by us: unlock
-+                       * - by someone else: 401
-+                       * if the resource is not locked:
-+                       * - 412
-+                       *  */
-+
-+                      buffer_copy_string_len(p->tmp_buf, locktoken->ptr + 1, locktoken->used - 3);
-+
-+                      sqlite3_reset(stmt);
-+
-+                      sqlite3_bind_text(stmt, 1,
-+                                CONST_BUF_LEN(p->tmp_buf),
-+                                SQLITE_TRANSIENT);
-+
-+                      sqlite3_bind_text(stmt, 2,
-+                                CONST_BUF_LEN(con->uri.path),
-+                                SQLITE_TRANSIENT);
-+
-+                      if (SQLITE_DONE != sqlite3_step(stmt)) {
-+                              log_error_write(srv, __FILE__, __LINE__, "ss",
-+                                      "remove lock:", sqlite3_errmsg(p->conf.sql));
-+                      }
-+
-+                      if (0 == sqlite3_changes(p->conf.sql)) {
-+                              con->http_status = 401;
-+                      } else {
-+                              con->http_status = 204;
-+                      }
-+                      return HANDLER_FINISHED;
-+              } else {
-+                      /* we need a lock-token to unlock */
-+                      con->http_status = 400;
-+
-+                      return HANDLER_FINISHED;
-+              }
-+              break;
-+#else
-+              con->http_status = 501;
-+              return HANDLER_FINISHED;
-+#endif
-       default:
-               break;
-       }
--      
-+
-       /* not found */
-       return HANDLER_GO_ON;
- }
-@@ -1845,14 +2457,14 @@
- int mod_webdav_plugin_init(plugin *p) {
-       p->version     = LIGHTTPD_VERSION_ID;
-       p->name        = buffer_init_string("webdav");
--      
-+
-       p->init        = mod_webdav_init;
-       p->handle_uri_clean  = mod_webdav_uri_handler;
-       p->handle_physical   = mod_webdav_subrequest_handler;
-       p->set_defaults  = mod_webdav_set_defaults;
-       p->cleanup     = mod_webdav_free;
--      
-+
-       p->data        = NULL;
--      
-+
-       return 0;
- }
---- ../lighttpd-1.4.11/src/network.c   2006-03-04 16:45:46.000000000 +0200
-+++ lighttpd-1.5.0/src/network.c       2006-09-07 00:57:05.000000000 +0300
-@@ -1,14 +1,14 @@
- #include <sys/types.h>
- #include <sys/stat.h>
--#include <sys/time.h>
- #include <errno.h>
- #include <fcntl.h>
--#include <unistd.h>
- #include <string.h>
- #include <stdlib.h>
- #include <assert.h>
-+#include <stdio.h>
-+
- #include "network.h"
- #include "fdevent.h"
- #include "log.h"
-@@ -19,11 +19,12 @@
- #include "network_backends.h"
- #include "sys-mmap.h"
- #include "sys-socket.h"
-+#include "sys-files.h"
- #ifdef USE_OPENSSL
--# include <openssl/ssl.h> 
--# include <openssl/err.h> 
--# include <openssl/rand.h> 
-+# include <openssl/ssl.h>
-+# include <openssl/err.h>
-+# include <openssl/rand.h>
- #endif
- handler_t network_server_handle_fdevent(void *s, void *context, int revents) {
-@@ -31,25 +32,25 @@
-       server_socket *srv_socket = (server_socket *)context;
-       connection *con;
-       int loops = 0;
--      
-+
-       UNUSED(context);
--      
-+
-       if (revents != FDEVENT_IN) {
--              log_error_write(srv, __FILE__, __LINE__, "sdd", 
-+              log_error_write(srv, __FILE__, __LINE__, "sdd",
-                               "strange event for server socket",
--                              srv_socket->fd,
-+                              srv_socket->sock->fd,
-                               revents);
-               return HANDLER_ERROR;
-       }
-       /* accept()s at most 100 connections directly
-        *
--       * we jump out after 100 to give the waiting connections a chance */    
-+       * we jump out after 100 to give the waiting connections a chance */
-       for (loops = 0; loops < 100 && NULL != (con = connection_accept(srv, srv_socket)); loops++) {
-               handler_t r;
--              
-+
-               connection_state_machine(srv, con);
--              
-+
-               switch(r = plugins_call_handle_joblist(srv, con)) {
-               case HANDLER_FINISHED:
-               case HANDLER_GO_ON:
-@@ -72,18 +73,18 @@
-       buffer *b;
-       int is_unix_domain_socket = 0;
-       int fd;
--      
-+
- #ifdef SO_ACCEPTFILTER
-       struct accept_filter_arg afa;
- #endif
--#ifdef __WIN32
-+#ifdef _WIN32
-       WORD wVersionRequested;
-       WSADATA wsaData;
-       int err;
--       
-+
-       wVersionRequested = MAKEWORD( 2, 2 );
--       
-+
-       err = WSAStartup( wVersionRequested, &wsaData );
-       if ( err != 0 ) {
-                   /* Tell the user that we could not find a usable */
-@@ -91,37 +92,37 @@
-                   return -1;
-       }
- #endif
--      
-+
-       srv_socket = calloc(1, sizeof(*srv_socket));
--      srv_socket->fd = -1;
--      
-+      srv_socket->sock = iosocket_init();
-+
-       srv_socket->srv_token = buffer_init();
-       buffer_copy_string_buffer(srv_socket->srv_token, host_token);
--      
-+
-       b = buffer_init();
-       buffer_copy_string_buffer(b, host_token);
--      
--      /* ipv4:port 
-+
-+      /* ipv4:port
-        * [ipv6]:port
-        */
-       if (NULL == (sp = strrchr(b->ptr, ':'))) {
-               log_error_write(srv, __FILE__, __LINE__, "sb", "value of $SERVER[\"socket\"] has to be \"ip:port\".", b);
--              
-+
-               return -1;
-       }
--      
-+
-       host = b->ptr;
--      
-+
-       /* check for [ and ] */
-       if (b->ptr[0] == '[' && *(sp-1) == ']') {
-               *(sp-1) = '\0';
-               host++;
--              
-+
-               s->use_ipv6 = 1;
-       }
--      
-+
-       *(sp++) = '\0';
--      
-+
-       port = strtol(sp, NULL, 10);
-       if (host[0] == '/') {
-@@ -129,18 +130,18 @@
-               is_unix_domain_socket = 1;
-       } else if (port == 0 || port > 65535) {
-               log_error_write(srv, __FILE__, __LINE__, "sd", "port out of range:", port);
--      
-+
-               return -1;
-       }
--      
-+
-       if (*host == '\0') host = NULL;
-       if (is_unix_domain_socket) {
- #ifdef HAVE_SYS_UN_H
-               srv_socket->addr.plain.sa_family = AF_UNIX;
--              
--              if (-1 == (srv_socket->fd = socket(srv_socket->addr.plain.sa_family, SOCK_STREAM, 0))) {
-+
-+              if (-1 == (srv_socket->sock->fd = socket(srv_socket->addr.plain.sa_family, SOCK_STREAM, 0))) {
-                       log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed:", strerror(errno));
-                       return -1;
-               }
-@@ -154,32 +155,32 @@
- #ifdef HAVE_IPV6
-       if (s->use_ipv6) {
-               srv_socket->addr.plain.sa_family = AF_INET6;
--              
--              if (-1 == (srv_socket->fd = socket(srv_socket->addr.plain.sa_family, SOCK_STREAM, IPPROTO_TCP))) {
-+
-+              if (-1 == (srv_socket->sock->fd = socket(srv_socket->addr.plain.sa_family, SOCK_STREAM, IPPROTO_TCP))) {
-                       log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed:", strerror(errno));
-                       return -1;
-               }
-               srv_socket->use_ipv6 = 1;
-       }
- #endif
--                              
--      if (srv_socket->fd == -1) {
-+
-+      if (srv_socket->sock->fd == -1) {
-               srv_socket->addr.plain.sa_family = AF_INET;
--              if (-1 == (srv_socket->fd = socket(srv_socket->addr.plain.sa_family, SOCK_STREAM, IPPROTO_TCP))) {
-+              if (-1 == (srv_socket->sock->fd = socket(srv_socket->addr.plain.sa_family, SOCK_STREAM, IPPROTO_TCP))) {
-                       log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed:", strerror(errno));
-                       return -1;
-               }
-       }
--      
-+
-       /* */
--      srv->cur_fds = srv_socket->fd;
--      
-+      srv->cur_fds = srv_socket->sock->fd;
-+
-       val = 1;
--      if (setsockopt(srv_socket->fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) {
-+      if (setsockopt(srv_socket->sock->fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) {
-               log_error_write(srv, __FILE__, __LINE__, "ss", "socketsockopt failed:", strerror(errno));
-               return -1;
-       }
--      
-+
-       switch(srv_socket->addr.plain.sa_family) {
- #ifdef HAVE_IPV6
-       case AF_INET6:
-@@ -190,23 +191,23 @@
-               } else {
-                       struct addrinfo hints, *res;
-                       int r;
--                      
-+
-                       memset(&hints, 0, sizeof(hints));
--                      
-+
-                       hints.ai_family   = AF_INET6;
-                       hints.ai_socktype = SOCK_STREAM;
-                       hints.ai_protocol = IPPROTO_TCP;
--                      
-+
-                       if (0 != (r = getaddrinfo(host, NULL, &hints, &res))) {
--                              log_error_write(srv, __FILE__, __LINE__, 
--                                              "sssss", "getaddrinfo failed: ", 
-+                              log_error_write(srv, __FILE__, __LINE__,
-+                                              "sssss", "getaddrinfo failed: ",
-                                               gai_strerror(r), "'", host, "'");
--                              
-+
-                               return -1;
-                       }
--                      
-+
-                       memcpy(&(srv_socket->addr), res->ai_addr, res->ai_addrlen);
--                      
-+
-                       freeaddrinfo(res);
-               }
-               srv_socket->addr.ipv6.sin6_port = htons(port);
-@@ -221,33 +222,34 @@
-               } else {
-                       struct hostent *he;
-                       if (NULL == (he = gethostbyname(host))) {
--                              log_error_write(srv, __FILE__, __LINE__, 
--                                              "sds", "gethostbyname failed: ", 
-+                              log_error_write(srv, __FILE__, __LINE__,
-+                                              "sds", "gethostbyname failed: ",
-                                               h_errno, host);
-                               return -1;
-                       }
--                      
-+
-                       if (he->h_addrtype != AF_INET) {
-                               log_error_write(srv, __FILE__, __LINE__, "sd", "addr-type != AF_INET: ", he->h_addrtype);
-                               return -1;
-                       }
--                      
-+
-                       if (he->h_length != sizeof(struct in_addr)) {
-                               log_error_write(srv, __FILE__, __LINE__, "sd", "addr-length != sizeof(in_addr): ", he->h_length);
-                               return -1;
-                       }
--                      
-+
-                       memcpy(&(srv_socket->addr.ipv4.sin_addr.s_addr), he->h_addr_list[0], he->h_length);
-               }
-               srv_socket->addr.ipv4.sin_port = htons(port);
--              
-+
-               addr_len = sizeof(struct sockaddr_in);
--              
-+
-               break;
-+#ifndef _WIN32
-       case AF_UNIX:
-               srv_socket->addr.un.sun_family = AF_UNIX;
-               strcpy(srv_socket->addr.un.sun_path, host);
--              
-+
- #ifdef SUN_LEN
-               addr_len = SUN_LEN(&srv_socket->addr.un);
- #else
-@@ -256,11 +258,11 @@
- #endif
-               /* check if the socket exists and try to connect to it. */
--              if (-1 != (fd = connect(srv_socket->fd, (struct sockaddr *) &(srv_socket->addr), addr_len))) {
-+              if (-1 != (fd = connect(srv_socket->sock->fd, (struct sockaddr *) &(srv_socket->addr), addr_len))) {
-                       close(fd);
--                      log_error_write(srv, __FILE__, __LINE__, "ss", 
--                              "server socket is still in use:", 
-+                      log_error_write(srv, __FILE__, __LINE__, "ss",
-+                              "server socket is still in use:",
-                               host);
-@@ -275,88 +277,89 @@
-               case ENOENT:
-                       break;
-               default:
--                      log_error_write(srv, __FILE__, __LINE__, "sds", 
--                              "testing socket failed:", 
-+                      log_error_write(srv, __FILE__, __LINE__, "sds",
-+                              "testing socket failed:",
-                               host, strerror(errno));
-                       return -1;
-               }
-               break;
-+#endif
-       default:
-               addr_len = 0;
--              
-+
-               return -1;
-       }
--      
--      if (0 != bind(srv_socket->fd, (struct sockaddr *) &(srv_socket->addr), addr_len)) {
-+
-+      if (0 != bind(srv_socket->sock->fd, (struct sockaddr *) &(srv_socket->addr), addr_len)) {
-               switch(srv_socket->addr.plain.sa_family) {
-               case AF_UNIX:
--                      log_error_write(srv, __FILE__, __LINE__, "sds", 
--                                      "can't bind to socket:", 
-+                      log_error_write(srv, __FILE__, __LINE__, "sds",
-+                                      "can't bind to socket:",
-                                       host, strerror(errno));
-                       break;
-               default:
--                      log_error_write(srv, __FILE__, __LINE__, "ssds", 
--                                      "can't bind to port:", 
-+                      log_error_write(srv, __FILE__, __LINE__, "ssds",
-+                                      "can't bind to port:",
-                                       host, port, strerror(errno));
-                       break;
-               }
-               return -1;
-       }
--      
--      if (-1 == listen(srv_socket->fd, 128 * 8)) {
-+
-+      if (-1 == listen(srv_socket->sock->fd, 128 * 8)) {
-               log_error_write(srv, __FILE__, __LINE__, "ss", "listen failed: ", strerror(errno));
-               return -1;
-       }
--      
-+
-       if (s->is_ssl) {
- #ifdef USE_OPENSSL
-               if (srv->ssl_is_init == 0) {
-                       SSL_load_error_strings();
-                       SSL_library_init();
-                       srv->ssl_is_init = 1;
--                      
-+
-                       if (0 == RAND_status()) {
--                              log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", 
-+                              log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
-                                               "not enough entropy in the pool");
-                               return -1;
-                       }
-               }
--              
-+
-               if (NULL == (s->ssl_ctx = SSL_CTX_new(SSLv23_server_method()))) {
--                      log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", 
-+                      log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
-                                       ERR_error_string(ERR_get_error(), NULL));
-                       return -1;
-               }
--              
-+
-               if (buffer_is_empty(s->ssl_pemfile)) {
-                       log_error_write(srv, __FILE__, __LINE__, "s", "ssl.pemfile has to be set");
-                       return -1;
-               }
--              
-+
-               if (!buffer_is_empty(s->ssl_ca_file)) {
-                       if (1 != SSL_CTX_load_verify_locations(s->ssl_ctx, s->ssl_ca_file->ptr, NULL)) {
--                              log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", 
-+                              log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
-                                               ERR_error_string(ERR_get_error(), NULL), s->ssl_ca_file);
-                               return -1;
-                       }
-               }
--              
-+
-               if (SSL_CTX_use_certificate_file(s->ssl_ctx, s->ssl_pemfile->ptr, SSL_FILETYPE_PEM) < 0) {
--                      log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", 
-+                      log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
-                                       ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile);
-                       return -1;
-               }
--              
-+
-               if (SSL_CTX_use_PrivateKey_file (s->ssl_ctx, s->ssl_pemfile->ptr, SSL_FILETYPE_PEM) < 0) {
--                      log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", 
-+                      log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
-                                       ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile);
-                       return -1;
-               }
--              
-+
-               if (SSL_CTX_check_private_key(s->ssl_ctx) != 1) {
--                      log_error_write(srv, __FILE__, __LINE__, "sssb", "SSL:", 
-+                      log_error_write(srv, __FILE__, __LINE__, "sssb", "SSL:",
-                                       "Private key does not match the certificate public key, reason:",
-                                       ERR_error_string(ERR_get_error(), NULL),
-                                       s->ssl_pemfile);
-@@ -364,15 +367,15 @@
-               }
-               srv_socket->ssl_ctx = s->ssl_ctx;
- #else
--              
-+
-               buffer_free(srv_socket->srv_token);
-               free(srv_socket);
--              
-+
-               buffer_free(b);
--              
--              log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", 
-+
-+              log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
-                               "ssl requested but openssl support is not compiled in");
--              
-+
-               return -1;
- #endif
-       } else {
-@@ -383,17 +386,16 @@
-                */
-               memset(&afa, 0, sizeof(afa));
-               strcpy(afa.af_name, "httpready");
--              if (setsockopt(srv_socket->fd, SOL_SOCKET, SO_ACCEPTFILTER, &afa, sizeof(afa)) < 0) {
-+              if (setsockopt(srv_socket->sock->fd, SOL_SOCKET, SO_ACCEPTFILTER, &afa, sizeof(afa)) < 0) {
-                       if (errno != ENOENT) {
-                               log_error_write(srv, __FILE__, __LINE__, "ss", "can't set accept-filter 'httpready': ", strerror(errno));
-                       }
-               }
- #endif
-       }
--      
-+
-       srv_socket->is_ssl = s->is_ssl;
--      srv_socket->fde_ndx = -1;
--      
-+
-       if (srv->srv_sockets.size == 0) {
-               srv->srv_sockets.size = 4;
-               srv->srv_sockets.used = 0;
-@@ -402,11 +404,10 @@
-               srv->srv_sockets.size += 4;
-               srv->srv_sockets.ptr = realloc(srv->srv_sockets.ptr, srv->srv_sockets.size * sizeof(server_socket));
-       }
--      
-+
-       srv->srv_sockets.ptr[srv->srv_sockets.used++] = srv_socket;
--      
-       buffer_free(b);
--      
-+
-       return 0;
- }
-@@ -414,45 +415,60 @@
-       size_t i;
-       for (i = 0; i < srv->srv_sockets.used; i++) {
-               server_socket *srv_socket = srv->srv_sockets.ptr[i];
--              
--              if (srv_socket->fd != -1) {
-+
-+              if (srv_socket->sock->fd != -1) {
-                       /* check if server fd are already registered */
--                      if (srv_socket->fde_ndx != -1) {
--                              fdevent_event_del(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd);
--                              fdevent_unregister(srv->ev, srv_socket->fd);
-+                      if (srv_socket->sock->fde_ndx != -1) {
-+                              fdevent_event_del(srv->ev, srv_socket->sock);
-+                              fdevent_unregister(srv->ev, srv_socket->sock);
-                       }
--              
--                      close(srv_socket->fd);
-+
-+                      closesocket(srv_socket->sock->fd);
-+              }
-+
-+              if (srv_socket->is_ssl) {
-+#ifdef USE_OPENSSL
-+                      SSL_CTX_free(srv_socket->ssl_ctx);
-+#endif
-               }
--              
-+
-+              iosocket_free(srv_socket->sock);
-+
-               buffer_free(srv_socket->srv_token);
--              
-+
-               free(srv_socket);
-       }
--      
-+
-+#ifdef USE_OPENSSL
-+      ERR_free_strings();
-+#endif
-       free(srv->srv_sockets.ptr);
--      
-+
-       return 0;
- }
- typedef enum {
-       NETWORK_BACKEND_UNSET,
-+
-       NETWORK_BACKEND_WRITE,
-       NETWORK_BACKEND_WRITEV,
-       NETWORK_BACKEND_LINUX_SENDFILE,
-       NETWORK_BACKEND_FREEBSD_SENDFILE,
--      NETWORK_BACKEND_SOLARIS_SENDFILEV
-+      NETWORK_BACKEND_SOLARIS_SENDFILEV,
-+
-+    NETWORK_BACKEND_WIN32_SEND,
-+    NETWORK_BACKEND_WIN32_TRANSMITFILE,
- } network_backend_t;
- int network_init(server *srv) {
-       buffer *b;
-       size_t i;
-       network_backend_t backend;
--      
--      struct nb_map { 
--              network_backend_t nb; 
--              const char *name; 
--      } network_backends[] = { 
-+
-+      struct nb_map {
-+              network_backend_t nb;
-+              const char *name;
-+      } network_backends[] = {
-               /* lowest id wins */
- #if defined USE_LINUX_SENDFILE
-               { NETWORK_BACKEND_LINUX_SENDFILE,       "linux-sendfile" },
-@@ -466,21 +482,30 @@
- #if defined USE_WRITEV
-               { NETWORK_BACKEND_WRITEV,               "writev" },
- #endif
-+#if defined USE_WRITE
-               { NETWORK_BACKEND_WRITE,                "write" },
-+#endif
-+#if defined USE_WIN32_TRANSMITFILE
-+              { NETWORK_BACKEND_WIN32_TRANSMITFILE,   "win32-transmitfile" },
-+#endif
-+#if defined USE_WIN32_SEND
-+              { NETWORK_BACKEND_WIN32_SEND,           "win32-send" },
-+#endif
-+
-               { NETWORK_BACKEND_UNSET,                NULL }
-       };
--      
-+
-       b = buffer_init();
--              
-+
-       buffer_copy_string_buffer(b, srv->srvconf.bindhost);
-       buffer_append_string(b, ":");
-       buffer_append_long(b, srv->srvconf.port);
--      
-+
-       if (0 != network_server_init(srv, b, srv->config_storage[0])) {
-               return -1;
-       }
-       buffer_free(b);
--              
-+
- #ifdef USE_OPENSSL
-       srv->network_ssl_backend_write = network_write_chunkqueue_openssl;
- #endif
-@@ -500,54 +525,80 @@
-               if (NULL == network_backends[i].name) {
-                       /* we don't know it */
--                      log_error_write(srv, __FILE__, __LINE__, "sb", 
--                                      "server.network-backend has a unknown value:", 
-+                      log_error_write(srv, __FILE__, __LINE__, "sb",
-+                                      "server.network-backend has a unknown value:",
-                                       srv->srvconf.network_backend);
-                       return -1;
-               }
-       }
-+#define SET_NETWORK_BACKEND(read, write) \
-+    srv->network_backend_write = network_write_chunkqueue_##write;\
-+    srv->network_backend_read = network_read_chunkqueue_##read
-+
-+#define SET_NETWORK_BACKEND_SSL(read, write) \
-+    srv->network_ssl_backend_write = network_write_chunkqueue_##write;\
-+    srv->network_ssl_backend_read = network_read_chunkqueue_##read
-+
-       switch(backend) {
-+
-+#ifdef USE_WIN32_SEND
-+      case NETWORK_BACKEND_WIN32_SEND:
-+        SET_NETWORK_BACKEND(win32recv, win32send);
-+              break;
-+#ifdef USE_WIN32_TRANSMITFILE
-+      case NETWORK_BACKEND_WIN32_TRANSMITFILE:
-+        SET_NETWORK_BACKEND(win32recv, win32transmitfile);
-+              break;
-+#endif
-+#endif
-+
-+#ifdef USE_WRITE
-       case NETWORK_BACKEND_WRITE:
--              srv->network_backend_write = network_write_chunkqueue_write;
-+        SET_NETWORK_BACKEND(read, write);
-               break;
-+
- #ifdef USE_WRITEV
-       case NETWORK_BACKEND_WRITEV:
--              srv->network_backend_write = network_write_chunkqueue_writev;
-+        SET_NETWORK_BACKEND(read, writev);
-               break;
- #endif
- #ifdef USE_LINUX_SENDFILE
-       case NETWORK_BACKEND_LINUX_SENDFILE:
--              srv->network_backend_write = network_write_chunkqueue_linuxsendfile; 
-+        SET_NETWORK_BACKEND(read, linuxsendfile);
-               break;
- #endif
- #ifdef USE_FREEBSD_SENDFILE
-       case NETWORK_BACKEND_FREEBSD_SENDFILE:
--              srv->network_backend_write = network_write_chunkqueue_freebsdsendfile; 
-+        SET_NETWORK_BACKEND(read, freebsdsendfile);
-               break;
- #endif
- #ifdef USE_SOLARIS_SENDFILEV
-       case NETWORK_BACKEND_SOLARIS_SENDFILEV:
--              srv->network_backend_write = network_write_chunkqueue_solarissendfilev; 
-+        SET_NETWORK_BACKEND(read, solarissendfilev);
-               break;
- #endif
-+#endif
-       default:
-               return -1;
-       }
-+#ifdef USE_OPENSSL
-+        SET_NETWORK_BACKEND_SSL(openssl, openssl);
-+#endif
-       /* check for $SERVER["socket"] */
-       for (i = 1; i < srv->config_context->used; i++) {
-               data_config *dc = (data_config *)srv->config_context->data[i];
-               specific_config *s = srv->config_storage[i];
-               size_t j;
--              
-+
-               /* not our stage */
-               if (COMP_SERVER_SOCKET != dc->comp) continue;
--              
-+
-               if (dc->cond != CONFIG_COND_EQ) {
-                       log_error_write(srv, __FILE__, __LINE__, "s", "only == is allowed for $SERVER[\"socket\"].");
--                      
-+
-                       return -1;
-               }
-@@ -558,36 +609,47 @@
-                               break;
-                       }
-               }
--              
-+
-               if (j == srv->srv_sockets.used) {
-                       if (0 != network_server_init(srv, dc->string, s)) return -1;
-               }
-       }
--      
-+
-       return 0;
- }
- int network_register_fdevents(server *srv) {
-       size_t i;
--      
-       if (-1 == fdevent_reset(srv->ev)) {
-               return -1;
-       }
--      
-       /* register fdevents after reset */
-       for (i = 0; i < srv->srv_sockets.used; i++) {
-               server_socket *srv_socket = srv->srv_sockets.ptr[i];
--              
--              fdevent_register(srv->ev, srv_socket->fd, network_server_handle_fdevent, srv_socket);
--              fdevent_event_add(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd, FDEVENT_IN);
-+              fdevent_register(srv->ev, srv_socket->sock, network_server_handle_fdevent, srv_socket);
-+              fdevent_event_add(srv->ev, srv_socket->sock, FDEVENT_IN);
-       }
-       return 0;
- }
--int network_write_chunkqueue(server *srv, connection *con, chunkqueue *cq) {
--      int ret = -1;
-+network_status_t network_read(server *srv, connection *con, iosocket *sock, chunkqueue *cq) {
-+      server_socket *srv_socket = con->srv_socket;
-+
-+      if (srv_socket->is_ssl) {
-+#ifdef USE_OPENSSL
-+              return srv->network_ssl_backend_read(srv, con, sock, cq);
-+#else
-+              return NETWORK_STATUS_FATAL_ERROR;
-+#endif
-+      } else {
-+              return srv->network_backend_read(srv, con, sock, cq);
-+      }
-+}
-+
-+network_status_t network_write_chunkqueue(server *srv, connection *con, chunkqueue *cq) {
-+      network_status_t ret = NETWORK_STATUS_UNSET;
-       off_t written = 0;
--#ifdef TCP_CORK       
-+#ifdef TCP_CORK
-       int corked = 0;
- #endif
-       server_socket *srv_socket = con->srv_socket;
-@@ -600,37 +662,42 @@
-               joblist_append(srv, con);
-               return 1;
--      }  
-+      }
-       written = cq->bytes_out;
--#ifdef TCP_CORK       
-+#ifdef TCP_CORK
-       /* Linux: put a cork into the socket as we want to combine the write() calls
-        * but only if we really have multiple chunks
-        */
-       if (cq->first && cq->first->next) {
-               corked = 1;
--              setsockopt(con->fd, IPPROTO_TCP, TCP_CORK, &corked, sizeof(corked));
-+              setsockopt(con->sock->fd, IPPROTO_TCP, TCP_CORK, &corked, sizeof(corked));
-       }
- #endif
--      
-+
-       if (srv_socket->is_ssl) {
- #ifdef USE_OPENSSL
--              ret = srv->network_ssl_backend_write(srv, con, con->ssl, cq);
-+              ret = srv->network_ssl_backend_write(srv, con, con->sock, cq);
- #endif
-       } else {
--              ret = srv->network_backend_write(srv, con, con->fd, cq);
-+              ret = srv->network_backend_write(srv, con, con->sock, cq);
-       }
--      
--      if (ret >= 0) {
-+
-+    switch (ret) {
-+    case NETWORK_STATUS_WAIT_FOR_EVENT:
-+    case NETWORK_STATUS_SUCCESS:
-               chunkqueue_remove_finished_chunks(cq);
--              ret = chunkqueue_is_empty(cq) ? 0 : 1;
-+
-+        break;
-+    default:
-+        break;
-       }
--      
-+
- #ifdef TCP_CORK
-       if (corked) {
-               corked = 0;
--              setsockopt(con->fd, IPPROTO_TCP, TCP_CORK, &corked, sizeof(corked));
-+              setsockopt(con->sock->fd, IPPROTO_TCP, TCP_CORK, &corked, sizeof(corked));
-       }
- #endif
-@@ -639,13 +706,13 @@
-       con->bytes_written_cur_second += written;
-       *(con->conf.global_bytes_per_second_cnt_ptr) += written;
--      
-+
-       if (con->conf.kbytes_per_second &&
-           (con->bytes_written_cur_second > con->conf.kbytes_per_second * 1024)) {
-               /* we reached the traffic limit */
-               con->traffic_limit_reached = 1;
-               joblist_append(srv, con);
--      }  
-+      }
-       return ret;
- }
---- ../lighttpd-1.4.11/src/network.h   2005-08-11 01:26:42.000000000 +0300
-+++ lighttpd-1.5.0/src/network.h       2006-09-07 00:57:05.000000000 +0300
-@@ -3,11 +3,13 @@
- #include "server.h"
--int network_write_chunkqueue(server *srv, connection *con, chunkqueue *c);
-+network_status_t network_write_chunkqueue(server *srv, connection *con, chunkqueue *c);
-+network_status_t network_read(server *srv, connection *con, iosocket *sock, chunkqueue *c);
- int network_init(server *srv);
- int network_close(server *srv);
- int network_register_fdevents(server *srv);
-+handler_t network_server_handle_fdevent(void *s, void *context, int revents);
- #endif
---- ../lighttpd-1.4.11/src/network_backends.h  2005-10-24 15:13:51.000000000 +0300
-+++ lighttpd-1.5.0/src/network_backends.h      2006-07-18 13:03:40.000000000 +0300
-@@ -43,16 +43,47 @@
- # define USE_AIX_SENDFILE
- #endif
-+/**
-+* unix can use read/write or recv/send on sockets
-+* win32 only recv/send
-+*/
-+#ifdef _WIN32
-+# define USE_WIN32_SEND
-+/* wait for async-io support
-+# define USE_WIN32_TRANSMITFILE
-+*/
-+#else
-+# define USE_WRITE
-+#endif
-+
- #include "base.h"
-+#include "network.h"
-+
-+#define NETWORK_BACKEND_WRITE_CHUNK(x) \
-+    network_status_t network_write_chunkqueue_##x(server *srv, connection *con, iosocket *sock, chunkqueue *cq, chunk *c)
-+
-+#define NETWORK_BACKEND_WRITE(x) \
-+    network_status_t network_write_chunkqueue_##x(server *srv, connection *con, iosocket *sock, chunkqueue *cq)
-+#define NETWORK_BACKEND_READ(x) \
-+    network_status_t network_read_chunkqueue_##x(server *srv, connection *con, iosocket *sock, chunkqueue *cq)
-+
-+NETWORK_BACKEND_WRITE_CHUNK(writev_mem);
-+
-+NETWORK_BACKEND_WRITE(write);
-+NETWORK_BACKEND_WRITE(writev);
-+NETWORK_BACKEND_WRITE(linuxsendfile);
-+NETWORK_BACKEND_WRITE(freebsdsendfile);
-+NETWORK_BACKEND_WRITE(solarissendfilev);
-+
-+NETWORK_BACKEND_WRITE(win32transmitfile);
-+NETWORK_BACKEND_WRITE(win32send);
-+NETWORK_BACKEND_READ(read);
-+NETWORK_BACKEND_READ(win32recv);
--int network_write_chunkqueue_write(server *srv, connection *con, int fd, chunkqueue *cq);
--int network_write_chunkqueue_writev(server *srv, connection *con, int fd, chunkqueue *cq);
--int network_write_chunkqueue_linuxsendfile(server *srv, connection *con, int fd, chunkqueue *cq);
--int network_write_chunkqueue_freebsdsendfile(server *srv, connection *con, int fd, chunkqueue *cq);
--int network_write_chunkqueue_solarissendfilev(server *srv, connection *con, int fd, chunkqueue *cq);
- #ifdef USE_OPENSSL
--int network_write_chunkqueue_openssl(server *srv, connection *con, SSL *ssl, chunkqueue *cq);
-+NETWORK_BACKEND_WRITE(openssl);
-+NETWORK_BACKEND_READ(openssl);
- #endif
- #endif
---- ../lighttpd-1.4.11/src/network_freebsd_sendfile.c  2005-10-22 12:28:18.000000000 +0300
-+++ lighttpd-1.5.0/src/network_freebsd_sendfile.c      2006-09-07 00:57:05.000000000 +0300
-@@ -26,182 +26,115 @@
- #ifndef UIO_MAXIOV
- # ifdef __FreeBSD__
--/* FreeBSD 4.7, 4.9 defined it in sys/uio.h only if _KERNEL is specified */ 
-+/* FreeBSD 4.7, 4.9 defined it in sys/uio.h only if _KERNEL is specified */
- #  define UIO_MAXIOV 1024
- # endif
- #endif
--int network_write_chunkqueue_freebsdsendfile(server *srv, connection *con, int fd, chunkqueue *cq) {
-+NETWORK_BACKEND_WRITE(freebsdsendfile) {
-       chunk *c;
-       size_t chunks_written = 0;
--      
-+
-       for(c = cq->first; c; c = c->next, chunks_written++) {
-+              chunk *tc;
-               int chunk_finished = 0;
--              
-+              network_status_t ret;
-+
-               switch(c->type) {
--              case MEM_CHUNK: {
--                      char * offset;
--                      size_t toSend;
--                      ssize_t r;
--                      
--                      size_t num_chunks, i;
--                      struct iovec chunks[UIO_MAXIOV];
--                      chunk *tc;
--                      size_t num_bytes = 0;
--                      
--                      /* we can't send more then SSIZE_MAX bytes in one chunk */
--                      
--                      /* build writev list 
--                       * 
--                       * 1. limit: num_chunks < UIO_MAXIOV
--                       * 2. limit: num_bytes < SSIZE_MAX
--                       */
--                      for(num_chunks = 0, tc = c; tc && tc->type == MEM_CHUNK && num_chunks < UIO_MAXIOV; num_chunks++, tc = tc->next);
--                      
--                      for(tc = c, i = 0; i < num_chunks; tc = tc->next, i++) {
--                              if (tc->mem->used == 0) {
--                                      chunks[i].iov_base = tc->mem->ptr;
--                                      chunks[i].iov_len  = 0;
--                              } else {
--                                      offset = tc->mem->ptr + tc->offset;
--                                      toSend = tc->mem->used - 1 - tc->offset;
--                                      
--                                      chunks[i].iov_base = offset;
--                                      
--                                      /* protect the return value of writev() */
--                                      if (toSend > SSIZE_MAX ||
--                                          num_bytes + toSend > SSIZE_MAX) {
--                                              chunks[i].iov_len = SSIZE_MAX - num_bytes;
--                                              
--                                              num_chunks = i + 1;
--                                              break;
--                                      } else {
--                                              chunks[i].iov_len = toSend;
--                                      }
--                               
--                                      num_bytes += toSend;
--                              }
--                      }
--                      
--                      if ((r = writev(fd, chunks, num_chunks)) < 0) {
--                              switch (errno) {
--                              case EAGAIN:
--                              case EINTR:
--                                      r = 0;
--                                      break;
--                              case EPIPE:
--                              case ECONNRESET:
--                                      return -2;
--                              default:
--                                      log_error_write(srv, __FILE__, __LINE__, "ssd", 
--                                                      "writev failed:", strerror(errno), fd);
--                                      
--                                      return -1;
--                              }
-+              case MEM_CHUNK:
-+                      ret = network_write_chunkqueue_writev_mem(srv, con, sock, cq, c);
--                              r = 0;
--                      }
--                      
--                      /* check which chunks have been written */
--                      cq->bytes_out += r;
--                      
--                      for(i = 0, tc = c; i < num_chunks; i++, tc = tc->next) {
--                              if (r >= (ssize_t)chunks[i].iov_len) {
--                                      /* written */
--                                      r -= chunks[i].iov_len;
--                                      tc->offset += chunks[i].iov_len;
--                                      
-+                      /* check which chunks are finished now */
-+                      for (tc = c; tc; tc = tc->next) {
-+                              /* finished the chunk */
-+                              if (tc->offset == tc->mem->used - 1) {
-+                                      /* skip the first c->next as that will be done by the c = c->next in the other for()-loop */
-                                       if (chunk_finished) {
--                                              /* skip the chunks from further touches */
--                                              chunks_written++;
-                                               c = c->next;
-                                       } else {
--                                              /* chunks_written + c = c->next is done in the for()*/
--                                              chunk_finished++;
-+                                              chunk_finished = 1;
-                                       }
-                               } else {
--                                      /* partially written */
--                                      
--                                      tc->offset += r;
--                                      chunk_finished = 0;
--                                      
-                                       break;
-                               }
-                       }
--                      
-+
-+                      if (ret != NETWORK_STATUS_SUCCESS) {
-+                              return ret;
-+                      }
-+
-                       break;
--              }
-               case FILE_CHUNK: {
-                       off_t offset, r;
-                       size_t toSend;
-                       stat_cache_entry *sce = NULL;
-                       int ifd;
--                      
-+
-                       if (HANDLER_ERROR == stat_cache_get_entry(srv, con, c->file.name, &sce)) {
-                               log_error_write(srv, __FILE__, __LINE__, "sb",
-                                               strerror(errno), c->file.name);
--                              return -1;
-+                              return NETWORK_STATUS_FATAL_ERROR;
-                       }
--                      
-+
-                       offset = c->file.start + c->offset;
-                       /* limit the toSend to 2^31-1 bytes in a chunk */
--                      toSend = c->file.length - c->offset > ((1 << 30) - 1) ? 
-+                      toSend = c->file.length - c->offset > ((1 << 30) - 1) ?
-                               ((1 << 30) - 1) : c->file.length - c->offset;
--                              
-+
-                       if (offset > sce->st.st_size) {
-                               log_error_write(srv, __FILE__, __LINE__, "sb", "file was shrinked:", c->file.name);
--                              
--                              return -1;
-+
-+                              return NETWORK_STATUS_FATAL_ERROR;
-                       }
--                      
-+
-                       if (-1 == (ifd = open(c->file.name->ptr, O_RDONLY))) {
-                               log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno));
--                              
--                              return -1;
-+
-+                              return NETWORK_STATUS_FATAL_ERROR;
-                       }
--                      
-+
-                       r = 0;
--                      
-+
-                       /* FreeBSD sendfile() */
--                      if (-1 == sendfile(ifd, fd, offset, toSend, NULL, &r, 0)) {
-+                      if (-1 == sendfile(ifd, sock->fd, offset, toSend, NULL, &r, 0)) {
-                               switch(errno) {
-                               case EAGAIN:
-                                       break;
-                               case ENOTCONN:
-                                       close(ifd);
--                                      return -2;
-+                                      return NETWORK_STATUS_CONNECTION_CLOSE;
-                               default:
-                                       log_error_write(srv, __FILE__, __LINE__, "ssd", "sendfile: ", strerror(errno), errno);
-                                       close(ifd);
--                                      return -1;
-+                                      return NETWORK_STATUS_FATAL_ERROR;
-                               }
-                       }
-                       close(ifd);
--                      
-+
-                       c->offset += r;
-                       cq->bytes_out += r;
--                      
-+
-                       if (c->offset == c->file.length) {
-                               chunk_finished = 1;
-                       }
--                      
-+
-                       break;
-               }
-               default:
--                      
-+
-                       log_error_write(srv, __FILE__, __LINE__, "ds", c, "type not known");
--                      
--                      return -1;
-+
-+                      return NETWORK_STATUS_FATAL_ERROR;
-               }
--              
-+
-               if (!chunk_finished) {
-                       /* not finished yet */
--                      
--                      break;
-+
-+                      return NETWORK_STATUS_WAIT_FOR_EVENT;
-               }
-       }
--      return chunks_written;
-+      return NETWORK_STATUS_SUCCESS;
- }
- #endif
---- ../lighttpd-1.4.11/src/network_linux_sendfile.c    2006-02-15 20:02:36.000000000 +0200
-+++ lighttpd-1.5.0/src/network_linux_sendfile.c        2006-09-07 00:57:05.000000000 +0300
-@@ -26,122 +26,54 @@
- /* on linux 2.4.29 + debian/ubuntu we have crashes if this is enabled */
- #undef HAVE_POSIX_FADVISE
--int network_write_chunkqueue_linuxsendfile(server *srv, connection *con, int fd, chunkqueue *cq) {
--      chunk *c;
-+NETWORK_BACKEND_WRITE(linuxsendfile) {
-+      chunk *c, *tc;
-       size_t chunks_written = 0;
--      
-+
-       for(c = cq->first; c; c = c->next, chunks_written++) {
-               int chunk_finished = 0;
--              
-+              network_status_t ret;
-+
-               switch(c->type) {
--              case MEM_CHUNK: {
--                      char * offset;
--                      size_t toSend;
--                      ssize_t r;
--                      
--                      size_t num_chunks, i;
--                      struct iovec chunks[UIO_MAXIOV];
--                      chunk *tc;
--                      size_t num_bytes = 0;
--                      
--                      /* we can't send more then SSIZE_MAX bytes in one chunk */
--                      
--                      /* build writev list 
--                       * 
--                       * 1. limit: num_chunks < UIO_MAXIOV
--                       * 2. limit: num_bytes < SSIZE_MAX
--                       */
--                      for (num_chunks = 0, tc = c; 
--                           tc && tc->type == MEM_CHUNK && num_chunks < UIO_MAXIOV; 
--                           tc = tc->next, num_chunks++);
--                      
--                      for (tc = c, i = 0; i < num_chunks; tc = tc->next, i++) {
--                              if (tc->mem->used == 0) {
--                                      chunks[i].iov_base = tc->mem->ptr;
--                                      chunks[i].iov_len  = 0;
--                              } else {
--                                      offset = tc->mem->ptr + tc->offset;
--                                      toSend = tc->mem->used - 1 - tc->offset;
--                              
--                                      chunks[i].iov_base = offset;
--                                      
--                                      /* protect the return value of writev() */
--                                      if (toSend > SSIZE_MAX ||
--                                          num_bytes + toSend > SSIZE_MAX) {
--                                              chunks[i].iov_len = SSIZE_MAX - num_bytes;
--                                              
--                                              num_chunks = i + 1;
--                                              break;
--                                      } else {
--                                              chunks[i].iov_len = toSend;
--                                      }
--                               
--                                      num_bytes += toSend;
--                              }
--                      }
--                      
--                      if ((r = writev(fd, chunks, num_chunks)) < 0) {
--                              switch (errno) {
--                              case EAGAIN:
--                              case EINTR:
--                                      r = 0;
--                                      break;
--                              case EPIPE:
--                              case ECONNRESET:
--                                      return -2;
--                              default:
--                                      log_error_write(srv, __FILE__, __LINE__, "ssd", 
--                                                      "writev failed:", strerror(errno), fd);
--                              
--                                      return -1;
--                              }
--                      }
--                      
--                      /* check which chunks have been written */
--                      cq->bytes_out += r;
-+              case MEM_CHUNK:
-+                      ret = network_write_chunkqueue_writev_mem(srv, con, sock, cq, c);
--                      for(i = 0, tc = c; i < num_chunks; i++, tc = tc->next) {
--                              if (r >= (ssize_t)chunks[i].iov_len) {
--                                      /* written */
--                                      r -= chunks[i].iov_len;
--                                      tc->offset += chunks[i].iov_len;
--                                      
-+                      /* check which chunks are finished now */
-+                      for (tc = c; tc; tc = tc->next) {
-+                              /* finished the chunk */
-+                              if (tc->offset == tc->mem->used - 1) {
-+                                      /* skip the first c->next as that will be done by the c = c->next in the other for()-loop */
-                                       if (chunk_finished) {
--                                              /* skip the chunks from further touches */
--                                              chunks_written++;
-                                               c = c->next;
-                                       } else {
--                                              /* chunks_written + c = c->next is done in the for()*/
--                                              chunk_finished++;
-+                                              chunk_finished = 1;
-                                       }
-                               } else {
--                                      /* partially written */
--                                      
--                                      tc->offset += r;
--                                      chunk_finished = 0;
--                                      
-                                       break;
-                               }
-                       }
--                      
-+
-+                      if (ret != NETWORK_STATUS_SUCCESS) {
-+                              return ret;
-+                      }
-+
-                       break;
--              }
-               case FILE_CHUNK: {
-                       ssize_t r;
-                       off_t offset;
-                       size_t toSend;
-                       stat_cache_entry *sce = NULL;
--                      
-+
-                       offset = c->file.start + c->offset;
-                       /* limit the toSend to 2^31-1 bytes in a chunk */
--                      toSend = c->file.length - c->offset > ((1 << 30) - 1) ? 
-+                      toSend = c->file.length - c->offset > ((1 << 30) - 1) ?
-                               ((1 << 30) - 1) : c->file.length - c->offset;
--                              
--                      /* open file if not already opened */   
-+
-+                      /* open file if not already opened */
-                       if (-1 == c->file.fd) {
-                               if (-1 == (c->file.fd = open(c->file.name->ptr, O_RDONLY))) {
-                                       log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno));
--                              
-+
-                                       return -1;
-                               }
- #ifdef FD_CLOEXEC
-@@ -151,26 +83,25 @@
-                               /* tell the kernel that we want to stream the file */
-                               if (-1 == posix_fadvise(c->file.fd, 0, 0, POSIX_FADV_SEQUENTIAL)) {
-                                       if (ENOSYS != errno) {
--                                              log_error_write(srv, __FILE__, __LINE__, "ssd", 
-+                                              log_error_write(srv, __FILE__, __LINE__, "ssd",
-                                                       "posix_fadvise failed:", strerror(errno), c->file.fd);
-                                       }
-                               }
- #endif
-                       }
--                      if (-1 == (r = sendfile(fd, c->file.fd, &offset, toSend))) {
-+                      if (-1 == (r = sendfile(sock->fd, c->file.fd, &offset, toSend))) {
-                               switch (errno) {
-                               case EAGAIN:
-                               case EINTR:
--                                      r = 0;
--                                      break;
-+                                      return NETWORK_STATUS_WAIT_FOR_EVENT;
-                               case EPIPE:
-                               case ECONNRESET:
--                                      return -2;
-+                                      return NETWORK_STATUS_CONNECTION_CLOSE;
-                               default:
--                                      log_error_write(srv, __FILE__, __LINE__, "ssd", 
--                                                      "sendfile failed:", strerror(errno), fd);
--                                      return -1;
-+                                      log_error_write(srv, __FILE__, __LINE__, "ssd",
-+                                                      "sendfile failed:", strerror(errno), sock->fd);
-+                                      return NETWORK_STATUS_FATAL_ERROR;
-                               }
-                       }
-@@ -179,39 +110,39 @@
-                                *
-                                * - the file shrinked -> error
-                                * - the remote side closed inbetween -> remote-close */
--      
-+
-                               if (HANDLER_ERROR == stat_cache_get_entry(srv, con, c->file.name, &sce)) {
-                                       /* file is gone ? */
--                                      return -1;
-+                                      return NETWORK_STATUS_FATAL_ERROR;
-                               }
-                               if (offset > sce->st.st_size) {
-                                       /* file shrinked, close the connection */
--                                      return -1;
-+                                      return NETWORK_STATUS_FATAL_ERROR;
-                               }
--                              return -2;
-+                              return NETWORK_STATUS_CONNECTION_CLOSE;
-                       }
- #ifdef HAVE_POSIX_FADVISE
- #if 0
- #define K * 1024
--#define M * 1024 K    
-+#define M * 1024 K
- #define READ_AHEAD 4 M
-                       /* check if we need a new chunk */
-                       if ((c->offset & ~(READ_AHEAD - 1)) != ((c->offset + r) & ~(READ_AHEAD - 1))) {
-                               /* tell the kernel that we want to stream the file */
-                               if (-1 == posix_fadvise(c->file.fd, (c->offset + r) & ~(READ_AHEAD - 1), READ_AHEAD, POSIX_FADV_NOREUSE)) {
--                                      log_error_write(srv, __FILE__, __LINE__, "ssd", 
-+                                      log_error_write(srv, __FILE__, __LINE__, "ssd",
-                                               "posix_fadvise failed:", strerror(errno), c->file.fd);
-                               }
-                       }
- #endif
- #endif
--                      
-+
-                       c->offset += r;
-                       cq->bytes_out += r;
--                      
-+
-                       if (c->offset == c->file.length) {
-                               chunk_finished = 1;
-@@ -222,24 +153,24 @@
-                                       c->file.fd = -1;
-                               }
-                       }
--                      
-+
-                       break;
-               }
-               default:
--                      
-+
-                       log_error_write(srv, __FILE__, __LINE__, "ds", c, "type not known");
--                      
--                      return -1;
-+
-+                      return NETWORK_STATUS_FATAL_ERROR;
-               }
--              
-+
-               if (!chunk_finished) {
-                       /* not finished yet */
--                      
--                      break;
-+
-+                      return NETWORK_STATUS_WAIT_FOR_EVENT;
-               }
-       }
--      return chunks_written;
-+      return NETWORK_STATUS_SUCCESS;
- }
- #endif
---- ../lighttpd-1.4.11/src/network_openssl.c   2005-11-17 14:53:29.000000000 +0200
-+++ lighttpd-1.5.0/src/network_openssl.c       2006-09-07 00:57:05.000000000 +0300
-@@ -23,17 +23,94 @@
- #include "log.h"
- #include "stat_cache.h"
--# include <openssl/ssl.h> 
--# include <openssl/err.h> 
-+# include <openssl/ssl.h>
-+# include <openssl/err.h>
--int network_write_chunkqueue_openssl(server *srv, connection *con, SSL *ssl, chunkqueue *cq) {
-+NETWORK_BACKEND_READ(openssl) {
-+      buffer *b;
-+      off_t len;
-+      int read_something = 0;
-+      off_t max_read = 256 * 1024;
-+
-+      off_t start_bytes_in = cq->bytes_in;
-+      do {
-+              b = chunkqueue_get_append_buffer(cq);
-+              buffer_prepare_copy(b, 8192 + 12); /* ssl-chunk-size is 8kb */
-+              len = SSL_read(sock->ssl, b->ptr, b->size - 1);
-+
-+              if (len < 0) {
-+                      int r, ssl_err;
-+      
-+                      switch ((r = SSL_get_error(sock->ssl, len))) {
-+                      case SSL_ERROR_WANT_READ:
-+                              chunkqueue_remove_empty_last_chunk(cq);
-+                              return read_something ? NETWORK_STATUS_SUCCESS : NETWORK_STATUS_WAIT_FOR_EVENT;
-+                      case SSL_ERROR_SYSCALL:
-+                              /**
-+                               * man SSL_get_error()
-+                               *
-+                               * SSL_ERROR_SYSCALL
-+                               *   Some I/O error occurred.  The OpenSSL error queue may contain more
-+                               *   information on the error.  If the error queue is empty (i.e.
-+                               *   ERR_get_error() returns 0), ret can be used to find out more about
-+                               *   the error: If ret == 0, an EOF was observed that violates the
-+                               *   protocol.  If ret == -1, the underlying BIO reported an I/O error
-+                               *   (for socket I/O on Unix systems, consult errno for details).
-+                               *
-+                               */
-+                              while((ssl_err = ERR_get_error())) {
-+                                      /* get all errors from the error-queue */
-+                                      ERROR("ssl-errors: %s", ERR_error_string(ssl_err, NULL));
-+                              }
-+
-+                              switch(errno) {
-+                              default:
-+                                      ERROR("last-errno: (%d) %s", errno, strerror(errno));
-+                                      break;
-+                              }
-+
-+                              break;
-+                      case SSL_ERROR_ZERO_RETURN:
-+                              /* clean shutdown on the remote side */
-+      
-+                              if (r == 0) {
-+                                      /* FIXME: later */
-+                              }
-+
-+                              /* fall through */
-+                      default:
-+                              while((ssl_err = ERR_get_error())) {
-+                                      /* get all errors from the error-queue */
-+                                      ERROR("ssl-errors: %s", ERR_error_string(ssl_err, NULL));
-+                              }
-+
-+                              return NETWORK_STATUS_FATAL_ERROR;
-+                      }
-+              } else if (len == 0) {
-+                      return NETWORK_STATUS_FATAL_ERROR;
-+              } else {
-+                      b->used += len;
-+                      b->ptr[b->used++] = '\0';
-+
-+                      read_something = 1;
-+                      cq->bytes_in += len;
-+              }
-+
-+              if (cq->bytes_in - start_bytes_in > max_read) return NETWORK_STATUS_SUCCESS;
-+      } while (1);
-+
-+      return NETWORK_STATUS_FATAL_ERROR;
-+}
-+
-+
-+NETWORK_BACKEND_WRITE(openssl) {
-       int ssl_r;
-       chunk *c;
-       size_t chunks_written = 0;
-       /* this is a 64k sendbuffer
-        *
--       * it has to stay at the same location all the time to satisfy the needs 
-+       * it has to stay at the same location all the time to satisfy the needs
-        * of SSL_write to pass the SAME parameter in case of a _WANT_WRITE
-        *
-        * the buffer is allocated once, is NOT realloced and is NOT freed at shutdown
-@@ -43,59 +120,61 @@
-        * In reality we would like to use mmap() but we don't have a guarantee that
-        * we get the same mmap() address for each call. On openbsd the mmap() address
-        * even randomized.
--       *   That means either we keep the mmap() open or we do a read() into a 
--       * constant buffer 
-+       *   That means either we keep the mmap() open or we do a read() into a
-+       * constant buffer
-        * */
- #define LOCAL_SEND_BUFSIZE (64 * 1024)
-       static char *local_send_buffer = NULL;
-       /* the remote side closed the connection before without shutdown request
--       * - IE 
-+       * - IE
-        * - wget
-        * if keep-alive is disabled */
-       if (con->keep_alive == 0) {
--              SSL_set_shutdown(ssl, SSL_RECEIVED_SHUTDOWN);
-+              SSL_set_shutdown(sock->ssl, SSL_RECEIVED_SHUTDOWN);
-       }
-       for(c = cq->first; c; c = c->next) {
-               int chunk_finished = 0;
--              
-+
-               switch(c->type) {
-               case MEM_CHUNK: {
-                       char * offset;
-                       size_t toSend;
--                      ssize_t r;
--                      
-+                      ssize_t r = 0;
-+
-                       if (c->mem->used == 0) {
-                               chunk_finished = 1;
-                               break;
-                       }
--                      
-+
-                       offset = c->mem->ptr + c->offset;
-                       toSend = c->mem->used - 1 - c->offset;
--                      
-+
-                       /**
-                        * SSL_write man-page
--                       * 
-+                       *
-                        * WARNING
-                        *        When an SSL_write() operation has to be repeated because of
-                        *        SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE, it must be
-                        *        repeated with the same arguments.
--                       * 
-+                       *
-+                       * SSL_write(..., 0) return 0 which is handle as an error (Success)
-+                       * checking toSend and not calling SSL_write() is simpler
-                        */
--                      
--                      if ((r = SSL_write(ssl, offset, toSend)) <= 0) {
-+
-+                      if (toSend != 0 && (r = SSL_write(sock->ssl, offset, toSend)) <= 0) {
-                               unsigned long err;
--                              switch ((ssl_r = SSL_get_error(ssl, r))) {
-+                              switch ((ssl_r = SSL_get_error(sock->ssl, r))) {
-                               case SSL_ERROR_WANT_WRITE:
-                                       break;
-                               case SSL_ERROR_SYSCALL:
-                                       /* perhaps we have error waiting in our error-queue */
-                                       if (0 != (err = ERR_get_error())) {
-                                               do {
--                                                      log_error_write(srv, __FILE__, __LINE__, "sdds", "SSL:", 
-+                                                      log_error_write(srv, __FILE__, __LINE__, "sdds", "SSL:",
-                                                                       ssl_r, r,
-                                                                       ERR_error_string(err, NULL));
-                                               } while((err = ERR_get_error()));
-@@ -105,43 +184,43 @@
-                                               case EPIPE:
-                                                       return -2;
-                                               default:
--                                                      log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL:", 
-+                                                      log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL:",
-                                                                       ssl_r, r, errno,
-                                                                       strerror(errno));
-                                                       break;
-                                               }
-                                       } else {
-                                               /* neither error-queue nor errno ? */
--                                              log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL (error):", 
-+                                              log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL (error):",
-                                                               ssl_r, r, errno,
-                                                               strerror(errno));
-                                       }
--                                      
-+
-                                       return  -1;
-                               case SSL_ERROR_ZERO_RETURN:
-                                       /* clean shutdown on the remote side */
--                                      
-+
-                                       if (r == 0) return -2;
--                                      
-+
-                                       /* fall through */
-                               default:
-                                       while((err = ERR_get_error())) {
--                                              log_error_write(srv, __FILE__, __LINE__, "sdds", "SSL:", 
-+                                              log_error_write(srv, __FILE__, __LINE__, "sdds", "SSL:",
-                                                               ssl_r, r,
-                                                               ERR_error_string(err, NULL));
-                                       }
--                                      
-+
-                                       return  -1;
-                               }
-                       } else {
-                               c->offset += r;
-                               cq->bytes_out += r;
-                       }
--                      
-+
-                       if (c->offset == (off_t)c->mem->used - 1) {
-                               chunk_finished = 1;
-                       }
--                      
-+
-                       break;
-               }
-               case FILE_CHUNK: {
-@@ -150,7 +229,7 @@
-                       stat_cache_entry *sce = NULL;
-                       int ifd;
-                       int write_wait = 0;
--                      
-+
-                       if (HANDLER_ERROR == stat_cache_get_entry(srv, con, c->file.name, &sce)) {
-                               log_error_write(srv, __FILE__, __LINE__, "sb",
-                                               strerror(errno), c->file.name);
-@@ -164,13 +243,13 @@
-                       do {
-                               off_t offset = c->file.start + c->offset;
--                              off_t toSend = c->file.length - c->offset; 
-+                              off_t toSend = c->file.length - c->offset;
-                               if (toSend > LOCAL_SEND_BUFSIZE) toSend = LOCAL_SEND_BUFSIZE;
--                      
-+
-                               if (-1 == (ifd = open(c->file.name->ptr, O_RDONLY))) {
-                                       log_error_write(srv, __FILE__, __LINE__, "ss", "open failed:", strerror(errno));
--                              
-+
-                                       return -1;
-                               }
-@@ -183,13 +262,13 @@
-                               }
-                               s = local_send_buffer;
--                      
-+
-                               close(ifd);
--                      
--                              if ((r = SSL_write(ssl, s, toSend)) <= 0) {
-+
-+                              if ((r = SSL_write(sock->ssl, s, toSend)) <= 0) {
-                                       unsigned long err;
--                                      switch ((ssl_r = SSL_get_error(ssl, r))) {
-+                                      switch ((ssl_r = SSL_get_error(sock->ssl, r))) {
-                                       case SSL_ERROR_WANT_WRITE:
-                                               write_wait = 1;
-                                               break;
-@@ -197,7 +276,7 @@
-                                               /* perhaps we have error waiting in our error-queue */
-                                               if (0 != (err = ERR_get_error())) {
-                                                       do {
--                                                              log_error_write(srv, __FILE__, __LINE__, "sdds", "SSL:", 
-+                                                              log_error_write(srv, __FILE__, __LINE__, "sdds", "SSL:",
-                                                                               ssl_r, r,
-                                                                               ERR_error_string(err, NULL));
-                                                       } while((err = ERR_get_error()));
-@@ -207,62 +286,62 @@
-                                                       case EPIPE:
-                                                               return -2;
-                                                       default:
--                                                              log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL:", 
-+                                                              log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL:",
-                                                                               ssl_r, r, errno,
-                                                                               strerror(errno));
-                                                               break;
-                                                       }
-                                               } else {
-                                                       /* neither error-queue nor errno ? */
--                                                      log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL (error):", 
-+                                                      log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL (error):",
-                                                                       ssl_r, r, errno,
-                                                                       strerror(errno));
-                                               }
--                                      
-+
-                                               return  -1;
-                                       case SSL_ERROR_ZERO_RETURN:
-                                               /* clean shutdown on the remote side */
--                                      
-+
-                                               if (r == 0)  return -2;
--                                      
-+
-                                               /* fall thourgh */
-                                       default:
-                                               while((err = ERR_get_error())) {
--                                                      log_error_write(srv, __FILE__, __LINE__, "sdds", "SSL:", 
-+                                                      log_error_write(srv, __FILE__, __LINE__, "sdds", "SSL:",
-                                                                       ssl_r, r,
-                                                                       ERR_error_string(err, NULL));
-                                               }
--                                      
-+
-                                               return -1;
-                                       }
-                               } else {
-                                       c->offset += r;
-                                       cq->bytes_out += r;
-                               }
--                      
-+
-                               if (c->offset == c->file.length) {
-                                       chunk_finished = 1;
-                               }
-                       } while(!chunk_finished && !write_wait);
--                      
-+
-                       break;
-               }
-               default:
-                       log_error_write(srv, __FILE__, __LINE__, "s", "type not known");
--                      
-+
-                       return -1;
-               }
--                      
-+
-               if (!chunk_finished) {
-                       /* not finished yet */
--                      
-+
-                       break;
-               }
--                      
-+
-               chunks_written++;
-       }
--      return chunks_written;
-+      return NETWORK_STATUS_SUCCESS;
- }
- #endif
---- ../lighttpd-1.4.11/src/network_solaris_sendfilev.c 2005-10-22 12:28:27.000000000 +0300
-+++ lighttpd-1.5.0/src/network_solaris_sendfilev.c     2006-07-16 00:26:04.000000000 +0300
-@@ -29,114 +29,34 @@
- #endif
- /**
-- * a very simple sendfilev() interface for solaris which can be optimised a lot more 
-+ * a very simple sendfilev() interface for solaris which can be optimised a lot more
-  * as solaris sendfilev() supports 'sending everythin in one syscall()'
-- * 
-- * If you want such an interface and need the performance, just give me an account on 
-- * a solaris box. 
-+ *
-+ * If you want such an interface and need the performance, just give me an account on
-+ * a solaris box.
-  *   - jan@kneschke.de
-  */
--int network_write_chunkqueue_solarissendfilev(server *srv, connection *con, int fd, chunkqueue *cq) {
-+NETWORK_BACKEND_WRITE(solarissendfilev) {
-       chunk *c;
-       size_t chunks_written = 0;
--      
-+
-       for(c = cq->first; c; c = c->next, chunks_written++) {
-               int chunk_finished = 0;
--              
-+              network_status_t ret;
-+
-               switch(c->type) {
--              case MEM_CHUNK: {
--                      char * offset;
--                      size_t toSend;
--                      ssize_t r;
--                      
--                      size_t num_chunks, i;
--                      struct iovec chunks[UIO_MAXIOV];
--                      chunk *tc;
--                      
--                      size_t num_bytes = 0;
--                      
--                      /* we can't send more then SSIZE_MAX bytes in one chunk */
--                      
--                      /* build writev list 
--                       * 
--                       * 1. limit: num_chunks < UIO_MAXIOV
--                       * 2. limit: num_bytes < SSIZE_MAX
--                       */
--                      for(num_chunks = 0, tc = c; tc && tc->type == MEM_CHUNK && num_chunks < UIO_MAXIOV; num_chunks++, tc = tc->next);
--                      
--                      for(tc = c, i = 0; i < num_chunks; tc = tc->next, i++) {
--                              if (tc->mem->used == 0) {
--                                      chunks[i].iov_base = tc->mem->ptr;
--                                      chunks[i].iov_len  = 0;
--                              } else {
--                                      offset = tc->mem->ptr + tc->offset;
--                                      toSend = tc->mem->used - 1 - tc->offset;
--                              
--                                      chunks[i].iov_base = offset;
--                                      
--                                      /* protect the return value of writev() */
--                                      if (toSend > SSIZE_MAX ||
--                                          num_bytes + toSend > SSIZE_MAX) {
--                                              chunks[i].iov_len = SSIZE_MAX - num_bytes;
--                                              
--                                              num_chunks = i + 1;
--                                              break;
--                                      } else {
--                                              chunks[i].iov_len = toSend;
--                                      }
--                                      
--                                      num_bytes += toSend;
--                              }
--                      }
--                      
--                      if ((r = writev(fd, chunks, num_chunks)) < 0) {
--                              switch (errno) {
--                              case EAGAIN:
--                              case EINTR:
--                                      r = 0;
--                                      break;
--                              case EPIPE:
--                              case ECONNRESET:
--                                      return -2;
--                              default:
--                                      log_error_write(srv, __FILE__, __LINE__, "ssd", 
--                                                      "writev failed:", strerror(errno), fd);
--                              
--                                      return -1;
--                              }
--                      }
--                      
--                      /* check which chunks have been written */
--                      cq->bytes_out += r;
--                      
--                      for(i = 0, tc = c; i < num_chunks; i++, tc = tc->next) {
--                              if (r >= (ssize_t)chunks[i].iov_len) {
--                                      /* written */
--                                      r -= chunks[i].iov_len;
--                                      tc->offset += chunks[i].iov_len;
--                                      
--                                      if (chunk_finished) {
--                                              /* skip the chunks from further touches */
--                                              chunks_written++;
--                                              c = c->next;
--                                      } else {
--                                              /* chunks_written + c = c->next is done in the for()*/
--                                              chunk_finished++;
--                                      }
--                              } else {
--                                      /* partially written */
--                                      
--                                      tc->offset += r;
--                                      chunk_finished = 0;
--                                      
--                                      break;
--                              }
-+              case MEM_CHUNK:
-+                      ret = network_write_chunkqueue_writev_mem(srv, con, fd, cq, &c);
-+
-+                      if (ret != NETWORK_STATUS_SUCCESS) {
-+                              return ret;
-                       }
--                      
-+
-+                      chunk_finished = 1;
-+
-                       break;
--              }
-               case FILE_CHUNK: {
-                       ssize_t r;
-                       off_t offset;
-@@ -144,25 +64,25 @@
-                       sendfilevec_t fvec;
-                       stat_cache_entry *sce = NULL;
-                       int ifd;
--                      
-+
-                       if (HANDLER_ERROR == stat_cache_get_entry(srv, con, c->file.name, &sce)) {
-                               log_error_write(srv, __FILE__, __LINE__, "sb",
-                                               strerror(errno), c->file.name);
-                               return -1;
-                       }
--                                      
-+
-                       offset = c->file.start + c->offset;
-                       toSend = c->file.length - c->offset;
--                      
-+
-                       if (offset > sce->st.st_size) {
-                               log_error_write(srv, __FILE__, __LINE__, "sb", "file was shrinked:", c->file.name);
--                              
-+
-                               return -1;
-                       }
-                       if (-1 == (ifd = open(c->file.name->ptr, O_RDONLY))) {
-                               log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno));
--                              
-+
-                               return -1;
-                       }
-@@ -170,44 +90,43 @@
-                       fvec.sfv_flag = 0;
-                       fvec.sfv_off = offset;
-                       fvec.sfv_len = toSend;
--                      
-+
-                       /* Solaris sendfilev() */
-                       if (-1 == (r = sendfilev(fd, &fvec, 1, &written))) {
-                               if (errno != EAGAIN) {
-                                       log_error_write(srv, __FILE__, __LINE__, "ssd", "sendfile: ", strerror(errno), errno);
--                                      
-+
-                                       close(ifd);
--                                      return -1;
-+                                      return NETWORK_STATUS_FATAL_ERROR;
-                               }
--                              
-+
-                               r = 0;
-                       }
--                      
-+
-                       close(ifd);
-                       c->offset += written;
-                       cq->bytes_out += written;
--                      
-+
-                       if (c->offset == c->file.length) {
-                               chunk_finished = 1;
-                       }
--                      
-+
-                       break;
-               }
-               default:
--                      
-                       log_error_write(srv, __FILE__, __LINE__, "ds", c, "type not known");
--                      
--                      return -1;
-+
-+                      return NETWORK_STATUS_FATAL_ERROR;
-               }
--              
-+
-               if (!chunk_finished) {
-                       /* not finished yet */
--                      
-+
-                       break;
-               }
-       }
--      return chunks_written;
-+      return NETWORK_STATUS_SUCCESS;
- }
- #endif
---- ../lighttpd-1.4.11/src/network_write.c     2005-10-22 12:27:56.000000000 +0300
-+++ lighttpd-1.5.0/src/network_write.c 2006-09-07 00:57:05.000000000 +0300
-@@ -1,11 +1,11 @@
- #include <sys/types.h>
- #include <sys/stat.h>
--#include <sys/time.h>
-+
- #include <errno.h>
- #include <fcntl.h>
--#include <unistd.h>
- #include <string.h>
- #include <stdlib.h>
-+#include <assert.h>
- #include "network.h"
- #include "fdevent.h"
-@@ -13,9 +13,12 @@
- #include "stat_cache.h"
- #include "sys-socket.h"
-+#include "sys-files.h"
- #include "network_backends.h"
-+#ifdef USE_WRITE
-+
- #ifdef HAVE_SYS_FILIO_H
- # include <sys/filio.h>
- #endif
-@@ -24,47 +27,100 @@
- #include <sys/resource.h>
- #endif
--int network_write_chunkqueue_write(server *srv, connection *con, int fd, chunkqueue *cq) {
-+
-+/**
-+* fill the chunkqueue will all the data that we can get
-+*
-+* this might be optimized into a readv() which uses the chunks
-+* as vectors
-+*/
-+NETWORK_BACKEND_READ(read) {
-+      int toread;
-+      buffer *b;
-+      off_t r, start_bytes_in;
-+      off_t max_read = 256 * 1024;
-+
-+      /**
-+       * a EAGAIN is a successful read if we already read something to the chunkqueue
-+       */
-+      int read_something = 0;
-+
-+      start_bytes_in = cq->bytes_in;
-+      
-+      /* use a chunk-size of 16k */
-+      do {
-+              toread = 16384;
-+
-+              b = chunkqueue_get_append_buffer(cq);
-+
-+              buffer_prepare_copy(b, toread);
-+
-+              if (-1 == (r = read(sock->fd, b->ptr, toread))) {
-+                      switch (errno) {
-+                      case EAGAIN:
-+                              /* remove the last chunk from the chunkqueue */
-+                              chunkqueue_remove_empty_last_chunk(cq);
-+                              return read_something ? NETWORK_STATUS_SUCCESS : NETWORK_STATUS_WAIT_FOR_EVENT;
-+                      case ECONNRESET:
-+                              return NETWORK_STATUS_CONNECTION_CLOSE;
-+                      default:
-+                              ERROR("oops, read from fd=%d failed: %s (%d)", sock->fd, strerror(errno), errno );
-+
-+                              return NETWORK_STATUS_FATAL_ERROR;
-+                      }
-+              }
-+
-+              if (r == 0) {
-+                      chunkqueue_remove_empty_last_chunk(cq);
-+                      return read_something ? NETWORK_STATUS_SUCCESS : NETWORK_STATUS_CONNECTION_CLOSE;
-+              }
-+
-+              read_something = 1;
-+
-+              b->used = r;
-+              b->ptr[b->used++] = '\0';
-+              cq->bytes_in += r;
-+
-+              if (cq->bytes_in - start_bytes_in > max_read) break;
-+      } while (r == toread); 
-+
-+      return NETWORK_STATUS_SUCCESS;
-+}
-+
-+NETWORK_BACKEND_WRITE(write) {
-       chunk *c;
-       size_t chunks_written = 0;
--      
-+
-       for(c = cq->first; c; c = c->next) {
-               int chunk_finished = 0;
--              
-+
-               switch(c->type) {
-               case MEM_CHUNK: {
-                       char * offset;
-                       size_t toSend;
-                       ssize_t r;
--                      
-+
-                       if (c->mem->used == 0) {
-                               chunk_finished = 1;
-                               break;
-                       }
--                      
-+
-                       offset = c->mem->ptr + c->offset;
-                       toSend = c->mem->used - 1 - c->offset;
--#ifdef __WIN32        
--                      if ((r = send(fd, offset, toSend, 0)) < 0) {
--                              log_error_write(srv, __FILE__, __LINE__, "ssd", "write failed: ", strerror(errno), fd);
--                              
--                              return -1;
--                      }
--#else
--                      if ((r = write(fd, offset, toSend)) < 0) {
--                              log_error_write(srv, __FILE__, __LINE__, "ssd", "write failed: ", strerror(errno), fd);
--                              
--                              return -1;
-+
-+                      if ((r = write(sock->fd, offset, toSend)) < 0) {
-+                              log_error_write(srv, __FILE__, __LINE__, "ssd", "write failed: ", strerror(errno), sock->fd);
-+
-+                              return NETWORK_STATUS_FATAL_ERROR;
-                       }
--#endif
--                      
-+
-                       c->offset += r;
-                       cq->bytes_out += r;
--                      
-+
-                       if (c->offset == (off_t)c->mem->used - 1) {
-                               chunk_finished = 1;
-                       }
--                      
-+
-                       break;
-               }
-               case FILE_CHUNK: {
-@@ -76,93 +132,89 @@
-                       size_t toSend;
-                       stat_cache_entry *sce = NULL;
-                       int ifd;
--                      
-+
-                       if (HANDLER_ERROR == stat_cache_get_entry(srv, con, c->file.name, &sce)) {
-                               log_error_write(srv, __FILE__, __LINE__, "sb",
-                                               strerror(errno), c->file.name);
--                              return -1;
-+                              return NETWORK_STATUS_FATAL_ERROR;
-                       }
--                      
-+
-                       offset = c->file.start + c->offset;
-                       toSend = c->file.length - c->offset;
--                      
-+
-                       if (offset > sce->st.st_size) {
-                               log_error_write(srv, __FILE__, __LINE__, "sb", "file was shrinked:", c->file.name);
--                              
--                              return -1;
-+
-+                              return NETWORK_STATUS_FATAL_ERROR;
-                       }
-                       if (-1 == (ifd = open(c->file.name->ptr, O_RDONLY))) {
-                               log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno));
--                              
--                              return -1;
-+
-+                              return NETWORK_STATUS_FATAL_ERROR;
-                       }
--                      
-+
- #if defined USE_MMAP
-                       if (MAP_FAILED == (p = mmap(0, sce->st.st_size, PROT_READ, MAP_SHARED, ifd, 0))) {
-                               log_error_write(srv, __FILE__, __LINE__, "ss", "mmap failed: ", strerror(errno));
-                               close(ifd);
--                              
--                              return -1;
-+
-+                              return NETWORK_STATUS_FATAL_ERROR;
-                       }
-                       close(ifd);
--                      if ((r = write(fd, p + offset, toSend)) <= 0) {
-+                      if ((r = write(sock->fd, p + offset, toSend)) <= 0) {
-                               log_error_write(srv, __FILE__, __LINE__, "ss", "write failed: ", strerror(errno));
-                               munmap(p, sce->st.st_size);
--                              return -1;
-+                              return NETWORK_STATUS_FATAL_ERROR;
-                       }
--                      
-+
-                       munmap(p, sce->st.st_size);
- #else
-                       buffer_prepare_copy(srv->tmp_buf, toSend);
--                      
-+
-                       lseek(ifd, offset, SEEK_SET);
-                       if (-1 == (toSend = read(ifd, srv->tmp_buf->ptr, toSend))) {
-                               log_error_write(srv, __FILE__, __LINE__, "ss", "read: ", strerror(errno));
-                               close(ifd);
--                              
--                              return -1;
-+
-+                              return NETWORK_STATUS_FATAL_ERROR;
-                       }
-                       close(ifd);
--                      if (-1 == (r = send(fd, srv->tmp_buf->ptr, toSend, 0))) {
-+                      if (-1 == (r = send(sock->fd, srv->tmp_buf->ptr, toSend, 0))) {
-                               log_error_write(srv, __FILE__, __LINE__, "ss", "write: ", strerror(errno));
--                              
--                              return -1;
-+
-+                              return NETWORK_STATUS_FATAL_ERROR;
-                       }
- #endif
-                       c->offset += r;
-                       cq->bytes_out += r;
--                      
-+
-                       if (c->offset == c->file.length) {
-                               chunk_finished = 1;
-                       }
--                      
-+
-                       break;
-               }
-               default:
--                      
-+
-                       log_error_write(srv, __FILE__, __LINE__, "ds", c, "type not known");
--                      
--                      return -1;
-+
-+                      return NETWORK_STATUS_FATAL_ERROR;
-               }
--              
-+
-               if (!chunk_finished) {
-                       /* not finished yet */
--                      
-+
-                       break;
-               }
--              
-+
-               chunks_written++;
-       }
--      return chunks_written;
-+      return NETWORK_STATUS_SUCCESS;
- }
--#if 0
--network_write_init(void) {
--      p->write = network_write_write_chunkset;
--}
- #endif
---- ../lighttpd-1.4.11/src/network_writev.c    2006-02-15 01:02:36.000000000 +0200
-+++ lighttpd-1.5.0/src/network_writev.c        2006-07-18 13:03:40.000000000 +0300
-@@ -28,10 +28,10 @@
- #ifndef UIO_MAXIOV
- # if defined(__FreeBSD__) || defined(__APPLE__) || defined(__NetBSD__)
--/* FreeBSD 4.7 defines it in sys/uio.h only if _KERNEL is specified */ 
-+/* FreeBSD 4.7 defines it in sys/uio.h only if _KERNEL is specified */
- #  define UIO_MAXIOV 1024
- # elif defined(__sgi)
--/* IRIX 6.5 has sysconf(_SC_IOV_MAX) which might return 512 or bigger */ 
-+/* IRIX 6.5 has sysconf(_SC_IOV_MAX) which might return 512 or bigger */
- #  define UIO_MAXIOV 512
- # elif defined(__sun)
- /* Solaris (and SunOS?) defines IOV_MAX instead */
-@@ -51,105 +51,121 @@
- #define LOCAL_BUFFERING 1
- #endif
--int network_write_chunkqueue_writev(server *srv, connection *con, int fd, chunkqueue *cq) {
--      chunk *c;
-+NETWORK_BACKEND_WRITE_CHUNK(writev_mem) {
-+      char * offset;
-+      size_t toSend;
-+      ssize_t r;
-+
-+      size_t num_chunks, i;
-+      struct iovec chunks[UIO_MAXIOV];
-+      chunk *tc; /* transfer chunks */
-+      size_t num_bytes = 0;
-+
-+      /* we can't send more then SSIZE_MAX bytes in one chunk */
-+
-+      /* build writev list
-+       *
-+       * 1. limit: num_chunks < UIO_MAXIOV
-+       * 2. limit: num_bytes < SSIZE_MAX
-+       */
-+      for(num_chunks = 0, tc = c; tc && tc->type == MEM_CHUNK && num_chunks < UIO_MAXIOV; num_chunks++, tc = tc->next);
-+
-+      for(tc = c, i = 0; i < num_chunks; tc = tc->next, i++) {
-+              if (tc->mem->used == 0) {
-+                      chunks[i].iov_base = tc->mem->ptr;
-+                      chunks[i].iov_len  = 0;
-+              } else {
-+                      offset = tc->mem->ptr + tc->offset;
-+                      toSend = tc->mem->used - 1 - tc->offset;
-+
-+                      chunks[i].iov_base = offset;
-+
-+                      /* protect the return value of writev() */
-+                      if (toSend > SSIZE_MAX ||
-+                          num_bytes + toSend > SSIZE_MAX) {
-+                              chunks[i].iov_len = SSIZE_MAX - num_bytes;
-+
-+                              num_chunks = i + 1;
-+                              break;
-+                      } else {
-+                              chunks[i].iov_len = toSend;
-+                      }
-+
-+                      num_bytes += toSend;
-+              }
-+      }
-+
-+      if ((r = writev(sock->fd, chunks, num_chunks)) < 0) {
-+              switch (errno) {
-+              case EAGAIN:
-+                      return NETWORK_STATUS_WAIT_FOR_EVENT;
-+              case EINTR:
-+                      return NETWORK_STATUS_INTERRUPTED;
-+              case EPIPE:
-+              case ECONNRESET:
-+                      return NETWORK_STATUS_CONNECTION_CLOSE;
-+              default:
-+                      log_error_write(srv, __FILE__, __LINE__, "ssd",
-+                                      "writev failed:", strerror(errno), sock->fd);
-+
-+                      return NETWORK_STATUS_FATAL_ERROR;
-+              }
-+      }
-+
-+      cq->bytes_out += r;
-+
-+      /* check which chunks have been written */
-+
-+      for(i = 0, tc = c; i < num_chunks; i++, tc = tc->next) {
-+              if (r >= (ssize_t)chunks[i].iov_len) {
-+                      /* written */
-+                      r -= chunks[i].iov_len;
-+                      tc->offset += chunks[i].iov_len;
-+              } else {
-+                      /* partially written */
-+
-+                      tc->offset += r;
-+
-+                      return NETWORK_STATUS_WAIT_FOR_EVENT;
-+              }
-+      }
-+
-+      /* all chunks have been pushed out */
-+      return NETWORK_STATUS_SUCCESS;
-+}
-+
-+NETWORK_BACKEND_WRITE(writev) {
-+      chunk *c, *tc;
-       size_t chunks_written = 0;
--      
-+
-       for(c = cq->first; c; c = c->next) {
-               int chunk_finished = 0;
--              
-+              network_status_t ret;
-+
-               switch(c->type) {
--              case MEM_CHUNK: {
--                      char * offset;
--                      size_t toSend;
--                      ssize_t r;
--                      
--                      size_t num_chunks, i;
--                      struct iovec chunks[UIO_MAXIOV];
--                      chunk *tc;
--                      size_t num_bytes = 0;
--                      
--                      /* we can't send more then SSIZE_MAX bytes in one chunk */
--                      
--                      /* build writev list 
--                       * 
--                       * 1. limit: num_chunks < UIO_MAXIOV
--                       * 2. limit: num_bytes < SSIZE_MAX
--                       */
--                      for(num_chunks = 0, tc = c; tc && tc->type == MEM_CHUNK && num_chunks < UIO_MAXIOV; num_chunks++, tc = tc->next);
--                      
--                      for(tc = c, i = 0; i < num_chunks; tc = tc->next, i++) {
--                              if (tc->mem->used == 0) {
--                                      chunks[i].iov_base = tc->mem->ptr;
--                                      chunks[i].iov_len  = 0;
--                              } else {
--                                      offset = tc->mem->ptr + tc->offset;
--                                      toSend = tc->mem->used - 1 - tc->offset;
--                              
--                                      chunks[i].iov_base = offset;
--                                      
--                                      /* protect the return value of writev() */
--                                      if (toSend > SSIZE_MAX ||
--                                          num_bytes + toSend > SSIZE_MAX) {
--                                              chunks[i].iov_len = SSIZE_MAX - num_bytes;
--                                              
--                                              num_chunks = i + 1;
--                                              break;
--                                      } else {
--                                              chunks[i].iov_len = toSend;
--                                      }
--                                      
--                                      num_bytes += toSend;
--                              }
--                      }
--                      
--                      if ((r = writev(fd, chunks, num_chunks)) < 0) {
--                              switch (errno) {
--                              case EAGAIN:
--                              case EINTR:
--                                      r = 0;
--                                      break;
--                              case EPIPE:
--                              case ECONNRESET:
--                                      return -2;
--                              default:
--                                      log_error_write(srv, __FILE__, __LINE__, "ssd", 
--                                                      "writev failed:", strerror(errno), fd);
--                              
--                                      return -1;
--                              }
--                      }
--                      
--                      cq->bytes_out += r;
-+              case MEM_CHUNK:
-+                      ret = network_write_chunkqueue_writev_mem(srv, con, sock, cq, c);
--                      /* check which chunks have been written */
--                      
--                      for(i = 0, tc = c; i < num_chunks; i++, tc = tc->next) {
--                              if (r >= (ssize_t)chunks[i].iov_len) {
--                                      /* written */
--                                      r -= chunks[i].iov_len;
--                                      tc->offset += chunks[i].iov_len;
--                                      
-+                      /* check which chunks are finished now */
-+                      for (tc = c; tc; tc = tc->next) {
-+                              /* finished the chunk */
-+                              if (tc->offset == tc->mem->used - 1) {
-+                                      /* skip the first c->next as that will be done by the c = c->next in the other for()-loop */
-                                       if (chunk_finished) {
--                                              /* skip the chunks from further touches */
--                                              chunks_written++;
-                                               c = c->next;
-                                       } else {
--                                              /* chunks_written + c = c->next is done in the for()*/
--                                              chunk_finished++;
-+                                              chunk_finished = 1;
-                                       }
-                               } else {
--                                      /* partially written */
--                                      
--                                      tc->offset += r;
--                                      chunk_finished = 0;
--
-                                       break;
-                               }
-                       }
--                      
-+
-+                      if (ret != NETWORK_STATUS_SUCCESS) {
-+                              return ret;
-+                      }
-+
-                       break;
--              }
-               case FILE_CHUNK: {
-                       ssize_t r;
-                       off_t abs_offset;
-@@ -159,26 +175,26 @@
- #define KByte * 1024
- #define MByte * 1024 KByte
- #define GByte * 1024 MByte
--                      const off_t we_want_to_mmap = 512 KByte; 
-+                      const off_t we_want_to_mmap = 512 KByte;
-                       char *start = NULL;
-                       if (HANDLER_ERROR == stat_cache_get_entry(srv, con, c->file.name, &sce)) {
-                               log_error_write(srv, __FILE__, __LINE__, "sb",
-                                               strerror(errno), c->file.name);
--                              return -1;
-+                              return NETWORK_STATUS_FATAL_ERROR;
-                       }
-                       abs_offset = c->file.start + c->offset;
--                      
-+
-                       if (abs_offset > sce->st.st_size) {
--                              log_error_write(srv, __FILE__, __LINE__, "sb", 
-+                              log_error_write(srv, __FILE__, __LINE__, "sb",
-                                               "file was shrinked:", c->file.name);
--                              
--                              return -1;
-+
-+                              return NETWORK_STATUS_FATAL_ERROR;
-                       }
--                      /* mmap the buffer 
--                       * - first mmap 
-+                      /* mmap the buffer
-+                       * - first mmap
-                        * - new mmap as the we are at the end of the last one */
-                       if (c->file.mmap.start == MAP_FAILED ||
-                           abs_offset == (off_t)(c->file.mmap.offset + c->file.mmap.length)) {
-@@ -188,7 +204,7 @@
-                                * adaptive mem-mapping
-                                *   the problem:
-                                *     we mmap() the whole file. If someone has alot large files and 32bit
--                               *     machine the virtual address area will be unrun and we will have a failing 
-+                               *     machine the virtual address area will be unrun and we will have a failing
-                                *     mmap() call.
-                                *   solution:
-                                *     only mmap 16M in one chunk and move the window as soon as we have finished
-@@ -234,8 +250,8 @@
-                               if (-1 == c->file.fd) {  /* open the file if not already open */
-                                       if (-1 == (c->file.fd = open(c->file.name->ptr, O_RDONLY))) {
-                                               log_error_write(srv, __FILE__, __LINE__, "sbs", "open failed for:", c->file.name, strerror(errno));
--                              
--                                              return -1;
-+
-+                                              return NETWORK_STATUS_FATAL_ERROR;
-                                       }
- #ifdef FD_CLOEXEC
-                                       fcntl(c->file.fd, F_SETFD, FD_CLOEXEC);
-@@ -245,10 +261,10 @@
-                               if (MAP_FAILED == (c->file.mmap.start = mmap(0, to_mmap, PROT_READ, MAP_SHARED, c->file.fd, c->file.mmap.offset))) {
-                                       /* close it here, otherwise we'd have to set FD_CLOEXEC */
--                                      log_error_write(srv, __FILE__, __LINE__, "ssbd", "mmap failed:", 
-+                                      log_error_write(srv, __FILE__, __LINE__, "ssbd", "mmap failed:",
-                                                       strerror(errno), c->file.name, c->file.fd);
--                                      return -1;
-+                                      return NETWORK_STATUS_FATAL_ERROR;
-                               }
-                               c->file.mmap.length = to_mmap;
-@@ -258,7 +274,7 @@
- #ifdef HAVE_MADVISE
-                               /* don't advise files < 64Kb */
-                               if (c->file.mmap.length > (64 KByte)) {
--                                      /* darwin 7 is returning EINVAL all the time and I don't know how to 
-+                                      /* darwin 7 is returning EINVAL all the time and I don't know how to
-                                        * detect this at runtime.i
-                                        *
-                                        * ignore the return value for now */
-@@ -274,12 +290,12 @@
-                       toSend = (c->file.mmap.offset + c->file.mmap.length) - (abs_offset);
-                       if (toSend < 0) {
--                              log_error_write(srv, __FILE__, __LINE__, "soooo", 
-+                              log_error_write(srv, __FILE__, __LINE__, "soooo",
-                                               "toSend is negative:",
-                                               toSend,
-                                               c->file.mmap.length,
-                                               abs_offset,
--                                              c->file.mmap.offset); 
-+                                              c->file.mmap.offset);
-                               assert(toSend < 0);
-                       }
-@@ -289,7 +305,7 @@
-                       start = c->file.mmap.start;
- #endif
--                      if ((r = write(fd, start + (abs_offset - c->file.mmap.offset), toSend)) < 0) {
-+                      if ((r = write(sock->fd, start + (abs_offset - c->file.mmap.offset), toSend)) < 0) {
-                               switch (errno) {
-                               case EAGAIN:
-                               case EINTR:
-@@ -297,18 +313,18 @@
-                                       break;
-                               case EPIPE:
-                               case ECONNRESET:
--                                      return -2;
-+                                      return NETWORK_STATUS_CONNECTION_CLOSE;
-                               default:
--                                      log_error_write(srv, __FILE__, __LINE__, "ssd", 
--                                                      "write failed:", strerror(errno), fd);
--                                      
--                                      return -1;
-+                                      log_error_write(srv, __FILE__, __LINE__, "ssd",
-+                                                      "write failed:", strerror(errno), sock->fd);
-+
-+                                      return NETWORK_STATUS_FATAL_ERROR;
-                               }
-                       }
--                      
-+
-                       c->offset += r;
-                       cq->bytes_out += r;
--                      
-+
-                       if (c->offset == c->file.length) {
-                               chunk_finished = 1;
-@@ -318,26 +334,26 @@
-                                       c->file.mmap.start = MAP_FAILED;
-                               }
-                       }
--                      
-+
-                       break;
-               }
-               default:
--                      
-+
-                       log_error_write(srv, __FILE__, __LINE__, "ds", c, "type not known");
--                      
--                      return -1;
-+
-+                      return NETWORK_STATUS_FATAL_ERROR;
-               }
--              
-+
-               if (!chunk_finished) {
-                       /* not finished yet */
--                      
-+
-                       break;
-               }
--              
-+
-               chunks_written++;
-       }
--      return chunks_written;
-+      return NETWORK_STATUS_SUCCESS;
- }
- #endif
---- ../lighttpd-1.4.11/src/plugin.c    2006-02-08 14:00:54.000000000 +0200
-+++ lighttpd-1.5.0/src/plugin.c        2006-09-07 00:57:05.000000000 +0300
-@@ -13,69 +13,73 @@
- #include <valgrind/valgrind.h>
- #endif
--#ifndef __WIN32
-+#ifndef _WIN32
- #include <dlfcn.h>
- #endif
- /*
-- * 
-+ *
-  * if you change this enum to add a new callback, be sure
-  * - that PLUGIN_FUNC_SIZEOF is the last entry
-  * - that you add PLUGIN_TO_SLOT twice:
-- *   1. as callback-dispatcher 
-+ *   1. as callback-dispatcher
-  *   2. in plugins_call_init()
-- * 
-+ *
-  */
- typedef struct {
-       PLUGIN_DATA;
- } plugin_data;
--typedef enum { 
-+typedef enum {
-       PLUGIN_FUNC_UNSET,
--              PLUGIN_FUNC_HANDLE_URI_CLEAN, 
--              PLUGIN_FUNC_HANDLE_URI_RAW, 
--              PLUGIN_FUNC_HANDLE_REQUEST_DONE,
-+              PLUGIN_FUNC_HANDLE_URI_CLEAN,
-+              PLUGIN_FUNC_HANDLE_URI_RAW,
-+              PLUGIN_FUNC_HANDLE_RESPONSE_DONE,
-               PLUGIN_FUNC_HANDLE_CONNECTION_CLOSE,
-               PLUGIN_FUNC_HANDLE_TRIGGER,
-               PLUGIN_FUNC_HANDLE_SIGHUP,
--              PLUGIN_FUNC_HANDLE_SUBREQUEST,
--              PLUGIN_FUNC_HANDLE_SUBREQUEST_START,
-+              PLUGIN_FUNC_HANDLE_START_BACKEND,
-+              PLUGIN_FUNC_HANDLE_SEND_REQUEST_CONTENT,
-               PLUGIN_FUNC_HANDLE_JOBLIST,
-               PLUGIN_FUNC_HANDLE_DOCROOT,
-               PLUGIN_FUNC_HANDLE_PHYSICAL,
-               PLUGIN_FUNC_CONNECTION_RESET,
--              PLUGIN_FUNC_INIT, 
-+              PLUGIN_FUNC_INIT,
-               PLUGIN_FUNC_CLEANUP,
-               PLUGIN_FUNC_SET_DEFAULTS,
--              
-+
-               PLUGIN_FUNC_SIZEOF
- } plugin_t;
- static plugin *plugin_init(void) {
-       plugin *p;
--      
-+
-       p = calloc(1, sizeof(*p));
--      
-+
-+      p->required_plugins = array_init();
-+
-       return p;
- }
- static void plugin_free(plugin *p) {
-       int use_dlclose = 1;
-       if (p->name) buffer_free(p->name);
-+
-+      array_free(p->required_plugins);
- #ifdef HAVE_VALGRIND_VALGRIND_H
-       /*if (RUNNING_ON_VALGRIND) use_dlclose = 0;*/
- #endif
- #ifndef LIGHTTPD_STATIC
--      if (use_dlclose && p->lib) {    
--#ifdef __WIN32
-+      if (use_dlclose && p->lib) {
-+#ifdef _WIN32
-               FreeLibrary(p->lib);
- #else
-               dlclose(p->lib);
- #endif
-       }
- #endif
--              
-+
-       free(p);
- }
-@@ -89,17 +93,17 @@
-               srv->plugins.size += 4;
-               srv->plugins.ptr   = realloc(srv->plugins.ptr, srv->plugins.size * sizeof(*ps));
-       }
--      
-+
-       ps = srv->plugins.ptr;
-       ps[srv->plugins.used++] = p;
--      
-+
-       return 0;
- }
- /**
-- * 
-- * 
-- * 
-+ *
-+ *
-+ *
-  */
- #ifdef LIGHTTPD_STATIC
-@@ -121,30 +125,35 @@
- #else
- int plugins_load(server *srv) {
-       plugin *p;
-+#ifdef _WIN32
-+    FARPROC init;
-+#else
-       int (*init)(plugin *pl);
-+#endif
-+
-       const char *error;
--      size_t i;
--      
-+      size_t i, j, k;
-+
-       for (i = 0; i < srv->srvconf.modules->used; i++) {
-               data_string *d = (data_string *)srv->srvconf.modules->data[i];
-               char *modules = d->value->ptr;
--      
-+
-               buffer_copy_string_buffer(srv->tmp_buf, srv->srvconf.modules_dir);
-               buffer_append_string(srv->tmp_buf, "/");
-               buffer_append_string(srv->tmp_buf, modules);
--#if defined(__WIN32) || defined(__CYGWIN__)
-+#if defined(_WIN32) || defined(__CYGWIN__)
-               buffer_append_string(srv->tmp_buf, ".dll");
- #else
-               buffer_append_string(srv->tmp_buf, ".so");
- #endif
--      
-+
-               p = plugin_init();
--#ifdef __WIN32
-+#ifdef _WIN32
-               if (NULL == (p->lib = LoadLibrary(srv->tmp_buf->ptr))) {
-                       LPVOID lpMsgBuf;
-                       FormatMessage(
--                              FORMAT_MESSAGE_ALLOCATE_BUFFER | 
-+                              FORMAT_MESSAGE_ALLOCATE_BUFFER |
-                               FORMAT_MESSAGE_FROM_SYSTEM,
-                               NULL,
-                               GetLastError(),
-@@ -152,36 +161,36 @@
-                               (LPTSTR) &lpMsgBuf,
-                               0, NULL );
--                      log_error_write(srv, __FILE__, __LINE__, "ssb", "LoadLibrary() failed", 
-+                      log_error_write(srv, __FILE__, __LINE__, "ssb", "LoadLibrary() failed",
-                                       lpMsgBuf, srv->tmp_buf);
--                      
-+
-                       plugin_free(p);
--                      
-+
-                       return -1;
-               }
--#else 
-+#else
-               if (NULL == (p->lib = dlopen(srv->tmp_buf->ptr, RTLD_LAZY))) {
--                      log_error_write(srv, __FILE__, __LINE__, "sbs", "dlopen() failed for:", 
-+                      log_error_write(srv, __FILE__, __LINE__, "sbs", "dlopen() failed for:",
-                                       srv->tmp_buf, dlerror());
--                      
-+
-                       plugin_free(p);
--                      
-+
-                       return -1;
-               }
--              
-+
- #endif
-               buffer_reset(srv->tmp_buf);
-               buffer_copy_string(srv->tmp_buf, modules);
-               buffer_append_string(srv->tmp_buf, "_plugin_init");
--#ifdef __WIN32
-+#ifdef _WIN32
-               init = GetProcAddress(p->lib, srv->tmp_buf->ptr);
-               if (init == NULL)  {
-                       LPVOID lpMsgBuf;
-                       FormatMessage(
--                              FORMAT_MESSAGE_ALLOCATE_BUFFER | 
-+                              FORMAT_MESSAGE_ALLOCATE_BUFFER |
-                               FORMAT_MESSAGE_FROM_SYSTEM,
-                               NULL,
-                               GetLastError(),
-@@ -190,7 +199,7 @@
-                               0, NULL );
-                       log_error_write(srv, __FILE__, __LINE__, "sbs", "getprocaddress failed:", srv->tmp_buf, lpMsgBuf);
--                      
-+
-                       plugin_free(p);
-                       return -1;
-               }
-@@ -203,24 +212,43 @@
- #endif
-               if ((error = dlerror()) != NULL)  {
-                       log_error_write(srv, __FILE__, __LINE__, "s", error);
--                      
-+
-                       plugin_free(p);
-                       return -1;
-               }
--      
-+
- #endif
-               if ((*init)(p)) {
-                       log_error_write(srv, __FILE__, __LINE__, "ss", modules, "plugin init failed" );
--                      
-+
-                       plugin_free(p);
-                       return -1;
-               }
- #if 0
-               log_error_write(srv, __FILE__, __LINE__, "ss", modules, "plugin loaded" );
- #endif
-+              /* check if the required plugin is loaded */
-+              for (k = 0; k < p->required_plugins->used; k++) {
-+                      data_string *req = (data_string *)p->required_plugins->data[k];
-+
-+                      for (j = 0; j < i; j++) {
-+                              data_string *mod = (data_string *)srv->srvconf.modules->data[j];
-+
-+                              if (buffer_is_equal(req->value, mod->value)) break;
-+                      }
-+
-+                      if (j == i) {
-+                              /* not found */
-+                              log_error_write(srv, __FILE__, __LINE__, "ssbs", modules, "failed to load. required plugin", req->value, "was not loaded" );
-+
-+                              plugin_free(p);
-+                      
-+                              return -1;
-+                      }
-+              }
-               plugins_register(srv, p);
-       }
--      
-+
-       return 0;
- }
- #endif
-@@ -253,8 +281,8 @@
-       }
- /**
-- * plugins that use 
-- * 
-+ * plugins that use
-+ *
-  * - server *srv
-  * - connection *con
-  * - void *p_d (plugin_data *)
-@@ -262,13 +290,13 @@
- PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_URI_CLEAN, handle_uri_clean)
- PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_URI_RAW, handle_uri_raw)
--PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_REQUEST_DONE, handle_request_done)
--PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_CONNECTION_CLOSE, handle_connection_close)
--PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_SUBREQUEST, handle_subrequest)
--PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_SUBREQUEST_START, handle_subrequest_start)
--PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_JOBLIST, handle_joblist)
- PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_DOCROOT, handle_docroot)
- PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_PHYSICAL, handle_physical)
-+PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_START_BACKEND, handle_start_backend)
-+PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_SEND_REQUEST_CONTENT, handle_send_request_content)
-+PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_CONNECTION_CLOSE, handle_connection_close)
-+PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_RESPONSE_DONE, handle_response_done)
-+PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_JOBLIST, handle_joblist)
- PLUGIN_TO_SLOT(PLUGIN_FUNC_CONNECTION_RESET, connection_reset)
- #undef PLUGIN_TO_SLOT
-@@ -301,12 +329,12 @@
-       }
- /**
-- * plugins that use 
-- * 
-+ * plugins that use
-+ *
-  * - server *srv
-  * - void *p_d (plugin_data *)
-  */
--                                                                      
-+
- PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_TRIGGER, handle_trigger)
- PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_SIGHUP, handle_sighup)
- PLUGIN_TO_SLOT(PLUGIN_FUNC_CLEANUP, cleanup)
-@@ -314,18 +342,18 @@
- #undef PLUGIN_TO_SLOT
--#if 0                                                                 
-+#if 0
- /**
-- * 
-+ *
-  * special handler
-- * 
-+ *
-  */
- handler_t plugins_call_handle_fdevent(server *srv, const fd_conn *fdc) {
-       size_t i;
-       plugin **ps;
--      
-+
-       ps = srv->plugins.ptr;
--      
-+
-       for (i = 0; i < srv->plugins.used; i++) {
-               plugin *p = ps[i];
-               if (p->handle_fdevent) {
-@@ -344,34 +372,34 @@
-                       }
-               }
-       }
--      
-+
-       return HANDLER_GO_ON;
- }
- #endif
- /**
-- * 
-+ *
-  * - call init function of all plugins to init the plugin-internals
-  * - added each plugin that supports has callback to the corresponding slot
-- * 
-+ *
-  * - is only called once.
-  */
- handler_t plugins_call_init(server *srv) {
-       size_t i;
-       plugin **ps;
--      
-+
-       ps = srv->plugins.ptr;
--      
-+
-       /* fill slots */
--      
-+
-       srv->plugin_slots = calloc(PLUGIN_FUNC_SIZEOF, sizeof(ps));
--      
-+
-       for (i = 0; i < srv->plugins.used; i++) {
-               size_t j;
-               /* check which calls are supported */
--              
-+
-               plugin *p = ps[i];
--              
-+
- #define PLUGIN_TO_SLOT(x, y) \
-       if (p->y) { \
-               plugin **slot = ((plugin ***)(srv->plugin_slots))[x]; \
-@@ -384,37 +412,38 @@
-                       slot[j] = p;\
-                       break;\
-               }\
--      } 
--              
--              
--              PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_URI_CLEAN, handle_uri_clean); 
--              PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_URI_RAW, handle_uri_raw); 
--              PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_REQUEST_DONE, handle_request_done);
--              PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_CONNECTION_CLOSE, handle_connection_close);
--              PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_TRIGGER, handle_trigger);
--              PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_SIGHUP, handle_sighup);
--              PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_SUBREQUEST, handle_subrequest);
--              PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_SUBREQUEST_START, handle_subrequest_start);
--              PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_JOBLIST, handle_joblist);
-+      }
-+
-+
-+              PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_URI_CLEAN, handle_uri_clean);
-+              PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_URI_RAW, handle_uri_raw);
-               PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_DOCROOT, handle_docroot);
-               PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_PHYSICAL, handle_physical);
-+              PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_START_BACKEND, handle_start_backend);
-+              PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_SEND_REQUEST_CONTENT, handle_send_request_content);
-+              PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_RESPONSE_DONE, handle_response_done);
-+              PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_CONNECTION_CLOSE, handle_connection_close);
-+
-+              PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_JOBLIST, handle_joblist);
-               PLUGIN_TO_SLOT(PLUGIN_FUNC_CONNECTION_RESET, connection_reset);
-               PLUGIN_TO_SLOT(PLUGIN_FUNC_CLEANUP, cleanup);
-               PLUGIN_TO_SLOT(PLUGIN_FUNC_SET_DEFAULTS, set_defaults);
-+              PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_TRIGGER, handle_trigger);
-+              PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_SIGHUP, handle_sighup);
- #undef PLUGIN_TO_SLOT
--              
-+
-               if (p->init) {
-                       if (NULL == (p->data = p->init())) {
--                              log_error_write(srv, __FILE__, __LINE__, "sb", 
-+                              log_error_write(srv, __FILE__, __LINE__, "sb",
-                                               "plugin-init failed for module", p->name);
-                               return HANDLER_ERROR;
-                       }
--                      
-+
-                       /* used for con->mode, DIRECT == 0, plugins above that */
-                       ((plugin_data *)(p->data))->id = i + 1;
--                      
-+
-                       if (p->version != LIGHTTPD_VERSION_ID) {
--                              log_error_write(srv, __FILE__, __LINE__, "sb", 
-+                              log_error_write(srv, __FILE__, __LINE__, "sb",
-                                               "plugin-version doesn't match lighttpd-version for", p->name);
-                               return HANDLER_ERROR;
-                       }
-@@ -422,29 +451,46 @@
-                       p->data = NULL;
-               }
-       }
--      
-+
-       return HANDLER_GO_ON;
- }
-+/**
-+ * get the config-storage of the named plugin 
-+ */
-+void *plugin_get_config(server *srv, const char *name) {
-+      size_t i;
-+
-+      for (i = 0; i < srv->plugins.used; i++) {
-+              plugin *p = ((plugin **)srv->plugins.ptr)[i];
-+
-+              if (buffer_is_equal_string(p->name, name, strlen(name))) {
-+                      return p->data;
-+              }
-+      }
-+
-+      return NULL;
-+}
-+
- void plugins_free(server *srv) {
-       size_t i;
-       plugins_call_cleanup(srv);
--      
-+
-       for (i = 0; i < srv->plugins.used; i++) {
-               plugin *p = ((plugin **)srv->plugins.ptr)[i];
--              
-+
-               plugin_free(p);
-       }
--      
-+
-       for (i = 0; srv->plugin_slots && i < PLUGIN_FUNC_SIZEOF; i++) {
-               plugin **slot = ((plugin ***)(srv->plugin_slots))[i];
--              
-+
-               if (slot) free(slot);
-       }
--      
-+
-       free(srv->plugin_slots);
-       srv->plugin_slots = NULL;
--      
-+
-       free(srv->plugins.ptr);
-       srv->plugins.ptr = NULL;
-       srv->plugins.used = 0;
---- ../lighttpd-1.4.11/src/plugin.h    2005-08-15 12:28:56.000000000 +0300
-+++ lighttpd-1.5.0/src/plugin.h        2006-09-07 00:57:05.000000000 +0300
-@@ -12,6 +12,12 @@
- #define INIT_FUNC(x) \
-               static void *x()
-+/*
-+ * The PATCH_OPTION() macro is used in the patch_connection() functions
-+ * of the modules to update the config object for the current request.
-+ */
-+#define PATCH_OPTION(x) \
-+              p->conf.x = s->x
- #define FREE_FUNC          SERVER_FUNC
- #define TRIGGER_FUNC       SERVER_FUNC
-@@ -25,40 +31,45 @@
- #define URIHANDLER_FUNC    CONNECTION_FUNC
- #define PLUGIN_DATA        size_t id
--                                                                                                                                              
-+
-+/**
-+ * we have 4 states on the connection:
-+ * - read-header
-+ * - read-content
-+ * - write-header
-+ * - write-content
-+ */
-+
- typedef struct {
-       size_t version;
--      
-+
-       buffer *name; /* name of the plugin */
--      
-+
-       void *(* init)                       ();
-       handler_t (* set_defaults)           (server *srv, void *p_d);
-       handler_t (* cleanup)                (server *srv, void *p_d);
-                                                                                          /* is called ... */
-       handler_t (* handle_trigger)         (server *srv, void *p_d);                     /* once a second */
-       handler_t (* handle_sighup)          (server *srv, void *p_d);                     /* at a signup */
--      
--      handler_t (* handle_uri_raw)         (server *srv, connection *con, void *p_d);    /* after uri_raw is set */
--      handler_t (* handle_uri_clean)       (server *srv, connection *con, void *p_d);    /* after uri is set */
--      handler_t (* handle_docroot)         (server *srv, connection *con, void *p_d);    /* getting the document-root */
--      handler_t (* handle_physical)        (server *srv, connection *con, void *p_d);    /* mapping url to physical path */
--      handler_t (* handle_request_done)    (server *srv, connection *con, void *p_d);    /* at the end of a request */
--      handler_t (* handle_connection_close)(server *srv, connection *con, void *p_d);    /* at the end of a connection */
--      handler_t (* handle_joblist)         (server *srv, connection *con, void *p_d);    /* after all events are handled */
--      
--      
--      
--      handler_t (* handle_subrequest_start)(server *srv, connection *con, void *p_d);   
--      
--                                                                                         /* when a handler for the request 
--                                                                                          * has to be found
--                                                                                          */
--      handler_t (* handle_subrequest)      (server *srv, connection *con, void *p_d);    /* */
--      handler_t (* connection_reset)       (server *srv, connection *con, void *p_d);    /* */
-+
-+      handler_t (* handle_uri_raw)         (server *srv, connection *con, void *p_d);    /* after uri_raw is set (mod_rewrite) */
-+      handler_t (* handle_uri_clean)       (server *srv, connection *con, void *p_d);    /* after uri is set (mod_access, mod_auth) */
-+      handler_t (* handle_docroot)         (server *srv, connection *con, void *p_d);    /* getting the document-root (e.g. mod_simple_vhost) */
-+      handler_t (* handle_physical)        (server *srv, connection *con, void *p_d);    /* mapping url to physical path (e.g. mod_alias, mod_proxy_core) */
-+      handler_t (* handle_start_backend)   (server *srv, connection *con, void *p_d);    /* file exists locally (e.g. mod_staticfile) */
-+      handler_t (* handle_send_request_content)(server *srv, connection *con, void *p_d);    /* a handler for the request content */
-+      handler_t (* handle_response_header) (server *srv, connection *con, void *p_d);    /* a handler for the request content */
-+      handler_t (* handle_response_done)   (server *srv, connection *con, void *p_d);    /* after the response is sent (e.g. mod_accesslog) */
-+      handler_t (* connection_reset)       (server *srv, connection *con, void *p_d);    /* end of a request-response cycle (mod_acceslog, mod_proxy_core) */
-+      handler_t (* handle_connection_close)(server *srv, connection *con, void *p_d);    /* at the end of a connection [remove-me ?] */
-+      handler_t (* handle_joblist)         (server *srv, connection *con, void *p_d);    /* after all events are handled [remove-me ?] */
-+
-       void *data;
--      
-+
-       /* dlopen handle */
-       void *lib;
-+
-+      array *required_plugins;
- } plugin;
- int plugins_load(server *srv);
-@@ -66,11 +77,12 @@
- handler_t plugins_call_handle_uri_raw(server *srv, connection *con);
- handler_t plugins_call_handle_uri_clean(server *srv, connection *con);
--handler_t plugins_call_handle_subrequest_start(server *srv, connection *con);
--handler_t plugins_call_handle_subrequest(server *srv, connection *con);
--handler_t plugins_call_handle_request_done(server *srv, connection *con);
- handler_t plugins_call_handle_docroot(server *srv, connection *con);
- handler_t plugins_call_handle_physical(server *srv, connection *con);
-+handler_t plugins_call_handle_start_backend(server *srv, connection *con);
-+handler_t plugins_call_handle_send_request_content(server *srv, connection *con);
-+handler_t plugins_call_handle_response_header(server *srv, connection *con);
-+handler_t plugins_call_handle_response_done(server *srv, connection *con);
- handler_t plugins_call_handle_connection_close(server *srv, connection *con);
- handler_t plugins_call_handle_joblist(server *srv, connection *con);
- handler_t plugins_call_connection_reset(server *srv, connection *con);
-@@ -88,5 +100,8 @@
- int config_patch_connection(server *srv, connection *con, comp_key_t comp);
- int config_check_cond(server *srv, connection *con, data_config *dc);
- int config_append_cond_match_buffer(connection *con, data_config *dc, buffer *buf, int n);
-+int config_exec_pcre_keyvalue_buffer(connection *con, pcre_keyvalue_buffer *kvb, data_config *context, buffer *match_buf, buffer *result);
-+
-+void *plugin_get_config(server *srv, const char *name);
- #endif
---- ../lighttpd-1.4.11/src/proc_open.c 2005-08-11 01:26:39.000000000 +0300
-+++ lighttpd-1.5.0/src/proc_open.c     2006-07-16 00:26:04.000000000 +0300
-@@ -13,13 +13,13 @@
- #endif
--#ifdef WIN32
-+#ifdef _WIN32
- /* {{{ win32 stuff */
- # define SHELLENV "ComSpec"
- # define SECURITY_DC , SECURITY_ATTRIBUTES *security
- # define SECURITY_CC , security
- # define pipe(pair) (CreatePipe(&pair[0], &pair[1], security, 2048L) ? 0 : -1)
--static inline HANDLE dup_handle(HANDLE src, BOOL inherit, BOOL closeorig)
-+static HANDLE dup_handle(HANDLE src, BOOL inherit, BOOL closeorig)
- {
-       HANDLE copy, self = GetCurrentProcess();
-@@ -148,11 +148,14 @@
-       STARTUPINFO si;
-       BOOL procok;
-       SECURITY_ATTRIBUTES security;
--      const char *shell;
-+      const char *shell = NULL;
-+      const char *windir = NULL;
-       buffer *cmdline;
--      if (NULL == (shell = getenv(SHELLENV))) {
--              fprintf(stderr, "env %s is required", SHELLENV);
-+      if (NULL == (shell = getenv(SHELLENV)) &&
-+                      NULL == (windir = getenv("SystemRoot")) &&
-+                      NULL == (windir = getenv("windir"))) {
-+              fprintf(stderr, "One of %s,%%SystemRoot,%%windir is required", SHELLENV);
-               return -1;
-       }
-@@ -177,17 +180,23 @@
-       memset(&pi, 0, sizeof(pi));
-       cmdline = buffer_init();
--      buffer_append_string(cmdline, shell);
-+      if (shell) {
-+              buffer_append_string(cmdline, shell);
-+      } else {
-+              buffer_append_string(cmdline, windir);
-+              buffer_append_string(cmdline, "\\system32\\cmd.exe");
-+      }
-       buffer_append_string_len(cmdline, CONST_STR_LEN(" /c "));
-       buffer_append_string(cmdline, command);
-       procok = CreateProcess(NULL, cmdline->ptr, &security, &security, TRUE,
-                       NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi);
--      buffer_free(cmdline);
-       if (FALSE == procok) {
--              fprintf(stderr, "failed to CreateProcess");
-+              fprintf(stderr, "failed to CreateProcess: %s", cmdline->ptr);
-+              buffer_free(cmdline);
-               return -1;
-       }
-+      buffer_free(cmdline);
-       proc->child = pi.hProcess;
-       CloseHandle(pi.hThread);
-@@ -226,8 +235,7 @@
-       const char *shell;
-       if (NULL == (shell = getenv(SHELLENV))) {
--              fprintf(stderr, "env %s is required", SHELLENV);
--              return -1;
-+              shell = "/bin/sh";
-       }
-       if (proc_open_pipes(proc) != 0) {
-@@ -262,11 +270,11 @@
-       }
- }
- /* }}} */
--#endif /* WIN32 */
-+#endif /* _WIN32 */
- /* {{{ proc_read_fd_to_buffer */
- static void proc_read_fd_to_buffer(int fd, buffer *b) {
--      ssize_t s;
-+      int s; /* win32 has not ssize_t */
-       for (;;) {
-               buffer_prepare_append(b, 512);
---- ../lighttpd-1.4.11/src/proc_open.h 2005-08-11 01:26:39.000000000 +0300
-+++ lighttpd-1.5.0/src/proc_open.h     2006-07-16 00:26:04.000000000 +0300
-@@ -1,7 +1,7 @@
- #include "buffer.h"
--#ifdef WIN32
-+#ifdef _WIN32
- #include <windows.h>
- typedef HANDLE descriptor_t;
- typedef HANDLE proc_pid_t;
---- ../lighttpd-1.4.11/src/request.c   2006-03-05 11:58:09.000000000 +0200
-+++ lighttpd-1.5.0/src/request.c       2006-09-07 00:57:05.000000000 +0300
-@@ -5,22 +5,23 @@
- #include <string.h>
- #include <stdio.h>
- #include <ctype.h>
-+#include <errno.h>
- #include "request.h"
- #include "keyvalue.h"
- #include "log.h"
-+#include "http_req.h"
--static int request_check_hostname(server *srv, connection *con, buffer *host) {
-+#include "sys-strings.h"
-+
-+static int request_check_hostname(buffer *host) {
-       enum { DOMAINLABEL, TOPLABEL } stage = TOPLABEL;
-       size_t i;
-       int label_len = 0;
-       size_t host_len;
-       char *colon;
--      int is_ip = -1; /* -1 don't know yet, 0 no, 1 yes */ 
-+      int is_ip = -1; /* -1 don't know yet, 0 no, 1 yes */
-       int level = 0;
--      
--      UNUSED(srv);
--      UNUSED(con);
-       /*
-        *       hostport      = host [ ":" port ]
-@@ -32,17 +33,18 @@
-        *       IPv6address   = "[" ... "]"
-        *       port          = *digit
-        */
--      
-+
-       /* no Host: */
--      if (!host || host->used == 0) return 0;
--      
-+      if (buffer_is_empty(host)) return 0;
-+      if (host->used < 1) return 0;
-+
-       host_len = host->used - 1;
--      
-+
-       /* IPv6 adress */
-       if (host->ptr[0] == '[') {
-               char *c = host->ptr + 1;
-               int colon_cnt = 0;
--              
-+
-               /* check portnumber */
-               for (; *c && *c != ']'; c++) {
-                       if (*c == ':') {
-@@ -53,12 +55,12 @@
-                               return -1;
-                       }
-               }
--              
-+
-               /* missing ] */
-               if (!*c) {
-                       return -1;
-               }
--              
-+
-               /* check port */
-               if (*(c+1) == ':') {
-                       for (c += 2; *c; c++) {
-@@ -69,39 +71,39 @@
-               }
-               return 0;
-       }
--      
-+
-       if (NULL != (colon = memchr(host->ptr, ':', host_len))) {
-               char *c = colon + 1;
--              
-+
-               /* check portnumber */
-               for (; *c; c++) {
-                       if (!light_isdigit(*c)) return -1;
-               }
--              
-+
-               /* remove the port from the host-len */
-               host_len = colon - host->ptr;
-       }
--      
-+
-       /* Host is empty */
-       if (host_len == 0) return -1;
--      
-+
-       /* scan from the right and skip the \0 */
-       for (i = host_len - 1; i + 1 > 0; i--) {
-               const char c = host->ptr[i];
-               switch (stage) {
--              case TOPLABEL: 
-+              case TOPLABEL:
-                       if (c == '.') {
-                               /* only switch stage, if this is not the last character */
-                               if (i != host_len - 1) {
-                                       if (label_len == 0) {
-                                               return -1;
-                                       }
--                                      
-+
-                                       /* check the first character at right of the dot */
-                                       if (is_ip == 0) {
-                                               if (!light_isalpha(host->ptr[i+1])) {
--                                                      return -1; 
-+                                                      return -1;
-                                               }
-                                       } else if (!light_isdigit(host->ptr[i+1])) {
-                                               is_ip = 0;
-@@ -111,9 +113,9 @@
-                                               /* just digits */
-                                               is_ip = 1;
-                                       }
--                                              
-+
-                                       stage = DOMAINLABEL;
--                                      
-+
-                                       label_len = 0;
-                                       level++;
-                               } else if (i == 0) {
-@@ -135,7 +137,7 @@
-                               }
-                               label_len++;
-                       }
--                      
-+
-                       break;
-               case DOMAINLABEL:
-                       if (is_ip == 1) {
-@@ -143,7 +145,7 @@
-                                       if (label_len == 0) {
-                                               return -1;
-                                       }
--                                      
-+
-                                       label_len = 0;
-                                       level++;
-                               } else if (!light_isdigit(c)) {
-@@ -156,12 +158,12 @@
-                                       if (label_len == 0) {
-                                               return -1;
-                                       }
--                                      
-+
-                                       /* c is either - or alphanum here */
-                                       if ('-' == host->ptr[i+1]) {
-                                               return -1;
-                                       }
--                                      
-+
-                                       label_len = 0;
-                                       level++;
-                               } else if (i == 0) {
-@@ -176,20 +178,20 @@
-                                       label_len++;
-                               }
-                       }
--                      
-+
-                       break;
-               }
-       }
--      
-+
-       /* a IP has to consist of 4 parts */
-       if (is_ip == 1 && level != 3) {
-               return -1;
-       }
--      
-+
-       if (label_len == 0) {
-               return -1;
-       }
--      
-+
-       return 0;
- }
-@@ -201,53 +203,53 @@
-       char *s;
-       size_t i;
-       int state = 0;
--      /*  
--       * parse 
--       * 
-+      /*
-+       * parse
-+       *
-        * val1, val2, val3, val4
--       * 
-+       *
-        * into a array (more or less a explode() incl. striping of whitespaces
-        */
--      
-+
-       if (b->used == 0) return 0;
--      
-+
-       s = b->ptr;
--      
-+
-       for (i =0; i < b->used - 1; ) {
-               char *start = NULL, *end = NULL;
-               data_string *ds;
--              
-+
-               switch (state) {
-               case 0: /* ws */
--                      
-+
-                       /* skip ws */
-                       for (; (*s == ' ' || *s == '\t') && i < b->used - 1; i++, s++);
--                      
--                      
-+
-+
-                       state = 1;
-                       break;
-               case 1: /* value */
-                       start = s;
--                      
-+
-                       for (; *s != ',' && i < b->used - 1; i++, s++);
-                       end = s - 1;
--                      
-+
-                       for (; (*end == ' ' || *end == '\t') && end > start; end--);
--                      
-+
-                       if (NULL == (ds = (data_string *)array_get_unused_element(vals, TYPE_STRING))) {
-                               ds = data_string_init();
-                       }
-                       buffer_copy_string_len(ds->value, start, end-start+1);
-                       array_insert_unique(vals, (data_unset *)ds);
--                      
-+
-                       if (*s == ',') {
-                               state = 0;
-                               i++;
-                               s++;
-                       } else {
-                               /* end of string */
--                              
-+
-                               state = 2;
-                       }
-                       break;
-@@ -263,747 +265,239 @@
-       if (c <= 32) return 0;
-       if (c == 127) return 0;
-       if (c == 255) return 0;
--      
-+
-       return 1;
- }
--int http_request_parse(server *srv, connection *con) {
--      char *uri = NULL, *proto = NULL, *method = NULL, con_length_set;
--      int is_key = 1, key_len = 0, is_ws_after_key = 0, in_folding;
--      char *value = NULL, *key = NULL;
--      
--      enum { HTTP_CONNECTION_UNSET, HTTP_CONNECTION_KEEPALIVE, HTTP_CONNECTION_CLOSE } keep_alive_set = HTTP_CONNECTION_UNSET;
--      
--      int line = 0;
--      
--      int request_line_stage = 0;
--      size_t i, first;
--      
--      int done = 0;
--      
--      data_string *ds = NULL;
--      
--      /* 
--       * Request: "^(GET|POST|HEAD) ([^ ]+(\\?[^ ]+|)) (HTTP/1\\.[01])$" 
--       * Option : "^([-a-zA-Z]+): (.+)$"                    
--       * End    : "^$"
--       */
-+int http_request_parse(server *srv, connection *con, http_req *req) {
-+      size_t i;
-+      enum { HTTP_CONNECTION_UNSET, HTTP_CONNECTION_CLOSE, HTTP_CONNECTION_KEEPALIVE } keep_alive_set = HTTP_CONNECTION_UNSET;
--      if (con->conf.log_request_header) {
--              log_error_write(srv, __FILE__, __LINE__, "sdsdSb", 
--                              "fd:", con->fd, 
--                              "request-len:", con->request.request->used, 
--                              "\n", con->request.request);
-+      if (req->protocol == HTTP_VERSION_UNSET) {
-+              con->http_status = 505; /* Version not Supported */
-+              return 0;
-       }
--      if (con->request_count > 1 &&
--          con->request.request->ptr[0] == '\r' &&
--          con->request.request->ptr[1] == '\n') {
--              /* we are in keep-alive and might get \r\n after a previous POST request.*/
--              
--              buffer_copy_string_len(con->parse_request, con->request.request->ptr + 2, con->request.request->used - 1 - 2);
--      } else {
--              /* fill the local request buffer */
--              buffer_copy_string_buffer(con->parse_request, con->request.request);
-+      if (req->method == HTTP_METHOD_UNSET) {
-+              con->http_status = 405; /* Method not allowed */
-+              return 0;
-       }
--      
--      keep_alive_set = 0;
--      con_length_set = 0;
--      /* parse the first line of the request
--       *
--       * should be:
--       *
--       * <method> <uri> <protocol>\r\n
-+      if (buffer_is_empty(req->uri_raw)) {
-+              con->http_status = 400;
-+              return 0;
-+      }
-+
-+      /* strip absolute URLs
-        * */
--      for (i = 0, first = 0; i < con->parse_request->used && line == 0; i++) {
--              char *cur = con->parse_request->ptr + i;
-+
-+      buffer_copy_string_buffer(con->request.orig_uri, req->uri_raw);
-+      if (req->uri_raw->ptr[0] == '/') {
-+              buffer_copy_string_buffer(con->request.uri, req->uri_raw);
-+      } else if (req->uri_raw->ptr[0] == '*') {
-+              if (req->method != HTTP_METHOD_OPTIONS) {
-+                      con->http_status = 400;
-+                      return 0;
-+              }
-+              buffer_copy_string_buffer(con->request.uri, req->uri_raw);
-+      } else {
-+              /* GET http://www.example.org/foobar */
-+              char *sl;
-+
-+              if (0 != strncmp(BUF_STR(req->uri_raw), "http://", 7)) {
-+                      con->http_status = 400;
-+                      return 0;
-+              }
-+
-+              if (NULL == (sl = strchr(BUF_STR(req->uri_raw) + 7, '/'))) {
-+                      con->http_status = 400;
-+                      return 0;
-+              }
-               
--              switch(*cur) {
--              case '\r': 
--                      if (con->parse_request->ptr[i+1] == '\n') {
--                              http_method_t r;
--                              char *nuri = NULL;
--                              size_t j;
--                              
--                              /* \r\n -> \0\0 */
--                              con->parse_request->ptr[i] = '\0';
--                              con->parse_request->ptr[i+1] = '\0';
--                              
--                              buffer_copy_string_len(con->request.request_line, con->parse_request->ptr, i);
--                              
--                              if (request_line_stage != 2) {
--                                      con->http_status = 400;
--                                      con->response.keep_alive = 0;
--                                      con->keep_alive = 0;
--                                      
--                                      if (srv->srvconf.log_request_header_on_error) {
--                                              log_error_write(srv, __FILE__, __LINE__, "s", "incomplete request line -> 400");
--                                              log_error_write(srv, __FILE__, __LINE__, "Sb",
--                                                              "request-header:\n",
--                                                              con->request.request);
--                                      }
--                                      return 0;
--                              }
--                              
--                              proto = con->parse_request->ptr + first;
--                              
--                              *(uri - 1) = '\0';
--                              *(proto - 1) = '\0';
--                              
--                              /* we got the first one :) */
--                              if (-1 == (r = get_http_method_key(method))) {
--                                      con->http_status = 501;
--                                      con->response.keep_alive = 0;
--                                      con->keep_alive = 0;
--                                      
--                                      if (srv->srvconf.log_request_header_on_error) {
--                                              log_error_write(srv, __FILE__, __LINE__, "s", "unknown http-method -> 501");
--                                              log_error_write(srv, __FILE__, __LINE__, "Sb",
--                                                              "request-header:\n",
--                                                              con->request.request);
--                                      }
--                              
--                                      return 0;
-+              buffer_copy_string(con->request.uri, sl);
-+              buffer_copy_string_len(con->request.http_host, BUF_STR(req->uri_raw) + 7, sl - BUF_STR(req->uri_raw) - 7);
-+      }
-+
-+      con->request.http_method = req->method;
-+      con->request.http_version = req->protocol;
-+
-+      for (i = 0; i < req->headers->used; i++) {
-+              data_string *ds = (data_string *)req->headers->data[i];
-+              data_string *hdr;
-+              int cmp;
-+
-+              /* this list is sorted */
-+              if (0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Connection")))) {
-+                      array *vals;
-+                      size_t vi;
-+                      /* Connection: Keep-Alive, ... */
-+
-+                      vals = srv->split_vals;
-+
-+                      array_reset(vals);
-+                      http_request_split_value(vals, ds->value);
-+
-+                      for (vi = 0; vi < vals->used; vi++) {
-+                              data_string *dsv = (data_string *)vals->data[vi];
-+
-+                              if (0 == buffer_caseless_compare(CONST_BUF_LEN(dsv->value), CONST_STR_LEN("keep-alive"))) {
-+                                      keep_alive_set = HTTP_CONNECTION_KEEPALIVE;
-+
-+                                      break;
-+                              } else if (0 == buffer_caseless_compare(CONST_BUF_LEN(dsv->value), CONST_STR_LEN("close"))) {
-+                                      keep_alive_set = HTTP_CONNECTION_CLOSE;
-+
-+                                      break;
-                               }
--                              
--                              con->request.http_method = r;
--                      
--                              /* 
--                               * RFC2616 says:
--                               *
--                               * HTTP-Version   = "HTTP" "/" 1*DIGIT "." 1*DIGIT
--                               *
--                               * */   
--                              if (0 == strncmp(proto, "HTTP/", sizeof("HTTP/") - 1)) {
--                                      char * major = proto + sizeof("HTTP/") - 1;
--                                      char * minor = strchr(major, '.');
--                                      char *err = NULL;
--                                      int major_num = 0, minor_num = 0;
--
--                                      int invalid_version = 0;
--
--                                      if (NULL == minor || /* no dot */
--                                          minor == major || /* no major */
--                                          *(minor + 1) == '\0' /* no minor */) {
--                                              invalid_version = 1;
--                                      } else {
--                                              *minor = '\0';
--                                              major_num = strtol(major, &err, 10);
-+                      }
-+              } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Content-Length")))) {
-+                      char *err;
-+                      long long int r;
--                                              if (*err != '\0') invalid_version = 1;
-+                      /* ignore the header, if it is a duplicate */
-+                      if (con->request.content_length != -1) continue;
--                                              *minor++ = '.';
--                                              minor_num = strtol(minor, &err, 10);
-+                      r = strtoll(ds->value->ptr, &err, 10);
--                                              if (*err != '\0') invalid_version = 1;
--                                      }
-+                      if (*err != '\0') {
-+                              TRACE("content-length is not a number: %s (Status: 400)", err);
--                                      if (invalid_version) {
--                                              con->http_status = 400;
--                                              con->keep_alive = 0;
--
--                                              if (srv->srvconf.log_request_header_on_error) {
--                                                      log_error_write(srv, __FILE__, __LINE__, "s", "unknown protocol -> 400");
--                                                      log_error_write(srv, __FILE__, __LINE__, "Sb",
--                                                                      "request-header:\n",
--                                                                      con->request.request);
--                                              }
--                                              return 0;
--                                      }
-+                              con->http_status = 400;
--                                      if (major_num == 1 && minor_num == 1) {
--                                              con->request.http_version = con->conf.allow_http11 ? HTTP_VERSION_1_1 : HTTP_VERSION_1_0;
--                                      } else if (major_num == 1 && minor_num == 0) {
--                                              con->request.http_version = HTTP_VERSION_1_0;
--                                      } else { 
--                                              con->http_status = 505;
--
--                                              if (srv->srvconf.log_request_header_on_error) {
--                                                      log_error_write(srv, __FILE__, __LINE__, "s", "unknown HTTP version -> 505");
--                                                      log_error_write(srv, __FILE__, __LINE__, "Sb",
--                                                                      "request-header:\n",
--                                                                      con->request.request);
--                                              }
--                                              return 0;
--                                      }
--                              } else {
--                                      con->http_status = 400;
--                                      con->keep_alive = 0;
-+                              return 0;
-+                      }
-+
-+                      if (r == LLONG_MIN ||
-+                          r == LLONG_MAX) {
-+                              if (errno == ERANGE) {
-+                                      con->http_status = 413;
--                                      if (srv->srvconf.log_request_header_on_error) {
--                                              log_error_write(srv, __FILE__, __LINE__, "s", "unknown protocol -> 400");
--                                              log_error_write(srv, __FILE__, __LINE__, "Sb",
--                                                              "request-header:\n",
--                                                              con->request.request);
--                                      }
-                                       return 0;
-                               }
--                              
--                              if (0 == strncmp(uri, "http://", 7) &&
--                                  NULL != (nuri = strchr(uri + 7, '/'))) {
--                                      /* ignore the host-part */
--                                      
--                                      buffer_copy_string_len(con->request.uri, nuri, proto - nuri - 1);
--                              } else {
--                                      /* everything looks good so far */
--                                      buffer_copy_string_len(con->request.uri, uri, proto - uri - 1);
--                              }
--                              
--                              /* check uri for invalid characters */
--                              for (j = 0; j < con->request.uri->used - 1; j++) {
--                                      if (!request_uri_is_valid_char(con->request.uri->ptr[j])) {
--                                              unsigned char buf[2];
--                                              con->http_status = 400;
--                                              con->keep_alive = 0;
--                                              
--                                              if (srv->srvconf.log_request_header_on_error) {
--                                                      buf[0] = con->request.uri->ptr[j];
--                                                      buf[1] = '\0';
--                                      
--                                                      if (con->request.uri->ptr[j] > 32 &&
--                                                          con->request.uri->ptr[j] != 127) {  
--                                                              /* the character is printable -> print it */
--                                                              log_error_write(srv, __FILE__, __LINE__, "ss",
--                                                                              "invalid character in URI -> 400",
--                                                                              buf);
--                                                      } else {
--                                                              /* a control-character, print ascii-code */
--                                                              log_error_write(srv, __FILE__, __LINE__, "sd",
--                                                                              "invalid character in URI -> 400",
--                                                                              con->request.uri->ptr[j]);
--                                                      }
--                                              
--                                                      log_error_write(srv, __FILE__, __LINE__, "Sb",
--                                                                      "request-header:\n",
--                                                                      con->request.request);
--                                              }
--                                              
--                                              return 0;
--                                      }
--                              }
--                              
--                              buffer_copy_string_buffer(con->request.orig_uri, con->request.uri);
--                              
--                              con->http_status = 0;
--                              
--                              i++;
--                              line++;
--                              first = i+1;
-                       }
--                      break;
--              case ' ':
--                      switch(request_line_stage) {
--                      case 0: 
--                              /* GET|POST|... */
--                              method = con->parse_request->ptr + first; 
--                              first = i + 1;
--                              break;
--                      case 1:
--                              /* /foobar/... */
--                              uri = con->parse_request->ptr + first; 
--                              first = i + 1;
--                              break;
--                      default:
--                              /* ERROR, one space to much */
-+
-+                      if (r < 0) {
-                               con->http_status = 400;
--                              con->response.keep_alive = 0;
--                              con->keep_alive = 0;
--                              
--                              if (srv->srvconf.log_request_header_on_error) {
--                                      log_error_write(srv, __FILE__, __LINE__, "s", "overlong request line -> 400");
--                                      log_error_write(srv, __FILE__, __LINE__, "Sb",
--                                                      "request-header:\n",
--                                                      con->request.request);
--                              }
-+
-                               return 0;
-                       }
--                      
--                      request_line_stage++;
--                      break;
--              }
--      }
--      
--      in_folding = 0;
--      if (con->request.uri->used == 1) {
--              con->http_status = 400;
--              con->response.keep_alive = 0;
--              con->keep_alive = 0;
-+                      /* don't handle more the SSIZE_MAX bytes in content-length */
-+                      if (r > SSIZE_MAX) {
-+                              con->http_status = 413;
--              log_error_write(srv, __FILE__, __LINE__, "s", "no uri specified -> 400");
--              if (srv->srvconf.log_request_header_on_error) {
--                      log_error_write(srv, __FILE__, __LINE__, "Sb",
--                                                      "request-header:\n",
--                                                      con->request.request);
--              }
--              return 0;
--      }
-+                              ERROR("request-size too long: %s (Status: 413)", BUF_STR(ds->value));
--      
--      for (; i < con->parse_request->used && !done; i++) {
--              char *cur = con->parse_request->ptr + i;
--              
--              if (is_key) {
--                      size_t j;
--                      int got_colon = 0;
--                      
--                      /**
--                       * 1*<any CHAR except CTLs or separators>
--                       * CTLs == 0-31 + 127
--                       * 
-+                              return 0;
-+                      }
-+
-+                      con->request.content_length = r;
-+              } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Expect")))) {
-+                      /* HTTP 2616 8.2.3
-+                       * Expect: 100-continue
-+                       *
-+                       *   -> (10.1.1)  100 (read content, process request, send final status-code)
-+                       *   -> (10.4.18) 417 (close)
-+                       *
-+                       *
-                        */
--                      switch(*cur) {
--                      case ':':
--                              is_key = 0;
--                              
--                              value = cur + 1;
--                              
--                              if (is_ws_after_key == 0) {
--                                      key_len = i - first;
--                              }
--                              is_ws_after_key = 0;
--                                      
--                              break;
--                      case '(':
--                      case ')':
--                      case '<':
--                      case '>':
--                      case '@':
--                      case ',':
--                      case ';':
--                      case '\\':
--                      case '\"':
--                      case '/':
--                      case '[':
--                      case ']':
--                      case '?':
--                      case '=':
--                      case '{':
--                      case '}':
-+
-+                      if (0 != buffer_caseless_compare(CONST_BUF_LEN(ds->value), CONST_STR_LEN("100-continue"))) {
-+                              /* we only support 100-continue */
-+                              con->http_status = 417;
-+                              return 0;
-+                      }
-+
-+                      if (con->request.http_version != HTTP_VERSION_1_1) {
-+                              /* only HTTP/1.1 clients can send us this header */
-+                              con->http_status = 417;
-+                              return 0;
-+                      }
-+              } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Host")))) {
-+                      if (request_check_hostname(ds->value)) {
-+                              TRACE("%s", "Host header is invalue (Status: 400)");
-                               con->http_status = 400;
-                               con->keep_alive = 0;
--                              con->response.keep_alive = 0;
--                              
--                              log_error_write(srv, __FILE__, __LINE__, "sbsds", 
--                                              "invalid character in key", con->request.request, cur, *cur, "-> 400");
-+
-                               return 0;
--                      case ' ':
--                      case '\t':
--                              if (i == first) {
--                                      is_key = 0;
--                                      in_folding = 1;
--                                      value = cur;
--                                      
--                                      break;
--                              }
--                              
--                              
--                              key_len = i - first;
--                              
--                              /* skip every thing up to the : */
--                              for (j = 1; !got_colon; j++) {
--                                      switch(con->parse_request->ptr[j + i]) {
--                                      case ' ':
--                                      case '\t':
--                                              /* skip WS */
--                                              continue;
--                                      case ':':
--                                              /* ok, done */
--                                              
--                                              i += j - 1;
--                                              got_colon = 1;
--                                              
--                                              break;
--                                      default:
--                                              /* error */
--                                              
--                                              if (srv->srvconf.log_request_header_on_error) {
--                                                      log_error_write(srv, __FILE__, __LINE__, "s", "WS character in key -> 400");
--                                                      log_error_write(srv, __FILE__, __LINE__, "Sb",
--                                                              "request-header:\n",
--                                                              con->request.request);
--                                              }
--                                      
--                                              con->http_status = 400;
--                                              con->response.keep_alive = 0;
--                                              con->keep_alive = 0;
--                                              
--                                              return 0;
--                                      }
--                              }
--                              
--                              break;
--                      case '\r':
--                              if (con->parse_request->ptr[i+1] == '\n' && i == first) {
--                                      /* End of Header */
--                                      con->parse_request->ptr[i] = '\0';
--                                      con->parse_request->ptr[i+1] = '\0';
--                                      
--                                      i++;
--                                      
--                                      done = 1;
--                                      
--                                      break;
--                              } else {
--                                      if (srv->srvconf.log_request_header_on_error) {
--                                              log_error_write(srv, __FILE__, __LINE__, "s", "CR without LF -> 400");
--                                              log_error_write(srv, __FILE__, __LINE__, "Sb",
--                                                      "request-header:\n",
--                                                      con->request.request);
--                                      }
--                                      
--                                      con->http_status = 400;
--                                      con->keep_alive = 0;
--                                      con->response.keep_alive = 0;
--                                      return 0;
--                              }
--                              /* fall thru */
--                      case 0: /* illegal characters (faster than a if () :) */
--                      case 1:
--                      case 2:
--                      case 3:
--                      case 4:
--                      case 5:
--                      case 6:
--                      case 7:
--                      case 8:
--                      case 10:
--                      case 11:
--                      case 12:
--                      case 14:
--                      case 15:
--                      case 16:
--                      case 17:
--                      case 18:
--                      case 19:
--                      case 20:
--                      case 21:
--                      case 22:
--                      case 23:
--                      case 24:
--                      case 25:
--                      case 26:
--                      case 27:
--                      case 28:
--                      case 29:
--                      case 30:
--                      case 31:
--                      case 127:
-+                      }
-+
-+                      if (!buffer_is_empty(con->request.http_host)) {
-+                              TRACE("%s", "Host header is duplicate (Status: 400)");
-                               con->http_status = 400;
--                              con->keep_alive = 0;
--                              con->response.keep_alive = 0;
--                              
--                              if (srv->srvconf.log_request_header_on_error) {
--                                      log_error_write(srv, __FILE__, __LINE__, "sbsds", 
--                                              "CTL character in key", con->request.request, cur, *cur, "-> 400");
--                                      log_error_write(srv, __FILE__, __LINE__, "Sb",
--                                              "request-header:\n",
--                                              con->request.request);
--                              }
--                              
-                               return 0;
--                      default:
--                              /* ok */
--                              break;
-                       }
--              } else {
--                      switch(*cur) {
--                      case '\r': 
--                              if (con->parse_request->ptr[i+1] == '\n') {
--                                      /* End of Headerline */
--                                      con->parse_request->ptr[i] = '\0';
--                                      con->parse_request->ptr[i+1] = '\0';
--                                      
--                                      if (in_folding) {
--                                              if (!ds) {
--                                                      /* 400 */
--                                      
--                                                      if (srv->srvconf.log_request_header_on_error) {
--                                                              log_error_write(srv, __FILE__, __LINE__, "s", "WS at the start of first line -> 400");
--                                                      
--                                                              log_error_write(srv, __FILE__, __LINE__, "Sb",
--                                                                      "request-header:\n",
--                                                                      con->request.request);
--                                                      }
--
--                                      
--                                                      con->http_status = 400;
--                                                      con->keep_alive = 0;
--                                                      con->response.keep_alive = 0;
--                                                      return 0;
--                                              }
--                                              buffer_append_string(ds->value, value);
--                                      } else {
--                                              int s_len;
--                                              key = con->parse_request->ptr + first;
--                                      
--                                              s_len = cur - value;
--                                              
--                                              if (s_len > 0) {
--                                                      int cmp = 0;
--                                                      if (NULL == (ds = (data_string *)array_get_unused_element(con->request.headers, TYPE_STRING))) {
--                                                              ds = data_string_init();
--                                                      }
--                                                      buffer_copy_string_len(ds->key, key, key_len);
--                                                      buffer_copy_string_len(ds->value, value, s_len);
--                                                      
--                                                      /* retreive values 
--                                                       * 
--                                                       * 
--                                                       * the list of options is sorted to simplify the search
--                                                       */
--                                                      
--                                                      if (0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Connection")))) {
--                                                              array *vals;
--                                                              size_t vi;
--                                                              
--                                                              /* split on , */
--                                                              
--                                                              vals = srv->split_vals;
--
--                                                              array_reset(vals);
--                                                              
--                                                              http_request_split_value(vals, ds->value);
--                                                              
--                                                              for (vi = 0; vi < vals->used; vi++) {
--                                                                      data_string *dsv = (data_string *)vals->data[vi];
--                                                                      
--                                                                      if (0 == buffer_caseless_compare(CONST_BUF_LEN(dsv->value), CONST_STR_LEN("keep-alive"))) {
--                                                                              keep_alive_set = HTTP_CONNECTION_KEEPALIVE;
--                                                                              
--                                                                              break;
--                                                                      } else if (0 == buffer_caseless_compare(CONST_BUF_LEN(dsv->value), CONST_STR_LEN("close"))) {
--                                                                              keep_alive_set = HTTP_CONNECTION_CLOSE;
--                                                                              
--                                                                              break;
--                                                                      }
--                                                              }
--                                                              
--                                                      } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Content-Length")))) {
--                                                              char *err;
--                                                              unsigned long int r;
--                                                              size_t j;
--                                                              
--                                                              if (con_length_set) {
--                                                                      con->http_status = 400;
--                                                                      con->keep_alive = 0;
--                                                                      
--                                                                      if (srv->srvconf.log_request_header_on_error) {
--                                                                              log_error_write(srv, __FILE__, __LINE__, "s", 
--                                                                                              "duplicate Content-Length-header -> 400");
--                                                                              log_error_write(srv, __FILE__, __LINE__, "Sb",
--                                                                                              "request-header:\n",
--                                                                                              con->request.request);
--                                                                      }
--                                                                      return 0;
--                                                              }
--                                                              
--                                                              if (ds->value->used == 0) SEGFAULT();
--                                                              
--                                                              for (j = 0; j < ds->value->used - 1; j++) {
--                                                                      char c = ds->value->ptr[j];
--                                                                      if (!isdigit((unsigned char)c)) {
--                                                                              log_error_write(srv, __FILE__, __LINE__, "sbs", 
--                                                                                              "content-length broken:", ds->value, "-> 400");
--                                                                              
--                                                                              con->http_status = 400;
--                                                                              con->keep_alive = 0;
--                                                                              
--                                                                              array_insert_unique(con->request.headers, (data_unset *)ds);
--                                                                              return 0;
--                                                                      }
--                                                              }
--                                                              
--                                                              r = strtoul(ds->value->ptr, &err, 10);
--                                                              
--                                                              if (*err == '\0') {
--                                                                      con_length_set = 1;
--                                                                      con->request.content_length = r;
--                                                              } else {
--                                                                      log_error_write(srv, __FILE__, __LINE__, "sbs", 
--                                                                                      "content-length broken:", ds->value, "-> 400");
--                                                                      
--                                                                      con->http_status = 400;
--                                                                      con->keep_alive = 0;
--                                                                      
--                                                                      array_insert_unique(con->request.headers, (data_unset *)ds);
--                                                                      return 0;
--                                                              }
--                                                      } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Content-Type")))) {
--                                                              /* if dup, only the first one will survive */
--                                                              if (!con->request.http_content_type) {
--                                                                      con->request.http_content_type = ds->value->ptr;
--                                                              } else {
--                                                                      con->http_status = 400;
--                                                                      con->keep_alive = 0;
--                                                                      
--                                                                      if (srv->srvconf.log_request_header_on_error) {
--                                                                              log_error_write(srv, __FILE__, __LINE__, "s", 
--                                                                                              "duplicate Content-Type-header -> 400");
--                                                                              log_error_write(srv, __FILE__, __LINE__, "Sb",
--                                                                                              "request-header:\n",
--                                                                                              con->request.request);
--                                                                      }
--                                                                      return 0;
--                                                              }
--                                                      } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Expect")))) {
--                                                              /* HTTP 2616 8.2.3 
--                                                               * Expect: 100-continue
--                                                               * 
--                                                               *   -> (10.1.1)  100 (read content, process request, send final status-code)
--                                                               *   -> (10.4.18) 417 (close)
--                                                               * 
--                                                               * (not handled at all yet, we always send 417 here)
--                                                               *
--                                                               * What has to be added ?
--                                                               * 1. handling of chunked request body
--                                                               * 2. out-of-order sending from the HTTP/1.1 100 Continue
--                                                               *    header
--                                                               *
--                                                               */
--                                                              
--                                                              con->http_status = 417;
--                                                              con->keep_alive = 0;
--                                                              
--                                                              array_insert_unique(con->request.headers, (data_unset *)ds);
--                                                              return 0;
--                                                      } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Host")))) {
--                                                              if (!con->request.http_host) {
--                                                                      con->request.http_host = ds->value;
--                                                              } else {
--                                                                      con->http_status = 400;
--                                                                      con->keep_alive = 0;
--                                                                      
--                                                                      if (srv->srvconf.log_request_header_on_error) {
--                                                                              log_error_write(srv, __FILE__, __LINE__, "s", 
--                                                                                              "duplicate Host-header -> 400");
--                                                                              log_error_write(srv, __FILE__, __LINE__, "Sb",
--                                                                                              "request-header:\n",
--                                                                                              con->request.request);
--                                                                      }
--                                                                      return 0;
--                                                              }
--                                                      } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("If-Modified-Since")))) {
--                                                              /* Proxies sometimes send dup headers
--                                                               * if they are the same we ignore the second
--                                                               * if not, we raise an error */
--                                                              if (!con->request.http_if_modified_since) {
--                                                                      con->request.http_if_modified_since = ds->value->ptr;
--                                                              } else if (0 == strcasecmp(con->request.http_if_modified_since,
--                                                                                      ds->value->ptr)) {
--                                                                      /* ignore it if they are the same */
--                                                              } else {
--                                                                      con->http_status = 400;
--                                                                      con->keep_alive = 0;
--                                                                      
--                                                                      if (srv->srvconf.log_request_header_on_error) {
--                                                                              log_error_write(srv, __FILE__, __LINE__, "s", 
--                                                                                              "duplicate If-Modified-Since header -> 400");
--                                                                              log_error_write(srv, __FILE__, __LINE__, "Sb",
--                                                                                              "request-header:\n",
--                                                                                              con->request.request);
--                                                                      }
--                                                                      return 0;
--                                                              }
--                                                      } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("If-None-Match")))) {
--                                                              /* if dup, only the first one will survive */
--                                                              if (!con->request.http_if_none_match) {
--                                                                      con->request.http_if_none_match = ds->value->ptr;
--                                                              } else {
--                                                                      con->http_status = 400;
--                                                                      con->keep_alive = 0;
--                                                                      
--                                                                      if (srv->srvconf.log_request_header_on_error) {
--                                                                              log_error_write(srv, __FILE__, __LINE__, "s", 
--                                                                                              "duplicate If-None-Match-header -> 400");
--                                                                              log_error_write(srv, __FILE__, __LINE__, "Sb",
--                                                                                              "request-header:\n",
--                                                                                              con->request.request);
--                                                                      }
--                                                                      return 0;
--                                                              }
--                                                      } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Range")))) {
--                                                              if (!con->request.http_range) {
--                                                                      /* bytes=.*-.* */
--                                                              
--                                                                      if (0 == strncasecmp(ds->value->ptr, "bytes=", 6) &&
--                                                                          NULL != strchr(ds->value->ptr+6, '-')) {
--                                                                              
--                                                                              /* if dup, only the first one will survive */
--                                                                              con->request.http_range = ds->value->ptr + 6;
--                                                                      }
--                                                              } else {
--                                                                      con->http_status = 400;
--                                                                      con->keep_alive = 0;
--                                                                      
--                                                                      if (srv->srvconf.log_request_header_on_error) {
--                                                                              log_error_write(srv, __FILE__, __LINE__, "s", 
--                                                                                              "duplicate Range-header -> 400");
--                                                                              log_error_write(srv, __FILE__, __LINE__, "Sb",
--                                                                                              "request-header:\n",
--                                                                                              con->request.request);
--                                                                      }
--                                                                      return 0;
--                                                              }
--                                                      }
--                                                      
--                                                      array_insert_unique(con->request.headers, (data_unset *)ds);
--                                              } else {
--                                                      /* empty header-fields are not allowed by HTTP-RFC, we just ignore them */
--                                              }
--                                      }
--                                      
--                                      i++;
--                                      first = i+1;
--                                      is_key = 1;
--                                      value = 0;
--                                      key_len = 0;
--                                      in_folding = 0;
--                              } else {
--                                      if (srv->srvconf.log_request_header_on_error) {
--                                              log_error_write(srv, __FILE__, __LINE__, "sbs", 
--                                                              "CR without LF", con->request.request, "-> 400");
--                                      }
--                                      
-+
-+                      buffer_copy_string_buffer(con->request.http_host, ds->value);
-+              } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("If-Modified-Since")))) {
-+                      data_string *old;
-+                      
-+                      if (NULL != (old = (data_string *)array_get_element(con->request.headers, "If-Modified-Since"))) {
-+                              if (0 != buffer_caseless_compare(CONST_BUF_LEN(old->value), CONST_BUF_LEN(ds->value))) {
-+                                      /* duplicate header and different timestamps */
-                                       con->http_status = 400;
--                                      con->keep_alive = 0;
--                                      con->response.keep_alive = 0;
-+
-+                                      TRACE("%s", "If-Modified-Since is duplicate (Status: 400)");
-+
-+                                      return 0;
-+                              }
-+                      }
-+              } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("If-None-Match")))) {
-+                      data_string *old;
-+                      /* if dup, only the first one will survive */
-+                      if (NULL != (old = (data_string *)array_get_element(con->request.headers, "If-None-Match"))) {
-+                              if (0 != buffer_caseless_compare(CONST_BUF_LEN(old->value), CONST_BUF_LEN(ds->value))) {
-+                                      /* duplicate header and different timestamps */
-+                                      con->http_status = 400;
-+
-+                                      TRACE("%s", "If-None-Match is duplicate (Status: 400)");
-+
-                                       return 0;
-                               }
--                              break;
--                      case ' ':
--                      case '\t':
--                              /* strip leading WS */
--                              if (value == cur) value = cur+1;
--                      default:
--                              break;
-+                      }
-+              } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Range")))) {
-+                      if (NULL != array_get_element(con->request.headers, "Range")) {
-+                              /* duplicate Range header */
-+
-+                              TRACE("%s", "Range: header is duplicate (Status: 400)");
-+
-+                              con->http_status = 400;
-+                              con->keep_alive = 0;
-+                      
-+                              return 0;
-                       }
-               }
-+
-+              hdr = data_string_init();
-+
-+              buffer_copy_string_buffer(hdr->key, ds->key);
-+              buffer_copy_string_buffer(hdr->value, ds->value);
-+
-+              array_insert_unique(con->request.headers, (data_unset *)hdr);
-       }
--      
-+
-+
-       con->header_len = i;
--      
-+
-       /* do some post-processing */
-       if (con->request.http_version == HTTP_VERSION_1_1) {
-               if (keep_alive_set != HTTP_CONNECTION_CLOSE) {
-                       /* no Connection-Header sent */
--                      
-+
-                       /* HTTP/1.1 -> keep-alive default TRUE */
-                       con->keep_alive = 1;
-               } else {
-                       con->keep_alive = 0;
-               }
--              
-+
-               /* RFC 2616, 14.23 */
--              if (con->request.http_host == NULL ||
--                  buffer_is_empty(con->request.http_host)) {
-+              if (buffer_is_empty(con->request.http_host)) {
-                       con->http_status = 400;
-                       con->response.keep_alive = 0;
-                       con->keep_alive = 0;
--                      
-+
-                       if (srv->srvconf.log_request_header_on_error) {
-                               log_error_write(srv, __FILE__, __LINE__, "s", "HTTP/1.1 but Host missing -> 400");
-                               log_error_write(srv, __FILE__, __LINE__, "Sb",
-@@ -1015,40 +509,21 @@
-       } else {
-               if (keep_alive_set == HTTP_CONNECTION_KEEPALIVE) {
-                       /* no Connection-Header sent */
--                      
-+
-                       /* HTTP/1.0 -> keep-alive default FALSE  */
-                       con->keep_alive = 1;
-               } else {
-                       con->keep_alive = 0;
-               }
-       }
--      
--      /* check hostname field if it is set */
--      if (NULL != con->request.http_host &&
--          0 != request_check_hostname(srv, con, con->request.http_host)) {
--              
--              if (srv->srvconf.log_request_header_on_error) {
--                      log_error_write(srv, __FILE__, __LINE__, "s",
--                                      "Invalid Hostname -> 400");
--                      log_error_write(srv, __FILE__, __LINE__, "Sb",
--                                      "request-header:\n",
--                                      con->request.request);
--              }
--
--              con->http_status = 400;
--              con->response.keep_alive = 0;
--              con->keep_alive = 0;
--              
--              return 0;
--      }
-       switch(con->request.http_method) {
-       case HTTP_METHOD_GET:
-       case HTTP_METHOD_HEAD:
-               /* content-length is forbidden for those */
--              if (con_length_set && con->request.content_length != 0) {
-+              if (con->request.content_length != -1) {
-                       /* content-length is missing */
--                      log_error_write(srv, __FILE__, __LINE__, "s", 
-+                      log_error_write(srv, __FILE__, __LINE__, "s",
-                                       "GET/HEAD with content-length -> 400");
-                       con->keep_alive = 0;
-@@ -1058,9 +533,9 @@
-               break;
-       case HTTP_METHOD_POST:
-               /* content-length is required for them */
--              if (!con_length_set) {
-+              if (con->request.content_length == -1) {
-                       /* content-length is missing */
--                      log_error_write(srv, __FILE__, __LINE__, "s", 
-+                      log_error_write(srv, __FILE__, __LINE__, "s",
-                                       "POST-request, but content-length missing -> 411");
-                       con->keep_alive = 0;
-@@ -1073,52 +548,27 @@
-               /* the may have a content-length */
-               break;
-       }
--                      
--      
--      /* check if we have read post data */
--      if (con_length_set) {
--              /* don't handle more the SSIZE_MAX bytes in content-length */
--              if (con->request.content_length > SSIZE_MAX) {
--                      con->http_status = 413; 
--                      con->keep_alive = 0;
--                      log_error_write(srv, __FILE__, __LINE__, "sds", 
--                                      "request-size too long:", con->request.content_length, "-> 413");
--                      return 0;
--              }
-+      /* check if we have read post data */
-+      if (con->request.content_length != -1) {
-               /* divide by 1024 as srvconf.max_request_size is in kBytes */
-               if (srv->srvconf.max_request_size != 0 &&
-                   (con->request.content_length >> 10) > srv->srvconf.max_request_size) {
--                      /* the request body itself is larger then 
-+                      /* the request body itself is larger then
-                        * our our max_request_size
-                        */
--              
-+
-                       con->http_status = 413;
-                       con->keep_alive = 0;
--              
--                      log_error_write(srv, __FILE__, __LINE__, "sds", 
-+
-+                      log_error_write(srv, __FILE__, __LINE__, "sds",
-                                       "request-size too long:", con->request.content_length, "-> 413");
-                       return 0;
-               }
--              
--              
--              /* we have content */
--              if (con->request.content_length != 0) {
--                      return 1;
--              }
-       }
--      
-+
-       return 0;
- }
--int http_request_header_finished(server *srv, connection *con) {
--      UNUSED(srv);
--      if (con->request.request->used < 5) return 0;
--      
--      if (0 == memcmp(con->request.request->ptr + con->request.request->used - 5, "\r\n\r\n", 4)) return 1;
--      if (NULL != strstr(con->request.request->ptr, "\r\n\r\n")) return 1;
--      
--      return 0;
--}
---- ../lighttpd-1.4.11/src/request.h   2005-08-11 01:26:40.000000000 +0300
-+++ lighttpd-1.5.0/src/request.h       2006-09-07 00:57:05.000000000 +0300
-@@ -1,9 +1,9 @@
- #ifndef _REQUEST_H_
- #define _REQUEST_H_
--#include "server.h"
-+#include "base.h"
-+#include "http_req.h"
--int http_request_parse(server *srv, connection *con);
--int http_request_header_finished(server *srv, connection *con);
-+int http_request_parse(server *srv, connection *con, http_req *req);
- #endif
---- ../lighttpd-1.4.11/src/response.c  2006-03-04 16:41:39.000000000 +0200
-+++ lighttpd-1.5.0/src/response.c      2006-09-07 00:57:05.000000000 +0300
-@@ -7,7 +7,6 @@
- #include <stdlib.h>
- #include <string.h>
- #include <time.h>
--#include <unistd.h>
- #include <ctype.h>
- #include <assert.h>
-@@ -24,15 +23,17 @@
- #include "plugin.h"
- #include "sys-socket.h"
-+#include "sys-files.h"
-+#include "sys-strings.h"
--int http_response_write_header(server *srv, connection *con) {
-+int http_response_write_header(server *srv, connection *con, chunkqueue *raw) {
-       buffer *b;
-       size_t i;
-       int have_date = 0;
-       int have_server = 0;
--      
--      b = chunkqueue_get_prepend_buffer(con->write_queue);
--      
-+
-+      b = chunkqueue_get_prepend_buffer(raw);
-+
-       if (con->request.http_version == HTTP_VERSION_1_1) {
-               BUFFER_COPY_STRING_CONST(b, "HTTP/1.1 ");
-       } else {
-@@ -41,25 +42,26 @@
-       buffer_append_long(b, con->http_status);
-       BUFFER_APPEND_STRING_CONST(b, " ");
-       buffer_append_string(b, get_http_status_name(con->http_status));
--      
-+
-       if (con->request.http_version != HTTP_VERSION_1_1 || con->keep_alive == 0) {
-               BUFFER_APPEND_STRING_CONST(b, "\r\nConnection: ");
-               buffer_append_string(b, con->keep_alive ? "keep-alive" : "close");
-       }
--      
-+
-       if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
-               BUFFER_APPEND_STRING_CONST(b, "\r\nTransfer-Encoding: chunked");
-       }
--      
--      
-+
-+
-       /* add all headers */
-       for (i = 0; i < con->response.headers->used; i++) {
-               data_string *ds;
--              
-+
-               ds = (data_string *)con->response.headers->data[i];
--              
-+
-               if (ds->value->used && ds->key->used &&
--                  0 != strncmp(ds->key->ptr, "X-LIGHTTPD-", sizeof("X-LIGHTTPD-") - 1)) {
-+                  0 != strncmp(ds->key->ptr, "X-LIGHTTPD-", sizeof("X-LIGHTTPD-") - 1) &&
-+                  0 != strcasecmp(ds->key->ptr, "X-Sendfile")) {
-                       if (buffer_is_equal_string(ds->key, CONST_STR_LEN("Date"))) have_date = 1;
-                       if (buffer_is_equal_string(ds->key, CONST_STR_LEN("Server"))) have_server = 1;
-@@ -68,28 +70,28 @@
-                       BUFFER_APPEND_STRING_CONST(b, ": ");
-                       buffer_append_string_buffer(b, ds->value);
- #if 0
--                      log_error_write(srv, __FILE__, __LINE__, "bb", 
-+                      log_error_write(srv, __FILE__, __LINE__, "bb",
-                                       ds->key, ds->value);
- #endif
-               }
-       }
--      
-+
-       if (!have_date) {
-               /* HTTP/1.1 requires a Date: header */
-               BUFFER_APPEND_STRING_CONST(b, "\r\nDate: ");
--      
-+
-               /* cache the generated timestamp */
-               if (srv->cur_ts != srv->last_generated_date_ts) {
-                       buffer_prepare_copy(srv->ts_date_str, 255);
--              
--                      strftime(srv->ts_date_str->ptr, srv->ts_date_str->size - 1, 
-+
-+                      strftime(srv->ts_date_str->ptr, srv->ts_date_str->size - 1,
-                                "%a, %d %b %Y %H:%M:%S GMT", gmtime(&(srv->cur_ts)));
--                       
-+
-                       srv->ts_date_str->used = strlen(srv->ts_date_str->ptr) + 1;
--              
-+
-                       srv->last_generated_date_ts = srv->cur_ts;
-               }
--      
-+
-               buffer_append_string_buffer(b, srv->ts_date_str);
-       }
-@@ -101,88 +103,85 @@
-                       buffer_append_string_buffer(b, con->conf.server_tag);
-               }
-       }
--      
-+
-       BUFFER_APPEND_STRING_CONST(b, "\r\n\r\n");
--      
--      
-+
-+
-       con->bytes_header = b->used - 1;
--      
-+
-       if (con->conf.log_response_header) {
-               log_error_write(srv, __FILE__, __LINE__, "sSb", "Response-Header:", "\n", b);
-       }
--      
-+
-       return 0;
- }
--handler_t http_response_prepare(server *srv, connection *con) {
-+handler_t handle_get_backend(server *srv, connection *con) {
-       handler_t r;
--      
--      /* looks like someone has already done a decision */
--      if (con->mode == DIRECT && 
-+
-+      /* looks like someone has already made a decision */
-+      if (con->mode == DIRECT &&
-           (con->http_status != 0 && con->http_status != 200)) {
-               /* remove a packets in the queue */
--              if (con->file_finished == 0) {
--                      chunkqueue_reset(con->write_queue);
--              }
--              
-+
-               return HANDLER_FINISHED;
-       }
--      
-+
-       /* no decision yet, build conf->filename */
-       if (con->mode == DIRECT && con->physical.path->used == 0) {
-               char *qstr;
--              /* we only come here when we have the parse the full request again
--               * 
--               * a HANDLER_COMEBACK from mod_rewrite and mod_fastcgi might be a 
-+              /* we only come here when we have to parse the full request again
-+               *
-+               * a HANDLER_COMEBACK from mod_rewrite and mod_fastcgi might be a
-                * problem here as mod_setenv might get called multiple times
-                *
-                * fastcgi-auth might lead to a COMEBACK too
-                * fastcgi again dead server too
-                *
-                * mod_compress might add headers twice too
--               * 
-+               *
-                *  */
--              
-+
-               if (con->conf.log_condition_handling) {
-                       log_error_write(srv, __FILE__, __LINE__,  "s",  "run condition");
-               }
-               config_patch_connection(srv, con, COMP_SERVER_SOCKET); /* SERVERsocket */
--              
-+
-               /**
-                * prepare strings
--               * 
--               * - uri.path_raw 
-+               *
-+               * - uri.path_raw
-                * - uri.path (secure)
-                * - uri.query
--               * 
-+               *
-                */
--              
--              /** 
-+
-+              /**
-                * Name according to RFC 2396
--               * 
-+               *
-                * - scheme
-                * - authority
-                * - path
-                * - query
--               * 
-+               *
-                * (scheme)://(authority)(path)?(query)
--               * 
--               * 
-+               *
-+               *
-                */
--      
-+
-               buffer_copy_string(con->uri.scheme, con->conf.is_ssl ? "https" : "http");
-               buffer_copy_string_buffer(con->uri.authority, con->request.http_host);
-               buffer_to_lower(con->uri.authority);
--              
-+
-               config_patch_connection(srv, con, COMP_HTTP_HOST);      /* Host:        */
-               config_patch_connection(srv, con, COMP_HTTP_REMOTEIP);  /* Client-IP */
-               config_patch_connection(srv, con, COMP_HTTP_REFERER);   /* Referer:     */
-               config_patch_connection(srv, con, COMP_HTTP_USERAGENT); /* User-Agent:  */
-               config_patch_connection(srv, con, COMP_HTTP_COOKIE);    /* Cookie:  */
--              
-+
-               /** extract query string from request.uri */
-               if (NULL != (qstr = strchr(con->request.uri->ptr, '?'))) {
-                       buffer_copy_string    (con->uri.query, qstr + 1);
-@@ -200,22 +199,22 @@
-                       log_error_write(srv, __FILE__, __LINE__,  "sb", "URI-path     : ", con->uri.path_raw);
-                       log_error_write(srv, __FILE__, __LINE__,  "sb", "URI-query    : ", con->uri.query);
-               }
--              
-+
-               /* disable keep-alive if requested */
--              
-+
-               if (con->request_count > con->conf.max_keep_alive_requests) {
-                       con->keep_alive = 0;
-               }
--              
--              
-+
-+
-               /**
--               *  
--               * call plugins 
--               * 
-+               *
-+               * call plugins
-+               *
-                * - based on the raw URL
--               * 
-+               *
-                */
--              
-+
-               switch(r = plugins_call_handle_uri_raw(srv, con)) {
-               case HANDLER_GO_ON:
-                       break;
-@@ -229,14 +228,14 @@
-                       break;
-               }
--              /* build filename 
-+              /* build filename
-                *
-                * - decode url-encodings  (e.g. %20 -> ' ')
-                * - remove path-modifiers (e.g. /../)
-                */
--              
--              
--              
-+
-+
-+
-               if (con->request.http_method == HTTP_METHOD_OPTIONS &&
-                   con->uri.path_raw->ptr[0] == '*' && con->uri.path_raw->ptr[1] == '\0') {
-                       /* OPTIONS * ... */
-@@ -253,15 +252,21 @@
-               }
-               /**
--               *  
--               * call plugins 
--               * 
-+               *
-+               * call plugins
-+               *
-                * - based on the clean URL
--               * 
-+               *
-                */
--              
-+
-               config_patch_connection(srv, con, COMP_HTTP_URL); /* HTTPurl */
--              
-+              config_patch_connection(srv, con, COMP_HTTP_QUERYSTRING); /* HTTPqs */
-+
-+              /* do we have to downgrade to 1.0 ? */
-+              if (!con->conf.allow_http11) {
-+                      con->request.http_version = HTTP_VERSION_1_0;
-+              }
-+
-               switch(r = plugins_call_handle_uri_clean(srv, con)) {
-               case HANDLER_GO_ON:
-                       break;
-@@ -274,60 +279,62 @@
-                       log_error_write(srv, __FILE__, __LINE__, "");
-                       break;
-               }
--              
-+
-               if (con->request.http_method == HTTP_METHOD_OPTIONS &&
-                   con->uri.path->ptr[0] == '*' && con->uri.path_raw->ptr[1] == '\0') {
--                      /* option requests are handled directly without checking of the path */
--              
-+                      /* option requests are handled directly without checking the path */
-+
-                       response_header_insert(srv, con, CONST_STR_LEN("Allow"), CONST_STR_LEN("OPTIONS, GET, HEAD, POST"));
-                       con->http_status = 200;
--                      con->file_finished = 1;
-+                      /* no more content to send */
-+                      con->send->is_closed = 1;
-                       return HANDLER_FINISHED;
-               }
-               /***
--               * 
--               * border 
--               * 
-+               *
-+               * border
-+               *
-                * logical filename (URI) becomes a physical filename here
--               * 
--               * 
--               * 
-+               *
-+               *
-+               *
-                */
--              
--              
--              
--              
-+
-+
-+
-+
-               /* 1. stat()
-                * ... ISREG() -> ok, go on
-                * ... ISDIR() -> index-file -> redirect
--               * 
--               * 2. pathinfo() 
-+               *
-+               * 2. pathinfo()
-                * ... ISREG()
--               * 
-+               *
-                * 3. -> 404
--               * 
-+               *
-                */
--              
-+
-               /*
-                * SEARCH DOCUMENT ROOT
-                */
--              
-+
-               /* set a default */
--              
-+
-               buffer_copy_string_buffer(con->physical.doc_root, con->conf.document_root);
-               buffer_copy_string_buffer(con->physical.rel_path, con->uri.path);
--              
--#if defined(__WIN32) || defined(__CYGWIN__)
--              /* strip dots from the end and spaces
-+
-+              filename_unix2local(con->physical.rel_path);
-+#if defined(_WIN32) || defined(__CYGWIN__)
-+              /* strip dots and spaces from the end
-                *
-                * windows/dos handle those filenames as the same file
-                *
-                * foo == foo. == foo..... == "foo...   " == "foo..  ./"
-                *
--               * This will affect in some cases PATHINFO
-+               * This will affect PATHINFO in some cases
-                *
-                * on native windows we could prepend the filename with \\?\ to circumvent
-                * this behaviour. I have no idea how to push this through cygwin
-@@ -377,36 +384,41 @@
-                       log_error_write(srv, __FILE__, __LINE__, "");
-                       break;
-               }
--              
--              /* MacOS X and Windows can't distiguish between upper and lower-case 
--               * 
--               * convert to lower-case
-+
-+              /* The default Mac OS X and Windows filesystems can't distiguish between
-+               * upper- and lowercase, so convert to lowercase
-                */
-               if (con->conf.force_lowercase_filenames) {
-                       buffer_to_lower(con->physical.rel_path);
-               }
--              /* the docroot plugins might set the servername, if they don't we take http-host */
-+              /* the docroot plugins might set the servername; if they don't we take http-host */
-               if (buffer_is_empty(con->server_name)) {
-                       buffer_copy_string_buffer(con->server_name, con->uri.authority);
-               }
--              
--              /** 
--               * create physical filename 
-+
-+              /**
-+               * create physical filename
-                * -> physical.path = docroot + rel_path
--               * 
-+               *
-                */
--              
-+
-               buffer_copy_string_buffer(con->physical.path, con->physical.doc_root);
--              BUFFER_APPEND_SLASH(con->physical.path);
-+              PATHNAME_APPEND_SLASH(con->physical.path);
-               buffer_copy_string_buffer(con->physical.basedir, con->physical.path);
-               if (con->physical.rel_path->used &&
--                  con->physical.rel_path->ptr[0] == '/') {
-+                  con->physical.rel_path->ptr[0] == DIR_SEPERATOR) {
-                       buffer_append_string_len(con->physical.path, con->physical.rel_path->ptr + 1, con->physical.rel_path->used - 2);
-               } else {
-                       buffer_append_string_buffer(con->physical.path, con->physical.rel_path);
-               }
-+              /* win32: directories can't have a trailing slash */
-+              if (con->physical.path->ptr[con->physical.path->used - 2] == DIR_SEPERATOR) {
-+                      con->physical.path->ptr[con->physical.path->used - 2] = '\0';
-+                      con->physical.path->used--;
-+              }
-+
-               if (con->conf.log_request_handling) {
-                       log_error_write(srv, __FILE__, __LINE__,  "s",  "-- after doc_root");
-                       log_error_write(srv, __FILE__, __LINE__,  "sb", "Doc-Root     :", con->physical.doc_root);
-@@ -426,7 +438,7 @@
-                       log_error_write(srv, __FILE__, __LINE__, "");
-                       break;
-               }
--              
-+
-               if (con->conf.log_request_handling) {
-                       log_error_write(srv, __FILE__, __LINE__,  "s",  "-- logical -> physical");
-                       log_error_write(srv, __FILE__, __LINE__,  "sb", "Doc-Root     :", con->physical.doc_root);
-@@ -434,41 +446,60 @@
-                       log_error_write(srv, __FILE__, __LINE__,  "sb", "Path         :", con->physical.path);
-               }
-       }
--      
--      /* 
--       * Noone catched away the file from normal path of execution yet (like mod_access)
-+
-+      /*
-+       * No one took the file away from the normal path of execution yet (like mod_access)
-+       *
-+       * we don't have a backend yet, try to resolve the physical path and go on
-        * 
--       * Go on and check of the file exists at all
-        */
--      
-+
-       if (con->mode == DIRECT) {
-               char *slash = NULL;
-               char *pathinfo = NULL;
-               int found = 0;
-               stat_cache_entry *sce = NULL;
--              
-+
-               if (con->conf.log_request_handling) {
-                       log_error_write(srv, __FILE__, __LINE__,  "s",  "-- handling physical path");
-                       log_error_write(srv, __FILE__, __LINE__,  "sb", "Path         :", con->physical.path);
-               }
--              
-+
-               if (HANDLER_ERROR != stat_cache_get_entry(srv, con, con->physical.path, &sce)) {
-                       /* file exists */
--                      
-+
-                       if (con->conf.log_request_handling) {
-                               log_error_write(srv, __FILE__, __LINE__,  "s",  "-- file found");
-                               log_error_write(srv, __FILE__, __LINE__,  "sb", "Path         :", con->physical.path);
-                       }
--                      
-+
-+#ifdef HAVE_LSTAT
-+                      if ((sce->is_symlink != 0) && !con->conf.follow_symlink) {
-+                              con->http_status = 403;
-+
-+                              if (con->conf.log_request_handling) {
-+                                      log_error_write(srv, __FILE__, __LINE__,  "s",  "-- access denied due symlink restriction");
-+                                      log_error_write(srv, __FILE__, __LINE__,  "sb", "Path         :", con->physical.path);
-+                              }
-+
-+                              buffer_reset(con->physical.path);
-+                              return HANDLER_FINISHED;
-+                      };
-+#endif
-+
-                       if (S_ISDIR(sce->st.st_mode)) {
--                              if (con->physical.path->ptr[con->physical.path->used - 2] != '/') {
-+                              if (con->uri.path->ptr[con->uri.path->used - 2] != '/') {
-                                       /* redirect to .../ */
--                                      
-+
-                                       http_response_redirect_to_directory(srv, con);
--                                      
-+
-                                       return HANDLER_FINISHED;
-                               }
-+#ifdef HAVE_LSTAT
-+                      } else if (!S_ISREG(sce->st.st_mode) && !sce->is_symlink) {
-+#else
-                       } else if (!S_ISREG(sce->st.st_mode)) {
-+#endif
-                               /* any special handling of non-reg files ?*/
-@@ -477,12 +508,12 @@
-                       switch (errno) {
-                       case EACCES:
-                               con->http_status = 403;
--      
-+
-                               if (con->conf.log_request_handling) {
-                                       log_error_write(srv, __FILE__, __LINE__,  "s",  "-- access denied");
-                                       log_error_write(srv, __FILE__, __LINE__,  "sb", "Path         :", con->physical.path);
-                               }
--                      
-+
-                               buffer_reset(con->physical.path);
-                               return HANDLER_FINISHED;
-                       case ENOENT:
-@@ -499,77 +530,77 @@
-                               /* PATH_INFO ! :) */
-                               break;
-                       default:
--                              /* we have no idea what happend. let's tell the user so. */
-+                              /* we have no idea what happened, so tell the user. */
-                               con->http_status = 500;
-                               buffer_reset(con->physical.path);
--                              
-+
-                               log_error_write(srv, __FILE__, __LINE__, "ssbsb",
-                                               "file not found ... or so: ", strerror(errno),
-                                               con->uri.path,
-                                               "->", con->physical.path);
--                              
-+
-                               return HANDLER_FINISHED;
-                       }
--                      
-+
-                       /* not found, perhaps PATHINFO */
--                      
-+
-                       buffer_copy_string_buffer(srv->tmp_buf, con->physical.path);
--                      
-+
-                       do {
-                               struct stat st;
--                              
-+
-                               if (slash) {
-                                       buffer_copy_string_len(con->physical.path, srv->tmp_buf->ptr, slash - srv->tmp_buf->ptr);
-                               } else {
-                                       buffer_copy_string_buffer(con->physical.path, srv->tmp_buf);
-                               }
--                              
-+
-                               if (0 == stat(con->physical.path->ptr, &(st)) &&
-                                   S_ISREG(st.st_mode)) {
-                                       found = 1;
-                                       break;
-                               }
--                              
-+
-                               if (pathinfo != NULL) {
-                                       *pathinfo = '\0';
-                               }
-                               slash = strrchr(srv->tmp_buf->ptr, '/');
--                              
-+
-                               if (pathinfo != NULL) {
-                                       /* restore '/' */
-                                       *pathinfo = '/';
-                               }
--                              
-+
-                               if (slash) pathinfo = slash;
-                       } while ((found == 0) && (slash != NULL) && (slash - srv->tmp_buf->ptr > con->physical.basedir->used - 2));
--                      
-+
-                       if (found == 0) {
--                              /* no it really doesn't exists */
-+                              /* no, it really doesn't exists */
-                               con->http_status = 404;
--                              
-+
-                               if (con->conf.log_file_not_found) {
-                                       log_error_write(srv, __FILE__, __LINE__, "sbsb",
-                                                       "file not found:", con->uri.path,
-                                                       "->", con->physical.path);
-                               }
--                              
-+
-                               buffer_reset(con->physical.path);
--                              
-+
-                               return HANDLER_FINISHED;
-                       }
--                      
-+
-                       /* we have a PATHINFO */
-                       if (pathinfo) {
-                               buffer_copy_string(con->request.pathinfo, pathinfo);
--                              
-+
-                               /*
-                                * shorten uri.path
-                                */
--                              
-+
-                               con->uri.path->used -= strlen(pathinfo);
-                               con->uri.path->ptr[con->uri.path->used - 1] = '\0';
-                       }
--                      
-+
-                       if (con->conf.log_request_handling) {
-                               log_error_write(srv, __FILE__, __LINE__,  "s",  "-- after pathinfo check");
-                               log_error_write(srv, __FILE__, __LINE__,  "sb", "Path         :", con->physical.path);
-@@ -577,50 +608,37 @@
-                               log_error_write(srv, __FILE__, __LINE__,  "sb", "Pathinfo     :", con->request.pathinfo);
-                       }
-               }
--              
-+
-               if (con->conf.log_request_handling) {
-                       log_error_write(srv, __FILE__, __LINE__,  "s",  "-- handling subrequest");
-                       log_error_write(srv, __FILE__, __LINE__,  "sb", "Path         :", con->physical.path);
-               }
--              
-+
-               /* call the handlers */
--              switch(r = plugins_call_handle_subrequest_start(srv, con)) {
-+              switch(r = plugins_call_handle_start_backend(srv, con)) {
-               case HANDLER_GO_ON:
--                      /* request was not handled */
--                      break;
-               case HANDLER_FINISHED:
-+                      /* if we are still here, no one wanted the file; status 403 is ok I think */
-+
-               default:
-                       if (con->conf.log_request_handling) {
-                               log_error_write(srv, __FILE__, __LINE__,  "s",  "-- subrequest finished");
-                       }
--                      
--                      /* something strange happend */
-+
-+                      /* something strange happened */
-                       return r;
-               }
--              
--              /* if we are still here, no one wanted the file, status 403 is ok I think */
--              
--              if (con->mode == DIRECT) {
--                      con->http_status = 403;
--                      
--                      return HANDLER_FINISHED;
--              }
--              
-       }
--      
--      switch(r = plugins_call_handle_subrequest(srv, con)) {
--      case HANDLER_GO_ON:
--              /* request was not handled, looks like we are done */
-+
-+      if (con->mode == DIRECT) {
-+              con->http_status = 403;
-+
-+              TRACE("%s", "aaaaaaah, sending 403");
-+
-               return HANDLER_FINISHED;
--      case HANDLER_FINISHED:
--              /* request is finished */
--      default:
--              /* something strange happend */
--              return r;
--      }
--      
--      /* can't happen */
--      return HANDLER_COMEBACK;
-+      } else {
-+              return HANDLER_GO_ON;
-+      }
- }
---- ../lighttpd-1.4.11/src/response.h  2005-08-31 16:25:50.000000000 +0300
-+++ lighttpd-1.5.0/src/response.h      2006-09-07 00:57:05.000000000 +0300
-@@ -6,12 +6,12 @@
- #include "server.h"
- int http_response_parse(server *srv, connection *con);
--int http_response_write_header(server *srv, connection *con);
-+int http_response_write_header(server *srv, connection *con, chunkqueue *cq);
- int response_header_insert(server *srv, connection *con, const char *key, size_t keylen, const char *value, size_t vallen);
- int response_header_overwrite(server *srv, connection *con, const char *key, size_t keylen, const char *value, size_t vallen);
--handler_t http_response_prepare(server *srv, connection *con);
-+handler_t handle_get_backend(server *srv, connection *con);
- int http_response_redirect_to_directory(server *srv, connection *con);
- int http_response_handle_cachable(server *srv, connection *con, buffer * mtime);
---- ../lighttpd-1.4.11/src/server.c    2006-03-04 19:12:17.000000000 +0200
-+++ lighttpd-1.5.0/src/server.c        2006-09-07 00:57:05.000000000 +0300
-@@ -1,11 +1,9 @@
- #include <sys/types.h>
--#include <sys/time.h>
- #include <sys/stat.h>
- #include <string.h>
- #include <errno.h>
- #include <fcntl.h>
--#include <unistd.h>
- #include <stdlib.h>
- #include <time.h>
- #include <signal.h>
-@@ -22,16 +20,21 @@
- #include "response.h"
- #include "request.h"
- #include "chunk.h"
--#include "http_chunk.h"
- #include "fdevent.h"
- #include "connections.h"
- #include "stat_cache.h"
- #include "plugin.h"
- #include "joblist.h"
- #include "network_backends.h"
--
-+#include "status_counter.h"
-+#ifdef _WIN32
-+/* use local getopt implementation */
-+# undef HAVE_GETOPT_H
-+#endif
- #ifdef HAVE_GETOPT_H
- #include <getopt.h>
-+#else
-+#include "getopt.h"
- #endif
- #ifdef HAVE_VALGRIND_VALGRIND_H
-@@ -60,8 +63,17 @@
- /* #define USE_ALARM */
- #endif
-+#ifdef _WIN32
-+#undef HAVE_SIGNAL
-+#endif
-+
-+#include "sys-files.h"
-+#include "sys-process.h"
-+#include "sys-socket.h"
-+
- static volatile sig_atomic_t srv_shutdown = 0;
- static volatile sig_atomic_t graceful_shutdown = 0;
-+static volatile sig_atomic_t graceful_restart = 0;
- static volatile sig_atomic_t handle_sig_alarm = 1;
- static volatile sig_atomic_t handle_sig_hup = 0;
-@@ -72,9 +84,9 @@
-       switch (sig) {
-       case SIGTERM: srv_shutdown = 1; break;
--      case SIGINT: 
-+      case SIGINT:
-            if (graceful_shutdown) srv_shutdown = 1;
--           else graceful_shutdown = 1; 
-+           else graceful_shutdown = 1;
-            break;
-       case SIGALRM: handle_sig_alarm = 1; break;
-@@ -86,9 +98,9 @@
- static void signal_handler(int sig) {
-       switch (sig) {
-       case SIGTERM: srv_shutdown = 1; break;
--      case SIGINT: 
-+      case SIGINT:
-            if (graceful_shutdown) srv_shutdown = 1;
--           else graceful_shutdown = 1; 
-+           else graceful_shutdown = 1;
-            break;
-       case SIGALRM: handle_sig_alarm = 1; break;
-@@ -110,35 +122,35 @@
-       signal(SIGTSTP, SIG_IGN);
- #endif
-       if (0 != fork()) exit(0);
--      
-+
-       if (-1 == setsid()) exit(0);
-       signal(SIGHUP, SIG_IGN);
-       if (0 != fork()) exit(0);
--      
-+
-       if (0 != chdir("/")) exit(0);
- }
- #endif
- static server *server_init(void) {
-       int i;
--      
-+
-       server *srv = calloc(1, sizeof(*srv));
-       assert(srv);
-+    srv->max_fds = 1024;
- #define CLEAN(x) \
-       srv->x = buffer_init();
--      
-+
-       CLEAN(response_header);
-       CLEAN(parse_full_path);
-       CLEAN(ts_debug_str);
-       CLEAN(ts_date_str);
--      CLEAN(errorlog_buf);
-       CLEAN(response_range);
-       CLEAN(tmp_buf);
-       srv->empty_string = buffer_init_string("");
-       CLEAN(cond_check_buf);
--      
-+
-       CLEAN(srvconf.errorlog_file);
-       CLEAN(srvconf.groupname);
-       CLEAN(srvconf.username);
-@@ -146,68 +158,62 @@
-       CLEAN(srvconf.bindhost);
-       CLEAN(srvconf.event_handler);
-       CLEAN(srvconf.pid_file);
--      
-+
-       CLEAN(tmp_chunk_len);
- #undef CLEAN
--      
-+
- #define CLEAN(x) \
-       srv->x = array_init();
--      
-+
-       CLEAN(config_context);
-       CLEAN(config_touched);
--      CLEAN(status);
- #undef CLEAN
--      
-+
-       for (i = 0; i < FILE_CACHE_MAX; i++) {
-               srv->mtime_cache[i].str = buffer_init();
-       }
--      
-+
-       srv->cur_ts = time(NULL);
-       srv->startup_ts = srv->cur_ts;
--      
-+
-       srv->conns = calloc(1, sizeof(*srv->conns));
-       assert(srv->conns);
--      
-+
-       srv->joblist = calloc(1, sizeof(*srv->joblist));
-       assert(srv->joblist);
--      
-+
-       srv->fdwaitqueue = calloc(1, sizeof(*srv->fdwaitqueue));
-       assert(srv->fdwaitqueue);
--      
-+
-       srv->srvconf.modules = array_init();
-       srv->srvconf.modules_dir = buffer_init_string(LIBRARY_DIR);
-       srv->srvconf.network_backend = buffer_init();
-       srv->srvconf.upload_tempdirs = array_init();
--      
--      /* use syslog */
--      srv->errorlog_fd = -1;
--      srv->errorlog_mode = ERRORLOG_STDERR;
-       srv->split_vals = array_init();
--      
-+
-       return srv;
- }
- static void server_free(server *srv) {
-       size_t i;
--      
-+
-       for (i = 0; i < FILE_CACHE_MAX; i++) {
-               buffer_free(srv->mtime_cache[i].str);
-       }
--      
-+
- #define CLEAN(x) \
-       buffer_free(srv->x);
--      
-+
-       CLEAN(response_header);
-       CLEAN(parse_full_path);
-       CLEAN(ts_debug_str);
-       CLEAN(ts_date_str);
--      CLEAN(errorlog_buf);
-       CLEAN(response_range);
-       CLEAN(tmp_buf);
-       CLEAN(empty_string);
-       CLEAN(cond_check_buf);
--      
-+
-       CLEAN(srvconf.errorlog_file);
-       CLEAN(srvconf.groupname);
-       CLEAN(srvconf.username);
-@@ -217,7 +223,7 @@
-       CLEAN(srvconf.pid_file);
-       CLEAN(srvconf.modules_dir);
-       CLEAN(srvconf.network_backend);
--      
-+
-       CLEAN(tmp_chunk_len);
- #undef CLEAN
-@@ -225,15 +231,15 @@
-       fdevent_unregister(srv->ev, srv->fd);
- #endif
-       fdevent_free(srv->ev);
--      
-+
-       free(srv->conns);
--      
-+
-       if (srv->config_storage) {
-               for (i = 0; i < srv->config_context->used; i++) {
-                       specific_config *s = srv->config_storage[i];
-                       if (!s) continue;
--                      
-+
-                       buffer_free(s->document_root);
-                       buffer_free(s->server_name);
-                       buffer_free(s->server_tag);
-@@ -242,32 +248,31 @@
-                       buffer_free(s->error_handler);
-                       buffer_free(s->errorfile_prefix);
-                       array_free(s->mimetypes);
--                      
-+
-                       free(s);
-               }
-               free(srv->config_storage);
-               srv->config_storage = NULL;
-       }
--      
-+
- #define CLEAN(x) \
-       array_free(srv->x);
--      
-+
-       CLEAN(config_context);
-       CLEAN(config_touched);
--      CLEAN(status);
-       CLEAN(srvconf.upload_tempdirs);
- #undef CLEAN
--      
-+
-       joblist_free(srv, srv->joblist);
-       fdwaitqueue_free(srv, srv->fdwaitqueue);
--      
-+
-       if (srv->stat_cache) {
-               stat_cache_free(srv->stat_cache);
-       }
-       array_free(srv->srvconf.modules);
-       array_free(srv->split_vals);
--      
-+
-       free(srv);
- }
-@@ -281,14 +286,12 @@
- " - a light and fast webserver\n" \
- "Build-Date: " __DATE__ " " __TIME__ "\n";
- ;
--#undef TEXT_SSL       
-+#undef TEXT_SSL
-       write(STDOUT_FILENO, b, strlen(b));
- }
- static void show_features (void) {
--  show_version();
--  printf("\nEvent Handlers:\n\n%s",
--
-+  const char *s = ""
- #ifdef USE_SELECT
-       "\t+ select (generic)\n"
- #else
-@@ -355,11 +358,6 @@
- #else
-       "\t- crypt support\n"
- #endif
--#ifdef USE_PAM
--      "\t+ PAM support\n"
--#else
--      "\t- PAM support\n"
--#endif
- #ifdef USE_OPENSSL
-       "\t+ SSL Support\n"
- #else
-@@ -371,9 +369,9 @@
-       "\t- PCRE support\n"
- #endif
- #ifdef HAVE_MYSQL
--      "\t+ mySQL support\n"
-+      "\t+ MySQL support\n"
- #else
--      "\t- mySQL support\n"
-+      "\t- MySQL support\n"
- #endif
- #if defined(HAVE_LDAP_H) && defined(HAVE_LBER_H) && defined(HAVE_LIBLDAP) && defined(HAVE_LIBLBER)
-       "\t+ LDAP support\n"
-@@ -410,8 +408,11 @@
- #else
-       "\t- GDBM support\n"
- #endif
--      "\n"
--      );
-+      "\n";
-+
-+  show_version();
-+
-+  printf("\nEvent Handlers:\n\n%s", s);
- }
- static void show_help (void) {
-@@ -433,197 +434,570 @@
- " -h         show this help\n" \
- "\n"
- ;
--#undef TEXT_SSL       
-+#undef TEXT_SSL
- #undef TEXT_IPV6
-       write(STDOUT_FILENO, b, strlen(b));
- }
--int main (int argc, char **argv) {
--      server *srv = NULL;
--      int print_config = 0;
--      int test_config = 0;
--      int i_am_root;
--      int o;
--      int num_childs = 0;
--      int pid_fd = -1, fd;
--      size_t i;
--#ifdef HAVE_SIGACTION
--      struct sigaction act;
--#endif
--#ifdef HAVE_GETRLIMIT
--      struct rlimit rlim;
--#endif
--      
--#ifdef USE_ALARM
--      struct itimerval interval;
--      
--      interval.it_interval.tv_sec = 1;
--      interval.it_interval.tv_usec = 0;
--      interval.it_value.tv_sec = 1;
--      interval.it_value.tv_usec = 0;
--#endif
--      
--      
--      /* for nice %b handling in strfime() */
--      setlocale(LC_TIME, "C");
--      
--      if (NULL == (srv = server_init())) {
--              fprintf(stderr, "did this really happen?\n");
--              return -1;
--      }
--      
--      /* init structs done */
--      
--      srv->srvconf.port = 0;
--#ifdef HAVE_GETUID
--      i_am_root = (getuid() == 0);
--#else
--      i_am_root = 0;
--#endif
--      srv->srvconf.dont_daemonize = 0;
--      
--      while(-1 != (o = getopt(argc, argv, "f:m:hvVDpt"))) {
--              switch(o) {
--              case 'f': 
--                      if (config_read(srv, optarg)) { 
--                              server_free(srv);
--                              return -1;
--                      }
--                      break;
--              case 'm':
--                      buffer_copy_string(srv->srvconf.modules_dir, optarg);
--                      break;
--              case 'p': print_config = 1; break;
--              case 't': test_config = 1; break;
--              case 'D': srv->srvconf.dont_daemonize = 1; break;
--              case 'v': show_version(); return 0;
--              case 'V': show_features(); return 0;          
--              case 'h': show_help(); return 0;
--              default: 
--                      show_help();
--                      server_free(srv);
--                      return -1;
--              }
--      }
--      
--      if (!srv->config_storage) {
--              log_error_write(srv, __FILE__, __LINE__, "s",
--                              "No configuration available. Try using -f option.");
--              
--              server_free(srv);
--              return -1;
--      }
--      
--      if (print_config) {
--              data_unset *dc = srv->config_context->data[0];
--              if (dc) {
--                      dc->print(dc, 0);
--                      fprintf(stderr, "\n");
--              } else {
--                      /* shouldn't happend */
--                      fprintf(stderr, "global config not found\n");
--              }
--      }
-+int lighty_mainloop(server *srv) {
-+      fdevent_revents *revents = fdevent_revents_init();
--      if (test_config) {
--              printf("Syntax OK\n");
--      }
-+      /* main-loop */
-+      while (!srv_shutdown) {
-+              int n;
-+              size_t ndx;
-+              time_t min_ts;
--      if (test_config || print_config) {
--              server_free(srv);
--              return 0;
--      }
--      
--      /* close stdin and stdout, as they are not needed */
--      /* move stdin to /dev/null */
--      if (-1 != (fd = open("/dev/null", O_RDONLY))) {
--              close(STDIN_FILENO);
--              dup2(fd, STDIN_FILENO);
--              close(fd);
--      }
--      
--      /* move stdout to /dev/null */
--      if (-1 != (fd = open("/dev/null", O_WRONLY))) {
--              close(STDOUT_FILENO);
--              dup2(fd, STDOUT_FILENO);
--              close(fd);
--      }
--      
--      if (0 != config_set_defaults(srv)) {
--              log_error_write(srv, __FILE__, __LINE__, "s", 
--                              "setting default values failed");
--              server_free(srv);
--              return -1;
--      }
--      
--      /* UID handling */
--#ifdef HAVE_GETUID
--      if (!i_am_root && (geteuid() == 0 || getegid() == 0)) {
--              /* we are setuid-root */
--              
--              log_error_write(srv, __FILE__, __LINE__, "s", 
--                              "Are you nuts ? Don't apply a SUID bit to this binary");
--              
--              server_free(srv);
--              return -1;
--      }
--#endif
--      
--      /* check document-root */
--      if (srv->config_storage[0]->document_root->used <= 1) {
--              log_error_write(srv, __FILE__, __LINE__, "s", 
--                              "document-root is not set\n");
--              
--              server_free(srv);
--              
--              return -1;
--      }
--      
--      if (plugins_load(srv)) {
--              log_error_write(srv, __FILE__, __LINE__, "s",
--                              "loading plugins finally failed");
--              
--              plugins_free(srv);
--              server_free(srv);
--              
--              return -1;
--      }
--      
--      /* open pid file BEFORE chroot */
--      if (srv->srvconf.pid_file->used) {
--              if (-1 == (pid_fd = open(srv->srvconf.pid_file->ptr, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) {
--                      struct stat st;
--                      if (errno != EEXIST) {
--                              log_error_write(srv, __FILE__, __LINE__, "sbs",
--                                      "opening pid-file failed:", srv->srvconf.pid_file, strerror(errno));
--                              return -1;
--                      }
--                      
--                      if (0 != stat(srv->srvconf.pid_file->ptr, &st)) {
--                              log_error_write(srv, __FILE__, __LINE__, "sbs",
--                                              "stating existing pid-file failed:", srv->srvconf.pid_file, strerror(errno));
-+              if (handle_sig_hup) {
-+                      handler_t r;
-+
-+                      /* reset notification */
-+                      handle_sig_hup = 0;
-+
-+#if 0
-+                              pid_t pid;
-+
-+                      /* send the old process into a graceful-shutdown and start a
-+                       * new process right away
-+                       *
-+                       * BUGS:
-+                       * - if webserver is running on port < 1024 (e.g. 80, 433)
-+                       *   we don't have the permissions to bind to that port anymore
-+                       *
-+                       *
-+                       *  */
-+                      if (0 == (pid = fork())) {
-+                              execve(argv[0], argv, envp);
-+
-+                              exit(-1);
-+                      } else if (pid == -1) {
-+
-+                      } else {
-+                              /* parent */
-+
-+                              graceful_shutdown = 1; /* shutdown without killing running connections */
-+                              graceful_restart = 1;  /* don't delete pid file */
-                       }
--                      
--                      if (!S_ISREG(st.st_mode)) {
--                              log_error_write(srv, __FILE__, __LINE__, "sb",
--                                              "pid-file exists and isn't regular file:", srv->srvconf.pid_file);
--                              return -1;
-+#else
-+                      /* cycle logfiles */
-+
-+                      switch(r = plugins_call_handle_sighup(srv)) {
-+                      case HANDLER_GO_ON:
-+                              break;
-+                      default:
-+                              log_error_write(srv, __FILE__, __LINE__, "sd", "sighup-handler return with an error", r);
-+                              break;
-                       }
--                      
--                      if (-1 == (pid_fd = open(srv->srvconf.pid_file->ptr, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) {
--                              log_error_write(srv, __FILE__, __LINE__, "sbs",
--                                              "opening pid-file failed:", srv->srvconf.pid_file, strerror(errno));
-+
-+                      if (-1 == log_error_cycle()) {
-+                              log_error_write(srv, __FILE__, __LINE__, "s", "cycling errorlog failed, dying");
-+
-                               return -1;
-                       }
-+#endif
-               }
-+
-+              if (handle_sig_alarm) {
-+                      /* a new second */
-+
-+#ifdef USE_ALARM
-+                      /* reset notification */
-+                      handle_sig_alarm = 0;
-+#endif
-+
-+                      /* get current time */
-+                      min_ts = time(NULL);
-+
-+                      if (min_ts != srv->cur_ts) {
-+                              int cs = 0;
-+                              connections *conns = srv->conns;
-+                              handler_t r;
-+
-+                              switch(r = plugins_call_handle_trigger(srv)) {
-+                              case HANDLER_GO_ON:
-+                                      break;
-+                              case HANDLER_ERROR:
-+                                      log_error_write(srv, __FILE__, __LINE__, "s", "one of the triggers failed");
-+                                      break;
-+                              default:
-+                                      log_error_write(srv, __FILE__, __LINE__, "d", r);
-+                                      break;
-+                              }
-+
-+                              /* trigger waitpid */
-+                              srv->cur_ts = min_ts;
-+
-+                              /* cleanup stat-cache */
-+                              stat_cache_trigger_cleanup(srv);
-+                              /**
-+                               * check all connections for timeouts
-+                               *
-+                               */
-+                              for (ndx = 0; ndx < conns->used; ndx++) {
-+                                      int changed = 0;
-+                                      connection *con;
-+                                      int t_diff;
-+
-+                                      con = conns->ptr[ndx];
-+
-+                                      switch (con->state) {
-+                                      case CON_STATE_READ_REQUEST_HEADER:
-+                                      case CON_STATE_READ_REQUEST_CONTENT: 
-+                                              if (con->recv->is_closed) break; /* everything is read, no need to fear a timeout */
-+                                              
-+                                              if (con->request_count == 1) {
-+                                                      if (srv->cur_ts - con->read_idle_ts > con->conf.max_read_idle) {
-+                                                              /* time - out */
-+#if 0
-+                                                              log_error_write(srv, __FILE__, __LINE__, "sd",
-+                                                                              "connection closed - read-timeout:", con->fd);
-+#endif
-+                                                              TRACE("%s", "(timeout)");
-+                                                              connection_set_state(srv, con, CON_STATE_ERROR);
-+                                                              changed = 1;
-+                                                      }
-+                                              } else {
-+                                                      if (srv->cur_ts - con->read_idle_ts > con->conf.max_keep_alive_idle) {
-+                                                              /* time - out */
-+#if 0
-+                                                              log_error_write(srv, __FILE__, __LINE__, "sd",
-+                                                                              "connection closed - read-timeout:", con->fd);
-+#endif
-+                                                              TRACE("%s", "(timeout)");
-+                                                              connection_set_state(srv, con, CON_STATE_ERROR);
-+                                                              changed = 1;
-+                                                      }
-+                                              }
-+                                              break;
-+                                      case CON_STATE_WRITE_RESPONSE_HEADER:
-+                                      case CON_STATE_WRITE_RESPONSE_CONTENT:
-+                                      
-+
-+                                              if (con->write_request_ts != 0 &&
-+                                                  srv->cur_ts - con->write_request_ts > con->conf.max_write_idle) {
-+                                                      /* time - out */
-+#if 1
-+                                                      log_error_write(srv, __FILE__, __LINE__, "sbsosds",
-+                                                                      "NOTE: a request for",
-+                                                                      con->request.uri,
-+                                                                      "timed out after writing",
-+                                                                      con->bytes_written,
-+                                                                      "bytes. We waited",
-+                                                                      (int)con->conf.max_write_idle,
-+                                                                      "seconds. If this a problem increase server.max-write-idle");
-+#endif
-+                                                              TRACE("%s", "(timeout)");
-+                                                      connection_set_state(srv, con, CON_STATE_ERROR);
-+                                                      changed = 1;
-+                                              }
-+                                              break;
-+                                      default:
-+                                              /* the other ones are uninteresting */
-+                                              break;
-+                                      }
-+                                      /* we don't like div by zero */
-+                                      if (0 == (t_diff = srv->cur_ts - con->connection_start)) t_diff = 1;
-+
-+                                      if (con->traffic_limit_reached &&
-+                                          (con->conf.kbytes_per_second == 0 ||
-+                                           ((con->bytes_written / t_diff) < con->conf.kbytes_per_second * 1024))) {
-+                                              /* enable connection again */
-+                                              con->traffic_limit_reached = 0;
-+
-+                                              changed = 1;
-+                                      }
-+
-+                                      if (changed) {
-+                                              connection_state_machine(srv, con);
-+                                      }
-+                                      con->bytes_written_cur_second = 0;
-+                                      *(con->conf.global_bytes_per_second_cnt_ptr) = 0;
-+
-+#if 0
-+                                      if (cs == 0) {
-+                                              fprintf(stderr, "connection-state: ");
-+                                              cs = 1;
-+                                      }
-+
-+                                      fprintf(stderr, "c[%d,%d]: %s ",
-+                                              con->fd,
-+                                              con->fcgi.fd,
-+                                              connection_get_state(con->state));
-+#endif
-+                              }
-+
-+                              if (cs == 1) fprintf(stderr, "\n");
-+                      }
-+              }
-+
-+              if (srv->sockets_disabled) {
-+                      /* our server sockets are disabled, why ? */
-+
-+                      if ((srv->cur_fds + srv->want_fds < srv->max_fds * 0.8) && /* we have enough unused fds */
-+                          (srv->conns->used < srv->max_conns * 0.9) &&
-+                          (0 == graceful_shutdown)) {
-+                              size_t i;
-+
-+                              for (i = 0; i < srv->srv_sockets.used; i++) {
-+                                      server_socket *srv_socket = srv->srv_sockets.ptr[i];
-+                                      fdevent_event_add(srv->ev, srv_socket->sock, FDEVENT_IN);
-+                              }
-+
-+                              log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets enabled again");
-+
-+                              srv->sockets_disabled = 0;
-+                      }
-+              } else {
-+                      if ((srv->cur_fds + srv->want_fds > srv->max_fds * 0.9) || /* out of fds */
-+                          (srv->conns->used > srv->max_conns) || /* out of connections */
-+                          (graceful_shutdown)) { /* graceful_shutdown */
-+                              size_t i;
-+
-+                              /* disable server-fds */
-+
-+                              for (i = 0; i < srv->srv_sockets.used; i++) {
-+                                      server_socket *srv_socket = srv->srv_sockets.ptr[i];
-+                                      fdevent_event_del(srv->ev, srv_socket->sock);
-+
-+                                      if (graceful_shutdown) {
-+                                              /* we don't want this socket anymore,
-+                                               *
-+                                               * closing it right away will make it possible for
-+                                               * the next lighttpd to take over (graceful restart)
-+                                               *  */
-+
-+                                              fdevent_unregister(srv->ev, srv_socket->sock);
-+                                              closesocket(srv_socket->sock->fd);
-+                                              srv_socket->sock->fd = -1;
-+
-+                                              /* network_close() will cleanup after us */
-+                                      }
-+                              }
-+
-+                              if (graceful_shutdown) {
-+                                      log_error_write(srv, __FILE__, __LINE__, "s", "[note] graceful shutdown started");
-+                              } else if (srv->conns->used > srv->max_conns) {
-+                                      log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, connection limit reached");
-+                              } else {
-+                                      log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, out-of-fds");
-+                              }
-+
-+                              srv->sockets_disabled = 1;
-+                      }
-+              }
-+
-+              if (graceful_shutdown && srv->conns->used == 0) {
-+                      /* we are in graceful shutdown phase and all connections are closed
-+                       * we are ready to terminate without harming anyone */
-+                      srv_shutdown = 1;
-+              }
-+
-+              /* we still have some fds to share */
-+              if (srv->want_fds) {
-+                      /* check the fdwaitqueue for waiting fds */
-+                      int free_fds = srv->max_fds - srv->cur_fds - 16;
-+                      connection *con;
-+
-+                      for (; free_fds > 0 && NULL != (con = fdwaitqueue_unshift(srv, srv->fdwaitqueue)); free_fds--) {
-+                              connection_state_machine(srv, con);
-+
-+                              srv->want_fds--;
-+                      }
-+              }
-+
-+              if ((n = fdevent_poll(srv->ev, 1000)) > 0) {
-+                      /* n is the number of events */
-+                      size_t i;
-+                      fdevent_get_revents(srv->ev, n, revents);
-+
-+                      /* handle client connections first
-+                       * 
-+                       * this is a bit of a hack, but we have to make sure than we handle 
-+                       * close-events before the connection is reused for a keep-alive 
-+                       * request
-+                       *
-+                       * this is mostly an issue for mod_proxy_core, but you never know
-+                       *
-+                       */
-+
-+                      for (i = 0; i < revents->used; i++) {
-+                              fdevent_revent *revent = revents->ptr[i];
-+                              handler_t r;
-+
-+                              /* skip server-fds */
-+                              if (revent->handler == network_server_handle_fdevent) continue;
-+
-+                              switch (r = (*(revent->handler))(srv, revent->context, revent->revents)) {
-+                              case HANDLER_FINISHED:
-+                              case HANDLER_GO_ON:
-+                              case HANDLER_WAIT_FOR_EVENT:
-+                              case HANDLER_WAIT_FOR_FD:
-+                                      break;
-+                              case HANDLER_ERROR:
-+                                      /* should never happen */
-+                                      SEGFAULT();
-+                                      break;
-+                              default:
-+                                      log_error_write(srv, __FILE__, __LINE__, "d", r);
-+                                      break;
-+                              }
-+                      } 
-+
-+                      for (i = 0; i < revents->used; i++) {
-+                              fdevent_revent *revent = revents->ptr[i];
-+                              handler_t r;
-+
-+                              /* server fds only */
-+                              if (revent->handler != network_server_handle_fdevent) continue;
-+
-+                              switch (r = (*(revent->handler))(srv, revent->context, revent->revents)) {
-+                              case HANDLER_FINISHED:
-+                              case HANDLER_GO_ON:
-+                              case HANDLER_WAIT_FOR_EVENT:
-+                              case HANDLER_WAIT_FOR_FD:
-+                                      break;
-+                              case HANDLER_ERROR:
-+                                      /* should never happen */
-+                                      SEGFAULT();
-+                                      break;
-+                              default:
-+                                      log_error_write(srv, __FILE__, __LINE__, "d", r);
-+                                      break;
-+                              }
-+                      } 
-+
-+              } else if (n < 0 && errno != EINTR) {
-+                      log_error_write(srv, __FILE__, __LINE__, "ss",
-+                                      "fdevent_poll failed:",
-+                                      strerror(errno));
-+              }
-+
-+              for (ndx = 0; ndx < srv->joblist->used; ndx++) {
-+                      connection *con = srv->joblist->ptr[ndx];
-+                      handler_t r;
-+
-+                      connection_state_machine(srv, con);
-+
-+                      switch(r = plugins_call_handle_joblist(srv, con)) {
-+                      case HANDLER_FINISHED:
-+                      case HANDLER_GO_ON:
-+                              break;
-+                      default:
-+                              log_error_write(srv, __FILE__, __LINE__, "d", r);
-+                              break;
-+                      }
-+
-+                      con->in_joblist = 0;
-+              }
-+
-+              srv->joblist->used = 0;
-+      }
-+
-+      fdevent_revents_free(revents);
-+
-+      return 0;
-+}
-+
-+
-+int main (int argc, char **argv, char **envp) {
-+      server *srv = NULL;
-+      int print_config = 0;
-+      int test_config = 0;
-+      int i_am_root;
-+      int o;
-+      int num_childs = 0;
-+      int pid_fd = -1, fd;
-+      size_t i;
-+#ifdef _WIN32
-+      char *optarg = NULL;
-+#endif
-+
-+#ifdef HAVE_SIGACTION
-+      struct sigaction act;
-+#endif
-+#ifdef HAVE_GETRLIMIT
-+      struct rlimit rlim;
-+#endif
-+
-+#ifdef USE_ALARM
-+      struct itimerval interval;
-+
-+      interval.it_interval.tv_sec = 1;
-+      interval.it_interval.tv_usec = 0;
-+      interval.it_value.tv_sec = 1;
-+      interval.it_value.tv_usec = 0;
-+#endif
-+
-+      log_init();
-+      status_counter_init();
-+
-+      /* for nice %b handling in strfime() */
-+      setlocale(LC_TIME, "C");
-+      
-+      if (NULL == (srv = server_init())) {
-+              fprintf(stderr, "did this really happen?\n");
-+              return -1;
-+      }
-+
-+      /* init structs done */
-+
-+      srv->srvconf.port = 0;
-+#ifdef HAVE_GETUID
-+      i_am_root = (getuid() == 0);
-+#else
-+      i_am_root = 0;
-+#endif
-+      srv->srvconf.dont_daemonize = 0;
-+
-+      while(-1 != (o = getopt(argc, argv, "f:m:hvVDpt"))) {
-+              switch(o) {
-+              case 'f':
-+#ifdef _WIN32
-+                      /* evil HACK for windows, optarg is not set */
-+                      optarg = argv[optind-1];
-+#endif
-+                      if (config_read(srv, optarg)) {
-+                              server_free(srv);
-+                              return -1;
-+                      }
-+
-+                      break;
-+              case 'm':
-+                      buffer_copy_string(srv->srvconf.modules_dir, optarg);
-+                      break;
-+              case 'p': print_config = 1; break;
-+              case 't': test_config = 1; break;
-+              case 'D': srv->srvconf.dont_daemonize = 1; break;
-+              case 'v': show_version(); return 0;
-+              case 'V': show_features(); return 0;
-+              case 'h': show_help(); return 0;
-+              default:
-+                      show_help();
-+                      server_free(srv);
-+                      return -1;
-+              }
-+      }
-+
-+      if (!srv->config_storage) {
-+              log_error_write(srv, __FILE__, __LINE__, "s",
-+                              "No configuration available. Try using -f option.");
-+
-+              server_free(srv);
-+              return -1;
-+      }
-+
-+      if (print_config) {
-+              data_unset *dc = srv->config_context->data[0];
-+              if (dc) {
-+                      dc->print(dc, 0);
-+                      fprintf(stderr, "\n");
-+              } else {
-+                      /* shouldn't happend */
-+                      fprintf(stderr, "global config not found\n");
-+              }
-+      }
-+
-+      if (test_config) {
-+              printf("Syntax OK\n");
-+      }
-+
-+      if (test_config || print_config) {
-+              server_free(srv);
-+              return 0;
-       }
-+      /* close stdin and stdout, as they are not needed */
-+      /* move stdin to /dev/null */
-+      if (-1 != (fd = open("/dev/null", O_RDONLY))) {
-+              close(STDIN_FILENO);
-+              dup2(fd, STDIN_FILENO);
-+              close(fd);
-+      }
-+
-+      /* move stdout to /dev/null */
-+      if (-1 != (fd = open("/dev/null", O_WRONLY))) {
-+              close(STDOUT_FILENO);
-+              dup2(fd, STDOUT_FILENO);
-+              close(fd);
-+      }
-+
-+      if (0 != config_set_defaults(srv)) {
-+              log_error_write(srv, __FILE__, __LINE__, "s",
-+                              "setting default values failed");
-+              server_free(srv);
-+              return -1;
-+      }
-+
-+      /* UID handling */
-+#ifdef HAVE_GETUID
-+      if (!i_am_root && (geteuid() == 0 || getegid() == 0)) {
-+              /* we are setuid-root */
-+
-+              log_error_write(srv, __FILE__, __LINE__, "s",
-+                              "Are you nuts ? Don't apply a SUID bit to this binary");
-+
-+              server_free(srv);
-+              return -1;
-+      }
-+#endif
-+
-+      /* check document-root */
-+      if (srv->config_storage[0]->document_root->used <= 1) {
-+              log_error_write(srv, __FILE__, __LINE__, "s",
-+                              "document-root is not set\n");
-+
-+              server_free(srv);
-+
-+              return -1;
-+      }
-+
-+      if (plugins_load(srv)) {
-+              log_error_write(srv, __FILE__, __LINE__, "s",
-+                              "loading plugins finally failed");
-+
-+              plugins_free(srv);
-+              server_free(srv);
-+
-+              return -1;
-+      }
-+
-+#ifndef _WIN32
-+      /* open pid file BEFORE chroot */
-+      if (srv->srvconf.pid_file->used) {
-+              if (-1 == (pid_fd = open(srv->srvconf.pid_file->ptr, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) {
-+                      struct stat st;
-+                      if (errno != EEXIST) {
-+                              log_error_write(srv, __FILE__, __LINE__, "sbs",
-+                                      "opening pid-file failed:", srv->srvconf.pid_file, strerror(errno));
-+                              return -1;
-+                      }
-+
-+                      if (0 != stat(srv->srvconf.pid_file->ptr, &st)) {
-+                              log_error_write(srv, __FILE__, __LINE__, "sbs",
-+                                              "stating existing pid-file failed:", srv->srvconf.pid_file, strerror(errno));
-+                      }
-+
-+                      if (!S_ISREG(st.st_mode)) {
-+                              log_error_write(srv, __FILE__, __LINE__, "sb",
-+                                              "pid-file exists and isn't regular file:", srv->srvconf.pid_file);
-+                              return -1;
-+                      }
-+
-+                      if (-1 == (pid_fd = open(srv->srvconf.pid_file->ptr, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) {
-+                              log_error_write(srv, __FILE__, __LINE__, "sbs",
-+                                              "opening pid-file failed:", srv->srvconf.pid_file, strerror(errno));
-+                              return -1;
-+                      }
-+              }
-+      }
-+#endif
-       if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
-               /* select limits itself
-                *
-                * as it is a hard limit and will lead to a segfault we add some safety
-                * */
--              srv->max_fds = FD_SETSIZE - 200;
-+        fprintf(stderr, "%s.%d: max parallel connections: %d\r\n", __FILE__, __LINE__, FD_SETSIZE);
-+              srv->max_fds = FD_SETSIZE - 4;
-       } else {
-               srv->max_fds = 4096;
-       }
-@@ -636,7 +1010,7 @@
- #ifdef HAVE_VALGRIND_VALGRIND_H
-               if (RUNNING_ON_VALGRIND) use_rlimit = 0;
- #endif
--              
-+
- #ifdef HAVE_GETRLIMIT
-               if (0 != getrlimit(RLIMIT_NOFILE, &rlim)) {
-                       log_error_write(srv, __FILE__, __LINE__,
-@@ -644,13 +1018,13 @@
-                                       strerror(errno));
-                       return -1;
-               }
--              
-+
-               if (use_rlimit && srv->srvconf.max_fds) {
-                       /* set rlimits */
--                      
-+
-                       rlim.rlim_cur = srv->srvconf.max_fds;
-                       rlim.rlim_max = srv->srvconf.max_fds;
--                      
-+
-                       if (0 != setrlimit(RLIMIT_NOFILE, &rlim)) {
-                               log_error_write(srv, __FILE__, __LINE__,
-                                               "ss", "couldn't set 'max filedescriptors'",
-@@ -659,7 +1033,7 @@
-                       }
-               }
--              /* #372: solaris need some fds extra for devpoll */     
-+              /* #372: solaris need some fds extra for devpoll */
-               if (rlim.rlim_cur > 10) rlim.rlim_cur -= 10;
-               if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
-@@ -677,33 +1051,33 @@
-               if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
-                       /* don't raise the limit above FD_SET_SIZE */
-                       if (srv->max_fds > FD_SETSIZE - 200) {
--                              log_error_write(srv, __FILE__, __LINE__, "sd", 
-+                              log_error_write(srv, __FILE__, __LINE__, "sd",
-                                               "can't raise max filedescriptors above",  FD_SETSIZE - 200,
-                                               "if event-handler is 'select'. Use 'poll' or something else or reduce server.max-fds.");
-                               return -1;
-                       }
-               }
--              
-+
- #ifdef HAVE_PWD_H
-               /* set user and group */
-               if (srv->srvconf.username->used) {
-                       if (NULL == (pwd = getpwnam(srv->srvconf.username->ptr))) {
--                              log_error_write(srv, __FILE__, __LINE__, "sb", 
-+                              log_error_write(srv, __FILE__, __LINE__, "sb",
-                                               "can't find username", srv->srvconf.username);
-                               return -1;
-                       }
--                      
-+
-                       if (pwd->pw_uid == 0) {
-                               log_error_write(srv, __FILE__, __LINE__, "s",
-                                               "I will not set uid to 0\n");
-                               return -1;
-                       }
-               }
--              
-+
-               if (srv->srvconf.groupname->used) {
-                       if (NULL == (grp = getgrnam(srv->srvconf.groupname->ptr))) {
--                              log_error_write(srv, __FILE__, __LINE__, "sb", 
-+                              log_error_write(srv, __FILE__, __LINE__, "sb",
-                                       "can't find groupname", srv->srvconf.groupname);
-                               return -1;
-                       }
-@@ -713,15 +1087,15 @@
-                               return -1;
-                       }
-               }
--#endif                
-+#endif
-               /* we need root-perms for port < 1024 */
-               if (0 != network_init(srv)) {
-                       plugins_free(srv);
-                       server_free(srv);
--                      
-+
-                       return -1;
-               }
--#ifdef HAVE_CHROOT    
-+#ifdef HAVE_CHROOT
-               if (srv->srvconf.changeroot->used) {
-                       tzset();
-@@ -761,7 +1135,7 @@
-               }
-               if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
--                      srv->max_fds = rlim.rlim_cur < FD_SETSIZE - 200 ? rlim.rlim_cur : FD_SETSIZE - 200;
-+                      srv->max_fds = rlim.rlim_cur < FD_SETSIZE - 4 ? rlim.rlim_cur : FD_SETSIZE - 4;
-               } else {
-                       srv->max_fds = rlim.rlim_cur;
-               }
-@@ -775,18 +1149,18 @@
- #endif
-               if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
-                       /* don't raise the limit above FD_SET_SIZE */
--                      if (srv->max_fds > FD_SETSIZE - 200) {
--                              log_error_write(srv, __FILE__, __LINE__, "sd", 
--                                              "can't raise max filedescriptors above",  FD_SETSIZE - 200,
-+                      if (srv->max_fds > FD_SETSIZE - 4) {
-+                              log_error_write(srv, __FILE__, __LINE__, "sd",
-+                                              "can't raise max filedescriptors above",  FD_SETSIZE - 4,
-                                               "if event-handler is 'select'. Use 'poll' or something else or reduce server.max-fds.");
-                               return -1;
-                       }
-               }
--              
-+
-               if (0 != network_init(srv)) {
-                       plugins_free(srv);
-                       server_free(srv);
--                      
-+
-                       return -1;
-               }
-       }
-@@ -802,25 +1176,27 @@
-               /* or use the default */
-               srv->max_conns = srv->max_fds;
-       }
--      
-+
-       if (HANDLER_GO_ON != plugins_call_init(srv)) {
-               log_error_write(srv, __FILE__, __LINE__, "s", "Initialization of plugins failed. Going down.");
--              
-+
-               plugins_free(srv);
-               network_close(srv);
-               server_free(srv);
--              
-+
-               return -1;
-       }
--#ifdef HAVE_FORK      
-+#ifdef HAVE_FORK
-       /* network is up, let's deamonize ourself */
-       if (srv->srvconf.dont_daemonize == 0) daemonize();
- #endif
-+#ifdef HAVE_PWD_H
-       srv->gid = getgid();
-       srv->uid = getuid();
--      
-+#endif
-+
-       /* write pid file */
-       if (pid_fd != -1) {
-               buffer_copy_long(srv->tmp_buf, getpid());
-@@ -829,17 +1205,17 @@
-               close(pid_fd);
-               pid_fd = -1;
-       }
--      
-+
-       if (HANDLER_GO_ON != plugins_call_set_defaults(srv)) {
-               log_error_write(srv, __FILE__, __LINE__, "s", "Configuration of plugins failed. Going down.");
--              
-+
-               plugins_free(srv);
-               network_close(srv);
-               server_free(srv);
--              
-+
-               return -1;
-       }
--      
-+
-       /* dump unused config-keys */
-       for (i = 0; i < srv->config_context->used; i++) {
-               array *config = ((data_config *)srv->config_context->data[i])->value;
-@@ -847,43 +1223,49 @@
-               for (j = 0; config && j < config->used; j++) {
-                       data_unset *du = config->data[j];
--                      
-+
-                       /* all var.* is known as user defined variable */
-                       if (strncmp(du->key->ptr, "var.", sizeof("var.") - 1) == 0) {
-                               continue;
-                       }
-                       if (NULL == array_get_element(srv->config_touched, du->key->ptr)) {
--                              log_error_write(srv, __FILE__, __LINE__, "sbs", 
-+                              log_error_write(srv, __FILE__, __LINE__, "sbs",
-                                               "WARNING: unknown config-key:",
-                                               du->key,
-                                               "(ignored)");
-                       }
-               }
-       }
--      
--      if (srv->config_deprecated) {
-+
-+      if (srv->config_unsupported) {
-               log_error_write(srv, __FILE__, __LINE__, "s", 
-+                              "Configuration contains unsupported keys. Going down.");
-+      }
-+
-+      if (srv->config_deprecated) {
-+              log_error_write(srv, __FILE__, __LINE__, "s",
-                               "Configuration contains deprecated keys. Going down.");
--              
-+      }
-+
-+      if (srv->config_unsupported || srv->config_deprecated) {
-               plugins_free(srv);
-               network_close(srv);
-               server_free(srv);
--              
-+
-               return -1;
-       }
--      
--      if (-1 == log_error_open(srv)) {
--              log_error_write(srv, __FILE__, __LINE__, "s", 
-+
-+      if (-1 == log_error_open(srv->srvconf.errorlog_file, srv->srvconf.errorlog_use_syslog)) {
-+              log_error_write(srv, __FILE__, __LINE__, "s",
-                               "opening errorlog failed, dying");
--              
-+
-               plugins_free(srv);
-               network_close(srv);
-               server_free(srv);
-               return -1;
-       }
--      
--      
-+
- #ifdef HAVE_SIGACTION
-       memset(&act, 0, sizeof(act));
-       act.sa_handler = SIG_IGN;
-@@ -903,7 +1285,7 @@
-       sigaction(SIGHUP,  &act, NULL);
-       sigaction(SIGALRM, &act, NULL);
-       sigaction(SIGCHLD, &act, NULL);
--      
-+
- #elif defined(HAVE_SIGNAL)
-       /* ignore the SIGPIPE from sendfile() */
-       signal(SIGPIPE, SIG_IGN);
-@@ -914,20 +1296,20 @@
-       signal(SIGCHLD,  signal_handler);
-       signal(SIGINT,  signal_handler);
- #endif
--      
-+
- #ifdef USE_ALARM
-       signal(SIGALRM, signal_handler);
--      
-+
-       /* setup periodic timer (1 second) */
-       if (setitimer(ITIMER_REAL, &interval, NULL)) {
-               log_error_write(srv, __FILE__, __LINE__, "s", "setting timer failed");
-               return -1;
-       }
--      
-+
-       getitimer(ITIMER_REAL, &interval);
- #endif
--#ifdef HAVE_FORK      
-+#ifdef HAVE_FORK
-       /* start watcher and workers */
-       num_childs = srv->srvconf.max_worker;
-       if (num_childs > 0) {
-@@ -957,13 +1339,13 @@
-       }
- #endif
--      if (NULL == (srv->ev = fdevent_init(srv->max_fds + 1, srv->event_handler))) {
-+      if (NULL == (srv->ev = fdevent_init(/*srv->max_fds + 1*/ 4096, srv->event_handler))) {
-               log_error_write(srv, __FILE__, __LINE__,
-                               "s", "fdevent_init failed");
-               return -1;
-       }
--      /* 
--       * kqueue() is called here, select resets its internals, 
-+      /*
-+       * kqueue() is called here, select resets its internals,
-        * all server sockets get their handlers
-        *
-        * */
-@@ -971,7 +1353,7 @@
-               plugins_free(srv);
-               network_close(srv);
-               server_free(srv);
--              
-+
-               return -1;
-       }
-@@ -986,17 +1368,17 @@
-       /* setup FAM */
-       if (srv->srvconf.stat_cache_engine == STAT_CACHE_ENGINE_FAM) {
-               if (0 != FAMOpen2(srv->stat_cache->fam, "lighttpd")) {
--                      log_error_write(srv, __FILE__, __LINE__, "s", 
-+                      log_error_write(srv, __FILE__, __LINE__, "s",
-                                        "could not open a fam connection, dieing.");
-                       return -1;
-               }
- #ifdef HAVE_FAMNOEXISTS
-               FAMNoExists(srv->stat_cache->fam);
- #endif
-+              srv->stat_cache->sock->fd = FAMCONNECTION_GETFD(srv->stat_cache->fam);
--              srv->stat_cache->fam_fcce_ndx = -1;
--              fdevent_register(srv->ev, FAMCONNECTION_GETFD(srv->stat_cache->fam), stat_cache_handle_fdevent, NULL);
--              fdevent_event_add(srv->ev, &(srv->stat_cache->fam_fcce_ndx), FAMCONNECTION_GETFD(srv->stat_cache->fam), FDEVENT_IN);
-+              fdevent_register(srv->ev, srv->stat_cache->sock, stat_cache_handle_fdevent, NULL);
-+              fdevent_event_add(srv->ev, srv->stat_cache->sock, FDEVENT_IN);
-       }
- #endif
-@@ -1007,330 +1389,36 @@
-       for (i = 0; i < srv->srv_sockets.used; i++) {
-               server_socket *srv_socket = srv->srv_sockets.ptr[i];
--              if (-1 == fdevent_fcntl_set(srv->ev, srv_socket->fd)) {
-+              if (-1 == fdevent_fcntl_set(srv->ev, srv_socket->sock)) {
-                       log_error_write(srv, __FILE__, __LINE__, "ss", "fcntl failed:", strerror(errno));
-                       return -1;
-               }
-       }
--      /* main-loop */
--      while (!srv_shutdown) {
--              int n;
--              size_t ndx;
--              time_t min_ts;
--              
--              if (handle_sig_hup) {
--                      handler_t r;
--                      
--                      /* reset notification */
--                      handle_sig_hup = 0;
--                      
--                      
--                      /* cycle logfiles */
--                      
--                      switch(r = plugins_call_handle_sighup(srv)) {
--                      case HANDLER_GO_ON:
--                              break;
--                      default:
--                              log_error_write(srv, __FILE__, __LINE__, "sd", "sighup-handler return with an error", r);
--                              break;
--                      }
--                      
--                      if (-1 == log_error_cycle(srv)) {
--                              log_error_write(srv, __FILE__, __LINE__, "s", "cycling errorlog failed, dying");
--                              
--                              return -1;
--                      }
--              }
--              
--              if (handle_sig_alarm) {
--                      /* a new second */
--                      
--#ifdef USE_ALARM
--                      /* reset notification */
--                      handle_sig_alarm = 0;
--#endif
--                      
--                      /* get current time */
--                      min_ts = time(NULL);
--                      
--                      if (min_ts != srv->cur_ts) {
--                              int cs = 0;
--                              connections *conns = srv->conns;
--                              handler_t r;
--                              
--                              switch(r = plugins_call_handle_trigger(srv)) {
--                              case HANDLER_GO_ON:
--                                      break;
--                              case HANDLER_ERROR:
--                                      log_error_write(srv, __FILE__, __LINE__, "s", "one of the triggers failed");
--                                      break;
--                              default:
--                                      log_error_write(srv, __FILE__, __LINE__, "d", r);
--                                      break;
--                              }
--                              
--                              /* trigger waitpid */
--                              srv->cur_ts = min_ts;
--                      
--                              /* cleanup stat-cache */        
--                              stat_cache_trigger_cleanup(srv);
--                              /**
--                               * check all connections for timeouts 
--                               * 
--                               */
--                              for (ndx = 0; ndx < conns->used; ndx++) {
--                                      int changed = 0;
--                                      connection *con;
--                                      int t_diff;
--                                      
--                                      con = conns->ptr[ndx];
--
--                                      if (con->state == CON_STATE_READ ||
--                                          con->state == CON_STATE_READ_POST) {
--                                              if (con->request_count == 1) {
--                                                      if (srv->cur_ts - con->read_idle_ts > con->conf.max_read_idle) {
--                                                              /* time - out */
--#if 0
--                                                              log_error_write(srv, __FILE__, __LINE__, "sd", 
--                                                                              "connection closed - read-timeout:", con->fd);
--#endif
--                                                              connection_set_state(srv, con, CON_STATE_ERROR);
--                                                              changed = 1;
--                                                      }
--                                              } else {
--                                                      if (srv->cur_ts - con->read_idle_ts > con->conf.max_keep_alive_idle) {
--                                                              /* time - out */
--#if 0
--                                                              log_error_write(srv, __FILE__, __LINE__, "sd", 
--                                                                              "connection closed - read-timeout:", con->fd);
--#endif
--                                                              connection_set_state(srv, con, CON_STATE_ERROR);
--                                                              changed = 1;
--                                                      }
--                                              }
--                                      }
--                                      
--                                      if ((con->state == CON_STATE_WRITE) &&
--                                          (con->write_request_ts != 0)) { 
--#if 0
--                                              if (srv->cur_ts - con->write_request_ts > 60) {
--                                                      log_error_write(srv, __FILE__, __LINE__, "sdd", 
--                                                                      "connection closed - pre-write-request-timeout:", con->fd, srv->cur_ts - con->write_request_ts);
--                                              }
--#endif
--                                              
--                                              if (srv->cur_ts - con->write_request_ts > con->conf.max_write_idle) {
--                                                      /* time - out */
--#if 1
--                                                      log_error_write(srv, __FILE__, __LINE__, "sbsosds", 
--                                                                      "NOTE: a request for",
--                                                                      con->request.uri,
--                                                                      "timed out after writing",
--                                                                      con->bytes_written,
--                                                                      "bytes. We waited",
--                                                                      (int)con->conf.max_write_idle,
--                                                                      "seconds. If this a problem increase server.max-write-idle");
--#endif
--                                                      connection_set_state(srv, con, CON_STATE_ERROR);
--                                                      changed = 1;
--                                              }
--                                      }
--                                      /* we don't like div by zero */
--                                      if (0 == (t_diff = srv->cur_ts - con->connection_start)) t_diff = 1;
--      
--                                      if (con->traffic_limit_reached && 
--                                          (con->conf.kbytes_per_second == 0 || 
--                                           ((con->bytes_written / t_diff) < con->conf.kbytes_per_second * 1024))) {
--                                              /* enable connection again */
--                                              con->traffic_limit_reached = 0;
--                                              
--                                              changed = 1;
--                                      }
--                                      
--                                      if (changed) {
--                                              connection_state_machine(srv, con);
--                                      }
--                                      con->bytes_written_cur_second = 0;
--                                      *(con->conf.global_bytes_per_second_cnt_ptr) = 0;
--                                      
--#if 0
--                                      if (cs == 0) {
--                                              fprintf(stderr, "connection-state: ");
--                                              cs = 1;
--                                      }
--                                      
--                                      fprintf(stderr, "c[%d,%d]: %s ",
--                                              con->fd,
--                                              con->fcgi.fd,
--                                              connection_get_state(con->state));
--#endif
--                              }
--                              
--                              if (cs == 1) fprintf(stderr, "\n");
--                      }
--              }
--
--              if (srv->sockets_disabled) {
--                      /* our server sockets are disabled, why ? */
--
--                      if ((srv->cur_fds + srv->want_fds < srv->max_fds * 0.8) && /* we have enough unused fds */
--                          (srv->conns->used < srv->max_conns * 0.9) &&
--                          (0 == graceful_shutdown)) {
--                              for (i = 0; i < srv->srv_sockets.used; i++) {
--                                      server_socket *srv_socket = srv->srv_sockets.ptr[i];
--                                      fdevent_event_add(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd, FDEVENT_IN);
--                              }
--                      
--                              log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets enabled again");
--                      
--                              srv->sockets_disabled = 0;
--                      }
--              } else {
--                      if ((srv->cur_fds + srv->want_fds > srv->max_fds * 0.9) || /* out of fds */
--                          (srv->conns->used > srv->max_conns) || /* out of connections */
--                          (graceful_shutdown)) { /* graceful_shutdown */ 
--
--                              /* disable server-fds */
--                      
--                              for (i = 0; i < srv->srv_sockets.used; i++) {
--                                      server_socket *srv_socket = srv->srv_sockets.ptr[i];
--                                      fdevent_event_del(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd);
--
--                                      if (graceful_shutdown) {
--                                              /* we don't want this socket anymore,
--                                               *
--                                               * closing it right away will make it possible for
--                                               * the next lighttpd to take over (graceful restart)
--                                               *  */
--
--                                              fdevent_unregister(srv->ev, srv_socket->fd);
--                                              close(srv_socket->fd);
--                                              srv_socket->fd = -1;
--
--                                              /* network_close() will cleanup after us */
--                                      }
--                              }
--              
--                              if (graceful_shutdown) {
--                                      log_error_write(srv, __FILE__, __LINE__, "s", "[note] graceful shutdown started");
--                              } else if (srv->conns->used > srv->max_conns) {
--                                      log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, connection limit reached");
--                              } else {
--                                      log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, out-of-fds");
--                              }
--                      
--                              srv->sockets_disabled = 1;
--                      }
--              }
-+      lighty_mainloop(srv);
--              if (graceful_shutdown && srv->conns->used == 0) {
--                      /* we are in graceful shutdown phase and all connections are closed
--                       * we are ready to terminate without harming anyone */
--                      srv_shutdown = 1;
--              }
--              
--              /* we still have some fds to share */
--              if (srv->want_fds) { 
--                      /* check the fdwaitqueue for waiting fds */
--                      int free_fds = srv->max_fds - srv->cur_fds - 16;
--                      connection *con;
--                      
--                      for (; free_fds > 0 && NULL != (con = fdwaitqueue_unshift(srv, srv->fdwaitqueue)); free_fds--) {
--                              connection_state_machine(srv, con);
--                              
--                              srv->want_fds--;
--                      }
--              }
-+      status_counter_free();
--              if ((n = fdevent_poll(srv->ev, 1000)) > 0) {
--                      /* n is the number of events */
--                      int revents;
--                      int fd_ndx;
--#if 0
--                      if (n > 0) {
--                              log_error_write(srv, __FILE__, __LINE__, "sd", 
--                                              "polls:", n);
--                      }
--#endif                        
--                      fd_ndx = -1;
--                      do {
--                              fdevent_handler handler;
--                              void *context;
--                              handler_t r;
--                              
--                              fd_ndx  = fdevent_event_next_fdndx (srv->ev, fd_ndx);
--                              revents = fdevent_event_get_revent (srv->ev, fd_ndx);
--                              fd      = fdevent_event_get_fd     (srv->ev, fd_ndx);
--                              handler = fdevent_get_handler(srv->ev, fd);
--                              context = fdevent_get_context(srv->ev, fd);
--                              
--                              /* connection_handle_fdevent needs a joblist_append */
--#if 0
--                              log_error_write(srv, __FILE__, __LINE__, "sdd", 
--                                              "event for", fd, revents);
--#endif                                
--                              switch (r = (*handler)(srv, context, revents)) {
--                              case HANDLER_FINISHED:
--                              case HANDLER_GO_ON:
--                              case HANDLER_WAIT_FOR_EVENT:
--                              case HANDLER_WAIT_FOR_FD:
--                                      break;
--                              case HANDLER_ERROR:
--                                      /* should never happen */
--                                      SEGFAULT();
--                                      break;
--                              default:
--                                      log_error_write(srv, __FILE__, __LINE__, "d", r);
--                                      break;
--                              }
--                      } while (--n > 0);
--              } else if (n < 0 && errno != EINTR) {
--                      log_error_write(srv, __FILE__, __LINE__, "ss", 
--                                      "fdevent_poll failed:", 
--                                      strerror(errno));
--              }
--              
--              for (ndx = 0; ndx < srv->joblist->used; ndx++) {
--                      connection *con = srv->joblist->ptr[ndx];
--                      handler_t r;
--                      
--                      connection_state_machine(srv, con);
--                      
--                      switch(r = plugins_call_handle_joblist(srv, con)) {
--                      case HANDLER_FINISHED:
--                      case HANDLER_GO_ON:
--                              break;
--                      default:
--                              log_error_write(srv, __FILE__, __LINE__, "d", r);
--                              break;
--                      }
--                      
--                      con->in_joblist = 0;
--              }
--              
--              srv->joblist->used = 0;
--      }
--      
--      if (srv->srvconf.pid_file->used &&
-+      if (0 == graceful_restart &&
-+          srv->srvconf.pid_file->used &&
-           srv->srvconf.changeroot->used == 0) {
-               if (0 != unlink(srv->srvconf.pid_file->ptr)) {
-                       if (errno != EACCES && errno != EPERM) {
--                              log_error_write(srv, __FILE__, __LINE__, "sbds", 
--                                              "unlink failed for:", 
-+                              log_error_write(srv, __FILE__, __LINE__, "sbds",
-+                                              "unlink failed for:",
-                                               srv->srvconf.pid_file,
-                                               errno,
-                                               strerror(errno));
-                       }
-               }
-       }
--      
-+
-       /* clean-up */
--      log_error_close(srv);
-       network_close(srv);
-       connections_free(srv);
-       plugins_free(srv);
-       server_free(srv);
--      
-+      log_free();
-+
-       return 0;
- }
---- ../lighttpd-1.4.11/src/settings.h  2005-08-11 01:26:41.000000000 +0300
-+++ lighttpd-1.5.0/src/settings.h      2006-07-16 00:26:04.000000000 +0300
-@@ -9,24 +9,24 @@
- /**
-  * max size of a buffer which will just be reset
-  * to ->used = 0 instead of really freeing the buffer
-- * 
-+ *
-  * 64kB (no real reason, just a guess)
-  */
- #define BUFFER_MAX_REUSE_SIZE  (4 * 1024)
- /**
-  * max size of the HTTP request header
-- * 
-+ *
-  * 32k should be enough for everything (just a guess)
-- * 
-+ *
-  */
- #define MAX_HTTP_REQUEST_HEADER  (32 * 1024)
--typedef enum { HANDLER_UNSET, 
--              HANDLER_GO_ON, 
-+typedef enum { HANDLER_UNSET,
-+              HANDLER_GO_ON,
-               HANDLER_FINISHED,
--              HANDLER_COMEBACK, 
--              HANDLER_WAIT_FOR_EVENT, 
-+              HANDLER_COMEBACK,
-+              HANDLER_WAIT_FOR_EVENT,
-               HANDLER_ERROR,
-               HANDLER_WAIT_FOR_FD
- } handler_t;
---- ../lighttpd-1.4.11/src/spawn-fcgi.c        2006-03-07 14:18:10.000000000 +0200
-+++ lighttpd-1.5.0/src/spawn-fcgi.c    2006-07-16 00:26:04.000000000 +0300
-@@ -1,19 +1,16 @@
- #include <sys/types.h>
--#include <sys/time.h>
- #include <sys/stat.h>
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
- #include <stdio.h>
--#include <unistd.h>
- #include <fcntl.h>
--
-+#include <time.h>
- #ifdef HAVE_CONFIG_H
- #include "config.h"
- #endif
--
- #ifdef HAVE_PWD_H
- #include <grp.h>
- #include <pwd.h>
-@@ -30,6 +27,7 @@
- #endif
- #include "sys-socket.h"
-+#include "sys-files.h"
- #ifdef HAVE_SYS_WAIT_H
- #include <sys/wait.h>
-@@ -45,28 +43,28 @@
-       int fcgi_fd;
-       int socket_type, status;
-       struct timeval tv = { 0, 100 * 1000 };
--      
-+
-       struct sockaddr_un fcgi_addr_un;
-       struct sockaddr_in fcgi_addr_in;
-       struct sockaddr *fcgi_addr;
--      
-+
-       socklen_t servlen;
--      
-+
-       if (child_count < 2) {
-               child_count = 5;
-       }
--      
-+
-       if (child_count > 256) {
-               child_count = 256;
-       }
--      
--      
-+
-+
-       if (unixsocket) {
-               memset(&fcgi_addr, 0, sizeof(fcgi_addr));
--              
-+
-               fcgi_addr_un.sun_family = AF_UNIX;
-               strcpy(fcgi_addr_un.sun_path, unixsocket);
--              
-+
- #ifdef SUN_LEN
-               servlen = SUN_LEN(&fcgi_addr_un);
- #else
-@@ -84,50 +82,50 @@
-                 }
-               fcgi_addr_in.sin_port = htons(port);
-               servlen = sizeof(fcgi_addr_in);
--              
-+
-               socket_type = AF_INET;
-               fcgi_addr = (struct sockaddr *) &fcgi_addr_in;
-       }
--      
-+
-       if (-1 == (fcgi_fd = socket(socket_type, SOCK_STREAM, 0))) {
--              fprintf(stderr, "%s.%d\n", 
-+              fprintf(stderr, "%s.%d\n",
-                       __FILE__, __LINE__);
-               return -1;
-       }
--      
-+
-       if (-1 == connect(fcgi_fd, fcgi_addr, servlen)) {
-               /* server is not up, spawn in  */
-               pid_t child;
-               int val;
--              
-+
-               if (unixsocket) unlink(unixsocket);
--              
-+
-               close(fcgi_fd);
--              
-+
-               /* reopen socket */
-               if (-1 == (fcgi_fd = socket(socket_type, SOCK_STREAM, 0))) {
--                      fprintf(stderr, "%s.%d\n", 
-+                      fprintf(stderr, "%s.%d\n",
-                               __FILE__, __LINE__);
-                       return -1;
-               }
-               val = 1;
-               if (setsockopt(fcgi_fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) {
--                      fprintf(stderr, "%s.%d\n", 
-+                      fprintf(stderr, "%s.%d\n",
-                               __FILE__, __LINE__);
-                       return -1;
-               }
-               /* create socket */
-               if (-1 == bind(fcgi_fd, fcgi_addr, servlen)) {
--                      fprintf(stderr, "%s.%d: bind failed: %s\n", 
-+                      fprintf(stderr, "%s.%d: bind failed: %s\n",
-                               __FILE__, __LINE__,
-                               strerror(errno));
-                       return -1;
-               }
--              
-+
-               if (-1 == listen(fcgi_fd, 1024)) {
--                      fprintf(stderr, "%s.%d: fd = -1\n", 
-+                      fprintf(stderr, "%s.%d: fd = -1\n",
-                               __FILE__, __LINE__);
-                       return -1;
-               }
-@@ -137,42 +135,45 @@
-               } else {
-                       child = 0;
-               }
--              
-+
-               switch (child) {
-               case 0: {
-                       char cgi_childs[64];
-                       char *b;
--                      
-+
-                       int i = 0;
--                      
-+
-+                      /* loose control terminal */
-+                      setsid();
-+
-                       /* is save as we limit to 256 childs */
-                       sprintf(cgi_childs, "PHP_FCGI_CHILDREN=%d", child_count);
--                      
-+
-                       if(fcgi_fd != FCGI_LISTENSOCK_FILENO) {
-                               close(FCGI_LISTENSOCK_FILENO);
-                               dup2(fcgi_fd, FCGI_LISTENSOCK_FILENO);
-                               close(fcgi_fd);
-                       }
--                      
-+
-                       /* we don't need the client socket */
-                       for (i = 3; i < 256; i++) {
-                               close(i);
-                       }
--                      
-+
-                       /* create environment */
--                      
-+
-                       putenv(cgi_childs);
--                      
-+
-                       /* fork and replace shell */
-                       b = malloc(strlen("exec ") + strlen(appPath) + 1);
-                       strcpy(b, "exec ");
-                       strcat(b, appPath);
--                      
-+
-                       /* exec the cgi */
-                       execl("/bin/sh", "sh", "-c", b, NULL);
--                      
-+
-                       exit(errno);
--                      
-+
-                       break;
-               }
-               case -1:
-@@ -180,47 +181,47 @@
-                       break;
-               default:
-                       /* father */
--                      
-+
-                       /* wait */
-                       select(0, NULL, NULL, NULL, &tv);
--                      
-+
-                       switch (waitpid(child, &status, WNOHANG)) {
-                       case 0:
--                              fprintf(stderr, "%s.%d: child spawned successfully: PID: %d\n", 
-+                              fprintf(stderr, "%s.%d: child spawned successfully: PID: %d\n",
-                                       __FILE__, __LINE__,
-                                       child);
--                              
-+
-                               /* write pid file */
-                               if (pid_fd != -1) {
-                                       /* assume a 32bit pid_t */
-                                       char pidbuf[12];
--                                      
-+
-                                       snprintf(pidbuf, sizeof(pidbuf) - 1, "%d", child);
--                                      
-+
-                                       write(pid_fd, pidbuf, strlen(pidbuf));
-                                       close(pid_fd);
-                                       pid_fd = -1;
-                               }
--                              
-+
-                               break;
-                       case -1:
-                               break;
-                       default:
-                               if (WIFEXITED(status)) {
--                                      fprintf(stderr, "%s.%d: child exited with: %d, %s\n", 
-+                                      fprintf(stderr, "%s.%d: child exited with: %d, %s\n",
-                                               __FILE__, __LINE__,
-                                               WEXITSTATUS(status), strerror(WEXITSTATUS(status)));
-                               } else if (WIFSIGNALED(status)) {
--                                      fprintf(stderr, "%s.%d: child signaled: %d\n", 
-+                                      fprintf(stderr, "%s.%d: child signaled: %d\n",
-                                               __FILE__, __LINE__,
-                                               WTERMSIG(status));
-                               } else {
--                                      fprintf(stderr, "%s.%d: child died somehow: %d\n", 
-+                                      fprintf(stderr, "%s.%d: child died somehow: %d\n",
-                                               __FILE__, __LINE__,
-                                               status);
-                               }
-                       }
--                              
-+
-                       break;
-               }
-       } else {
-@@ -228,16 +229,16 @@
-                       __FILE__, __LINE__);
-               return -1;
-       }
--      
-+
-       close(fcgi_fd);
--      
-+
-       return 0;
- }
- void show_version () {
-       char *b = "spawn-fcgi" "-" PACKAGE_VERSION \
--" - spawns fastcgi processes\n" 
-+" - spawns fastcgi processes\n"
- ;
-       write(1, b, strlen(b));
- }
-@@ -265,7 +266,7 @@
- int main(int argc, char **argv) {
--      char *fcgi_app = NULL, *changeroot = NULL, *username = NULL, 
-+      char *fcgi_app = NULL, *changeroot = NULL, *username = NULL,
-                *groupname = NULL, *unixsocket = NULL, *pid_file = NULL,
-                 *addr = NULL;
-       unsigned short port = 0;
-@@ -273,9 +274,9 @@
-       int i_am_root, o;
-       int pid_fd = -1;
-       int nofork = 0;
--      
-+
-       i_am_root = (getuid() == 0);
--      
-+
-        while(-1 != (o = getopt(argc, argv, "c:f:g:hna:p:u:vC:s:P:"))) {
-               switch(o) {
-               case 'f': fcgi_app = optarg; break;
-@@ -290,137 +291,137 @@
-               case 'P': pid_file = optarg; /* PID file */ break;
-               case 'v': show_version(); return 0;
-               case 'h': show_help(); return 0;
--              default: 
-+              default:
-                       show_help();
-                       return -1;
-               }
-       }
--      
-+
-       if (fcgi_app == NULL || (port == 0 && unixsocket == NULL)) {
-               show_help();
-               return -1;
-       }
--          
-+
-       if (unixsocket && port) {
--              fprintf(stderr, "%s.%d: %s\n", 
-+              fprintf(stderr, "%s.%d: %s\n",
-                       __FILE__, __LINE__,
-                       "either a unix domain socket or a tcp-port, but not both\n");
--              
-+
-               return -1;
-       }
--      
-+
-       if (unixsocket && strlen(unixsocket) > UNIX_PATH_MAX - 1) {
--              fprintf(stderr, "%s.%d: %s\n", 
-+              fprintf(stderr, "%s.%d: %s\n",
-                       __FILE__, __LINE__,
-                       "path of the unix socket is too long\n");
--              
-+
-               return -1;
-       }
-       /* UID handling */
-       if (!i_am_root && (geteuid() == 0 || getegid() == 0)) {
-               /* we are setuid-root */
--              
--              fprintf(stderr, "%s.%d: %s\n", 
-+
-+              fprintf(stderr, "%s.%d: %s\n",
-                       __FILE__, __LINE__,
-                       "Are you nuts ? Don't apply a SUID bit to this binary\n");
--              
-+
-               return -1;
-       }
--      
--      if (pid_file && 
-+
-+      if (pid_file &&
-           (-1 == (pid_fd = open(pid_file, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)))) {
-               struct stat st;
-               if (errno != EEXIST) {
--                      fprintf(stderr, "%s.%d: opening pid-file '%s' failed: %s\n", 
-+                      fprintf(stderr, "%s.%d: opening pid-file '%s' failed: %s\n",
-                               __FILE__, __LINE__,
-                               pid_file, strerror(errno));
--                      
-+
-                       return -1;
-               }
--              
-+
-               /* ok, file exists */
--              
-+
-               if (0 != stat(pid_file, &st)) {
--                      fprintf(stderr, "%s.%d: stating pid-file '%s' failed: %s\n", 
-+                      fprintf(stderr, "%s.%d: stating pid-file '%s' failed: %s\n",
-                               __FILE__, __LINE__,
-                               pid_file, strerror(errno));
--                      
-+
-                       return -1;
-               }
--              
-+
-               /* is it a regular file ? */
--              
-+
-               if (!S_ISREG(st.st_mode)) {
--                      fprintf(stderr, "%s.%d: pid-file exists and isn't regular file: '%s'\n", 
-+                      fprintf(stderr, "%s.%d: pid-file exists and isn't regular file: '%s'\n",
-                               __FILE__, __LINE__,
-                               pid_file);
--                      
-+
-                       return -1;
-               }
--              
-+
-               if (-1 == (pid_fd = open(pid_file, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) {
--                      fprintf(stderr, "%s.%d: opening pid-file '%s' failed: %s\n", 
-+                      fprintf(stderr, "%s.%d: opening pid-file '%s' failed: %s\n",
-                               __FILE__, __LINE__,
-                               pid_file, strerror(errno));
--                      
-+
-                       return -1;
-               }
-       }
--      
-+
-       if (i_am_root) {
-               struct group *grp = NULL;
-               struct passwd *pwd = NULL;
--              
-+
-               /* set user and group */
--              
-+
-               if (username) {
-                       if (NULL == (pwd = getpwnam(username))) {
--                              fprintf(stderr, "%s.%d: %s, %s\n", 
-+                              fprintf(stderr, "%s.%d: %s, %s\n",
-                                       __FILE__, __LINE__,
-                                       "can't find username", username);
-                               return -1;
-                       }
--                      
-+
-                       if (pwd->pw_uid == 0) {
--                              fprintf(stderr, "%s.%d: %s\n", 
-+                              fprintf(stderr, "%s.%d: %s\n",
-                                       __FILE__, __LINE__,
-                                       "I will not set uid to 0\n");
-                               return -1;
-                       }
-               }
--              
-+
-               if (groupname) {
-                       if (NULL == (grp = getgrnam(groupname))) {
--                              fprintf(stderr, "%s.%d: %s %s\n", 
-+                              fprintf(stderr, "%s.%d: %s %s\n",
-                                       __FILE__, __LINE__,
--                                      "can't find groupname", 
-+                                      "can't find groupname",
-                                       groupname);
-                               return -1;
-                       }
-                       if (grp->gr_gid == 0) {
--                              fprintf(stderr, "%s.%d: %s\n", 
-+                              fprintf(stderr, "%s.%d: %s\n",
-                                       __FILE__, __LINE__,
-                                       "I will not set gid to 0\n");
-                               return -1;
-                       }
-               }
--              
-+
-               if (changeroot) {
-                       if (-1 == chroot(changeroot)) {
--                              fprintf(stderr, "%s.%d: %s %s\n", 
-+                              fprintf(stderr, "%s.%d: %s %s\n",
-                                       __FILE__, __LINE__,
-                                       "chroot failed: ", strerror(errno));
-                               return -1;
-                       }
-                       if (-1 == chdir("/")) {
--                              fprintf(stderr, "%s.%d: %s %s\n", 
-+                              fprintf(stderr, "%s.%d: %s %s\n",
-                                       __FILE__, __LINE__,
-                                       "chdir failed: ", strerror(errno));
-                               return -1;
-                       }
-               }
--              
-+
-               /* drop root privs */
-               if (groupname) {
-                       setgid(grp->gr_gid);
-@@ -428,7 +429,7 @@
-               }
-               if (username) setuid(pwd->pw_uid);
-       }
--      
-+
-        return fcgi_spawn_connection(fcgi_app, addr, port, unixsocket, child_count, pid_fd, nofork);
- }
- #else
---- ../lighttpd-1.4.11/src/splaytree.c 2005-09-12 21:51:28.000000000 +0300
-+++ lighttpd-1.5.0/src/splaytree.c     2006-07-16 00:26:03.000000000 +0300
-@@ -56,19 +56,19 @@
- #define node_size splaytree_size
--/* Splay using the key i (which may or may not be in the tree.) 
-- * The starting root is t, and the tree used is defined by rat 
-+/* Splay using the key i (which may or may not be in the tree.)
-+ * The starting root is t, and the tree used is defined by rat
-  * size fields are maintained */
- splay_tree * splaytree_splay (splay_tree *t, int i) {
-     splay_tree N, *l, *r, *y;
-     int comp, root_size, l_size, r_size;
--    
-+
-     if (t == NULL) return t;
-     N.left = N.right = NULL;
-     l = r = &N;
-     root_size = node_size(t);
-     l_size = r_size = 0;
-- 
-+
-     for (;;) {
-         comp = compare(i, t->key);
-         if (comp < 0) {
-@@ -120,7 +120,7 @@
-         y->size = r_size;
-         r_size -= 1+node_size(y->right);
-     }
-- 
-+
-     l->right = t->left;                                /* assemble */
-     r->left = t->right;
-     t->left = N.right;
---- ../lighttpd-1.4.11/src/splaytree.h 2005-09-12 21:51:13.000000000 +0300
-+++ lighttpd-1.5.0/src/splaytree.h     2006-07-16 00:26:03.000000000 +0300
-@@ -19,6 +19,6 @@
- /* This macro returns the size of a node.  Unlike "x->size",     */
- /* it works even if x=NULL.  The test could be avoided by using  */
- /* a special version of NULL which was a real node with size 0.  */
-- 
-+
- #endif
---- ../lighttpd-1.4.11/src/stat_cache.c        2005-11-22 15:23:51.000000000 +0200
-+++ lighttpd-1.5.0/src/stat_cache.c    2006-09-07 00:57:05.000000000 +0300
-@@ -6,7 +6,6 @@
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
--#include <unistd.h>
- #include <stdio.h>
- #include <fcntl.h>
- #include <assert.h>
-@@ -25,19 +24,8 @@
- #endif
- #include "sys-mmap.h"
--
--/* NetBSD 1.3.x needs it */
--#ifndef MAP_FAILED
--# define MAP_FAILED -1
--#endif
--
--#ifndef O_LARGEFILE
--# define O_LARGEFILE 0
--#endif
--
--#ifndef HAVE_LSTAT
--#define lstat stat
--#endif
-+#include "sys-files.h"
-+#include "sys-strings.h"
- #if 0
- /* enables debug code for testing if all nodes in the stat-cache as accessable */
-@@ -52,8 +40,8 @@
-  *
-  * if we get a change-event from FAM, we increment the version in the FAM->dir mapping
-  *
-- * if the stat()-cache is queried we check if the version id for the directory is the 
-- * same and return immediatly. 
-+ * if the stat()-cache is queried we check if the version id for the directory is the
-+ * same and return immediatly.
-  *
-  *
-  * What we need:
-@@ -62,17 +50,17 @@
-  * - for each FAMRequest we have to find the version in the directory cache (index as userdata)
-  *
-  * stat <<-> directory <-> FAMRequest
-- * 
-- * if file is deleted, directory is dirty, file is rechecked ... 
-+ *
-+ * if file is deleted, directory is dirty, file is rechecked ...
-  * if directory is deleted, directory mapping is removed
-- *  
-+ *
-  * */
- #ifdef HAVE_FAM_H
- typedef struct {
-       FAMRequest *req;
-       FAMConnection *fc;
--      
-+
-       buffer *name;
-       int version;
-@@ -83,16 +71,16 @@
-  * - we need a hash
-  * - the hash-key is used as sorting criteria for a tree
-  * - a splay-tree is used as we can use the caching effect of it
-- */ 
-+ */
- /* we want to cleanup the stat-cache every few seconds, let's say 10
-  *
-  * - remove entries which are outdated since 30s
-  * - remove entries which are fresh but havn't been used since 60s
-  * - if we don't have a stat-cache entry for a directory, release it from the monitor
-- */ 
-+ */
--#ifdef DEBUG_STAT_CACHE       
-+#ifdef DEBUG_STAT_CACHE
- typedef struct {
-       int *ptr;
-@@ -105,15 +93,16 @@
- stat_cache *stat_cache_init(void) {
-       stat_cache *fc = NULL;
--      
-+
-       fc = calloc(1, sizeof(*fc));
--      
-+
-       fc->dir_name = buffer_init();
- #ifdef HAVE_FAM_H
-       fc->fam = calloc(1, sizeof(*fc->fam));
-+      fc->sock = iosocket_init();
- #endif
--#ifdef DEBUG_STAT_CACHE       
-+#ifdef DEBUG_STAT_CACHE
-       ctrl.size = 0;
- #endif
-@@ -122,24 +111,24 @@
- static stat_cache_entry * stat_cache_entry_init(void) {
-       stat_cache_entry *sce = NULL;
--      
-+
-       sce = calloc(1, sizeof(*sce));
--      
-+
-       sce->name = buffer_init();
-       sce->etag = buffer_init();
-       sce->content_type = buffer_init();
--      
-+
-       return sce;
- }
- static void stat_cache_entry_free(void *data) {
-       stat_cache_entry *sce = data;
-       if (!sce) return;
--      
-+
-       buffer_free(sce->etag);
-       buffer_free(sce->name);
-       buffer_free(sce->content_type);
--      
-+
-       free(sce);
- }
-@@ -148,22 +137,22 @@
-       fam_dir_entry *fam_dir = NULL;
-       fam_dir = calloc(1, sizeof(*fam_dir));
--      
-+
-       fam_dir->name = buffer_init();
--      
-+
-       return fam_dir;
- }
- static void fam_dir_entry_free(void *data) {
-       fam_dir_entry *fam_dir = data;
--      
-+
-       if (!fam_dir) return;
--      
-+
-       FAMCancelMonitor(fam_dir->fc, fam_dir->req);
--      
-+
-       buffer_free(fam_dir->name);
-       free(fam_dir->req);
--      
-+
-       free(fam_dir);
- }
- #endif
-@@ -174,7 +163,7 @@
-               splay_tree *node = sc->files;
-               osize = sc->files->size;
--                      
-+
-               stat_cache_entry_free(node->data);
-               sc->files = splaytree_delete(sc->files, node->key);
-@@ -187,12 +176,12 @@
-       while (sc->dirs) {
-               int osize;
-               splay_tree *node = sc->dirs;
--              
-+
-               osize = sc->dirs->size;
-               fam_dir_entry_free(node->data);
-               sc->dirs = splaytree_delete(sc->dirs, node->key);
--              
-+
-               if (osize == 1) {
-                       assert(NULL == sc->dirs);
-               } else {
-@@ -202,6 +191,7 @@
-       if (sc->fam) {
-               FAMClose(sc->fam);
-+              iosocket_free(sc->sock);
-               free(sc->fam);
-       }
- #endif
-@@ -212,7 +202,7 @@
- static int stat_cache_attr_get(buffer *buf, char *name) {
-       int attrlen;
-       int ret;
--      
-+
-       attrlen = 1024;
-       buffer_prepare_copy(buf, attrlen);
-       attrlen--;
-@@ -251,15 +241,15 @@
-           sc->fam) {
-               events = FAMPending(sc->fam);
--      
-+
-               for (i = 0; i < events; i++) {
-                       FAMEvent fe;
-                       fam_dir_entry *fam_dir;
-                       splay_tree *node;
-                       int ndx;
--              
-+
-                       FAMNextEvent(sc->fam, &fe);
--      
-+
-                       /* handle event */
-                       switch(fe.code) {
-@@ -280,7 +270,7 @@
-                               sc->dirs = splaytree_splay(sc->dirs, ndx);
-                               node = sc->dirs;
--                      
-+
-                               if (node && (node->key == ndx)) {
-                                       int osize = splaytree_size(sc->dirs);
-@@ -298,17 +288,15 @@
-       if (revent & FDEVENT_HUP) {
-               /* fam closed the connection */
--              srv->stat_cache->fam_fcce_ndx = -1;
--
--              fdevent_event_del(srv->ev, &(sc->fam_fcce_ndx), FAMCONNECTION_GETFD(sc->fam));
--              fdevent_unregister(srv->ev, FAMCONNECTION_GETFD(sc->fam));
-+              fdevent_event_del(srv->ev, sc->sock);
-+              fdevent_unregister(srv->ev, sc->sock);
-               FAMClose(sc->fam);
-               free(sc->fam);
-               sc->fam = NULL;
-       }
--      
-+
-       return HANDLER_GO_ON;
- }
-@@ -328,11 +316,25 @@
- }
- #endif
-+#ifdef HAVE_LSTAT
-+static int stat_cache_lstat(server *srv, char *dname, struct stat *lst) {
-+      if (lstat(dname, lst) == 0) {
-+              return S_ISLNK(lst->st_mode) ? 0 : 1;
-+      }
-+      else {
-+              log_error_write(srv, __FILE__, __LINE__, "sss",
-+                              "lstat failed for:",
-+                              dname, strerror(errno));
-+      };
-+      return -1;
-+}
-+#endif
-+
- /***
-  *
-  *
-  *
-- * returns: 
-+ * returns:
-  *  - HANDLER_FINISHED on cache-miss (don't forget to reopen the file)
-  *  - HANDLER_ERROR on stat() failed -> see errno for problem
-  */
-@@ -348,16 +350,16 @@
-       struct stat st;
-       size_t k;
-       int fd;
--#ifdef DEBUG_STAT_CACHE       
-+#ifdef DEBUG_STAT_CACHE
-       size_t i;
- #endif
-       int file_ndx;
-       splay_tree *file_node = NULL;
--      *ret_sce = NULL; 
-+      *ret_sce = NULL;
--      /* 
-+      /*
-        * check if the directory for this file has changed
-        */
-@@ -366,23 +368,23 @@
-       file_ndx = hashme(name);
-       sc->files = splaytree_splay(sc->files, file_ndx);
--#ifdef DEBUG_STAT_CACHE       
-+#ifdef DEBUG_STAT_CACHE
-       for (i = 0; i < ctrl.used; i++) {
-               if (ctrl.ptr[i] == file_ndx) break;
-       }
- #endif
-       if (sc->files && (sc->files->key == file_ndx)) {
--#ifdef DEBUG_STAT_CACHE       
-+#ifdef DEBUG_STAT_CACHE
-               /* it was in the cache */
-               assert(i < ctrl.used);
- #endif
--              
--              /* we have seen this file already and 
-+
-+              /* we have seen this file already and
-                * don't stat() it again in the same second */
-               file_node = sc->files;
--              
-+
-               sce = file_node->data;
-               /* check if the name is the same, we might have a collision */
-@@ -390,7 +392,7 @@
-               if (buffer_is_equal(name, sce->name)) {
-                       if (srv->srvconf.stat_cache_engine == STAT_CACHE_ENGINE_SIMPLE) {
-                               if (sce->stat_ts == srv->cur_ts) {
--                                      *ret_sce = sce; 
-+                                      *ret_sce = sce;
-                                       return HANDLER_GO_ON;
-                               }
-                       }
-@@ -400,15 +402,15 @@
-                        * file_node is used by the FAM check below to see if we know this file
-                        * and if we can save a stat().
-                        *
--                       * BUT, the sce is not reset here as the entry into the cache is ok, we 
-+                       * BUT, the sce is not reset here as the entry into the cache is ok, we
-                        * it is just not pointing to our requested file.
--                       * 
-+                       *
-                        *  */
-                       file_node = NULL;
-               }
-       } else {
--#ifdef DEBUG_STAT_CACHE       
-+#ifdef DEBUG_STAT_CACHE
-               if (i != ctrl.used) {
-                       fprintf(stderr, "%s.%d: %08x was already inserted but not found in cache, %s\n", __FILE__, __LINE__, file_ndx, name->ptr);
-               }
-@@ -424,23 +426,23 @@
-               }
-               dir_ndx = hashme(sc->dir_name);
--              
-+
-               sc->dirs = splaytree_splay(sc->dirs, dir_ndx);
--              
-+
-               if (sc->dirs && (sc->dirs->key == dir_ndx)) {
-                       dir_node = sc->dirs;
-               }
--              
-+
-               if (dir_node && file_node) {
-                       /* we found a file */
--                      
-+
-                       sce = file_node->data;
-                       fam_dir = dir_node->data;
--                      
-+
-                       if (fam_dir->version == sce->dir_version) {
-                               /* the stat()-cache entry is still ok */
--                              
--                              *ret_sce = sce; 
-+
-+                              *ret_sce = sce;
-                               return HANDLER_GO_ON;
-                       }
-               }
-@@ -448,12 +450,11 @@
- #endif
-       /*
--       * *lol* 
-+       * *lol*
-        * - open() + fstat() on a named-pipe results in a (intended) hang.
--       * - stat() if regualar file + open() to see if we can read from it is better
-+       * - stat() if regular file + open() to see if we can read from it is better
-        *
-        * */
--
-       if (-1 == stat(name->ptr, &st)) {
-               return HANDLER_ERROR;
-       }
-@@ -469,16 +470,16 @@
-       if (NULL == sce) {
-               int osize = 0;
--                     
-+
-               if (sc->files) {
-                       osize = sc->files->size;
-               }
-               sce = stat_cache_entry_init();
-               buffer_copy_string_buffer(sce->name, name);
--              
--              sc->files = splaytree_insert(sc->files, file_ndx, sce); 
--#ifdef DEBUG_STAT_CACHE       
-+
-+              sc->files = splaytree_insert(sc->files, file_ndx, sce);
-+#ifdef DEBUG_STAT_CACHE
-               if (ctrl.size == 0) {
-                       ctrl.size = 16;
-                       ctrl.used = 0;
-@@ -499,29 +500,70 @@
-       sce->st = st;
-       sce->stat_ts = srv->cur_ts;
--      /* catch the obvious symlinks 
-+      /* catch the obvious symlinks
-        *
-        * this is not a secure check as we still have a race-condition between
--       * the stat() and the open. We can only solve this by 
-+       * the stat() and the open. We can only solve this by
-        * 1. open() the file
-        * 2. fstat() the fd
-        *
-        * and keeping the file open for the rest of the time. But this can
-        * only be done at network level.
--       * 
--       * */
--      if (S_ISLNK(st.st_mode) && !con->conf.follow_symlink) {
--              return HANDLER_ERROR;
--      }
-+       *
-+       * per default it is not a symlink
-+       **/
-+#ifdef HAVE_LSTAT
-+      sce->is_symlink = 0;
-+      struct stat lst;
-+      if (stat_cache_lstat(srv, name->ptr, &lst)  == 0) {
-+#ifdef DEBUG_STAT_CACHE
-+                      log_error_write(srv, __FILE__, __LINE__, "sb",
-+                                      "found symlink", name);
-+#endif
-+                      sce->is_symlink = 1;
-+              }
--      if (S_ISREG(st.st_mode)) {      
-+      /*
-+       * we assume "/" can not be symlink, so
-+       * skip the symlink stuff if our path is /
-+       **/
-+      else if ((name->used > 2)) {
-+              char *dname, *s_cur;
-+
-+              dname = strndup(name->ptr, name->used);
-+              while ((s_cur = strrchr(dname,'/'))) {
-+                      *s_cur = '\0';
-+                      if (dname == s_cur) {
-+#ifdef DEBUG_STAT_CACHE
-+                              log_error_write(srv, __FILE__, __LINE__, "s", "reached /");
-+#endif
-+                              break;
-+                      }
-+#ifdef DEBUG_STAT_CACHE
-+                      log_error_write(srv, __FILE__, __LINE__, "sss",
-+                                      "checking if", dname, "is a symlink");
-+#endif
-+                      if (stat_cache_lstat(srv, dname, &lst)  == 0) {
-+                              sce->is_symlink = 1;
-+#ifdef DEBUG_STAT_CACHE
-+                              log_error_write(srv, __FILE__, __LINE__, "ss",
-+                                              "found symlink", dname);
-+#endif
-+                              break;
-+                      };
-+              };
-+              free(dname);
-+      };
-+#endif
-+
-+      if (S_ISREG(st.st_mode)) {
-               /* determine mimetype */
-               buffer_reset(sce->content_type);
--              
-+
-               for (k = 0; k < con->conf.mimetypes->used; k++) {
-                       data_string *ds = (data_string *)con->conf.mimetypes->data[k];
-                       buffer *type = ds->key;
--              
-+
-                       if (type->used == 0) continue;
-                       /* check if the right side is the same */
-@@ -538,8 +580,10 @@
-                       stat_cache_attr_get(sce->content_type, name->ptr);
-               }
- #endif
-+      } else if (S_ISDIR(st.st_mode)) {
-+              etag_create(sce->etag, &(sce->st));
-       }
--              
-+
- #ifdef HAVE_FAM_H
-       if (sc->fam &&
-           (srv->srvconf.stat_cache_engine == STAT_CACHE_ENGINE_FAM)) {
-@@ -549,19 +593,19 @@
-                       fam_dir->fc = sc->fam;
-                       buffer_copy_string_buffer(fam_dir->name, sc->dir_name);
--                      
-+
-                       fam_dir->version = 1;
--                      
-+
-                       fam_dir->req = calloc(1, sizeof(FAMRequest));
--                      
--                      if (0 != FAMMonitorDirectory(sc->fam, fam_dir->name->ptr, 
-+
-+                      if (0 != FAMMonitorDirectory(sc->fam, fam_dir->name->ptr,
-                                                    fam_dir->req, fam_dir)) {
--                              
--                              log_error_write(srv, __FILE__, __LINE__, "sbs", 
--                                              "monitoring dir failed:", 
--                                              fam_dir->name, 
-+
-+                              log_error_write(srv, __FILE__, __LINE__, "sbs",
-+                                              "monitoring dir failed:",
-+                                              fam_dir->name,
-                                               FamErrlist[FAMErrno]);
--                              
-+
-                               fam_dir_entry_free(fam_dir);
-                       } else {
-                               int osize = 0;
-@@ -570,7 +614,7 @@
-                                       osize = sc->dirs->size;
-                               }
--                              sc->dirs = splaytree_insert(sc->dirs, dir_ndx, fam_dir); 
-+                              sc->dirs = splaytree_insert(sc->dirs, dir_ndx, fam_dir);
-                               assert(sc->dirs);
-                               assert(sc->dirs->data == fam_dir);
-                               assert(osize == (sc->dirs->size - 1));
-@@ -578,9 +622,9 @@
-               } else {
-                       fam_dir = dir_node->data;
-               }
--              
-+
-               /* bind the fam_fc to the stat() cache entry */
--                      
-+
-               if (fam_dir) {
-                       sce->dir_version = fam_dir->version;
-                       sce->dir_ndx     = dir_ndx;
-@@ -594,11 +638,11 @@
- }
- /**
-- * remove stat() from cache which havn't been stat()ed for 
-+ * remove stat() from cache which havn't been stat()ed for
-  * more than 10 seconds
-- * 
-  *
-- * walk though the stat-cache, collect the ids which are too old 
-+ *
-+ * walk though the stat-cache, collect the ids which are too old
-  * and remove them in a second loop
-  */
-@@ -639,9 +683,9 @@
-               sc->files = splaytree_splay(sc->files, ndx);
-               node = sc->files;
--              
-+
-               if (node && (node->key == ndx)) {
--#ifdef DEBUG_STAT_CACHE       
-+#ifdef DEBUG_STAT_CACHE
-                       size_t j;
-                       int osize = splaytree_size(sc->files);
-                       stat_cache_entry *sce = node->data;
-@@ -649,7 +693,7 @@
-                       stat_cache_entry_free(node->data);
-                       sc->files = splaytree_delete(sc->files, ndx);
--#ifdef DEBUG_STAT_CACHE       
-+#ifdef DEBUG_STAT_CACHE
-                       for (j = 0; j < ctrl.used; j++) {
-                               if (ctrl.ptr[j] == ndx) {
-                                       ctrl.ptr[j] = ctrl.ptr[--ctrl.used];
---- ../lighttpd-1.4.11/src/status_counter.c    1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/status_counter.c        2006-07-19 20:02:55.000000000 +0300
-@@ -0,0 +1,75 @@
-+#include <stdlib.h>
-+
-+#include "status_counter.h"
-+/**
-+ * The status array can carry all the status information you want
-+ * the key to the array is <module-prefix>.<name>
-+ * and the values are counters
-+ *
-+ * example:
-+ *   fastcgi.backends        = 10
-+ *   fastcgi.active-backends = 6
-+ *   fastcgi.backend.<key>.load = 24
-+ *   fastcgi.backend.<key>....
-+ *
-+ *   fastcgi.backend.<key>.disconnects = ...
-+ */
-+
-+static array *counters = NULL;
-+
-+void status_counter_init(void) {
-+      counters = array_init();
-+}
-+void status_counter_free(void) {
-+      array_free(counters);
-+}
-+
-+array *status_counter_get_array(void) {
-+      return counters;
-+}
-+
-+data_integer *status_counter_get_counter(const char *s, size_t len) {
-+      data_integer *di;
-+      array *status = status_counter_get_array();
-+
-+      if (NULL == (di = (data_integer *)array_get_element(status, s))) {
-+              /* not found, create it */
-+
-+              if (NULL == (di = (data_integer *)array_get_unused_element(status, TYPE_INTEGER))) {
-+                      di = data_integer_init();
-+              }
-+              buffer_copy_string_len(di->key, s, len);
-+              di->value = 0;
-+
-+              array_insert_unique(status, (data_unset *)di);
-+      }
-+      return di;
-+}
-+
-+/* dummies of the statistic framework functions
-+ * they will be moved to a statistics.c later */
-+int status_counter_inc(const char *s, size_t len) {
-+      data_integer *di = status_counter_get_counter(s, len);
-+
-+      di->value++;
-+
-+      return 0;
-+}
-+
-+int status_counter_dec(const char *s, size_t len) {
-+      data_integer *di = status_counter_get_counter(s, len);
-+
-+      if (di->value > 0) di->value--;
-+
-+      return 0;
-+}
-+
-+int status_counter_set(const char *s, size_t len, int val) {
-+      data_integer *di = status_counter_get_counter(s, len);
-+
-+      di->value = val;
-+
-+      return 0;
-+}
-+
-+
---- ../lighttpd-1.4.11/src/status_counter.h    1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/status_counter.h        2006-07-19 20:02:55.000000000 +0300
-@@ -0,0 +1,16 @@
-+#ifndef _STATUS_COUNTER_H_
-+#define _STATUS_COUNTER_H_
-+
-+#include <sys/types.h>
-+
-+#include "array.h"
-+
-+void status_counter_init(void);
-+void status_counter_free(void);
-+array *status_counter_get_array(void);
-+data_integer *status_counter_get_counter(const char *s, size_t len);
-+int status_counter_inc(const char *s, size_t len);
-+int status_counter_dec(const char *s, size_t len);
-+int status_counter_set(const char *s, size_t len, int val);
-+
-+#endif 
---- ../lighttpd-1.4.11/src/stream.c    2005-09-23 21:50:15.000000000 +0300
-+++ lighttpd-1.5.0/src/stream.c        2006-07-16 00:26:04.000000000 +0300
-@@ -1,7 +1,6 @@
- #include <sys/types.h>
- #include <sys/stat.h>
--#include <unistd.h> 
- #include <fcntl.h>
- #include "stream.h"
-@@ -10,6 +9,7 @@
- #endif
- #include "sys-mmap.h"
-+#include "sys-files.h"
- #ifndef O_BINARY
- # define O_BINARY 0
-@@ -19,39 +19,39 @@
-       struct stat st;
- #ifdef HAVE_MMAP
-       int fd;
--#elif defined __WIN32
-+#elif defined _WIN32
-       HANDLE *fh, *mh;
-       void *p;
- #endif
-       f->start = NULL;
--      
-+
-       if (-1 == stat(fn->ptr, &st)) {
-               return -1;
-       }
--      
-+
-       f->size = st.st_size;
- #ifdef HAVE_MMAP
-       if (-1 == (fd = open(fn->ptr, O_RDONLY | O_BINARY))) {
-               return -1;
-       }
--      
-+
-       f->start = mmap(0, f->size, PROT_READ, MAP_SHARED, fd, 0);
--      
-+
-       close(fd);
--      
-+
-       if (MAP_FAILED == f->start) {
-               return -1;
-       }
--#elif defined __WIN32
--      fh = CreateFile(fn->ptr, 
--                      GENERIC_READ, 
--                      FILE_SHARE_READ, 
--                      NULL, 
--                      OPEN_EXISTING, 
--                      FILE_ATTRIBUTE_READONLY, 
-+#elif defined _WIN32
-+      fh = CreateFile(fn->ptr,
-+                      GENERIC_READ,
-+                      FILE_SHARE_READ,
-+                      NULL,
-+                      OPEN_EXISTING,
-+                      FILE_ATTRIBUTE_READONLY,
-                       NULL);
-       if (!fh) return -1;
-@@ -66,7 +66,7 @@
-       if (!mh) {
-               LPVOID lpMsgBuf;
-               FormatMessage(
--                      FORMAT_MESSAGE_ALLOCATE_BUFFER | 
-+                      FORMAT_MESSAGE_ALLOCATE_BUFFER |
-                       FORMAT_MESSAGE_FROM_SYSTEM,
-                       NULL,
-                       GetLastError(),
-@@ -76,7 +76,7 @@
-               return -1;
-       }
--      
-+
-       p = MapViewOfFile(mh,
-                       FILE_MAP_READ,
-                       0,
-@@ -87,9 +87,9 @@
-       f->start = p;
- #else
--# error no mmap found 
-+# error no mmap found
- #endif
--      
-+
-       return 0;
- }
---- ../lighttpd-1.4.11/src/sys-files.h 1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/sys-files.h     2006-07-16 00:26:04.000000000 +0300
-@@ -0,0 +1,67 @@
-+#ifndef _SYS_FILES_H_
-+#define _SYS_FILES_H_
-+
-+#define DIR_SEPERATOR_UNIX '/'
-+#define DIR_SEPERATOR_WIN '\\'
-+
-+#ifdef _WIN32
-+#include <windows.h>
-+#include <io.h>     /* open */
-+#include <direct.h> /* chdir */
-+
-+#include "buffer.h"
-+
-+#define DIR_SEPERATOR DIR_SEPERATOR_WIN
-+
-+#define __S_ISTYPE(mode, mask)  (((mode) & _S_IFMT) == (mask))
-+
-+#define S_ISDIR(mode)    __S_ISTYPE((mode), _S_IFDIR)
-+#define S_ISCHR(mode)    __S_ISTYPE((mode), _S_IFCHR)
-+#define S_ISBLK(mode)    __S_ISTYPE((mode), _S_IFBLK)
-+#define S_ISREG(mode)    __S_ISTYPE((mode), _S_IFREG)
-+/* we don't support symlinks */
-+#define S_ISLNK(mode)    0
-+
-+#define lstat stat
-+#define mkstemp mktemp
-+#define mkdir(x, y) mkdir(x)
-+
-+struct dirent {
-+    const char *d_name;
-+};
-+
-+typedef struct {
-+    HANDLE h;
-+    WIN32_FIND_DATA finddata;
-+    struct dirent dent;
-+} DIR;
-+
-+DIR *opendir(const char *dn);
-+struct dirent *readdir(DIR *d);
-+void closedir(DIR *d);
-+
-+buffer *filename_unix2local(buffer *b);
-+buffer *pathname_unix2local(buffer *b);
-+
-+#else
-+#include <unistd.h>
-+#include <dirent.h>
-+
-+#define DIR_SEPERATOR DIR_SEPERATOR_UNIX
-+
-+#define filename_unix2local(x) (x)
-+#define pathname_unix2local(x) (x)
-+#endif
-+
-+#define PATHNAME_APPEND_SLASH(x) \
-+      if (x->used > 1 && x->ptr[x->used - 2] != DIR_SEPERATOR) { \
-+        char sl[2] = { DIR_SEPERATOR, 0 }; \
-+        BUFFER_APPEND_STRING_CONST(x, sl); \
-+    }
-+
-+#ifndef O_LARGEFILE
-+# define O_LARGEFILE 0
-+#endif
-+
-+#endif
-+
---- ../lighttpd-1.4.11/src/sys-mmap.h  2005-08-11 01:26:34.000000000 +0300
-+++ lighttpd-1.5.0/src/sys-mmap.h      2006-07-16 00:26:04.000000000 +0300
-@@ -1,7 +1,7 @@
- #ifndef WIN32_MMAP_H
- #define WIN32_MMAP_H
--#ifdef __WIN32
-+#ifdef _WIN32
- #define MAP_FAILED -1
- #define PROT_SHARED 0
---- ../lighttpd-1.4.11/src/sys-process.h       1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/sys-process.h   2006-07-16 00:26:04.000000000 +0300
-@@ -0,0 +1,17 @@
-+#ifndef _SYS_PROCESS_H_
-+#define _SYS_PROCESS_H_
-+
-+#ifdef _WIN32
-+#include <process.h>
-+#define pid_t int
-+/* win32 has no fork() */
-+#define kill(x, y)
-+#define getpid() 0
-+
-+#else
-+#include <sys/wait.h>
-+#include <unistd.h>
-+#endif
-+
-+#endif
-+
---- ../lighttpd-1.4.11/src/sys-socket.h        2005-08-11 01:26:39.000000000 +0300
-+++ lighttpd-1.5.0/src/sys-socket.h    2006-09-07 00:57:05.000000000 +0300
-@@ -1,16 +1,32 @@
- #ifndef WIN32_SOCKET_H
- #define WIN32_SOCKET_H
--#ifdef __WIN32
-+#ifdef HAVE_CONFIG_H
-+#include "config.h"
-+#endif
-+
-+#ifdef _WIN32
- #include <winsock2.h>
- #define ECONNRESET WSAECONNRESET
- #define EINPROGRESS WSAEINPROGRESS
- #define EALREADY WSAEALREADY
-+#define ENOTCONN WSAENOTCONN
-+#define EWOULDBLOCK WSAEWOULDBLOCK
- #define ioctl ioctlsocket
- #define hstrerror(x) ""
-+#define STDIN_FILENO 0
-+#define STDOUT_FILENO 1
-+#define STDERR_FILENO 2
-+#define ssize_t int
-+
-+int inet_aton(const char *cp, struct in_addr *inp);
-+#define HAVE_INET_ADDR
-+#undef HAVE_INET_ATON
-+
- #else
-+#include <sys/types.h> /* required by netinet/tcp.h on FreeBSD */
- #include <sys/socket.h>
- #include <sys/ioctl.h>
- #include <netinet/in.h>
-@@ -18,7 +34,32 @@
- #include <sys/un.h>
- #include <arpa/inet.h>
-+#ifndef SUN_LEN
-+#define SUN_LEN(su) \
-+        (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))
-+#endif
-+
-+#define closesocket(x) close(x)
-+
- #include <netdb.h>
-+#endif /* !_WIN32 */
-+
-+#ifdef HAVE_INET_NTOP
-+/* only define it if it isn't defined yet */
-+#ifndef HAVE_IPV6
-+#define HAVE_IPV6
-+#endif
-+#endif
-+
-+typedef union {
-+#ifdef HAVE_IPV6
-+      struct sockaddr_in6 ipv6;
-+#endif
-+      struct sockaddr_in ipv4;
-+#ifdef HAVE_SYS_UN_H
-+      struct sockaddr_un un;
- #endif
-+      struct sockaddr plain;
-+} sock_addr;
- #endif
---- ../lighttpd-1.4.11/src/sys-strings.h       1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/src/sys-strings.h   2006-07-16 00:26:03.000000000 +0300
-@@ -0,0 +1,11 @@
-+#ifndef _SYS_STRINGS_H_
-+#define _SYS_STRINGS_H_
-+
-+#ifdef _WIN32
-+#define strcasecmp stricmp
-+#define strncasecmp strnicmp
-+#define strtoll(p, e, b) _strtoi64(p, e, b)
-+#endif
-+
-+#endif
-+
---- ../lighttpd-1.4.11/tests/LightyTest.pm     2006-01-14 20:32:31.000000000 +0200
-+++ lighttpd-1.5.0/tests/LightyTest.pm 2006-09-07 00:57:05.000000000 +0300
-@@ -87,14 +87,16 @@
-       # pre-process configfile if necessary
-       #
--      unlink($self->{TESTDIR}."/tmp/cfg.file");
--      system("cat ".$self->{SRCDIR}."/".$self->{CONFIGFILE}.' | perl -pe "s#\@SRCDIR\@#'.$self->{BASEDIR}.'/tests/#" > '.$self->{TESTDIR}.'/tmp/cfg.file');
-+      $ENV{'SRCDIR'} = $self->{BASEDIR}.'/tests';
-+      $ENV{'PORT'} = $self->{PORT};
-       unlink($self->{LIGHTTPD_PIDFILE});
--      if (1) {
--              system($self->{LIGHTTPD_PATH}." -f ".$self->{TESTDIR}."/tmp/cfg.file -m ".$self->{MODULES_PATH});
-+      if (defined $ENV{"TRACEME"} && $ENV{"TRACEME"} eq 'strace') {
-+              system("strace -tt -s 512 -o strace ".$self->{LIGHTTPD_PATH}." -D -f ".$self->{SRCDIR}."/".$self->{CONFIGFILE}." -m ".$self->{MODULES_PATH}." &");
-+      } elsif (defined $ENV{"TRACEME"} && $ENV{"TRACEME"} eq 'valgrind') {
-+              system("valgrind --tool=memcheck --show-reachable=yes --leak-check=yes --log-file=valgrind ".$self->{LIGHTTPD_PATH}." -D -f ".$self->{SRCDIR}."/".$self->{CONFIGFILE}." -m ".$self->{MODULES_PATH}." &");
-       } else {
--              system("valgrind --tool=memcheck --show-reachable=yes --leak-check=yes --logfile=foo ".$self->{LIGHTTPD_PATH}." -D -f ".$self->{TESTDIR}."/tmp/cfg.file -m ".$self->{MODULES_PATH}." &");
-+              system($self->{LIGHTTPD_PATH}." -f ".$self->{SRCDIR}."/".$self->{CONFIGFILE}." -m ".$self->{MODULES_PATH});
-       }
-       select(undef, undef, undef, 0.1);
-@@ -184,7 +186,7 @@
-                                       (my $h = $1) =~ tr/[A-Z]/[a-z]/;
-                                       if (defined $resp_hdr{$h}) {
--                                              diag(sprintf("header %s is duplicated: %s and %s\n",
-+                                              diag(sprintf("header '%s' is duplicated: '%s' and '%s'\n",
-                                                            $h, $resp_hdr{$h}, $2));
-                                       } else {
-                                               $resp_hdr{$h} = $2;
-@@ -196,6 +198,9 @@
-                       }
-               }
-+              $t->{etag} = $resp_hdr{'etag'};
-+              $t->{date} = $resp_hdr{'date'};
-+
-               # check length
-               if (defined $resp_hdr{"content-length"}) {
-                       $resp_body = substr($lines, 0, $resp_hdr{"content-length"});
---- ../lighttpd-1.4.11/tests/Makefile.am       2005-09-16 15:48:40.000000000 +0300
-+++ lighttpd-1.5.0/tests/Makefile.am   2006-07-16 00:26:05.000000000 +0300
-@@ -39,10 +39,18 @@
-       mod-redirect.t \
-       mod-userdir.t \
-       mod-rewrite.t \
-+      mod-proxy.t \
-       request.t \
-       mod-ssi.t \
-       LightyTest.pm \
--      mod-setenv.t 
-+      mod-setenv.t \
-+      lowercase.t \
-+      lowercase.conf \
-+      proxy.conf \
-+      cachable.t \
-+      default.conf \
-+      proxy-backend-1.conf \
-+      proxy-backend-2.conf 
- TESTS_ENVIRONMENT=$(srcdir)/wrapper.sh $(srcdir) $(top_builddir) 
---- ../lighttpd-1.4.11/tests/bug-06.conf       2005-08-27 17:44:19.000000000 +0300
-+++ lighttpd-1.5.0/tests/bug-06.conf   2006-07-16 00:26:04.000000000 +0300
-@@ -1,5 +1,5 @@
--server.document-root         = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
--server.pid-file              = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
-+server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
-+server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
- ## bind to port (default: 80)
- server.port                 = 2048
-@@ -8,7 +8,7 @@
- ## bind to localhost (default: all interfaces)
- server.bind                = "localhost"
--server.errorlog            = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log"
-+server.errorlog            = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
- server.name                = "www.example.org"
- server.tag                 = "Apache 1.3.29"
-@@ -59,7 +59,7 @@
- ######################## MODULE CONFIG ############################
--accesslog.filename          = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log"
-+accesslog.filename          = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log"
- mimetype.assign             = ( ".png"  => "image/png", 
-                                 ".jpg"  => "image/jpeg",
-@@ -77,7 +77,7 @@
-                               ".c"    => "text/plain",
-                               ".conf" => "text/plain" )
--compress.cache-dir          = "@SRCDIR@/tmp/lighttpd/cache/compress/"
-+compress.cache-dir          = env.SRCDIR + "/tmp/lighttpd/cache/compress/"
- compress.filetype           = ("text/plain", "text/html")
- setenv.add-environment      = ( "TRAC_ENV" => "foo")
-@@ -90,7 +90,7 @@
-                                   "host" => "127.0.0.1",
-                                   "port" => 1026,
- #                                 "mode" => "authorizer",
--#                                 "docroot" => "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/",
-+#                                 "docroot" => env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/",
-                                 )
-                               )
-                             )
-@@ -106,7 +106,7 @@
- ssl.pemfile                 = "server.pem"
- auth.backend                = "plain"
--auth.backend.plain.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.user"
-+auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user"
- auth.backend.plain.groupfile = "lighttpd.group"
- auth.backend.ldap.hostname  = "localhost"
-@@ -149,15 +149,15 @@
- status.config-url           = "/server-config"
- simple-vhost.document-root  = "pages"
--simple-vhost.server-root    = "@SRCDIR@/tmp/lighttpd/servers/"
-+simple-vhost.server-root    = env.SRCDIR + "/tmp/lighttpd/servers/"
- simple-vhost.default-host   = "www.example.org"
- $HTTP["host"] == "vvv.example.org" {
--  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
-+  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
- }
- $HTTP["host"] == "zzz.example.org" {
--  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
-+  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
-   server.name = "zzz.example.org"
- }
---- ../lighttpd-1.4.11/tests/bug-12.conf       2005-08-27 17:44:19.000000000 +0300
-+++ lighttpd-1.5.0/tests/bug-12.conf   2006-07-16 00:26:04.000000000 +0300
-@@ -1,5 +1,5 @@
--server.document-root         = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
--server.pid-file              = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
-+server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
-+server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
- ## bind to port (default: 80)
- server.port                 = 2048
-@@ -8,7 +8,7 @@
- ## bind to localhost (default: all interfaces)
- server.bind                = "localhost"
--server.errorlog            = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log"
-+server.errorlog            = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
- server.name                = "www.example.org"
- server.tag                 = "Apache 1.3.29"
-@@ -61,7 +61,7 @@
- ######################## MODULE CONFIG ############################
--accesslog.filename          = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log"
-+accesslog.filename          = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log"
- mimetype.assign             = ( ".png"  => "image/png", 
-                                 ".jpg"  => "image/jpeg",
-@@ -79,7 +79,7 @@
-                               ".c"    => "text/plain",
-                               ".conf" => "text/plain" )
--compress.cache-dir          = "@SRCDIR@/tmp/lighttpd/cache/compress/"
-+compress.cache-dir          = env.SRCDIR + "/tmp/lighttpd/cache/compress/"
- compress.filetype           = ("text/plain", "text/html")
- setenv.add-environment      = ( "TRAC_ENV" => "foo")
-@@ -92,7 +92,7 @@
-                                   "host" => "127.0.0.1",
-                                   "port" => 1026,
- #                                 "mode" => "authorizer",
--#                                 "docroot" => "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/",
-+#                                 "docroot" => env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/",
-                                 )
-                               )
-                             )
-@@ -108,7 +108,7 @@
- ssl.pemfile                 = "server.pem"
- auth.backend                = "plain"
--auth.backend.plain.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.user"
-+auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user"
- auth.backend.plain.groupfile = "lighttpd.group"
- auth.backend.ldap.hostname  = "localhost"
-@@ -151,15 +151,15 @@
- status.config-url           = "/server-config"
- simple-vhost.document-root  = "pages"
--simple-vhost.server-root    = "@SRCDIR@/tmp/lighttpd/servers/"
-+simple-vhost.server-root    = env.SRCDIR + "/tmp/lighttpd/servers/"
- simple-vhost.default-host   = "www.example.org"
- $HTTP["host"] == "vvv.example.org" {
--  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
-+  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
- }
- $HTTP["host"] == "zzz.example.org" {
--  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
-+  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
-   server.name = "zzz.example.org"
- }
---- ../lighttpd-1.4.11/tests/cachable.t        1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/tests/cachable.t    2006-07-18 13:03:40.000000000 +0300
-@@ -0,0 +1,112 @@
-+#!/usr/bin/env perl
-+BEGIN {
-+    # add current source dir to the include-path
-+    # we need this for make distcheck
-+   (my $srcdir = $0) =~ s#/[^/]+$#/#;
-+   unshift @INC, $srcdir;
-+}
-+
-+use strict;
-+use IO::Socket;
-+use Test::More tests => 12;
-+use LightyTest;
-+
-+my $tf = LightyTest->new();
-+my $t;
-+
-+$tf->{CONFIGFILE} = 'lighttpd.conf';
-+    
-+ok($tf->start_proc == 0, "Starting lighttpd") or die();
-+
-+## check if If-Modified-Since, If-None-Match works
-+
-+$t->{REQUEST}  = ( <<EOF
-+GET / HTTP/1.0
-+If-Modified-Since: Sun, 01 Jan 1970 00:00:01 GMT
-+EOF
-+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
-+ok($tf->handle_http($t) == 0, 'Conditional GET - old If-Modified-Since');
-+
-+$t->{REQUEST}  = ( <<EOF
-+GET / HTTP/1.0
-+If-Modified-Since: Sun, 01 Jan 1970 00:00:01 GMT; foo
-+EOF
-+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, '+Last-Modified' => ''} ];
-+ok($tf->handle_http($t) == 0, 'Conditional GET - old If-Modified-Since, comment');
-+
-+my $now = $t->{date};
-+
-+$t->{REQUEST}  = ( <<EOF
-+GET / HTTP/1.0
-+If-Modified-Since: $now
-+EOF
-+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 304 } ];
-+ok($tf->handle_http($t) == 0, 'Conditional GET - new If-Modified-Since');
-+
-+$t->{REQUEST}  = ( <<EOF
-+GET / HTTP/1.0
-+If-Modified-Since: $now; foo
-+EOF
-+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 304 } ];
-+ok($tf->handle_http($t) == 0, 'Conditional GET - new If-Modified-Since, comment');
-+
-+$t->{REQUEST}  = ( <<EOF
-+GET / HTTP/1.0
-+If-None-Match: foo
-+EOF
-+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, '+ETag' => ''} ];
-+ok($tf->handle_http($t) == 0, 'Conditional GET - old If-None-Match');
-+
-+my $etag = $t->{etag};
-+
-+$t->{REQUEST}  = ( <<EOF
-+GET / HTTP/1.0
-+If-None-Match: $etag
-+EOF
-+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 304 } ];
-+ok($tf->handle_http($t) == 0, 'Conditional GET - old If-None-Match');
-+
-+$t->{REQUEST}  = ( <<EOF
-+GET / HTTP/1.0
-+If-None-Match: $etag
-+If-Modified-Since: Sun, 01 Jan 1970 00:00:01 GMT; foo
-+EOF
-+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
-+ok($tf->handle_http($t) == 0, 'Conditional GET - ETag + old Last-Modified');
-+
-+$t->{REQUEST}  = ( <<EOF
-+GET / HTTP/1.0
-+If-None-Match: $etag
-+If-Modified-Since: $now; foo
-+EOF
-+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 304 } ];
-+ok($tf->handle_http($t) == 0, 'Conditional GET - ETag, Last-Modified + comment');
-+
-+$t->{REQUEST}  = ( <<EOF
-+GET / HTTP/1.0
-+If-None-Match: Foo
-+If-Modified-Since: Sun, 01 Jan 1970 00:00:01 GMT; foo
-+EOF
-+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
-+ok($tf->handle_http($t) == 0, 'Conditional GET - old ETAG + old Last-Modified');
-+
-+$t->{REQUEST}  = ( <<EOF
-+GET / HTTP/1.0
-+If-None-Match: $etag
-+If-Modified-Since: $now foo
-+EOF
-+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 412 } ];
-+ok($tf->handle_http($t) == 0, 'Conditional GET - ETag + Last-Modified + overlong timestamp');
-+
-+ok($tf->stop_proc == 0, "Stopping lighttpd");
-+
---- ../lighttpd-1.4.11/tests/condition.conf    2005-08-27 17:44:19.000000000 +0300
-+++ lighttpd-1.5.0/tests/condition.conf        2006-07-16 00:26:05.000000000 +0300
-@@ -2,15 +2,15 @@
- debug.log-request-handling = "enable"
- debug.log-condition-handling = "enable"
--server.document-root         = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
--server.pid-file              = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
-+server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
-+server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
- ## bind to port (default: 80)
- server.port                 = 2048
- ## bind to localhost (default: all interfaces)
- server.bind                = "localhost"
--server.errorlog            = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log"
-+server.errorlog            = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
- server.name                = "www.example.org"
- server.tag                 = "Apache 1.3.29"
-@@ -22,25 +22,25 @@
- ######################## MODULE CONFIG ############################
--accesslog.filename          = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log"
-+accesslog.filename          = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log"
- mimetype.assign             = ( ".html" => "text/html" )
- url.redirect = ("^" => "/default")
- $HTTP["host"] == "www.example.org" {
--  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
-+  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
-   server.name = "www.example.org"
-   url.redirect = ("^" => "/match_1")
- }
- else $HTTP["host"] == "test1.example.org" {
--  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
-+  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
-   server.name = "test1.example.org"
-   url.redirect = ("^" => "/match_2")
- }
- # comments
- else $HTTP["host"] == "test2.example.org" {
--  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
-+  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
-   server.name = "test2.example.org"
-   url.redirect = ("^" => "/match_3")
- }
-@@ -48,7 +48,7 @@
-        # comments
- else $HTTP["host"] == "test3.example.org" {
--  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
-+  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
-   server.name = "test3.example.org"
-   url.redirect = ("^" => "/match_4")
---- ../lighttpd-1.4.11/tests/core-keepalive.t  2005-11-17 15:54:19.000000000 +0200
-+++ lighttpd-1.5.0/tests/core-keepalive.t      2006-07-16 00:26:05.000000000 +0300
-@@ -40,7 +40,7 @@
- GET /12345.txt HTTP/1.0
- Host: 123.example.org
--Connection: keep-alive
-+Connection: close
- EOF
-  );
- $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } , { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
---- ../lighttpd-1.4.11/tests/core.t    2006-03-04 19:08:22.000000000 +0200
-+++ lighttpd-1.5.0/tests/core.t        2006-09-07 00:57:05.000000000 +0300
-@@ -44,21 +44,21 @@
- GET / HTTP/.01
- EOF
-  );
--$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 505 } ];
- ok($tf->handle_http($t) == 0, 'missing major version');
- $t->{REQUEST}  = ( <<EOF
- GET / HTTP/01.
- EOF
-  );
--$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 505 } ];
- ok($tf->handle_http($t) == 0, 'missing minor version');
- $t->{REQUEST}  = ( <<EOF
- GET / HTTP/a.b
- EOF
-  );
--$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 505 } ];
- ok($tf->handle_http($t) == 0, 'strings as version');
- $t->{REQUEST}  = ( <<EOF
---- ../lighttpd-1.4.11/tests/default.conf      1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/tests/default.conf  2006-07-16 00:26:05.000000000 +0300
-@@ -0,0 +1,111 @@
-+server.name                = "www.example.org"
-+
-+## bind to port (default: 80)
-+server.port                 = env.PORT
-+
-+
-+server.dir-listing          = "enable"
-+
-+#server.event-handler        = "linux-sysepoll"
-+#server.event-handler        = "linux-rtsig"
-+
-+server.modules              = ( 
-+                              "mod_rewrite",
-+                              "mod_setenv",
-+                              "mod_access", 
-+                              "mod_auth",
-+                              "mod_status", 
-+                              "mod_expire",
-+                              "mod_simple_vhost",
-+                              "mod_redirect", 
-+                              "mod_secdownload",
-+                              "mod_ssi",
-+                              "mod_fastcgi",
-+                              "mod_proxy",
-+                              "mod_cgi",
-+                              "mod_compress",
-+                              "mod_userdir",
-+                              "mod_accesslog" ) 
-+
-+server.indexfiles           = ( "index.php", "index.html", 
-+                                "index.htm", "default.htm" )
-+
-+ssi.extension = ( ".shtml" )
-+
-+######################## MODULE CONFIG ############################
-+
-+
-+accesslog.filename          = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log"
-+server.errorlog             = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
-+
-+mimetype.assign             = ( ".png"  => "image/png", 
-+                                ".jpg"  => "image/jpeg",
-+                                ".jpeg" => "image/jpeg",
-+                                ".gif"  => "image/gif",
-+                                ".html" => "text/html",
-+                                ".htm"  => "text/html",
-+                                ".pdf"  => "application/pdf",
-+                                ".swf"  => "application/x-shockwave-flash",
-+                                ".spl"  => "application/futuresplash",
-+                                ".txt"  => "text/plain",
-+                                ".tar.gz" =>   "application/x-tgz",
-+                                ".tgz"  => "application/x-tgz",
-+                                ".gz"   => "application/x-gzip",
-+                              ".c"    => "text/plain",
-+                              ".conf" => "text/plain" )
-+
-+compress.cache-dir          = env.SRCDIR + "/tmp/lighttpd/cache/compress/"
-+compress.filetype           = ("text/plain", "text/html")
-+
-+setenv.add-environment      = ( "TRAC_ENV" => "tracenv", "SETENV" => "setenv")
-+
-+cgi.assign                  = ( ".pl"  => "/usr/bin/perl",
-+                                ".cgi" => "/usr/bin/perl",
-+                              ".py"  => "/usr/bin/python" )
-+                      
-+userdir.include-user = ( "jan" )
-+userdir.path = "/"
-+
-+ssl.engine                  = "disable"
-+ssl.pemfile                 = "server.pem"
-+
-+auth.backend                = "plain"
-+auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user"
-+auth.backend.htpasswd.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.htpasswd"
-+auth.backend.plain.groupfile = "lighttpd.group"
-+
-+auth.backend.ldap.hostname  = "localhost"
-+auth.backend.ldap.base-dn   = "dc=my-domain,dc=com"
-+auth.backend.ldap.filter    = "(uid=$)"
-+
-+auth.require                = ( "/server-status" => 
-+                                ( 
-+                                "method"  => "digest",
-+                                "realm"   => "download archiv",
-+                                "require" => "valid-user"
-+                              ),
-+                              "/auth.php" => 
-+                                ( 
-+                                "method"  => "basic",
-+                                "realm"   => "download archiv",
-+                                "require" => "user=jan"
-+                              ),
-+                              "/server-config" => 
-+                                ( 
-+                                "method"  => "basic",
-+                                "realm"   => "download archiv",
-+                                "require" => "valid-user"
-+                              )
-+                              )
-+
-+url.access-deny             = ( "~", ".inc")
-+
-+url.redirect                = ( "^/redirect/$" => "http://localhost:2048/" )
-+
-+url.rewrite               = ( "^/rewrite/foo($|\?.+)" => "/indexfile/rewrite.php$1",
-+                              "^/rewrite/bar(?:$|\?(.+))" => "/indexfile/rewrite.php?bar&$1" )
-+
-+#### status module
-+status.status-url           = "/server-status"
-+status.config-url           = "/server-config"
-+
---- ../lighttpd-1.4.11/tests/docroot/www/dummydir/.svn/entries 2006-03-09 19:21:49.000000000 +0200
-+++ lighttpd-1.5.0/tests/docroot/www/dummydir/.svn/entries     2006-09-07 00:57:05.000000000 +0300
-@@ -9,5 +9,6 @@
-    last-author="jan"
-    kind="dir"
-    uuid="152afb58-edef-0310-8abb-c4023f1b3aa9"
--   revision="1040"/>
-+   repos="svn://svn.lighttpd.net/lighttpd"
-+   revision="1277"/>
- </wc-entries>
---- ../lighttpd-1.4.11/tests/fastcgi-10.conf   2005-08-31 23:36:34.000000000 +0300
-+++ lighttpd-1.5.0/tests/fastcgi-10.conf       2006-07-16 00:26:04.000000000 +0300
-@@ -1,12 +1,12 @@
--server.document-root         = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
--server.pid-file              = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
-+server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
-+server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
- ## bind to port (default: 80)
- server.port                 = 2048
- ## bind to localhost (default: all interfaces)
- server.bind                = "localhost"
--server.errorlog            = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log"
-+server.errorlog            = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
- server.name                = "www.example.org"
- server.tag                 = "Apache 1.3.29"
-@@ -44,7 +44,7 @@
- ######################## MODULE CONFIG ############################
--accesslog.filename          = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log"
-+accesslog.filename          = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log"
- mimetype.assign             = ( ".png"  => "image/png", 
-                                 ".jpg"  => "image/jpeg",
-@@ -62,7 +62,7 @@
-                               ".c"    => "text/plain",
-                               ".conf" => "text/plain" )
--compress.cache-dir          = "@SRCDIR@/tmp/lighttpd/cache/compress/"
-+compress.cache-dir          = env.SRCDIR + "/tmp/lighttpd/cache/compress/"
- compress.filetype           = ("text/plain", "text/html")
- fastcgi.debug               = 0
-@@ -85,7 +85,7 @@
- ssl.pemfile                 = "server.pem"
- auth.backend                = "plain"
--auth.backend.plain.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.user"
-+auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user"
- auth.backend.plain.groupfile = "lighttpd.group"
- auth.backend.ldap.hostname  = "localhost"
-@@ -128,11 +128,11 @@
- status.config-url           = "/server-config"
- $HTTP["host"] == "vvv.example.org" {
--  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
-+  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
- }
- $HTTP["host"] == "zzz.example.org" {
--  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
-+  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
-   server.name = "zzz.example.org"
- }
---- ../lighttpd-1.4.11/tests/fastcgi-13.conf   2006-01-03 12:38:17.000000000 +0200
-+++ lighttpd-1.5.0/tests/fastcgi-13.conf       2006-07-18 13:03:40.000000000 +0300
-@@ -1,5 +1,5 @@
--server.document-root         = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
--server.pid-file              = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
-+server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
-+server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
- debug.log-request-header   = "enable"
- debug.log-response-header  = "enable"
-@@ -10,7 +10,7 @@
- ## bind to localhost (default: all interfaces)
- server.bind                = "localhost"
--server.errorlog            = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log"
-+server.errorlog            = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
- server.name                = "www.example.org"
- server.tag                 = "Apache 1.3.29"
-@@ -59,7 +59,7 @@
- ######################## MODULE CONFIG ############################
--accesslog.filename          = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log"
-+accesslog.filename          = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log"
- mimetype.assign             = ( ".png"  => "image/png", 
-                                 ".jpg"  => "image/jpeg",
-@@ -77,7 +77,7 @@
-                               ".c"    => "text/plain",
-                               ".conf" => "text/plain" )
--compress.cache-dir          = "@SRCDIR@/tmp/lighttpd/cache/compress/"
-+compress.cache-dir          = env.SRCDIR + "/tmp/lighttpd/cache/compress/"
- compress.filetype           = ("text/plain", "text/html")
- fastcgi.debug               = 0
-@@ -85,7 +85,7 @@
-                                   "grisu" => ( 
-                                   "host" => "127.0.0.1",
-                                   "port" => 1048,
--                                  "bin-path" => "/home/jan/Documents/php-5.1.0/sapi/cgi/php -c /usr/local/lib/php.ini",
-+                                  "bin-path" => "/home/jan/Documents/php-5.1.4/sapi/cgi/php -c /usr/local/lib/php.ini",
-                                   "bin-copy-environment" => ( "PATH", "SHELL", "USER" ),
-                                 )
-                               )
-@@ -102,7 +102,7 @@
- ssl.pemfile                 = "server.pem"
- auth.backend                = "plain"
--auth.backend.plain.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.user"
-+auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user"
- auth.backend.plain.groupfile = "lighttpd.group"
- auth.backend.ldap.hostname  = "localhost"
-@@ -145,11 +145,11 @@
- status.config-url           = "/server-config"
- $HTTP["host"] == "vvv.example.org" {
--  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
-+  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
- }
- $HTTP["host"] == "zzz.example.org" {
--  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
-+  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
-   server.name = "zzz.example.org"
- }
---- ../lighttpd-1.4.11/tests/fastcgi-auth.conf 2005-08-27 17:44:19.000000000 +0300
-+++ lighttpd-1.5.0/tests/fastcgi-auth.conf     2006-07-16 00:26:05.000000000 +0300
-@@ -1,5 +1,5 @@
--server.document-root         = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
--server.pid-file              = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
-+server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
-+server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
- debug.log-request-header   = "enable"
- debug.log-response-header  = "enable"
-@@ -12,7 +12,7 @@
- ## bind to localhost (default: all interfaces)
- server.bind                = "localhost"
--server.errorlog            = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log"
-+server.errorlog            = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
- server.name                = "www.example.org"
- server.tag                 = "Apache 1.3.29"
-@@ -61,7 +61,7 @@
- ######################## MODULE CONFIG ############################
--accesslog.filename          = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log"
-+accesslog.filename          = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log"
- mimetype.assign             = ( ".png"  => "image/png", 
-                                 ".jpg"  => "image/jpeg",
-@@ -79,7 +79,7 @@
-                               ".c"    => "text/plain",
-                               ".conf" => "text/plain" )
--compress.cache-dir          = "@SRCDIR@/tmp/lighttpd/cache/compress/"
-+compress.cache-dir          = env.SRCDIR + "/tmp/lighttpd/cache/compress/"
- compress.filetype           = ("text/plain", "text/html")
- fastcgi.debug               = 0
-@@ -87,9 +87,9 @@
-                                   "grisu" => ( 
-                                   "host" => "127.0.0.1",
-                                   "port" => 20000,
--                                  "bin-path" => "@SRCDIR@/fcgi-auth",
-+                                  "bin-path" => env.SRCDIR + "/fcgi-auth",
-                                     "mode" => "authorizer",
--                                    "docroot" => "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/",
-+                                    "docroot" => env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/",
-                                   
-                                 )
-                               )
-@@ -106,7 +106,7 @@
- ssl.pemfile                 = "server.pem"
- auth.backend                = "plain"
--auth.backend.plain.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.user"
-+auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user"
- auth.backend.plain.groupfile = "lighttpd.group"
- auth.backend.ldap.hostname  = "localhost"
-@@ -149,11 +149,11 @@
- status.config-url           = "/server-config"
- $HTTP["host"] == "vvv.example.org" {
--  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
-+  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
- }
- $HTTP["host"] == "zzz.example.org" {
--  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
-+  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
-   server.name = "zzz.example.org"
- }
---- ../lighttpd-1.4.11/tests/fastcgi-responder.conf    2005-08-27 17:44:19.000000000 +0300
-+++ lighttpd-1.5.0/tests/fastcgi-responder.conf        2006-07-16 00:26:05.000000000 +0300
-@@ -1,5 +1,5 @@
--server.document-root         = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
--server.pid-file              = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
-+server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
-+server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
- #debug.log-request-header   = "enable"
- #debug.log-response-header  = "enable"
-@@ -15,7 +15,7 @@
- ## bind to localhost (default: all interfaces)
- server.bind                = "localhost"
--server.errorlog            = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log"
-+server.errorlog            = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
- server.name                = "www.example.org"
- server.tag                 = "Apache 1.3.29"
-@@ -64,7 +64,7 @@
- ######################## MODULE CONFIG ############################
--accesslog.filename          = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log"
-+accesslog.filename          = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log"
- mimetype.assign             = ( ".png"  => "image/png", 
-                                 ".jpg"  => "image/jpeg",
-@@ -82,7 +82,7 @@
-                               ".c"    => "text/plain",
-                               ".conf" => "text/plain" )
--compress.cache-dir          = "@SRCDIR@/tmp/lighttpd/cache/compress/"
-+compress.cache-dir          = env.SRCDIR + "/tmp/lighttpd/cache/compress/"
- compress.filetype           = ("text/plain", "text/html")
- fastcgi.debug               = 0
-@@ -90,10 +90,11 @@
-                                   "grisu" => ( 
-                                   "host" => "127.0.0.1",
-                                   "port" => 10000,
--                                  "bin-path" => "@SRCDIR@/fcgi-responder",
-+                                  "bin-path" => env.SRCDIR + "/fcgi-responder",
-                                   "check-local" => "disable",
-                                   "max-procs" => 1,
--                                  "min-procs" => 1
-+                                  "min-procs" => 1,
-+                                  "allow-x-send-file" => "enable",
-                                 )
-                               )
-                             )
-@@ -109,7 +110,7 @@
- ssl.pemfile                 = "server.pem"
- auth.backend                = "plain"
--auth.backend.plain.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.user"
-+auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user"
- auth.backend.plain.groupfile = "lighttpd.group"
- auth.backend.ldap.hostname  = "localhost"
-@@ -152,11 +153,11 @@
- status.config-url           = "/server-config"
- $HTTP["host"] == "vvv.example.org" {
--  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
-+  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
- }
- $HTTP["host"] == "zzz.example.org" {
--  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
-+  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
-   server.name = "zzz.example.org"
- }
---- ../lighttpd-1.4.11/tests/fcgi-responder.c  2005-08-11 01:26:55.000000000 +0300
-+++ lighttpd-1.5.0/tests/fcgi-responder.c      2006-07-16 00:26:05.000000000 +0300
-@@ -6,11 +6,17 @@
- int main () {
-       int num_requests = 2;
-       
--      while (num_requests > 0 &&
--             FCGI_Accept() >= 0) {
--              char* p;
--              
--              if (NULL != (p = getenv("QUERY_STRING"))) {
-+      while (num_requests > 0 && FCGI_Accept() >= 0) {
-+              char* p = NULL;
-+              char* doc_root = NULL;
-+              char fname[4096];
-+              char* pfname = (char *)fname;
-+
-+              doc_root = getenv("DOCUMENT_ROOT");
-+              p = getenv("QUERY_STRING");
-+
-+              if (NULL != p && NULL != doc_root) {
-+                      snprintf(pfname, sizeof(fname), "%s/phpinfo.php", doc_root);
-                       if (0 == strcmp(p, "lf")) {
-                               printf("Status: 200 OK\n\n");
-                       } else if (0 == strcmp(p, "crlf")) {
-@@ -23,6 +29,18 @@
-                               printf("Status: 200 OK\r\n");
-                               fflush(stdout);
-                               printf("\r\n");
-+                      } else if (0 == strcmp(p,"x-lighttpd-send-file")) {
-+                              printf("Status: 200 OK\r\n");
-+                              printf("X-LIGHTTPD-send-file: %s\r\n", pfname);
-+                              printf("\r\n");
-+                      } else if (0 == strcmp(p,"xsendfile")) {
-+                              printf("Status: 200 OK\r\n");
-+                              printf("X-Sendfile: %s\r\n", pfname);
-+                              printf("\r\n");
-+                      } else if (0 == strcmp(p,"xsendfile-mixed-case")) {
-+                              printf("Status: 200 OK\r\n");
-+                              printf("X-SeNdFiLe: %s\r\n", pfname);
-+                              printf("\r\n");
-                       } else if (0 == strcmp(p, "die-at-end")) {
-                               printf("Status: 200 OK\r\n\r\n");
-                               num_requests--;
---- ../lighttpd-1.4.11/tests/lighttpd.conf     2006-03-09 15:26:58.000000000 +0200
-+++ lighttpd-1.5.0/tests/lighttpd.conf 2006-09-07 00:57:05.000000000 +0300
-@@ -1,80 +1,20 @@
--debug.log-request-handling = "enable"
--debug.log-condition-handling = "enable"
--server.document-root         = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
--server.pid-file              = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
-+server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
-+server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
-+server.tag = "Apache 1.3.29"
-+debug.log-request-handling = "enable"
-+debug.log-response-header = "enable"
- ## 64 Mbyte ... nice limit
- server.max-request-size = 65000
--## bind to port (default: 80)
--server.port                 = 2048
-+include "default.conf"
--## bind to localhost (default: all interfaces)
--server.bind                = "localhost"
--server.errorlog            = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log"
--server.name                = "www.example.org"
--server.tag                 = "Apache 1.3.29"
--
--server.dir-listing          = "enable"
--
--#server.event-handler        = "linux-sysepoll"
--#server.event-handler        = "linux-rtsig"
--
--#server.modules.path         = ""
--server.modules              = ( 
--                              "mod_rewrite",
--                              "mod_setenv",
--                              "mod_secdownload",
--                              "mod_access", 
--                              "mod_auth",
--#                             "mod_httptls",
--                              "mod_status", 
--                              "mod_expire",
--                              "mod_simple_vhost",
--                              "mod_redirect", 
--#                             "mod_evhost",
--#                             "mod_localizer",
--                              "mod_fastcgi",
--                              "mod_cgi",
--                              "mod_compress",
--                              "mod_userdir",
--                              "mod_ssi",
--                              "mod_accesslog" ) 
--
--server.indexfiles           = ( "index.php", "index.html", 
--                                "index.htm", "default.htm" )
--
--
--######################## MODULE CONFIG ############################
--
--ssi.extension = ( ".shtml" )
--
--accesslog.filename          = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log"
--
--mimetype.assign             = ( ".png"  => "image/png", 
--                                ".jpg"  => "image/jpeg",
--                                ".jpeg" => "image/jpeg",
--                                ".gif"  => "image/gif",
--                                ".html" => "text/html",
--                                ".htm"  => "text/html",
--                                ".pdf"  => "application/pdf",
--                                ".swf"  => "application/x-shockwave-flash",
--                                ".spl"  => "application/futuresplash",
--                                ".txt"  => "text/plain",
--                                ".tar.gz" =>   "application/x-tgz",
--                                ".tgz"  => "application/x-tgz",
--                                ".gz"   => "application/x-gzip",
--                              ".c"    => "text/plain",
--                              ".conf" => "text/plain" )
-+setenv.add-request-header   = ( "FOO" => "foo")
-+setenv.add-response-header  = ( "BAR" => "foo")
- $HTTP["host"] == "cache.example.org" {
--  compress.cache-dir          = "@SRCDIR@/tmp/lighttpd/cache/compress/"
-+  compress.cache-dir          = env.SRCDIR + "/tmp/lighttpd/cache/compress/"
- }
--compress.filetype           = ("text/plain", "text/html")
--
--setenv.add-environment      = ( "TRAC_ENV" => "tracenv", "SETENV" => "setenv")
--setenv.add-request-header   = ( "FOO" => "foo")
--setenv.add-response-header  = ( "BAR" => "foo")
- $HTTP["url"] =~ "\.pdf$" {
-   server.range-requests = "disable"
-@@ -85,76 +25,43 @@
-                               "/prefix.fcgi" => ( ( "host" => "127.0.0.1", "port" => 1026, "check-local" => "disable", "broken-scriptfilename" => "enable" ) )
-                             )
-               
--
--cgi.assign                  = ( ".pl"  => "/usr/bin/perl",
--                                ".cgi" => "/usr/bin/perl",
--                              ".py"  => "/usr/bin/python" )
--                      
--userdir.include-user = ( "jan" )
--userdir.path = "/"
--
--ssl.engine                  = "disable"
--ssl.pemfile                 = "server.pem"
--
- $HTTP["host"] == "auth-htpasswd.example.org" {
-       auth.backend                = "htpasswd"
- }
--auth.backend                = "plain"
--auth.backend.plain.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.user"
--
--auth.backend.htpasswd.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.htpasswd"
--
--
--auth.require                = ( "/server-status" => 
--                                ( 
--                                "method"  => "digest",
--                                "realm"   => "download archiv",
--                                "require" => "group=www|user=jan|host=192.168.2.10"
--                              ),
--                              "/server-config" => 
--                                ( 
--                                "method"  => "basic",
--                                "realm"   => "download archiv",
--                                "require" => "valid-user"
--                              )
--                              )
--
--url.access-deny             = ( "~", ".inc")
--
--url.rewrite               = ( "^/rewrite/foo($|\?.+)" => "/indexfile/rewrite.php$1",
--                              "^/rewrite/bar(?:$|\?(.+))" => "/indexfile/rewrite.php?bar&$1" )
--
--expire.url                  = ( "/expire/access" => "access 2 hours", 
--                              "/expire/modification" => "access plus 1 seconds 2 minutes")
--
--#cache.cache-dir             = "/home/weigon/wwwroot/cache/"
--
--#### status module
--status.status-url           = "/server-status"
--status.config-url           = "/server-config"
--
- $HTTP["host"] == "vvv.example.org" {
--  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
-+  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
-   secdownload.secret          = "verysecret"
--  secdownload.document-root   = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
-+  secdownload.document-root   = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
-   secdownload.uri-prefix      = "/sec/"
-   secdownload.timeout         = 120
- }
- $HTTP["host"] == "zzz.example.org" {
--  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
-+  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
-   server.name = "zzz.example.org"
- }
-+$HTTP["host"] == "symlink.example.org" {
-+  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
-+  server.name = "symlink.example.org"
-+  server.follow-symlink = "enable"
-+}
-+
-+$HTTP["host"] == "nosymlink.example.org" {
-+  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
-+  server.name = "symlink.example.org"
-+  server.follow-symlink = "disable"
-+}
-+
- $HTTP["host"] == "no-simple.example.org" {
--  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/123.example.org/pages/"
-+  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/123.example.org/pages/"
-   server.name = "zzz.example.org"
- }
- $HTTP["host"] !~ "(no-simple\.example\.org)" {
-   simple-vhost.document-root  = "pages"
--  simple-vhost.server-root    = "@SRCDIR@/tmp/lighttpd/servers/"
-+  simple-vhost.server-root    = env.SRCDIR + "/tmp/lighttpd/servers/"
-   simple-vhost.default-host   = "www.example.org"
- }
---- ../lighttpd-1.4.11/tests/lowercase.conf    1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/tests/lowercase.conf        2006-07-16 00:26:05.000000000 +0300
-@@ -0,0 +1,80 @@
-+server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
-+server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
-+
-+## bind to port (default: 80)
-+server.port                 = 2048
-+
-+## bind to localhost (default: all interfaces)
-+server.bind                = "localhost"
-+server.errorlog            = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
-+
-+server.force-lowercase-filenames = "enable"
-+
-+server.dir-listing          = "enable"
-+
-+server.modules              = ( 
-+                              "mod_rewrite",
-+                              "mod_setenv",
-+                              "mod_secdownload",
-+                              "mod_access", 
-+                              "mod_auth",
-+                              "mod_status", 
-+                              "mod_expire",
-+                              "mod_redirect", 
-+                              "mod_fastcgi",
-+                              "mod_cgi" ) 
-+
-+server.indexfiles           = ( "index.php", "index.html", 
-+                                "index.htm", "default.htm" )
-+
-+
-+######################## MODULE CONFIG ############################
-+
-+mimetype.assign             = ( ".png"  => "image/png", 
-+                                ".jpg"  => "image/jpeg",
-+                                ".jpeg" => "image/jpeg",
-+                                ".gif"  => "image/gif",
-+                                ".html" => "text/html",
-+                                ".htm"  => "text/html",
-+                                ".pdf"  => "application/pdf",
-+                                ".swf"  => "application/x-shockwave-flash",
-+                                ".spl"  => "application/futuresplash",
-+                                ".txt"  => "text/plain",
-+                                ".tar.gz" =>   "application/x-tgz",
-+                                ".tgz"  => "application/x-tgz",
-+                                ".gz"   => "application/x-gzip",
-+                              ".c"    => "text/plain",
-+                              ".conf" => "text/plain" )
-+
-+fastcgi.debug               = 0
-+fastcgi.server              = ( ".php" =>        ( ( "host" => "127.0.0.1", "port" => 1026, "broken-scriptfilename" => "enable" ) ),
-+                              "/prefix.fcgi" => ( ( "host" => "127.0.0.1", "port" => 1026, "check-local" => "disable", "broken-scriptfilename" => "enable" ) )
-+                            )
-+              
-+
-+cgi.assign                  = ( ".pl"  => "/usr/bin/perl",
-+                                ".cgi" => "/usr/bin/perl",
-+                              ".py"  => "/usr/bin/python" )
-+                      
-+auth.backend                = "plain"
-+auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user"
-+
-+auth.backend.htpasswd.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.htpasswd"
-+
-+$HTTP["host"] == "lowercase-auth" {
-+  auth.require             = ( "/image.jpg" => 
-+                                ( 
-+                                "method"  => "digest",
-+                                "realm"   => "download archiv",
-+                                "require" => "valid-user"
-+                              )
-+                              )
-+}
-+
-+$HTTP["host"] == "lowercase-deny" {
-+  url.access-deny             = ( ".jpg")
-+}
-+
-+$HTTP["host"] == "lowercase-exclude" {
-+  static-file.exclude-extensions = ( ".jpg" )
-+}
---- ../lighttpd-1.4.11/tests/lowercase.t       1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/tests/lowercase.t   2006-07-16 00:26:05.000000000 +0300
-@@ -0,0 +1,94 @@
-+#!/usr/bin/env perl
-+BEGIN {
-+    # add current source dir to the include-path
-+    # we need this for make distcheck
-+   (my $srcdir = $0) =~ s#/[^/]+$#/#;
-+   unshift @INC, $srcdir;
-+}
-+
-+use strict;
-+use IO::Socket;
-+use Test::More tests => 10;
-+use LightyTest;
-+
-+my $tf = LightyTest->new();
-+my $t;
-+
-+$tf->{CONFIGFILE} = 'lowercase.conf';
-+    
-+ok($tf->start_proc == 0, "Starting lighttpd") or die();
-+
-+## check if lower-casing works
-+
-+$t->{REQUEST}  = ( <<EOF
-+GET /image.JPG HTTP/1.0
-+EOF
-+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
-+ok($tf->handle_http($t) == 0, 'uppercase access');
-+
-+$t->{REQUEST}  = ( <<EOF
-+GET /image.jpg HTTP/1.0
-+EOF
-+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
-+ok($tf->handle_http($t) == 0, 'lowercase access');
-+
-+## check that mod-auth works
-+
-+$t->{REQUEST}  = ( <<EOF
-+GET /image.JPG HTTP/1.0
-+Host: lowercase-auth
-+EOF
-+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 401 } ];
-+ok($tf->handle_http($t) == 0, 'uppercase access');
-+
-+$t->{REQUEST}  = ( <<EOF
-+GET /image.jpg HTTP/1.0
-+Host: lowercase-auth
-+EOF
-+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 401 } ];
-+ok($tf->handle_http($t) == 0, 'lowercase access');
-+
-+
-+## check that mod-staticfile exclude works
-+$t->{REQUEST}  = ( <<EOF
-+GET /image.JPG HTTP/1.0
-+Host: lowercase-exclude
-+EOF
-+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 403 } ];
-+ok($tf->handle_http($t) == 0, 'upper case access to staticfile.exclude-extension');
-+
-+$t->{REQUEST}  = ( <<EOF
-+GET /image.jpg HTTP/1.0
-+Host: lowercase-exclude
-+EOF
-+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 403 } ];
-+ok($tf->handle_http($t) == 0, 'lowercase access');
-+
-+
-+## check that mod-access exclude works
-+$t->{REQUEST}  = ( <<EOF
-+GET /image.JPG HTTP/1.0
-+Host: lowercase-deny
-+EOF
-+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 403 } ];
-+ok($tf->handle_http($t) == 0, 'uppercase access to url.access-deny protected location');
-+
-+$t->{REQUEST}  = ( <<EOF
-+GET /image.jpg HTTP/1.0
-+Host: lowercase-deny
-+EOF
-+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 403 } ];
-+ok($tf->handle_http($t) == 0, 'lowercase access');
-+
-+
-+
-+ok($tf->stop_proc == 0, "Stopping lighttpd");
-+
---- ../lighttpd-1.4.11/tests/mod-cgi.t 2005-09-01 14:43:05.000000000 +0300
-+++ lighttpd-1.5.0/tests/mod-cgi.t     2006-07-18 13:03:40.000000000 +0300
-@@ -43,7 +43,7 @@
- GET /nph-status.pl HTTP/1.0
- EOF
-  );
--$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 502 } ];
- ok($tf->handle_http($t) == 0, 'NPH + perl, Bug #14');
- $t->{REQUEST} = ( <<EOF
---- ../lighttpd-1.4.11/tests/mod-fastcgi.t     2006-03-09 15:30:45.000000000 +0200
-+++ lighttpd-1.5.0/tests/mod-fastcgi.t 2006-07-18 13:03:40.000000000 +0300
-@@ -7,7 +7,7 @@
- }
- use strict;
--use Test::More tests => 47;
-+use Test::More tests => 49;
- use LightyTest;
- my $tf = LightyTest->new();
-@@ -15,7 +15,7 @@
- my $t;
- SKIP: {
--      skip "no PHP running on port 1026", 30 unless $tf->listening_on(1026);
-+      skip "no PHP running on port 1026", 29 unless $tf->listening_on(1026);
-       ok($tf->start_proc == 0, "Starting lighttpd") or die();
-@@ -223,7 +223,7 @@
- }
- SKIP: {
--      skip "no php found", 4 unless -x "/home/jan/Documents/php-5.1.0/sapi/cgi/php"; 
-+      skip "no php found", 4 unless -x "/home/jan/Documents/php-5.1.4/sapi/cgi/php";
-       $tf->{CONFIGFILE} = 'fastcgi-13.conf';
-       ok($tf->start_proc == 0, "Starting lighttpd with $tf->{CONFIGFILE}") or die();
-       $t->{REQUEST}  = ( <<EOF
-@@ -285,6 +285,34 @@
-       $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => 'test123' } ];
-       ok($tf->handle_http($t) == 0, 'line-ending \r\n + \r\n');
-+    # X-LIGHTTPD-send-file
-+      $t->{REQUEST}  = ( <<EOF
-+GET /index.fcgi?x-lighttpd-send-file HTTP/1.0
-+Host: www.example.org
-+EOF
-+ );
-+      $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '<?php phpinfo(); ?>
-+' } ];
-+      ok($tf->handle_http($t) == 0, 'X-LIGHTTPD-send-file');
-+    # X-Sendfile
-+      $t->{REQUEST}  = ( <<EOF
-+GET /index.fcgi?xsendfile HTTP/1.0
-+Host: www.example.org
-+EOF
-+ );
-+      $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '<?php phpinfo(); ?>
-+' } ];
-+      ok($tf->handle_http($t) == 0, 'X-Sendfile');
-+
-+      $t->{REQUEST}  = ( <<EOF
-+GET /index.fcgi?xsendfile-mixed-case HTTP/1.0
-+Host: www.example.org
-+EOF
-+ );
-+      $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '<?php phpinfo(); ?>
-+' } ];
-+      ok($tf->handle_http($t) == 0, 'X-SeNdFiLe in mixed case');
-+
-       $t->{REQUEST}  = ( <<EOF
- GET /index.fcgi?die-at-end HTTP/1.0
- Host: www.example.org
---- ../lighttpd-1.4.11/tests/mod-proxy.t       1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/tests/mod-proxy.t   2006-07-18 13:03:40.000000000 +0300
-@@ -0,0 +1,175 @@
-+#!/usr/bin/env perl
-+BEGIN {
-+    # add current source dir to the include-path
-+    # we need this for make distcheck
-+   (my $srcdir = $0) =~ s#/[^/]+$#/#;
-+   unshift @INC, $srcdir;
-+}
-+
-+use strict;
-+use IO::Socket;
-+use Test::More tests => 21;
-+use LightyTest;
-+
-+my $tf_proxy = LightyTest->new();
-+my $tf_backend1 = LightyTest->new();
-+my $tf_backend2 = LightyTest->new();
-+
-+my $t;
-+
-+## we need two procs
-+## 1. the real webserver
-+## 2. the proxy server
-+
-+SKIP: {
-+  skip "disabled for now", 21;
-+$tf_proxy->{PORT} = 2048;
-+$tf_proxy->{CONFIGFILE} = 'proxy.conf';
-+$tf_proxy->{LIGHTTPD_PIDFILE} = $tf_proxy->{SRCDIR}.'/tmp/lighttpd/lighttpd-proxy.pid';
-+
-+$tf_backend1->{PORT} = 2050;
-+$tf_backend1->{CONFIGFILE} = 'proxy-backend-1.conf';
-+$tf_backend1->{LIGHTTPD_PIDFILE} = $tf_backend1->{SRCDIR}.'/tmp/lighttpd/lighttpd-backend-1.pid';
-+
-+$tf_backend2->{PORT} = 2051;
-+$tf_backend2->{CONFIGFILE} = 'proxy-backend-2.conf';
-+$tf_backend2->{LIGHTTPD_PIDFILE} = $tf_backend2->{SRCDIR}.'/tmp/lighttpd/lighttpd-backend-2.pid';
-+
-+
-+ok($tf_backend1->start_proc == 0, "Starting lighttpd") or die();
-+
-+ok($tf_proxy->start_proc == 0, "Starting lighttpd as proxy") or die();
-+
-+sleep(1);
-+
-+$t->{REQUEST}  = ( <<EOF
-+GET /index.html HTTP/1.0
-+Host: www.example.org
-+EOF
-+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
-+ok($tf_proxy->handle_http($t) == 0, 'valid request');
-+
-+$t->{REQUEST}  = ( <<EOF
-+GET /index.html HTTP/1.0
-+Host: www.example.org
-+EOF
-+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'Server' => 'proxy-backend-1' } ];
-+ok($tf_proxy->handle_http($t) == 0, 'drop Server from real server');
-+
-+$t->{REQUEST}  = ( <<EOF
-+GET /balance-rr/foo HTTP/1.0
-+Host: www.example.org
-+EOF
-+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-1' } ];
-+ok($tf_proxy->handle_http($t) == 0, 'balance rr - one backend');
-+
-+$t->{REQUEST}  = ( <<EOF
-+GET /balance-rr/foo HTTP/1.0
-+Host: www.example.org
-+EOF
-+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-1' } ];
-+ok($tf_proxy->handle_http($t) == 0, 'balance rr - one host down, failover');
-+
-+$t->{REQUEST}  = ( <<EOF
-+GET /balance-fair/foo HTTP/1.0
-+Host: www.example.org
-+EOF
-+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-1' } ];
-+ok($tf_proxy->handle_http($t) == 0, 'balance fair - one backend');
-+
-+## backend 2 starting 
-+ok($tf_backend2->start_proc == 0, "Starting second proxy backend") or die();
-+
-+$t->{REQUEST}  = ( <<EOF
-+GET /balance-rr/foo HTTP/1.0
-+Host: www.example.org
-+EOF
-+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-2' } ];
-+ok($tf_proxy->handle_http($t) == 0, 'balance rr - lb, backend 1');
-+
-+$t->{REQUEST}  = ( <<EOF
-+GET /balance-rr/foo HTTP/1.0
-+Host: www.example.org
-+EOF
-+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-1' } ];
-+ok($tf_proxy->handle_http($t) == 0, 'balance rr - lb, backend 2');
-+
-+$t->{REQUEST}  = ( <<EOF
-+GET /balance-hash/foo HTTP/1.0
-+Host: www.example.org
-+EOF
-+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-1' } ];
-+ok($tf_proxy->handle_http($t) == 0, 'balance hash - lb, backend 1');
-+
-+$t->{REQUEST}  = ( <<EOF
-+GET /balance-hash/foo HTTP/1.0
-+Host: www.example.org
-+EOF
-+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-1' } ];
-+ok($tf_proxy->handle_http($t) == 0, 'balance hash - lb, backend 1 - same URL');
-+
-+$t->{REQUEST}  = ( <<EOF
-+GET /balance-hash/bar HTTP/1.0
-+Host: www.example.org
-+EOF
-+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-2' } ];
-+ok($tf_proxy->handle_http($t) == 0, 'balance hash - lb, backend 2');
-+
-+$t->{REQUEST}  = ( <<EOF
-+GET /balance-hash/bar HTTP/1.0
-+Host: www.example.org
-+EOF
-+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-2' } ];
-+ok($tf_proxy->handle_http($t) == 0, 'balance hash - lb, backend 2 - same URL');
-+
-+## backend 1 stopping, failover 
-+ok($tf_backend1->stop_proc == 0, "Stopping backend 1");
-+
-+$t->{REQUEST}  = ( <<EOF
-+GET /balance-hash/foo HTTP/1.0
-+Host: www.example.org
-+EOF
-+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-2' } ];
-+ok($tf_proxy->handle_http($t) == 0, 'balance hash - failover to backend 2');
-+
-+$t->{REQUEST}  = ( <<EOF
-+GET /balance-hash/bar HTTP/1.0
-+Host: www.example.org
-+EOF
-+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-2' } ];
-+ok($tf_proxy->handle_http($t) == 0, 'balance hash - failover to backend 2 - same URL');
-+
-+$t->{REQUEST}  = ( <<EOF
-+GET /balance-rr/foo HTTP/1.0
-+Host: www.example.org
-+EOF
-+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-2' } ];
-+ok($tf_proxy->handle_http($t) == 0, 'balance rr - failover to backend 2');
-+
-+$t->{REQUEST}  = ( <<EOF
-+GET /balance-fair/foo HTTP/1.0
-+Host: www.example.org
-+EOF
-+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-2' } ];
-+ok($tf_proxy->handle_http($t) == 0, 'balance fair - failover to backend 2');
-+
-+
-+ok($tf_backend2->stop_proc == 0, "Stopping lighttpd");
-+
-+ok($tf_proxy->stop_proc == 0, "Stopping lighttpd proxy");
-+}
---- ../lighttpd-1.4.11/tests/proxy-backend-1.conf      1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/tests/proxy-backend-1.conf  2006-07-16 00:26:05.000000000 +0300
-@@ -0,0 +1,7 @@
-+server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
-+server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd-backend-1.pid"
-+
-+include "default.conf"
-+
-+
-+server.tag = "proxy-backend-1"
---- ../lighttpd-1.4.11/tests/proxy-backend-2.conf      1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/tests/proxy-backend-2.conf  2006-07-16 00:26:04.000000000 +0300
-@@ -0,0 +1,7 @@
-+server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
-+server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd-backend-2.pid"
-+
-+include "default.conf"
-+
-+
-+server.tag = "proxy-backend-2"
---- ../lighttpd-1.4.11/tests/proxy.conf        1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.5.0/tests/proxy.conf    2006-07-16 00:26:05.000000000 +0300
-@@ -0,0 +1,26 @@
-+server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
-+server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd-proxy.pid"
-+server.tag = "proxy"
-+
-+include "default.conf"
-+
-+## 127.0.0.1 and 127.0.0.2 are the same host
-+proxy.server              = ( 
-+  "" => (( "host" => "127.0.0.1",
-+         "port" => 2050 ),
-+         ( "host" => "127.0.0.2",
-+           "port" => 2051 )
-+  ))
-+              
-+$HTTP["url"] =~ "^/balance-rr/" {
-+  proxy.balance = "round-robin"
-+}
-+
-+$HTTP["url"] =~ "^/balance-hash/" {
-+  proxy.balance = "hash"
-+}
-+
-+$HTTP["url"] =~ "^/balance-fair/" {
-+  proxy.balance = "fair"
-+}
-+
---- ../lighttpd-1.4.11/tests/request.t 2006-03-04 16:37:20.000000000 +0200
-+++ lighttpd-1.5.0/tests/request.t     2006-09-07 00:57:05.000000000 +0300
-@@ -96,12 +96,16 @@
- ok($tf->handle_http($t) == 0, 'HEAD request, file-not-found, query-string');
- $t->{REQUEST}  = ( <<EOF
--GET / HTTP/1.1
-+POST / HTTP/1.1
- Connection: close
-+Content-Length: 4
-+Host: www.example.org
- Expect: 100-continue
-+
-+1234
- EOF
-  );
--$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 417, '-HTTP-Content' => ''} ];
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 100} ];
- ok($tf->handle_http($t) == 0, 'Continue, Expect');
- ## ranges
---- ../lighttpd-1.4.11/tests/var-include.conf  2005-08-27 17:44:19.000000000 +0300
-+++ lighttpd-1.5.0/tests/var-include.conf      2006-07-16 00:26:05.000000000 +0300
-@@ -2,15 +2,15 @@
- debug.log-request-handling = "enable"
- debug.log-condition-handling = "enable"
--server.document-root         = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
--server.pid-file              = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
-+server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
-+server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
- ## bind to port (default: 80)
- server.port                 = 2048
- ## bind to localhost (default: all interfaces)
- server.bind                = "localhost"
--server.errorlog            = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log"
-+server.errorlog            = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
- server.name                = "www.example.org"
- server.tag                 = "Apache 1.3.29"
-@@ -21,19 +21,19 @@
- ######################## MODULE CONFIG ############################
--accesslog.filename          = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log"
-+accesslog.filename          = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log"
- mimetype.assign             = ( ".html" => "text/html" )
- url.redirect = ("^" => "/default")
- $HTTP["host"] == "www.example.org" {
--  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
-+  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
-   server.name = "www.example.org"
-   url.redirect = ("^" => "/redirect")
- }
- $HTTP["host"] == "test.example.org" {
--  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
-+  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
-   server.name = "test.example.org"
-   var.myvar = "good"
-   var.one = 1
+       if (srv->srvconf.pid_file->used &&
+-          srv->srvconf.changeroot->used == 0) {
++          srv->srvconf.changeroot->used == 0 &&
++          0 == graceful_shutdown) {
+               if (0 != unlink(srv->srvconf.pid_file->ptr)) {
+                       if (errno != EACCES && errno != EPERM) {
+                               log_error_write(srv, __FILE__, __LINE__, "sbds",
+
+Property changes on: .
+___________________________________________________________________
+Name: svk:merge
+   + a98e19e4-a712-0410-8832-6551a15ffc53:/local/branches/lighttpd-1.4.x:1557
+
This page took 3.176909 seconds and 4 git commands to generate.