X-Git-Url: http://git.pld-linux.org/?a=blobdiff_plain;f=lighttpd-branch.diff;h=c9ee19e9c4d51d7924b8eb10ba8cb0f92ffdc883;hb=ae21d33d0a2f24ba3f93fbb7d163af468e196255;hp=76ef47a9d7dcb133adb2cd6d36c1213cbf353bab;hpb=99ee3d188f96cb64c1b959e241502a6fa9a3ca41;p=packages%2Flighttpd.git diff --git a/lighttpd-branch.diff b/lighttpd-branch.diff index 76ef47a..c9ee19e 100644 --- a/lighttpd-branch.diff +++ b/lighttpd-branch.diff @@ -1,1250 +1,3065 @@ -Index: configure.in +Index: ChangeLog =================================================================== ---- configure.in (.../tags/lighttpd-1.4.13) (revision 1718) -+++ configure.in (.../branches/lighttpd-1.4.x) (revision 1718) -@@ -398,7 +398,7 @@ +Index: .cvsignore +=================================================================== +Index: src/.cvsignore +=================================================================== +Index: src/configfile-glue.c +=================================================================== +--- src/configfile-glue.c (.../tags/lighttpd-1.4.23) ++++ src/configfile-glue.c (.../branches/lighttpd-1.4.x) +@@ -103,7 +103,6 @@ + if (e != ds->value->ptr && !*e && l >=0 && l <= 65535) { + *((unsigned short *)(cv[i].destination)) = l; + break; +- + } + } + +@@ -112,10 +111,40 @@ + return -1; + } + default: +- log_error_write(srv, __FILE__, __LINE__, "ssds", "unexpected type for key:", cv[i].key, du->type, "expected a integer, range 0 ... 65535"); ++ log_error_write(srv, __FILE__, __LINE__, "ssds", "unexpected type for key:", cv[i].key, du->type, "expected a short integer, range 0 ... 65535"); + return -1; + } + break; ++ case T_CONFIG_INT: ++ switch(du->type) { ++ case TYPE_INTEGER: { ++ data_integer *di = (data_integer *)du; ++ ++ *((unsigned int *)(cv[i].destination)) = di->value; ++ break; ++ } ++ case TYPE_STRING: { ++ data_string *ds = (data_string *)du; ++ ++ if (ds->value->ptr && *ds->value->ptr) { ++ char *e; ++ long l = strtol(ds->value->ptr, &e, 10); ++ if (e != ds->value->ptr && !*e && l >= 0) { ++ *((unsigned int *)(cv[i].destination)) = l; ++ break; ++ } ++ } ++ ++ ++ log_error_write(srv, __FILE__, __LINE__, "ssb", "got a string but expected an integer:", cv[i].key, ds->value); ++ ++ return -1; ++ } ++ default: ++ log_error_write(srv, __FILE__, __LINE__, "ssds", "unexpected type for key:", cv[i].key, du->type, "expected an integer, range 0 ... 4294967295"); ++ return -1; ++ } ++ break; + case T_CONFIG_BOOLEAN: + if (du->type == TYPE_STRING) { + data_string *ds = (data_string *)du; +Index: src/mod_cgi.c +=================================================================== +--- src/mod_cgi.c (.../tags/lighttpd-1.4.23) ++++ src/mod_cgi.c (.../branches/lighttpd-1.4.x) +@@ -56,6 +56,7 @@ - AC_MSG_RESULT($WITH_LUA) - if test "$WITH_LUA" != "no"; then -- if test "$WITH_LUA" == "yes"; then -+ if test "$WITH_LUA" = "yes"; then - WITH_LUA=lua - fi - PKG_CHECK_MODULES(LUA, $WITH_LUA >= 5.1, [ -@@ -538,7 +538,7 @@ - AC_OUTPUT + typedef struct { + array *cgi; ++ unsigned short execute_x_only; + } plugin_config; + typedef struct { +@@ -151,6 +152,7 @@ --do_build="mod_cgi mod_fastcgi mod_proxy mod_evhost mod_simple_vhost mod_access mod_alias mod_setenv mod_usertrack mod_auth mod_status mod_accesslog mod_rrdtool mod_secdownload mod_expire mod_compress mod_dirlisting mod_indexfiles mod_userdir mod_webdav mod_staticfile mod_scgi mod_flv_streaming" -+do_build="mod_cgi mod_fastcgi mod_extforward mod_proxy mod_evhost mod_simple_vhost mod_access mod_alias mod_setenv mod_usertrack mod_auth mod_status mod_accesslog mod_rrdtool mod_secdownload mod_expire mod_compress mod_dirlisting mod_indexfiles mod_userdir mod_webdav mod_staticfile mod_scgi mod_flv_streaming" + config_values_t cv[] = { + { "cgi.assign", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 0 */ ++ { "cgi.execute-x-only", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 1 */ + { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET} + }; - plugins="mod_rewrite mod_redirect mod_ssi mod_trigger_b4_dl" - features="regex-conditionals" -Index: src/mod_cgi.c +@@ -165,8 +167,10 @@ + assert(s); + + s->cgi = array_init(); ++ s->execute_x_only = 0; + + cv[0].destination = s->cgi; ++ cv[1].destination = &(s->execute_x_only); + + p->config_storage[i] = s; + +@@ -580,12 +584,9 @@ + #if 0 + log_error_write(srv, __FILE__, __LINE__, "sd", "(debug) cgi exited fine, pid:", pid); + #endif +- pid = 0; +- + return HANDLER_GO_ON; + } else { + log_error_write(srv, __FILE__, __LINE__, "sd", "cgi died, pid:", pid); +- pid = 0; + return HANDLER_GO_ON; + } + } +@@ -1005,7 +1006,7 @@ + args[i++] = cgi_handler->ptr; + } + args[i++] = con->physical.path->ptr; +- args[i++] = NULL; ++ args[i ] = NULL; + + /* search for the last / */ + if (NULL != (c = strrchr(con->physical.path->ptr, '/'))) { +@@ -1018,8 +1019,6 @@ + *c = '/'; + } + +- openDevNull(STDERR_FILENO); +- + /* we don't need the client socket */ + for (i = 3; i < 256; i++) { + if (i != srv->errorlog_fd) close(i); +@@ -1198,6 +1197,8 @@ + + if (buffer_is_equal_string(du->key, CONST_STR_LEN("cgi.assign"))) { + PATCH(cgi); ++ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("cgi.execute-x-only"))) { ++ PATCH(execute_x_only); + } + } + } +@@ -1220,6 +1221,7 @@ + + if (HANDLER_ERROR == stat_cache_get_entry(srv, con, con->physical.path, &sce)) return HANDLER_GO_ON; + if (!S_ISREG(sce->st.st_mode)) return HANDLER_GO_ON; ++ if (p->conf.execute_x_only == 1 && (sce->st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) == 0) return HANDLER_GO_ON; + + s_len = fn->used - 1; + +Index: src/network_write.c +=================================================================== +--- src/network_write.c (.../tags/lighttpd-1.4.23) ++++ src/network_write.c (.../branches/lighttpd-1.4.x) +@@ -46,15 +46,27 @@ + toSend = c->mem->used - 1 - c->offset; + #ifdef __WIN32 + if ((r = send(fd, offset, toSend, 0)) < 0) { +- log_error_write(srv, __FILE__, __LINE__, "ssd", "write failed: ", strerror(errno), fd); ++ /* no error handling for windows... */ ++ log_error_write(srv, __FILE__, __LINE__, "ssd", "send failed: ", strerror(errno), fd); + + return -1; + } + #else + if ((r = write(fd, offset, toSend)) < 0) { +- log_error_write(srv, __FILE__, __LINE__, "ssd", "write failed: ", strerror(errno), fd); ++ switch (errno) { ++ case EAGAIN: ++ case EINTR: ++ r = 0; ++ break; ++ case EPIPE: ++ case ECONNRESET: ++ return -2; ++ default: ++ log_error_write(srv, __FILE__, __LINE__, "ssd", ++ "write failed:", strerror(errno), fd); + +- return -1; ++ return -1; ++ } + } + #endif + +@@ -98,7 +110,7 @@ + return -1; + } + +-#if defined USE_MMAP ++#ifdef USE_MMAP + if (MAP_FAILED == (p = mmap(0, sce->st.st_size, PROT_READ, MAP_SHARED, ifd, 0))) { + log_error_write(srv, __FILE__, __LINE__, "ss", "mmap failed: ", strerror(errno)); + +@@ -109,13 +121,26 @@ + close(ifd); + + if ((r = write(fd, p + offset, toSend)) <= 0) { +- log_error_write(srv, __FILE__, __LINE__, "ss", "write failed: ", strerror(errno)); +- munmap(p, sce->st.st_size); +- return -1; ++ switch (errno) { ++ case EAGAIN: ++ case EINTR: ++ r = 0; ++ break; ++ case EPIPE: ++ case ECONNRESET: ++ munmap(p, sce->st.st_size); ++ return -2; ++ default: ++ log_error_write(srv, __FILE__, __LINE__, "ssd", ++ "write failed:", strerror(errno), fd); ++ munmap(p, sce->st.st_size); ++ ++ return -1; ++ } + } + + munmap(p, sce->st.st_size); +-#else ++#else /* USE_MMAP */ + buffer_prepare_copy(srv->tmp_buf, toSend); + + lseek(ifd, offset, SEEK_SET); +@@ -127,12 +152,33 @@ + } + close(ifd); + +- if (-1 == (r = send(fd, srv->tmp_buf->ptr, toSend, 0))) { +- log_error_write(srv, __FILE__, __LINE__, "ss", "write: ", strerror(errno)); ++#ifdef __WIN32 ++ if ((r = send(fd, srv->tmp_buf->ptr, toSend, 0)) < 0) { ++ /* no error handling for windows... */ ++ log_error_write(srv, __FILE__, __LINE__, "ssd", "send failed: ", strerror(errno), fd); + + return -1; + } +-#endif ++#else /* __WIN32 */ ++ if ((r = write(fd, srv->tmp_buf->ptr, toSend)) < 0) { ++ switch (errno) { ++ case EAGAIN: ++ case EINTR: ++ r = 0; ++ break; ++ case EPIPE: ++ case ECONNRESET: ++ return -2; ++ default: ++ log_error_write(srv, __FILE__, __LINE__, "ssd", ++ "write failed:", strerror(errno), fd); ++ ++ return -1; ++ } ++ } ++#endif /* __WIN32 */ ++#endif /* USE_MMAP */ ++ + c->offset += r; + cq->bytes_out += r; + +Index: src/mod_secure_download.c +=================================================================== +--- src/mod_secure_download.c (.../tags/lighttpd-1.4.23) ++++ src/mod_secure_download.c (.../branches/lighttpd-1.4.x) +@@ -37,7 +37,7 @@ + buffer *secret; + buffer *uri_prefix; + +- unsigned short timeout; ++ unsigned int timeout; + } plugin_config; + + typedef struct { +@@ -99,7 +99,7 @@ + { "secdownload.secret", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 0 */ + { "secdownload.document-root", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 1 */ + { "secdownload.uri-prefix", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 2 */ +- { "secdownload.timeout", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 3 */ ++ { "secdownload.timeout", NULL, T_CONFIG_INT, T_CONFIG_SCOPE_CONNECTION }, /* 3 */ + { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } + }; + +@@ -245,8 +245,8 @@ + } + + /* timed-out */ +- if ( (srv->cur_ts > ts && srv->cur_ts - ts > p->conf.timeout) || +- (srv->cur_ts < ts && ts - srv->cur_ts > p->conf.timeout) ) { ++ if ( (srv->cur_ts > ts && (unsigned int) (srv->cur_ts - ts) > p->conf.timeout) || ++ (srv->cur_ts < ts && (unsigned int) (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; + +Index: src/base.h +=================================================================== +--- src/base.h (.../tags/lighttpd-1.4.23) ++++ src/base.h (.../branches/lighttpd-1.4.x) +@@ -84,6 +84,7 @@ + typedef enum { T_CONFIG_UNSET, + T_CONFIG_STRING, + T_CONFIG_SHORT, ++ T_CONFIG_INT, + T_CONFIG_BOOLEAN, + T_CONFIG_ARRAY, + T_CONFIG_LOCAL, +@@ -281,7 +282,7 @@ + unsigned short etag_use_mtime; + unsigned short etag_use_size; + unsigned short force_lowercase_filenames; /* if the FS is case-insensitive, force all files to lower-case */ +- unsigned short max_request_size; ++ unsigned int max_request_size; + + unsigned short kbytes_per_second; /* connection kb/s limit */ + +@@ -472,6 +473,7 @@ + + buffer *errorlog_file; + unsigned short errorlog_use_syslog; ++ buffer *breakagelog_file; + + unsigned short dont_daemonize; + buffer *changeroot; +@@ -490,7 +492,7 @@ + unsigned short max_worker; + unsigned short max_fds; + unsigned short max_conns; +- unsigned short max_request_size; ++ unsigned int max_request_size; + + unsigned short log_request_header_on_error; + unsigned short log_state_handling; +@@ -538,7 +540,7 @@ + + /* the errorlog */ + int errorlog_fd; +- enum { ERRORLOG_STDERR, ERRORLOG_FILE, ERRORLOG_SYSLOG, ERRORLOG_PIPE } errorlog_mode; ++ enum { ERRORLOG_FILE, ERRORLOG_FD, ERRORLOG_SYSLOG, ERRORLOG_PIPE } errorlog_mode; + buffer *errorlog_buf; + + fdevents *ev, *ev_ins; +Index: src/mod_rewrite.c +=================================================================== +--- src/mod_rewrite.c (.../tags/lighttpd-1.4.23) ++++ src/mod_rewrite.c (.../branches/lighttpd-1.4.x) +@@ -176,7 +176,7 @@ + data_unset *du; + + if (NULL != (du = array_get_element(ca, option))) { +- data_array *da = (data_array *)du; ++ data_array *da; + size_t j; + + if (du->type != TYPE_ARRAY) { +@@ -373,7 +373,7 @@ + } + } else { + const char **list; +- size_t start, end; ++ size_t start; + size_t k; + + /* it matched */ +@@ -383,17 +383,15 @@ + + buffer_reset(con->request.uri); + +- start = 0; end = pattern_len; ++ start = 0; + for (k = 0; k < pattern_len; k++) { + if (pattern[k] == '$' || pattern[k] == '%') { + /* got one */ + + size_t num = pattern[k + 1] - '0'; + +- end = k; ++ buffer_append_string_len(con->request.uri, pattern + start, k - start); + +- buffer_append_string_len(con->request.uri, pattern + start, end - start); +- + if (!isdigit((unsigned char)pattern[k + 1])) { + /* enable escape: "%%" => "%", "%a" => "%a", "$$" => "$" */ + buffer_append_string_len(con->request.uri, pattern+k, pattern[k] == pattern[k+1] ? 1 : 2); +Index: src/connections.c +=================================================================== +--- src/connections.c (.../tags/lighttpd-1.4.23) ++++ src/connections.c (.../branches/lighttpd-1.4.x) +@@ -782,13 +782,13 @@ + CLEAN(request.pathinfo); + CLEAN(request.request); + +- CLEAN(request.orig_uri); ++ /* CLEAN(request.orig_uri); */ + + CLEAN(uri.scheme); +- CLEAN(uri.authority); +- CLEAN(uri.path); ++ /* CLEAN(uri.authority); */ ++ /* CLEAN(uri.path); */ + CLEAN(uri.path_raw); +- CLEAN(uri.query); ++ /* CLEAN(uri.query); */ + + CLEAN(physical.doc_root); + CLEAN(physical.path); +@@ -1401,6 +1401,11 @@ + "state for fd", con->fd, connection_get_state(con->state)); + } + ++ buffer_reset(con->uri.authority); ++ buffer_reset(con->uri.path); ++ buffer_reset(con->uri.query); ++ buffer_reset(con->request.orig_uri); ++ + if (http_request_parse(srv, con)) { + /* we have to read some data from the POST request */ + +@@ -1725,7 +1730,7 @@ + case HANDLER_FINISHED: + break; + default: +- log_error_write(srv, __FILE__, __LINE__, ""); ++ log_error_write(srv, __FILE__, __LINE__, "sd", "unhandling return value", r); + break; + } + break; +Index: src/network.c =================================================================== ---- src/mod_cgi.c (.../tags/lighttpd-1.4.13) (revision 1718) -+++ src/mod_cgi.c (.../branches/lighttpd-1.4.x) (revision 1718) -@@ -842,6 +842,12 @@ - CONST_BUF_LEN(con->authed_user)); +--- src/network.c (.../tags/lighttpd-1.4.23) ++++ src/network.c (.../branches/lighttpd-1.4.x) +@@ -90,6 +90,7 @@ + + srv_socket = calloc(1, sizeof(*srv_socket)); + srv_socket->fd = -1; ++ srv_socket->fde_ndx = -1; + + srv_socket->srv_token = buffer_init(); + buffer_copy_string_buffer(srv_socket->srv_token, host_token); +@@ -103,7 +104,7 @@ + if (NULL == (sp = strrchr(b->ptr, ':'))) { + log_error_write(srv, __FILE__, __LINE__, "sb", "value of $SERVER[\"socket\"] has to be \"ip:port\".", b); + +- return -1; ++ goto error_free_socket; + } + + host = b->ptr; +@@ -126,7 +127,7 @@ + } else if (port == 0 || port > 65535) { + log_error_write(srv, __FILE__, __LINE__, "sd", "port out of range:", port); + +- return -1; ++ goto error_free_socket; + } + + if (*host == '\0') host = NULL; +@@ -138,12 +139,12 @@ + + if (-1 == (srv_socket->fd = socket(srv_socket->addr.plain.sa_family, SOCK_STREAM, 0))) { + log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed:", strerror(errno)); +- return -1; ++ goto error_free_socket; + } + #else + log_error_write(srv, __FILE__, __LINE__, "s", + "ERROR: Unix Domain sockets are not supported."); +- return -1; ++ goto error_free_socket; + #endif + } + +@@ -153,7 +154,7 @@ + + if (-1 == (srv_socket->fd = socket(srv_socket->addr.plain.sa_family, SOCK_STREAM, IPPROTO_TCP))) { + log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed:", strerror(errno)); +- return -1; ++ goto error_free_socket; + } + srv_socket->use_ipv6 = 1; + } +@@ -163,17 +164,22 @@ + srv_socket->addr.plain.sa_family = AF_INET; + if (-1 == (srv_socket->fd = socket(srv_socket->addr.plain.sa_family, SOCK_STREAM, IPPROTO_TCP))) { + log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed:", strerror(errno)); +- return -1; ++ goto error_free_socket; + } + } + ++#ifdef FD_CLOEXEC ++ /* set FD_CLOEXEC now, fdevent_fcntl_set is called later; needed for pipe-logger forks */ ++ fcntl(srv_socket->fd, F_SETFD, FD_CLOEXEC); ++#endif ++ + /* */ + srv->cur_fds = srv_socket->fd; + + val = 1; + if (setsockopt(srv_socket->fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) { + log_error_write(srv, __FILE__, __LINE__, "ss", "socketsockopt failed:", strerror(errno)); +- return -1; ++ goto error_free_socket; + } + + switch(srv_socket->addr.plain.sa_family) { +@@ -198,7 +204,7 @@ + "sssss", "getaddrinfo failed: ", + gai_strerror(r), "'", host, "'"); + +- return -1; ++ goto error_free_socket; + } + + memcpy(&(srv_socket->addr), res->ai_addr, res->ai_addrlen); +@@ -220,17 +226,17 @@ + log_error_write(srv, __FILE__, __LINE__, + "sds", "gethostbyname failed: ", + h_errno, host); +- return -1; ++ goto error_free_socket; + } + + if (he->h_addrtype != AF_INET) { + log_error_write(srv, __FILE__, __LINE__, "sd", "addr-type != AF_INET: ", he->h_addrtype); +- return -1; ++ goto error_free_socket; + } + + if (he->h_length != sizeof(struct in_addr)) { + log_error_write(srv, __FILE__, __LINE__, "sd", "addr-length != sizeof(in_addr): ", he->h_length); +- return -1; ++ goto error_free_socket; + } + + memcpy(&(srv_socket->addr.ipv4.sin_addr.s_addr), he->h_addr_list[0], he->h_length); +@@ -260,7 +266,7 @@ + host); + + +- return -1; ++ goto error_free_socket; + } + + /* connect failed */ +@@ -275,14 +281,12 @@ + "testing socket failed:", + host, strerror(errno)); + +- return -1; ++ goto error_free_socket; + } + + break; + default: +- addr_len = 0; +- +- return -1; ++ goto error_free_socket; + } + + if (0 != bind(srv_socket->fd, (struct sockaddr *) &(srv_socket->addr), addr_len)) { +@@ -298,12 +302,12 @@ + host, port, strerror(errno)); + break; + } +- return -1; ++ goto error_free_socket; + } + + if (-1 == listen(srv_socket->fd, 128 * 8)) { + log_error_write(srv, __FILE__, __LINE__, "ss", "listen failed: ", strerror(errno)); +- return -1; ++ goto error_free_socket; + } + + if (s->is_ssl) { +@@ -316,14 +320,14 @@ + if (0 == RAND_status()) { + log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", + "not enough entropy in the pool"); +- return -1; ++ goto error_free_socket; + } + } + + if (NULL == (s->ssl_ctx = SSL_CTX_new(SSLv23_server_method()))) { + log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", + ERR_error_string(ERR_get_error(), NULL)); +- return -1; ++ goto error_free_socket; + } + + if (!s->ssl_use_sslv2) { +@@ -331,7 +335,7 @@ + if (SSL_OP_NO_SSLv2 != SSL_CTX_set_options(s->ssl_ctx, SSL_OP_NO_SSLv2)) { + log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", + ERR_error_string(ERR_get_error(), NULL)); +- return -1; ++ goto error_free_socket; + } + } + +@@ -340,33 +344,33 @@ + if (SSL_CTX_set_cipher_list(s->ssl_ctx, s->ssl_cipher_list->ptr) != 1) { + log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", + ERR_error_string(ERR_get_error(), NULL)); +- return -1; ++ goto error_free_socket; + } + } + + if (buffer_is_empty(s->ssl_pemfile)) { + log_error_write(srv, __FILE__, __LINE__, "s", "ssl.pemfile has to be set"); +- return -1; ++ goto error_free_socket; + } + + if (!buffer_is_empty(s->ssl_ca_file)) { + if (1 != SSL_CTX_load_verify_locations(s->ssl_ctx, s->ssl_ca_file->ptr, NULL)) { + log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", + ERR_error_string(ERR_get_error(), NULL), s->ssl_ca_file); +- return -1; ++ goto error_free_socket; + } + } + + if (SSL_CTX_use_certificate_file(s->ssl_ctx, s->ssl_pemfile->ptr, SSL_FILETYPE_PEM) < 0) { + log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", + ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile); +- return -1; ++ goto error_free_socket; } -+#ifdef USE_OPENSSL -+ if (srv_sock->is_ssl) { -+ cgi_env_add(&env, CONST_STR_LEN("HTTPS"), CONST_STR_LEN("on")); + if (SSL_CTX_use_PrivateKey_file (s->ssl_ctx, s->ssl_pemfile->ptr, SSL_FILETYPE_PEM) < 0) { + log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", + ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile); +- return -1; ++ goto error_free_socket; + } + + if (SSL_CTX_check_private_key(s->ssl_ctx) != 1) { +@@ -374,7 +378,7 @@ + "Private key does not match the certificate public key, reason:", + ERR_error_string(ERR_get_error(), NULL), + s->ssl_pemfile); +- return -1; ++ goto error_free_socket; + } + SSL_CTX_set_default_read_ahead(s->ssl_ctx, 1); + SSL_CTX_set_mode(s->ssl_ctx, SSL_CTX_get_mode(s->ssl_ctx) | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); +@@ -390,7 +394,7 @@ + log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", + "ssl requested but openssl support is not compiled in"); + +- return -1; ++ goto error_free_socket; + #endif + #ifdef TCP_DEFER_ACCEPT + } else if (s->defer_accept) { +@@ -414,7 +418,6 @@ + } + + srv_socket->is_ssl = s->is_ssl; +- srv_socket->fde_ndx = -1; + + if (srv->srv_sockets.size == 0) { + srv->srv_sockets.size = 4; +@@ -430,6 +433,21 @@ + buffer_free(b); + + return 0; ++ ++error_free_socket: ++ if (srv_socket->fd != -1) { ++ /* check if server fd are already registered */ ++ if (srv_socket->fde_ndx != -1) { ++ fdevent_event_del(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd); ++ fdevent_unregister(srv->ev, srv_socket->fd); ++ } ++ ++ close(srv_socket->fd); + } ++ buffer_free(srv_socket->srv_token); ++ free(srv_socket); ++ ++ return -1; + } + + int network_close(server *srv) { +@@ -567,12 +585,8 @@ + /* not our stage */ + if (COMP_SERVER_SOCKET != dc->comp) continue; + +- if (dc->cond != CONFIG_COND_EQ) { +- log_error_write(srv, __FILE__, __LINE__, "s", "only == is allowed for $SERVER[\"socket\"]."); ++ if (dc->cond != CONFIG_COND_EQ) continue; + +- return -1; +- } +- + /* check if we already know this socket, + * if yes, don't init it */ + for (j = 0; j < srv->srv_sockets.used; j++) { +Index: src/configfile.c +=================================================================== +--- src/configfile.c (.../tags/lighttpd-1.4.23) ++++ src/configfile.c (.../branches/lighttpd-1.4.x) +@@ -42,12 +42,12 @@ + + { "server.event-handler", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 10 */ + { "server.pid-file", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 11 */ +- { "server.max-request-size", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 12 */ ++ { "server.max-request-size", NULL, T_CONFIG_INT, T_CONFIG_SCOPE_CONNECTION }, /* 12 */ + { "server.max-worker", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_SERVER }, /* 13 */ + { "server.document-root", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 14 */ +- { "server.force-lowercase-filenames", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 15 */ ++ { "server.force-lowercase-filenames", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },/* 15 */ + { "debug.log-condition-handling", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 16 */ +- { "server.max-keep-alive-requests", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 17 */ ++ { "server.max-keep-alive-requests", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },/* 17 */ + { "server.name", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 18 */ + { "server.max-keep-alive-idle", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 19 */ + +@@ -91,12 +91,13 @@ + { "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 */ ++ { "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.reject-expect-100-with-417", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 52 */ + { "debug.log-timeouts", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 53 */ +- { "server.defer-accept", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 54 */ ++ { "server.defer-accept", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 54 */ ++ { "server.breakagelog", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 55 */ + { "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 }, +@@ -139,6 +140,8 @@ + cv[43].destination = &(srv->srvconf.max_conns); + cv[12].destination = &(srv->srvconf.max_request_size); + cv[52].destination = &(srv->srvconf.reject_expect_100_with_417); ++ cv[55].destination = srv->srvconf.breakagelog_file; ++ + srv->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); + + assert(srv->config_storage); +@@ -290,6 +293,7 @@ + PATCH(log_condition_handling); + PATCH(log_file_not_found); + PATCH(log_ssl_noise); ++ PATCH(log_timeouts); + + PATCH(range_requests); + PATCH(force_lowercase_filenames); +@@ -1135,15 +1139,15 @@ + * - select works everywhere + * - linux-* are experimental + */ ++#ifdef USE_LINUX_EPOLL ++ { FDEVENT_HANDLER_LINUX_SYSEPOLL, "linux-sysepoll" }, ++#endif + #ifdef USE_POLL + { FDEVENT_HANDLER_POLL, "poll" }, + #endif + #ifdef USE_SELECT + { FDEVENT_HANDLER_SELECT, "select" }, + #endif +-#ifdef USE_LINUX_EPOLL +- { FDEVENT_HANDLER_LINUX_SYSEPOLL, "linux-sysepoll" }, +-#endif + #ifdef USE_LINUX_SIGIO + { FDEVENT_HANDLER_LINUX_RTSIG, "linux-rtsig" }, + #endif +Index: src/mod_evhost.c +=================================================================== +--- src/mod_evhost.c (.../tags/lighttpd-1.4.23) ++++ src/mod_evhost.c (.../branches/lighttpd-1.4.x) +@@ -213,7 +213,7 @@ + if (colon != ptr) { + ds = data_string_init(); + buffer_copy_string_len(ds->key,CONST_STR_LEN("%")); +- buffer_append_long(ds->key, i++); ++ buffer_append_long(ds->key, i /* ++ */); + buffer_copy_string_len(ds->value,ptr,colon-ptr); + + array_insert_unique(host,(data_unset *)ds); +@@ -294,10 +294,10 @@ + char *colon = strchr(con->uri.authority->ptr, ':'); + + if(colon == NULL) { +- buffer_append_string_buffer(p->tmp_buf, con->uri.authority); // adds fqdn ++ buffer_append_string_buffer(p->tmp_buf, con->uri.authority); /* adds fqdn */ + } else { + /* strip the port out of the authority-part of the URI scheme */ +- buffer_append_string_len(p->tmp_buf, con->uri.authority->ptr, colon - con->uri.authority->ptr); // adds fqdn ++ buffer_append_string_len(p->tmp_buf, con->uri.authority->ptr, colon - con->uri.authority->ptr); /* adds fqdn */ + } + } else if (NULL != (ds = (data_string *)array_get_element(parsed_host,p->conf.path_pieces[i]->ptr))) { + if (ds->value->used) { +Index: src/splaytree.c +=================================================================== +--- src/splaytree.c (.../tags/lighttpd-1.4.23) ++++ src/splaytree.c (.../branches/lighttpd-1.4.x) +@@ -61,12 +61,11 @@ + * size fields are maintained */ + splay_tree * splaytree_splay (splay_tree *t, int i) { + splay_tree N, *l, *r, *y; +- int comp, root_size, l_size, r_size; ++ int comp, l_size, r_size; + + if (t == NULL) return t; + N.left = N.right = NULL; + l = r = &N; +- root_size = node_size(t); + l_size = r_size = 0; + + for (;;) { +Index: src/lemon.c +=================================================================== +--- src/lemon.c (.../tags/lighttpd-1.4.23) ++++ src/lemon.c (.../branches/lighttpd-1.4.x) +@@ -39,6 +39,12 @@ + # endif + #endif + ++#if __GNUC__ > 2 ++#define NORETURN __attribute__ ((__noreturn__)) ++#else ++#define NORETURN +#endif + - /* request.content_length < SSIZE_MAX, see request.c */ - ltostr(buf, con->request.content_length); - cgi_env_add(&env, CONST_STR_LEN("CONTENT_LENGTH"), buf, strlen(buf)); -Index: src/base.h + /* #define PRIVATE static */ + #define PRIVATE static + +@@ -51,7 +57,7 @@ + char *msort(); + extern void *malloc(); + +-extern void memory_error(); ++extern void memory_error() NORETURN; + + /******** From the file "action.h" *************************************/ + struct action *Action_new(); +@@ -59,7 +65,7 @@ + void Action_add(); + + /********* From the file "assert.h" ************************************/ +-void myassert(); ++void myassert() NORETURN; + #ifndef NDEBUG + # define assert(X) if(!(X))myassert(__FILE__,__LINE__) + #else +@@ -1333,7 +1339,7 @@ + /* Report an out-of-memory condition and abort. This function + ** is used mostly by the "MemoryCheck" macro in struct.h + */ +-void memory_error(){ ++void memory_error() { + fprintf(stderr,"Out of memory. Aborting...\n"); + exit(1); + } +@@ -1608,7 +1614,6 @@ + FILE *err; + { + int spcnt, i; +- spcnt = 0; + if( argv[0] ) fprintf(err,"%s",argv[0]); + spcnt = strlen(argv[0]) + 1; + for(i=1; ierrorcnt++; + return; + } +@@ -2343,6 +2349,7 @@ + ErrorMsg(ps.filename,0,"Can't read in all %d bytes of this file.", + filesize); + free(filebuf); ++ fclose(fp); + gp->errorcnt++; + return; + } +@@ -2913,7 +2920,7 @@ + }else if( sp->destructor ){ + cp = sp->destructor; + fprintf(out,"#line %d \"%s\"\n{",sp->destructorln,lemp->filename); +- }else if( lemp->vardest ){ ++ }else{ + cp = lemp->vardest; + if( cp==0 ) return; + fprintf(out,"#line %d \"%s\"\n{",lemp->vardestln,lemp->filename); +@@ -3042,7 +3049,7 @@ + int *plineno; /* Pointer to the line number */ + int mhflag; /* True if generating makeheaders output */ + { +- int lineno = *plineno; /* The line number of the output */ ++ int lineno; /* The line number of the output */ + char **types; /* A hash table of datatypes */ + int arraysize; /* Size of the "types" array */ + int maxdtlength; /* Maximum length of any ".datatype" field. */ +Index: src/mod_scgi.c =================================================================== ---- src/base.h (.../tags/lighttpd-1.4.13) (revision 1718) -+++ src/base.h (.../branches/lighttpd-1.4.x) (revision 1718) -@@ -481,7 +481,9 @@ - enum { STAT_CACHE_ENGINE_UNSET, - STAT_CACHE_ENGINE_NONE, - STAT_CACHE_ENGINE_SIMPLE, -+#ifdef HAVE_FAM_H - STAT_CACHE_ENGINE_FAM +--- src/mod_scgi.c (.../tags/lighttpd-1.4.23) ++++ src/mod_scgi.c (.../branches/lighttpd-1.4.x) +@@ -331,8 +331,21 @@ + + int scgi_proclist_sort_down(server *srv, scgi_extension_host *host, scgi_proc *proc); + ++static void reset_signals(void) { ++#ifdef SIGTTOU ++ signal(SIGTTOU, SIG_DFL); +#endif - } stat_cache_engine; - unsigned short enable_cores; - } server_config; -Index: src/connections.c ++#ifdef SIGTTIN ++ signal(SIGTTIN, SIG_DFL); ++#endif ++#ifdef SIGTSTP ++ signal(SIGTSTP, SIG_DFL); ++#endif ++ signal(SIGHUP, SIG_DFL); ++ signal(SIGPIPE, SIG_DFL); ++ signal(SIGUSR1, SIG_DFL); ++} + +- + static handler_ctx * handler_ctx_init() { + handler_ctx * hctx; + +@@ -772,10 +785,8 @@ + 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 */ +@@ -783,8 +794,6 @@ + close(fd); + } + +- openDevNull(STDERR_FILENO); +- + /* build clean environment */ + if (host->bin_env_copy->used) { + for (i = 0; i < host->bin_env_copy->used; i++) { +@@ -828,6 +837,8 @@ + buffer_copy_string_len(b, CONST_STR_LEN("exec ")); + buffer_append_string_buffer(b, host->bin_path); + ++ reset_signals(); ++ + /* exec the cgi */ + execle("/bin/sh", "sh", "-c", b->ptr, (char *)NULL, env.ptr); + +@@ -2163,8 +2174,11 @@ + int ret; + + /* sanity check */ +- if (!host || +- ((!host->host->used || !host->port) && !host->unixsocket->used)) { ++ if (!host) { ++ log_error_write(srv, __FILE__, __LINE__, "s", "fatal error: host = NULL"); ++ return HANDLER_ERROR; ++ } ++ if (((!host->host->used || !host->port) && !host->unixsocket->used)) { + log_error_write(srv, __FILE__, __LINE__, "sxddd", + "write-req: error", + host, +@@ -2299,8 +2313,8 @@ + + chunkqueue_remove_finished_chunks(hctx->wb); + +- if (-1 == ret) { +- if (errno == ENOTCONN) { ++ if (ret < 0) { ++ if (errno == ENOTCONN || ret == -2) { + /* the connection got dropped after accept() + * + * this is most of the time a PHP which dies +@@ -2325,24 +2339,17 @@ + */ + + log_error_write(srv, __FILE__, __LINE__, "ssosd", +- "[REPORT ME] connection was dropped after accept(). reconnect() denied:", ++ "connection was dropped after accept(). reconnect() denied:", + "write-offset:", hctx->wb->bytes_out, + "reconnect attempts:", hctx->reconnects); + + return HANDLER_ERROR; +- } +- +- if ((errno != EAGAIN) && +- (errno != EINTR)) { +- ++ } else { ++ /* -1 == ret => error on our side */ + log_error_write(srv, __FILE__, __LINE__, "ssd", +- "write failed:", strerror(errno), errno); ++ "write failed:", strerror(errno), errno); + + return HANDLER_ERROR; +- } else { +- fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT); +- +- return HANDLER_WAIT_FOR_EVENT; + } + } + +@@ -2469,12 +2476,10 @@ + } + + static handler_t scgi_connection_close(server *srv, handler_ctx *hctx) { +- plugin_data *p; + connection *con; + + if (NULL == hctx) return HANDLER_GO_ON; + +- p = hctx->plugin_data; + con = hctx->remote_conn; + + log_error_write(srv, __FILE__, __LINE__, "ssdsd", +@@ -2724,27 +2729,29 @@ + /* check if extension matches */ + for (k = 0; k < p->conf.exts->used; k++) { + size_t ct_len; ++ scgi_extension *ext = p->conf.exts->exts[k]; + +- extension = p->conf.exts->exts[k]; ++ if (ext->key->used == 0) continue; + +- if (extension->key->used == 0) continue; ++ ct_len = ext->key->used - 1; + +- ct_len = extension->key->used - 1; +- + if (s_len < ct_len) continue; + + /* check extension in the form "/scgi_pattern" */ +- if (*(extension->key->ptr) == '/') { +- if (strncmp(fn->ptr, extension->key->ptr, ct_len) == 0) ++ if (*(ext->key->ptr) == '/') { ++ if (strncmp(fn->ptr, ext->key->ptr, ct_len) == 0) { ++ extension = ext; + break; +- } else if (0 == strncmp(fn->ptr + s_len - ct_len, extension->key->ptr, ct_len)) { ++ } ++ } else if (0 == strncmp(fn->ptr + s_len - ct_len, ext->key->ptr, ct_len)) { + /* check extension in the form ".fcg" */ ++ extension = ext; + break; + } + } + + /* extension doesn't match */ +- if (k == p->conf.exts->used) { ++ if (NULL == extension) { + return HANDLER_GO_ON; + } + +Index: src/mod_mysql_vhost.c +=================================================================== +--- src/mod_mysql_vhost.c (.../tags/lighttpd-1.4.23) ++++ src/mod_mysql_vhost.c (.../branches/lighttpd-1.4.x) +@@ -259,8 +259,14 @@ + + #define FOO(x) (s->x->used ? s->x->ptr : NULL) + ++#if MYSQL_VERSION_ID >= 40100 ++ /* CLIENT_MULTI_STATEMENTS first appeared in 4.1 */ + if (!mysql_real_connect(s->mysql, FOO(hostname), FOO(myuser), FOO(mypass), ++ FOO(mydb), s->port, FOO(mysock), CLIENT_MULTI_STATEMENTS)) { ++#else ++ if (!mysql_real_connect(s->mysql, FOO(hostname), FOO(myuser), FOO(mypass), + FOO(mydb), s->port, FOO(mysock), 0)) { ++#endif + log_error_write(srv, __FILE__, __LINE__, "s", mysql_error(s->mysql)); + + return HANDLER_ERROR; +@@ -369,6 +375,9 @@ + if (!row || cols < 1) { + /* no such virtual host */ + mysql_free_result(result); ++#if MYSQL_VERSION_ID >= 40100 ++ while (mysql_next_result(p->conf.mysql) == 0); ++#endif + return HANDLER_GO_ON; + } + +@@ -402,6 +411,9 @@ + c->fcgi_offset = c->fcgi_arg->used = 0; + } + mysql_free_result(result); ++#if MYSQL_VERSION_ID >= 40100 ++ while (mysql_next_result(p->conf.mysql) == 0); ++#endif + + /* fix virtual server and docroot */ + GO_ON: buffer_copy_string_buffer(con->server_name, c->server_name); +@@ -416,6 +428,9 @@ + return HANDLER_GO_ON; + + ERR500: if (result) mysql_free_result(result); ++#if MYSQL_VERSION_ID >= 40100 ++ while (mysql_next_result(p->conf.mysql) == 0); ++#endif + con->http_status = 500; /* Internal Error */ + con->mode = DIRECT; + return HANDLER_FINISHED; +@@ -424,15 +439,15 @@ + /* this function is called at dlopen() time and inits the callbacks */ + int mod_mysql_vhost_plugin_init(plugin *p); + int mod_mysql_vhost_plugin_init(plugin *p) { +- p->version = LIGHTTPD_VERSION_ID; +- p->name = buffer_init_string("mysql_vhost"); ++ p->version = LIGHTTPD_VERSION_ID; ++ p->name = buffer_init_string("mysql_vhost"); + +- p->init = mod_mysql_vhost_init; +- p->cleanup = mod_mysql_vhost_cleanup; +- p->handle_request_done = mod_mysql_vhost_handle_connection_close; ++ p->init = mod_mysql_vhost_init; ++ p->cleanup = mod_mysql_vhost_cleanup; ++ p->connection_reset = mod_mysql_vhost_handle_connection_close; + +- p->set_defaults = mod_mysql_vhost_set_defaults; +- p->handle_docroot = mod_mysql_vhost_handle_docroot; ++ p->set_defaults = mod_mysql_vhost_set_defaults; ++ p->handle_docroot = mod_mysql_vhost_handle_docroot; + + return 0; + } +@@ -441,7 +456,7 @@ + int mod_mysql_vhost_plugin_init(plugin *p); + int mod_mysql_vhost_plugin_init(plugin *p) { + p->version = LIGHTTPD_VERSION_ID; +- p->name = buffer_init_string("mysql_vhost"); ++ p->name = buffer_init_string("mysql_vhost"); + + return 0; + } +Index: src/request.c +=================================================================== +--- src/request.c (.../tags/lighttpd-1.4.23) ++++ src/request.c (.../branches/lighttpd-1.4.x) +@@ -111,7 +111,7 @@ + + /* check the first character at right of the dot */ + if (is_ip == 0) { +- if (!light_isalpha(host->ptr[i+1])) { ++ if (!light_isalnum(host->ptr[i+1])) { + return -1; + } + } else if (!light_isdigit(host->ptr[i+1])) { +@@ -133,7 +133,7 @@ + } + } else if (i == 0) { + /* the first character of the hostname */ +- if (!light_isalpha(c)) { ++ if (!light_isalnum(c)) { + return -1; + } + label_len++; +@@ -540,8 +540,8 @@ + con->response.keep_alive = 0; + con->keep_alive = 0; + +- log_error_write(srv, __FILE__, __LINE__, "s", "no uri specified -> 400"); + if (srv->srvconf.log_request_header_on_error) { ++ log_error_write(srv, __FILE__, __LINE__, "s", "no uri specified -> 400"); + log_error_write(srv, __FILE__, __LINE__, "Sb", + "request-header:\n", + con->request.request); +Index: src/network_backends.h +=================================================================== +--- src/network_backends.h (.../tags/lighttpd-1.4.23) ++++ src/network_backends.h (.../branches/lighttpd-1.4.x) +@@ -45,6 +45,11 @@ + + #include "base.h" + ++/* return values: ++ * >= 0 : chunks completed ++ * -1 : error (on our side) ++ * -2 : remote close ++ */ + + int network_write_chunkqueue_write(server *srv, connection *con, int fd, chunkqueue *cq); + int network_write_chunkqueue_writev(server *srv, connection *con, int fd, chunkqueue *cq); +Index: src/mod_rrdtool.c +=================================================================== +--- src/mod_rrdtool.c (.../tags/lighttpd-1.4.23) ++++ src/mod_rrdtool.c (.../branches/lighttpd-1.4.x) +@@ -139,10 +139,8 @@ + + args[i++] = p->conf.path_rrdtool_bin->ptr; + args[i++] = dash; +- args[i++] = NULL; ++ args[i ] = NULL; + +- openDevNull(STDERR_FILENO); +- + /* we don't need the client socket */ + for (i = 3; i < 256; i++) { + close(i); +@@ -268,7 +266,7 @@ + "RRA:MIN:0.5:24:775 " + "RRA:MIN:0.5:288:797\n")); + +- if (-1 == (r = safe_write(p->write_fd, p->cmd->ptr, p->cmd->used - 1))) { ++ if (-1 == (safe_write(p->write_fd, p->cmd->ptr, p->cmd->used - 1))) { + log_error_write(srv, __FILE__, __LINE__, "ss", + "rrdtool-write: failed", strerror(errno)); + +Index: src/stat_cache.c +=================================================================== +--- src/stat_cache.c (.../tags/lighttpd-1.4.23) ++++ src/stat_cache.c (.../branches/lighttpd-1.4.x) +@@ -503,12 +503,10 @@ + } + + if (NULL == sce) { +- int osize = 0; ++#ifdef DEBUG_STAT_CACHE ++ int osize = splaytree_size(sc->files); ++#endif + +- if (sc->files) { +- osize = sc->files->size; +- } +- + sce = stat_cache_entry_init(); + buffer_copy_string_buffer(sce->name, name); + +Index: src/response.h +=================================================================== +--- src/response.h (.../tags/lighttpd-1.4.23) ++++ src/response.h (.../branches/lighttpd-1.4.x) +@@ -10,6 +10,7 @@ + + int response_header_insert(server *srv, connection *con, const char *key, size_t keylen, const char *value, size_t vallen); + int response_header_overwrite(server *srv, connection *con, const char *key, size_t keylen, const char *value, size_t vallen); ++int response_header_append(server *srv, connection *con, const char *key, size_t keylen, const char *value, size_t vallen); + + handler_t http_response_prepare(server *srv, connection *con); + int http_response_redirect_to_directory(server *srv, connection *con); +Index: src/mod_proxy.c +=================================================================== +--- src/mod_proxy.c (.../tags/lighttpd-1.4.23) ++++ src/mod_proxy.c (.../branches/lighttpd-1.4.x) +@@ -756,12 +756,15 @@ + + switch(hctx->state) { + case PROXY_STATE_INIT: ++#if defined(HAVE_IPV6) && defined(HAVE_INET_PTON) + if (strstr(host->host->ptr,":")) { + if (-1 == (hctx->fd = socket(AF_INET6, SOCK_STREAM, 0))) { + log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed: ", strerror(errno)); + return HANDLER_ERROR; + } +- } else { ++ } else ++#endif ++ { + if (-1 == (hctx->fd = socket(AF_INET, SOCK_STREAM, 0))) { + log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed: ", strerror(errno)); + return HANDLER_ERROR; +@@ -842,17 +845,14 @@ + + chunkqueue_remove_finished_chunks(hctx->wb); + +- if (-1 == ret) { +- if (errno != EAGAIN && +- errno != EINTR) { +- log_error_write(srv, __FILE__, __LINE__, "ssd", "write failed:", strerror(errno), errno); ++ if (-1 == ret) { /* error on our side */ ++ log_error_write(srv, __FILE__, __LINE__, "ssd", "write failed:", strerror(errno), errno); + +- return HANDLER_ERROR; +- } else { +- fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT); ++ return HANDLER_WAIT_FOR_EVENT; ++ } else if (-2 == ret) { /* remote close */ ++ log_error_write(srv, __FILE__, __LINE__, "ssd", "write failed, remote connection close:", strerror(errno), errno); + +- return HANDLER_WAIT_FOR_EVENT; +- } ++ return HANDLER_WAIT_FOR_EVENT; + } + + if (hctx->wb->bytes_out == hctx->wb->bytes_in) { +@@ -1107,19 +1107,20 @@ + + /* check if extension matches */ + for (k = 0; k < p->conf.extensions->used; k++) { ++ data_array *ext = NULL; + size_t ct_len; + +- extension = (data_array *)p->conf.extensions->data[k]; ++ ext = (data_array *)p->conf.extensions->data[k]; + +- if (extension->key->used == 0) continue; ++ if (ext->key->used == 0) continue; + +- ct_len = extension->key->used - 1; ++ ct_len = ext->key->used - 1; + + if (s_len < ct_len) continue; + + /* check extension in the form "/proxy_pattern" */ +- if (*(extension->key->ptr) == '/') { +- if (strncmp(fn->ptr, extension->key->ptr, ct_len) == 0) { ++ if (*(ext->key->ptr) == '/') { ++ if (strncmp(fn->ptr, ext->key->ptr, ct_len) == 0) { + if (s_len > ct_len + 1) { + char *pi_offset; + +@@ -1127,15 +1128,17 @@ + path_info_offset = pi_offset - fn->ptr; + } + } ++ extension = ext; + break; + } +- } else if (0 == strncmp(fn->ptr + s_len - ct_len, extension->key->ptr, ct_len)) { ++ } else if (0 == strncmp(fn->ptr + s_len - ct_len, ext->key->ptr, ct_len)) { + /* check extension in the form ".fcg" */ ++ extension = ext; + break; + } + } + +- if (k == p->conf.extensions->used) { ++ if (NULL == extension) { + return HANDLER_GO_ON; + } + +Index: src/Makefile.am +=================================================================== +--- src/Makefile.am (.../tags/lighttpd-1.4.23) ++++ src/Makefile.am (.../branches/lighttpd-1.4.x) +@@ -13,14 +13,14 @@ + versionstamp: + @test -f versionstamp.h || touch versionstamp.h; \ + REVISION=""; \ +- if test -x "`which svnversion`"; then \ +- REVISION="$$(LANG=C svnversion "$(top_srcdir)" 2>/dev/null || echo exported)"; \ ++ if test -d "$(top_srcdir)/.svn" -a -x "`which svnversion`"; then \ ++ REVISION="$$(LANG= LC_ALL=C svnversion "$(top_srcdir)" 2>/dev/null || echo exported)"; \ + if test "$$REVISION" = "exported"; then \ + REVISION=""; \ + fi; \ + fi; \ + if test -z "$$REVISION" -a -x "`which git`"; then \ +- REVISION="$$(cd "$(top_srcdir)"; LANG=C git describe --always 2>/dev/null || echo)"; \ ++ REVISION="$$(cd "$(top_srcdir)"; LANG= LC_ALL=C git describe --always 2>/dev/null || echo)"; \ + fi; \ + if test -n "$$REVISION"; then \ + echo "#define REPO_VERSION \"-devel-$$REVISION\"" > versionstamp.h.tmp; \ +Index: src/mod_expire.c +=================================================================== +--- src/mod_expire.c (.../tags/lighttpd-1.4.23) ++++ src/mod_expire.c (.../branches/lighttpd-1.4.x) +@@ -342,7 +342,7 @@ + buffer_copy_string_len(p->expire_tstmp, CONST_STR_LEN("max-age=")); + buffer_append_long(p->expire_tstmp, expires - srv->cur_ts); /* as expires >= srv->cur_ts the difference is >= 0 */ + +- response_header_overwrite(srv, con, CONST_STR_LEN("Cache-Control"), CONST_BUF_LEN(p->expire_tstmp)); ++ response_header_append(srv, con, CONST_STR_LEN("Cache-Control"), CONST_BUF_LEN(p->expire_tstmp)); + + return HANDLER_GO_ON; + } +Index: src/http_auth.c +=================================================================== +--- src/http_auth.c (.../tags/lighttpd-1.4.23) ++++ src/http_auth.c (.../branches/lighttpd-1.4.x) +@@ -918,15 +918,15 @@ + char a1[256]; + char a2[256]; + +- char *username; +- char *realm; +- char *nonce; +- char *uri; +- char *algorithm; +- char *qop; +- char *cnonce; +- char *nc; +- char *respons; ++ char *username = NULL; ++ char *realm = NULL; ++ char *nonce = NULL; ++ char *uri = NULL; ++ char *algorithm = NULL; ++ char *qop = NULL; ++ char *cnonce = NULL; ++ char *nc = NULL; ++ char *respons = NULL; + + char *e, *c; + const char *m = NULL; +@@ -967,15 +967,9 @@ + dkv[6].ptr = &cnonce; + dkv[7].ptr = &nc; + dkv[8].ptr = &respons; +- dkv[9].ptr = NULL; + + UNUSED(req); + +- for (i = 0; dkv[i].key; i++) { +- *(dkv[i].ptr) = NULL; +- } +- +- + if (p->conf.auth_backend != AUTH_BACKEND_HTDIGEST && + p->conf.auth_backend != AUTH_BACKEND_PLAIN) { + log_error_write(srv, __FILE__, __LINE__, "s", +Index: src/mod_redirect.c +=================================================================== +--- src/mod_redirect.c (.../tags/lighttpd-1.4.23) ++++ src/mod_redirect.c (.../branches/lighttpd-1.4.x) +@@ -203,7 +203,7 @@ + } + } else { + const char **list; +- size_t start, end; ++ size_t start; + size_t k; + + /* it matched */ +@@ -213,17 +213,15 @@ + + buffer_reset(p->location); + +- start = 0; end = pattern_len; ++ start = 0; + for (k = 0; k < pattern_len; k++) { + if (pattern[k] == '$' || pattern[k] == '%') { + /* got one */ + + size_t num = pattern[k + 1] - '0'; + +- end = k; ++ buffer_append_string_len(p->location, pattern + start, k - start); + +- buffer_append_string_len(p->location, pattern + start, end - start); +- + if (!isdigit((unsigned char)pattern[k + 1])) { + /* enable escape: "%%" => "%", "%a" => "%a", "$$" => "$" */ + buffer_append_string_len(p->location, pattern+k, pattern[k] == pattern[k+1] ? 1 : 2); +Index: src/mod_webdav.c +=================================================================== +--- src/mod_webdav.c (.../tags/lighttpd-1.4.23) ++++ src/mod_webdav.c (.../branches/lighttpd-1.4.x) +@@ -1096,6 +1096,7 @@ + } + #endif + ++#ifdef USE_LOCKS + static int webdav_lockdiscovery(server *srv, connection *con, + buffer *locktoken, const char *lockscope, const char *locktype, int depth) { + +@@ -1150,6 +1151,8 @@ + + return 0; + } ++#endif ++ + /** + * check if resource is having the right locks to access to resource + * +Index: src/configparser.y +=================================================================== +--- src/configparser.y (.../tags/lighttpd-1.4.23) ++++ src/configparser.y (.../branches/lighttpd-1.4.x) +@@ -72,7 +72,7 @@ + op1->free(op1); + return (data_unset *)ds; + } else { +- fprintf(stderr, "data type mismatch, cannot be merge\n"); ++ fprintf(stderr, "data type mismatch, cannot merge\n"); + return NULL; + } + } +@@ -193,7 +193,6 @@ + du = configparser_merge_data(du, B); + if (NULL == du) { + ctx->ok = 0; +- du->free(du); + } + else { + buffer_copy_string_buffer(du->key, A); +@@ -470,7 +469,7 @@ + case CONFIG_COND_MATCH: { + #ifdef HAVE_PCRE_H + const char *errptr; +- int erroff; ++ int erroff, captures; + + if (NULL == (dc->regex = + pcre_compile(rvalue->ptr, 0, &errptr, &erroff, NULL))) { +@@ -487,6 +486,14 @@ + fprintf(stderr, "studying regex failed: %s -> %s\n", + rvalue->ptr, errptr); + ctx->ok = 0; ++ } else if (0 != (pcre_fullinfo(dc->regex, dc->regex_study, PCRE_INFO_CAPTURECOUNT, &captures))) { ++ fprintf(stderr, "getting capture count for regex failed: %s\n", ++ rvalue->ptr); ++ ctx->ok = 0; ++ } else if (captures > 9) { ++ fprintf(stderr, "Too many captures in regex, use (?:...) instead of (...): %s\n", ++ rvalue->ptr); ++ ctx->ok = 0; + } else { + dc->string = buffer_init_buffer(rvalue); + } +Index: src/mod_status.c +=================================================================== +--- src/mod_status.c (.../tags/lighttpd-1.4.23) ++++ src/mod_status.c (.../branches/lighttpd-1.4.x) +@@ -438,7 +438,7 @@ + + buffer_append_string_len(b, CONST_STR_LEN( + "
\n
legend\n"
+-		". = connect, C = close, E = hard error\n"
++		". = connect, C = close, E = hard error, k = keep-alive\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"));
+@@ -449,8 +449,14 @@
+ 
+ 	for (j = 0; j < srv->conns->used; j++) {
+ 		connection *c = srv->conns->ptr[j];
+-		const char *state = connection_get_short_state(c->state);
++		const char *state;
+ 
++		if (CON_STATE_READ == c->state && c->request.orig_uri->used > 0) {
++			state = "k";
++		} else {
++			state = connection_get_short_state(c->state);
++		}
++
+ 		buffer_append_string_len(b, state, 1);
+ 
+ 		if (((j + 1) % 50) == 0) {
+@@ -497,7 +503,11 @@
+ 
+ 		buffer_append_string_len(b, CONST_STR_LEN(""));
+ 
+-		buffer_append_string(b, connection_get_state(c->state));
++		if (CON_STATE_READ == c->state && c->request.orig_uri->used > 0) {
++			buffer_append_string_len(b, CONST_STR_LEN("keep-alive"));
++		} else {
++			buffer_append_string(b, connection_get_state(c->state));
++		}
+ 
+ 		buffer_append_string_len(b, CONST_STR_LEN(""));
+ 
+@@ -611,10 +621,10 @@
+ }
+ 
+ static handler_t mod_status_handle_server_statistics(server *srv, connection *con, void *p_d) {
+-	plugin_data *p = p_d;
+-	buffer *b = p->module_list;
++	buffer *b;
+ 	size_t i;
+ 	array *st = srv->status;
++	UNUSED(p_d);
+ 
+ 	if (0 == st->used) {
+ 		/* we have nothing to send */
+Index: src/mod_ssi.c
+===================================================================
+--- src/mod_ssi.c	(.../tags/lighttpd-1.4.23)
++++ src/mod_ssi.c	(.../branches/lighttpd-1.4.x)
+@@ -362,7 +362,8 @@
+ 	switch(ssicmd) {
+ 	case SSI_ECHO: {
+ 		/* echo */
+-		int var = 0, enc = 0;
++		int var = 0;
++		/* int enc = 0; */
+ 		const char *var_val = NULL;
+ 		stat_cache_entry *sce = NULL;
+ 
+@@ -381,6 +382,7 @@
+ 			{ NULL, SSI_ECHO_UNSET }
+ 		};
+ 
++/*
+ 		struct {
+ 			const char *var;
+ 			enum { SSI_ENC_UNSET, SSI_ENC_URL, SSI_ENC_NONE, SSI_ENC_ENTITY } type;
+@@ -391,6 +393,7 @@
+ 
+ 			{ NULL, SSI_ENC_UNSET }
+ 		};
++*/
+ 
+ 		for (i = 2; i < n; i += 2) {
+ 			if (0 == strcmp(l[i], "var")) {
+@@ -405,6 +408,7 @@
+ 					}
+ 				}
+ 			} else if (0 == strcmp(l[i], "encoding")) {
++/*
+ 				int j;
+ 
+ 				for (j = 0; encvars[j].var; j++) {
+@@ -413,6 +417,7 @@
+ 						break;
+ 					}
+ 				}
++*/
+ 			} else {
+ 				log_error_write(srv, __FILE__, __LINE__, "sss",
+ 						"ssi: unknow attribute for ",
+Index: src/mod_auth.c
+===================================================================
+--- src/mod_auth.c	(.../tags/lighttpd-1.4.23)
++++ src/mod_auth.c	(.../branches/lighttpd-1.4.x)
+@@ -468,7 +468,7 @@
+ 
+ 			if (method == NULL) {
+ 				log_error_write(srv, __FILE__, __LINE__, "ss",
+-						"the require field is missing in:",
++						"the method field is missing in:",
+ 						"auth.require = ( \"...\" => ( ..., \"method\" => \"...\" ) )");
+ 				return HANDLER_ERROR;
+ 			} else {
+@@ -483,7 +483,7 @@
+ 
+ 			if (realm == NULL) {
+ 				log_error_write(srv, __FILE__, __LINE__, "ss",
+-						"the require field is missing in:",
++						"the realm field is missing in:",
+ 						"auth.require = ( \"...\" => ( ..., \"realm\" => \"...\" ) )");
+ 				return HANDLER_ERROR;
+ 			}
+Index: src/mod_cml_lua.c
+===================================================================
+--- src/mod_cml_lua.c	(.../tags/lighttpd-1.4.23)
++++ src/mod_cml_lua.c	(.../branches/lighttpd-1.4.x)
+@@ -2,6 +2,7 @@
+ #include 
+ #include 
+ #include 
++#include 
+ 
+ #include "mod_cml.h"
+ #include "mod_cml_funcs.h"
+Index: src/http-header-glue.c
+===================================================================
+--- src/http-header-glue.c	(.../tags/lighttpd-1.4.23)
++++ src/http-header-glue.c	(.../branches/lighttpd-1.4.x)
+@@ -104,6 +104,21 @@
+ 	return response_header_insert(srv, con, key, keylen, value, vallen);
+ }
+ 
++int response_header_append(server *srv, connection *con, const char *key, size_t keylen, const char *value, size_t vallen) {
++	data_string *ds;
++
++	UNUSED(srv);
++
++	/* if there already is a key by this name append the value */
++	if (NULL != (ds = (data_string *)array_get_element(con->response.headers, key))) {
++		buffer_append_string_len(ds->value, CONST_STR_LEN(", "));
++		buffer_append_string_len(ds->value, value, vallen);
++		return 0;
++	}
++
++	return response_header_insert(srv, con, key, keylen, value, vallen);
++}
++
+ int http_response_redirect_to_directory(server *srv, connection *con) {
+ 	buffer *o;
+ 
+@@ -259,7 +274,7 @@
+ 					}
+ 
+ 					if (0 == strncmp(con->request.http_if_modified_since, mtime->ptr, used_len)) {
+-						con->http_status = 304;
++						if ('\0' == mtime->ptr[used_len]) con->http_status = 304;
+ 						return HANDLER_FINISHED;
+ 					} else {
+ 						char buf[sizeof("Sat, 23 Jul 2005 21:20:01 GMT")];
+@@ -281,15 +296,16 @@
+ 						strncpy(buf, con->request.http_if_modified_since, used_len);
+ 						buf[used_len] = '\0';
+ 
+-						tm.tm_isdst = 0;
+ 						if (NULL == strptime(buf, "%a, %d %b %Y %H:%M:%S GMT", &tm)) {
+ 							con->http_status = 412;
+ 							con->mode = DIRECT;
+ 							return HANDLER_FINISHED;
+ 						}
++						tm.tm_isdst = 0;
+ 						t_header = mktime(&tm);
+ 
+ 						strptime(mtime->ptr, "%a, %d %b %Y %H:%M:%S GMT", &tm);
++						tm.tm_isdst = 0;
+ 						t_file = mktime(&tm);
+ 
+ 						if (t_file > t_header) return HANDLER_GO_ON;
+@@ -318,7 +334,7 @@
+ 		}
+ 
+ 		if (0 == strncmp(con->request.http_if_modified_since, mtime->ptr, used_len)) {
+-			con->http_status = 304;
++			if ('\0' == mtime->ptr[used_len]) con->http_status = 304;
+ 			return HANDLER_FINISHED;
+ 		} else {
+ 			char buf[sizeof("Sat, 23 Jul 2005 21:20:01 GMT")];
+@@ -331,18 +347,17 @@
+ 			strncpy(buf, con->request.http_if_modified_since, used_len);
+ 			buf[used_len] = '\0';
+ 
+-			tm.tm_isdst = 0;
+ 			if (NULL == strptime(buf, "%a, %d %b %Y %H:%M:%S GMT", &tm)) {
+ 				/**
+ 				 * parsing failed, let's get out of here 
+ 				 */
+-				log_error_write(srv, __FILE__, __LINE__, "ss",
+-						"strptime() failed on", buf);
+ 				return HANDLER_GO_ON;
+ 			}
++			tm.tm_isdst = 0;
+ 			t_header = mktime(&tm);
+ 
+ 			strptime(mtime->ptr, "%a, %d %b %Y %H:%M:%S GMT", &tm);
++			tm.tm_isdst = 0;
+ 			t_file = mktime(&tm);
+ 
+ 			if (t_file > t_header) return HANDLER_GO_ON;
+Index: src/mod_setenv.c
+===================================================================
+--- src/mod_setenv.c	(.../tags/lighttpd-1.4.23)
++++ src/mod_setenv.c	(.../branches/lighttpd-1.4.x)
+@@ -215,7 +215,7 @@
+ 	return HANDLER_GO_ON;
+ }
+ 
+-REQUESTDONE_FUNC(mod_setenv_reset) {
++CONNECTION_FUNC(mod_setenv_reset) {
+ 	plugin_data *p = p_d;
+ 
+ 	UNUSED(srv);
+@@ -240,7 +240,7 @@
+ 	p->set_defaults  = mod_setenv_set_defaults;
+ 	p->cleanup     = mod_setenv_free;
+ 
+-	p->handle_request_done  = mod_setenv_reset;
++	p->connection_reset  = mod_setenv_reset;
+ 
+ 	p->data        = NULL;
+ 
+Index: src/mod_fastcgi.c
+===================================================================
+--- src/mod_fastcgi.c	(.../tags/lighttpd-1.4.23)
++++ src/mod_fastcgi.c	(.../branches/lighttpd-1.4.x)
+@@ -122,24 +122,11 @@
+ 	 *
+ 	 */
+ 
+-	unsigned short min_procs;
+ 	unsigned short max_procs;
+ 	size_t num_procs;    /* how many procs are started */
+ 	size_t active_procs; /* how many of them are really running */
+ 
+-	unsigned short max_load_per_proc;
+-
+ 	/*
+-	 * kick the process from the list if it was not
+-	 * used for idle_timeout until min_procs is
+-	 * reached. this helps to get the processlist
+-	 * small again we had a small peak load.
+-	 *
+-	 */
+-
+-	unsigned short idle_timeout;
+-
+-	/*
+ 	 * time after a disabled remote connection is tried to be re-enabled
+ 	 *
+ 	 *
+@@ -384,6 +371,21 @@
+ /* ok, we need a prototype */
+ static handler_t fcgi_handle_fdevent(void *s, void *ctx, int revents);
+ 
++static void reset_signals(void) {
++#ifdef SIGTTOU
++	signal(SIGTTOU, SIG_DFL);
++#endif
++#ifdef SIGTTIN
++	signal(SIGTTIN, SIG_DFL);
++#endif
++#ifdef SIGTSTP
++	signal(SIGTSTP, SIG_DFL);
++#endif
++	signal(SIGHUP, SIG_DFL);
++	signal(SIGPIPE, SIG_DFL);
++	signal(SIGUSR1, SIG_DFL);
++}
++
+ static void fastcgi_status_copy_procname(buffer *b, fcgi_extension_host *host, fcgi_proc *proc) {
+ 	buffer_copy_string_len(b, CONST_STR_LEN("fastcgi.backend."));
+ 	buffer_append_string_buffer(b, host->id);
+@@ -993,8 +995,6 @@
+ 				close(fcgi_fd);
+ 			}
+ 
+-			openDevNull(STDERR_FILENO);
+-
+ 			/* we don't need the client socket */
+ 			for (i = 3; i < 256; i++) {
+ 				close(i);
+@@ -1054,6 +1054,7 @@
+ 				*c = '/';
+ 			}
+ 
++			reset_signals();
+ 
+ 			/* exec the cgi */
+ 			execve(arg.ptr[0], arg.ptr, env.ptr);
+@@ -1235,20 +1236,17 @@
+ 
+ 						{ "check-local",       NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },      /* 5 */
+ 						{ "port",              NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },        /* 6 */
+-						{ "min-procs-not-working",         NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },        /* 7 this is broken for now */
+-						{ "max-procs",         NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },        /* 8 */
+-						{ "max-load-per-proc", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },        /* 9 */
+-						{ "idle-timeout",      NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },        /* 10 */
+-						{ "disable-time",      NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },        /* 11 */
++						{ "max-procs",         NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },        /* 7 */
++						{ "disable-time",      NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },        /* 8 */
+ 
+-						{ "bin-environment",   NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },        /* 12 */
+-						{ "bin-copy-environment", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },     /* 13 */
++						{ "bin-environment",   NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },        /* 9 */
++						{ "bin-copy-environment", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },     /* 10 */
+ 
+-						{ "broken-scriptfilename", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },  /* 14 */
+-						{ "allow-x-send-file",  NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },      /* 15 */
+-						{ "strip-request-uri",  NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },      /* 16 */
+-						{ "kill-signal",        NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },      /* 17 */
+-						{ "fix-root-scriptname",   NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },  /* 18 */
++						{ "broken-scriptfilename", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },  /* 11 */
++						{ "allow-x-send-file",  NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },     /* 12 */
++						{ "strip-request-uri",  NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },      /* 13 */
++						{ "kill-signal",        NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },       /* 14 */
++						{ "fix-root-scriptname",   NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },  /* 15 */
+ 
+ 						{ NULL,                NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
+ 					};
+@@ -1267,12 +1265,9 @@
+ 					buffer_copy_string_buffer(host->id, da_host->key);
+ 
+ 					host->check_local  = 1;
+-					host->min_procs    = 4;
+ 					host->max_procs    = 4;
+-					host->max_load_per_proc = 1;
+-					host->idle_timeout = 60;
+ 					host->mode = FCGI_RESPONDER;
+-					host->disable_time = 60;
++					host->disable_time = 1;
+ 					host->break_scriptfilename_for_php = 0;
+ 					host->allow_xsendfile = 0; /* handle X-LIGHTTPD-send-file */
+ 					host->kill_signal = SIGTERM;
+@@ -1286,19 +1281,16 @@
+ 
+ 					fcv[5].destination = &(host->check_local);
+ 					fcv[6].destination = &(host->port);
+-					fcv[7].destination = &(host->min_procs);
+-					fcv[8].destination = &(host->max_procs);
+-					fcv[9].destination = &(host->max_load_per_proc);
+-					fcv[10].destination = &(host->idle_timeout);
+-					fcv[11].destination = &(host->disable_time);
++					fcv[7].destination = &(host->max_procs);
++					fcv[8].destination = &(host->disable_time);
+ 
+-					fcv[12].destination = host->bin_env;
+-					fcv[13].destination = host->bin_env_copy;
+-					fcv[14].destination = &(host->break_scriptfilename_for_php);
+-					fcv[15].destination = &(host->allow_xsendfile);
+-					fcv[16].destination = host->strip_request_uri;
+-					fcv[17].destination = &(host->kill_signal);
+-					fcv[18].destination = &(host->fix_root_path_name);
++					fcv[9].destination = host->bin_env;
++					fcv[10].destination = host->bin_env_copy;
++					fcv[11].destination = &(host->break_scriptfilename_for_php);
++					fcv[12].destination = &(host->allow_xsendfile);
++					fcv[13].destination = host->strip_request_uri;
++					fcv[14].destination = &(host->kill_signal);
++					fcv[15].destination = &(host->fix_root_path_name);
+ 
+ 					if (0 != config_insert_values_internal(srv, da_host->value, fcv)) {
+ 						return HANDLER_ERROR;
+@@ -1355,23 +1347,16 @@
+ 						/* a local socket + self spawning */
+ 						size_t pno;
+ 
+-						/* HACK:  just to make sure the adaptive spawing is disabled */
+-						host->min_procs = host->max_procs;
+-
+-						if (host->min_procs > host->max_procs) host->max_procs = host->min_procs;
+-						if (host->max_load_per_proc < 1) host->max_load_per_proc = 0;
+-
+ 						if (s->debug) {
+-							log_error_write(srv, __FILE__, __LINE__, "ssbsdsbsdsd",
++							log_error_write(srv, __FILE__, __LINE__, "ssbsdsbsd",
+ 									"--- fastcgi spawning local",
+ 									"\n\tproc:", host->bin_path,
+ 									"\n\tport:", host->port,
+ 									"\n\tsocket", host->unixsocket,
+-									"\n\tmin-procs:", host->min_procs,
+ 									"\n\tmax-procs:", host->max_procs);
+ 						}
+ 
+-						for (pno = 0; pno < host->min_procs; pno++) {
++						for (pno = 0; pno < host->max_procs; pno++) {
+ 							fcgi_proc *proc;
+ 
+ 							proc = fastcgi_process_init();
+@@ -1391,7 +1376,7 @@
+ 										"--- fastcgi spawning",
+ 										"\n\tport:", host->port,
+ 										"\n\tsocket", host->unixsocket,
+-										"\n\tcurrent:", pno, "/", host->min_procs);
++										"\n\tcurrent:", pno, "/", host->max_procs);
+ 							}
+ 
+ 							if (fcgi_spawn_connection(srv, p, host, proc)) {
+@@ -1426,7 +1411,6 @@
+ 
+ 						host->first = proc;
+ 
+-						host->min_procs = 1;
+ 						host->max_procs = 1;
+ 					}
+ 
+@@ -2739,7 +2723,7 @@
+ 					log_error_write(srv, __FILE__, __LINE__, "ssbsdsd",
+ 							"--- fastcgi spawning",
+ 							"\n\tsocket", proc->connection_name,
+-							"\n\tcurrent:", 1, "/", host->min_procs);
++							"\n\tcurrent:", 1, "/", host->max_procs);
+ 				}
+ 
+ 				if (fcgi_spawn_connection(srv, p, host, proc)) {
+@@ -2778,8 +2762,11 @@
+ 	 *     - tcp socket (do not check host->host->uses, as it may be not set which means INADDR_LOOPBACK)
+ 	 *     - unix socket
+ 	 */
+-	if (!host ||
+-	    (!host->port && !host->unixsocket->used)) {
++	if (!host) {
++		log_error_write(srv, __FILE__, __LINE__, "s", "fatal error: host = NULL");
++		return HANDLER_ERROR;
++	}
++	if ((!host->port && !host->unixsocket->used)) {
+ 		log_error_write(srv, __FILE__, __LINE__, "sxddd",
+ 				"write-req: error",
+ 				host,
+@@ -2787,7 +2774,7 @@
+ 				host->port,
+ 				host->unixsocket->used);
+ 
+-		hctx->proc->disabled_until = srv->cur_ts + 10;
++		hctx->proc->disabled_until = srv->cur_ts + hctx->host->disable_time;
+ 		hctx->proc->state = PROC_STATE_DIED;
+ 
+ 		return HANDLER_ERROR;
+@@ -2803,7 +2790,7 @@
+ 			log_error_write(srv, __FILE__, __LINE__, "ss",
+ 					"getsockopt failed:", strerror(errno));
+ 
+-			hctx->proc->disabled_until = srv->cur_ts + 10;
++			hctx->proc->disabled_until = srv->cur_ts + hctx->host->disable_time;
+ 			hctx->proc->state = PROC_STATE_DIED;
+ 
+ 			return HANDLER_ERROR;
+@@ -2817,7 +2804,7 @@
+ 						"socket:", hctx->proc->connection_name);
+ 			}
+ 
+-			hctx->proc->disabled_until = srv->cur_ts + 5;
++			hctx->proc->disabled_until = srv->cur_ts + hctx->host->disable_time;
+ 
+ 			if (hctx->proc->is_local) {
+ 				hctx->proc->state = PROC_STATE_DIED_WAIT_FOR_PID;
+@@ -2910,13 +2897,13 @@
+ 			/* cool down the backend, it is overloaded
+ 			 * -> EAGAIN */
+ 
+-			log_error_write(srv, __FILE__, __LINE__, "ssdsd",
+-				"backend is overloaded; we'll disable it for 2 seconds and send the request to another backend instead:",
++			log_error_write(srv, __FILE__, __LINE__, "sdssdsd",
++				"backend is overloaded; we'll disable it for", hctx->host->disable_time, "seconds and send the request to another backend instead:",
+ 				"reconnects:", hctx->reconnects,
+ 				"load:", host->load);
+ 
+ 
+-			hctx->proc->disabled_until = srv->cur_ts + 2;
++			hctx->proc->disabled_until = srv->cur_ts + hctx->host->disable_time;
+ 			hctx->proc->state = PROC_STATE_OVERLOADED;
+ 
+ 			fastcgi_status_copy_procname(p->statuskey, hctx->host, hctx->proc);
+@@ -2930,18 +2917,18 @@
+ 			 * - ECONNREFUSED for tcp-ip sockets
+ 			 * - ENOENT for unix-domain-sockets
+ 			 *
+-			 * for check if the host is back in 5 seconds
++			 * for check if the host is back in hctx->host->disable_time seconds
+ 			 *  */
+ 
+-			hctx->proc->disabled_until = srv->cur_ts + 5;
++			hctx->proc->disabled_until = srv->cur_ts + hctx->host->disable_time;
+ 			if (hctx->proc->is_local) {
+ 				hctx->proc->state = PROC_STATE_DIED_WAIT_FOR_PID;
+ 			} else {
+ 				hctx->proc->state = PROC_STATE_DIED;
+ 			}
+ 
+-			log_error_write(srv, __FILE__, __LINE__, "ssdsd",
+-				"backend died; we'll disable it for 5 seconds and send the request to another backend instead:",
++			log_error_write(srv, __FILE__, __LINE__, "sdssdsd",
++				"backend died; we'll disable it for", hctx->host->disable_time, "seconds and send the request to another backend instead:",
+ 				"reconnects:", hctx->reconnects,
+ 				"load:", host->load);
+ 
+@@ -3032,11 +3019,6 @@
+ 						"reconnect attempts:", hctx->reconnects);
+ 
+ 				return HANDLER_ERROR;
+-			case EAGAIN:
+-			case EINTR:
+-				fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
+-
+-				return HANDLER_WAIT_FOR_EVENT;
+ 			default:
+ 				log_error_write(srv, __FILE__, __LINE__, "ssd",
+ 						"write failed:", strerror(errno), errno);
+@@ -3266,7 +3248,7 @@
+ 						log_error_write(srv, __FILE__, __LINE__, "ssbsdsd",
+ 								"--- fastcgi spawning",
+ 								"\n\tsocket", proc->connection_name,
+-								"\n\tcurrent:", 1, "/", host->min_procs);
++								"\n\tcurrent:", 1, "/", host->max_procs);
+ 					}
+ 
+ 					if (fcgi_spawn_connection(srv, p, host, proc)) {
+@@ -3288,18 +3270,18 @@
+ 				    hctx->reconnects < 5) {
+ 					fcgi_reconnect(srv, hctx);
+ 
+-					log_error_write(srv, __FILE__, __LINE__, "ssbsbs",
++					log_error_write(srv, __FILE__, __LINE__, "ssbsBSBs",
+ 						"response not received, request not sent",
+ 						"on socket:", proc->connection_name,
+-						"for", con->uri.path, ", reconnecting");
++						"for", con->uri.path, "?", con->uri.query, ", reconnecting");
+ 
+ 					return HANDLER_WAIT_FOR_FD;
+ 				}
+ 
+-				log_error_write(srv, __FILE__, __LINE__, "sosbsbs",
++				log_error_write(srv, __FILE__, __LINE__, "sosbsBSBs",
+ 						"response not received, request sent:", hctx->wb->bytes_out,
+ 						"on socket:", proc->connection_name,
+-						"for", con->uri.path, ", closing connection");
++						"for", con->uri.path, "?", con->uri.query, ", closing connection");
+ 
+ 				fcgi_connection_close(srv, hctx);
+ 
+@@ -3311,10 +3293,10 @@
+ 				/* response might have been already started, kill the connection */
+ 				fcgi_connection_close(srv, hctx);
+ 
+-				log_error_write(srv, __FILE__, __LINE__, "ssbsbs",
++				log_error_write(srv, __FILE__, __LINE__, "ssbsBSBs",
+ 						"response already sent out, but backend returned error",
+ 						"on socket:", proc->connection_name,
+-						"for", con->uri.path, ", terminating connection");
++						"for", con->uri.path, "?", con->uri.query, ", terminating connection");
+ 
+ 				connection_set_state(srv, con, CON_STATE_ERROR);
+ 			}
+@@ -3364,9 +3346,9 @@
+ 			 * even if the FCGI_FIN packet is not received yet
+ 			 */
+ 		} else {
+-			log_error_write(srv, __FILE__, __LINE__, "sbsbsd",
++			log_error_write(srv, __FILE__, __LINE__, "sBSbsbsd",
+ 					"error: unexpected close of fastcgi connection for",
+-					con->uri.path,
++					con->uri.path, "?", con->uri.query,
+ 					"(no fastcgi process on socket:", proc->connection_name, "?)",
+ 					hctx->state);
+ 
+@@ -3489,25 +3471,27 @@
+ 		/* check if extension matches */
+ 		for (k = 0; k < p->conf.exts->used; k++) {
+ 			size_t ct_len; /* length of the config entry */
++			fcgi_extension *ext = p->conf.exts->exts[k];
+ 
+-			extension = p->conf.exts->exts[k];
++			if (ext->key->used == 0) continue;
+ 
+-			if (extension->key->used == 0) continue;
++			ct_len = ext->key->used - 1;
+ 
+-			ct_len = extension->key->used - 1;
+-
+ 			/* check _url_ in the form "/fcgi_pattern" */
+-			if (extension->key->ptr[0] == '/') {
++			if (ext->key->ptr[0] == '/') {
+ 				if ((ct_len <= con->uri.path->used -1) &&
+-				    (strncmp(con->uri.path->ptr, extension->key->ptr, ct_len) == 0))
++				    (strncmp(con->uri.path->ptr, ext->key->ptr, ct_len) == 0)) {
++					extension = ext;
+ 					break;
+-			} else if ((ct_len <= s_len) && (0 == strncmp(fn->ptr + s_len - ct_len, extension->key->ptr, ct_len))) {
++				}
++			} else if ((ct_len <= s_len) && (0 == strncmp(fn->ptr + s_len - ct_len, ext->key->ptr, ct_len))) {
+ 				/* check extension in the form ".fcg" */
++				extension = ext;
+ 				break;
+ 			}
+ 		}
+ 		/* extension doesn't match */
+-		if (k == p->conf.exts->used) {
++		if (NULL == extension) {
+ 			return HANDLER_GO_ON;
+ 		}
+ 	}
+@@ -3535,8 +3519,8 @@
+ 		if (!extension->note_is_sent) {
+ 			extension->note_is_sent = 1;
+ 
+-			log_error_write(srv, __FILE__, __LINE__, "sbsbs",
+-					"all handlers for ", con->uri.path,
++			log_error_write(srv, __FILE__, __LINE__, "sBSbsbs",
++					"all handlers for", con->uri.path, "?", con->uri.query,
+ 					"on", extension->key,
+ 					"are down.");
+ 		}
+@@ -3727,107 +3711,12 @@
+ 			for (n = 0; n < ex->used; n++) {
+ 
+ 				fcgi_proc *proc;
+-				unsigned long sum_load = 0;
+ 				fcgi_extension_host *host;
+ 
+ 				host = ex->hosts[n];
+ 
+ 				fcgi_restart_dead_procs(srv, p, host);
+ 
+-				for (proc = host->first; proc; proc = proc->next) {
+-					sum_load += proc->load;
+-				}
+-
+-				if (host->num_procs &&
+-				    host->num_procs < host->max_procs &&
+-				    (sum_load / host->num_procs) > host->max_load_per_proc) {
+-					/* overload, spawn new child */
+-					if (p->conf.debug) {
+-						log_error_write(srv, __FILE__, __LINE__, "s",
+-								"overload detected, spawning a new child");
+-					}
+-
+-					for (proc = host->unused_procs; proc && proc->pid != 0; proc = proc->next);
+-
+-					if (proc) {
+-						if (proc == host->unused_procs) host->unused_procs = proc->next;
+-
+-						if (proc->next) proc->next->prev = NULL;
+-
+-						host->max_id++;
+-					} else {
+-						proc = fastcgi_process_init();
+-						proc->id = host->max_id++;
+-					}
+-
+-					host->num_procs++;
+-
+-					if (buffer_is_empty(host->unixsocket)) {
+-						proc->port = host->port + proc->id;
+-					} else {
+-						buffer_copy_string_buffer(proc->unixsocket, host->unixsocket);
+-						buffer_append_string_len(proc->unixsocket, CONST_STR_LEN("-"));
+-						buffer_append_long(proc->unixsocket, proc->id);
+-					}
+-
+-					if (fcgi_spawn_connection(srv, p, host, proc)) {
+-						log_error_write(srv, __FILE__, __LINE__, "s",
+-								"ERROR: spawning fcgi failed.");
+-						return HANDLER_ERROR;
+-					}
+-
+-					proc->prev = NULL;
+-					proc->next = host->first;
+-					if (host->first) {
+-						host->first->prev = proc;
+-					}
+-					host->first = proc;
+-				}
+-
+-				for (proc = host->first; proc; proc = proc->next) {
+-					if (proc->load != 0) break;
+-					if (host->num_procs <= host->min_procs) break;
+-					if (proc->pid == 0) continue;
+-
+-					if (srv->cur_ts - proc->last_used > host->idle_timeout) {
+-						/* a proc is idling for a long time now,
+-						 * terminate it */
+-
+-						if (p->conf.debug) {
+-							log_error_write(srv, __FILE__, __LINE__, "ssbsd",
+-									"idle-timeout reached; terminating child:",
+-									"socket:", proc->connection_name,
+-									"pid", proc->pid);
+-						}
+-
+-
+-						if (proc->next) proc->next->prev = proc->prev;
+-						if (proc->prev) proc->prev->next = proc->next;
+-
+-						if (proc->prev == NULL) host->first = proc->next;
+-
+-						proc->prev = NULL;
+-						proc->next = host->unused_procs;
+-
+-						if (host->unused_procs) host->unused_procs->prev = proc;
+-						host->unused_procs = proc;
+-
+-						kill(proc->pid, SIGTERM);
+-
+-						proc->state = PROC_STATE_KILLED;
+-
+-						log_error_write(srv, __FILE__, __LINE__, "ssbsd",
+-									"killed:",
+-									"socket:", proc->connection_name,
+-									"pid", proc->pid);
+-
+-						host->num_procs--;
+-
+-						/* proc is now in unused, let the next second handle the next process */
+-						break;
+-					}
+-				}
+-
+ 				for (proc = host->unused_procs; proc; proc = proc->next) {
+ 					int status;
+ 
+Index: src/fdevent_poll.c
+===================================================================
+--- src/fdevent_poll.c	(.../tags/lighttpd-1.4.23)
++++ src/fdevent_poll.c	(.../branches/lighttpd-1.4.x)
+@@ -132,7 +132,7 @@
+ 	if (poll_r & POLLNVAL) r |= FDEVENT_NVAL;
+ 	if (poll_r & POLLPRI) r |= FDEVENT_PRI;
+ 
+-	return ev->pollfds[ndx].revents;
++	return r;
+ }
+ 
+ static int fdevent_poll_event_get_fd(fdevents *ev, size_t ndx) {
+Index: src/fdevent_select.c
+===================================================================
+--- src/fdevent_select.c	(.../tags/lighttpd-1.4.23)
++++ src/fdevent_select.c	(.../branches/lighttpd-1.4.x)
+@@ -38,7 +38,7 @@
+ 	UNUSED(fde_ndx);
+ 
+ 	/* we should be protected by max-fds, but you never know */
+-	assert(fd < FD_SETSIZE);
++	assert(fd < ((int)FD_SETSIZE));
+ 
+ 	if (events & FDEVENT_IN) {
+ 		FD_SET(fd, &(ev->select_set_read));
+Index: src/CMakeLists.txt
+===================================================================
+Index: src/server.c
+===================================================================
+--- src/server.c	(.../tags/lighttpd-1.4.23)
++++ src/server.c	(.../branches/lighttpd-1.4.x)
+@@ -187,6 +187,7 @@
+ 	CLEAN(cond_check_buf);
+ 
+ 	CLEAN(srvconf.errorlog_file);
++	CLEAN(srvconf.breakagelog_file);
+ 	CLEAN(srvconf.groupname);
+ 	CLEAN(srvconf.username);
+ 	CLEAN(srvconf.changeroot);
+@@ -242,8 +243,8 @@
+ 	srv->srvconf.reject_expect_100_with_417 = 1;
+ 
+ 	/* use syslog */
+-	srv->errorlog_fd = -1;
+-	srv->errorlog_mode = ERRORLOG_STDERR;
++	srv->errorlog_fd = STDERR_FILENO;
++	srv->errorlog_mode = ERRORLOG_FD;
+ 
+ 	srv->split_vals = array_init();
+ 
+@@ -271,6 +272,7 @@
+ 	CLEAN(cond_check_buf);
+ 
+ 	CLEAN(srvconf.errorlog_file);
++	CLEAN(srvconf.breakagelog_file);
+ 	CLEAN(srvconf.groupname);
+ 	CLEAN(srvconf.username);
+ 	CLEAN(srvconf.changeroot);
+@@ -717,7 +719,7 @@
+ 		}
+ 
+ 		if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
+-			srv->max_fds = rlim.rlim_cur < FD_SETSIZE - 200 ? rlim.rlim_cur : FD_SETSIZE - 200;
++			srv->max_fds = rlim.rlim_cur < ((int)FD_SETSIZE) - 200 ? rlim.rlim_cur : FD_SETSIZE - 200;
+ 		} else {
+ 			srv->max_fds = rlim.rlim_cur;
+ 		}
+@@ -730,7 +732,7 @@
+ #endif
+ 		if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
+ 			/* don't raise the limit above FD_SET_SIZE */
+-			if (srv->max_fds > FD_SETSIZE - 200) {
++			if (srv->max_fds > ((int)FD_SETSIZE) - 200) {
+ 				log_error_write(srv, __FILE__, __LINE__, "sd",
+ 						"can't raise max filedescriptors above",  FD_SETSIZE - 200,
+ 						"if event-handler is 'select'. Use 'poll' or something else or reduce server.max-fds.");
+@@ -780,7 +782,7 @@
+ 		 * Change group before chroot, when we have access
+ 		 * to /etc/group
+ 		 * */
+-		if (srv->srvconf.groupname->used) {
++		if (NULL != grp) {
+ 			setgid(grp->gr_gid);
+ 			setgroups(0, NULL);
+ 			if (srv->srvconf.username->used) {
+@@ -804,7 +806,7 @@
+ #endif
+ #ifdef HAVE_PWD_H
+ 		/* drop root privs */
+-		if (srv->srvconf.username->used) {
++		if (NULL != pwd) {
+ 			setuid(pwd->pw_uid);
+ 		}
+ #endif
+@@ -843,7 +845,7 @@
+ 		}
+ 
+ 		if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
+-			srv->max_fds = rlim.rlim_cur < FD_SETSIZE - 200 ? rlim.rlim_cur : FD_SETSIZE - 200;
++			srv->max_fds = rlim.rlim_cur < ((int)FD_SETSIZE) - 200 ? rlim.rlim_cur : FD_SETSIZE - 200;
+ 		} else {
+ 			srv->max_fds = rlim.rlim_cur;
+ 		}
+@@ -857,7 +859,7 @@
+ #endif
+ 		if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
+ 			/* don't raise the limit above FD_SET_SIZE */
+-			if (srv->max_fds > FD_SETSIZE - 200) {
++			if (srv->max_fds > ((int)FD_SETSIZE) - 200) {
+ 				log_error_write(srv, __FILE__, __LINE__, "sd",
+ 						"can't raise max filedescriptors above",  FD_SETSIZE - 200,
+ 						"if event-handler is 'select'. Use 'poll' or something else or reduce server.max-fds.");
+Index: src/mod_dirlisting.c
+===================================================================
+--- src/mod_dirlisting.c	(.../tags/lighttpd-1.4.23)
++++ src/mod_dirlisting.c	(.../branches/lighttpd-1.4.x)
+@@ -198,7 +198,7 @@
+ 	data_unset *du;
+ 
+ 	if (NULL != (du = array_get_element(ca, option))) {
+-		data_array *da = (data_array *)du;
++		data_array *da;
+ 		size_t j;
+ 
+ 		if (du->type != TYPE_ARRAY) {
+Index: src/mod_magnet.c
+===================================================================
+--- src/mod_magnet.c	(.../tags/lighttpd-1.4.23)
++++ src/mod_magnet.c	(.../branches/lighttpd-1.4.x)
+@@ -283,17 +283,11 @@
+ }
+ 
+ static int magnet_reqhdr_get(lua_State *L) {
+-	server *srv;
+ 	connection *con;
+ 	data_string *ds;
+ 
+ 	const char *key = luaL_checkstring(L, 2);
+ 
+-	lua_pushstring(L, "lighty.srv");
+-	lua_gettable(L, LUA_REGISTRYINDEX);
+-	srv = lua_touserdata(L, -1);
+-	lua_pop(L, 1);
+-
+ 	lua_pushstring(L, "lighty.con");
+ 	lua_gettable(L, LUA_REGISTRYINDEX);
+ 	con = lua_touserdata(L, -1);
+Index: src/log.c
+===================================================================
+--- src/log.c	(.../tags/lighttpd-1.4.23)
++++ src/log.c	(.../branches/lighttpd-1.4.x)
+@@ -62,7 +62,6 @@
+ 		/* create write pipe and spawn process */
+ 
+ 		int to_log_fds[2];
+-		pid_t pid;
+ 
+ 		if (pipe(to_log_fds)) {
+ 			log_error_write(srv, __FILE__, __LINE__, "ss", "pipe failed: ", strerror(errno));
+@@ -70,7 +69,7 @@
+ 		}
+ 
+ 		/* fork, execve */
+-		switch (pid = fork()) {
++		switch (fork()) {
+ 		case 0:
+ 			/* child */
+ 			close(STDIN_FILENO);
+@@ -150,14 +149,14 @@
+  */
+ 
+ int log_error_open(server *srv) {
+-	int close_stderr = 1;
+-
+ #ifdef HAVE_SYSLOG_H
+ 	/* perhaps someone wants to use syslog() */
+ 	openlog("lighttpd", LOG_CONS | LOG_PID, LOG_DAEMON);
+ #endif
+-	srv->errorlog_mode = ERRORLOG_STDERR;
+ 
++	srv->errorlog_mode = ERRORLOG_FD;
++	srv->errorlog_fd = STDERR_FILENO;
++
+ 	if (srv->srvconf.errorlog_use_syslog) {
+ 		srv->errorlog_mode = ERRORLOG_SYSLOG;
+ 	} else if (!buffer_is_empty(srv->srvconf.errorlog_file)) {
+@@ -171,20 +170,36 @@
+ 
+ 	log_error_write(srv, __FILE__, __LINE__, "s", "server started");
+ 
+-#ifdef HAVE_VALGRIND_VALGRIND_H
+-	/* don't close stderr for debugging purposes if run in valgrind */
+-	if (RUNNING_ON_VALGRIND) close_stderr = 0;
+-#endif
+-
+-	if (srv->errorlog_mode == ERRORLOG_STDERR && srv->srvconf.dont_daemonize) {
++	if (srv->errorlog_mode == ERRORLOG_FD && !srv->srvconf.dont_daemonize) {
+ 		/* We can only log to stderr in dont-daemonize mode;
+ 		 * if we do daemonize and no errorlog file is specified, we log into /dev/null
+ 		 */
+-		close_stderr = 0;
++		srv->errorlog_fd = -1;
+ 	}
+ 
+-	/* move stderr to /dev/null */
+-	if (close_stderr) openDevNull(STDERR_FILENO);
++	if (!buffer_is_empty(srv->srvconf.breakagelog_file)) {
++		int breakage_fd;
++		const char *logfile = srv->srvconf.breakagelog_file->ptr;
++
++		if (srv->errorlog_mode == ERRORLOG_FD) {
++			srv->errorlog_fd = dup(STDERR_FILENO);
++#ifdef FD_CLOEXEC
++			fcntl(srv->errorlog_fd, F_SETFD, FD_CLOEXEC);
++#endif
++		}
++
++		if (-1 == (breakage_fd = open_logfile_or_pipe(srv, logfile))) {
++			return -1;
++		}
++
++		if (STDERR_FILENO != breakage_fd) {
++			dup2(breakage_fd, STDERR_FILENO);
++			close(breakage_fd);
++		}
++	} else if (!srv->srvconf.dont_daemonize) {
++		/* move stderr to /dev/null */
++		openDevNull(STDERR_FILENO);
++	}
+ 	return 0;
+ }
+ 
+@@ -235,15 +250,19 @@
+ 	switch(srv->errorlog_mode) {
+ 	case ERRORLOG_PIPE:
+ 	case ERRORLOG_FILE:
+-		close(srv->errorlog_fd);
++	case ERRORLOG_FD:
++		if (-1 != srv->errorlog_fd) {
++			/* don't close STDERR */
++			if (STDERR_FILENO != srv->errorlog_fd)
++				close(srv->errorlog_fd);
++			srv->errorlog_fd = -1;
++		}
+ 		break;
+ 	case ERRORLOG_SYSLOG:
+ #ifdef HAVE_SYSLOG_H
+ 		closelog();
+ #endif
+ 		break;
+-	case ERRORLOG_STDERR:
+-		break;
+ 	}
+ 
+ 	return 0;
+@@ -255,7 +274,8 @@
+ 	switch(srv->errorlog_mode) {
+ 	case ERRORLOG_PIPE:
+ 	case ERRORLOG_FILE:
+-	case ERRORLOG_STDERR:
++	case ERRORLOG_FD:
++		if (-1 == srv->errorlog_fd) return 0;
+ 		/* cache the generated timestamp */
+ 		if (srv->cur_ts != srv->last_generated_debug_ts) {
+ 			buffer_prepare_copy(srv->ts_debug_str, 255);
+@@ -349,13 +369,10 @@
+ 	switch(srv->errorlog_mode) {
+ 	case ERRORLOG_PIPE:
+ 	case ERRORLOG_FILE:
++	case ERRORLOG_FD:
+ 		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_len(srv->errorlog_buf, CONST_STR_LEN("\n"));
+-		write(STDERR_FILENO, srv->errorlog_buf->ptr, srv->errorlog_buf->used - 1);
+-		break;
+ 	case ERRORLOG_SYSLOG:
+ 		syslog(LOG_ERR, "%s", srv->errorlog_buf->ptr);
+ 		break;
+Index: src/proc_open.c
+===================================================================
+--- src/proc_open.c	(.../tags/lighttpd-1.4.23)
++++ src/proc_open.c	(.../branches/lighttpd-1.4.x)
+@@ -309,6 +309,14 @@
+ 
+ 	if (err) {
+ 		proc_read_fd_to_buffer(proc.err.fd, err);
++	} else {
++		buffer *tmp = buffer_init();
++		proc_read_fd_to_buffer(proc.err.fd, tmp);
++		if (tmp->used > 0 &&  write(2, (void*)tmp->ptr, tmp->used) < 0) {
++			perror("error writing pipe");
++			return -1;
++		}
++		buffer_free(tmp);
+ 	}
+ 	pipe_close(&proc.err);
+ 
+Index: tests/.cvsignore
+===================================================================
+Index: tests/bug-12.conf
+===================================================================
+--- tests/bug-12.conf	(.../tags/lighttpd-1.4.23)
++++ tests/bug-12.conf	(.../branches/lighttpd-1.4.x)
+@@ -8,6 +8,7 @@
+ ## bind to localhost (default: all interfaces)
+ server.bind                = "localhost"
+ server.errorlog            = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
++server.breakagelog         = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.breakage.log"
+ server.name                = "www.example.org"
+ server.tag                 = "Apache 1.3.29"
+ 
+Index: tests/fastcgi-10.conf
 ===================================================================
---- src/connections.c	(.../tags/lighttpd-1.4.13)	(revision 1718)
-+++ src/connections.c	(.../branches/lighttpd-1.4.x)	(revision 1718)
-@@ -500,11 +500,10 @@
- 	case 201:
- 	case 301:
- 	case 302:
-+	case 303:
- 		break;
+--- tests/fastcgi-10.conf	(.../tags/lighttpd-1.4.23)
++++ tests/fastcgi-10.conf	(.../branches/lighttpd-1.4.x)
+@@ -6,6 +6,7 @@
+ ## bind to localhost (default: all interfaces)
+ server.bind                = "localhost"
+ server.errorlog            = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
++server.breakagelog         = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.breakage.log"
+ server.name                = "www.example.org"
+ server.tag                 = "Apache 1.3.29"
  
- 	case 206: /* write_queue is already prepared */
--		con->file_finished = 1;
--
- 		break;
- 	case 205: /* class: header only */
- 	case 304:
-@@ -970,7 +969,7 @@
- 								}
- 							} else {
- 								/* a splited \r \n */
--								return -1;
-+								break;
- 							}
- 						}
- 					}
-Index: src/configfile.c
+Index: tests/bug-06.conf
 ===================================================================
---- src/configfile.c	(.../tags/lighttpd-1.4.13)	(revision 1718)
-+++ src/configfile.c	(.../branches/lighttpd-1.4.x)	(revision 1718)
-@@ -218,13 +218,19 @@
- 		srv->srvconf.stat_cache_engine = STAT_CACHE_ENGINE_SIMPLE;
- 	} else if (buffer_is_equal_string(stat_cache_string, CONST_STR_LEN("simple"))) {
- 		srv->srvconf.stat_cache_engine = STAT_CACHE_ENGINE_SIMPLE;
-+#ifdef HAVE_FAM_H
- 	} else if (buffer_is_equal_string(stat_cache_string, CONST_STR_LEN("fam"))) {
- 		srv->srvconf.stat_cache_engine = STAT_CACHE_ENGINE_FAM;
-+#endif
- 	} else if (buffer_is_equal_string(stat_cache_string, CONST_STR_LEN("disable"))) {
- 		srv->srvconf.stat_cache_engine = STAT_CACHE_ENGINE_NONE;
- 	} else {
- 		log_error_write(srv, __FILE__, __LINE__, "sb",
--				"server.stat-cache-engine can be one of \"disable\", \"simple\", \"fam\", but not:", stat_cache_string);
-+				"server.stat-cache-engine can be one of \"disable\", \"simple\","
-+#ifdef HAVE_FAM_H
-+				" \"fam\","
-+#endif
-+				" but not:", stat_cache_string);
- 		ret = HANDLER_ERROR;
- 	}
+--- tests/bug-06.conf	(.../tags/lighttpd-1.4.23)
++++ tests/bug-06.conf	(.../branches/lighttpd-1.4.x)
+@@ -8,6 +8,7 @@
+ ## bind to localhost (default: all interfaces)
+ server.bind                = "localhost"
+ server.errorlog            = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
++server.breakagelog         = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.breakage.log"
+ server.name                = "www.example.org"
+ server.tag                 = "Apache 1.3.29"
  
-Index: src/mod_scgi.c
+Index: tests/mod-extforward.conf
 ===================================================================
---- src/mod_scgi.c	(.../tags/lighttpd-1.4.13)	(revision 1718)
-+++ src/mod_scgi.c	(.../branches/lighttpd-1.4.x)	(revision 1718)
-@@ -2528,7 +2528,7 @@
- 				    hctx->reconnects < 5) {
- 					scgi_reconnect(srv, hctx);
+Index: tests/var-include.conf
+===================================================================
+--- tests/var-include.conf	(.../tags/lighttpd-1.4.23)
++++ tests/var-include.conf	(.../branches/lighttpd-1.4.x)
+@@ -10,6 +10,7 @@
+ ## bind to localhost (default: all interfaces)
+ server.bind                = "localhost"
+ server.errorlog            = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
++server.breakagelog         = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.breakage.log"
+ server.name                = "www.example.org"
+ server.tag                 = "Apache 1.3.29"
  
--					log_error_write(srv, __FILE__, __LINE__, "sdsdsd",
-+					log_error_write(srv, __FILE__, __LINE__, "ssdsd",
- 						"response not sent, request not sent, reconnection.",
- 						"connection-fd:", con->fd,
- 						"fcgi-fd:", hctx->fd);
-Index: src/request.c
+Index: tests/404-handler.conf
 ===================================================================
---- src/request.c	(.../tags/lighttpd-1.4.13)	(revision 1718)
-+++ src/request.c	(.../branches/lighttpd-1.4.x)	(revision 1718)
-@@ -85,6 +85,9 @@
- 	/* Host is empty */
- 	if (host_len == 0) return -1;
+--- tests/404-handler.conf	(.../tags/lighttpd-1.4.23)
++++ tests/404-handler.conf	(.../branches/lighttpd-1.4.x)
+@@ -10,6 +10,7 @@
+ ## bind to localhost (default: all interfaces)
+ server.bind                = "localhost"
+ server.errorlog            = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
++server.breakagelog         = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.breakage.log"
+ server.name                = "www.example.org"
+ server.tag                 = "Apache 1.3.29"
  
-+	/* if the hostname ends in a "." strip it */
-+	if (host->ptr[host_len-1] == '.') host_len -= 1;
-+
- 	/* scan from the right and skip the \0 */
- 	for (i = host_len - 1; i + 1 > 0; i--) {
- 		const char c = host->ptr[i];
-Index: src/network_backends.h
+Index: tests/lowercase.conf
 ===================================================================
---- src/network_backends.h	(.../tags/lighttpd-1.4.13)	(revision 1718)
-+++ src/network_backends.h	(.../branches/lighttpd-1.4.x)	(revision 1718)
-@@ -14,7 +14,7 @@
- # include 
- #endif
+--- tests/lowercase.conf	(.../tags/lighttpd-1.4.23)
++++ tests/lowercase.conf	(.../branches/lighttpd-1.4.x)
+@@ -6,6 +6,7 @@
+ ## bind to localhost (default: all interfaces)
+ server.bind                = "localhost"
+ server.errorlog            = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
++server.breakagelog         = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.breakage.log"
  
--#if defined HAVE_SYS_UIO_H && defined HAVE_SENDFILE && defined HAVE_WRITEV && defined(__FreeBSD__)
-+#if defined HAVE_SYS_UIO_H && defined HAVE_SENDFILE && defined HAVE_WRITEV && (defined(__FreeBSD__) || defined(__DragonFly__))
- # define USE_FREEBSD_SENDFILE
- # include 
- #endif
-Index: src/mod_proxy.c
+ server.force-lowercase-filenames = "enable"
+ 
+Index: tests/condition.conf
 ===================================================================
---- src/mod_proxy.c	(.../tags/lighttpd-1.4.13)	(revision 1718)
-+++ src/mod_proxy.c	(.../branches/lighttpd-1.4.x)	(revision 1718)
-@@ -656,6 +656,7 @@
- 		}
+--- tests/condition.conf	(.../tags/lighttpd-1.4.23)
++++ tests/condition.conf	(.../branches/lighttpd-1.4.x)
+@@ -10,6 +10,7 @@
+ ## bind to localhost (default: all interfaces)
+ server.bind                = "localhost"
+ server.errorlog            = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
++server.breakagelog         = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.breakage.log"
+ server.name                = "www.example.org"
+ server.tag                 = "Apache 1.3.29"
  
- 		if (-1 == (r = read(hctx->fd, hctx->response->ptr + hctx->response->used - 1, b))) {
-+			if (errno == EAGAIN) return 0;
- 			log_error_write(srv, __FILE__, __LINE__, "sds",
- 					"unexpected end-of-file (perhaps the proxy process died):",
- 					proxy_fd, strerror(errno));
-Index: src/mod_extforward.c
-===================================================================
---- src/mod_extforward.c	(.../tags/lighttpd-1.4.13)	(revision 0)
-+++ src/mod_extforward.c	(.../branches/lighttpd-1.4.x)	(revision 1718)
-@@ -0,0 +1,490 @@
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+#include "base.h"
-+#include "log.h"
-+#include "buffer.h"
-+
-+#include "plugin.h"
-+
-+#include "inet_ntop_cache.h"
-+#ifdef HAVE_CONFIG_H
-+#include "config.h"
-+#endif
-+
-+/**
-+ * mod_extforward.c for lighttpd, by comman.kang  gmail  com
-+ *                  extended, modified by Lionel Elie Mamane (LEM), lionel  mamane  lu
-+ *
-+ * Config example:
-+ *
-+ *       Trust proxy 10.0.0.232 and 10.0.0.232
-+ *       extforward.forwarder = ( "10.0.0.232" => "trust",
-+ *                                "10.0.0.233" => "trust" )
-+ *
-+ *       Trust all proxies  (NOT RECOMMENDED!)
-+ *       extforward.forwarder = ( "all" => "trust")
-+ *
-+ *       Note that "all" has precedence over specific entries,
-+ *       so "all except" setups will not work.
-+ *
-+ * Note: The effect of this module is variable on $HTTP["remotip"] directives and
-+ *       other module's remote ip dependent actions.
-+ *  Things done by modules before we change the remoteip or after we reset it will match on the proxy's IP.
-+ *  Things done in between these two moments will match on the real client's IP.
-+ *  The moment things are done by a module depends on in which hook it does things and within the same hook
-+ *  on whether they are before/after us in the module loading order
-+ *  (order in the server.modules directive in the config file).
-+ *
-+ * Tested behaviours:
-+ *
-+ *  mod_access: Will match on the real client.
-+ *
-+ *  mod_accesslog:
-+ *   In order to see the "real" ip address in access log ,
-+ *   you'll have to load mod_extforward after mod_accesslog.
-+ *   like this:
-+ *
-+ *    server.modules  = (
-+ *       .....
-+ *       mod_accesslog,
-+ *       mod_extforward
-+ *    )
-+ *
-+ * Known issues:
-+ *      seems causing segfault with mod_ssl and $HTTP{"socket"} directives
-+ *      LEM 2006.05.26: Fixed segfault $SERVER["socket"] directive. Untested with SSL.
-+ *
-+ * ChangeLog:
-+ *     2005.12.19   Initial Version
-+ *     2005.12.19   fixed conflict with conditional directives
-+ *     2006.05.26   LEM: IPv6 support
-+ *     2006.05.26   LEM: Fix a segfault with $SERVER["socket"] directive.
-+ *     2006.05.26   LEM: Run at uri_raw time, as we don't need to see the URI
-+ *                       In this manner, we run before mod_access and $HTTP["remoteip"] directives work!
-+ *     2006.05.26   LEM: Clean config_cond cache of tests whose result we probably change.
-+ */
-+
-+
-+/* plugin config for all request/connections */
-+
-+typedef struct {
-+	array *forwarder;
-+} plugin_config;
-+
-+typedef struct {
-+	PLUGIN_DATA;
-+
-+	plugin_config **config_storage;
-+
-+	plugin_config conf;
-+} plugin_data;
-+
-+
-+/* context , used for restore remote ip */
-+
-+typedef struct {
-+	sock_addr saved_remote_addr;
-+	buffer *saved_remote_addr_buf;
-+} handler_ctx;
-+
-+
-+static handler_ctx * handler_ctx_init(sock_addr oldaddr, buffer *oldaddr_buf) {
-+	handler_ctx * hctx;
-+	hctx = calloc(1, sizeof(*hctx));
-+	hctx->saved_remote_addr = oldaddr;
-+	hctx->saved_remote_addr_buf = oldaddr_buf;
-+	return hctx;
-+}
-+
-+static void handler_ctx_free(handler_ctx *hctx) {
-+	free(hctx);
-+}
-+
-+/* init the plugin data */
-+INIT_FUNC(mod_extforward_init) {
-+	plugin_data *p;
-+	p = calloc(1, sizeof(*p));
-+	return p;
-+}
-+
-+/* destroy the plugin data */
-+FREE_FUNC(mod_extforward_free) {
-+	plugin_data *p = p_d;
-+
-+	UNUSED(srv);
-+
-+	if (!p) return HANDLER_GO_ON;
-+
-+	if (p->config_storage) {
-+		size_t i;
-+
-+		for (i = 0; i < srv->config_context->used; i++) {
-+			plugin_config *s = p->config_storage[i];
-+
-+			if (!s) continue;
-+
-+			array_free(s->forwarder);
-+
-+			free(s);
-+		}
-+		free(p->config_storage);
-+	}
-+
-+
-+	free(p);
-+
-+	return HANDLER_GO_ON;
-+}
-+
-+/* handle plugin config and check values */
-+
-+SETDEFAULTS_FUNC(mod_extforward_set_defaults) {
-+	plugin_data *p = p_d;
-+	size_t i = 0;
-+
-+	config_values_t cv[] = {
-+		{ "extforward.forwarder",             NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
-+		{ NULL,                         NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
-+	};
-+
-+	if (!p) return HANDLER_ERROR;
-+
-+	p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
-+
-+	for (i = 0; i < srv->config_context->used; i++) {
-+		plugin_config *s;
-+
-+		s = calloc(1, sizeof(plugin_config));
-+		s->forwarder    = array_init();
-+
-+		cv[0].destination = s->forwarder;
-+
-+		p->config_storage[i] = s;
-+
-+		if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
-+			return HANDLER_ERROR;
-+		}
-+	}
-+
-+	return HANDLER_GO_ON;
-+}
-+
-+#define PATCH(x) \
-+	p->conf.x = s->x;
-+static int mod_extforward_patch_connection(server *srv, connection *con, plugin_data *p) {
-+	size_t i, j;
-+	plugin_config *s = p->config_storage[0];
-+
-+	PATCH(forwarder);
-+
-+	/* LEM: The purpose of this seems to match extforward configuration
-+	        stanzas that are not in the global context, but in some sub-context.
-+                I fear this will break contexts of the form HTTP['remote'] = .
-+		(in the form that they do not work with the real remote, but matching on
-+		the proxy instead).
-+
-+		I'm not sure this this is all thread-safe. Is the p we are passed different
-+		for each connection or is it global?
-+
-+		mod_fastcgi does the same, so it must be safe.
-+	 */
-+	/* skip the first, the global context */
-+	for (i = 1; i < srv->config_context->used; i++) {
-+		data_config *dc = (data_config *)srv->config_context->data[i];
-+		s = p->config_storage[i];
-+
-+		/* condition didn't match */
-+		if (!config_check_cond(srv, con, dc)) continue;
-+
-+		/* merge config */
-+		for (j = 0; j < dc->value->used; j++) {
-+			data_unset *du = dc->value->data[j];
-+
-+			if (buffer_is_equal_string(du->key, CONST_STR_LEN("extforward.forwarder"))) {
-+				PATCH(forwarder);
-+			}
-+		}
-+	}
-+
-+	return 0;
-+}
-+#undef PATCH
-+
-+
-+static void put_string_into_array_len(array *ary, const char *str, int len)
-+{
-+	data_string *tempdata;
-+	if (len == 0)
-+		return;
-+	tempdata = data_string_init();
-+	buffer_copy_string_len(tempdata->value,str,len);
-+	array_insert_unique(ary,(data_unset *)tempdata);
-+}
-+/*
-+   extract a forward array from the environment
-+*/
-+static array *extract_forward_array(buffer *pbuffer)
-+{
-+	array *result = array_init();
-+	if (pbuffer->used > 0) {
-+		char *base, *curr;
-+		/* state variable, 0 means not in string, 1 means in string */
-+		int in_str = 0;
-+		for (base = pbuffer->ptr, curr = pbuffer->ptr; *curr; curr++)
-+		{
-+			if (in_str) {
-+				if ( (*curr > '9' || *curr < '0') && *curr != '.' && *curr != ':' ) {
-+					/* found an separator , insert value into result array */
-+					put_string_into_array_len(result, base, curr-base);
-+					/* change state to not in string */
-+					in_str = 0;
-+				}
-+			} else {
-+				if (*curr >= '0' && *curr <= '9')
-+				{
-+					/* found leading char of an IP address, move base pointer and change state */
-+					base = curr;
-+					in_str = 1;
-+				}
-+			}
-+		}
-+		/* if breaking out while in str, we got to the end of string, so add it */
-+		if (in_str)
-+		{
-+			put_string_into_array_len(result, base, curr-base);
-+		}
-+	}
-+	return result;
-+}
-+
-+#define IP_TRUSTED 1
-+#define IP_UNTRUSTED 0
-+/*
-+   check whether ip is trusted, return 1 for trusted , 0 for untrusted
-+*/
-+static int is_proxy_trusted(const char *ipstr, plugin_data *p)
-+{
-+	data_string* allds = (data_string *) array_get_element(p->conf.forwarder,"all");
-+	if (allds) {
-+		if (strcasecmp(allds->value->ptr,"trust") == 0)
-+			return IP_TRUSTED;
-+		else
-+			return IP_UNTRUSTED;
-+	}
-+	return (data_string *)array_get_element(p->conf.forwarder,ipstr) ? IP_TRUSTED : IP_UNTRUSTED ;
-+}
-+
-+struct addrinfo *ipstr_to_sockaddr(const char *host)
-+{
-+   struct addrinfo hints, *res0;
-+   int result;
-+   memset(&hints, 0, sizeof(hints));
-+   hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
-+
-+   result = getaddrinfo(host, NULL, &hints, &res0);
-+   if ( result != 0 )
-+   {
-+      fprintf(stderr,"could not resolve hostname %s because %s\n", host,gai_strerror(result));
-+      if (result == EAI_SYSTEM)
-+         perror("The system error is ");
-+      return NULL;
-+   }
-+   else
-+      if (res0==0)
-+         fprintf(stderr, "Problem in resolving hostname %s: succeeded, but no information returned\n", host);
-+
-+   return res0;
-+}
-+
-+
-+static void clean_cond_cache(server *srv, connection *con)
-+{
-+	size_t i;
-+
-+	for (i = 0; i < srv->config_context->used; i++) {
-+		data_config *dc = (data_config *)srv->config_context->data[i];
-+
-+		if (dc->comp == COMP_HTTP_REMOTEIP)
-+		{
-+			con->cond_cache[i].result = COND_RESULT_UNSET;
-+			con->cond_cache[i].patterncount = 0;
-+		}
-+	}
-+}
-+
-+URIHANDLER_FUNC(mod_extforward_uri_handler) {
-+	plugin_data *p = p_d;
-+	data_string *forwarded = NULL;
-+#ifdef HAVE_IPV6
-+	char b2[INET6_ADDRSTRLEN + 1];
-+#endif
-+	const char *s;
-+	UNUSED(srv);
-+	mod_extforward_patch_connection(srv, con, p);
-+
-+/* 	log_error_write(srv, __FILE__, __LINE__,"s","mod_extforward_uri_handler called\n"); */
-+
-+	/* if the remote ip itself is not trusted , then do nothing */
-+#ifdef HAVE_IPV6
-+	s = inet_ntop(con->dst_addr.plain.sa_family,
-+		      con->dst_addr.plain.sa_family == AF_INET6 ?
-+		       &(con->dst_addr.ipv6.sin6_addr) :
-+		       &(con->dst_addr.ipv4.sin_addr),
-+		      b2,
-+		      (sizeof b2) - 1);
-+#else
-+	s = inet_ntoa(con->dst_addr.ipv4.sin_addr);
-+#endif
-+	if (IP_UNTRUSTED == is_proxy_trusted (s, p) )
-+		return HANDLER_GO_ON;
-+
-+	/* log_error_write(srv, __FILE__, __LINE__,"s","remote address is trusted proxy, go on\n");*/
-+	if (con->request.headers &&
-+	    ((forwarded = (data_string *) array_get_element(con->request.headers,"X-Forwarded-For")) ||
-+	     (forwarded = (data_string *) array_get_element(con->request.headers,  "Forwarded-For"))))
-+	{
-+		/* log_error_write(srv, __FILE__, __LINE__,"s","found forwarded header\n");*/
-+		/* found forwarded for header */
-+		int i;
-+		array *forward_array = extract_forward_array(forwarded->value);
-+		char *real_remote_addr = NULL;
-+#ifdef HAVE_IPV6
-+		struct addrinfo *addrlist = NULL;
-+#endif
-+		/* Testing shows that multiple headers and multiple values in one header
-+		   come in _reverse_ order. So the first one we get is the last one in the request. */
-+		for (i = forward_array->used - 1; i >= 0; i--)
-+		{
-+			data_string *ds = (data_string *) forward_array->data[i];
-+			if (ds) {
-+/* 				log_error_write(srv, __FILE__, __LINE__,"ss","forward",ds->value->ptr); */
-+				real_remote_addr = ds->value->ptr;
-+				break;
-+				/* LEM: What the hell is this about?
-+				        We test whether the forwarded for IP is trusted?
-+					This looks like an ugly hack to handle multiple Forwarded-For's
-+					and avoid those set to our proxies, or something like that.
-+					My testing shows that reverse proxies add a new X-Forwarded-For header,
-+					and we should thus take the last one, which is the first one we see.
-+
-+					The net result of the old code is that we use the first untrusted IP,
-+					or if all are trusted, the last trusted IP.
-+					That's crazy. So I've disabled this.
-+				 */
-+				/* check whether it is trusted */
-+/* 				if (IP_UNTRUSTED == is_proxy_trusted(ds->value->ptr,p) ) */
-+/* 					break; */
-+/* 				log_error_write(srv, __FILE__, __LINE__,"ss",ds->value->ptr," is trusted."); */
-+
-+			}
-+			else {
-+				/* bug ?  bailing out here */
-+				break;
-+			}
-+		}
-+		if (real_remote_addr != NULL) /* parsed */
-+		{
-+			sock_addr s;
-+			struct addrinfo *addrs_left;
-+/* 			log_error_write(srv, __FILE__, __LINE__,"ss","use forward",real_remote_addr); */
-+#ifdef HAVE_IPV6
-+			addrlist = ipstr_to_sockaddr(real_remote_addr);
-+			s.plain.sa_family = AF_UNSPEC;
-+			for (addrs_left = addrlist; addrs_left != NULL;
-+			     addrs_left = addrs_left -> ai_next)
-+			{
-+				s.plain.sa_family = addrs_left->ai_family;
-+				if ( s.plain.sa_family == AF_INET )
-+				{
-+					s.ipv4.sin_addr = ((struct sockaddr_in*)addrs_left->ai_addr)->sin_addr;
-+					break;
-+				}
-+				else if ( s.plain.sa_family == AF_INET6 )
-+				{
-+					s.ipv6.sin6_addr = ((struct sockaddr_in6*)addrs_left->ai_addr)->sin6_addr;
-+					break;
-+				}
-+			}
-+#else
-+			s.ipv4.sin_addr.s_addr = inet_addr(real_remote_addr);
-+			s.plain.sa_family = (s.ipv4.sin_addr.s_addr == 0xFFFFFFFF) ? AF_UNSPEC : AF_INET;
-+#endif
-+			if (s.plain.sa_family != AF_UNSPEC)
-+			{
-+				/* we found the remote address, modify current connection and save the old address */
-+				if (con->plugin_ctx[p->id]) {
-+					log_error_write(srv, __FILE__, __LINE__,"patching an already patched connection!");
-+					handler_ctx_free(con->plugin_ctx[p->id]);
-+					con->plugin_ctx[p->id] = NULL;
-+				}
-+				/* save old address */
-+				con->plugin_ctx[p->id] = handler_ctx_init(con->dst_addr, con->dst_addr_buf);
-+				/* patch connection address */
-+				con->dst_addr = s;
-+				con->dst_addr_buf = buffer_init();
-+				buffer_copy_string(con->dst_addr_buf, real_remote_addr);
-+/* 				log_error_write(srv, __FILE__, __LINE__,"ss","Set dst_addr_buf to ", real_remote_addr); */
-+				/* Now, clean the conf_cond cache, because we may have changed the results of tests */
-+				clean_cond_cache(srv, con);
-+			}
-+#ifdef HAVE_IPV6
-+			if (addrlist != NULL ) freeaddrinfo(addrlist);
-+#endif
-+		}
-+	   	array_free(forward_array);
-+	}
-+
-+	/* not found */
-+	return HANDLER_GO_ON;
-+}
-+
-+CONNECTION_FUNC(mod_extforward_restore) {
-+	plugin_data *p = p_d;
-+	UNUSED(srv);
-+
-+	/* LEM: This seems completely unuseful, as we are not using
-+	        p->conf in this function. Furthermore, it brings a
-+	        segfault if one of the conditional configuration
-+	        blocks is "SERVER['socket'] == foo", because the
-+	        socket is not known yet in the srv/con structure.
-+	 */
-+	/* mod_extforward_patch_connection(srv, con, p); */
-+
-+	/* restore this connection's remote ip */
-+	if (con->plugin_ctx[p->id]) {
-+		handler_ctx *hctx = con->plugin_ctx[p->id];
-+		con->dst_addr = hctx->saved_remote_addr;
-+		buffer_free(con->dst_addr_buf);
-+		con->dst_addr_buf = hctx->saved_remote_addr_buf;
-+/* 		log_error_write(srv, __FILE__, __LINE__,"s","LEM: Reset dst_addr_buf"); */
-+		handler_ctx_free(hctx);
-+		con->plugin_ctx[p->id] = NULL;
-+		/* Now, clean the conf_cond cache, because we may have changed the results of tests */
-+		clean_cond_cache(srv, con);
-+	}
-+	return HANDLER_GO_ON;
-+}
-+
-+
-+/* this function is called at dlopen() time and inits the callbacks */
-+
-+int mod_extforward_plugin_init(plugin *p) {
-+	p->version     = LIGHTTPD_VERSION_ID;
-+	p->name        = buffer_init_string("extforward");
-+
-+	p->init        = mod_extforward_init;
-+	p->handle_uri_raw = mod_extforward_uri_handler;
-+	p->handle_request_done = mod_extforward_restore;
-+	p->connection_reset = mod_extforward_restore;
-+	p->set_defaults  = mod_extforward_set_defaults;
-+	p->cleanup     = mod_extforward_free;
-+
-+	p->data        = NULL;
-+
-+	return 0;
-+}
-+
-
-Property changes on: src/mod_extforward.c
-___________________________________________________________________
-Name: svn:eol-style
-   + native
-
-Index: src/Makefile.am
+Index: tests/fastcgi-13.conf
 ===================================================================
---- src/Makefile.am	(.../tags/lighttpd-1.4.13)	(revision 1718)
-+++ src/Makefile.am	(.../branches/lighttpd-1.4.x)	(revision 1718)
-@@ -199,6 +199,11 @@
- mod_fastcgi_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
- mod_fastcgi_la_LIBADD = $(common_libadd)
+--- tests/fastcgi-13.conf	(.../tags/lighttpd-1.4.23)
++++ tests/fastcgi-13.conf	(.../branches/lighttpd-1.4.x)
+@@ -10,6 +10,7 @@
+ ## bind to localhost (default: all interfaces)
+ server.bind                = "localhost"
+ server.errorlog            = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
++server.breakagelog         = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.breakage.log"
+ server.name                = "www.example.org"
+ server.tag                 = "Apache 1.3.29"
  
-+lib_LTLIBRARIES += mod_extforward.la
-+mod_extforward_la_SOURCES = mod_extforward.c
-+mod_extforward_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
-+mod_extforward_la_LIBADD = $(common_libadd)
-+
- lib_LTLIBRARIES += mod_access.la
- mod_access_la_SOURCES = mod_access.c
- mod_access_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
-Index: src/network_writev.c
-===================================================================
---- src/network_writev.c	(.../tags/lighttpd-1.4.13)	(revision 1718)
-+++ src/network_writev.c	(.../branches/lighttpd-1.4.x)	(revision 1718)
-@@ -55,7 +55,7 @@
- 			const size_t max_chunks = MAX_IOVEC;
- #elif defined(UIO_MAXIOV) /* Linux x86 (glibc-2.2.5-233) */
- 			const size_t max_chunks = UIO_MAXIOV;
--#elif (defined(__FreeBSD__) && __FreeBSD_version < 500000) /* FreeBSD 4.x */
-+#elif (defined(__FreeBSD__) && __FreeBSD_version < 500000) || defined(__DragonFly__) /* FreeBSD 4.x */
- 			const size_t max_chunks = 1024; /* UIO_MAXIOV value from sys/uio.h */
- #else
- #error "sysconf() doesnt return _SC_IOV_MAX ..., check the output of 'man writev' for the EINVAL error and send the output to jan@kneschke.de"
-Index: src/mod_expire.c
+Index: tests/mod-compress.conf
 ===================================================================
---- src/mod_expire.c	(.../tags/lighttpd-1.4.13)	(revision 1718)
-+++ src/mod_expire.c	(.../branches/lighttpd-1.4.x)	(revision 1718)
-@@ -85,7 +85,7 @@
- 	/*
- 	 * parse
- 	 *
--	 * '(access|modification) [plus] { }*'
-+	 * '(access|now|modification) [plus] { }*'
- 	 *
- 	 * e.g. 'access 1 years'
- 	 */
-@@ -101,6 +101,9 @@
- 	if (0 == strncmp(ts, "access ", 7)) {
- 		type  = 0;
- 		ts   += 7;
-+	} else if (0 == strncmp(ts, "now ", 4)) {
-+		type  = 0;
-+		ts   += 4;
- 	} else if (0 == strncmp(ts, "modification ", 13)) {
- 		type  = 1;
- 		ts   += 13;
-@@ -116,7 +119,7 @@
- 		ts   += 5;
- 	}
+--- tests/mod-compress.conf	(.../tags/lighttpd-1.4.23)
++++ tests/mod-compress.conf	(.../branches/lighttpd-1.4.x)
+@@ -11,6 +11,7 @@
+ ## bind to localhost (default: all interfaces)
+ server.bind                = "localhost"
+ server.errorlog            = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
++server.breakagelog         = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.breakage.log"
+ server.name                = "www.example.org"
  
--	/* the rest is just  (years|months|days|hours|minutes|seconds) */
-+	/* the rest is just  (years|months|weeks|days|hours|minutes|seconds) */
- 	while (1) {
- 		char *space, *err;
- 		int num;
-@@ -148,6 +151,9 @@
- 			} else if (slen == 6 &&
- 				   0 == strncmp(ts, "months", slen)) {
- 				num *= 60 * 60 * 24 * 30;
-+			} else if (slen == 5 &&
-+				   0 == strncmp(ts, "weeks", slen)) {
-+				num *= 60 * 60 * 24 * 7;
- 			} else if (slen == 4 &&
- 				   0 == strncmp(ts, "days", slen)) {
- 				num *= 60 * 60 * 24;
-@@ -174,6 +180,8 @@
- 				num *= 60 * 60 * 24 * 30 * 12;
- 			} else if (0 == strcmp(ts, "months")) {
- 				num *= 60 * 60 * 24 * 30;
-+			} else if (0 == strcmp(ts, "weeks")) {
-+				num *= 60 * 60 * 24 * 7;
- 			} else if (0 == strcmp(ts, "days")) {
- 				num *= 60 * 60 * 24;
- 			} else if (0 == strcmp(ts, "hours")) {
-Index: src/network_freebsd_sendfile.c
-===================================================================
---- src/network_freebsd_sendfile.c	(.../tags/lighttpd-1.4.13)	(revision 1718)
-+++ src/network_freebsd_sendfile.c	(.../branches/lighttpd-1.4.x)	(revision 1718)
-@@ -25,7 +25,7 @@
- 
- 
- #ifndef UIO_MAXIOV
--# ifdef __FreeBSD__
-+# if defined(__FreeBSD__) || defined(__DragonFly__)
- /* FreeBSD 4.7, 4.9 defined it in sys/uio.h only if _KERNEL is specified */
- #  define UIO_MAXIOV 1024
- # endif
-Index: src/http_auth.c
+ server.modules = (
+Index: tests/lighttpd.conf
 ===================================================================
---- src/http_auth.c	(.../tags/lighttpd-1.4.13)	(revision 1718)
-+++ src/http_auth.c	(.../branches/lighttpd-1.4.x)	(revision 1718)
-@@ -733,8 +733,9 @@
- 			}
- 		}
+--- tests/lighttpd.conf	(.../tags/lighttpd-1.4.23)
++++ tests/lighttpd.conf	(.../branches/lighttpd-1.4.x)
+@@ -13,6 +13,7 @@
+ ## bind to localhost (default: all interfaces)
+ server.bind                = "localhost"
+ server.errorlog            = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
++server.breakagelog         = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.breakage.log"
+ server.name                = "www.example.org"
+ server.tag                 = "Apache 1.3.29"
  
-+		if (p->conf.auth_ldap_allow_empty_pw != 1 && pw[0] == '\0')
-+			return -1;
+Index: tests/fastcgi-responder.conf
+===================================================================
+--- tests/fastcgi-responder.conf	(.../tags/lighttpd-1.4.23)
++++ tests/fastcgi-responder.conf	(.../branches/lighttpd-1.4.x)
+@@ -15,6 +15,7 @@
+ ## bind to localhost (default: all interfaces)
+ server.bind                = "localhost"
+ server.errorlog            = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
++server.breakagelog         = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.breakage.log"
+ server.name                = "www.example.org"
+ server.tag                 = "Apache 1.3.29"
  
--
- 		/* build filter */
- 		buffer_copy_string_buffer(p->ldap_filter, p->conf.ldap_filter_pre);
- 		buffer_append_string_buffer(p->ldap_filter, username);
-Index: src/http_auth.h
+Index: tests/fastcgi-auth.conf
 ===================================================================
---- src/http_auth.h	(.../tags/lighttpd-1.4.13)	(revision 1718)
-+++ src/http_auth.h	(.../branches/lighttpd-1.4.x)	(revision 1718)
-@@ -36,6 +36,7 @@
- 	buffer *auth_ldap_filter;
- 	buffer *auth_ldap_cafile;
- 	unsigned short auth_ldap_starttls;
-+	unsigned short auth_ldap_allow_empty_pw;
+--- tests/fastcgi-auth.conf	(.../tags/lighttpd-1.4.23)
++++ tests/fastcgi-auth.conf	(.../branches/lighttpd-1.4.x)
+@@ -12,6 +12,7 @@
+ ## bind to localhost (default: all interfaces)
+ server.bind                = "localhost"
+ server.errorlog            = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
++server.breakagelog         = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.breakage.log"
+ server.name                = "www.example.org"
+ server.tag                 = "Apache 1.3.29"
  
- 	unsigned short auth_debug;
+Index: tests/proxy.conf
+===================================================================
+--- tests/proxy.conf	(.../tags/lighttpd-1.4.23)
++++ tests/proxy.conf	(.../branches/lighttpd-1.4.x)
+@@ -6,6 +6,7 @@
+ ## bind to localhost (default: all interfaces)
+ server.bind                = "localhost"
+ server.errorlog            = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
++server.breakagelog         = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.breakage.log"
+ server.name                = "www.example.org"
+ server.tag                 = "Proxy"
  
-Index: src/mod_auth.c
+Index: tests/LightyTest.pm
 ===================================================================
---- src/mod_auth.c	(.../tags/lighttpd-1.4.13)	(revision 1718)
-+++ src/mod_auth.c	(.../branches/lighttpd-1.4.x)	(revision 1718)
-@@ -113,6 +113,7 @@
- 	PATCH(auth_ldap_filter);
- 	PATCH(auth_ldap_cafile);
- 	PATCH(auth_ldap_starttls);
-+	PATCH(auth_ldap_allow_empty_pw);
- #ifdef USE_LDAP
- 	PATCH(ldap);
- 	PATCH(ldap_filter_pre);
-@@ -160,6 +161,8 @@
- 				PATCH(auth_ldap_cafile);
- 			} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.starttls"))) {
- 				PATCH(auth_ldap_starttls);
-+			} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.allow-empty-pw"))) {
-+				PATCH(auth_ldap_allow_empty_pw);
- 			}
+--- tests/LightyTest.pm	(.../tags/lighttpd-1.4.23)
++++ tests/LightyTest.pm	(.../branches/lighttpd-1.4.x)
+@@ -87,14 +87,21 @@
+ 	my $self = shift;
+ 	my $port = shift;
+ 	my $child = shift;
++	my $timeout = 5*10; # 5 secs, select waits 0.1 s
+ 
+ 	while (0 == $self->listening_on($port)) {
+ 		select(undef, undef, undef, 0.1);
++		$timeout--;
+ 
+ 		# the process is gone, we failed
+ 		if (0 != waitpid($child, WNOHANG)) {
+ 			return -1;
  		}
++		if (0 >= $timeout) {
++			diag("Timeout while trying to connect; killing child");
++			kill('TERM', $child);
++			return -1;
++		}
  	}
-@@ -312,6 +315,7 @@
- 		{ "auth.backend.ldap.starttls",     NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },
-  		{ "auth.backend.ldap.bind-dn",      NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
-  		{ "auth.backend.ldap.bind-pw",      NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 10 */
-+		{ "auth.backend.ldap.allow-empty-pw",     NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },
- 		{ "auth.backend.htdigest.userfile", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
- 		{ "auth.backend.htpasswd.userfile", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
- 		{ "auth.debug",                     NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },  /* 13 */
-@@ -359,11 +363,12 @@
- 		cv[6].destination = s->auth_ldap_filter;
- 		cv[7].destination = s->auth_ldap_cafile;
- 		cv[8].destination = &(s->auth_ldap_starttls);
-- 		cv[9].destination = s->auth_ldap_binddn;
-- 		cv[10].destination = s->auth_ldap_bindpw;
--		cv[11].destination = s->auth_htdigest_userfile;
--		cv[12].destination = s->auth_htpasswd_userfile;
--		cv[13].destination = &(s->auth_debug);
-+		cv[9].destination = s->auth_ldap_binddn;
-+		cv[10].destination = s->auth_ldap_bindpw;
-+		cv[11].destination = &(s->auth_ldap_allow_empty_pw);
-+		cv[12].destination = s->auth_htdigest_userfile;
-+		cv[13].destination = s->auth_htpasswd_userfile;
-+		cv[14].destination = &(s->auth_debug);
  
- 		p->config_storage[i] = s;
- 		ca = ((data_config *)srv->config_context->data[i])->value;
-Index: src/http-header-glue.c
+ 	return 0;
+Index: configure.ac
 ===================================================================
---- src/http-header-glue.c	(.../tags/lighttpd-1.4.13)	(revision 1718)
-+++ src/http-header-glue.c	(.../branches/lighttpd-1.4.x)	(revision 1718)
-@@ -148,7 +148,7 @@
- 				char dst[INET6_ADDRSTRLEN];
- 
- 				log_error_write(srv, __FILE__, __LINE__,
--						"SSSS", "NOTICE: getnameinfo failed: ",
-+						"SSS", "NOTICE: getnameinfo failed: ",
- 						strerror(errno), ", using ip-address instead");
- 
- 				buffer_append_string(o,
-@@ -162,7 +162,7 @@
- 		case AF_INET:
- 			if (NULL == (he = gethostbyaddr((char *)&our_addr.ipv4.sin_addr, sizeof(struct in_addr), AF_INET))) {
- 				log_error_write(srv, __FILE__, __LINE__,
--						"SdSS", "NOTICE: gethostbyaddr failed: ",
-+						"SdS", "NOTICE: gethostbyaddr failed: ",
- 						h_errno, ", using ip-address instead");
- 
- 				buffer_append_string(o, inet_ntoa(our_addr.ipv4.sin_addr));
-Index: src/mod_fastcgi.c
+Index: doc/.cvsignore
+===================================================================
+Index: doc/fastcgi.txt
 ===================================================================
---- src/mod_fastcgi.c	(.../tags/lighttpd-1.4.13)	(revision 1718)
-+++ src/mod_fastcgi.c	(.../branches/lighttpd-1.4.x)	(revision 1718)
-@@ -275,6 +275,7 @@
- 	buffer *key; /* like .php */
+--- doc/fastcgi.txt	(.../tags/lighttpd-1.4.23)
++++ doc/fastcgi.txt	(.../branches/lighttpd-1.4.x)
+@@ -95,23 +95,22 @@
+       (
+         ( "host" =>  ,
+           "port" =>  ,
+-	  "socket" => ,       # either socket
+-	                              # or host+port
+-	  "bin-path" => ,     # OPTIONAL
+-	  "bin-environment" => , # OPTIONAL
+-	  "bin-copy-environment" => , # OPTIONAL
++          "socket" => ,       # either socket
++                                      # or host+port
++          "bin-path" => ,     # OPTIONAL
++          "bin-environment" => , # OPTIONAL
++          "bin-copy-environment" => , # OPTIONAL
+           "mode" => ,         # OPTIONAL
+           "docroot" =>  ,     # OPTIONAL if "mode"
+-	                              # is not "authorizer"
++                                      # is not "authorizer"
+           "check-local" => ,  # OPTIONAL
+-	  "min-procs" => ,   # OPTIONAL
+-	  "max-procs" => ,   # OPTIONAL
+-	  "max-load-per-proc" => , # OPTIONAL
+-	  "idle-timeout" => , # OPTIONAL
+-	  "broken-scriptfilename" => , # OPTIONAL
++          "max-procs" => ,   # OPTIONAL
++          "broken-scriptfilename" => , # OPTIONAL
+           "disable-time" => , # optional
+-          "allow-x-send-file" =>  # optional
+-	),
++          "allow-x-send-file" => , # optional
++          "kill-signal" => , # OPTIONAL
++          "fix-root-scriptname" => ,
++                                      # OPTIONAL
+         ( "host" => ...
+         )
+       )
+@@ -127,42 +126,38 @@
+   :"socket":    path to the unix-domain socket
+   :"mode":      is the FastCGI protocol mode.
+                 Default is "responder", also "authorizer"
+-		mode is implemented.
++                mode is implemented.
+   :"docroot":   is optional and is the docroot on the remote
+                 host for default "responder" mode. For
+-		"authorizer" mode it is MANDATORY and it points
+-		to docroot for authorized requests. For security
+-		reasons it is recommended to keep this docroot
++                "authorizer" mode it is MANDATORY and it points
++                to docroot for authorized requests. For security
++                reasons it is recommended to keep this docroot
+                 outside of server.document-root tree.
+   :"check-local": is optional and may be "enable" (default) or
+                 "disable". If enabled the server first check
+-		for a file in local server.document-root tree
+-		and return 404 (Not Found) if no such file.
++                for a file in local server.document-root tree
++                and return 404 (Not Found) if no such file.
+                 If disabled, the server forward request to
+-		FastCGI interface without this check.
++                FastCGI interface without this check.
+   :"broken-scriptfilename": breaks SCRIPT_FILENAME in a wat that
+                 PHP can extract PATH_INFO from it (default: disabled)
+   :"disable-time": time to wait before a disabled backend is checked
+                 again
+   :"allow-x-send-file": controls if X-LIGHTTPD-send-file headers
+                 are allowed
++  :"fix-root-scriptname": fix broken path-info split for "/" extension ("prefix")
  
- 	int note_is_sent;
-+	int last_used_ndx;
+   If bin-path is set:
  
- 	fcgi_extension_host **hosts;
+-  :"min-procs": sets the minium processes to start
+   :"max-procs": the upper limit of the processess to start
+-  :"max-load-per-proc": maximum number of waiting processes on
+-                average per process before a new process is
+-                spawned
+-  :"idle-timeout": number of seconds before a unused process
+-                gets terminated
+   :"bin-environment": put an entry into the environment of
+                 the started process
+   :"bin-copy-environement": clean up the environment and copy
+                 only the specified entries into the fresh
+                 environment of the spawn process
++  :"kill-signal": signal to terminate the FastCGI process with,
++                defauls to SIGTERM
  
-@@ -563,6 +564,7 @@
- 		fe = calloc(1, sizeof(*fe));
- 		assert(fe);
- 		fe->key = buffer_init();
-+		fe->last_used_ndx = -1;
- 		buffer_copy_string_buffer(fe->key, key);
+-
+ Examples
+ --------
  
- 		/* */
-@@ -2365,6 +2367,7 @@
- 	 * check how much we have to read
- 	 */
- 	if (ioctl(hctx->fd, FIONREAD, &toread)) {
-+		if (errno == EAGAIN) return 0;
- 		log_error_write(srv, __FILE__, __LINE__, "sd",
- 				"unexpected end-of-file (perhaps the fastcgi process died):",
- 				fcgi_fd);
-@@ -2375,12 +2378,23 @@
- 
- 	if (toread > 0) {
- 		buffer *b;
-+		chunk *cq_first = hctx->rb->first;
-+		chunk *cq_last = hctx->rb->last;
- 
- 		b = chunkqueue_get_append_buffer(hctx->rb);
- 		buffer_prepare_copy(b, toread + 1);
- 
- 		/* append to read-buffer */
- 		if (-1 == (r = read(hctx->fd, b->ptr, toread))) {
-+			if (errno == EAGAIN) {
-+				/* roll back the last chunk allocation,
-+                                   and continue on next iteration        */
-+				buffer_free(hctx->rb->last->mem);
-+				free(hctx->rb->last);
-+				hctx->rb->first = cq_first;
-+				hctx->rb->last = cq_last;
-+				return 0;
-+			}
- 			log_error_write(srv, __FILE__, __LINE__, "sds",
- 					"unexpected end-of-file (perhaps the fastcgi process died):",
- 					fcgi_fd, strerror(errno));
-@@ -2393,6 +2407,7 @@
- 		b->used = r + 1; /* one extra for the fake \0 */
- 		b->ptr[b->used - 1] = '\0';
- 	} else {
-+		if (errno == EAGAIN) return 0;
- 		log_error_write(srv, __FILE__, __LINE__, "ssdsb",
- 				"unexpected end-of-file (perhaps the fastcgi process died):",
- 				"pid:", proc->pid,
-@@ -2499,6 +2514,8 @@
- 			}
- 			break;
- 		case FCGI_STDERR:
-+			if (packet.len == 0) break;
-+
- 			log_error_write(srv, __FILE__, __LINE__, "sb",
- 					"FastCGI-stderr:", packet.b);
- 
-@@ -2979,17 +2996,23 @@
- 		size_t k;
- 		int ndx, used = -1;
- 
--		/* get best server */
--		for (k = 0, ndx = -1; k < hctx->ext->used; k++) {
--			host = hctx->ext->hosts[k];
-+		/* check if the next server has no load. */
-+		ndx = hctx->ext->last_used_ndx + 1;
-+		if(ndx >= hctx->ext->used || ndx < 0) ndx = 0;
-+		host = hctx->ext->hosts[ndx];
-+		if (host->load > 0) {
-+			/* get backend with the least load. */
-+			for (k = 0, ndx = -1; k < hctx->ext->used; k++) {
-+				host = hctx->ext->hosts[k];
- 
--			/* we should have at least one proc that can do something */
--			if (host->active_procs == 0) continue;
-+				/* we should have at least one proc that can do something */
-+				if (host->active_procs == 0) continue;
- 
--			if (used == -1 || host->load < used) {
--				used = host->load;
-+				if (used == -1 || host->load < used) {
-+					used = host->load;
- 
--				ndx = k;
-+					ndx = k;
-+				}
- 			}
- 		}
+@@ -171,11 +166,11 @@
+     fastcgi.server = ( ".php" =>
+       (( "host" => "127.0.0.1",
+          "port" => 1026,
+-	 "bin-path" => "/usr/local/bin/php"
++         "bin-path" => "/usr/local/bin/php"
+       )),
+       ".php4" =>
+       (( "host" => "127.0.0.1",
+-	 "port" => 1026
++         "port" => 1026
+       ))
+     )
  
-@@ -3005,6 +3028,7 @@
- 			return HANDLER_FINISHED;
- 		}
+@@ -183,10 +178,10 @@
  
-+		hctx->ext->last_used_ndx = ndx;
- 		host = hctx->ext->hosts[ndx];
+     fastcgi.server = ( "/remote_scripts/" =>
+       (( "host" => "192.168.0.3",
+-	 "port" => 9000,
++         "port" => 9000,
+          "check-local" => "disable",
+          "docroot" => "/" # remote server may use
+-	                  # it's own docroot
++                          # it's own docroot
+       ))
+     )
  
- 		/*
-Index: src/server.c
-===================================================================
---- src/server.c	(.../tags/lighttpd-1.4.13)	(revision 1718)
-+++ src/server.c	(.../branches/lighttpd-1.4.x)	(revision 1718)
-@@ -163,6 +163,7 @@
- #undef CLEAN
+@@ -206,7 +201,7 @@
  
- 	for (i = 0; i < FILE_CACHE_MAX; i++) {
-+		srv->mtime_cache[i].mtime = (time_t)-1;
- 		srv->mtime_cache[i].str = buffer_init();
- 	}
+     fastcgi.server = ( "/remote_scripts/" =>
+       (( "host" => "10.0.0.2",
+-	 "port" => 9000,
++         "port" => 9000,
+          "docroot" => "/path_to_private_docs",
+          "mode" => "authorizer"
+       ))
+@@ -318,10 +313,10 @@
+      $ PHP_FCGI_CHILDREN=384 ./lighttpd -f ./lighttpd.conf
  
-@@ -1231,6 +1232,19 @@
- 						srv_socket->fd = -1;
+      fastcgi.server = ( ".php" =>
+-  	(( "socket" => "/tmp/php.socket",
++        (( "socket" => "/tmp/php.socket",
+            "bin-path" => "/usr/local/bin/php",
+            "min-procs" => 1,
+-	   "max-procs" => 1,
++           "max-procs" => 1,
+            "max-load-per-proc" => 4,
+            "idle-timeout" => 20
+         ))
+@@ -408,7 +403,7 @@
+            "PHP_FCGI_CHILDREN" => "16",
+            "PHP_FCGI_MAX_REQUESTS" => "10000" ),
+         "bin-copy-environment" => (
+-	   "PATH", "SHELL", "USER" )
++           "PATH", "SHELL", "USER" )
+      ))
+    )
  
- 						/* network_close() will cleanup after us */
-+
-+						if (srv->srvconf.pid_file->used &&
-+						    srv->srvconf.changeroot->used == 0) {
-+							if (0 != unlink(srv->srvconf.pid_file->ptr)) {
-+								if (errno != EACCES && errno != EPERM) {
-+									log_error_write(srv, __FILE__, __LINE__, "sbds",
-+											"unlink failed for:",
-+											srv->srvconf.pid_file,
-+											errno,
-+											strerror(errno));
-+								}
-+							}
-+						}
- 					}
- 				}
+Index: SConstruct
+===================================================================
+Index: Makefile.am
+===================================================================
+--- Makefile.am	(.../tags/lighttpd-1.4.23)
++++ Makefile.am	(.../branches/lighttpd-1.4.x)
+@@ -2,4 +2,6 @@
  
-@@ -1335,7 +1349,8 @@
- 	}
+ EXTRA_DIST=autogen.sh SConstruct
  
- 	if (srv->srvconf.pid_file->used &&
--	    srv->srvconf.changeroot->used == 0) {
-+	    srv->srvconf.changeroot->used == 0 &&
-+	    0 == graceful_shutdown) {
- 		if (0 != unlink(srv->srvconf.pid_file->ptr)) {
- 			if (errno != EACCES && errno != EPERM) {
- 				log_error_write(srv, __FILE__, __LINE__, "sbds",
-Index: doc/extforward.txt
-===================================================================
---- doc/extforward.txt	(.../tags/lighttpd-1.4.13)	(revision 0)
-+++ doc/extforward.txt	(.../branches/lighttpd-1.4.x)	(revision 1718)
-@@ -0,0 +1,96 @@
-+==============
-+mod_extforward
-+==============
-+
-+.. contents::
-+
-+Overview
-+========
-+
-+Comman Kang  sent me: ::
-+
-+  Hello jan.
-+
-+       I've made something rough but similar to mod_extract_forwarded for
-+  Apache.  This module will extract the client's "real" ip from
-+  X-Forwarded-For header which is added by squid or other proxies. It might be
-+  useful for servers behind reverse proxy servers.
-+
-+       However, this module is causing segfault with mod_ssl or
-+  $HTTP{''socket"} directive,  crashing in config_check_cond while patching
-+  connection ,  I do not understand architecture of the lighttpd well, does it
-+  need to call patch_connection in either handle_request_done and
-+  connection_reset ?
++ACLOCAL_AMFLAGS = -I m4
 +
-+Lionel Elie Mamane  improved the patch: ::
-+
-+    I've taken lighttpd-1.4.10-mod_extforward.c from the wiki and I've
-+  extended it. Here is the result.
-+
-+  Major changes:
-+
-+   - IPv6 support
-+
-+   - Fixed at least one segfault with SERVER['socket']
-+
-+   - Arrange things so that a url.access-deny under scope of a
-+     HTTP['remoteip'] condition works well :)
-+
-+  I've commented the code in some places, mostly where I wasn't sure
-+  what was going on, or I didn't see what the original author meant to
-+  do.
-+
-+Options
-+=======
-+
-+extforward.forwarder
-+  Sets trust level of proxy IP's.
-+
-+  Default: empty
-+
-+  Example: ::
-+    
-+    extforward.forwarder = ("10.0.0.232" => "trust")
-+
-+  will translate ip addresses coming from 10.0.0.232 to real ip addresses extracted from X-Forwarded-For: HTTP request header.
-+
-+Note
-+=======
-+
-+The effect of this module is variable on $HTTP["remotip"] directives and other module's remote ip dependent actions.
-+Things done by modules before we change the remoteip or after we reset it will match on the proxy's IP.
-+Things done in between these two moments will match on the real client's IP.
-+The moment things are done by a module depends on in which hook it does things and within the same hook
-+on whether they are before/after us in the module loading order
-+(order in the server.modules directive in the config file).
-+
-+Tested behaviours:
-+
-+  mod_access: Will match on the real client.
-+
-+  mod_accesslog:
-+   In order to see the "real" ip address in access log ,
-+   you'll have to load mod_extforward after mod_accesslog.
-+   like this: ::
-+
-+    server.modules  = (
-+       .....
-+       mod_accesslog,
-+       mod_extforward
-+    )
-+
-+Samples
-+=======
-+
-+Trust proxy 10.0.0.232 and 10.0.0.232 ::
-+
-+  extforward.forwarder = (
-+     "10.0.0.232" => "trust",
-+     "10.0.0.233" => "trust",
-+  )
-+
-+Trust all proxies  (NOT RECOMMENDED!) ::
-+
-+  extforward.forwarder = ( "all" => "trust")
-+
-+Note that "all" has precedence over specific entries, so "all except" setups will not work.
-Index: doc/Makefile.am
+ distcleancheck_listfiles = find -type f -exec sh -c 'test -f $(srcdir)/{} || echo {}' ';'
+Index: autogen.sh
 ===================================================================
---- doc/Makefile.am	(.../tags/lighttpd-1.4.13)	(revision 1718)
-+++ doc/Makefile.am	(.../branches/lighttpd-1.4.x)	(revision 1718)
-@@ -6,6 +6,7 @@
- cgi.txt \
- compress.txt \
- configuration.txt \
-+extforward.txt \
- fastcgi-state.txt \
- fastcgi.txt \
- features.txt \
-@@ -43,6 +44,7 @@
- 	 cgi.html \
- 	 compress.html \
- 	 configuration.html \
-+	 extforward.html \
- 	 fastcgi-state.html \
- 	 fastcgi.html \
- 	 features.html \
+--- autogen.sh	(.../tags/lighttpd-1.4.23)
++++ autogen.sh	(.../branches/lighttpd-1.4.x)
+@@ -1,27 +1,92 @@
+ #!/bin/sh
+ # Run this to generate all the initial makefiles, etc.
+ 
+-LIBTOOLIZE=${LIBTOOLIZE:-libtoolize}
+ LIBTOOLIZE_FLAGS="--copy --force"
+-ACLOCAL=${ACLOCAL:-aclocal}
+-AUTOHEADER=${AUTOHEADER:-autoheader}
+-AUTOMAKE=${AUTOMAKE:-automake}
+-AUTOMAKE_FLAGS="--add-missing --copy"
+-AUTOCONF=${AUTOCONF:-autoconf}
++AUTOMAKE_FLAGS="--add-missing --copy --foreign"
+ 
+ ARGV0=$0
++ARGS="$@"
+ 
+-set -e
+ 
+-
+ run() {
+-	echo "$ARGV0: running \`$@'"
+-	$@
++	echo "$ARGV0: running \`$@' $ARGS"
++	$@ $ARGS
+ }
+ 
++## jump out if one of the programs returns 'false'
++set -e
++
++## on macosx glibtoolize, others have libtool
++if test x$LIBTOOLIZE = x; then
++  if test \! "x`which glibtoolize 2> /dev/null | grep -v '^no'`" = x; then
++    LIBTOOLIZE=glibtoolize
++  elif test \! "x`which libtoolize-1.5 2> /dev/null | grep -v '^no'`" = x; then
++    LIBTOOLIZE=libtoolize-1.5
++  elif test \! "x`which libtoolize 2> /dev/null | grep -v '^no'`" = x; then
++    LIBTOOLIZE=libtoolize
++  else 
++    echo "libtoolize 1.5.x wasn't found, exiting"; exit 0
++  fi
++fi
++
++## suse has aclocal and aclocal-1.9
++if test x$ACLOCAL = x; then
++  if test \! "x`which aclocal-1.9 2> /dev/null | grep -v '^no'`" = x; then
++    ACLOCAL=aclocal-1.9
++  elif test \! "x`which aclocal19 2> /dev/null | grep -v '^no'`" = x; then
++    ACLOCAL=aclocal19
++  elif test \! "x`which aclocal 2> /dev/null | grep -v '^no'`" = x; then
++    ACLOCAL=aclocal
++  else 
++    echo "automake 1.9.x (aclocal) wasn't found, exiting"; exit 0
++  fi
++fi
++
++if test x$AUTOMAKE = x; then
++  if test \! "x`which automake-1.9 2> /dev/null | grep -v '^no'`" = x; then
++    AUTOMAKE=automake-1.9
++  elif test \! "x`which automake19 2> /dev/null | grep -v '^no'`" = x; then
++    AUTOMAKE=automake19
++  elif test \! "x`which automake 2> /dev/null | grep -v '^no'`" = x; then
++    AUTOMAKE=automake
++  else 
++    echo "automake 1.9.x wasn't found, exiting"; exit 0
++  fi
++fi
++
++
++## macosx has autoconf-2.59 and autoconf-2.60
++if test x$AUTOCONF = x; then
++  if test \! "x`which autoconf-2.59 2> /dev/null | grep -v '^no'`" = x; then
++    AUTOCONF=autoconf-2.59
++  elif test \! "x`which autoconf259 2> /dev/null | grep -v '^no'`" = x; then
++    AUTOCONF=autoconf259
++  elif test \! "x`which autoconf 2> /dev/null | grep -v '^no'`" = x; then
++    AUTOCONF=autoconf
++  else 
++    echo "autoconf 2.59+ wasn't found, exiting"; exit 0
++  fi
++fi
++
++if test x$AUTOHEADER = x; then
++  if test \! "x`which autoheader-2.59 2> /dev/null | grep -v '^no'`" = x; then
++    AUTOHEADER=autoheader-2.59
++  elif test \! "x`which autoheader259 2> /dev/null | grep -v '^no'`" = x; then
++    AUTOHEADER=autoheader259
++  elif test \! "x`which autoheader 2> /dev/null | grep -v '^no'`" = x; then
++    AUTOHEADER=autoheader
++  else 
++    echo "autoconf 2.59+ (autoheader) wasn't found, exiting"; exit 0
++  fi
++fi
++
++mkdir -p m4
+ run $LIBTOOLIZE $LIBTOOLIZE_FLAGS
+-run $ACLOCAL $ACLOCAL_FLAGS
++run $ACLOCAL $ACLOCAL_FLAGS -I m4
+ run $AUTOHEADER
+ run $AUTOMAKE $AUTOMAKE_FLAGS
+ run $AUTOCONF
+-echo "Now type './configure ...' and 'make' to compile."
++
++if test "$ARGS" = "" ; then
++  echo "Now type './configure ...' and 'make' to compile."
++fi
 Index: NEWS
 ===================================================================
---- NEWS	(.../tags/lighttpd-1.4.13)	(revision 1718)
-+++ NEWS	(.../branches/lighttpd-1.4.x)	(revision 1718)
-@@ -3,6 +3,23 @@
+--- NEWS	(.../tags/lighttpd-1.4.23)
++++ NEWS	(.../branches/lighttpd-1.4.x)
+@@ -3,7 +3,42 @@
  NEWS
  ====
  
-+- 1.4.14 - ???
-+  * added mod_extforward module [1665]
-+  * added HTTPS=on to the environment of cgi scripts (#861)
-+  * fix handling of 303 #1045
-+  * made the configure check for lua more portable [1677]  
-+  * fix http 500 errors (colin.stephen/at/o2.com) #1041
-+  * prevent wrong pidfile unlinking on graceful restart (Chris Webb) [1656]
-+  * ignore empty packets from STDERR stream. #998 
-+  * fix a crash for files with an mtime of 0 reported by cubiq on irc [1519]
-+  * allow empty passwords with ldap (Jörg Sonnenberger) [1516]
-+  * mod_scgi.c segfault fix #964
-+  * Added round-robin support to mod_fastcgi [1500]
-+  * Handle DragonFlyBSD the same way as Freebsd (Jörg Sonnenberger) [1492]
-+  * added now and weeks support to mod_expire. #943
-+  * fix cpu hog in certain requests [1473]
-+  * fix for handling hostnames with trailing dot [1406]
-+
- - 1.4.13 - 2006-10-09
- 
-   * added initgroups in spawn-fcgi (#871)
-@@ -56,7 +73,7 @@
- - 1.4.11 - 2006-03-09
- 
-   * added ability to specify which ip address spawn-fci listens on
--    (agkr@pobox.com)
-+    (agkr/at/pobox.com)
-   * added mod_flv_streaming to streaming Flash Movies efficiently
-   * fixed handling of error codes returned by mod_dav_svn behing a
-     mod_proxy
-@@ -68,7 +85,7 @@
-   * fixed local source retrieval on windows
-     (secunia)
-   * fixed hanging cgi if remote side is dieing while reading
--    from the pipe (sandy@meebo.com)
-+    from the pipe (sandy/at/meebo.com)
- 
- - 1.4.10 - 2006-02-08
- 
-@@ -84,23 +101,23 @@
- 
- - 1.4.9 - 2006-01-14
- 
--  * added server.core-files option (sandy )
-+  * added server.core-files option (sandy )
-   * added docs for mod_status
--  * added mod_evasive to limit the number of connections by IP ()
-+  * added mod_evasive to limit the number of connections by IP ()
-   * added the power-magnet to mod_cml
-   * added internal statistics to mod_fastcgi
-   * added server.statistics-url to get internal statistics from mod_status
-   * added support for conditional range-requests through If-Range
-   * added static building via scons
--  * fixed 100% cpu loops in mod_cgi ("sandy" )
--  * fixed handling for secure-download.timeout (jamis@37signals.com)
--  * fixed IE bug in content-charset in the output of mod_dirlisting (sniper@php.net)
--  * fixed typos and language in the docs (ryan-2005@ryandesign.com)
--  * fixed assertion in mod_cgi on HEAD request is Content-Length ()
-+  * fixed 100% cpu loops in mod_cgi ("sandy" )
-+  * fixed handling for secure-download.timeout (jamis/at/37signals.com)
-+  * fixed IE bug in content-charset in the output of mod_dirlisting (sniper/at/php.net)
-+  * fixed typos and language in the docs (ryan-2005/at/ryandesign.com)
-+  * fixed assertion in mod_cgi on HEAD request is Content-Length ()
-   * fixed handling if equal but duplicate If-Modified-Since request headers
-   * fixed endless loops in mod_fastcgi if backend is dead
-   * fixed Depth: 1 handling in PROPFIND requests on empty dirs
--  * fixed encoding of UTF8 encoded dirlistings (Jani Taskinen )
-+  * fixed encoding of UTF8 encoded dirlistings (Jani Taskinen )
-   * fixed initial bind to a unix-domain socket through server.bind
-   * fixed handling of lowercase filesystems
-   * fixed duplicate request headers cause by mod_setenv
-@@ -108,12 +125,12 @@
- - 1.4.8 - 2005-11-23
- 
-   * added auto-reconnect to ldap-server in mod_auth
--    (joerg@netbsd.org)
-+    (joerg/at/netbsd.org)
-   * changed auth.ldap-cafile to be optional
--    (joerg@netbsd.org)
-+    (joerg/at/netbsd.org)
-   * added strip_request_uri in mod_fastcgi
-   * added more X-* headers to mod_proxy
--    (Ben Grimm )
-+    (Ben Grimm )
-   * added 'debug' to simple-vhost to suppress the
-     (mod_simple_vhost.c.157) No such file or directory /servers/ww.lighttpd.net/pages/
-     messages by default
-@@ -124,11 +141,11 @@
-   * fixed encoding the filenames in PROPFIND in mod_webdav
-   * fixed range request handling in network_writev
-   * fixed retry on connect error in mod_fastcgi
--    (Robert G. Jakabosky )
-+    (Robert G. Jakabosky )
-   * fixed possible crash in mod_webdav if sqlite3 support
-     is available but not use
-   * fixed fdvent-handler init if server.max-worker was used
--    (Siddharth Vijayakrishnan )
-+    (Siddharth Vijayakrishnan )
-   * fixed missing cleanup in mysql_vhost
-   * fixed assert() in "connections.c:962:
-       connection_handle_read_state: Assertion 'c->mem->used' failed."
-@@ -139,7 +156,7 @@
-   * fixed unsigned/signed comparisions
-   * fixed streaming in mod_cgi
-   * fixed possible overflow in password-salt handling
--    (reported on slashdot by james-web@and.org)
-+    (reported on slashdot by james-web/at/and.org)
-   * fixed server-traffic-limit if connection limit is not set
- 
- - 1.4.7 - 2005-11-02
-@@ -150,7 +167,7 @@
-   * added support for %I in mod_accesslog
-   * added better compat to Apache for ?auto in mod_status
-   * added support for userdirs without a entry in /etc/passwd in mod_userdir
--    (rob@inversepath.com)
-+    (rob/at/inversepath.com)
-   * added startup-time selectable network-backend
-   * added location of upload-files to config as array
-   * added webdav.log-xml for logging xml-content in mod_webdav
-
-Property changes on: .
-___________________________________________________________________
-Name: svk:merge
-   + a98e19e4-a712-0410-8832-6551a15ffc53:/local/branches/lighttpd-1.4.x:1557
-
+-- 1.4.23 -
++- 1.4.24 -
++  * Add T_CONFIG_INT for bigger integers from the config (needed for #1966)
++  * Use unsigned int (and T_CONFIG_INT) for max_request_size
++  * Use unsigned int for secdownload.timeout (fixes #1966)
++  * Keep url/host values from connection to display information while keep-alive in mod_status (fixes #1202)
++  * Add server.breakagelog, a "special" stderr (fixes #1863)
++  * Fix config evaluation for debug.log-timeouts option (#1529)
++  * Add "cgi.execute-x-only" to mod_cgi, requires +x for cgi scripts (fixes #2013)
++  * Fix FD_SETSIZE comparision warnings
++  * Add "lua-5.1" to searched pkg-config names for lua
++  * Fix unused function webdav_lockdiscovery in mod_webdav
++  * cmake: Fix crypt lib check
++  * cmake: Add -export-dynamic to link flags, fixes build on FreeBSD
++  * Set FD_CLOEXEC for bound sockets before pipe-logger forks (fixes #2026)
++  * Reset ignored signals to SIG_DFL before exec() in fastcgi/scgi (fixes #2029)
++  * Show "no uri specified -> 400" error only when "debug.log-request-header-on-error" is enabled (fixes #2030)
++  * Fix hanging connection in mod_scgi (fixes #2024)
++  * Allow digits in hostnames in more places (fixes #1148)
++  * Use connection_reset instead of handle_request_done for cleanup callbacks
++  * Change mod_expire to append Cache-Control instead of overwriting it (fixes #1997)
++  * Allow all comparisons for $SERVER["socket"] - only bind for "=="
++  * Remove strptime failed message (fixes #2031)
++  * Fix issues found with clang analyzer
++  * Try to fix server.tag issue with localized svnversion
++  * Fix handling network-write return values (#2024)
++  * Use disable-time in fastcgi for all disables after errors, default is 1sec (fixes #2040)
++  * Remove adaptive spawning code from fastcgi (was disabled for a long time)
++  * Allow mod_mysql_vhost to use stored procedures (fixes #2011, thx Ben Brown)
++  * Fix ipv6 in mod_proxy (fixes #2043)
++  * Print errors from include_shell to stderr
++  * Set tm.tm_isdst = 0 before mktime() (fixes #2047)
++  * Use linux-epoll by default if available (fixes #2021, thx Olaf van der Spek)
++  * Print an error if you use too many captures in a regex pattern (fixes #2059)
++  * Combine Cache-Control header value in mod_expire to existing HTTP header if header already added by other modules (fixes #2068)
++
++- 1.4.23 - 2009-06-19
+   * Added some extra warning options in cmake and fix the resulting warnings (unused/static functions)
+   * New lighttpd man page (moved it to section 8) (fixes #1875)
+   * Create rrd file for empty rrdfile in mod_rrdtool (#1788)
+Index: CMakeLists.txt
+===================================================================