]> git.pld-linux.org Git - packages/lighttpd.git/commitdiff
- up to r2303:
authorElan Ruusamäe <glen@pld-linux.org>
Fri, 19 Sep 2008 14:37:09 +0000 (14:37 +0000)
committercvs2git <feedback@pld-linux.org>
Sun, 24 Jun 2012 12:13:13 +0000 (12:13 +0000)
  * close connection after redirect in trigger_b4_dl (thx icy)
  * close connection in mod_magnet if returned status code
  * fix bug with IPv6 in mod_evasive (#1579)
  * fix scgi HTTP/1.* status parsing (#1638), found by met@uberstats.com
  * [tests] fixed system, use foreground daemons and waitpid
  * [tests] removed pidfile from test system
  * [tests] fixed tests needing php running (if not running on port 1026, search php in env[PHP] or /usr/bin/php-cgi)
  * fixed typo in mod_accesslog (#1699)
  * replaced buffer_{append,copy}_string with the _len variant where possible (#1732) (thx crypt)
  * case insensitive match for secdownload md5 token (#1710)
  * Handle only HEAD, GET and POST in mod_dirlisting (same as in staticfile) (#1687)
  * fixed mod_secdownload problem with unsigned time_t (#1688)
  * handle EAGAIN and EINTR for freebsd sendfile (#1675)
  * Use filedescriptor 0 for mod_scgi spawn socket, redirect STDERR to /dev/null (#1716)
  * fixed round-robin balancing in mod_proxy (#1715)
  * fixed EINTR handling for waitpid in mod_fastcgi
  * mod_{fast,s}cgi: overwrite environment variables (#1722)
  * inserted many con->mode checks; they should prevent two modules to handle the same request if they shouldn't (#631)
  * fixed url encoding to encode more characters (#266)
  * allow digits in [s]cgi env vars (#1712)
  * fixed dropping last character of evhost pattern (#161)
  * print helpful error message on conditionals in global block (#1550)
  * decode url before matching in mod_rewrite (#1720)
  * fixed conditional patching of ldap filter (#1564)
  * Match headers case insensitive in response (removing of X-{Sendfile,LIGHTTPD-*}, catching Date/Server)
  * fixed bug with case-insensitive filenames in mod_userdir (#1589), spotted by "anders1"
  * fixed format string bugs in mod_accesslog for SYSLOG
  * replaced fprintf with log_error_write in fastcgi debug
  * fixed mem leak in ssi expression parser (#1753), thx Take5k
  * hide some ssl errors per default, enable them with debug.log-ssl-noise (#397)
  * do not send content-encoding for 304 (#1754), thx yzlai
  * fix segfault for stat_cache(fam) calls with relative path (without '/', can be triggered by x-sendfile) (#1750)
  * fix splitting of auth-ldap filter
  * workaround ldap connection leak if a ldap connection failed (restarting ldap)

Changed files:
    lighttpd-branch.diff -> 1.39

lighttpd-branch.diff

index dbbf95a8652029101ef9080f48b3f4d327b30bca..96af28930a0467556e5e6474dd37e25e4286ec34 100644 (file)
@@ -1,7 +1,7 @@
 Index: lighttpd.spec.in
 ===================================================================
---- lighttpd.spec.in   (.../tags/lighttpd-1.4.19)      (revision 2199)
-+++ lighttpd.spec.in   (.../branches/lighttpd-1.4.x)   (revision 2199)
+--- lighttpd.spec.in   (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ lighttpd.spec.in   (.../branches/lighttpd-1.4.x)   (revision 2303)
 @@ -1,83 +0,0 @@
 -Summary: A fast webserver with minimal memory-footprint (lighttpd)
 -Name: lighttpd
@@ -90,8 +90,8 @@ Index: configure.in
 ===================================================================
 Index: src/mod_ssi_exprparser.h
 ===================================================================
---- src/mod_ssi_exprparser.h   (.../tags/lighttpd-1.4.19)      (revision 2199)
-+++ src/mod_ssi_exprparser.h   (.../branches/lighttpd-1.4.x)   (revision 2199)
+--- src/mod_ssi_exprparser.h   (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/mod_ssi_exprparser.h   (.../branches/lighttpd-1.4.x)   (revision 2303)
 @@ -1,12 +0,0 @@
 -#define TK_AND                             1
 -#define TK_OR                              2
@@ -107,8 +107,26 @@ Index: src/mod_ssi_exprparser.h
 -#define TK_VALUE                          12
 Index: src/configfile-glue.c
 ===================================================================
---- src/configfile-glue.c      (.../tags/lighttpd-1.4.19)      (revision 2199)
-+++ src/configfile-glue.c      (.../branches/lighttpd-1.4.x)   (revision 2199)
+--- src/configfile-glue.c      (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/configfile-glue.c      (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -155,7 +155,7 @@
+               /* touched */
+               touched = data_string_init();
+-              buffer_copy_string(touched->value, "");
++              buffer_copy_string_len(touched->value, CONST_STR_LEN(""));
+               buffer_copy_string_buffer(touched->key, du->key);
+               array_insert_unique(srv->config_touched, (data_unset *)touched);
+@@ -260,7 +260,7 @@
+                               if (ck_colon) {
+                                       /* condition "host:port" but client send "host" */
+                                       buffer_copy_string_buffer(srv->cond_check_buf, l);
+-                                      BUFFER_APPEND_STRING_CONST(srv->cond_check_buf, ":");
++                                      buffer_append_string_len(srv->cond_check_buf, CONST_STR_LEN(":"));
+                                       buffer_append_long(srv->cond_check_buf, sock_addr_get_port(&(srv_sock->addr)));
+                                       l = srv->cond_check_buf;
+                               } else if (!ck_colon) {
 @@ -529,7 +529,7 @@
  int config_append_cond_match_buffer(connection *con, data_config *dc, buffer *buf, int n)
  {
@@ -120,8 +138,26 @@ Index: src/configfile-glue.c
  
 Index: src/mod_cgi.c
 ===================================================================
---- src/mod_cgi.c      (.../tags/lighttpd-1.4.19)      (revision 2199)
-+++ src/mod_cgi.c      (.../branches/lighttpd-1.4.x)   (revision 2199)
+--- src/mod_cgi.c      (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/mod_cgi.c      (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -912,7 +912,7 @@
+                               buffer_reset(p->tmp_buf);
+                               if (0 != strcasecmp(ds->key->ptr, "CONTENT-TYPE")) {
+-                                      buffer_copy_string(p->tmp_buf, "HTTP_");
++                                      buffer_copy_string_len(p->tmp_buf, CONST_STR_LEN("HTTP_"));
+                                       p->tmp_buf->used--; /* strip \0 after HTTP_ */
+                               }
+@@ -949,7 +949,7 @@
+                               for (j = 0; j < ds->key->used - 1; j++) {
+                                       p->tmp_buf->ptr[p->tmp_buf->used++] =
+-                                              isalpha((unsigned char)ds->key->ptr[j]) ?
++                                              light_isalnum((unsigned char)ds->key->ptr[j]) ?
+                                               toupper((unsigned char)ds->key->ptr[j]) : '_';
+                               }
+                               p->tmp_buf->ptr[p->tmp_buf->used++] = '\0';
 @@ -987,6 +987,8 @@
                        *c = '/';
                }
@@ -171,11 +207,129 @@ Index: src/mod_cgi.c
                                        break;
                                }
                                chunkqueue_remove_finished_chunks(cq);
+@@ -1174,6 +1180,8 @@
+       plugin_data *p = p_d;
+       buffer *fn = con->physical.path;
++      if (con->mode != DIRECT) return HANDLER_GO_ON;
++
+       if (fn->used == 0) return HANDLER_GO_ON;
+       mod_cgi_patch_connection(srv, con, p);
+@@ -1189,6 +1197,7 @@
+               if (0 == strncmp(fn->ptr + s_len - ct_len, ds->key->ptr, ct_len)) {
+                       if (cgi_create_env(srv, con, p, ds->value)) {
++                              con->mode = DIRECT;
+                               con->http_status = 500;
+                               buffer_reset(con->physical.path);
+Index: src/mod_secure_download.c
+===================================================================
+--- src/mod_secure_download.c  (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/mod_secure_download.c  (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -204,6 +204,8 @@
+       time_t ts = 0;
+       size_t i;
++      if (con->mode != DIRECT) return HANDLER_GO_ON;
++
+       if (con->uri.path->used == 0) return HANDLER_GO_ON;
+       mod_secdownload_patch_connection(srv, con, p);
+@@ -243,8 +245,8 @@
+       }
+       /* timed-out */
+-      if (srv->cur_ts - ts > p->conf.timeout ||
+-          srv->cur_ts - ts < -p->conf.timeout) {
++      if ( (srv->cur_ts > ts && srv->cur_ts - ts > p->conf.timeout) ||
++           (srv->cur_ts < ts && ts - srv->cur_ts > p->conf.timeout) ) {
+               /* "Gone" as the url will never be valid again instead of "408 - Timeout" where the request may be repeated */
+               con->http_status = 410;
+@@ -268,7 +270,7 @@
+       buffer_copy_string_hex(p->md5, (char *)HA1, 16);
+-      if (0 != strncmp(md5_str, p->md5->ptr, 32)) {
++      if (0 != strncasecmp(md5_str, p->md5->ptr, 32)) {
+               con->http_status = 403;
+               log_error_write(srv, __FILE__, __LINE__, "sss",
+Index: src/array.c
+===================================================================
+--- src/array.c        (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/array.c        (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -330,30 +330,30 @@
+       a = array_init();
+       ds = data_string_init();
+-      buffer_copy_string(ds->key, "abc");
+-      buffer_copy_string(ds->value, "alfrag");
++      buffer_copy_string_len(ds->key, CONST_STR_LEN("abc"));
++      buffer_copy_string_len(ds->value, CONST_STR_LEN("alfrag"));
+       array_insert_unique(a, (data_unset *)ds);
+       ds = data_string_init();
+-      buffer_copy_string(ds->key, "abc");
+-      buffer_copy_string(ds->value, "hameplman");
++      buffer_copy_string_len(ds->key, CONST_STR_LEN("abc"));
++      buffer_copy_string_len(ds->value, CONST_STR_LEN("hameplman"));
+       array_insert_unique(a, (data_unset *)ds);
+       ds = data_string_init();
+-      buffer_copy_string(ds->key, "123");
+-      buffer_copy_string(ds->value, "alfrag");
++      buffer_copy_string_len(ds->key, CONST_STR_LEN("123"));
++      buffer_copy_string_len(ds->value, CONST_STR_LEN("alfrag"));
+       array_insert_unique(a, (data_unset *)ds);
+       dc = data_count_init();
+-      buffer_copy_string(dc->key, "def");
++      buffer_copy_string_len(dc->key, CONST_STR_LEN("def"));
+       array_insert_unique(a, (data_unset *)dc);
+       dc = data_count_init();
+-      buffer_copy_string(dc->key, "def");
++      buffer_copy_string_len(dc->key, CONST_STR_LEN("def"));
+       array_insert_unique(a, (data_unset *)dc);
+Index: src/base.h
+===================================================================
+--- src/base.h (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/base.h (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -259,6 +259,7 @@
+       unsigned short log_request_handling;
+       unsigned short log_response_header;
+       unsigned short log_condition_handling;
++      unsigned short log_ssl_noise;
+       /* server wide */
 Index: src/mod_rewrite.c
 ===================================================================
---- src/mod_rewrite.c  (.../tags/lighttpd-1.4.19)      (revision 2199)
-+++ src/mod_rewrite.c  (.../branches/lighttpd-1.4.x)   (revision 2199)
-@@ -385,8 +385,7 @@
+--- src/mod_rewrite.c  (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/mod_rewrite.c  (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -350,7 +350,11 @@
+       if (!p->conf.rewrite) return HANDLER_GO_ON;
+-      buffer_copy_string_buffer(p->match_buf, con->request.uri);
++      buffer_copy_string_buffer(p->match_buf, con->uri.path);
++      if (con->uri.query->used > 0) {
++              buffer_append_string_len(p->match_buf, CONST_STR_LEN("?"));
++              buffer_append_string_buffer(p->match_buf, con->uri.query);
++      }
+       for (i = 0; i < p->conf.rewrite->used; i++) {
+               pcre *match;
+@@ -385,8 +389,7 @@
  
                        start = 0; end = pattern_len;
                        for (k = 0; k < pattern_len; k++) {
@@ -185,7 +339,7 @@ Index: src/mod_rewrite.c
                                        /* got one */
  
                                        size_t num = pattern[k + 1] - '0';
-@@ -395,7 +394,10 @@
+@@ -395,7 +398,10 @@
  
                                        buffer_append_string_len(con->request.uri, pattern + start, end - start);
  
@@ -199,8 +353,8 @@ Index: src/mod_rewrite.c
                                                        buffer_append_string(con->request.uri, list[num]);
 Index: src/lempar.c
 ===================================================================
---- src/lempar.c       (.../tags/lighttpd-1.4.19)      (revision 2199)
-+++ src/lempar.c       (.../branches/lighttpd-1.4.x)   (revision 2199)
+--- src/lempar.c       (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/lempar.c       (.../branches/lighttpd-1.4.x)   (revision 2303)
 @@ -210,7 +210,7 @@
  */
  const char *ParseTokenName(int tokenType){
@@ -248,8 +402,8 @@ Index: src/lempar.c
  %%
 Index: src/connections.c
 ===================================================================
---- src/connections.c  (.../tags/lighttpd-1.4.19)      (revision 2199)
-+++ src/connections.c  (.../branches/lighttpd-1.4.x)   (revision 2199)
+--- src/connections.c  (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/connections.c  (.../branches/lighttpd-1.4.x)   (revision 2303)
 @@ -199,6 +199,7 @@
  
        /* don't resize the buffer if we were in SSL_ERROR_WANT_* */
@@ -258,7 +412,28 @@ Index: src/connections.c
        do {
                if (!con->ssl_error_want_reuse_buffer) {
                        b = buffer_init();
-@@ -299,6 +300,8 @@
+@@ -275,9 +276,19 @@
+                       /* fall thourgh */
+               default:
+                       while((ssl_err = ERR_get_error())) {
++                              switch (ERR_GET_REASON(ssl_err)) {
++                              case SSL_R_SSL_HANDSHAKE_FAILURE:
++                              case SSL_R_TLSV1_ALERT_UNKNOWN_CA:
++                              case SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN:
++                              case SSL_R_SSLV3_ALERT_BAD_CERTIFICATE:
++                                      if (!con->conf.log_ssl_noise) continue;
++                                      break;
++                              default:
++                                      break;
++                              }
+                               /* get all errors from the error-queue */
+                               log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:",
+-                                              r, ERR_error_string(ssl_err, NULL));
++                                              r, ERR_error_string(ssl_err, NULL));
+                       }
+                       break;
+               }
+@@ -299,6 +310,8 @@
  
        return 0;
  #else
@@ -267,7 +442,7 @@ Index: src/connections.c
        return -1;
  #endif
  }
-@@ -427,21 +430,22 @@
+@@ -427,21 +440,22 @@
        }
  
        switch(con->http_status) {
@@ -303,7 +478,7 @@ Index: src/connections.c
                con->file_finished = 0;
  
                buffer_reset(con->physical.path);
-@@ -451,7 +455,8 @@
+@@ -451,7 +465,8 @@
                        stat_cache_entry *sce = NULL;
  
                        buffer_copy_string_buffer(con->physical.path, con->conf.errorfile_prefix);
@@ -313,7 +488,42 @@ Index: src/connections.c
  
                        if (HANDLER_ERROR != stat_cache_get_entry(srv, con, con->physical.path, &sce)) {
                                con->file_finished = 1;
-@@ -497,30 +502,7 @@
+@@ -470,57 +485,34 @@
+                       b = chunkqueue_get_append_buffer(con->write_queue);
+                       /* build default error-page */
+-                      buffer_copy_string(b,
++                      buffer_copy_string_len(b, CONST_STR_LEN(
+                                          "<?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>");
++                                         "  <title>"));
+                       buffer_append_long(b, con->http_status);
+-                      buffer_append_string(b, " - ");
++                      buffer_append_string_len(b, CONST_STR_LEN(" - "));
+                       buffer_append_string(b, get_http_status_name(con->http_status));
+-                      buffer_append_string(b,
++                      buffer_append_string_len(b, CONST_STR_LEN(
+                                            "</title>\n"
+                                            " </head>\n"
+                                            " <body>\n"
+-                                           "  <h1>");
++                                           "  <h1>"));
+                       buffer_append_long(b, con->http_status);
+-                      buffer_append_string(b, " - ");
++                      buffer_append_string_len(b, CONST_STR_LEN(" - "));
+                       buffer_append_string(b, get_http_status_name(con->http_status));
+-                      buffer_append_string(b,"</h1>\n"
++                      buffer_append_string_len(b, CONST_STR_LEN("</h1>\n"
+                                            " </body>\n"
+                                            "</html>\n"
+-                                           );
++                                           ));
  
                        response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html"));
                }
@@ -344,7 +554,7 @@ Index: src/connections.c
        }
  
        if (con->file_finished) {
-@@ -544,7 +526,7 @@
+@@ -544,7 +536,7 @@
                                data_string *ds;
                                /* no Content-Body, no Content-Length */
                                if (NULL != (ds = (data_string*) array_get_element(con->response.headers, "Content-Length"))) {
@@ -353,7 +563,7 @@ Index: src/connections.c
                                }
                        } else if (qlen > 0 || con->request.http_method != HTTP_METHOD_HEAD) {
                                /* qlen = 0 is important for Redirects (301, ...) as they MAY have
-@@ -846,7 +828,7 @@
+@@ -846,7 +838,7 @@
        }
  
        /* The cond_cache gets reset in response.c */
@@ -362,7 +572,7 @@ Index: src/connections.c
  
  #ifdef USE_OPENSSL
        if (con->ssl_error_want_reuse_buffer) {
-@@ -1668,21 +1650,51 @@
+@@ -1668,21 +1660,51 @@
                        }
  #ifdef USE_OPENSSL
                        if (srv_sock->is_ssl) {
@@ -421,10 +631,80 @@ Index: src/connections.c
  #endif
  
                        switch(con->mode) {
+Index: src/mod_staticfile.c
+===================================================================
+--- src/mod_staticfile.c       (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/mod_staticfile.c       (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -282,22 +282,22 @@
+                               b = chunkqueue_get_append_buffer(con->write_queue);
+-                              buffer_copy_string(b, "\r\n--");
++                              buffer_copy_string_len(b, CONST_STR_LEN("\r\n--"));
+                               buffer_append_string(b, boundary);
+                               /* write Content-Range */
+-                              buffer_append_string(b, "\r\nContent-Range: bytes ");
++                              buffer_append_string_len(b, CONST_STR_LEN("\r\nContent-Range: bytes "));
+                               buffer_append_off_t(b, start);
+-                              buffer_append_string(b, "-");
++                              buffer_append_string_len(b, CONST_STR_LEN("-"));
+                               buffer_append_off_t(b, end);
+-                              buffer_append_string(b, "/");
++                              buffer_append_string_len(b, CONST_STR_LEN("/"));
+                               buffer_append_off_t(b, sce->st.st_size);
+-                              buffer_append_string(b, "\r\nContent-Type: ");
++                              buffer_append_string_len(b, CONST_STR_LEN("\r\nContent-Type: "));
+                               buffer_append_string_buffer(b, content_type);
+                               /* write END-OF-HEADER */
+-                              buffer_append_string(b, "\r\n\r\n");
++                              buffer_append_string_len(b, CONST_STR_LEN("\r\n\r\n"));
+                               con->response.content_length += b->used - 1;
+@@ -325,7 +325,7 @@
+               /* set header-fields */
+-              buffer_copy_string(p->range_buf, "multipart/byteranges; boundary=");
++              buffer_copy_string_len(p->range_buf, CONST_STR_LEN("multipart/byteranges; boundary="));
+               buffer_append_string(p->range_buf, boundary);
+               /* overwrite content-type */
+@@ -333,11 +333,11 @@
+       } else {
+               /* add Content-Range-header */
+-              buffer_copy_string(p->range_buf, "bytes ");
++              buffer_copy_string_len(p->range_buf, CONST_STR_LEN("bytes "));
+               buffer_append_off_t(p->range_buf, start);
+-              buffer_append_string(p->range_buf, "-");
++              buffer_append_string_len(p->range_buf, CONST_STR_LEN("-"));
+               buffer_append_off_t(p->range_buf, end);
+-              buffer_append_string(p->range_buf, "/");
++              buffer_append_string_len(p->range_buf, CONST_STR_LEN("/"));
+               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));
+Index: src/network.c
+===================================================================
+--- src/network.c      (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/network.c      (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -494,7 +494,7 @@
+       b = buffer_init();
+       buffer_copy_string_buffer(b, srv->srvconf.bindhost);
+-      buffer_append_string(b, ":");
++      buffer_append_string_len(b, CONST_STR_LEN(":"));
+       buffer_append_long(b, srv->srvconf.port);
+       if (0 != network_server_init(srv, b, srv->config_storage[0])) {
 Index: src/configfile.c
 ===================================================================
---- src/configfile.c   (.../tags/lighttpd-1.4.19)      (revision 2199)
-+++ src/configfile.c   (.../branches/lighttpd-1.4.x)   (revision 2199)
+--- src/configfile.c   (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/configfile.c   (.../branches/lighttpd-1.4.x)   (revision 2303)
 @@ -7,6 +7,7 @@
  #include <string.h>
  #include <stdio.h>
@@ -433,7 +713,110 @@ Index: src/configfile.c
  #include <assert.h>
  
  #include "server.h"
-@@ -305,9 +306,6 @@
+@@ -74,24 +75,25 @@
+               { "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 */
++              { "debug.log-ssl-noise",         NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },     /* 35 */
+-              { "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.protocol-http11",      NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },     /* 36 */
++              { "debug.log-request-header-on-error", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 37 */
++              { "debug.log-state-handling",    NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },     /* 38 */
++              { "ssl.ca-file",                 NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER },      /* 39 */
+-              { "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 */
+-              { "server.max-connections",      NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_SERVER },       /* 42 */
+-              { "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 */
+-              { "ssl.cipher-list",             NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER },      /* 46 */
+-              { "ssl.use-sslv2",               NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 47 */
+-              { "etag.use-inode",             NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 48 */
+-              { "etag.use-mtime",             NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 49 */
+-              { "etag.use-size",             NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 50 */
++              { "server.errorlog-use-syslog",  NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },     /* 40 */
++              { "server.range-requests",       NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 41 */
++              { "server.stat-cache-engine",    NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },  /* 42 */
++              { "server.max-connections",      NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_SERVER },       /* 43 */
++              { "server.network-backend",      NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },  /* 44 */
++              { "server.upload-dirs",          NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },   /* 45 */
++              { "server.core-files",           NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 46 */
++              { "ssl.cipher-list",             NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER },      /* 47 */
++              { "ssl.use-sslv2",               NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 48 */
++              { "etag.use-inode",             NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 49 */
++              { "etag.use-mtime",             NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 50 */
++              { "etag.use-size",             NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 51 */
+               { "server.host",                 "use server.bind instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET },
+               { "server.docroot",              "use server.document-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET },
+               { "server.virtual-root",         "load mod_simple_vhost and use simple-vhost.server-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET },
+@@ -120,18 +122,18 @@
+       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[37].destination = &(srv->srvconf.log_request_header_on_error);
++      cv[38].destination = &(srv->srvconf.log_state_handling);
+-      cv[39].destination = &(srv->srvconf.errorlog_use_syslog);
++      cv[40].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 = stat_cache_string;
++      cv[44].destination = srv->srvconf.network_backend;
++      cv[45].destination = srv->srvconf.upload_tempdirs;
++      cv[46].destination = &(srv->srvconf.enable_cores);
+-      cv[42].destination = &(srv->srvconf.max_conns);
++      cv[43].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 *));
+@@ -204,16 +206,17 @@
+               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->log_ssl_noise);
+-              cv[35].destination = &(s->allow_http11);
+-              cv[38].destination = s->ssl_ca_file;
+-              cv[40].destination = &(s->range_requests);
++              cv[36].destination = &(s->allow_http11);
++              cv[39].destination = s->ssl_ca_file;
++              cv[41].destination = &(s->range_requests);
+-              cv[46].destination = s->ssl_cipher_list;
+-              cv[47].destination = &(s->ssl_use_sslv2);
+-              cv[48].destination = &(s->etag_use_inode);
+-              cv[49].destination = &(s->etag_use_mtime);
+-              cv[50].destination = &(s->etag_use_size);
++              cv[47].destination = s->ssl_cipher_list;
++              cv[48].destination = &(s->ssl_use_sslv2);
++              cv[49].destination = &(s->etag_use_inode);
++              cv[50].destination = &(s->etag_use_mtime);
++              cv[51].destination = &(s->etag_use_size);
+               srv->config_storage[i] = s;
+@@ -279,6 +282,7 @@
+       PATCH(log_request_handling);
+       PATCH(log_condition_handling);
+       PATCH(log_file_not_found);
++      PATCH(log_ssl_noise);
+       PATCH(range_requests);
+       PATCH(force_lowercase_filenames);
+@@ -305,9 +309,6 @@
                data_config *dc = (data_config *)srv->config_context->data[i];
                specific_config *s = srv->config_storage[i];
  
@@ -443,7 +826,16 @@ Index: src/configfile.c
                /* condition didn't match */
                if (!config_check_cond(srv, con, dc)) continue;
  
-@@ -410,8 +408,8 @@
+@@ -371,6 +372,8 @@
+                               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("debug.log-ssl-noise"))) {
++                              PATCH(log_ssl_noise);
+                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.protocol-http11"))) {
+                               PATCH(allow_http11);
+                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.force-lowercase-filenames"))) {
+@@ -410,8 +413,8 @@
  
  #if 0
  static int tokenizer_open(server *srv, tokenizer_t *t, buffer *basedir, const char *fn) {
@@ -454,7 +846,152 @@ Index: src/configfile.c
                        (fn[0] == '.' && (fn[1] == '/' || fn[1] == '\\'))) {
                t->file = buffer_init_string(fn);
        } else {
-@@ -884,8 +882,8 @@
+@@ -480,7 +483,7 @@
+                               if (t->input[t->offset + 1] == '>') {
+                                       t->offset += 2;
+-                                      buffer_copy_string(token, "=>");
++                                      buffer_copy_string_len(token, CONST_STR_LEN("=>"));
+                                       tid = TK_ARRAY_ASSIGN;
+                               } else {
+@@ -494,13 +497,13 @@
+                               if (t->input[t->offset + 1] == '=') {
+                                       t->offset += 2;
+-                                      buffer_copy_string(token, "==");
++                                      buffer_copy_string_len(token, CONST_STR_LEN("=="));
+                                       tid = TK_EQ;
+                               } else if (t->input[t->offset + 1] == '~') {
+                                       t->offset += 2;
+-                                      buffer_copy_string(token, "=~");
++                                      buffer_copy_string_len(token, CONST_STR_LEN("=~"));
+                                       tid = TK_MATCH;
+                               } else {
+@@ -533,13 +536,13 @@
+                               if (t->input[t->offset + 1] == '=') {
+                                       t->offset += 2;
+-                                      buffer_copy_string(token, "!=");
++                                      buffer_copy_string_len(token, CONST_STR_LEN("!="));
+                                       tid = TK_NE;
+                               } else if (t->input[t->offset + 1] == '~') {
+                                       t->offset += 2;
+-                                      buffer_copy_string(token, "!~");
++                                      buffer_copy_string_len(token, CONST_STR_LEN("!~"));
+                                       tid = TK_NOMATCH;
+                               } else {
+@@ -594,7 +597,7 @@
+                               }
+                               t->in_key = 1;
+                               tid = TK_EOL;
+-                              buffer_copy_string(token, "(EOL)");
++                              buffer_copy_string_len(token, CONST_STR_LEN("(EOL)"));
+                       } else {
+                               config_skip_newline(t);
+                               t->line_pos = 1;
+@@ -605,7 +608,7 @@
+                       if (t->in_brace > 0) {
+                               tid = TK_COMMA;
+-                              buffer_copy_string(token, "(COMMA)");
++                              buffer_copy_string_len(token, CONST_STR_LEN("(COMMA)"));
+                       }
+                       t->offset++;
+@@ -614,7 +617,7 @@
+               case '"':
+                       /* search for the terminating " */
+                       start = t->input + t->offset + 1;
+-                      buffer_copy_string(token, "");
++                      buffer_copy_string_len(token, CONST_STR_LEN(""));
+                       for (i = 1; t->input[t->offset + i]; i++) {
+                               if (t->input[t->offset + i] == '\\' &&
+@@ -660,7 +663,7 @@
+                       tid = TK_LPARAN;
+-                      buffer_copy_string(token, "(");
++                      buffer_copy_string_len(token, CONST_STR_LEN("("));
+                       break;
+               case ')':
+                       t->offset++;
+@@ -668,7 +671,7 @@
+                       tid = TK_RPARAN;
+-                      buffer_copy_string(token, ")");
++                      buffer_copy_string_len(token, CONST_STR_LEN(")"));
+                       break;
+               case '$':
+                       t->offset++;
+@@ -677,19 +680,19 @@
+                       t->in_cond = 1;
+                       t->in_key = 0;
+-                      buffer_copy_string(token, "$");
++                      buffer_copy_string_len(token, CONST_STR_LEN("$"));
+                       break;
+               case '+':
+                       if (t->input[t->offset + 1] == '=') {
+                               t->offset += 2;
+-                              buffer_copy_string(token, "+=");
++                              buffer_copy_string_len(token, CONST_STR_LEN("+="));
+                               tid = TK_APPEND;
+                       } else {
+                               t->offset++;
+                               tid = TK_PLUS;
+-                              buffer_copy_string(token, "+");
++                              buffer_copy_string_len(token, CONST_STR_LEN("+"));
+                       }
+                       break;
+@@ -698,7 +701,7 @@
+                       tid = TK_LCURLY;
+-                      buffer_copy_string(token, "{");
++                      buffer_copy_string_len(token, CONST_STR_LEN("{"));
+                       break;
+@@ -707,7 +710,7 @@
+                       tid = TK_RCURLY;
+-                      buffer_copy_string(token, "}");
++                      buffer_copy_string_len(token, CONST_STR_LEN("}"));
+                       break;
+@@ -716,7 +719,7 @@
+                       tid = TK_LBRACKET;
+-                      buffer_copy_string(token, "[");
++                      buffer_copy_string_len(token, CONST_STR_LEN("["));
+                       break;
+@@ -725,7 +728,7 @@
+                       tid = TK_RBRACKET;
+-                      buffer_copy_string(token, "]");
++                      buffer_copy_string_len(token, CONST_STR_LEN("]"));
+                       break;
+               case '#':
+@@ -884,8 +887,8 @@
        int ret;
        buffer *filename;
  
@@ -465,7 +1002,7 @@ Index: src/configfile.c
                        (fn[0] == '.' && (fn[1] == '/' || fn[1] == '\\'))) {
                filename = buffer_init_string(fn);
        } else {
-@@ -912,15 +910,39 @@
+@@ -912,15 +915,39 @@
        return ret;
  }
  
@@ -507,7 +1044,7 @@ Index: src/configfile.c
                log_error_write(srv, __FILE__, __LINE__, "s",
                                "cannot get cwd", strerror(errno));
                return -1;
-@@ -945,6 +967,7 @@
+@@ -945,6 +972,7 @@
        buffer_free(source);
        buffer_free(out);
        chdir(oldpwd);
@@ -515,10 +1052,185 @@ Index: src/configfile.c
        return ret;
  }
  
+@@ -986,7 +1014,7 @@
+       }
+       dc = data_config_init();
+-      buffer_copy_string(dc->key, "global");
++      buffer_copy_string_len(dc->key, CONST_STR_LEN("global"));
+       assert(context.all_configs->used == 0);
+       dc->context_ndx = context.all_configs->used;
+@@ -997,14 +1025,14 @@
+       srv->config = dc->value;
+       dpid = data_integer_init();
+       dpid->value = getpid();
+-      buffer_copy_string(dpid->key, "var.PID");
++      buffer_copy_string_len(dpid->key, CONST_STR_LEN("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)) {
+               dcwd->value->used = strlen(dcwd->value->ptr) + 1;
+-              buffer_copy_string(dcwd->key, "var.CWD");
++              buffer_copy_string_len(dcwd->key, CONST_STR_LEN("var.CWD"));
+               array_insert_unique(srv->config, (data_unset *)dcwd);
+       }
+@@ -1038,7 +1066,7 @@
+               /* prepend default modules */
+               if (NULL == array_get_element(modules->value, "mod_indexfile")) {
+                       ds = data_string_init();
+-                      buffer_copy_string(ds->value, "mod_indexfile");
++                      buffer_copy_string_len(ds->value, CONST_STR_LEN("mod_indexfile"));
+                       array_insert_unique(prepends->value, (data_unset *)ds);
+               }
+@@ -1051,13 +1079,13 @@
+               /* append default modules */
+               if (NULL == array_get_element(modules->value, "mod_dirlisting")) {
+                       ds = data_string_init();
+-                      buffer_copy_string(ds->value, "mod_dirlisting");
++                      buffer_copy_string_len(ds->value, CONST_STR_LEN("mod_dirlisting"));
+                       array_insert_unique(modules->value, (data_unset *)ds);
+               }
+               if (NULL == array_get_element(modules->value, "mod_staticfile")) {
+                       ds = data_string_init();
+-                      buffer_copy_string(ds->value, "mod_staticfile");
++                      buffer_copy_string_len(ds->value, CONST_STR_LEN("mod_staticfile"));
+                       array_insert_unique(modules->value, (data_unset *)ds);
+               }
+       } else {
+@@ -1067,18 +1095,18 @@
+               /* server.modules is not set */
+               ds = data_string_init();
+-              buffer_copy_string(ds->value, "mod_indexfile");
++              buffer_copy_string_len(ds->value, CONST_STR_LEN("mod_indexfile"));
+               array_insert_unique(modules->value, (data_unset *)ds);
+               ds = data_string_init();
+-              buffer_copy_string(ds->value, "mod_dirlisting");
++              buffer_copy_string_len(ds->value, CONST_STR_LEN("mod_dirlisting"));
+               array_insert_unique(modules->value, (data_unset *)ds);
+               ds = data_string_init();
+-              buffer_copy_string(ds->value, "mod_staticfile");
++              buffer_copy_string_len(ds->value, CONST_STR_LEN("mod_staticfile"));
+               array_insert_unique(modules->value, (data_unset *)ds);
+-              buffer_copy_string(modules->key, "server.modules");
++              buffer_copy_string_len(modules->key, CONST_STR_LEN("server.modules"));
+               array_insert_unique(srv->config, (data_unset *)modules);
+       }
+Index: src/mod_trigger_b4_dl.c
+===================================================================
+--- src/mod_trigger_b4_dl.c    (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/mod_trigger_b4_dl.c    (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -316,6 +316,8 @@
+ # define N 10
+       int ovec[N * 3];
++      if (con->mode != DIRECT) return HANDLER_GO_ON;
++
+       if (con->uri.path->used == 0) return HANDLER_GO_ON;
+       mod_trigger_b4_dl_patch_connection(srv, con, p);
+@@ -425,8 +427,8 @@
+                               /* not found, redirect */
+                               response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(p->conf.deny_url));
+-
+                               con->http_status = 307;
++                              con->file_finished = 1;
+                               return HANDLER_FINISHED;
+                       }
+@@ -440,6 +442,7 @@
+                               response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(p->conf.deny_url));
+                               con->http_status = 307;
++                              con->file_finished = 1;
+                               if (p->conf.db) {
+                                       if (0 != gdbm_delete(p->conf.db, key)) {
+@@ -490,6 +493,7 @@
+                               response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(p->conf.deny_url));
+                               con->http_status = 307;
++                              con->file_finished = 1;
+                               return HANDLER_FINISHED;
+                       }
+Index: src/mod_evhost.c
+===================================================================
+--- src/mod_evhost.c   (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/mod_evhost.c   (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -95,7 +95,7 @@
+               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);
++              buffer_copy_string_len(s->path_pieces[s->len],pos,ptr-pos);
+               s->len += 1;
+       }
+@@ -181,7 +181,7 @@
+       }
+       ds = data_string_init();
+-      buffer_copy_string(ds->key,"%0");
++      buffer_copy_string_len(ds->key,CONST_STR_LEN("%0"));
+       /* if we stopped at a dot, skip the dot */
+       if (*ptr == '.') ptr++;
+@@ -197,7 +197,7 @@
+                               if (ptr != colon - 1) {
+                                       /* is something between the dots */
+                                       ds = data_string_init();
+-                                      buffer_copy_string(ds->key,"%");
++                                      buffer_copy_string_len(ds->key,CONST_STR_LEN("%"));
+                                       buffer_append_long(ds->key, i++);
+                                       buffer_copy_string_len(ds->value,ptr+1,colon-ptr-1);
+@@ -210,7 +210,7 @@
+               /* if the . is not the first charactor of the hostname */
+               if (colon != ptr) {
+                       ds = data_string_init();
+-                      buffer_copy_string(ds->key,"%");
++                      buffer_copy_string_len(ds->key,CONST_STR_LEN("%"));
+                       buffer_append_long(ds->key, i++);
+                       buffer_copy_string_len(ds->value,ptr,colon-ptr);
+@@ -286,7 +286,7 @@
+                       if (*(ptr+1) == '%') {
+                               /* %% */
+-                              BUFFER_APPEND_STRING_CONST(p->tmp_buf,"%");
++                              buffer_append_string_len(p->tmp_buf,CONST_STR_LEN("%"));
+                       } else if (NULL != (ds = (data_string *)array_get_element(parsed_host,p->conf.path_pieces[i]->ptr))) {
+                               if (ds->value->used) {
+                                       buffer_append_string_buffer(p->tmp_buf,ds->value);
+Index: src/chunk.c
+===================================================================
+--- src/chunk.c        (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/chunk.c        (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -296,7 +296,7 @@
+                       buffer_copy_string_buffer(template, ds->value);
+                       BUFFER_APPEND_SLASH(template);
+-                      BUFFER_APPEND_STRING_CONST(template, "lighttpd-upload-XXXXXX");
++                      buffer_append_string_len(template, CONST_STR_LEN("lighttpd-upload-XXXXXX"));
+                       if (-1 != (c->file.fd = mkstemp(template->ptr))) {
+                               /* only trigger the unlink if we created the temp-file successfully */
 Index: src/lemon.c
 ===================================================================
---- src/lemon.c        (.../tags/lighttpd-1.4.19)      (revision 2199)
-+++ src/lemon.c        (.../branches/lighttpd-1.4.x)   (revision 2199)
+--- src/lemon.c        (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/lemon.c        (.../branches/lighttpd-1.4.x)   (revision 2303)
 @@ -12,6 +12,19 @@
  #include <ctype.h>
  #include <stdlib.h>
@@ -599,10 +1311,23 @@ Index: src/lemon.c
    FILE *fp;
    char *filebuf;
    size_t filesize;
+Index: src/mod_skeleton.c
+===================================================================
+--- src/mod_skeleton.c (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/mod_skeleton.c (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -169,6 +169,8 @@
+       UNUSED(srv);
++      if (con->mode != DIRECT) return HANDLER_GO_ON;
++
+       if (con->uri.path->used == 0) return HANDLER_GO_ON;
+       mod_skeleton_patch_connection(srv, con, p);
 Index: src/mod_scgi.c
 ===================================================================
---- src/mod_scgi.c     (.../tags/lighttpd-1.4.19)      (revision 2199)
-+++ src/mod_scgi.c     (.../branches/lighttpd-1.4.x)   (revision 2199)
+--- src/mod_scgi.c     (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/mod_scgi.c     (.../branches/lighttpd-1.4.x)   (revision 2303)
 @@ -202,6 +202,15 @@
         *
         */
@@ -627,7 +1352,62 @@ Index: src/mod_scgi.c
        scgi_extension_host **hosts;
  
        size_t used;
-@@ -968,6 +978,7 @@
+@@ -583,6 +593,7 @@
+ static int env_add(char_array *env, const char *key, size_t key_len, const char *val, size_t val_len) {
+       char *dst;
++      size_t i;
+       if (!key || !val) return -1;
+@@ -592,6 +603,15 @@
+       /* add the \0 from the value */
+       memcpy(dst + key_len + 1, val, val_len + 1);
++      for (i = 0; i < env->used; i++) {
++              if (0 == strncmp(dst, env->ptr[i], key_len + 1)) {
++                      /* don't care about free as we are in a forked child which is going to exec(...) */
++                      /* free(env->ptr[i]); */
++                      env->ptr[i] = dst;
++                      return 0;
++              }
++      }
++
+       if (env->size == 0) {
+               env->size = 16;
+               env->ptr = malloc(env->size * sizeof(*env->ptr));
+@@ -749,11 +769,20 @@
+                       env.size = 0;
+                       env.used = 0;
++                      if (scgi_fd != 0) {
++                              close(0);
++                              dup2(scgi_fd, 0);
++                              close(scgi_fd);
++                              scgi_fd = 0;
++                      }
++
+                       /* we don't need the client socket */
+                       for (fd = 3; fd < 256; fd++) {
+-                              if (fd != 2 && fd != scgi_fd) close(fd);
++                              close(fd);
+                       }
++                      openDevNull(STDERR_FILENO);
++
+                       /* build clean environment */
+                       if (host->bin_env_copy->used) {
+                               for (i = 0; i < host->bin_env_copy->used; i++) {
+@@ -794,7 +823,7 @@
+                       env.ptr[env.used] = NULL;
+                       b = buffer_init();
+-                      buffer_copy_string(b, "exec ");
++                      buffer_copy_string_len(b, CONST_STR_LEN("exec "));
+                       buffer_append_string_buffer(b, host->bin_path);
+                       /* exec the cgi */
+@@ -968,6 +997,7 @@
  
                                                { "bin-environment",   NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },        /* 11 */
                                                { "bin-copy-environment", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },     /* 12 */
@@ -635,7 +1415,7 @@ Index: src/mod_scgi.c
  
  
                                                { NULL,                NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
-@@ -990,6 +1001,7 @@
+@@ -990,6 +1020,7 @@
                                        df->max_load_per_proc = 1;
                                        df->idle_timeout = 60;
                                        df->disable_time = 60;
@@ -643,7 +1423,7 @@ Index: src/mod_scgi.c
  
                                        fcv[0].destination = df->host;
                                        fcv[1].destination = df->docroot;
-@@ -1006,6 +1018,7 @@
+@@ -1006,6 +1037,7 @@
  
                                        fcv[11].destination = df->bin_env;
                                        fcv[12].destination = df->bin_env_copy;
@@ -651,7 +1431,74 @@ Index: src/mod_scgi.c
  
  
                                        if (0 != config_insert_values_internal(srv, da_host->value, fcv)) {
-@@ -2668,10 +2681,10 @@
+@@ -1084,7 +1116,7 @@
+                                                               proc->port = df->port + pno;
+                                                       } else {
+                                                               buffer_copy_string_buffer(proc->socket, df->unixsocket);
+-                                                              buffer_append_string(proc->socket, "-");
++                                                              buffer_append_string_len(proc->socket, CONST_STR_LEN("-"));
+                                                               buffer_append_long(proc->socket, pno);
+                                                       }
+@@ -1155,11 +1187,6 @@
+       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);
+@@ -1366,7 +1393,7 @@
+                       buffer_reset(srv->tmp_buf);
+                       if (0 != strcasecmp(ds->key->ptr, "CONTENT-TYPE")) {
+-                              BUFFER_COPY_STRING_CONST(srv->tmp_buf, "HTTP_");
++                              buffer_copy_string_len(srv->tmp_buf, CONST_STR_LEN("HTTP_"));
+                               srv->tmp_buf->used--;
+                       }
+@@ -1394,7 +1421,7 @@
+                       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]) ?
++                                      light_isalnum((unsigned char)ds->key->ptr[j]) ?
+                                       toupper((unsigned char)ds->key->ptr[j]) : '_';
+                       }
+                       srv->tmp_buf->ptr[srv->tmp_buf->used++] = '\0';
+@@ -1673,9 +1700,8 @@
+                               status = strtol(s+9, NULL, 10);
+-                              if (con->http_status >= 100 &&
+-                                  con->http_status < 1000) {
+-                                      /* we expected 3 digits and didn't got them */
++                              if (status >= 100 && status < 1000) {
++                                      /* we expected 3 digits got them */
+                                       con->parsed_response |= HTTP_STATUS;
+                                       con->http_status = status;
+                               }
+@@ -2438,15 +2464,11 @@
+       p    = hctx->plugin_data;
+       con  = hctx->remote_conn;
+-      if (con->mode != p->id) return HANDLER_GO_ON;
+-
+       log_error_write(srv, __FILE__, __LINE__, "ssdsd",
+                       "emergency exit: scgi:",
+                       "connection-fd:", con->fd,
+                       "fcgi-fd:", hctx->fd);
+-
+-
+       scgi_connection_cleanup(srv, hctx);
+       return HANDLER_FINISHED;
+@@ -2668,11 +2690,13 @@
        plugin_data *p = p_d;
        size_t s_len;
        int used = -1;
@@ -661,9 +1508,12 @@ Index: src/mod_scgi.c
        scgi_extension *extension = NULL;
 +      scgi_extension_host *host = NULL;
  
++      if (con->mode != DIRECT) return HANDLER_GO_ON;
++
        /* Possibly, we processed already this request */
        if (con->file_started == 1) return HANDLER_GO_ON;
-@@ -2712,95 +2725,59 @@
+@@ -2712,95 +2736,59 @@
        }
  
        /* get best server */
@@ -794,7 +1644,7 @@ Index: src/mod_scgi.c
  
                        hctx->conf.exts        = p->conf.exts;
                        hctx->conf.debug       = p->conf.debug;
-@@ -2812,22 +2789,69 @@
+@@ -2812,22 +2800,69 @@
                        con->mode = p->id;
  
                        if (con->conf.log_request_handling) {
@@ -873,10 +1723,53 @@ Index: src/mod_scgi.c
        return HANDLER_GO_ON;
  }
  
+@@ -2949,7 +2984,7 @@
+                                               fp->port = host->port + fp->id;
+                                       } else {
+                                               buffer_copy_string_buffer(fp->socket, host->unixsocket);
+-                                              buffer_append_string(fp->socket, "-");
++                                              buffer_append_string_len(fp->socket, CONST_STR_LEN("-"));
+                                               buffer_append_long(fp->socket, fp->id);
+                                       }
+Index: src/mod_mysql_vhost.c
+===================================================================
+--- src/mod_mysql_vhost.c      (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/mod_mysql_vhost.c      (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -410,6 +410,7 @@
+ ERR500:       if (result) mysql_free_result(result);
+       con->http_status = 500; /* Internal Error */
++      con->mode = DIRECT;
+       return HANDLER_FINISHED;
+ }
+Index: src/mod_flv_streaming.c
+===================================================================
+--- src/mod_flv_streaming.c    (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/mod_flv_streaming.c    (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -193,6 +193,8 @@
+       UNUSED(srv);
++      if (con->mode != DIRECT) return HANDLER_GO_ON;
++
+       if (buffer_is_empty(con->physical.path)) return HANDLER_GO_ON;
+       mod_flv_streaming_patch_connection(srv, con, p);
+@@ -245,7 +247,7 @@
+                       /* we are safe now, let's build a flv header */
+                       b = chunkqueue_get_append_buffer(con->write_queue);
+-                      BUFFER_COPY_STRING_CONST(b, "FLV\x1\x1\0\0\0\x9\0\0\0\x9");
++                      buffer_copy_string_len(b, CONST_STR_LEN("FLV\x1\x1\0\0\0\x9\0\0\0\x9"));
+                       http_chunk_append_file(srv, con, con->physical.path, start, sce->st.st_size - start);
 Index: src/lighttpd-angel.c
 ===================================================================
---- src/lighttpd-angel.c       (.../tags/lighttpd-1.4.19)      (revision 2199)
-+++ src/lighttpd-angel.c       (.../branches/lighttpd-1.4.x)   (revision 2199)
+--- src/lighttpd-angel.c       (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/lighttpd-angel.c       (.../branches/lighttpd-1.4.x)   (revision 2303)
 @@ -28,9 +28,12 @@
  static volatile sig_atomic_t graceful_restart = 0;
  static volatile pid_t pid = -1;
@@ -901,8 +1794,8 @@ Index: src/lighttpd-angel.c
         */
 Index: src/mod_rrdtool.c
 ===================================================================
---- src/mod_rrdtool.c  (.../tags/lighttpd-1.4.19)      (revision 2199)
-+++ src/mod_rrdtool.c  (.../branches/lighttpd-1.4.x)   (revision 2199)
+--- src/mod_rrdtool.c  (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/mod_rrdtool.c  (.../branches/lighttpd-1.4.x)   (revision 2303)
 @@ -148,6 +148,8 @@
                args[i++] = dash;
                args[i++] = NULL;
@@ -921,20 +1814,281 @@ Index: src/mod_rrdtool.c
  
                /* */
                SEGFAULT();
+@@ -202,24 +204,25 @@
+               int r ;
+               /* create a new one */
+-              BUFFER_COPY_STRING_CONST(p->cmd, "create ");
++              buffer_copy_string_len(p->cmd, CONST_STR_LEN("create "));
+               buffer_append_string_buffer(p->cmd, s->path_rrd);
+-              buffer_append_string(p->cmd, " --step 60 ");
+-              buffer_append_string(p->cmd, "DS:InOctets:ABSOLUTE:600:U:U ");
+-              buffer_append_string(p->cmd, "DS:OutOctets:ABSOLUTE:600:U:U ");
+-              buffer_append_string(p->cmd, "DS:Requests:ABSOLUTE:600:U:U ");
+-              buffer_append_string(p->cmd, "RRA:AVERAGE:0.5:1:600 ");
+-              buffer_append_string(p->cmd, "RRA:AVERAGE:0.5:6:700 ");
+-              buffer_append_string(p->cmd, "RRA:AVERAGE:0.5:24:775 ");
+-              buffer_append_string(p->cmd, "RRA:AVERAGE:0.5:288:797 ");
+-              buffer_append_string(p->cmd, "RRA:MAX:0.5:1:600 ");
+-              buffer_append_string(p->cmd, "RRA:MAX:0.5:6:700 ");
+-              buffer_append_string(p->cmd, "RRA:MAX:0.5:24:775 ");
+-              buffer_append_string(p->cmd, "RRA:MAX:0.5:288:797 ");
+-              buffer_append_string(p->cmd, "RRA:MIN:0.5:1:600 ");
+-              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");
++              buffer_append_string_len(p->cmd, CONST_STR_LEN(
++                      " --step 60 "
++                      "DS:InOctets:ABSOLUTE:600:U:U "
++                      "DS:OutOctets:ABSOLUTE:600:U:U "
++                      "DS:Requests:ABSOLUTE:600:U:U "
++                      "RRA:AVERAGE:0.5:1:600 "
++                      "RRA:AVERAGE:0.5:6:700 "
++                      "RRA:AVERAGE:0.5:24:775 "
++                      "RRA:AVERAGE:0.5:288:797 "
++                      "RRA:MAX:0.5:1:600 "
++                      "RRA:MAX:0.5:6:700 "
++                      "RRA:MAX:0.5:24:775 "
++                      "RRA:MAX:0.5:288:797 "
++                      "RRA:MIN:0.5:1:600 "
++                      "RRA:MIN:0.5:6:700 "
++                      "RRA:MIN:0.5:24:775 "
++                      "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",
+@@ -372,15 +375,15 @@
+               if (HANDLER_GO_ON != mod_rrdtool_create_rrd(srv, p, s)) return HANDLER_ERROR;
+-              BUFFER_COPY_STRING_CONST(p->cmd, "update ");
++              buffer_copy_string_len(p->cmd, CONST_STR_LEN("update "));
+               buffer_append_string_buffer(p->cmd, s->path_rrd);
+-              BUFFER_APPEND_STRING_CONST(p->cmd, " N:");
++              buffer_append_string_len(p->cmd, CONST_STR_LEN(" N:"));
+               buffer_append_off_t(p->cmd, s->bytes_read);
+-              BUFFER_APPEND_STRING_CONST(p->cmd, ":");
++              buffer_append_string_len(p->cmd, CONST_STR_LEN(":"));
+               buffer_append_off_t(p->cmd, s->bytes_written);
+-              BUFFER_APPEND_STRING_CONST(p->cmd, ":");
++              buffer_append_string_len(p->cmd, CONST_STR_LEN(":"));
+               buffer_append_long(p->cmd, s->requests);
+-              BUFFER_APPEND_STRING_CONST(p->cmd, "\n");
++              buffer_append_string_len(p->cmd, CONST_STR_LEN("\n"));
+               if (-1 == (r = write(p->write_fd, p->cmd->ptr, p->cmd->used - 1))) {
+                       p->rrdtool_running = 0;
+Index: src/mod_ssi_expr.c
+===================================================================
+--- src/mod_ssi_expr.c (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/mod_ssi_expr.c (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -59,7 +59,7 @@
+                       t->offset++;
+                       t->line_pos++;
+-                      buffer_copy_string(token, "(=)");
++                      buffer_copy_string_len(token, CONST_STR_LEN("(=)"));
+                       break;
+               case '>':
+@@ -69,14 +69,14 @@
+                               tid = TK_GE;
+-                              buffer_copy_string(token, "(>=)");
++                              buffer_copy_string_len(token, CONST_STR_LEN("(>=)"));
+                       } else {
+                               t->offset += 1;
+                               t->line_pos += 1;
+                               tid = TK_GT;
+-                              buffer_copy_string(token, "(>)");
++                              buffer_copy_string_len(token, CONST_STR_LEN("(>)"));
+                       }
+                       break;
+@@ -87,14 +87,14 @@
+                               tid = TK_LE;
+-                              buffer_copy_string(token, "(<=)");
++                              buffer_copy_string_len(token, CONST_STR_LEN("(<=)"));
+                       } else {
+                               t->offset += 1;
+                               t->line_pos += 1;
+                               tid = TK_LT;
+-                              buffer_copy_string(token, "(<)");
++                              buffer_copy_string_len(token, CONST_STR_LEN("(<)"));
+                       }
+                       break;
+@@ -106,14 +106,14 @@
+                               tid = TK_NE;
+-                              buffer_copy_string(token, "(!=)");
++                              buffer_copy_string_len(token, CONST_STR_LEN("(!=)"));
+                       } else {
+                               t->offset += 1;
+                               t->line_pos += 1;
+                               tid = TK_NOT;
+-                              buffer_copy_string(token, "(!)");
++                              buffer_copy_string_len(token, CONST_STR_LEN("(!)"));
+                       }
+                       break;
+@@ -124,7 +124,7 @@
+                               tid = TK_AND;
+-                              buffer_copy_string(token, "(&&)");
++                              buffer_copy_string_len(token, CONST_STR_LEN("(&&)"));
+                       } else {
+                               log_error_write(srv, __FILE__, __LINE__, "sds",
+                                               "pos:", t->line_pos,
+@@ -140,7 +140,7 @@
+                               tid = TK_OR;
+-                              buffer_copy_string(token, "(||)");
++                              buffer_copy_string_len(token, CONST_STR_LEN("(||)"));
+                       } else {
+                               log_error_write(srv, __FILE__, __LINE__, "sds",
+                                               "pos:", t->line_pos,
+@@ -183,7 +183,7 @@
+                       tid = TK_LPARAN;
+-                      buffer_copy_string(token, "(");
++                      buffer_copy_string_len(token, CONST_STR_LEN("("));
+                       break;
+               case ')':
+                       t->offset++;
+@@ -191,7 +191,7 @@
+                       tid = TK_RPARAN;
+-                      buffer_copy_string(token, ")");
++                      buffer_copy_string_len(token, CONST_STR_LEN(")"));
+                       break;
+               case '$':
+                       if (t->input[t->offset + 1] == '{') {
+@@ -219,7 +219,7 @@
+                       } else if (NULL != (ds = (data_string *)array_get_element(p->ssi_vars, token->ptr))) {
+                               buffer_copy_string_buffer(token, ds->value);
+                       } else {
+-                              buffer_copy_string(token, "");
++                              buffer_copy_string_len(token, CONST_STR_LEN(""));
+                       }
+                       t->offset += i;
+Index: src/stat_cache.c
+===================================================================
+--- src/stat_cache.c   (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/stat_cache.c   (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -445,7 +445,9 @@
+       /* dir-check */
+       if (srv->srvconf.stat_cache_engine == STAT_CACHE_ENGINE_FAM) {
+               if (0 != buffer_copy_dirname(sc->dir_name, name)) {
+-                      SEGFAULT();
++                      log_error_write(srv, __FILE__, __LINE__, "sb",
++                              "no '/' found in filename:", name);
++                      return HANDLER_ERROR;
+               }
+               buffer_copy_string_buffer(sc->hash_key, sc->dir_name);
 Index: src/response.c
 ===================================================================
---- src/response.c     (.../tags/lighttpd-1.4.19)      (revision 2199)
-+++ src/response.c     (.../branches/lighttpd-1.4.x)   (revision 2199)
-@@ -101,7 +101,7 @@
+--- src/response.c     (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/response.c     (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -35,21 +35,25 @@
+       b = chunkqueue_get_prepend_buffer(con->write_queue);
+       if (con->request.http_version == HTTP_VERSION_1_1) {
+-              BUFFER_COPY_STRING_CONST(b, "HTTP/1.1 ");
++              buffer_copy_string_len(b, CONST_STR_LEN("HTTP/1.1 "));
+       } else {
+-              BUFFER_COPY_STRING_CONST(b, "HTTP/1.0 ");
++              buffer_copy_string_len(b, CONST_STR_LEN("HTTP/1.0 "));
+       }
+       buffer_append_long(b, con->http_status);
+-      BUFFER_APPEND_STRING_CONST(b, " ");
++      buffer_append_string_len(b, CONST_STR_LEN(" "));
+       buffer_append_string(b, get_http_status_name(con->http_status));
+       if (con->request.http_version != HTTP_VERSION_1_1 || con->keep_alive == 0) {
+-              BUFFER_APPEND_STRING_CONST(b, "\r\nConnection: ");
+-              buffer_append_string(b, con->keep_alive ? "keep-alive" : "close");
++              buffer_append_string_len(b, CONST_STR_LEN("\r\nConnection: "));
++              if (con->keep_alive) {
++                      buffer_append_string_len(b, CONST_STR_LEN("keep-alive"));
++              } else {
++                      buffer_append_string_len(b, CONST_STR_LEN("close"));
++              }
+       }
+       if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
+-              BUFFER_APPEND_STRING_CONST(b, "\r\nTransfer-Encoding: chunked");
++              buffer_append_string_len(b, CONST_STR_LEN("\r\nTransfer-Encoding: chunked"));
+       }
+@@ -60,14 +64,15 @@
+               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-Sendfile", sizeof("X-Sendfile") - 1)) {
+-                      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;
++                  0 != strncasecmp(ds->key->ptr, CONST_STR_LEN("X-LIGHTTPD-")) &&
++                      0 != strcasecmp(ds->key->ptr, "X-Sendfile")) {
++                      if (0 == strcasecmp(ds->key->ptr, "Date")) have_date = 1;
++                      if (0 == strcasecmp(ds->key->ptr, "Server")) have_server = 1;
++                      if (0 == strcasecmp(ds->key->ptr, "Content-Encoding") && 304 == con->http_status) continue;
+-                      BUFFER_APPEND_STRING_CONST(b, "\r\n");
++                      buffer_append_string_len(b, CONST_STR_LEN("\r\n"));
+                       buffer_append_string_buffer(b, ds->key);
+-                      BUFFER_APPEND_STRING_CONST(b, ": ");
++                      buffer_append_string_len(b, CONST_STR_LEN(": "));
+ #if 0
+                       /** 
+                        * the value might contain newlines, encode them with at least one white-space
+@@ -81,7 +86,7 @@
+       if (!have_date) {
+               /* HTTP/1.1 requires a Date: header */
+-              BUFFER_APPEND_STRING_CONST(b, "\r\nDate: ");
++              buffer_append_string_len(b, CONST_STR_LEN("\r\nDate: "));
+               /* cache the generated timestamp */
+               if (srv->cur_ts != srv->last_generated_date_ts) {
+@@ -100,14 +105,14 @@
        if (!have_server) {
                if (buffer_is_empty(con->conf.server_tag)) {
-                       BUFFER_APPEND_STRING_CONST(b, "\r\nServer: " PACKAGE_NAME "/" PACKAGE_VERSION);
+-                      BUFFER_APPEND_STRING_CONST(b, "\r\nServer: " PACKAGE_NAME "/" PACKAGE_VERSION);
 -              } else {
+-                      BUFFER_APPEND_STRING_CONST(b, "\r\nServer: ");
++                      buffer_append_string_len(b, CONST_STR_LEN("\r\nServer: " PACKAGE_NAME "/" PACKAGE_VERSION));
 +              } else if (con->conf.server_tag->used > 1) {
-                       BUFFER_APPEND_STRING_CONST(b, "\r\nServer: ");
++                      buffer_append_string_len(b, CONST_STR_LEN("\r\nServer: "));
                        buffer_append_string_encoded(b, CONST_BUF_LEN(con->conf.server_tag), ENCODING_HTTP_HEADER);
                }
-@@ -152,7 +152,7 @@
+       }
+-      BUFFER_APPEND_STRING_CONST(b, "\r\n\r\n");
++      buffer_append_string_len(b, CONST_STR_LEN("\r\n\r\n"));
+       con->bytes_header = b->used - 1;
+@@ -152,7 +157,7 @@
                 *  */
  
                config_cond_cache_reset(srv, con);
@@ -943,10 +2097,117 @@ Index: src/response.c
  
                if (con->conf.log_condition_handling) {
                        log_error_write(srv, __FILE__, __LINE__,  "s",  "run condition");
+@@ -181,7 +186,11 @@
+                *
+                */
+-              buffer_copy_string(con->uri.scheme, con->conf.is_ssl ? "https" : "http");
++              if (con->conf.is_ssl) {
++                      buffer_copy_string_len(con->uri.scheme, CONST_STR_LEN("https"));
++              } else {
++                      buffer_copy_string_len(con->uri.scheme, CONST_STR_LEN("http"));
++              }
+               buffer_copy_string_buffer(con->uri.authority, con->request.http_host);
+               buffer_to_lower(con->uri.authority);
+@@ -224,27 +233,6 @@
+               }
+-              /**
+-               *
+-               * call plugins
+-               *
+-               * - based on the raw URL
+-               *
+-               */
+-
+-              switch(r = plugins_call_handle_uri_raw(srv, con)) {
+-              case HANDLER_GO_ON:
+-                      break;
+-              case HANDLER_FINISHED:
+-              case HANDLER_COMEBACK:
+-              case HANDLER_WAIT_FOR_EVENT:
+-              case HANDLER_ERROR:
+-                      return r;
+-              default:
+-                      log_error_write(srv, __FILE__, __LINE__, "sd", "handle_uri_raw: unknown return value", r);
+-                      break;
+-              }
+-
+               /* build filename
+                *
+                * - decode url-encodings  (e.g. %20 -> ' ')
+@@ -252,7 +240,6 @@
+                */
+-
+               if (con->request.http_method == HTTP_METHOD_OPTIONS &&
+                   con->uri.path_raw->ptr[0] == '*' && con->uri.path_raw->ptr[1] == '\0') {
+                       /* OPTIONS * ... */
+@@ -268,10 +255,32 @@
+                       log_error_write(srv, __FILE__, __LINE__,  "sb", "URI-path     : ", con->uri.path);
+               }
++
+               /**
+                *
+                * call plugins
+                *
++               * - based on the raw URL
++               *
++               */
++
++              switch(r = plugins_call_handle_uri_raw(srv, con)) {
++              case HANDLER_GO_ON:
++                      break;
++              case HANDLER_FINISHED:
++              case HANDLER_COMEBACK:
++              case HANDLER_WAIT_FOR_EVENT:
++              case HANDLER_ERROR:
++                      return r;
++              default:
++                      log_error_write(srv, __FILE__, __LINE__, "sd", "handle_uri_raw: unknown return value", r);
++                      break;
++              }
++
++              /**
++               *
++               * call plugins
++               *
+                * - based on the clean URL
+                *
+                */
 Index: src/plugin.c
 ===================================================================
---- src/plugin.c       (.../tags/lighttpd-1.4.19)      (revision 2199)
-+++ src/plugin.c       (.../branches/lighttpd-1.4.x)   (revision 2199)
+--- src/plugin.c       (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/plugin.c       (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -131,12 +131,12 @@
+               buffer_copy_string_buffer(srv->tmp_buf, srv->srvconf.modules_dir);
+-              buffer_append_string(srv->tmp_buf, "/");
++              buffer_append_string_len(srv->tmp_buf, CONST_STR_LEN("/"));
+               buffer_append_string(srv->tmp_buf, modules);
+ #if defined(__WIN32) || defined(__CYGWIN__)
+-              buffer_append_string(srv->tmp_buf, ".dll");
++              buffer_append_string_len(srv->tmp_buf, CONST_STR_LEN(".dll"));
+ #else
+-              buffer_append_string(srv->tmp_buf, ".so");
++              buffer_append_string_len(srv->tmp_buf, CONST_STR_LEN(".so"));
+ #endif
+               p = plugin_init();
+@@ -173,7 +173,7 @@
+ #endif
+               buffer_reset(srv->tmp_buf);
+               buffer_copy_string(srv->tmp_buf, modules);
+-              buffer_append_string(srv->tmp_buf, "_plugin_init");
++              buffer_append_string_len(srv->tmp_buf, CONST_STR_LEN("_plugin_init"));
+ #ifdef __WIN32
+               init = GetProcAddress(p->lib, srv->tmp_buf->ptr);
 @@ -197,7 +197,7 @@
  
  #else
@@ -958,8 +2219,8 @@ Index: src/plugin.c
  #endif
 Index: src/SConscript
 ===================================================================
---- src/SConscript     (.../tags/lighttpd-1.4.19)      (revision 2199)
-+++ src/SConscript     (.../branches/lighttpd-1.4.x)   (revision 2199)
+--- src/SConscript     (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/SConscript     (.../branches/lighttpd-1.4.x)   (revision 2303)
 @@ -43,6 +43,7 @@
        'mod_cgi' : { 'src' : [ 'mod_cgi.c' ] },
        'mod_fastcgi' : { 'src' : [ 'mod_fastcgi.c' ] },
@@ -968,10 +2229,233 @@ Index: src/SConscript
        'mod_staticfile' : { 'src' : [ 'mod_staticfile.c' ] },
        'mod_dirlisting' : { 'src' : [ 'mod_dirlisting.c' ], 'lib' : [ env['LIBPCRE'] ] },
        'mod_indexfile' : { 'src' : [ 'mod_indexfile.c' ] },
+Index: src/buffer.c
+===================================================================
+--- src/buffer.c       (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/buffer.c       (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -55,6 +55,8 @@
+               free(b->ptr);
+               b->ptr = NULL;
+               b->size = 0;
++      } else if (b->size) {
++              b->ptr[0] = '\0';
+       }
+       b->used = 0;
+@@ -626,6 +628,7 @@
+       return 0;
+ }
++/* everything except: ! ( ) * - . 0-9 A-Z _ a-z */
+ const char encoded_chars_rel_uri_part[] = {
+       /*
+       0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
+@@ -633,11 +636,11 @@
+       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, 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 */
+-      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /*  50 -  5F */
+-      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /*  60 -  6F */
+-      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,  /*  70 -  7F DEL */
++      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,  /*  30 -  3F : ; < = > ? */
++      1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /*  40 -  4F @ */
++      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,  /*  50 -  5F [ \ ] ^ */
++      1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /*  60 -  6F ` */
++      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,  /*  70 -  7F { | } ~ DEL */
+       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 */
+       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  A0 -  AF */
+@@ -648,18 +651,19 @@
+       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  F0 -  FF */
+ };
++/* everything except: ! ( ) * - . / 0-9 A-Z _ a-z */
+ const char encoded_chars_rel_uri[] = {
+       /*
+       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, 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 */
+-      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /*  50 -  5F */
+-      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /*  60 -  6F */
+-      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,  /*  70 -  7F DEL */
++      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 : ; < = > ? */
++      1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /*  40 -  4F @ */
++      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,  /*  50 -  5F [ \ ] ^ */
++      1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /*  60 -  6F ` */
++      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,  /*  70 -  7F { | } ~ DEL */
+       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 */
+       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  A0 -  AF */
+Index: src/mod_userdir.c
+===================================================================
+--- src/mod_userdir.c  (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/mod_userdir.c  (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -262,6 +262,9 @@
+                               return HANDLER_GO_ON;
+                       }
+               }
++              if (con->conf.force_lowercase_filenames) {
++                      buffer_to_lower(p->username);
++              }
+               buffer_copy_string_buffer(p->temp_path, p->conf.basepath);
+               BUFFER_APPEND_SLASH(p->temp_path);
+@@ -284,8 +287,24 @@
+               }
+       }
++      /* the physical rel_path is basically the same as uri.path;
++       * but it is converted to lowercase in case of force_lowercase_filenames and some special handling
++       * for trailing '.', ' ' and '/' on windows
++       * we assume that no docroot/physical handler changed this
++       * (docroot should only set the docroot/server name, phyiscal should only change the phyiscal.path;
++       *  the exception mod_secure_download doesn't work with userdir anyway)
++       */
+       BUFFER_APPEND_SLASH(p->temp_path);
+-      buffer_append_string(p->temp_path, rel_url + 1); /* skip the / */
++      /* if no second '/' is found, we assume that it was stripped from the uri.path for the special handling
++       * on windows.
++       * we do not care about the trailing slash here on windows, as we already ensured it is a directory
++       *
++       * TODO: what to do with trailing dots in usernames on windows? they may result in the same directory
++       *       as a username without them.
++       */
++      if (NULL != (rel_url = strchr(con->physical.rel_path->ptr + 2, '/'))) {
++              buffer_append_string(p->temp_path, rel_url + 1); /* skip the / */
++      }
+       buffer_copy_string_buffer(con->physical.path, p->temp_path);
+       buffer_reset(p->temp_path);
+Index: src/mod_proxy.c
+===================================================================
+--- src/mod_proxy.c    (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/mod_proxy.c    (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -432,10 +432,10 @@
+       /* request line */
+       buffer_copy_string(b, get_http_method_name(con->request.http_method));
+-      BUFFER_APPEND_STRING_CONST(b, " ");
++      buffer_append_string_len(b, CONST_STR_LEN(" "));
+       buffer_append_string_buffer(b, con->request.uri);
+-      BUFFER_APPEND_STRING_CONST(b, " HTTP/1.0\r\n");
++      buffer_append_string_len(b, CONST_STR_LEN(" 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
+@@ -456,13 +456,13 @@
+                       if (buffer_is_equal_string(ds->key, CONST_STR_LEN("Connection"))) continue;
+                       buffer_append_string_buffer(b, ds->key);
+-                      BUFFER_APPEND_STRING_CONST(b, ": ");
++                      buffer_append_string_len(b, CONST_STR_LEN(": "));
+                       buffer_append_string_buffer(b, ds->value);
+-                      BUFFER_APPEND_STRING_CONST(b, "\r\n");
++                      buffer_append_string_len(b, CONST_STR_LEN("\r\n"));
+               }
+       }
+-      BUFFER_APPEND_STRING_CONST(b, "\r\n");
++      buffer_append_string_len(b, CONST_STR_LEN("\r\n"));
+       hctx->wb->bytes_in += b->used - 1;
+       /* body */
+@@ -1060,6 +1060,8 @@
+       data_array *extension = NULL;
+       size_t path_info_offset;
++      if (con->mode != DIRECT) return HANDLER_GO_ON;
++
+       /* Possibly, we processed already this request */
+       if (con->file_started == 1) return HANDLER_GO_ON;
+@@ -1118,7 +1120,13 @@
+               log_error_write(srv, __FILE__, __LINE__,  "s", "proxy - ext found");
+       }
+-      switch(p->conf.balance) {
++      if (extension->value->used == 1) {
++              if ( ((data_proxy *)extension->value->data[0])->is_disabled ) {
++                      ndx = -1;
++              } else {
++                      ndx = 0;
++              }
++      } else if (extension->value->used != 0) switch(p->conf.balance) {
+       case PROXY_BALANCE_HASH:
+               /* hash balancing */
+@@ -1175,7 +1183,9 @@
+               }
+               break;
+-      case PROXY_BALANCE_RR:
++      case PROXY_BALANCE_RR: {
++              data_proxy *host;
++
+               /* round robin */
+               if (p->conf.debug) {
+                       log_error_write(srv, __FILE__, __LINE__,  "s",
+@@ -1185,31 +1195,32 @@
+               /* 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];
++              host = (data_proxy *)extension->value->data[0];
+-                      if (host->is_disabled) continue;
++              /* Use last_used_ndx from first host in list */
++              k = ndx = host->last_used_ndx;
++              if (ndx < 0) ndx = 0;
+-                      /* first usable ndx */
+-                      if (max_usage == INT_MAX) {
+-                              max_usage = k;
+-                      }
++              /* Search first active host after last_used_ndx */
++              while ( ndx < (int) extension->value->used
++                              && (host = (data_proxy *)extension->value->data[ndx])->is_disabled ) ndx++;
+-                      /* get next ndx */
+-                      if ((int)k > host->last_used_ndx) {
+-                              ndx = k;
+-                              host->last_used_ndx = k;
+-
+-                              break;
++              if (ndx >= (int) extension->value->used) {
++                      /* didn't found a higher id, wrap to the start */
++                      for (ndx = 0; ndx < (int) k; ndx++) {
++                              host = (data_proxy *)extension->value->data[ndx];
++                              if (!host->is_disabled) break;
+                       }
+-              }
+-              /* didn't found a higher id, wrap to the start */
+-              if (ndx == -1 && max_usage != INT_MAX) {
+-                      ndx = max_usage;
++                      /* No active host found */
++                      if (host->is_disabled) ndx = -1;
+               }
++              /* Save new index for next round */
++              ((data_proxy *)extension->value->data[0])->last_used_ndx = ndx;
++
+               break;
++      }
+       default:
+               break;
+       }
 Index: src/mod_extforward.c
 ===================================================================
---- src/mod_extforward.c       (.../tags/lighttpd-1.4.19)      (revision 2199)
-+++ src/mod_extforward.c       (.../branches/lighttpd-1.4.x)   (revision 2199)
+--- src/mod_extforward.c       (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/mod_extforward.c       (.../branches/lighttpd-1.4.x)   (revision 2303)
 @@ -281,8 +281,9 @@
  static const char *last_not_in_array(array *a, plugin_data *p)
  {
@@ -985,37 +2469,68 @@ Index: src/mod_extforward.c
  
 Index: src/Makefile.am
 ===================================================================
---- src/Makefile.am    (.../tags/lighttpd-1.4.19)      (revision 2199)
-+++ src/Makefile.am    (.../branches/lighttpd-1.4.x)   (revision 2199)
-@@ -16,20 +16,17 @@
+--- src/Makefile.am    (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/Makefile.am    (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -3,7 +3,7 @@
+ noinst_PROGRAMS=proc_open lemon # simple-fcgi #graphic evalo bench ajp ssl error_test adserver gen-license
+ sbin_PROGRAMS=lighttpd lighttpd-angel
+ bin_PROGRAMS=spawn-fcgi
+-LEMON=$(top_builddir)/src/lemon
++LEMON=$(top_builddir)/src/lemon$(EXEEXT)
+ lemon_SOURCES=lemon.c
+@@ -15,21 +15,26 @@
+ if CROSS_COMPILING
  configparser.c configparser.h:
  mod_ssi_exprparser.c mod_ssi_exprparser.h:
++
++.PHONY: parsers
++parsers:
  else
 -$(srcdir)/configparser.y: lemon
 -$(srcdir)/mod_ssi_exprparser.y: lemon
 -
 -configparser.c configparser.h: $(srcdir)/configparser.y
-+configparser.c configparser.h: lemon $(srcdir)/configparser.y $(srcdir)/lempar.c
++configparser.h: configparser.c
++configparser.c: $(srcdir)/configparser.y $(srcdir)/lempar.c lemon$(EXEEXT)
        rm -f configparser.h
        $(LEMON) -q $(srcdir)/configparser.y $(srcdir)/lempar.c
  
 -mod_ssi_exprparser.c mod_ssi_exprparser.h: $(srcdir)/mod_ssi_exprparser.y
-+mod_ssi_exprparser.c mod_ssi_exprparser.h: lemon $(srcdir)/mod_ssi_exprparser.y $(srcdir)/lempar.c
++mod_ssi_exprparser.h: mod_ssi_exprparser.c
++mod_ssi_exprparser.c: $(srcdir)/mod_ssi_exprparser.y $(srcdir)/lempar.c lemon$(EXEEXT)
        rm -f mod_ssi_exprparser.h
        $(LEMON) -q $(srcdir)/mod_ssi_exprparser.y $(srcdir)/lempar.c
++
++.PHONY: parsers
++parsers: configparser.c mod_ssi_exprparser.c
  endif
  
 -$(srcdir)/configfile.c: configparser.h
 -$(srcdir)/mod_ssi_expr.c: mod_ssi_exprparser.h
-+configfile.o: configparser.h
-+mod_ssi_expr.o: mod_ssi_exprparser.h
++BUILT_SOURCES = parsers
++MAINTAINERCLEANFILES = configparser.c configparser.h mod_ssi_exprparser.c mod_ssi_exprparser.h
  
  common_src=buffer.c log.c \
        keyvalue.c chunk.c  \
+Index: src/mod_expire.c
+===================================================================
+--- src/mod_expire.c   (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/mod_expire.c   (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -339,7 +339,7 @@
+                       response_header_overwrite(srv, con, CONST_STR_LEN("Expires"), CONST_BUF_LEN(p->expire_tstmp));
+                       /* HTTP/1.1 */
+-                      buffer_copy_string(p->expire_tstmp, "max-age=");
++                      buffer_copy_string_len(p->expire_tstmp, CONST_STR_LEN("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));
 Index: src/network_openssl.c
 ===================================================================
---- src/network_openssl.c      (.../tags/lighttpd-1.4.19)      (revision 2199)
-+++ src/network_openssl.c      (.../branches/lighttpd-1.4.x)   (revision 2199)
+--- src/network_openssl.c      (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/network_openssl.c      (.../branches/lighttpd-1.4.x)   (revision 2303)
 @@ -85,6 +85,7 @@
                         *
                         */
@@ -1032,10 +2547,31 @@ Index: src/network_openssl.c
                                if ((r = SSL_write(ssl, s, toSend)) <= 0) {
                                        unsigned long err;
  
+Index: src/network_freebsd_sendfile.c
+===================================================================
+--- src/network_freebsd_sendfile.c     (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/network_freebsd_sendfile.c     (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -166,6 +166,7 @@
+                       if (-1 == sendfile(c->file.fd, fd, offset, toSend, NULL, &r, 0)) {
+                               switch(errno) {
+                               case EAGAIN:
++                              case EINTR:
+                                       break;
+                               case ENOTCONN:
+                                       return -2;
+@@ -175,7 +176,7 @@
+                               }
+                       }
+-                      if (r == 0) {
++                      if (r == 0 && (errno != EAGAIN && errno != EINTR)) {
+                               int oerrno = errno;
+                               /* We got an event to write but we wrote nothing
+                                *
 Index: src/mod_redirect.c
 ===================================================================
---- src/mod_redirect.c (.../tags/lighttpd-1.4.19)      (revision 2199)
-+++ src/mod_redirect.c (.../branches/lighttpd-1.4.x)   (revision 2199)
+--- src/mod_redirect.c (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/mod_redirect.c (.../branches/lighttpd-1.4.x)   (revision 2303)
 @@ -215,8 +215,7 @@
  
                        start = 0; end = pattern_len;
@@ -1058,10 +2594,210 @@ Index: src/mod_redirect.c
                                                /* n is always > 0 */
                                                if (num < (size_t)n) {
                                                        buffer_append_string(p->location, list[num]);
+@@ -251,6 +253,7 @@
+                       response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(p->location));
+                       con->http_status = 301;
++                      con->mode = DIRECT;
+                       con->file_finished = 1;
+                       return HANDLER_FINISHED;
+Index: src/http_auth.c
+===================================================================
+--- src/http_auth.c    (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/http_auth.c    (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -697,7 +697,7 @@
+               }
+       } else if (p->conf.auth_backend == AUTH_BACKEND_LDAP) {
+ #ifdef USE_LDAP
+-              LDAP *ldap;
++              LDAP *ldap = NULL;
+               LDAPMessage *lm, *first;
+               char *dn;
+               int ret;
+@@ -742,39 +742,56 @@
+               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))) {
+-                      if (auth_ldap_init(srv, &p->conf) != HANDLER_GO_ON)
+-                              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))) {
++                      /* try again if ldap was only temporary down */
++                      if (p->conf.ldap == NULL || ret != LDAP_SERVER_DOWN ||  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))) {
++                              if (auth_ldap_init(srv, &p->conf) != HANDLER_GO_ON)
++                                      return -1;
+-                      log_error_write(srv, __FILE__, __LINE__, "sssb",
+-                                      "ldap:", ldap_err2string(ret), "filter:", p->ldap_filter);
+-
+-                      return -1;
++                              ldap = p->conf.ldap; /* save temporary ldap connection (TODO: redo ldap) */
++                              if (LDAP_SUCCESS != (ret = ldap_search_s(p->conf.ldap, p->conf.auth_ldap_basedn->ptr, LDAP_SCOPE_SUBTREE, p->ldap_filter->ptr, attrs, 0, &lm))) {
++                                      log_error_write(srv, __FILE__, __LINE__, "sssb",
++                                                      "ldap:", ldap_err2string(ret), "filter:", p->ldap_filter);
++                                      /* destroy temporary ldap connection (TODO: redo ldap) */
++                                      ldap_unbind_s(ldap);
++                                      return -1;
++                              }
+                       }
+               }
+               if (NULL == (first = ldap_first_entry(p->conf.ldap, lm))) {
+-                      log_error_write(srv, __FILE__, __LINE__, "s", "ldap ...");
++                      /* No matching entry is not an error */
++                      /* log_error_write(srv, __FILE__, __LINE__, "s", "ldap ..."); */
+                       ldap_msgfree(lm);
++                      /* destroy temporary ldap connection (TODO: redo ldap) */
++                      if (NULL != ldap) {
++                              ldap_unbind_s(ldap);
++                      }
+                       return -1;
+               }
+               if (NULL == (dn = ldap_get_dn(p->conf.ldap, first))) {
+-                      log_error_write(srv, __FILE__, __LINE__, "s", "ldap ...");
++                      log_error_write(srv, __FILE__, __LINE__, "s", "ldap: ldap_get_dn failed");
+                       ldap_msgfree(lm);
++                      /* destroy temporary ldap connection (TODO: redo ldap) */
++                      if (NULL != ldap) {
++                              ldap_unbind_s(ldap);
++                      }
+                       return -1;
+               }
+               ldap_msgfree(lm);
++              /* destroy temporary ldap connection (TODO: redo ldap) */
++              if (NULL != ldap) {
++                      ldap_unbind_s(ldap);
++              }
+               /* 3. */
+               if (NULL == (ldap = ldap_init(p->conf.auth_ldap_hostname->ptr, LDAP_PORT))) {
+Index: src/mod_usertrack.c
+===================================================================
+--- src/mod_usertrack.c        (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/mod_usertrack.c        (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -103,7 +103,7 @@
+               }
+               if (buffer_is_empty(s->cookie_name)) {
+-                      buffer_copy_string(s->cookie_name, "TRACKID");
++                      buffer_copy_string_len(s->cookie_name, CONST_STR_LEN("TRACKID"));
+               } else {
+                       size_t j;
+                       for (j = 0; j < s->cookie_name->used - 1; j++) {
+@@ -214,9 +214,9 @@
+       if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
+               ds = data_response_init();
+       }
+-      buffer_copy_string(ds->key, "Set-Cookie");
++      buffer_copy_string_len(ds->key, CONST_STR_LEN("Set-Cookie"));
+       buffer_copy_string_buffer(ds->value, p->conf.cookie_name);
+-      buffer_append_string(ds->value, "=");
++      buffer_append_string_len(ds->value, CONST_STR_LEN("="));
+       /* taken from mod_auth.c */
+@@ -235,16 +235,16 @@
+       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");
++      buffer_append_string_len(ds->value, CONST_STR_LEN("; Path=/"));
++      buffer_append_string_len(ds->value, CONST_STR_LEN("; Version=1"));
+       if (!buffer_is_empty(p->conf.cookie_domain)) {
+-              buffer_append_string(ds->value, "; Domain=");
++              buffer_append_string_len(ds->value, CONST_STR_LEN("; 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_string_len(ds->value, CONST_STR_LEN("; max-age="));
+               buffer_append_long(ds->value, p->conf.cookie_max_age);
+       }
 Index: src/mod_webdav.c
 ===================================================================
---- src/mod_webdav.c   (.../tags/lighttpd-1.4.19)      (revision 2199)
-+++ src/mod_webdav.c   (.../branches/lighttpd-1.4.x)   (revision 2199)
+--- src/mod_webdav.c   (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/mod_webdav.c   (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -485,23 +485,23 @@
+       UNUSED(con);
+       if (value) {
+-              buffer_append_string(b,"<");
++              buffer_append_string_len(b,CONST_STR_LEN("<"));
+               buffer_append_string(b, prop_name);
+-              buffer_append_string(b, " xmlns=\"");
++              buffer_append_string_len(b, CONST_STR_LEN(" xmlns=\""));
+               buffer_append_string(b, prop_ns);
+-              buffer_append_string(b, "\">");
++              buffer_append_string_len(b, CONST_STR_LEN("\">"));
+               buffer_append_string(b, value);
+-              buffer_append_string(b,"</");
++              buffer_append_string_len(b,CONST_STR_LEN("</"));
+               buffer_append_string(b, prop_name);
+-              buffer_append_string(b, ">");
++              buffer_append_string_len(b, CONST_STR_LEN(">"));
+       } else {
+-              buffer_append_string(b,"<");
++              buffer_append_string_len(b,CONST_STR_LEN("<"));
+               buffer_append_string(b, prop_name);
+-              buffer_append_string(b, " xmlns=\"");
++              buffer_append_string_len(b, CONST_STR_LEN(" xmlns=\""));
+               buffer_append_string(b, prop_ns);
+-              buffer_append_string(b, "\"/>");
++              buffer_append_string_len(b, CONST_STR_LEN("\"/>"));
+       }
+       return 0;
+@@ -511,24 +511,24 @@
+ static int webdav_gen_response_status_tag(server *srv, connection *con, physical *dst, int status, buffer *b) {
+       UNUSED(srv);
+-      buffer_append_string(b,"<D:response xmlns:ns0=\"urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/\">\n");
++      buffer_append_string_len(b,CONST_STR_LEN("<D:response xmlns:ns0=\"urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/\">\n"));
+-      buffer_append_string(b,"<D:href>\n");
++      buffer_append_string_len(b,CONST_STR_LEN("<D:href>\n"));
+       buffer_append_string_buffer(b, dst->rel_path);
+-      buffer_append_string(b,"</D:href>\n");
+-      buffer_append_string(b,"<D:status>\n");
++      buffer_append_string_len(b,CONST_STR_LEN("</D:href>\n"));
++      buffer_append_string_len(b,CONST_STR_LEN("<D:status>\n"));
+       if (con->request.http_version == HTTP_VERSION_1_1) {
+-              BUFFER_COPY_STRING_CONST(b, "HTTP/1.1 ");
++              buffer_copy_string_len(b, CONST_STR_LEN("HTTP/1.1 "));
+       } else {
+-              BUFFER_COPY_STRING_CONST(b, "HTTP/1.0 ");
++              buffer_copy_string_len(b, CONST_STR_LEN("HTTP/1.0 "));
+       }
+       buffer_append_long(b, status);
+-      BUFFER_APPEND_STRING_CONST(b, " ");
++      buffer_append_string_len(b, CONST_STR_LEN(" "));
+       buffer_append_string(b, get_http_status_name(status));
+-      buffer_append_string(b,"</D:status>\n");
+-      buffer_append_string(b,"</D:response>\n");
++      buffer_append_string_len(b,CONST_STR_LEN("</D:status>\n"));
++      buffer_append_string_len(b,CONST_STR_LEN("</D:response>\n"));
+       return 0;
+ }
 @@ -570,6 +570,8 @@
                                /* */
                        }
@@ -1080,6 +2816,140 @@ Index: src/mod_webdav.c
  #endif
        return status;
  }
+@@ -840,12 +844,12 @@
+               if (0 == strcmp(prop_name, "resourcetype")) {
+                       if (S_ISDIR(sce->st.st_mode)) {
+-                              buffer_append_string(b, "<D:resourcetype><D:collection/></D:resourcetype>");
++                              buffer_append_string_len(b, CONST_STR_LEN("<D:resourcetype><D:collection/></D:resourcetype>"));
+                               found = 1;
+                       }
+               } else if (0 == strcmp(prop_name, "getcontenttype")) {
+                       if (S_ISDIR(sce->st.st_mode)) {
+-                              buffer_append_string(b, "<D:getcontenttype>httpd/unix-directory</D:getcontenttype>");
++                              buffer_append_string_len(b, CONST_STR_LEN("<D:getcontenttype>httpd/unix-directory</D:getcontenttype>"));
+                               found = 1;
+                       } else if(S_ISREG(sce->st.st_mode)) {
+                               for (k = 0; k < con->conf.mimetypes->used; k++) {
+@@ -854,9 +858,9 @@
+                                       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_len(b,CONST_STR_LEN("<D:getcontenttype>"));
+                                               buffer_append_string_buffer(b, ds->value);
+-                                              buffer_append_string(b, "</D:getcontenttype>");
++                                              buffer_append_string_len(b, CONST_STR_LEN("</D:getcontenttype>"));
+                                               found = 1;
+                                               break;
+@@ -864,26 +868,26 @@
+                               }
+                       }
+               } else if (0 == strcmp(prop_name, "creationdate")) {
+-                      buffer_append_string(b, "<D:creationdate ns0:dt=\"dateTime.tz\">");
++                      buffer_append_string_len(b, CONST_STR_LEN("<D:creationdate ns0:dt=\"dateTime.tz\">"));
+                       strftime(ctime_buf, sizeof(ctime_buf), "%Y-%m-%dT%H:%M:%SZ", gmtime(&(sce->st.st_ctime)));
+                       buffer_append_string(b, ctime_buf);
+-                      buffer_append_string(b, "</D:creationdate>");
++                      buffer_append_string_len(b, CONST_STR_LEN("</D:creationdate>"));
+                       found = 1;
+               } else if (0 == strcmp(prop_name, "getlastmodified")) {
+-                      buffer_append_string(b,"<D:getlastmodified ns0:dt=\"dateTime.rfc1123\">");
++                      buffer_append_string_len(b,CONST_STR_LEN("<D:getlastmodified ns0:dt=\"dateTime.rfc1123\">"));
+                       strftime(mtime_buf, sizeof(mtime_buf), "%a, %d %b %Y %H:%M:%S GMT", gmtime(&(sce->st.st_mtime)));
+                       buffer_append_string(b, mtime_buf);
+-                      buffer_append_string(b, "</D:getlastmodified>");
++                      buffer_append_string_len(b, CONST_STR_LEN("</D:getlastmodified>"));
+                       found = 1;
+               } else if (0 == strcmp(prop_name, "getcontentlength")) {
+-                      buffer_append_string(b,"<D:getcontentlength>");
++                      buffer_append_string_len(b,CONST_STR_LEN("<D:getcontentlength>"));
+                       buffer_append_off_t(b, sce->st.st_size);
+-                      buffer_append_string(b, "</D:getcontentlength>");
++                      buffer_append_string_len(b, CONST_STR_LEN("</D:getcontentlength>"));
+                       found = 1;
+               } else if (0 == strcmp(prop_name, "getcontentlanguage")) {
+-                      buffer_append_string(b,"<D:getcontentlanguage>");
+-                      buffer_append_string(b, "en");
+-                      buffer_append_string(b, "</D:getcontentlanguage>");
++                      buffer_append_string_len(b,CONST_STR_LEN("<D:getcontentlanguage>"));
++                      buffer_append_string_len(b, CONST_STR_LEN("en"));
++                      buffer_append_string_len(b, CONST_STR_LEN("</D:getcontentlanguage>"));
+                       found = 1;
+               }
+       }
+@@ -1103,44 +1107,44 @@
+       b = chunkqueue_get_append_buffer(con->write_queue);
+-      buffer_copy_string(b, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
++      buffer_copy_string_len(b, CONST_STR_LEN("<?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_len(b,CONST_STR_LEN("<D:prop xmlns:D=\"DAV:\" xmlns:ns0=\"urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/\">\n"));
++      buffer_append_string_len(b,CONST_STR_LEN("<D:lockdiscovery>\n"));
++      buffer_append_string_len(b,CONST_STR_LEN("<D:activelock>\n"));
+-      buffer_append_string(b,"<D:lockscope>");
+-      buffer_append_string(b,"<D:");
++      buffer_append_string_len(b,CONST_STR_LEN("<D:lockscope>"));
++      buffer_append_string_len(b,CONST_STR_LEN("<D:"));
+       buffer_append_string(b, lockscope);
+-      buffer_append_string(b, "/>");
+-      buffer_append_string(b,"</D:lockscope>\n");
++      buffer_append_string_len(b, CONST_STR_LEN("/>"));
++      buffer_append_string_len(b,CONST_STR_LEN("</D:lockscope>\n"));
+-      buffer_append_string(b,"<D:locktype>");
+-      buffer_append_string(b,"<D:");
++      buffer_append_string_len(b,CONST_STR_LEN("<D:locktype>"));
++      buffer_append_string_len(b,CONST_STR_LEN("<D:"));
+       buffer_append_string(b, locktype);
+-      buffer_append_string(b, "/>");
+-      buffer_append_string(b,"</D:locktype>\n");
++      buffer_append_string_len(b, CONST_STR_LEN("/>"));
++      buffer_append_string_len(b,CONST_STR_LEN("</D:locktype>\n"));
+-      buffer_append_string(b,"<D:depth>");
++      buffer_append_string_len(b,CONST_STR_LEN("<D:depth>"));
+       buffer_append_string(b, depth == 0 ? "0" : "infinity");
+-      buffer_append_string(b,"</D:depth>\n");
++      buffer_append_string_len(b,CONST_STR_LEN("</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_len(b,CONST_STR_LEN("<D:timeout>"));
++      buffer_append_string_len(b, CONST_STR_LEN("Second-600"));
++      buffer_append_string_len(b,CONST_STR_LEN("</D:timeout>\n"));
+-      buffer_append_string(b,"<D:owner>");
+-      buffer_append_string(b,"</D:owner>\n");
++      buffer_append_string_len(b,CONST_STR_LEN("<D:owner>"));
++      buffer_append_string_len(b,CONST_STR_LEN("</D:owner>\n"));
+-      buffer_append_string(b,"<D:locktoken>");
+-      buffer_append_string(b, "<D:href>");
++      buffer_append_string_len(b,CONST_STR_LEN("<D:locktoken>"));
++      buffer_append_string_len(b, CONST_STR_LEN("<D:href>"));
+       buffer_append_string_buffer(b, locktoken);
+-      buffer_append_string(b, "</D:href>");
+-      buffer_append_string(b,"</D:locktoken>\n");
++      buffer_append_string_len(b, CONST_STR_LEN("</D:href>"));
++      buffer_append_string_len(b,CONST_STR_LEN("</D:locktoken>\n"));
+-      buffer_append_string(b,"</D:activelock>\n");
+-      buffer_append_string(b,"</D:lockdiscovery>\n");
+-      buffer_append_string(b,"</D:prop>\n");
++      buffer_append_string_len(b,CONST_STR_LEN("</D:activelock>\n"));
++      buffer_append_string_len(b,CONST_STR_LEN("</D:lockdiscovery>\n"));
++      buffer_append_string_len(b,CONST_STR_LEN("</D:prop>\n"));
+       return 0;
+ }
 @@ -1154,6 +1158,7 @@
        int has_lock = 1;
  
@@ -1100,10 +2970,753 @@ Index: src/mod_webdav.c
  #endif
  
        return has_lock;
+@@ -1334,9 +1344,9 @@
+               b = chunkqueue_get_append_buffer(con->write_queue);
+-              buffer_copy_string(b, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
++              buffer_copy_string_len(b, CONST_STR_LEN("<?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");
++              buffer_append_string_len(b,CONST_STR_LEN("<D:multistatus xmlns:D=\"DAV:\" xmlns:ns0=\"urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/\">\n"));
+               /* allprop */
+@@ -1348,40 +1358,40 @@
+                       /* 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_len(b,CONST_STR_LEN("<D:response>\n"));
++                      buffer_append_string_len(b,CONST_STR_LEN("<D:href>"));
+                       buffer_append_string_buffer(b, con->uri.scheme);
+-                      buffer_append_string(b,"://");
++                      buffer_append_string_len(b,CONST_STR_LEN("://"));
+                       buffer_append_string_buffer(b, con->uri.authority);
+                       buffer_append_string_encoded(b, CONST_BUF_LEN(con->uri.path), ENCODING_REL_URI);
+-                      buffer_append_string(b,"</D:href>\n");
++                      buffer_append_string_len(b,CONST_STR_LEN("</D:href>\n"));
+                       if (!buffer_is_empty(prop_200)) {
+-                              buffer_append_string(b,"<D:propstat>\n");
+-                              buffer_append_string(b,"<D:prop>\n");
++                              buffer_append_string_len(b,CONST_STR_LEN("<D:propstat>\n"));
++                              buffer_append_string_len(b,CONST_STR_LEN("<D:prop>\n"));
+                               buffer_append_string_buffer(b, prop_200);
+-                              buffer_append_string(b,"</D:prop>\n");
++                              buffer_append_string_len(b,CONST_STR_LEN("</D:prop>\n"));
+-                              buffer_append_string(b,"<D:status>HTTP/1.1 200 OK</D:status>\n");
++                              buffer_append_string_len(b,CONST_STR_LEN("<D:status>HTTP/1.1 200 OK</D:status>\n"));
+-                              buffer_append_string(b,"</D:propstat>\n");
++                              buffer_append_string_len(b,CONST_STR_LEN("</D:propstat>\n"));
+                       }
+                       if (!buffer_is_empty(prop_404)) {
+-                              buffer_append_string(b,"<D:propstat>\n");
+-                              buffer_append_string(b,"<D:prop>\n");
++                              buffer_append_string_len(b,CONST_STR_LEN("<D:propstat>\n"));
++                              buffer_append_string_len(b,CONST_STR_LEN("<D:prop>\n"));
+                               buffer_append_string_buffer(b, prop_404);
+-                              buffer_append_string(b,"</D:prop>\n");
++                              buffer_append_string_len(b,CONST_STR_LEN("</D:prop>\n"));
+-                              buffer_append_string(b,"<D:status>HTTP/1.1 404 Not Found</D:status>\n");
++                              buffer_append_string_len(b,CONST_STR_LEN("<D:status>HTTP/1.1 404 Not Found</D:status>\n"));
+-                              buffer_append_string(b,"</D:propstat>\n");
++                              buffer_append_string_len(b,CONST_STR_LEN("</D:propstat>\n"));
+                       }
+-                      buffer_append_string(b,"</D:response>\n");
++                      buffer_append_string_len(b,CONST_STR_LEN("</D:response>\n"));
+                       break;
+               case 1:
+@@ -1417,40 +1427,40 @@
+                                       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_len(b,CONST_STR_LEN("<D:response>\n"));
++                                      buffer_append_string_len(b,CONST_STR_LEN("<D:href>"));
+                                       buffer_append_string_buffer(b, con->uri.scheme);
+-                                      buffer_append_string(b,"://");
++                                      buffer_append_string_len(b,CONST_STR_LEN("://"));
+                                       buffer_append_string_buffer(b, con->uri.authority);
+                                       buffer_append_string_encoded(b, CONST_BUF_LEN(d.rel_path), ENCODING_REL_URI);
+-                                      buffer_append_string(b,"</D:href>\n");
++                                      buffer_append_string_len(b,CONST_STR_LEN("</D:href>\n"));
+                                       if (!buffer_is_empty(prop_200)) {
+-                                              buffer_append_string(b,"<D:propstat>\n");
+-                                              buffer_append_string(b,"<D:prop>\n");
++                                              buffer_append_string_len(b,CONST_STR_LEN("<D:propstat>\n"));
++                                              buffer_append_string_len(b,CONST_STR_LEN("<D:prop>\n"));
+                                               buffer_append_string_buffer(b, prop_200);
+-                                              buffer_append_string(b,"</D:prop>\n");
++                                              buffer_append_string_len(b,CONST_STR_LEN("</D:prop>\n"));
+-                                              buffer_append_string(b,"<D:status>HTTP/1.1 200 OK</D:status>\n");
++                                              buffer_append_string_len(b,CONST_STR_LEN("<D:status>HTTP/1.1 200 OK</D:status>\n"));
+-                                              buffer_append_string(b,"</D:propstat>\n");
++                                              buffer_append_string_len(b,CONST_STR_LEN("</D:propstat>\n"));
+                                       }
+                                       if (!buffer_is_empty(prop_404)) {
+-                                              buffer_append_string(b,"<D:propstat>\n");
+-                                              buffer_append_string(b,"<D:prop>\n");
++                                              buffer_append_string_len(b,CONST_STR_LEN("<D:propstat>\n"));
++                                              buffer_append_string_len(b,CONST_STR_LEN("<D:prop>\n"));
+                                               buffer_append_string_buffer(b, prop_404);
+-                                              buffer_append_string(b,"</D:prop>\n");
++                                              buffer_append_string_len(b,CONST_STR_LEN("</D:prop>\n"));
+-                                              buffer_append_string(b,"<D:status>HTTP/1.1 404 Not Found</D:status>\n");
++                                              buffer_append_string_len(b,CONST_STR_LEN("<D:status>HTTP/1.1 404 Not Found</D:status>\n"));
+-                                              buffer_append_string(b,"</D:propstat>\n");
++                                              buffer_append_string_len(b,CONST_STR_LEN("</D:propstat>\n"));
+                                       }
+-                                      buffer_append_string(b,"</D:response>\n");
++                                      buffer_append_string_len(b,CONST_STR_LEN("</D:response>\n"));
+                               }
+                               closedir(dir);
+                               buffer_free(d.path);
+@@ -1473,7 +1483,7 @@
+               buffer_free(prop_200);
+               buffer_free(prop_404);
+-              buffer_append_string(b,"</D:multistatus>\n");
++              buffer_append_string_len(b,CONST_STR_LEN("</D:multistatus>\n"));
+               if (p->conf.log_xml) {
+                       log_error_write(srv, __FILE__, __LINE__, "sb", "XML-response-body:", b);
+@@ -1548,13 +1558,13 @@
+                               b = chunkqueue_get_append_buffer(con->write_queue);
+-                              buffer_copy_string(b, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
++                              buffer_copy_string_len(b, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"));
+-                              buffer_append_string(b,"<D:multistatus xmlns:D=\"DAV:\">\n");
++                              buffer_append_string_len(b,CONST_STR_LEN("<D:multistatus xmlns:D=\"DAV:\">\n"));
+                               buffer_append_string_buffer(b, multi_status_resp);
+-                              buffer_append_string(b,"</D:multistatus>\n");
++                              buffer_append_string_len(b,CONST_STR_LEN("</D:multistatus>\n"));
+                               if (p->conf.log_xml) {
+                                       log_error_write(srv, __FILE__, __LINE__, "sb", "XML-response-body:", b);
+@@ -2286,7 +2296,7 @@
+                                                       uuid_generate(id);
+                                                       uuid_unparse(id, uuid);
+-                                                      buffer_copy_string(p->tmp_buf, "opaquelocktoken:");
++                                                      buffer_copy_string_len(p->tmp_buf, CONST_STR_LEN("opaquelocktoken:"));
+                                                       buffer_append_string(p->tmp_buf, uuid);
+                                                       /* "CREATE TABLE locks ("
+Index: src/configparser.y
+===================================================================
+--- src/configparser.y (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/configparser.y (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -21,6 +21,10 @@
+     dc->parent = ctx->current;
+     array_insert_unique(dc->parent->childs, (data_unset *)dc);
+   }
++  if (ctx->configs_stack->used > 0 && ctx->current->context_ndx == 0) {
++    fprintf(stderr, "Cannot use conditionals inside a global { ... } block\n");
++    exit(-1);
++  }
+   array_insert_unique(ctx->configs_stack, (data_unset *)ctx->current);
+   ctx->current = dc;
+ }
+Index: src/mod_status.c
+===================================================================
+--- src/mod_status.c   (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/mod_status.c   (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -143,24 +143,24 @@
+ static int mod_status_row_append(buffer *b, const char *key, const char *value) {
+-      BUFFER_APPEND_STRING_CONST(b, "   <tr>\n");
+-      BUFFER_APPEND_STRING_CONST(b, "    <td><b>");
++      buffer_append_string_len(b, CONST_STR_LEN("   <tr>\n"));
++      buffer_append_string_len(b, CONST_STR_LEN("    <td><b>"));
+       buffer_append_string(b, key);
+-      BUFFER_APPEND_STRING_CONST(b, "</b></td>\n");
+-      BUFFER_APPEND_STRING_CONST(b, "    <td>");
++      buffer_append_string_len(b, CONST_STR_LEN("</b></td>\n"));
++      buffer_append_string_len(b, CONST_STR_LEN("    <td>"));
+       buffer_append_string(b, value);
+-      BUFFER_APPEND_STRING_CONST(b, "</td>\n");
+-      BUFFER_APPEND_STRING_CONST(b, "   </tr>\n");
++      buffer_append_string_len(b, CONST_STR_LEN("</td>\n"));
++      buffer_append_string_len(b, CONST_STR_LEN("   </tr>\n"));
+       return 0;
+ }
+ static int mod_status_header_append(buffer *b, const char *key) {
+-      BUFFER_APPEND_STRING_CONST(b, "   <tr>\n");
+-      BUFFER_APPEND_STRING_CONST(b, "    <th colspan=\"2\">");
++      buffer_append_string_len(b, CONST_STR_LEN("   <tr>\n"));
++      buffer_append_string_len(b, CONST_STR_LEN("    <th colspan=\"2\">"));
+       buffer_append_string(b, key);
+-      BUFFER_APPEND_STRING_CONST(b, "</th>\n");
+-      BUFFER_APPEND_STRING_CONST(b, "   </tr>\n");
++      buffer_append_string_len(b, CONST_STR_LEN("</th>\n"));
++      buffer_append_string_len(b, CONST_STR_LEN("   </tr>\n"));
+       return 0;
+ }
+@@ -169,13 +169,13 @@
+       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_len(b, CONST_STR_LEN("<th class=\"status\"><a href=\"#\" class=\"sortheader\" onclick=\"resort(this);return false;\">"));
+               buffer_append_string(b, key);
+-              BUFFER_APPEND_STRING_CONST(b, "<span class=\"sortarrow\">:</span></a></th>\n");
++              buffer_append_string_len(b, CONST_STR_LEN("<span class=\"sortarrow\">:</span></a></th>\n"));
+       } else {
+-              BUFFER_APPEND_STRING_CONST(b, "<th class=\"status\">");
++              buffer_append_string_len(b, CONST_STR_LEN("<th class=\"status\">"));
+               buffer_append_string(b, key);
+-              BUFFER_APPEND_STRING_CONST(b, "</th>\n");
++              buffer_append_string_len(b, CONST_STR_LEN("</th>\n"));
+       }
+       return 0;
+@@ -209,15 +209,14 @@
+       b = chunkqueue_get_append_buffer(con->write_queue);
+-      BUFFER_COPY_STRING_CONST(b,
++      buffer_copy_string_len(b, CONST_STR_LEN(
+                                "<?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");
++                               "  <title>Status</title>\n"
+-      BUFFER_APPEND_STRING_CONST(b,
+                                  "  <style type=\"text/css\">\n"
+                                  "    table.status { border: black solid thin; }\n"
+                                  "    td { white-space: nowrap; }\n"
+@@ -226,16 +225,15 @@
+                                  "    th.status { background-color: black; color: white; font-weight: bold; }\n"
+                                  "    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");
++                                 "  </style>\n"));
+       if (p->conf.sort) {
+-              BUFFER_APPEND_STRING_CONST(b,
++              buffer_append_string_len(b, CONST_STR_LEN(
+                                          "<script type=\"text/javascript\">\n"
+                                          "// <!--\n"
+                                          "var sort_column;\n"
+-                                         "var prev_span = null;\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"
+                                          "  return el;\n"
+@@ -251,9 +249,8 @@
+                                          "  }\n"
+                                          " }\n"
+                                          " return str;\n"
+-                                         "}\n");
++                                         "}\n"
+-              BUFFER_APPEND_STRING_CONST(b,
+                                          "function sortfn(a,b) {\n"
+                                          " var at = get_inner_text(a.cells[sort_column]);\n"
+                                          " var bt = get_inner_text(b.cells[sort_column]);\n"
+@@ -266,9 +263,8 @@
+                                          "  else if (aa<bb) return -1;\n"
+                                          "  else return 1;\n"
+                                          " }\n"
+-                                         "}\n");
++                                         "}\n"
+-              BUFFER_APPEND_STRING_CONST(b,
+                                          "function resort(lnk) {\n"
+                                          " var span = lnk.childNodes[1];\n"
+                                          " var table = lnk.parentNode.parentNode.parentNode.parentNode;\n"
+@@ -276,9 +272,8 @@
+                                          " for (j=1;j<table.rows.length;j++)\n"
+                                          "  rows[j-1] = table.rows[j];\n"
+                                          " sort_column = lnk.parentNode.cellIndex;\n"
+-                                         " rows.sort(sortfn);\n");
++                                         " rows.sort(sortfn);\n"
+-              BUFFER_APPEND_STRING_CONST(b,
+                                          " if (prev_span != null) prev_span.innerHTML = '';\n"
+                                          " if (span.getAttribute('sortdir')=='down') {\n"
+                                          "  span.innerHTML = '&uarr;';\n"
+@@ -293,25 +288,25 @@
+                                          " prev_span = span;\n"
+                                          "}\n"
+                                          "// -->\n"
+-                                         "</script>\n");
++                                         "</script>\n"));
+       }
+-      BUFFER_APPEND_STRING_CONST(b,
++      buffer_append_string_len(b, CONST_STR_LEN(
+                                " </head>\n"
+-                               " <body>\n");
++                               " <body>\n"));
+       /* connection listing */
+-      BUFFER_APPEND_STRING_CONST(b, "<h1>Server-Status</h1>");
++      buffer_append_string_len(b, CONST_STR_LEN("<h1>Server-Status</h1>"));
+-      BUFFER_APPEND_STRING_CONST(b, "<table summary=\"status\" class=\"status\">");
+-      BUFFER_APPEND_STRING_CONST(b, "<tr><td>Hostname</td><td class=\"string\">");
++      buffer_append_string_len(b, CONST_STR_LEN("<table summary=\"status\" class=\"status\">"));
++      buffer_append_string_len(b, CONST_STR_LEN("<tr><td>Hostname</td><td class=\"string\">"));
+       buffer_append_string_buffer(b, con->uri.authority);
+-      BUFFER_APPEND_STRING_CONST(b, " (");
++      buffer_append_string_len(b, CONST_STR_LEN(" ("));
+       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_len(b, CONST_STR_LEN(")</td></tr>\n"));
++      buffer_append_string_len(b, CONST_STR_LEN("<tr><td>Uptime</td><td class=\"string\">"));
+       ts = srv->cur_ts - srv->startup_ts;
+@@ -328,98 +323,98 @@
+       if (days) {
+               buffer_append_long(b, days);
+-              BUFFER_APPEND_STRING_CONST(b, " days ");
++              buffer_append_string_len(b, CONST_STR_LEN(" days "));
+       }
+       if (hours) {
+               buffer_append_long(b, hours);
+-              BUFFER_APPEND_STRING_CONST(b, " hours ");
++              buffer_append_string_len(b, CONST_STR_LEN(" hours "));
+       }
+       if (mins) {
+               buffer_append_long(b, mins);
+-              BUFFER_APPEND_STRING_CONST(b, " min ");
++              buffer_append_string_len(b, CONST_STR_LEN(" min "));
+       }
+       buffer_append_long(b, seconds);
+-      BUFFER_APPEND_STRING_CONST(b, " s");
++      buffer_append_string_len(b, CONST_STR_LEN(" s"));
+-      BUFFER_APPEND_STRING_CONST(b, "</td></tr>\n");
+-      BUFFER_APPEND_STRING_CONST(b, "<tr><td>Started at</td><td class=\"string\">");
++      buffer_append_string_len(b, CONST_STR_LEN("</td></tr>\n"));
++      buffer_append_string_len(b, CONST_STR_LEN("<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));
+       buffer_append_string(b, buf);
+-      BUFFER_APPEND_STRING_CONST(b, "</td></tr>\n");
++      buffer_append_string_len(b, CONST_STR_LEN("</td></tr>\n"));
+-      BUFFER_APPEND_STRING_CONST(b, "<tr><th colspan=\"2\">absolute (since start)</th></tr>\n");
++      buffer_append_string_len(b, CONST_STR_LEN("<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_len(b, CONST_STR_LEN("<tr><td>Requests</td><td class=\"string\">"));
+       avg = p->abs_requests;
+       mod_status_get_multiplier(&avg, &multiplier, 1000);
+       buffer_append_long(b, avg);
+-      BUFFER_APPEND_STRING_CONST(b, " ");
++      buffer_append_string_len(b, CONST_STR_LEN(" "));
+       if (multiplier) buffer_append_string_len(b, &multiplier, 1);
+-      BUFFER_APPEND_STRING_CONST(b, "req</td></tr>\n");
++      buffer_append_string_len(b, CONST_STR_LEN("req</td></tr>\n"));
+-      BUFFER_APPEND_STRING_CONST(b, "<tr><td>Traffic</td><td class=\"string\">");
++      buffer_append_string_len(b, CONST_STR_LEN("<tr><td>Traffic</td><td class=\"string\">"));
+       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_len(b, CONST_STR_LEN(" "));
+       if (multiplier) buffer_append_string_len(b, &multiplier, 1);
+-      BUFFER_APPEND_STRING_CONST(b, "byte</td></tr>\n");
++      buffer_append_string_len(b, CONST_STR_LEN("byte</td></tr>\n"));
+-      BUFFER_APPEND_STRING_CONST(b, "<tr><th colspan=\"2\">average (since start)</th></tr>\n");
++      buffer_append_string_len(b, CONST_STR_LEN("<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_len(b, CONST_STR_LEN("<tr><td>Requests</td><td class=\"string\">"));
+       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_len(b, CONST_STR_LEN(" "));
+       if (multiplier) buffer_append_string_len(b, &multiplier, 1);
+-      BUFFER_APPEND_STRING_CONST(b, "req/s</td></tr>\n");
++      buffer_append_string_len(b, CONST_STR_LEN("req/s</td></tr>\n"));
+-      BUFFER_APPEND_STRING_CONST(b, "<tr><td>Traffic</td><td class=\"string\">");
++      buffer_append_string_len(b, CONST_STR_LEN("<tr><td>Traffic</td><td class=\"string\">"));
+       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_len(b, CONST_STR_LEN(" "));
+       if (multiplier) buffer_append_string_len(b, &multiplier, 1);
+-      BUFFER_APPEND_STRING_CONST(b, "byte/s</td></tr>\n");
++      buffer_append_string_len(b, CONST_STR_LEN("byte/s</td></tr>\n"));
+-      BUFFER_APPEND_STRING_CONST(b, "<tr><th colspan=\"2\">average (5s sliding average)</th></tr>\n");
++      buffer_append_string_len(b, CONST_STR_LEN("<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_len(b, CONST_STR_LEN("<tr><td>Requests</td><td class=\"string\">"));
+       mod_status_get_multiplier(&avg, &multiplier, 1000);
+       buffer_append_long(b, avg);
+-      BUFFER_APPEND_STRING_CONST(b, " ");
++      buffer_append_string_len(b, CONST_STR_LEN(" "));
+       if (multiplier) buffer_append_string_len(b, &multiplier, 1);
+-      BUFFER_APPEND_STRING_CONST(b, "req/s</td></tr>\n");
++      buffer_append_string_len(b, CONST_STR_LEN("req/s</td></tr>\n"));
+       for (j = 0, avg = 0; j < 5; j++) {
+               avg += p->mod_5s_traffic_out[j];
+@@ -427,28 +422,29 @@
+       avg /= 5;
+-      BUFFER_APPEND_STRING_CONST(b, "<tr><td>Traffic</td><td class=\"string\">");
++      buffer_append_string_len(b, CONST_STR_LEN("<tr><td>Traffic</td><td class=\"string\">"));
+       mod_status_get_multiplier(&avg, &multiplier, 1024);
+       sprintf(buf, "%.2f", avg);
+       buffer_append_string(b, buf);
+-      BUFFER_APPEND_STRING_CONST(b, " ");
++      buffer_append_string_len(b, CONST_STR_LEN(" "));
+       if (multiplier) buffer_append_string_len(b, &multiplier, 1);
+-      BUFFER_APPEND_STRING_CONST(b, "byte/s</td></tr>\n");
++      buffer_append_string_len(b, CONST_STR_LEN("byte/s</td></tr>\n"));
+-      BUFFER_APPEND_STRING_CONST(b, "</table>\n");
++      buffer_append_string_len(b, CONST_STR_LEN("</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_len(b, CONST_STR_LEN(
++              "<hr />\n<pre><b>legend</b>\n"
++              ". = connect, C = close, E = hard error\n"
++              "r = read, R = read-POST, W = write, h = handle-request\n"
++              "q = request-start,  Q = request-end\n"
++              "s = response-start, S = response-end\n"));
+-      BUFFER_APPEND_STRING_CONST(b, "<b>");
++      buffer_append_string_len(b, CONST_STR_LEN("<b>"));
+       buffer_append_long(b, srv->conns->used);
+-      BUFFER_APPEND_STRING_CONST(b, " connections</b>\n");
++      buffer_append_string_len(b, CONST_STR_LEN(" connections</b>\n"));
+       for (j = 0; j < srv->conns->used; j++) {
+               connection *c = srv->conns->ptr[j];
+@@ -457,14 +453,14 @@
+               buffer_append_string_len(b, state, 1);
+               if (((j + 1) % 50) == 0) {
+-                      BUFFER_APPEND_STRING_CONST(b, "\n");
++                      buffer_append_string_len(b, CONST_STR_LEN("\n"));
+               }
+       }
+-      BUFFER_APPEND_STRING_CONST(b, "\n</pre><hr />\n<h2>Connections</h2>\n");
++      buffer_append_string_len(b, CONST_STR_LEN("\n</pre><hr />\n<h2>Connections</h2>\n"));
+-      BUFFER_APPEND_STRING_CONST(b, "<table summary=\"status\" class=\"status\">\n");
+-      BUFFER_APPEND_STRING_CONST(b, "<tr>");
++      buffer_append_string_len(b, CONST_STR_LEN("<table summary=\"status\" class=\"status\">\n"));
++      buffer_append_string_len(b, CONST_STR_LEN("<tr>"));
+       mod_status_header_append_sort(b, p_d, "Client IP");
+       mod_status_header_append_sort(b, p_d, "Read");
+       mod_status_header_append_sort(b, p_d, "Written");
+@@ -473,40 +469,40 @@
+       mod_status_header_append_sort(b, p_d, "Host");
+       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");
++      buffer_append_string_len(b, CONST_STR_LEN("</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_len(b, CONST_STR_LEN("<tr><td class=\"string\">"));
+               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_len(b, CONST_STR_LEN("</td><td class=\"int\">"));
+               if (con->request.content_length) {
+                       buffer_append_long(b, c->request_content_queue->bytes_in);
+-                      BUFFER_APPEND_STRING_CONST(b, "/");
++                      buffer_append_string_len(b, CONST_STR_LEN("/"));
+                       buffer_append_long(b, c->request.content_length);
+               } else {
+-                      BUFFER_APPEND_STRING_CONST(b, "0/0");
++                      buffer_append_string_len(b, CONST_STR_LEN("0/0"));
+               }
+-              BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"int\">");
++              buffer_append_string_len(b, CONST_STR_LEN("</td><td class=\"int\">"));
+               buffer_append_off_t(b, chunkqueue_written(c->write_queue));
+-              BUFFER_APPEND_STRING_CONST(b, "/");
++              buffer_append_string_len(b, CONST_STR_LEN("/"));
+               buffer_append_off_t(b, chunkqueue_length(c->write_queue));
+-              BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string\">");
++              buffer_append_string_len(b, CONST_STR_LEN("</td><td class=\"string\">"));
+               buffer_append_string(b, connection_get_state(c->state));
+-              BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"int\">");
++              buffer_append_string_len(b, CONST_STR_LEN("</td><td class=\"int\">"));
+               buffer_append_long(b, srv->cur_ts - c->request_start);
+-              BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string\">");
++              buffer_append_string_len(b, CONST_STR_LEN("</td><td class=\"string\">"));
+               if (buffer_is_empty(c->server_name)) {
+                       buffer_append_string_buffer(b, c->uri.authority);
+@@ -515,38 +511,38 @@
+                       buffer_append_string_buffer(b, c->server_name);
+               }
+-              BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string\">");
++              buffer_append_string_len(b, CONST_STR_LEN("</td><td class=\"string\">"));
+               if (!buffer_is_empty(c->uri.path)) {
+                       buffer_append_string_encoded(b, CONST_BUF_LEN(c->uri.path), ENCODING_HTML);
+               }
+               if (!buffer_is_empty(c->uri.query)) {
+-                      BUFFER_APPEND_STRING_CONST(b, "?");
++                      buffer_append_string_len(b, CONST_STR_LEN("?"));
+                       buffer_append_string_encoded(b, CONST_BUF_LEN(c->uri.query), ENCODING_HTML);
+               }
+               if (!buffer_is_empty(c->request.orig_uri)) {
+-                      BUFFER_APPEND_STRING_CONST(b, " (");
++                      buffer_append_string_len(b, CONST_STR_LEN(" ("));
+                       buffer_append_string_encoded(b, CONST_BUF_LEN(c->request.orig_uri), ENCODING_HTML);
+-                      BUFFER_APPEND_STRING_CONST(b, ")");
++                      buffer_append_string_len(b, CONST_STR_LEN(")"));
+               }
+-              BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string\">");
++              buffer_append_string_len(b, CONST_STR_LEN("</td><td class=\"string\">"));
+               buffer_append_string_buffer(b, c->physical.path);
+-              BUFFER_APPEND_STRING_CONST(b, "</td></tr>\n");
++              buffer_append_string_len(b, CONST_STR_LEN("</td></tr>\n"));
+       }
+-      BUFFER_APPEND_STRING_CONST(b,
+-                    "</table>\n");
++      buffer_append_string_len(b, CONST_STR_LEN(
++                    "</table>\n"));
+-      BUFFER_APPEND_STRING_CONST(b,
++      buffer_append_string_len(b, CONST_STR_LEN(
+                     " </body>\n"
+                     "</html>\n"
+-                    );
++                    ));
+       response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html"));
+@@ -566,45 +562,45 @@
+       b = chunkqueue_get_append_buffer(con->write_queue);
+       /* output total number of requests */
+-      BUFFER_APPEND_STRING_CONST(b, "Total Accesses: ");
++      buffer_append_string_len(b, CONST_STR_LEN("Total Accesses: "));
+       avg = p->abs_requests;
+       snprintf(buf, sizeof(buf) - 1, "%.0f", avg);
+       buffer_append_string(b, buf);
+-      BUFFER_APPEND_STRING_CONST(b, "\n");
++      buffer_append_string_len(b, CONST_STR_LEN("\n"));
+       /* output total traffic out in kbytes */
+-      BUFFER_APPEND_STRING_CONST(b, "Total kBytes: ");
++      buffer_append_string_len(b, CONST_STR_LEN("Total kBytes: "));
+       avg = p->abs_traffic_out / 1024;
+       snprintf(buf, sizeof(buf) - 1, "%.0f", avg);
+       buffer_append_string(b, buf);
+-      BUFFER_APPEND_STRING_CONST(b, "\n");
++      buffer_append_string_len(b, CONST_STR_LEN("\n"));
+       /* output uptime */
+-      BUFFER_APPEND_STRING_CONST(b, "Uptime: ");
++      buffer_append_string_len(b, CONST_STR_LEN("Uptime: "));
+       ts = srv->cur_ts - srv->startup_ts;
+       buffer_append_long(b, ts);
+-      BUFFER_APPEND_STRING_CONST(b, "\n");
++      buffer_append_string_len(b, CONST_STR_LEN("\n"));
+       /* output busy servers */
+-      BUFFER_APPEND_STRING_CONST(b, "BusyServers: ");
++      buffer_append_string_len(b, CONST_STR_LEN("BusyServers: "));
+       buffer_append_long(b, srv->conns->used);
+-      BUFFER_APPEND_STRING_CONST(b, "\n");
++      buffer_append_string_len(b, CONST_STR_LEN("\n"));
+-      BUFFER_APPEND_STRING_CONST(b, "IdleServers: ");
++      buffer_append_string_len(b, CONST_STR_LEN("IdleServers: "));
+        buffer_append_long(b, srv->conns->size - srv->conns->used);
+-       BUFFER_APPEND_STRING_CONST(b, "\n");
++       buffer_append_string_len(b, CONST_STR_LEN("\n"));
+        /* output scoreboard */
+-       BUFFER_APPEND_STRING_CONST(b, "Scoreboard: ");
++       buffer_append_string_len(b, CONST_STR_LEN("Scoreboard: "));
+        for (k = 0; k < srv->conns->used; k++) {
+               connection *c = srv->conns->ptr[k];
+               const char *state = connection_get_short_state(c->state);
+               buffer_append_string_len(b, state, 1);
+       }
+       for (l = 0; l < srv->conns->size - srv->conns->used; l++) {
+-              BUFFER_APPEND_STRING_CONST(b, "_");
++              buffer_append_string_len(b, CONST_STR_LEN("_"));
+       }
+-      BUFFER_APPEND_STRING_CONST(b, "\n");
++      buffer_append_string_len(b, CONST_STR_LEN("\n"));
+       /* set text/plain output */
+@@ -633,9 +629,9 @@
+               size_t ndx = st->sorted[i];
+               buffer_append_string_buffer(b, st->data[ndx]->key);
+-              buffer_append_string(b, ": ");
++              buffer_append_string_len(b, CONST_STR_LEN(": "));
+               buffer_append_long(b, ((data_integer *)(st->data[ndx]))->value);
+-              buffer_append_string(b, "\n");
++              buffer_append_string_len(b, CONST_STR_LEN("\n"));
+       }
+       response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/plain"));
+@@ -696,7 +692,7 @@
+       b = chunkqueue_get_append_buffer(con->write_queue);
+-      BUFFER_COPY_STRING_CONST(b,
++      buffer_copy_string_len(b, CONST_STR_LEN(
+                          "<?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"
+@@ -706,7 +702,7 @@
+                          " </head>\n"
+                          " <body>\n"
+                          "  <h1>" PACKAGE_NAME " " PACKAGE_VERSION "</h1>\n"
+-                         "  <table summary=\"status\" border=\"1\">\n");
++                         "  <table summary=\"status\" border=\"1\">\n"));
+       mod_status_header_append(b, "Server-Features");
+ #ifdef HAVE_PCRE_H
+@@ -733,19 +729,19 @@
+               if (i == 0) {
+                       buffer_copy_string_buffer(m, pl->name);
+               } else {
+-                      BUFFER_APPEND_STRING_CONST(m, "<br />");
++                      buffer_append_string_len(m, CONST_STR_LEN("<br />"));
+                       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_len(b, CONST_STR_LEN("  </table>\n"));
+-      BUFFER_APPEND_STRING_CONST(b,
++      buffer_append_string_len(b, CONST_STR_LEN(
+                     " </body>\n"
+                     "</html>\n"
+-                    );
++                    ));
+       response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html"));
+@@ -796,6 +792,8 @@
+ static handler_t mod_status_handler(server *srv, connection *con, void *p_d) {
+       plugin_data *p = p_d;
++      if (con->mode != DIRECT) return HANDLER_GO_ON;
++
+       mod_status_patch_connection(srv, con, p);
+       if (!buffer_is_empty(p->conf.status_url) &&
 Index: src/md5.c
 ===================================================================
---- src/md5.c  (.../tags/lighttpd-1.4.19)      (revision 2199)
-+++ src/md5.c  (.../branches/lighttpd-1.4.x)   (revision 2199)
+--- src/md5.c  (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/md5.c  (.../branches/lighttpd-1.4.x)   (revision 2303)
 @@ -52,9 +52,9 @@
  #define S43 15
  #define S44 21
@@ -1152,8 +3765,8 @@ Index: src/md5.c
    unsigned int i, j;
 Index: src/mod_compress.c
 ===================================================================
---- src/mod_compress.c (.../tags/lighttpd-1.4.19)      (revision 2199)
-+++ src/mod_compress.c (.../branches/lighttpd-1.4.x)   (revision 2199)
+--- src/mod_compress.c (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/mod_compress.c (.../branches/lighttpd-1.4.x)   (revision 2303)
 @@ -102,7 +102,7 @@
        return HANDLER_GO_ON;
  }
@@ -1199,10 +3812,27 @@ Index: src/mod_compress.c
                        if (0 != stat(s->compress_cache_dir->ptr, &st)) {
                                log_error_write(srv, __FILE__, __LINE__, "sbs", "can't stat compress.cache-dir",
                                                s->compress_cache_dir, strerror(errno));
+@@ -396,13 +396,13 @@
+       switch(type) {
+       case HTTP_ACCEPT_ENCODING_GZIP:
+-              buffer_append_string(p->ofn, "-gzip-");
++              buffer_append_string_len(p->ofn, CONST_STR_LEN("-gzip-"));
+               break;
+       case HTTP_ACCEPT_ENCODING_DEFLATE:
+-              buffer_append_string(p->ofn, "-deflate-");
++              buffer_append_string_len(p->ofn, CONST_STR_LEN("-deflate-"));
+               break;
+       case HTTP_ACCEPT_ENCODING_BZIP2:
+-              buffer_append_string(p->ofn, "-bzip2-");
++              buffer_append_string_len(p->ofn, CONST_STR_LEN("-bzip2-"));
+               break;
+       default:
+               log_error_write(srv, __FILE__, __LINE__, "sd", "unknown compression type", type);
 Index: src/md5.h
 ===================================================================
---- src/md5.h  (.../tags/lighttpd-1.4.19)      (revision 2199)
-+++ src/md5.h  (.../branches/lighttpd-1.4.x)   (revision 2199)
+--- src/md5.h  (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/md5.h  (.../branches/lighttpd-1.4.x)   (revision 2303)
 @@ -42,6 +42,6 @@
  } MD5_CTX;
  
@@ -1211,10 +3841,133 @@ Index: src/md5.h
 +void MD5_Update (MD5_CTX *, const void *, unsigned int);
  void MD5_Final (unsigned char [16], MD5_CTX *);
  
+Index: src/mod_ssi.c
+===================================================================
+--- src/mod_ssi.c      (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/mod_ssi.c      (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -177,7 +177,7 @@
+                       }
+                       if (0 != strcasecmp(ds->key->ptr, "CONTENT-TYPE")) {
+-                              buffer_copy_string(srv->tmp_buf, "HTTP_");
++                              buffer_copy_string_len(srv->tmp_buf, CONST_STR_LEN("HTTP_"));
+                               srv->tmp_buf->used--;
+                       }
+@@ -419,7 +419,7 @@
+                       b = chunkqueue_get_append_buffer(con->write_queue);
+                       if (0 == strftime(buf, sizeof(buf), p->timefmt->ptr, localtime(&t))) {
+-                              buffer_copy_string(b, "(none)");
++                              buffer_copy_string_len(b, CONST_STR_LEN("(none)"));
+                       } else {
+                               buffer_copy_string(b, buf);
+                       }
+@@ -430,7 +430,7 @@
+                       b = chunkqueue_get_append_buffer(con->write_queue);
+                       if (0 == strftime(buf, sizeof(buf), p->timefmt->ptr, localtime(&t))) {
+-                              buffer_copy_string(b, "(none)");
++                              buffer_copy_string_len(b, CONST_STR_LEN("(none)"));
+                       } else {
+                               buffer_copy_string(b, buf);
+                       }
+@@ -441,7 +441,7 @@
+                       b = chunkqueue_get_append_buffer(con->write_queue);
+                       if (0 == strftime(buf, sizeof(buf), p->timefmt->ptr, gmtime(&t))) {
+-                              buffer_copy_string(b, "(none)");
++                              buffer_copy_string_len(b, CONST_STR_LEN("(none)"));
+                       } else {
+                               buffer_copy_string(b, buf);
+                       }
+@@ -472,7 +472,7 @@
+                       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)");
++                              buffer_copy_string_len(b, CONST_STR_LEN("(none)"));
+                       }
+                       break;
+@@ -519,7 +519,7 @@
+               if (file_path) {
+                       /* current doc-root */
+                       if (NULL == (sl = strrchr(con->physical.path->ptr, '/'))) {
+-                              buffer_copy_string(p->stat_fn, "/");
++                              buffer_copy_string_len(p->stat_fn, CONST_STR_LEN("/"));
+                       } else {
+                               buffer_copy_string_len(p->stat_fn, con->physical.path->ptr, sl - con->physical.path->ptr + 1);
+                       }
+@@ -573,7 +573,7 @@
+                       case SSI_FLASTMOD:
+                               b = chunkqueue_get_append_buffer(con->write_queue);
+                               if (0 == strftime(buf, sizeof(buf), p->timefmt->ptr, localtime(&t))) {
+-                                      buffer_copy_string(b, "(none)");
++                                      buffer_copy_string_len(b, CONST_STR_LEN("(none)"));
+                               } else {
+                                       buffer_copy_string(b, buf);
+                               }
+@@ -656,17 +656,17 @@
+               if (p->if_is_false) break;
+               b = chunkqueue_get_append_buffer(con->write_queue);
+-              buffer_copy_string(b, "<pre>");
++              buffer_copy_string_len(b, CONST_STR_LEN("<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_len(b, CONST_STR_LEN(": "));
+                       buffer_append_string_buffer(b, ds->value);
+-                      buffer_append_string(b, "<br />");
++                      buffer_append_string_len(b, CONST_STR_LEN("<br />"));
+               }
+-              buffer_append_string(b, "</pre>");
++              buffer_append_string_len(b, CONST_STR_LEN("</pre>"));
+               break;
+       case SSI_EXEC: {
+@@ -924,7 +924,7 @@
+       array_reset(p->ssi_vars);
+       array_reset(p->ssi_cgi_env);
+-      buffer_copy_string(p->timefmt, "%a, %d %b %Y %H:%M:%S %Z");
++      buffer_copy_string_len(p->timefmt, CONST_STR_LEN("%a, %d %b %Y %H:%M:%S %Z"));
+       p->sizefmt = 0;
+       build_ssi_cgi_vars(srv, con, p);
+       p->if_is_false = 0;
+@@ -1027,6 +1027,7 @@
+       con->file_started  = 1;
+       con->file_finished = 1;
++      con->mode = p->id;
+       response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html"));
+@@ -1094,6 +1095,8 @@
+       plugin_data *p = p_d;
+       size_t k;
++      if (con->mode != DIRECT) return HANDLER_GO_ON;
++
+       if (con->physical.path->used == 0) return HANDLER_GO_ON;
+       mod_ssi_patch_connection(srv, con, p);
+@@ -1109,6 +1112,7 @@
+                       if (mod_ssi_handle_request(srv, con, p)) {
+                               /* on error */
+                               con->http_status = 500;
++                              con->mode = DIRECT;
+                       }
+                       return HANDLER_FINISHED;
 Index: src/spawn-fcgi.c
 ===================================================================
---- src/spawn-fcgi.c   (.../tags/lighttpd-1.4.19)      (revision 2199)
-+++ src/spawn-fcgi.c   (.../branches/lighttpd-1.4.x)   (revision 2199)
+--- src/spawn-fcgi.c   (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/spawn-fcgi.c   (.../branches/lighttpd-1.4.x)   (revision 2303)
 @@ -37,9 +37,9 @@
  #endif
  
@@ -1594,23 +4347,145 @@ Index: src/spawn-fcgi.c
                                initgroups(username, grp->gr_gid);
                        }
 +
-               }
+               }
+               if (changeroot) {
+@@ -451,7 +471,7 @@
+               }
+       }
+-       return fcgi_spawn_connection(fcgi_app, fcgi_app_argv, addr, port, unixsocket, child_count, pid_fd, nofork);
++       return fcgi_spawn_connection(fcgi_app, fcgi_app_argv, addr, port, unixsocket, fork_count, child_count, pid_fd, nofork);
+ }
+ #else
+ int main() {
+Index: src/mod_auth.c
+===================================================================
+--- src/mod_auth.c     (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/mod_auth.c     (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -150,13 +150,15 @@
+                               PATCH(auth_ldap_hostname);
+ #ifdef USE_LDAP
+                               PATCH(ldap);
+-                              PATCH(ldap_filter_pre);
+-                              PATCH(ldap_filter_post);
+ #endif
+                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.base-dn"))) {
+                               PATCH(auth_ldap_basedn);
+                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.filter"))) {
+                               PATCH(auth_ldap_filter);
++#ifdef USE_LDAP
++                              PATCH(ldap_filter_pre);
++                              PATCH(ldap_filter_post);
++#endif
+                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.ca-file"))) {
+                               PATCH(auth_ldap_cafile);
+                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.starttls"))) {
+@@ -248,6 +250,7 @@
+                               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;
++                                              con->mode = DIRECT;
+                                               /* a field was missing */
+@@ -268,22 +271,23 @@
+               realm = (data_string *)array_get_element(req, "realm");
+               con->http_status = 401;
++              con->mode = DIRECT;
+               if (0 == strcmp(method->value->ptr, "basic")) {
+-                      buffer_copy_string(p->tmp_buf, "Basic realm=\"");
++                      buffer_copy_string_len(p->tmp_buf, CONST_STR_LEN("Basic realm=\""));
+                       buffer_append_string_buffer(p->tmp_buf, realm->value);
+-                      buffer_append_string(p->tmp_buf, "\"");
++                      buffer_append_string_len(p->tmp_buf, CONST_STR_LEN("\""));
+                       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_copy_string_len(p->tmp_buf, CONST_STR_LEN("Digest realm=\""));
+                       buffer_append_string_buffer(p->tmp_buf, realm->value);
+-                      buffer_append_string(p->tmp_buf, "\", nonce=\"");
++                      buffer_append_string_len(p->tmp_buf, CONST_STR_LEN("\", nonce=\""));
+                       buffer_append_string(p->tmp_buf, hh);
+-                      buffer_append_string(p->tmp_buf, "\", qop=\"auth\"");
++                      buffer_append_string_len(p->tmp_buf, CONST_STR_LEN("\", qop=\"auth\""));
+                       response_header_insert(srv, con, CONST_STR_LEN("WWW-Authenticate"), CONST_BUF_LEN(p->tmp_buf));
+               } else {
+@@ -393,6 +397,23 @@
+                       }
+               }
++#ifdef USE_LDAP
++              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);
++              }
++#endif
++
+               /* no auth.require for this section */
+               if (NULL == (da = (data_array *)array_get_element(ca, "auth.require"))) continue;
  
-               if (changeroot) {
-@@ -451,7 +471,7 @@
+@@ -479,21 +500,21 @@
+                               ds = data_string_init();
+-                              buffer_copy_string(ds->key, "method");
++                              buffer_copy_string_len(ds->key, CONST_STR_LEN("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_len(ds->key, CONST_STR_LEN("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_len(ds->key, CONST_STR_LEN("require"));
+                               buffer_copy_string(ds->value, require);
+                               array_insert_unique(a->value, (data_unset *)ds);
+@@ -507,97 +528,83 @@
+                       handler_t ret = auth_ldap_init(srv, s);
+                       if (ret == HANDLER_ERROR)
+                               return (ret);
+-                        break;
++                      break;
                }
-       }
+-                default:
+-                        break;
+-                }
+-        }
++              default:
++                      break;
++              }
++      }
  
--       return fcgi_spawn_connection(fcgi_app, fcgi_app_argv, addr, port, unixsocket, child_count, pid_fd, nofork);
-+       return fcgi_spawn_connection(fcgi_app, fcgi_app_argv, addr, port, unixsocket, fork_count, child_count, pid_fd, nofork);
+-        return HANDLER_GO_ON;
++      return HANDLER_GO_ON;
  }
- #else
- int main() {
-Index: src/mod_auth.c
-===================================================================
---- src/mod_auth.c     (.../tags/lighttpd-1.4.19)      (revision 2199)
-+++ src/mod_auth.c     (.../branches/lighttpd-1.4.x)   (revision 2199)
-@@ -519,85 +519,86 @@
  
  handler_t auth_ldap_init(server *srv, mod_auth_plugin_config *s) {
  #ifdef USE_LDAP
@@ -1630,16 +4505,19 @@ Index: src/mod_auth.c
  
 -                      if (s->auth_ldap_filter->used) {
 -                              char *dollar;
-+      if (s->auth_ldap_filter->used) {
-+              char *dollar;
++      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));
  
 -                              /* parse filter */
-+              /* parse filter */
++                      return HANDLER_ERROR;
++              }
  
 -                              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 '$'");
-+              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 '$'");
++              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;
 -                              }
@@ -1649,32 +4527,6 @@ Index: src/mod_auth.c
 -                              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);
 -                      }
-+              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));
-+      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;
--                              }
-+                      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));
-+              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 the server requires a CAfile it will tell us */
@@ -1683,11 +4535,27 @@ Index: src/mod_auth.c
 +                                                              s->auth_ldap_cafile->ptr))) {
 +                                      log_error_write(srv, __FILE__, __LINE__, "ss",
 +                                                      "Loading CA certificate failed:", ldap_err2string(ret));
-+
+-                      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));
++                      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;
+-                              }
++                              return HANDLER_ERROR;
++                      }
++              }
 -                              if (s->auth_ldap_starttls) {
 -                                      /* if no CA file is given, it is ok, as we will use encryption
 -                                       * if the server requires a CAfile it will tell us */
@@ -1696,33 +4564,28 @@ Index: src/mod_auth.c
 -                                                                              s->auth_ldap_cafile->ptr))) {
 -                                                      log_error_write(srv, __FILE__, __LINE__, "ss",
 -                                                                      "Loading CA certificate failed:", ldap_err2string(ret));
-+                      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;
 -                                              }
 -                                      }
-+                              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));
  
+-                                      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;
 +                      }
 +              } 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;
+-                                      }
+-                              }
+-
+-
 -                              /* 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))) {
@@ -1753,10 +4616,215 @@ Index: src/mod_auth.c
  }
  
  int mod_auth_plugin_init(plugin *p) {
+Index: src/data_string.c
+===================================================================
+--- src/data_string.c  (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/data_string.c  (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -37,7 +37,7 @@
+       data_string *ds_src = (data_string *)src;
+       if (ds_dst->value->used) {
+-              buffer_append_string(ds_dst->value, ", ");
++              buffer_append_string_len(ds_dst->value, CONST_STR_LEN(", "));
+               buffer_append_string_buffer(ds_dst->value, ds_src->value);
+       } else {
+               buffer_copy_string_buffer(ds_dst->value, ds_src->value);
+@@ -53,9 +53,9 @@
+       data_string *ds_src = (data_string *)src;
+       if (ds_dst->value->used) {
+-              buffer_append_string(ds_dst->value, "\r\n");
++              buffer_append_string_len(ds_dst->value, CONST_STR_LEN("\r\n"));
+               buffer_append_string_buffer(ds_dst->value, ds_dst->key);
+-              buffer_append_string(ds_dst->value, ": ");
++              buffer_append_string_len(ds_dst->value, CONST_STR_LEN(": "));
+               buffer_append_string_buffer(ds_dst->value, ds_src->value);
+       } else {
+               buffer_copy_string_buffer(ds_dst->value, ds_src->value);
+Index: src/http-header-glue.c
+===================================================================
+--- src/http-header-glue.c     (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/http-header-glue.c     (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -109,9 +109,9 @@
+       o = buffer_init();
+       if (con->conf.is_ssl) {
+-              buffer_copy_string(o, "https://");
++              buffer_copy_string_len(o, CONST_STR_LEN("https://"));
+       } else {
+-              buffer_copy_string(o, "http://");
++              buffer_copy_string_len(o, CONST_STR_LEN("http://"));
+       }
+       if (con->uri.authority->used) {
+               buffer_append_string_buffer(o, con->uri.authority);
+@@ -180,14 +180,14 @@
+               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_string_len(o, CONST_STR_LEN(":"));
+                       buffer_append_long(o, srv->srvconf.port);
+               }
+       }
+       buffer_append_string_buffer(o, con->uri.path);
+-      buffer_append_string(o, "/");
++      buffer_append_string_len(o, CONST_STR_LEN("/"));
+       if (!buffer_is_empty(con->uri.query)) {
+-              buffer_append_string(o, "?");
++              buffer_append_string_len(o, CONST_STR_LEN("?"));
+               buffer_append_string_buffer(o, con->uri.query);
+       }
+@@ -272,6 +272,7 @@
+                                                                       con->request.http_if_modified_since, used_len, sizeof(buf) - 1);
+                                                       con->http_status = 412;
++                                                      con->mode = DIRECT;
+                                                       return HANDLER_FINISHED;
+                                               }
+@@ -281,6 +282,7 @@
+                                               if (NULL == strptime(buf, "%a, %d %b %Y %H:%M:%S GMT", &tm)) {
+                                                       con->http_status = 412;
++                                                      con->mode = DIRECT;
+                                                       return HANDLER_FINISHED;
+                                               }
+                                               t_header = mktime(&tm);
+@@ -299,6 +301,7 @@
+                               }
+                       } else {
+                               con->http_status = 412;
++                              con->mode = DIRECT;
+                               return HANDLER_FINISHED;
+                       }
+               }
+Index: src/mod_evasive.c
+===================================================================
+--- src/mod_evasive.c  (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/mod_evasive.c  (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -138,24 +138,47 @@
+       /* no limit set, nothing to block */
+       if (p->conf.max_conns == 0) return HANDLER_GO_ON;
++      switch (con->dst_addr.plain.sa_family) {
++              case AF_INET:
++#ifdef HAVE_IPV6
++              case AF_INET6:
++#endif
++                      break;
++              default: // Address family not supported
++                      return HANDLER_GO_ON;
++      };
++
+       for (j = 0; j < srv->conns->used; j++) {
+               connection *c = srv->conns->ptr[j];
+               /* check if other connections are already actively serving data for the same IP
+                * we can only ban connections which are already behind the 'read request' state
+                * */
+-              if (c->dst_addr.ipv4.sin_addr.s_addr == con->dst_addr.ipv4.sin_addr.s_addr &&
+-                  c->state > CON_STATE_REQUEST_END) {
+-                      conns_by_ip++;
++              if (c->dst_addr.plain.sa_family != con->dst_addr.plain.sa_family) continue;
++              if (c->state <= CON_STATE_REQUEST_END) continue;
+-                      if (conns_by_ip > p->conf.max_conns) {
+-                              log_error_write(srv, __FILE__, __LINE__, "ss",
+-                                      inet_ntop_cache_get_ip(srv, &(con->dst_addr)),
+-                                      "turned away. Too many connections.");
++              switch (con->dst_addr.plain.sa_family) {
++                      case AF_INET:
++                              if (c->dst_addr.ipv4.sin_addr.s_addr != con->dst_addr.ipv4.sin_addr.s_addr) continue;
++                              break;
++#ifdef HAVE_IPV6
++                      case AF_INET6:
++                              if (0 != memcmp(c->dst_addr.ipv6.sin6_addr.s6_addr, con->dst_addr.ipv6.sin6_addr.s6_addr, 16)) continue;
++                              break;
++#endif
++                      default: /* Address family not supported, should never be reached */
++                              continue;
++              };
++              conns_by_ip++;
+-                              con->http_status = 403;
+-                              return HANDLER_FINISHED;
+-                      }
++              if (conns_by_ip > p->conf.max_conns) {
++                      log_error_write(srv, __FILE__, __LINE__, "ss",
++                              inet_ntop_cache_get_ip(srv, &(con->dst_addr)),
++                              "turned away. Too many connections.");
++
++                      con->http_status = 403;
++                      con->mode = DIRECT;
++                      return HANDLER_FINISHED;
+               }
+       }
+Index: src/mod_indexfile.c
+===================================================================
+--- src/mod_indexfile.c        (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/mod_indexfile.c        (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -140,6 +140,8 @@
+       size_t k;
+       stat_cache_entry *sce = NULL;
++      if (con->mode != DIRECT) 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;
+Index: src/mod_uploadprogress.c
+===================================================================
+--- src/mod_uploadprogress.c   (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/mod_uploadprogress.c   (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -355,6 +355,7 @@
+               con->file_finished = 1;
+               con->http_status = 200;
++              con->mode = DIRECT;
+               /* get the connection */
+               if (NULL == (post_con = connection_map_get_connection(p->con_map, b))) {
+@@ -363,7 +364,7 @@
+                       b = chunkqueue_get_append_buffer(con->write_queue);
+-                      BUFFER_APPEND_STRING_CONST(b, "starting");
++                      buffer_append_string_len(b, CONST_STR_LEN("starting"));
+                       return HANDLER_FINISHED;
+               }
+@@ -378,15 +379,18 @@
+               b = chunkqueue_get_append_buffer(con->write_queue);
+               /* prepare XML */
+-              BUFFER_COPY_STRING_CONST(b, "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>");
+-              BUFFER_APPEND_STRING_CONST(b, "<upload>");
+-              BUFFER_APPEND_STRING_CONST(b, "<size>");
++              buffer_copy_string_len(b, CONST_STR_LEN(
++                      "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>"
++                      "<upload>"
++                      "<size>"));
+               buffer_append_off_t(b, post_con->request.content_length);
+-              BUFFER_APPEND_STRING_CONST(b, "</size>");
+-              BUFFER_APPEND_STRING_CONST(b, "<received>");
++              buffer_append_string_len(b, CONST_STR_LEN(
++                      "</size>"
++                      "<received>"));
+               buffer_append_off_t(b, post_con->request_content_queue->bytes_in);
+-              BUFFER_APPEND_STRING_CONST(b, "</received>");
+-              BUFFER_APPEND_STRING_CONST(b, "</upload>");
++              buffer_append_string_len(b, CONST_STR_LEN(
++                      "</received>"
++                      "</upload>"));
+               log_error_write(srv, __FILE__, __LINE__, "sb", "...", b);
 Index: src/mod_fastcgi.c
 ===================================================================
---- src/mod_fastcgi.c  (.../tags/lighttpd-1.4.19)      (revision 2199)
-+++ src/mod_fastcgi.c  (.../branches/lighttpd-1.4.x)   (revision 2199)
+--- src/mod_fastcgi.c  (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/mod_fastcgi.c  (.../branches/lighttpd-1.4.x)   (revision 2303)
 @@ -236,6 +236,16 @@
        unsigned short break_scriptfilename_for_php;
  
@@ -1774,7 +4842,88 @@ Index: src/mod_fastcgi.c
         * If the backend includes X-LIGHTTPD-send-file in the response
         * we use the value as filename and ignore the content.
         *
-@@ -937,6 +947,8 @@
+@@ -380,10 +390,10 @@
+ static handler_t fcgi_handle_fdevent(void *s, void *ctx, int revents);
+ int fastcgi_status_copy_procname(buffer *b, fcgi_extension_host *host, fcgi_proc *proc) {
+-      buffer_copy_string(b, "fastcgi.backend.");
++      buffer_copy_string_len(b, CONST_STR_LEN("fastcgi.backend."));
+       buffer_append_string_buffer(b, host->id);
+       if (proc) {
+-              buffer_append_string(b, ".");
++              buffer_append_string_len(b, CONST_STR_LEN("."));
+               buffer_append_long(b, proc->id);
+       }
+@@ -393,7 +403,7 @@
+ int fastcgi_status_init(server *srv, buffer *b, fcgi_extension_host *host, fcgi_proc *proc) {
+ #define CLEAN(x) \
+       fastcgi_status_copy_procname(b, host, proc); \
+-      buffer_append_string(b, x); \
++      buffer_append_string_len(b, CONST_STR_LEN(x)); \
+       status_counter_set(srv, CONST_BUF_LEN(b), 0);
+       CLEAN(".disabled");
+@@ -406,7 +416,7 @@
+ #define CLEAN(x) \
+       fastcgi_status_copy_procname(b, host, NULL); \
+-      buffer_append_string(b, x); \
++      buffer_append_string_len(b, CONST_STR_LEN(x)); \
+       status_counter_set(srv, CONST_BUF_LEN(b), 0);
+       CLEAN(".load");
+@@ -693,6 +703,7 @@
+ static int env_add(char_array *env, const char *key, size_t key_len, const char *val, size_t val_len) {
+       char *dst;
++      size_t i;
+       if (!key || !val) return -1;
+@@ -702,6 +713,15 @@
+       /* add the \0 from the value */
+       memcpy(dst + key_len + 1, val, val_len + 1);
++      for (i = 0; i < env->used; i++) {
++              if (0 == strncmp(dst, env->ptr[i], key_len + 1)) {
++                      /* don't care about free as we are in a forked child which is going to exec(...) */
++                      /* free(env->ptr[i]); */
++                      env->ptr[i] = dst;
++                      return 0;
++              }
++      }
++
+       if (env->size == 0) {
+               env->size = 16;
+               env->ptr = malloc(env->size * sizeof(*env->ptr));
+@@ -811,7 +831,7 @@
+               socket_type = AF_UNIX;
+               fcgi_addr = (struct sockaddr *) &fcgi_addr_un;
+-              buffer_copy_string(proc->connection_name, "unix:");
++              buffer_copy_string_len(proc->connection_name, CONST_STR_LEN("unix:"));
+               buffer_append_string_buffer(proc->connection_name, proc->unixsocket);
+ #else
+@@ -857,13 +877,13 @@
+               socket_type = AF_INET;
+               fcgi_addr = (struct sockaddr *) &fcgi_addr_in;
+-              buffer_copy_string(proc->connection_name, "tcp:");
++              buffer_copy_string_len(proc->connection_name, CONST_STR_LEN("tcp:"));
+               if (!buffer_is_empty(host->host)) {
+                       buffer_append_string_buffer(proc->connection_name, host->host);
+               } else {
+-                      buffer_append_string(proc->connection_name, "localhost");
++                      buffer_append_string_len(proc->connection_name, CONST_STR_LEN("localhost"));
+               }
+-              buffer_append_string(proc->connection_name, ":");
++              buffer_append_string_len(proc->connection_name, CONST_STR_LEN(":"));
+               buffer_append_long(proc->connection_name, proc->port);
+       }
+@@ -937,6 +957,8 @@
                                close(fcgi_fd);
                        }
  
@@ -1783,7 +4932,7 @@ Index: src/mod_fastcgi.c
                        /* we don't need the client socket */
                        for (i = 3; i < 256; i++) {
                                close(i);
-@@ -1000,8 +1012,8 @@
+@@ -1000,8 +1022,8 @@
                        /* exec the cgi */
                        execve(arg.ptr[0], arg.ptr, env.ptr);
  
@@ -1794,7 +4943,7 @@ Index: src/mod_fastcgi.c
  
                        exit(errno);
  
-@@ -1193,6 +1205,7 @@
+@@ -1193,6 +1215,7 @@
                                                { "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 */
                                                { "kill-signal",        NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },      /* 17 */
@@ -1802,7 +4951,7 @@ Index: src/mod_fastcgi.c
  
                                                { NULL,                NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
                                        };
-@@ -1220,6 +1233,7 @@
+@@ -1220,6 +1243,7 @@
                                        host->break_scriptfilename_for_php = 0;
                                        host->allow_xsendfile = 0; /* handle X-LIGHTTPD-send-file */
                                        host->kill_signal = SIGTERM;
@@ -1810,7 +4959,7 @@ Index: src/mod_fastcgi.c
  
                                        fcv[0].destination = host->host;
                                        fcv[1].destination = host->docroot;
-@@ -1241,6 +1255,7 @@
+@@ -1241,6 +1265,7 @@
                                        fcv[15].destination = &(host->allow_xsendfile);
                                        fcv[16].destination = host->strip_request_uri;
                                        fcv[17].destination = &(host->kill_signal);
@@ -1818,7 +4967,128 @@ Index: src/mod_fastcgi.c
  
                                        if (0 != config_insert_values_internal(srv, da_host->value, fcv)) {
                                                return HANDLER_ERROR;
-@@ -2544,7 +2559,10 @@
+@@ -1324,7 +1349,7 @@
+                                                               proc->port = host->port + pno;
+                                                       } else {
+                                                               buffer_copy_string_buffer(proc->unixsocket, host->unixsocket);
+-                                                              buffer_append_string(proc->unixsocket, "-");
++                                                              buffer_append_string_len(proc->unixsocket, CONST_STR_LEN("-"));
+                                                               buffer_append_long(proc->unixsocket, pno);
+                                                       }
+@@ -1482,7 +1507,7 @@
+                       status_counter_dec(srv, CONST_STR_LEN("fastcgi.active-requests"));
+                       fastcgi_status_copy_procname(p->statuskey, hctx->host, hctx->proc);
+-                      buffer_append_string(p->statuskey, ".load");
++                      buffer_append_string_len(p->statuskey, CONST_STR_LEN(".load"));
+                       status_counter_set(srv, CONST_BUF_LEN(p->statuskey), hctx->proc->load);
+@@ -1683,7 +1708,7 @@
+               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:");
++                      buffer_copy_string_len(proc->connection_name, CONST_STR_LEN("unix:"));
+                       buffer_append_string_buffer(proc->connection_name, proc->unixsocket);
+               }
+ #else
+@@ -1709,13 +1734,13 @@
+               if (buffer_is_empty(proc->connection_name)) {
+                       /* on remote spawing we have to set the connection-name now */
+-                      buffer_copy_string(proc->connection_name, "tcp:");
++                      buffer_copy_string_len(proc->connection_name, CONST_STR_LEN("tcp:"));
+                       if (!buffer_is_empty(host->host)) {
+                               buffer_append_string_buffer(proc->connection_name, host->host);
+                       } else {
+-                              buffer_append_string(proc->connection_name, "localhost");
++                              buffer_append_string_len(proc->connection_name, CONST_STR_LEN("localhost"));
+                       }
+-                      buffer_append_string(proc->connection_name, ":");
++                      buffer_append_string_len(proc->connection_name, CONST_STR_LEN(":"));
+                       buffer_append_long(proc->connection_name, proc->port);
+               }
+       }
+@@ -1771,7 +1796,7 @@
+                       buffer_reset(srv->tmp_buf);
+                       if (0 != strcasecmp(ds->key->ptr, "CONTENT-TYPE")) {
+-                              BUFFER_COPY_STRING_CONST(srv->tmp_buf, "HTTP_");
++                              buffer_copy_string_len(srv->tmp_buf, CONST_STR_LEN("HTTP_"));
+                               srv->tmp_buf->used--;
+                       }
+@@ -2026,7 +2051,7 @@
+                */
+               if ('/' != host->strip_request_uri->ptr[host->strip_request_uri->used - 2]) {
+                       /* fix the user-input to have / as last char */
+-                      buffer_append_string(host->strip_request_uri, "/");
++                      buffer_append_string_len(host->strip_request_uri, CONST_STR_LEN("/"));
+               }
+               if (con->request.orig_uri->used >= host->strip_request_uri->used &&
+@@ -2094,12 +2119,12 @@
+                       hctx->wb->bytes_in += sizeof(header);
+                       if (p->conf.debug > 10) {
+-                              fprintf(stderr, "%s.%d: tosend: %lld / %lld\n", __FILE__, __LINE__, offset, req_cq->bytes_in);
++                              log_error_write(srv, __FILE__, __LINE__, "soso", "tosend:", offset, "/", req_cq->bytes_in);
+                       }
+                       for (written = 0; written != weWant; ) {
+                               if (p->conf.debug > 10) {
+-                                      fprintf(stderr, "%s.%d: chunk: %lld / %lld\n", __FILE__, __LINE__, written, weWant);
++                                      log_error_write(srv, __FILE__, __LINE__, "soso", "chunk:", written, "/", weWant);
+                               }
+                               switch (req_c->type) {
+@@ -2109,12 +2134,10 @@
+                                       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,
+-                                                              req_c->file.name->ptr);
++                                              log_error_write(srv, __FILE__, __LINE__, "soSosOsb",
++                                                      "sending", weHave, "bytes from (",
++                                                      req_c->offset, "/", req_c->file.length, ")",
++                                                      req_c->file.name);
+                                       }
+                                       assert(weHave != 0);
+@@ -2143,7 +2166,7 @@
+                                               chunk *c;
+                                               if (p->conf.debug > 10) {
+-                                                      fprintf(stderr, "%s.%d: next chunk\n", __FILE__, __LINE__);
++                                                      log_error_write(srv, __FILE__, __LINE__, "s", "next chunk");
+                                               }
+                                               c = hctx->wb->last;
+@@ -2173,7 +2196,7 @@
+                                       hctx->wb->bytes_in += weHave;
+-                                      if (req_c->offset == req_c->mem->used - 1) {
++                                      if (req_c->offset == (off_t) req_c->mem->used - 1) {
+                                               chunkqueue_remove_finished_chunks(req_cq);
+                                               req_c = req_cq->first;
+@@ -2368,7 +2391,7 @@
+       offset = sizeof(*header);
+       /* ->b should only be the content */
+-      buffer_copy_string(packet->b, ""); /* used == 1 */
++      buffer_copy_string_len(packet->b, CONST_STR_LEN("")); /* used == 1 */
+       if (packet->len) {
+               /* copy the content */
+@@ -2544,7 +2567,10 @@
                                        stat_cache_entry *sce;
  
                                        if (HANDLER_ERROR != stat_cache_get_entry(srv, con, ds->value, &sce)) {
@@ -1830,7 +5100,127 @@ Index: src/mod_fastcgi.c
                                                /* found */
                                                http_chunk_append_file(srv, con, ds->value, 0, sce->st.st_size);
                                                hctx->send_content_body = 0; /* ignore the content */
-@@ -3074,7 +3092,7 @@
+@@ -2663,30 +2689,48 @@
+                       /* the child should not terminate at all */
+-                      switch(waitpid(proc->pid, &status, WNOHANG)) {
+-                      case 0:
+-                              /* child is still alive */
+-                              break;
+-                      case -1:
+-                              break;
+-                      default:
+-                              if (WIFEXITED(status)) {
++                      for ( ;; ) {
++                              switch(waitpid(proc->pid, &status, WNOHANG)) {
++                              case 0:
++                                      /* child is still alive */
++                                      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,
++                                                      host->unixsocket);
++                                      break;
++                              case -1:
++                                      if (errno == EINTR) continue;
++
++                                      log_error_write(srv, __FILE__, __LINE__, "sd",
++                                                      "child died somehow, waitpid failed:",
++                                                      errno);
++                                      proc->state = PROC_STATE_DIED;
++                                      break;
++                              default:
++                                      if (WIFEXITED(status)) {
+ #if 0
+-                                      log_error_write(srv, __FILE__, __LINE__, "sdsd",
+-                                                      "child exited, pid:", proc->pid,
+-                                                      "status:", WEXITSTATUS(status));
++                                              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:",
+-                                                      WTERMSIG(status));
+-                              } else {
+-                                      log_error_write(srv, __FILE__, __LINE__, "sd",
+-                                                      "child died somehow:",
+-                                                      status);
++                                      } else if (WIFSIGNALED(status)) {
++                                              log_error_write(srv, __FILE__, __LINE__, "sd",
++                                                              "child signaled:",
++                                                              WTERMSIG(status));
++                                      } else {
++                                              log_error_write(srv, __FILE__, __LINE__, "sd",
++                                                              "child died somehow:",
++                                                              status);
++                                      }
++      
++                                      proc->state = PROC_STATE_DIED;
++                                      break;
+                               }
+-
+-                              proc->state = PROC_STATE_DIED;
+                               break;
+                       }
+@@ -2797,7 +2841,7 @@
+                       hctx->proc->state = PROC_STATE_DIED;
+                       fastcgi_status_copy_procname(p->statuskey, hctx->host, hctx->proc);
+-                      buffer_append_string(p->statuskey, ".died");
++                      buffer_append_string_len(p->statuskey, CONST_STR_LEN(".died"));
+                       status_counter_inc(srv, CONST_BUF_LEN(p->statuskey));
+@@ -2889,7 +2933,7 @@
+                       hctx->proc->state = PROC_STATE_OVERLOADED;
+                       fastcgi_status_copy_procname(p->statuskey, hctx->host, hctx->proc);
+-                      buffer_append_string(p->statuskey, ".overloaded");
++                      buffer_append_string_len(p->statuskey, CONST_STR_LEN(".overloaded"));
+                       status_counter_inc(srv, CONST_BUF_LEN(p->statuskey));
+@@ -2915,7 +2959,7 @@
+                               "load:", host->load);
+                       fastcgi_status_copy_procname(p->statuskey, hctx->host, hctx->proc);
+-                      buffer_append_string(p->statuskey, ".died");
++                      buffer_append_string_len(p->statuskey, CONST_STR_LEN(".died"));
+                       status_counter_inc(srv, CONST_BUF_LEN(p->statuskey));
+@@ -2941,19 +2985,19 @@
+               status_counter_inc(srv, CONST_STR_LEN("fastcgi.active-requests"));
+               fastcgi_status_copy_procname(p->statuskey, hctx->host, hctx->proc);
+-              buffer_append_string(p->statuskey, ".connected");
++              buffer_append_string_len(p->statuskey, CONST_STR_LEN(".connected"));
+               status_counter_inc(srv, CONST_BUF_LEN(p->statuskey));
+               /* the proc-load */
+               fastcgi_status_copy_procname(p->statuskey, hctx->host, hctx->proc);
+-              buffer_append_string(p->statuskey, ".load");
++              buffer_append_string_len(p->statuskey, CONST_STR_LEN(".load"));
+               status_counter_set(srv, CONST_BUF_LEN(p->statuskey), hctx->proc->load);
+               /* the host-load */
+               fastcgi_status_copy_procname(p->statuskey, hctx->host, NULL);
+-              buffer_append_string(p->statuskey, ".load");
++              buffer_append_string_len(p->statuskey, CONST_STR_LEN(".load"));
+               status_counter_set(srv, CONST_BUF_LEN(p->statuskey), hctx->host->load);
+@@ -3074,7 +3118,7 @@
  
                /* check if the next server has no load. */
                ndx = hctx->ext->last_used_ndx + 1;
@@ -1839,7 +5229,16 @@ Index: src/mod_fastcgi.c
                host = hctx->ext->hosts[ndx];
                if (host->load > 0) {
                        /* get backend with the least load. */
-@@ -3480,13 +3498,12 @@
+@@ -3418,6 +3462,8 @@
+       fcgi_extension *extension = NULL;
+       fcgi_extension_host *host = NULL;
++      if (con->mode != DIRECT) return HANDLER_GO_ON;
++
+       /* Possibly, we processed already this request */
+       if (con->file_started == 1) return HANDLER_GO_ON;
+@@ -3480,13 +3526,12 @@
  
                        ct_len = extension->key->used - 1;
  
@@ -1858,7 +5257,7 @@ Index: src/mod_fastcgi.c
                                /* check extension in the form ".fcg" */
                                break;
                        }
-@@ -3499,16 +3516,15 @@
+@@ -3499,16 +3544,15 @@
  
        /* check if we have at least one server for this extension up and running */
        for (k = 0; k < extension->used; k++) {
@@ -1878,7 +5277,7 @@ Index: src/mod_fastcgi.c
                break;
        }
  
-@@ -3582,6 +3598,13 @@
+@@ -3582,6 +3626,13 @@
                         * SCRIPT_NAME = /fcgi-bin/foo
                         * PATH_INFO   = /bar
                         *
@@ -1892,7 +5291,7 @@ Index: src/mod_fastcgi.c
                         */
  
                        /* the rewrite is only done for /prefix/? matches */
-@@ -3594,6 +3617,10 @@
+@@ -3594,6 +3645,10 @@
  
                                con->uri.path->used -= con->request.pathinfo->used - 1;
                                con->uri.path->ptr[con->uri.path->used - 1] = '\0';
@@ -1903,10 +5302,68 @@ Index: src/mod_fastcgi.c
                        }
                }
        } else {
+@@ -3738,7 +3793,7 @@
+                                               proc->port = host->port + proc->id;
+                                       } else {
+                                               buffer_copy_string_buffer(proc->unixsocket, host->unixsocket);
+-                                              buffer_append_string(proc->unixsocket, "-");
++                                              buffer_append_string_len(proc->unixsocket, CONST_STR_LEN("-"));
+                                               buffer_append_long(proc->unixsocket, proc->id);
+                                       }
+Index: src/mod_ssi_exprparser.y
+===================================================================
+--- src/mod_ssi_exprparser.y   (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/mod_ssi_exprparser.y   (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -105,12 +105,13 @@
+ }
+ value(A) ::= VALUE(B). {
+-  A = buffer_init_string(B->ptr);
++  A = B;
+ }
+ value(A) ::= value(B) VALUE(C). {
+   A = B;
+   buffer_append_string_buffer(A, C);
++  buffer_free(C);
+ }
+ cond(A) ::= EQ. { A = SSI_COND_EQ; }
+Index: src/mod_access.c
+===================================================================
+--- src/mod_access.c   (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/mod_access.c   (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -159,6 +159,7 @@
+               if (denied) {
+                       con->http_status = 403;
++                      con->mode = DIRECT;
+                       if (con->conf.log_request_handling) {
+                               log_error_write(srv, __FILE__, __LINE__, "sb", 
 Index: src/mod_accesslog.c
 ===================================================================
---- src/mod_accesslog.c        (.../tags/lighttpd-1.4.19)      (revision 2199)
-+++ src/mod_accesslog.c        (.../branches/lighttpd-1.4.x)   (revision 2199)
+--- src/mod_accesslog.c        (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/mod_accesslog.c        (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -356,7 +356,7 @@
+                               if (s->use_syslog) {
+ # ifdef HAVE_SYSLOG_H
+                                       if (s->access_logbuffer->used > 2) {
+-                                              syslog(LOG_INFO, "%*s", s->access_logbuffer->used - 2, s->access_logbuffer->ptr);
++                                              syslog(LOG_INFO, "%*s", (int) s->access_logbuffer->used - 2, s->access_logbuffer->ptr);
+                                       }
+ # endif
+                               } else if (s->log_access_fd != -1) {
+@@ -433,7 +433,7 @@
+               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\"");
++                      buffer_copy_string_len(s->format, CONST_STR_LEN("%h %V %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\""));
+               }
+               /* parse */
 @@ -473,7 +473,7 @@
                        continue;
                }
@@ -1925,6 +5382,15 @@ Index: src/mod_accesslog.c
                                /* we don't need the client socket */
                                for (i = 3; i < 256; i++) {
                                        close(i);
+@@ -559,7 +561,7 @@
+ #ifdef HAVE_SYSLOG_H
+                               if (s->access_logbuffer->used > 2) {
+                                       /* syslog appends a \n on its own */
+-                                      syslog(LOG_INFO, "%*s", s->access_logbuffer->used - 2, s->access_logbuffer->ptr);
++                                      syslog(LOG_INFO, "%*s", (int) s->access_logbuffer->used - 2, s->access_logbuffer->ptr);
+                               }
+ #endif
+                       } else if (s->log_access_fd != -1) {
 @@ -570,7 +572,7 @@
                }
  
@@ -1934,7 +5400,7 @@ Index: src/mod_accesslog.c
                    s->access_logfile->ptr[0] != '|') {
  
                        close(s->log_access_fd);
-@@ -647,6 +649,9 @@
+@@ -647,9 +649,12 @@
  
        mod_accesslog_patch_connection(srv, con, p);
  
@@ -1943,9 +5409,133 @@ Index: src/mod_accesslog.c
 +
        b = p->conf.access_logbuffer;
        if (b->used == 0) {
-               buffer_copy_string(b, "");
-@@ -806,7 +811,14 @@
-                               buffer_append_string(b, "%");
+-              buffer_copy_string(b, "");
++              buffer_copy_string_len(b, CONST_STR_LEN(""));
+       }
+       for (j = 0; j < p->conf.parsed_format->used; j++) {
+@@ -674,23 +679,23 @@
+                                       localtime_r(&(srv->cur_ts), &tm);
+                                       strftime(p->conf.ts_accesslog_str->ptr, p->conf.ts_accesslog_str->size - 1, "[%d/%b/%Y:%H:%M:%S ", &tm);
+ # else
+-                                      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)));
++                                      strftime(p->conf.ts_accesslog_str->ptr, p->conf.ts_accesslog_str->size - 1, "[%d/%b/%Y:%H:%M:%S ", localtime(&(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 ? "+" : "-");
++                                      buffer_append_string_len(p->conf.ts_accesslog_str, tm.tm_gmtoff >= 0 ? "+" : "-", 1);
+                                       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");
++                                      if (hrs < 10) buffer_append_string_len(p->conf.ts_accesslog_str, CONST_STR_LEN("0"));
+                                       buffer_append_long(p->conf.ts_accesslog_str, hrs);
+-                                      if (min < 10) buffer_append_string(p->conf.ts_accesslog_str, "0");
++                                      if (min < 10) buffer_append_string_len(p->conf.ts_accesslog_str, CONST_STR_LEN("0"));
+                                       buffer_append_long(p->conf.ts_accesslog_str, min);
+-                                      BUFFER_APPEND_STRING_CONST(p->conf.ts_accesslog_str, "]");
++                                      buffer_append_string_len(p->conf.ts_accesslog_str, CONST_STR_LEN("]"));
+ #else
+ #ifdef HAVE_GMTIME_R
+                                       gmtime_r(&(srv->cur_ts), &tm);
+@@ -717,13 +722,13 @@
+                               break;
+                       case FORMAT_REMOTE_IDENT:
+                               /* ident */
+-                              BUFFER_APPEND_STRING_CONST(b, "-");
++                              buffer_append_string_len(b, CONST_STR_LEN("-"));
+                               break;
+                       case FORMAT_REMOTE_USER:
+                               if (con->authed_user->used > 1) {
+                                       buffer_append_string_buffer(b, con->authed_user);
+                               } else {
+-                                      BUFFER_APPEND_STRING_CONST(b, "-");
++                                      buffer_append_string_len(b, CONST_STR_LEN("-"));
+                               }
+                               break;
+                       case FORMAT_REQUEST_LINE:
+@@ -740,42 +745,42 @@
+                                       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, "-");
++                                      buffer_append_string_len(b, CONST_STR_LEN("-"));
+                               }
+                               break;
+                       case FORMAT_HEADER:
+                               if (NULL != (ds = (data_string *)array_get_element(con->request.headers, p->conf.parsed_format->ptr[j]->string->ptr))) {
+                                       buffer_append_string_buffer(b, ds->value);
+                               } else {
+-                                      BUFFER_APPEND_STRING_CONST(b, "-");
++                                      buffer_append_string_len(b, CONST_STR_LEN("-"));
+                               }
+                               break;
+                       case FORMAT_RESPONSE_HEADER:
+                               if (NULL != (ds = (data_string *)array_get_element(con->response.headers, p->conf.parsed_format->ptr[j]->string->ptr))) {
+                                       buffer_append_string_buffer(b, ds->value);
+                               } else {
+-                                      BUFFER_APPEND_STRING_CONST(b, "-");
++                                      buffer_append_string_len(b, CONST_STR_LEN("-"));
+                               }
+                               break;
+                       case FORMAT_FILENAME:
+                               if (con->physical.path->used > 1) {
+                                       buffer_append_string_buffer(b, con->physical.path);
+                               } else {
+-                                      BUFFER_APPEND_STRING_CONST(b, "-");
++                                      buffer_append_string_len(b, CONST_STR_LEN("-"));
+                               }
+                               break;
+                       case FORMAT_BYTES_OUT:
+                               if (con->bytes_written > 0) {
+                                       buffer_append_off_t(b, con->bytes_written);
+                               } else {
+-                                      BUFFER_APPEND_STRING_CONST(b, "-");
++                                      buffer_append_string_len(b, CONST_STR_LEN("-"));
+                               }
+                               break;
+                       case FORMAT_BYTES_IN:
+                               if (con->bytes_read > 0) {
+                                       buffer_append_off_t(b, con->bytes_read);
+                               } else {
+-                                      BUFFER_APPEND_STRING_CONST(b, "-");
++                                      buffer_append_string_len(b, CONST_STR_LEN("-"));
+                               }
+                               break;
+                       case FORMAT_TIME_USED:
+@@ -785,28 +790,35 @@
+                               if (con->server_name->used > 1) {
+                                       buffer_append_string_buffer(b, con->server_name);
+                               } else {
+-                                      BUFFER_APPEND_STRING_CONST(b, "-");
++                                      buffer_append_string_len(b, CONST_STR_LEN("-"));
+                               }
+                               break;
+                       case FORMAT_HTTP_HOST:
+                               if (con->uri.authority->used > 1) {
+                                       buffer_append_string_buffer(b, con->uri.authority);
+                               } else {
+-                                      BUFFER_APPEND_STRING_CONST(b, "-");
++                                      buffer_append_string_len(b, CONST_STR_LEN("-"));
+                               }
+                               break;
+                       case FORMAT_REQUEST_PROTOCOL:
+-                              buffer_append_string(b,
+-                                                   con->request.http_version == HTTP_VERSION_1_1 ? "HTTP/1.1" : "HTTP/1.0");
++                              buffer_append_string_len(b,
++                                                   con->request.http_version == HTTP_VERSION_1_1 ? "HTTP/1.1" : "HTTP/1.0", 8);
+                               break;
+                       case FORMAT_REQUEST_METHOD:
+                               buffer_append_string(b, get_http_method_name(con->request.http_method));
+                               break;
+                       case FORMAT_PERCENT:
+-                              buffer_append_string(b, "%");
++                              buffer_append_string_len(b, CONST_STR_LEN("%"));
                                break;
                        case FORMAT_SERVER_PORT:
 -                              buffer_append_long(b, srv->srvconf.port);
@@ -1960,10 +5550,66 @@ Index: src/mod_accesslog.c
                                break;
                        case FORMAT_QUERY_STRING:
                                buffer_append_string_buffer(b, con->uri.query);
+@@ -816,8 +828,8 @@
+                               break;
+                       case FORMAT_CONNECTION_STATUS:
+                               switch(con->keep_alive) {
+-                              case 0: buffer_append_string(b, "-"); break;
+-                              default: buffer_append_string(b, "+"); break;
++                              case 0: buffer_append_string_len(b, CONST_STR_LEN("-")); break;
++                              default: buffer_append_string_len(b, CONST_STR_LEN("+")); break;
+                               }
+                               break;
+                       default:
+@@ -837,7 +849,7 @@
+               }
+       }
+-      BUFFER_APPEND_STRING_CONST(b, "\n");
++      buffer_append_string_len(b, CONST_STR_LEN("\n"));
+       if (p->conf.use_syslog ||  /* syslog doesn't cache */
+           (p->conf.access_logfile->used && p->conf.access_logfile->ptr[0] == '|') || /* pipes don't cache */
+@@ -847,7 +859,7 @@
+ #ifdef HAVE_SYSLOG_H
+                       if (b->used > 2) {
+                               /* syslog appends a \n on its own */
+-                              syslog(LOG_INFO, "%*s", b->used - 2, b->ptr);
++                              syslog(LOG_INFO, "%*s", (int) b->used - 2, b->ptr);
+                       }
+ #endif
+               } else if (p->conf.log_access_fd != -1) {
 Index: src/server.c
 ===================================================================
---- src/server.c       (.../tags/lighttpd-1.4.19)      (revision 2199)
-+++ src/server.c       (.../branches/lighttpd-1.4.x)   (revision 2199)
+--- src/server.c       (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/server.c       (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -80,7 +80,7 @@
+       switch (sig) {
+       case SIGTERM:
+               srv_shutdown = 1;
+-              memcpy(&last_sigterm_info, si, sizeof(*si));
++              last_sigterm_info = *si;
+               break;
+       case SIGINT:
+               if (graceful_shutdown) {
+@@ -88,7 +88,7 @@
+               } else {
+                       graceful_shutdown = 1;
+               }
+-              memcpy(&last_sigterm_info, si, sizeof(*si));
++              last_sigterm_info = *si;
+               break;
+       case SIGALRM: 
+@@ -104,7 +104,7 @@
+                */
+               if (!forwarded_sig_hup) {
+                       handle_sig_hup = 1;
+-                      memcpy(&last_sighup_info, si, sizeof(*si));
++                      last_sighup_info = *si;
+               } else {
+                       forwarded_sig_hup = 0;
+               }
 @@ -573,20 +573,9 @@
        }
  
@@ -1987,7 +5633,14 @@ Index: src/server.c
        if (0 != config_set_defaults(srv)) {
                log_error_write(srv, __FILE__, __LINE__, "s",
                                "setting default values failed");
-@@ -893,8 +882,8 @@
+@@ -887,14 +876,14 @@
+       /* write pid file */
+       if (pid_fd != -1) {
+               buffer_copy_long(srv->tmp_buf, getpid());
+-              buffer_append_string(srv->tmp_buf, "\n");
++              buffer_append_string_len(srv->tmp_buf, CONST_STR_LEN("\n"));
+               write(pid_fd, srv->tmp_buf->ptr, srv->tmp_buf->used - 1);
+               close(pid_fd);
                pid_fd = -1;
        }
  
@@ -2000,26 +5653,265 @@ Index: src/server.c
  
 Index: src/mod_dirlisting.c
 ===================================================================
---- src/mod_dirlisting.c       (.../tags/lighttpd-1.4.19)      (revision 2199)
-+++ src/mod_dirlisting.c       (.../branches/lighttpd-1.4.x)   (revision 2199)
-@@ -841,11 +841,11 @@
+--- src/mod_dirlisting.c       (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/mod_dirlisting.c       (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -454,21 +454,21 @@
+ static void http_list_directory_header(server *srv, connection *con, plugin_data *p, buffer *out) {
+       UNUSED(srv);
+-      BUFFER_APPEND_STRING_CONST(out,
++      buffer_append_string_len(out, CONST_STR_LEN(
+               "<!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"
+               "<head>\n"
+               "<title>Index of "
+-      );
++      ));
+       buffer_append_string_encoded(out, CONST_BUF_LEN(con->uri.path), ENCODING_MINIMAL_XML);
+-      BUFFER_APPEND_STRING_CONST(out, "</title>\n");
++      buffer_append_string_len(out, CONST_STR_LEN("</title>\n"));
+       if (p->conf.external_css->used > 1) {
+-              BUFFER_APPEND_STRING_CONST(out, "<link rel=\"stylesheet\" type=\"text/css\" href=\"");
++              buffer_append_string_len(out, CONST_STR_LEN("<link rel=\"stylesheet\" type=\"text/css\" href=\""));
+               buffer_append_string_buffer(out, p->conf.external_css);
+-              BUFFER_APPEND_STRING_CONST(out, "\" />\n");
++              buffer_append_string_len(out, CONST_STR_LEN("\" />\n"));
+       } else {
+-              BUFFER_APPEND_STRING_CONST(out,
++              buffer_append_string_len(out, CONST_STR_LEN(
+                       "<style type=\"text/css\">\n"
+                       "a, a:active {text-decoration: none; color: blue;}\n"
+                       "a:visited {color: #48468F;}\n"
+@@ -485,8 +485,6 @@
+                       " padding-right: 14px;"
+                       " padding-bottom: 3px;"
+                       "}\n"
+-              );
+-              BUFFER_APPEND_STRING_CONST(out,
+                       "td {padding-right: 14px;}\n"
+                       "td.s, th.s {text-align: right;}\n"
+                       "div.list {"
+@@ -502,10 +500,10 @@
+                       " padding-top: 4px;"
+                       "}\n"
+                       "</style>\n"
+-              );
++              ));
+       }
+-      BUFFER_APPEND_STRING_CONST(out, "</head>\n<body>\n");
++      buffer_append_string_len(out, CONST_STR_LEN("</head>\n<body>\n"));
+       /* HEADER.txt */
+       if (p->conf.show_header) {
+@@ -514,19 +512,19 @@
+               buffer_copy_string_buffer(p->tmp_buf, con->physical.path);
+               BUFFER_APPEND_SLASH(p->tmp_buf);
+-              BUFFER_APPEND_STRING_CONST(p->tmp_buf, "HEADER.txt");
++              buffer_append_string_len(p->tmp_buf, CONST_STR_LEN("HEADER.txt"));
+               if (-1 != stream_open(&s, p->tmp_buf)) {
+-                      BUFFER_APPEND_STRING_CONST(out, "<pre class=\"header\">");
++                      buffer_append_string_len(out, CONST_STR_LEN("<pre class=\"header\">"));
+                       buffer_append_string_encoded(out, s.start, s.size, ENCODING_MINIMAL_XML);
+-                      BUFFER_APPEND_STRING_CONST(out, "</pre>");
++                      buffer_append_string_len(out, CONST_STR_LEN("</pre>"));
+               }
+               stream_close(&s);
+       }
+-      BUFFER_APPEND_STRING_CONST(out, "<h2>Index of ");
++      buffer_append_string_len(out, CONST_STR_LEN("<h2>Index of "));
+       buffer_append_string_encoded(out, CONST_BUF_LEN(con->uri.path), ENCODING_MINIMAL_XML);
+-      BUFFER_APPEND_STRING_CONST(out,
++      buffer_append_string_len(out, CONST_STR_LEN(
+               "</h2>\n"
+               "<div class=\"list\">\n"
+               "<table summary=\"Directory Listing\" cellpadding=\"0\" cellspacing=\"0\">\n"
+@@ -545,17 +543,17 @@
+                       "<td class=\"s\">- &nbsp;</td>"
+                       "<td class=\"t\">Directory</td>"
+               "</tr>\n"
+-      );
++      ));
+ }
+ static void http_list_directory_footer(server *srv, connection *con, plugin_data *p, buffer *out) {
+       UNUSED(srv);
+-      BUFFER_APPEND_STRING_CONST(out,
++      buffer_append_string_len(out, CONST_STR_LEN(
+               "</tbody>\n"
+               "</table>\n"
+               "</div>\n"
+-      );
++      ));
+       if (p->conf.show_readme) {
+               stream s;
+@@ -563,33 +561,33 @@
+               buffer_copy_string_buffer(p->tmp_buf,  con->physical.path);
+               BUFFER_APPEND_SLASH(p->tmp_buf);
+-              BUFFER_APPEND_STRING_CONST(p->tmp_buf, "README.txt");
++              buffer_append_string_len(p->tmp_buf, CONST_STR_LEN("README.txt"));
+               if (-1 != stream_open(&s, p->tmp_buf)) {
+-                      BUFFER_APPEND_STRING_CONST(out, "<pre class=\"readme\">");
++                      buffer_append_string_len(out, CONST_STR_LEN("<pre class=\"readme\">"));
+                       buffer_append_string_encoded(out, s.start, s.size, ENCODING_MINIMAL_XML);
+-                      BUFFER_APPEND_STRING_CONST(out, "</pre>");
++                      buffer_append_string_len(out, CONST_STR_LEN("</pre>"));
+               }
+               stream_close(&s);
+       }
+-      BUFFER_APPEND_STRING_CONST(out,
++      buffer_append_string_len(out, CONST_STR_LEN(
+               "<div class=\"foot\">"
+-      );
++      ));
+       if (p->conf.set_footer->used > 1) {
+               buffer_append_string_buffer(out, p->conf.set_footer);
+       } else if (buffer_is_empty(con->conf.server_tag)) {
+-              BUFFER_APPEND_STRING_CONST(out, PACKAGE_NAME "/" PACKAGE_VERSION);
++              buffer_append_string_len(out, CONST_STR_LEN(PACKAGE_NAME "/" PACKAGE_VERSION));
+       } else {
+               buffer_append_string_buffer(out, con->conf.server_tag);
+       }
+-      BUFFER_APPEND_STRING_CONST(out,
++      buffer_append_string_len(out, CONST_STR_LEN(
+               "</div>\n"
+               "</body>\n"
+               "</html>\n"
+-      );
++      ));
+ }
+ static int http_list_directory(server *srv, connection *con, plugin_data *p, buffer *dir) {
+@@ -742,13 +740,13 @@
+       if (files.used) http_dirls_sort(files.ent, files.used);
+       out = chunkqueue_get_append_buffer(con->write_queue);
+-      BUFFER_COPY_STRING_CONST(out, "<?xml version=\"1.0\" encoding=\"");
++      buffer_copy_string_len(out, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\""));
+       if (buffer_is_empty(p->conf.encoding)) {
+-              BUFFER_APPEND_STRING_CONST(out, "iso-8859-1");
++              buffer_append_string_len(out, CONST_STR_LEN("iso-8859-1"));
+       } else {
+               buffer_append_string_buffer(out, p->conf.encoding);
+       }
+-      BUFFER_APPEND_STRING_CONST(out, "\"?>\n");
++      buffer_append_string_len(out, CONST_STR_LEN("\"?>\n"));
+       http_list_directory_header(srv, con, p, out);
+       /* directories */
+@@ -762,13 +760,13 @@
+               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_len(out, CONST_STR_LEN("<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, "/\">");
++              buffer_append_string_len(out, CONST_STR_LEN("/\">"));
+               buffer_append_string_encoded(out, DIRLIST_ENT_NAME(tmp), tmp->namelen, ENCODING_MINIMAL_XML);
+-              BUFFER_APPEND_STRING_CONST(out, "</a>/</td><td class=\"m\">");
++              buffer_append_string_len(out, CONST_STR_LEN("</a>/</td><td class=\"m\">"));
+               buffer_append_string_len(out, datebuf, sizeof(datebuf) - 1);
+-              BUFFER_APPEND_STRING_CONST(out, "</td><td class=\"s\">- &nbsp;</td><td class=\"t\">Directory</td></tr>\n");
++              buffer_append_string_len(out, CONST_STR_LEN("</td><td class=\"s\">- &nbsp;</td><td class=\"t\">Directory</td></tr>\n"));
+               free(tmp);
+       }
+@@ -818,17 +816,17 @@
+ #endif
+               http_list_directory_sizefmt(sizebuf, tmp->size);
+-              BUFFER_APPEND_STRING_CONST(out, "<tr><td class=\"n\"><a href=\"");
++              buffer_append_string_len(out, CONST_STR_LEN("<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, "\">");
++              buffer_append_string_len(out, CONST_STR_LEN("\">"));
+               buffer_append_string_encoded(out, DIRLIST_ENT_NAME(tmp), tmp->namelen, ENCODING_MINIMAL_XML);
+-              BUFFER_APPEND_STRING_CONST(out, "</a></td><td class=\"m\">");
++              buffer_append_string_len(out, CONST_STR_LEN("</a></td><td class=\"m\">"));
+               buffer_append_string_len(out, datebuf, sizeof(datebuf) - 1);
+-              BUFFER_APPEND_STRING_CONST(out, "</td><td class=\"s\">");
++              buffer_append_string_len(out, CONST_STR_LEN("</td><td class=\"s\">"));
+               buffer_append_string(out, sizebuf);
+-              BUFFER_APPEND_STRING_CONST(out, "</td><td class=\"t\">");
++              buffer_append_string_len(out, CONST_STR_LEN("</td><td class=\"t\">"));
+               buffer_append_string(out, content_type);
+-              BUFFER_APPEND_STRING_CONST(out, "</td></tr>\n");
++              buffer_append_string_len(out, CONST_STR_LEN("</td></tr>\n"));
+               free(tmp);
+       }
+@@ -841,11 +839,11 @@
  
        /* Insert possible charset to Content-Type */
        if (buffer_is_empty(p->conf.encoding)) {
 -              response_header_insert(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html"));
 +              response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html"));
        } else {
-               buffer_copy_string(p->content_charset, "text/html; charset=");
+-              buffer_copy_string(p->content_charset, "text/html; charset=");
++              buffer_copy_string_len(p->content_charset, CONST_STR_LEN("text/html; charset="));
                buffer_append_string_buffer(p->content_charset, p->conf.encoding);
 -              response_header_insert(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(p->content_charset));
 +              response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(p->content_charset));
        }
  
        con->file_finished = 1;
+@@ -861,6 +859,18 @@
+       UNUSED(srv);
++      /* we only handle GET, POST and HEAD */
++      switch(con->request.http_method) {
++      case HTTP_METHOD_GET:
++      case HTTP_METHOD_POST:
++      case HTTP_METHOD_HEAD:
++              break;
++      default:
++              return HANDLER_GO_ON;
++      }
++
++      if (con->mode != DIRECT) return HANDLER_GO_ON;
++
+       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;
+Index: src/http_chunk.c
+===================================================================
+--- src/http_chunk.c   (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/http_chunk.c   (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -27,7 +27,7 @@
+       b = srv->tmp_chunk_len;
+       if (len == 0) {
+-              buffer_copy_string(b, "0");
++              buffer_copy_string_len(b, CONST_STR_LEN("0"));
+       } else {
+               for (i = 0; i < 8 && len; i++) {
+                       len >>= 4;
+@@ -44,7 +44,7 @@
+               b->ptr[b->used++] = '\0';
+       }
+-      buffer_append_string(b, "\r\n");
++      buffer_append_string_len(b, CONST_STR_LEN("\r\n"));
+       chunkqueue_append_buffer(con->write_queue, b);
+       return 0;
 Index: src/mod_magnet.c
 ===================================================================
---- src/mod_magnet.c   (.../tags/lighttpd-1.4.19)      (revision 2199)
-+++ src/mod_magnet.c   (.../branches/lighttpd-1.4.x)   (revision 2199)
+--- src/mod_magnet.c   (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/mod_magnet.c   (.../branches/lighttpd-1.4.x)   (revision 2303)
 @@ -414,10 +414,16 @@
        case MAGNET_ENV_URI_AUTHORITY: dest = con->uri.authority; break;
        case MAGNET_ENV_URI_QUERY: dest = con->uri.query; break;
@@ -2039,12 +5931,23 @@ Index: src/mod_magnet.c
  
        case MAGNET_ENV_UNSET: break;
        }
-@@ -761,11 +767,13 @@
+@@ -647,6 +653,7 @@
+               assert(lua_gettop(L) == 0); /* only the function should be on the stack */
  
-       if (lua_return_value > 99) {
-               con->http_status = lua_return_value;
--              con->file_finished = 1;
+               con->http_status = 500;
++              con->mode = DIRECT;
+               return HANDLER_FINISHED;
+       }
+@@ -744,6 +751,7 @@
+               assert(lua_gettop(L) == 1); /* only the function should be on the stack */
  
+               con->http_status = 500;
++              con->mode = DIRECT;
+               return HANDLER_FINISHED;
+       }
+@@ -766,9 +774,13 @@
                /* try { ...*/
                if (0 == setjmp(exceptionjmp)) {
                        magnet_attach_content(srv, con, p, L);
@@ -2054,10 +5957,14 @@ Index: src/mod_magnet.c
                } else {
                        /* } catch () { */
                        con->http_status = 500;
++                      con->mode = DIRECT;
+               }
+               assert(lua_gettop(L) == 1); /* only the function should be on the stack */
 Index: src/log.c
 ===================================================================
---- src/log.c  (.../tags/lighttpd-1.4.19)      (revision 2199)
-+++ src/log.c  (.../branches/lighttpd-1.4.x)   (revision 2199)
+--- src/log.c  (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/log.c  (.../branches/lighttpd-1.4.x)   (revision 2303)
 @@ -31,6 +31,29 @@
  # define O_LARGEFILE 0
  #endif
@@ -2120,10 +6027,111 @@ Index: src/log.c
        return 0;
  }
  
+@@ -162,18 +185,18 @@
+               }
+               buffer_copy_string_buffer(srv->errorlog_buf, srv->ts_debug_str);
+-              BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, ": (");
++              buffer_append_string_len(srv->errorlog_buf, CONST_STR_LEN(": ("));
+               break;
+       case ERRORLOG_SYSLOG:
+               /* syslog is generating its own timestamps */
+-              BUFFER_COPY_STRING_CONST(srv->errorlog_buf, "(");
++              buffer_copy_string_len(srv->errorlog_buf, CONST_STR_LEN("("));
+               break;
+       }
+       buffer_append_string(srv->errorlog_buf, filename);
+-      BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, ".");
++      buffer_append_string_len(srv->errorlog_buf, CONST_STR_LEN("."));
+       buffer_append_long(srv->errorlog_buf, line);
+-      BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, ") ");
++      buffer_append_string_len(srv->errorlog_buf, CONST_STR_LEN(") "));
+       for(va_start(ap, fmt); *fmt; fmt++) {
+@@ -186,28 +209,28 @@
+               case 's':           /* string */
+                       s = va_arg(ap, char *);
+                       buffer_append_string(srv->errorlog_buf, s);
+-                      BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, " ");
++                      buffer_append_string_len(srv->errorlog_buf, CONST_STR_LEN(" "));
+                       break;
+               case 'b':           /* buffer */
+                       b = va_arg(ap, buffer *);
+                       buffer_append_string_buffer(srv->errorlog_buf, b);
+-                      BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, " ");
++                      buffer_append_string_len(srv->errorlog_buf, CONST_STR_LEN(" "));
+                       break;
+               case 'd':           /* int */
+                       d = va_arg(ap, int);
+                       buffer_append_long(srv->errorlog_buf, d);
+-                      BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, " ");
++                      buffer_append_string_len(srv->errorlog_buf, CONST_STR_LEN(" "));
+                       break;
+               case 'o':           /* off_t */
+                       o = va_arg(ap, off_t);
+                       buffer_append_off_t(srv->errorlog_buf, o);
+-                      BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, " ");
++                      buffer_append_string_len(srv->errorlog_buf, CONST_STR_LEN(" "));
+                       break;
+               case 'x':           /* int (hex) */
+                       d = va_arg(ap, int);
+-                      BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, "0x");
++                      buffer_append_string_len(srv->errorlog_buf, CONST_STR_LEN("0x"));
+                       buffer_append_long_hex(srv->errorlog_buf, d);
+-                      BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, " ");
++                      buffer_append_string_len(srv->errorlog_buf, CONST_STR_LEN(" "));
+                       break;
+               case 'S':           /* string */
+                       s = va_arg(ap, char *);
+@@ -221,6 +244,15 @@
+                       d = va_arg(ap, int);
+                       buffer_append_long(srv->errorlog_buf, d);
+                       break;
++              case 'O':           /* off_t */
++                      o = va_arg(ap, off_t);
++                      buffer_append_off_t(srv->errorlog_buf, o);
++                      break;
++              case 'X':           /* int (hex) */
++                      d = va_arg(ap, int);
++                      buffer_append_string_len(srv->errorlog_buf, CONST_STR_LEN("0x"));
++                      buffer_append_long_hex(srv->errorlog_buf, d);
++                      break;
+               case '(':
+               case ')':
+               case '<':
+@@ -235,11 +267,11 @@
+       switch(srv->errorlog_mode) {
+       case ERRORLOG_FILE:
+-              BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, "\n");
++              buffer_append_string_len(srv->errorlog_buf, CONST_STR_LEN("\n"));
+               write(srv->errorlog_fd, srv->errorlog_buf->ptr, srv->errorlog_buf->used - 1);
+               break;
+       case ERRORLOG_STDERR:
+-              BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, "\n");
++              buffer_append_string_len(srv->errorlog_buf, CONST_STR_LEN("\n"));
+               write(STDERR_FILENO, srv->errorlog_buf->ptr, srv->errorlog_buf->used - 1);
+               break;
+       case ERRORLOG_SYSLOG:
+Index: src/proc_open.c
+===================================================================
+--- src/proc_open.c    (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/proc_open.c    (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -184,7 +184,7 @@
+               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("\\system32\\cmd.exe"));
+       }
+       buffer_append_string_len(cmdline, CONST_STR_LEN(" /c "));
+       buffer_append_string(cmdline, command);
 Index: src/log.h
 ===================================================================
---- src/log.h  (.../tags/lighttpd-1.4.19)      (revision 2199)
-+++ src/log.h  (.../branches/lighttpd-1.4.x)   (revision 2199)
+--- src/log.h  (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ src/log.h  (.../branches/lighttpd-1.4.x)   (revision 2303)
 @@ -3,6 +3,11 @@
  
  #include "server.h"
@@ -2136,16 +6144,90 @@ Index: src/log.h
  #define WP() log_error_write(srv, __FILE__, __LINE__, "");
  
  int log_error_open(server *srv);
+Index: tests/env-variables.conf
+===================================================================
+--- tests/env-variables.conf   (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ tests/env-variables.conf   (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -1 +0,0 @@
+-server.document-root = env.CWD
+Index: tests/env-variables.t
+===================================================================
+--- tests/env-variables.t      (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ tests/env-variables.t      (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -1,21 +0,0 @@
+-#!/usr/bin/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 => 2;
+-use LightyTest;
+-
+-my $tf = LightyTest->new();
+-$tf->{CONFIGFILE} = 'env-variables.conf';
+-
+-TODO: {
+-    local $TODO = 'we still crash on undefined environment variables';
+-    ok($tf->start_proc == 0, "Starting lighttpd");
+-    ok($tf->stop_proc  == 0, "Stopping lighttpd");
+-};
+Index: tests/bug-12.conf
+===================================================================
+--- tests/bug-12.conf  (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ tests/bug-12.conf  (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -1,5 +1,4 @@
+ 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
+Index: tests/fastcgi-10.conf
+===================================================================
+--- tests/fastcgi-10.conf      (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ tests/fastcgi-10.conf      (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -1,5 +1,4 @@
+ 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
+Index: tests/bug-06.conf
+===================================================================
+--- tests/bug-06.conf  (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ tests/bug-06.conf  (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -1,5 +1,4 @@
+ 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
+Index: tests/mod-extforward.conf
+===================================================================
+--- tests/mod-extforward.conf  (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ tests/mod-extforward.conf  (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -3,7 +3,6 @@
+ debug.log-request-header   = "disable"
+ 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
 
 Property changes on: tests/symlink.t
 ___________________________________________________________________
-Name: svn:executable
+Added: svn:executable
    + *
 
 Index: tests/request.t
 ===================================================================
---- tests/request.t    (.../tags/lighttpd-1.4.19)      (revision 2199)
-+++ tests/request.t    (.../branches/lighttpd-1.4.x)   (revision 2199)
+--- tests/request.t    (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ tests/request.t    (.../branches/lighttpd-1.4.x)   (revision 2303)
 @@ -101,7 +101,7 @@
  Expect: 100-continue
  EOF
@@ -2155,17 +6237,122 @@ Index: tests/request.t
  ok($tf->handle_http($t) == 0, 'Continue, Expect');
  
  ## ranges
-
-Property changes on: tests/env-variables.t
-___________________________________________________________________
-Name: svn:executable
-   + *
-
+Index: tests/var-include.conf
+===================================================================
+--- tests/var-include.conf     (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ tests/var-include.conf     (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -3,7 +3,6 @@
+ debug.log-condition-handling = "enable"
+ 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
+Index: tests/mod-proxy.t
+===================================================================
+--- tests/mod-proxy.t  (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ tests/mod-proxy.t  (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -22,11 +22,9 @@
+ $tf_real->{PORT} = 2048;
+ $tf_real->{CONFIGFILE} = 'lighttpd.conf';
+-$tf_real->{LIGHTTPD_PIDFILE} = $tf_real->{TESTDIR}.'/tmp/lighttpd/lighttpd.pid';
+ $tf_proxy->{PORT} = 2050;
+ $tf_proxy->{CONFIGFILE} = 'proxy.conf';
+-$tf_proxy->{LIGHTTPD_PIDFILE} = $tf_proxy->{TESTDIR}.'/tmp/lighttpd/lighttpd-proxy.pid';
+ ok($tf_real->start_proc == 0, "Starting lighttpd") or die();
+Index: tests/404-handler.conf
+===================================================================
+--- tests/404-handler.conf     (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ tests/404-handler.conf     (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -3,7 +3,6 @@
+ debug.log-request-header   = "enable"
+ 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
+Index: tests/lowercase.conf
+===================================================================
+--- tests/lowercase.conf       (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ tests/lowercase.conf       (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -1,5 +1,4 @@
+ 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
+Index: tests/condition.conf
+===================================================================
+--- tests/condition.conf       (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ tests/condition.conf       (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -3,7 +3,6 @@
+ debug.log-condition-handling = "enable"
+ 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
+Index: tests/fastcgi-13.conf
+===================================================================
+--- tests/fastcgi-13.conf      (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ tests/fastcgi-13.conf      (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -1,5 +1,4 @@
+ server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
+-server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
+ debug.log-request-header   = "enable"
+ debug.log-response-header  = "enable"
+@@ -85,7 +84,7 @@
+                                   "grisu" => ( 
+                                   "host" => "127.0.0.1",
+                                   "port" => 1048,
+-                                  "bin-path" => "/usr/bin/php-cgi",
++                                  "bin-path" => env.PHP,
+                                   "bin-copy-environment" => ( "PATH", "SHELL", "USER" ),
+                                 )
+                               )
 Index: tests/mod-fastcgi.t
 ===================================================================
---- tests/mod-fastcgi.t        (.../tags/lighttpd-1.4.19)      (revision 2199)
-+++ tests/mod-fastcgi.t        (.../branches/lighttpd-1.4.x)   (revision 2199)
-@@ -65,7 +65,7 @@
+--- tests/mod-fastcgi.t        (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ tests/mod-fastcgi.t        (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -7,17 +7,27 @@
+ }
+ use strict;
+-use Test::More tests => 47;
++use Test::More tests => 49;
+ use LightyTest;
+ my $tf = LightyTest->new();
+ my $t;
++my $php_child = -1;
++my $phpbin = (defined $ENV{'PHP'} ? $ENV{'PHP'} : '/usr/bin/php-cgi');
++$ENV{'PHP'} = $phpbin;
++
+ SKIP: {
++      skip "PHP already running on port 1026", 1 if $tf->listening_on(1026);
++      skip "no php binary found", 1 unless -x $phpbin;
++      ok(-1 != ($php_child = $tf->spawnfcgi($phpbin, 1026)), "Spawning php");
++}
++
++SKIP: {
+       skip "no PHP running on port 1026", 29 unless $tf->listening_on(1026);
+-      ok($tf->start_proc == 0, "Starting lighttpd") or die();
++      ok($tf->start_proc == 0, "Starting lighttpd") or goto cleanup;
+       $t->{REQUEST} = ( <<EOF
+ GET /phpinfo.php HTTP/1.0
+@@ -65,7 +75,7 @@
  EOF
   );
        $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '/get-server-env.php' } ];
@@ -2174,26 +6361,532 @@ Index: tests/mod-fastcgi.t
  
        $t->{REQUEST}  = ( <<EOF
  GET /get-server-env.php/foo?env=PATH_INFO HTTP/1.0
+@@ -161,7 +171,7 @@
+       $tf->{CONFIGFILE} = 'fastcgi-10.conf';
+-      ok($tf->start_proc == 0, "Starting lighttpd with $tf->{CONFIGFILE}") or die();
++      ok($tf->start_proc == 0, "Starting lighttpd with $tf->{CONFIGFILE}") or goto cleanup;
+       $t->{REQUEST}  = ( <<EOF
+ GET /get-server-env.php?env=SERVER_NAME HTTP/1.0
+ Host: zzz.example.org
+@@ -173,7 +183,7 @@
+       ok($tf->stop_proc == 0, "Stopping lighttpd");
+       
+       $tf->{CONFIGFILE} = 'bug-06.conf';
+-      ok($tf->start_proc == 0, "Starting lighttpd with $tf->{CONFIGFILE}") or die();
++      ok($tf->start_proc == 0, "Starting lighttpd with $tf->{CONFIGFILE}") or goto cleanup;
+       $t->{REQUEST}  = ( <<EOF
+ GET /indexfile/ HTTP/1.0
+ Host: www.example.org
+@@ -185,7 +195,7 @@
+       ok($tf->stop_proc == 0, "Stopping lighttpd");
+       $tf->{CONFIGFILE} = 'bug-12.conf';
+-      ok($tf->start_proc == 0, "Starting lighttpd with bug-12.conf") or die();
++      ok($tf->start_proc == 0, "Starting lighttpd with bug-12.conf") or goto cleanup;
+       $t->{REQUEST}  = ( <<EOF
+ POST /indexfile/abc HTTP/1.0
+ Host: www.example.org
+@@ -199,6 +209,12 @@
+ }
+ SKIP: {
++      skip "PHP not started, cannot stop it", 1 unless $php_child != -1;
++      ok(0 == $tf->endspawnfcgi($php_child), "Stopping php");
++      $php_child = -1;
++}
++
++SKIP: {
+       skip "no fcgi-auth found", 4 unless -x $tf->{BASEDIR}."/tests/fcgi-auth" || -x $tf->{BASEDIR}."/tests/fcgi-auth.exe"; 
+       $tf->{CONFIGFILE} = 'fastcgi-auth.conf';
+@@ -223,7 +239,7 @@
+ }
+ SKIP: {
+-      skip "no php found", 5 unless -x "/usr/bin/php-cgi"; 
++      skip "no php found", 5 unless -x $phpbin;
+       $tf->{CONFIGFILE} = 'fastcgi-13.conf';
+       ok($tf->start_proc == 0, "Starting lighttpd with $tf->{CONFIGFILE}") or die();
+       $t->{REQUEST}  = ( <<EOF
+@@ -325,3 +341,10 @@
+       ok($tf->stop_proc == 0, "Stopping lighttpd");
+ }
++exit 0;
++
++cleanup: ;
++
++$tf->endspawnfcgi($php_child) if $php_child != -1;
++
++die();
+Index: tests/mod-rewrite.t
+===================================================================
+--- tests/mod-rewrite.t        (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ tests/mod-rewrite.t        (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -8,18 +8,26 @@
+ use strict;
+ use IO::Socket;
+-use Test::More tests => 5;
++use Test::More tests => 8;
+ use LightyTest;
+ my $tf = LightyTest->new();
+ my $t;
++my $php_child = -1;
++my $phpbin = (defined $ENV{'PHP'} ? $ENV{'PHP'} : '/usr/bin/php-cgi');
+ SKIP: {
+-      skip "no PHP running on port 1026", 5 unless $tf->listening_on(1026);
++      skip "PHP already running on port 1026", 1 if $tf->listening_on(1026);
++      skip "no php binary found", 1 unless -x $phpbin;
++      ok(-1 != ($php_child = $tf->spawnfcgi($phpbin, 1026)), "Spawning php");
++}
+-      ok($tf->start_proc == 0, "Starting lighttpd") or die();
++SKIP: {
++      skip "no PHP running on port 1026", 6 unless $tf->listening_on(1026);
++      ok($tf->start_proc == 0, "Starting lighttpd") or goto cleanup;
++
+       $t->{REQUEST}  = ( <<EOF
+ GET /rewrite/foo HTTP/1.0
+ Host: www.example.org
+@@ -44,5 +52,27 @@
+       $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => 'bar&a=b' } ];
+       ok($tf->handle_http($t) == 0, 'valid request');
++      $t->{REQUEST}  = ( <<EOF
++GET %2Frewrite/f%6Fo?a=b HTTP/1.0
++Host: www.example.org
++EOF
++ );
++      $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => 'a=b' } ];
++      ok($tf->handle_http($t) == 0, 'valid request with url encoded characters');
++
+       ok($tf->stop_proc == 0, "Stopping lighttpd");
+ }
++
++SKIP: {
++      skip "PHP not started, cannot stop it", 1 unless $php_child != -1;
++      ok(0 == $tf->endspawnfcgi($php_child), "Stopping php");
++}
++
++
++exit 0;
++
++cleanup: ;
++
++$tf->endspawnfcgi($php_child) if $php_child != -1;
++
++die();
+Index: tests/lighttpd.conf
+===================================================================
+--- tests/lighttpd.conf        (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ tests/lighttpd.conf        (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -3,7 +3,6 @@
+ debug.log-response-header = "enable"
+ debug.log-condition-handling = "enable"
+ server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
+-server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
+ ## 64 Mbyte ... nice limit
+ server.max-request-size = 65000
+Index: tests/fastcgi-responder.conf
+===================================================================
+--- tests/fastcgi-responder.conf       (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ tests/fastcgi-responder.conf       (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -1,5 +1,4 @@
+ server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
+-server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
+ #debug.log-request-header   = "enable"
+ #debug.log-response-header  = "enable"
+Index: tests/fastcgi-auth.conf
+===================================================================
+--- tests/fastcgi-auth.conf    (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ tests/fastcgi-auth.conf    (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -1,5 +1,4 @@
+ server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
+-server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
+ debug.log-request-header   = "enable"
+ debug.log-response-header  = "enable"
+Index: tests/proxy.conf
+===================================================================
+--- tests/proxy.conf   (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ tests/proxy.conf   (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -1,5 +1,4 @@
+ server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
+-server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd-proxy.pid"
+ ## bind to port (default: 80)
+ server.port                 = 2050
 Index: tests/docroot/www/get-env.php
 ===================================================================
---- tests/docroot/www/get-env.php      (.../tags/lighttpd-1.4.19)      (revision 2199)
-+++ tests/docroot/www/get-env.php      (.../branches/lighttpd-1.4.x)   (revision 2199)
+--- tests/docroot/www/get-env.php      (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ tests/docroot/www/get-env.php      (.../branches/lighttpd-1.4.x)   (revision 2303)
 @@ -1,3 +1,4 @@
  <?php
 -      print $_ENV[$_GET["env"]];
 +      $env = $_GET["env"];
 +      print isset($_ENV[$env]) ? $_ENV[$env] : '';
  ?>
+Index: tests/docroot/www/Makefile.am
+===================================================================
+--- tests/docroot/www/Makefile.am      (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ tests/docroot/www/Makefile.am      (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -1,4 +1,4 @@
+-EXTRA_DIST=cgi.php cgi.pl dummydir index.html index.txt phpinfo.php \
++EXTRA_DIST=cgi.php cgi.pl index.html index.txt phpinfo.php \
+          redirect.php cgi-pathinfo.pl get-env.php get-server-env.php \
+          nph-status.pl prefix.fcgi get-header.pl ssi.shtml get-post-len.pl \
+          exec-date.shtml index.html~ 404.fcgi 404.html 404.pl send404.pl crlfcrash.pl
+Index: tests/Makefile.am
+===================================================================
+--- tests/Makefile.am  (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ tests/Makefile.am  (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -42,8 +42,6 @@
+       mod-redirect.t \
+       mod-rewrite.t \
+       mod-userdir.t \
+-        env-variables.t \
+-        env-variables.conf \
+         symlink.t \
+       request.t \
+       mod-ssi.t \
 
 Property changes on: tests/core-404-handler.t
 ___________________________________________________________________
-Name: svn:executable
+Added: svn:executable
    + *
 
+Index: tests/LightyTest.pm
+===================================================================
+--- tests/LightyTest.pm        (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ tests/LightyTest.pm        (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -6,6 +6,7 @@
+ use Test::More;
+ use Socket;
+ use Cwd 'abs_path';
++use POSIX ":sys_wait_h";
+ sub mtime {
+       my $file = shift;
+@@ -30,14 +31,17 @@
+       if (mtime($self->{BASEDIR}.'/src/lighttpd') > mtime($self->{BASEDIR}.'/build/lighttpd')) {
+-              $self->{LIGHTTPD_PATH} = $self->{BASEDIR}.'/src/lighttpd';
+-              $self->{MODULES_PATH} = $self->{BASEDIR}.'/src/.libs';
++              $self->{BINDIR} = $self->{BASEDIR}.'/src';
++              if (mtime($self->{BASEDIR}.'/src/.libs')) {
++                      $self->{MODULES_PATH} = $self->{BASEDIR}.'/src/.libs';
++              } else {
++                      $self->{MODULES_PATH} = $self->{BASEDIR}.'/src';
++              }
+       } else {
+-              $self->{LIGHTTPD_PATH} = $self->{BASEDIR}.'/build/lighttpd';
++              $self->{BINDIR} = $self->{BASEDIR}.'/build';
+               $self->{MODULES_PATH} = $self->{BASEDIR}.'/build';
+       }
+-      $self->{LIGHTTPD_PIDFILE} = $self->{TESTDIR}.'/tmp/lighttpd/lighttpd.pid';
+-      $self->{PIDOF_PIDFILE} = $self->{TESTDIR}.'/tmp/lighttpd/pidof.pid';
++      $self->{LIGHTTPD_PATH} = $self->{BINDIR}.'/lighttpd';
+       $self->{PORT} = 2048;
+       my ($name, $aliases, $addrtype, $net) = gethostbyaddr(inet_aton("127.0.0.1"), AF_INET);
+@@ -66,59 +70,73 @@
+ sub stop_proc {
+       my $self = shift;
+-      open F, $self->{LIGHTTPD_PIDFILE} or return -1;
+-      my $pid = <F>;
+-      close F;
++      my $pid = $self->{LIGHTTPD_PID};
++      if (defined $pid && $pid != -1) {
++              kill('TERM', $pid) or return -1;
++              return -1 if ($pid != waitpid($pid, 0));
++      } else {
++              diag("Process not started, nothing to stop");
++              return -1;
++      }
+-      if (defined $pid) {
+-              kill('TERM',$pid) or return -1;
++      return 0;
++}
++
++sub wait_for_port_with_proc {
++      my $self = shift;
++      my $port = shift;
++      my $child = shift;
++
++      while (0 == $self->listening_on($port)) {
+               select(undef, undef, undef, 0.1);
++
++              # the process is gone, we failed
++              if (0 != waitpid($child, WNOHANG)) {
++                      return -1;
++              }
+       }
+       return 0;
+ }
+-
+ sub start_proc {
+       my $self = shift;
+       # kill old proc if necessary
+-      $self->stop_proc;
++      #$self->stop_proc;
+       # pre-process configfile if necessary
+       #
+       $ENV{'SRCDIR'} = $self->{BASEDIR}.'/tests';
++      $ENV{'PORT'} = $self->{PORT};
+-      unlink($self->{LIGHTTPD_PIDFILE});
++      my $cmdline = $self->{LIGHTTPD_PATH}." -D -f ".$self->{SRCDIR}."/".$self->{CONFIGFILE}." -m ".$self->{MODULES_PATH};
+       if (defined $ENV{"TRACEME"} && $ENV{"TRACEME"} eq 'strace') {
+-              system("strace -tt -s 512 -o strace ".$self->{LIGHTTPD_PATH}." -D -f ".$self->{SRCDIR}."/".$self->{CONFIGFILE}." -m ".$self->{MODULES_PATH}." &");
++              $cmdline = "strace -tt -s 512 -o strace ".$cmdline;
+       } elsif (defined $ENV{"TRACEME"} && $ENV{"TRACEME"} eq 'truss') {
+-              system("/usr/dtrctkit/bin/dtruss -d -e ".$self->{LIGHTTPD_PATH}." -D -f ".$self->{SRCDIR}."/".$self->{CONFIGFILE}." -m ".$self->{MODULES_PATH}." 2> strace &");
++              $cmdline = "truss -a -l -w all -v all -o strace ".$cmdline;
++      } elsif (defined $ENV{"TRACEME"} && $ENV{"TRACEME"} eq 'gdb') {
++              $cmdline = "gdb --batch --ex 'run' --ex 'bt' --args ".$cmdline." > gdb.out";
+       } elsif (defined $ENV{"TRACEME"} && $ENV{"TRACEME"} eq 'valgrind') {
+-              system("valgrind --tool=memcheck --show-reachable=yes --leak-check=yes --log-file=valgrind ".$self->{LIGHTTPD_PATH}." -D -f ".$self->{SRCDIR}."/".$self->{CONFIGFILE}." -m ".$self->{MODULES_PATH}." &");
+-      } else {
+-              system($self->{LIGHTTPD_PATH}." -f ".$self->{SRCDIR}."/".$self->{CONFIGFILE}." -m ".$self->{MODULES_PATH});
++              $cmdline = "valgrind --tool=memcheck --show-reachable=yes --leak-check=yes --log-file=valgrind ".$cmdline;
+       }
+-
+-      select(undef, undef, undef, 0.1);
+-      if (not -e $self->{LIGHTTPD_PIDFILE} or 0 == kill 0, `cat $self->{LIGHTTPD_PIDFILE}`) {
+-              select(undef, undef, undef, 2); 
+-      }
+-
+-      unlink($self->{TESTDIR}."/tmp/cfg.file");
+-
+-      # no pidfile, we failed
+-      if (not -e $self->{LIGHTTPD_PIDFILE}) {
+-              diag(sprintf('Could not find pidfile: %s', $self->{LIGHTTPD_PIDFILE}));
++      # diag("starting lighttpd at :".$self->{PORT}.", cmdline: ".$cmdline );
++      my $child = fork();
++      if (not defined $child) {
++              diag("Fork failed");
+               return -1;
+       }
++      if ($child == 0) {
++              exec $cmdline or die($?);
++      }
+-      # the process is gone, we failed
+-      if (0 == kill 0, `cat $self->{LIGHTTPD_PIDFILE}`) {
+-              diag(sprintf('the process referenced by %s is not up', $self->{LIGHTTPD_PIDFILE}));
++      if (0 != $self->wait_for_port_with_proc($self->{PORT}, $child)) {
++              diag(sprintf('The process %i is not up', $child));
+               return -1;
+       }
++      $self->{LIGHTTPD_PID} = $child;
++
+       0;
+ }
+@@ -131,6 +149,7 @@
+       my @request = $t->{REQUEST};
+       my @response = $t->{RESPONSE};
++      my $is_debug = $ENV{"TRACE_HTTP"};
+       my $remote = 
+         IO::Socket::INET->new(Proto    => "tcp",
+@@ -144,20 +163,27 @@
+       $remote->autoflush(1);
++      diag("sending request header to ".$host.":".$self->{PORT}) if $is_debug;
+       foreach(@request) {
+               # pipeline requests
+               s/\r//g;
+               s/\n/$EOL/g;
+-              print $remote $_.$BLANK;        
++              print $remote $_.$BLANK;
++              diag("<< ".$_) if $is_debug;
+       }
++      shutdown($remote, 1); # I've stopped writing data
++      diag("... done") if $is_debug;
+       my $lines = "";
++      diag("receiving response") if $is_debug;
+       # read everything
+       while(<$remote>) {
+               $lines .= $_;
++              diag(">> ".$_) if $is_debug;
+       }
++      diag("... done") if $is_debug;
+       
+       close $remote;
+@@ -187,18 +213,24 @@
+                                       (my $h = $1) =~ tr/[A-Z]/[a-z]/;
+                                       if (defined $resp_hdr{$h}) {
+-                                              diag(sprintf("header %s is duplicated: %s and %s\n",
+-                                                           $h, $resp_hdr{$h}, $2));
++#                                             diag(sprintf("header '%s' is duplicated: '%s' and '%s'\n",
++#                                                          $h, $resp_hdr{$h}, $2));
++                                              $resp_hdr{$h} .= ', '.$2;
+                                       } else {
+                                               $resp_hdr{$h} = $2;
+                                       }
+                               } else {
+-                                      diag(sprintf("unexpected line '$line'\n"));
++                                      diag(sprintf("unexpected line '%s'\n", $line));
+                                       return -1;
+                               }
+                       }
+               }
++              if (not defined($resp_line)) {
++                      diag(sprintf("empty response\n"));
++                      return -1;
++              }
++
+               $t->{etag} = $resp_hdr{'etag'};
+               $t->{date} = $resp_hdr{'date'};
+@@ -227,7 +259,7 @@
+                               return -1;
+                       }
+               } else {
+-                      diag(sprintf("unexpected resp_line '$resp_line'\n"));
++                      diag(sprintf("unexpected resp_line '%s'\n", $resp_line));
+                       return -1;
+               }
+@@ -237,7 +269,9 @@
+                               diag(sprintf("body failed: expected '%s', got '%s'\n", $href->{'HTTP-Content'}, $resp_body));
+                               return -1;
+                       }
+-              } elsif (defined $href->{'-HTTP-Content'}) {
++              }
++              
++              if (defined $href->{'-HTTP-Content'}) {
+                       if (defined $resp_body && $resp_body ne '') {
+                               diag(sprintf("body failed: expected empty body, got '%s'\n", $resp_body));
+                               return -1;
+@@ -245,7 +279,6 @@
+               }
+               foreach (keys %{ $href }) {
+-                      ## filter special keys
+                       next if $_ eq 'HTTP-Protocol';
+                       next if $_ eq 'HTTP-Status';
+                       next if $_ eq 'HTTP-Content';
+@@ -257,7 +290,6 @@
+                       my $key_inverted = 0;
+                       if (substr($k, 0, 1) eq '+') {
+-                              ## the key has to exist, but the value is ignored
+                               $k = substr($k, 1);
+                               $verify_value = 0;
+                       } elsif (substr($k, 0, 1) eq '-') {
+@@ -265,11 +297,11 @@
+                               $k = substr($k, 1);
+                               $key_inverted = 1;
+                               $verify_value = 0; ## skip the value check
+-                      }
++                        }
+                       if ($key_inverted) {
+                               if (defined $resp_hdr{$k}) {
+-                                      diag(sprintf("required header '%s' is missing\n", $k));
++                                      diag(sprintf("header '%s' MUST not be set\n", $k));
+                                       return -1;
+                               }
+                       } else {
+@@ -297,12 +329,38 @@
+       # we should have sucked up everything
+       if (defined $lines) {
+-              diag(sprintf("unexpected lines '$lines'\n"));
++              diag(sprintf("unexpected lines '%s'\n", $lines));
+               return -1;
+       }
+       return 0;
+ }
+-    
++
++sub spawnfcgi {
++      my ($self, $binary, $port) = @_;
++      my $child = fork();
++      if (not defined $child) {
++              diag("Couldn't fork\n");
++              return -1;
++      }
++      if ($child == 0) {
++              my $cmd = $self->{BINDIR}.'/spawn-fcgi -n -p '.$port.' -f "'.$binary.'"';
++              exec $cmd or die($?);
++      } else {
++              if (0 != $self->wait_for_port_with_proc($port, $child)) {
++                      diag(sprintf('The process %i is not up (port %i, %s)', $child, $port, $binary));
++                      return -1;
++              }
++              return $child;
++      }
++}
++
++sub endspawnfcgi {
++      my ($self, $pid) = @_;
++      return -1 if (-1 == $pid);
++      kill(2, $pid);
++      waitpid($pid, 0);
++      return 0;
++}
++
+ 1;
+-
+Index: tests/run-tests.pl
+===================================================================
+--- tests/run-tests.pl (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ tests/run-tests.pl (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -3,17 +3,18 @@
+ use strict;
+ use Test::Harness qw(&runtests $verbose);
+-$verbose = (defined $ENV{'VERBOSE'} ? $ENV{'VERBOSE'} : 0);;
++$verbose = (defined $ENV{'VERBOSE'} ? $ENV{'VERBOSE'} : 0);
++my $tests = (defined $ENV{'TESTS'} ? $ENV{'TESTS'} : '');
+ my $srcdir = (defined $ENV{'srcdir'} ? $ENV{'srcdir'} : '.');
+ opendir DIR, $srcdir;
+ my (@fs, $f);
+ while ($f = readdir(DIR)) {
+-      if ($f =~ /\.t$/) {
++      if ($f =~ /^(.*)\.t$/) {
++              next if ($tests ne '' and $tests !~ /(^|\s+)$1(\s+|$)/);
+               push @fs, $srcdir.'/'.$f;
+       }
+ }
+ closedir DIR;
+ runtests @fs;
+-
 Index: doc/userdir.txt
 ===================================================================
---- doc/userdir.txt    (.../tags/lighttpd-1.4.19)      (revision 2199)
-+++ doc/userdir.txt    (.../branches/lighttpd-1.4.x)   (revision 2199)
+--- doc/userdir.txt    (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ doc/userdir.txt    (.../branches/lighttpd-1.4.x)   (revision 2303)
 @@ -46,10 +46,10 @@
  Options
  =======
@@ -2207,10 +6900,21 @@ Index: doc/userdir.txt
    Example: ::
  
      userdir.path = "public_html"
+Index: doc/configuration.txt
+===================================================================
+--- doc/configuration.txt      (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ doc/configuration.txt      (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -513,3 +513,6 @@
+ debug.log-request-handling
+   default: disabled
++
++debug.log-ssl-noise
++  default: disabled
 Index: SConstruct
 ===================================================================
---- SConstruct (.../tags/lighttpd-1.4.19)      (revision 2199)
-+++ SConstruct (.../branches/lighttpd-1.4.x)   (revision 2199)
+--- SConstruct (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ SConstruct (.../branches/lighttpd-1.4.x)   (revision 2303)
 @@ -5,7 +5,7 @@
  from stat import *
  
@@ -2222,18 +6926,20 @@ Index: SConstruct
        p = re.compile('[^A-Z0-9]')
 Index: Makefile.am
 ===================================================================
---- Makefile.am        (.../tags/lighttpd-1.4.19)      (revision 2199)
-+++ Makefile.am        (.../branches/lighttpd-1.4.x)   (revision 2199)
-@@ -1,3 +1,3 @@
+--- Makefile.am        (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ Makefile.am        (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -1,3 +1,5 @@
  SUBDIRS=src doc tests cygwin openwrt
  
 -EXTRA_DIST=lighttpd.spec autogen.sh SConstruct
 +EXTRA_DIST=autogen.sh SConstruct
++
++distcleancheck_listfiles = find -type f -exec sh -c 'test -f $(srcdir)/{} || echo {}' ';'
 Index: NEWS
 ===================================================================
---- NEWS       (.../tags/lighttpd-1.4.19)      (revision 2199)
-+++ NEWS       (.../branches/lighttpd-1.4.x)   (revision 2199)
-@@ -3,8 +3,33 @@
+--- NEWS       (.../tags/lighttpd-1.4.19)      (revision 2303)
++++ NEWS       (.../branches/lighttpd-1.4.x)   (revision 2303)
+@@ -3,8 +3,67 @@
  NEWS
  ====
  
@@ -2262,6 +6968,40 @@ Index: NEWS
 +  * Implement a clean way to open /dev/null and use it to close stdin/out/err in the needed places (#624)
 +  * merge spawn-fcgi changes from trunk (from @2191)
 +  * let spawn-fcgi propagate exit code from spawned fcgi application
++  * close connection after redirect in trigger_b4_dl (thx icy)
++  * close connection in mod_magnet if returned status code
++  * fix bug with IPv6 in mod_evasive (#1579)
++  * fix scgi HTTP/1.* status parsing (#1638), found by met@uberstats.com
++  * [tests] fixed system, use foreground daemons and waitpid
++  * [tests] removed pidfile from test system
++  * [tests] fixed tests needing php running (if not running on port 1026, search php in env[PHP] or /usr/bin/php-cgi)
++  * fixed typo in mod_accesslog (#1699)
++  * replaced buffer_{append,copy}_string with the _len variant where possible (#1732) (thx crypt)
++  * case insensitive match for secdownload md5 token (#1710)
++  * Handle only HEAD, GET and POST in mod_dirlisting (same as in staticfile) (#1687)
++  * fixed mod_secdownload problem with unsigned time_t (#1688)
++  * handle EAGAIN and EINTR for freebsd sendfile (#1675)
++  * Use filedescriptor 0 for mod_scgi spawn socket, redirect STDERR to /dev/null (#1716)
++  * fixed round-robin balancing in mod_proxy (#1715)
++  * fixed EINTR handling for waitpid in mod_fastcgi
++  * mod_{fast,s}cgi: overwrite environment variables (#1722)
++  * inserted many con->mode checks; they should prevent two modules to handle the same request if they shouldn't (#631)
++  * fixed url encoding to encode more characters (#266)
++  * allow digits in [s]cgi env vars (#1712)
++  * fixed dropping last character of evhost pattern (#161)
++  * print helpful error message on conditionals in global block (#1550)
++  * decode url before matching in mod_rewrite (#1720)
++  * fixed conditional patching of ldap filter (#1564)
++  * Match headers case insensitive in response (removing of X-{Sendfile,LIGHTTPD-*}, catching Date/Server)
++  * fixed bug with case-insensitive filenames in mod_userdir (#1589), spotted by "anders1"
++  * fixed format string bugs in mod_accesslog for SYSLOG
++  * replaced fprintf with log_error_write in fastcgi debug
++  * fixed mem leak in ssi expression parser (#1753), thx Take5k
++  * hide some ssl errors per default, enable them with debug.log-ssl-noise (#397)
++  * do not send content-encoding for 304 (#1754), thx yzlai
++  * fix segfault for stat_cache(fam) calls with relative path (without '/', can be triggered by x-sendfile) (#1750)
++  * fix splitting of auth-ldap filter
++  * workaround ldap connection leak if a ldap connection failed (restarting ldap)
 +
 +- 1.4.19 - 2008-03-10
 +
@@ -2273,7 +7013,7 @@ Index: .cvsignore
 
 Property changes on: .
 ___________________________________________________________________
-Name: svk:merge
+Modified: svk:merge
    - 152afb58-edef-0310-8abb-c4023f1b3aa9:/branches/lighttpd-1.3.x:499
 152afb58-edef-0310-8abb-c4023f1b3aa9:/branches/lighttpd-1.4.11-ssl-fixes:1346
 152afb58-edef-0310-8abb-c4023f1b3aa9:/branches/lighttpd-merge-1.4.x:1041
@@ -2290,4 +7030,58 @@ ebd0e9cf-3e47-4385-9dd4-f0e25e97baa2:/local/lighttpd/branches/lighttpd-1.4.x:216
 152afb58-edef-0310-8abb-c4023f1b3aa9:/trunk:104
 a98e19e4-a712-0410-8832-6551a15ffc53:/local/branches/lighttpd-1.4.x:1557
 ebd0e9cf-3e47-4385-9dd4-f0e25e97baa2:/local/lighttpd/branches/lighttpd-1.4.x:2250
+Added: bzr:revision-info
+   + timestamp: 2008-09-17 16:23:00.644000053 +0200
+committer: Stefan Bühler <stbuehler@web.de>
+properties: 
+       branch-nick: lighttpd-1.4.x
+
+Added: bzr:file-ids
+   + 
+Added: bzr:revision-id:v3-trunk0
+   + 1127 stbuehler@web.de-20080728081644-j4cxnhduw8kbt8um
+1128 stbuehler@web.de-20080728084246-axvxdtjsrratxixs
+1129 stbuehler@web.de-20080729211700-s8v6nq2cu06qesls
+1130 stbuehler@web.de-20080729211726-4yxb6e5dva1cn0lz
+1131 stbuehler@web.de-20080729211750-4ulzigswx17uciyu
+1132 stbuehler@web.de-20080729211850-nliz3kd0m576ztuu
+1133 stbuehler@web.de-20080730163440-dg2y2sbf0u4grmn4
+1134 stbuehler@web.de-20080730173952-kiutzg6geqy7mick
+1135 stbuehler@web.de-20080730193616-9kc2ms7rrhv1lkn7
+1136 stbuehler@web.de-20080730211457-z4a6uth1y29glbqh
+1137 stbuehler@web.de-20080730213517-b6sjcrdwbmipl334
+1138 stbuehler@web.de-20080731102617-2xw8unjfqic7lsew
+1139 stbuehler@web.de-20080731102703-q4tu5a6em9y8xdg0
+1140 stbuehler@web.de-20080731102729-l6vn5b05w9swqbg5
+1141 stbuehler@web.de-20080731102756-oj3d4tnk0l90mj77
+1142 stbuehler@web.de-20080731204442-blw14cj2fkr3l8ly
+1143 stbuehler@web.de-20080731204508-imtfnurf922mg7tj
+1144 stbuehler@web.de-20080801112347-girnwswdkwm8wuip
+1145 stbuehler@web.de-20080801161245-kx1temr529o7xko9
+1146 stbuehler@web.de-20080801175332-oc9e7x8edn1owcc0
+1147 stbuehler@web.de-20080801183454-5i66v0gsdv0cgmia
+1148 stbuehler@web.de-20080801192849-6zklfbb832sx0hvr
+1149 stbuehler@web.de-20080801203119-o16elp8w854s6lol
+1150 stbuehler@web.de-20080802162146-a4v57svc788pwdsv
+1151 stbuehler@web.de-20080802162202-9udlc1wuwt09pyh2
+1152 stbuehler@web.de-20080804135803-yuor9ze06px7qta4
+1153 stbuehler@web.de-20080812194728-fupt781o6q058unh
+1154 stbuehler@web.de-20080818162116-piz0ukqsaecv2li2
+1155 stbuehler@web.de-20080818235700-94t0xc6ml70zojwq
+1156 stbuehler@web.de-20080819163650-1qhwsqszr78cr4xx
+1157 stbuehler@web.de-20080819163757-1qq3t1f1wj69t8xs
+1158 stbuehler@web.de-20080819163914-rklhkurg8apv85l2
+1159 stbuehler@web.de-20080819163953-tlqew751e43phf5b
+1160 stbuehler@web.de-20080819164108-8ogh68sm1uyteawe
+1161 stbuehler@web.de-20080819173911-w5bqpb7cp9jmdqye
+1162 stbuehler@web.de-20080819222242-c0ta5gnli9p3j35a
+1163 stbuehler@web.de-20080820100730-g1bwdh4nqb53ag9u
+1164 stbuehler@web.de-20080820100752-9pggugdyfnnps8qu
+1165 stbuehler@web.de-20080820164258-v2j00motsrsc5esp
+1166 stbuehler@web.de-20080827144628-hi9hf4ch3n1wf9ao
+1167 stbuehler@web.de-20080827144903-tfxu4yehlyu5kegc
+1168 stbuehler@web.de-20080827155155-7mt92orehbxkh2lh
+1169 stbuehler@web.de-20080917142048-zbcwpk39q9ewd516
+1170 stbuehler@web.de-20080917142300-16gzt21x4nbjtj87
+
 
This page took 0.769826 seconds and 4 git commands to generate.