]> git.pld-linux.org Git - packages/lighttpd.git/commitdiff
- due missing files in previous diff, create diff from make dist in svn dir
authorElan Ruusamäe <glen@pld-linux.org>
Tue, 11 Jul 2006 18:53:35 +0000 (18:53 +0000)
committercvs2git <feedback@pld-linux.org>
Sun, 24 Jun 2012 12:13:13 +0000 (12:13 +0000)
Changed files:
    lighttpd-branch.diff -> 1.3

lighttpd-branch.diff

index 941f5b5edb37e5afe3a0e09a387cdce60a03efdf..76cbf3e5a6d3934e6b269bc157ac6af933564b74 100644 (file)
@@ -1,5 +1,49 @@
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/Makefile.in lighttpd-1.4.12/Makefile.in
+--- lighttpd-1.4.11/Makefile.in        2006-03-07 14:21:08.000000000 +0200
++++ lighttpd-1.4.12/Makefile.in        2006-07-11 21:48:16.000000000 +0300
+@@ -1,4 +1,4 @@
+-# Makefile.in generated by automake 1.9.5 from Makefile.am.
++# Makefile.in generated by automake 1.9.6 from Makefile.am.
+ # @configure_input@
+ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+@@ -41,7 +41,7 @@
+       $(srcdir)/distribute.sh.in $(srcdir)/lighttpd.spec.in \
+       $(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \
+       compile config.guess config.sub depcomp install-sh ltmain.sh \
+-      missing mkinstalldirs
++      missing
+ subdir = .
+ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+ am__aclocal_m4_deps = $(top_srcdir)/configure.in
+@@ -49,7 +49,7 @@
+       $(ACLOCAL_M4)
+ am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+  configure.lineno configure.status.lineno
+-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
++mkinstalldirs = $(install_sh) -d
+ CONFIG_HEADER = config.h
+ CONFIG_CLEAN_FILES = lighttpd.spec distribute.sh
+ SOURCES =
+@@ -126,7 +126,6 @@
+ LIBTOOL = @LIBTOOL@
+ LN_S = @LN_S@
+ LTLIBOBJS = @LTLIBOBJS@
+-LUACONFIG = @LUACONFIG@
+ LUA_CFLAGS = @LUA_CFLAGS@
+ LUA_LIBS = @LUA_LIBS@
+ MAINT = @MAINT@
+@@ -169,6 +168,7 @@
+ ac_ct_F77 = @ac_ct_F77@
+ ac_ct_RANLIB = @ac_ct_RANLIB@
+ ac_ct_STRIP = @ac_ct_STRIP@
++ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@
+ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/NEWS lighttpd-1.4.12/NEWS
 --- lighttpd-1.4.11/NEWS       2006-03-09 19:34:33.000000000 +0200
-+++ lighttpd/NEWS      2006-07-11 21:23:42.928033114 +0300
++++ lighttpd-1.4.12/NEWS       2006-07-11 21:23:42.000000000 +0300
 @@ -3,6 +3,23 @@
  NEWS
  ====
@@ -24,8 +68,9 @@
  - 1.4.11 - 2006-03-09
  
    * added ability to specify which ip address spawn-fci listens on 
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/configure.in lighttpd-1.4.12/configure.in
 --- lighttpd-1.4.11/configure.in       2006-03-04 16:32:38.000000000 +0200
-+++ lighttpd/configure.in      2006-07-11 21:23:42.880030107 +0300
++++ lighttpd-1.4.12/configure.in       2006-07-11 21:23:42.000000000 +0300
 @@ -1,7 +1,7 @@
  #                                               -*- Autoconf -*-
  # Process this file with autoconf to produce a configure script.
 - if test x"$LUACONFIG" != x; then
 -   LUA_CFLAGS=`$LUACONFIG --include`
 -   LUA_LIBS=`$LUACONFIG --libs --extralibs`
--   AC_DEFINE([HAVE_LUA], [1], [liblua])
--   AC_DEFINE([HAVE_LUA_H], [1], [lua.h])
++ # 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],[
 - fi
 -
 - if test x"$LUA_LIBS" = x; then
-    # try pkgconfig
+-   # try pkgconfig
 -   PKG_CHECK_MODULES(LUA, lua, [
-+ PKG_CHECK_MODULES(LUA, lua >= 5.1, [
-      AC_DEFINE([HAVE_LUA], [1], [liblua])
-      AC_DEFINE([HAVE_LUA_H], [1], [lua.h])
-    ])
+-     AC_DEFINE([HAVE_LUA], [1], [liblua])
+-     AC_DEFINE([HAVE_LUA_H], [1], [lua.h])
+-   ])
 - fi
++ ])
  
   AC_SUBST(LUA_CFLAGS)
   AC_SUBST(LUA_LIBS)
  ## output
  
  $ECHO
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/cygwin/Makefile.in lighttpd-1.4.12/cygwin/Makefile.in
+--- lighttpd-1.4.11/cygwin/Makefile.in 2006-03-07 14:20:57.000000000 +0200
++++ lighttpd-1.4.12/cygwin/Makefile.in 2006-07-11 21:48:12.000000000 +0300
+@@ -1,4 +1,4 @@
+-# Makefile.in generated by automake 1.9.5 from Makefile.am.
++# Makefile.in generated by automake 1.9.6 from Makefile.am.
+ # @configure_input@
+ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+@@ -43,7 +43,7 @@
+ am__aclocal_m4_deps = $(top_srcdir)/configure.in
+ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+       $(ACLOCAL_M4)
+-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
++mkinstalldirs = $(install_sh) -d
+ CONFIG_HEADER = $(top_builddir)/config.h
+ CONFIG_CLEAN_FILES = lighttpd.README
+ SOURCES =
+@@ -101,7 +101,6 @@
+ LIBTOOL = @LIBTOOL@
+ LN_S = @LN_S@
+ LTLIBOBJS = @LTLIBOBJS@
+-LUACONFIG = @LUACONFIG@
+ LUA_CFLAGS = @LUA_CFLAGS@
+ LUA_LIBS = @LUA_LIBS@
+ MAINT = @MAINT@
+@@ -144,6 +143,7 @@
+ ac_ct_F77 = @ac_ct_F77@
+ ac_ct_RANLIB = @ac_ct_RANLIB@
+ ac_ct_STRIP = @ac_ct_STRIP@
++ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@
+ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/cygwin/lighttpd.README lighttpd-1.4.12/cygwin/lighttpd.README
+--- lighttpd-1.4.11/cygwin/lighttpd.README     2006-03-07 14:22:19.000000000 +0200
++++ lighttpd-1.4.12/cygwin/lighttpd.README     2006-07-11 21:49:09.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.4.12-<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.4.12-<REL>.sh all
++
++This will create:
++  /usr/src/lighttpd-1.4.12-<REL>.tar.bz2
++  /usr/src/lighttpd-1.4.12-<REL>-src.tar.bz2
++
++Or use './lighttpd-1.4.12-<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>
++
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/cygwin/lighttpd.README.in lighttpd-1.4.12/cygwin/lighttpd.README.in
+--- lighttpd-1.4.11/cygwin/lighttpd.README.in  2005-08-11 01:26:59.000000000 +0300
++++ lighttpd-1.4.12/cygwin/lighttpd.README.in  2006-07-11 21:23: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-@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>
++
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/doc/Makefile.in lighttpd-1.4.12/doc/Makefile.in
+--- lighttpd-1.4.11/doc/Makefile.in    2006-03-07 14:20:57.000000000 +0200
++++ lighttpd-1.4.12/doc/Makefile.in    2006-07-11 21:48:12.000000000 +0300
+@@ -1,4 +1,4 @@
+-# Makefile.in generated by automake 1.9.5 from Makefile.am.
++# Makefile.in generated by automake 1.9.6 from Makefile.am.
+ # @configure_input@
+ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+@@ -43,7 +43,7 @@
+ am__aclocal_m4_deps = $(top_srcdir)/configure.in
+ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+       $(ACLOCAL_M4)
+-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
++mkinstalldirs = $(install_sh) -d
+ CONFIG_HEADER = $(top_builddir)/config.h
+ CONFIG_CLEAN_FILES =
+ SOURCES =
+@@ -105,7 +105,6 @@
+ LIBTOOL = @LIBTOOL@
+ LN_S = @LN_S@
+ LTLIBOBJS = @LTLIBOBJS@
+-LUACONFIG = @LUACONFIG@
+ LUA_CFLAGS = @LUA_CFLAGS@
+ LUA_LIBS = @LUA_LIBS@
+ MAINT = @MAINT@
+@@ -148,6 +147,7 @@
+ ac_ct_F77 = @ac_ct_F77@
+ ac_ct_RANLIB = @ac_ct_RANLIB@
+ ac_ct_STRIP = @ac_ct_STRIP@
++ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@
+ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/doc/authentication.txt lighttpd-1.4.12/doc/authentication.txt
 --- lighttpd-1.4.11/doc/authentication.txt     2006-01-12 20:34:26.000000000 +0200
-+++ lighttpd/doc/authentication.txt    2006-07-11 21:23:42.708019334 +0300
++++ lighttpd-1.4.12/doc/authentication.txt     2006-07-11 21:23:42.000000000 +0300
 @@ -7,8 +7,8 @@
  ----------------
  
  
  :abstract:
    The auth module provides ...
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/doc/compress.txt lighttpd-1.4.12/doc/compress.txt
 --- lighttpd-1.4.11/doc/compress.txt   2005-08-11 01:26:16.000000000 +0300
-+++ lighttpd/doc/compress.txt  2006-07-11 21:23:42.680017580 +0300
++++ lighttpd-1.4.12/doc/compress.txt   2006-07-11 21:23:42.000000000 +0300
 @@ -22,12 +22,38 @@
  ===========
  
  
  Options
  =======
-@@ -47,14 +73,27 @@
+@@ -47,15 +73,28 @@
    Default: not set, compress the file for every request
  
  compress.filetype
 +  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
  ===========================
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/doc/configuration.txt lighttpd-1.4.12/doc/configuration.txt
 --- lighttpd-1.4.11/doc/configuration.txt      2006-03-09 02:10:40.000000000 +0200
-+++ lighttpd/doc/configuration.txt     2006-07-11 21:23:42.696018582 +0300
++++ lighttpd-1.4.12/doc/configuration.txt      2006-07-11 21:23:42.000000000 +0300
 @@ -7,8 +7,8 @@
  ------------
  
 +debug.log-condition-cache-handling
 +  for developers only
 +  default: disabled 
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/doc/fastcgi.txt lighttpd-1.4.12/doc/fastcgi.txt
 --- lighttpd-1.4.11/doc/fastcgi.txt    2006-02-16 17:03:52.000000000 +0200
-+++ lighttpd/doc/fastcgi.txt   2006-07-11 21:23:42.712019584 +0300
++++ lighttpd-1.4.12/doc/fastcgi.txt    2006-07-11 21:23:42.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
  
    If bin-path is set:
  
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/doc/lighttpd.conf lighttpd-1.4.12/doc/lighttpd.conf
 --- lighttpd-1.4.11/doc/lighttpd.conf  2006-03-04 14:41:12.000000000 +0200
-+++ lighttpd/doc/lighttpd.conf 2006-07-11 21:23:42.736021088 +0300
-@@ -176,6 +176,7 @@
- #debug.log-response-header  = "enable"
- #debug.log-request-handling = "enable"
- #debug.log-file-not-found   = "enable"
++++ lighttpd-1.4.12/doc/lighttpd.conf  2006-07-11 21:23:42.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
  #
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/doc/performance.txt lighttpd-1.4.12/doc/performance.txt
 --- lighttpd-1.4.11/doc/performance.txt        2006-02-02 13:01:08.000000000 +0200
-+++ lighttpd/doc/performance.txt       2006-07-11 21:23:42.632014574 +0300
++++ lighttpd-1.4.12/doc/performance.txt        2006-07-11 21:23:42.000000000 +0300
 @@ -183,6 +183,8 @@
  
    server.stat-cache-engine = "fam"   # either fam, simple or disabled
  
  Platform-Specific Notes
  =======================
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/doc/secdownload.txt lighttpd-1.4.12/doc/secdownload.txt
 --- lighttpd-1.4.11/doc/secdownload.txt        2005-12-20 15:58:58.000000000 +0200
-+++ lighttpd/doc/secdownload.txt       2006-07-11 21:23:42.640015075 +0300
++++ lighttpd-1.4.12/doc/secdownload.txt        2006-07-11 21:23:42.000000000 +0300
 @@ -118,7 +118,7 @@
    $secret = "verysecret";
    $uri_prefix = "/dl/";
    $f = "/secret-file.txt";
    
    # current timestamp
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/lighttpd.spec lighttpd-1.4.12/lighttpd.spec
+--- lighttpd-1.4.11/lighttpd.spec      2006-03-07 14:22:18.000000000 +0200
++++ lighttpd-1.4.12/lighttpd.spec      2006-07-11 21:49:09.000000000 +0300
+@@ -1,6 +1,6 @@
+ Summary: A fast webserver with minimal memory-footprint (lighttpd)
+ Name: lighttpd
+-Version: 1.4.11
++Version: 1.4.12
+ Release: 1
+ Source: http://jan.kneschke.de/projects/lighttpd/download/lighttpd-%version.tar.gz
+ Packager: Jan Kneschke <jan@kneschke.de>
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/openwrt/Makefile.in lighttpd-1.4.12/openwrt/Makefile.in
+--- lighttpd-1.4.11/openwrt/Makefile.in        2006-03-07 14:20:58.000000000 +0200
++++ lighttpd-1.4.12/openwrt/Makefile.in        2006-07-11 21:48:12.000000000 +0300
+@@ -1,4 +1,4 @@
+-# Makefile.in generated by automake 1.9.5 from Makefile.am.
++# Makefile.in generated by automake 1.9.6 from Makefile.am.
+ # @configure_input@
+ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+@@ -43,7 +43,7 @@
+ am__aclocal_m4_deps = $(top_srcdir)/configure.in
+ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+       $(ACLOCAL_M4)
+-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
++mkinstalldirs = $(install_sh) -d
+ CONFIG_HEADER = $(top_builddir)/config.h
+ CONFIG_CLEAN_FILES = control lighttpd.mk
+ SOURCES =
+@@ -101,7 +101,6 @@
+ LIBTOOL = @LIBTOOL@
+ LN_S = @LN_S@
+ LTLIBOBJS = @LTLIBOBJS@
+-LUACONFIG = @LUACONFIG@
+ LUA_CFLAGS = @LUA_CFLAGS@
+ LUA_LIBS = @LUA_LIBS@
+ MAINT = @MAINT@
+@@ -144,6 +143,7 @@
+ ac_ct_F77 = @ac_ct_F77@
+ ac_ct_RANLIB = @ac_ct_RANLIB@
+ ac_ct_STRIP = @ac_ct_STRIP@
++ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@
+ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/openwrt/control lighttpd-1.4.12/openwrt/control
+--- lighttpd-1.4.11/openwrt/control    2006-03-07 14:22:19.000000000 +0200
++++ lighttpd-1.4.12/openwrt/control    2006-07-11 21:49:10.000000000 +0300
+@@ -1,8 +1,8 @@
+ Package: lighttpd
+-Version: 1.4.11
++Version: 1.4.12
+ 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.4.12.tar.gz
+ Section: net
+ Priority: optional
+ Depends:
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/openwrt/lighttpd.mk lighttpd-1.4.12/openwrt/lighttpd.mk
+--- lighttpd-1.4.11/openwrt/lighttpd.mk        2006-03-07 14:22:19.000000000 +0200
++++ lighttpd-1.4.12/openwrt/lighttpd.mk        2006-07-11 21:49:10.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.4.12
+ LIGHTTPD_TARGET=.built
+ LIGHTTPD_DIR=$(BUILD_DIR)/$(LIGHTTPD)
+ LIGHTTPD_IPK=$(BUILD_DIR)/$(LIGHTTPD)_mipsel.ipk
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/Makefile.am lighttpd-1.4.12/src/Makefile.am
 --- lighttpd-1.4.11/src/Makefile.am    2006-03-07 14:20:20.000000000 +0200
-+++ lighttpd/src/Makefile.am   2006-07-11 21:23:40.099855979 +0300
++++ lighttpd-1.4.12/src/Makefile.am    2006-07-11 21:23:40.000000000 +0300
 @@ -16,14 +16,19 @@
  else
  configparser.y: lemon
        
  src = server.c response.c connections.c network.c \
        configfile.c configparser.c request.c proc_open.c
-@@ -84,7 +89,7 @@
+@@ -82,9 +87,9 @@
+ 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_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)
  
  DEFS= @DEFS@ -DLIBRARY_DIR="\"$(libdir)\""
  
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/Makefile.in lighttpd-1.4.12/src/Makefile.in
+--- lighttpd-1.4.11/src/Makefile.in    2006-03-07 14:21:02.000000000 +0200
++++ lighttpd-1.4.12/src/Makefile.in    2006-07-11 21:48:14.000000000 +0300
+@@ -1,4 +1,4 @@
+-# Makefile.in generated by automake 1.9.5 from Makefile.am.
++# Makefile.in generated by automake 1.9.6 from Makefile.am.
+ # @configure_input@
+ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+@@ -16,8 +16,6 @@
+-SOURCES = $(liblightcomp_la_SOURCES) $(mod_access_la_SOURCES) $(mod_accesslog_la_SOURCES) $(mod_alias_la_SOURCES) $(mod_auth_la_SOURCES) $(mod_cgi_la_SOURCES) $(mod_cml_la_SOURCES) $(mod_compress_la_SOURCES) $(mod_dirlisting_la_SOURCES) $(mod_evasive_la_SOURCES) $(mod_evhost_la_SOURCES) $(mod_expire_la_SOURCES) $(mod_fastcgi_la_SOURCES) $(mod_flv_streaming_la_SOURCES) $(mod_indexfile_la_SOURCES) $(mod_mysql_vhost_la_SOURCES) $(mod_proxy_la_SOURCES) $(mod_redirect_la_SOURCES) $(mod_rewrite_la_SOURCES) $(mod_rrdtool_la_SOURCES) $(mod_scgi_la_SOURCES) $(mod_secdownload_la_SOURCES) $(mod_setenv_la_SOURCES) $(mod_simple_vhost_la_SOURCES) $(mod_ssi_la_SOURCES) $(mod_staticfile_la_SOURCES) $(mod_status_la_SOURCES) $(mod_trigger_b4_dl_la_SOURCES) $(mod_userdir_la_SOURCES) $(mod_usertrack_la_SOURCES) $(mod_webdav_la_SOURCES) $(lemon_SOURCES) $(lighttpd_SOURCES) $(proc_open_SOURCES) $(spawn_fcgi_SOURCES)
+-
+ srcdir = @srcdir@
+ top_srcdir = @top_srcdir@
+ VPATH = @srcdir@
+@@ -57,7 +55,7 @@
+ am__aclocal_m4_deps = $(top_srcdir)/configure.in
+ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+       $(ACLOCAL_M4)
+-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
++mkinstalldirs = $(install_sh) -d
+ CONFIG_HEADER = $(top_builddir)/config.h
+ CONFIG_CLEAN_FILES =
+ am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+@@ -84,7 +82,8 @@
+       inet_ntop_cache.c crc32.c connections-glue.c configfile-glue.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
++      network_solaris_sendfilev.c network_openssl.c splaytree.c \
++      http_resp.c http_resp_parser.c
+ am__objects_1 = liblightcomp_la-buffer.lo liblightcomp_la-log.lo \
+       liblightcomp_la-keyvalue.lo liblightcomp_la-chunk.lo \
+       liblightcomp_la-http_chunk.lo liblightcomp_la-stream.lo \
+@@ -111,7 +110,8 @@
+       liblightcomp_la-network_writev.lo \
+       liblightcomp_la-network_solaris_sendfilev.lo \
+       liblightcomp_la-network_openssl.lo \
+-      liblightcomp_la-splaytree.lo
++      liblightcomp_la-splaytree.lo liblightcomp_la-http_resp.lo \
++      liblightcomp_la-http_resp_parser.lo
+ @NO_RDYNAMIC_TRUE@am_liblightcomp_la_OBJECTS = $(am__objects_1)
+ liblightcomp_la_OBJECTS = $(am_liblightcomp_la_OBJECTS)
+ @NO_RDYNAMIC_TRUE@am_liblightcomp_la_rpath = -rpath $(libdir)
+@@ -193,6 +193,9 @@
+ mod_simple_vhost_la_DEPENDENCIES = $(am__DEPENDENCIES_2)
+ am_mod_simple_vhost_la_OBJECTS = mod_simple_vhost.lo
+ mod_simple_vhost_la_OBJECTS = $(am_mod_simple_vhost_la_OBJECTS)
++mod_sql_vhost_core_la_DEPENDENCIES = $(am__DEPENDENCIES_2)
++am_mod_sql_vhost_core_la_OBJECTS = mod_sql_vhost_core.lo
++mod_sql_vhost_core_la_OBJECTS = $(am_mod_sql_vhost_core_la_OBJECTS)
+ mod_ssi_la_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
+ am_mod_ssi_la_OBJECTS = mod_ssi_exprparser.lo mod_ssi_expr.lo \
+       mod_ssi.lo
+@@ -236,7 +239,8 @@
+       connections-glue.c configfile-glue.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
++      network_solaris_sendfilev.c network_openssl.c splaytree.c \
++      http_resp.c http_resp_parser.c
+ am__objects_2 = buffer.$(OBJEXT) log.$(OBJEXT) keyvalue.$(OBJEXT) \
+       chunk.$(OBJEXT) http_chunk.$(OBJEXT) stream.$(OBJEXT) \
+       fdevent.$(OBJEXT) stat_cache.$(OBJEXT) plugin.$(OBJEXT) \
+@@ -254,7 +258,8 @@
+       network_linux_sendfile.$(OBJEXT) \
+       network_freebsd_sendfile.$(OBJEXT) network_writev.$(OBJEXT) \
+       network_solaris_sendfilev.$(OBJEXT) network_openssl.$(OBJEXT) \
+-      splaytree.$(OBJEXT)
++      splaytree.$(OBJEXT) http_resp.$(OBJEXT) \
++      http_resp_parser.$(OBJEXT)
+ @NO_RDYNAMIC_FALSE@am__objects_3 = $(am__objects_2)
+ am__objects_4 = server.$(OBJEXT) response.$(OBJEXT) \
+       connections.$(OBJEXT) network.$(OBJEXT) configfile.$(OBJEXT) \
+@@ -282,8 +287,8 @@
+       $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+       $(AM_CFLAGS) $(CFLAGS)
+ CCLD = $(CC)
+-LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+-      $(AM_LDFLAGS) $(LDFLAGS) -o $@
++LINK = $(LIBTOOL) --tag=CC --mode=link "$(CCLD)" $(AM_CFLAGS) \
++      $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+ SOURCES = $(liblightcomp_la_SOURCES) $(mod_access_la_SOURCES) \
+       $(mod_accesslog_la_SOURCES) $(mod_alias_la_SOURCES) \
+       $(mod_auth_la_SOURCES) $(mod_cgi_la_SOURCES) \
+@@ -296,11 +301,12 @@
+       $(mod_rewrite_la_SOURCES) $(mod_rrdtool_la_SOURCES) \
+       $(mod_scgi_la_SOURCES) $(mod_secdownload_la_SOURCES) \
+       $(mod_setenv_la_SOURCES) $(mod_simple_vhost_la_SOURCES) \
+-      $(mod_ssi_la_SOURCES) $(mod_staticfile_la_SOURCES) \
+-      $(mod_status_la_SOURCES) $(mod_trigger_b4_dl_la_SOURCES) \
+-      $(mod_userdir_la_SOURCES) $(mod_usertrack_la_SOURCES) \
+-      $(mod_webdav_la_SOURCES) $(lemon_SOURCES) $(lighttpd_SOURCES) \
+-      $(proc_open_SOURCES) $(spawn_fcgi_SOURCES)
++      $(mod_sql_vhost_core_la_SOURCES) $(mod_ssi_la_SOURCES) \
++      $(mod_staticfile_la_SOURCES) $(mod_status_la_SOURCES) \
++      $(mod_trigger_b4_dl_la_SOURCES) $(mod_userdir_la_SOURCES) \
++      $(mod_usertrack_la_SOURCES) $(mod_webdav_la_SOURCES) \
++      $(lemon_SOURCES) $(lighttpd_SOURCES) $(proc_open_SOURCES) \
++      $(spawn_fcgi_SOURCES)
+ DIST_SOURCES = $(am__liblightcomp_la_SOURCES_DIST) \
+       $(mod_access_la_SOURCES) $(mod_accesslog_la_SOURCES) \
+       $(mod_alias_la_SOURCES) $(mod_auth_la_SOURCES) \
+@@ -313,7 +319,8 @@
+       $(mod_redirect_la_SOURCES) $(mod_rewrite_la_SOURCES) \
+       $(mod_rrdtool_la_SOURCES) $(mod_scgi_la_SOURCES) \
+       $(mod_secdownload_la_SOURCES) $(mod_setenv_la_SOURCES) \
+-      $(mod_simple_vhost_la_SOURCES) $(mod_ssi_la_SOURCES) \
++      $(mod_simple_vhost_la_SOURCES) \
++      $(mod_sql_vhost_core_la_SOURCES) $(mod_ssi_la_SOURCES) \
+       $(mod_staticfile_la_SOURCES) $(mod_status_la_SOURCES) \
+       $(mod_trigger_b4_dl_la_SOURCES) $(mod_userdir_la_SOURCES) \
+       $(mod_usertrack_la_SOURCES) $(mod_webdav_la_SOURCES) \
+@@ -375,7 +382,6 @@
+ LIBTOOL = @LIBTOOL@
+ LN_S = @LN_S@
+ LTLIBOBJS = @LTLIBOBJS@
+-LUACONFIG = @LUACONFIG@
+ LUA_CFLAGS = @LUA_CFLAGS@
+ LUA_LIBS = @LUA_LIBS@
+ MAINT = @MAINT@
+@@ -418,6 +424,7 @@
+ ac_ct_F77 = @ac_ct_F77@
+ ac_ct_RANLIB = @ac_ct_RANLIB@
+ ac_ct_STRIP = @ac_ct_STRIP@
++ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@
+ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+@@ -479,7 +486,7 @@
+       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 
+ src = server.c response.c connections.c network.c configfile.c \
+       configparser.c request.c proc_open.c $(am__append_2)
+@@ -491,10 +498,11 @@
+ #mod_httptls_la_LIBADD = $(common_libadd)
+ lib_LTLIBRARIES = $(am__append_1) mod_flv_streaming.la mod_evasive.la \
+       mod_webdav.la mod_cml.la mod_trigger_b4_dl.la \
+-      mod_mysql_vhost.la mod_cgi.la mod_scgi.la mod_staticfile.la \
+-      mod_dirlisting.la mod_indexfile.la mod_setenv.la mod_alias.la \
+-      mod_userdir.la mod_rrdtool.la mod_usertrack.la mod_proxy.la \
+-      mod_ssi.la mod_secdownload.la mod_expire.la mod_evhost.la \
++      mod_mysql_vhost.la mod_sql_vhost_core.la mod_cgi.la \
++      mod_scgi.la mod_staticfile.la mod_dirlisting.la \
++      mod_indexfile.la mod_setenv.la mod_alias.la mod_userdir.la \
++      mod_rrdtool.la mod_usertrack.la mod_proxy.la mod_ssi.la \
++      mod_secdownload.la mod_expire.la mod_evhost.la \
+       mod_simple_vhost.la mod_fastcgi.la mod_access.la \
+       mod_compress.la mod_auth.la mod_rewrite.la mod_redirect.la \
+       mod_status.la mod_accesslog.la
+@@ -511,9 +519,9 @@
+ mod_evasive_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
+ mod_evasive_la_LIBADD = $(common_libadd)
+ 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)
+ mod_cml_la_SOURCES = mod_cml.c mod_cml_lua.c mod_cml_funcs.c
+ mod_cml_la_CFLAGS = $(AM_CFLAGS) $(LUA_CFLAGS)
+ mod_cml_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
+@@ -525,6 +533,9 @@
+ mod_mysql_vhost_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
+ mod_mysql_vhost_la_LIBADD = $(MYSQL_LIBS) $(common_libadd)
+ mod_mysql_vhost_la_CPPFLAGS = $(MYSQL_INCLUDE)
++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)
+ mod_cgi_la_SOURCES = mod_cgi.c 
+ mod_cgi_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
+ mod_cgi_la_LIBADD = $(common_libadd)
+@@ -608,7 +619,7 @@
+       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 http_resp.h mod_sql_vhost_core.h
+ lighttpd_SOURCES = $(src)
+ lighttpd_LDADD = $(PCRE_LIB) $(DL_LIB) $(SENDFILE_LIB) $(ATTR_LIB) $(common_libadd) $(SSL_LIB) $(FAM_LIBS)
+@@ -739,6 +750,8 @@
+       $(LINK) -rpath $(libdir) $(mod_setenv_la_LDFLAGS) $(mod_setenv_la_OBJECTS) $(mod_setenv_la_LIBADD) $(LIBS)
+ mod_simple_vhost.la: $(mod_simple_vhost_la_OBJECTS) $(mod_simple_vhost_la_DEPENDENCIES) 
+       $(LINK) -rpath $(libdir) $(mod_simple_vhost_la_LDFLAGS) $(mod_simple_vhost_la_OBJECTS) $(mod_simple_vhost_la_LIBADD) $(LIBS)
++mod_sql_vhost_core.la: $(mod_sql_vhost_core_la_OBJECTS) $(mod_sql_vhost_core_la_DEPENDENCIES) 
++      $(LINK) -rpath $(libdir) $(mod_sql_vhost_core_la_LDFLAGS) $(mod_sql_vhost_core_la_OBJECTS) $(mod_sql_vhost_core_la_LIBADD) $(LIBS)
+ mod_ssi.la: $(mod_ssi_la_OBJECTS) $(mod_ssi_la_DEPENDENCIES) 
+       $(LINK) -rpath $(libdir) $(mod_ssi_la_LDFLAGS) $(mod_ssi_la_OBJECTS) $(mod_ssi_la_LIBADD) $(LIBS)
+ mod_staticfile.la: $(mod_staticfile_la_OBJECTS) $(mod_staticfile_la_DEPENDENCIES) 
+@@ -863,6 +876,8 @@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/http_auth.Plo@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/http_auth_digest.Plo@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/http_chunk.Po@am__quote@
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/http_resp.Po@am__quote@
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/http_resp_parser.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/inet_ntop_cache.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/joblist.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keyvalue.Po@am__quote@
+@@ -890,6 +905,8 @@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblightcomp_la-fdevent_solaris_devpoll.Plo@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblightcomp_la-http-header-glue.Plo@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblightcomp_la-http_chunk.Plo@am__quote@
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblightcomp_la-http_resp.Plo@am__quote@
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblightcomp_la-http_resp_parser.Plo@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblightcomp_la-inet_ntop_cache.Plo@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblightcomp_la-joblist.Plo@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblightcomp_la-keyvalue.Plo@am__quote@
+@@ -932,6 +949,7 @@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_secure_download.Plo@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_setenv.Plo@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_simple_vhost.Plo@am__quote@
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_sql_vhost_core.Plo@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_ssi.Plo@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_ssi_expr.Plo@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_ssi_exprparser.Plo@am__quote@
+@@ -1247,6 +1265,20 @@
+ @AMDEP_TRUE@@am__fastdepCC_FALSE@     DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblightcomp_la_CFLAGS) $(CFLAGS) -c -o liblightcomp_la-splaytree.lo `test -f 'splaytree.c' || echo '$(srcdir)/'`splaytree.c
++liblightcomp_la-http_resp.lo: http_resp.c
++@am__fastdepCC_TRUE@  if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblightcomp_la_CFLAGS) $(CFLAGS) -MT liblightcomp_la-http_resp.lo -MD -MP -MF "$(DEPDIR)/liblightcomp_la-http_resp.Tpo" -c -o liblightcomp_la-http_resp.lo `test -f 'http_resp.c' || echo '$(srcdir)/'`http_resp.c; \
++@am__fastdepCC_TRUE@  then mv -f "$(DEPDIR)/liblightcomp_la-http_resp.Tpo" "$(DEPDIR)/liblightcomp_la-http_resp.Plo"; else rm -f "$(DEPDIR)/liblightcomp_la-http_resp.Tpo"; exit 1; fi
++@AMDEP_TRUE@@am__fastdepCC_FALSE@     source='http_resp.c' object='liblightcomp_la-http_resp.lo' libtool=yes @AMDEPBACKSLASH@
++@AMDEP_TRUE@@am__fastdepCC_FALSE@     DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
++@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblightcomp_la_CFLAGS) $(CFLAGS) -c -o liblightcomp_la-http_resp.lo `test -f 'http_resp.c' || echo '$(srcdir)/'`http_resp.c
++
++liblightcomp_la-http_resp_parser.lo: http_resp_parser.c
++@am__fastdepCC_TRUE@  if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblightcomp_la_CFLAGS) $(CFLAGS) -MT liblightcomp_la-http_resp_parser.lo -MD -MP -MF "$(DEPDIR)/liblightcomp_la-http_resp_parser.Tpo" -c -o liblightcomp_la-http_resp_parser.lo `test -f 'http_resp_parser.c' || echo '$(srcdir)/'`http_resp_parser.c; \
++@am__fastdepCC_TRUE@  then mv -f "$(DEPDIR)/liblightcomp_la-http_resp_parser.Tpo" "$(DEPDIR)/liblightcomp_la-http_resp_parser.Plo"; else rm -f "$(DEPDIR)/liblightcomp_la-http_resp_parser.Tpo"; exit 1; fi
++@AMDEP_TRUE@@am__fastdepCC_FALSE@     source='http_resp_parser.c' object='liblightcomp_la-http_resp_parser.lo' libtool=yes @AMDEPBACKSLASH@
++@AMDEP_TRUE@@am__fastdepCC_FALSE@     DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
++@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblightcomp_la_CFLAGS) $(CFLAGS) -c -o liblightcomp_la-http_resp_parser.lo `test -f 'http_resp_parser.c' || echo '$(srcdir)/'`http_resp_parser.c
++
+ mod_cml_la-mod_cml.lo: mod_cml.c
+ @am__fastdepCC_TRUE@  if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mod_cml_la_CFLAGS) $(CFLAGS) -MT mod_cml_la-mod_cml.lo -MD -MP -MF "$(DEPDIR)/mod_cml_la-mod_cml.Tpo" -c -o mod_cml_la-mod_cml.lo `test -f 'mod_cml.c' || echo '$(srcdir)/'`mod_cml.c; \
+ @am__fastdepCC_TRUE@  then mv -f "$(DEPDIR)/mod_cml_la-mod_cml.Tpo" "$(DEPDIR)/mod_cml_la-mod_cml.Plo"; else rm -f "$(DEPDIR)/mod_cml_la-mod_cml.Tpo"; exit 1; fi
+@@ -1506,14 +1538,19 @@
+ @CROSS_COMPILING_TRUE@mod_ssi_exprparser.c mod_ssi_exprparser.h: 
+ @CROSS_COMPILING_FALSE@configparser.y: lemon
+ @CROSS_COMPILING_FALSE@mod_ssi_exprparser.y: lemon
++@CROSS_COMPILING_FALSE@http_resp_parser.y: lemon
+ @CROSS_COMPILING_FALSE@configparser.c configparser.h: configparser.y
+ @CROSS_COMPILING_FALSE@       rm -f configparser.h
+-@CROSS_COMPILING_FALSE@       $(LEMON) -q $(srcdir)/configparser.y $(srcdir)/lempar.c
++@CROSS_COMPILING_FALSE@       $(LEMON) -q $(srcdir)/$< $(srcdir)/lempar.c
++
++@CROSS_COMPILING_FALSE@http_resp_parser.c http_resp_parser.h: http_resp_parser.y
++@CROSS_COMPILING_FALSE@       rm -f http_resp_parser.h
++@CROSS_COMPILING_FALSE@       $(LEMON) -q $(srcdir)/$< $(srcdir)/lempar.c
+ @CROSS_COMPILING_FALSE@mod_ssi_exprparser.c mod_ssi_exprparser.h: mod_ssi_exprparser.y 
+ @CROSS_COMPILING_FALSE@       rm -f mod_ssi_exprparser.h
+-@CROSS_COMPILING_FALSE@       $(LEMON) -q $(srcdir)/mod_ssi_exprparser.y $(srcdir)/lempar.c
++@CROSS_COMPILING_FALSE@       $(LEMON) -q $(srcdir)/$< $(srcdir)/lempar.c
+ configfile.c: configparser.h
+ mod_ssi_expr.c: mod_ssi_exprparser.h
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/array.c lighttpd-1.4.12/src/array.c
 --- lighttpd-1.4.11/src/array.c        2005-11-18 13:58:32.000000000 +0200
-+++ lighttpd/src/array.c       2006-07-11 21:23:39.943846207 +0300
-@@ -165,7 +165,7 @@
++++ lighttpd-1.4.12/src/array.c        2006-07-11 21:23:39.000000000 +0300
+@@ -11,12 +11,12 @@
+ array *array_init(void) {
+       array *a;
+-      
++
+       a = calloc(1, sizeof(*a));
+       assert(a);
+-      
++
+       a->next_power_of_2 = 1;
+-      
++
+       return a;
+ }
+@@ -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);
+ }
+ 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]);
+               }
+       }
+-      
++
+       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 @@
+               }
+               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);
+       if (a->size == 0) return NULL;
+-      
++
+       if (a->used == a->size) return NULL;
+       if (a->data[a->used]) {
+               ds = a->data[a->used];
+-              
++
+               a->data[a->used] = NULL;
+       }
+-      
++
+       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;
-@@ -215,7 +215,7 @@
+       }
+-      
++
+       /* 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;
+ }
+@@ -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, ")");
+-      
++
+       return 0;
+ }
+@@ -323,47 +323,47 @@
+       array *a;
+       data_string *ds;
+       data_count *dc;
+-      
++
+       UNUSED(argc);
+       UNUSED(argv);
+       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
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/array.h lighttpd-1.4.12/src/array.h
 --- lighttpd-1.4.11/src/array.h        2005-09-23 21:24:18.000000000 +0300
-+++ lighttpd/src/array.h       2006-07-11 21:23:39.963847460 +0300
++++ lighttpd-1.4.12/src/array.h        2006-07-11 21:23:39.000000000 +0300
 @@ -16,7 +16,7 @@
  #define DATA_UNSET \
        data_type_t type; \
        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,7 +60,7 @@
+ typedef struct {
+       DATA_UNSET;
+-      
++
+       array *value;
+ } data_array;
+@@ -74,7 +74,7 @@
+       COMP_SERVER_SOCKET, COMP_HTTP_URL, COMP_HTTP_HOST, COMP_HTTP_REFERER, COMP_HTTP_USERAGENT, COMP_HTTP_COOKIE, COMP_HTTP_REMOTEIP
+ } 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 +82,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 +98,7 @@
+       /* for chaining only */
+       data_config *prev;
+       data_config *next;
+-      
++
+       buffer *string;
+ #ifdef HAVE_PCRE_H
+       pcre   *regex;
+@@ -110,7 +110,7 @@
+ typedef struct {
+       DATA_UNSET;
+-      
++
+       int value;
+ } data_integer;
+@@ -120,13 +120,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;
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/base.h lighttpd-1.4.12/src/base.h
 --- lighttpd-1.4.11/src/base.h 2006-01-11 16:51:04.000000000 +0200
-+++ lighttpd/src/base.h        2006-07-11 21:23:39.947846458 +0300
++++ lighttpd-1.4.12/src/base.h 2006-07-11 21:23:39.000000000 +0300
 @@ -2,7 +2,6 @@
  #define _BASE_H_
  
  #include <sys/stat.h>
  
  #ifdef HAVE_CONFIG_H
-@@ -26,7 +25,6 @@
+@@ -26,10 +25,9 @@
  #include "sys-socket.h"
  #include "splaytree.h"
  
 -
  #if defined HAVE_LIBSSL && defined HAVE_OPENSSL_SSL_H
  # define USE_OPENSSL
- # include <openssl/ssl.h> 
+-# include <openssl/ssl.h> 
++# include <openssl/ssl.h>
+ #endif
+ #ifdef HAVE_FAM_H
 @@ -40,10 +38,6 @@
  # define O_BINARY 0
  #endif
  #endif
  
  
-@@ -171,7 +166,7 @@
+@@ -80,24 +75,24 @@
+ #include "settings.h"
+-typedef enum { T_CONFIG_UNSET, 
+-              T_CONFIG_STRING, 
+-              T_CONFIG_SHORT, 
+-              T_CONFIG_BOOLEAN, 
+-              T_CONFIG_ARRAY, 
+-              T_CONFIG_LOCAL, 
++typedef enum { T_CONFIG_UNSET,
++              T_CONFIG_STRING,
++              T_CONFIG_SHORT,
++              T_CONFIG_BOOLEAN,
++              T_CONFIG_ARRAY,
++              T_CONFIG_LOCAL,
+               T_CONFIG_DEPRECATED
+ } 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 {
-       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 */
-       
+       const char *key;
+       void *destination;
+-      
++
+       config_values_type_t type;
+       config_scope_type_t scope;
+ } config_values_t;
+@@ -142,40 +137,40 @@
+       /* 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;
+-      
++
        array  *headers;
-       
-@@ -215,7 +210,7 @@
+-      
++
+       /* CONTENT */
+       size_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 +186,21 @@
+ 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_FAM_H
+       int    dir_version;
+       int    dir_ndx;
+@@ -215,8 +210,8 @@
  } 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
-@@ -252,6 +247,7 @@
+       splay_tree *dirs; /* the nodes of the tree are fam_dir_entry */
+@@ -228,7 +223,7 @@
+ typedef struct {
+       array *mimetypes;
+-      
++
+       /* virtual-servers */
+       buffer *document_root;
+       buffer *server_name;
+@@ -236,7 +231,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 +239,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 */
-@@ -272,13 +268,13 @@
+       buffer *ssl_pemfile;
+       buffer *ssl_ca_file;
+@@ -268,22 +264,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
 -       * we somehow have to loose our "we are writable" signal 
 +       * we somehow have to lose our "we are writable" signal
         * on the way.
-        * 
+-       * 
++       *
         */
-@@ -341,7 +337,7 @@
+       off_t *global_bytes_per_second_cnt_ptr; /*  */
+-      
++
+ #ifdef USE_OPENSSL
+       SSL_CTX *ssl_ctx;
+ #endif
+@@ -291,18 +287,18 @@
+ /* 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,
++      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
+ } connection_state_t;
+ typedef enum { COND_RESULT_UNSET, COND_RESULT_FALSE, COND_RESULT_TRUE } cond_result_t;
+@@ -315,88 +311,88 @@
+ 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 */
+       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;
-@@ -439,6 +435,15 @@
+-      
++
+       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 ]*/
+-      
++
+       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 */
+-      
++
+       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
+@@ -439,39 +435,48 @@
        size_t size;
  } buffer_plugin;
  
  typedef struct {
        unsigned short port;
        buffer *bindhost;
-@@ -591,15 +596,17 @@
-       
+-      
++
+       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;
+ } server_config;
+@@ -480,14 +485,14 @@
+       sock_addr addr;
+       int       fd;
+       int       fde_ndx;
+-      
++
+       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 +500,37 @@
+ 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 +538,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,31 +552,31 @@
+       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;
+-      
++
+       connections *conns;
+       connections *joblist;
+       connections *fdwaitqueue;
+-      
++
+       stat_cache  *stat_cache;
+       /**
+@@ -588,18 +593,20 @@
+        *   fastcgi.backend.<key>.disconnects = ...
+        */
+       array *status;
+-      
++
        fdevent_handler_t event_handler;
  
 -      int (* network_backend_write)(struct server *srv, connection *con, int fd, chunkqueue *cq);
  } server;
  
  
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/buffer.c lighttpd-1.4.12/src/buffer.c
 --- lighttpd-1.4.11/src/buffer.c       2006-01-13 00:00:45.000000000 +0200
-+++ lighttpd/src/buffer.c      2006-07-11 21:23:40.087855227 +0300
-@@ -63,7 +63,7 @@
++++ lighttpd-1.4.12/src/buffer.c       2006-07-11 21:23: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
-  * 
+- * 
++ *
   */
-@@ -79,7 +79,7 @@
-               
+ #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);
-@@ -91,7 +91,7 @@
+               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
-  * 
+- * 
++ *
   */
-@@ -102,7 +102,7 @@
+ 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);
-@@ -111,7 +111,7 @@
+               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);
-@@ -203,7 +203,7 @@
+               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' 
+- * 
+- * 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
-@@ -402,6 +402,75 @@
+  * @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
 + *
 + */
 +}
 +
 +/**
-  * init the buffer 
-  * 
++ * 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
++ *
   */
-@@ -507,7 +576,7 @@
+ 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.
-@@ -531,7 +600,7 @@
+  */
+@@ -522,100 +591,100 @@
+ 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) {
-@@ -592,7 +661,7 @@
+       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, 
++
++      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,13 @@
+       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 (s_len == 0) return 0;
+       switch(encoding) {
 @@ -760,12 +829,12 @@
                map = encoded_chars_hex;
                break;
        }
  
        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) {
-@@ -829,7 +898,7 @@
+@@ -787,9 +856,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 +889,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;
  }
  
  
   * replaces non-printable characters with '_'
   */
  
-@@ -855,7 +924,7 @@
+@@ -854,10 +923,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 +960,7 @@
   * /abc/./xyz       gets  /abc/xyz
   * /abc//xyz        gets  /abc/xyz
   *       the operation is performed in-place.
   */
  
-@@ -993,6 +1062,31 @@
+@@ -979,7 +1048,7 @@
+ int light_isxdigit(int c) {
+       if (light_isdigit(c)) return 1;
+-      
++
+       c |= 32;
+       return (c >= 'a' && c <= 'f');
+ }
+@@ -993,31 +1062,56 @@
        return light_isdigit(c) || light_isalpha(c);
  }
  
 +
  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;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/buffer.h lighttpd-1.4.12/src/buffer.h
 --- lighttpd-1.4.11/src/buffer.h       2006-01-13 00:00:45.000000000 +0200
-+++ lighttpd/src/buffer.h      2006-07-11 21:23:40.095855728 +0300
-@@ -17,6 +17,16 @@
++++ lighttpd-1.4.12/src/buffer.h       2006-07-11 21:23:40.000000000 +0300
+@@ -12,27 +12,44 @@
+ typedef struct {
+       char *ptr;
+-      
++
+       size_t used;
        size_t size;
  } buffer;
  
 +
  typedef struct {
        buffer **ptr;
-       
-@@ -27,12 +37,19 @@
- typedef struct {
-       char *ptr;
-       
+-      
++
+       size_t used;
+       size_t size;
+ } buffer_array;
+ typedef struct {
+       char *ptr;
+-      
 -      size_t offset; /* input-pointer */
-+      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_array* buffer_array_init(void);
  void buffer_array_free(buffer_array *b);
  void buffer_array_reset(buffer_array *b);
+@@ -43,7 +60,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 +102,9 @@
  
  typedef enum {
  #define SEGFAULT() do { fprintf(stderr, "%s.%d: aborted\n", __FILE__, __LINE__); abort(); } while(0)
  #define UNUSED(x) ( (void)(x) )
  
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/chunk.c lighttpd-1.4.12/src/chunk.c
 --- lighttpd-1.4.11/src/chunk.c        2005-11-18 15:18:19.000000000 +0200
-+++ lighttpd/src/chunk.c       2006-07-11 21:23:39.995849464 +0300
-@@ -6,11 +6,9 @@
++++ lighttpd-1.4.12/src/chunk.c        2006-07-11 21:23:39.000000000 +0300
+@@ -1,16 +1,14 @@
+ /**
+  * the network chunk-API
+- * 
+- * 
++ *
++ *
+  */
  
  #include <sys/types.h>
  #include <sys/stat.h>
  
  #include <stdio.h>
  #include <errno.h>
-@@ -18,6 +16,9 @@
+@@ -18,36 +16,39 @@
  
  #include "chunk.h"
  
 +
  chunkqueue *chunkqueue_init(void) {
        chunkqueue *cq;
-       
-@@ -99,7 +100,7 @@
+-      
++
+       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 {
-@@ -278,7 +279,7 @@
+@@ -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;
+               }
+       }
+@@ -162,93 +163,93 @@
+ 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 +264,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 +274,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_STRING_CONST(template, "lighttpd-upload-XXXXXX");
  
                        if (-1 != (c->file.fd = mkstemp(template->ptr))) {
+@@ -300,7 +301,7 @@
+       chunkqueue_append_chunk(cq, c);
+       buffer_free(template);
+-      
++
+       return c;
+ }
+@@ -308,7 +309,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 +322,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 +340,7 @@
+                       break;
+               }
+       }
+-      
++
+       return len;
+ }
+@@ -358,9 +359,9 @@
+                       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;
+               }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/chunk.h lighttpd-1.4.12/src/chunk.h
 --- lighttpd-1.4.11/src/chunk.h        2005-11-01 09:32:21.000000000 +0200
-+++ lighttpd/src/chunk.h       2006-07-11 21:23:40.015850717 +0300
-@@ -19,10 +19,10 @@
-               struct { 
++++ lighttpd-1.4.12/src/chunk.h        2006-07-11 21:23:40.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,28 +16,28 @@
+               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 */
 -              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 
+-      
+-      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;
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/configfile-glue.c lighttpd-1.4.12/src/configfile-glue.c
 --- lighttpd-1.4.11/src/configfile-glue.c      2006-03-03 20:14:56.000000000 +0200
-+++ lighttpd/src/configfile-glue.c     2006-07-11 21:23:39.879842199 +0300
++++ lighttpd-1.4.12/src/configfile-glue.c      2006-07-11 21:23:39.000000000 +0300
 @@ -1,4 +1,5 @@
  #include <string.h>
 +#include <ctype.h>
  
  #include "base.h"
  #include "buffer.h"
-@@ -71,6 +72,10 @@
-                               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;
+@@ -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;
+-      
 +
-+                              buffer_copy_long(cv[i].destination, di->value);
-                       } else {
-                               log_error_write(srv, __FILE__, __LINE__, "ssss", "unexpected type for key: ", cv[i].key, "(string)", "\"...\"");
-                               
-@@ -88,6 +93,11 @@
-                       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;
-+                              }
+       for (i = 0; cv[i].key; i++) {
+-              
 +
-                               log_error_write(srv, __FILE__, __LINE__, "ssb", "get a string but expected a short:", cv[i].key, ds->value);
-                               
-                               return -1;
-@@ -230,7 +240,7 @@
-                               break;
-                       }
-               } else {
--                      l = NULL;
+               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,19 +110,19 @@
+               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;
+@@ -121,9 +131,9 @@
+                       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 +143,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 +201,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 +240,21 @@
+                               break;
+                       }
+               } else {
+-                      l = NULL;
 +                      l = srv->empty_string;
                }
                break;
        }
-@@ -254,6 +264,13 @@
+       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 +263,48 @@
+                       long nm;
                        char *err;
                        struct in_addr val_inp;
-                       
+-                      
++
 +                      if (con->conf.log_condition_handling) {
 +                              l = srv->empty_string;
 +
 +
                        if (*(nm_slash+1) == '\0') {
                                log_error_write(srv, __FILE__, __LINE__, "sb", "ERROR: no number after / ", dc->string);
-                                       
-@@ -270,7 +287,7 @@
-                       
+-                                      
++
+                               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 {
+@@ -308,7 +325,7 @@
+       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 +355,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 +363,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 +382,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 +404,7 @@
+               /* no way */
+               break;
+       }
+-      
++
+       return COND_RESULT_FALSE;
+ }
 @@ -395,6 +412,9 @@
        cond_cache_t *caches = con->cond_cache;
  
 +#endif
 +}
 +
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/configfile.c lighttpd-1.4.12/src/configfile.c
 --- lighttpd-1.4.11/src/configfile.c   2006-02-15 14:26:42.000000000 +0200
-+++ lighttpd/src/configfile.c  2006-07-11 21:23:39.987848963 +0300
++++ lighttpd-1.4.12/src/configfile.c   2006-07-11 21:23:39.000000000 +0300
 @@ -2,7 +2,6 @@
  
  #include <stdlib.h>
  #include <errno.h>
  #include <string.h>
  #include <stdio.h>
-@@ -13,14 +12,17 @@
+@@ -13,21 +12,24 @@
  #include "log.h"
  #include "stream.h"
  #include "plugin.h"
  
  static int config_insert(server *srv) {
        size_t i;
-@@ -80,6 +82,7 @@
+       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,7 +51,7 @@
+               { "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 */
+@@ -60,19 +62,19 @@
+               { "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 +82,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 },
-@@ -165,6 +168,7 @@
+               { "server.virtual-root",         "load mod_simple_vhost and use simple-vhost.server-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET },
+@@ -90,11 +93,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 +105,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();
+@@ -154,17 +157,18 @@
+               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[17].destination = &(s->max_keep_alive_requests);
                cv[18].destination = s->server_name;
                cv[19].destination = &(s->max_keep_alive_idle);
-@@ -216,8 +220,8 @@
-                                                                
- }
+@@ -179,23 +183,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 +209,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];
-       
-@@ -244,6 +248,7 @@
-       PATCH(log_response_header);
-       PATCH(log_request_handling);
-       PATCH(log_condition_handling);
-+      PATCH(log_condition_cache_handling);
+-      
++
+       PATCH(allow_http11);
+       PATCH(mimetypes);
+       PATCH(document_root);
+@@ -236,20 +240,21 @@
+       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);
-@@ -315,6 +320,8 @@
+       PATCH(force_lowercase_filenames);
+       PATCH(is_ssl);
+-      
++
+       PATCH(ssl_pemfile);
+       PATCH(ssl_ca_file);
+       return 0;
+@@ -257,22 +262,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"))) {
+@@ -315,11 +320,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-file-not-found"))) {
                                PATCH(log_file_not_found);
                        } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.protocol-http11"))) {
-@@ -699,21 +706,13 @@
+                               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 +335,7 @@
+                       }
+               }
+       }
+-      
++
+       return 0;
+ }
+ #undef PATCH
+@@ -336,15 +343,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 +369,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 +380,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 +408,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 +418,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 +463,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 +553,10 @@
+               case ',':
+                       if (t->in_brace > 0) {
+                               tid = TK_COMMA;
+-                              
++
+                               buffer_copy_string(token, "(COMMA)");
+                       }
+-                      
++
+                       t->offset++;
+                       t->line_pos++;
+                       break;
+@@ -557,70 +564,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,96 +644,88 @@
+               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 {
                                }
                        } else {
                                /* the key might consist of [-.0-9a-z] */
-@@ -781,6 +780,7 @@
+-                              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) {
+                                               tid = TK_INCLUDE;
+                                       } else if (strcmp(token->ptr, "include_shell") == 0) {
+@@ -738,14 +737,14 @@
+                                       } 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 +752,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 +780,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);
-@@ -896,13 +896,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);
+-              
++
+               token = buffer_init();
+       }
+       buffer_free(token);
+@@ -797,14 +797,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 +821,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 +844,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 +866,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 +879,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 +896,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,13 +917,10 @@
+@@ -918,18 +917,15 @@
        context_init(srv, &context);
        context.all_configs = srv->config_context;
  
        if (pos) {
                buffer_copy_string_len(context.basedir, fn, pos - fn + 1);
                fn = pos + 1;
-@@ -1035,6 +1031,7 @@
+       }
+-      
++
+       dc = data_config_init();
+       buffer_copy_string(dc->key, "global");
+@@ -944,7 +940,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 +964,7 @@
+       } else {
+               return -1;
+       }
+-      
++
+       if (NULL != (modules = (data_array *)array_get_element(srv->config, "server.modules"))) {
+               data_string *ds;
+               data_array *prepends;
+@@ -1026,22 +1022,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];
-@@ -1077,10 +1074,11 @@
-       }  
-       
+       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 +1064,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)) {
-+        pathname_unix2local(s->document_root);
-               if (-1 == stat(s->document_root->ptr, &st1)) {  
+-              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);  
                        return -1;
                }
  
+@@ -1088,18 +1086,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 +1105,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 +1174,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;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/configfile.h lighttpd-1.4.12/src/configfile.h
 --- lighttpd-1.4.11/src/configfile.h   2005-08-23 17:36:12.000000000 +0300
-+++ lighttpd/src/configfile.h  2006-07-11 21:23:39.995849464 +0300
++++ lighttpd-1.4.12/src/configfile.h   2006-07-11 21:23:39.000000000 +0300
 @@ -9,7 +9,7 @@
        server *srv;
        int     ok;
        data_config *current; /* current started with { */
        buffer *basedir;
  } config_t;
---- lighttpd-1.4.11/src/configparser.y 2006-01-26 18:46:25.000000000 +0200
-+++ lighttpd/src/configparser.y        2006-07-11 21:23:40.127857732 +0300
-@@ -21,33 +21,18 @@
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/configparser.c lighttpd-1.4.12/src/configparser.c
+--- lighttpd-1.4.11/src/configparser.c 2006-02-01 19:51:15.000000000 +0200
++++ lighttpd-1.4.12/src/configparser.c 2006-07-11 21:49:18.000000000 +0300
+@@ -24,52 +24,34 @@
      dc->parent = ctx->current;
      array_insert_unique(dc->parent->childs, (data_unset *)dc);
    }
 -
 -    return NULL;
 -  } else {
-     data_unset *du;
-     data_config *dc;
+-    data_unset *du;
+-    data_config *dc;
++  data_unset *du;
++  data_config *dc;
  
-@@ -63,11 +48,8 @@
-         return du->copy(du);
-       }
+ #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;
    }
--}
++  return NULL;
+ }
  
  /* op1 is to be eat/return by this function, op1->key is not cared
-    op2 is left untouch, unreferenced
-@@ -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 @@
+@@ -124,14 +106,14 @@
+ }
  
- 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) {
+-#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, A->ptr);
++        ctx->current->key->ptr, yymsp[-2].minor.yy43->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 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 {
-@@ -180,7 +168,12 @@
+@@ -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, A->ptr))) {
-+  if (strncmp(A->ptr, "env.", sizeof("env.") - 1) == 0) {
+-  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, A->ptr);
++        ctx->current->key->ptr, yymsp[-2].minor.yy43->ptr);
 +    ctx->ok = 0;
-+  } else if (NULL != (du = array_get_element(vars, A->ptr))) {
++  } else if (NULL != (du = array_get_element(vars, yymsp[-2].minor.yy43->ptr))) {
      /* exists in current block */
-     du = configparser_merge_data(du, B);
+     du = configparser_merge_data(du, yymsp[0].minor.yy41);
      if (NULL == du) {
-@@ -190,6 +183,7 @@
-       buffer_copy_string_buffer(du->key, A);
+@@ -883,6 +879,7 @@
+       buffer_copy_string_buffer(du->key, yymsp[-2].minor.yy43);
        array_replace(vars, du);
      }
-+    B->free(B);
-   } else if (NULL != (du = configparser_get_variable(ctx, A))) {
-     du = configparser_merge_data(du, B);
++    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) {
-@@ -199,15 +193,13 @@
-       buffer_copy_string_buffer(du->key, A);
+@@ -892,22 +889,20 @@
+       buffer_copy_string_buffer(du->key, yymsp[-2].minor.yy43);
        array_insert_unique(ctx->current->value, du);
      }
-+    B->free(B);
++    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, A->ptr);
+-            ctx->current->key->ptr, yymsp[-2].minor.yy43->ptr);
 -    ctx->ok = 0;
-+    buffer_copy_string_buffer(B->key, A);
-+    array_insert_unique(ctx->current->value, B);
++    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(A);
-   A = NULL;
--  B->free(B);
-   B = NULL;
+   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;
  }
-@@ -239,7 +231,24 @@
+-#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;
+   }
  }
- value(A) ::= key(B). {
--  A = configparser_get_variable(ctx, B);
-+  if (strncmp(B->ptr, "env.", sizeof("env.") - 1) == 0) {
+-#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(B->ptr + 4))) {
++    if (NULL != (env = getenv(yymsp[0].minor.yy43->ptr + 4))) {
 +      data_string *ds;
 +      ds = data_string_init();
 +      buffer_append_string(ds->value, env);
-+      A = (data_unset *)ds;
++      yygotominor.yy41 = (data_unset *)ds;
 +    }
 +    else {
-+      A = NULL;
-+      fprintf(stderr, "Undefined env variable: %s\n", B->ptr + 4);
++      yygotominor.yy41 = NULL;
++      fprintf(stderr, "Undefined env variable: %s\n", yymsp[0].minor.yy43->ptr + 4);
 +      ctx->ok = 0;
 +    }
-+  } else if (NULL == (A = configparser_get_variable(ctx, B))) {
-+    fprintf(stderr, "Undefined config variable: %s\n", B->ptr);
++  } 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 (!A) {
+   if (!yygotominor.yy41) {
      /* 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;
+     yygotominor.yy41 = (data_unset *)data_string_init();
+@@ -954,50 +966,59 @@
+   buffer_free(yymsp[0].minor.yy43);
+   yymsp[0].minor.yy43 = NULL;
  }
-+array(A) ::= LPARAN RPARAN. {
-+  A = array_init();
+-#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();
 +}
- array(A) ::= LPARAN aelements(B) RPARAN. {
-   A = B;
-   B = NULL;
---- lighttpd-1.4.11/src/connections.c  2006-03-05 22:14:53.000000000 +0200
-+++ lighttpd/src/connections.c 2006-07-11 21:23:39.955846959 +0300
-@@ -2,7 +2,6 @@
- #include <stdlib.h>
- #include <stdio.h>
--#include <unistd.h>
- #include <errno.h>
- #include <string.h>
- #include <fcntl.h>
++#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;
+@@ -1266,45 +1287,45 @@
+   yymsp[0].minor.yy41->free(yymsp[0].minor.yy41);
+   yymsp[0].minor.yy41 = NULL;
+ }
+-#line 1269 "configparser.c"
++#line 1290 "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 508 "./configparser.y"
+ {
+   yygotominor.yy27 = CONFIG_COND_EQ;
+ }
+-#line 1279 "configparser.c"
++#line 1300 "configparser.c"
+   yy_destructor(20,&yymsp[0].minor);
+         break;
+-      case 33:
+-#line 499 "./configparser.y"
++      case 34:
++#line 511 "./configparser.y"
+ {
+   yygotominor.yy27 = CONFIG_COND_MATCH;
+ }
+-#line 1287 "configparser.c"
++#line 1308 "configparser.c"
+   yy_destructor(21,&yymsp[0].minor);
+         break;
+-      case 34:
+-#line 502 "./configparser.y"
++      case 35:
++#line 514 "./configparser.y"
+ {
+   yygotominor.yy27 = CONFIG_COND_NE;
+ }
+-#line 1295 "configparser.c"
++#line 1316 "configparser.c"
+   yy_destructor(22,&yymsp[0].minor);
+         break;
+-      case 35:
+-#line 505 "./configparser.y"
++      case 36:
++#line 517 "./configparser.y"
+ {
+   yygotominor.yy27 = CONFIG_COND_NOMATCH;
+ }
+-#line 1303 "configparser.c"
++#line 1324 "configparser.c"
+   yy_destructor(23,&yymsp[0].minor);
+         break;
+-      case 36:
+-#line 509 "./configparser.y"
++      case 37:
++#line 521 "./configparser.y"
+ {
+   yygotominor.yy43 = NULL;
+   if (ctx->ok) {
+@@ -1321,10 +1342,10 @@
+   yymsp[0].minor.yy41->free(yymsp[0].minor.yy41);
+   yymsp[0].minor.yy41 = NULL;
+ }
+-#line 1324 "configparser.c"
++#line 1345 "configparser.c"
+         break;
+-      case 37:
+-#line 526 "./configparser.y"
++      case 38:
++#line 538 "./configparser.y"
+ {
+   if (ctx->ok) {
+     if (0 != config_parse_file(ctx->srv, ctx, yymsp[0].minor.yy43->ptr)) {
+@@ -1334,11 +1355,11 @@
+     yymsp[0].minor.yy43 = NULL;
+   }
+ }
+-#line 1337 "configparser.c"
++#line 1358 "configparser.c"
+   yy_destructor(24,&yymsp[-1].minor);
+         break;
+-      case 38:
+-#line 536 "./configparser.y"
++      case 39:
++#line 548 "./configparser.y"
+ {
+   if (ctx->ok) {
+     if (0 != config_parse_cmd(ctx->srv, ctx, yymsp[0].minor.yy43->ptr)) {
+@@ -1348,7 +1369,7 @@
+     yymsp[0].minor.yy43 = NULL;
+   }
+ }
+-#line 1351 "configparser.c"
++#line 1372 "configparser.c"
+   yy_destructor(25,&yymsp[-1].minor);
+         break;
+   };
+@@ -1378,11 +1399,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 1406 "configparser.c"
+   configparserARG_STORE; /* Suppress warning about unused %extra_argument variable */
+ }
+@@ -1489,7 +1510,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:
+       **
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/configparser.y lighttpd-1.4.12/src/configparser.y
+--- lighttpd-1.4.11/src/configparser.y 2006-01-26 18:46:25.000000000 +0200
++++ lighttpd-1.4.12/src/configparser.y 2006-07-11 21:23:40.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;
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/connections-glue.c lighttpd-1.4.12/src/connections-glue.c
+--- lighttpd-1.4.11/src/connections-glue.c     2005-09-12 10:04:23.000000000 +0300
++++ lighttpd-1.4.12/src/connections-glue.c     2006-07-11 21:23:39.000000000 +0300
+@@ -13,7 +13,7 @@
+       case CON_STATE_REQUEST_END: return "req-end";
+       case CON_STATE_RESPONSE_START: return "resp-start";
+       case CON_STATE_RESPONSE_END: return "resp-end";
+-      default: return "(unknown)";    
++      default: return "(unknown)";
+       }
+ }
+@@ -30,15 +30,15 @@
+       case CON_STATE_REQUEST_END: return "Q";
+       case CON_STATE_RESPONSE_START: return "s";
+       case CON_STATE_RESPONSE_END: return "S";
+-      default: return "x";    
++      default: return "x";
+       }
+ }
+ int connection_set_state(server *srv, connection *con, connection_state_t state) {
+       UNUSED(srv);
+-      
++
+       con->state = state;
+-      
++
+       return 0;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/connections.c lighttpd-1.4.12/src/connections.c
+--- lighttpd-1.4.11/src/connections.c  2006-03-05 22:14:53.000000000 +0200
++++ lighttpd-1.4.12/src/connections.c  2006-07-11 21:23:39.000000000 +0300
+@@ -2,7 +2,6 @@
+ #include <stdlib.h>
+ #include <stdio.h>
+-#include <unistd.h>
+ #include <errno.h>
+ #include <string.h>
+ #include <fcntl.h>
+@@ -26,8 +25,8 @@
+ #include "inet_ntop_cache.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,6 +34,7 @@
  #endif
  
  
  typedef struct {
                PLUGIN_DATA;
-@@ -111,9 +111,7 @@
- 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;
-@@ -122,7 +120,7 @@
-       
-       fdevent_event_del(srv->ev, &(con->fde_ndx), con->fd);
-       fdevent_unregister(srv->ev, con->fd);
--#ifdef __WIN32
-+#ifdef _WIN32
-       if (closesocket(con->fd)) {
-               log_error_write(srv, __FILE__, __LINE__, "sds",
-                               "(warning) close:", con->fd, strerror(errno));
-@@ -190,150 +188,39 @@
- }
- #endif 
+@@ -43,7 +43,7 @@
+ 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 +54,21 @@
+       } 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);
+               }
+       }
  
--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
+       connection_reset(srv, conns->ptr[conns->used]);
+-#if 0 
++#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        
+-      
++#endif
++
+       conns->ptr[conns->used]->ndx = conns->used;
+       return conns->ptr[conns->used++];
+ }
+@@ -77,26 +77,26 @@
+       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);
+@@ -104,25 +104,23 @@
+               fprintf(stderr, "%d ", conns->ptr[i]->fd);
+       }
+       fprintf(stderr, "\n");
+-#endif        
++#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;
+       }
+ #endif
+-      
++
+       fdevent_event_del(srv->ev, &(con->fde_ndx), con->fd);
+       fdevent_unregister(srv->ev, con->fd);
+-#ifdef __WIN32
++#ifdef _WIN32
+       if (closesocket(con->fd)) {
+               log_error_write(srv, __FILE__, __LINE__, "sds",
+                               "(warning) close:", con->fd, strerror(errno));
+@@ -133,207 +131,96 @@
+                               "(warning) close:", con->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);
--
++static network_status_t connection_handle_read(server *srv, connection *con) {
++      off_t oldlen, newlen;
 -#ifdef USE_OPENSSL
 -      if (srv_sock->is_ssl) {
 -              len = SSL_read(con->ssl, b->ptr, b->size - 1);
 -                      return -1;
 -              }
 -              buffer_prepare_copy(b, toread);
--
++    oldlen = chunkqueue_length(con->read_queue);
 -              len = read(con->fd, b->ptr, b->size - 1);
 -      }
 -#elif defined(__WIN32)
 -                                      log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:", 
 -                                                      r, ERR_error_string(ssl_err, NULL));
 -                              }
--
++    switch(network_read_chunkqueue(srv, con, con->read_queue)) {
++    case NETWORK_STATUS_SUCCESS:
++        break;
++    case NETWORK_STATUS_WAIT_FOR_EVENT:
++        con->is_readable = 0;
++        return NETWORK_STATUS_WAIT_FOR_EVENT;
++    case NETWORK_STATUS_INTERRUPTED:
++        con->is_readable = 1;
++        return NETWORK_STATUS_WAIT_FOR_EVENT;
++    case NETWORK_STATUS_CONNECTION_CLOSE:
++        /* pipelining */
++        con->is_readable = 0;
++        return NETWORK_STATUS_CONNECTION_CLOSE;
++    case NETWORK_STATUS_FATAL_ERROR:
++        con->is_readable = 0;
++
++        connection_set_state(srv, con, CON_STATE_ERROR);
++        return NETWORK_STATUS_FATAL_ERROR;
++    default:
++        SEGFAULT();
++        break;
++    }
 -                              switch(errno) {
 -                              default:
 -                                      log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL:", 
 -                              break;
 -                      case SSL_ERROR_ZERO_RETURN:
 -                              /* clean shutdown on the remote side */
-+static network_status_t connection_handle_read(server *srv, connection *con) {
-+      off_t oldlen, newlen;
-                               
+-                              
 -                              if (r == 0) {
 -                                      /* FIXME: later */
 -                              }
-+    oldlen = chunkqueue_length(con->read_queue);
-                               
+-                              
 -                              /* fall thourgh */
 -                      default:
 -                              while((ssl_err = ERR_get_error())) {
 -                                      log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:", 
 -                                                      r, ERR_error_string(ssl_err, NULL));
 -                              }
-+    switch(network_read_chunkqueue(srv, con, con->read_queue)) {
-+    case NETWORK_STATUS_SUCCESS:
-                               break;
+-                              break;
 -                      }
 -              } else {
 -                      if (errno == EAGAIN) return 0;
 -              
 -              return -1;
 -      } else if (len == 0) {
-+    case NETWORK_STATUS_WAIT_FOR_EVENT:
-               con->is_readable = 0;
+-              con->is_readable = 0;
 -              /* the other end close the connection -> KEEP-ALIVE */
 -
-+        return NETWORK_STATUS_WAIT_FOR_EVENT;
-+    case NETWORK_STATUS_INTERRUPTED:
-+        con->is_readable = 1;
-+        return NETWORK_STATUS_WAIT_FOR_EVENT;
-+    case NETWORK_STATUS_CONNECTION_CLOSE:
-               /* pipelining */
+-              /* 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;
-+        return NETWORK_STATUS_CONNECTION_CLOSE;
-+    case NETWORK_STATUS_FATAL_ERROR:
-+        con->is_readable = 0;
-+
-+        connection_set_state(srv, con, CON_STATE_ERROR);
-+        return NETWORK_STATUS_FATAL_ERROR;
-+    default:
-+        SEGFAULT();
-+        break;
-       }
-       
+-              con->is_readable = 0;
+-      }
+-      
 -      b->used = len;
 -      b->ptr[b->used++] = '\0';
-+    newlen = chunkqueue_length(con->read_queue);
-       
+-      
 -      con->bytes_read += len;
 -#if 0
 -      dump_packet(b->ptr, len);
 -#endif
-+      con->bytes_read += (newlen - oldlen);
-       
+-      
 -      return 0;
++    newlen = chunkqueue_length(con->read_queue);
++
++      con->bytes_read += (newlen - oldlen);
++
 +      return NETWORK_STATUS_SUCCESS;
  }
  
                case HTTP_METHOD_PUT:
                case HTTP_METHOD_MKCOL:
                case HTTP_METHOD_DELETE:
-@@ -350,6 +238,8 @@
+@@ -350,12 +238,14 @@
                case HTTP_METHOD_MOVE:
                case HTTP_METHOD_PROPFIND:
                case HTTP_METHOD_PROPPATCH:
                        break;
                case HTTP_METHOD_OPTIONS:
                        /*
-@@ -392,6 +282,8 @@
+                        * 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] != '*') {
+@@ -381,55 +271,58 @@
+                       break;
+               }
+       }
+-      
++
+       if (con->http_status == 0) {
+               con->http_status = 403;
+       }
+-      
++
+       switch(con->http_status) {
+       case 400: /* class: header + custom body */
+       case 401:
        case 403:
        case 404:
        case 408:
        case 411:
        case 416:
        case 423:
-@@ -399,6 +291,7 @@
+       case 500:
        case 501:
        case 503:
-       case 505: 
+-      case 505: 
++      case 505:
 +      case 509:
                if (con->mode != DIRECT) break;
-               
+-              
++
                con->file_finished = 0;
-@@ -528,34 +421,37 @@
- static int connection_handle_write(server *srv, connection *con) {
-       switch(network_write_chunkqueue(srv, con, con->write_queue)) {
--      case 0:
-+      case NETWORK_STATUS_SUCCESS:
-               if (con->file_finished) {
-                       connection_set_state(srv, con, CON_STATE_RESPONSE_END);
-                       joblist_append(srv, con);
+-              
++
+               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);
+                               response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(sce->content_type));
+                       }
                }
+-              
+-              if (!con->file_finished) {                      
++
++              if (!con->file_finished) {
+                       buffer *b;
+-                      
++
+                       buffer_reset(con->physical.path);
+-                      
++
+                       con->file_finished = 1;
+                       b = chunkqueue_get_append_buffer(con->write_queue);
+-                              
++
+                       /* 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 +332,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 +341,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,10 +356,10 @@
+       case 301:
+       case 302:
                break;
--      case -1: /* error on our side */
-+      case NETWORK_STATUS_FATAL_ERROR: /* 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 */
-+      case NETWORK_STATUS_CONNECTION_CLOSE: /* remote close */
-               connection_set_state(srv, con, CON_STATE_ERROR);
-               joblist_append(srv, con);
+-              
++
+       case 206: /* write_queue is already prepared */
+               con->file_finished = 1;
+-              
++
                break;
--      case 1:
-+      case NETWORK_STATUS_WAIT_FOR_EVENT:
-               con->is_writable = 0;
-               
-               /* not finished yet -> WRITE */
+       case 205: /* class: header only */
+       case 304:
+@@ -474,19 +367,19 @@
+               /* 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;
                break;
-+      case NETWORK_STATUS_INTERRUPTED:
-+              con->is_writable = 1;
-+              break;
-+      case NETWORK_STATUS_UNSET:
-+              break;
        }
-       
-       return 0;
- }
+-      
++
  
--
+       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)) && 
++              /* 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));
+-              
++
+                       response_header_overwrite(srv, con, CONST_STR_LEN("Content-Length"), CONST_BUF_LEN(srv->tmp_buf));
+               }
+       } else {
+@@ -495,74 +388,77 @@
+                   ((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) {
+                               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);
+       }
+       http_response_write_header(srv, con);
+-              
++
+       return 0;
+ }
+ static int connection_handle_write(server *srv, connection *con) {
+-      switch(network_write_chunkqueue(srv, con, con->write_queue)) {
+-      case 0:
++    switch(network_write_chunkqueue(srv, con, con->write_queue)) {
++      case NETWORK_STATUS_SUCCESS:
+               if (con->file_finished) {
+                       connection_set_state(srv, con, CON_STATE_RESPONSE_END);
+                       joblist_append(srv, con);
+               }
+               break;
+-      case -1: /* error on our side */
++      case NETWORK_STATUS_FATAL_ERROR: /* 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 */
++      case NETWORK_STATUS_CONNECTION_CLOSE: /* remote close */
+               connection_set_state(srv, con, CON_STATE_ERROR);
+               joblist_append(srv, con);
+               break;
+-      case 1:
++      case NETWORK_STATUS_WAIT_FOR_EVENT:
+               con->is_writable = 0;
+-              
++
+               /* not finished yet -> WRITE */
+               break;
++      case NETWORK_STATUS_INTERRUPTED:
++              con->is_writable = 1;
++              break;
++      case NETWORK_STATUS_UNSET:
++              break;
+       }
+-      
++
+       return 0;
+ }
+-
 -
  connection *connection_init(server *srv) {
        connection *con;
-       
-@@ -845,17 +741,20 @@
+-      
++
+       UNUSED(srv);
+       con = calloc(1, sizeof(*con));
+-              
++
+       con->fd = 0;
+       con->ndx = -1;
+       con->fde_ndx = -1;
+@@ -573,32 +469,32 @@
+ #define CLEAN(x) \
+       con->x = buffer_init();
+-      
++
+       CLEAN(request.uri);
+       CLEAN(request.request_line);
+       CLEAN(request.request);
+       CLEAN(request.pathinfo);
+-      
++
+       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();
+@@ -608,26 +504,26 @@
+       con->request.headers      = array_init();
+       con->response.headers     = array_init();
+       con->environment     = array_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);
+@@ -637,27 +533,27 @@
+ #define CLEAN(x) \
+       buffer_free(con->x);
+-              
++
+               CLEAN(request.uri);
+               CLEAN(request.request_line);
+               CLEAN(request.request);
+               CLEAN(request.pathinfo);
+-              
++
+               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 +561,97 @@
+ #undef CLEAN
+               free(con->plugin_ctx);
+               free(con->cond_cache);
+-              
++
+               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->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.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  
+-      
++#undef CLEAN
++
+ #define CLEAN(x) \
+-      if (con->x) con->x->used = 0;   
+-      
++      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);
+ #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 */       
++      /* 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,7 +664,7 @@
+               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;
+@@ -777,56 +673,56 @@
+ #else
+       memset(con->cond_cache, 0, sizeof(cond_cache_t) * srv->config_context->used);
+ #endif
+-      
++
+       con->header_len = 0;
+       con->in_error_handler = 0;
+-      
++
+       config_setup_connection(srv, con);
+-      
++
+       return 0;
+ }
+ /**
+- * 
+- * search for \r\n\r\n 
+- * 
++ *
++ * search for \r\n\r\n
++ *
+  * this is a special 32bit version which is using a sliding window for
+- * the comparisions 
+- * 
++ * 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 
++ *
++ * 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;
+ }
+ /**
+@@ -840,22 +736,25 @@
+       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:
 +              case NETWORK_STATUS_FATAL_ERROR:
                        }
                default:
                        break;
-@@ -925,6 +824,7 @@
-                               
+@@ -891,14 +790,14 @@
+                       /* the last node was empty */
+                       if (c->next == NULL) {
+                               cq->last = c;
+-                      } 
++                      }
+                       c = c->next;
+               } else {
+                       c = c->next;
+               }
+       }
+-      
++
+       /* nothing to handle */
+       if (cq->first == NULL) return 0;
+@@ -906,25 +805,26 @@
+       case CON_STATE_READ:
+               /* prepare con->request.request */
+               c = cq->first;
+-              
++
+               /* 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, 
++
++                              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);
-@@ -1177,6 +1077,13 @@
-       if (con->state == CON_STATE_READ ||
-           con->state == CON_STATE_READ_POST) {
-               connection_handle_read_state(srv, con);
-+              /**
-+               * if SSL_read() is not readin in the full packet we won't get
-+               * a fdevent as the low-level has already fetched everything.
-+               *
-+               * we have to call the state-engine to read the rest of the packet
-+               */
-+              if (con->is_readable) joblist_append(srv, con);
-       }
-       
-       if (con->state == CON_STATE_WRITE &&
-@@ -1233,9 +1140,13 @@
-       cnt_len = sizeof(cnt_addr);
-       if (-1 == (cnt = accept(srv_socket->fd, (struct sockaddr *) &cnt_addr, &cnt_len))) {
-+#ifdef _WIN32
+@@ -932,14 +832,14 @@
+                       }
+               } 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' &&
+@@ -948,7 +848,7 @@
+                           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 &&
+@@ -958,7 +858,7 @@
+                                  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 &&
+@@ -968,17 +868,17 @@
+                                  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, 
++
++                              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 {
+@@ -999,16 +899,16 @@
+                       connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
+               }
+               break;
+-      case CON_STATE_READ_POST: 
++      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 */
+@@ -1017,13 +917,13 @@
+                               /* copy everything to max 1Mb sized tempfiles */
+                               /*
+-                               * if the last chunk is 
++                               * if the last chunk is
+                                * - smaller than 1Mb (size < 1Mb)
+                                * - not read yet (offset == 0)
+                                * -> append to it
+                                * otherwise
+-                               * -> create a new chunk 
+-                               * 
++                               * -> create a new chunk
++                               *
+                                * */
+                               if (dst_cq->last &&
+@@ -1056,14 +956,14 @@
+                               /* we have a chunk, let's write to it */
+                               if (dst_c->file.fd == -1) {
+-                                      /* we don't have file to write to, 
++                                      /* 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:", 
++                                                      "denying upload as opening to temp-file for upload failed:",
+                                                       dst_c->file.name, strerror(errno));
+                                       con->http_status = 413; /* Request-Entity too large */
+@@ -1074,15 +974,15 @@
+                               }
+                               if (toRead != write(dst_c->file.fd, c->mem->ptr + c->offset, toRead)) {
+-                                      /* write failed for some reason ... disk full ? */ 
++                                      /* write failed for some reason ... disk full ? */
+                                       log_error_write(srv, __FILE__, __LINE__, "sbs",
+-                                                      "denying upload as writing to file failed:", 
++                                                      "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;
+@@ -1090,7 +990,7 @@
+                               }
+                               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);
+@@ -1102,7 +1002,7 @@
+                               b = chunkqueue_get_append_buffer(dst_cq);
+                               buffer_copy_string_len(b, c->mem->ptr + c->offset, toRead);
+                       }
+-                      
++
+                       c->offset += toRead;
+                       dst_cq->bytes_in += toRead;
+               }
+@@ -1111,7 +1011,7 @@
+               if (dst_cq->bytes_in == (off_t)con->request.content_length) {
+                       connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
+               }
+-                      
++
+               break;
+       }
+@@ -1123,9 +1023,9 @@
+ 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
+@@ -1136,19 +1036,19 @@
+               con->is_writable = 1;
+               /* we don't need the event twice */
+       }
+-      
+-      
++
++
+       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 
++                               *
++                               * there was no HUP at all
+                                */
+ #ifdef USE_LINUX_SIGIO
+                               if (srv->ev->in_sigio == 1) {
+@@ -1160,32 +1060,39 @@
+ #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        
++#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 SSL_read() is not readin in the full packet we won't get
++               * a fdevent as the low-level has already fetched everything.
++               *
++               * we have to call the state-engine to read the rest of the packet
++               */
++              if (con->is_readable) joblist_append(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.");
+@@ -1193,30 +1100,30 @@
+                       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;
+               }
+       }
+-      
++
+       return HANDLER_FINISHED;
+ }
+@@ -1229,63 +1136,68 @@
+       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))) {
++#ifdef _WIN32
 +        errno = WSAGetLastError();
 +#endif
                if ((errno != EAGAIN) &&
                }
                return NULL;
        } else {
-@@ -1251,7 +1162,6 @@
+               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         
-@@ -1268,6 +1178,7 @@
-               
+-#if 0         
++#if 0
+               gettimeofday(&(con->start_tv), NULL);
+-#endif                
++#endif
+               fdevent_register(srv->ev, con->fd, 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))) {
                        log_error_write(srv, __FILE__, __LINE__, "ss", "fcntl failed: ", strerror(errno));
 +                      connection_close(srv, con);
                        return NULL;
                }
  #ifdef USE_OPENSSL
-@@ -1276,7 +1187,7 @@
+               /* 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:", 
+-                              log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", 
++                              log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
                                                ERR_error_string(ERR_get_error(), NULL));
 -                              
 +                              connection_close(srv, con);
                                return NULL;
                        }
-                       
-@@ -1286,6 +1197,7 @@
+-                      
++
+                       SSL_set_accept_state(con->ssl);
+                       con->conf.is_ssl=1;
+-                      
++
                        if (1 != (SSL_set_fd(con->ssl, cnt))) {
-                               log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", 
+-                              log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", 
++                              log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
                                                ERR_error_string(ERR_get_error(), NULL));
 +                              connection_close(srv, con);
                                return NULL;
                        }
                }
---- lighttpd-1.4.11/src/crc32.h        2005-09-30 20:18:59.000000000 +0300
-+++ lighttpd/src/crc32.h       2006-07-11 21:23:40.131857983 +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>
+@@ -1300,10 +1212,10 @@
+ #ifdef USE_OPENSSL
+       server_socket *srv_sock = con->srv_socket;
  #endif
-+#ifdef _WIN32
-+#define uint32_t unsigned __int32
-+#endif
+-      
 +
- uint32_t generate_crc32c(char *string, size_t length);
- #endif
---- lighttpd-1.4.11/src/etag.h 2005-08-11 01:26:40.000000000 +0300
-+++ lighttpd/src/etag.h        2006-07-11 21:23:40.027851469 +0300
-@@ -3,7 +3,6 @@
- #include <sys/types.h>
- #include <sys/stat.h>
--#include <unistd.h>
- #include "buffer.h"
---- lighttpd-1.4.11/src/fdevent.c      2005-11-15 10:51:05.000000000 +0200
-+++ lighttpd/src/fdevent.c     2006-07-11 21:23:40.287867754 +0300
-@@ -2,7 +2,6 @@
- #include "settings.h"
--#include <unistd.h>
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
-@@ -12,6 +11,8 @@
- #include "fdevent.h"
- #include "buffer.h"
-+#include "sys-socket.h"
+       if (srv->srvconf.log_state_handling) {
+-              log_error_write(srv, __FILE__, __LINE__, "sds", 
+-                              "state at start", 
++              log_error_write(srv, __FILE__, __LINE__, "sds",
++                              "state at start",
+                               con->fd,
+                               connection_get_state(con->state));
+       }
+@@ -1311,91 +1223,91 @@
+       while (done == 0) {
+               size_t ostate = con->state;
+               int b;
+-              
 +
- fdevents *fdevent_init(size_t maxfds, fdevent_handler_t type) {
-       fdevents *ev;
-       
-@@ -181,6 +182,9 @@
- }
- int fdevent_fcntl_set(fdevents *ev, int fd) {
-+#ifdef _WIN32
-+    int i = 1;
-+#endif
- #ifdef FD_CLOEXEC
-       /* close fd on exec (cgi) */
-       fcntl(fd, F_SETFD, FD_CLOEXEC);
-@@ -188,6 +192,8 @@
-       if ((ev) && (ev->fcntl_set)) return ev->fcntl_set(ev, fd);
- #ifdef O_NONBLOCK     
-       return fcntl(fd, F_SETFL, O_NONBLOCK | O_RDWR);
-+#elif defined _WIN32
-+    return ioctlsocket(fd, FIONBIO, &i);
- #else
-       return 0;
- #endif
---- lighttpd-1.4.11/src/fdevent.h      2005-09-27 11:26:33.000000000 +0300
-+++ lighttpd/src/fdevent.h     2006-07-11 21:23:39.883842449 +0300
-@@ -31,9 +31,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
---- lighttpd-1.4.11/src/fdevent_freebsd_kqueue.c       2005-09-01 10:46:24.000000000 +0300
-+++ lighttpd/src/fdevent_freebsd_kqueue.c      2006-07-11 21:23:39.987848963 +0300
-@@ -1,6 +1,5 @@
- #include <sys/types.h>
+               switch (con->state) {
+               case CON_STATE_REQUEST_START: /* transient */
+                       if (srv->srvconf.log_state_handling) {
+-                              log_error_write(srv, __FILE__, __LINE__, "sds", 
++                              log_error_write(srv, __FILE__, __LINE__, "sds",
+                                               "state for fd", con->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);
+-                      
++
+                       break;
+               case CON_STATE_REQUEST_END: /* transient */
+                       if (srv->srvconf.log_state_handling) {
+-                              log_error_write(srv, __FILE__, __LINE__, "sds", 
++                              log_error_write(srv, __FILE__, __LINE__, "sds",
+                                               "state for fd", con->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);
  
--#include <unistd.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
---- lighttpd-1.4.11/src/fdevent_linux_rtsig.c  2005-11-21 19:56:11.000000000 +0200
-+++ lighttpd/src/fdevent_linux_rtsig.c 2006-07-11 21:23:40.179860989 +0300
-@@ -1,6 +1,5 @@
- #include <sys/types.h>
--#include <unistd.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
-@@ -14,6 +13,7 @@
- #include "fdevent.h"
- #include "settings.h"
- #include "buffer.h"
-+#include "sys-process.h"
- #ifdef USE_LINUX_SIGIO
- static void fdevent_linux_rtsig_free(fdevents *ev) {
---- lighttpd-1.4.11/src/fdevent_linux_sysepoll.c       2005-09-30 20:29:27.000000000 +0300
-+++ lighttpd/src/fdevent_linux_sysepoll.c      2006-07-11 21:23:40.223863745 +0300
-@@ -1,6 +1,5 @@
- #include <sys/types.h>
--#include <unistd.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
-@@ -12,6 +11,8 @@
- #include "settings.h"
- #include "buffer.h"
-+#include "sys-files.h"
+                               break;
+                       }
+-                      
 +
- #ifdef USE_LINUX_EPOLL
- static void fdevent_linux_sysepoll_free(fdevents *ev) {
-       close(ev->epoll_fd);
---- lighttpd-1.4.11/src/fdevent_poll.c 2005-11-18 13:59:16.000000000 +0200
-+++ lighttpd/src/fdevent_poll.c        2006-07-11 21:23:40.207862743 +0300
-@@ -1,6 +1,5 @@
- #include <sys/types.h>
--#include <unistd.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
---- lighttpd-1.4.11/src/fdevent_select.c       2005-08-31 11:12:46.000000000 +0300
-+++ lighttpd/src/fdevent_select.c      2006-07-11 21:23:40.211862994 +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"
+                       connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
+-                      
 +
- #ifdef USE_SELECT
- static int fdevent_select_reset(fdevents *ev) {
-@@ -38,7 +39,9 @@
-       UNUSED(fde_ndx);
-       /* we should be protected by max-fds, but you never know */
-+#ifndef _WIN32
-       assert(fd < FD_SETSIZE);
-+#endif
-       if (events & FDEVENT_IN) {
-               FD_SET(fd, &(ev->select_set_read));
---- lighttpd-1.4.11/src/fdevent_solaris_devpoll.c      2005-09-01 10:45:26.000000000 +0300
-+++ lighttpd/src/fdevent_solaris_devpoll.c     2006-07-11 21:23:40.015850717 +0300
-@@ -1,6 +1,5 @@
- #include <sys/types.h>
--#include <unistd.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
---- lighttpd-1.4.11/src/http-header-glue.c     2006-02-08 15:31:36.000000000 +0200
-+++ lighttpd/src/http-header-glue.c    2006-07-11 21:23:40.187861491 +0300
-@@ -261,13 +261,22 @@
-                                               con->http_status = 304;
-                                               return HANDLER_FINISHED;
-                                       } else {
-+#ifdef HAVE_STRPTIME
-                                               char buf[sizeof("Sat, 23 Jul 2005 21:20:01 GMT")];
--
--                                              /* convert to timestamp */
--                                              if (used_len < sizeof(buf)) {
-                                                       time_t t_header, t_file;
-                                                       struct tm tm;
-                                                       
-+                                              /* check if we can safely copy the string */
-+                                              if (used_len >= sizeof(buf)) {
-+                                                      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);
+                       break;
+               case CON_STATE_HANDLE_REQUEST:
+-                      /* 
++                      /*
+                        * the request is parsed
+-                       * 
++                       *
+                        * decided what to do with the request
+-                       * - 
+-                       * 
+-                       * 
++                       * -
++                       *
++                       *
+                        */
+-                      
 +
-+                                                      con->http_status = 412;
-+                                                      return HANDLER_FINISHED;
-+                                              }
+                       if (srv->srvconf.log_state_handling) {
+-                              log_error_write(srv, __FILE__, __LINE__, "sds", 
++                              log_error_write(srv, __FILE__, __LINE__, "sds",
+                                               "state for fd", con->fd, connection_get_state(con->state));
+                       }
+-                      
 +
+                       switch (r = http_response_prepare(srv, con)) {
+                       case HANDLER_FINISHED:
+                               if (con->http_status == 404 ||
+                                   con->http_status == 403) {
+                                       /* 404 error-handler */
+-                                      
+-                                      if (con->in_error_handler == 0 && 
 +
-                                                       strncpy(buf, con->request.http_if_modified_since, used_len);
-                                                       buf[used_len] = '\0';
-                                                       
-@@ -277,18 +286,13 @@
-                                                       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);
-+                                              if (t_file > t_header) return HANDLER_GO_ON;
-                                                       
--                                                      con->http_status = 412;
-+                                              con->http_status = 304;
-                                                       return HANDLER_FINISHED;
--                                              }
-+#else
-+                        return HANDLER_GO_ON;
-+#endif
++                                      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", 
++                                              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", 
++                                              log_error_write(srv, __FILE__, __LINE__, "sd",
+                                                               "returning the original status", con->error_handler_saved_status);
+-                                              log_error_write(srv, __FILE__, __LINE__, "s", 
++                                              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 {
-                                       con->http_status = 304;
-@@ -312,6 +316,31 @@
-               if (0 == strncmp(con->request.http_if_modified_since, 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;
+@@ -1403,26 +1315,26 @@
+                                       /* error-handler is back and has generated content */
+                                       /* if Status: was set, take it otherwise use 200 */
+                               }
+-                              
 +
-+                      /* convert to timestamp */
-+                      if (used_len >= sizeof(buf)) return HANDLER_GO_ON;
+                               if (con->http_status == 0) con->http_status = 200;
+-                              
 +
-+                      strncpy(buf, con->request.http_if_modified_since, used_len);
-+                      buf[used_len] = '\0';
+                               /* 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++;
+-                              
 +
-+                      strptime(buf, "%a, %d %b %Y %H:%M:%S GMT", &tm);
-+                      t_header = mktime(&tm);
+                               fdwaitqueue_append(srv, con);
+-                              
 +
-+                      strptime(mtime->ptr, "%a, %d %b %Y %H:%M:%S GMT", &tm);
-+                      t_file = mktime(&tm);
+                               connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
+-                              
 +
-+                      if (t_file > t_header) return HANDLER_GO_ON;
+                               break;
+                       case HANDLER_COMEBACK:
+                               done = -1;
+                       case HANDLER_WAIT_FOR_EVENT:
+                               /* come back here */
+                               connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
+-                              
 +
-+                      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/src/http_auth.c   2006-07-11 21:23:40.115856981 +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,14 @@
- #include "http_auth_digest.h"
- #include "stream.h"
-+#include "sys-strings.h"
+                               break;
+                       case HANDLER_ERROR:
+                               /* something went wrong */
+@@ -1432,44 +1344,44 @@
+                               log_error_write(srv, __FILE__, __LINE__, "sdd", "unknown ret-value: ", con->fd, r);
+                               break;
+                       }
+-                      
++
+                       break;
+               case CON_STATE_RESPONSE_START:
+-                      /* 
++                      /*
+                        * the decision is done
+                        * - create the HTTP-Response-Header
+-                       * 
++                       *
+                        */
+-                      
++
+                       if (srv->srvconf.log_state_handling) {
+-                              log_error_write(srv, __FILE__, __LINE__, "sds", 
++                              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)) {
+                               connection_set_state(srv, con, CON_STATE_ERROR);
+-                              
++
+                               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", 
++                              log_error_write(srv, __FILE__, __LINE__, "sds",
+                                               "state for fd", con->fd, connection_get_state(con->state));
+                       }
+-                      
++
+                       plugins_call_handle_request_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,7 +1394,7 @@
+                                       log_error_write(srv, __FILE__, __LINE__, "sd", "unhandling return value", r);
+                                       break;
+                               }
+-                              
 +
  #ifdef USE_OPENSSL
- # include <openssl/md5.h>
- #else
- # include "md5.h"
+                               if (srv_sock->is_ssl) {
+                                       switch (SSL_shutdown(con->ssl)) {
+@@ -1490,44 +1402,44 @@
+                                               /* done */
+                                               break;
+                                       case 0:
+-                                              /* wait for fd-event 
+-                                               * 
++                                              /* wait for fd-event
++                                               *
+                                                * FIXME: wait for fdevent and call SSL_shutdown again
+-                                               * 
++                                               *
+                                                */
+-                                              
++
+                                               break;
+                                       default:
+-                                              log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", 
++                                              log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
+                                                               ERR_error_string(ERR_get_error(), NULL));
+                                       }
+                               }
  #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 = '=';
-@@ -509,33 +499,6 @@
-               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");
--                      return 0;
--              } else {
--                      log_error_write(srv, __FILE__, __LINE__, "s", "Not Authenticated");
--              }
--#endif
-       } else if (p->conf.auth_backend == AUTH_BACKEND_LDAP) { 
- #ifdef USE_LDAP
-               LDAP *ldap;
---- lighttpd-1.4.11/src/http_auth.h    2005-08-14 17:12:31.000000000 +0300
-+++ lighttpd/src/http_auth.h   2006-07-11 21:23:40.119857231 +0300
-@@ -9,9 +9,13 @@
- # include <ldap.h>
+                               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", 
++                              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", 
++                              log_error_write(srv, __FILE__, __LINE__, "sds",
+                                               "state for fd", con->fd, connection_get_state(con->state));
+                       }
+-                      
++
+                       if (con->keep_alive) {
+                               if (ioctl(con->fd, FIONREAD, &b)) {
+                                       log_error_write(srv, __FILE__, __LINE__, "ss",
+@@ -1537,43 +1449,43 @@
+                                       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;
+                               }
+                       } 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", 
++                                      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", 
++                              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", 
++                              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
+@@ -1593,10 +1505,10 @@
+                                       con->write_request_ts = srv->cur_ts;
+                               }
+                       }
+-                      
++
+                       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);
+@@ -1612,19 +1524,19 @@
+                                       SSL_shutdown(con->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->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", 
++                              log_error_write(srv, __FILE__, __LINE__, "sd",
++                                              "emergency exit: direct",
+                                               con->fd);
+ #endif
+                               break;
+@@ -1639,35 +1551,35 @@
+                               }
+                               break;
+                       }
+-                      
++
+                       connection_reset(srv, con);
+-                      
++
+                       /* close the connection */
+                       if ((con->keep_alive == 1) &&
+                           (0 == shutdown(con->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", 
++                                      log_error_write(srv, __FILE__, __LINE__, "sd",
+                                                       "shutdown for fd", con->fd);
+                               }
+                       } else {
+                               connection_close(srv, con);
+                       }
+-                      
++
+                       con->keep_alive = 0;
+-                      
++
+                       srv->con_closed++;
+-                      
++
+                       break;
+               default:
+-                      log_error_write(srv, __FILE__, __LINE__, "sdd", 
++                      log_error_write(srv, __FILE__, __LINE__, "sdd",
+                                       "unknown state:", con->fd, con->state);
+-                      
++
+                       break;
+               }
+-              
++
+               if (done == -1) {
+                       done = 0;
+               } else if (ostate == con->state) {
+@@ -1676,12 +1588,12 @@
+       }
  
--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 */
---- lighttpd-1.4.11/src/http_chunk.c   2005-08-11 01:26:50.000000000 +0300
-+++ lighttpd/src/http_chunk.c  2006-07-11 21:23:40.251865499 +0300
-@@ -9,7 +9,6 @@
- #include <stdlib.h>
- #include <fcntl.h>
--#include <unistd.h>
+       if (srv->srvconf.log_state_handling) {
+-              log_error_write(srv, __FILE__, __LINE__, "sds", 
+-                              "state at exit:", 
++              log_error_write(srv, __FILE__, __LINE__, "sds",
++                              "state at exit:",
+                               con->fd,
+                               connection_get_state(con->state));
+       }
+-      
++
+       switch(con->state) {
+       case CON_STATE_READ_POST:
+       case CON_STATE_READ:
+@@ -1689,11 +1601,11 @@
+               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 
++              /* request write-fdevent only if we really need it
+                * - if we have data to write
+-               * - if the socket is not writable yet 
++               * - if the socket is not writable yet
+                */
+-              if (!chunkqueue_is_empty(con->write_queue) && 
++              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);
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/crc32.h lighttpd-1.4.12/src/crc32.h
+--- lighttpd-1.4.11/src/crc32.h        2005-09-30 20:18:59.000000000 +0300
++++ lighttpd-1.4.12/src/crc32.h        2006-07-11 21:23:40.000000000 +0300
+@@ -6,6 +6,7 @@
+ #endif
  
- #include <stdio.h>
- #include <errno.h>
---- lighttpd-1.4.11/src/keyvalue.c     2006-03-02 16:08:06.000000000 +0200
-+++ lighttpd/src/keyvalue.c    2006-07-11 21:23:40.027851469 +0300
-@@ -87,6 +87,7 @@
-       { 504, "Gateway Timeout" },
-       { 505, "HTTP Version Not Supported" },
-       { 507, "Insufficient Storage" }, /* WebDAV */
-+      { 509, "Bandwidth Limit exceeded" },
-       
-       { -1, NULL }
- };
---- lighttpd-1.4.11/src/log.c  2005-11-07 15:01:35.000000000 +0200
-+++ lighttpd/src/log.c 2006-07-11 21:23:40.275867002 +0300
-@@ -5,7 +5,6 @@
- #include <errno.h>
- #include <fcntl.h>
- #include <time.h>
--#include <unistd.h>
- #include <string.h>
- #include <stdlib.h>
+ #include <sys/types.h>
++#include <stdlib.h>
  
-@@ -16,6 +15,10 @@
- #include "config.h"
+ #if defined HAVE_STDINT_H
+ #include <stdint.h>
+@@ -13,6 +14,10 @@
+ #include <inttypes.h>
  #endif
  
 +#ifdef _WIN32
-+#undef HAVE_SYSLOG_H
++#define uint32_t unsigned __int32
 +#endif
 +
- #ifdef HAVE_SYSLOG_H
- #include <syslog.h>
- #endif
-@@ -23,6 +26,8 @@
- #include "log.h"
- #include "array.h"
+ uint32_t generate_crc32c(char *string, size_t length);
  
-+#include "sys-files.h"
-+
- #ifdef HAVE_VALGRIND_VALGRIND_H
- #include <valgrind/valgrind.h>
- #endif
-@@ -246,9 +251,11 @@
-               BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, "\n");
-               write(STDERR_FILENO, srv->errorlog_buf->ptr, srv->errorlog_buf->used - 1);
-               break;
-+#ifdef HAVE_SYSLOG_H
-       case ERRORLOG_SYSLOG:
-               syslog(LOG_ERR, "%s", srv->errorlog_buf->ptr);
-               break;
-+#endif
-       }
-       
-       return 0;
---- lighttpd-1.4.11/src/md5.h  2005-11-17 16:20:40.000000000 +0200
-+++ lighttpd/src/md5.h 2006-07-11 21:23:40.155859486 +0300
-@@ -30,9 +30,15 @@
- # include <inttypes.h>
  #endif
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/data_array.c lighttpd-1.4.12/src/data_array.c
+--- lighttpd-1.4.11/src/data_array.c   2005-08-23 17:36:12.000000000 +0300
++++ lighttpd-1.4.12/src/data_array.c   2006-07-11 21:23:40.000000000 +0300
+@@ -17,16 +17,16 @@
  
-+#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/src/mod_access.c  2006-07-11 21:23:40.219863495 +0300
-@@ -8,6 +8,8 @@
+ static void data_array_free(data_unset *d) {
+       data_array *ds = (data_array *)d;
+-      
++
+       buffer_free(ds->key);
+       array_free(ds->value);
+-      
++
+       free(d);
+ }
  
- #include "plugin.h"
+ 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);
  
-+#include "sys-strings.h"
+       src->free(src);
+-      
 +
- typedef struct {
-       array *access_deny;
- } plugin_config;
-@@ -81,13 +83,11 @@
-       return HANDLER_GO_ON;
+       return 0;
  }
  
--#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];
+@@ -48,18 +48,18 @@
  
--      PATCH(access_deny);
-+      PATCH_OPTION(access_deny);
-       
-       /* skip the first, the global context */
-       for (i = 1; i < srv->config_context->used; i++) {
-@@ -102,14 +102,13 @@
-                       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;
+ 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;
  }
--#undef PATCH
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/data_config.c lighttpd-1.4.12/src/data_config.c
+--- lighttpd-1.4.11/src/data_config.c  2005-08-17 12:53:19.000000000 +0300
++++ lighttpd-1.4.12/src/data_config.c  2006-07-11 21:23:39.000000000 +0300
+@@ -17,26 +17,26 @@
  
- URIHANDLER_FUNC(mod_access_uri_handler) {
-       plugin_data *p = p_d;
---- lighttpd-1.4.11/src/mod_accesslog.c        2006-01-31 14:01:43.000000000 +0200
-+++ lighttpd/src/mod_accesslog.c       2006-07-11 21:23:40.219863495 +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>
+ 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);
+ }
  
-@@ -22,6 +21,7 @@
- #include "inet_ntop_cache.h"
+ 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 @@
  
- #include "sys-socket.h"
-+#include "sys-files.h"
+ static int data_config_insert_dup(data_unset *dst, data_unset *src) {
+       UNUSED(dst);
+-      
++
+       src->free(src);
+-      
++
+       return 0;
+ }
  
- #ifdef HAVE_SYSLOG_H
- # include <syslog.h>
-@@ -517,8 +517,9 @@
-                       
-                       return HANDLER_ERROR;
-               }
-+#ifndef _WIN32
-               fcntl(s->log_access_fd, F_SETFD, FD_CLOEXEC);
+@@ -56,7 +56,7 @@
+       array *a = (array *)ds->value;
+       size_t i;
+       size_t maxlen;
 -      
-+#endif
++
+       if (0 == ds->context_ndx) {
+               fprintf(stderr, "config {\n");
        }
-       
-       return HANDLER_GO_ON;
-@@ -567,20 +568,18 @@
-       return HANDLER_GO_ON;
+@@ -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;
  }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/data_count.c lighttpd-1.4.12/src/data_count.c
+--- lighttpd-1.4.11/src/data_count.c   2005-08-23 17:36:12.000000000 +0300
++++ lighttpd-1.4.12/src/data_count.c   2006-07-11 21:23:40.000000000 +0300
+@@ -16,53 +16,53 @@
  
--#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++) {
-@@ -595,23 +594,22 @@
-                       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);
-                       }
-               }
-       }
-       
+ 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;
  }
--#undef PATCH
  
- REQUESTDONE_FUNC(log_access_write) {
-       plugin_data *p = p_d;
---- lighttpd-1.4.11/src/mod_alias.c    2006-03-01 23:18:51.000000000 +0200
-+++ lighttpd/src/mod_alias.c   2006-07-11 21:23:39.979848462 +0300
-@@ -8,6 +8,7 @@
- #include "buffer.h"
+ 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);
+ }
  
- #include "plugin.h"
-+#include "sys-strings.h"
  
- /* plugin config for all request/connections */
- typedef struct {
-@@ -114,13 +115,11 @@
-       return HANDLER_GO_ON;
+ 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;
  }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/data_fastcgi.c lighttpd-1.4.12/src/data_fastcgi.c
+--- lighttpd-1.4.11/src/data_fastcgi.c 2005-08-23 17:36:12.000000000 +0300
++++ lighttpd-1.4.12/src/data_fastcgi.c 2006-07-11 21:23:40.000000000 +0300
+@@ -17,53 +17,53 @@
  
--#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++) {
-@@ -135,14 +134,13 @@
-                       data_unset *du = dc->value->data[j];
-                       
-                       if (buffer_is_equal_string(du->key, CONST_STR_LEN("alias.url"))) {
--                              PATCH(alias);
-+                              PATCH_OPTION(alias);
-                       }
-               }
-       }
-       
+ 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;
  }
--#undef PATCH
  
- PHYSICALPATH_FUNC(mod_alias_physical_handler) {
-       plugin_data *p = p_d;
---- lighttpd-1.4.11/src/mod_auth.c     2006-02-15 20:01:31.000000000 +0200
-+++ lighttpd/src/mod_auth.c    2006-07-11 21:23:40.171860488 +0300
-@@ -5,13 +5,15 @@
- #include <string.h>
- #include <errno.h>
- #include <fcntl.h>
--#include <unistd.h>
+ 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);
+ }
  
- #include "plugin.h"
- #include "http_auth.h"
- #include "log.h"
- #include "response.h"
  
-+#include "sys-strings.h"
-+#include "sys-files.h"
+ data_fastcgi *data_fastcgi_init(void) {
+       data_fastcgi *ds;
+-      
 +
- handler_t auth_ldap_init(server *srv, mod_auth_plugin_config *s);
+       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;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/data_integer.c lighttpd-1.4.12/src/data_integer.c
+--- lighttpd-1.4.11/src/data_integer.c 2005-08-23 17:36:12.000000000 +0300
++++ lighttpd-1.4.12/src/data_integer.c 2006-07-11 21:23:39.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 @@
  
-@@ -93,30 +95,28 @@
-       return HANDLER_GO_ON;
+ static int data_integer_insert_dup(data_unset *dst, data_unset *src) {
+       UNUSED(dst);
+-      
++
+       src->free(src);
+-      
++
+       return 0;
  }
  
--#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];
+@@ -48,18 +48,18 @@
  
--      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 */
-@@ -132,41 +132,40 @@
-                       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);
-                       }
-               }
+ 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;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/data_string.c lighttpd-1.4.12/src/data_string.c
+--- lighttpd-1.4.11/src/data_string.c  2005-08-23 17:36:12.000000000 +0300
++++ lighttpd-1.4.12/src/data_string.c  2006-07-11 21:23:40.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;
  }
--#undef PATCH
  
- static handler_t mod_auth_uri_handler(server *srv, connection *con, void *p_d) {
-       size_t k;
---- lighttpd-1.4.11/src/mod_cgi.c      2006-02-22 15:15:10.000000000 +0200
-+++ lighttpd/src/mod_cgi.c     2006-07-11 21:23:39.887842700 +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
+ 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;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/etag.c lighttpd-1.4.12/src/etag.c
+--- lighttpd-1.4.11/src/etag.c 2005-08-11 01:26:40.000000000 +0300
++++ lighttpd-1.4.12/src/etag.c 2006-07-11 21:23:40.000000000 +0300
+@@ -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;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/etag.h lighttpd-1.4.12/src/etag.h
+--- lighttpd-1.4.11/src/etag.h 2005-08-11 01:26:40.000000000 +0300
++++ lighttpd-1.4.12/src/etag.h 2006-07-11 21:23:40.000000000 +0300
+@@ -3,13 +3,12 @@
  
+ #include <sys/types.h>
+ #include <sys/stat.h>
 -#include <unistd.h>
- #include <errno.h>
- #include <stdlib.h>
- #include <string.h>
--#include <fdevent.h>
- #include <signal.h>
- #include <ctype.h>
- #include <assert.h>
-@@ -29,9 +16,16 @@
- #include "connections.h"
- #include "joblist.h"
- #include "http_chunk.h"
-+#include "fdevent.h"
  
- #include "plugin.h"
+ #include "buffer.h"
  
-+#include "sys-files.h"
-+#include "sys-mmap.h"
-+#include "sys-socket.h"
-+#include "sys-strings.h"
-+#include "sys-process.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);
+-      
 +
- #ifdef HAVE_SYS_FILIO_H
- # include <sys/filio.h>
  #endif
-@@ -45,6 +39,7 @@
-       size_t used;
- } char_array;
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/fastcgi.h lighttpd-1.4.12/src/fastcgi.h
+--- lighttpd-1.4.11/src/fastcgi.h      2005-08-11 01:26:40.000000000 +0300
++++ lighttpd-1.4.12/src/fastcgi.h      2006-07-11 21:23:40.000000000 +0300
+@@ -1,4 +1,4 @@
+-/* 
++/*
+  * fastcgi.h --
+  *
+  *    Defines for the FastCGI protocol.
+@@ -123,7 +123,7 @@
  
-+#define pid_t int
- typedef struct {
-       pid_t *ptr;
-       size_t used;
-@@ -478,7 +473,7 @@
-       
-       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 
-@@ -509,6 +504,7 @@
-       /* 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 */
-@@ -558,7 +554,7 @@
-               
-       
-               kill(pid, SIGTERM);
--              
-+#endif
-               /* cgi-script is still alive, queue the PID for removal */
-               cgi_pid_add(srv, p, pid);
-       }
-@@ -695,7 +691,7 @@
-       int from_cgi_fds[2];
-       struct stat st;
-       
--#ifndef __WIN32       
-+#ifndef _WIN32
-       
-       if (cgi_handler->used > 1) {
-               /* stat the exec file */
-@@ -811,6 +807,9 @@
-               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));
-@@ -1101,13 +1100,11 @@
- #endif
- }
+ typedef struct {
+-    unsigned char type;    
++    unsigned char type;
+     unsigned char reserved[7];
+ } FCGI_UnknownTypeBody;
  
--#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++) {
-@@ -1122,14 +1119,13 @@
-                       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
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/fdevent.c lighttpd-1.4.12/src/fdevent.c
+--- lighttpd-1.4.11/src/fdevent.c      2005-11-15 10:51:05.000000000 +0200
++++ lighttpd-1.4.12/src/fdevent.c      2006-07-11 21:23:40.000000000 +0300
+@@ -2,7 +2,6 @@
  
- URIHANDLER_FUNC(cgi_is_handled) {
-       size_t k, s_len;
-@@ -1168,7 +1164,7 @@
-       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
+ #include "settings.h"
  
-       for (ndx = 0; ndx < p->cgi_pid.used; ndx++) {
-               int status;
-@@ -1218,7 +1214,7 @@
-       log_error_write(srv, __FILE__, __LINE__, "sdd", "subrequest, pid =", hctx, hctx->pid);
- #endif        
-       if (hctx->pid == 0) return HANDLER_FINISHED;
--#ifndef __WIN32       
-+#ifndef _WIN32
-       switch(waitpid(hctx->pid, &status, WNOHANG)) {
-       case 0:
-               /* we only have for events here if we don't have the header yet,
---- lighttpd-1.4.11/src/mod_cml.c      2006-01-30 13:51:48.000000000 +0200
-+++ lighttpd/src/mod_cml.c     2006-07-11 21:23:39.931845456 +0300
-@@ -4,7 +4,6 @@
+-#include <unistd.h>
  #include <stdlib.h>
  #include <string.h>
  #include <errno.h>
--#include <unistd.h>
- #include <stdio.h>
+@@ -12,59 +11,61 @@
+ #include "fdevent.h"
  #include "buffer.h"
-@@ -135,18 +134,16 @@
-       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++) {
-@@ -161,22 +158,21 @@
-                       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);
-                       }
++#include "sys-socket.h"
++
+ 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;
        }
-       
-       return 0;
+@@ -75,26 +76,26 @@
+ 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);
  }
--#undef PATCH
  
- int cache_call_lua(server *srv, connection *con, plugin_data *p, buffer *cml_file) {
-       buffer *b;
---- lighttpd-1.4.11/src/mod_cml_funcs.c        2005-11-17 16:15:08.000000000 +0200
-+++ lighttpd/src/mod_cml_funcs.c       2006-07-11 21:23:40.083854976 +0300
-@@ -4,8 +4,7 @@
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
--#include <unistd.h>
--#include <dirent.h>
+ int fdevent_reset(fdevents *ev) {
+       if (ev->reset) return ev->reset(ev);
+-      
 +
- #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"
-@@ -92,7 +92,7 @@
-       
-       return 1;
- }
--
-+#ifndef _WIN32
- int f_dir_files_iter(lua_State *L) {
-       DIR *d;
-       struct dirent *de;
-@@ -136,7 +136,7 @@
-       
-       return 1;
+       return 0;
  }
--
-+#endif
- int f_file_isreg(lua_State *L) {
-       struct stat st;
-       int n = lua_gettop(L);
---- lighttpd-1.4.11/src/mod_cml_lua.c  2006-01-30 13:56:40.000000000 +0200
-+++ lighttpd/src/mod_cml_lua.c 2006-07-11 21:23:40.179860989 +0300
-@@ -31,6 +31,7 @@
- #include <lua.h>
- #include <lualib.h>
-+#include <lauxlib.h>
  
- typedef struct {
-       stream st;
-@@ -220,13 +221,8 @@
-       stream_open(&rm.st, fn);
-       
-       /* push the lua file to the interpreter and see what happends */
--      L = lua_open();
+ fdnode *fdnode_init() {
+       fdnode *fdn;
 -      
--      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);
---- lighttpd-1.4.11/src/mod_compress.c 2005-11-18 13:49:14.000000000 +0200
-+++ lighttpd/src/mod_compress.c        2006-07-11 21:23:40.139858484 +0300
-@@ -2,7 +2,6 @@
- #include <sys/stat.h>
- #include <fcntl.h>
--#include <unistd.h>
- #include <ctype.h>
- #include <stdlib.h>
- #include <string.h>
-@@ -14,6 +13,7 @@
- #include "buffer.h"
- #include "response.h"
- #include "stat_cache.h"
-+#include "http_chunk.h"
- #include "plugin.h"
-@@ -33,6 +33,7 @@
- #endif
- #include "sys-mmap.h"
-+#include "sys-files.h"
- /* request: accept-encoding */
- #define HTTP_ACCEPT_ENCODING_IDENTITY BV(0)
-@@ -102,6 +103,28 @@
-       return HANDLER_GO_ON;
- }
++
+       fdn = calloc(1, sizeof(*fdn));
+       fdn->fd = -1;
+       return fdn;
+@@ -106,12 +107,12 @@
  
-+void mkdir_recursive(const char *dir) {
+ int fdevent_register(fdevents *ev, int fd, fdevent_handler handler, void *ctx) {
+       fdnode *fdn;
+-      
 +
-+      char dir_copy[256];
-+      char *p = dir_copy;
+       fdn = fdnode_init();
+       fdn->handler = handler;
+       fdn->fd      = fd;
+       fdn->ctx     = ctx;
+-      
 +
-+      if (!dir || !dir[0])
-+              return;
+       ev->fdarray[fd] = fdn;
+       return 0;
+@@ -121,31 +122,31 @@
+       fdnode *fdn;
+         if (!ev) return 0;
+       fdn = ev->fdarray[fd];
+-      
 +
-+      strncpy(dir_copy, dir, sizeof(dir_copy) / sizeof(dir_copy[0]));
+       fdnode_free(fdn);
+-      
 +
-+      while ((p = strchr(p + 1, '/')) != NULL) {
+       ev->fdarray[fd] = NULL;
+-      
 +
-+              *p = '\0';
-+              if ((mkdir(dir_copy, 0700) != 0) && (errno != EEXIST))
-+                      return;
+       return 0;
+ }
+ int fdevent_event_del(fdevents *ev, int *fde_ndx, int fd) {
+       int fde = fde_ndx ? *fde_ndx : -1;
+-      
 +
-+              *p++ = '/';
-+      }
+       if (ev->event_del) fde = ev->event_del(ev, fde, fd);
+-      
 +
-+      mkdir(dir, 0700);
-+}
+       if (fde_ndx) *fde_ndx = fde;
+-      
 +
- SETDEFAULTS_FUNC(mod_compress_setdefaults) {
-       plugin_data *p = p_d;
-       size_t i = 0;
-@@ -136,13 +159,21 @@
-               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", 
+       return 0;
+ }
+ int fdevent_event_add(fdevents *ev, int *fde_ndx, int fd, int events) {
+       int fde = fde_ndx ? *fde_ndx : -1;
+-      
 +
-+                              log_error_write(srv, __FILE__, __LINE__, "sbs", "can't stat compress.cache-dir, attempting to create",
-+                                              s->compress_cache_dir, strerror(errno));
-+                              mkdir_recursive(s->compress_cache_dir->ptr);
+       if (ev->event_add) fde = ev->event_add(ev, fde, fd, events);
+-      
 +
-+                              if (0 != stat(s->compress_cache_dir->ptr, &st)) {
+       if (fde_ndx) *fde_ndx = fde;
+-      
 +
-+                                      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;
-       
-@@ -326,6 +357,9 @@
-       void *start;
-       const char *filename = fn->ptr;
-       ssize_t r;
-+      stat_cache_entry *compressed_sce = NULL;
+       return 0;
+ }
+@@ -156,38 +157,43 @@
+ int fdevent_event_get_revent(fdevents *ev, size_t ndx) {
+       if (ev->event_get_revent == NULL) SEGFAULT();
+-      
 +
-+      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;
-@@ -339,7 +373,7 @@
-       
-       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;
-@@ -384,26 +418,33 @@
-       
-       buffer_append_string_buffer(p->ofn, sce->etag);
-       
+       return ev->event_get_revent(ev, ndx);
+ }
+ int fdevent_event_get_fd(fdevents *ev, size_t ndx) {
+       if (ev->event_get_fd == NULL) SEGFAULT();
+-      
 +
-+      if (HANDLER_ERROR != stat_cache_get_entry(srv, con, p->ofn, &compressed_sce)) {
-+              /* file exists */
+       return ev->event_get_fd(ev, ndx);
+ }
+ fdevent_handler fdevent_get_handler(fdevents *ev, int fd) {
+       if (ev->fdarray[fd] == NULL) SEGFAULT();
+       if (ev->fdarray[fd]->fd != fd) SEGFAULT();
+-      
 +
-+              http_chunk_append_file(srv, con, p->ofn, 0, compressed_sce->st.st_size);
-+              con->file_finished = 1;
+       return ev->fdarray[fd]->handler;
+ }
+ void * fdevent_get_context(fdevents *ev, int fd) {
+       if (ev->fdarray[fd] == NULL) SEGFAULT();
+       if (ev->fdarray[fd]->fd != fd) SEGFAULT();
+-      
 +
-+              return 0;
-+      }
+       return ev->fdarray[fd]->ctx;
+ }
+ int fdevent_fcntl_set(fdevents *ev, int fd) {
++#ifdef _WIN32
++    int i = 1;
++#endif
+ #ifdef FD_CLOEXEC
+       /* close fd on exec (cgi) */
+       fcntl(fd, F_SETFD, FD_CLOEXEC);
+ #endif
+       if ((ev) && (ev->fcntl_set)) return ev->fcntl_set(ev, fd);
+-#ifdef O_NONBLOCK     
++#ifdef O_NONBLOCK
+       return fcntl(fd, F_SETFL, O_NONBLOCK | O_RDWR);
++#elif defined _WIN32
++    return ioctlsocket(fd, FIONBIO, &i);
+ #else
+       return 0;
+ #endif
+@@ -196,7 +202,7 @@
+ int fdevent_event_next_fdndx(fdevents *ev, int ndx) {
+       if (ev->event_next_fdndx) return ev->event_next_fdndx(ev, ndx);
+-      
 +
-       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;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/fdevent.h lighttpd-1.4.12/src/fdevent.h
+--- lighttpd-1.4.11/src/fdevent.h      2005-09-27 11:26:33.000000000 +0300
++++ lighttpd-1.4.12/src/fdevent.h      2006-07-11 21:23:39.000000000 +0300
+@@ -17,13 +17,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 +31,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 +69,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 +88,7 @@
+ /**
+  * a mapping from fd to connection structure
+- * 
++ *
+  */
+ typedef struct {
+       int fd;                  /**< the fd */
+@@ -98,41 +100,41 @@
+ typedef struct {
+       fd_conn *ptr;
+-      
++
+       size_t size;
+       size_t used;
+ } fd_conn_buffer;
+ /**
+  * array of unused fd's
+- * 
++ *
+  */
+ typedef struct _fdnode {
+       fdevent_handler handler;
+       void *ctx;
+       int 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;
+       size_t maxfds;
+-      
++
+ #ifdef USE_LINUX_SIGIO
+       int in_sigio;
+       int signum;
+@@ -146,21 +148,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 +179,16 @@
+ #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 (*poll)(struct fdevents *ev, int timeout_ms);
+-      
++
+       int (*fcntl_set)(struct fdevents *ev, int fd);
+ } fdevents;
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/fdevent_freebsd_kqueue.c lighttpd-1.4.12/src/fdevent_freebsd_kqueue.c
+--- lighttpd-1.4.11/src/fdevent_freebsd_kqueue.c       2005-09-01 10:46:24.000000000 +0300
++++ lighttpd-1.4.12/src/fdevent_freebsd_kqueue.c       2006-07-11 21:23:39.000000000 +0300
+@@ -1,6 +1,5 @@
+ #include <sys/types.h>
+-#include <unistd.h>
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <string.h>
+@@ -48,7 +47,7 @@
                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);
-               
-@@ -412,7 +453,9 @@
-       
-       
-       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);
-@@ -455,7 +498,8 @@
-       
-       if (ret != 0) return -1;
-       
--      buffer_copy_string_buffer(con->physical.path, p->ofn);
-+      http_chunk_append_file(srv, con, p->ofn, 0, r);
-+      con->file_finished = 1;
-       
-       return 0;
+       return -1;
  }
-@@ -476,18 +520,19 @@
-       
-       if (sce->st.st_size > 128 * 1024 * 1024) return -1;
-       
+@@ -65,7 +64,7 @@
+       ts.tv_sec  = 0;
+       ts.tv_nsec = 0;
 -      
-       if (-1 == (ifd = open(fn->ptr, O_RDONLY | O_BINARY))) {
-               log_error_write(srv, __FILE__, __LINE__, "sbss", "opening plain-file", fn, "failed", strerror(errno));
-               
++
+       ret = kevent(ev->kq_fd,
+                    &kev, 1,
+                    NULL, 0,
+@@ -77,7 +76,7 @@
                return -1;
        }
-       
-+      start = mmap(NULL, sce->st.st_size, PROT_READ, MAP_SHARED, ifd, 0);
-       
--      if (MAP_FAILED == (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;
+       if (filter == EVFILT_READ) {
+               bitset_set_bit(ev->kq_bevents, fd);
+       } else {
+@@ -124,7 +123,7 @@
+       } else if (e == EVFILT_WRITE) {
+               events |= FDEVENT_OUT;
        }
-       
-@@ -511,7 +556,6 @@
+-      
++
+       e = ev->kq_results[ndx].flags;
+       if (e & EV_EOF) {
+@@ -152,10 +151,10 @@
+       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;
        }
-               
-       munmap(start, sce->st.st_size);
--      close(ifd);
-       
-       if (ret != 0) return -1;
-       
-@@ -527,16 +571,13 @@
+-      
++
        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];
+@@ -186,7 +185,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;
+       }
  
--      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++) {
-@@ -551,18 +592,17 @@
-                       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);
-                       }
-               }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/fdevent_linux_rtsig.c lighttpd-1.4.12/src/fdevent_linux_rtsig.c
+--- lighttpd-1.4.11/src/fdevent_linux_rtsig.c  2005-11-21 19:56:11.000000000 +0200
++++ lighttpd-1.4.12/src/fdevent_linux_rtsig.c  2006-07-11 21:23: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,7 @@
+ #include "fdevent.h"
+ #include "settings.h"
+ #include "buffer.h"
++#include "sys-process.h"
+ #ifdef USE_LINUX_SIGIO
+ static void fdevent_linux_rtsig_free(fdevents *ev) {
+@@ -26,19 +26,19 @@
+ 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);
+               SEGFAULT();
        }
-       
-       return 0;
- }
--#undef PATCH
+-      
++
+       if (ev->pollfds[fde_ndx].fd == fd) {
+               size_t k = fde_ndx;
+-              
++
+               ev->pollfds[k].fd = -1;
  
- PHYSICALPATH_FUNC(mod_compress_physical) {
-       plugin_data *p = p_d;
-@@ -589,6 +629,9 @@
-       /* 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;
+               bitset_clear_bit(ev->sigbset, fd);
+-              
 +
-       /* 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];
-@@ -638,6 +681,19 @@
-                                       
-                                       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);
+               if (ev->unused.size == 0) {
+                       ev->unused.size = 16;
+                       ev->unused.ptr = malloc(sizeof(*(ev->unused.ptr)) * ev->unused.size);
+@@ -46,29 +46,29 @@
+                       ev->unused.size += 16;
+                       ev->unused.ptr = realloc(ev->unused.ptr, sizeof(*(ev->unused.ptr)) * ev->unused.size);
+               }
+-              
 +
-+                                      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));
+               ev->unused.ptr[ev->unused.used++] = k;
+       } else {
+               fprintf(stderr, "%s.%d: del! %d %d\n", __FILE__, __LINE__, ev->pollfds[fde_ndx].fd, fd);
+-              
 +
-+                                      /* 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) {
-@@ -651,29 +707,19 @@
-                                               compression_name = dflt_deflate;
-                                       }
-                                       
--                                      /* deflate it */
--                                      if (p->conf.compress_cache_dir->used) {
-+                                      /* deflate it to file (cached) or to memory */
-                                               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) ||
-+                                          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));
-+                                              response_header_overwrite(srv, con,
-+                                                              CONST_STR_LEN("Content-Encoding"),
-+                                                              compression_name, strlen(compression_name));
+               SEGFAULT();
+       }
+-      
 +
-+                                              response_header_overwrite(srv, con,
-+                                                              CONST_STR_LEN("Content-Type"),
-+                                                              CONST_BUF_LEN(sce->content_type));
-                                               
-                                               return HANDLER_FINISHED;
-                                       }
---- lighttpd-1.4.11/src/mod_dirlisting.c       2006-01-13 00:00:45.000000000 +0200
-+++ lighttpd/src/mod_dirlisting.c      2006-07-11 21:23:40.247865249 +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>
+       return -1;
+ }
  
- #include "base.h"
-@@ -31,6 +29,9 @@
- #include <attr/attributes.h>
+ #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
+@@ -78,21 +78,21 @@
+       if (fde_ndx != -1) {
+               if (ev->pollfds[fde_ndx].fd == fd) {
+                       ev->pollfds[fde_ndx].events = events;
+-                      
++
+                       return fde_ndx;
+               }
+               fprintf(stderr, "%s.%d: add: (%d, %d)\n", __FILE__, __LINE__, fde_ndx, ev->pollfds[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].events = events;
  
-+#include "sys-files.h"
-+#include "sys-strings.h"
+               bitset_set_bit(ev->sigbset, fd);
+-              
 +
- /* plugin config for all request/connections */
+               return k;
+       } else {
+               if (ev->size == 0) {
+@@ -102,12 +102,12 @@
+                       ev->size += 16;
+                       ev->pollfds = realloc(ev->pollfds, sizeof(*ev->pollfds) * ev->size);
+               }
+-              
++
+               ev->pollfds[ev->used].fd = fd;
+               ev->pollfds[ev->used].events = events;
  
- typedef struct {
-@@ -292,21 +293,19 @@
-       return HANDLER_GO_ON;
+               bitset_set_bit(ev->sigbset, fd);
+-      
++
+               return ev->used++;
+       }
  }
+@@ -115,20 +115,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 +140,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);
  
--#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];
+@@ -162,12 +162,12 @@
+               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              
++#  endif
+               if (ndx != 0) {
+                       fprintf(stderr, "+\n");
+                       return 0;
+               }
+-              
++
+               return ev->siginfo.si_band & 0x3f;
+       } else {
+               if (ndx >= ev->used) {
+@@ -188,13 +188,13 @@
  
--      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++) {
-@@ -322,30 +321,29 @@
-                       
-                       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);
-                       }
+ 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);
+ }
+@@ -205,12 +205,12 @@
+               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;
        }
-       
-       return 0;
  }
--#undef PATCH
- typedef struct {
-       size_t  namelen;
-@@ -494,7 +492,7 @@
-               /* 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)) {
-@@ -543,7 +541,7 @@
-               /* 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)) {
-@@ -606,7 +604,7 @@
-               name_max = 256; /* stupid default */
- #endif
+@@ -219,34 +219,34 @@
+       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);
+-      
++
+       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;
        }
--#elif defined __WIN32
-+#elif defined _WIN32
-       name_max = FILENAME_MAX;
+-      
++
+       ev->in_sigio = 1;
+       ev->sigbset = bitset_init(ev->maxfds);
+-      
++
+       return 0;
+ }
  #else
-       name_max = NAME_MAX;
-@@ -615,6 +613,11 @@
-       path = malloc(dir->used + name_max);
-       assert(path);
-       strcpy(path, dir->ptr);
-+#ifdef _WIN32
-+    /* append \*.* to the path and keep the \ as part of the pathname */
-+    strcat(path, "\\*.*");
-+    i++;
-+#endif
-       path_file = path + i;
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/fdevent_linux_sysepoll.c lighttpd-1.4.12/src/fdevent_linux_sysepoll.c
+--- lighttpd-1.4.11/src/fdevent_linux_sysepoll.c       2005-09-30 20:29:27.000000000 +0300
++++ lighttpd-1.4.12/src/fdevent_linux_sysepoll.c       2006-07-11 21:23:40.000000000 +0300
+@@ -1,6 +1,5 @@
+ #include <sys/types.h>
  
-       if (NULL == (dp = opendir(path))) {
-@@ -693,8 +696,10 @@
-               if (i > (size_t)name_max) continue;
-               
-               memcpy(path_file, dent->d_name, i + 1);
--              if (stat(path, &st) != 0)
-+              if (stat(path, &st) != 0) {
-+            fprintf(stderr, "%s.%d: %s, %s\r\n", __FILE__, __LINE__, path, strerror(errno));
-                       continue;
-+        }
+-#include <unistd.h>
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <string.h>
+@@ -12,6 +11,8 @@
+ #include "settings.h"
+ #include "buffer.h"
  
-               list = &files;
-               if (S_ISDIR(st.st_mode))
---- lighttpd-1.4.11/src/mod_evasive.c  2006-01-04 15:24:51.000000000 +0200
-+++ lighttpd/src/mod_evasive.c 2006-07-11 21:23:40.187861491 +0300
-@@ -96,13 +96,11 @@
-       return HANDLER_GO_ON;
++#include "sys-files.h"
++
+ #ifdef USE_LINUX_EPOLL
+ static void fdevent_linux_sysepoll_free(fdevents *ev) {
+       close(ev->epoll_fd);
+@@ -20,36 +21,36 @@
+ static int fdevent_linux_sysepoll_event_del(fdevents *ev, int fde_ndx, int fd) {
+       struct epoll_event ep;
+-      
++
+       if (fde_ndx < 0) return -1;
+-      
++
+       memset(&ep, 0, sizeof(ep));
+-      
++
+       ep.data.fd = fd;
+       ep.data.ptr = NULL;
+-      
++
+       if (0 != epoll_ctl(ev->epoll_fd, EPOLL_CTL_DEL, fd, &ep)) {
+               fprintf(stderr, "%s.%d: epoll_ctl failed: %s, dying\n", __FILE__, __LINE__, strerror(errno));
+-              
++
+               SEGFAULT();
+-              
++
+               return 0;
+       }
+-      
+-      
++
++
+       return -1;
  }
  
--#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];
+ static int fdevent_linux_sysepoll_event_add(fdevents *ev, int fde_ndx, int fd, int events) {
+       struct epoll_event ep;
+       int add = 0;
+-      
++
+       if (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;
  
--      PATCH(max_conns);
-+      PATCH_OPTION(max_conns);
-       
-       /* skip the first, the global context */
-       for (i = 1; i < srv->config_context->used; i++) {
-@@ -117,14 +115,13 @@
-                       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);
-                       }
-               }
+@@ -60,20 +61,20 @@
+        * 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)) {
+               fprintf(stderr, "%s.%d: epoll_ctl failed: %s, dying\n", __FILE__, __LINE__, strerror(errno));
+-              
++
+               SEGFAULT();
+-              
++
+               return 0;
        }
-       
-       return 0;
+-      
++
+       return fd;
  }
--#undef PATCH
  
- URIHANDLER_FUNC(mod_evasive_uri_handler) {
-       plugin_data *p = p_d;
---- lighttpd-1.4.11/src/mod_evhost.c   2005-08-17 10:42:03.000000000 +0300
-+++ lighttpd/src/mod_evhost.c  2006-07-11 21:23:39.991849214 +0300
-@@ -7,6 +7,8 @@
- #include "response.h"
- #include "stat_cache.h"
+@@ -83,14 +84,14 @@
  
-+#include "sys-files.h"
+ static int fdevent_linux_sysepoll_event_get_revent(fdevents *ev, size_t ndx) {
+       int events = 0, e;
+-      
 +
- typedef struct {
-       /* unparsed pieces */
-       buffer *path_pieces_raw;
-@@ -221,14 +223,12 @@
-       return 0;
+       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;
  }
  
--#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++) {
-@@ -243,16 +243,14 @@
-                       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;
+@@ -98,17 +99,17 @@
+ # 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;
  }
--#undef PATCH
--
  
- static handler_t mod_evhost_uri_handler(server *srv, connection *con, void *p_d) {
-       plugin_data *p = p_d;
-@@ -299,7 +297,7 @@
-               }
-       }
-       
--      BUFFER_APPEND_SLASH(p->tmp_buf);
-+      PATHNAME_APPEND_SLASH(p->tmp_buf);
-       
-       array_free(parsed_host);
-       
---- lighttpd-1.4.11/src/mod_expire.c   2005-11-03 09:52:13.000000000 +0200
-+++ lighttpd/src/mod_expire.c  2006-07-11 21:23:40.103856229 +0300
-@@ -245,13 +245,11 @@
-       return HANDLER_GO_ON;
- }
+ static int fdevent_linux_sysepoll_event_next_fdndx(fdevents *ev, int ndx) {
+       size_t i;
+-      
++
+       UNUSED(ev);
  
--#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++) {
-@@ -266,14 +264,13 @@
-                       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;
+       i = (ndx < 0) ? 0 : ndx + 1;
+-      
++
+       return i;
  }
--#undef PATCH
- URIHANDLER_FUNC(mod_expire_path_handler) {
-       plugin_data *p = p_d;
---- lighttpd-1.4.11/src/mod_fastcgi.c  2006-03-09 13:18:39.000000000 +0200
-+++ lighttpd/src/mod_fastcgi.c 2006-07-11 21:23:40.207862743 +0300
-@@ -1,5 +1,4 @@
- #include <sys/types.h>
--#include <unistd.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <string.h>
-@@ -24,7 +23,7 @@
- #include "inet_ntop_cache.h"
- #include "stat_cache.h"
  
--#include <fastcgi.h>
-+#include "fastcgi.h"
- #include <stdio.h>
+@@ -116,17 +117,17 @@
+       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);
+-      
++
+       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 +155,7 @@
  
- #ifdef HAVE_SYS_FILIO_H
-@@ -32,7 +31,11 @@
+       fprintf(stderr, "%s.%d: linux-sysepoll not supported, try to set server.event-handler = \"poll\" or \"select\"\n",
+               __FILE__, __LINE__);
+-      
++
+       return -1;
+ }
  #endif
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/fdevent_poll.c lighttpd-1.4.12/src/fdevent_poll.c
+--- lighttpd-1.4.11/src/fdevent_poll.c 2005-11-18 13:59:16.000000000 +0200
++++ lighttpd-1.4.12/src/fdevent_poll.c 2006-07-11 21:23:40.000000000 +0300
+@@ -1,6 +1,5 @@
+ #include <sys/types.h>
  
- #include "sys-socket.h"
-+#include "sys-files.h"
-+#include "sys-strings.h"
-+#include "sys-process.h"
+-#include <unistd.h>
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <string.h>
+@@ -20,19 +19,19 @@
  
-+#include "http_resp.h"
+ 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);
+               SEGFAULT();
+       }
+-      
++
+       if (ev->pollfds[fde_ndx].fd == fd) {
+               size_t k = 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,47 +39,47 @@
+                       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 {
+               SEGFAULT();
+       }
+-      
++
+       return -1;
+ }
  
- #ifndef UNIX_PATH_MAX
- # define UNIX_PATH_MAX 108
-@@ -45,7 +48,6 @@
- #include <sys/wait.h>
+ #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
  
--
- /*
-  * 
-  * TODO:
-@@ -310,10 +312,11 @@
-       buffer *fcgi_env;
-       
-       buffer *path;
--      buffer *parse_response;
-       buffer *statuskey;
-       
-+      http_resp *resp;
+ static int fdevent_poll_event_add(fdevents *ev, int fde_ndx, int fd, int events) {
+       /* known index */
+-      
 +
-       plugin_config **config_storage;
-       
-       plugin_config conf; /* this is only used as long as no handler_ctx is setup */
-@@ -339,11 +342,10 @@
-       
-       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;
+       if (fde_ndx != -1) {
+               if (ev->pollfds[fde_ndx].fd == fd) {
+                       ev->pollfds[fde_ndx].events = events;
+-                      
++
+                       return fde_ndx;
+               }
+               fprintf(stderr, "%s.%d: add: (%d, %d)\n", __FILE__, __LINE__, fde_ndx, ev->pollfds[fde_ndx].fd);
+               SEGFAULT();
+       }
 -      
-       size_t    request_id;
-       int       fd;        /* fd to the fastcgi process */
-       int       fde_ndx;   /* index into the fd-event buffer */
-@@ -451,8 +453,6 @@
-       
-       hctx->fde_ndx = -1;
-       
--      hctx->response_header = buffer_init();
++
+       if (ev->unused.used > 0) {
+               int k = ev->unused.ptr[--ev->unused.used];
+-              
++
+               ev->pollfds[k].fd = fd;
+               ev->pollfds[k].events = events;
+-              
++
+               return k;
+       } else {
+               if (ev->size == 0) {
+@@ -90,10 +89,10 @@
+                       ev->size += 16;
+                       ev->pollfds = realloc(ev->pollfds, sizeof(*ev->pollfds) * ev->size);
+               }
+-              
++
+               ev->pollfds[ev->used].fd = fd;
+               ev->pollfds[ev->used].events = events;
+-              
++
+               return ev->used++;
+       }
+ }
+@@ -109,12 +108,12 @@
+       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;
+       }
 -      
-       hctx->request_id = 0;
-       hctx->state = FCGI_STATE_INIT;
-       hctx->proc = NULL;
-@@ -463,6 +463,7 @@
-       hctx->send_content_body = 1;
++
+       if (ev->pollfds[ndx].revents & POLLNVAL) {
+               /* should never happen */
+               SEGFAULT();
+@@ -131,7 +130,7 @@
+       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;
+ }
  
-       hctx->rb = chunkqueue_init();
-+      hctx->http_rb = chunkqueue_init();
-       hctx->wb = chunkqueue_init();
-       
-       return hctx;
-@@ -474,9 +475,8 @@
-               hctx->host = NULL;
-       }
-       
--      buffer_free(hctx->response_header);
--
-       chunkqueue_free(hctx->rb);
-+      chunkqueue_free(hctx->http_rb);
-       chunkqueue_free(hctx->wb);
+@@ -141,12 +140,12 @@
  
-       free(hctx);
-@@ -639,7 +639,8 @@
-       p->fcgi_env = buffer_init();
-       
-       p->path = buffer_init();
--      p->parse_response = buffer_init();
+ static int fdevent_poll_event_next_fdndx(fdevents *ev, int ndx) {
+       size_t i;
+-      
 +
-+      p->resp = http_response_init();
+       i = (ndx < 0) ? 0 : ndx + 1;
+       for (; i < ev->used; i++) {
+               if (ev->pollfds[i].revents) break;
+       }
+-      
++
+       return i;
+ }
  
-       p->statuskey = buffer_init();
-       
-@@ -657,9 +658,10 @@
-       
-       buffer_free(p->fcgi_env);
-       buffer_free(p->path);
--      buffer_free(p->parse_response);
-       buffer_free(p->statuskey);
-       
-+      http_response_free(p->resp);
+@@ -154,17 +153,17 @@
+       ev->type = FDEVENT_HANDLER_POLL;
+ #define SET(x) \
+       ev->x = fdevent_poll_##x;
+-      
 +
-       if (p->config_storage) {
-               size_t i, j, n;
-               for (i = 0; i < srv->config_context->used; i++) {
-@@ -825,12 +827,8 @@
-               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
+       SET(free);
+       SET(poll);
+-      
 +
-               socket_type = AF_UNIX;
-               fcgi_addr = (struct sockaddr *) &fcgi_addr_un;
+       SET(event_del);
+       SET(event_add);
+-      
++
+       SET(event_next_fdndx);
+       SET(event_get_fd);
+       SET(event_get_revent);
+-      
++
+       return 0;
+ }
  
-@@ -933,7 +931,7 @@
-                       return -1;
-               }
-               
--#ifdef HAVE_FORK      
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/fdevent_select.c lighttpd-1.4.12/src/fdevent_select.c
+--- lighttpd-1.4.11/src/fdevent_select.c       2005-08-31 11:12:46.000000000 +0300
++++ lighttpd-1.4.12/src/fdevent_select.c       2006-07-11 21:23: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) {
+@@ -38,7 +39,9 @@
+       UNUSED(fde_ndx);
+       /* we should be protected by max-fds, but you never know */
 +#ifndef _WIN32
-               switch ((child = fork())) {
-               case 0: {
-                       size_t i = 0;
-@@ -1677,12 +1675,9 @@
-               /* use the unix domain socket */
-               fcgi_addr_un.sun_family = AF_UNIX;
-               strcpy(fcgi_addr_un.sun_path, proc->unixsocket->ptr);
--#ifdef SUN_LEN
+       assert(fd < FD_SETSIZE);
++#endif
+       if (events & FDEVENT_IN) {
+               FD_SET(fd, &(ev->select_set_read));
+@@ -49,28 +52,28 @@
+               FD_SET(fd, &(ev->select_set_write));
+       }
+       FD_SET(fd, &(ev->select_set_error));
+-      
 +
-               servlen = SUN_LEN(&fcgi_addr_un);
--#else
--              /* stevens says: */
--              servlen = proc->unixsocket->used + sizeof(fcgi_addr_un.sun_family);
--#endif
+       if (fd > ev->select_max_fd) ev->select_max_fd = fd;
+-      
 +
-               fcgi_addr = (struct sockaddr *) &fcgi_addr_un;
-       
-               if (buffer_is_empty(proc->connection_name)) {
-@@ -1695,6 +1690,7 @@
- #endif
-       } else {
-               fcgi_addr_in.sin_family = AF_INET;
+       return fd;
+ }
+ static int fdevent_select_poll(fdevents *ev, int timeout_ms) {
+       struct timeval tv;
+-      
 +
-               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, 
-@@ -1702,6 +1698,7 @@
-                       
-                       return -1;
-               }
+       tv.tv_sec =  timeout_ms / 1000;
+       tv.tv_usec = (timeout_ms % 1000) * 1000;
+-      
 +
-               fcgi_addr_in.sin_port = htons(proc->port);
-               servlen = sizeof(fcgi_addr_in);
-               
-@@ -2186,105 +2183,6 @@
-       return 0;
+       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 fcgi_response_parse(server *srv, connection *con, plugin_data *p, buffer *in) {
--      char *s, *ns;
+ static int fdevent_select_event_get_revent(fdevents *ev, size_t ndx) {
+       int revents = 0;
 -      
--      handler_ctx *hctx = con->plugin_ctx[p->id];
--      fcgi_extension_host *host= hctx->host;
++
+       if (FD_ISSET(ndx, &(ev->select_read))) {
+               revents |= FDEVENT_IN;
+       }
+@@ -80,7 +83,7 @@
+       if (FD_ISSET(ndx, &(ev->select_error))) {
+               revents |= FDEVENT_ERR;
+       }
 -      
--      UNUSED(srv);
--
--      buffer_copy_string_buffer(p->parse_response, in);
++
+       return revents;
+ }
+@@ -92,15 +95,15 @@
+ static int fdevent_select_event_next_fdndx(fdevents *ev, int ndx) {
+       int i;
 -      
--      /* 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';
++
+       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;
+ }
+@@ -108,17 +111,17 @@
+       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);
+-      
++
+       return 0;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/fdevent_solaris_devpoll.c lighttpd-1.4.12/src/fdevent_solaris_devpoll.c
+--- lighttpd-1.4.11/src/fdevent_solaris_devpoll.c      2005-09-01 10:45:26.000000000 +0300
++++ lighttpd-1.4.12/src/fdevent_solaris_devpoll.c      2006-07-11 21:23:40.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;
 -              
--              key = s;
--              if (NULL == (value = strchr(s, ':'))) {
--                      /* we expect: "<key>: <value>\n" */
--                      continue;
--              }
++
+       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));
 -              
--              key_len = value - key;
++
+               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;
 -              
--              value++;
--              /* strip WS */
--              while (*value == ' ' || *value == '\t') value++;
++
+       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));
 -              
--              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 -1;
+       }
 -      
--      return 0;
--}
--
- typedef struct {
-       buffer  *b; 
-       size_t   len;
-@@ -2386,52 +2284,24 @@
++
+       return fd;
+ }
  
- 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;
--      }
+ static int fdevent_solaris_devpoll_poll(fdevents *ev, int timeout_ms) {
+       struct dvpoll dopoll;
+       int ret;
 -      
--      /* init read-buffer */
++
+       dopoll.dp_timeout = timeout_ms;
+       dopoll.dp_nfds = ev->maxfds;
+       dopoll.dp_fds = ev->devpollfds;
 -      
--      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);
--
--              b->used = r + 1; /* one extra for the fake \0 */
--              b->ptr[b->used - 1] = '\0';
--      } else {
-+      switch(srv->network_backend_read(srv, con, hctx->fd, hctx->rb)) {
-+      case NETWORK_STATUS_WAIT_FOR_EVENT:
-+              /* we are only triggered when there is a event */
-               log_error_write(srv, __FILE__, __LINE__, "ssdsb", 
-                               "unexpected end-of-file (perhaps the fastcgi process died):",
-                               "pid:", proc->pid,
-                               "socket:", proc->connection_name);
--              
-+              return -1;
-+      case NETWORK_STATUS_SUCCESS:
-+              break;
-+      default:
-+              log_error_write(srv, __FILE__, __LINE__, "s", "fastcgi-read failed");
-               return -1;
-       }
++
+       ret = ioctl(ev->devpoll_fd, DP_POLL, &dopoll);
+-      
++
+       return ret;
+ }
  
-@@ -2454,80 +2324,123 @@
+@@ -85,11 +84,11 @@
  
-                       /* 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);
--                              }
-+                              int have_content_length = 0;
-+                              int need_more = 0;
-+                              size_t i;
+ static int fdevent_solaris_devpoll_event_next_fdndx(fdevents *ev, int last_ndx) {
+       size_t i;
+-      
++
+       UNUSED(ev);
  
--                              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 */
-+                              /* append the current packet to the chunk queue */
-+                              chunkqueue_append_buffer(hctx->http_rb, packet.b);
-+                              http_response_reset(p->resp);
+       i = (last_ndx < 0) ? 0 : last_ndx + 1;
+-      
 +
-+                              switch(http_response_parse_cq(hctx->http_rb, p->resp)) {
-+                              case PARSE_ERROR:
-+                                      /* parsing the response header failed */
+       return i;
+ }
+@@ -117,20 +116,20 @@
+       ev->type = FDEVENT_HANDLER_SOLARIS_DEVPOLL;
+ #define SET(x) \
+       ev->x = fdevent_solaris_devpoll_##x;
+-      
 +
-+                                      con->http_status = 502; /* Bad Gateway */
+       SET(free);
+       SET(poll);
+       SET(reset);
+-      
 +
-+                                      return 1;
-+                              case PARSE_NEED_MORE:
-+                                      need_more = 1;
-+                                      break; /* leave the loop */
-+                              case PARSE_SUCCESS:
-                                       break;
-+                              default:
-+                                      /* should not happen */
-+                                      SEGFAULT();
-                               }
+       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 @@
  
--                              /* parse the response header */
--                              fcgi_response_parse(srv, con, p, hctx->response_header);
-+                              if (need_more) break;
+       fprintf(stderr, "%s.%d: solaris-devpoll not supported, try to set server.event-handler = \"poll\" or \"select\"\n",
+                       __FILE__, __LINE__);
+-      
++
+       return -1;
+ }
+ #endif
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/http-header-glue.c lighttpd-1.4.12/src/http-header-glue.c
+--- lighttpd-1.4.11/src/http-header-glue.c     2006-02-08 15:31:36.000000000 +0200
++++ lighttpd-1.4.12/src/http-header-glue.c     2006-07-11 21:23:40.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 @@
  
--                              con->file_started = 1;
-+                              chunkqueue_remove_finished_chunks(hctx->http_rb);
+ 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 (host->mode == FCGI_AUTHORIZER &&
--                                  (con->http_status == 0 ||
--                                   con->http_status == 200)) {
-+                              con->http_status = p->resp->status;
+       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);
+-      
 +
-+                              /* handle the header fields */
-+                              if (host->mode == FCGI_AUTHORIZER) {
-+                                      /* auth mode is a bit different */
+       array_insert_unique(con->response.headers, (data_unset *)ds);
+-      
 +
-+                                      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;
-                               }
-+                              }
+       return 0;
+ }
  
--                              if (host->allow_xsendfile &&
--                                  NULL != (ds = (data_string *) array_get_element(con->response.headers, "X-LIGHTTPD-send-file"))) {
--                                      stat_cache_entry *sce;
-+                              /* copy the http-headers */
-+                              for (i = 0; i < p->resp->headers->used; i++) {
-+                                      const char *ign[] = { "Status", NULL };
-+                                      size_t j;
-+                                      data_string *ds;
+ 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 (HANDLER_ERROR != stat_cache_get_entry(srv, con, ds->value, &sce)) {
--                                              /* found */
-+                                      data_string *header = (data_string *)p->resp->headers->data[i];
+       /* 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);
+-              
 +
-+                                      /* ignore all headers in AUTHORIZER mode */
-+                                      if (host->mode == FCGI_AUTHORIZER) continue;
+               return 0;
+       }
+-      
 +
-+                                      /* 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;
+       return response_header_insert(srv, con, key, keylen, value, vallen);
+ }
+ int http_response_redirect_to_directory(server *srv, connection *con) {
+       buffer *o;
+-      
 +
-+                                      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"))) {
--                                              http_chunk_append_file(srv, con, ds->value, 0, sce->st.st_size);
-+                                              stat_cache_entry *sce;
-+                                              
-+                                              if (host->allow_xsendfile &&
-+                                                  HANDLER_ERROR != stat_cache_get_entry(srv, con, header->value, &sce)) {
-+                                                      http_chunk_append_file(srv, con, 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);
-                                               
--                              if (hctx->send_content_body && blen > 1) {                                              
--                                      /* enable chunked-transfer-encoding */
-+                                      array_insert_unique(con->response.headers, (data_unset *)ds);
-+                              }
+       o = buffer_init();
+-      
 +
-+                              /* header is complete ... go on with the body */
+       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;
+-              
 +
-+                              con->file_started = 1;
+               our_addr_len = sizeof(our_addr);
+-              
 +
-+                              if (hctx->send_content_body) {
-+                                      chunk *c = hctx->http_rb->first;
+               if (-1 == getsockname(con->fd, &(our_addr.plain), &our_addr_len)) {
+                       con->http_status = 500;
+-                      
 +
-+                                      /* if we don't have a content-length enable chunked encoding 
-+                                       * if possible
-+                                       * 
-+                                       * TODO: move this to a later stage in the filter-queue
-+                                       *  */
-                                       if (con->request.http_version == HTTP_VERSION_1_1 &&
--                                          !(con->parsed_response & HTTP_CONTENT_LENGTH)) {
-+                                          !have_content_length) {
-                                               con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
-                                       }
--                                      http_chunk_append_mem(srv, con, c, blen);
-+                                      /* copy the rest of the data */
-+                                      for (c = hctx->http_rb->first; c; c = c->next) {
-+                                              if (c->mem->used > 1) {
-+                                                      http_chunk_append_mem(srv, con, 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);
-                               joblist_append(srv, con);
-                       }
-@@ -2606,7 +2519,7 @@
-                       if (!proc->is_local) break;
-                       /* the child should not terminate at all */
+                       log_error_write(srv, __FILE__, __LINE__, "ss",
+                                       "can't get sockname", strerror(errno));
 -                      
-+#ifndef _WIN32
-                       switch(waitpid(proc->pid, &status, WNOHANG)) {
-                       case 0:
-                               /* child is still alive */
-@@ -2633,7 +2546,7 @@
-                               proc->state = PROC_STATE_DIED;
-                               break;
-                       }
--
-+#endif
-                       /* fall through if we have a dead proc now */
-                       if (proc->state != PROC_STATE_DIED) break;
-@@ -2934,10 +2847,11 @@
-                                */ 
-                               if (hctx->wb->bytes_out == 0 &&
-                                   hctx->reconnects < 5) {
-+#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;
-@@ -2949,7 +2863,7 @@
-                                * 
-                                */
-                               
--                              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);
-@@ -3155,7 +3069,7 @@
-                               int status;
-                               
-                               /* only fetch the zombie if it is not already done */
++
+                       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)) {
 -                              
-+#ifndef _WIN32
-                               switch(waitpid(proc->pid, &status, WNOHANG)) {
-                               case 0:
-                                       /* child is still alive */
-@@ -3195,6 +3109,7 @@
-                                       
-                                       break;
-                               }
-+#endif
-                       }
-                       if (con->file_started == 0) {
-@@ -3307,15 +3222,14 @@
-       
-       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++) {
-@@ -3330,19 +3244,17 @@
-                       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);
-                       }
+                               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,41 +190,41 @@
+               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;
+-      
++
+       buffer_free(o);
+-      
++
        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;
-@@ -3610,10 +3522,33 @@
-        * 
-        * currently we wait for the TCP timeout which is on Linux 180 seconds
-        * 
--       * 
--       * 
+ 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;
+ }
+@@ -239,56 +239,60 @@
+        *    request. That is, if no entity tags match, then the server MUST NOT
+        *    return a 304 (Not Modified) response.
         */
+-      
++
+       /* 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 (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) {
+                                       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);
+                                       } else {
+                                               used_len = semicolon - con->request.http_if_modified_since;
+                                       }
+-                                      
++
+                                       if (0 == strncmp(con->request.http_if_modified_since, 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;
  
-+      for (i = 0; i < srv->conns->used; i++) {
-+              connection *con = srv->conns->ptr[i];
-+              handler_ctx *hctx = con->plugin_ctx[p->id];
+-                                              /* 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:", 
++                                              /* check if we can safely copy the string */
++                                              if (used_len >= sizeof(buf)) {
++                                                      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);
+-                                                      
 +
-+              /* if a connection is ours and is in handle-req for more than max-request-time
-+               * kill the connection */
+                                                       con->http_status = 412;
+                                                       return HANDLER_FINISHED;
+                                               }
 +
-+              if (con->mode != p->id) continue;
-+              if (con->state != CON_STATE_HANDLE_REQUEST) continue;
-+              if (srv->cur_ts < con->request_start + 60) continue;
 +
-+              /* the request is waiting for a FCGI_STDOUT since 60 seconds */
++                                              strncpy(buf, con->request.http_if_modified_since, used_len);
++                                              buf[used_len] = '\0';
 +
-+              /* kill the connection */
++                                              strptime(buf, "%a, %d %b %Y %H:%M:%S GMT", &tm);
++                                              t_header = mktime(&tm);
 +
-+              log_error_write(srv, __FILE__, __LINE__, "s", "fastcgi backend didn't responded after 60 seconds");
++                                              strptime(mtime->ptr, "%a, %d %b %Y %H:%M:%S GMT", &tm);
++                                              t_file = mktime(&tm);
 +
-+              fcgi_connection_close(srv, hctx);
++                                              if (t_file > t_header) return HANDLER_GO_ON;
 +
-+              con->mode = DIRECT;
-+              con->http_status = 500;
++                                              con->http_status = 304;
++                                              return HANDLER_FINISHED;
++#else
++                        return HANDLER_GO_ON;
++#endif
+                                       }
+                               } else {
+                                       con->http_status = 304;
+@@ -302,16 +306,41 @@
+       } else if (con->request.http_if_modified_since) {
+               size_t used_len;
+               char *semicolon;
+-              
 +
-+              joblist_append(srv, con);
-+      }
+               if (NULL == (semicolon = strchr(con->request.http_if_modified_since, ';'))) {
+                       used_len = strlen(con->request.http_if_modified_since);
+               } else {
+                       used_len = semicolon - con->request.http_if_modified_since;
+               }
+-              
 +
-       /* check all childs if they are still up */
-       for (i = 0; i < srv->config_context->used; i++) {
-@@ -3737,7 +3672,7 @@
-                                       int status;
-                                       
-                                       if (proc->pid == 0) continue;
--                                      
-+#ifndef _WIN32
-                                       switch (waitpid(proc->pid, &status, WNOHANG)) {
-                                       case 0:
-                                               /* child still running after timeout, good */
-@@ -3781,6 +3716,7 @@
-                                               proc->state = PROC_STATE_UNSET;
-                                               host->max_id--;
-                                       }
+               if (0 == strncmp(con->request.http_if_modified_since, 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, 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) return HANDLER_GO_ON;
++
++                      con->http_status = 304;
++                      return HANDLER_FINISHED;
++#else
++            return HANDLER_GO_ON;
 +#endif
-                               }
-                       }
-               }
---- lighttpd-1.4.11/src/mod_flv_streaming.c    2006-03-07 14:06:26.000000000 +0200
-+++ lighttpd/src/mod_flv_streaming.c   2006-07-11 21:23:40.043852471 +0300
-@@ -108,13 +108,11 @@
-       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++) {
-@@ -129,16 +127,15 @@
-                       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;
-@@ -167,7 +164,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));
-@@ -217,7 +214,7 @@
-                       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;
---- lighttpd-1.4.11/src/mod_indexfile.c        2005-09-30 01:08:53.000000000 +0300
-+++ lighttpd/src/mod_indexfile.c       2006-07-11 21:23:40.191861741 +0300
-@@ -103,13 +103,11 @@
-       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++) {
-@@ -124,16 +122,15 @@
-                       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;
---- lighttpd-1.4.11/src/mod_mysql_vhost.c      2006-01-14 20:35:10.000000000 +0200
-+++ lighttpd/src/mod_mysql_vhost.c     2006-07-11 21:23:40.031851719 +0300
-@@ -1,13 +1,18 @@
--#include <unistd.h>
- #include <stdio.h>
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/http_auth.c lighttpd-1.4.12/src/http_auth.c
+--- lighttpd-1.4.11/src/http_auth.c    2006-02-01 13:02:52.000000000 +0200
++++ lighttpd-1.4.12/src/http_auth.c    2006-07-11 21:23:40.000000000 +0300
+@@ -22,7 +22,6 @@
+ #include <string.h>
+ #include <time.h>
  #include <errno.h>
- #include <fcntl.h>
--#include <strings.h>
-+#include <string.h>
+-#include <unistd.h>
+ #include <ctype.h>
  
- #ifdef HAVE_CONFIG_H
- #include "config.h"
- #endif
+ #include "server.h"
+@@ -31,23 +30,14 @@
+ #include "http_auth_digest.h"
+ #include "stream.h"
  
-+#ifdef HAVE_MYSQL_H 
-+# ifdef HAVE_LIBMYSQL
-+#  define HAVE_MYSQL
-+# endif
-+#endif
++#include "sys-strings.h"
 +
- #ifdef HAVE_MYSQL
- #include <mysql.h>
+ #ifdef USE_OPENSSL
+ # include <openssl/md5.h>
+ #else
+ # include "md5.h"
  #endif
-@@ -16,36 +21,21 @@
- #include "log.h"
  
- #include "stat_cache.h"
--#ifdef DEBUG_MOD_MYSQL_VHOST
--#define DEBUG
+-
+-#ifdef USE_PAM
+-#include <security/pam_appl.h>
+-#include <security/pam_misc.h>
+-
+-static struct pam_conv conv = {
+-      misc_conv,
+-              NULL
+-};
 -#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"
+-
+ handler_t auth_ldap_init(server *srv, mod_auth_plugin_config *s);
  
- #ifdef HAVE_MYSQL
--typedef struct {
--      MYSQL   *mysql;
-       
--      buffer  *mydb;
--      buffer  *myuser;
--      buffer  *mypass;
--      buffer  *mysock;
-+#define CORE_PLUGIN "mod_sql_vhost_core"
-       
--      buffer  *hostname;
--      unsigned short port;
-+typedef struct {
-+      MYSQL   *mysql;
-       
-       buffer  *mysql_pre;
-       buffer  *mysql_post;
+ static const char base64_pad = '=';
+@@ -75,25 +65,25 @@
+       unsigned char *result;
+       int ch, j = 0, k;
+       size_t i;
+-      
 +
-+      mod_sql_vhost_core_plugin_config *core;
- } plugin_config;
- /* global plugin data */
-@@ -59,13 +49,7 @@
-       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) {
-@@ -84,10 +68,6 @@
-       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) {
-@@ -99,10 +79,6 @@
-                       
-                       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);
-                       
-@@ -117,109 +93,50 @@
-       return HANDLER_GO_ON;
+       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 +115,168 @@
+               }
+       }
+       result[k] = '\0';
+-      
++
+       out->used = k;
+-      
++
+       return result;
  }
  
--/* 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
+ static int http_auth_get_password(server *srv, mod_auth_plugin_data *p, buffer *username, buffer *realm, buffer *password) {
+       int ret = -1;
 -      
--      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);
--
--      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 }
--        };
++
+       if (!username->used|| !realm->used) return -1;
 -      
-+      /* 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);
 +
+       if (p->conf.auth_backend == AUTH_BACKEND_HTDIGEST) {
+               stream f;
+               char * f_line;
+-              
 +
-+      /* walk through all conditionals and check for assignments */
-       for (i = 0; i < srv->config_context->used; i++) {
-               plugin_config *s;
-               buffer *sel;
-+              char *qmark;
-               
+               if (buffer_is_empty(p->conf.auth_htdigest_userfile)) return -1;
 -              
-+              /* 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->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);
+               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;
+               }
 -              
-               p->config_storage[i] = s;
-               
--              if (config_insert_values_global(srv, 
--                      ((data_config *)srv->config_context->data[i])->value,
--                      cv)) return HANDLER_ERROR;
-+              /* check if we are the plugin for this backend */
-+              if (!buffer_is_equal_string(s->core->backend, CONST_STR_LEN("mysql"))) continue;
-               
--              s->mysql_pre = buffer_init();
--              s->mysql_post = buffer_init();
-+              /* 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';
-@@ -241,8 +158,8 @@
-                */
-               
-               /* 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;
-               
-@@ -251,10 +168,10 @@
-                               
-                               return HANDLER_ERROR;
+               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;
                        }
--#define FOO(x) (s->x->used ? s->x->ptr : NULL)
-+#define FOO(x) (s->core->x->used ? s->core->x->ptr : NULL)
-                       
--                      if (!mysql_real_connect(s->mysql, FOO(hostname), FOO(myuser), FOO(mypass), 
--                                              FOO(mydb), s->port, FOO(mysock), 0)) {
-+                      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;
-@@ -275,17 +192,13 @@
-         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++) {
-@@ -295,31 +208,21 @@
-               /* 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 +235,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,76 +243,42 @@
-       }
-       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 (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'");
+-                              
 +
-       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;
--      }
--
--      /* cache the data */
--      buffer_copy_string_buffer(c->server_name, con->uri.authority);
--      buffer_copy_string_buffer(c->document_root, p->tmp_buf);
-+      buffer_copy_string(docroot, row[0]);
--      /* fcgi_offset and fcgi_arg are optional */
--      if (cols > 1 && row[1]) {
--              c->fcgi_offset = atoi(row[1]);
+                               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;
+               }
 -              
--              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;
- }
- /* 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;
- }
---- lighttpd-1.4.11/src/mod_proxy.c    2006-01-31 13:01:22.000000000 +0200
-+++ lighttpd/src/mod_proxy.c   2006-07-11 21:23:40.099855979 +0300
-@@ -1,6 +1,5 @@
- #include <sys/types.h>
--#include <unistd.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <string.h>
-@@ -23,6 +22,9 @@
- #include "inet_ntop_cache.h"
- #include "crc32.h"
-+#include "network.h"
 +
-+#include "http_resp.h"
- #include <stdio.h>
-@@ -31,6 +33,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
-@@ -66,6 +70,8 @@
-       int debug;
-       proxy_balance_t balance;
+               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;
+-              
 +
-+      array *last_used_backends; /* "extension" : last_used_backend */
- } plugin_config;
- typedef struct {
-@@ -74,6 +80,8 @@
-       buffer *parse_response;
-       buffer *balance_buf;
-       
-+      array *ignore_headers;
+               auth_fn = (p->conf.auth_backend == AUTH_BACKEND_HTPASSWD) ? p->conf.auth_htpasswd_userfile : p->conf.auth_plain_userfile;
+-              
 +
-       plugin_config **config_storage;
-       
-       plugin_config conf;
-@@ -84,7 +92,8 @@
-       PROXY_STATE_CONNECT, 
-       PROXY_STATE_PREPARE_WRITE, 
-       PROXY_STATE_WRITE, 
--      PROXY_STATE_READ, 
-+    PROXY_STATE_RESPONSE_HEADER,
-+    PROXY_STATE_RESPONSE_CONTENT,
-       PROXY_STATE_ERROR 
- } proxy_connection_state_t;
-@@ -100,6 +109,7 @@
-       buffer *response_header;
-       chunkqueue *wb;
-+    chunkqueue *rb;
-       
-       int fd; /* fd to the proxy process */
-       int fde_ndx; /* index into the fd-event buffer */
-@@ -127,6 +137,7 @@
-       hctx->response_header = buffer_init();
-       hctx->wb = chunkqueue_init();
-+    hctx->rb = chunkqueue_init();
-       hctx->fd = -1;
-       hctx->fde_ndx = -1;
-@@ -138,17 +149,38 @@
-       buffer_free(hctx->response);
-       buffer_free(hctx->response_header);
-       chunkqueue_free(hctx->wb);
-+    chunkqueue_free(hctx->rb);
-       
-       free(hctx);
- }
- INIT_FUNC(mod_proxy_init) {
-       plugin_data *p;
-+      size_t i;
+               if (buffer_is_empty(auth_fn)) return -1;
+-              
 +
-+      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();
+               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));
+-                      
 +
-+      for (i = 0; hop2hop_headers[i]; i++) {
-+              data_string *ds;
+                       return -1;
+               }
+-              
 +
-+              if (NULL == (ds = (data_string *)array_get_unused_element(p->ignore_headers, TYPE_STRING))) {
-+                      ds = data_string_init();
-+              }
+               f_line = f.start;
+-              
 +
-+              buffer_copy_string(ds->value, hop2hop_headers[i]);
-+              array_insert_unique(p->ignore_headers, (data_unset *)ds);
-+      }
-       
-       return p;
- }
-@@ -168,8 +200,8 @@
-                       plugin_config *s = p->config_storage[i];
-                       
-                       if (s) {
+               while (f_line - f.start != f.size) {
+                       char *f_user, *f_pwd, *e;
+                       size_t u_len, pwd_len;
 -                      
-                               array_free(s->extensions);
-+                              array_free(s->last_used_backends);
-                       
-                               free(s);
++
+                       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;
                        }
-@@ -177,6 +209,8 @@
-               free(p->config_storage);
-       }
-       
-+      free(p->ignore_headers);
+-                      
 +
-       free(p);
-       
-       return HANDLER_GO_ON;
-@@ -202,6 +236,7 @@
-               
-               s = malloc(sizeof(plugin_config));
-               s->extensions    = array_init();
-+              s->last_used_backends = array_init();
-               s->debug         = 0;
-               
-               cv[0].destination = s->extensions;
-@@ -372,14 +407,22 @@
-       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", 
-                                               "connect delayed:", proxy_fd);
+                       /* 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);
                        }
-                       
-                       return 1;
--              } else {
-+              default:
-                       
-                       log_error_write(srv, __FILE__, __LINE__, "sdsd", 
-                                       "connect failed:", proxy_fd, strerror(errno), errno);
-@@ -387,6 +430,7 @@
-                       return -1;
+-                      
++
+                       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;
        }
-+    fprintf(stderr, "%s.%d: connected fd = %d\r\n", __FILE__, __LINE__, proxy_fd);
-       if (p->conf.debug) {
-               log_error_write(srv, __FILE__, __LINE__, "sd", 
-                               "connect succeeded: ", proxy_fd);
-@@ -424,6 +468,7 @@
-       size_t i;
-       
-       connection *con   = hctx->remote_conn;
-+      plugin_data *p    = hctx->plugin_data;
-       buffer *b;
-       
-       /* build header */
-@@ -453,7 +498,9 @@
-               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;
+-      
 +
-+                      /* don't copy hop-to-hop headers */
-+                      if (array_get_element(p->ignore_headers, ds->key->ptr)) continue;
-                       
-                       buffer_append_string_buffer(b, ds->key);
-                       BUFFER_APPEND_STRING_CONST(b, ": ");
-@@ -531,199 +578,101 @@
+       return ret;
  }
  
+@@ -296,7 +286,7 @@
+       int username_len;
+       data_string *require;
+       array *req;
+-      
++
+       UNUSED(group);
+       UNUSED(host);
  
--static int proxy_response_parse(server *srv, connection *con, plugin_data *p, buffer *in) {
--      char *s, *ns;
--      int http_response_status = -1;
+@@ -304,12 +294,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;
+               }
+       }
 -      
--      UNUSED(srv);
--
--      /* \r\n -> \0\0 */
++
+       if (i == p->conf.auth_require->used) {
+               return -1;
+       }
+@@ -317,72 +307,72 @@
+       req = ((data_array *)(p->conf.auth_require->data[i]))->value;
+       require = (data_string *)array_get_element(req, "require");
 -      
--      buffer_copy_string_buffer(p->parse_response, in);
++
+       /* if we get here, the user we got a authed user */
+       if (0 == strcmp(require->value->ptr, "valid-user")) {
+               return 0;
+       }
 -      
--      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;
++
+       /* 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;
 -              
--              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++);
-+static void chunkqueue_print(chunkqueue *cq) {
-+    chunk *c;
--                      if (*key) {
--                              http_response_status = (int) strtol(key, NULL, 10);
--                              if (http_response_status <= 0) http_response_status = 502;
--                      } else {
--                              http_response_status = 502;
-+    for (c = cq->first; c; c = c->next) {
-+        fprintf(stderr, "%s", c->mem->ptr + c->offset);
-                       }
--
--                      con->http_status = http_response_status;
--                      con->parsed_response |= HTTP_STATUS;
--                      continue;
-+    fprintf(stderr, "\r\n");
++
+               e = strchr(r, '|');
+-              
++
+               if (e) {
+                       r_len = e - r;
+               } else {
+                       r_len = strlen(rules) - (r - rules);
                }
-               
--              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++;
++
+               /* from r to r + r_len is a rule */
 -              
--              copy_header = 1;
-+static int proxy_demux_response(server *srv, handler_ctx *hctx) {
-+      plugin_data *p    = hctx->plugin_data;
-+      connection *con   = hctx->remote_conn;
-+      int proxy_fd       = hctx->fd;
-+    chunkqueue *next_queue = NULL;
-+    chunk *c = NULL;
-               
--              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;
--                      }
-+    switch(srv->network_backend_read(srv, con, proxy_fd, hctx->rb)) {
-+    case NETWORK_STATUS_SUCCESS:
-+        /* we got content */
-                       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;
--              }
-+    case NETWORK_STATUS_CONNECTION_CLOSE:
-+        /* we are done, get out of here */
-+              con->file_finished = 1;
--              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);
-+        /* close the chunk-queue with a empty chunk */
-+              http_chunk_append_mem(srv, con, NULL, 0);
-+              joblist_append(srv, con);
-                       
--                      array_insert_unique(con->response.headers, (data_unset *)ds);
--              }
-+        return 1;
-+    default:
-+        /* oops */
-+        return -1;
++
+               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 +394,19 @@
+                       log_error_write(srv, __FILE__, __LINE__, "s", "unknown  key");
+                       return -1;
+               }
+-              
++
+               if (!e) break;
+               r = e + 1;
        }
-       
--      return 0;
--}
-+    /* looks like we got some content
-+    *
-+    * split off the header from the incoming stream
-+    */
+-      
++
+       log_error_write(srv, __FILE__, __LINE__, "s", "nothing matched");
+-      
++
+       return -1;
+ }
  
-+    if (hctx->state == PROXY_STATE_RESPONSE_HEADER) {
-+        http_resp *resp = http_response_init();
+ /**
+- * 
+- * 
++ *
++ *
+  * @param password password-string from the auth-backend
+  * @param pw       password-string from the client
+  */
+@@ -426,16 +416,16 @@
+       UNUSED(req);
  
--static int proxy_demux_response(server *srv, handler_ctx *hctx) {
--      int fin = 0;
--      int b;
--      ssize_t r;
-+        /* the response header is not fully received yet,
-+        *
-+        * extract the http-response header from the rb-cq
-+        */
-+        fprintf(stderr, "%s.%d: network-read\r\n", __FILE__, __LINE__);
-+        chunkqueue_print(hctx->rb);
-       
--      plugin_data *p    = hctx->plugin_data;
--      connection *con   = hctx->remote_conn;
--      int proxy_fd       = hctx->fd;
-+        switch (http_response_parse_cq(hctx->rb, resp)) {
-+        case PARSE_ERROR:
-+            /* parsing failed */
-       
--      /* check how much we have to read */
--      if (ioctl(hctx->fd, FIONREAD, &b)) {
--              log_error_write(srv, __FILE__, __LINE__, "sd", 
--                              "ioctl failed: ",
--                              proxy_fd);
--              return -1;
--      }
-+            con->http_status = 502; /* Bad Gateway */
-+            return 1;
-+        case PARSE_NEED_MORE:
-+            return 0;
-+        case PARSE_SUCCESS:
-+            con->http_status = resp->status;
+       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 +433,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)) {
+                       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
+                */
  
-+            fprintf(stderr, "%s.%d: parsing done\r\n", __FILE__, __LINE__);
-+            chunkqueue_print(hctx->rb);
+-              /* 
++              /*
+                *  Algorithm      Salt
+                *  CRYPT_STD_DES   2-character (Default)
+                *  CRYPT_EXT_DES   9-character
+@@ -478,7 +468,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,7 +485,7 @@
+               strncpy(salt, password->ptr, salt_len);
  
--      if (p->conf.debug) {
--              log_error_write(srv, __FILE__, __LINE__, "sd",
--                             "proxy - have to read:", b);
--      }
-+            con->file_started = 1;
+               salt[salt_len] = '\0';
+-              
++
+               crypted = crypt(pw, salt);
  
--      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);
-+            hctx->state = PROXY_STATE_RESPONSE_CONTENT;
-+            break;
+               if (0 == strcmp(password->ptr, crypted)) {
+@@ -503,40 +493,13 @@
+               } else {
+                       fprintf(stderr, "%s.%d\n", __FILE__, __LINE__);
                }
--              
--              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;
+-      
+-#endif        
+-      } else if (p->conf.auth_backend == AUTH_BACKEND_PLAIN) { 
++
++#endif
++      } else if (p->conf.auth_backend == AUTH_BACKEND_PLAIN) {
+               if (0 == strcmp(password->ptr, pw)) {
+                       return 0;
                }
-               
--              /* this should be catched by the b > 0 above */
--              assert(r);
-+    /* FIXME: pass the response-header to the other plugins to
-+    * setup the filter-queue
-+    *
-+    * - use next-queue instead of con->write_queue
-+    */
-               
--              hctx->response->used += r;
--              hctx->response->ptr[hctx->response->used - 1] = '\0';
-+    next_queue = con->write_queue;
--#if 0
--              log_error_write(srv, __FILE__, __LINE__, "sdsbs", 
--                              "demux: Response buffer len", hctx->response->used, ":", hctx->response, ":");
--#endif
-+    assert(hctx->state == PROXY_STATE_RESPONSE_CONTENT);
--              if (0 == con->got_response) {
--                      con->got_response = 1;
--                      buffer_prepare_copy(hctx->response_header, 128);
+-      } 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 (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);
-+    /* FIXME: if we have a content-length or chunked-encoding
-+    * handle it.
-+    *
-+    * for now we wait for EOF on the socket */
-                                       
--                              /* 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;
--                              }
-+    /* copy the content to the next cq */
-+    for (c = hctx->rb->first; c; c = c->next) {
-+        http_chunk_append_mem(srv, con, c->mem->ptr + c->offset, c->mem->used - c->offset);
-                                       
--                              con->file_started = 1;
--                              if (blen) {
--                                      http_chunk_append_mem(srv, con, c + 4, blen + 1);
--                                      joblist_append(srv, con);
-+        c->offset = c->mem->used - 1;
-                               }
--                              hctx->response->used = 0;
--                      }
+-              
+-              if (retval == PAM_SUCCESS) {
+-                      log_error_write(srv, __FILE__, __LINE__, "s", "Authenticated");
+-                      return 0;
 -              } else {
--                      http_chunk_append_mem(srv, con, hctx->response->ptr, hctx->response->used);
--                      joblist_append(srv, con);
--                      hctx->response->used = 0;
+-                      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 +507,45 @@
+               int ret;
+               char *attrs[] = { LDAP_NO_ATTRS, NULL };
+               size_t i;
 -              
--      } else {
--              /* reading from upstream done */
--              con->file_finished = 1;
++
+               /* for now we stay synchronous */
 -              
--              http_chunk_append_mem(srv, con, NULL, 0);
--              joblist_append(srv, con);
-               
--              fin = 1;
--      }
-+    chunkqueue_remove_finished_chunks(hctx->rb);
-       
--      return fin;
-+      return 0;
- }
-@@ -803,6 +752,7 @@
-                       if (p->conf.debug) {
-                               log_error_write(srv, __FILE__, __LINE__,  "s", "proxy - connect - delayed success"); 
-                       }
-+            fprintf(stderr, "%s.%d: connected fd = %d\r\n", __FILE__, __LINE__, hctx->fd);
-               }
-               
-               proxy_set_state(srv, hctx, PROXY_STATE_PREPARE_WRITE);
-@@ -818,21 +768,20 @@
-               chunkqueue_remove_finished_chunks(hctx->wb);
--              if (-1 == ret) {
--                      if (errno != EAGAIN &&
--                          errno != EINTR) {
-+              switch(ret) {
-+        case NETWORK_STATUS_FATAL_ERROR:
-                               log_error_write(srv, __FILE__, __LINE__, "ssd", "write failed:", strerror(errno), errno);
-                               
-                               return HANDLER_ERROR;
--                      } else {
-+        case NETWORK_STATUS_WAIT_FOR_EVENT:
+-              /* 
 +
-                               fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
-                               return HANDLER_WAIT_FOR_EVENT;
++              /*
+                * 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;
                        }
--              }
-               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);
-@@ -843,8 +792,9 @@
                }
-               
-               return HANDLER_WAIT_FOR_EVENT;
--      case PROXY_STATE_READ:
-+      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");
-@@ -854,15 +804,14 @@
-       return HANDLER_GO_ON;
- }
++
++
+               /* 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 +553,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))) {
  
--#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++) {
-@@ -877,18 +826,18 @@
-                       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);
+-                      log_error_write(srv, __FILE__, __LINE__, "sssb", 
++                      log_error_write(srv, __FILE__, __LINE__, "sssb",
+                                       "ldap:", ldap_err2string(ret), "filter:", p->ldap_filter);
+-                      
++
+                       return -1;
                        }
                }
-       }
-       
-       return 0;
- }
--#undef PATCH
- SUBREQUEST_FUNC(mod_proxy_handle_subrequest) {
-       plugin_data *p = p_d;
-@@ -954,7 +903,8 @@
-       
-       
-       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", 
-@@ -1058,6 +1008,11 @@
-       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;
-@@ -1111,6 +1066,8 @@
-               return HANDLER_GO_ON;
-       }
-+      backends = extension->value;
+               if (NULL == (first = ldap_first_entry(p->conf.ldap, lm))) {
+                       log_error_write(srv, __FILE__, __LINE__, "s", "ldap ...");
+-                      
 +
-       if (p->conf.debug) {    
-               log_error_write(srv, __FILE__, __LINE__,  "s", "proxy - ext found");
-       }
-@@ -1121,33 +1078,33 @@
-               if (p->conf.debug) {
-                       log_error_write(srv, __FILE__, __LINE__,  "sd", 
--                                      "proxy - used hash balancing, hosts:", extension->value->used);
-+                                      "proxy - used hash balancing, hosts:", backends->used);
+                       ldap_msgfree(lm);
+-                      
++
+                       return -1;
                }
--              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", 
-                                               "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;
-                       }
+               if (NULL == (dn = ldap_get_dn(p->conf.ldap, first))) {
+                       log_error_write(srv, __FILE__, __LINE__, "s", "ldap ...");
+-                      
++
+                       ldap_msgfree(lm);
+-                      
++
+                       return -1;
                }
-@@ -1159,15 +1116,16 @@
-                                       "proxy - used fair balancing");
+-              
++
+               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;
                }
--              for (k = 0, ndx = -1, max_usage = INT_MAX; k < extension->value->used; k++) {
--                      data_proxy *host = (data_proxy *)extension->value->data[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 (host->is_disabled) continue;
-+                      if (cur->is_disabled) continue;
--                      if (host->usage < max_usage) {
--                              max_usage = host->usage;
-+                      if (NULL == host || cur->usage < max_usage) {
-+                              max_usage = cur->usage;
-                       
--                              ndx = k;
-+                              host = cur;
-                       }
+-              
++
+               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;
+                       }
+               }
  
-@@ -1180,30 +1138,50 @@
+-              
++
+               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;
                }
-               /* just to be sure */
--              assert(extension->value->used < INT_MAX);
-+              assert(backends->used < INT_MAX);
+-              
 +
-+              /* send each request to another host:
-+               *
-+               * e.g.:
-+               *
-+               * if we have three hosts it is
-+               *
-+               * 1 .. 2 .. 3 .. 1 .. 2 .. 3
-+               *
-+               **/
+               /* 5. */
+               ldap_unbind_s(ldap);
+-              
 +
-+              /* walk through the list */
-+              last_used_backend = (data_integer *)array_get_element(p->conf.last_used_backends, extension->key->ptr);
-               
--              for (k = 0, ndx = -1, max_usage = INT_MAX; k < extension->value->used; k++) {
--                      data_proxy *host = (data_proxy *)extension->value->data[k];
-+              if (NULL == last_used_backend) {
-+                      last_used_backend = data_integer_init();
-               
--                      if (host->is_disabled) continue;
-+                      buffer_copy_string_buffer(last_used_backend->key, extension->key);
-+                      last_used_backend->value = 0;
--                      /* first usable ndx */
--                      if (max_usage == INT_MAX) {
--                              max_usage = k;
-+                      array_insert_unique(p->conf.last_used_backends, (data_unset *)last_used_backend);
-                       }
--                      /* get next ndx */
--                      if ((int)k > host->last_used_ndx) {
--                              ndx = k;
--                              host->last_used_ndx = k;
-+              /* 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];
+               /* everything worked, good, access granted */
+-              
 +
-+                      if (cur->is_disabled) continue;
+               return 0;
+ #endif
+       }
+@@ -664,65 +627,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;
+-      
 +
-+                      host = cur;
+       data_string *realm;
+-      
 +
-+                      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];
+       realm = (data_string *)array_get_element(req, "realm");
+-      
 +
-+                      if (host->is_disabled) host = NULL;
-               }
-               break;
-@@ -1211,17 +1189,18 @@
-               break;
+       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;
        }
-       
--      /* found a server */
--      if (ndx != -1) {
--              data_proxy *host = (data_proxy *)extension->value->data[ndx];
-+      /* we havn't found a host */
-+      if (NULL == host) {
-+              con->http_status = 500;
-               
--              /* 
--               * if check-local is disabled, use the uri.path handler 
--               * 
--               */
-+              log_error_write(srv, __FILE__, __LINE__,  "sb",
-+                              "no proxy-handler found for:",
-+                              fn);
+-      
 +
-+              return HANDLER_FINISHED;
-+      }
-               
-               /* init handler-context */
--              handler_ctx *hctx;
-               hctx = handler_ctx_init();
-                               
-               hctx->path_info_offset = path_info_offset;
-@@ -1233,6 +1212,7 @@
-               
-               host->usage++;
-               
-+      /* we handle this request */
-               con->mode = p->id;
-               
-               if (p->conf.debug) {
-@@ -1242,17 +1222,6 @@
-               }
-               return HANDLER_GO_ON;
--      } else {
--              /* no handler found */
--              con->http_status = 500;
+       *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__,  "sb", 
--                              "no proxy-handler found for:", 
--                              fn);
++
+               log_error_write(srv, __FILE__, __LINE__, "s", "get_password failed");
 -              
--              return HANDLER_FINISHED;
--      }
--      return HANDLER_GO_ON;
++
+               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;
  }
  
- static handler_t mod_proxy_connection_close_callback(server *srv, connection *con, void *p_d) {
---- lighttpd-1.4.11/src/mod_redirect.c 2006-02-08 15:38:06.000000000 +0200
-+++ lighttpd/src/mod_redirect.c        2006-07-11 21:23:40.111856730 +0300
-@@ -166,7 +166,7 @@
- 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;
+@@ -735,7 +698,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 +708,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;
+-      
++
  
-       /* 
-        * REWRITE URL
-@@ -178,70 +178,9 @@
-       mod_redirect_patch_connection(srv, con, p);
-       
-       buffer_copy_string_buffer(p->match_buf, con->request.uri);
-+      i = config_exec_pcre_keyvalue_buffer(con, p->conf.redirect, p->conf.context, p->match_buf, p->location);
-       
--      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;
+       /* init pointers */
+ #define S(x) \
+@@ -771,11 +734,11 @@
+               { S("cnonce=") },
+               { S("nc=") },
+               { S("response=") },
 -              
--              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);
--                                      }
++
+               { NULL, 0, NULL }
+       };
+ #undef S
+-      
++
+       dkv[0].ptr = &username;
+       dkv[1].ptr = &realm;
+       dkv[2].ptr = &nonce;
+@@ -786,24 +749,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 +775,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;
 -                                      
--                                      k++;
--                                      start = k + 1;
--                              } 
--                      }
--                      
--                      buffer_append_string_len(p->location, pattern + start, pattern_len - start);
--                      
--                      pcre_free(list);
--                      
-+      if (i >= 0) {
-                       response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(p->location));
-                       
-                       con->http_status = 301;
-@@ -249,6 +188,9 @@
-                       
-                       return HANDLER_FINISHED;
++
+                                       *e = '\0';
+                               } else {
+                                       /* value without "...", terminated by EOL */
+@@ -833,7 +796,7 @@
+                       }
                }
-+      else if (i != PCRE_ERROR_NOMATCH) {
+       }
+-      
++
+       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 +808,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",
-+                              "execution error while matching", i);
+                               "digest: missing field");
+               return -1;
        }
- #undef N
-               
---- lighttpd-1.4.11/src/mod_rewrite.c  2005-09-29 20:59:10.000000000 +0300
-+++ lighttpd/src/mod_rewrite.c 2006-07-11 21:23:39.947846458 +0300
-@@ -13,24 +13,8 @@
- #endif
  
- typedef struct {
--#ifdef HAVE_PCRE_H
--      pcre *key;
--#endif
+-      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 +836,10 @@
+               buffer_free(realm_buf);
+               return 0;
+       }
 -      
--      buffer *value;
++
+       buffer_free(username_buf);
+       buffer_free(realm_buf);
 -      
--      int once;
--} rewrite_rule;
--
--typedef struct {
--      rewrite_rule **ptr;
++
+       if (p->conf.auth_backend == AUTH_BACKEND_PLAIN) {
+               /* generate password from plain-text */
+               MD5_Init(&Md5Ctx);
+@@ -890,16 +853,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();
+       }
 -      
--      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;
-@@ -63,80 +47,6 @@
-       free(hctx);
- }
--rewrite_rule_buffer *rewrite_rule_buffer_init(void) {
--      rewrite_rule_buffer *kvb;
++
+       buffer_free(password);
 -      
--      kvb = calloc(1, sizeof(*kvb));
++
+       if (algorithm &&
+           strcasecmp(algorithm, "md5-sess") == 0) {
+               MD5_Init(&Md5Ctx);
+@@ -910,9 +873,9 @@
+               MD5_Update(&Md5Ctx, (unsigned char *)cnonce, strlen(cnonce));
+               MD5_Final(HA1, &Md5Ctx);
+       }
 -      
--      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;
++
+       CvtHex(HA1, a1);
 -      
--      if (!key) return -1;
--
--      if (kvb->size == 0) {
--              kvb->size = 4;
--              kvb->used = 0;
--              
--              kvb->ptr = malloc(kvb->size * sizeof(*kvb->ptr));
++
+       /* calculate H(A2) */
+       MD5_Init(&Md5Ctx);
+       MD5_Update(&Md5Ctx, (unsigned char *)m, strlen(m));
+@@ -924,7 +887,7 @@
+       }
+       MD5_Final(HA2, &Md5Ctx);
+       CvtHex(HA2, HA2Hex);
+-      
++
+       /* calculate response */
+       MD5_Init(&Md5Ctx);
+       MD5_Update(&Md5Ctx, (unsigned char *)a1, HASHHEXLEN);
+@@ -942,39 +905,39 @@
+       MD5_Update(&Md5Ctx, (unsigned char *)HA2Hex, HASHHEXLEN);
+       MD5_Final(RespHash, &Md5Ctx);
+       CvtHex(RespHash, a2);
+-      
++
+       if (0 != strcmp(a2, respons)) {
+               /* digest not ok */
 -              
--              for(i = 0; i < kvb->size; i++) {
--                      kvb->ptr[i] = calloc(1, sizeof(**kvb->ptr));
--              }
--      } else if (kvb->used == kvb->size) {
--              kvb->size += 4;
++
+               if (p->conf.auth_debug) {
+-                      log_error_write(srv, __FILE__, __LINE__, "sss", 
++                      log_error_write(srv, __FILE__, __LINE__, "sss",
+                               "digest: digest mismatch", a2, respons);
+               }
 -              
--              kvb->ptr = realloc(kvb->ptr, kvb->size * sizeof(*kvb->ptr));
+-              log_error_write(srv, __FILE__, __LINE__, "sss", 
++
++              log_error_write(srv, __FILE__, __LINE__, "sss",
+                               "digest: auth failed for", username, "wrong password");
 -              
--              for(i = kvb->used; i < kvb->size; i++) {
--                      kvb->ptr[i] = calloc(1, sizeof(**kvb->ptr));
--              }
--      }
++
+               buffer_free(b);
+               return 0;
+       }
 -      
--      if (NULL == (kvb->ptr[kvb->used]->key = pcre_compile(key->ptr,
--                                                          0, &errptr, &erroff, NULL))) {
++
+       /* value is our allow-rules */
+       if (http_auth_match_rules(srv, p, url->ptr, username, NULL, NULL)) {
+               buffer_free(b);
 -              
--              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;
+-              log_error_write(srv, __FILE__, __LINE__, "s", 
++
++              log_error_write(srv, __FILE__, __LINE__, "s",
+                               "digest: rules did match");
+-              
++
+               return 0;
+       }
 -      
--      kvb->used++;
++
+       /* remember the username */
+       buffer_copy_string(p->auth_user, username);
 -      
--      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]);
--      }
++
+       buffer_free(b);
 -      
--      if (kvb->ptr) free(kvb->ptr);
--#endif
++
+       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 +948,23 @@
+       HASH h;
+       MD5_CTX Md5Ctx;
+       char hh[32];
 -      
--      free(kvb);
--}
--
++
+       UNUSED(p);
  
- INIT_FUNC(mod_rewrite_init) {
-       plugin_data *p;
-@@ -160,7 +70,8 @@
-               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);
-               }
-@@ -198,10 +109,9 @@
-                               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", 
-                                               "pcre-compile failed for", da->value->data[j]->key);
-@@ -210,6 +120,12 @@
-                                               "pcre support is missing, please install libpcre and the headers");
+       /* 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;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/http_auth.h lighttpd-1.4.12/src/http_auth.h
+--- lighttpd-1.4.11/src/http_auth.h    2005-08-14 17:12:31.000000000 +0300
++++ lighttpd-1.4.12/src/http_auth.h    2006-07-11 21:23:40.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;
+-      
 +
-+                      if (once) {
-+                              buffer_append_string_len(s->once, CONST_STR_LEN("1"));
-+                      } else {
-+                              buffer_append_string_len(s->once, CONST_STR_LEN("0"));
-+                      }
-               }
-       }
-       
-@@ -245,11 +161,8 @@
-               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;
-@@ -271,6 +184,7 @@
-       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++) {
-@@ -288,15 +202,19 @@
-                       
-                       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;
-                       }
-               }
-@@ -321,7 +239,7 @@
- URIHANDLER_FUNC(mod_rewrite_uri_handler) {
- #ifdef HAVE_PCRE_H
-       plugin_data *p = p_d;
--      size_t i;
-+      int i;
-       handler_ctx *hctx;
-       /* 
-@@ -349,76 +267,21 @@
-       if (!p->conf.rewrite) return HANDLER_GO_ON;
-       
-       buffer_copy_string_buffer(p->match_buf, con->request.uri);
-+      i = config_exec_pcre_keyvalue_buffer(con, p->conf.rewrite, p->conf.context, 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);
--                      
-+      if (i >= 0) {
-                       hctx = handler_ctx_init();
-                               
-                       con->plugin_ctx[p->id] = hctx;
-                       
--                      if (rule->once) hctx->state = REWRITE_STATE_FINISHED;
-+              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
-               
---- lighttpd-1.4.11/src/mod_rrdtool.c  2005-08-22 01:52:24.000000000 +0300
-+++ lighttpd/src/mod_rrdtool.c 2006-07-11 21:23:40.059853473 +0300
-@@ -5,7 +5,6 @@
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
--#include <unistd.h>
- #include <errno.h>
- #include <time.h>
+       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;
  
-@@ -20,6 +19,10 @@
- /* no need for waitpid if we don't have fork */
- #include <sys/wait.h>
+ #ifdef USE_LDAP
+       buffer *ldap_filter;
  #endif
+-      
 +
-+#include "sys-files.h"
-+#include "sys-process.h"
+       mod_auth_plugin_config **config_storage;
+-      
 +
- typedef struct {
-       buffer *path_rrdtool_bin;
-       buffer *path_rrd;
-@@ -250,14 +253,12 @@
-       return HANDLER_GO_ON;
- }
+       mod_auth_plugin_config conf; /* this is only used as long as no handler_ctx is setup */
+ } mod_auth_plugin_data;
  
--#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);
-@@ -276,7 +277,7 @@
-                       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);
-@@ -288,7 +289,6 @@
-       
-       return 0;
- }
--#undef PATCH
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/http_auth_digest.h lighttpd-1.4.12/src/http_auth_digest.h
+--- lighttpd-1.4.11/src/http_auth_digest.h     2006-01-05 00:54:01.000000000 +0200
++++ lighttpd-1.4.12/src/http_auth_digest.h     2006-07-11 21:23:40.000000000 +0300
+@@ -12,7 +12,7 @@
+ #ifdef USE_OPENSSL
+ #define IN const
+ #else
+-#define IN 
++#define IN
+ #endif
+ #define OUT
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/http_chunk.c lighttpd-1.4.12/src/http_chunk.c
+--- lighttpd-1.4.11/src/http_chunk.c   2005-08-11 01:26:50.000000000 +0300
++++ lighttpd-1.4.12/src/http_chunk.c   2006-07-11 21:23:40.000000000 +0300
+@@ -1,7 +1,7 @@
+ /**
+  * the HTTP chunk-API
+- * 
+- * 
++ *
++ *
+  */
  
- SETDEFAULTS_FUNC(mod_rrd_set_defaults) {
-       plugin_data *p = p_d;
---- lighttpd-1.4.11/src/mod_scgi.c     2006-03-04 17:15:26.000000000 +0200
-+++ lighttpd/src/mod_scgi.c    2006-07-11 21:23:40.023851218 +0300
-@@ -1,5 +1,4 @@
  #include <sys/types.h>
--#include <unistd.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <string.h>
-@@ -30,7 +29,9 @@
- #endif
+@@ -9,7 +9,6 @@
  
- #include "sys-socket.h"
--
-+#include "sys-files.h"
-+#include "sys-strings.h"
-+#include "sys-process.h"
+ #include <stdlib.h>
+ #include <fcntl.h>
+-#include <unistd.h>
  
- #ifndef UNIX_PATH_MAX
- # define UNIX_PATH_MAX 108
-@@ -61,7 +62,6 @@
-       
-       pid_t pid;   /* PID of the spawned process (0 if not spawned locally) */
+ #include <stdio.h>
+ #include <errno.h>
+@@ -23,19 +22,19 @@
+ 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;
+@@ -43,61 +42,61 @@
+               b->used = i;
+               b->ptr[b->used++] = '\0';
+       }
+-              
++
+       buffer_append_string(b, "\r\n");
+       chunkqueue_append_buffer(con->write_queue, b);
+-      
++
+       return 0;
+ }
  
--
-       size_t load; /* number of requests waiting on this process */
  
-       time_t last_used; /* see idle_timeout */
-@@ -308,7 +308,6 @@
-       size_t    request_id;
-       int       fd;        /* fd to the scgi process */
-       int       fde_ndx;   /* index into the fd-event buffer */
--
-       pid_t     pid;
-       int       got_proc;
-       
-@@ -555,7 +554,9 @@
-                                       host = ex->hosts[n];
-                                       
-                                       for (proc = host->first; proc; proc = proc->next) {
-+#ifndef _WIN32
-                                               if (proc->pid != 0) kill(proc->pid, SIGTERM);
-+#endif
-                                               
-                                               if (proc->is_local && 
-                                                   !buffer_is_empty(proc->socket)) {
-@@ -564,7 +565,9 @@
-                                       }
-                                       
-                                       for (proc = host->unused_procs; proc; proc = proc->next) {
-+#ifndef _WIN32
-                                               if (proc->pid != 0) kill(proc->pid, SIGTERM);
-+#endif
-                                               
-                                               if (proc->is_local && 
-                                                   !buffer_is_empty(proc->socket)) {
-@@ -641,12 +644,8 @@
-               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
+ int http_chunk_append_file(server *srv, connection *con, buffer *fn, off_t offset, off_t len) {
+       chunkqueue *cq;
+-      
 +
-               socket_type = AF_UNIX;
-               scgi_addr = (struct sockaddr *) &scgi_addr_un;
- #else
-@@ -1292,12 +1291,9 @@
-               /* 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
+       if (!con) return -1;
+-      
 +
-               scgi_addr = (struct sockaddr *) &scgi_addr_un;
- #else
-               return -1;
-@@ -2058,6 +2054,7 @@
-                       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 */
-@@ -2084,6 +2081,7 @@
-                                       proc->state = PROC_STATE_DIED;
-                                       break;
-                               }
-+#endif
-                       }
-                       
-                       /* 
-@@ -2271,10 +2269,11 @@
-                                */ 
-                               if (hctx->wb->bytes_out == 0 &&
-                                   hctx->reconnects < 5) {
-+#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;
-@@ -2286,7 +2285,7 @@
-                                * 
-                                */
-                               
--                              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);
-@@ -2479,7 +2478,7 @@
-                               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 */
-@@ -2519,6 +2518,7 @@
-                                       
-                                       break;
-                               }
-+#endif
-                       }
-                       if (con->file_started == 0) {
-@@ -2536,7 +2536,7 @@
-                                       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);
-@@ -2631,14 +2631,13 @@
-       
-       return HANDLER_FINISHED;
- }
--#define PATCH(x) \
--      p->conf.x = s->x;
+       cq = con->write_queue;
+-      
 +
- 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++) {
-@@ -2653,17 +2652,15 @@
-                       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);
-                       }
-               }
+       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;
  }
--#undef PATCH
--
  
- static handler_t scgi_check_extension(server *srv, connection *con, void *p_d, int uri_path_handler) {
-       plugin_data *p = p_d;
-@@ -2971,7 +2968,7 @@
-                                       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 */
-@@ -3009,13 +3006,14 @@
-                                               /* 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 */
-@@ -3059,6 +3057,7 @@
-                                               proc->state = PROC_STATE_UNSET;
-                                               host->max_id--;
-                                       }
-+#endif
-                               }
-                       }
-               }
---- lighttpd-1.4.11/src/mod_secure_download.c  2005-12-14 14:37:29.000000000 +0200
-+++ lighttpd/src/mod_secure_download.c 2006-07-11 21:23:39.935845706 +0300
-@@ -156,16 +156,14 @@
-       return i == len;
+ 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;
  }
  
--#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++) {
-@@ -180,21 +178,19 @@
-                       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);
-                       }
+ 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);
+@@ -107,17 +106,17 @@
                }
+               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;
  }
--#undef PATCH
--
  
- URIHANDLER_FUNC(mod_secdownload_uri_handler) {
-       plugin_data *p = p_d;
---- lighttpd-1.4.11/src/mod_setenv.c   2006-01-14 20:33:12.000000000 +0200
-+++ lighttpd/src/mod_setenv.c  2006-07-11 21:23:40.191861741 +0300
-@@ -120,15 +120,13 @@
-       return HANDLER_GO_ON;
+@@ -125,9 +124,9 @@
+ 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);
  }
--#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++) {
-@@ -143,18 +141,17 @@
-                       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"))) {
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/http_resp.c lighttpd-1.4.12/src/http_resp.c
+--- lighttpd-1.4.11/src/http_resp.c    1970-01-01 03:00:00.000000000 +0300
++++ lighttpd-1.4.12/src/http_resp.c    2006-07-11 21:23:40.000000000 +0300
+@@ -0,0 +1,263 @@
++#include <string.h>
++#include <stdlib.h>
++#include <stdio.h>
++#include <assert.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();
++    /* http_resp_parserTrace(stderr, "http-response: "); */
++
++      while((1 == http_resp_tokenizer(&t, &token_id, token)) && context.ok) {
++              http_resp_parser(pParser, token_id, token, &context);
++
++              token = buffer_init();
++
++        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;
++
++        fprintf(stderr, "%s.%d: parsing failed at: ...%20s\r\n",
++            __FILE__, __LINE__, t.c->mem->ptr + t.offset);
++    }
++
++      http_resp_parser(pParser, 0, token, &context);
++      http_resp_parserFree(pParser, free );
++
++    if (context.ok == 0) {
++        /* we are missing the some tokens */
++
++        if (ret == PARSE_UNSET) ret = PARSE_NEED_MORE;
++    } 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);
++
++    return ret;
++}
++
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/http_resp.h lighttpd-1.4.12/src/http_resp.h
+--- lighttpd-1.4.11/src/http_resp.h    1970-01-01 03:00:00.000000000 +0300
++++ lighttpd-1.4.12/src/http_resp.h    2006-07-11 21:23:40.000000000 +0300
+@@ -0,0 +1,34 @@
++#ifndef _HTTP_RESP_H_
++#define _HTTP_RESP_H_
++
++#include "array.h"
++#include "chunk.h"
++
++typedef enum {
++    PARSE_UNSET,
++    PARSE_SUCCESS,
++    PARSE_ERROR,
++    PARSE_NEED_MORE
++} parse_status_t;
++
++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
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/http_resp_parser.c lighttpd-1.4.12/src/http_resp_parser.c
+--- lighttpd-1.4.11/src/http_resp_parser.c     1970-01-01 03:00:00.000000000 +0300
++++ lighttpd-1.4.12/src/http_resp_parser.c     2006-07-11 21:49:18.000000000 +0300
+@@ -0,0 +1,894 @@
++/* 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"
++
++#line 16 "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 23 "./http_resp_parser.y"
++{ buffer_free((yypminor->yy0)); }
++#line 326 "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 26 "./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') {
++            buffer_copy_string(ctx->errmsg, "expected a number: ");
++            buffer_append_string_buffer(ctx->errmsg, ds->value);
++        
++            ctx->ok = 0;
++        }
++
++    }
++
++    yymsp[-1].minor.yy12 = NULL;
++}
++#line 576 "http_resp_parser.c"
++  yy_destructor(1,&yymsp[0].minor);
++        break;
++      case 1:
++#line 54 "./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);
++    
++    array_free(resp->headers);
++    
++    resp->headers = yymsp[-1].minor.yy12;
++    
++    yymsp[-1].minor.yy12 = NULL;
++}
++#line 594 "http_resp_parser.c"
++  yy_destructor(1,&yymsp[-2].minor);
++  yy_destructor(1,&yymsp[0].minor);
++        break;
++      case 2:
++#line 68 "./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;
++    }
++}
++#line 612 "http_resp_parser.c"
++        break;
++      case 3:
++#line 81 "./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: ");
++        buffer_append_string_buffer(ctx->errmsg, yymsp[0].minor.yy0);
++        
++        ctx->ok = 0;
++    }
++}
++#line 627 "http_resp_parser.c"
++        break;
++      case 4:
++#line 93 "./http_resp_parser.y"
++{
++    buffer_copy_string_buffer(yygotominor.yy0, yymsp[0].minor.yy0);
++}
++#line 634 "http_resp_parser.c"
++        break;
++      case 5:
++#line 97 "./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);
++    
++    yymsp[-1].minor.yy0 = NULL;
++}
++#line 646 "http_resp_parser.c"
++        break;
++      case 6:
++#line 106 "./http_resp_parser.y"
++{
++    yygotominor.yy12 = yymsp[-1].minor.yy12;
++    
++    array_insert_unique(yygotominor.yy12, (data_unset *)yymsp[0].minor.yy9);
++    
++    yymsp[-1].minor.yy12 = NULL;
++}
++#line 657 "http_resp_parser.c"
++        break;
++      case 7:
++#line 114 "./http_resp_parser.y"
++{
++    yygotominor.yy12 = array_init();
++
++    array_insert_unique(yygotominor.yy12, (data_unset *)yymsp[0].minor.yy9);
++}
++#line 666 "http_resp_parser.c"
++        break;
++      case 8:
++#line 119 "./http_resp_parser.y"
++{
++    yygotominor.yy9 = data_string_init();
++    
++    buffer_copy_string_buffer(yygotominor.yy9->key, yymsp[-3].minor.yy0);
++    buffer_copy_string_buffer(yygotominor.yy9->value, yymsp[-1].minor.yy0);    
++}
++#line 676 "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 14 "./http_resp_parser.y"
++
++  ctx->ok = 0;
++
++#line 711 "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;
++}
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/inet_ntop_cache.c lighttpd-1.4.12/src/inet_ntop_cache.c
+--- lighttpd-1.4.11/src/inet_ntop_cache.c      2005-08-11 01:26:38.000000000 +0300
++++ lighttpd-1.4.12/src/inet_ntop_cache.c      2006-07-11 21:23:40.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);
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/joblist.c lighttpd-1.4.12/src/joblist.c
+--- lighttpd-1.4.11/src/joblist.c      2005-08-11 01:26:41.000000000 +0300
++++ lighttpd-1.4.12/src/joblist.c      2006-07-11 21:23:39.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;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/keyvalue.c lighttpd-1.4.12/src/keyvalue.c
+--- lighttpd-1.4.11/src/keyvalue.c     2006-03-02 16:08:06.000000000 +0200
++++ lighttpd-1.4.12/src/keyvalue.c     2006-07-11 21:23:40.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);
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/keyvalue.h lighttpd-1.4.12/src/keyvalue.h
+--- lighttpd-1.4.11/src/keyvalue.h     2006-03-02 16:08:06.000000000 +0200
++++ lighttpd-1.4.12/src/keyvalue.h     2006-07-11 21:23:40.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,
+@@ -39,13 +39,13 @@
+ typedef struct {
+       int key;
+-      
++
+       char *value;
+ } keyvalue;
+ typedef struct {
+       char *key;
+-      
++
+       char *value;
+ } s_keyvalue;
+@@ -54,7 +54,7 @@
+       pcre *key;
+       pcre_extra *key_extra;
+ #endif
+-      
++
+       buffer *value;
+ } pcre_keyvalue;
+@@ -62,7 +62,7 @@
+ typedef struct {
+       char *key;
+-      
++
+       char *realm;
+       httpauth_type type;
+ } httpauth_keyvalue;
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/lemon.c lighttpd-1.4.12/src/lemon.c
+--- lighttpd-1.4.11/src/lemon.c        2005-09-01 00:21:34.000000000 +0300
++++ lighttpd-1.4.12/src/lemon.c        2006-07-11 21:23:40.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);
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/lempar.c lighttpd-1.4.12/src/lempar.c
+--- lighttpd-1.4.11/src/lempar.c       2005-08-11 01:26:40.000000000 +0300
++++ lighttpd-1.4.12/src/lempar.c       2006-07-11 21:23:39.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:
+       **
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/log.c lighttpd-1.4.12/src/log.c
+--- lighttpd-1.4.11/src/log.c  2005-11-07 15:01:35.000000000 +0200
++++ lighttpd-1.4.12/src/log.c  2006-07-11 21:23: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,38 +36,38 @@
+ # 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) {
+       int fd;
+       int close_stderr = 1;
+-      
++
+ #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", 
++                      log_error_write(srv, __FILE__, __LINE__, "SSSS",
+                                       "opening errorlog '", logfile,
+                                       "' failed: ", strerror(errno));
+-                      
++
+                       return -1;
+               }
+ #ifdef FD_CLOEXEC
+@@ -71,15 +76,15 @@
+ #endif
+               srv->errorlog_mode = ERRORLOG_FILE;
+       }
+-      
++
+       log_error_write(srv, __FILE__, __LINE__, "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;
+-      
++
+       /* move stderr to /dev/null */
+       if (close_stderr &&
+           -1 != (fd = open("/dev/null", O_WRONLY))) {
+@@ -90,33 +95,33 @@
+       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) {
+       /* only cycle if we are not in syslog-mode */
+-      
++
+       if (srv->errorlog_mode == ERRORLOG_FILE) {
+               const char *logfile = srv->srvconf.errorlog_file->ptr;
+               /* already check of opening time */
+-              
++
+               int new_fd;
+-              
++
+               if (-1 == (new_fd = open(logfile, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) {
+                       /* write to old log */
+-                      log_error_write(srv, __FILE__, __LINE__, "SSSSS", 
++                      log_error_write(srv, __FILE__, __LINE__, "SSSSS",
+                                       "cycling errorlog '", logfile,
+                                       "' failed: ", strerror(errno),
+                                       ", falling back to syslog()");
+-                      
++
+                       close(srv->errorlog_fd);
+                       srv->errorlog_fd = -1;
+-#ifdef HAVE_SYSLOG_H  
++#ifdef HAVE_SYSLOG_H
+                       srv->errorlog_mode = ERRORLOG_SYSLOG;
+ #endif
+               } else {
+@@ -125,15 +130,15 @@
+                       srv->errorlog_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);
+@@ -146,13 +151,13 @@
+       case ERRORLOG_STDERR:
+               break;
+       }
+-      
++
+       return 0;
+ }
+ int log_error_write(server *srv, const char *filename, unsigned int line, const char *fmt, ...) {
+       va_list ap;
+-      
++
+       switch(srv->errorlog_mode) {
+       case ERRORLOG_FILE:
+       case ERRORLOG_STDERR:
+@@ -161,7 +166,7 @@
+                       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;
+               }
+@@ -173,19 +178,19 @@
+               BUFFER_COPY_STRING_CONST(srv->errorlog_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, ") ");
+-      
+-      
++
++
+       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 *);
+@@ -227,7 +232,7 @@
+                       break;
+               case '(':
+               case ')':
+-              case '<':       
++              case '<':
+               case '>':
+               case ',':
+               case ' ':
+@@ -236,7 +241,7 @@
+               }
+       }
+       va_end(ap);
+-      
++
+       switch(srv->errorlog_mode) {
+       case ERRORLOG_FILE:
+               BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, "\n");
+@@ -246,11 +251,13 @@
+               BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, "\n");
+               write(STDERR_FILENO, srv->errorlog_buf->ptr, srv->errorlog_buf->used - 1);
+               break;
++#ifdef HAVE_SYSLOG_H
+       case ERRORLOG_SYSLOG:
+               syslog(LOG_ERR, "%s", srv->errorlog_buf->ptr);
+               break;
++#endif
+       }
+-      
++
+       return 0;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/log.h lighttpd-1.4.12/src/log.h
+--- lighttpd-1.4.11/src/log.h  2005-08-11 01:26:36.000000000 +0300
++++ lighttpd-1.4.12/src/log.h  2006-07-11 21:23:40.000000000 +0300
+@@ -9,5 +9,5 @@
+ 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);
+-      
++
+ #endif
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/md5.h lighttpd-1.4.12/src/md5.h
+--- lighttpd-1.4.11/src/md5.h  2005-11-17 16:20:40.000000000 +0200
++++ lighttpd-1.4.12/src/md5.h  2006-07-11 21:23:40.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 {
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_access.c lighttpd-1.4.12/src/mod_access.c
+--- lighttpd-1.4.11/src/mod_access.c   2006-01-14 19:44:54.000000000 +0200
++++ lighttpd-1.4.12/src/mod_access.c   2006-07-11 21:23:40.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;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_accesslog.c lighttpd-1.4.12/src/mod_accesslog.c
+--- lighttpd-1.4.11/src/mod_accesslog.c        2006-01-31 14:01:43.000000000 +0200
++++ lighttpd-1.4.12/src/mod_accesslog.c        2006-07-11 21:23:40.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 */
+@@ -710,10 +708,10 @@
+                       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 +770,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 +799,7 @@
+                                { 'D', FORMAT_TIME_USED_MS },
+                                { 'e', FORMAT_ENV },
+                                */
+-                              
++
+                               break;
+                       }
+                       break;
+@@ -809,7 +807,7 @@
+                       break;
+               }
+       }
+-      
++
+       BUFFER_APPEND_STRING_CONST(b, "\n");
+       if (p->conf.use_syslog ||  /* syslog doesn't cache */
+@@ -828,7 +826,7 @@
+               }
+               buffer_reset(b);
+       }
+-      
++
+       return HANDLER_GO_ON;
+ }
+@@ -836,15 +834,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->data        = NULL;
+-      
++
+       return 0;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_alias.c lighttpd-1.4.12/src/mod_alias.c
+--- lighttpd-1.4.11/src/mod_alias.c    2006-03-01 23:18:51.000000000 +0200
++++ lighttpd-1.4.12/src/mod_alias.c    2006-07-11 21:23:39.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;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_auth.c lighttpd-1.4.12/src/mod_auth.c
+--- lighttpd-1.4.11/src/mod_auth.c     2006-02-15 20:01:31.000000000 +0200
++++ lighttpd-1.4.12/src/mod_auth.c     2006-07-11 21:23: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,31 +211,31 @@
+                       }
+               }
+       }
+-      
++
+       /* 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")) {
+                                       auth_satisfied = http_auth_basic_check(srv, con, p, req, con->uri.path, auth_realm+1);
+                               }
+@@ -245,43 +244,43 @@
+                               if (0 == strcmp(method->value->ptr, "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")) {
+                       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")) {
+                       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,14 +363,14 @@
+               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")) {
+                               s->auth_backend = AUTH_BACKEND_HTPASSWD;
+@@ -383,31 +382,31 @@
+                               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;
+-                      
++
+                       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")) {
+@@ -417,8 +416,8 @@
+                                       } 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:", 
++                                              log_error_write(srv, __FILE__, __LINE__, "ssbs",
++                                                      "the field is unknown in:",
+                                                       "auth.require = ( \"...\" => ( ..., -> \"",
+                                                       da_file->value->data[m]->key,
+                                                       "\" <- => \"...\" ) )");
+@@ -426,19 +425,19 @@
+                                               return HANDLER_ERROR;
+                                       }
+                               } else {
+-                                      log_error_write(srv, __FILE__, __LINE__, "ssbs", 
+-                                              "a string was expected for:", 
++                                      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 {
+@@ -450,60 +449,60 @@
+                                       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);
+-                              
++
+                               array_insert_unique(a->value, (data_unset *)ds);
+-                              
++
+                               ds = data_string_init();
+-                              
++
+                               buffer_copy_string(ds->key, "realm");
+                               buffer_copy_string(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);
+-                              
++
+                               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 +515,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 +528,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 +553,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 +640,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;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_cgi.c lighttpd-1.4.12/src/mod_cgi.c
+--- lighttpd-1.4.11/src/mod_cgi.c      2006-02-22 15:15:10.000000000 +0200
++++ lighttpd-1.4.12/src/mod_cgi.c      2006-07-11 21:23:39.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>
+@@ -29,9 +16,16 @@
+ #include "connections.h"
+ #include "joblist.h"
+ #include "http_chunk.h"
++#include "fdevent.h"
+ #include "plugin.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>
+ #endif
+@@ -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,23 +53,23 @@
+ typedef struct {
+       PLUGIN_DATA;
+       buffer_pid_t cgi_pid;
+-      
++
+       buffer *tmp_buf;
+       buffer *parse_response;
+-      
++
+       plugin_config **config_storage;
+-      
+-      plugin_config conf; 
++
++      plugin_config conf;
+ } plugin_data;
+ 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;
+@@ -83,17 +78,17 @@
+       handler_ctx *hctx = calloc(1, sizeof(*hctx));
+       assert(hctx);
+-      
++
+       hctx->response = buffer_init();
+       hctx->response_header = buffer_init();
+-      
++
+       return hctx;
+ }
+ static void cgi_handler_ctx_free(handler_ctx *hctx) {
+       buffer_free(hctx->response);
+       buffer_free(hctx->response_header);
+-      
++
+       free(hctx);
+ }
+@@ -101,14 +96,14 @@
+ 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();
+-      
++
+       return p;
+ }
+@@ -116,62 +111,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);
+-      
++
+       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 +175,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,31 +189,31 @@
+               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;
+ }
+@@ -226,32 +221,32 @@
+       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'))); 
++
++      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 && 
++
++              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 */
+@@ -260,27 +255,27 @@
+                               }
+                       }
+               } 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)) {
+@@ -315,13 +310,13 @@
+                       }
+               }
+       }
+-      
++
+       /* 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;
+ }
+@@ -329,10 +324,10 @@
+ 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) {
+@@ -343,125 +338,125 @@
+                       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+2) == '\r' &&
+                                           *(c+3) == '\n') {
+                                               header_end = 1;
+                                               break;
+                                       }
+-                                      
++
+                                       /* skip the \n */
+                                       c++;
+                                       cp++;
+                                       used--;
+                               }
+                       }
+-                      
++
+                       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);
+                                       }
+                               }
+-                              
++
+                               con->file_started = 1;
+                       }
+               } else {
+                       http_chunk_append_mem(srv, con, hctx->response->ptr, hctx->response->used);
+                       joblist_append(srv, con);
+               }
+-              
+-#if 0         
++
++#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;
+ }
+@@ -470,45 +465,46 @@
+       pid_t pid;
+       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;
+-#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) {
+               /* 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;
+       }
+-      
++
+       pid = hctx->pid;
+-      
++
+       con->plugin_ctx[p->id] = NULL;
+-      
++
+       /* is this a good idea ? */
+       cgi_handler_ctx_free(hctx);
+-      
++
+       /* 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,19 +515,19 @@
+               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:
+@@ -541,13 +537,13 @@
+                               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,20 +551,20 @@
+                               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]);
+ }
+@@ -577,43 +573,43 @@
+       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;
+       }
+-      
++
+       if (revents & FDEVENT_IN) {
+               switch (cgi_demux_response(srv, hctx)) {
+               case FDEVENT_HANDLED_NOT_FINISHED:
+                       break;
+               case FDEVENT_HANDLED_FINISHED:
+                       /* we are done */
+-                      
++
+ #if 0
+                       log_error_write(srv, __FILE__, __LINE__, "ddss", con->fd, hctx->fd, connection_get_state(con->state), "finished");
+ #endif
+                       cgi_connection_close(srv, hctx);
+-                      
+-                      /* if we get a IN|HUP and have read everything don't exec the close twice */ 
++
++                      /* 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: ");
+                       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 */
+@@ -623,54 +619,54 @@
+                       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);
+       } else if (revents & FDEVENT_ERR) {
+               con->file_finished = 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                        
++#endif
+               return HANDLER_ERROR;
+       }
+-      
++
+       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 +674,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,22 +726,22 @@
+               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: 
++
++              /* HACK:
+                * this is not nice, but it works
+                *
+                * we feed the stderr of the CGI to our errorlog, if possible
+@@ -754,20 +750,20 @@
+                       close(STDERR_FILENO);
+                       dup2(srv->errorlog_fd, 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 +775,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 +786,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 +807,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 +827,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 +835,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 +862,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 +892,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 +941,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);
+@@ -954,12 +953,12 @@
+               for (i = 3; i < 256; i++) {
+                       if (i != srv->errorlog_fd) 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;
+@@ -974,11 +973,11 @@
+               close(from_cgi_fds[1]);
+               close(to_cgi_fds[0]);
+-              
++
+               if (con->request.content_length) {
+                       chunkqueue *cq = con->request_content_queue;
+                       chunk *c;
+-              
++
+                       assert(chunkqueue_length(cq) == (off_t)con->request.content_length);
+                       /* there is content to send */
+@@ -993,16 +992,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 +1011,7 @@
+                                               close(c->file.fd);
+                                               c->file.fd = -1;
+-      
++
+                                               /* chunk_reset() or chunk_free() will cleanup for us */
+                                       }
+@@ -1020,7 +1019,7 @@
+                                               switch(errno) {
+                                               case ENOSPC:
+                                                       con->http_status = 507;
+-              
++
+                                                       break;
+                                               default:
+                                                       con->http_status = 403;
+@@ -1033,7 +1032,7 @@
+                                               switch(errno) {
+                                               case ENOSPC:
+                                                       con->http_status = 507;
+-              
++
+                                                       break;
+                                               default:
+                                                       con->http_status = 403;
+@@ -1056,103 +1055,100 @@
+               }
+               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)) {
+                       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;
+-                      
++
+                       return -1;
+               }
+-              
++
+               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 +1156,7 @@
+                       break;
+               }
+       }
+-      
++
+       return HANDLER_GO_ON;
+ }
+@@ -1168,11 +1164,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 +1178,7 @@
+                       break;
+               case -1:
+                       log_error_write(srv, __FILE__, __LINE__, "ss", "waitpid failed: ", strerror(errno));
+-                      
++
+                       return HANDLER_ERROR;
+               default:
+@@ -1193,16 +1189,16 @@
+                       } 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;
+ }
+@@ -1210,15 +1206,15 @@
+       int status;
+       plugin_data *p = p_d;
+       handler_ctx *hctx = con->plugin_ctx[p->id];
+-      
++
+       if (con->mode != p->id) return HANDLER_GO_ON;
+       if (NULL == hctx) return HANDLER_GO_ON;
+-      
++
+ #if 0
+       log_error_write(srv, __FILE__, __LINE__, "sdd", "subrequest, pid =", hctx, hctx->pid);
+-#endif        
++#endif
+       if (hctx->pid == 0) return HANDLER_FINISHED;
+-#ifndef __WIN32       
++#ifndef _WIN32
+       switch(waitpid(hctx->pid, &status, WNOHANG)) {
+       case 0:
+               /* we only have for events here if we don't have the header yet,
+@@ -1228,61 +1224,61 @@
+               return HANDLER_WAIT_FOR_EVENT;
+       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);
+-              
++
+               con->plugin_ctx[p->id] = NULL;
+-              
++
+               return HANDLER_FINISHED;
+       default:
+-              /* cgi process exited cleanly 
+-               * 
+-               * check if we already got the response 
++              /* cgi process exited cleanly
++               *
++               * check if we already got the response
+                */
+-              
++
+               if (!con->file_started) return HANDLER_WAIT_FOR_EVENT;
+-              
++
+               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);
+-              
++
+               con->plugin_ctx[p->id] = NULL;
+               return HANDLER_FINISHED;
+       }
+@@ -1306,8 +1302,8 @@
+       p->init           = mod_cgi_init;
+       p->cleanup        = mod_cgi_free;
+       p->set_defaults   = mod_fastcgi_set_defaults;
+-      
++
+       p->data        = NULL;
+-      
++
+       return 0;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_cml.c lighttpd-1.4.12/src/mod_cml.c
+--- lighttpd-1.4.11/src/mod_cml.c      2006-01-30 13:51:48.000000000 +0200
++++ lighttpd-1.4.12/src/mod_cml.c      2006-07-11 21:23:39.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_physical         = mod_cml_power_magnet;
+-      
++
+       p->data        = NULL;
+-      
++
+       return 0;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_cml.h lighttpd-1.4.12/src/mod_cml.h
+--- lighttpd-1.4.11/src/mod_cml.h      2006-01-30 13:51:35.000000000 +0200
++++ lighttpd-1.4.12/src/mod_cml.h      2006-07-11 21:23:39.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);
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_cml_funcs.c lighttpd-1.4.12/src/mod_cml_funcs.c
+--- lighttpd-1.4.11/src/mod_cml_funcs.c        2005-11-17 16:15:08.000000000 +0200
++++ lighttpd-1.4.12/src/mod_cml_funcs.c        2006-07-11 21:23:40.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
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_cml_lua.c lighttpd-1.4.12/src/mod_cml_lua.c
+--- lighttpd-1.4.11/src/mod_cml_lua.c  2006-01-30 13:56:40.000000000 +0200
++++ lighttpd-1.4.12/src/mod_cml_lua.c  2006-07-11 21:23:40.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;
+@@ -393,12 +389,12 @@
+                                               "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")];
+@@ -410,9 +406,9 @@
+                       /* 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,9 +424,9 @@
+                               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);
+@@ -440,24 +436,24 @@
+                       chunkqueue_reset(con->write_queue);
+               }
+       }
+-      
++
+       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);
+       }
+-      
++
+ error:
+       lua_close(L);
+-      
++
+       stream_close(&rm.st);
+       buffer_free(b);
+-      
++
+       return ret /* cache-error */;
+ }
+ #else
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_compress.c lighttpd-1.4.12/src/mod_compress.c
+--- lighttpd-1.4.11/src/mod_compress.c 2005-11-18 13:49:14.000000000 +0200
++++ lighttpd-1.4.12/src/mod_compress.c 2006-07-11 21:23:40.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>
+@@ -14,6 +13,7 @@
+ #include "buffer.h"
+ #include "response.h"
+ #include "stat_cache.h"
++#include "http_chunk.h"
+ #include "plugin.h"
+@@ -33,6 +33,7 @@
+ #endif
+ #include "sys-mmap.h"
++#include "sys-files.h"
+ /* request: accept-encoding */
+ #define HTTP_ACCEPT_ENCODING_IDENTITY BV(0)
+@@ -55,97 +56,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 +184,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 +221,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 +252,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 +305,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 +357,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 +415,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 */
++
++              http_chunk_append_file(srv, con, p->ofn, 0, compressed_sce->st.st_size);
++              con->file_finished = 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 +480,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);
+-      
++
++      http_chunk_append_file(srv, con, p->ofn, 0, r);
++      con->file_finished = 1;
++
+       return 0;
+ }
+@@ -465,43 +509,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 +554,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);
+       buffer_copy_memory(b, p->b->ptr, p->b->used + 1);
+-      
++
+       buffer_reset(con->physical.path);
+-      
++
+       con->file_finished = 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 +619,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 +670,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 +706,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 +728,20 @@
+                       }
+               }
+       }
+-      
++
+       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;
+       p->cleanup     = mod_compress_free;
+-      
++
+       p->data        = NULL;
+-      
++
+       return 0;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_dirlisting.c lighttpd-1.4.12/src/mod_dirlisting.c
+--- lighttpd-1.4.11/src/mod_dirlisting.c       2006-01-13 00:00:45.000000000 +0200
++++ lighttpd-1.4.12/src/mod_dirlisting.c       2006-07-11 21:23:40.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"
+@@ -31,6 +29,9 @@
+ #include <attr/attributes.h>
+ #endif
++#include "sys-files.h"
++#include "sys-strings.h"
++
+ /* plugin config for all request/connections */
+ typedef struct {
+@@ -54,7 +55,7 @@
+       unsigned short hide_readme_file;
+       unsigned short show_header;
+       unsigned short hide_header_file;
+-      
++
+       excludes_buffer *excludes;
+       buffer *external_css;
+@@ -63,13 +64,13 @@
+ typedef struct {
+       PLUGIN_DATA;
+-      
++
+       buffer *tmp_buf;
+       buffer *content_charset;
+-      
++
+       plugin_config **config_storage;
+-      
+-      plugin_config conf; 
++
++      plugin_config conf;
+ } plugin_data;
+ excludes_buffer *excludes_buffer_init(void) {
+@@ -146,44 +147,44 @@
+ /* 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();
+-      
++
+       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->content_charset);
+-      
++
+       free(p);
+-      
++
+       return HANDLER_GO_ON;
+ }
+@@ -215,10 +216,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 +234,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 +246,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 +268,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 +293,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 +430,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 +490,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 +529,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 +551,7 @@
+               }
+               stream_close(&s);
+       }
+-      
++
+       BUFFER_APPEND_STRING_CONST(out,
+               "<div class=\"foot\">"
+       );
+@@ -595,7 +593,7 @@
+ #endif
+       if (dir->used == 0) return -1;
+-      
++
+       i = dir->used - 1;
+ #ifdef HAVE_PATHCONF
+@@ -606,19 +604,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);
++#ifdef _WIN32
++    /* append \*.* to the path and keep the \ as part of the pathname */
++    strcat(path, "\\*.*");
++    i++;
++#endif
+       path_file = path + i;
+       if (NULL == (dp = opendir(path))) {
+-              log_error_write(srv, __FILE__, __LINE__, "sbs", 
++              log_error_write(srv, __FILE__, __LINE__, "sbs",
+                       "opendir failed:", dir, strerror(errno));
+               free(path);
+@@ -633,7 +636,7 @@
+       assert(files.ent);
+       files.size = DIRLIST_BLOB_SIZE;
+       files.used = 0;
+-      
++
+       while ((dent = readdir(dp)) != NULL) {
+               unsigned short exclude_match = 0;
+@@ -686,15 +689,17 @@
+ #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)
++              if (stat(path, &st) != 0) {
++            fprintf(stderr, "%s.%d: %s, %s\r\n", __FILE__, __LINE__, path, strerror(errno));
+                       continue;
++        }
+               list = &files;
+               if (S_ISDIR(st.st_mode))
+@@ -740,7 +745,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, "/\">");
+@@ -758,7 +763,7 @@
+               content_type = NULL;
+ #ifdef HAVE_XATTR
+-              
++
+               if (con->conf.use_xattr) {
+                       memcpy(path_file, DIRLIST_ENT_NAME(tmp), tmp->namelen + 1);
+                       attrlen = sizeof(attrval) - 1;
+@@ -768,7 +773,7 @@
+                       }
+               }
+ #endif
+-              
++
+               if (content_type == NULL) {
+                       content_type = "application/octet-stream";
+                       for (k = 0; k < con->conf.mimetypes->used; k++) {
+@@ -788,7 +793,7 @@
+                               }
+                       }
+               }
+-                      
++
+ #ifdef HAVE_LOCALTIME_R
+               localtime_r(&(tmp->mtime), &tm);
+               strftime(datebuf, sizeof(datebuf), "%Y-%b-%d %H:%M:%S", &tm);
+@@ -837,36 +842,36 @@
+ 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;
+       if (con->uri.path->ptr[con->uri.path->used - 2] != '/') return HANDLER_GO_ON;
+-      
++
+       mod_dirlisting_patch_connection(srv, con, p);
+       if (!p->conf.dir_listing) 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();
+       }
+-      
++
+       if (!S_ISDIR(sce->st.st_mode)) return HANDLER_GO_ON;
+-      
++
+       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 +881,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->set_defaults  = mod_dirlisting_set_defaults;
+       p->cleanup     = mod_dirlisting_free;
+-      
++
+       p->data        = NULL;
+-      
++
+       return 0;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_evasive.c lighttpd-1.4.12/src/mod_evasive.c
+--- lighttpd-1.4.11/src/mod_evasive.c  2006-01-04 15:24:51.000000000 +0200
++++ lighttpd-1.4.12/src/mod_evasive.c  2006-07-11 21:23:40.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++) {
+@@ -147,7 +144,7 @@
+               if (c->dst_addr.ipv4.sin_addr.s_addr == con->dst_addr.ipv4.sin_addr.s_addr &&
+                   c->state > CON_STATE_REQUEST_END) {
+                       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;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_evhost.c lighttpd-1.4.12/src/mod_evhost.c
+--- lighttpd-1.4.11/src/mod_evhost.c   2005-08-17 10:42:03.000000000 +0300
++++ lighttpd-1.4.12/src/mod_evhost.c   2006-07-11 21:23:39.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;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_expire.c lighttpd-1.4.12/src/mod_expire.c
+--- lighttpd-1.4.11/src/mod_expire.c   2005-11-03 09:52:13.000000000 +0200
++++ lighttpd-1.4.12/src/mod_expire.c   2006-07-11 21:23:40.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->set_defaults  = mod_expire_set_defaults;
+       p->cleanup     = mod_expire_free;
+-      
++
+       p->data        = NULL;
+-      
++
+       return 0;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_fastcgi.c lighttpd-1.4.12/src/mod_fastcgi.c
+--- lighttpd-1.4.11/src/mod_fastcgi.c  2006-03-09 13:18:39.000000000 +0200
++++ lighttpd-1.4.12/src/mod_fastcgi.c  2006-07-11 21:23:40.000000000 +0300
+@@ -1,5 +1,4 @@
+ #include <sys/types.h>
+-#include <unistd.h>
+ #include <errno.h>
+ #include <fcntl.h>
+ #include <string.h>
+@@ -24,7 +23,7 @@
+ #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,44 +308,44 @@
+ 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 */
+@@ -352,9 +354,9 @@
+       int       got_proc;
+       int       send_content_body;
+-      
++
+       plugin_config conf;
+-      
++
+       connection *remote_conn;  /* dumb pointer */
+       plugin_data *plugin_data; /* dumb pointer */
+ } handler_ctx;
+@@ -380,7 +382,7 @@
+       return di;
+ }
+-/* dummies of the statistic framework functions 
++/* 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);
+@@ -429,7 +431,7 @@
+       CLEAN(".connected");
+       CLEAN(".load");
+-#undef CLEAN  
++#undef CLEAN
+ #define CLEAN(x) \
+       fastcgi_status_copy_procname(b, host, NULL); \
+@@ -438,33 +440,32 @@
+       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->reconnects = 0;
+       hctx->send_content_body = 1;
+       hctx->rb = chunkqueue_init();
++      hctx->http_rb = chunkqueue_init();
+       hctx->wb = chunkqueue_init();
+-      
++
+       return hctx;
+ }
+@@ -473,10 +474,9 @@
+               hctx->host->load--;
+               hctx->host = NULL;
+       }
+-      
+-      buffer_free(hctx->response_header);
+       chunkqueue_free(hctx->rb);
++      chunkqueue_free(hctx->http_rb);
+       chunkqueue_free(hctx->wb);
+       free(hctx);
+@@ -488,21 +488,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 +519,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 +534,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 +625,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 +651,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 +734,9 @@
+               env->size += 16;
+               env->ptr = realloc(env->ptr, env->size * sizeof(*env->ptr));
+       }
+-      
++
+       env->ptr[env->used++] = dst;
+-      
++
+       return 0;
+ }
+@@ -753,15 +755,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 +796,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 +808,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 +842,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 +953,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 +972,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 +1016,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 +1029,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 +1047,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 +1058,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 +1069,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 +1080,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 +1109,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 +1203,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 +1236,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 +1250,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 +1286,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 +1326,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 +1341,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 +1349,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 +1357,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 +1409,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 +1427,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 +1441,54 @@
+               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);
+               srv->cur_fds--;
+       }
+-      
++
+       if (hctx->request_id != 0) {
+               fcgi_requestid_del(srv, p, hctx->request_id);
+       }
+@@ -1499,7 +1497,7 @@
+               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"));
+                       fastcgi_status_copy_procname(p->statuskey, hctx->host, hctx->proc);
+@@ -1509,39 +1507,39 @@
+                       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) {
+@@ -1551,59 +1549,59 @@
+               srv->cur_fds--;
+               hctx->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 +1610,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 +1619,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 +1637,11 @@
+       header->contentLengthB1 = (contentLength >> 8) & 0xff;
+       header->paddingLength = paddingLength;
+       header->reserved = 0;
+-      
++
+       return 0;
+ }
+ /**
+- * 
++ *
+  * returns
+  *   -1 error
+  *    0 connected
+@@ -1665,26 +1663,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;
+-      
++
+       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 +1690,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 +1712,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 +1733,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 +1744,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 +1753,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 +1781,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 +1808,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 +1821,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 +1846,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 +1869,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)) {
+               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 +1927,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 +1954,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 +1984,7 @@
+               /**
+                * /app1/index/list
+                *
+-               * stripping /app1 or /app1/ should lead to 
++               * stripping /app1 or /app1/ should lead to
+                *
+                * /index/list
+                *
+@@ -2001,7 +1998,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 +2015,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));
+@@ -2057,7 +2054,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 +2077,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 +2101,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 +2138,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 +2152,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 +2172,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 +2225,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 +2246,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 +2278,37 @@
+       }
+       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);
+-              b->used = r + 1; /* one extra for the fake \0 */
+-              b->ptr[b->used - 1] = '\0';
+-      } else {
+-              log_error_write(srv, __FILE__, __LINE__, "ssdsb", 
++      switch(srv->network_backend_read(srv, con, hctx->fd, hctx->rb)) {
++      case NETWORK_STATUS_WAIT_FOR_EVENT:
++              /* we are only triggered when there is a event */
++              log_error_write(srv, __FILE__, __LINE__, "ssdsb",
+                               "unexpected end-of-file (perhaps the fastcgi process died):",
+                               "pid:", proc->pid,
+                               "socket:", proc->connection_name);
+-              
++              return -1;
++      case NETWORK_STATUS_SUCCESS:
++              break;
++      default:
++              log_error_write(srv, __FILE__, __LINE__, "s", "fastcgi-read failed");
+               return -1;
+       }
+       /*
+        * parse the fastcgi packets and forward the content to the write-queue
+        *
+-       */     
++       */
+       while (fin == 0) {
+               fastcgi_response_packet packet;
+@@ -2454,92 +2324,135 @@
+                       /* 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;
++
++                              /* 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"))) {
++                                              
++                                              stat_cache_entry *sce;
+                                               
+-                              if (hctx->send_content_body && blen > 1) {                                              
+-                                      /* enable chunked-transfer-encoding */
++                                              if (host->allow_xsendfile &&
++                                                  HANDLER_ERROR != stat_cache_get_entry(srv, con, header->value, &sce)) {
++                                                      http_chunk_append_file(srv, con, 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);
++
++                                      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;
++
++                                      /* if we don't have a content-length enable chunked encoding 
++                                       * if possible
++                                       * 
++                                       * TODO: move this to a later stage in the filter-queue
++                                       *  */
+                                       if (con->request.http_version == HTTP_VERSION_1_1 &&
+-                                          !(con->parsed_response & HTTP_CONTENT_LENGTH)) {
++                                          !have_content_length) {
+                                               con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
+                                       }
+-                                      http_chunk_append_mem(srv, con, c, blen);
++                                      /* copy the rest of the data */
++                                      for (c = hctx->http_rb->first; c; c = c->next) {
++                                              if (c->mem->used > 1) {
++                                                      http_chunk_append_mem(srv, con, 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);
+                               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;
+-                      
++
+                       if (host->mode != FCGI_AUTHORIZER ||
+                           !(con->http_status == 0 ||
+                             con->http_status == 200)) {
+@@ -2547,39 +2460,39 @@
+                               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 +2505,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 +2519,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 +2529,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 +2575,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 +2595,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 +2618,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", 
++                      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 +2632,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 +2645,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));
+-              
++
+                       return HANDLER_ERROR;
+               }
+-              /* go on with preparing the request */ 
++              /* go on with preparing the request */
+               hctx->state = FCGI_STATE_PREPARE_WRITE;
+       }
+@@ -2755,14 +2668,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;
+-              
++
+                       return HANDLER_ERROR;
+               }
+@@ -2775,50 +2688,50 @@
+               }
+               ret = host->unixsocket->used ? AF_UNIX : AF_INET;
+-              
++
+               if (-1 == (hctx->fd = socket(ret, SOCK_STREAM, 0))) {
+                       if (errno == EMFILE ||
+                           errno == EINTR) {
+-                              log_error_write(srv, __FILE__, __LINE__, "sd", 
++                              log_error_write(srv, __FILE__, __LINE__, "sd",
+                                               "wait for fd at connection:", con->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;
+-              
++
+               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", 
++                      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);
+-                      
++
+                       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);
+@@ -2831,7 +2744,7 @@
+                       buffer_append_string(p->statuskey, ".overloaded");
+                       status_counter_inc(srv, CONST_BUF_LEN(p->statuskey));
+-                      
++
+                       return HANDLER_ERROR;
+               case CONNECTION_DEAD:
+                       /* we got a hard error from the backend like
+@@ -2840,19 +2753,19 @@
+                        *
+                        * 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");
+@@ -2863,19 +2776,19 @@
+                       /* 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"));
+@@ -2898,9 +2811,9 @@
+               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,62 +2821,63 @@
+               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->fd, 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);
+-                              
++
+                               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;
+                       }
+               }
+@@ -2975,7 +2889,7 @@
+                       fcgi_set_state(srv, hctx, FCGI_STATE_READ);
+               } else {
+                       fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
+-                              
++
+                       return HANDLER_WAIT_FOR_EVENT;
+               }
+@@ -2987,7 +2901,7 @@
+               log_error_write(srv, __FILE__, __LINE__, "s", "(debug) unknown state");
+               return HANDLER_ERROR;
+       }
+-      
++
+       return HANDLER_WAIT_FOR_EVENT;
+ }
+@@ -2996,18 +2910,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 +2930,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 +2954,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 +2977,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 +2992,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 +3002,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 +3029,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 +3039,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 +3050,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,60 +3079,61 @@
+                               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;
+@@ -3226,76 +3141,76 @@
+                       } 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 +3219,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 +3263,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 +3280,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 +3319,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 +3353,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 +3371,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 +3444,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 +3478,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) {
+               switch (hctx->state) {
+               case FCGI_STATE_READ:
+                       fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
+-                      
++
+                       break;
+               case FCGI_STATE_CONNECT_DELAYED:
+               case FCGI_STATE_WRITE:
+                       fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
+-                      
++
+                       break;
+               case FCGI_STATE_INIT:
+                       /* at reconnect */
+@@ -3595,7 +3507,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 +3516,39 @@
+ 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 (con->state != CON_STATE_HANDLE_REQUEST) 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 +3563,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 +3609,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 +3623,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 +3680,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 +3697,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
+                               }
+                       }
+               }
+@@ -3804,8 +3740,8 @@
+       p->handle_subrequest       = mod_fastcgi_handle_subrequest;
+       p->handle_joblist          = mod_fastcgi_handle_joblist;
+       p->handle_trigger          = mod_fastcgi_handle_trigger;
+-      
++
+       p->data         = NULL;
+-      
++
+       return 0;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_flv_streaming.c lighttpd-1.4.12/src/mod_flv_streaming.c
+--- lighttpd-1.4.11/src/mod_flv_streaming.c    2006-03-07 14:06:26.000000000 +0200
++++ lighttpd-1.4.12/src/mod_flv_streaming.c    2006-07-11 21:23:40.000000000 +0300
+@@ -23,35 +23,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 +59,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 +80,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 +164,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 +172,14 @@
+                               array_insert_unique(get_params, (data_unset *)ds);
+                       }
+-                      
++
+                       key = qrystr->ptr + i + 1;
+                       val = NULL;
+                       is_key = 1;
+                       break;
+               }
+       }
+-      
++
+       return 0;
+ }
+@@ -190,34 +187,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;
+@@ -256,7 +253,7 @@
+                       return HANDLER_FINISHED;
+               }
+       }
+-      
++
+       /* not found */
+       return HANDLER_GO_ON;
+ }
+@@ -266,13 +263,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;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_indexfile.c lighttpd-1.4.12/src/mod_indexfile.c
+--- lighttpd-1.4.11/src/mod_indexfile.c        2005-09-30 01:08:53.000000000 +0300
++++ lighttpd-1.4.12/src/mod_indexfile.c        2006-07-11 21:23:40.000000000 +0300
+@@ -20,51 +20,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 +73,128 @@
+ 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);
+-      
++
+       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);
+               }
+               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 +204,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->set_defaults  = mod_indexfile_set_defaults;
+       p->cleanup     = mod_indexfile_free;
+-      
++
+       p->data        = NULL;
+-      
++
+       return 0;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_mysql_vhost.c lighttpd-1.4.12/src/mod_mysql_vhost.c
+--- lighttpd-1.4.11/src/mod_mysql_vhost.c      2006-01-14 20:35:10.000000000 +0200
++++ lighttpd-1.4.12/src/mod_mysql_vhost.c      2006-07-11 21:23:40.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,35 @@
+               } else {
+                       buffer_copy_string_buffer(s->mysql_pre, 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)
++
++                      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 +182,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 +235,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 +243,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
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_proxy.c lighttpd-1.4.12/src/mod_proxy.c
+--- lighttpd-1.4.11/src/mod_proxy.c    2006-01-31 13:01:22.000000000 +0200
++++ lighttpd-1.4.12/src/mod_proxy.c    2006-07-11 21:23:40.000000000 +0300
+@@ -1,6 +1,5 @@
+ #include <sys/types.h>
+-#include <unistd.h>
+ #include <errno.h>
+ #include <fcntl.h>
+ #include <string.h>
+@@ -23,6 +22,9 @@
+ #include "inet_ntop_cache.h"
+ #include "crc32.h"
++#include "network.h"
++
++#include "http_resp.h"
+ #include <stdio.h>
+@@ -31,6 +33,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,16 +42,16 @@
+ #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).
+@@ -66,26 +70,31 @@
+       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;
+-      
++
++      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 +102,20 @@
+ typedef struct {
+       proxy_connection_state_t state;
+       time_t state_timestamp;
+-      
++
+       data_proxy *host;
+-      
++
+       buffer *response;
+       buffer *response_header;
+       chunkqueue *wb;
+-      
++    chunkqueue *rb;
++
+       int fd; /* fd to the proxy process */
+       int fde_ndx; /* index into the fd-event buffer */
+       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,21 +126,22 @@
+ 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->fd = -1;
+       hctx->fde_ndx = -1;
+-      
++
+       return hctx;
+ }
+@@ -138,47 +149,70 @@
+       buffer_free(hctx->response);
+       buffer_free(hctx->response_header);
+       chunkqueue_free(hctx->wb);
+-      
++    chunkqueue_free(hctx->rb);
++
+       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();
++
++      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->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);
+       }
+-      
++
++      free(p->ignore_headers);
++
+       free(p);
+-      
++
+       return HANDLER_GO_ON;
+ }
+@@ -186,37 +220,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,7 +261,7 @@
+               } 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", 
++                      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;
+               }
+@@ -234,91 +269,91 @@
+               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,19 +363,19 @@
+                       }
+               }
+       }
+-      
++
+       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);
+@@ -348,47 +383,56 @@
+               close(hctx->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;
+-      
++
+       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);
+       }
+@@ -422,25 +466,26 @@
+ 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,24 +494,26 @@
+       /* 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;
+-                      
++
++                      /* don't copy hop-to-hop headers */
++                      if (array_get_element(p->ignore_headers, ds->key->ptr)) 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;
+               chunk *req_c;
+@@ -479,7 +526,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 +554,125 @@
+                               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);
++static void chunkqueue_print(chunkqueue *cq) {
++    chunk *c;
+-      /* \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;
++    for (c = cq->first; c; c = c->next) {
++        fprintf(stderr, "%s", c->mem->ptr + c->offset);
++    }
++    fprintf(stderr, "\r\n");
+ }
+-
+ 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);
+-              return -1;
+-      }
+-
++    chunkqueue *next_queue = NULL;
++    chunk *c = NULL;
+-      if (p->conf.debug) {
+-              log_error_write(srv, __FILE__, __LINE__, "sd",
+-                             "proxy - have to read:", b);
+-      }
+-
+-      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
+-
+-              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;
+-                              }
+-                                      
+-                              con->file_started = 1;
+-                              if (blen) {
+-                                      http_chunk_append_mem(srv, con, c + 4, blen + 1);
+-                                      joblist_append(srv, con);
+-                              }
+-                              hctx->response->used = 0;
+-                      }
+-              } else {
+-                      http_chunk_append_mem(srv, con, hctx->response->ptr, hctx->response->used);
+-                      joblist_append(srv, con);
+-                      hctx->response->used = 0;
+-              }
+-              
+-      } else {
+-              /* reading from upstream done */
++    switch(srv->network_backend_read(srv, con, proxy_fd, hctx->rb)) {
++    case NETWORK_STATUS_SUCCESS:
++        /* we got content */
++        break;
++    case NETWORK_STATUS_CONNECTION_CLOSE:
++        /* we are done, get out of here */
+               con->file_finished = 1;
+-              
++
++        /* close the chunk-queue with a empty chunk */
+               http_chunk_append_mem(srv, con, NULL, 0);
+               joblist_append(srv, con);
+-              
+-              fin = 1;
++
++        return 1;
++    default:
++        /* oops */
++        return -1;
++    }
++
++    /* looks like we got some content
++    *
++    * split off the header from the incoming stream
++    */
++
++    if (hctx->state == PROXY_STATE_RESPONSE_HEADER) {
++        http_resp *resp = http_response_init();
++
++        /* the response header is not fully received yet,
++        *
++        * extract the http-response header from the rb-cq
++        */
++        fprintf(stderr, "%s.%d: network-read\r\n", __FILE__, __LINE__);
++        chunkqueue_print(hctx->rb);
++
++        switch (http_response_parse_cq(hctx->rb, 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 = resp->status;
++
++            fprintf(stderr, "%s.%d: parsing done\r\n", __FILE__, __LINE__);
++            chunkqueue_print(hctx->rb);
++
++            con->file_started = 1;
++
++            hctx->state = PROXY_STATE_RESPONSE_CONTENT;
++            break;
++        }
++    }
++
++    /* 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->write_queue;
++
++    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) {
++        http_chunk_append_mem(srv, con, c->mem->ptr + c->offset, c->mem->used - c->offset);
++
++        c->offset = c->mem->used - 1;
+       }
+-      
+-      return fin;
++
++    chunkqueue_remove_finished_chunks(hctx->rb);
++
++      return 0;
+ }
+@@ -731,12 +680,12 @@
+       data_proxy *host= hctx->host;
+       plugin_data *p    = hctx->plugin_data;
+       connection *con   = hctx->remote_conn;
+-      
++
+       int ret;
+-      
+-      if (!host || 
++
++      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))) {
+@@ -744,19 +693,19 @@
+                       return HANDLER_ERROR;
+               }
+               hctx->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)) {
+                       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 +713,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);
+-                              
++
+                               return HANDLER_WAIT_FOR_EVENT;
+                       case -1:
+                               /* if ECONNREFUSED choose another connection -> FIXME */
+                               hctx->fde_ndx = -1;
+-                              
++
+                               return HANDLER_ERROR;
+                       default:
+                               /* everything is ok, go on */
+@@ -782,152 +731,152 @@
+               } else {
+                       int socket_error;
+                       socklen_t socket_error_len = sizeof(socket_error);
+-              
+-                      /* we don't need it anymore */  
++
++                      /* we don't need it anymore */
+                       fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
+                       /* 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", 
++                              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");
+                       }
++            fprintf(stderr, "%s.%d: connected fd = %d\r\n", __FILE__, __LINE__, hctx->fd);
+               }
+-              
++
+               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->fd, 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->fde_ndx), hctx->fd, 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);
+               } else {
+                       fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
+-                              
++
+                       return HANDLER_WAIT_FOR_EVENT;
+               }
+-              
++
+               return HANDLER_WAIT_FOR_EVENT;
+-      case PROXY_STATE_READ:
++      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);
+-              
++
+               /* 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 +887,7 @@
+       default:
+               break;
+       }
+-      
++
+       if (con->file_started == 1) {
+               return HANDLER_FINISHED;
+       } else {
+@@ -951,13 +900,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);
+               }
+@@ -966,10 +916,10 @@
+                       break;
+               case 1:
+                       hctx->host->usage--;
+-                      
++
+                       /* we are done */
+                       proxy_connection_close(srv, hctx);
+-                      
++
+                       joblist_append(srv, con);
+                       return HANDLER_FINISHED;
+               case -1:
+@@ -982,53 +932,53 @@
+                               /* 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;
+               }
+@@ -1038,13 +988,13 @@
+               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 +1008,49 @@
+       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 +1061,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 +1077,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 +1112,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 +1133,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 +1245,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 +1259,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);
+@@ -1317,8 +1286,8 @@
+       p->handle_uri_clean        = mod_proxy_check_extension;
+       p->handle_subrequest       = mod_proxy_handle_subrequest;
+       p->handle_trigger          = mod_proxy_trigger;
+-      
++
+       p->data         = NULL;
+-      
++
+       return 0;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_redirect.c lighttpd-1.4.12/src/mod_redirect.c
+--- lighttpd-1.4.11/src/mod_redirect.c 2006-02-08 15:38:06.000000000 +0200
++++ lighttpd-1.4.12/src/mod_redirect.c 2006-07-11 21:23:40.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->file_finished = 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;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_rewrite.c lighttpd-1.4.12/src/mod_rewrite.c
+--- lighttpd-1.4.11/src/mod_rewrite.c  2005-09-29 20:59:10.000000000 +0300
++++ lighttpd-1.4.12/src/mod_rewrite.c  2006-07-11 21:23:39.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;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_rrdtool.c lighttpd-1.4.12/src/mod_rrdtool.c
+--- lighttpd-1.4.11/src/mod_rrdtool.c  2005-08-22 01:52:24.000000000 +0300
++++ lighttpd-1.4.12/src/mod_rrdtool.c  2006-07-11 21:23:40.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,33 @@
+               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 +155,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 +171,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 +192,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 +223,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 +381,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->data        = NULL;
+-      
++
+       return 0;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_scgi.c lighttpd-1.4.12/src/mod_scgi.c
+--- lighttpd-1.4.11/src/mod_scgi.c     2006-03-04 17:15:26.000000000 +0200
++++ lighttpd-1.4.12/src/mod_scgi.c     2006-07-11 21:23:40.000000000 +0300
+@@ -1,5 +1,4 @@
+ #include <sys/types.h>
+-#include <unistd.h>
+ #include <errno.h>
+ #include <fcntl.h>
+ #include <string.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;
+-      
++
+       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 { FCGI_STATE_INIT, FCGI_STATE_CONNECT, FCGI_STATE_PREPARE_WRITE,
++              FCGI_STATE_WRITE, FCGI_STATE_READ
+ } scgi_connection_state_t;
+ typedef struct {
+-      buffer  *response; 
++      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 *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 */
+-
+       pid_t     pid;
+       int       got_proc;
+-      
++
+       plugin_config conf;
+-      
++
+       connection *remote_conn;  /* dumb pointer */
+       plugin_data *plugin_data; /* dumb pointer */
+ } handler_ctx;
+@@ -328,28 +327,28 @@
+ 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->request_id = 0;
+       hctx->state = FCGI_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();
+-      
++
+       return hctx;
+ }
+@@ -358,12 +357,12 @@
+       buffer_free(hctx->response_header);
+       chunkqueue_free(hctx->wb);
+-      
++
+       if (hctx->rb) {
+               if (hctx->rb->ptr) free(hctx->rb->ptr);
+               free(hctx->rb);
+       }
+-      
++
+       free(hctx);
+ }
+@@ -372,20 +371,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 +399,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 +503,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();
+-      
++
+       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);
+-      
++
+       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 +607,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 +625,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 +655,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 +771,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 +816,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 +851,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 +879,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 +969,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 +1007,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 +1055,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 +1072,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 +1087,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 +1095,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,34 +1149,34 @@
+ 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);
+               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:", 
++                                              "release proc:",
+                                               hctx->fd,
+                                               hctx->proc->pid, hctx->proc->socket);
+                       }
+@@ -1186,87 +1185,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);
+       srv->cur_fds--;
+-      
++
+       scgi_set_state(srv, hctx, FCGI_STATE_INIT);
+-      
++
+       hctx->request_id = 0;
+       hctx->reconnects++;
+-      
++
+       if (p->conf.debug) {
+               log_error_write(srv, __FILE__, __LINE__, "sddb",
+-                              "release proc:", 
++                              "release proc:",
+                               hctx->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 +1279,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;
+-      
++
+       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 +1301,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 +1411,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 +1432,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 +1447,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)) {
+               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 +1496,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 +1522,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,30 +1547,30 @@
+       } 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;
+               chunk *req_c;
+@@ -1587,7 +1583,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,32 +1611,32 @@
+                               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;
+ }
+@@ -1648,32 +1644,32 @@
+       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'))); 
++
++      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 && 
++
++              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 */
+@@ -1682,27 +1678,27 @@
+                               }
+                       }
+               } 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)) {
+@@ -1737,13 +1733,13 @@
+                       }
+               }
+       }
+-      
++
+       /* 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;
+ }
+@@ -1751,10 +1747,10 @@
+ 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) {
+@@ -1765,143 +1761,143 @@
+                       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);
+-                      
++
+                       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+2) == '\r' &&
+                                           *(c+3) == '\n') {
+                                               header_end = 1;
+                                               break;
+                                       }
+-                                      
++
+                                       /* skip the \n */
+                                       c++;
+                                       cp++;
+                                       used--;
+                               }
+                       }
+-                      
++
+                       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);
+                                       }
+                               }
+-                              
++
+                               con->file_started = 1;
+                       }
+               } else {
+                       http_chunk_append_mem(srv, con, hctx->response->ptr, hctx->response->used);
+                       joblist_append(srv, con);
+               }
+-              
+-#if 0         
++
++#if 0
+               log_error_write(srv, __FILE__, __LINE__, "ddss", con->fd, hctx->fd, connection_get_state(con->state), b->ptr);
+ #endif
+       }
+-      
++
+       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 +1905,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 +1926,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 +1947,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 +1971,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 +1980,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 +2005,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 +2019,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 +2064,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 +2099,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 +2119,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,179 +2133,180 @@
+                               host->unixsocket->used);
+               return HANDLER_ERROR;
+       }
+-      
++
+       switch(hctx->state) {
+       case FCGI_STATE_INIT:
+               ret = host->unixsocket->used ? AF_UNIX : AF_INET;
+-              
++
+               if (-1 == (hctx->fd = socket(ret, SOCK_STREAM, 0))) {
+                       if (errno == EMFILE ||
+                           errno == EINTR) {
+-                              log_error_write(srv, __FILE__, __LINE__, "sd", 
++                              log_error_write(srv, __FILE__, __LINE__, "sd",
+                                               "wait for fd at connection:", con->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;
+-              
++
+               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", 
++                      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; 
++                      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;
+-                              
++
+                               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);
+-                              
++
+                               /* connection is in progress, wait for an event and call getsockopt() below */
+-                              
++
+                               fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
+-                              
++
+                               return HANDLER_WAIT_FOR_EVENT;
+                       case -1:
+                               /* if ECONNREFUSED choose another connection -> FIXME */
+                               hctx->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", 
++                              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:", 
++                                      "got proc:",
+                                       hctx->fd,
+-                                      hctx->proc->pid, 
+-                                      hctx->proc->socket, 
++                                      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);
+               /* fall through */
+       case FCGI_STATE_PREPARE_WRITE:
+               scgi_create_env(srv, hctx);
+-              
++
+               scgi_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->fd, 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);
+-                              
++
+                               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);
+@@ -2315,10 +2314,10 @@
+                       scgi_set_state(srv, hctx, FCGI_STATE_READ);
+               } else {
+                       fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
+-                      
++
+                       return HANDLER_WAIT_FOR_EVENT;
+               }
+-              
++
+               break;
+       case FCGI_STATE_READ:
+               /* waiting for a response */
+@@ -2327,67 +2326,67 @@
+               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 
++                      /* 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 +2394,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 +2432,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:", 
++
++      log_error_write(srv, __FILE__, __LINE__, "ssdsd",
++                      "emergency exit: scgi:",
+                       "connection-fd:", con->fd,
+                       "fcgi-fd:", hctx->fd);
+-      
+-      
+-      
++
++
++
+       scgi_connection_cleanup(srv, hctx);
+-      
++
+       return HANDLER_FINISHED;
+ }
+@@ -2459,7 +2458,7 @@
+       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;
+@@ -2471,15 +2470,15 @@
+               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 +2488,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,40 +2508,41 @@
+                                                               "\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);
+-                                      
++
+                                       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);
+-                              
++
+                               scgi_connection_cleanup(srv, hctx);
+-                              
++
+                               connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
+                               buffer_reset(con->physical.path);
+                               con->http_status = 500;
+@@ -2550,76 +2550,76 @@
+                       } 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_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) {
+                       /* 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) {
+                       /* 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 &&
+                          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 +2628,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 +2670,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 +2707,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 +2725,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 +2738,7 @@
+                               char *pathinfo;
+                               hctx = handler_ctx_init();
+-                              
++
+                               hctx->remote_conn      = con;
+                               hctx->plugin_data      = p;
+                               hctx->host             = host;
+@@ -2749,45 +2746,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 +2793,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 +2818,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,19 +2841,19 @@
+ 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) {
+               switch (hctx->state) {
+               case FCGI_STATE_READ:
+                       fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
+-                      
++
+                       break;
+               case FCGI_STATE_CONNECT:
+               case FCGI_STATE_WRITE:
+                       fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
+-                      
++
+                       break;
+               case FCGI_STATE_INIT:
+                       /* at reconnect */
+@@ -2873,21 +2870,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 +2901,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 +2949,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 +2963,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 +3021,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 +3038,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
+                               }
+                       }
+               }
+@@ -3082,8 +3081,8 @@
+       p->handle_subrequest       = mod_scgi_handle_subrequest;
+       p->handle_joblist          = mod_scgi_handle_joblist;
+       p->handle_trigger          = mod_scgi_handle_trigger;
+-      
++
+       p->data         = NULL;
+-      
++
+       return 0;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_secure_download.c lighttpd-1.4.12/src/mod_secure_download.c
+--- lighttpd-1.4.11/src/mod_secure_download.c  2005-12-14 14:37:29.000000000 +0200
++++ lighttpd-1.4.12/src/mod_secure_download.c  2006-07-11 21:23:39.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;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_setenv.c lighttpd-1.4.12/src/mod_setenv.c
+--- lighttpd-1.4.11/src/mod_setenv.c   2006-01-14 20:33:12.000000000 +0200
++++ lighttpd-1.4.12/src/mod_setenv.c   2006-07-11 21:23:40.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->data        = NULL;
+-      
++
+       return 0;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_simple_vhost.c lighttpd-1.4.12/src/mod_simple_vhost.c
+--- lighttpd-1.4.11/src/mod_simple_vhost.c     2005-11-18 15:16:13.000000000 +0200
++++ lighttpd-1.4.12/src/mod_simple_vhost.c     2006-07-11 21:23:40.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;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_skeleton.c lighttpd-1.4.12/src/mod_skeleton.c
+--- lighttpd-1.4.11/src/mod_skeleton.c 2005-10-02 18:30:51.000000000 +0300
++++ lighttpd-1.4.12/src/mod_skeleton.c 2006-07-11 21:23:40.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;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_sql_vhost_core.c lighttpd-1.4.12/src/mod_sql_vhost_core.c
+--- lighttpd-1.4.11/src/mod_sql_vhost_core.c   1970-01-01 03:00:00.000000000 +0300
++++ lighttpd-1.4.12/src/mod_sql_vhost_core.c   2006-07-11 21:23:40.000000000 +0300
+@@ -0,0 +1,209 @@
++#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);
++
++                      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;
++}
++
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_sql_vhost_core.h lighttpd-1.4.12/src/mod_sql_vhost_core.h
+--- lighttpd-1.4.11/src/mod_sql_vhost_core.h   1970-01-01 03:00:00.000000000 +0300
++++ lighttpd-1.4.12/src/mod_sql_vhost_core.h   2006-07-11 21:23:40.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
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_ssi.c lighttpd-1.4.12/src/mod_ssi.c
+--- lighttpd-1.4.11/src/mod_ssi.c      2006-03-04 17:09:48.000000000 +0200
++++ lighttpd-1.4.12/src/mod_ssi.c      2006-07-11 21:23:40.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,26 +378,26 @@
+                               }
+                       } 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);
+ #ifdef HAVE_PWD_H
+                       if (NULL == (pw = getpwuid(sce->st.st_uid))) {
+@@ -411,7 +412,7 @@
+               }
+               case SSI_ECHO_LAST_MODIFIED:    {
+                       time_t t = sce->st.st_mtime;
+-                      
++
+                       b = chunkqueue_get_append_buffer(con->write_queue);
+                       if (0 == strftime(buf, sizeof(buf), p->timefmt->ptr, localtime(&t))) {
+                               buffer_copy_string(b, "(none)");
+@@ -422,7 +423,7 @@
+               }
+               case SSI_ECHO_DATE_LOCAL: {
+                       time_t t = time(NULL);
+-                      
++
+                       b = chunkqueue_get_append_buffer(con->write_queue);
+                       if (0 == strftime(buf, sizeof(buf), p->timefmt->ptr, localtime(&t))) {
+                               buffer_copy_string(b, "(none)");
+@@ -433,7 +434,7 @@
+               }
+               case SSI_ECHO_DATE_GMT: {
+                       time_t t = time(NULL);
+-                      
++
+                       b = chunkqueue_get_append_buffer(con->write_queue);
+                       if (0 == strftime(buf, sizeof(buf), p->timefmt->ptr, gmtime(&t))) {
+                               buffer_copy_string(b, "(none)");
+@@ -444,7 +445,7 @@
+               }
+               case SSI_ECHO_DOCUMENT_NAME: {
+                       char *sl;
+-                      
++
+                       b = chunkqueue_get_append_buffer(con->write_queue);
+                       if (NULL == (sl = strrchr(con->physical.path->ptr, '/'))) {
+                               buffer_copy_string_buffer(b, con->physical.path);
+@@ -461,15 +462,15 @@
+               default: {
+                       data_string *ds;
+                       /* check if it is a cgi-var */
+-                      
++
+                       b = chunkqueue_get_append_buffer(con->write_queue);
+-                      
++
+                       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);
+                               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 {
+@@ -579,7 +580,7 @@
+                       }
+               } 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);
+               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,7 +733,7 @@
+                               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;
+                                       }
+@@ -738,10 +741,10 @@
+                                       if (toread > 0) {
+                                               b = chunkqueue_get_append_buffer(con->write_queue);
+-                                              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);
+-              
++
+               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);
+-              
++
+               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;
+-      
++
+       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->set_defaults  = mod_ssi_set_defaults;
+       p->cleanup     = mod_ssi_free;
+-      
++
+       p->data        = NULL;
+-      
++
+       return 0;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_ssi.h lighttpd-1.4.12/src/mod_ssi.h
+--- lighttpd-1.4.11/src/mod_ssi.h      2005-08-11 01:26:39.000000000 +0300
++++ lighttpd-1.4.12/src/mod_ssi.h      2006-07-11 21:23:40.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);
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_ssi_expr.c lighttpd-1.4.12/src/mod_ssi_expr.c
+--- lighttpd-1.4.11/src/mod_ssi_expr.c 2005-08-11 01:26:48.000000000 +0300
++++ lighttpd-1.4.12/src/mod_ssi_expr.c 2006-07-11 21:23:40.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;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_ssi_expr.h lighttpd-1.4.12/src/mod_ssi_expr.h
+--- lighttpd-1.4.11/src/mod_ssi_expr.h 2005-08-11 01:26:48.000000000 +0300
++++ lighttpd-1.4.12/src/mod_ssi_expr.h 2006-07-11 21:23:40.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;
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_ssi_exprparser.c lighttpd-1.4.12/src/mod_ssi_exprparser.c
+--- lighttpd-1.4.11/src/mod_ssi_exprparser.c   2005-10-03 00:40:25.000000000 +0300
++++ lighttpd-1.4.12/src/mod_ssi_exprparser.c   2006-07-11 21:49:18.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:
+       **
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_staticfile.c lighttpd-1.4.12/src/mod_staticfile.c
+--- lighttpd-1.4.11/src/mod_staticfile.c       2006-02-15 14:31:14.000000000 +0200
++++ lighttpd-1.4.12/src/mod_staticfile.c       2006-07-11 21:23:39.000000000 +0300
+@@ -14,9 +14,11 @@
+ #include "http_chunk.h"
+ #include "response.h"
++#include "sys-files.h"
++#include "sys-strings.h"
+ /**
+  * this is a staticfile for a lighttpd plugin
+- * 
++ *
+  */
+@@ -29,48 +31,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,63 +81,60 @@
+ 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;
+@@ -146,69 +145,69 @@
+       data_string *ds;
+       stat_cache_entry *sce = NULL;
+       buffer *content_type = NULL;
+-      
++
+       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 {
+@@ -220,64 +219,64 @@
+                       }
+               } 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 */
+-                                      
++
+                                       error = 1;
+                               }
+                       } else {
+                               /* error */
+-                              
++
+                               error = 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 (!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);
+@@ -285,54 +284,54 @@
+                               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;
+               }
+       }
+-      
++
+       /* something went wrong */
+       if (error) return -1;
+-      
++
+       if (multipart) {
+               /* add boundary end */
+               buffer *b;
+-              
++
+               b = chunkqueue_get_append_buffer(con->write_queue);
+-              
++
+               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 */
+-              
++
+               buffer_copy_string(p->range_buf, "bytes ");
+               buffer_append_off_t(p->range_buf, start);
+               buffer_append_string(p->range_buf, "-");
+               buffer_append_off_t(p->range_buf, 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));
+       }
+@@ -347,12 +346,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 +364,52 @@
+       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;
+               }
+       }
+-      
++
+       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 */
+       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 +419,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);
+@@ -444,34 +443,34 @@
+               /* 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;
+-              
++
+                       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;
+-      
++
+       return HANDLER_FINISHED;
+ }
+@@ -480,13 +479,13 @@
+ 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->set_defaults  = mod_staticfile_set_defaults;
+       p->cleanup     = mod_staticfile_free;
+-      
++
+       p->data        = NULL;
+-      
++
+       return 0;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_status.c lighttpd-1.4.12/src/mod_status.c
+--- lighttpd-1.4.11/src/mod_status.c   2006-01-10 21:45:32.000000000 +0200
++++ lighttpd-1.4.12/src/mod_status.c   2006-07-11 21:23:40.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>
+@@ -29,114 +28,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 +150,7 @@
+       buffer_append_string(b, value);
+       BUFFER_APPEND_STRING_CONST(b, "</td>\n");
+       BUFFER_APPEND_STRING_CONST(b, "   </tr>\n");
+-      
++
+       return 0;
+ }
+@@ -161,13 +160,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 +176,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 +201,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, 
++      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 +225,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 +250,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 +265,7 @@
+                                          "  else return 1;\n"
+                                          " }\n"
+                                          "}\n");
+-              
++
+               BUFFER_APPEND_STRING_CONST(b,
+                                          "function resort(lnk) {\n"
+                                          " var span = lnk.childNodes[1];\n"
+@@ -276,7 +275,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 +293,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,16 +472,16 @@
+       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\">");
+-              
++
++              BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"int bytes_read\">");
++
+               if (con->request.content_length) {
+                       buffer_append_long(b, c->request_content_queue->bytes_in);
+                       BUFFER_APPEND_STRING_CONST(b, "/");
+@@ -490,55 +489,55 @@
+               } else {
+                       BUFFER_APPEND_STRING_CONST(b, "0/0");
+               }
+-      
+-              BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"int\">");
+-              
++
++              BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"int bytes_written\">");
++
+               buffer_append_off_t(b, chunkqueue_written(c->write_queue));
+               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_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,7 +547,7 @@
+       buffer *b;
+       double avg;
+       time_t ts;
+-      
++
+       b = chunkqueue_get_append_buffer(con->write_queue);
+       /* output total number of requests */
+@@ -556,19 +555,19 @@
+       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 +576,7 @@
+       /* set text/plain output */
+       response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/plain"));
+-      
++
+       return 0;
+ }
+@@ -591,10 +590,10 @@
+               /* we have nothing to send */
+               con->http_status = 204;
+               con->file_finished = 1;
+-      
++
+               return HANDLER_FINISHED;
+       }
+-      
++
+       b = chunkqueue_get_append_buffer(con->write_queue);
+       for (i = 0; i < st->used; i++) {
+@@ -605,27 +604,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;
+-      
++
+       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;
+-      
++
+       return HANDLER_FINISHED;
+ }
+@@ -634,9 +633,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 +660,10 @@
+ #endif
+               { FDEVENT_HANDLER_UNSET,          NULL }
+       };
+-      
++
+       b = chunkqueue_get_append_buffer(con->write_queue);
+-      
+-      BUFFER_COPY_STRING_CONST(b, 
++
++      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 +674,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 +682,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 +704,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;
+-      
++
+       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->data        = NULL;
+-      
++
+       return 0;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_trigger_b4_dl.c lighttpd-1.4.12/src/mod_trigger_b4_dl.c
+--- lighttpd-1.4.11/src/mod_trigger_b4_dl.c    2005-09-23 22:53:55.000000000 +0300
++++ lighttpd-1.4.12/src/mod_trigger_b4_dl.c    2006-07-11 21:23:39.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;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_userdir.c lighttpd-1.4.12/src/mod_userdir.c
+--- lighttpd-1.4.11/src/mod_userdir.c  2005-10-28 16:48:28.000000000 +0300
++++ lighttpd-1.4.12/src/mod_userdir.c  2006-07-11 21:23:40.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;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_usertrack.c lighttpd-1.4.12/src/mod_usertrack.c
+--- lighttpd-1.4.11/src/mod_usertrack.c        2006-01-31 15:01:20.000000000 +0200
++++ lighttpd-1.4.12/src/mod_usertrack.c        2006-07-11 21:23:40.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;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_webdav.c lighttpd-1.4.12/src/mod_webdav.c
+--- lighttpd-1.4.11/src/mod_webdav.c   2006-03-03 01:28:58.000000000 +0200
++++ lighttpd-1.4.12/src/mod_webdav.c   2006-07-11 21:23:40.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,11 +555,11 @@
+                       /* 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();
+@@ -493,14 +590,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 +605,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,11 +632,11 @@
+                                               /* 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();
+@@ -569,7 +666,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 +698,7 @@
+                       break;
+               }
+       }
+-      
++
+       stream_close(&s);
+       close(ofd);
+@@ -614,16 +711,16 @@
+                       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 +752,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,16 +789,16 @@
+                                               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();
+@@ -721,7 +818,7 @@
+               buffer_free(s.rel_path);
+               buffer_free(d.path);
+               buffer_free(d.rel_path);
+-              
++
+               closedir(srcdir);
+       }
+@@ -748,12 +845,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 +904,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 +937,7 @@
+       char *prop;
+ } webdav_property;
+-webdav_property live_properties[] = { 
++webdav_property live_properties[] = {
+       { "DAV:", "creationdate" },
+       { "DAV:", "displayname" },
+       { "DAV:", "getcontentlanguage" },
+@@ -871,8 +968,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 +1013,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 +1035,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 +1053,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 +1088,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->write_queue);
++
++      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 +1205,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,7 +1224,19 @@
+               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) {
+@@ -1087,12 +1304,12 @@
+                                                               /* 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();
+                                                               }
+@@ -1115,13 +1332,13 @@
+               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);
+-                              
++
+               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 +1346,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 +1362,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 +1374,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 +1396,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 +1415,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 +1431,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 +1443,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");
+                                       }
+@@ -1275,7 +1492,7 @@
+                       return HANDLER_FINISHED;
+               }
+-      
++
+               /* let's create the directory */
+               if (-1 == mkdir(con->physical.path->ptr, 0700)) {
+@@ -1303,7 +1520,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 */
+@@ -1323,7 +1546,7 @@
+                               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);
+-                      
++
+                               buffer_copy_string(b, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
+                               buffer_append_string(b,"<D:multistatus xmlns:D=\"DAV:\">\n");
+@@ -1331,7 +1554,7 @@
+                               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);
+                               }
+@@ -1340,7 +1563,7 @@
+                               con->file_finished = 1;
+                       } else {
+                               /* everything went fine, remove the directory */
+-      
++
+                               if (-1 == rmdir(con->physical.path->ptr)) {
+                                       switch(errno) {
+                                       case ENOENT:
+@@ -1375,97 +1598,174 @@
+       case HTTP_METHOD_PUT: {
+               int fd;
+               chunkqueue *cq = con->request_content_queue;
++              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 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;
+-                              if (r > 0) {
+-                                      c->offset += r;
+-                                      cq->bytes_out += r;
++                                      return HANDLER_FINISHED;
+                               } else {
+-                                      break;
++                                      con->http_status = 201; /* created */
++                              }
++                      } else {
++                              con->http_status = 200; /* modified */
++                      }
++              }
++
++              con->file_finished = 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;
++                                      }
+                               }
+-                              chunkqueue_remove_finished_chunks(cq);
++                              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;
+                       }
+-                      close(fd);
++                      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 +1775,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 +1857,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 {
+@@ -1613,6 +1921,12 @@
+                       /* 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)) {
+@@ -1636,7 +1950,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 +1969,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 +2005,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) {
+@@ -1737,7 +2056,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 +2081,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 +2124,7 @@
+                                                       goto propmatch_cleanup;
+                                               }
+-      
++
+                                               con->http_status = 400;
+                                       } else {
+                                               if (SQLITE_OK != sqlite3_exec(p->conf.sql, "COMMIT", NULL, NULL, &err)) {
+@@ -1821,6 +2141,7 @@
+                               }
+ propmatch_cleanup:
++
+                               xmlFreeDoc(xml);
+                       } else {
+                               con->http_status = 400;
+@@ -1830,11 +2151,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->request_content_queue, &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->file_finished = 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->file_finished = 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 +2462,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;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/network.c lighttpd-1.4.12/src/network.c
+--- lighttpd-1.4.11/src/network.c      2006-03-04 16:45:46.000000000 +0200
++++ lighttpd-1.4.12/src/network.c      2006-07-11 21:23:39.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,11 +32,11 @@
+       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,
+                               revents);
+@@ -44,12 +45,12 @@
+       /* 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->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,17 +130,17 @@
+               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))) {
+                       log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed:", strerror(errno));
+                       return -1;
+@@ -154,7 +155,7 @@
+ #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))) {
+                       log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed:", strerror(errno));
+                       return -1;
+@@ -162,7 +163,7 @@
+               srv_socket->use_ipv6 = 1;
+       }
+ #endif
+-                              
++
+       if (srv_socket->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))) {
+@@ -170,16 +171,16 @@
+                       return -1;
+               }
+       }
+-      
++
+       /* */
+       srv->cur_fds = srv_socket->fd;
+-      
++
+       val = 1;
+       if (setsockopt(srv_socket->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
+@@ -259,8 +261,8 @@
+               if (-1 != (fd = connect(srv_socket->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)) {
+               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)) {
+               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 {
+@@ -390,10 +393,10 @@
+               }
+ #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 +405,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 +416,58 @@
+       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) {
+                       /* 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);
+                       }
+-              
++
+                       close(srv_socket->fd);
+               }
+-              
++
++              if (srv_socket->is_ssl) {
++#ifdef USE_OPENSSL
++                      SSL_CTX_free(srv_socket->ssl_ctx);
++#endif
++              }
++
+               buffer_free(srv_socket->srv_token);
+-              
++
+               free(srv_socket);
+       }
+-      
++
++#ifdef USE_OPENSSL
++      ERR_free_strings();
++#endif
+       free(srv->srv_sockets.ptr);
+-      
++
        return 0;
  }
--#undef PATCH
  
- URIHANDLER_FUNC(mod_setenv_uri_handler) {
-       plugin_data *p = p_d;
---- lighttpd-1.4.11/src/mod_simple_vhost.c     2005-11-18 15:16:13.000000000 +0200
-+++ lighttpd/src/mod_simple_vhost.c    2006-07-11 21:23:40.087855227 +0300
-@@ -10,6 +10,8 @@
+ 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 +481,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 +524,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 +608,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);
+       }
+       return 0;
+ }
+-int network_write_chunkqueue(server *srv, connection *con, chunkqueue *cq) {
+-      int ret = -1;
++network_status_t network_read_chunkqueue(server *srv, connection *con, 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, con->ssl, cq);
++#else
++              return NETWORK_STATUS_FATAL_ERROR;
++#endif
++      } else {
++              return srv->network_backend_read(srv, con, con->fd, 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,11 +661,11 @@
+               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
+        */
+@@ -613,7 +674,7 @@
+               setsockopt(con->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);
+@@ -621,12 +682,17 @@
+       } else {
+               ret = srv->network_backend_write(srv, con, con->fd, 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;
+@@ -639,13 +705,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;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/network.h lighttpd-1.4.12/src/network.h
+--- lighttpd-1.4.11/src/network.h      2005-08-11 01:26:42.000000000 +0300
++++ lighttpd-1.4.12/src/network.h      2006-07-11 21:23:39.000000000 +0300
+@@ -3,7 +3,8 @@
+ #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_chunkqueue(server *srv, connection *con, chunkqueue *c);
+ int network_init(server *srv);
+ int network_close(server *srv);
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/network_backends.h lighttpd-1.4.12/src/network_backends.h
+--- lighttpd-1.4.11/src/network_backends.h     2005-10-24 15:13:51.000000000 +0300
++++ lighttpd-1.4.12/src/network_backends.h     2006-07-11 21:23:40.000000000 +0300
+@@ -43,16 +43,52 @@
+ # 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, int fd, chunkqueue *cq, chunk *c)
++
++#define NETWORK_BACKEND_WRITE(x) \
++    network_status_t network_write_chunkqueue_##x(server *srv, connection *con, int fd, chunkqueue *cq)
++#define NETWORK_BACKEND_READ(x) \
++    network_status_t network_read_chunkqueue_##x(server *srv, connection *con, int fd, chunkqueue *cq)
  
- #include "plugin.h"
++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);
  
-+#include "sys-files.h"
+-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);
++#define NETWORK_BACKEND_WRITE_SSL(x) \
++    network_status_t network_write_chunkqueue_##x(server *srv, connection *con, SSL *ssl, chunkqueue *cq)
++#define NETWORK_BACKEND_READ_SSL(x) \
++    network_status_t network_read_chunkqueue_##x(server *srv, connection *con, SSL *ssl, chunkqueue *cq)
 +
- #ifdef HAVE_CONFIG_H
- #include "config.h"
++NETWORK_BACKEND_WRITE_SSL(openssl);
++NETWORK_BACKEND_READ_SSL(openssl);
  #endif
-@@ -139,7 +141,7 @@
-                        */
-                       char *dp;
-                       
--                      BUFFER_APPEND_SLASH(out);
-+                      PATHNAME_APPEND_SLASH(out);
-                       
-                       if (NULL == (dp = strchr(host->ptr, ':'))) {
-                               buffer_append_string_buffer(out, host);
-@@ -147,17 +149,17 @@
-                               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)) {
-@@ -173,22 +175,19 @@
-       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);
+ #endif
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/network_freebsd_sendfile.c lighttpd-1.4.12/src/network_freebsd_sendfile.c
+--- lighttpd-1.4.11/src/network_freebsd_sendfile.c     2005-10-22 12:28:18.000000000 +0300
++++ lighttpd-1.4.12/src/network_freebsd_sendfile.c     2006-07-11 21:23:40.000000000 +0300
+@@ -26,142 +26,61 @@
+ #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;
 -      
--      PATCH(docroot_cache_key);
--      PATCH(docroot_cache_value);
--      PATCH(docroot_cache_servername);
-+      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(debug);
-+      PATCH_OPTION(debug);
-       
-       /* skip the first, the global context */
-       for (i = 1; i < srv->config_context->used; i++) {
-@@ -203,23 +202,22 @@
-                       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);
+       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;
+-                              }
++              case MEM_CHUNK:
++                      ret = network_write_chunkqueue_writev_mem(srv, con, fd, 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;
+-                                      
+-                                      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;
+-                              }
++                      if (ret != NETWORK_STATUS_SUCCESS) {
++                              return ret;
+                       }
+-                      
++
++                      chunk_finished = 1;
++
+                       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)) {
+                               switch(errno) {
+@@ -169,39 +88,39 @@
+                                       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;
+                               }
                        }
-               }
-       }
-       
-       return 0;
- }
--#undef PATCH
- static handler_t mod_simple_vhost_docroot(server *srv, connection *con, void *p_data) {
-       plugin_data *p = p_data;
---- lighttpd-1.4.11/src/mod_skeleton.c 2005-10-02 18:30:51.000000000 +0300
-+++ lighttpd/src/mod_skeleton.c        2006-07-11 21:23:40.019850968 +0300
-@@ -132,13 +132,11 @@
-       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++) {
-@@ -153,14 +151,13 @@
-                       data_unset *du = dc->value->data[j];
-                       
-                       if (buffer_is_equal_string(du->key, CONST_STR_LEN("skeleton.array"))) {
--                              PATCH(match);
-+                              PATCH_OPTION(match);
+                       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;
+               }
+-              
++
+               if (!chunk_finished) {
+                       /* not finished yet */
+-                      
++
+                       break;
                }
        }
-       
-       return 0;
- }
--#undef PATCH
  
- URIHANDLER_FUNC(mod_skeleton_uri_handler) {
-       plugin_data *p = p_d;
---- lighttpd-1.4.11/src/mod_ssi.c      2006-03-04 17:09:48.000000000 +0200
-+++ lighttpd/src/mod_ssi.c     2006-07-11 21:23:40.159859737 +0300
-@@ -6,7 +6,6 @@
- #include <string.h>
- #include <errno.h>
- #include <time.h>
--#include <unistd.h>
+-      return chunks_written;
++      return NETWORK_STATUS_SUCCESS;
+ }
  
- #include "base.h"
- #include "log.h"
-@@ -23,6 +22,8 @@
- #include "inet_ntop_cache.h"
+ #endif
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/network_linux_sendfile.c lighttpd-1.4.12/src/network_linux_sendfile.c
+--- lighttpd-1.4.11/src/network_linux_sendfile.c       2006-02-15 20:02:36.000000000 +0200
++++ lighttpd-1.4.12/src/network_linux_sendfile.c       2006-07-11 21:23:40.000000000 +0300
+@@ -26,122 +26,54 @@
+ /* on linux 2.4.29 + debian/ubuntu we have crashes if this is enabled */
+ #undef HAVE_POSIX_FADVISE
  
- #include "sys-socket.h"
-+#include "sys-strings.h"
-+#include "sys-files.h"
+-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, fd, cq, c);
  
- #ifdef HAVE_PWD_H
- #include <pwd.h>
-@@ -660,6 +661,8 @@
-               
-               break;
-       case SSI_EXEC: {
-+#ifndef _WIN32
+-                      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;
+                               }
+                       }
+-                      
 +
-               const char *cmd = NULL;
-               pid_t pid;
-               int from_exec_fds[2];
-@@ -682,7 +685,7 @@
-                */
-               
-               if (!cmd) break;
--#ifdef HAVE_FORK      
++                      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 */   
 +
-               if (pipe(from_exec_fds)) {
-                       log_error_write(srv, __FILE__, __LINE__, "ss", 
-                                       "pipe failed: ", strerror(errno));
-@@ -760,7 +763,6 @@
-               }
-               }
- #else
--
-               return -1;
++                      /* 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,7 +83,7 @@
+                               /* 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);
+                                       }
+                               }
+@@ -168,7 +100,7 @@
+                               case ECONNRESET:
+                                       return -2;
+                               default:
+-                                      log_error_write(srv, __FILE__, __LINE__, "ssd", 
++                                      log_error_write(srv, __FILE__, __LINE__, "ssd",
+                                                       "sendfile failed:", strerror(errno), fd);
+                                       return -1;
+                               }
+@@ -179,7 +111,7 @@
+                                *
+                                * - 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;
+@@ -196,22 +128,22 @@
+ #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
-               
-@@ -1008,13 +1010,11 @@
-       return 0;
- }
+ #endif
+-                      
++
+                       c->offset += r;
+                       cq->bytes_out += r;
+-                      
++
+                       if (c->offset == c->file.length) {
+                               chunk_finished = 1;
  
--#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++) {
-@@ -1029,14 +1029,13 @@
-                       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);
+@@ -222,19 +154,19 @@
+                                       c->file.fd = -1;
+                               }
                        }
+-                      
++
+                       break;
+               }
+               default:
+-                      
++
+                       log_error_write(srv, __FILE__, __LINE__, "ds", c, "type not known");
+-                      
++
+                       return -1;
+               }
+-              
++
+               if (!chunk_finished) {
+                       /* not finished yet */
+-                      
++
+                       break;
                }
        }
-       
-       return 0;
- }
--#undef PATCH
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/network_openssl.c lighttpd-1.4.12/src/network_openssl.c
+--- lighttpd-1.4.11/src/network_openssl.c      2005-11-17 14:53:29.000000000 +0200
++++ lighttpd-1.4.12/src/network_openssl.c      2006-07-11 21:23:40.000000000 +0300
+@@ -23,17 +23,87 @@
+ #include "log.h"
+ #include "stat_cache.h"
  
- URIHANDLER_FUNC(mod_ssi_physical_path) {
-       plugin_data *p = p_d;
---- lighttpd-1.4.11/src/mod_staticfile.c       2006-02-15 14:31:14.000000000 +0200
-+++ lighttpd/src/mod_staticfile.c      2006-07-11 21:23:39.979848462 +0300
-@@ -14,6 +14,8 @@
- #include "http_chunk.h"
- #include "response.h"
+-# include <openssl/ssl.h> 
+-# include <openssl/err.h> 
++# include <openssl/ssl.h>
++# include <openssl/err.h>
  
-+#include "sys-files.h"
-+#include "sys-strings.h"
- /**
-  * this is a staticfile for a lighttpd plugin
-  * 
-@@ -48,7 +50,7 @@
-       return p;
- }
+-int network_write_chunkqueue_openssl(server *srv, connection *con, SSL *ssl, chunkqueue *cq) {
++NETWORK_BACKEND_READ_SSL(openssl) {
++      buffer *b;
++      off_t len;
++
++      b = chunkqueue_get_append_buffer(cq);
++      buffer_prepare_copy(b, 8192);
++      len = SSL_read(ssl, b->ptr, b->size - 1);
++
++      log_error_write(srv, __FILE__, __LINE__, "so", "SSL:", len);
++
++      if (len < 0) {
++              int r, ssl_err;
++
++              switch ((r = SSL_get_error(con->ssl, len))) {
++              case SSL_ERROR_WANT_READ:
++                      return 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 */
++                              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;
++              }
++      }
++
++      assert(len > 0);
++      b->used += len;
++      b->ptr[b->used - 1] = '\0';
++
++      return NETWORK_STATUS_SUCCESS;
++}
++
++
++NETWORK_BACKEND_WRITE_SSL(openssl) {
+       int ssl_r;
+       chunk *c;
+       size_t chunks_written = 0;
  
--/* detroy the plugin data */
-+/* destroy the plugin data */
- FREE_FUNC(mod_staticfile_free) {
-       plugin_data *p = p_d;
-       
-@@ -107,13 +109,11 @@
-       return HANDLER_GO_ON;
- }
+       /* 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,14 +113,14 @@
+        * 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 */
+@@ -60,32 +130,34 @@
+       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(ssl, offset, toSend)) <= 0) {
+                               unsigned long err;
  
--#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++) {
-@@ -128,14 +128,13 @@
-                       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);
+                               switch ((ssl_r = SSL_get_error(ssl, r))) {
+@@ -95,7 +167,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()));
+@@ -105,43 +177,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;
                }
-       }
-       
-       return 0;
- }
--#undef PATCH
+               case FILE_CHUNK: {
+@@ -150,7 +222,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 +236,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;
  
- static int http_response_parse_range(server *srv, connection *con, plugin_data *p) {
-       int multipart = 0;
-@@ -396,7 +395,7 @@
-               return HANDLER_FINISHED;
-       }
-       
--      /* we only handline regular files */
-+      /* we only handle regular files */
-       if (!S_ISREG(sce->st.st_mode)) {
-               con->http_status = 404;
-               
-@@ -409,7 +408,7 @@
-               return HANDLER_FINISHED;
-       }
+                               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;
+                               }
  
--      /* 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 */
+@@ -183,9 +255,9 @@
+                               }
  
---- lighttpd-1.4.11/src/mod_status.c   2006-01-10 21:45:32.000000000 +0200
-+++ lighttpd/src/mod_status.c  2006-07-11 21:23:40.131857983 +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>
-@@ -202,7 +201,7 @@
-       size_t j;
-       double avg;
-       char multiplier = '\0';
--      char buf[32];
-+      char buf[128];
-       time_t ts;
-       
-       int days, hours, mins, seconds;
-@@ -304,13 +303,13 @@
-       /* 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;
-       
-@@ -348,58 +347,58 @@
-       
-       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;
+                               s = local_send_buffer;
+-                      
++
+                               close(ifd);
+-                      
++
+                               if ((r = SSL_write(ssl, s, toSend)) <= 0) {
+                                       unsigned long err;
+@@ -197,7 +269,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,58 +279,58 @@
+                                                       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++;
+       }
  
-       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, "</span>req</td></tr>\n");
-       
--      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=\"traffic\">");
-       avg = p->abs_traffic_out;
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/network_solaris_sendfilev.c lighttpd-1.4.12/src/network_solaris_sendfilev.c
+--- lighttpd-1.4.11/src/network_solaris_sendfilev.c    2005-10-22 12:28:27.000000000 +0300
++++ lighttpd-1.4.12/src/network_solaris_sendfilev.c    2006-07-11 21:23:40.000000000 +0300
+@@ -29,114 +29,34 @@
+ #endif
  
-       mod_status_get_multiplier(&avg, &multiplier, 1024);
+ /**
+- * 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
+  */
  
-       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");
  
+-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;
+                       }
  
-       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);
+@@ -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;
+               }
+       }
  
-       mod_status_get_multiplier(&avg, &multiplier, 1000);
+-      return chunks_written;
++      return NETWORK_STATUS_SUCCESS;
+ }
  
-       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, "</span>req/s</td></tr>\n");
-       
--      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=\"traffic_avg\">");
-       avg = p->abs_traffic_out / (srv->cur_ts - srv->startup_ts);
+ #endif
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/network_write.c lighttpd-1.4.12/src/network_write.c
+--- lighttpd-1.4.11/src/network_write.c        2005-10-22 12:27:56.000000000 +0300
++++ lighttpd-1.4.12/src/network_write.c        2006-07-11 21:23:39.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>
  
-       mod_status_get_multiplier(&avg, &multiplier, 1024);
+ #include "network.h"
+ #include "fdevent.h"
+@@ -13,9 +13,12 @@
+ #include "stat_cache.h"
  
-       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");
+ #include "sys-socket.h"
++#include "sys-files.h"
  
-       
-       
-@@ -410,15 +409,15 @@
-       
-       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\">");
+ #include "network_backends.h"
  
-       mod_status_get_multiplier(&avg, &multiplier, 1000);
++#ifdef USE_WRITE
++
+ #ifdef HAVE_SYS_FILIO_H
+ # include <sys/filio.h>
+ #endif
+@@ -24,47 +27,86 @@
+ #include <sys/resource.h>
+ #endif
  
-       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];
-@@ -426,15 +425,15 @@
-       
-       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\">");
+-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;
++
++      /* check how much we have to read */
++      if (ioctl(fd, FIONREAD, &toread)) {
++              log_error_write(srv, __FILE__, __LINE__, "sd",
++                              "ioctl failed: ",
++                              fd);
++              return NETWORK_STATUS_FATAL_ERROR;
++      }
++
++      if (toread == 0) return NETWORK_STATUS_WAIT_FOR_EVENT;
++
++    /*
++    * our chunk queue is quiet large already
++    *
++    * let's buffer it to disk
++    */
++
++    b = chunkqueue_get_append_buffer(cq);
++
++    buffer_prepare_copy(b, toread);
++
++    if (-1 == (r = read(fd, b->ptr, toread))) {
++              log_error_write(srv, __FILE__, __LINE__, "sds",
++                              "unexpected end-of-file (perhaps the proxy process died):",
++                              fd, strerror(errno));
++              return NETWORK_STATUS_FATAL_ERROR;
++      }
++
++      /* this should be catched by the b > 0 above */
++      assert(r);
++      b->used += r + 1;
++      b->ptr[b->used - 1] = '\0';
++
++    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;
++
++                              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 +118,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;
+                       }
  
-       mod_status_get_multiplier(&avg, &multiplier, 1024);
+                       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));
  
-       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");
-       
-@@ -445,9 +444,9 @@
-       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];
-@@ -462,7 +461,7 @@
-       
-       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");
-@@ -477,11 +476,11 @@
-       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\">");
-+              BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"int bytes_read\">");
-               
-               if (con->request.content_length) {
-                       buffer_append_long(b, c->request_content_queue->bytes_in);
-@@ -491,21 +490,21 @@
-                       BUFFER_APPEND_STRING_CONST(b, "0/0");
+                               close(ifd);
+-                              
+-                              return -1;
++
++                              return NETWORK_STATUS_FATAL_ERROR;
+                       }
+                       close(ifd);
+                       if ((r = write(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))) {
+                               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;
                }
-       
--              BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"int\">");
-+              BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"int bytes_written\">");
-               
-               buffer_append_off_t(b, chunkqueue_written(c->write_queue));
-               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_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);
-@@ -514,13 +513,13 @@
-                       buffer_append_string_buffer(b, c->server_name);
+               default:
+-                      
++
+                       log_error_write(srv, __FILE__, __LINE__, "ds", c, "type not known");
+-                      
+-                      return -1;
++
++                      return NETWORK_STATUS_FATAL_ERROR;
                }
-               
--              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);
+-              
++
+               if (!chunk_finished) {
+                       /* not finished yet */
+-                      
++
+                       break;
                }
-               
--              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);
-               
-@@ -723,16 +722,14 @@
-       return HANDLER_FINISHED;
+-              
++
+               chunks_written++;
+       }
+-      return chunks_written;
++      return NETWORK_STATUS_SUCCESS;
  }
  
--#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++) {
-@@ -747,13 +744,13 @@
-                       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);
-                       } 
-               }
-       }
---- lighttpd-1.4.11/src/mod_trigger_b4_dl.c    2005-09-23 22:53:55.000000000 +0300
-+++ lighttpd/src/mod_trigger_b4_dl.c   2006-07-11 21:23:39.991849214 +0300
-@@ -241,25 +241,23 @@
-       return HANDLER_GO_ON;
- }
+-#if 0
+-network_write_init(void) {
+-      p->write = network_write_write_chunkset;
+-}
+ #endif
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/network_writev.c lighttpd-1.4.12/src/network_writev.c
+--- lighttpd-1.4.11/src/network_writev.c       2006-02-15 01:02:36.000000000 +0200
++++ lighttpd-1.4.12/src/network_writev.c       2006-07-11 21:23: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,119 @@
+ #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(fd, chunks, num_chunks)) < 0) {
++              switch (errno) {
++              case EAGAIN:
++              case EINTR:
++                      r = 0;
++                      break;
++              case EPIPE:
++              case ECONNRESET:
++                      return NETWORK_STATUS_CONNECTION_CLOSE;
++              default:
++                      log_error_write(srv, __FILE__, __LINE__, "ssd",
++                                      "writev failed:", strerror(errno), 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;
++                      break;
++              }
++      }
++
++      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, fd, 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 +173,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;
  
--#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);
-+      PATCH_OPTION(db);
- #endif        
- #if defined(HAVE_PCRE_H)
--      PATCH(download_regex);
--      PATCH(trigger_regex);
-+      PATCH_OPTION(download_regex);
-+      PATCH_OPTION(trigger_regex);
- #endif        
--      PATCH(trigger_timeout);
--      PATCH(deny_url);
--      PATCH(mc_namespace);
--      PATCH(debug);
-+      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 */
-@@ -276,27 +274,27 @@
+                       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;
+                       }
  
-                       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
+                       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;
                        }
-               }
-@@ -304,7 +302,6 @@
-       
-       return 0;
- }
--#undef PATCH
  
- URIHANDLER_FUNC(mod_trigger_b4_dl_uri_handler) {
-       plugin_data *p = p_d;
---- lighttpd-1.4.11/src/mod_userdir.c  2005-10-28 16:48:28.000000000 +0300
-+++ lighttpd/src/mod_userdir.c 2006-07-11 21:23:40.091855478 +0300
-@@ -10,6 +10,7 @@
- #include "response.h"
+-                      /* 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 +202,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 +248,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 +259,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 */
  
- #include "plugin.h"
-+#include "sys-files.h"
+-                                      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);
  
- #ifdef HAVE_PWD_H
- #include <pwd.h>
-@@ -118,16 +119,14 @@
-       return HANDLER_GO_ON;
- }
+-                                      return -1;
++                                      return NETWORK_STATUS_FATAL_ERROR;
+                               }
  
--#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++) {
-@@ -142,20 +141,19 @@
-                       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);
+                               c->file.mmap.length = to_mmap;
+@@ -258,7 +272,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 +288,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);
+                       }
+@@ -297,18 +311,18 @@
+                                       break;
+                               case EPIPE:
+                               case ECONNRESET:
+-                                      return -2;
++                                      return NETWORK_STATUS_CONNECTION_CLOSE;
+                               default:
+-                                      log_error_write(srv, __FILE__, __LINE__, "ssd", 
++                                      log_error_write(srv, __FILE__, __LINE__, "ssd",
+                                                       "write failed:", strerror(errno), fd);
+-                                      
+-                                      return -1;
++
++                                      return NETWORK_STATUS_FATAL_ERROR;
+                               }
                        }
+-                      
++
+                       c->offset += r;
+                       cq->bytes_out += r;
+-                      
++
+                       if (c->offset == c->file.length) {
+                               chunk_finished = 1;
+@@ -318,26 +332,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 0;
+-      return chunks_written;
++      return NETWORK_STATUS_SUCCESS;
  }
--#undef PATCH
  
- URIHANDLER_FUNC(mod_userdir_docroot_handler) {
-       plugin_data *p = p_d;
-@@ -252,10 +250,10 @@
-               }
+ #endif
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/plugin.c lighttpd-1.4.12/src/plugin.c
+--- lighttpd-1.4.11/src/plugin.c       2006-02-08 14:00:54.000000000 +0200
++++ lighttpd-1.4.12/src/plugin.c       2006-07-11 21:23:40.000000000 +0300
+@@ -13,27 +13,27 @@
+ #include <valgrind/valgrind.h>
+ #endif
  
-               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);
-+      PATHNAME_APPEND_SLASH(p->temp_path);
-       buffer_append_string_buffer(p->temp_path, p->conf.path); 
+-#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()
+- * 
++ *
+  */
  
-       if (buffer_is_empty(p->conf.basepath)) {
-@@ -268,7 +266,7 @@
-               } 
-       }
+ typedef struct {
+       PLUGIN_DATA;
+ } plugin_data;
  
--      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);
+-typedef enum { 
++typedef enum {
+       PLUGIN_FUNC_UNSET,
+-              PLUGIN_FUNC_HANDLE_URI_CLEAN, 
+-              PLUGIN_FUNC_HANDLE_URI_RAW, 
++              PLUGIN_FUNC_HANDLE_URI_CLEAN,
++              PLUGIN_FUNC_HANDLE_URI_RAW,
+               PLUGIN_FUNC_HANDLE_REQUEST_DONE,
+               PLUGIN_FUNC_HANDLE_CONNECTION_CLOSE,
+               PLUGIN_FUNC_HANDLE_TRIGGER,
+@@ -44,38 +44,42 @@
+               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;
  
---- lighttpd-1.4.11/src/mod_usertrack.c        2006-01-31 15:01:20.000000000 +0200
-+++ lighttpd/src/mod_usertrack.c       2006-07-11 21:23:40.115856981 +0300
-@@ -136,15 +136,13 @@
-       return HANDLER_GO_ON;
+ static plugin *plugin_init(void) {
+       plugin *p;
+-      
++
+       p = calloc(1, sizeof(*p));
+-      
++
++      p->required_plugins = array_init();
++
+       return p;
  }
  
--#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++) {
-@@ -159,18 +157,17 @@
-                       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);
-                       }
-               }
+ 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;
  }
--#undef PATCH
  
- URIHANDLER_FUNC(mod_usertrack_uri_handler) {
-       plugin_data *p = p_d;
---- lighttpd-1.4.11/src/mod_webdav.c   2006-03-03 01:28:58.000000000 +0200
-+++ lighttpd/src/mod_webdav.c  2006-07-11 21:23:40.123857482 +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>
+ #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 @@
+       }
  
-+#if defined(HAVE_LIBXML_H) && defined(HAVE_SQLITE3_H) && defined(HAVE_UUID_H)
-+#define USE_LOCKS
-+#include <uuid/uuid.h>
-+#endif
+ /**
+- * plugins that use 
+- * 
++ * plugins that use
++ *
+  * - server *srv
+  * - connection *con
+  * - void *p_d (plugin_data *)
+@@ -301,12 +329,12 @@
+       }
+ /**
+- * plugins that use 
+- * 
++ * plugins that use
++ *
+  * - server *srv
+  * - void *p_d (plugin_data *)
+  */
+-                                                                      
 +
- #include "base.h"
- #include "log.h"
- #include "buffer.h"
-@@ -33,6 +35,9 @@
- #include "stream.h"
- #include "stat_cache.h"
+ 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 @@
  
-+#include "sys-files.h"
-+#include "sys-mmap.h"
-+#include "sys-strings.h"
+ #undef PLUGIN_TO_SLOT
  
+-#if 0                                                                 
++#if 0
  /**
-  * this is a webdav for a lighttpd plugin
-@@ -62,6 +67,12 @@
-       sqlite3_stmt *stmt_delete_uri;
-       sqlite3_stmt *stmt_move_uri;
-       sqlite3_stmt *stmt_copy_uri;
+- * 
++ *
+  * special handler
+- * 
++ *
+  */
+ handler_t plugins_call_handle_fdevent(server *srv, const fd_conn *fdc) {
+       size_t i;
+       plugin **ps;
+-      
 +
-+      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;
-@@ -123,6 +134,12 @@
-                               sqlite3_finalize(s->stmt_update_prop);
-                               sqlite3_finalize(s->stmt_select_prop);
-                               sqlite3_finalize(s->stmt_select_propnames);
+       ps = srv->plugins.ptr;
+-      
 +
-+                              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        
-@@ -193,6 +210,24 @@
-                               return HANDLER_ERROR;
+       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.
+  */
  
-+                      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)) {
+ handler_t plugins_call_init(server *srv) {
+       size_t i;
+       plugin **ps;
+-      
 +
-+                              if (0 != strcmp(err, "table properties already exists")) {
-+                                      log_error_write(srv, __FILE__, __LINE__, "ss", "can't open transaction:", err);
-+                                      sqlite3_free(err);
+       ps = srv->plugins.ptr;
+-      
 +
-+                                      return HANDLER_ERROR;
-+                              }
-+                              sqlite3_free(err);
-+                      }
+       /* fill slots */
+-      
 +
-                       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)) {
-@@ -211,23 +246,6 @@
-                               return HANDLER_ERROR;
-                       }
--                      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("REPLACE INTO properties (resource, prop, ns, value) VALUES (?, ?, ?, ?)"), 
-@@ -273,6 +291,76 @@
-                               return HANDLER_ERROR;
-                       }
+       srv->plugin_slots = calloc(PLUGIN_FUNC_SIZEOF, sizeof(ps));
+-      
 +
-+                      /* LOCKS */
+       for (i = 0; i < srv->plugins.used; i++) {
+               size_t j;
+               /* check which calls are supported */
+-              
 +
-+                      if (SQLITE_OK != sqlite3_exec(s->sql,
-+                                      "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,"
-+                                      "  timeout TIMESTAMP NOT NULL,"
-+                                      "  PRIMARY KEY(locktoken))",
-+                                      NULL, NULL, &err)) {
+               plugin *p = ps[i];
+-              
 +
-+                              if (0 != strcmp(err, "table locks already exists")) {
-+                                      log_error_write(srv, __FILE__, __LINE__, "ss", "can't open transaction:", err);
-+                                      sqlite3_free(err);
+ #define PLUGIN_TO_SLOT(x, y) \
+       if (p->y) { \
+               plugin **slot = ((plugin ***)(srv->plugin_slots))[x]; \
+@@ -384,11 +412,11 @@
+                       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); 
++      }
 +
-+                                      return HANDLER_ERROR;
-+                              }
-+                              sqlite3_free(err);
-+                      }
 +
-+                      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));
++              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);
+@@ -402,19 +430,19 @@
+               PLUGIN_TO_SLOT(PLUGIN_FUNC_CLEANUP, cleanup);
+               PLUGIN_TO_SLOT(PLUGIN_FUNC_SET_DEFAULTS, set_defaults);
+ #undef PLUGIN_TO_SLOT
+-              
 +
-+                              return HANDLER_ERROR;
-+                      }
+               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;
+                       }
+-                      
 +
-+                      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));
+                       /* used for con->mode, DIRECT == 0, plugins above that */
+                       ((plugin_data *)(p->data))->id = i + 1;
+-                      
 +
-+                              return HANDLER_ERROR;
-+                      }
+                       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 +450,46 @@
+                       p->data = NULL;
+               }
+       }
+-      
 +
-+                      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_GO_ON;
+ }
++/**
++ * get the config-storage of the named plugin 
++ */
++void *plugin_get_config(server *srv, const char *name) {
++      size_t i;
 +
-+                              return HANDLER_ERROR;
-+                      }
++      for (i = 0; i < srv->plugins.used; i++) {
++              plugin *p = ((plugin **)srv->plugins.ptr)[i];
 +
-+                      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));
++              if (buffer_is_equal_string(p->name, name, strlen(name))) {
++                      return p->data;
++              }
++      }
 +
-+                              return HANDLER_ERROR;
-+                      }
++      return NULL;
++}
 +
-+                      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));
+ void plugins_free(server *srv) {
+       size_t i;
+       plugins_call_cleanup(srv);
+-      
 +
-+                              return HANDLER_ERROR;
-+                      }
+       for (i = 0; i < srv->plugins.used; i++) {
+               plugin *p = ((plugin **)srv->plugins.ptr)[i];
+-              
 +
+               plugin_free(p);
+       }
+-      
 +
- #else
-                       log_error_write(srv, __FILE__, __LINE__, "s", "Sorry, no sqlite3 and libxml2 support include, compile with --with-webdav-props");
-                       return HANDLER_ERROR;
-@@ -283,26 +371,30 @@
-       return HANDLER_GO_ON;
- }
+       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;
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/plugin.h lighttpd-1.4.12/src/plugin.h
+--- lighttpd-1.4.11/src/plugin.h       2005-08-15 12:28:56.000000000 +0300
++++ lighttpd-1.4.12/src/plugin.h       2006-07-11 21:23:40.000000000 +0300
+@@ -12,6 +12,12 @@
  
--#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);
+ #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,19 +31,19 @@
+ #define URIHANDLER_FUNC    CONNECTION_FUNC
+ #define PLUGIN_DATA        size_t id
+-                                                                                                                                              
 +
-+      PATCH_OPTION(stmt_delete_uri);
-+      PATCH_OPTION(stmt_move_uri);
-+      PATCH_OPTION(stmt_copy_uri);
+ typedef struct {
+       size_t version;
+-      
 +
-+      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++) {
-@@ -317,22 +409,28 @@
-                       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);
+       buffer *name; /* name of the plugin */
+-      
 +
-+                              PATCH_OPTION(stmt_delete_uri);
-+                              PATCH_OPTION(stmt_move_uri);
-+                              PATCH_OPTION(stmt_copy_uri);
+       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 */
+-      
 +
-+                              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);
+       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 */
+@@ -45,20 +51,22 @@
+       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 
++
++
++
++      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);    /* */
+       void *data;
+-      
++
+       /* dlopen handle */
+       void *lib;
++
++      array *required_plugins;
+ } plugin;
+ int plugins_load(server *srv);
+@@ -88,5 +96,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
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/proc_open.c lighttpd-1.4.12/src/proc_open.c
+--- lighttpd-1.4.11/src/proc_open.c    2005-08-11 01:26:39.000000000 +0300
++++ lighttpd-1.4.12/src/proc_open.c    2006-07-11 21:23:40.000000000 +0300
+@@ -13,13 +13,13 @@
  #endif
-                       }
-               }
-@@ -340,7 +438,6 @@
-       
-       return 0;
- }
--#undef PATCH
  
- URIHANDLER_FUNC(mod_webdav_uri_handler) {
-       plugin_data *p = p_d;
-@@ -362,7 +459,7 @@
-               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:
-@@ -496,11 +593,11 @@
-                       } 
  
-                       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);
+-#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();
  
-                       /* stat and unlink afterwards */
-@@ -657,19 +754,19 @@
-                       }
-                       
-                       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);
+@@ -148,11 +148,14 @@
+       STARTUPINFO si;
+       BOOL procok;
+       SECURITY_ATTRIBUTES security;
+-      const char *shell;
++      const char *shell = NULL;
++      const char *windir = NULL;
+       buffer *cmdline;
  
-                       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);
+-      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;
+       }
  
-                       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);
+@@ -177,17 +180,23 @@
+       memset(&pi, 0, sizeof(pi));
  
-                       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);
+       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 (-1 == stat(s.path->ptr, &st)) {
-@@ -821,9 +918,9 @@
-                                         SQLITE_TRANSIENT);
+       if (FALSE == procok) {
+-              fprintf(stderr, "failed to CreateProcess");
++              fprintf(stderr, "failed to CreateProcess: %s", cmdline->ptr);
++              buffer_free(cmdline);
+               return -1;
+       }
++      buffer_free(cmdline);
  
-                       /* 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;
-                       }
-               }
-@@ -991,6 +1088,113 @@
+       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
+ /* }}} */
+-#endif /* WIN32 */
++#endif /* _WIN32 */
  
-+int webdav_lockdiscovery(server *srv, connection *con,
-+              buffer *locktoken, const char *lockscope, const char *locktype, int depth) {
+ /* {{{ 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);
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/proc_open.h lighttpd-1.4.12/src/proc_open.h
+--- lighttpd-1.4.11/src/proc_open.h    2005-08-11 01:26:39.000000000 +0300
++++ lighttpd-1.4.12/src/proc_open.h    2006-07-11 21:23:40.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;
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/request.c lighttpd-1.4.12/src/request.c
+--- lighttpd-1.4.11/src/request.c      2006-03-05 11:58:09.000000000 +0200
++++ lighttpd-1.4.12/src/request.c      2006-07-11 21:23:40.000000000 +0300
+@@ -10,15 +10,17 @@
+ #include "keyvalue.h"
+ #include "log.h"
++#include "sys-strings.h"
 +
-+      buffer *b;
+ static int request_check_hostname(server *srv, connection *con, 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;
+-      
 +
-+      response_header_overwrite(srv, con, CONST_STR_LEN("Lock-Token"), CONST_BUF_LEN(locktoken));
+       UNUSED(srv);
+       UNUSED(con);
+@@ -32,17 +34,17 @@
+        *       IPv6address   = "[" ... "]"
+        *       port          = *digit
+        */
+-      
++
+       /* no Host: */
+       if (!host || host->used == 0) 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;
+               }
+-              
 +
-+      response_header_overwrite(srv, con,
-+              CONST_STR_LEN("Content-Type"),
-+              CONST_STR_LEN("text/xml; charset=\"utf-8\""));
+               /* remove the port from the host-len */
+               host_len = colon - host->ptr;
+       }
+-      
 +
-+      b = chunkqueue_get_append_buffer(con->write_queue);
+       /* Host is empty */
+       if (host_len == 0) return -1;
+-      
 +
-+      buffer_copy_string(b, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
+       /* 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;
+                                       }
+-                                      
 +
-+      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");
+                                       /* 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;
+                                       }
+-                                              
 +
-+      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");
+                                       stage = DOMAINLABEL;
+-                                      
 +
-+      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");
+                                       label_len = 0;
+                                       level++;
+                               } else if (i == 0) {
+@@ -135,7 +137,7 @@
+                               }
+                               label_len++;
+                       }
+-                      
 +
-+      buffer_append_string(b,"<D:depth>");
-+      buffer_append_string(b, depth == 0 ? "0" : "infinity");
-+      buffer_append_string(b,"</D:depth>\n");
+                       break;
+               case DOMAINLABEL:
+                       if (is_ip == 1) {
+@@ -143,7 +145,7 @@
+                                       if (label_len == 0) {
+                                               return -1;
+                                       }
+-                                      
 +
-+      buffer_append_string(b,"<D:timeout>");
-+      buffer_append_string(b, "Second-600");
-+      buffer_append_string(b,"</D:timeout>\n");
+                                       label_len = 0;
+                                       level++;
+                               } else if (!light_isdigit(c)) {
+@@ -156,12 +158,12 @@
+                                       if (label_len == 0) {
+                                               return -1;
+                                       }
+-                                      
 +
-+      buffer_append_string(b,"<D:owner>");
-+      buffer_append_string(b,"</D:owner>\n");
+                                       /* c is either - or alphanum here */
+                                       if ('-' == host->ptr[i+1]) {
+                                               return -1;
+                                       }
+-                                      
 +
-+      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");
+                                       label_len = 0;
+                                       level++;
+                               } else if (i == 0) {
+@@ -176,20 +178,20 @@
+                                       label_len++;
+                               }
+                       }
+-                      
 +
-+      buffer_append_string(b,"</D:activelock>\n");
-+      buffer_append_string(b,"</D:lockdiscovery>\n");
-+      buffer_append_string(b,"</D:prop>\n");
+                       break;
+               }
+       }
+-      
 +
-+      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;
+       /* a IP has to consist of 4 parts */
+       if (is_ip == 1 && level != 3) {
+               return -1;
+       }
+-      
 +
-+#ifdef USE_LOCKS
-+      data_string *ds;
+       if (label_len == 0) {
+               return -1;
+       }
+-      
 +
-+      /**
-+       * 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. :)
+       return 0;
+ }
+@@ -201,53 +203,53 @@
+       char *s;
+       size_t i;
+       int state = 0;
+-      /*  
+-       * parse 
+-       * 
++      /*
++       * parse
 +       *
-+       * X-Litmus: locks: 11 (owner_modify)
-+       * If: <http://127.0.0.1:1025/dav/litmus/lockme> (<opaquelocktoken:2165478d-0611-49c4-be92-e790d68a38f1>)
+        * val1, val2, val3, val4
+-       * 
 +       *
-+       * 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 */
+        * into a array (more or less a explode() incl. striping of whitespaces
+        */
+-      
 +
-+              sqlite3_stmt *stmt = p->conf.stmt_read_lock_by_uri;
+       if (b->used == 0) return 0;
+-      
 +
-+              sqlite3_reset(stmt);
+       s = b->ptr;
+-      
 +
-+              sqlite3_bind_text(stmt, 1,
-+                        CONST_BUF_LEN(uri),
-+                        SQLITE_TRANSIENT);
+       for (i =0; i < b->used - 1; ) {
+               char *start = NULL, *end = NULL;
+               data_string *ds;
+-              
 +
-+              while (SQLITE_ROW == sqlite3_step(stmt)) {
-+                      has_lock = 0;
-+              }
-+      }
-+#endif
+               switch (state) {
+               case 0: /* ws */
+-                      
 +
-+      return has_lock;
-+}
+                       /* skip ws */
+                       for (; (*s == ' ' || *s == '\t') && i < b->used - 1; i++, s++);
+-                      
+-                      
 +
- URIHANDLER_FUNC(mod_webdav_subrequest_handler) {
-       plugin_data *p = p_d;
-       buffer *b;
-@@ -1001,6 +1205,7 @@
-       buffer *prop_200;
-       buffer *prop_404;
-       webdav_properties *req_props;
-+      stat_cache_entry *sce = NULL;
-       
-       UNUSED(srv);
-@@ -1020,6 +1225,18 @@
-               /* 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;
-+              }
 +
+                       state = 1;
+                       break;
+               case 1: /* value */
+                       start = s;
+-                      
 +
- #ifdef USE_PROPPATCH
-               /* any special requests or just allprop ? */
-               if (con->request.content_length) {
-@@ -1182,10 +1399,10 @@
-                                       } 
-                                       buffer_copy_string_buffer(d.path, dst->path);
--                                      BUFFER_APPEND_SLASH(d.path);
-+                                      PATHNAME_APPEND_SLASH(d.path);
+                       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_buffer(d.rel_path, dst->rel_path);
--                                      BUFFER_APPEND_SLASH(d.rel_path);
-+                                      PATHNAME_APPEND_SLASH(d.rel_path);
+                       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,7 +265,7 @@
+       if (c <= 32) return 0;
+       if (c == 127) return 0;
+       if (c == 255) return 0;
+-      
++
+       return 1;
+ }
  
-                                       if (de->d_name[0] == '.' && de->d_name[1] == '\0') {
-                                               /* don't append the . */ 
-@@ -1304,6 +1521,12 @@
-                       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;
-+              }
+@@ -271,28 +273,28 @@
+       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;
+-      
 +
-               /* stat and unlink afterwards */
-               if (-1 == stat(con->physical.path->ptr, &st)) {
-                       /* don't about it yet, unlink will fail too */
-@@ -1375,22 +1598,100 @@
-       case HTTP_METHOD_PUT: {
-               int fd;
-               chunkqueue *cq = con->request_content_queue;
-+              chunk *c;
-+              data_string *ds_range;
+       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]+): (.+)$"                    
++
++      /*
++       * Request: "^(GET|POST|HEAD) ([^ ]+(\\?[^ ]+|)) (HTTP/1\\.[01])$"
++       * Option : "^([-a-zA-Z]+): (.+)$"
+        * End    : "^$"
+        */
  
-               if (p->conf.is_readonly) {
-                       con->http_status = 403;
-                       return HANDLER_FINISHED;
-               }
+       if (con->conf.log_request_header) {
+-              log_error_write(srv, __FILE__, __LINE__, "sdsdSb", 
+-                              "fd:", con->fd, 
+-                              "request-len:", con->request.request->used, 
++              log_error_write(srv, __FILE__, __LINE__, "sdsdSb",
++                              "fd:", con->fd,
++                              "request-len:", con->request.request->used,
+                               "\n", con->request.request);
+       }
  
-+              /* 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;
-+              }
+@@ -300,13 +302,13 @@
+           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);
+       }
+-      
 +
-               assert(chunkqueue_length(cq) == (off_t)con->request.content_length);
+       keep_alive_set = 0;
+       con_length_set = 0;
  
--              /* 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))) {
-+              /* 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 */
+@@ -318,25 +320,25 @@
+        * */
+       for (i = 0, first = 0; i < con->parse_request->used && line == 0; i++) {
+               char *cur = con->parse_request->ptr + i;
+-              
 +
-+              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;
+               switch(*cur) {
+-              case '\r': 
++              case '\r':
+                       if (con->parse_request->ptr[i+1] == '\n') {
+                               http_method_t r;
+                               char *nuri = NULL;
+                               size_t j;
+-                              
 +
-+                      if (0 != strncmp(num, "bytes ", 6)) {
-+                              con->http_status = 501; /* not implemented */
+                               /* \r\n -> \0\0 */
+                               con->parse_request->ptr[i] = '\0';
+                               con->parse_request->ptr[i+1] = '\0';
+-                              
 +
-+                              return HANDLER_FINISHED;
-+                      }
+                               buffer_copy_string_len(con->request.request_line, con->parse_request->ptr, i);
+-                              
 +
-+                      /* we only support <num>- ... */
+                               if (request_line_stage != 2) {
+                                       con->http_status = 400;
+                                       con->response.keep_alive = 0;
+                                       con->keep_alive = 0;
+-                                      
 +
-+                      num += 6;
+                                       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",
+@@ -345,36 +347,36 @@
+                                       }
+                                       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;
+                               }
+-                              
 +
-+                      /* skip WS */
-+                      while (*num == ' ' || *num == '\t') num++;
+                               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, '.');
+@@ -413,10 +415,10 @@
+                                       }
+                                       if (major_num == 1 && minor_num == 1) {
+-                                              con->request.http_version = con->conf.allow_http11 ? HTTP_VERSION_1_1 : HTTP_VERSION_1_0;
++                                              con->request.http_version = HTTP_VERSION_1_1;
+                                       } else if (major_num == 1 && minor_num == 0) {
+                                               con->request.http_version = HTTP_VERSION_1_0;
+-                                      } else { 
++                                      } else {
+                                               con->http_status = 505;
+                                               if (srv->srvconf.log_request_header_on_error) {
+@@ -439,30 +441,30 @@
+                                       }
+                                       return 0;
+                               }
+-                              
 +
-+                      if (*num == '\0') {
-+                              con->http_status = 501; /* not implemented */
+                               if (0 == strncmp(uri, "http://", 7) &&
+                                   NULL != (nuri = strchr(uri + 7, '/'))) {
+                                       /* ignore the host-part */
+-                                      
 +
-+                              return HANDLER_FINISHED;
-+                      }
+                                       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);
+                               }
+-                              
 +
-+                      offset = strtoll(num, &err, 10);
+                               /* 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 (*err != '-' || offset < 0) {
-+                              con->http_status = 501; /* not implemented */
+                                               if (srv->srvconf.log_request_header_on_error) {
+                                                       buf[0] = con->request.uri->ptr[j];
+                                                       buf[1] = '\0';
+-                                      
 +
-+                              return HANDLER_FINISHED;
-+                      }
+                                                       if (con->request.uri->ptr[j] > 32 &&
+-                                                          con->request.uri->ptr[j] != 127) {  
++                                                          con->request.uri->ptr[j] != 127) {
+                                                               /* the character is printable -> print it */
+                                                               log_error_write(srv, __FILE__, __LINE__, "ss",
+                                                                               "invalid character in URI -> 400",
+@@ -473,20 +475,20 @@
+                                                                               "invalid character in URI -> 400",
+                                                                               con->request.uri->ptr[j]);
+                                                       }
+-                                              
 +
-+                      if (-1 == (fd = open(con->physical.path->ptr, O_WRONLY, 0600))) {
-+                              switch (errno) {
-+                              case ENOENT:
-+                                      con->http_status = 404; /* not found */
-+                                      break;
-+                              default:
-+                                      con->http_status = 403; /* not found */
-+                                      break;
-+                              }
-+                              return HANDLER_FINISHED;
-+                      }
+                                                       log_error_write(srv, __FILE__, __LINE__, "Sb",
+                                                                       "request-header:\n",
+                                                                       con->request.request);
+                                               }
+-                                              
 +
-+                      if (-1 == lseek(fd, offset, SEEK_SET)) {
-+                              con->http_status = 501; /* not implemented */
+                                               return 0;
+                                       }
+                               }
+-                              
 +
-+                              close(fd);
+                               buffer_copy_string_buffer(con->request.orig_uri, con->request.uri);
+-                              
 +
-+                              return HANDLER_FINISHED;
-+                      }
-+                      con->http_status = 200; /* modified */
-+              } else {
-+                      /* take what we have in the request-body and write it to a file */
+                               con->http_status = 0;
+-                              
 +
-+                      /* 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;
--              } else {
--                      chunk *c;
-+                                      return HANDLER_FINISHED;
-+                              } else {
-                       con->http_status = 201; /* created */
-+                              }
-+                      } else {
-+                              con->http_status = 200; /* modified */
-+                      }
-+              }
+                               i++;
+                               line++;
+                               first = i+1;
+@@ -494,14 +496,14 @@
+                       break;
+               case ' ':
+                       switch(request_line_stage) {
+-                      case 0: 
++                      case 0:
+                               /* GET|POST|... */
+-                              method = con->parse_request->ptr + first; 
++                              method = con->parse_request->ptr + first;
+                               first = i + 1;
+                               break;
+                       case 1:
+                               /* /foobar/... */
+-                              uri = con->parse_request->ptr + first; 
++                              uri = con->parse_request->ptr + first;
+                               first = i + 1;
+                               break;
+                       default:
+@@ -509,7 +511,7 @@
+                               con->http_status = 400;
+                               con->response.keep_alive = 0;
+                               con->keep_alive = 0;
+-                              
 +
-                       con->file_finished = 1;
-                       for (c = cq->first; c; c = cq->first) {
-@@ -1462,7 +1763,6 @@
+                               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",
+@@ -518,12 +520,12 @@
+                               }
+                               return 0;
                        }
-                       close(fd);
--              }
-               return HANDLER_FINISHED;
-       }
-       case HTTP_METHOD_MOVE: 
-@@ -1476,6 +1776,14 @@
-                       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,7 +1857,7 @@
+                       request_line_stage++;
+                       break;
                }
-               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 / */ 
-@@ -1613,6 +1921,12 @@
-                       /* 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)) {
-@@ -1691,12 +2005,17 @@
+       in_folding = 0;
  
-               return HANDLER_FINISHED;
+       if (con->request.uri->used == 1) {
+@@ -540,30 +542,30 @@
+               return 0;
        }
--      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) {
-@@ -1789,7 +2108,8 @@
-                                                                       }
-                                                               
-                                                                       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));
-                                                                       }
-                                                               }
-                                                       }
-@@ -1821,6 +2141,7 @@
+       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
+-                       * 
++                       *
+                        */
+                       switch(*cur) {
+                       case ':':
+                               is_key = 0;
+-                              
++
+                               value = cur + 1;
+-                              
++
+                               if (is_ws_after_key == 0) {
+                                       key_len = i - first;
                                }
- propmatch_cleanup:
+                               is_ws_after_key = 0;
+-                                      
 +
-                               xmlFreeDoc(xml);
-                       } else {
+                               break;
+                       case '(':
+                       case ')':
+@@ -584,8 +586,8 @@
                                con->http_status = 400;
-@@ -1830,7 +2151,303 @@
- #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
-+               */
+                               con->keep_alive = 0;
+                               con->response.keep_alive = 0;
+-                              
+-                              log_error_write(srv, __FILE__, __LINE__, "sbsds", 
++
++                              log_error_write(srv, __FILE__, __LINE__, "sbsds",
+                                               "invalid character in key", con->request.request, cur, *cur, "-> 400");
+                               return 0;
+                       case ' ':
+@@ -594,13 +596,13 @@
+                                       is_key = 0;
+                                       in_folding = 1;
+                                       value = cur;
+-                                      
 +
-+              if (depth != 0 && depth != -1) {
-+                      con->http_status = 400;
+                                       break;
+                               }
+-                              
+-                              
 +
-+                      return HANDLER_FINISHED;
-+              }
 +
-+#ifdef USE_LOCKS
-+              if (con->request.content_length) {
-+                      xmlDocPtr xml;
-+                      buffer *hdr_if = NULL;
+                               key_len = i - first;
+-                              
 +
-+                      if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "If"))) {
-+                              hdr_if = ds->value;
-+                      }
+                               /* skip every thing up to the : */
+                               for (j = 1; !got_colon; j++) {
+                                       switch(con->parse_request->ptr[j + i]) {
+@@ -610,40 +612,40 @@
+                                               continue;
+                                       case ':':
+                                               /* ok, done */
+-                                              
 +
-+                      /* we don't support Depth: Infinity on locks */
-+                      if (hdr_if == NULL && depth == -1) {
-+                              con->http_status = 409; /* Conflict */
+                                               i += j - 1;
+                                               got_colon = 1;
+-                                              
 +
-+                              return HANDLER_FINISHED;
-+                      }
+                                               break;
+                                       default:
+                                               /* error */
+-                                              
 +
-+                      if (1 == webdav_parse_chunkqueue(srv, con, p, con->request_content_queue, &xml)) {
-+                              xmlNode *rootnode = xmlDocGetRootElement(xml);
+                                               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);
+                                               }
+-                                      
 +
-+                              assert(rootnode);
+                                               con->http_status = 400;
+                                               con->response.keep_alive = 0;
+                                               con->keep_alive = 0;
+-                                              
 +
-+                              if (0 == xmlStrcmp(rootnode->name, BAD_CAST "lockinfo")) {
-+                                      xmlNode *lockinfo;
-+                                      const xmlChar *lockscope = NULL, *locktype = NULL, *owner = NULL;
+                                               return 0;
+                                       }
+                               }
+-                              
 +
-+                                      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;
+                               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';
+-                                      
 +
-+                                                                      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;
+                                       i++;
+-                                      
++
+                                       done = 1;
+-                                      
++
+                                       break;
+                               } else {
+                                       if (srv->srvconf.log_request_header_on_error) {
+@@ -652,7 +654,7 @@
+                                                       "request-header:\n",
+                                                       con->request.request);
+                                       }
+-                                      
 +
-+                                                                      xmlFreeDoc(xml);
-+                                                                      return HANDLER_FINISHED;
-+                                                              }
-+                                                      }
+                                       con->http_status = 400;
+                                       con->keep_alive = 0;
+                                       con->response.keep_alive = 0;
+@@ -693,16 +695,16 @@
+                               con->http_status = 400;
+                               con->keep_alive = 0;
+                               con->response.keep_alive = 0;
+-                              
 +
-+                                              } else if (0 == xmlStrcmp(lockinfo->name, BAD_CAST "owner")) {
-+                                              }
-+                                      }
+                               if (srv->srvconf.log_request_header_on_error) {
+-                                      log_error_write(srv, __FILE__, __LINE__, "sbsds", 
++                                      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);
+                               }
+-                              
 +
-+                                      if (lockscope && locktype) {
-+                                              sqlite3_stmt *stmt = p->conf.stmt_read_lock_by_uri;
+                               return 0;
+                       default:
+                               /* ok */
+@@ -710,25 +712,25 @@
+                       }
+               } else {
+                       switch(*cur) {
+-                      case '\r': 
++                      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';
+-                                      
 +
-+                                              /* is this resourse already locked ? */
+                                       if (in_folding) {
+                                               if (!ds) {
+                                                       /* 400 */
+-                                      
 +
-+                                              /* SELECT locktoken, resource, lockscope, locktype, owner, depth, timeout
-+                                               *   FROM locks
-+                                               *  WHERE resource = ? */
+                                                       if (srv->srvconf.log_request_header_on_error) {
+                                                               log_error_write(srv, __FILE__, __LINE__, "s", "WS at the start of first line -> 400");
+-                                                      
 +
-+                                              if (stmt) {
+                                                               log_error_write(srv, __FILE__, __LINE__, "Sb",
+                                                                       "request-header:\n",
+                                                                       con->request.request);
+                                                       }
+-                                      
 +
-+                                                      sqlite3_reset(stmt);
+                                                       con->http_status = 400;
+                                                       con->keep_alive = 0;
+                                                       con->response.keep_alive = 0;
+@@ -738,9 +740,9 @@
+                                       } else {
+                                               int s_len;
+                                               key = con->parse_request->ptr + first;
+-                                      
 +
-+                                                      sqlite3_bind_text(stmt, 1,
-+                                                                        p->uri.path->ptr,
-+                                                                        p->uri.path->used - 1,
-+                                                                        SQLITE_TRANSIENT);
+                                               s_len = cur - value;
+-                                              
 +
-+                                                      /* 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 (s_len > 0) {
+                                                       int cmp = 0;
+                                                       if (NULL == (ds = (data_string *)array_get_unused_element(con->request.headers, TYPE_STRING))) {
+@@ -748,86 +750,87 @@
+                                                       }
+                                                       buffer_copy_string_len(ds->key, key, key_len);
+                                                       buffer_copy_string_len(ds->value, value, s_len);
+-                                                      
+-                                                      /* retreive values 
+-                                                       * 
+-                                                       * 
++
++                                                      /* retreive values
++                                                       *
++                                                       *
+                                                        * the list of options is sorted to simplify the search
+                                                        */
+-                                                      
 +
-+                                                              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;
-+                                                      }
-       }
+                                                       if (0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Connection")))) {
+                                                               array *vals;
+                                                               size_t vi;
+-                                                              
 +
-+                                              stmt = p->conf.stmt_create_lock;
-+                                              if (stmt) {
-+                                                      /* create a lock-token */
-+                                                      uuid_t id;
-+                                                      char uuid[37] /* 36 + \0 */;
+                                                               /* split on , */
+-                                                              
 +
-+                                                      uuid_generate(id);
-+                                                      uuid_unparse(id, uuid);
+                                                               vals = srv->split_vals;
+                                                               array_reset(vals);
+-                                                              
 +
-+                                                      buffer_copy_string(p->tmp_buf, "opaquelocktoken:");
-+                                                      buffer_append_string(p->tmp_buf, uuid);
+                                                               http_request_split_value(vals, ds->value);
+-                                                              
 +
-+                                                      /* "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,"
-+                                                       */
+                                                               for (vi = 0; vi < vals->used; vi++) {
+                                                                       data_string *dsv = (data_string *)vals->data[vi];
+-                                                                      
 +
-+                                                      sqlite3_reset(stmt);
+                                                                       if (0 == buffer_caseless_compare(CONST_BUF_LEN(dsv->value), CONST_STR_LEN("keep-alive"))) {
+                                                                               keep_alive_set = HTTP_CONNECTION_KEEPALIVE;
+-                                                                              
 +
-+                                                      sqlite3_bind_text(stmt, 1,
-+                                                                        CONST_BUF_LEN(p->tmp_buf),
-+                                                                        SQLITE_TRANSIENT);
+                                                                               break;
+                                                                       } else if (0 == buffer_caseless_compare(CONST_BUF_LEN(dsv->value), CONST_STR_LEN("close"))) {
+                                                                               keep_alive_set = HTTP_CONNECTION_CLOSE;
+-                                                                              
 +
-+                                                      sqlite3_bind_text(stmt, 2,
-+                                                                        CONST_BUF_LEN(con->uri.path),
-+                                                                        SQLITE_TRANSIENT);
+                                                                               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", 
++                                                                              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);
+                                                                       }
++                                                                      ds->free((data_unset *) ds);
+                                                                       return 0;
+                                                               }
+-                                                              
 +
-+                                                      sqlite3_bind_text(stmt, 3,
-+                                                                        lockscope,
-+                                                                        xmlStrlen(lockscope),
-+                                                                        SQLITE_TRANSIENT);
+                                                               if (ds->value->used == 0) SEGFAULT();
+-                                                              
 +
-+                                                      sqlite3_bind_text(stmt, 4,
-+                                                                        locktype,
-+                                                                        xmlStrlen(locktype),
-+                                                                        SQLITE_TRANSIENT);
+                                                               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", 
++                                                                              log_error_write(srv, __FILE__, __LINE__, "sbs",
+                                                                                               "content-length broken:", ds->value, "-> 400");
+-                                                                              
 +
-+                                                      /* owner */
-+                                                      sqlite3_bind_text(stmt, 5,
-+                                                                        "",
-+                                                                        0,
-+                                                                        SQLITE_TRANSIENT);
+                                                                               con->http_status = 400;
+                                                                               con->keep_alive = 0;
+-                                                                              
 +
-+                                                      /* depth */
-+                                                      sqlite3_bind_int(stmt, 6,
-+                                                                       depth);
+                                                                               array_insert_unique(con->request.headers, (data_unset *)ds);
+                                                                               return 0;
+                                                                       }
+                                                               }
+-                                                              
 +
+                                                               r = strtoul(ds->value->ptr, &err, 10);
+-                                                              
 +
-+                                                      if (SQLITE_DONE != sqlite3_step(stmt)) {
-+                                                              log_error_write(srv, __FILE__, __LINE__, "ss",
-+                                                                              "create lock:", sqlite3_errmsg(p->conf.sql));
-+                                                      }
+                                                               if (*err == '\0') {
+                                                                       con_length_set = 1;
+                                                                       con->request.content_length = r;
+                                                               } else {
+-                                                                      log_error_write(srv, __FILE__, __LINE__, "sbs", 
++                                                                      log_error_write(srv, __FILE__, __LINE__, "sbs",
+                                                                                       "content-length broken:", ds->value, "-> 400");
+-                                                                      
 +
-+                                                      /* looks like we survived */
-+                                                      webdav_lockdiscovery(srv, con, p->tmp_buf, lockscope, locktype, depth);
+                                                                       con->http_status = 400;
+                                                                       con->keep_alive = 0;
+-                                                                      
 +
-+                                                      con->http_status = 201;
-+                                                      con->file_finished = 1;
-+                                              }
-+                                      }
-+                              }
+                                                                       array_insert_unique(con->request.headers, (data_unset *)ds);
+                                                                       return 0;
+                                                               }
+@@ -838,23 +841,24 @@
+                                                               } else {
+                                                                       con->http_status = 400;
+                                                                       con->keep_alive = 0;
+-                                                                      
++
+                                                                       if (srv->srvconf.log_request_header_on_error) {
+-                                                                              log_error_write(srv, __FILE__, __LINE__, "s", 
++                                                                              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);
+                                                                       }
++                                                                      ds->free((data_unset *) ds);
+                                                                       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 
++                                                              /* 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 ?
+@@ -863,10 +867,10 @@
+                                                                *    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")))) {
+@@ -875,14 +879,15 @@
+                                                               } else {
+                                                                       con->http_status = 400;
+                                                                       con->keep_alive = 0;
+-                                                                      
++
+                                                                       if (srv->srvconf.log_request_header_on_error) {
+-                                                                              log_error_write(srv, __FILE__, __LINE__, "s", 
++                                                                              log_error_write(srv, __FILE__, __LINE__, "s",
+                                                                                               "duplicate Host-header -> 400");
+                                                                               log_error_write(srv, __FILE__, __LINE__, "Sb",
+                                                                                               "request-header:\n",
+                                                                                               con->request.request);
+                                                                       }
++                                                                      ds->free((data_unset *) ds);
+                                                                       return 0;
+                                                               }
+                                                       } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("If-Modified-Since")))) {
+@@ -897,14 +902,15 @@
+                                                               } else {
+                                                                       con->http_status = 400;
+                                                                       con->keep_alive = 0;
+-                                                                      
++
+                                                                       if (srv->srvconf.log_request_header_on_error) {
+-                                                                              log_error_write(srv, __FILE__, __LINE__, "s", 
++                                                                              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);
+                                                                       }
++                                                                      ds->free((data_unset *) ds);
+                                                                       return 0;
+                                                               }
+                                                       } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("If-None-Match")))) {
+@@ -914,47 +920,49 @@
+                                                               } else {
+                                                                       con->http_status = 400;
+                                                                       con->keep_alive = 0;
+-                                                                      
++
+                                                                       if (srv->srvconf.log_request_header_on_error) {
+-                                                                              log_error_write(srv, __FILE__, __LINE__, "s", 
++                                                                              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);
+                                                                       }
++                                                                      ds->free((data_unset *) ds);
+                                                                       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=.*-.* */
+-                                                              
 +
-+                              xmlFreeDoc(xml);
-+                              return HANDLER_FINISHED;
-+                      } else {
-+                              con->http_status = 400;
-+                              return HANDLER_FINISHED;
-+                      }
-+              } else {
+                                                                       if (0 == strncasecmp(ds->value->ptr, "bytes=", 6) &&
+                                                                           NULL != strchr(ds->value->ptr+6, '-')) {
+-                                                                              
 +
-+                      if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "If"))) {
-+                              buffer *locktoken = ds->value;
-+                              sqlite3_stmt *stmt = p->conf.stmt_refresh_lock;
+                                                                               /* 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", 
++                                                                              log_error_write(srv, __FILE__, __LINE__, "s",
+                                                                                               "duplicate Range-header -> 400");
+                                                                               log_error_write(srv, __FILE__, __LINE__, "Sb",
+                                                                                               "request-header:\n",
+                                                                                               con->request.request);
+                                                                       }
++                                                                      ds->free((data_unset *) ds);
+                                                                       return 0;
+                                                               }
+                                                       }
+-                                                      
 +
-+                              /* remove the < > around the token */
-+                              if (locktoken->used < 6) {
-+                                      con->http_status = 400;
+                                                       array_insert_unique(con->request.headers, (data_unset *)ds);
+                                               } else {
+                                                       /* empty header-fields are not allowed by HTTP-RFC, we just ignore them */
+                                               }
+                                       }
+-                                      
 +
-+                                      return HANDLER_FINISHED;
-+                              }
+                                       i++;
+                                       first = i+1;
+                                       is_key = 1;
+@@ -963,10 +971,10 @@
+                                       in_folding = 0;
+                               } else {
+                                       if (srv->srvconf.log_request_header_on_error) {
+-                                              log_error_write(srv, __FILE__, __LINE__, "sbs", 
++                                              log_error_write(srv, __FILE__, __LINE__, "sbs",
+                                                               "CR without LF", con->request.request, "-> 400");
+                                       }
+-                                      
 +
-+                              buffer_copy_string_len(p->tmp_buf, locktoken->ptr + 2, locktoken->used - 5);
+                                       con->http_status = 400;
+                                       con->keep_alive = 0;
+                                       con->response.keep_alive = 0;
+@@ -982,28 +990,28 @@
+                       }
+               }
+       }
+-      
 +
-+                              sqlite3_reset(stmt);
+       con->header_len = i;
+-      
 +
-+                              sqlite3_bind_text(stmt, 1,
-+                                        CONST_BUF_LEN(p->tmp_buf),
-+                                        SQLITE_TRANSIENT);
+       /* do some post-processing */
+       if (con->request.http_version == HTTP_VERSION_1_1) {
+               if (keep_alive_set != HTTP_CONNECTION_CLOSE) {
+                       /* no Connection-Header sent */
+-                      
 +
-+                              if (SQLITE_DONE != sqlite3_step(stmt)) {
-+                                      log_error_write(srv, __FILE__, __LINE__, "ss",
-+                                              "refresh lock:", sqlite3_errmsg(p->conf.sql));
-+                              }
+                       /* HTTP/1.1 -> keep-alive default TRUE */
+                       con->keep_alive = 1;
+               } else {
+                       con->keep_alive = 0;
+               }
+-              
 +
-+                              webdav_lockdiscovery(srv, con, p->tmp_buf, "exclusive", "write", 0);
+               /* RFC 2616, 14.23 */
+               if (con->request.http_host == NULL ||
+                   buffer_is_empty(con->request.http_host)) {
+                       con->http_status = 400;
+                       con->response.keep_alive = 0;
+                       con->keep_alive = 0;
+-                      
 +
-+                              con->http_status = 200;
-+                              con->file_finished = 1;
-+                              return HANDLER_FINISHED;
-+                      } else {
-+                              /* we need a lock-token to refresh */
-+                              con->http_status = 400;
+                       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,18 +1023,18 @@
+       } else {
+               if (keep_alive_set == HTTP_CONNECTION_KEEPALIVE) {
+                       /* no Connection-Header sent */
+-                      
 +
-+                              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;
+                       /* HTTP/1.0 -> keep-alive default FALSE  */
+                       con->keep_alive = 1;
+               } else {
+                       con->keep_alive = 0;
+               }
+       }
+-      
 +
-+                      /* remove the < > around the token */
-+                      if (locktoken->used < 4) {
-+                              con->http_status = 400;
+       /* check hostname field if it is set */
+       if (NULL != con->request.http_host &&
+           0 != request_check_hostname(srv, con, con->request.http_host)) {
+-              
 +
-+                              return HANDLER_FINISHED;
-+                      }
+               if (srv->srvconf.log_request_header_on_error) {
+                       log_error_write(srv, __FILE__, __LINE__, "s",
+                                       "Invalid Hostname -> 400");
+@@ -1038,7 +1046,7 @@
+               con->http_status = 400;
+               con->response.keep_alive = 0;
+               con->keep_alive = 0;
+-              
 +
-+                      /**
-+                       * FIXME:
-+                       *
-+                       * if the resourse is locked:
-+                       * - by us: unlock
-+                       * - by someone else: 401
-+                       * if the resource is not locked:
-+                       * - 412
-+                       *  */
+               return 0;
+       }
+@@ -1048,7 +1056,7 @@
+               /* content-length is forbidden for those */
+               if (con_length_set && con->request.content_length != 0) {
+                       /* 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;
+@@ -1060,7 +1068,7 @@
+               /* content-length is required for them */
+               if (!con_length_set) {
+                       /* 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,16 +1081,16 @@
+               /* 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->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;
+               }
+@@ -1090,25 +1098,25 @@
+               /* 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
+                        */
+-              
 +
-+                      buffer_copy_string_len(p->tmp_buf, locktoken->ptr + 1, locktoken->used - 3);
+                       con->http_status = 413;
+                       con->keep_alive = 0;
+-              
+-                      log_error_write(srv, __FILE__, __LINE__, "sds", 
 +
-+                      sqlite3_reset(stmt);
++                      log_error_write(srv, __FILE__, __LINE__, "sds",
+                                       "request-size too long:", con->request.content_length, "-> 413");
+                       return 0;
+               }
+-              
+-              
 +
-+                      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);
+               /* we have content */
+               if (con->request.content_length != 0) {
+                       return 1;
+               }
+       }
+-      
 +
-+                      if (SQLITE_DONE != sqlite3_step(stmt)) {
-+                              log_error_write(srv, __FILE__, __LINE__, "ss",
-+                                      "remove lock:", sqlite3_errmsg(p->conf.sql));
-+                      }
+       return 0;
+ }
+@@ -1116,9 +1124,9 @@
+       UNUSED(srv);
+       if (con->request.request->used < 5) return 0;
+-      
 +
-+                      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;
+       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 HANDLER_FINISHED;
-+              }
-+              break;
-+#else
-+              con->http_status = 501;
-+              return HANDLER_FINISHED;
-+#endif
-       default:
-               break;
-       }
---- lighttpd-1.4.11/src/network.c      2006-03-04 16:45:46.000000000 +0200
-+++ lighttpd/src/network.c     2006-07-11 21:23:39.983848713 +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>
+       return 0;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/response.c lighttpd-1.4.12/src/response.c
+--- lighttpd-1.4.11/src/response.c     2006-03-04 16:41:39.000000000 +0200
++++ lighttpd-1.4.12/src/response.c     2006-07-11 21:23:40.000000000 +0300
+@@ -7,7 +7,6 @@
  #include <stdlib.h>
+ #include <string.h>
+ #include <time.h>
+-#include <unistd.h>
+ #include <ctype.h>
  #include <assert.h>
  
-+#include <stdio.h>
-+
- #include "network.h"
- #include "fdevent.h"
- #include "log.h"
-@@ -19,6 +19,7 @@
- #include "network_backends.h"
- #include "sys-mmap.h"
+@@ -24,15 +23,17 @@
+ #include "plugin.h"
  #include "sys-socket.h"
 +#include "sys-files.h"
++#include "sys-strings.h"
  
- #ifdef USE_OPENSSL
- # include <openssl/ssl.h> 
-@@ -77,7 +78,7 @@
-       struct accept_filter_arg afa;
- #endif
--#ifdef __WIN32
-+#ifdef _WIN32
-       WORD wVersionRequested;
-       WSADATA wsaData;
-       int err;
-@@ -244,6 +245,7 @@
-               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);
-@@ -283,6 +285,7 @@
-               }
-               break;
-+#endif
-       default:
-               addr_len = 0;
-               
-@@ -404,7 +407,6 @@
-       }
-       
-       srv->srv_sockets.ptr[srv->srv_sockets.used++] = srv_socket;
+ int http_response_write_header(server *srv, connection *con) {
+       buffer *b;
+       size_t i;
+       int have_date = 0;
+       int have_server = 0;
 -      
-       buffer_free(b);
-       
-       return 0;
-@@ -425,11 +427,20 @@
-                       close(srv_socket->fd);
-               }
-               
-+              if (srv_socket->is_ssl) {
-+#ifdef USE_OPENSSL
-+                      SSL_CTX_free(srv_socket->ssl_ctx);
-+#endif
-+              }
-+
-               buffer_free(srv_socket->srv_token);
-               
-               free(srv_socket);
-       }
-       
-+#ifdef USE_OPENSSL
-+      ERR_free_strings();
-+#endif
-       free(srv->srv_sockets.ptr);
-       
-       return 0;
-@@ -437,11 +448,15 @@
- 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,
+       b = chunkqueue_get_prepend_buffer(con->write_queue);
+-      
 +
-+    NETWORK_BACKEND_WIN32_SEND,
-+    NETWORK_BACKEND_WIN32_TRANSMITFILE,
- } network_backend_t;
- int network_init(server *srv) {
-@@ -466,7 +481,16 @@
- #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
+       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));
+-      
 +
-               { NETWORK_BACKEND_UNSET,                NULL }
-       };
-       
-@@ -508,33 +532,59 @@
-               }
+       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");
        }
-+#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
+       if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
+               BUFFER_APPEND_STRING_CONST(b, "\r\nTransfer-Encoding: chunked");
+       }
+-      
+-      
 +
-       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
+       /* add all headers */
+       for (i = 0; i < con->response.headers->used; i++) {
+               data_string *ds;
+-              
 +
-+#ifdef USE_WRITE
-       case NETWORK_BACKEND_WRITE:
--              srv->network_backend_write = network_write_chunkqueue_write;
-+        SET_NETWORK_BACKEND(read, write);
-               break;
+               ds = (data_string *)con->response.headers->data[i];
+-              
 +
- #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;
+               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
-+#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++) {
-@@ -569,23 +619,34 @@
- int network_register_fdevents(server *srv) {
-       size_t i;
 -      
-       if (-1 == fdevent_reset(srv->ev)) {
-               return -1;
-       }
++
+       if (!have_date) {
+               /* HTTP/1.1 requires a Date: header */
+               BUFFER_APPEND_STRING_CONST(b, "\r\nDate: ");
 -      
-       /* register fdevents after reset */
-       for (i = 0; i < srv->srv_sockets.used; i++) {
-               server_socket *srv_socket = srv->srv_sockets.ptr[i];
++
+               /* 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;
 -              
-               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);
-       }
-       return 0;
- }
--int network_write_chunkqueue(server *srv, connection *con, chunkqueue *cq) {
--      int ret = -1;
-+network_status_t network_read_chunkqueue(server *srv, connection *con, 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, con->ssl, cq);
-+#else
-+              return NETWORK_STATUS_FATAL_ERROR;
-+#endif
-+      } else {
-+              return srv->network_backend_read(srv, con, con->fd, cq);
-+      }
-+}
+                       srv->last_generated_date_ts = srv->cur_ts;
+               }
+-      
 +
-+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       
-       int corked = 0;
-@@ -622,9 +683,14 @@
-               ret = srv->network_backend_write(srv, con, con->fd, cq);
+               buffer_append_string_buffer(b, srv->ts_date_str);
        }
-       
--      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;
+@@ -101,16 +103,16 @@
+                       buffer_append_string_buffer(b, con->conf.server_tag);
+               }
+       }
+-      
 +
-+        break;
-+    default:
-+        break;
+       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);
        }
-       
- #ifdef TCP_CORK
---- lighttpd-1.4.11/src/network.h      2005-08-11 01:26:42.000000000 +0300
-+++ lighttpd/src/network.h     2006-07-11 21:23:39.983848713 +0300
-@@ -3,7 +3,8 @@
- #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_chunkqueue(server *srv, connection *con, chunkqueue *c);
+-      
++
+       return 0;
+ }
  
- int network_init(server *srv);
- int network_close(server *srv);
---- lighttpd-1.4.11/src/network_backends.h     2005-10-24 15:13:51.000000000 +0300
-+++ lighttpd/src/network_backends.h    2006-07-11 21:23:40.035851970 +0300
-@@ -43,16 +43,52 @@
- # define USE_AIX_SENDFILE
- #endif
+@@ -118,71 +120,71 @@
  
-+/**
-+* 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
+ handler_t http_response_prepare(server *srv, connection *con) {
+       handler_t r;
+-      
+-      /* looks like someone has already done a decision */
+-      if (con->mode == DIRECT && 
 +
- #include "base.h"
-+#include "network.h"
++      /* 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);
+               }
+-              
 +
-+#define NETWORK_BACKEND_WRITE_CHUNK(x) \
-+    network_status_t network_write_chunkqueue_##x(server *srv, connection *con, int fd, chunkqueue *cq, chunk *c)
+               return HANDLER_FINISHED;
+       }
+-      
 +
-+#define NETWORK_BACKEND_WRITE(x) \
-+    network_status_t network_write_chunkqueue_##x(server *srv, connection *con, int fd, chunkqueue *cq)
-+#define NETWORK_BACKEND_READ(x) \
-+    network_status_t network_read_chunkqueue_##x(server *srv, connection *con, int fd, chunkqueue *cq)
+       /* no decision yet, build conf->filename */
+       if (con->mode == DIRECT && con->physical.path->used == 0) {
+               char *qstr;
  
-+NETWORK_BACKEND_WRITE_CHUNK(writev_mem);
+-              /* 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
+-               * 
++               *
+                *  */
+-              
 +
-+NETWORK_BACKEND_WRITE(write);
-+NETWORK_BACKEND_WRITE(writev);
-+NETWORK_BACKEND_WRITE(linuxsendfile);
-+NETWORK_BACKEND_WRITE(freebsdsendfile);
-+NETWORK_BACKEND_WRITE(solarissendfilev);
+               if (con->conf.log_condition_handling) {
+                       log_error_write(srv, __FILE__, __LINE__,  "s",  "run condition");
+               }
+               config_patch_connection(srv, con, COMP_SERVER_SOCKET); /* SERVERsocket */
+-              
 +
-+NETWORK_BACKEND_WRITE(win32transmitfile);
-+NETWORK_BACKEND_WRITE(win32send);
+               /**
+                * prepare strings
+-               * 
+-               * - uri.path_raw 
++               *
++               * - uri.path_raw
+                * - uri.path (secure)
+                * - uri.query
+-               * 
++               *
+                */
+-              
+-              /** 
 +
-+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);
-+#define NETWORK_BACKEND_WRITE_SSL(x) \
-+    network_status_t network_write_chunkqueue_##x(server *srv, connection *con, SSL *ssl, chunkqueue *cq)
-+#define NETWORK_BACKEND_READ_SSL(x) \
-+    network_status_t network_read_chunkqueue_##x(server *srv, connection *con, SSL *ssl, chunkqueue *cq)
++              /**
+                * Name according to RFC 2396
+-               * 
++               *
+                * - scheme
+                * - authority
+                * - path
+                * - query
+-               * 
++               *
+                * (scheme)://(authority)(path)?(query)
+-               * 
+-               * 
++               *
++               *
+                */
+-      
 +
-+NETWORK_BACKEND_WRITE_SSL(openssl);
-+NETWORK_BACKEND_READ_SSL(openssl);
- #endif
- #endif
---- lighttpd-1.4.11/src/network_freebsd_sendfile.c     2005-10-22 12:28:18.000000000 +0300
-+++ lighttpd/src/network_freebsd_sendfile.c    2006-07-11 21:23:40.107856480 +0300
-@@ -31,106 +31,25 @@
- # 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++) {
-               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;
--                              }
--
--                              r = 0;
--                      }
-+              case MEM_CHUNK:
-+                      ret = network_write_chunkqueue_writev_mem(srv, con, fd, cq, &c);
-                       
--                      /* 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++;
-+                      if (ret != NETWORK_STATUS_SUCCESS) {
-+                              return ret;
-                                       }
--                              } else {
--                                      /* partially written */
-                                       
--                                      tc->offset += r;
--                                      chunk_finished = 0;
--                                      
--                                      break;
--                              }
--                      }
-+                      chunk_finished = 1;
-                       
+               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 +202,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 +231,14 @@
                        break;
--              }
-               case FILE_CHUNK: {
-                       off_t offset, r;
-                       size_t toSend;
-@@ -140,7 +59,7 @@
-                       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;
-@@ -151,13 +70,13 @@
-                       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;
-@@ -169,11 +88,11 @@
-                                       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);
-@@ -201,7 +120,7 @@
                }
-       }
--      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/src/network_linux_sendfile.c      2006-07-11 21:23:40.271866752 +0300
-@@ -26,106 +26,38 @@
- /* 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;
--
--                      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;
-+              case MEM_CHUNK:
-+                      ret = network_write_chunkqueue_writev_mem(srv, con, fd, cq, c);
-                                       
-+                      /* 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;
-                               }
-                       }
-                       
--                      break;
-+                      if (ret != NETWORK_STATUS_SUCCESS) {
-+                              return ret;
-               }
+-              /* build filename 
++              /* build filename
+                *
+                * - decode url-encodings  (e.g. %20 -> ' ')
+                * - remove path-modifiers (e.g. /../)
+                */
+-              
+-              
+-              
 +
-+                      break;
-               case FILE_CHUNK: {
-                       ssize_t r;
-                       off_t offset;
---- lighttpd-1.4.11/src/network_openssl.c      2005-11-17 14:53:29.000000000 +0200
-+++ lighttpd/src/network_openssl.c     2006-07-11 21:23:40.107856480 +0300
-@@ -26,7 +26,77 @@
- # include <openssl/ssl.h> 
- # include <openssl/err.h> 
++
++
+               if (con->request.http_method == HTTP_METHOD_OPTIONS &&
+                   con->uri.path_raw->ptr[0] == '*' && con->uri.path_raw->ptr[1] == '\0') {
+                       /* OPTIONS * ... */
+@@ -253,15 +255,20 @@
+               }
  
--int network_write_chunkqueue_openssl(server *srv, connection *con, SSL *ssl, chunkqueue *cq) {
-+NETWORK_BACKEND_READ_SSL(openssl) {
-+      buffer *b;
-+      off_t len;
+               /**
+-               *  
+-               * call plugins 
+-               * 
++               *
++               * call plugins
++               *
+                * - based on the clean URL
+-               * 
++               *
+                */
+-              
 +
-+      b = chunkqueue_get_append_buffer(cq);
-+      buffer_prepare_copy(b, 8192);
-+      len = SSL_read(ssl, b->ptr, b->size - 1);
+               config_patch_connection(srv, con, COMP_HTTP_URL); /* HTTPurl */
+-              
 +
-+      log_error_write(srv, __FILE__, __LINE__, "so", "SSL:", len);
++              /* do we have to downgrade to 1.0 ? */
++              if (!con->conf.allow_http11) {
++                      con->request.http_version = HTTP_VERSION_1_0;
++              }
 +
-+      if (len < 0) {
-+              int r, ssl_err;
+               switch(r = plugins_call_handle_uri_clean(srv, con)) {
+               case HANDLER_GO_ON:
+                       break;
+@@ -274,11 +281,11 @@
+                       log_error_write(srv, __FILE__, __LINE__, "");
+                       break;
+               }
+-              
 +
-+              switch ((r = SSL_get_error(con->ssl, len))) {
-+              case SSL_ERROR_WANT_READ:
-+                      return 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 */
-+                              log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:",
-+                                              r, ERR_error_string(ssl_err, NULL));
-+                      }
+               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;
+@@ -288,46 +295,47 @@
+               }
+               /***
+-               * 
+-               * border 
+-               * 
++               *
++               * border
++               *
+                * logical filename (URI) becomes a physical filename here
+-               * 
+-               * 
+-               * 
++               *
++               *
++               *
+                */
+-              
+-              
+-              
+-              
 +
-+                      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;
-+              }
-+      }
+               /* 1. stat()
+                * ... ISREG() -> ok, go on
+                * ... ISDIR() -> index-file -> redirect
+-               * 
+-               * 2. pathinfo() 
++               *
++               * 2. pathinfo()
+                * ... ISREG()
+-               * 
++               *
+                * 3. -> 404
+-               * 
++               *
+                */
+-              
 +
-+      assert(len > 0);
-+      b->used += len;
-+      b->ptr[b->used - 1] = '\0';
+               /*
+                * SEARCH DOCUMENT ROOT
+                */
+-              
 +
-+      return NETWORK_STATUS_SUCCESS;
-+}
+               /* 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
 +
-+NETWORK_BACKEND_WRITE_SSL(openssl) {
-       int ssl_r;
-       chunk *c;
-       size_t chunks_written = 0;
-@@ -65,7 +135,7 @@
-               case MEM_CHUNK: {
-                       char * offset;
-                       size_t toSend;
--                      ssize_t r;
-+                      ssize_t r = 0;
-                       
-                       if (c->mem->used == 0) {
-                               chunk_finished = 1;
-@@ -83,9 +153,11 @@
-                        *        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(ssl, offset, toSend)) <= 0) {
-                               unsigned long err;
-                               switch ((ssl_r = SSL_get_error(ssl, r))) {
---- lighttpd-1.4.11/src/network_solaris_sendfilev.c    2005-10-22 12:28:27.000000000 +0300
-+++ lighttpd/src/network_solaris_sendfilev.c   2006-07-11 21:23:40.211862994 +0300
-@@ -38,105 +38,25 @@
-  */
--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;
--                              }
--                      }
-+              case MEM_CHUNK:
-+                      ret = network_write_chunkqueue_writev_mem(srv, con, fd, cq, &c);
-                       
--                      /* 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++;
-+                      if (ret != NETWORK_STATUS_SUCCESS) {
-+                              return ret;
-                                       }
--                              } else {
--                                      /* partially written */
--                                      
--                                      tc->offset += r;
--                                      chunk_finished = 0;
-                                       
--                                      break;
--                              }
--                      }
-+                      chunk_finished = 1;
-                       
-                       break;
--              }
-               case FILE_CHUNK: {
-                       ssize_t r;
-                       off_t offset;
-@@ -177,7 +97,7 @@
-                                       log_error_write(srv, __FILE__, __LINE__, "ssd", "sendfile: ", strerror(errno), errno);
-                                       
-                                       close(ifd);
--                                      return -1;
-+                                      return NETWORK_STATUS_FATAL_ERROR;
-                               }
-                               
-                               r = 0;
-@@ -194,10 +114,9 @@
++              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 +385,41 @@
+                       log_error_write(srv, __FILE__, __LINE__, "");
                        break;
                }
-               default:
--                      
-                       log_error_write(srv, __FILE__, __LINE__, "ds", c, "type not known");
-                       
--                      return -1;
-+                      return NETWORK_STATUS_FATAL_ERROR;
+-              
+-              /* 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 +439,7 @@
+                       log_error_write(srv, __FILE__, __LINE__, "");
+                       break;
                }
-               
-               if (!chunk_finished) {
-@@ -207,7 +126,7 @@
+-              
++
+               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,38 +447,38 @@
+                       log_error_write(srv, __FILE__, __LINE__,  "sb", "Path         :", con->physical.path);
                }
        }
--      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/src/network_write.c       2006-07-11 21:23:39.887842700 +0300
-@@ -1,11 +1,11 @@
- #include <sys/types.h>
- #include <sys/stat.h>
--#include <sys/time.h>
+-      
+-      /* 
+-       * Noone catched away the file from normal path of execution yet (like mod_access)
+-       * 
 +
- #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
++      /*
++       * No one took the file away from the normal path of execution yet (like mod_access)
++       *
+        * Go on and check of the file exists at all
+        */
+-      
 +
- #ifdef HAVE_SYS_FILIO_H
- # include <sys/filio.h>
- #endif
-@@ -24,7 +27,53 @@
- #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;
+       if (con->mode == DIRECT) {
+               char *slash = NULL;
+               char *pathinfo = NULL;
+               int found = 0;
+               stat_cache_entry *sce = NULL;
+-              
 +
-+      /* check how much we have to read */
-+      if (ioctl(fd, FIONREAD, &toread)) {
-+              log_error_write(srv, __FILE__, __LINE__, "sd",
-+                              "ioctl failed: ",
-+                              fd);
-+              return NETWORK_STATUS_FATAL_ERROR;
-+      }
+               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 (toread == 0) return NETWORK_STATUS_WAIT_FOR_EVENT;
+               if (HANDLER_ERROR != stat_cache_get_entry(srv, con, con->physical.path, &sce)) {
+                       /* file exists */
+-                      
 +
-+    /*
-+    * our chunk queue is quiet large already
-+    *
-+    * let's buffer it to disk
-+    */
+                       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);
+                       }
+-                      
 +
-+    b = chunkqueue_get_append_buffer(cq);
+                       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 .../ */
+-                                      
 +
-+    buffer_prepare_copy(b, toread);
+                                       http_response_redirect_to_directory(srv, con);
+-                                      
 +
-+    if (-1 == (r = read(fd, b->ptr, toread))) {
-+              log_error_write(srv, __FILE__, __LINE__, "sds",
-+                              "unexpected end-of-file (perhaps the proxy process died):",
-+                              fd, strerror(errno));
-+              return NETWORK_STATUS_FATAL_ERROR;
-+      }
+                                       return HANDLER_FINISHED;
+                               }
+                       } else if (!S_ISREG(sce->st.st_mode)) {
+@@ -477,12 +490,12 @@
+                       switch (errno) {
+                       case EACCES:
+                               con->http_status = 403;
+-      
 +
-+      /* this should be catched by the b > 0 above */
-+      assert(r);
-+      b->used += r + 1;
-+      b->ptr[b->used - 1] = '\0';
+                               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);
+                               }
+-                      
 +
-+    return NETWORK_STATUS_SUCCESS;
-+}
+                               buffer_reset(con->physical.path);
+                               return HANDLER_FINISHED;
+                       case ENOENT:
+@@ -499,77 +512,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);
+-                              
 +
-+NETWORK_BACKEND_WRITE(write) {
-       chunk *c;
-       size_t chunks_written = 0;
-       
-@@ -44,19 +93,12 @@
-                       
-                       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;
-+                              return NETWORK_STATUS_FATAL_ERROR;
+                               log_error_write(srv, __FILE__, __LINE__, "ssbsb",
+                                               "file not found ... or so: ", strerror(errno),
+                                               con->uri.path,
+                                               "->", con->physical.path);
+-                              
++
+                               return HANDLER_FINISHED;
                        }
--#endif
-                       
-                       c->offset += r;
-                       cq->bytes_out += r;
-@@ -80,7 +122,7 @@
-                       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;
+-                      
++
+                       /* 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;
                        }
-                       
-                       offset = c->file.start + c->offset;
-@@ -89,13 +131,13 @@
-                       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;
+-                      
++
+                       /* 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 (-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 (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,12 +590,12 @@
+                               log_error_write(srv, __FILE__, __LINE__,  "sb", "Pathinfo     :", con->request.pathinfo);
                        }
-                       
- #if defined USE_MMAP
-@@ -104,14 +146,14 @@
-                               close(ifd);
-                               
--                              return -1;
-+                              return NETWORK_STATUS_FATAL_ERROR;
+               }
+-              
++
+               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)) {
+               case HANDLER_GO_ON:
+@@ -593,32 +606,32 @@
+                       if (con->conf.log_request_handling) {
+                               log_error_write(srv, __FILE__, __LINE__,  "s",  "-- subrequest finished");
                        }
-                       close(ifd);
+-                      
+-                      /* 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 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 */
++              /* request was not handled; looks like we are done */
+               return HANDLER_FINISHED;
+       case HANDLER_FINISHED:
+               /* request is finished */
+       default:
+-              /* something strange happend */
++              /* something strange happened */
+               return r;
+       }
+-      
++
+       /* can't happen */
+       return HANDLER_COMEBACK;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/server.c lighttpd-1.4.12/src/server.c
+--- lighttpd-1.4.11/src/server.c       2006-03-04 19:12:17.000000000 +0200
++++ lighttpd-1.4.12/src/server.c       2006-07-11 21:23:40.000000000 +0300
+@@ -1,11 +1,9 @@
+ #include <sys/types.h>
+-#include <sys/time.h>
+ #include <sys/stat.h>
  
-                       if ((r = write(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);
-@@ -123,14 +165,14 @@
-                               log_error_write(srv, __FILE__, __LINE__, "ss", "read: ", strerror(errno));
-                               close(ifd);
-                               
--                              return -1;
-+                              return NETWORK_STATUS_FATAL_ERROR;
-                       }
-                       close(ifd);
+ #include <string.h>
+ #include <errno.h>
+ #include <fcntl.h>
+-#include <unistd.h>
+ #include <stdlib.h>
+ #include <time.h>
+ #include <signal.h>
+@@ -29,9 +27,14 @@
+ #include "plugin.h"
+ #include "joblist.h"
+ #include "network_backends.h"
+-
++#ifdef _WIN32
++/* use local getopt implementation */
++# undef HAVE_GETOPT_H
++#endif
+ #ifdef HAVE_GETOPT_H
+ #include <getopt.h>
++#else
++#include "getopt.h"
+ #endif
  
-                       if (-1 == (r = send(fd, srv->tmp_buf->ptr, toSend, 0))) {
-                               log_error_write(srv, __FILE__, __LINE__, "ss", "write: ", strerror(errno));
-                               
--                              return -1;
-+                              return NETWORK_STATUS_FATAL_ERROR;
-                       }
+ #ifdef HAVE_VALGRIND_VALGRIND_H
+@@ -60,8 +63,16 @@
+ /* #define USE_ALARM */
  #endif
-                       c->offset += r;
-@@ -146,7 +188,7 @@
-                       
-                       log_error_write(srv, __FILE__, __LINE__, "ds", c, "type not known");
-                       
--                      return -1;
-+                      return NETWORK_STATUS_FATAL_ERROR;
-               }
-               
-               if (!chunk_finished) {
-@@ -158,11 +200,7 @@
-               chunks_written++;
-       }
  
--      return chunks_written;
-+      return NETWORK_STATUS_SUCCESS;
- }
++#ifdef _WIN32
++#undef HAVE_SIGNAL
++#endif
++
++#include "sys-files.h"
++#include "sys-process.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;
  
--#if 0
--network_write_init(void) {
--      p->write = network_write_write_chunkset;
--}
+@@ -72,9 +83,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 +97,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,25 +121,26 @@
+       signal(SIGTSTP, SIG_IGN);
  #endif
---- lighttpd-1.4.11/src/network_writev.c       2006-02-15 01:02:36.000000000 +0200
-+++ lighttpd/src/network_writev.c      2006-07-11 21:23:40.103856229 +0300
-@@ -51,22 +51,14 @@
- #define LOCAL_BUFFERING 1
+       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
  
--int network_write_chunkqueue_writev(server *srv, connection *con, int fd, chunkqueue *cq) {
--      chunk *c;
--      size_t chunks_written = 0;
+ static server *server_init(void) {
+       int i;
 -      
--      for(c = cq->first; c; c = c->next) {
--              int chunk_finished = 0;
--              
--              switch(c->type) {
--              case MEM_CHUNK: {
-+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;
-+      chunk *tc; /* transfer chunks */
-                       size_t num_bytes = 0;
-                       
-                       /* we can't send more then SSIZE_MAX bytes in one chunk */
-@@ -111,12 +103,12 @@
-                                       break;
-                               case EPIPE:
-                               case ECONNRESET:
--                                      return -2;
-+                      return NETWORK_STATUS_CONNECTION_CLOSE;
-                               default:
-                                       log_error_write(srv, __FILE__, __LINE__, "ssd", 
-                                                       "writev failed:", strerror(errno), fd);
-                               
--                                      return -1;
-+                      return NETWORK_STATUS_FATAL_ERROR;
-                               }
-                       }
-                       
-@@ -129,27 +121,49 @@
-                                       /* written */
-                                       r -= chunks[i].iov_len;
-                                       tc->offset += chunks[i].iov_len;
-+              } else {
-+                      /* partially written */
-                                       
-+                      tc->offset += r;
-+                      break;
-+              }
-+      }
 +
-+      return NETWORK_STATUS_SUCCESS;
-+}
+       server *srv = calloc(1, sizeof(*srv));
+       assert(srv);
++    srv->max_fds = 1024;
+ #define CLEAN(x) \
+       srv->x = buffer_init();
+-      
 +
-+NETWORK_BACKEND_WRITE(writev) {
-+      chunk *c, *tc;
-+      size_t chunks_written = 0;
+       CLEAN(response_header);
+       CLEAN(parse_full_path);
+       CLEAN(ts_debug_str);
+@@ -138,7 +150,7 @@
+       CLEAN(tmp_buf);
+       srv->empty_string = buffer_init_string("");
+       CLEAN(cond_check_buf);
+-      
 +
-+      for(c = cq->first; c; c = c->next) {
-+              int chunk_finished = 0;
-+              network_status_t ret;
+       CLEAN(srvconf.errorlog_file);
+       CLEAN(srvconf.groupname);
+       CLEAN(srvconf.username);
+@@ -146,58 +158,58 @@
+       CLEAN(srvconf.bindhost);
+       CLEAN(srvconf.event_handler);
+       CLEAN(srvconf.pid_file);
+-      
 +
-+              switch(c->type) {
-+              case MEM_CHUNK:
-+                      ret = network_write_chunkqueue_writev_mem(srv, con, fd, cq, c);
+       CLEAN(tmp_chunk_len);
+ #undef CLEAN
+-      
 +
-+                      /* 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;
-                               }
-                       }
-                       
--                      break;
-+                      if (ret != NETWORK_STATUS_SUCCESS) {
-+                              return ret;
-               }
+ #define CLEAN(x) \
+       srv->x = array_init();
+-      
 +
-+                      break;
-               case FILE_CHUNK: {
-                       ssize_t r;
-                       off_t abs_offset;
-@@ -165,7 +179,7 @@
-                       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;
-                       }
+       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;
  
-                       abs_offset = c->file.start + c->offset;
-@@ -174,7 +188,7 @@
-                               log_error_write(srv, __FILE__, __LINE__, "sb", 
-                                               "file was shrinked:", c->file.name);
-                               
--                              return -1;
-+                              return NETWORK_STATUS_FATAL_ERROR;
-                       }
+       srv->split_vals = array_init();
+-      
++
+       return srv;
+ }
  
-                       /* mmap the buffer 
-@@ -235,7 +249,7 @@
-                                       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);
-@@ -248,7 +262,7 @@
-                                       log_error_write(srv, __FILE__, __LINE__, "ssbd", "mmap failed:", 
-                                                       strerror(errno), c->file.name, c->file.fd);
+ 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);
+@@ -207,7 +219,7 @@
+       CLEAN(tmp_buf);
+       CLEAN(empty_string);
+       CLEAN(cond_check_buf);
+-      
++
+       CLEAN(srvconf.errorlog_file);
+       CLEAN(srvconf.groupname);
+       CLEAN(srvconf.username);
+@@ -217,7 +229,7 @@
+       CLEAN(srvconf.pid_file);
+       CLEAN(srvconf.modules_dir);
+       CLEAN(srvconf.network_backend);
+-      
++
+       CLEAN(tmp_chunk_len);
+ #undef CLEAN
  
--                                      return -1;
-+                                      return NETWORK_STATUS_FATAL_ERROR;
-                               }
+@@ -225,15 +237,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];
  
-                               c->file.mmap.length = to_mmap;
-@@ -297,12 +311,12 @@
-                                       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;
-+                                      return NETWORK_STATUS_FATAL_ERROR;
-                               }
-                       }
-                       
-@@ -325,7 +339,7 @@
-                       
-                       log_error_write(srv, __FILE__, __LINE__, "ds", c, "type not known");
-                       
--                      return -1;
-+                      return NETWORK_STATUS_FATAL_ERROR;
+                       if (!s) continue;
+-                      
++
+                       buffer_free(s->document_root);
+                       buffer_free(s->server_name);
+                       buffer_free(s->server_tag);
+@@ -242,32 +254,32 @@
+                       buffer_free(s->error_handler);
+                       buffer_free(s->errorfile_prefix);
+                       array_free(s->mimetypes);
+-                      
++
+                       free(s);
                }
-               
-               if (!chunk_finished) {
-@@ -337,7 +351,7 @@
-               chunks_written++;
+               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);
        }
  
--      return chunks_written;
-+      return NETWORK_STATUS_SUCCESS;
+       array_free(srv->srvconf.modules);
+       array_free(srv->split_vals);
+-      
++
+       free(srv);
+ }
+@@ -281,14 +293,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 +365,6 @@
+ #else
+       "\t- crypt support\n"
  #endif
---- lighttpd-1.4.11/src/plugin.c       2006-02-08 14:00:54.000000000 +0200
-+++ lighttpd/src/plugin.c      2006-07-11 21:23:40.067853974 +0300
-@@ -13,7 +13,7 @@
- #include <valgrind/valgrind.h>
+-#ifdef USE_PAM
+-      "\t+ PAM support\n"
+-#else
+-      "\t- PAM support\n"
+-#endif
+ #ifdef USE_OPENSSL
+       "\t+ SSL Support\n"
+ #else
+@@ -371,9 +376,9 @@
+       "\t- PCRE support\n"
  #endif
--#ifndef __WIN32
-+#ifndef _WIN32
- #include <dlfcn.h>
+ #ifdef HAVE_MYSQL
+-      "\t+ mySQL support\n"
++      "\t+ MySQL support\n"
+ #else
+-      "\t- mySQL support\n"
++      "\t- MySQL support\n"
  #endif
- /*
-@@ -56,19 +56,23 @@
-       
-       p = calloc(1, sizeof(*p));
-       
-+      p->required_plugins = array_init();
+ #if defined(HAVE_LDAP_H) && defined(HAVE_LBER_H) && defined(HAVE_LIBLDAP) && defined(HAVE_LIBLBER)
+       "\t+ LDAP support\n"
+@@ -410,8 +415,11 @@
+ #else
+       "\t- GDBM support\n"
+ #endif
+-      "\n"
+-      );
++      "\n";
 +
-       return p;
++  show_version();
++
++  printf("\nEvent Handlers:\n\n%s", s);
  }
  
- 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
+ static void show_help (void) {
+@@ -433,12 +441,12 @@
+ " -h         show this help\n" \
+ "\n"
+ ;
+-#undef TEXT_SSL       
++#undef TEXT_SSL
+ #undef TEXT_IPV6
+       write(STDOUT_FILENO, b, strlen(b));
+ }
  
- #ifndef LIGHTTPD_STATIC
-       if (use_dlclose && p->lib) {    
--#ifdef __WIN32
-+#ifdef _WIN32
-               FreeLibrary(p->lib);
- #else
-               dlclose(p->lib);
-@@ -121,9 +125,14 @@
- #else
- int plugins_load(server *srv) {
-       plugin *p;
+-int main (int argc, char **argv) {
++int main (int argc, char **argv, char **envp) {
+       server *srv = NULL;
+       int print_config = 0;
+       int test_config = 0;
+@@ -447,33 +455,37 @@
+       int num_childs = 0;
+       int pid_fd = -1, fd;
+       size_t i;
 +#ifdef _WIN32
-+    FARPROC init;
-+#else
-       int (*init)(plugin *pl);
++      char *optarg = NULL;
 +#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];
-@@ -133,14 +142,14 @@
-               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");
+ #ifdef HAVE_SIGACTION
+       struct sigaction act;
  #endif
-       
-               p = plugin_init();
--#ifdef __WIN32
-+#ifdef _WIN32
-               if (NULL == (p->lib = LoadLibrary(srv->tmp_buf->ptr))) {
-                       LPVOID lpMsgBuf;
-                       FormatMessage(
-@@ -175,7 +184,7 @@
-               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)  {
-@@ -218,6 +227,25 @@
- #if 0
-               log_error_write(srv, __FILE__, __LINE__, "ss", modules, "plugin loaded" );
+ #ifdef HAVE_GETRLIMIT
+       struct rlimit rlim;
  #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];
+ #ifdef USE_ALARM
+       struct itimerval interval;
+-      
 +
-+                              if (buffer_is_equal(req->value, mod->value)) break;
-+                      }
+       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
+-      
+-      
 +
-+                      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);
+       /* for nice %b handling in strfime() */
+       setlocale(LC_TIME, "C");
+-      
++
+       if (NULL == (srv = server_init())) {
+               fprintf(stderr, "did this really happen?\n");
+               return -1;
        }
-       
-@@ -426,6 +454,23 @@
-       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];
+       /* init structs done */
+-      
 +
-+              if (buffer_is_equal_string(p->name, name, strlen(name))) {
-+                      return p->data;
-+              }
-+      }
+       srv->srvconf.port = 0;
+ #ifdef HAVE_GETUID
+       i_am_root = (getuid() == 0);
+@@ -481,14 +493,19 @@
+       i_am_root = 0;
+ #endif
+       srv->srvconf.dont_daemonize = 0;
+-      
 +
-+      return NULL;
-+}
+       while(-1 != (o = getopt(argc, argv, "f:m:hvVDpt"))) {
+               switch(o) {
+-              case 'f': 
+-                      if (config_read(srv, optarg)) { 
++              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;
+                       }
 +
- void plugins_free(server *srv) {
-       size_t i;
-       plugins_call_cleanup(srv);
---- lighttpd-1.4.11/src/plugin.h       2005-08-15 12:28:56.000000000 +0300
-+++ lighttpd/src/plugin.h      2006-07-11 21:23:40.075854475 +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
-@@ -59,6 +65,8 @@
-       
-       /* dlopen handle */
-       void *lib;
+                       break;
+               case 'm':
+                       buffer_copy_string(srv->srvconf.modules_dir, optarg);
+@@ -497,23 +514,23 @@
+               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 'V': show_features(); return 0;
+               case 'h': show_help(); return 0;
+-              default: 
++              default:
+                       show_help();
+                       server_free(srv);
+                       return -1;
+               }
+       }
+-      
 +
-+      array *required_plugins;
- } plugin;
- int plugins_load(server *srv);
-@@ -88,5 +96,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);
+       if (!srv->config_storage) {
+               log_error_write(srv, __FILE__, __LINE__, "s",
+                               "No configuration available. Try using -f option.");
+-              
 +
-+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/src/proc_open.c   2006-07-11 21:23:40.283867504 +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);
+               server_free(srv);
+               return -1;
+       }
+-      
++
+       if (print_config) {
+               data_unset *dc = srv->config_context->data[0];
+               if (dc) {
+@@ -533,7 +550,7 @@
+               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))) {
+@@ -541,54 +558,55 @@
+               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", 
++              log_error_write(srv, __FILE__, __LINE__, "s",
+                               "setting default values failed");
+               server_free(srv);
                return -1;
        }
-@@ -177,17 +180,23 @@
-       memset(&pi, 0, sizeof(pi));
-       cmdline = buffer_init();
-+      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);
+-      
++
+       /* UID handling */
+ #ifdef HAVE_GETUID
+       if (!i_am_root && (geteuid() == 0 || getegid() == 0)) {
+               /* we are setuid-root */
+-              
+-              log_error_write(srv, __FILE__, __LINE__, "s", 
++
++              log_error_write(srv, __FILE__, __LINE__, "s",
+                               "Are you nuts ? Don't apply a SUID bit to this binary");
+-              
++
+               server_free(srv);
                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";
+ #endif
+-      
++
+       /* check document-root */
+       if (srv->config_storage[0]->document_root->used <= 1) {
+-              log_error_write(srv, __FILE__, __LINE__, "s", 
++              log_error_write(srv, __FILE__, __LINE__, "s",
+                               "document-root is not set\n");
+-              
++
+               server_free(srv);
+-              
++
+               return -1;
        }
-       if (proc_open_pipes(proc) != 0) {
-@@ -262,11 +270,11 @@
+-      
++
+       if (plugins_load(srv)) {
+               log_error_write(srv, __FILE__, __LINE__, "s",
+                               "loading plugins finally failed");
+-              
++
+               plugins_free(srv);
+               server_free(srv);
+-              
++
+               return -1;
        }
- }
- /* }}} */
--#endif /* WIN32 */
-+#endif /* _WIN32 */
+-      
++
++#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))) {
+@@ -598,18 +616,18 @@
+                                       "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));
+@@ -617,13 +635,14 @@
+                       }
+               }
+       }
+-
++#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 +655,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 +663,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 +678,7 @@
+                       }
+               }
  
- /* {{{ 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 */
+-              /* #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;
  
-       for (;;) {
-               buffer_prepare_append(b, 512);
---- lighttpd-1.4.11/src/proc_open.h    2005-08-11 01:26:39.000000000 +0300
-+++ lighttpd/src/proc_open.h   2006-07-11 21:23:40.287867754 +0300
-@@ -1,7 +1,7 @@
+               if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
+@@ -677,33 +696,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;
+                       }
+               }
  
- #include "buffer.h"
+-              
++
+ #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 +732,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();
  
--#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/src/request.c     2006-07-11 21:23:40.035851970 +0300
-@@ -10,6 +10,8 @@
- #include "keyvalue.h"
- #include "log.h"
+@@ -761,7 +780,7 @@
+               }
  
-+#include "sys-strings.h"
+               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 +794,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;
+                       }
+               }
+-              
 +
- static int request_check_hostname(server *srv, connection *con, buffer *host) {
-       enum { DOMAINLABEL, TOPLABEL } stage = TOPLABEL;
-       size_t i;
-@@ -413,7 +415,7 @@
-                                       }
+               if (0 != network_init(srv)) {
+                       plugins_free(srv);
+                       server_free(srv);
+-                      
++
+                       return -1;
+               }
+       }
+@@ -802,25 +821,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;
+       }
  
-                                       if (major_num == 1 && minor_num == 1) {
--                                              con->request.http_version = con->conf.allow_http11 ? HTTP_VERSION_1_1 : HTTP_VERSION_1_0;
-+                                              con->request.http_version = HTTP_VERSION_1_1;
-                                       } else if (major_num == 1 && minor_num == 0) {
-                                               con->request.http_version = HTTP_VERSION_1_0;
-                                       } else { 
-@@ -797,6 +799,7 @@
-                                                                                               "request-header:\n",
-                                                                                               con->request.request);
-                                                                       }
-+                                                                      ds->free((data_unset *) ds);
-                                                                       return 0;
-                                                               }
-                                                               
-@@ -846,6 +849,7 @@
-                                                                                               "request-header:\n",
-                                                                                               con->request.request);
-                                                                       }
-+                                                                      ds->free((data_unset *) ds);
-                                                                       return 0;
-                                                               }
-                                                       } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Expect")))) {
-@@ -883,6 +887,7 @@
-                                                                                               "request-header:\n",
-                                                                                               con->request.request);
-                                                                       }
-+                                                                      ds->free((data_unset *) ds);
-                                                                       return 0;
-                                                               }
-                                                       } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("If-Modified-Since")))) {
-@@ -905,6 +910,7 @@
-                                                                                               "request-header:\n",
-                                                                                               con->request.request);
-                                                                       }
-+                                                                      ds->free((data_unset *) ds);
-                                                                       return 0;
-                                                               }
-                                                       } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("If-None-Match")))) {
-@@ -922,6 +928,7 @@
-                                                                                               "request-header:\n",
-                                                                                               con->request.request);
-                                                                       }
-+                                                                      ds->free((data_unset *) ds);
-                                                                       return 0;
-                                                               }
-                                                       } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Range")))) {
-@@ -945,6 +952,7 @@
-                                                                                               "request-header:\n",
-                                                                                               con->request.request);
-                                                                       }
-+                                                                      ds->free((data_unset *) ds);
-                                                                       return 0;
-                                                               }
-                                                       }
---- lighttpd-1.4.11/src/response.c     2006-03-04 16:41:39.000000000 +0200
-+++ lighttpd/src/response.c    2006-07-11 21:23:40.067853974 +0300
-@@ -7,7 +7,6 @@
- #include <stdlib.h>
- #include <string.h>
- #include <time.h>
--#include <unistd.h>
- #include <ctype.h>
- #include <assert.h>
+-#ifdef HAVE_FORK      
++#ifdef HAVE_FORK
+       /* network is up, let's deamonize ourself */
+       if (srv->srvconf.dont_daemonize == 0) daemonize();
+ #endif
  
-@@ -24,6 +23,8 @@
- #include "plugin.h"
++#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 +850,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 +868,42 @@
  
- #include "sys-socket.h"
-+#include "sys-files.h"
-+#include "sys-strings.h"
+               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;
+                       }
  
- int http_response_write_header(server *srv, connection *con) {
-       buffer *b;
-@@ -59,7 +60,8 @@
-               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;
+                       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) {
+-              log_error_write(srv, __FILE__, __LINE__, "s", 
++              log_error_write(srv, __FILE__, __LINE__, "s",
+                               "Configuration contains deprecated keys. Going down.");
+-              
++
+               plugins_free(srv);
+               network_close(srv);
+               server_free(srv);
+-              
++
+               return -1;
+       }
+-      
++
+       if (-1 == log_error_open(srv)) {
+-              log_error_write(srv, __FILE__, __LINE__, "s", 
++              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 +923,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 +934,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
  
-@@ -119,7 +121,7 @@
- handler_t http_response_prepare(server *srv, connection *con) {
-       handler_t r;
-       
--      /* looks like someone has already done a decision */
-+      /* 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 */
-@@ -134,7 +136,7 @@
-       if (con->mode == DIRECT && con->physical.path->used == 0) {
-               char *qstr;
+-#ifdef HAVE_FORK      
++#ifdef HAVE_FORK
+       /* start watcher and workers */
+       num_childs = srv->srvconf.max_worker;
+       if (num_childs > 0) {
+@@ -957,13 +977,13 @@
+       }
+ #endif
  
--              /* we only come here when we have the parse the full request again
-+              /* 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
-@@ -262,6 +264,11 @@
-               
-               config_patch_connection(srv, con, COMP_HTTP_URL); /* HTTPurl */
-               
-+              /* do we have to downgrade to 1.0 ? */
-+              if (!con->conf.allow_http11) {
-+                      con->request.http_version = HTTP_VERSION_1_0;
-+              }
+-      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 +991,7 @@
+               plugins_free(srv);
+               network_close(srv);
+               server_free(srv);
+-              
 +
-               switch(r = plugins_call_handle_uri_clean(srv, con)) {
-               case HANDLER_GO_ON:
-                       break;
-@@ -277,7 +284,7 @@
-               
-               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"));
+               return -1;
+       }
  
-@@ -320,14 +327,15 @@
-               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
-@@ -378,15 +386,14 @@
-                       break;
+@@ -986,7 +1006,7 @@
+       /* 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;
                }
-               
--              /* 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);
+@@ -1018,16 +1038,40 @@
+               int n;
+               size_t ndx;
+               time_t min_ts;
+-              
++
+               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 */
++                      }
++#else
+                       /* cycle logfiles */
+-                      
++
+                       switch(r = plugins_call_handle_sighup(srv)) {
+                       case HANDLER_GO_ON:
+                               break;
+@@ -1035,30 +1079,31 @@
+                               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;
+                       }
++#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;
+@@ -1069,21 +1114,21 @@
+                                       log_error_write(srv, __FILE__, __LINE__, "d", r);
+                                       break;
+                               }
+-                              
++
+                               /* trigger waitpid */
+                               srv->cur_ts = min_ts;
+-                      
+-                              /* cleanup stat-cache */        
++
++                              /* cleanup stat-cache */
+                               stat_cache_trigger_cleanup(srv);
+                               /**
+-                               * check all connections for timeouts 
+-                               * 
++                               * 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 ||
+@@ -1092,7 +1137,7 @@
+                                                       if (srv->cur_ts - con->read_idle_ts > con->conf.max_read_idle) {
+                                                               /* time - out */
+ #if 0
+-                                                              log_error_write(srv, __FILE__, __LINE__, "sd", 
++                                                              log_error_write(srv, __FILE__, __LINE__, "sd",
+                                                                               "connection closed - read-timeout:", con->fd);
+ #endif
+                                                               connection_set_state(srv, con, CON_STATE_ERROR);
+@@ -1102,7 +1147,7 @@
+                                                       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", 
++                                                              log_error_write(srv, __FILE__, __LINE__, "sd",
+                                                                               "connection closed - read-timeout:", con->fd);
+ #endif
+                                                               connection_set_state(srv, con, CON_STATE_ERROR);
+@@ -1110,20 +1155,20 @@
+                                                       }
+                                               }
+                                       }
+-                                      
++
+                                       if ((con->state == CON_STATE_WRITE) &&
+-                                          (con->write_request_ts != 0)) { 
++                                          (con->write_request_ts != 0)) {
+ #if 0
+                                               if (srv->cur_ts - con->write_request_ts > 60) {
+-                                                      log_error_write(srv, __FILE__, __LINE__, "sdd", 
++                                                      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", 
++                                                      log_error_write(srv, __FILE__, __LINE__, "sbsosds",
+                                                                       "NOTE: a request for",
+                                                                       con->request.uri,
+                                                                       "timed out after writing",
+@@ -1138,35 +1183,35 @@
+                                       }
+                                       /* 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 || 
++
++                                      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");
+                       }
                }
+@@ -1181,18 +1226,18 @@
+                                       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 */ 
++                          (graceful_shutdown)) { /* graceful_shutdown */
  
--              /* 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);
+                               /* 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);
+@@ -1211,7 +1256,7 @@
+                                               /* 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) {
+@@ -1219,7 +1264,7 @@
+                               } else {
+                                       log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, out-of-fds");
+                               }
+-                      
++
+                               srv->sockets_disabled = 1;
+                       }
                }
-@@ -398,15 +405,21 @@
-                */
-               
-               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);
+@@ -1229,16 +1274,16 @@
+                        * we are ready to terminate without harming anyone */
+                       srv_shutdown = 1;
                }
-+        /* 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);
-@@ -436,7 +449,7 @@
-       }
-       
-       /* 
--       * 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)
-        * 
-        * Go on and check of the file exists at all
-        */
-@@ -461,7 +474,7 @@
+               /* we still have some fds to share */
+-              if (srv->want_fds) { 
++              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 (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);
-@@ -499,7 +512,7 @@
-                               /* PATH_INFO ! :) */
+               }
+@@ -1249,27 +1294,27 @@
+                       int fd_ndx;
+ #if 0
+                       if (n > 0) {
+-                              log_error_write(srv, __FILE__, __LINE__, "sd", 
++                              log_error_write(srv, __FILE__, __LINE__, "sd",
+                                               "polls:", n);
+                       }
+-#endif                        
++#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", 
++                              log_error_write(srv, __FILE__, __LINE__, "sdd",
+                                               "event for", fd, revents);
+-#endif                                
++#endif
+                               switch (r = (*handler)(srv, context, revents)) {
+                               case HANDLER_FINISHED:
+                               case HANDLER_GO_ON:
+@@ -1286,17 +1331,17 @@
+                               }
+                       } while (--n > 0);
+               } else if (n < 0 && errno != EINTR) {
+-                      log_error_write(srv, __FILE__, __LINE__, "ss", 
+-                                      "fdevent_poll failed:", 
++                      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:
+@@ -1305,32 +1350,33 @@
+                               log_error_write(srv, __FILE__, __LINE__, "d", r);
                                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);
-                               
-@@ -544,7 +557,7 @@
-                       } 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) {
-@@ -594,11 +607,11 @@
-                               log_error_write(srv, __FILE__, __LINE__,  "s",  "-- subrequest finished");
                        }
-                       
--                      /* something strange happend */
-+                      /* something strange happened */
-                       return r;
+-                      
++
+                       con->in_joblist = 0;
                }
-               
--              /* if we are still here, no one wanted the file, status 403 is ok I think */
-+              /* if we are still here, no one wanted the file; status 403 is ok I think */
-               
-               if (con->mode == DIRECT) {
-                       con->http_status = 403;
-@@ -610,12 +623,12 @@
-       
-       switch(r = plugins_call_handle_subrequest(srv, con)) {
-       case HANDLER_GO_ON:
--              /* request was not handled, looks like we are done */
-+              /* request was not handled; looks like we are done */
-               return HANDLER_FINISHED;
-       case HANDLER_FINISHED:
-               /* request is finished */
-       default:
--              /* something strange happend */
-+              /* something strange happened */
-               return r;
+-              
++
+               srv->joblist->used = 0;
        }
-       
---- lighttpd-1.4.11/src/server.c       2006-03-04 19:12:17.000000000 +0200
-+++ lighttpd/src/server.c      2006-07-11 21:23:40.247865249 +0300
-@@ -1,11 +1,9 @@
+-      
+-      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);
+-      
++
+       return 0;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/settings.h lighttpd-1.4.12/src/settings.h
+--- lighttpd-1.4.11/src/settings.h     2005-08-11 01:26:41.000000000 +0300
++++ lighttpd-1.4.12/src/settings.h     2006-07-11 21:23:40.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;
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/spawn-fcgi.c lighttpd-1.4.12/src/spawn-fcgi.c
+--- lighttpd-1.4.11/src/spawn-fcgi.c   2006-03-07 14:18:10.000000000 +0200
++++ lighttpd-1.4.12/src/spawn-fcgi.c   2006-07-11 21:23:40.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 <fcntl.h>
+ #include <stdio.h>
 -#include <unistd.h>
- #include <stdlib.h>
- #include <time.h>
- #include <signal.h>
-@@ -29,9 +27,14 @@
- #include "plugin.h"
- #include "joblist.h"
- #include "network_backends.h"
+ #include <fcntl.h>
 -
-+#ifdef _WIN32
-+/* use local getopt implementation */
-+# undef HAVE_GETOPT_H
-+#endif
- #ifdef HAVE_GETOPT_H
- #include <getopt.h>
-+#else
-+#include "getopt.h"
++#include <time.h>
+ #ifdef HAVE_CONFIG_H
+ #include "config.h"
  #endif
  
- #ifdef HAVE_VALGRIND_VALGRIND_H
-@@ -60,8 +63,16 @@
- /* #define USE_ALARM */
+-
+ #ifdef HAVE_PWD_H
+ #include <grp.h>
+ #include <pwd.h>
+@@ -30,6 +27,7 @@
  #endif
  
-+#ifdef _WIN32
-+#undef HAVE_SIGNAL
-+#endif
-+
+ #include "sys-socket.h"
 +#include "sys-files.h"
-+#include "sys-process.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;
-@@ -126,6 +137,7 @@
-       
-       server *srv = calloc(1, sizeof(*srv));
-       assert(srv);
-+    srv->max_fds = 1024;
- #define CLEAN(x) \
-       srv->x = buffer_init();
-       
-@@ -286,9 +298,7 @@
- }
  
- 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 +365,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 +376,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 +415,11 @@
+ #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
-       "\t- GDBM support\n"
- #endif
--      "\n"
--      );
-+      "\n";
+@@ -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;
+       }
+-      
 +
-+  show_version();
+       if (-1 == (fcgi_fd = socket(socket_type, SOCK_STREAM, 0))) {
+-              fprintf(stderr, "%s.%d\n", 
++              fprintf(stderr, "%s.%d\n",
+                       __FILE__, __LINE__);
+               return -1;
+       }
+-      
 +
-+  printf("\nEvent Handlers:\n\n%s", s);
- }
+       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;
+               }
  
- static void show_help (void) {
-@@ -438,7 +446,7 @@
-       write(STDOUT_FILENO, b, strlen(b));
- }
+               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;
+               }
  
--int main (int argc, char **argv) {
-+int main (int argc, char **argv, char **envp) {
-       server *srv = NULL;
-       int print_config = 0;
-       int test_config = 0;
-@@ -447,6 +455,10 @@
-       int num_childs = 0;
-       int pid_fd = -1, fd;
-       size_t i;
-+#ifdef _WIN32
-+      char *optarg = NULL;
-+#endif
+               /* 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;
+               }
+-              
 +
- #ifdef HAVE_SIGACTION
-       struct sigaction act;
- #endif
-@@ -485,10 +497,15 @@
-       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;
+               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 'm':
-                       buffer_copy_string(srv->srvconf.modules_dir, optarg);
-@@ -589,6 +606,7 @@
-               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))) {
-@@ -617,13 +635,14 @@
+               }
+               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;
                }
-       }
--
-+#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;
+@@ -228,16 +229,16 @@
+                       __FILE__, __LINE__);
+               return -1;
        }
-@@ -761,7 +780,7 @@
-               }
+-      
++
+       close(fcgi_fd);
+-      
++
+       return 0;
+ }
  
-               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,9 +794,9 @@
- #endif
-               if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
-                       /* don't raise the limit above FD_SET_SIZE */
--                      if (srv->max_fds > 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 - 200,
-+                                              "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;
-                       }
-@@ -818,8 +837,10 @@
-       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) {
-@@ -883,7 +904,6 @@
+ 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;
        }
-       
 -      
- #ifdef HAVE_SIGACTION
-       memset(&act, 0, sizeof(act));
-       act.sa_handler = SIG_IGN;
-@@ -957,7 +977,7 @@
++
+       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;
        }
- #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");
+       /* 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;
-@@ -1025,7 +1045,31 @@
-                       /* 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);
+       }
+-      
+-      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));
+-                      
 +
-+                              exit(-1);
-+                      } else if (pid == -1) {
+                       return -1;
+               }
+-              
 +
-+                      } else {
-+                              /* parent */
+               /* 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;
+                       }
+               }
+-              
 +
-+                              graceful_shutdown = 1; /* shutdown without killing running connections */
-+                              graceful_restart = 1;  /* don't delete pid file */
-+                      }
-+#else
-                       /* cycle logfiles */
-                       
-                       switch(r = plugins_call_handle_sighup(srv)) {
-@@ -1041,6 +1085,7 @@
-                               
+               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;
                        }
-+#endif
                }
-               
-               if (handle_sig_alarm) {
-@@ -1312,7 +1357,8 @@
-               srv->joblist->used = 0;
+-              
++
+               /* drop root privs */
+               if (groupname) {
+                       setgid(grp->gr_gid);
+@@ -428,7 +429,7 @@
+               }
+               if (username) setuid(pwd->pw_uid);
        }
-       
--      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) {
---- lighttpd-1.4.11/src/spawn-fcgi.c   2006-03-07 14:18:10.000000000 +0200
-+++ lighttpd/src/spawn-fcgi.c  2006-07-11 21:23:40.167860238 +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
+-      
++
+        return fcgi_spawn_connection(fcgi_app, addr, port, unixsocket, child_count, pid_fd, nofork);
+ }
+ #else
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/splaytree.c lighttpd-1.4.12/src/splaytree.c
+--- lighttpd-1.4.11/src/splaytree.c    2005-09-12 21:51:28.000000000 +0300
++++ lighttpd-1.4.12/src/splaytree.c    2006-07-11 21:23:39.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;
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/splaytree.h lighttpd-1.4.12/src/splaytree.h
+--- lighttpd-1.4.11/src/splaytree.h    2005-09-12 21:51:13.000000000 +0300
++++ lighttpd-1.4.12/src/splaytree.h    2006-07-11 21:23:40.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.  */
+- 
++
  
--
- #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>
-@@ -145,6 +143,9 @@
-                       
-                       int i = 0;
-                       
-+                      /* loose control terminal */
-+                      setsid();
-+
-                       /* is save as we limit to 256 childs */
-                       sprintf(cgi_childs, "PHP_FCGI_CHILDREN=%d", child_count);
-                       
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/stat_cache.c lighttpd-1.4.12/src/stat_cache.c
 --- lighttpd-1.4.11/src/stat_cache.c   2005-11-22 15:23:51.000000000 +0200
-+++ lighttpd/src/stat_cache.c  2006-07-11 21:23:40.067853974 +0300
++++ lighttpd-1.4.12/src/stat_cache.c   2006-07-11 21:23:40.000000000 +0300
 @@ -6,7 +6,6 @@
  #include <stdlib.h>
  #include <string.h>
 +#include "sys-files.h"
 +#include "sys-strings.h"
  
- #if 0
- /* enables debug code for testing if all nodes in the stat-cache as accessable */
+ #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,15 @@
+ 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));
+ #endif
+-#ifdef DEBUG_STAT_CACHE       
++#ifdef DEBUG_STAT_CACHE
+       ctrl.size = 0;
+ #endif
+@@ -122,24 +110,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 +136,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 +162,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 +175,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 {
+@@ -212,7 +200,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 +239,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 +268,7 @@
+                               sc->dirs = splaytree_splay(sc->dirs, ndx);
+                               node = sc->dirs;
+-                      
++
+                               if (node && (node->key == ndx)) {
+                                       int osize = splaytree_size(sc->dirs);
+@@ -308,7 +296,7 @@
+               sc->fam = NULL;
+       }
+-      
++
+       return HANDLER_GO_ON;
+ }
+@@ -332,7 +320,7 @@
+  *
+  *
+  *
+- * 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 +336,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 +354,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 +378,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 +388,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 +412,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,7 +436,7 @@
+ #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
+        *
+@@ -469,16 +457,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 +487,29 @@
+       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;
+       }
+-      if (S_ISREG(st.st_mode)) {      
++      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 */
+@@ -539,7 +527,7 @@
+               }
+ #endif
+       }
+-              
++
+ #ifdef HAVE_FAM_H
+       if (sc->fam &&
+           (srv->srvconf.stat_cache_engine == STAT_CACHE_ENGINE_FAM)) {
+@@ -549,19 +537,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 +558,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 +566,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 +582,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 +627,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 +637,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];
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/stream.c lighttpd-1.4.12/src/stream.c
 --- lighttpd-1.4.11/src/stream.c       2005-09-23 21:50:15.000000000 +0300
-+++ lighttpd/src/stream.c      2006-07-11 21:23:40.215863244 +0300
++++ lighttpd-1.4.12/src/stream.c       2006-07-11 21:23:40.000000000 +0300
 @@ -1,7 +1,6 @@
  #include <sys/types.h>
  #include <sys/stat.h>
  
  #ifndef O_BINARY
  # define O_BINARY 0
-@@ -19,7 +19,7 @@
+@@ -19,39 +19,39 @@
        struct stat st;
  #ifdef HAVE_MMAP
        int fd;
        HANDLE *fh, *mh;
        void *p;
  #endif
-@@ -45,7 +45,7 @@
+       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, 
++      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;
+ }
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/sys-mmap.h lighttpd-1.4.12/src/sys-mmap.h
 --- lighttpd-1.4.11/src/sys-mmap.h     2005-08-11 01:26:34.000000000 +0300
-+++ lighttpd/src/sys-mmap.h    2006-07-11 21:23:40.051852972 +0300
++++ lighttpd-1.4.12/src/sys-mmap.h     2006-07-11 21:23:40.000000000 +0300
 @@ -1,7 +1,7 @@
  #ifndef WIN32_MMAP_H
  #define WIN32_MMAP_H
  
  #define MAP_FAILED -1
  #define PROT_SHARED 0
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/sys-socket.h lighttpd-1.4.12/src/sys-socket.h
 --- lighttpd-1.4.11/src/sys-socket.h   2005-08-11 01:26:39.000000000 +0300
-+++ lighttpd/src/sys-socket.h  2006-07-11 21:23:40.051852972 +0300
++++ lighttpd-1.4.12/src/sys-socket.h   2006-07-11 21:23:40.000000000 +0300
 @@ -1,15 +1,26 @@
  #ifndef WIN32_SOCKET_H
  #define WIN32_SOCKET_H
  #include <netdb.h>
  #endif
  
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/LightyTest.pm lighttpd-1.4.12/tests/LightyTest.pm
 --- lighttpd-1.4.11/tests/LightyTest.pm        2006-01-14 20:32:31.000000000 +0200
-+++ lighttpd/tests/LightyTest.pm       2006-07-11 21:23:42.047977994 +0300
++++ lighttpd-1.4.12/tests/LightyTest.pm        2006-07-11 21:23:42.000000000 +0300
 @@ -87,14 +87,14 @@
        # pre-process configfile if necessary
        #
                # check length
                if (defined $resp_hdr{"content-length"}) {
                        $resp_body = substr($lines, 0, $resp_hdr{"content-length"});
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/Makefile.am lighttpd-1.4.12/tests/Makefile.am
 --- lighttpd-1.4.11/tests/Makefile.am  2005-09-16 15:48:40.000000000 +0300
-+++ lighttpd/tests/Makefile.am 2006-07-11 21:23:42.039977492 +0300
++++ lighttpd-1.4.12/tests/Makefile.am  2006-07-11 21:23:42.000000000 +0300
 @@ -39,10 +39,15 @@
        mod-redirect.t \
        mod-userdir.t \
  
  
  TESTS_ENVIRONMENT=$(srcdir)/wrapper.sh $(srcdir) $(top_builddir) 
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/Makefile.in lighttpd-1.4.12/tests/Makefile.in
+--- lighttpd-1.4.11/tests/Makefile.in  2006-03-07 14:21:03.000000000 +0200
++++ lighttpd-1.4.12/tests/Makefile.in  2006-07-11 21:48:14.000000000 +0300
+@@ -1,4 +1,4 @@
+-# Makefile.in generated by automake 1.9.5 from Makefile.am.
++# Makefile.in generated by automake 1.9.6 from Makefile.am.
+ # @configure_input@
+ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+@@ -13,8 +13,6 @@
+ # PARTICULAR PURPOSE.
+ @SET_MAKE@
+-SOURCES = $(fcgi_auth_SOURCES) $(fcgi_responder_SOURCES)
+-
+ srcdir = @srcdir@
+ top_srcdir = @top_srcdir@
+ VPATH = @srcdir@
+@@ -46,7 +44,7 @@
+ am__aclocal_m4_deps = $(top_srcdir)/configure.in
+ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+       $(ACLOCAL_M4)
+-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
++mkinstalldirs = $(install_sh) -d
+ CONFIG_HEADER = $(top_builddir)/config.h
+ CONFIG_CLEAN_FILES =
+ am__fcgi_auth_SOURCES_DIST = fcgi-auth.c
+@@ -67,8 +65,8 @@
+       $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+       $(AM_CFLAGS) $(CFLAGS)
+ CCLD = $(CC)
+-LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+-      $(AM_LDFLAGS) $(LDFLAGS) -o $@
++LINK = $(LIBTOOL) --tag=CC --mode=link "$(CCLD)" $(AM_CFLAGS) \
++      $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+ SOURCES = $(fcgi_auth_SOURCES) $(fcgi_responder_SOURCES)
+ DIST_SOURCES = $(am__fcgi_auth_SOURCES_DIST) \
+       $(am__fcgi_responder_SOURCES_DIST)
+@@ -134,7 +132,6 @@
+ LIBTOOL = @LIBTOOL@
+ LN_S = @LN_S@
+ LTLIBOBJS = @LTLIBOBJS@
+-LUACONFIG = @LUACONFIG@
+ LUA_CFLAGS = @LUA_CFLAGS@
+ LUA_LIBS = @LUA_LIBS@
+ MAINT = @MAINT@
+@@ -177,6 +174,7 @@
+ ac_ct_F77 = @ac_ct_F77@
+ ac_ct_RANLIB = @ac_ct_RANLIB@
+ ac_ct_STRIP = @ac_ct_STRIP@
++ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@
+ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+@@ -253,10 +251,15 @@
+       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
+ TESTS_ENVIRONMENT = $(srcdir)/wrapper.sh $(srcdir) $(top_builddir) 
+ EXTRA_DIST = wrapper.sh lighttpd.conf \
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/bug-06.conf lighttpd-1.4.12/tests/bug-06.conf
 --- lighttpd-1.4.11/tests/bug-06.conf  2005-08-27 17:44:19.000000000 +0300
-+++ lighttpd/tests/bug-06.conf 2006-07-11 21:23:41.915969726 +0300
++++ lighttpd-1.4.12/tests/bug-06.conf  2006-07-11 21:23:41.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.name = "zzz.example.org"
  }
  
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/bug-12.conf lighttpd-1.4.12/tests/bug-12.conf
 --- lighttpd-1.4.11/tests/bug-12.conf  2005-08-27 17:44:19.000000000 +0300
-+++ lighttpd/tests/bug-12.conf 2006-07-11 21:23:41.907969224 +0300
++++ lighttpd-1.4.12/tests/bug-12.conf  2006-07-11 21:23:41.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.name = "zzz.example.org"
  }
  
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/cachable.t lighttpd-1.4.12/tests/cachable.t
+--- lighttpd-1.4.11/tests/cachable.t   1970-01-01 03:00:00.000000000 +0300
++++ lighttpd-1.4.12/tests/cachable.t   2006-07-11 21:23:41.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 } ];
++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 } ];
++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");
++
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/condition.conf lighttpd-1.4.12/tests/condition.conf
 --- lighttpd-1.4.11/tests/condition.conf       2005-08-27 17:44:19.000000000 +0300
-+++ lighttpd/tests/condition.conf      2006-07-11 21:23:41.951971980 +0300
++++ lighttpd-1.4.12/tests/condition.conf       2006-07-11 21:23:41.000000000 +0300
 @@ -2,15 +2,15 @@
  debug.log-request-handling = "enable"
  debug.log-condition-handling = "enable"
    server.name = "test3.example.org"
    url.redirect = ("^" => "/match_4")
  
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/core-keepalive.t lighttpd-1.4.12/tests/core-keepalive.t
 --- lighttpd-1.4.11/tests/core-keepalive.t     2005-11-17 15:54:19.000000000 +0200
-+++ lighttpd/tests/core-keepalive.t    2006-07-11 21:23:41.939971229 +0300
++++ lighttpd-1.4.12/tests/core-keepalive.t     2006-07-11 21:23:41.000000000 +0300
 @@ -40,7 +40,7 @@
  
  GET /12345.txt HTTP/1.0
  EOF
   );
  $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } , { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/docroot/123/Makefile.in lighttpd-1.4.12/tests/docroot/123/Makefile.in
+--- lighttpd-1.4.11/tests/docroot/123/Makefile.in      2006-03-07 14:21:03.000000000 +0200
++++ lighttpd-1.4.12/tests/docroot/123/Makefile.in      2006-07-11 21:48:15.000000000 +0300
+@@ -1,4 +1,4 @@
+-# Makefile.in generated by automake 1.9.5 from Makefile.am.
++# Makefile.in generated by automake 1.9.6 from Makefile.am.
+ # @configure_input@
+ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+@@ -42,7 +42,7 @@
+ am__aclocal_m4_deps = $(top_srcdir)/configure.in
+ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+       $(ACLOCAL_M4)
+-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
++mkinstalldirs = $(install_sh) -d
+ CONFIG_HEADER = $(top_builddir)/config.h
+ CONFIG_CLEAN_FILES =
+ SOURCES =
+@@ -100,7 +100,6 @@
+ LIBTOOL = @LIBTOOL@
+ LN_S = @LN_S@
+ LTLIBOBJS = @LTLIBOBJS@
+-LUACONFIG = @LUACONFIG@
+ LUA_CFLAGS = @LUA_CFLAGS@
+ LUA_LIBS = @LUA_LIBS@
+ MAINT = @MAINT@
+@@ -143,6 +142,7 @@
+ ac_ct_F77 = @ac_ct_F77@
+ ac_ct_RANLIB = @ac_ct_RANLIB@
+ ac_ct_STRIP = @ac_ct_STRIP@
++ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@
+ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/docroot/Makefile.in lighttpd-1.4.12/tests/docroot/Makefile.in
+--- lighttpd-1.4.11/tests/docroot/Makefile.in  2006-03-07 14:21:04.000000000 +0200
++++ lighttpd-1.4.12/tests/docroot/Makefile.in  2006-07-11 21:48:15.000000000 +0300
+@@ -1,4 +1,4 @@
+-# Makefile.in generated by automake 1.9.5 from Makefile.am.
++# Makefile.in generated by automake 1.9.6 from Makefile.am.
+ # @configure_input@
+ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+@@ -42,7 +42,7 @@
+ am__aclocal_m4_deps = $(top_srcdir)/configure.in
+ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+       $(ACLOCAL_M4)
+-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
++mkinstalldirs = $(install_sh) -d
+ CONFIG_HEADER = $(top_builddir)/config.h
+ CONFIG_CLEAN_FILES =
+ SOURCES =
+@@ -109,7 +109,6 @@
+ LIBTOOL = @LIBTOOL@
+ LN_S = @LN_S@
+ LTLIBOBJS = @LTLIBOBJS@
+-LUACONFIG = @LUACONFIG@
+ LUA_CFLAGS = @LUA_CFLAGS@
+ LUA_LIBS = @LUA_LIBS@
+ MAINT = @MAINT@
+@@ -152,6 +151,7 @@
+ ac_ct_F77 = @ac_ct_F77@
+ ac_ct_RANLIB = @ac_ct_RANLIB@
+ ac_ct_STRIP = @ac_ct_STRIP@
++ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@
+ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/docroot/www/Makefile.in lighttpd-1.4.12/tests/docroot/www/Makefile.in
+--- lighttpd-1.4.11/tests/docroot/www/Makefile.in      2006-03-07 14:21:05.000000000 +0200
++++ lighttpd-1.4.12/tests/docroot/www/Makefile.in      2006-07-11 21:48:15.000000000 +0300
+@@ -1,4 +1,4 @@
+-# Makefile.in generated by automake 1.9.5 from Makefile.am.
++# Makefile.in generated by automake 1.9.6 from Makefile.am.
+ # @configure_input@
+ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+@@ -42,7 +42,7 @@
+ am__aclocal_m4_deps = $(top_srcdir)/configure.in
+ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+       $(ACLOCAL_M4)
+-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
++mkinstalldirs = $(install_sh) -d
+ CONFIG_HEADER = $(top_builddir)/config.h
+ CONFIG_CLEAN_FILES =
+ SOURCES =
+@@ -109,7 +109,6 @@
+ LIBTOOL = @LIBTOOL@
+ LN_S = @LN_S@
+ LTLIBOBJS = @LTLIBOBJS@
+-LUACONFIG = @LUACONFIG@
+ LUA_CFLAGS = @LUA_CFLAGS@
+ LUA_LIBS = @LUA_LIBS@
+ MAINT = @MAINT@
+@@ -152,6 +151,7 @@
+ ac_ct_F77 = @ac_ct_F77@
+ ac_ct_RANLIB = @ac_ct_RANLIB@
+ ac_ct_STRIP = @ac_ct_STRIP@
++ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@
+ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/docroot/www/dummydir/.svn/entries lighttpd-1.4.12/tests/docroot/www/dummydir/.svn/entries
 --- lighttpd-1.4.11/tests/docroot/www/dummydir/.svn/entries    2006-03-09 19:21:49.000000000 +0200
-+++ lighttpd/tests/docroot/www/dummydir/.svn/entries   2006-07-11 21:23:41.575948429 +0300
++++ lighttpd-1.4.12/tests/docroot/www/dummydir/.svn/entries    2006-07-11 21:23:41.000000000 +0300
 @@ -9,5 +9,6 @@
     last-author="jan"
     kind="dir"
 +   repos="svn://svn.lighttpd.net/lighttpd"
 +   revision="1159"/>
  </wc-entries>
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/docroot/www/expire/Makefile.in lighttpd-1.4.12/tests/docroot/www/expire/Makefile.in
+--- lighttpd-1.4.11/tests/docroot/www/expire/Makefile.in       2006-03-07 14:21:05.000000000 +0200
++++ lighttpd-1.4.12/tests/docroot/www/expire/Makefile.in       2006-07-11 21:48:15.000000000 +0300
+@@ -1,4 +1,4 @@
+-# Makefile.in generated by automake 1.9.5 from Makefile.am.
++# Makefile.in generated by automake 1.9.6 from Makefile.am.
+ # @configure_input@
+ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+@@ -42,7 +42,7 @@
+ am__aclocal_m4_deps = $(top_srcdir)/configure.in
+ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+       $(ACLOCAL_M4)
+-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
++mkinstalldirs = $(install_sh) -d
+ CONFIG_HEADER = $(top_builddir)/config.h
+ CONFIG_CLEAN_FILES =
+ SOURCES =
+@@ -100,7 +100,6 @@
+ LIBTOOL = @LIBTOOL@
+ LN_S = @LN_S@
+ LTLIBOBJS = @LTLIBOBJS@
+-LUACONFIG = @LUACONFIG@
+ LUA_CFLAGS = @LUA_CFLAGS@
+ LUA_LIBS = @LUA_LIBS@
+ MAINT = @MAINT@
+@@ -143,6 +142,7 @@
+ ac_ct_F77 = @ac_ct_F77@
+ ac_ct_RANLIB = @ac_ct_RANLIB@
+ ac_ct_STRIP = @ac_ct_STRIP@
++ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@
+ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/docroot/www/go/Makefile.in lighttpd-1.4.12/tests/docroot/www/go/Makefile.in
+--- lighttpd-1.4.11/tests/docroot/www/go/Makefile.in   2006-03-07 14:21:06.000000000 +0200
++++ lighttpd-1.4.12/tests/docroot/www/go/Makefile.in   2006-07-11 21:48:16.000000000 +0300
+@@ -1,4 +1,4 @@
+-# Makefile.in generated by automake 1.9.5 from Makefile.am.
++# Makefile.in generated by automake 1.9.6 from Makefile.am.
+ # @configure_input@
+ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+@@ -42,7 +42,7 @@
+ am__aclocal_m4_deps = $(top_srcdir)/configure.in
+ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+       $(ACLOCAL_M4)
+-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
++mkinstalldirs = $(install_sh) -d
+ CONFIG_HEADER = $(top_builddir)/config.h
+ CONFIG_CLEAN_FILES =
+ SOURCES =
+@@ -100,7 +100,6 @@
+ LIBTOOL = @LIBTOOL@
+ LN_S = @LN_S@
+ LTLIBOBJS = @LTLIBOBJS@
+-LUACONFIG = @LUACONFIG@
+ LUA_CFLAGS = @LUA_CFLAGS@
+ LUA_LIBS = @LUA_LIBS@
+ MAINT = @MAINT@
+@@ -143,6 +142,7 @@
+ ac_ct_F77 = @ac_ct_F77@
+ ac_ct_RANLIB = @ac_ct_RANLIB@
+ ac_ct_STRIP = @ac_ct_STRIP@
++ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@
+ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/docroot/www/indexfile/Makefile.in lighttpd-1.4.12/tests/docroot/www/indexfile/Makefile.in
+--- lighttpd-1.4.11/tests/docroot/www/indexfile/Makefile.in    2006-03-07 14:21:07.000000000 +0200
++++ lighttpd-1.4.12/tests/docroot/www/indexfile/Makefile.in    2006-07-11 21:48:16.000000000 +0300
+@@ -1,4 +1,4 @@
+-# Makefile.in generated by automake 1.9.5 from Makefile.am.
++# Makefile.in generated by automake 1.9.6 from Makefile.am.
+ # @configure_input@
+ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+@@ -42,7 +42,7 @@
+ am__aclocal_m4_deps = $(top_srcdir)/configure.in
+ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+       $(ACLOCAL_M4)
+-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
++mkinstalldirs = $(install_sh) -d
+ CONFIG_HEADER = $(top_builddir)/config.h
+ CONFIG_CLEAN_FILES =
+ SOURCES =
+@@ -100,7 +100,6 @@
+ LIBTOOL = @LIBTOOL@
+ LN_S = @LN_S@
+ LTLIBOBJS = @LTLIBOBJS@
+-LUACONFIG = @LUACONFIG@
+ LUA_CFLAGS = @LUA_CFLAGS@
+ LUA_LIBS = @LUA_LIBS@
+ MAINT = @MAINT@
+@@ -143,6 +142,7 @@
+ ac_ct_F77 = @ac_ct_F77@
+ ac_ct_RANLIB = @ac_ct_RANLIB@
+ ac_ct_STRIP = @ac_ct_STRIP@
++ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@
+ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/fastcgi-10.conf lighttpd-1.4.12/tests/fastcgi-10.conf
 --- lighttpd-1.4.11/tests/fastcgi-10.conf      2005-08-31 23:36:34.000000000 +0300
-+++ lighttpd/tests/fastcgi-10.conf     2006-07-11 21:23:41.911969475 +0300
++++ lighttpd-1.4.12/tests/fastcgi-10.conf      2006-07-11 21:23:41.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.name = "zzz.example.org"
  }
  
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/fastcgi-13.conf lighttpd-1.4.12/tests/fastcgi-13.conf
 --- lighttpd-1.4.11/tests/fastcgi-13.conf      2006-01-03 12:38:17.000000000 +0200
-+++ lighttpd/tests/fastcgi-13.conf     2006-07-11 21:23:41.971973233 +0300
++++ lighttpd-1.4.12/tests/fastcgi-13.conf      2006-07-11 21:23:41.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.name = "zzz.example.org"
  }
  
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/fastcgi-auth.conf lighttpd-1.4.12/tests/fastcgi-auth.conf
 --- lighttpd-1.4.11/tests/fastcgi-auth.conf    2005-08-27 17:44:19.000000000 +0300
-+++ lighttpd/tests/fastcgi-auth.conf   2006-07-11 21:23:42.003975238 +0300
++++ lighttpd-1.4.12/tests/fastcgi-auth.conf    2006-07-11 21:23:42.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.name = "zzz.example.org"
  }
  
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/fastcgi-responder.conf lighttpd-1.4.12/tests/fastcgi-responder.conf
 --- lighttpd-1.4.11/tests/fastcgi-responder.conf       2005-08-27 17:44:19.000000000 +0300
-+++ lighttpd/tests/fastcgi-responder.conf      2006-07-11 21:23:41.999974987 +0300
++++ lighttpd-1.4.12/tests/fastcgi-responder.conf       2006-07-11 21:23:41.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.name = "zzz.example.org"
  }
  
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/fcgi-responder.c lighttpd-1.4.12/tests/fcgi-responder.c
 --- lighttpd-1.4.11/tests/fcgi-responder.c     2005-08-11 01:26:55.000000000 +0300
-+++ lighttpd/tests/fcgi-responder.c    2006-07-11 21:23:41.979973734 +0300
++++ lighttpd-1.4.12/tests/fcgi-responder.c     2006-07-11 21:23:41.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;
-               
--              if (NULL != (p = getenv("QUERY_STRING"))) {
++
 +              doc_root = getenv("DOCUMENT_ROOT");
 +              p = getenv("QUERY_STRING");
 +
                        } else if (0 == strcmp(p, "die-at-end")) {
                                printf("Status: 200 OK\r\n\r\n");
                                num_requests--;
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/lighttpd.conf lighttpd-1.4.12/tests/lighttpd.conf
 --- lighttpd-1.4.11/tests/lighttpd.conf        2006-03-09 15:26:58.000000000 +0200
-+++ lighttpd/tests/lighttpd.conf       2006-07-11 21:23:41.999974987 +0300
++++ lighttpd-1.4.12/tests/lighttpd.conf        2006-07-11 21:23:41.000000000 +0300
 @@ -1,80 +1,18 @@
 -debug.log-request-handling = "enable"
 -debug.log-condition-handling = "enable"
  
 -## 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.tag                 = "Apache 1.3.29"
 -
 -server.dir-listing          = "enable"
-+include "default.conf"
+-
 -#server.event-handler        = "linux-sysepoll"
 -#server.event-handler        = "linux-rtsig"
 -
    simple-vhost.default-host   = "www.example.org"
  }
  
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/lowercase.conf lighttpd-1.4.12/tests/lowercase.conf
+--- lighttpd-1.4.11/tests/lowercase.conf       1970-01-01 03:00:00.000000000 +0300
++++ lighttpd-1.4.12/tests/lowercase.conf       2006-07-11 21:23:41.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" )
++}
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/lowercase.t lighttpd-1.4.12/tests/lowercase.t
+--- lighttpd-1.4.11/tests/lowercase.t  1970-01-01 03:00:00.000000000 +0300
++++ lighttpd-1.4.12/tests/lowercase.t  2006-07-11 21:23:41.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");
++
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/mod-fastcgi.t lighttpd-1.4.12/tests/mod-fastcgi.t
 --- lighttpd-1.4.11/tests/mod-fastcgi.t        2006-03-09 15:30:45.000000000 +0200
-+++ lighttpd/tests/mod-fastcgi.t       2006-07-11 21:23:41.995974736 +0300
++++ lighttpd-1.4.12/tests/mod-fastcgi.t        2006-07-11 21:23:41.000000000 +0300
 @@ -7,7 +7,7 @@
  }
  
  
        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.0/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');
        $t->{REQUEST}  = ( <<EOF
  GET /index.fcgi?die-at-end HTTP/1.0
  Host: www.example.org
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/mod-proxy.t lighttpd-1.4.12/tests/mod-proxy.t
+--- lighttpd-1.4.11/tests/mod-proxy.t  1970-01-01 03:00:00.000000000 +0300
++++ lighttpd-1.4.12/tests/mod-proxy.t  2006-07-11 21:23:41.000000000 +0300
+@@ -0,0 +1,173 @@
++#!/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
++
++$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");
++
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/proxy.conf lighttpd-1.4.12/tests/proxy.conf
+--- lighttpd-1.4.11/tests/proxy.conf   1970-01-01 03:00:00.000000000 +0300
++++ lighttpd-1.4.12/tests/proxy.conf   2006-07-11 21:23:42.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"
++}
++
+diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/var-include.conf lighttpd-1.4.12/tests/var-include.conf
 --- lighttpd-1.4.11/tests/var-include.conf     2005-08-27 17:44:19.000000000 +0300
-+++ lighttpd/tests/var-include.conf    2006-07-11 21:23:41.943971479 +0300
++++ lighttpd-1.4.12/tests/var-include.conf     2006-07-11 21:23:41.000000000 +0300
 @@ -2,15 +2,15 @@
  debug.log-request-handling = "enable"
  debug.log-condition-handling = "enable"
This page took 2.554153 seconds and 4 git commands to generate.