+Index: configure.in
+===================================================================
+Index: src/spawn-fcgi.c
+===================================================================
+--- src/spawn-fcgi.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/spawn-fcgi.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -1,481 +0,0 @@
+-#include <sys/types.h>
+-#include <sys/time.h>
+-#include <sys/stat.h>
+-
+-#include <stdlib.h>
+-#include <string.h>
+-#include <errno.h>
+-#include <stdio.h>
+-#include <unistd.h>
+-#include <fcntl.h>
+-
+-#ifdef HAVE_CONFIG_H
+-#include "config.h"
+-#endif
+-
+-
+-#ifdef HAVE_PWD_H
+-#include <grp.h>
+-#include <pwd.h>
+-#endif
+-
+-#ifdef HAVE_GETOPT_H
+-#include <getopt.h>
+-#endif
+-
+-#define FCGI_LISTENSOCK_FILENO 0
+-
+-#include "sys-socket.h"
+-
+-#ifdef HAVE_SYS_WAIT_H
+-#include <sys/wait.h>
+-#endif
+-
+-/* for solaris 2.5 and netbsd 1.3.x */
+-#ifndef HAVE_SOCKLEN_T
+-typedef int socklen_t;
+-#endif
+-
+-#ifdef HAVE_SYS_UN_H
+-int fcgi_spawn_connection(char *appPath, char **appArgv, char *addr, unsigned short port, const char *unixsocket, int fork_count, int child_count, int pid_fd, int nofork) {
+- int fcgi_fd;
+- int socket_type, status, rc = 0;
+- struct timeval tv = { 0, 100 * 1000 };
+-
+- struct sockaddr_un fcgi_addr_un;
+- struct sockaddr_in fcgi_addr_in;
+- struct sockaddr *fcgi_addr;
+-
+- socklen_t servlen;
+-
+- if (child_count < 2) {
+- child_count = 5;
+- }
+-
+- if (child_count > 256) {
+- child_count = 256;
+- }
+-
+-
+- if (unixsocket) {
+- memset(&fcgi_addr_un, 0, sizeof(fcgi_addr_un));
+-
+- fcgi_addr_un.sun_family = AF_UNIX;
+- strcpy(fcgi_addr_un.sun_path, unixsocket);
+-
+-#ifdef SUN_LEN
+- servlen = SUN_LEN(&fcgi_addr_un);
+-#else
+- /* stevens says: */
+- servlen = strlen(fcgi_addr_un.sun_path) + sizeof(fcgi_addr_un.sun_family);
+-#endif
+- socket_type = AF_UNIX;
+- fcgi_addr = (struct sockaddr *) &fcgi_addr_un;
+- } else {
+- memset(&fcgi_addr_in, 0, sizeof(fcgi_addr_in));
+- fcgi_addr_in.sin_family = AF_INET;
+- if (addr != NULL) {
+- fcgi_addr_in.sin_addr.s_addr = inet_addr(addr);
+- } else {
+- fcgi_addr_in.sin_addr.s_addr = htonl(INADDR_ANY);
+- }
+- fcgi_addr_in.sin_port = htons(port);
+- servlen = sizeof(fcgi_addr_in);
+-
+- socket_type = AF_INET;
+- fcgi_addr = (struct sockaddr *) &fcgi_addr_in;
+- }
+-
+- if (-1 == (fcgi_fd = socket(socket_type, SOCK_STREAM, 0))) {
+- fprintf(stderr, "%s.%d\n",
+- __FILE__, __LINE__);
+- return -1;
+- }
+-
+- if (-1 == connect(fcgi_fd, fcgi_addr, servlen)) {
+- /* server is not up, spawn in */
+- pid_t child;
+- int val;
+-
+- if (unixsocket) unlink(unixsocket);
+-
+- close(fcgi_fd);
+-
+- /* reopen socket */
+- if (-1 == (fcgi_fd = socket(socket_type, SOCK_STREAM, 0))) {
+- fprintf(stderr, "%s.%d\n",
+- __FILE__, __LINE__);
+- return -1;
+- }
+-
+- val = 1;
+- if (setsockopt(fcgi_fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) {
+- fprintf(stderr, "%s.%d\n",
+- __FILE__, __LINE__);
+- return -1;
+- }
+-
+- /* create socket */
+- if (-1 == bind(fcgi_fd, fcgi_addr, servlen)) {
+- fprintf(stderr, "%s.%d: bind failed: %s\n",
+- __FILE__, __LINE__,
+- strerror(errno));
+- return -1;
+- }
+-
+- if (-1 == listen(fcgi_fd, 1024)) {
+- fprintf(stderr, "%s.%d: fd = -1\n",
+- __FILE__, __LINE__);
+- return -1;
+- }
+-
+- while (fork_count-- > 0) {
+-
+- if (!nofork) {
+- child = fork();
+- } else {
+- child = 0;
+- }
+-
+- switch (child) {
+- case 0: {
+- char cgi_childs[64];
+- int max_fd = 0;
+-
+- int i = 0;
+-
+- /* loose control terminal */
+- setsid();
+-
+- /* is safe as we limit to 256 childs */
+- sprintf(cgi_childs, "PHP_FCGI_CHILDREN=%d", child_count);
+-
+- if(fcgi_fd != FCGI_LISTENSOCK_FILENO) {
+- close(FCGI_LISTENSOCK_FILENO);
+- dup2(fcgi_fd, FCGI_LISTENSOCK_FILENO);
+- close(fcgi_fd);
+- }
+-
+- max_fd = open("/dev/null", O_RDWR);
+- close(STDERR_FILENO);
+- dup2(max_fd, STDERR_FILENO);
+- close(max_fd);
+-
+- max_fd = open("/dev/null", O_RDWR);
+- close(STDOUT_FILENO);
+- dup2(max_fd, STDOUT_FILENO);
+- close(max_fd);
+-
+- /* we don't need the client socket */
+- for (i = 3; i < max_fd; i++) {
+- if (i != FCGI_LISTENSOCK_FILENO) close(i);
+- }
+-
+- /* create environment */
+-
+- putenv(cgi_childs);
+-
+- /* fork and replace shell */
+- if (appArgv) {
+- execv(appArgv[0], appArgv);
+-
+- } else {
+- char *b = malloc(strlen("exec ") + strlen(appPath) + 1);
+- strcpy(b, "exec ");
+- strcat(b, appPath);
+-
+- /* exec the cgi */
+- execl("/bin/sh", "sh", "-c", b, (char *)NULL);
+- }
+-
+- exit(errno);
+-
+- break;
+- }
+- case -1:
+- /* error */
+- break;
+- default:
+- /* father */
+-
+- /* wait */
+- select(0, NULL, NULL, NULL, &tv);
+-
+- switch (waitpid(child, &status, WNOHANG)) {
+- case 0:
+- fprintf(stdout, "%s.%d: child spawned successfully: PID: %d\n",
+- __FILE__, __LINE__,
+- child);
+-
+- /* write pid file */
+- if (pid_fd != -1) {
+- /* assume a 32bit pid_t */
+- char pidbuf[12];
+-
+- snprintf(pidbuf, sizeof(pidbuf) - 1, "%d", child);
+-
+- write(pid_fd, pidbuf, strlen(pidbuf));
+- /* avoid eol for the last one */
+- if (fork_count != 0) {
+- write(pid_fd, "\n", 1);
+- }
+- }
+-
+- break;
+- case -1:
+- break;
+- default:
+- if (WIFEXITED(status)) {
+- fprintf(stderr, "%s.%d: child exited with: %d\n",
+- __FILE__, __LINE__, WEXITSTATUS(status));
+- rc = WEXITSTATUS(status);
+- } else if (WIFSIGNALED(status)) {
+- fprintf(stderr, "%s.%d: child signaled: %d\n",
+- __FILE__, __LINE__,
+- WTERMSIG(status));
+- rc = 1;
+- } else {
+- fprintf(stderr, "%s.%d: child died somehow: %d\n",
+- __FILE__, __LINE__,
+- status);
+- rc = status;
+- }
+- }
+-
+- break;
+- }
+- }
+- close(pid_fd);
+- pid_fd = -1;
+- } else {
+- fprintf(stderr, "%s.%d: socket is already used, can't spawn\n",
+- __FILE__, __LINE__);
+- return -1;
+- }
+-
+- close(fcgi_fd);
+-
+- return rc;
+-}
+-
+-
+-void show_version () {
+- char *b = "spawn-fcgi" "-" PACKAGE_VERSION \
+-" - spawns fastcgi processes\n"
+-;
+- write(1, b, strlen(b));
+-}
+-
+-void show_help () {
+- char *b = \
+-"Usage: spawn-fcgi [options] -- <fcgiapp> [fcgi app arguments]\n" \
+-"\n" \
+-"spawn-fcgi v" PACKAGE_VERSION " - spawns fastcgi processes\n" \
+-"\n" \
+-"Options:\n" \
+-" -f <fcgiapp> filename of the fcgi-application\n" \
+-" -a <addr> bind to ip address\n" \
+-" -p <port> bind to tcp-port\n" \
+-" -s <path> bind to unix-domain socket\n" \
+-" -C <childs> (PHP only) numbers of childs to spawn (default 5)\n" \
+-" -F <childs> numbers of childs to fork (default 1)\n" \
+-" -P <path> name of PID-file for spawed process\n" \
+-" -n no fork (for daemontools)\n" \
+-" -v show version\n" \
+-" -h show this help\n" \
+-"(root only)\n" \
+-" -c <dir> chroot to directory\n" \
+-" -u <user> change to user-id\n" \
+-" -g <group> change to group-id\n" \
+-;
+- write(1, b, strlen(b));
+-}
+-
+-
+-int main(int argc, char **argv) {
+- char *fcgi_app = NULL, *changeroot = NULL, *username = NULL,
+- *groupname = NULL, *unixsocket = NULL, *pid_file = NULL,
+- *addr = NULL;
+- char **fcgi_app_argv = { NULL };
+- unsigned short port = 0;
+- int child_count = 5;
+- int fork_count = 1;
+- int i_am_root, o;
+- int pid_fd = -1;
+- int nofork = 0;
+- struct sockaddr_un un;
+-
+- i_am_root = (getuid() == 0);
+-
+- while (-1 != (o = getopt(argc, argv, "c:f:g:hna:p:u:vC:F:s:P:"))) {
+- switch(o) {
+- case 'f': fcgi_app = optarg; break;
+- case 'a': addr = optarg;/* ip addr */ break;
+- case 'p': port = strtol(optarg, NULL, 10);/* port */ break;
+- case 'C': child_count = strtol(optarg, NULL, 10);/* */ break;
+- case 'F': fork_count = strtol(optarg, NULL, 10);/* */ break;
+- case 's': unixsocket = optarg; /* unix-domain socket */ break;
+- case 'c': if (i_am_root) { changeroot = optarg; }/* chroot() */ break;
+- case 'u': if (i_am_root) { username = optarg; } /* set user */ break;
+- case 'g': if (i_am_root) { groupname = optarg; } /* set group */ break;
+- case 'n': nofork = 1; break;
+- case 'P': pid_file = optarg; /* PID file */ break;
+- case 'v': show_version(); return 0;
+- case 'h': show_help(); return 0;
+- default:
+- show_help();
+- return -1;
+- }
+- }
+-
+- if (optind < argc) {
+- fcgi_app_argv = &argv[optind];
+- }
+-
+- if ((fcgi_app == NULL && fcgi_app_argv == NULL) || (port == 0 && unixsocket == NULL)) {
+- show_help();
+- return -1;
+- }
+-
+- if (unixsocket && port) {
+- fprintf(stderr, "%s.%d: %s\n",
+- __FILE__, __LINE__,
+- "either a unix domain socket or a tcp-port, but not both\n");
+-
+- return -1;
+- }
+-
+- if (unixsocket && strlen(unixsocket) > sizeof(un.sun_path) - 1) {
+- fprintf(stderr, "%s.%d: %s\n",
+- __FILE__, __LINE__,
+- "path of the unix socket is too long\n");
+-
+- return -1;
+- }
+-
+- /* UID handling */
+- if (!i_am_root && (geteuid() == 0 || getegid() == 0)) {
+- /* we are setuid-root */
+-
+- fprintf(stderr, "%s.%d: %s\n",
+- __FILE__, __LINE__,
+- "Are you nuts ? Don't apply a SUID bit to this binary\n");
+-
+- return -1;
+- }
+-
+- if (pid_file &&
+- (-1 == (pid_fd = open(pid_file, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)))) {
+- struct stat st;
+- if (errno != EEXIST) {
+- fprintf(stderr, "%s.%d: opening pid-file '%s' failed: %s\n",
+- __FILE__, __LINE__,
+- pid_file, strerror(errno));
+-
+- return -1;
+- }
+-
+- /* ok, file exists */
+-
+- if (0 != stat(pid_file, &st)) {
+- fprintf(stderr, "%s.%d: stating pid-file '%s' failed: %s\n",
+- __FILE__, __LINE__,
+- pid_file, strerror(errno));
+-
+- return -1;
+- }
+-
+- /* is it a regular file ? */
+-
+- if (!S_ISREG(st.st_mode)) {
+- fprintf(stderr, "%s.%d: pid-file exists and isn't regular file: '%s'\n",
+- __FILE__, __LINE__,
+- pid_file);
+-
+- return -1;
+- }
+-
+- if (-1 == (pid_fd = open(pid_file, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) {
+- fprintf(stderr, "%s.%d: opening pid-file '%s' failed: %s\n",
+- __FILE__, __LINE__,
+- pid_file, strerror(errno));
+-
+- return -1;
+- }
+- }
+-
+- if (i_am_root) {
+- struct group *grp = NULL;
+- struct passwd *pwd = NULL;
+-
+- /* set user and group */
+-
+- if (username) {
+- if (NULL == (pwd = getpwnam(username))) {
+- fprintf(stderr, "%s.%d: %s, %s\n",
+- __FILE__, __LINE__,
+- "can't find username", username);
+- return -1;
+- }
+-
+- if (pwd->pw_uid == 0) {
+- fprintf(stderr, "%s.%d: %s\n",
+- __FILE__, __LINE__,
+- "I will not set uid to 0\n");
+- return -1;
+- }
+- }
+-
+- if (groupname) {
+- if (NULL == (grp = getgrnam(groupname))) {
+- fprintf(stderr, "%s.%d: %s %s\n",
+- __FILE__, __LINE__,
+- "can't find groupname",
+- groupname);
+- return -1;
+- }
+- if (grp->gr_gid == 0) {
+- fprintf(stderr, "%s.%d: %s\n",
+- __FILE__, __LINE__,
+- "I will not set gid to 0\n");
+- return -1;
+- }
+-
+- /* do the change before we do the chroot() */
+- setgid(grp->gr_gid);
+- setgroups(0, NULL);
+-
+- if (username) {
+- initgroups(username, grp->gr_gid);
+- }
+-
+- }
+-
+- if (changeroot) {
+- if (-1 == chroot(changeroot)) {
+- fprintf(stderr, "%s.%d: %s %s\n",
+- __FILE__, __LINE__,
+- "chroot failed: ", strerror(errno));
+- return -1;
+- }
+- if (-1 == chdir("/")) {
+- fprintf(stderr, "%s.%d: %s %s\n",
+- __FILE__, __LINE__,
+- "chdir failed: ", strerror(errno));
+- return -1;
+- }
+- }
+-
+- /* drop root privs */
+- if (username) {
+- setuid(pwd->pw_uid);
+- }
+- }
+-
+- return fcgi_spawn_connection(fcgi_app, fcgi_app_argv, addr, port, unixsocket, fork_count, child_count, pid_fd, nofork);
+-}
+-#else
+-int main() {
+- return -1;
+-}
+-#endif
+Index: src/configfile-glue.c
+===================================================================
+--- src/configfile-glue.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/configfile-glue.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -49,7 +49,7 @@
+ buffer_copy_string_buffer(ds->value, ((data_string *)(da->value->data[j]))->value);
+ if (!da->is_index_key) {
+ /* the id's were generated automaticly, as we copy now we might have to renumber them
+- * this is used to prepend server.modules by mod_indexfiles as it has to be loaded
++ * this is used to prepend server.modules by mod_indexfile as it has to be loaded
+ * before mod_fastcgi and friends */
+ buffer_copy_string_buffer(ds->key, ((data_string *)(da->value->data[j]))->key);
+ }
+@@ -181,7 +181,7 @@
+ return config_insert_values_internal(srv, ca, cv);
+ }
+
+-unsigned short sock_addr_get_port(sock_addr *addr) {
++static unsigned short sock_addr_get_port(sock_addr *addr) {
+ #ifdef HAVE_IPV6
+ return ntohs(addr->plain.sa_family ? addr->ipv6.sin6_port : addr->ipv4.sin_port);
+ #else
+Index: src/mod_cgi.c
+===================================================================
+--- src/mod_cgi.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/mod_cgi.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -24,6 +24,7 @@
+ #include <fcntl.h>
+
+ #include "server.h"
++#include "stat_cache.h"
+ #include "keyvalue.h"
+ #include "log.h"
+ #include "connections.h"
+@@ -36,6 +37,8 @@
+ # include <sys/filio.h>
+ #endif
+
++#include "version.h"
++
+ enum {EOL_UNSET, EOL_N, EOL_RN};
+
+ typedef struct {
+@@ -696,11 +699,11 @@
+
+ if (!key || !val) return -1;
+
+- dst = malloc(key_len + val_len + 3);
++ dst = malloc(key_len + val_len + 2);
+ memcpy(dst, key, key_len);
+ dst[key_len] = '=';
+- /* add the \0 from the value */
+- memcpy(dst + key_len + 1, val, val_len + 1);
++ memcpy(dst + key_len + 1, val, val_len);
++ dst[key_len + 1 + val_len] = '\0';
+
+ if (env->size == 0) {
+ env->size = 16;
+@@ -776,25 +779,23 @@
+ /* not needed */
+ close(to_cgi_fds[1]);
+
+- /* HACK:
+- * this is not nice, but it works
+- *
+- * we feed the stderr of the CGI to our errorlog, if possible
+- */
+- if (srv->errorlog_mode == ERRORLOG_FILE) {
+- close(STDERR_FILENO);
+- dup2(srv->errorlog_fd, STDERR_FILENO);
+- }
+-
+ /* create environment */
+ env.ptr = NULL;
+ env.size = 0;
+ env.used = 0;
+
+- cgi_env_add(&env, CONST_STR_LEN("SERVER_SOFTWARE"), CONST_STR_LEN(PACKAGE_NAME"/"PACKAGE_VERSION));
++ if (buffer_is_empty(con->conf.server_tag)) {
++ cgi_env_add(&env, CONST_STR_LEN("SERVER_SOFTWARE"), CONST_STR_LEN(PACKAGE_DESC));
++ } else {
++ cgi_env_add(&env, CONST_STR_LEN("SERVER_SOFTWARE"), CONST_BUF_LEN(con->conf.server_tag));
++ }
+
+ if (!buffer_is_empty(con->server_name)) {
+- cgi_env_add(&env, CONST_STR_LEN("SERVER_NAME"), CONST_BUF_LEN(con->server_name));
++ size_t len = con->server_name->used - 1;
++ char *colon = strchr(con->server_name->ptr, ':');
++ if (colon) len = colon - con->server_name->ptr;
++
++ cgi_env_add(&env, CONST_STR_LEN("SERVER_NAME"), con->server_name->ptr, len);
+ } else {
+ #ifdef HAVE_IPV6
+ s = inet_ntop(srv_sock->addr.plain.sa_family,
+@@ -972,9 +973,15 @@
+ buffer_prepare_append(p->tmp_buf, ds->key->used + 2);
+
+ for (j = 0; j < ds->key->used - 1; j++) {
+- p->tmp_buf->ptr[p->tmp_buf->used++] =
+- light_isalnum((unsigned char)ds->key->ptr[j]) ?
+- toupper((unsigned char)ds->key->ptr[j]) : '_';
++ char cr = '_';
++ if (light_isalpha(ds->key->ptr[j])) {
++ /* upper-case */
++ cr = ds->key->ptr[j] & ~32;
++ } else if (light_isdigit(ds->key->ptr[j])) {
++ /* copy */
++ cr = ds->key->ptr[j];
++ }
++ p->tmp_buf->ptr[p->tmp_buf->used++] = cr;
+ }
+ p->tmp_buf->ptr[p->tmp_buf->used++] = '\0';
+
+@@ -1203,6 +1210,7 @@
+ size_t k, s_len;
+ plugin_data *p = p_d;
+ buffer *fn = con->physical.path;
++ stat_cache_entry *sce = NULL;
+
+ if (con->mode != DIRECT) return HANDLER_GO_ON;
+
+@@ -1210,6 +1218,9 @@
+
+ mod_cgi_patch_connection(srv, con, p);
+
++ 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;
++
+ s_len = fn->used - 1;
+
+ for (k = 0; k < p->conf.cgi->used; k++) {
+@@ -1369,6 +1380,7 @@
+ }
+
+
++int mod_cgi_plugin_init(plugin *p);
+ int mod_cgi_plugin_init(plugin *p) {
+ p->version = LIGHTTPD_VERSION_ID;
+ p->name = buffer_init_string("cgi");
+Index: src/mod_cml.c
+===================================================================
+--- src/mod_cml.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/mod_cml.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -178,7 +178,7 @@
+ }
+ #undef PATCH
+
+-int cache_call_lua(server *srv, connection *con, plugin_data *p, buffer *cml_file) {
++static int cache_call_lua(server *srv, connection *con, plugin_data *p, buffer *cml_file) {
+ buffer *b;
+ char *c;
+
+@@ -305,6 +305,7 @@
+ }
+ }
+
++int mod_cml_plugin_init(plugin *p);
+ int mod_cml_plugin_init(plugin *p) {
+ p->version = LIGHTTPD_VERSION_ID;
+ p->name = buffer_init_string("cache");
+Index: src/mod_secure_download.c
+===================================================================
+--- src/mod_secure_download.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/mod_secure_download.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -138,7 +138,7 @@
+ * @return if the supplied string is a valid MD5 string 1 is returned otherwise 0
+ */
+
+-int is_hex_len(const char *str, size_t len) {
++static int is_hex_len(const char *str, size_t len) {
+ size_t i;
+
+ if (NULL == str) return 0;
+@@ -293,6 +293,7 @@
+
+ /* this function is called at dlopen() time and inits the callbacks */
+
++int mod_secdownload_plugin_init(plugin *p);
+ int mod_secdownload_plugin_init(plugin *p) {
+ p->version = LIGHTTPD_VERSION_ID;
+ p->name = buffer_init_string("secdownload");
Index: src/base.h
===================================================================
---- src/base.h (.../tags/lighttpd-1.4.15) (revision 1880)
-+++ src/base.h (.../branches/lighttpd-1.4.x) (revision 1880)
-@@ -269,6 +269,9 @@
+--- src/base.h (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/base.h (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -183,11 +183,15 @@
+ } response;
+
+ typedef struct {
+- buffer *scheme;
++ buffer *scheme; /* scheme without colon or slashes ( "http" or "https" ) */
++
++ /* authority with optional portnumber ("site.name" or "site.name:8080" ) NOTE: without "username:password@" */
+ buffer *authority;
++
++ /* path including leading slash ("/" or "/index.html") - urldecoded, and sanitized ( buffer_path_simplify() && buffer_urldecode_path() ) */
+ buffer *path;
+- buffer *path_raw;
+- buffer *query;
++ buffer *path_raw; /* raw path, as sent from client. no urldecoding or path simplifying */
++ buffer *query; /* querystring ( everything after "?", ie: in "/index.php?foo=1", query is "foo=1" ) */
+ } request_uri;
+
+ typedef struct {
+@@ -270,6 +274,7 @@
+ unsigned short ssl_use_sslv2;
+
unsigned short use_ipv6;
++ unsigned short defer_accept;
unsigned short is_ssl;
unsigned short allow_http11;
-+ unsigned short etag_use_inode;
-+ 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 short etag_use_inode;
+@@ -533,7 +538,7 @@
+
+ /* the errorlog */
+ int errorlog_fd;
+- enum { ERRORLOG_STDERR, ERRORLOG_FILE, ERRORLOG_SYSLOG } errorlog_mode;
++ enum { ERRORLOG_STDERR, ERRORLOG_FILE, 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.22) (revision 2504)
++++ src/mod_rewrite.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -63,7 +63,7 @@
+ free(hctx);
+ }
+
+-rewrite_rule_buffer *rewrite_rule_buffer_init(void) {
++static rewrite_rule_buffer *rewrite_rule_buffer_init(void) {
+ rewrite_rule_buffer *kvb;
+
+ kvb = calloc(1, sizeof(*kvb));
+@@ -71,7 +71,7 @@
+ return kvb;
+ }
+
+-int rewrite_rule_buffer_append(rewrite_rule_buffer *kvb, buffer *key, buffer *value, int once) {
++static int rewrite_rule_buffer_append(rewrite_rule_buffer *kvb, buffer *key, buffer *value, int once) {
+ #ifdef HAVE_PCRE_H
+ size_t i;
+ const char *errptr;
+@@ -121,7 +121,7 @@
+ #endif
+ }
+
+-void rewrite_rule_buffer_free(rewrite_rule_buffer *kvb) {
++static void rewrite_rule_buffer_free(rewrite_rule_buffer *kvb) {
+ #ifdef HAVE_PCRE_H
+ size_t i;
+
+@@ -444,6 +444,7 @@
+ return HANDLER_GO_ON;
+ }
++int mod_rewrite_plugin_init(plugin *p);
+ int mod_rewrite_plugin_init(plugin *p) {
+ p->version = LIGHTTPD_VERSION_ID;
+ p->name = buffer_init_string("rewrite");
Index: src/connections.c
===================================================================
---- src/connections.c (.../tags/lighttpd-1.4.15) (revision 1880)
-+++ src/connections.c (.../branches/lighttpd-1.4.x) (revision 1880)
-@@ -1252,6 +1252,16 @@
- socklen_t cnt_len;
- /* accept it and register the fd */
+--- src/connections.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/connections.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -192,7 +192,7 @@
+
+ static int connection_handle_read_ssl(server *srv, connection *con) {
+ #ifdef USE_OPENSSL
+- int r, ssl_err, len;
++ int r, ssl_err, len, count = 0;
+ buffer *b = NULL;
+
+ if (!con->conf.is_ssl) return -1;
+@@ -221,10 +221,11 @@
+ /* we move the buffer to the chunk-queue, no need to free it */
+
+ chunkqueue_append_buffer_weak(con->read_queue, b);
++ count += len;
+ con->bytes_read += len;
+ b = NULL;
+ }
+- } while (len > 0);
++ } while (len > 0 && count < MAX_READ_LIMIT);
+
+
+ if (len < 0) {
+@@ -334,6 +335,7 @@
+ b = chunkqueue_get_append_buffer(con->read_queue);
+ buffer_prepare_copy(b, 4 * 1024);
+ } else {
++ if (toread > MAX_READ_LIMIT) toread = MAX_READ_LIMIT;
+ b = chunkqueue_get_append_buffer(con->read_queue);
+ buffer_prepare_copy(b, toread + 1);
+ }
+@@ -858,7 +860,7 @@
+ *
+ * we get called by the state-engine and by the fdevent-handler
+ */
+-int connection_handle_read_state(server *srv, connection *con) {
++static int connection_handle_read_state(server *srv, connection *con) {
+ connection_state_t ostate = con->state;
+ chunk *c, *last_chunk;
+ off_t last_offset;
+@@ -1156,7 +1158,7 @@
+ return 0;
+ }
+
+-handler_t connection_handle_fdevent(void *s, void *context, int revents) {
++static handler_t connection_handle_fdevent(void *s, void *context, int revents) {
+ server *srv = (server *)s;
+ connection *con = context;
+
+Index: src/mod_staticfile.c
+===================================================================
+--- src/mod_staticfile.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/mod_staticfile.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -532,6 +532,7 @@
+
+ /* this function is called at dlopen() time and inits the callbacks */
+
++int mod_staticfile_plugin_init(plugin *p);
+ int mod_staticfile_plugin_init(plugin *p) {
+ p->version = LIGHTTPD_VERSION_ID;
+ p->name = buffer_init_string("staticfile");
+Index: src/mod_alias.c
+===================================================================
+--- src/mod_alias.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/mod_alias.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -187,6 +187,7 @@
+
+ /* this function is called at dlopen() time and inits the callbacks */
+
++int mod_alias_plugin_init(plugin *p);
+ int mod_alias_plugin_init(plugin *p) {
+ p->version = LIGHTTPD_VERSION_ID;
+ p->name = buffer_init_string("alias");
+Index: src/network.c
+===================================================================
+--- src/network.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/network.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -26,7 +26,7 @@
+ # include <openssl/rand.h>
+ #endif
+
+-handler_t network_server_handle_fdevent(void *s, void *context, int revents) {
++static handler_t network_server_handle_fdevent(void *s, void *context, int revents) {
+ server *srv = (server *)s;
+ server_socket *srv_socket = (server_socket *)context;
+ connection *con;
+@@ -62,7 +62,7 @@
+ return HANDLER_GO_ON;
+ }
+
+-int network_server_init(server *srv, buffer *host_token, specific_config *s) {
++static int network_server_init(server *srv, buffer *host_token, specific_config *s) {
+ int val;
+ socklen_t addr_len;
+ server_socket *srv_socket;
+@@ -73,10 +73,6 @@
+ int is_unix_domain_socket = 0;
+ int fd;
+
+-#ifdef SO_ACCEPTFILTER
+- struct accept_filter_arg afa;
+-#endif
+-
+ #ifdef __WIN32
+ WORD wVersionRequested;
+ WSADATA wsaData;
+@@ -396,12 +392,17 @@
+
+ return -1;
+ #endif
++#ifdef TCP_DEFER_ACCEPT
++ } else if (s->defer_accept) {
++ int v = s->defer_accept;
++ if (-1 == setsockopt(srv_socket->fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &v, sizeof(v))) {
++ log_error_write(srv, __FILE__, __LINE__, "ss", "can't set TCP_DEFER_ACCEPT: ", strerror(errno));
++ }
++#endif
+ } else {
+ #ifdef SO_ACCEPTFILTER
+- /*
+- * FreeBSD accf_http filter
+- *
+- */
++ /* FreeBSD accf_http filter */
++ struct accept_filter_arg afa;
+ memset(&afa, 0, sizeof(afa));
+ strcpy(afa.af_name, "httpready");
+ if (setsockopt(srv_socket->fd, SOL_SOCKET, SO_ACCEPTFILTER, &afa, sizeof(afa)) < 0) {
+Index: src/configfile.c
+===================================================================
+--- src/configfile.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/configfile.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -96,6 +96,7 @@
+ { "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.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 },
+@@ -164,6 +165,7 @@
+ s->is_ssl = 0;
+ s->ssl_use_sslv2 = 0;
+ s->use_ipv6 = 0;
++ s->defer_accept = 0;
+ #ifdef HAVE_LSTAT
+ s->follow_symlink = 1;
+ #endif
+@@ -182,6 +184,7 @@
+
+ cv[7].destination = s->server_tag;
+ cv[8].destination = &(s->use_ipv6);
++ cv[54].destination = &(s->defer_accept);
+
+
+ /* 13 max-worker */
+Index: src/mod_trigger_b4_dl.c
+===================================================================
+--- src/mod_trigger_b4_dl.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/mod_trigger_b4_dl.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -576,6 +576,7 @@
+
+ /* this function is called at dlopen() time and inits the callbacks */
+
++int mod_trigger_b4_dl_plugin_init(plugin *p);
+ int mod_trigger_b4_dl_plugin_init(plugin *p) {
+ p->version = LIGHTTPD_VERSION_ID;
+ p->name = buffer_init_string("trigger_b4_dl");
+Index: src/mod_evhost.c
+===================================================================
+--- src/mod_evhost.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/mod_evhost.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -115,6 +115,7 @@
+ * # %2 => domain name without tld
+ * # %3 => subdomain 1 name
+ * # %4 => subdomain 2 name
++ * # %_ => fqdn (without port info)
+ * #
+ * evhost.path-pattern = "/home/ckruse/dev/www/%3/htdocs/"
+ *
+@@ -154,11 +155,12 @@
+ }
+
+ /**
+- * assign the different parts of the domain to array-indezes
+- * - %0 - full hostname (authority w/o port)
++ * assign the different parts of the domain to array-indezes (sub2.sub1.domain.tld)
++ * - %0 - domain.tld
+ * - %1 - tld
+- * - %2 - domain.tld
+- * - %3 -
++ * - %2 - domain
++ * - %3 - sub1
++ * - ...
+ */
+
+ static int mod_evhost_parse_host(connection *con,array *host) {
+@@ -287,6 +289,16 @@
+ if (*(ptr+1) == '%') {
+ /* %% */
+ buffer_append_string_len(p->tmp_buf,CONST_STR_LEN("%"));
++ } else if (*(ptr+1) == '_' ) {
++ /* %_ == full hostname */
++ char *colon = strchr(con->uri.authority->ptr, ':');
++
++ if(colon == NULL) {
++ 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
++ }
+ } else if (NULL != (ds = (data_string *)array_get_element(parsed_host,p->conf.path_pieces[i]->ptr))) {
+ if (ds->value->used) {
+ buffer_append_string_buffer(p->tmp_buf,ds->value);
+@@ -318,6 +330,7 @@
+ return HANDLER_GO_ON;
+ }
+
++int mod_evhost_plugin_init(plugin *p);
+ int mod_evhost_plugin_init(plugin *p) {
+ p->version = LIGHTTPD_VERSION_ID;
+ p->name = buffer_init_string("evhost");
+Index: src/splaytree.c
+===================================================================
+--- src/splaytree.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/splaytree.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -187,7 +187,8 @@
+ }
+ }
+
+-splay_tree *find_rank(int r, splay_tree *t) {
++#if 0
++static splay_tree *find_rank(int r, splay_tree *t) {
+ /* Returns a pointer to the node in the tree with the given rank. */
+ /* Returns NULL if there is no such node. */
+ /* Does not change the tree. To guarantee logarithmic behavior, */
+@@ -206,5 +207,4 @@
+ }
+ }
+ }
+-
+-
++#endif
+Index: src/lemon.c
+===================================================================
+--- src/lemon.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/lemon.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -31,6 +31,7 @@
+ extern void free();
+ extern int access();
+ extern int atoi();
++extern char *getenv();
+
+ #ifndef __WIN32__
+ # if defined(_WIN32) || defined(WIN32)
+@@ -39,7 +40,7 @@
+ #endif
+
+ /* #define PRIVATE static */
+-#define PRIVATE
++#define PRIVATE static
+
+ #ifdef TEST
+ #define MAXRHS 5 /* Set low to exercise exception code */
+@@ -50,6 +51,8 @@
+ char *msort();
+ extern void *malloc();
+
++extern void memory_error();
++
+ /******** From the file "action.h" *************************************/
+ struct action *Action_new();
+ struct action *Action_sort();
+@@ -291,7 +294,6 @@
+ };
+
+ #define MemoryCheck(X) if((X)==0){ \
+- extern void memory_error(); \
+ memory_error(); \
+ }
+
+@@ -445,14 +447,16 @@
+ #define acttab_yylookahead(X,N) ((X)->aAction[N].lookahead)
+
+ /* Free all memory associated with the given acttab */
+-void acttab_free(acttab *p){
++/*
++PRIVATE void acttab_free(acttab *p){
+ free( p->aAction );
+ free( p->aLookahead );
+ free( p );
+ }
++*/
+
+ /* Allocate a new acttab structure */
+-acttab *acttab_alloc(void){
++PRIVATE acttab *acttab_alloc(void){
+ acttab *p = malloc( sizeof(*p) );
+ if( p==0 ){
+ fprintf(stderr,"Unable to allocate memory for a new acttab.");
+@@ -464,7 +468,7 @@
+
+ /* Add a new action to the current transaction set
+ */
+-void acttab_action(acttab *p, int lookahead, int action){
++PRIVATE void acttab_action(acttab *p, int lookahead, int action){
+ if( p->nLookahead>=p->nLookaheadAlloc ){
+ p->nLookaheadAlloc += 25;
+ p->aLookahead = realloc( p->aLookahead,
+@@ -497,7 +501,7 @@
+ **
+ ** Return the offset into the action table of the new transaction.
+ */
+-int acttab_insert(acttab *p){
++PRIVATE int acttab_insert(acttab *p){
+ int i, j, k, n;
+ assert( p->nLookahead>0 );
+
+@@ -2603,7 +2607,7 @@
+ }
+ }
+
+-void ConfigPrint(fp,cfp)
++PRIVATE void ConfigPrint(fp,cfp)
+ FILE *fp;
+ struct config *cfp;
+ {
+@@ -2640,7 +2644,7 @@
+ }
+
+ /* Print a plink chain */
+-PRIVATE void PlinkPrint(out,plp,tag)
++void PlinkPrint(out,plp,tag)
+ FILE *out;
+ struct plink *plp;
+ char *tag;
+@@ -2657,7 +2661,7 @@
+ /* Print an action to the given file descriptor. Return FALSE if
+ ** nothing was actually printed.
+ */
+-int PrintAction(struct action *ap, FILE *fp, int indent){
++PRIVATE int PrintAction(struct action *ap, FILE *fp, int indent){
+ int result = 1;
+ switch( ap->type ){
+ case SHIFT:
+@@ -2731,6 +2735,7 @@
+ return;
+ }
+
++ extern int access();
+ /* Search for the file "name" which is in the same directory as
+ ** the exacutable */
+ PRIVATE char *pathsearch(argv0,name,modemask)
+@@ -2741,7 +2746,6 @@
+ char *pathlist;
+ char *path,*cp;
+ char c;
+- extern int access();
+
+ #ifdef __WIN32__
+ cp = strrchr(argv0,'\\');
+@@ -2755,7 +2759,6 @@
+ if( path ) sprintf(path,"%s/%s",argv0,name);
+ *cp = c;
+ }else{
+- extern char *getenv();
+ pathlist = getenv("PATH");
+ if( pathlist==0 ) pathlist = ".:/bin:/usr/bin";
+ path = (char *)malloc( strlen(pathlist)+strlen(name)+2 );
+@@ -2894,7 +2897,7 @@
+ ** The following routine emits code for the destructor for the
+ ** symbol sp
+ */
+-void emit_destructor_code(out,sp,lemp,lineno)
++PRIVATE void emit_destructor_code(out,sp,lemp,lineno)
+ FILE *out;
+ struct symbol *sp;
+ struct lemon *lemp;
+@@ -2932,7 +2935,7 @@
+ /*
+ ** Return TRUE (non-zero) if the given symbol has a destructor.
+ */
+-int has_destructor(sp, lemp)
++PRIVATE int has_destructor(sp, lemp)
+ struct symbol *sp;
+ struct lemon *lemp;
+ {
+@@ -3033,7 +3036,7 @@
+ ** union, also set the ".dtnum" field of every terminal and nonterminal
+ ** symbol.
+ */
+-void print_stack_union(out,lemp,plineno,mhflag)
++PRIVATE void print_stack_union(out,lemp,plineno,mhflag)
+ FILE *out; /* The output stream */
+ struct lemon *lemp; /* The main info structure for this parser */
+ int *plineno; /* Pointer to the line number */
+@@ -3684,7 +3687,6 @@
+ int i;
+ s = (char*)malloc( global_size );
+ if( s==0 ){
+- extern void memory_error();
+ memory_error();
+ }
+ for(i=0; i<global_size; i++) s[i] = 0;
+Index: src/chunk.h
+===================================================================
+--- src/chunk.h (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/chunk.h (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -3,6 +3,7 @@
+
+ #include "buffer.h"
+ #include "array.h"
++#include "sys-mmap.h"
+
+ typedef struct chunk {
+ enum { UNUSED_CHUNK, MEM_CHUNK, FILE_CHUNK } type;
+Index: src/etag.c
+===================================================================
+--- src/etag.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/etag.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -44,7 +44,7 @@
+ size_t i;
+ uint32_t h;
+
+- for (h=0, i=0; i < etag->used; ++i) h = (h<<5)^(h>>27)^(etag->ptr[i]);
++ for (h=0, i=0; i < etag->used-1; ++i) h = (h<<5)^(h>>27)^(etag->ptr[i]);
+
+ buffer_reset(mut);
+ buffer_copy_string_len(mut, CONST_STR_LEN("\""));
+Index: src/mod_scgi.c
+===================================================================
+--- src/mod_scgi.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/mod_scgi.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -38,6 +38,8 @@
+ #include <sys/wait.h>
+ #endif
+
++#include "version.h"
++
+ enum {EOL_UNSET, EOL_N, EOL_RN};
+
+ /*
+@@ -372,7 +374,7 @@
+ free(hctx);
+ }
+
+-scgi_proc *scgi_process_init() {
++static scgi_proc *scgi_process_init() {
+ scgi_proc *f;
+
+ f = calloc(1, sizeof(*f));
+@@ -384,7 +386,7 @@
+ return f;
+ }
+
+-void scgi_process_free(scgi_proc *f) {
++static void scgi_process_free(scgi_proc *f) {
+ if (!f) return;
+
+ scgi_process_free(f->next);
+@@ -394,7 +396,7 @@
+ free(f);
+ }
+
+-scgi_extension_host *scgi_host_init() {
++static scgi_extension_host *scgi_host_init() {
+ scgi_extension_host *f;
+
+ f = calloc(1, sizeof(*f));
+@@ -409,7 +411,7 @@
+ return f;
+ }
+
+-void scgi_host_free(scgi_extension_host *h) {
++static void scgi_host_free(scgi_extension_host *h) {
+ if (!h) return;
+
+ buffer_free(h->host);
+@@ -426,7 +428,7 @@
+
+ }
+
+-scgi_exts *scgi_extensions_init() {
++static scgi_exts *scgi_extensions_init() {
+ scgi_exts *f;
+
+ f = calloc(1, sizeof(*f));
+@@ -434,7 +436,7 @@
+ return f;
+ }
+
+-void scgi_extensions_free(scgi_exts *f) {
++static void scgi_extensions_free(scgi_exts *f) {
+ size_t i;
+
+ if (!f) return;
+@@ -464,7 +466,7 @@
+ free(f);
+ }
+
+-int scgi_extension_insert(scgi_exts *ext, buffer *key, scgi_extension_host *fh) {
++static int scgi_extension_insert(scgi_exts *ext, buffer *key, scgi_extension_host *fh) {
+ scgi_extension *fe;
+ size_t i;
+
+@@ -1178,7 +1180,7 @@
+ }
+
+
+-void scgi_connection_cleanup(server *srv, handler_ctx *hctx) {
++static void scgi_connection_cleanup(server *srv, handler_ctx *hctx) {
+ plugin_data *p;
+ connection *con;
+
+@@ -1281,10 +1283,11 @@
+
+ buffer_prepare_append(env, len);
+
+- /* include the NUL */
+- memcpy(env->ptr + env->used, key, key_len + 1);
++ memcpy(env->ptr + env->used, key, key_len);
++ env->ptr[env->used + key_len] = '\0';
+ env->used += key_len + 1;
+- memcpy(env->ptr + env->used, val, val_len + 1);
++ memcpy(env->ptr + env->used, val, val_len);
++ env->ptr[env->used + val_len] = '\0';
+ env->used += val_len + 1;
+
+ return 0;
+@@ -1461,10 +1464,18 @@
+ scgi_env_add(p->scgi_env, CONST_STR_LEN("SCGI"), CONST_STR_LEN("1"));
+
+
+- scgi_env_add(p->scgi_env, CONST_STR_LEN("SERVER_SOFTWARE"), CONST_STR_LEN(PACKAGE_NAME"/"PACKAGE_VERSION));
++ if (buffer_is_empty(con->conf.server_tag)) {
++ scgi_env_add(p->scgi_env, CONST_STR_LEN("SERVER_SOFTWARE"), CONST_STR_LEN(PACKAGE_DESC));
++ } else {
++ scgi_env_add(p->scgi_env, CONST_STR_LEN("SERVER_SOFTWARE"), CONST_BUF_LEN(con->conf.server_tag));
++ }
+
+ if (con->server_name->used) {
+- scgi_env_add(p->scgi_env, CONST_STR_LEN("SERVER_NAME"), CONST_BUF_LEN(con->server_name));
++ size_t len = con->server_name->used - 1;
++ char *colon = strchr(con->server_name->ptr, ':');
++ if (colon) len = colon - con->server_name->ptr;
++
++ scgi_env_add(p->scgi_env, CONST_STR_LEN("SERVER_NAME"), con->server_name->ptr, len);
+ } else {
+ #ifdef HAVE_IPV6
+ s = inet_ntop(srv_sock->addr.plain.sa_family,
+@@ -1915,7 +1926,7 @@
+ }
+
+
+-int scgi_proclist_sort_up(server *srv, scgi_extension_host *host, scgi_proc *proc) {
++static int scgi_proclist_sort_up(server *srv, scgi_extension_host *host, scgi_proc *proc) {
+ scgi_proc *p;
+
+ UNUSED(srv);
+@@ -2827,7 +2838,11 @@
+ */
+
+ /* the rewrite is only done for /prefix/? matches */
+- if (extension->key->ptr[0] == '/' &&
++ if (host->fix_root_path_name && extension->key->ptr[0] == '/' && extension->key->ptr[1] == '\0') {
++ buffer_copy_string(con->request.pathinfo, con->uri.path->ptr);
++ con->uri.path->used = 1;
++ con->uri.path->ptr[con->uri.path->used - 1] = '\0';
++ } else if (extension->key->ptr[0] == '/' &&
+ con->uri.path->used > extension->key->used &&
+ NULL != (pathinfo = strchr(con->uri.path->ptr + extension->key->used - 1, '/'))) {
+ /* rewrite uri.path and pathinfo */
+@@ -2836,10 +2851,6 @@
+
+ con->uri.path->used -= con->request.pathinfo->used - 1;
+ con->uri.path->ptr[con->uri.path->used - 1] = '\0';
+- } else if (host->fix_root_path_name && extension->key->ptr[0] == '/' && extension->key->ptr[1] == '\0') {
+- buffer_copy_string(con->request.pathinfo, con->uri.path->ptr);
+- con->uri.path->used = 1;
+- con->uri.path->ptr[con->uri.path->used - 1] = '\0';
+ }
+ }
+ } else {
+@@ -3105,6 +3116,7 @@
+ }
+
+
++int mod_scgi_plugin_init(plugin *p);
+ int mod_scgi_plugin_init(plugin *p) {
+ p->version = LIGHTTPD_VERSION_ID;
+ p->name = buffer_init_string("scgi");
+Index: src/mod_mysql_vhost.c
+===================================================================
+--- src/mod_mysql_vhost.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/mod_mysql_vhost.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -422,6 +422,7 @@
+ }
+
+ /* 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");
+@@ -437,6 +438,7 @@
+ }
+ #else
+ /* we don't have mysql support, this plugin does nothing */
++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");
+Index: src/request.c
+===================================================================
+--- src/request.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/request.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -86,10 +86,18 @@
+ if (host_len == 0) return -1;
+
+ /* if the hostname ends in a "." strip it */
+- if (host->ptr[host_len-1] == '.') host_len -= 1;
++ if (host->ptr[host_len-1] == '.') {
++ /* shift port info one left */
++ if (NULL != colon) memmove(colon-1, colon, host->used - host_len);
++ else host->ptr[host_len-1] = '\0';
++ host_len -= 1;
++ host->used -= 1;
++ }
+
++ if (host_len == 0) return -1;
++
+ /* scan from the right and skip the \0 */
+- for (i = host_len - 1; i + 1 > 0; i--) {
++ for (i = host_len; i-- > 0; ) {
+ const char c = host->ptr[i];
+
+ switch (stage) {
+@@ -200,7 +208,7 @@
+ #define DUMP_HEADER
+ #endif
+
+-int http_request_split_value(array *vals, buffer *b) {
++static int http_request_split_value(array *vals, buffer *b) {
+ char *s;
+ size_t i;
+ int state = 0;
+@@ -262,7 +270,7 @@
+ return 0;
+ }
+
+-int request_uri_is_valid_char(unsigned char c) {
++static int request_uri_is_valid_char(unsigned char c) {
+ if (c <= 32) return 0;
+ if (c == 127) return 0;
+ if (c == 255) return 0;
+Index: src/mod_magnet_cache.c
+===================================================================
+--- src/mod_magnet_cache.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/mod_magnet_cache.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -9,7 +9,7 @@
+ #include <lualib.h>
+ #include <lauxlib.h>
+
+-script *script_init() {
++static script *script_init() {
+ script *sc;
+
+ sc = calloc(1, sizeof(*sc));
+@@ -19,7 +19,7 @@
+ return sc;
+ }
+
+-void script_free(script *sc) {
++static void script_free(script *sc) {
+ if (!sc) return;
+
+ lua_pop(sc->L, 1); /* the function copy */
+Index: src/mod_flv_streaming.c
+===================================================================
+--- src/mod_flv_streaming.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/mod_flv_streaming.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -265,6 +265,7 @@
+
+ /* this function is called at dlopen() time and inits the callbacks */
+
++int mod_flv_streaming_plugin_init(plugin *p);
+ int mod_flv_streaming_plugin_init(plugin *p) {
+ p->version = LIGHTTPD_VERSION_ID;
+ p->name = buffer_init_string("flv_streaming");
+Index: src/mod_rrdtool.c
+===================================================================
+--- src/mod_rrdtool.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/mod_rrdtool.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -91,7 +91,7 @@
+ return HANDLER_GO_ON;
+ }
+
+-int mod_rrd_create_pipe(server *srv, plugin_data *p) {
++static int mod_rrd_create_pipe(server *srv, plugin_data *p) {
+ #ifdef HAVE_FORK
+ pid_t pid;
+
+@@ -230,6 +230,7 @@
+
+ static int mod_rrdtool_create_rrd(server *srv, plugin_data *p, plugin_config *s) {
+ struct stat st;
++ int r;
+
+ /* check if DB already exists */
+ if (0 == stat(s->path_rrd->ptr, &st)) {
+@@ -239,54 +240,57 @@
+ "not a regular file:", s->path_rrd);
+ return HANDLER_ERROR;
+ }
+- } else {
+- int r ;
+- /* create a new one */
++ }
+
+- buffer_copy_string_len(p->cmd, CONST_STR_LEN("create "));
+- buffer_append_string_buffer(p->cmd, s->path_rrd);
+- buffer_append_string_len(p->cmd, CONST_STR_LEN(
+- " --step 60 "
+- "DS:InOctets:ABSOLUTE:600:U:U "
+- "DS:OutOctets:ABSOLUTE:600:U:U "
+- "DS:Requests:ABSOLUTE:600:U:U "
+- "RRA:AVERAGE:0.5:1:600 "
+- "RRA:AVERAGE:0.5:6:700 "
+- "RRA:AVERAGE:0.5:24:775 "
+- "RRA:AVERAGE:0.5:288:797 "
+- "RRA:MAX:0.5:1:600 "
+- "RRA:MAX:0.5:6:700 "
+- "RRA:MAX:0.5:24:775 "
+- "RRA:MAX:0.5:288:797 "
+- "RRA:MIN:0.5:1:600 "
+- "RRA:MIN:0.5:6:700 "
+- "RRA:MIN:0.5:24:775 "
+- "RRA:MIN:0.5:288:797\n"));
++ /* still create DB if it's empty file */
++ if (st.st_size > 0) {
++ return HANDLER_GO_ON;
++ }
+
+- if (-1 == (r = safe_write(p->write_fd, p->cmd->ptr, p->cmd->used - 1))) {
+- log_error_write(srv, __FILE__, __LINE__, "ss",
+- "rrdtool-write: failed", strerror(errno));
++ /* create a new one */
++ buffer_copy_string_len(p->cmd, CONST_STR_LEN("create "));
++ buffer_append_string_buffer(p->cmd, s->path_rrd);
++ buffer_append_string_len(p->cmd, CONST_STR_LEN(
++ " --step 60 "
++ "DS:InOctets:ABSOLUTE:600:U:U "
++ "DS:OutOctets:ABSOLUTE:600:U:U "
++ "DS:Requests:ABSOLUTE:600:U:U "
++ "RRA:AVERAGE:0.5:1:600 "
++ "RRA:AVERAGE:0.5:6:700 "
++ "RRA:AVERAGE:0.5:24:775 "
++ "RRA:AVERAGE:0.5:288:797 "
++ "RRA:MAX:0.5:1:600 "
++ "RRA:MAX:0.5:6:700 "
++ "RRA:MAX:0.5:24:775 "
++ "RRA:MAX:0.5:288:797 "
++ "RRA:MIN:0.5:1:600 "
++ "RRA:MIN:0.5:6:700 "
++ "RRA:MIN:0.5:24:775 "
++ "RRA:MIN:0.5:288:797\n"));
+
+- return HANDLER_ERROR;
+- }
++ if (-1 == (r = safe_write(p->write_fd, p->cmd->ptr, p->cmd->used - 1))) {
++ log_error_write(srv, __FILE__, __LINE__, "ss",
++ "rrdtool-write: failed", strerror(errno));
+
+- buffer_prepare_copy(p->resp, 4096);
+- if (-1 == (r = safe_read(p->read_fd, p->resp->ptr, p->resp->size))) {
+- log_error_write(srv, __FILE__, __LINE__, "ss",
+- "rrdtool-read: failed", strerror(errno));
++ return HANDLER_ERROR;
++ }
+
+- return HANDLER_ERROR;
+- }
++ buffer_prepare_copy(p->resp, 4096);
++ if (-1 == (r = safe_read(p->read_fd, p->resp->ptr, p->resp->size))) {
++ log_error_write(srv, __FILE__, __LINE__, "ss",
++ "rrdtool-read: failed", strerror(errno));
+
+- p->resp->used = r;
++ return HANDLER_ERROR;
++ }
+
+- if (p->resp->ptr[0] != 'O' ||
+- p->resp->ptr[1] != 'K') {
+- log_error_write(srv, __FILE__, __LINE__, "sbb",
+- "rrdtool-response:", p->cmd, p->resp);
++ p->resp->used = r;
+
+- return HANDLER_ERROR;
+- }
++ if (p->resp->ptr[0] != 'O' ||
++ p->resp->ptr[1] != 'K') {
++ log_error_write(srv, __FILE__, __LINE__, "sbb",
++ "rrdtool-response:", p->cmd, p->resp);
++
++ return HANDLER_ERROR;
+ }
+
+ return HANDLER_GO_ON;
+@@ -477,6 +481,7 @@
+ return HANDLER_GO_ON;
+ }
+
++int mod_rrdtool_plugin_init(plugin *p);
+ int mod_rrdtool_plugin_init(plugin *p) {
+ p->version = LIGHTTPD_VERSION_ID;
+ p->name = buffer_init_string("rrd");
+Index: src/stat_cache.c
+===================================================================
+--- src/stat_cache.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/stat_cache.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -595,29 +595,31 @@
+ if (S_ISREG(st.st_mode)) {
+ /* determine mimetype */
+ buffer_reset(sce->content_type);
++#ifdef HAVE_XATTR
++ if (con->conf.use_xattr) {
++ stat_cache_attr_get(sce->content_type, name->ptr);
++ }
++#endif
++ /* xattr did not set a content-type. ask the config */
++ if (buffer_is_empty(sce->content_type)) {
++ for (k = 0; k < con->conf.mimetypes->used; k++) {
++ data_string *ds = (data_string *)con->conf.mimetypes->data[k];
++ buffer *type = ds->key;
+
+- for (k = 0; k < con->conf.mimetypes->used; k++) {
+- data_string *ds = (data_string *)con->conf.mimetypes->data[k];
+- buffer *type = ds->key;
++ if (type->used == 0) continue;
+
+- if (type->used == 0) continue;
++ /* check if the right side is the same */
++ if (type->used > name->used) continue;
+
+- /* check if the right side is the same */
+- if (type->used > name->used) continue;
+-
+- if (0 == strncasecmp(name->ptr + name->used - type->used, type->ptr, type->used - 1)) {
+- buffer_copy_string_buffer(sce->content_type, ds->value);
+- break;
++ if (0 == strncasecmp(name->ptr + name->used - type->used, type->ptr, type->used - 1)) {
++ buffer_copy_string_buffer(sce->content_type, ds->value);
++ break;
++ }
+ }
+ }
+- etag_create(sce->etag, &(sce->st), con->etag_flags);
+-#ifdef HAVE_XATTR
+- if (con->conf.use_xattr && buffer_is_empty(sce->content_type)) {
+- stat_cache_attr_get(sce->content_type, name->ptr);
+- }
+-#endif
++ etag_create(sce->etag, &(sce->st), con->etag_flags);
+ } else if (S_ISDIR(st.st_mode)) {
+- etag_create(sce->etag, &(sce->st), con->etag_flags);
++ etag_create(sce->etag, &(sce->st), con->etag_flags);
+ }
+
+ #ifdef HAVE_FAM_H
+Index: src/response.c
+===================================================================
+--- src/response.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/response.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -25,6 +25,7 @@
+ #include "plugin.h"
+
+ #include "sys-socket.h"
++#include "version.h"
+
+ int http_response_write_header(server *srv, connection *con) {
+ buffer *b;
+@@ -104,7 +105,7 @@
+
+ if (!have_server) {
+ if (buffer_is_empty(con->conf.server_tag)) {
+- buffer_append_string_len(b, CONST_STR_LEN("\r\nServer: " PACKAGE_NAME "/" PACKAGE_VERSION));
++ buffer_append_string_len(b, CONST_STR_LEN("\r\nServer: " PACKAGE_DESC));
+ } else if (con->conf.server_tag->used > 1) {
+ buffer_append_string_len(b, CONST_STR_LEN("\r\nServer: "));
+ buffer_append_string_encoded(b, CONST_BUF_LEN(con->conf.server_tag), ENCODING_HTTP_HEADER);
+Index: src/SConscript
+===================================================================
+--- src/SConscript (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/SConscript (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -70,7 +70,7 @@
+ 'mod_cml' : {
+ 'src' : [ 'mod_cml_lua.c', 'mod_cml.c', 'mod_cml_funcs.c' ],
+ 'lib' : [ env['LIBPCRE'], env['LIBMEMCACHE'], env['LIBLUA'], env['LIBLUALIB'] ] },
+- 'mod_uploadprogress' : { 'src' : [ 'mod_uploadprogress.c' ] },
++# 'mod_uploadprogress' : { 'src' : [ 'mod_uploadprogress.c' ] },
+ 'mod_evasive' : { 'src' : [ 'mod_evasive.c' ] },
+ 'mod_ssi' : { 'src' : [ 'mod_ssi_exprparser.c', 'mod_ssi_expr.c', 'mod_ssi.c' ], 'lib' : [ env['LIBPCRE'] ] },
+ 'mod_flv_streaming' : { 'src' : [ 'mod_flv_streaming.c' ] },
+@@ -153,8 +153,6 @@
+ instbin = env.Program(bin_targets, src, LINKFLAGS = bin_linkflags, LIBS= [ env['LIBS'], common_lib, env['LIBDL'] ])
+ env.Depends(instbin, configparser)
+
+-spawn_fcgi = env.Program("spawn-fcgi", "spawn-fcgi.c")
+-
+ if env['COMMON_LIB'] == 'bin':
+ common_lib = instbin[1]
+
+@@ -168,9 +166,6 @@
+
+ inst = []
+
+-Default(spawn_fcgi)
+-inst += env.Install('${bindir}', spawn_fcgi)
+-
+ if env['build_dynamic']:
+ Default(instbin[0], instlib)
+ inst += env.Install('${sbindir}', instbin[0])
+Index: src/mod_cml_funcs.c
+===================================================================
+--- src/mod_cml_funcs.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/mod_cml_funcs.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -93,7 +93,7 @@
+ return 1;
+ }
+
+-int f_dir_files_iter(lua_State *L) {
++static int f_dir_files_iter(lua_State *L) {
+ DIR *d;
+ struct dirent *de;
+
+@@ -211,7 +211,7 @@
+ }
+
+ if (NULL == (r = mc_aget(mc,
+- lua_tostring(L, 1), lua_strlen(L, 1)))) {
++ (char*) lua_tostring(L, 1), lua_strlen(L, 1)))) {
+
+ lua_pushboolean(L, 0);
+ return 1;
+@@ -248,7 +248,7 @@
+ }
+
+ if (NULL == (r = mc_aget(mc,
+- lua_tostring(L, 1), lua_strlen(L, 1)))) {
++ (char*) lua_tostring(L, 1), lua_strlen(L, 1)))) {
+ lua_pushnil(L);
+ return 1;
+ }
+@@ -285,7 +285,7 @@
+ }
+
+ if (NULL == (r = mc_aget(mc,
+- lua_tostring(L, 1), lua_strlen(L, 1)))) {
++ (char*) lua_tostring(L, 1), lua_strlen(L, 1)))) {
+ lua_pushnil(L);
+ return 1;
+ }
+Index: src/mod_simple_vhost.c
+===================================================================
+--- src/mod_simple_vhost.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/mod_simple_vhost.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -270,6 +270,7 @@
+ }
+
+
++int mod_simple_vhost_plugin_init(plugin *p);
+ int mod_simple_vhost_plugin_init(plugin *p) {
+ p->version = LIGHTTPD_VERSION_ID;
+ p->name = buffer_init_string("simple_vhost");
+Index: src/mod_userdir.c
+===================================================================
+--- src/mod_userdir.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/mod_userdir.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -314,6 +314,7 @@
+
+ /* this function is called at dlopen() time and inits the callbacks */
+
++int mod_userdir_plugin_init(plugin *p);
+ int mod_userdir_plugin_init(plugin *p) {
+ p->version = LIGHTTPD_VERSION_ID;
+ p->name = buffer_init_string("userdir");
+Index: src/mod_proxy.c
+===================================================================
+--- src/mod_proxy.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/mod_proxy.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -332,7 +332,7 @@
+ return HANDLER_GO_ON;
+ }
+
+-void proxy_connection_close(server *srv, handler_ctx *hctx) {
++static void proxy_connection_close(server *srv, handler_ctx *hctx) {
+ plugin_data *p;
+ connection *con;
+
+@@ -356,20 +356,35 @@
+ static int proxy_establish_connection(server *srv, handler_ctx *hctx) {
+ struct sockaddr *proxy_addr;
+ struct sockaddr_in proxy_addr_in;
++#if defined(HAVE_IPV6) && defined(HAVE_INET_PTON)
++ struct sockaddr_in6 proxy_addr_in6;
++#endif
+ socklen_t servlen;
+
+ plugin_data *p = hctx->plugin_data;
+ data_proxy *host= hctx->host;
+ int proxy_fd = hctx->fd;
+
+- memset(&proxy_addr, 0, sizeof(proxy_addr));
+
+- proxy_addr_in.sin_family = AF_INET;
+- proxy_addr_in.sin_addr.s_addr = inet_addr(host->host->ptr);
+- proxy_addr_in.sin_port = htons(host->port);
+- servlen = sizeof(proxy_addr_in);
++#if defined(HAVE_IPV6) && defined(HAVE_INET_PTON)
++ if (strstr(host->host->ptr, ":")) {
++ memset(&proxy_addr_in6, 0, sizeof(proxy_addr_in6));
++ proxy_addr_in6.sin6_family = AF_INET6;
++ inet_pton(AF_INET6, host->host->ptr, (char *) &proxy_addr_in6.sin6_addr);
++ proxy_addr_in6.sin6_port = htons(host->port);
++ servlen = sizeof(proxy_addr_in6);
++ proxy_addr = (struct sockaddr *) &proxy_addr_in6;
++ } else
++#endif
++ {
++ memset(&proxy_addr_in, 0, sizeof(proxy_addr_in));
++ proxy_addr_in.sin_family = AF_INET;
++ proxy_addr_in.sin_addr.s_addr = inet_addr(host->host->ptr);
++ proxy_addr_in.sin_port = htons(host->port);
++ servlen = sizeof(proxy_addr_in);
++ proxy_addr = (struct sockaddr *) &proxy_addr_in;
++ }
+
+- proxy_addr = (struct sockaddr *) &proxy_addr_in;
+
+ if (-1 == connect(proxy_fd, proxy_addr, servlen)) {
+ if (errno == EINPROGRESS || errno == EALREADY) {
+@@ -395,7 +410,7 @@
+ return 0;
+ }
+
+-void proxy_set_header(connection *con, const char *key, const char *value) {
++static void proxy_set_header(connection *con, const char *key, const char *value) {
+ data_string *ds_dst;
+
+ if (NULL == (ds_dst = (data_string *)array_get_unused_element(con->request.headers, TYPE_STRING))) {
+@@ -407,7 +422,7 @@
+ array_insert_unique(con->request.headers, (data_unset *)ds_dst);
+ }
+
+-void proxy_append_header(connection *con, const char *key, const char *value) {
++static void proxy_append_header(connection *con, const char *key, const char *value) {
+ data_string *ds_dst;
+
+ if (NULL == (ds_dst = (data_string *)array_get_unused_element(con->request.headers, TYPE_STRING))) {
+@@ -741,9 +756,16 @@
+
+ switch(hctx->state) {
+ case PROXY_STATE_INIT:
+- if (-1 == (hctx->fd = socket(AF_INET, SOCK_STREAM, 0))) {
++ 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 {
++ if (-1 == (hctx->fd = socket(AF_INET, SOCK_STREAM, 0))) {
++ log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed: ", strerror(errno));
++ return HANDLER_ERROR;
++ }
+ }
+ hctx->fde_ndx = -1;
+
+@@ -1209,7 +1231,7 @@
+
+ if (ndx >= (int) extension->value->used) {
+ /* didn't found a higher id, wrap to the start */
+- for (ndx = 0; ndx < (int) k; ndx++) {
++ for (ndx = 0; ndx <= (int) k; ndx++) {
+ host = (data_proxy *)extension->value->data[ndx];
+ if (!host->is_disabled) break;
+ }
+@@ -1321,6 +1343,7 @@
+ }
+
+
++int mod_proxy_plugin_init(plugin *p);
+ int mod_proxy_plugin_init(plugin *p) {
+ p->version = LIGHTTPD_VERSION_ID;
+ p->name = buffer_init_string("proxy");
+Index: src/mod_extforward.c
+===================================================================
+--- src/mod_extforward.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/mod_extforward.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -80,6 +80,7 @@
+
+ typedef struct {
+ array *forwarder;
++ array *headers;
+ } plugin_config;
+
+ typedef struct {
+@@ -135,6 +136,7 @@
+ if (!s) continue;
+
+ array_free(s->forwarder);
++ array_free(s->headers);
+
+ free(s);
+ }
+@@ -154,7 +156,8 @@
+ size_t i = 0;
+
+ config_values_t cv[] = {
+- { "extforward.forwarder", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
++ { "extforward.forwarder", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
++ { "extforward.headers", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
+ { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
+ };
+
+@@ -167,8 +170,10 @@
+
+ s = calloc(1, sizeof(plugin_config));
+ s->forwarder = array_init();
++ s->headers = array_init();
+
+ cv[0].destination = s->forwarder;
++ cv[1].destination = s->headers;
+
+ p->config_storage[i] = s;
+
+@@ -187,6 +192,7 @@
+ plugin_config *s = p->config_storage[0];
+
+ PATCH(forwarder);
++ PATCH(headers);
+
+ /* skip the first, the global context */
+ for (i = 1; i < srv->config_context->used; i++) {
+@@ -202,6 +208,8 @@
+
+ if (buffer_is_equal_string(du->key, CONST_STR_LEN("extforward.forwarder"))) {
+ PATCH(forwarder);
++ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("extforward.headers"))) {
++ PATCH(headers);
+ }
+ }
+ }
+@@ -294,37 +302,37 @@
+ return NULL;
+ }
+
+-struct addrinfo *ipstr_to_sockaddr(const char *host)
+-{
+- struct addrinfo hints, *res0;
+- int result;
++static struct addrinfo *ipstr_to_sockaddr(const char *host) {
++ struct addrinfo hints, *res0;
++ int result;
+
+- memset(&hints, 0, sizeof(hints));
++ memset(&hints, 0, sizeof(hints));
+ #ifndef AI_NUMERICSERV
+-/**
+- * quoting $ man getaddrinfo
+- *
+- * NOTES
+- * AI_ADDRCONFIG, AI_ALL, and AI_V4MAPPED are available since glibc 2.3.3.
+- * AI_NUMERICSERV is available since glibc 2.3.4.
+- */
++ /**
++ * quoting $ man getaddrinfo
++ *
++ * NOTES
++ * AI_ADDRCONFIG, AI_ALL, and AI_V4MAPPED are available since glibc 2.3.3.
++ * AI_NUMERICSERV is available since glibc 2.3.4.
++ */
+ #define AI_NUMERICSERV 0
+ #endif
+- hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
++ 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);
++ result = getaddrinfo(host, NULL, &hints, &res0);
+
+- return 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;
+ }
+
+
+@@ -351,16 +359,26 @@
+ mod_extforward_patch_connection(srv, con, p);
+
+ if (con->conf.log_request_handling) {
+- log_error_write(srv, __FILE__, __LINE__, "s",
+- "-- mod_extforward_uri_handler called");
++ log_error_write(srv, __FILE__, __LINE__, "s",
++ "-- mod_extforward_uri_handler called");
+ }
+
+- if ((NULL == (forwarded = (data_string *) array_get_element(con->request.headers,"X-Forwarded-For")) &&
+- NULL == (forwarded = (data_string *) array_get_element(con->request.headers, "Forwarded-For")))) {
++ if (p->conf.headers->used) {
++ data_string *ds;
++ size_t k;
+
++ for(k = 0; k < p->conf.headers->used; k++) {
++ ds = (data_string *) p->conf.headers->data[k];
++ if (NULL != (forwarded = (data_string*) array_get_element(con->request.headers, ds->value->ptr))) break;
++ }
++ } else {
++ forwarded = (data_string *) array_get_element(con->request.headers,"X-Forwarded-For");
++ if (NULL == forwarded) forwarded = (data_string *) array_get_element(con->request.headers, "Forwarded-For");
++ }
++
++ if (NULL == forwarded) {
+ if (con->conf.log_request_handling) {
+- log_error_write(srv, __FILE__, __LINE__, "s",
+- "no X-Forwarded-For|Forwarded-For: found, skipping");
++ log_error_write(srv, __FILE__, __LINE__, "s", "no forward header found, skipping");
+ }
+
+ return HANDLER_GO_ON;
+@@ -368,11 +386,10 @@
+
+ #ifdef HAVE_IPV6
+ dst_addr_str = inet_ntop(con->dst_addr.plain.sa_family,
+- con->dst_addr.plain.sa_family == AF_INET6 ?
+- (struct sockaddr *)&(con->dst_addr.ipv6.sin6_addr) :
+- (struct sockaddr *)&(con->dst_addr.ipv4.sin_addr),
+- b2,
+- (sizeof b2) - 1);
++ con->dst_addr.plain.sa_family == AF_INET6 ?
++ (struct sockaddr *)&(con->dst_addr.ipv6.sin6_addr) :
++ (struct sockaddr *)&(con->dst_addr.ipv4.sin_addr),
++ b2, (sizeof b2) - 1);
+ #else
+ dst_addr_str = inet_ntoa(con->dst_addr.ipv4.sin_addr);
+ #endif
+@@ -420,6 +437,7 @@
+ }
+ }
+ #else
++ UNUSED(addrs_left);
+ sock.ipv4.sin_addr.s_addr = inet_addr(real_remote_addr);
+ sock.plain.sa_family = (sock.ipv4.sin_addr.s_addr == 0xFFFFFFFF) ? AF_UNSPEC : AF_INET;
+ #endif
+@@ -439,7 +457,7 @@
+ buffer_copy_string(con->dst_addr_buf, real_remote_addr);
+
+ if (con->conf.log_request_handling) {
+- log_error_write(srv, __FILE__, __LINE__, "ss",
++ log_error_write(srv, __FILE__, __LINE__, "ss",
+ "patching con->dst_addr_buf for the accesslog:", real_remote_addr);
+ }
+ /* Now, clean the conf_cond cache, because we may have changed the results of tests */
+@@ -479,6 +497,7 @@
+
+ /* this function is called at dlopen() time and inits the callbacks */
+
++int mod_extforward_plugin_init(plugin *p);
+ int mod_extforward_plugin_init(plugin *p) {
+ p->version = LIGHTTPD_VERSION_ID;
+ p->name = buffer_init_string("extforward");
+Index: src/Makefile.am
+===================================================================
+--- src/Makefile.am (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/Makefile.am (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -2,21 +2,37 @@
+
+ noinst_PROGRAMS=proc_open lemon # simple-fcgi #graphic evalo bench ajp ssl error_test adserver gen-license
+ sbin_PROGRAMS=lighttpd lighttpd-angel
+-bin_PROGRAMS=spawn-fcgi
+ LEMON=$(top_builddir)/src/lemon$(EXEEXT)
+
+ lemon_SOURCES=lemon.c
+
+ lighttpd_angel_SOURCES=lighttpd-angel.c
+
+-#simple_fcgi_SOURCES=simple-fcgi.c
+-#simple_fcgi_LDADD=-lfcgi
++.PHONY: versionstamp parsers
+
++all: versionstamp
++
++versionstamp:
++ @test -f versionstamp.h || touch versionstamp.h; \
++ REVISION="$$(LANG=C svnversion "$(top_srcdir)" 2>/dev/null || echo exported)"; \
++ if test $$REVISION = "exported"; then \
++ REVISION="$$(LANG=C cd "$(top_srcdir)"; git describe --always 2>/dev/null)"; \
++ fi; \
++ if test -n "$$REVISION"; then \
++ echo "#define REPO_VERSION \"-devel-$$REVISION\"" > versionstamp.h.tmp; \
++ else \
++ echo "#define REPO_VERSION \"\"" > versionstamp.h.tmp; \
++ fi; \
++ if ! diff versionstamp.h.tmp versionstamp.h >/dev/null 2>/dev/null; then \
++ mv versionstamp.h.tmp versionstamp.h; \
++ else \
++ rm versionstamp.h.tmp; \
++ fi
++
+ if CROSS_COMPILING
+ configparser.c configparser.h:
+ mod_ssi_exprparser.c mod_ssi_exprparser.h:
+
+-.PHONY: parsers
+ parsers:
+ else
+ configparser.h: configparser.c
+@@ -29,12 +45,12 @@
+ rm -f mod_ssi_exprparser.h
+ $(LEMON) -q $(srcdir)/mod_ssi_exprparser.y $(srcdir)/lempar.c
+
+-.PHONY: parsers
+ parsers: configparser.c mod_ssi_exprparser.c
+ endif
+
+ BUILT_SOURCES = parsers
+ MAINTAINERCLEANFILES = configparser.c configparser.h mod_ssi_exprparser.c mod_ssi_exprparser.h
++CLEANFILES = versionstamp.h versionstamp.h.tmp
+
+ common_src=buffer.c log.c \
+ keyvalue.c chunk.c \
+@@ -58,8 +74,6 @@
+ src = server.c response.c connections.c network.c \
+ configfile.c configparser.c request.c proc_open.c
+
+-spawn_fcgi_SOURCES=spawn-fcgi.c
+-
+ lib_LTLIBRARIES =
+
+ if NO_RDYNAMIC
+@@ -259,9 +273,10 @@
+ configparser.h mod_ssi_exprparser.h \
+ sys-mmap.h sys-socket.h mod_cml.h mod_cml_funcs.h \
+ splaytree.h proc_open.h status_counter.h \
+- mod_magnet_cache.h
++ mod_magnet_cache.h \
++ version.h
+
+-DEFS= @DEFS@ -DLIBRARY_DIR="\"$(libdir)\"" -DSBIN_DIR="\"$(sbindir)\""
++DEFS= @DEFS@ -DHAVE_VERSION_H -DLIBRARY_DIR="\"$(libdir)\"" -DSBIN_DIR="\"$(sbindir)\""
+
+ lighttpd_SOURCES = $(src)
+ lighttpd_LDADD = $(PCRE_LIB) $(DL_LIB) $(SENDFILE_LIB) $(ATTR_LIB) $(common_libadd) $(SSL_LIB) $(FAM_LIBS)
+@@ -287,3 +302,4 @@
+
+ noinst_HEADERS = $(hdr)
+ EXTRA_DIST = mod_skeleton.c configparser.y mod_ssi_exprparser.y lempar.c SConscript
++
+Index: src/config.h.cmake
+===================================================================
+Index: src/mod_expire.c
+===================================================================
+--- src/mod_expire.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/mod_expire.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -75,10 +75,10 @@
+ return HANDLER_GO_ON;
+ }
+
+-static int mod_expire_get_offset(server *srv, plugin_data *p, buffer *expire, int *offset) {
++static int mod_expire_get_offset(server *srv, plugin_data *p, buffer *expire, time_t *offset) {
+ char *ts;
+ int type = -1;
+- int retts = 0;
++ time_t retts = 0;
+
+ UNUSED(p);
+
+@@ -302,8 +302,7 @@
+ if (ds->key->used == 0) continue;
+
+ if (0 == strncmp(con->uri.path->ptr, ds->key->ptr, ct_len)) {
+- int ts;
+- time_t t;
++ time_t ts, expires;
+ size_t len;
+ stat_cache_entry *sce = NULL;
+
+@@ -312,25 +311,26 @@
+ switch(mod_expire_get_offset(srv, p, ds->value, &ts)) {
+ case 0:
+ /* access */
+- t = (ts + srv->cur_ts);
++ expires = (ts + srv->cur_ts);
+ break;
+ case 1:
+ /* modification */
+
+- t = (ts + sce->st.st_mtime);
++ expires = (ts + sce->st.st_mtime);
+ break;
+ default:
+ /* -1 is handled at parse-time */
+ break;
+ }
+
++ /* expires should be at least srv->cur_ts */
++ if (expires < srv->cur_ts) expires = srv->cur_ts;
+
+ if (0 == (len = strftime(p->expire_tstmp->ptr, p->expire_tstmp->size - 1,
+- "%a, %d %b %Y %H:%M:%S GMT", gmtime(&(t))))) {
++ "%a, %d %b %Y %H:%M:%S GMT", gmtime(&(expires))))) {
+ /* could not set expire header, out of mem */
+
+ return HANDLER_GO_ON;
+-
+ }
+
+ p->expire_tstmp->used = len + 1;
+@@ -340,7 +340,7 @@
+
+ /* HTTP/1.1 */
+ buffer_copy_string_len(p->expire_tstmp, CONST_STR_LEN("max-age="));
+- buffer_append_long(p->expire_tstmp, ts);
++ 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));
+
+@@ -354,6 +354,7 @@
+
+ /* this function is called at dlopen() time and inits the callbacks */
+
++int mod_expire_plugin_init(plugin *p);
+ int mod_expire_plugin_init(plugin *p) {
+ p->version = LIGHTTPD_VERSION_ID;
+ p->name = buffer_init_string("expire");
+Index: src/http_auth.c
+===================================================================
+--- src/http_auth.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/http_auth.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -865,7 +865,11 @@
+ buffer_free(username);
+ buffer_free(password);
+
+- log_error_write(srv, __FILE__, __LINE__, "s", "get_password failed");
++ if (AUTH_BACKEND_UNSET == p->conf.auth_backend) {
++ log_error_write(srv, __FILE__, __LINE__, "s", "auth.backend is not set");
++ } else {
++ log_error_write(srv, __FILE__, __LINE__, "s", "get_password failed");
++ }
+
+ return 0;
+ }
+Index: src/mod_redirect.c
+===================================================================
+--- src/mod_redirect.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/mod_redirect.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -271,6 +271,7 @@
+ }
+
+
++int mod_redirect_plugin_init(plugin *p);
+ int mod_redirect_plugin_init(plugin *p) {
+ p->version = LIGHTTPD_VERSION_ID;
+ p->name = buffer_init_string("redirect");
+Index: src/mod_usertrack.c
+===================================================================
+--- src/mod_usertrack.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/mod_usertrack.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -255,6 +255,7 @@
+
+ /* this function is called at dlopen() time and inits the callbacks */
+
++int mod_usertrack_plugin_init(plugin *p);
+ int mod_usertrack_plugin_init(plugin *p) {
+ p->version = LIGHTTPD_VERSION_ID;
+ p->name = buffer_init_string("usertrack");
+Index: src/mod_webdav.c
+===================================================================
+--- src/mod_webdav.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/mod_webdav.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -1096,7 +1096,7 @@
+ }
+ #endif
+
+-int webdav_lockdiscovery(server *srv, connection *con,
++static int webdav_lockdiscovery(server *srv, connection *con,
+ buffer *locktoken, const char *lockscope, const char *locktype, int depth) {
+
+ buffer *b;
+@@ -1156,7 +1156,7 @@
+ *
+ *
+ */
+-int webdav_has_lock(server *srv, connection *con, plugin_data *p, buffer *uri) {
++static int webdav_has_lock(server *srv, connection *con, plugin_data *p, buffer *uri) {
+ int has_lock = 1;
+
+ #ifdef USE_LOCKS
+@@ -2474,6 +2474,7 @@
+
+ /* this function is called at dlopen() time and inits the callbacks */
+
++int mod_webdav_plugin_init(plugin *p);
+ int mod_webdav_plugin_init(plugin *p) {
+ p->version = LIGHTTPD_VERSION_ID;
+ p->name = buffer_init_string("webdav");
+Index: src/mod_status.c
+===================================================================
+--- src/mod_status.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/mod_status.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -18,6 +18,7 @@
+ #include "plugin.h"
+
+ #include "inet_ntop_cache.h"
++#include "version.h"
+
+ typedef struct {
+ buffer *config_url;
+@@ -701,7 +702,7 @@
+ " <title>Status</title>\n"
+ " </head>\n"
+ " <body>\n"
+- " <h1>" PACKAGE_NAME " " PACKAGE_VERSION "</h1>\n"
++ " <h1>" PACKAGE_DESC "</h1>\n"
+ " <table summary=\"status\" border=\"1\">\n"));
+
+ mod_status_header_append(b, "Server-Features");
+@@ -853,6 +854,7 @@
+ return HANDLER_GO_ON;
+ }
+
++int mod_status_plugin_init(plugin *p);
+ int mod_status_plugin_init(plugin *p) {
+ p->version = LIGHTTPD_VERSION_ID;
+ p->name = buffer_init_string("status");
+Index: src/mod_compress.c
+===================================================================
+--- src/mod_compress.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/mod_compress.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -104,7 +104,7 @@
+ }
+
+ /* 0 on success, -1 for error */
+-int mkdir_recursive(char *dir) {
++static int mkdir_recursive(char *dir) {
+ char *p = dir;
+
+ if (!dir || !dir[0])
+@@ -126,7 +126,7 @@
+ }
+
+ /* 0 on success, -1 for error */
+-int mkdir_for_file(char *filename) {
++static int mkdir_for_file(char *filename) {
+ char *p = filename;
+
+ if (!filename || !filename[0])
+@@ -815,6 +815,7 @@
+ return HANDLER_GO_ON;
+ }
+
++int mod_compress_plugin_init(plugin *p);
+ int mod_compress_plugin_init(plugin *p) {
+ p->version = LIGHTTPD_VERSION_ID;
+ p->name = buffer_init_string("compress");
+Index: src/mod_ssi.c
+===================================================================
+--- src/mod_ssi.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/mod_ssi.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -37,6 +37,7 @@
+ #endif
-+ /**
-+ * check if we can still open a new connections
-+ *
-+ * see #1216
-+ */
+ #include "etag.h"
++#include "version.h"
+
+ /* The newest modified time of included files for include statement */
+ static volatile time_t include_file_last_mtime = 0;
+@@ -139,7 +140,7 @@
+ return HANDLER_GO_ON;
+ }
+
+-int ssi_env_add(array *env, const char *key, const char *val) {
++static int ssi_env_add(array *env, const char *key, const char *val) {
+ data_string *ds;
+
+ if (NULL == (ds = (data_string *)array_get_unused_element(env, TYPE_STRING))) {
+@@ -199,6 +200,34 @@
+ }
+ }
+
++ for (i = 0; i < con->environment->used; i++) {
++ data_string *ds;
+
-+ if (srv->conns->used >= srv->max_conns) {
-+ return NULL;
++ ds = (data_string *)con->environment->data[i];
++
++ if (ds->value->used && ds->key->used) {
++ size_t j;
++
++ buffer_reset(srv->tmp_buf);
++ buffer_prepare_append(srv->tmp_buf, ds->key->used + 2);
++
++ for (j = 0; j < ds->key->used - 1; j++) {
++ char c = '_';
++ if (light_isalpha(ds->key->ptr[j])) {
++ /* upper-case */
++ c = ds->key->ptr[j] & ~32;
++ } else if (light_isdigit(ds->key->ptr[j])) {
++ /* copy */
++ c = ds->key->ptr[j];
++ }
++ srv->tmp_buf->ptr[srv->tmp_buf->used++] = c;
++ }
++ srv->tmp_buf->ptr[srv->tmp_buf->used] = '\0';
++
++ ssi_env_add(p->ssi_cgi_env, srv->tmp_buf->ptr, ds->value->ptr);
++ }
+ }
+
- cnt_len = sizeof(cnt_addr);
+ return 0;
+ }
- if (-1 == (cnt = accept(srv_socket->fd, (struct sockaddr *) &cnt_addr, &cnt_len))) {
-@@ -1265,6 +1275,9 @@
- case ECONNABORTED: /* this is a FreeBSD thingy */
- /* we were stopped _after_ we had a connection */
- break;
-+ case EMFILE:
-+ /* out of fds */
-+ break;
- default:
- log_error_write(srv, __FILE__, __LINE__, "ssd", "accept failed:", strerror(errno), errno);
+@@ -216,7 +245,7 @@
+
+ array_reset(p->ssi_cgi_env);
+
+- ssi_env_add(p->ssi_cgi_env, CONST_STRING("SERVER_SOFTWARE"), PACKAGE_NAME"/"PACKAGE_VERSION);
++ ssi_env_add(p->ssi_cgi_env, CONST_STRING("SERVER_SOFTWARE"), PACKAGE_DESC);
+ ssi_env_add(p->ssi_cgi_env, CONST_STRING("SERVER_NAME"),
+ #ifdef HAVE_IPV6
+ inet_ntop(srv_sock->addr.plain.sa_family,
+@@ -656,17 +685,22 @@
+ if (p->if_is_false) break;
+
+ b = chunkqueue_get_append_buffer(con->write_queue);
+- buffer_copy_string_len(b, CONST_STR_LEN("<pre>"));
+ for (i = 0; i < p->ssi_vars->used; i++) {
+ data_string *ds = (data_string *)p->ssi_vars->data[p->ssi_vars->sorted[i]];
+
+ buffer_append_string_buffer(b, ds->key);
+- buffer_append_string_len(b, CONST_STR_LEN(": "));
+- buffer_append_string_buffer(b, ds->value);
+- buffer_append_string_len(b, CONST_STR_LEN("<br />"));
++ buffer_append_string_len(b, CONST_STR_LEN("="));
++ buffer_append_string_encoded(b, CONST_BUF_LEN(ds->value), ENCODING_MINIMAL_XML);
++ buffer_append_string_len(b, CONST_STR_LEN("\n"));
++ }
++ for (i = 0; i < p->ssi_cgi_env->used; i++) {
++ data_string *ds = (data_string *)p->ssi_cgi_env->data[p->ssi_cgi_env->sorted[i]];
+
++ buffer_append_string_buffer(b, ds->key);
++ buffer_append_string_len(b, CONST_STR_LEN("="));
++ buffer_append_string_encoded(b, CONST_BUF_LEN(ds->value), ENCODING_MINIMAL_XML);
++ buffer_append_string_len(b, CONST_STR_LEN("\n"));
}
-@@ -1432,6 +1445,7 @@
- } else if (con->in_error_handler) {
- /* error-handler is back and has generated content */
- /* if Status: was set, take it otherwise use 200 */
-+ con->http_status = con->error_handler_saved_status;
- }
+- buffer_append_string_len(b, CONST_STR_LEN("</pre>"));
- if (con->http_status == 0) con->http_status = 200;
-Index: src/mod_staticfile.c
+ break;
+ case SSI_EXEC: {
+@@ -1125,6 +1159,7 @@
+
+ /* this function is called at dlopen() time and inits the callbacks */
+
++int mod_ssi_plugin_init(plugin *p);
+ int mod_ssi_plugin_init(plugin *p) {
+ p->version = LIGHTTPD_VERSION_ID;
+ p->name = buffer_init_string("ssi");
+Index: src/mod_auth.c
===================================================================
---- src/mod_staticfile.c (.../tags/lighttpd-1.4.15) (revision 1880)
-+++ src/mod_staticfile.c (.../branches/lighttpd-1.4.x) (revision 1880)
-@@ -25,6 +25,7 @@
+--- src/mod_auth.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/mod_auth.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -313,20 +313,20 @@
+
+ config_values_t cv[] = {
+ { "auth.backend", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
+- { "auth.backend.plain.groupfile", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
+- { "auth.backend.plain.userfile", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
+- { "auth.require", NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION },
+- { "auth.backend.ldap.hostname", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
+- { "auth.backend.ldap.base-dn", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
+- { "auth.backend.ldap.filter", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
+- { "auth.backend.ldap.ca-file", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
+- { "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.plain.groupfile", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
++ { "auth.backend.plain.userfile", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 2 */
++ { "auth.require", NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 3 */
++ { "auth.backend.ldap.hostname", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 4 */
++ { "auth.backend.ldap.base-dn", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 5 */
++ { "auth.backend.ldap.filter", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 6 */
++ { "auth.backend.ldap.ca-file", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 7 */
++ { "auth.backend.ldap.starttls", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 8 */
++ { "auth.backend.ldap.bind-dn", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 9 */
+ { "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 */
++ { "auth.backend.ldap.allow-empty-pw", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 11 */
++ { "auth.backend.htdigest.userfile", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 12 */
++ { "auth.backend.htpasswd.userfile", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 13 */
++ { "auth.debug", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 14 */
+ { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
+ };
+
+@@ -614,6 +614,7 @@
+ #endif
+ }
+
++int mod_auth_plugin_init(plugin *p);
+ int mod_auth_plugin_init(plugin *p) {
+ p->version = LIGHTTPD_VERSION_ID;
+ p->name = buffer_init_string("auth");
+Index: src/settings.h
+===================================================================
+--- src/settings.h (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/settings.h (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -13,6 +13,7 @@
+ * 64kB (no real reason, just a guess)
+ */
+ #define BUFFER_MAX_REUSE_SIZE (4 * 1024)
++#define MAX_READ_LIMIT (4*1024*1024)
+
+ /**
+ * max size of the HTTP request header
+Index: src/mod_cml_lua.c
+===================================================================
+--- src/mod_cml_lua.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/mod_cml_lua.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -105,7 +105,7 @@
+ }
+
+
+-int cache_export_get_params(lua_State *L, int tbl, buffer *qrystr) {
++static int cache_export_get_params(lua_State *L, int tbl, buffer *qrystr) {
+ size_t is_key = 1;
+ size_t i;
+ char *key = NULL, *val = NULL;
+Index: src/version.h
+===================================================================
+--- src/version.h (.../tags/lighttpd-1.4.22) (revision 0)
++++ src/version.h (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -0,0 +1,12 @@
++#ifndef _VERSION_H_
++#define _VERSION_H_
++
++#ifdef HAVE_VERSION_H
++#include "versionstamp.h"
++#else
++#define REPO_VERSION ""
++#endif
++
++#define PACKAGE_DESC PACKAGE_NAME "/" PACKAGE_VERSION REPO_VERSION
++
++#endif
+Index: src/mod_evasive.c
+===================================================================
+--- src/mod_evasive.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/mod_evasive.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -27,6 +27,7 @@
typedef struct {
- array *exclude_ext;
-+ unsigned short etags_used;
+ unsigned short max_conns;
++ unsigned short silent;
} plugin_config;
typedef struct {
-@@ -82,6 +83,7 @@
+@@ -72,7 +73,8 @@
+ size_t i = 0;
config_values_t cv[] = {
- { "static-file.exclude-extensions", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
-+ { "static-file.etags", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
- { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
+- { "evasive.max-conns-per-ip", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },
++ { "evasive.max-conns-per-ip", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
++ { "evasive.silent", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 2 */
+ { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
};
-@@ -94,8 +96,10 @@
+@@ -83,6 +85,7 @@
s = calloc(1, sizeof(plugin_config));
- s->exclude_ext = array_init();
-+ s->etags_used = 1;
+ s->max_conns = 0;
++ s->silent = 0;
- cv[0].destination = s->exclude_ext;
-+ cv[1].destination = &(s->etags_used);
-
- p->config_storage[i] = s;
+ cv[0].destination = &(s->max_conns);
-@@ -114,6 +118,7 @@
+@@ -103,6 +106,7 @@
plugin_config *s = p->config_storage[0];
- PATCH(exclude_ext);
-+ PATCH(etags_used);
+ PATCH(max_conns);
++ PATCH(silent);
/* skip the first, the global context */
for (i = 1; i < srv->config_context->used; i++) {
-@@ -129,7 +134,9 @@
+@@ -118,6 +122,8 @@
- if (buffer_is_equal_string(du->key, CONST_STR_LEN("static-file.exclude-extensions"))) {
- PATCH(exclude_ext);
-- }
-+ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("static-file.etags"))) {
-+ PATCH(etags_used);
-+ }
+ if (buffer_is_equal_string(du->key, CONST_STR_LEN("evasive.max-conns-per-ip"))) {
+ PATCH(max_conns);
++ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("evasive.silent"))) {
++ PATCH(silent);
+ }
}
}
+@@ -172,9 +178,11 @@
+ conns_by_ip++;
+
+ if (conns_by_ip > p->conf.max_conns) {
+- log_error_write(srv, __FILE__, __LINE__, "ss",
+- inet_ntop_cache_get_ip(srv, &(con->dst_addr)),
+- "turned away. Too many connections.");
++ if (!p->conf.silent) {
++ log_error_write(srv, __FILE__, __LINE__, "ss",
++ inet_ntop_cache_get_ip(srv, &(con->dst_addr)),
++ "turned away. Too many connections.");
++ }
-@@ -446,11 +453,17 @@
- response_header_overwrite(srv, con, CONST_STR_LEN("Accept-Ranges"), CONST_STR_LEN("bytes"));
+ con->http_status = 403;
+ con->mode = DIRECT;
+@@ -186,6 +194,7 @@
+ }
- if (allow_caching) {
-- if (NULL == array_get_element(con->response.headers, "ETag")) {
-- /* generate e-tag */
-- etag_mutate(con->physical.etag, sce->etag);
-+ etag_flags_t flags;
-- response_header_overwrite(srv, con, CONST_STR_LEN("ETag"), CONST_BUF_LEN(con->physical.etag));
-+ flags = (con->conf.etag_use_mtime ? ETAG_USE_MTIME : 0) | (con->conf.etag_use_inode ? ETAG_USE_INODE : 0) | (con->conf.etag_use_size ? ETAG_USE_SIZE : 0);
-+
-+ if (p->conf.etags_used && flags != 0 && !buffer_is_empty(sce->etag)) {
-+ if (NULL == array_get_element(con->response.headers, "ETag")) {
-+ /* generate e-tag */
-+ etag_mutate(con->physical.etag, sce->etag);
-+
-+ response_header_overwrite(srv, con, CONST_STR_LEN("ETag"), CONST_BUF_LEN(con->physical.etag));
-+ }
- }
++int mod_evasive_plugin_init(plugin *p);
+ int mod_evasive_plugin_init(plugin *p) {
+ p->version = LIGHTTPD_VERSION_ID;
+ p->name = buffer_init_string("evasive");
+Index: src/mod_setenv.c
+===================================================================
+--- src/mod_setenv.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/mod_setenv.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -230,6 +230,7 @@
- /* prepare header */
-Index: src/configfile.c
+ /* this function is called at dlopen() time and inits the callbacks */
+
++int mod_setenv_plugin_init(plugin *p);
+ int mod_setenv_plugin_init(plugin *p) {
+ p->version = LIGHTTPD_VERSION_ID;
+ p->name = buffer_init_string("setenv");
+Index: src/mod_indexfile.c
===================================================================
---- src/configfile.c (.../tags/lighttpd-1.4.15) (revision 1880)
-+++ src/configfile.c (.../branches/lighttpd-1.4.x) (revision 1880)
-@@ -89,7 +89,9 @@
- { "server.core-files", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 45 */
- { "ssl.cipher-list", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 46 */
- { "ssl.use-sslv2", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 47 */
--
-+ { "etag.use-inode", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 48 */
-+ { "etag.use-mtime", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 49 */
-+ { "etag.use-size", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 50 */
- { "server.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 },
-@@ -162,6 +164,9 @@
+--- src/mod_indexfile.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/mod_indexfile.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -206,6 +206,7 @@
+
+ /* this function is called at dlopen() time and inits the callbacks */
+
++int mod_indexfile_plugin_init(plugin *p);
+ int mod_indexfile_plugin_init(plugin *p) {
+ p->version = LIGHTTPD_VERSION_ID;
+ p->name = buffer_init_string("indexfile");
+Index: src/mod_uploadprogress.c
+===================================================================
+Index: src/mod_fastcgi.c
+===================================================================
+--- src/mod_fastcgi.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/mod_fastcgi.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -49,6 +49,8 @@
+ #include <sys/wait.h>
#endif
- s->kbytes_per_second = 0;
- s->allow_http11 = 1;
-+ s->etag_use_inode = 1;
-+ s->etag_use_mtime = 1;
-+ s->etag_use_size = 1;
- s->range_requests = 1;
- s->force_lowercase_filenames = 0;
- s->global_kbytes_per_second = 0;
-@@ -206,6 +211,9 @@
-
- cv[46].destination = s->ssl_cipher_list;
- cv[47].destination = &(s->ssl_use_sslv2);
-+ cv[48].destination = &(s->etag_use_inode);
-+ cv[49].destination = &(s->etag_use_mtime);
-+ cv[50].destination = &(s->etag_use_size);
-
- srv->config_storage[i] = s;
-
-@@ -280,8 +288,10 @@
- PATCH(ssl_ca_file);
- PATCH(ssl_cipher_list);
- PATCH(ssl_use_sslv2);
--
--
-+ PATCH(etag_use_inode);
-+ PATCH(etag_use_mtime);
-+ PATCH(etag_use_size);
-+
+
++#include "version.h"
++
+ #define FCGI_ENV_ADD_CHECK(ret, con) \
+ if (ret == -1) { \
+ con->http_status = 400; \
+@@ -316,12 +318,6 @@
+ } plugin_config;
+
+ typedef struct {
+- size_t *ptr;
+- size_t used;
+- size_t size;
+-} buffer_uint;
+-
+-typedef struct {
+ char **ptr;
+
+ size_t size;
+@@ -331,7 +327,6 @@
+ /* generic plugin data, shared between all connections */
+ typedef struct {
+ PLUGIN_DATA;
+- buffer_uint fcgi_request_id;
+
+ buffer *fcgi_env;
+
+@@ -389,7 +384,7 @@
+ /* ok, we need a prototype */
+ static handler_t fcgi_handle_fdevent(void *s, void *ctx, int revents);
+
+-int fastcgi_status_copy_procname(buffer *b, fcgi_extension_host *host, fcgi_proc *proc) {
++static int 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);
+ if (proc) {
+@@ -400,7 +395,7 @@
return 0;
}
-@@ -323,6 +333,12 @@
- PATCH(max_read_idle);
- } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("mimetype.use-xattr"))) {
- PATCH(use_xattr);
-+ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("etag.use-inode"))) {
-+ PATCH(etag_use_inode);
-+ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("etag.use-mtime"))) {
-+ PATCH(etag_use_mtime);
-+ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("etag.use-size"))) {
-+ PATCH(etag_use_size);
- } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.pemfile"))) {
- PATCH(ssl_pemfile);
- } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.ca-file"))) {
-Index: src/etag.c
-===================================================================
---- src/etag.c (.../tags/lighttpd-1.4.15) (revision 1880)
-+++ src/etag.c (.../branches/lighttpd-1.4.x) (revision 1880)
-@@ -8,13 +8,25 @@
- return 0;
+-int fastcgi_status_init(server *srv, buffer *b, fcgi_extension_host *host, fcgi_proc *proc) {
++static int fastcgi_status_init(server *srv, buffer *b, fcgi_extension_host *host, fcgi_proc *proc) {
+ #define CLEAN(x) \
+ fastcgi_status_copy_procname(b, host, proc); \
+ buffer_append_string_len(b, CONST_STR_LEN(x)); \
+@@ -465,7 +460,7 @@
+ free(hctx);
}
--int etag_create(buffer *etag, struct stat *st) {
-- buffer_copy_off_t(etag, st->st_ino);
-- buffer_append_string_len(etag, CONST_STR_LEN("-"));
-- buffer_append_off_t(etag, st->st_size);
-- buffer_append_string_len(etag, CONST_STR_LEN("-"));
-- buffer_append_long(etag, st->st_mtime);
-+int etag_create(buffer *etag, struct stat *st,etag_flags_t flags) {
-+ if (0 == flags) return 0;
+-fcgi_proc *fastcgi_process_init() {
++static fcgi_proc *fastcgi_process_init() {
+ fcgi_proc *f;
-+ buffer_reset(etag);
-+
-+ if (flags & ETAG_USE_INODE) {
-+ buffer_append_off_t(etag, st->st_ino);
-+ buffer_append_string_len(etag, CONST_STR_LEN("-"));
-+ }
-+
-+ if (flags & ETAG_USE_SIZE) {
-+ buffer_append_off_t(etag, st->st_size);
-+ buffer_append_string_len(etag, CONST_STR_LEN("-"));
-+ }
-+
-+ if (flags & ETAG_USE_MTIME) {
-+ buffer_append_long(etag, st->st_mtime);
-+ }
-+
- return 0;
+ f = calloc(1, sizeof(*f));
+@@ -478,7 +473,7 @@
+ return f;
}
-Index: src/mod_scgi.c
-===================================================================
---- src/mod_scgi.c (.../tags/lighttpd-1.4.15) (revision 1880)
-+++ src/mod_scgi.c (.../branches/lighttpd-1.4.x) (revision 1880)
-@@ -803,7 +803,7 @@
- buffer_append_string_buffer(b, host->bin_path);
+-void fastcgi_process_free(fcgi_proc *f) {
++static void fastcgi_process_free(fcgi_proc *f) {
+ if (!f) return;
- /* exec the cgi */
-- execle("/bin/sh", "sh", "-c", b->ptr, NULL, env.ptr);
-+ execle("/bin/sh", "sh", "-c", b->ptr, (char *)NULL, env.ptr);
+ fastcgi_process_free(f->next);
+@@ -489,7 +484,7 @@
+ free(f);
+ }
- log_error_write(srv, __FILE__, __LINE__, "sbs",
- "execl failed for:", host->bin_path, strerror(errno));
-Index: src/etag.h
-===================================================================
---- src/etag.h (.../tags/lighttpd-1.4.15) (revision 1880)
-+++ src/etag.h (.../branches/lighttpd-1.4.x) (revision 1880)
-@@ -7,8 +7,10 @@
+-fcgi_extension_host *fastcgi_host_init() {
++static fcgi_extension_host *fastcgi_host_init() {
+ fcgi_extension_host *f;
- #include "buffer.h"
+ f = calloc(1, sizeof(*f));
+@@ -506,7 +501,7 @@
+ return f;
+ }
-+typedef enum { ETAG_USE_INODE = 1, ETAG_USE_MTIME = 2, ETAG_USE_SIZE = 4 } etag_flags_t;
-+
- int etag_is_equal(buffer *etag, const char *matches);
--int etag_create(buffer *etag, struct stat *st);
-+int etag_create(buffer *etag, struct stat *st, etag_flags_t flags);
- int etag_mutate(buffer *mut, buffer *etag);
+-void fastcgi_host_free(fcgi_extension_host *h) {
++static void fastcgi_host_free(fcgi_extension_host *h) {
+ if (!h) return;
+ buffer_free(h->id);
+@@ -525,7 +520,7 @@
-Index: src/request.c
-===================================================================
---- src/request.c (.../tags/lighttpd-1.4.15) (revision 1880)
-+++ src/request.c (.../branches/lighttpd-1.4.x) (revision 1880)
-@@ -284,8 +284,6 @@
-
- int done = 0;
-
-- data_string *ds = NULL;
--
- /*
- * Request: "^(GET|POST|HEAD) ([^ ]+(\\?[^ ]+|)) (HTTP/1\\.[01])$"
- * Option : "^([-a-zA-Z]+): (.+)$"
-@@ -715,12 +713,24 @@
- switch(*cur) {
- case '\r':
- if (con->parse_request->ptr[i+1] == '\n') {
-+ data_string *ds = NULL;
-+
- /* End of Headerline */
- con->parse_request->ptr[i] = '\0';
- con->parse_request->ptr[i+1] = '\0';
-
- if (in_folding) {
-- if (!ds) {
-+ buffer *key_b;
-+ /**
-+ * we use a evil hack to handle the line-folding
-+ *
-+ * As array_insert_unique() deletes 'ds' in the case of a duplicate
-+ * ds points somewhere and we get a evil crash. As a solution we keep the old
-+ * "key" and get the current value from the hash and append us
-+ *
-+ * */
-+
-+ if (!key || !key_len) {
- /* 400 */
-
- if (srv->srvconf.log_request_header_on_error) {
-@@ -737,7 +747,15 @@
- con->response.keep_alive = 0;
- return 0;
- }
-- buffer_append_string(ds->value, value);
-+
-+ key_b = buffer_init();
-+ buffer_copy_string_len(key_b, key, key_len);
-+
-+ if (NULL != (ds = (data_string *)array_get_element(con->request.headers, key_b->ptr))) {
-+ buffer_append_string(ds->value, value);
-+ }
-+
-+ buffer_free(key_b);
- } else {
- int s_len;
- key = con->parse_request->ptr + first;
-@@ -969,7 +987,12 @@
- first = i+1;
- is_key = 1;
- value = 0;
-- key_len = 0;
-+#if 0
-+ /**
-+ * for Bug 1230 keep the key_len a live
-+ */
-+ key_len = 0;
-+#endif
- in_folding = 0;
- } else {
- if (srv->srvconf.log_request_header_on_error) {
-Index: src/stat_cache.c
-===================================================================
---- src/stat_cache.c (.../tags/lighttpd-1.4.15) (revision 1880)
-+++ src/stat_cache.c (.../branches/lighttpd-1.4.x) (revision 1880)
-@@ -608,14 +608,16 @@
- break;
- }
- }
-- etag_create(sce->etag, &(sce->st));
-+ etag_create(sce->etag, &(sce->st),
-+ (con->conf.etag_use_mtime ? ETAG_USE_MTIME : 0) | (con->conf.etag_use_inode ? ETAG_USE_INODE : 0) | (con->conf.etag_use_size ? ETAG_USE_SIZE : 0));
- #ifdef HAVE_XATTR
-- if (buffer_is_empty(sce->content_type)) {
-+ if (con->conf.use_xattr && buffer_is_empty(sce->content_type)) {
- stat_cache_attr_get(sce->content_type, name->ptr);
- }
- #endif
- } else if (S_ISDIR(st.st_mode)) {
-- etag_create(sce->etag, &(sce->st));
-+ etag_create(sce->etag, &(sce->st),
-+ (con->conf.etag_use_mtime ? ETAG_USE_MTIME : 0) | (con->conf.etag_use_inode ? ETAG_USE_INODE : 0) | (con->conf.etag_use_size ? ETAG_USE_SIZE : 0));
- }
+ }
- #ifdef HAVE_FAM_H
-Index: src/http_auth.c
-===================================================================
---- src/http_auth.c (.../tags/lighttpd-1.4.15) (revision 1880)
-+++ src/http_auth.c (.../branches/lighttpd-1.4.x) (revision 1880)
-@@ -830,8 +830,14 @@
+-fcgi_exts *fastcgi_extensions_init() {
++static fcgi_exts *fastcgi_extensions_init() {
+ fcgi_exts *f;
- username = buffer_init();
+ f = calloc(1, sizeof(*f));
+@@ -533,7 +528,7 @@
+ return f;
+ }
-- base64_decode(username, realm_str);
-+ if (!base64_decode(username, realm_str)) {
-+ buffer_free(username);
+-void fastcgi_extensions_free(fcgi_exts *f) {
++static void fastcgi_extensions_free(fcgi_exts *f) {
+ size_t i;
-+ log_error_write(srv, __FILE__, __LINE__, "sb", "decodeing base64-string failed", username);
-+
-+ return 0;
-+ }
-+
- /* r2 == user:password */
- if (NULL == (pw = strchr(username->ptr, ':'))) {
- buffer_free(username);
-@@ -967,7 +973,7 @@
- for (c = b->ptr; *c; c++) {
- /* skip whitespaces */
- while (*c == ' ' || *c == '\t') c++;
-- if (!c) break;
-+ if (!*c) break;
+ if (!f) return;
+@@ -563,7 +558,7 @@
+ free(f);
+ }
- for (i = 0; dkv[i].key; i++) {
- if ((0 == strncmp(c, dkv[i].key, dkv[i].key_len))) {
-@@ -1016,9 +1022,24 @@
+-int fastcgi_extension_insert(fcgi_exts *ext, buffer *key, fcgi_extension_host *fh) {
++static int fastcgi_extension_insert(fcgi_exts *ext, buffer *key, fcgi_extension_host *fh) {
+ fcgi_extension *fe;
+ size_t i;
- log_error_write(srv, __FILE__, __LINE__, "s",
- "digest: missing field");
-+
-+ buffer_free(b);
- return -1;
+@@ -633,12 +628,9 @@
+
+ FREE_FUNC(mod_fastcgi_free) {
+ plugin_data *p = p_d;
+- buffer_uint *r = &(p->fcgi_request_id);
+
+ UNUSED(srv);
+
+- if (r->ptr) free(r->ptr);
+-
+ buffer_free(p->fcgi_env);
+ buffer_free(p->path);
+ buffer_free(p->parse_response);
+@@ -710,8 +702,8 @@
+ dst = malloc(key_len + val_len + 3);
+ memcpy(dst, key, key_len);
+ dst[key_len] = '=';
+- /* add the \0 from the value */
+- memcpy(dst + key_len + 1, val, val_len + 1);
++ memcpy(dst + key_len + 1, val, val_len);
++ dst[key_len + 1 + val_len] = '\0';
+
+ for (i = 0; i < env->used; i++) {
+ if (0 == strncmp(dst, env->ptr[i], key_len + 1)) {
+@@ -1056,10 +1048,7 @@
+ "child exited with status",
+ WEXITSTATUS(status), host->bin_path);
+ log_error_write(srv, __FILE__, __LINE__, "s",
+- "If you're trying to run PHP as a FastCGI backend, make sure you're using the FastCGI-enabled version.\n"
+- "You can find out if it is the right one by executing 'php -v' and it should display '(cgi-fcgi)' "
+- "in the output, NOT '(cgi)' NOR '(cli)'.\n"
+- "For more information, check http://trac.lighttpd.net/trac/wiki/Docs%3AModFastCGI#preparing-php-as-a-fastcgi-program"
++ "If you're trying to run your app as a FastCGI backend, make sure you're using the FastCGI-enabled version.\n"
+ "If this is PHP on Gentoo, add 'fastcgi' to the USE flags.");
+ } else if (WIFSIGNALED(status)) {
+ log_error_write(srv, __FILE__, __LINE__, "sd",
+@@ -1434,52 +1423,7 @@
+ }
+
+
+-static size_t fcgi_requestid_new(server *srv, plugin_data *p) {
+- size_t m = 0;
+- size_t i;
+- buffer_uint *r = &(p->fcgi_request_id);
+-
+- UNUSED(srv);
+-
+- for (i = 0; i < r->used; i++) {
+- if (r->ptr[i] > m) m = r->ptr[i];
+- }
+-
+- if (r->size == 0) {
+- r->size = 16;
+- r->ptr = malloc(sizeof(*r->ptr) * r->size);
+- } else if (r->used == r->size) {
+- r->size += 16;
+- r->ptr = realloc(r->ptr, sizeof(*r->ptr) * r->size);
+- }
+-
+- r->ptr[r->used++] = ++m;
+-
+- return m;
+-}
+-
+-static int fcgi_requestid_del(server *srv, plugin_data *p, size_t request_id) {
+- size_t i;
+- buffer_uint *r = &(p->fcgi_request_id);
+-
+- UNUSED(srv);
+-
+- for (i = 0; i < r->used; i++) {
+- if (r->ptr[i] == request_id) break;
+- }
+-
+- if (i != r->used) {
+- /* found */
+-
+- if (i != r->used - 1) {
+- r->ptr[i] = r->ptr[r->used - 1];
+- }
+- r->used--;
+- }
+-
+- return 0;
+-}
+-void fcgi_connection_close(server *srv, handler_ctx *hctx) {
++static void fcgi_connection_close(server *srv, handler_ctx *hctx) {
+ plugin_data *p;
+ connection *con;
+
+@@ -1495,10 +1439,6 @@
+ srv->cur_fds--;
}
-+ /**
-+ * protect the md5-sess against missing cnonce and nonce
-+ */
-+ if (algorithm &&
-+ 0 == strcasecmp(algorithm, "md5-sess") &&
-+ (!nonce || !cnonce)) {
-+ log_error_write(srv, __FILE__, __LINE__, "s",
-+ "digest: (md5-sess: missing field");
-+
-+ buffer_free(b);
-+ return -1;
+- if (hctx->request_id != 0) {
+- fcgi_requestid_del(srv, p, hctx->request_id);
+- }
+-
+ if (hctx->host && hctx->proc) {
+ if (hctx->got_proc) {
+ /* after the connect the process gets a load */
+@@ -1556,8 +1496,6 @@
+ hctx->fd = -1;
+ }
+
+- fcgi_requestid_del(srv, p, hctx->request_id);
+-
+ fcgi_set_state(srv, hctx, FCGI_STATE_INIT);
+
+ hctx->request_id = 0;
+@@ -1885,10 +1823,18 @@
+ buffer_prepare_copy(p->fcgi_env, 1024);
+
+
+- FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_SOFTWARE"), CONST_STR_LEN(PACKAGE_NAME"/"PACKAGE_VERSION)),con)
++ if (buffer_is_empty(con->conf.server_tag)) {
++ FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_SOFTWARE"), CONST_STR_LEN(PACKAGE_DESC)),con)
++ } else {
++ FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_SOFTWARE"), CONST_BUF_LEN(con->conf.server_tag)),con)
+ }
+
+ if (con->server_name->used) {
+- FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_NAME"), CONST_BUF_LEN(con->server_name)),con)
++ size_t len = con->server_name->used - 1;
++ char *colon = strchr(con->server_name->ptr, ':');
++ if (colon) len = colon - con->server_name->ptr;
+
- m = get_http_method_name(con->request.http_method);
++ FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_NAME"), con->server_name->ptr, len),con)
+ } else {
+ #ifdef HAVE_IPV6
+ s = inet_ntop(srv_sock->addr.plain.sa_family,
+@@ -2060,7 +2006,7 @@
+
+ fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REQUEST_URI"),
+ con->request.orig_uri->ptr + (host->strip_request_uri->used - 2),
+- con->request.orig_uri->used - (host->strip_request_uri->used - 2));
++ con->request.orig_uri->used - (host->strip_request_uri->used - 2) - 1);
+ } else {
+ FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REQUEST_URI"), CONST_BUF_LEN(con->request.orig_uri)),con)
+ }
+@@ -2577,7 +2523,7 @@
+ joblist_append(srv, con);
- /* password-string == HA1 */
-Index: src/mod_status.c
-===================================================================
---- src/mod_status.c (.../tags/lighttpd-1.4.15) (revision 1880)
-+++ src/mod_status.c (.../branches/lighttpd-1.4.x) (revision 1880)
-@@ -220,6 +220,7 @@
- BUFFER_APPEND_STRING_CONST(b,
- " <style type=\"text/css\">\n"
- " table.status { border: black solid thin; }\n"
-+ " td { white-space: nowrap; }\n"
- " td.int { background-color: #f0f0f0; text-align: right }\n"
- " td.string { background-color: #f0f0f0; text-align: left }\n"
- " th.status { background-color: black; color: white; font-weight: bold; }\n"
-@@ -520,6 +521,16 @@
- buffer_append_string_encoded(b, CONST_BUF_LEN(c->uri.path), ENCODING_HTML);
+ buffer_copy_string_len(dcls->key, "Content-Length", sizeof("Content-Length")-1);
+- buffer_copy_long(dcls->value, sce->st.st_size);
++ buffer_copy_off_t(dcls->value, sce->st.st_size);
+ dcls = (data_string*) array_replace(con->response.headers, (data_unset *)dcls);
+ if (dcls) dcls->free((data_unset*)dcls);
+
+@@ -3011,7 +2957,7 @@
+
+ /* move the proc-list entry down the list */
+ if (hctx->request_id == 0) {
+- hctx->request_id = fcgi_requestid_new(srv, p);
++ hctx->request_id = 1; /* always use id 1 as we don't use multiplexing */
+ } else {
+ log_error_write(srv, __FILE__, __LINE__, "sd",
+ "fcgi-request is already in use:", hctx->request_id);
+@@ -3639,7 +3585,11 @@
+ */
+
+ /* the rewrite is only done for /prefix/? matches */
+- if (extension->key->ptr[0] == '/' &&
++ if (host->fix_root_path_name && extension->key->ptr[0] == '/' && extension->key->ptr[1] == '\0') {
++ buffer_copy_string(con->request.pathinfo, con->uri.path->ptr);
++ con->uri.path->used = 1;
++ con->uri.path->ptr[con->uri.path->used - 1] = '\0';
++ } else if (extension->key->ptr[0] == '/' &&
+ con->uri.path->used > extension->key->used &&
+ NULL != (pathinfo = strchr(con->uri.path->ptr + extension->key->used - 1, '/'))) {
+ /* rewrite uri.path and pathinfo */
+@@ -3648,10 +3598,6 @@
+
+ con->uri.path->used -= con->request.pathinfo->used - 1;
+ con->uri.path->ptr[con->uri.path->used - 1] = '\0';
+- } else if (host->fix_root_path_name && extension->key->ptr[0] == '/' && extension->key->ptr[1] == '\0') {
+- buffer_copy_string(con->request.pathinfo, con->uri.path->ptr);
+- con->uri.path->used = 1;
+- con->uri.path->ptr[con->uri.path->used - 1] = '\0';
+ }
+ }
}
+@@ -3916,6 +3862,7 @@
+ }
-+ if (!buffer_is_empty(c->uri.query)) {
-+ BUFFER_APPEND_STRING_CONST(b, "?");
-+ buffer_append_string_encoded(b, CONST_BUF_LEN(c->uri.query), ENCODING_HTML);
-+ }
-+
-+ if (!buffer_is_empty(c->request.orig_uri)) {
-+ BUFFER_APPEND_STRING_CONST(b, " (");
-+ buffer_append_string_encoded(b, CONST_BUF_LEN(c->request.orig_uri), ENCODING_HTML);
-+ BUFFER_APPEND_STRING_CONST(b, ")");
-+ }
- BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string\">");
- buffer_append_string_buffer(b, c->physical.path);
-Index: src/mod_ssi.c
++int mod_fastcgi_plugin_init(plugin *p);
+ int mod_fastcgi_plugin_init(plugin *p) {
+ p->version = LIGHTTPD_VERSION_ID;
+ p->name = buffer_init_string("fastcgi");
+Index: src/CMakeLists.txt
===================================================================
---- src/mod_ssi.c (.../tags/lighttpd-1.4.15) (revision 1880)
-+++ src/mod_ssi.c (.../branches/lighttpd-1.4.x) (revision 1880)
-@@ -702,7 +702,7 @@
- /* close stdin */
- close(STDIN_FILENO);
-
-- execl("/bin/sh", "sh", "-c", cmd, NULL);
-+ execl("/bin/sh", "sh", "-c", cmd, (char *)NULL);
+Index: src/mod_access.c
+===================================================================
+--- src/mod_access.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/mod_access.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -175,6 +175,7 @@
+ }
- log_error_write(srv, __FILE__, __LINE__, "sss", "spawing exec failed:", strerror(errno), cmd);
-Index: src/spawn-fcgi.c
++int mod_access_plugin_init(plugin *p);
+ int mod_access_plugin_init(plugin *p) {
+ p->version = LIGHTTPD_VERSION_ID;
+ p->name = buffer_init_string("access");
+Index: src/mod_accesslog.c
===================================================================
---- src/spawn-fcgi.c (.../tags/lighttpd-1.4.15) (revision 1880)
-+++ src/spawn-fcgi.c (.../branches/lighttpd-1.4.x) (revision 1880)
-@@ -169,7 +169,7 @@
- strcat(b, appPath);
+--- src/mod_accesslog.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/mod_accesslog.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -156,7 +156,7 @@
+ return p;
+ }
- /* exec the cgi */
-- execl("/bin/sh", "sh", "-c", b, NULL);
-+ execl("/bin/sh", "sh", "-c", b, (char *)NULL);
+-int accesslog_parse_format(server *srv, format_fields *fields, buffer *format) {
++static int accesslog_parse_format(server *srv, format_fields *fields, buffer *format) {
+ size_t i, j, k = 0, start = 0;
- exit(errno);
+ if (format->used == 0) return -1;
+@@ -475,74 +475,9 @@
-Index: src/mod_fastcgi.c
-===================================================================
---- src/mod_fastcgi.c (.../tags/lighttpd-1.4.15) (revision 1880)
-+++ src/mod_fastcgi.c (.../branches/lighttpd-1.4.x) (revision 1880)
-@@ -69,7 +69,7 @@
- buffer *unixsocket; /* config.socket + "-" + id */
- unsigned port; /* config.port + pno */
-
-- buffer *connection_name; /* either tcp:<host>:<port> or unix:<socket> for debuggin purposes */
-+ buffer *connection_name; /* either tcp:<host>:<port> or unix:<socket> for debugging purposes */
-
- pid_t pid; /* PID of the spawned process (0 if not spawned locally) */
-
-@@ -80,7 +80,7 @@
- size_t requests; /* see max_requests */
- struct fcgi_proc *prev, *next; /* see first */
-
-- time_t disabled_until; /* this proc is disabled until, use something else until than */
-+ time_t disabled_until; /* this proc is disabled until, use something else until then */
-
- int is_local;
-
-@@ -88,7 +88,7 @@
- PROC_STATE_UNSET, /* init-phase */
- PROC_STATE_RUNNING, /* alive */
- PROC_STATE_OVERLOADED, /* listen-queue is full,
-- don't send something to this proc for the next 2 seconds */
-+ don't send anything to this proc for the next 2 seconds */
- PROC_STATE_DIED_WAIT_FOR_PID, /* */
- PROC_STATE_DIED, /* marked as dead, should be restarted */
- PROC_STATE_KILLED /* was killed as we don't have the load anymore */
-@@ -145,7 +145,7 @@
- unsigned short disable_time;
-
- /*
-- * same fastcgi processes get a little bit larger
-+ * some fastcgi processes get a little bit larger
- * than wanted. max_requests_per_proc kills a
- * process after a number of handled requests.
- *
-@@ -184,7 +184,7 @@
- * bin-path is the path to the binary
- *
- * check min_procs and max_procs for the number
-- * of process to start-up
-+ * of process to start up
- */
- buffer *bin_path;
-
-@@ -217,7 +217,7 @@
- unsigned short mode;
-
- /*
-- * check_local tell you if the phys file is stat()ed
-+ * check_local tells you if the phys file is stat()ed
- * or not. FastCGI doesn't care if the service is
- * remote. If the web-server side doesn't contain
- * the fastcgi-files we should not stat() for them
-@@ -228,7 +228,7 @@
- /*
- * append PATH_INFO to SCRIPT_FILENAME
- *
-- * php needs this if cgi.fix_pathinfo is provied
-+ * php needs this if cgi.fix_pathinfo is provided
- *
- */
+ if (s->access_logfile->used < 2) continue;
+
+- if (s->access_logfile->ptr[0] == '|') {
+-#ifdef HAVE_FORK
+- /* create write pipe and spawn process */
+-
+- int to_log_fds[2];
+- pid_t pid;
+-
+- if (pipe(to_log_fds)) {
+- log_error_write(srv, __FILE__, __LINE__, "ss", "pipe failed: ", strerror(errno));
+- return HANDLER_ERROR;
+- }
+-
+- /* fork, execve */
+- switch (pid = fork()) {
+- case 0:
+- /* child */
+-
+- close(STDIN_FILENO);
+- dup2(to_log_fds[0], STDIN_FILENO);
+- close(to_log_fds[0]);
+- /* not needed */
+- close(to_log_fds[1]);
+-
+- openDevNull(STDERR_FILENO);
+-
+- /* we don't need the client socket */
+- for (i = 3; i < 256; i++) {
+- close(i);
+- }
+-
+- /* exec the log-process (skip the | )
+- *
+- */
+-
+- execl("/bin/sh", "sh", "-c", s->access_logfile->ptr + 1, (char *)NULL);
+-
+- log_error_write(srv, __FILE__, __LINE__, "sss",
+- "spawning log-process failed: ", strerror(errno),
+- s->access_logfile->ptr + 1);
+-
+- exit(-1);
+- break;
+- case -1:
+- /* error */
+- log_error_write(srv, __FILE__, __LINE__, "ss", "fork failed: ", strerror(errno));
+- break;
+- default:
+- close(to_log_fds[0]);
+-
+- s->log_access_fd = to_log_fds[1];
+-
+- break;
+- }
+-#else
+- return -1;
+-#endif
+- } else if (-1 == (s->log_access_fd =
+- open(s->access_logfile->ptr, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) {
+-
+- log_error_write(srv, __FILE__, __LINE__, "ssb",
+- "opening access-log failed:",
+- strerror(errno), s->access_logfile);
+-
++ if (-1 == (s->log_access_fd = open_logfile_or_pipe(srv, s->access_logfile->ptr)))
+ return HANDLER_ERROR;
+- }
+-#ifdef FD_CLOEXEC
+- fcntl(s->log_access_fd, F_SETFD, FD_CLOEXEC);
+-#endif
++
+ }
-@@ -247,7 +247,7 @@
- num_procs.
+ return HANDLER_GO_ON;
+@@ -876,6 +811,7 @@
+ }
- only if a process is killed max_id waits for the process itself
-- to die and decrements its afterwards */
-+ to die and decrements it afterwards */
- buffer *strip_request_uri;
++int mod_accesslog_plugin_init(plugin *p);
+ int mod_accesslog_plugin_init(plugin *p) {
+ p->version = LIGHTTPD_VERSION_ID;
+ p->name = buffer_init_string("accesslog");
+Index: src/server.c
+===================================================================
+--- src/server.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/server.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -29,6 +29,7 @@
+ #include "plugin.h"
+ #include "joblist.h"
+ #include "network_backends.h"
++#include "version.h"
+
+ #ifdef HAVE_GETOPT_H
+ #include <getopt.h>
+@@ -64,6 +65,17 @@
+ /* #define USE_ALARM */
+ #endif
-@@ -826,7 +826,7 @@
- } else {
- struct hostent *he;
++#ifdef HAVE_GETUID
++# ifndef HAVE_ISSETUGID
++
++static int l_issetugid() {
++ return (geteuid() != getuid() || getegid() != getgid());
++}
++
++# define issetugid l_issetugid
++# endif
++#endif
++
+ static volatile sig_atomic_t srv_shutdown = 0;
+ static volatile sig_atomic_t graceful_shutdown = 0;
+ static volatile sig_atomic_t handle_sig_alarm = 1;
+@@ -325,7 +337,7 @@
+ #else
+ # define TEXT_SSL
+ #endif
+- char *b = PACKAGE_NAME "-" PACKAGE_VERSION TEXT_SSL \
++ char *b = PACKAGE_DESC TEXT_SSL \
+ " - a light and fast webserver\n" \
+ "Build-Date: " __DATE__ " " __TIME__ "\n";
+ ;
+@@ -462,7 +474,7 @@
+ #else
+ # define TEXT_SSL
+ #endif
+- char *b = PACKAGE_NAME "-" PACKAGE_VERSION TEXT_SSL " ("__DATE__ " " __TIME__ ")" \
++ char *b = PACKAGE_DESC TEXT_SSL " ("__DATE__ " " __TIME__ ")" \
+ " - a light and fast webserver\n" \
+ "usage:\n" \
+ " -f <name> filename of the config-file\n" \
+@@ -589,7 +601,7 @@
+
+ /* UID handling */
+ #ifdef HAVE_GETUID
+- if (!i_am_root && (geteuid() == 0 || getegid() == 0)) {
++ if (!i_am_root && issetugid()) {
+ /* we are setuid-root */
-- /* set a usefull default */
-+ /* set a useful default */
- fcgi_addr_in.sin_addr.s_addr = htonl(INADDR_ANY);
+ log_error_write(srv, __FILE__, __LINE__, "s",
+Index: src/mod_dirlisting.c
+===================================================================
+--- src/mod_dirlisting.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/mod_dirlisting.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -31,6 +31,8 @@
+ #include <attr/attributes.h>
+ #endif
++#include "version.h"
++
+ /* plugin config for all request/connections */
-@@ -869,7 +869,7 @@
- }
+ typedef struct {
+@@ -52,8 +54,11 @@
+ unsigned short hide_dot_files;
+ unsigned short show_readme;
+ unsigned short hide_readme_file;
++ unsigned short encode_readme;
+ unsigned short show_header;
+ unsigned short hide_header_file;
++ unsigned short encode_header;
++ unsigned short auto_layout;
+
+ excludes_buffer *excludes;
+
+@@ -73,7 +78,7 @@
+ plugin_config conf;
+ } plugin_data;
+
+-excludes_buffer *excludes_buffer_init(void) {
++static excludes_buffer *excludes_buffer_init(void) {
+ excludes_buffer *exb;
+
+ exb = calloc(1, sizeof(*exb));
+@@ -81,7 +86,7 @@
+ return exb;
+ }
- if (-1 == connect(fcgi_fd, fcgi_addr, servlen)) {
-- /* server is not up, spawn in */
-+ /* server is not up, spawn it */
- pid_t child;
- int val;
+-int excludes_buffer_append(excludes_buffer *exb, buffer *string) {
++static int excludes_buffer_append(excludes_buffer *exb, buffer *string) {
+ #ifdef HAVE_PCRE_H
+ size_t i;
+ const char *errptr;
+@@ -128,7 +133,7 @@
+ #endif
+ }
-@@ -1029,10 +1029,11 @@
- "child exited with status",
- WEXITSTATUS(status), host->bin_path);
- log_error_write(srv, __FILE__, __LINE__, "s",
-- "if you try do run PHP as FastCGI backend make sure you use the FastCGI enabled version.\n"
-+ "If you're trying to run PHP as a FastCGI backend, make sure you're using the FastCGI-enabled version.\n"
- "You can find out if it is the right one by executing 'php -v' and it should display '(cgi-fcgi)' "
-- "in the output, NOT (cgi) NOR (cli)\n"
-- "For more information check http://www.lighttpd.net/documentation/fastcgi.html#preparing-php-as-a-fastcgi-program");
-+ "in the output, NOT '(cgi)' NOR '(cli)'.\n"
-+ "For more information, check http://trac.lighttpd.net/trac/wiki/Docs%3AModFastCGI#preparing-php-as-a-fastcgi-program"
-+ "If this is PHP on Gentoo, add 'fastcgi' to the USE flags.");
- } else if (WIFSIGNALED(status)) {
- log_error_write(srv, __FILE__, __LINE__, "sd",
- "terminated by signal:",
-@@ -1040,9 +1041,9 @@
-
- if (WTERMSIG(status) == 11) {
- log_error_write(srv, __FILE__, __LINE__, "s",
-- "to be exact: it seg-fault, crashed, died, ... you get the idea." );
-+ "to be exact: it segfaulted, crashed, died, ... you get the idea." );
- log_error_write(srv, __FILE__, __LINE__, "s",
-- "If this is PHP try to remove the byte-code caches for now and try again.");
-+ "If this is PHP, try removing the bytecode caches for now and try again.");
- }
- } else {
- log_error_write(srv, __FILE__, __LINE__, "sd",
-@@ -1066,7 +1067,7 @@
+-void excludes_buffer_free(excludes_buffer *exb) {
++static void excludes_buffer_free(excludes_buffer *exb) {
+ #ifdef HAVE_PCRE_H
+ size_t i;
+
+@@ -243,6 +248,9 @@
+ #define CONFIG_HIDE_HEADER_FILE "dir-listing.hide-header-file"
+ #define CONFIG_DIR_LISTING "server.dir-listing"
+ #define CONFIG_SET_FOOTER "dir-listing.set-footer"
++#define CONFIG_ENCODE_README "dir-listing.encode-readme"
++#define CONFIG_ENCODE_HEADER "dir-listing.encode-header"
++#define CONFIG_AUTO_LAYOUT "dir-listing.auto-layout"
+
+
+ SETDEFAULTS_FUNC(mod_dirlisting_set_defaults) {
+@@ -260,7 +268,10 @@
+ { CONFIG_SHOW_HEADER, NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 7 */
+ { CONFIG_HIDE_HEADER_FILE, NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 8 */
+ { CONFIG_DIR_LISTING, NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 9 */
+- { CONFIG_SET_FOOTER, NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 10 */
++ { CONFIG_SET_FOOTER, NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 10 */
++ { CONFIG_ENCODE_README, NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 11 */
++ { CONFIG_ENCODE_HEADER, NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 12 */
++ { CONFIG_AUTO_LAYOUT, NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 13 */
+
+ { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
+ };
+@@ -282,6 +293,10 @@
+ s->hide_readme_file = 0;
+ s->show_header = 0;
+ s->hide_header_file = 0;
++ s->encode_readme = 1;
++ s->encode_header = 1;
++ s->auto_layout = 1;
++
+ s->encoding = buffer_init();
+ s->set_footer = buffer_init();
- if (p->conf.debug) {
- log_error_write(srv, __FILE__, __LINE__, "sb",
-- "(debug) socket is already used, won't spawn:",
-+ "(debug) socket is already used; won't spawn:",
- proc->connection_name);
- }
- }
-@@ -1508,7 +1509,7 @@
- *
- * next step is resetting this attemp and setup a connection again
- *
-- * if we have more then 5 reconnects for the same request, die
-+ * if we have more than 5 reconnects for the same request, die
- *
- * 2.
- *
-@@ -1626,7 +1627,7 @@
- CONNECTION_UNSET,
- CONNECTION_OK,
- CONNECTION_DELAYED, /* retry after event, take same host */
-- CONNECTION_OVERLOADED, /* disable for 1 seconds, take another backend */
-+ CONNECTION_OVERLOADED, /* disable for 1 second, take another backend */
- CONNECTION_DEAD /* disable for 60 seconds, take another backend */
- } connection_result_t;
-
-@@ -1669,7 +1670,7 @@
- fcgi_addr_in.sin_family = AF_INET;
- if (0 == inet_aton(host->host->ptr, &(fcgi_addr_in.sin_addr))) {
- log_error_write(srv, __FILE__, __LINE__, "sbs",
-- "converting IP-adress failed for", host->host,
-+ "converting IP address failed for", host->host,
- "\nBe sure to specify an IP address here");
+@@ -296,6 +311,9 @@
+ cv[8].destination = &(s->hide_header_file);
+ cv[9].destination = &(s->dir_listing); /* old name */
+ cv[10].destination = s->set_footer;
++ cv[11].destination = &(s->encode_readme);
++ cv[12].destination = &(s->encode_header);
++ cv[13].destination = &(s->auto_layout);
- return -1;
-@@ -1694,16 +1695,16 @@
- errno == EINTR) {
- if (hctx->conf.debug > 2) {
- log_error_write(srv, __FILE__, __LINE__, "sb",
-- "connect delayed, will continue later:", proc->connection_name);
-+ "connect delayed; will continue later:", proc->connection_name);
- }
+ p->config_storage[i] = s;
+ ca = ((data_config *)srv->config_context->data[i])->value;
+@@ -326,6 +344,9 @@
+ PATCH(hide_header_file);
+ PATCH(excludes);
+ PATCH(set_footer);
++ PATCH(encode_readme);
++ PATCH(encode_header);
++ PATCH(auto_layout);
- return CONNECTION_DELAYED;
- } else if (errno == EAGAIN) {
- if (hctx->conf.debug) {
- log_error_write(srv, __FILE__, __LINE__, "sbsd",
-- "This means that the you have more incoming requests than your fastcgi-backend can handle in parallel. "
-- "Perhaps it helps to spawn more fastcgi backend or php-children, if not decrease server.max-connections."
-- "The load for this fastcgi backend", proc->connection_name, "is", proc->load);
-+ "This means that you have more incoming requests than your FastCGI backend can handle in parallel."
-+ "It might help to spawn more FastCGI backends or PHP children; if not, decrease server.max-connections."
-+ "The load for this FastCGI backend", proc->connection_name, "is", proc->load);
+ /* skip the first, the global context */
+ for (i = 1; i < srv->config_context->used; i++) {
+@@ -360,6 +381,12 @@
+ PATCH(set_footer);
+ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN(CONFIG_EXCLUDE))) {
+ PATCH(excludes);
++ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN(CONFIG_ENCODE_README))) {
++ PATCH(encode_readme);
++ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN(CONFIG_ENCODE_HEADER))) {
++ PATCH(encode_header);
++ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN(CONFIG_AUTO_LAYOUT))) {
++ PATCH(auto_layout);
}
+ }
+ }
+@@ -454,57 +481,59 @@
+ static void http_list_directory_header(server *srv, connection *con, plugin_data *p, buffer *out) {
+ UNUSED(srv);
+
+- buffer_append_string_len(out, CONST_STR_LEN(
+- "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n"
+- "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\">\n"
+- "<head>\n"
+- "<title>Index of "
+- ));
+- buffer_append_string_encoded(out, CONST_BUF_LEN(con->uri.path), ENCODING_MINIMAL_XML);
+- buffer_append_string_len(out, CONST_STR_LEN("</title>\n"));
+-
+- if (p->conf.external_css->used > 1) {
+- buffer_append_string_len(out, CONST_STR_LEN("<link rel=\"stylesheet\" type=\"text/css\" href=\""));
+- buffer_append_string_buffer(out, p->conf.external_css);
+- buffer_append_string_len(out, CONST_STR_LEN("\" />\n"));
+- } else {
++ if (p->conf.auto_layout) {
+ buffer_append_string_len(out, CONST_STR_LEN(
+- "<style type=\"text/css\">\n"
+- "a, a:active {text-decoration: none; color: blue;}\n"
+- "a:visited {color: #48468F;}\n"
+- "a:hover, a:focus {text-decoration: underline; color: red;}\n"
+- "body {background-color: #F5F5F5;}\n"
+- "h2 {margin-bottom: 12px;}\n"
+- "table {margin-left: 12px;}\n"
+- "th, td {"
+- " font: 90% monospace;"
+- " text-align: left;"
+- "}\n"
+- "th {"
+- " font-weight: bold;"
+- " padding-right: 14px;"
+- " padding-bottom: 3px;"
+- "}\n"
+- "td {padding-right: 14px;}\n"
+- "td.s, th.s {text-align: right;}\n"
+- "div.list {"
+- " background-color: white;"
+- " border-top: 1px solid #646464;"
+- " border-bottom: 1px solid #646464;"
+- " padding-top: 10px;"
+- " padding-bottom: 14px;"
+- "}\n"
+- "div.foot {"
+- " font: 90% monospace;"
+- " color: #787878;"
+- " padding-top: 4px;"
+- "}\n"
+- "</style>\n"
++ "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n"
++ "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\">\n"
++ "<head>\n"
++ "<title>Index of "
+ ));
++ buffer_append_string_encoded(out, CONST_BUF_LEN(con->uri.path), ENCODING_MINIMAL_XML);
++ buffer_append_string_len(out, CONST_STR_LEN("</title>\n"));
++
++ if (p->conf.external_css->used > 1) {
++ buffer_append_string_len(out, CONST_STR_LEN("<link rel=\"stylesheet\" type=\"text/css\" href=\""));
++ buffer_append_string_buffer(out, p->conf.external_css);
++ buffer_append_string_len(out, CONST_STR_LEN("\" />\n"));
++ } else {
++ buffer_append_string_len(out, CONST_STR_LEN(
++ "<style type=\"text/css\">\n"
++ "a, a:active {text-decoration: none; color: blue;}\n"
++ "a:visited {color: #48468F;}\n"
++ "a:hover, a:focus {text-decoration: underline; color: red;}\n"
++ "body {background-color: #F5F5F5;}\n"
++ "h2 {margin-bottom: 12px;}\n"
++ "table {margin-left: 12px;}\n"
++ "th, td {"
++ " font: 90% monospace;"
++ " text-align: left;"
++ "}\n"
++ "th {"
++ " font-weight: bold;"
++ " padding-right: 14px;"
++ " padding-bottom: 3px;"
++ "}\n"
++ "td {padding-right: 14px;}\n"
++ "td.s, th.s {text-align: right;}\n"
++ "div.list {"
++ " background-color: white;"
++ " border-top: 1px solid #646464;"
++ " border-bottom: 1px solid #646464;"
++ " padding-top: 10px;"
++ " padding-bottom: 14px;"
++ "}\n"
++ "div.foot {"
++ " font: 90% monospace;"
++ " color: #787878;"
++ " padding-top: 4px;"
++ "}\n"
++ "</style>\n"
++ ));
++ }
++
++ buffer_append_string_len(out, CONST_STR_LEN("</head>\n<body>\n"));
+ }
- return CONNECTION_OVERLOADED;
-@@ -1881,8 +1882,6 @@
- fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REMOTE_ADDR"), s, strlen(s));
-
- if (!buffer_is_empty(con->authed_user)) {
-- fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REMOTE_USER"), CONST_BUF_LEN(con->authed_user));
--
- /* AUTH_TYPE fix by Troy Kruthoff (tkruthoff@gmail.com)
- * section 4.1.1 of RFC 3875 (cgi spec) requires the server to set a AUTH_TYPE env
- * declaring the type of authentication used. (see http://tools.ietf.org/html/rfc3875#page-11)
-@@ -1896,6 +1895,8 @@
- char *http_authorization = NULL;
- data_string *ds;
-
-+ fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REMOTE_USER"), CONST_BUF_LEN(con->authed_user));
-+
- if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Authorization"))) {
- http_authorization = ds->value->ptr;
+- buffer_append_string_len(out, CONST_STR_LEN("</head>\n<body>\n"));
+-
+ /* HEADER.txt */
+ if (p->conf.show_header) {
+ stream s;
+@@ -515,9 +544,13 @@
+ buffer_append_string_len(p->tmp_buf, CONST_STR_LEN("HEADER.txt"));
+
+ if (-1 != stream_open(&s, p->tmp_buf)) {
+- buffer_append_string_len(out, CONST_STR_LEN("<pre class=\"header\">"));
+- buffer_append_string_encoded(out, s.start, s.size, ENCODING_MINIMAL_XML);
+- buffer_append_string_len(out, CONST_STR_LEN("</pre>"));
++ if (p->conf.encode_header) {
++ buffer_append_string_len(out, CONST_STR_LEN("<pre class=\"header\">"));
++ buffer_append_string_encoded(out, s.start, s.size, ENCODING_MINIMAL_XML);
++ buffer_append_string_len(out, CONST_STR_LEN("</pre>"));
++ } else {
++ buffer_append_string_len(out, s.start, s.size);
++ }
}
-@@ -2055,8 +2056,8 @@
- off_t written = 0;
- off_t weHave = 0;
-
-- /* we announce toWrite octects
-- * now take all the request_content chunk that we need to fill this request
-+ /* we announce toWrite octets
-+ * now take all the request_content chunks that we need to fill this request
- * */
-
- b = chunkqueue_get_append_buffer(hctx->wb);
-@@ -2356,7 +2357,7 @@
+ stream_close(&s);
+ }
+@@ -564,30 +597,36 @@
+ buffer_append_string_len(p->tmp_buf, CONST_STR_LEN("README.txt"));
+
+ if (-1 != stream_open(&s, p->tmp_buf)) {
+- buffer_append_string_len(out, CONST_STR_LEN("<pre class=\"readme\">"));
+- buffer_append_string_encoded(out, s.start, s.size, ENCODING_MINIMAL_XML);
+- buffer_append_string_len(out, CONST_STR_LEN("</pre>"));
++ if (p->conf.encode_readme) {
++ buffer_append_string_len(out, CONST_STR_LEN("<pre class=\"readme\">"));
++ buffer_append_string_encoded(out, s.start, s.size, ENCODING_MINIMAL_XML);
++ buffer_append_string_len(out, CONST_STR_LEN("</pre>"));
++ } else {
++ buffer_append_string_len(out, s.start, s.size);
++ }
}
-
- if (packet->b->used < packet->len + 1) {
-- /* we didn't got the full packet */
-+ /* we didn't get the full packet */
-
- buffer_free(packet->b);
- return -1;
-@@ -2439,7 +2440,6 @@
- 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,
-@@ -2558,7 +2558,7 @@
- if (host->mode != FCGI_AUTHORIZER ||
- !(con->http_status == 0 ||
- con->http_status == 200)) {
-- /* send chunk-end if nesseary */
-+ /* send chunk-end if necessary */
- http_chunk_append_mem(srv, con, NULL, 0);
- joblist_append(srv, con);
- }
-@@ -2653,7 +2653,7 @@
- if (proc->state != PROC_STATE_DIED) break;
-
- case PROC_STATE_DIED:
-- /* local proc get restarted by us,
-+ /* local procs get restarted by us,
- * remote ones hopefully by the admin */
-
- if (proc->is_local) {
-@@ -2774,7 +2774,7 @@
- proc && proc->state != PROC_STATE_RUNNING;
- proc = proc->next);
-
-- /* all childs are dead */
-+ /* all children are dead */
- if (proc == NULL) {
- hctx->fde_ndx = -1;
-
-@@ -2834,7 +2834,7 @@
- * -> EAGAIN */
-
- log_error_write(srv, __FILE__, __LINE__, "ssdsd",
-- "backend is overloaded, we disable it for a 2 seconds and send the request to another backend instead:",
-+ "backend is overloaded; we'll disable it for 2 seconds and send the request to another backend instead:",
- "reconnects:", hctx->reconnects,
- "load:", host->load);
-
-@@ -2864,7 +2864,7 @@
- }
-
- log_error_write(srv, __FILE__, __LINE__, "ssdsd",
-- "backend died, we disable it for a 5 seconds and send the request to another backend instead:",
-+ "backend died; we'll disable it for 5 seconds and send the request to another backend instead:",
- "reconnects:", hctx->reconnects,
- "load:", host->load);
-
-@@ -2950,7 +2950,7 @@
- if (hctx->wb->bytes_out == 0 &&
- hctx->reconnects < 5) {
- usleep(10000); /* take away the load of the webserver
-- * to let the php a chance to restart
-+ * to give the php a chance to restart
- */
-
- fcgi_reconnect(srv, hctx);
-@@ -3152,9 +3152,9 @@
- (con->http_status == 200 ||
- con->http_status == 0)) {
- /*
-- * If we are here in AUTHORIZER mode then a request for autorizer
-- * was proceeded already, and status 200 has been returned. We need
-- * now to handle autorized request.
-+ * If we are here in AUTHORIZER mode then a request for authorizer
-+ * was processed already, and status 200 has been returned. We need
-+ * now to handle authorized request.
- */
-
- buffer_copy_string_buffer(con->physical.doc_root, host->docroot);
-@@ -3220,7 +3220,7 @@
- }
-
- if (con->file_started == 0) {
-- /* nothing has been send out yet, try to use another child */
-+ /* nothing has been sent out yet, try to use another child */
-
- if (hctx->wb->bytes_out == 0 &&
- hctx->reconnects < 5) {
-@@ -3270,8 +3270,8 @@
- hctx->state == FCGI_STATE_WRITE) {
- /* we are allowed to send something out
- *
-- * 1. in a unfinished connect() call
-- * 2. in a unfinished write() call (long POST request)
-+ * 1. in an unfinished connect() call
-+ * 2. in an unfinished write() call (long POST request)
- */
- return mod_fastcgi_handle_subrequest(srv, con, p);
- } else {
-@@ -3286,8 +3286,8 @@
- if (hctx->state == FCGI_STATE_CONNECT_DELAYED) {
- /* getoptsock will catch this one (right ?)
- *
-- * if we are in connect we might get a EINPROGRESS
-- * in the first call and a FDEVENT_HUP in the
-+ * if we are in connect we might get an EINPROGRESS
-+ * in the first call and an FDEVENT_HUP in the
- * second round
- *
- * FIXME: as it is a bit ugly.
-@@ -3485,7 +3485,7 @@
- return HANDLER_FINISHED;
+ stream_close(&s);
}
-- /* a note about no handler is not sent yey */
-+ /* a note about no handler is not sent yet */
- extension->note_is_sent = 0;
+- buffer_append_string_len(out, CONST_STR_LEN(
+- "<div class=\"foot\">"
+- ));
++ if(p->conf.auto_layout) {
++ buffer_append_string_len(out, CONST_STR_LEN(
++ "<div class=\"foot\">"
++ ));
+
+- if (p->conf.set_footer->used > 1) {
+- buffer_append_string_buffer(out, p->conf.set_footer);
+- } else if (buffer_is_empty(con->conf.server_tag)) {
+- buffer_append_string_len(out, CONST_STR_LEN(PACKAGE_NAME "/" PACKAGE_VERSION));
+- } else {
+- buffer_append_string_buffer(out, con->conf.server_tag);
++ if (p->conf.set_footer->used > 1) {
++ buffer_append_string_buffer(out, p->conf.set_footer);
++ } else if (buffer_is_empty(con->conf.server_tag)) {
++ buffer_append_string_len(out, CONST_STR_LEN(PACKAGE_DESC));
++ } else {
++ buffer_append_string_buffer(out, con->conf.server_tag);
++ }
++
++ buffer_append_string_len(out, CONST_STR_LEN(
++ "</div>\n"
++ "</body>\n"
++ "</html>\n"
++ ));
+ }
+-
+- buffer_append_string_len(out, CONST_STR_LEN(
+- "</div>\n"
+- "</body>\n"
+- "</html>\n"
+- ));
+ }
- /*
-@@ -3520,7 +3520,7 @@
- }
+ static int http_list_directory(server *srv, connection *con, plugin_data *p, buffer *dir) {
+@@ -904,6 +943,7 @@
- /* the prefix is the SCRIPT_NAME,
-- * everthing from start to the next slash
-+ * everything from start to the next slash
- * this is important for check-local = "disable"
- *
- * if prefix = /admin.fcgi
-@@ -3630,13 +3630,13 @@
+ /* this function is called at dlopen() time and inits the callbacks */
- /* perhaps we should kill a connect attempt after 10-15 seconds
- *
-- * currently we wait for the TCP timeout which is on Linux 180 seconds
-+ * currently we wait for the TCP timeout which is 180 seconds on Linux
- *
- *
- *
- */
-
-- /* check all childs if they are still up */
-+ /* check all children if they are still up */
-
- for (i = 0; i < srv->config_context->used; i++) {
- plugin_config *conf;
-@@ -3718,11 +3718,11 @@
-
- if (srv->cur_ts - proc->last_used > host->idle_timeout) {
- /* a proc is idling for a long time now,
-- * terminated it */
-+ * terminate it */
-
- if (p->conf.debug) {
- log_error_write(srv, __FILE__, __LINE__, "ssbsd",
-- "idle-timeout reached, terminating child:",
-+ "idle-timeout reached; terminating child:",
- "socket:", proc->connection_name,
- "pid", proc->pid);
- }
-Index: src/mod_access.c
++int mod_dirlisting_plugin_init(plugin *p);
+ int mod_dirlisting_plugin_init(plugin *p) {
+ p->version = LIGHTTPD_VERSION_ID;
+ p->name = buffer_init_string("dirlisting");
+Index: src/mod_magnet.c
===================================================================
---- src/mod_access.c (.../tags/lighttpd-1.4.15) (revision 1880)
-+++ src/mod_access.c (.../branches/lighttpd-1.4.x) (revision 1880)
-@@ -111,6 +111,15 @@
+--- src/mod_magnet.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/mod_magnet.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -365,6 +365,8 @@
+ MAGNET_ENV_REQUEST_METHOD,
+ MAGNET_ENV_REQUEST_URI,
+ MAGNET_ENV_REQUEST_ORIG_URI,
++ MAGNET_ENV_REQUEST_PATH_INFO,
++ MAGNET_ENV_REQUEST_REMOTE_IP,
+ MAGNET_ENV_REQUEST_PROTOCOL
+ } type;
+ } magnet_env_t;
+@@ -387,6 +389,8 @@
+ { "request.method", MAGNET_ENV_REQUEST_METHOD },
+ { "request.uri", MAGNET_ENV_REQUEST_URI },
+ { "request.orig-uri", MAGNET_ENV_REQUEST_ORIG_URI },
++ { "request.path-info", MAGNET_ENV_REQUEST_PATH_INFO },
++ { "request.remote-ip", MAGNET_ENV_REQUEST_REMOTE_IP },
+ { "request.protocol", MAGNET_ENV_REQUEST_PROTOCOL },
+
+ { NULL, MAGNET_ENV_UNSET }
+@@ -420,6 +424,8 @@
+ break;
+ case MAGNET_ENV_REQUEST_URI: dest = con->request.uri; break;
+ case MAGNET_ENV_REQUEST_ORIG_URI: dest = con->request.orig_uri; break;
++ case MAGNET_ENV_REQUEST_PATH_INFO: dest = con->request.pathinfo; break;
++ case MAGNET_ENV_REQUEST_REMOTE_IP: dest = con->dst_addr_buf; break;
+ case MAGNET_ENV_REQUEST_PROTOCOL:
+ buffer_copy_string(srv->tmp_buf, get_http_version_name(con->request.http_version));
+ dest = srv->tmp_buf;
+@@ -840,6 +846,7 @@
+
+ /* this function is called at dlopen() time and inits the callbacks */
+
++int mod_magnet_plugin_init(plugin *p);
+ int mod_magnet_plugin_init(plugin *p) {
+ p->version = LIGHTTPD_VERSION_ID;
+ p->name = buffer_init_string("magnet");
+@@ -856,6 +863,7 @@
}
- #undef PATCH
-
-+/**
-+ * URI handler
-+ *
-+ * we will get called twice:
-+ * - after the clean up of the URL and
-+ * - after the pathinfo checks are done
-+ *
-+ * this handles the issue of trailing slashes
-+ */
- URIHANDLER_FUNC(mod_access_uri_handler) {
- plugin_data *p = p_d;
- int s_len;
-@@ -122,28 +131,41 @@
- s_len = con->uri.path->used - 1;
+ #else
++int mod_magnet_plugin_init(plugin *p);
+ int mod_magnet_plugin_init(plugin *p) {
+ UNUSED(p);
+ return -1;
+Index: src/log.c
+===================================================================
+--- src/log.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/log.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -54,13 +54,94 @@
+ return (tmpfd != -1) ? 0 : -1;
+ }
-+ if (con->conf.log_request_handling) {
-+ log_error_write(srv, __FILE__, __LINE__, "s",
-+ "-- mod_access_uri_handler called");
-+ }
++int open_logfile_or_pipe(server *srv, const char* logfile) {
++ int fd;
+
- for (k = 0; k < p->conf.access_deny->used; k++) {
- data_string *ds = (data_string *)p->conf.access_deny->data[k];
- int ct_len = ds->value->used - 1;
-+ int denied = 0;
-
++ if (logfile[0] == '|') {
++#ifdef HAVE_FORK
++ /* create write pipe and spawn process */
+
- if (ct_len > s_len) continue;
--
- if (ds->value->used == 0) continue;
-
- /* if we have a case-insensitive FS we have to lower-case the URI here too */
-
- if (con->conf.force_lowercase_filenames) {
- if (0 == strncasecmp(con->uri.path->ptr + s_len - ct_len, ds->value->ptr, ct_len)) {
-- con->http_status = 403;
--
-- return HANDLER_FINISHED;
-+ denied = 1;
- }
- } else {
- if (0 == strncmp(con->uri.path->ptr + s_len - ct_len, ds->value->ptr, ct_len)) {
-- con->http_status = 403;
-+ denied = 1;
++ int to_log_fds[2];
++ pid_t pid;
++ int i;
++
++ if (pipe(to_log_fds)) {
++ log_error_write(srv, __FILE__, __LINE__, "ss", "pipe failed: ", strerror(errno));
++ return -1;
++ }
++
++ /* fork, execve */
++ switch (pid = fork()) {
++ case 0:
++ /* child */
++ close(STDIN_FILENO);
++
++ /* dup the filehandle to STDIN */
++ if (to_log_fds[0] != STDIN_FILENO) {
++ if (STDIN_FILENO != dup2(to_log_fds[0], STDIN_FILENO)) {
++ log_error_write(srv, __FILE__, __LINE__, "ss",
++ "dup2 failed: ", strerror(errno));
++ exit(-1);
++ }
++ close(to_log_fds[0]);
++ }
++ close(to_log_fds[1]);
++
++#ifndef FD_CLOEXEC
++ /* we don't need the client socket */
++ for (i = 3; i < 256; i++) {
++ close(i);
+ }
++#endif
++
++ /* close old stderr */
++ openDevNull(STDERR_FILENO);
++
++ /* exec the log-process (skip the | ) */
++ execl("/bin/sh", "sh", "-c", logfile + 1, NULL);
++ log_error_write(srv, __FILE__, __LINE__, "sss",
++ "spawning log process failed: ", strerror(errno),
++ logfile + 1);
++
++ exit(-1);
++ break;
++ case -1:
++ /* error */
++ log_error_write(srv, __FILE__, __LINE__, "ss", "fork failed: ", strerror(errno));
++ return -1;
++ default:
++ close(to_log_fds[0]);
++ fd = to_log_fds[1];
++ break;
+ }
-
-- return HANDLER_FINISHED;
-+ if (denied) {
-+ con->http_status = 403;
+
-+ if (con->conf.log_request_handling) {
-+ log_error_write(srv, __FILE__, __LINE__, "sb",
-+ "url denied as we match:", ds->value);
- }
++#else
++ return -1;
++#endif
++ } else if (-1 == (fd = open(logfile, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) {
++ log_error_write(srv, __FILE__, __LINE__, "SSSS",
++ "opening errorlog '", logfile,
++ "' failed: ", strerror(errno));
++
++ return -1;
++ }
++
++#ifdef FD_CLOEXEC
++ fcntl(fd, F_SETFD, FD_CLOEXEC);
++#endif
++
++ return fd;
++}
+
-+ return HANDLER_FINISHED;
++
+ /**
+ * open the errorlog
+ *
+- * we have 3 possibilities:
++ * we have 4 possibilities:
+ * - stderr (default)
+ * - syslog
+ * - logfile
++ * - pipe
+ *
+ * if the open failed, report to the user and die
+ *
+@@ -80,18 +161,10 @@
+ } else if (!buffer_is_empty(srv->srvconf.errorlog_file)) {
+ const char *logfile = srv->srvconf.errorlog_file->ptr;
+
+- if (-1 == (srv->errorlog_fd = open(logfile, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) {
+- log_error_write(srv, __FILE__, __LINE__, "SSSS",
+- "opening errorlog '", logfile,
+- "' failed: ", strerror(errno));
+-
++ if (-1 == (srv->errorlog_fd = open_logfile_or_pipe(srv, logfile))) {
+ return -1;
}
+-#ifdef FD_CLOEXEC
+- /* close fd on exec (cgi) */
+- fcntl(srv->errorlog_fd, F_SETFD, FD_CLOEXEC);
+-#endif
+- srv->errorlog_mode = ERRORLOG_FILE;
++ srv->errorlog_mode = (logfile[0] == '|') ? ERRORLOG_PIPE : ERRORLOG_FILE;
}
-@@ -158,7 +180,8 @@
+ log_error_write(srv, __FILE__, __LINE__, "s", "server started");
+@@ -122,7 +195,7 @@
+ */
+
+ int log_error_cycle(server *srv) {
+- /* only cycle if we are not in syslog-mode */
++ /* only cycle if the error log is a file */
+
+ if (srv->errorlog_mode == ERRORLOG_FILE) {
+ const char *logfile = srv->srvconf.errorlog_file->ptr;
+@@ -130,7 +203,7 @@
+
+ int new_fd;
+
+- if (-1 == (new_fd = open(logfile, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) {
++ if (-1 == (new_fd = open_logfile_or_pipe(srv, logfile))) {
+ /* write to old log */
+ log_error_write(srv, __FILE__, __LINE__, "SSSSS",
+ "cycling errorlog '", logfile,
+@@ -158,6 +231,7 @@
+
+ int log_error_close(server *srv) {
+ switch(srv->errorlog_mode) {
++ case ERRORLOG_PIPE:
+ case ERRORLOG_FILE:
+ close(srv->errorlog_fd);
+ break;
+@@ -177,6 +251,7 @@
+ va_list ap;
+
+ switch(srv->errorlog_mode) {
++ case ERRORLOG_PIPE:
+ case ERRORLOG_FILE:
+ case ERRORLOG_STDERR:
+ /* cache the generated timestamp */
+@@ -270,6 +345,7 @@
+ va_end(ap);
+
+ switch(srv->errorlog_mode) {
++ case ERRORLOG_PIPE:
+ case ERRORLOG_FILE:
+ buffer_append_string_len(srv->errorlog_buf, CONST_STR_LEN("\n"));
+ write(srv->errorlog_fd, srv->errorlog_buf->ptr, srv->errorlog_buf->used - 1);
+Index: src/log.h
+===================================================================
+--- src/log.h (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/log.h (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -10,6 +10,8 @@
- p->init = mod_access_init;
- p->set_defaults = mod_access_set_defaults;
-- p->handle_uri_clean = mod_access_uri_handler;
-+ p->handle_uri_clean = mod_access_uri_handler;
-+ p->handle_subrequest_start = mod_access_uri_handler;
- p->cleanup = mod_access_free;
+ #define WP() log_error_write(srv, __FILE__, __LINE__, "");
- p->data = NULL;
-Index: src/mod_accesslog.c
++int open_logfile_or_pipe(server *srv, const char* logfile);
++
+ int log_error_open(server *srv);
+ int log_error_close(server *srv);
+ int log_error_write(server *srv, const char *filename, unsigned int line, const char *fmt, ...);
+Index: src/fdevent.c
===================================================================
---- src/mod_accesslog.c (.../tags/lighttpd-1.4.15) (revision 1880)
-+++ src/mod_accesslog.c (.../branches/lighttpd-1.4.x) (revision 1880)
-@@ -507,7 +507,7 @@
- *
- */
+--- src/fdevent.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ src/fdevent.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -92,7 +92,7 @@
+ return 0;
+ }
-- execl("/bin/sh", "sh", "-c", s->access_logfile->ptr + 1, NULL);
-+ execl("/bin/sh", "sh", "-c", s->access_logfile->ptr + 1, (char *)NULL);
+-fdnode *fdnode_init() {
++static fdnode *fdnode_init() {
+ fdnode *fdn;
- log_error_write(srv, __FILE__, __LINE__, "sss",
- "spawning log-process failed: ", strerror(errno),
-Index: src/server.c
+ fdn = calloc(1, sizeof(*fdn));
+@@ -100,7 +100,7 @@
+ return fdn;
+ }
+
+-void fdnode_free(fdnode *fdn) {
++static void fdnode_free(fdnode *fdn) {
+ free(fdn);
+ }
+
+Index: tests/fcgi-responder.c
===================================================================
---- src/server.c (.../tags/lighttpd-1.4.15) (revision 1880)
-+++ src/server.c (.../branches/lighttpd-1.4.x) (revision 1880)
-@@ -775,6 +775,22 @@
- return -1;
+--- tests/fcgi-responder.c (.../tags/lighttpd-1.4.22) (revision 2504)
++++ tests/fcgi-responder.c (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -40,7 +40,13 @@
+ printf("Status: 500 Internal Foo\r\n\r\n");
}
-+ /**
-+ * we are not root can can't increase the fd-limit, but we can reduce it
-+ */
-+ if (srv->srvconf.max_fds && srv->srvconf.max_fds < rlim.rlim_cur) {
-+ /* set rlimits */
-+
-+ rlim.rlim_cur = srv->srvconf.max_fds;
-+
-+ if (0 != setrlimit(RLIMIT_NOFILE, &rlim)) {
-+ log_error_write(srv, __FILE__, __LINE__,
-+ "ss", "couldn't set 'max filedescriptors'",
-+ strerror(errno));
-+ return -1;
-+ }
+- printf("test123");
++ if (0 == strcmp(p, "path_info")) {
++ printf("%s", getenv("PATH_INFO"));
++ } else if (0 == strcmp(p, "script_name")) {
++ printf("%s", getenv("SCRIPT_NAME"));
++ } else {
++ printf("test123");
+ }
-+
- if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
- srv->max_fds = rlim.rlim_cur < FD_SETSIZE - 200 ? rlim.rlim_cur : FD_SETSIZE - 200;
- } else {
-Index: src/proc_open.c
-===================================================================
---- src/proc_open.c (.../tags/lighttpd-1.4.15) (revision 1880)
-+++ src/proc_open.c (.../branches/lighttpd-1.4.x) (revision 1880)
-@@ -255,7 +255,7 @@
- */
- proc_close_parents(proc);
-
-- execl(shell, shell, "-c", command, NULL);
-+ execl(shell, shell, "-c", command, (char *)NULL);
- _exit(127);
+ }
- } else if (child < 0) {
-Index: tests/mod-auth.t
+ return 0;
+Index: tests/mod-fastcgi.t
===================================================================
---- tests/mod-auth.t (.../tags/lighttpd-1.4.15) (revision 1880)
-+++ tests/mod-auth.t (.../branches/lighttpd-1.4.x) (revision 1880)
-@@ -8,7 +8,7 @@
+--- tests/mod-fastcgi.t (.../tags/lighttpd-1.4.22) (revision 2504)
++++ tests/mod-fastcgi.t (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -7,7 +7,7 @@
+ }
use strict;
- use IO::Socket;
--use Test::More tests => 10;
-+use Test::More tests => 13;
+-use Test::More tests => 50;
++use Test::More tests => 52;
use LightyTest;
my $tf = LightyTest->new();
-@@ -93,7 +93,44 @@
- $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
- ok($tf->handle_http($t) == 0, 'Digest-Auth: missing nc (noncecount instead), no crash');
+@@ -166,7 +166,7 @@
+ $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '/foo/bar' } ];
+ ok($tf->handle_http($t) == 0, 'PATH_INFO, check-local off');
-+$t->{REQUEST} = ( <<EOF
-+GET /server-status HTTP/1.0
-+Authorization: Basic =
-+EOF
-+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 401 } ];
-+ok($tf->handle_http($t) == 0, 'Basic-Auth: Invalid Base64');
-
-
-+$t->{REQUEST} = ( <<EOF
-+GET /server-status HTTP/1.0
-+User-Agent: Wget/1.9.1
-+Authorization: Digest username="jan", realm="jan",
-+ nonce="b1d12348b4620437c43dd61c50ae4639", algorithm="md5-sess",
-+ uri="/MJ-BONG.xm.mpc", qop=auth, noncecount=00000001",
-+ cnonce="036FCA5B86F7E7C4965C7F9B8FE714B7",
-+ nc="asd",
-+ response="29B32C2953C763C6D033C8A49983B87E"
+-
++
+ ok($tf->stop_proc == 0, "Stopping lighttpd");
+
+
+@@ -282,7 +282,7 @@
+
+
+ SKIP: {
+- skip "no fcgi-responder found", 9 unless -x $tf->{BASEDIR}."/tests/fcgi-responder" || -x $tf->{BASEDIR}."/tests/fcgi-responder.exe";
++ skip "no fcgi-responder found", 11 unless -x $tf->{BASEDIR}."/tests/fcgi-responder" || -x $tf->{BASEDIR}."/tests/fcgi-responder.exe";
+
+ $tf->{CONFIGFILE} = 'fastcgi-responder.conf';
+ ok($tf->start_proc == 0, "Starting lighttpd with $tf->{CONFIGFILE}") or die();
+@@ -319,6 +319,23 @@
+ ok($tf->handle_http($t) == 0, 'line-ending \r\n + \r\n');
+
+ $t->{REQUEST} = ( <<EOF
++GET /abc/def/ghi?path_info HTTP/1.0
++Host: wsgi.example.org
+EOF
+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 401 } ];
-+ok($tf->handle_http($t) == 0, 'Digest-Auth: md5-sess + missing cnonce');
-+
-+$t->{REQUEST} = ( <<EOF
-+GET /server-status HTTP/1.0
-+User-Agent: Wget/1.9.1
-+Authorization: Digest username="jan", realm="jan",
-+ nonce="b1d12348b4620437c43dd61c50ae4639", algorithm="md5-sess",
-+ uri="/MJ-BONG.xm.mpc", qop=auth, noncecount=00000001",
-+ cnonce="036FCA5B86F7E7C4965C7F9B8FE714B7",
-+ nc="asd",
-+ response="29B32C2953C763C6D033C8A49983B87E"
++ $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '/abc/def/ghi' } ];
++ ok($tf->handle_http($t) == 0, 'PATH_INFO (wsgi)');
++
++ $t->{REQUEST} = ( <<EOF
++GET /abc/def/ghi?script_name HTTP/1.0
++Host: wsgi.example.org
+EOF
+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 401 } ];
-+ok($tf->handle_http($t) == 0, 'Digest-Auth: trailing WS');
++ $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '' } ];
++ ok($tf->handle_http($t) == 0, 'SCRIPT_NAME (wsgi)');
++
++
++ $t->{REQUEST} = ( <<EOF
+ GET /index.fcgi?die-at-end HTTP/1.0
+ Host: www.example.org
+ EOF
+Index: tests/fastcgi-responder.conf
+===================================================================
+--- tests/fastcgi-responder.conf (.../tags/lighttpd-1.4.22) (revision 2504)
++++ tests/fastcgi-responder.conf (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -159,3 +159,15 @@
+ server.name = "zzz.example.org"
+ }
+
++$HTTP["host"] == "wsgi.example.org" {
++ fastcgi.server = (
++ "/" =>
++ ( (
++ "host" => "127.0.0.1", "port" => 10000,
++ "fix-root-scriptname" => "enable",
++ "check-local" => "disable",
++ "bin-path" => env.SRCDIR + "/fcgi-responder",
++ "max-procs" => 1,
++ ) ),
++ )
++}
+Index: tests/LightyTest.pm
+===================================================================
+--- tests/LightyTest.pm (.../tags/lighttpd-1.4.22) (revision 2504)
++++ tests/LightyTest.pm (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -6,7 +6,8 @@
+ use Test::More;
+ use Socket;
+ use Cwd 'abs_path';
+-use POSIX ":sys_wait_h";
++use POSIX qw(:sys_wait_h dup2);
++use Errno qw(EADDRINUSE);
+
+ sub mtime {
+ my $file = shift;
+@@ -344,8 +345,14 @@
+ return -1;
+ }
+ if ($child == 0) {
+- my $cmd = $self->{BINDIR}.'/spawn-fcgi -n -p '.$port.' -f "'.$binary.'"';
+- exec $cmd or die($?);
++ my $iaddr = inet_aton('localhost') || die "no host: localhost";
++ my $proto = getprotobyname('tcp');
++ socket(SOCK, PF_INET, SOCK_STREAM, $proto) || die "socket: $!";
++ setsockopt(SOCK, SOL_SOCKET, SO_REUSEADDR, pack("l", 1)) || die "setsockopt: $!";
++ bind(SOCK, sockaddr_in($port, $iaddr)) || die "bind: $!";
++ listen(SOCK, 1024) || die "listen: $!";
++ dup2(fileno(SOCK), 0) || die "dup2: $!";
++ exec $binary or die($?);
+ } else {
+ if (0 != $self->wait_for_port_with_proc($port, $child)) {
+ diag(sprintf('The process %i is not up (port %i, %s)', $child, $port, $binary));
+Index: configure.ac
+===================================================================
+--- configure.ac (.../tags/lighttpd-1.4.22) (revision 0)
++++ configure.ac (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -0,0 +1,714 @@
++# -*- Autoconf -*-
++# Process this file with autoconf to produce a configure script.
++AC_PREREQ(2.57)
++AC_INIT([lighttpd], [1.4.23], [contact@lighttpd.net])
++AC_CONFIG_SRCDIR([src/server.c])
++AC_CONFIG_HEADER([config.h])
++
++AC_CANONICAL_TARGET
++
++AM_INIT_AUTOMAKE
++
++# Checks for programs.
++AC_PROG_CC
++AM_PROG_CC_C_O
++AC_PROG_LD
++AC_PROG_INSTALL
++AC_PROG_AWK
++AC_PROG_CPP
++dnl AC_PROG_CXX
++AC_PROG_LN_S
++AC_PROG_MAKE_SET
++
++dnl check environment
++AC_AIX
++AC_ISC_POSIX
++AC_MINIX
++
++dnl AC_CANONICAL_HOST
++case $host_os in
++ *darwin*|*cygwin*|*aix*|*mingw* ) NO_RDYNAMIC=yes;;
++ * ) NO_RDYNAMIC=no;;
++esac
++AM_CONDITIONAL(NO_RDYNAMIC, test x$NO_RDYNAMIC = xyes)
++
++AC_EXEEXT
++
++dnl more automake stuff
++AM_C_PROTOTYPES
++
++dnl libtool
++AC_DISABLE_STATIC
++AC_ENABLE_SHARED
++
++AC_LIBTOOL_DLOPEN
++AC_PROG_LIBTOOL
++
++dnl for solaris
++CPPFLAGS="${CPPFLAGS} -D_REENTRANT -D__EXTENSIONS__"
++
++# Checks for header files.
++AC_HEADER_STDC
++AC_HEADER_SYS_WAIT
++AC_CHECK_HEADERS([arpa/inet.h fcntl.h netinet/in.h stdlib.h string.h \
++sys/socket.h sys/time.h unistd.h sys/sendfile.h sys/uio.h \
++getopt.h sys/epoll.h sys/select.h poll.h sys/poll.h sys/devpoll.h sys/filio.h \
++sys/mman.h sys/event.h sys/port.h pwd.h sys/syslimits.h \
++sys/resource.h sys/un.h syslog.h sys/prctl.h uuid/uuid.h])
++
++# Checks for typedefs, structures, and compiler characteristics.
++AC_C_CONST
++AC_C_INLINE
++AC_C_CHAR_UNSIGNED
++AC_TYPE_OFF_T
++AC_TYPE_PID_T
++AC_TYPE_SIZE_T
++
++AC_CHECK_MEMBER(struct tm.tm_gmtoff,[AC_DEFINE([HAVE_STRUCT_TM_GMTOFF],[1],[gmtoff in struct tm])],,[#include <time.h>])
++AC_CHECK_TYPES(struct sockaddr_storage,,,[#include <sys/socket.h>])
++AC_CHECK_TYPES(socklen_t,,,[#include <sys/types.h>
++#include <sys/socket.h>])
++
++# Checks for library functions.
++AC_FUNC_FORK
++dnl AC_FUNC_MALLOC
++#AC_FUNC_MMAP
++dnl AC_FUNC_REALLOC
++AC_TYPE_SIGNAL
++AC_FUNC_STAT
++AC_FUNC_STRFTIME
++AC_CHECK_FUNCS([issetugid inet_pton])
++
++dnl Checks for database.
++MYSQL_INCLUDE=""
++MYSQL_LIBS=""
++
++AC_MSG_CHECKING(for MySQL support)
++AC_ARG_WITH(mysql,
++ AC_HELP_STRING([--with-mysql@<:@=PATH@:>@],[Include MySQL support. PATH is the path to 'mysql_config']),
++ [WITH_MYSQL=$withval],[WITH_MYSQL=no])
++
++if test "$WITH_MYSQL" != "no"; then
++ AC_MSG_RESULT(yes)
++ if test "$WITH_MYSQL" = "yes"; then
++ AC_PATH_PROG(MYSQL_CONFIG, mysql_config)
++ else
++ MYSQL_CONFIG=$WITH_MYSQL
++ fi
++
++ if test "$MYSQL_CONFIG" = ""; then
++ AC_MSG_ERROR(mysql_config is not found)
++ fi
++ if test \! -x $MYSQL_CONFIG; then
++ AC_MSG_ERROR(mysql_config not exists or not executable, use --with-mysql=path-to-mysql_config)
++ fi
++
++ if $MYSQL_CONFIG | grep -- '--include' > /dev/null ; then
++ MYSQL_INCLUDE="`$MYSQL_CONFIG --include | sed s/\'//g`"
++ else
++ MYSQL_INCLUDE="`$MYSQL_CONFIG --cflags | sed s/\'//g`"
++ fi
++ MYSQL_LIBS="`$MYSQL_CONFIG --libs | sed s/\'//g`"
++
++ AC_MSG_CHECKING(for MySQL includes at)
++ AC_MSG_RESULT($MYSQL_INCLUDE)
++
++ AC_MSG_CHECKING(for MySQL libraries at)
++ AC_MSG_RESULT($MYSQL_LIBS)
++dnl check for errmsg.h, which isn't installed by some versions of 3.21
++ old_CPPFLAGS="$CPPFLAGS"
++ CPPFLAGS="$CPPFLAGS $MYSQL_INCLUDE"
++ AC_CHECK_HEADERS(errmsg.h mysql.h)
++ CPPFLAGS="$old_CPPFLAGS"
++
++ AC_DEFINE([HAVE_MYSQL], [1], [mysql support])
++else
++ AC_MSG_RESULT(no)
++fi
++
++AC_SUBST(MYSQL_LIBS)
++AC_SUBST(MYSQL_INCLUDE)
++
++dnl Check for LDAP
++AC_MSG_CHECKING(for LDAP support)
++AC_ARG_WITH(ldap, AC_HELP_STRING([--with-ldap],[enable LDAP support]),
++[WITH_LDAP=$withval], [WITH_LDAP=no])
++AC_MSG_RESULT([$withval])
++if test "$WITH_LDAP" != "no"; then
++ AC_CHECK_LIB(ldap, ldap_bind, [
++ AC_CHECK_HEADERS([ldap.h],[
++ LDAP_LIB=-lldap
++ AC_DEFINE([HAVE_LIBLDAP], [1], [libldap])
++ AC_DEFINE([HAVE_LDAP_H], [1])
++ AC_DEFINE([LDAP_DEPRECATED], [1], [Using deprecated ldap api])
++ ])
++ ])
++ AC_SUBST(LDAP_LIB)
++ AC_CHECK_LIB(lber, ber_printf, [
++ AC_CHECK_HEADERS([lber.h],[
++ LBER_LIB=-llber
++ AC_DEFINE([HAVE_LIBLBER], [1], [liblber])
++ AC_DEFINE([HAVE_LBER_H], [1])
++ ])
++ ])
++ AC_SUBST(LBER_LIB)
++fi
+
++dnl Check for xattr
++AC_MSG_CHECKING(for extended attributes support)
++AC_ARG_WITH(attr, AC_HELP_STRING([--with-attr],[enable extended attribute support]),
++[WITH_ATTR=$withval],[WITH_ATTR=no])
++AC_MSG_RESULT($withval)
++if test "$WITH_ATTR" != "no"; then
++ AC_CHECK_LIB(attr, attr_get, [
++ AC_CHECK_HEADERS([attr/attributes.h],[
++ ATTR_LIB=-lattr
++ AC_DEFINE([HAVE_XATTR], [1], [libattr])
++ AC_DEFINE([HAVE_ATTR_ATTRIBUTES_H], [1])
++ ])
++ ])
++ AC_SUBST(ATTR_LIB)
++fi
+
++## openssl on solaris needs -lsocket -lnsl
++AC_SEARCH_LIBS(socket,socket)
++AC_SEARCH_LIBS(gethostbyname,nsl socket)
++AC_SEARCH_LIBS(hstrerror,resolv)
+
- ok($tf->stop_proc == 0, "Stopping lighttpd");
++save_LIBS=$LIBS
++AC_SEARCH_LIBS(dlopen,dl,[
++ AC_CHECK_HEADERS([dlfcn.h],[
++ if test "$ac_cv_search_dlopen" != no; then
++ test "$ac_cv_search_dlopen" = "none required" || DL_LIB="$ac_cv_search_dlopen"
++ fi
++
++ AC_DEFINE([HAVE_LIBDL], [1], [libdl])
++ AC_DEFINE([HAVE_DLFCN_H], [1])
++ ])
++])
++LIBS=$save_LIBS
++AC_SUBST(DL_LIB)
++
++dnl Check for valgrind
++AC_MSG_CHECKING(for valgrind)
++AC_ARG_WITH(valgrind, AC_HELP_STRING([--with-valgrind],[enable internal support for valgrind]),
++[WITH_VALGRIND=$withval],[WITH_VALGRIND=no])
++AC_MSG_RESULT([$WITH_VALGRIND])
++if test "$WITH_VALGRIND" != "no"; then
++ AC_CHECK_HEADERS([valgrind/valgrind.h])
++fi
++
++dnl Check for openssl
++AC_MSG_CHECKING(for OpenSSL)
++AC_ARG_WITH(openssl,
++ AC_HELP_STRING([--with-openssl@<:@=DIR@:>@],[Include openssl support (default no)]),
++ [WITH_OPENSSL=$withval],[WITH_OPENSSL=no])
++
++if test "$WITH_OPENSSL" != "no"; then
++ use_openssl=yes
++ if test "$WITH_OPENSSL" != "yes"; then
++ CPPFLAGS="$CPPFLAGS -I$WITH_OPENSSL/include"
++ LDFLAGS="$LDFLAGS -L$WITH_OPENSSL/lib"
++ fi
++else
++ use_openssl=no
++fi
++AC_MSG_RESULT([$use_openssl])
++
++AC_ARG_WITH(openssl-includes,
++ AC_HELP_STRING([--with-openssl-includes=DIR],[OpenSSL includes]),
++ [ use_openssl=yes CPPFLAGS="$CPPFLAGS -I$withval" ]
++)
++
++AC_ARG_WITH(openssl-libs,
++ AC_HELP_STRING([--with-openssl-libs=DIR],[OpenSSL libraries]),
++ [ use_openssl=yes LDFLAGS="$LDFLAGS -L$withval" ]
++)
++
++AC_ARG_WITH(kerberos5,
++ AC_HELP_STRING([--with-kerberos5],[use Kerberos5 support with OpenSSL]),
++ [ use_kerberos=yes ], [use_kerberos=no]
++)
++
++if test "x$use_openssl" = "xyes"; then
++ if test "x$use_kerberos" != "xyes"; then
++ CPPFLAGS="$CPPFLAGS -DOPENSSL_NO_KRB5"
++ fi
++
++ AC_CHECK_HEADERS([openssl/ssl.h])
++ OLDLIBS="$LIBS"
++ AC_CHECK_LIB(crypto, BIO_f_base64, [
++ AC_CHECK_LIB(ssl, SSL_new, [ SSL_LIB="-lssl -lcrypto"
++ AC_DEFINE(HAVE_LIBSSL, [], [Have libssl]) ], [], [ -lcrypto "$DL_LIB" ])
++ ], [], [])
++ LIBS="$OLDLIBS"
++ AC_SUBST(SSL_LIB)
++fi
++
++AC_MSG_CHECKING(for perl regular expressions support)
++AC_ARG_WITH(pcre, AC_HELP_STRING([--with-pcre],[Enable pcre support (default yes)]),
++ [WITH_PCRE=$withval],[WITH_PCRE=yes])
++AC_MSG_RESULT([$WITH_PCRE])
++
++if test "x$cross_compiling" = xno -a "$WITH_PCRE" != "no"; then
++ AC_PATH_PROG(PCRECONFIG, pcre-config)
++
++ if test x"$PCRECONFIG" != x; then
++ PCRE_LIB=`$PCRECONFIG --libs`
++ CPPFLAGS="$CPPFLAGS `$PCRECONFIG --cflags`"
++ AC_DEFINE([HAVE_LIBPCRE], [1], [libpcre])
++ AC_DEFINE([HAVE_PCRE_H], [1], [pcre.h])
++ else
++ AC_MSG_ERROR([pcre-config not found, install the pcre-devel package or build with --without-pcre])
++ fi
++fi
++
++AC_SUBST(PCRE_LIB)
++
++AC_MSG_CHECKING(for zlib support)
++AC_ARG_WITH(zlib, AC_HELP_STRING([--with-zlib],[Enable zlib support for mod_compress]),
++ [WITH_ZLIB=$withval],[WITH_ZLIB=yes])
++AC_MSG_RESULT([$WITH_ZLIB])
++
++if test "$WITH_ZLIB" != "no"; then
++ AC_CHECK_LIB(z, deflate, [
++ AC_CHECK_HEADERS([zlib.h],[
++ Z_LIB=-lz
++ AC_DEFINE([HAVE_LIBZ], [1], [libz])
++ AC_DEFINE([HAVE_ZLIB_H], [1])
++ ])
++ ])
++ if test x$Z_LIB = x; then
++ AC_MSG_ERROR([zlib-headers and/or libs where not found, install them or build with --without-zlib])
++ fi
++fi
++AC_SUBST(Z_LIB)
++
++AC_MSG_CHECKING(for bzip2 support)
++AC_ARG_WITH(bzip2, AC_HELP_STRING([--with-bzip2],[Enable bzip2 support for mod_compress]),
++ [WITH_BZIP2=$withval],[WITH_BZIP2=yes])
++AC_MSG_RESULT([$WITH_BZIP2])
++
++if test "$WITH_BZIP2" != "no"; then
++ AC_CHECK_LIB(bz2, BZ2_bzCompress, [
++ AC_CHECK_HEADERS([bzlib.h],[
++ BZ_LIB=-lbz2
++ AC_DEFINE([HAVE_LIBBZ2], [1], [libbz2])
++ AC_DEFINE([HAVE_BZLIB_H], [1])
++ ])
++ ])
++ if test x$BZ_LIB = x; then
++ AC_MSG_ERROR([bzip2-headers and/or libs where not found, install them or build with --without-bzip2])
++ fi
++fi
++AC_SUBST(BZ_LIB)
++
++if test -z "$PKG_CONFIG"; then
++ AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
++fi
++
++dnl Check for gamin
++AC_MSG_CHECKING(for FAM)
++AC_ARG_WITH(fam, AC_HELP_STRING([--with-fam],[fam/gamin for reducing number of stat() calls]),
++[WITH_FAM=$withval],[WITH_FAM=no])
++AC_MSG_RESULT([$WITH_FAM])
++
++if test "$WITH_FAM" != "no"; then
++ AC_CHECK_LIB(fam, FAMOpen2, [
++ AC_CHECK_HEADERS([fam.h],[
++ FAM_LIBS=-lfam
++ AC_DEFINE([HAVE_LIBFAM], [1], [libfam])
++ AC_DEFINE([HAVE_FAM_H], [1], [fam.h])
++ ])
++ ])
++ if test "x$FAM_LIBS" = x; then
++ PKG_CHECK_MODULES(FAM, gamin >= 0.1.0, [
++ AC_DEFINE([HAVE_LIBFAM], [1], [libfam])
++ AC_DEFINE([HAVE_FAM_H], [1], [fam.h])
++ ])
++ fi
++ OLD_LIBS=$LIBS
++ LIBS=$FAM_LIBS
++ AC_CHECK_FUNCS([FAMNoExists])
++ LIBS=$OLD_LIBS
++
++ if test x$FAM_LIBS = x; then
++ AC_MSG_ERROR([fam/gamin-headers and/or libs where not found, install them or build with --without-fam])
++ fi
++fi
++
++AC_MSG_CHECKING(for properties in mod_webdav)
++AC_ARG_WITH(webdav-props, AC_HELP_STRING([--with-webdav-props],[properties in mod_webdav]),
++[WITH_WEBDAV_PROPS=$withval],[WITH_WEBDAV_PROPS=no])
++AC_MSG_RESULT([$WITH_WEBDAV_PROPS])
++
++if test "$WITH_WEBDAV_PROPS" != "no"; then
++ PKG_CHECK_MODULES(XML, libxml-2.0, [
++ AC_DEFINE([HAVE_LIBXML2], [1], [libxml2])
++ AC_DEFINE([HAVE_LIBXML_H], [1], [libxml.h])
++ ])
++ PKG_CHECK_MODULES(SQLITE, sqlite3, [
++ AC_DEFINE([HAVE_SQLITE3], [1], [libsqlite3])
++ AC_DEFINE([HAVE_SQLITE3_H], [1], [sqlite3.h])
++ ])
++
++ AC_MSG_CHECKING(for locks in mod_webdav)
++ AC_ARG_WITH(webdav-locks, AC_HELP_STRING([--with-webdav-locks],[locks in mod_webdav]),
++ [WITH_WEBDAV_LOCKS=$withval],[WITH_WEBDAV_LOCKS=no])
++ AC_MSG_RESULT([$WITH_WEBDAV_LOCKS])
++
++ if test "$WITH_WEBDAV_LOCKS" != "no"; then
++ AC_CHECK_LIB(uuid, uuid_unparse, [
++ AC_CHECK_HEADERS([uuid/uuid.h],[
++ UUID_LIBS=-luuid
++ AC_DEFINE([HAVE_UUID], [1], [libuuid])
++ AC_DEFINE([HAVE_UUID_H], [1], [uuid/uuid.h is available])
++ ])
++ ])
++
++ fi
++fi
++AC_SUBST(UUID_LIBS)
++
++dnl Check for gdbm
++AC_MSG_CHECKING(for gdbm)
++AC_ARG_WITH(gdbm, AC_HELP_STRING([--with-gdbm],[gdbm storage for mod_trigger_b4_dl]),
++[WITH_GDBM=$withval],[WITH_GDBM=no])
++AC_MSG_RESULT([$WITH_GDBM])
++
++if test "$WITH_GDBM" != "no"; then
++ AC_CHECK_LIB(gdbm, gdbm_open, [
++ AC_CHECK_HEADERS([gdbm.h],[
++ GDBM_LIB=-lgdbm
++ AC_DEFINE([HAVE_GDBM], [1], [libgdbm])
++ AC_DEFINE([HAVE_GDBM_H], [1])
++ ])
++ ])
++ AC_SUBST(GDBM_LIB)
++fi
++
++dnl Check for memcache
++AC_MSG_CHECKING(for memcache)
++AC_ARG_WITH(memcache, AC_HELP_STRING([--with-memcache],[memcached storage for mod_trigger_b4_dl]),
++[WITH_MEMCACHE=$withval],[WITH_MEMCACHE=no])
++AC_MSG_RESULT([$WITH_MEMCACHE])
++if test "$WITH_MEMCACHE" != "no"; then
++ AC_CHECK_LIB(memcache, mc_new, [
++ AC_CHECK_HEADERS([memcache.h],[
++ MEMCACHE_LIB=-lmemcache
++ AC_DEFINE([HAVE_MEMCACHE], [1], [libmemcache])
++ AC_DEFINE([HAVE_MEMCACHE_H], [1], [memcache.h])
++ ])
++ ])
++ AC_SUBST(MEMCACHE_LIB)
++fi
++
++dnl Check for lua
++AC_MSG_CHECKING(if lua-support is requested)
++AC_ARG_WITH(lua, AC_HELP_STRING([--with-lua],[lua engine for mod_cml]),
++[WITH_LUA=$withval],[WITH_LUA=no])
++
++AC_MSG_RESULT($WITH_LUA)
++if test "$WITH_LUA" != "no"; then
++ if test "$WITH_LUA" = "yes"; then
++ WITH_LUA=lua
++ fi
++ PKG_CHECK_MODULES(LUA, $WITH_LUA >= 5.1, [
++ AC_DEFINE([HAVE_LUA], [1], [liblua])
++ AC_DEFINE([HAVE_LUA_H], [1], [lua.h])
++ ],[
++ # for debian based systems
++ PKG_CHECK_MODULES(LUA, lua5.1 >= 5.1, [
++ AC_DEFINE([HAVE_LUA], [1], [liblua])
++ AC_DEFINE([HAVE_LUA_H], [1], [lua.h])
++ ])
++ ])
++
++ AC_SUBST(LUA_CFLAGS)
++ AC_SUBST(LUA_LIBS)
++fi
++
++save_LIBS=$LIBS
++AC_SEARCH_LIBS(crypt,crypt,[
++ AC_CHECK_HEADERS([crypt.h],[
++ AC_DEFINE([HAVE_CRYPT_H], [1])
++ ])
++
++ AC_DEFINE([HAVE_LIBCRYPT], [1], [libcrypt])
++ if test "$ac_cv_search_crypt" != no; then
++ test "$ac_cv_search_crypt" = "none required" || CRYPT_LIB="$ac_cv_search_crypt"
++ fi
++])
++LIBS=$save_LIBS
++AC_SUBST(CRYPT_LIB)
++
++save_LIBS=$LIBS
++AC_SEARCH_LIBS(sendfilev,sendfile,[
++ if test "$ac_cv_search_sendfilev" != no; then
++ test "$ac_cv_search_sendfilev" = "none required" || SENDFILE_LIB="$ac_cv_search_sendfilev"
++ AC_DEFINE([HAVE_SENDFILEV], [1], [solaris sendfilev])
++ fi
++])
++LIBS=$save_LIBS
++AC_SUBST(SENDFILE_LIB)
++
++case $host_os in
++ *mingw* ) LIBS="$LIBS -lwsock32";;
++ * ) ;;
++esac
++
++AC_CHECK_FUNCS([dup2 getcwd inet_ntoa inet_ntop memset mmap munmap strchr \
++ strdup strerror strstr strtol sendfile getopt socket lstat \
++ gethostbyname poll sigtimedwait epoll_ctl getrlimit chroot \
++ getuid select signal pathconf madvise posix_fadvise posix_madvise \
++ writev sigaction sendfile64 send_file kqueue port_create localtime_r gmtime_r])
++
++AC_MSG_CHECKING(for Large File System support)
++AC_ARG_ENABLE(lfs,
++ AC_HELP_STRING([--enable-lfs],[Turn on Large File System (default)]),
++ [case "${enableval}" in
++ yes) CPPFLAGS="${CPPFLAGS} -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGE_FILES" ;;
++ no) ;;
++ *) AC_MSG_ERROR(bad value ${enableval} for --enable-lfs) ;;
++ esac],[CPPFLAGS="${CPPFLAGS} -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGE_FILES"
++ enable_lfs=yes])
++AC_MSG_RESULT($enableval)
++
++AC_CHECK_SIZEOF(long)
++AC_CHECK_SIZEOF(off_t)
++
++if test "x$ac_cv_func_sendfile" = xyes; then
++ # check if sendfile works
++ AC_MSG_CHECKING(if sendfile works)
++ if test "x$cross_compiling" = xno; then
++ AC_TRY_RUN([
++ #ifdef HAVE_SYS_SENDFILE_H
++ #include <sys/sendfile.h>
++ #endif /* HAVE_SYS_SENDFILE_H */
++ #include <errno.h>
++ int main() {
++ int o = 0;
++ if (-1 == sendfile(-1, 0, &o, 0) && errno == ENOSYS) return -1;
++ return 0;
++ } ],
++ AC_MSG_RESULT(yes),
++ [ AC_MSG_RESULT(no)
++ AC_DEFINE([HAVE_SENDFILE_BROKEN], [1], [broken sendfile]) ] )
++ else
++ AC_MSG_RESULT(no, cross-compiling)
++ AC_DEFINE([HAVE_SENDFILE_BROKEN], [1], [broken sendfile])
++ fi
++fi
++
++dnl Check for IPv6 support
++
++AC_ARG_ENABLE(ipv6,
++ AC_HELP_STRING([--disable-ipv6],[disable IPv6 support]),
++ [case "${enableval}" in
++ yes) ipv6=true ;;
++ no) ipv6=false ;;
++ *) AC_MSG_ERROR(bad value ${enableval} for --enable-ipv6) ;;
++ esac],[ipv6=true])
++
++if test x$ipv6 = xtrue; then
++ AC_CACHE_CHECK([for IPv6 support], ac_cv_ipv6_support,
++ [AC_TRY_LINK([ #include <sys/types.h>
++#include <sys/socket.h>
++#include <netinet/in.h>], [struct sockaddr_in6 s; struct in6_addr t=in6addr_any; int i=AF_INET6; s; t.s6_addr[0] = 0; ],
++ [ac_cv_ipv6_support=yes], [ac_cv_ipv6_support=no])])
++
++ if test "$ac_cv_ipv6_support" = yes; then
++ AC_DEFINE(HAVE_IPV6,1,[Whether to enable IPv6 support])
++ fi
++fi
++
++
++AM_CONDITIONAL(CROSS_COMPILING, test "x$cross_compiling" = xyes)
++
++dnl check for fastcgi lib, for the tests only
++fastcgi_found=no
++AC_CHECK_LIB(fcgi, FCGI_Accept, [
++ AC_CHECK_HEADERS([fastcgi.h fastcgi/fastcgi.h],[
++ fastcgi_found=yes
++ ])
++])
++
++AM_CONDITIONAL(CHECK_WITH_FASTCGI, test "x$fastcgi_found" = xyes)
++
++
++# check for extra compiler options (warning options)
++if test "${GCC}" = "yes"; then
++ CFLAGS="${CFLAGS} -Wall -W -Wshadow -pedantic -std=gnu99"
++fi
++
++AC_ARG_ENABLE(extra-warnings,
++ AC_HELP_STRING([--enable-extra-warnings],[enable extra warnings (gcc specific)]),
++ [case "${enableval}" in
++ yes) extrawarnings=true ;;
++ no) extrawarnings=false ;;
++ *) AC_MSG_ERROR(bad value ${enableval} for --enable-extra-warnings) ;;
++ esac],[extrawarnings=false])
++
++if test x$extrawarnings = xtrue; then
++ CFLAGS="${CFLAGS} -g -O2 -g2 -Wall -Wmissing-declarations -Wdeclaration-after-statement -Wno-pointer-sign -Wcast-align -Winline -Wsign-compare -Wnested-externs -Wpointer-arith -Wl,--as-needed -Wformat-security"
++fi
++
++dnl build version-id
++LIGHTTPD_VERSION_ID=`echo $PACKAGE_VERSION | $AWK -F '.' '{print "(" $1 " << 16 | " $2 " << 8 | " $3 ")"}'`
++AC_DEFINE_UNQUOTED([LIGHTTPD_VERSION_ID], [$LIGHTTPD_VERSION_ID], [lighttpd-version-id])
++
++AC_CONFIG_FILES([Makefile src/Makefile doc/Makefile tests/Makefile \
++ tests/docroot/Makefile \
++ tests/docroot/123/Makefile \
++ tests/docroot/www/Makefile \
++ tests/docroot/www/go/Makefile \
++ tests/docroot/www/indexfile/Makefile \
++ tests/docroot/www/expire/Makefile \
++ distribute.sh])
++AC_OUTPUT
++
++
++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"
++do_build="$do_build mod_rrdtool mod_secdownload mod_expire mod_compress mod_dirlisting mod_indexfile mod_userdir mod_webdav mod_staticfile mod_scgi mod_flv_streaming"
++
++plugins="mod_rewrite mod_redirect mod_ssi mod_trigger_b4_dl"
++features="regex-conditionals"
++if test ! "x$PCRE_LIB" = x; then
++ do_build="$do_build $plugins"
++ enable_feature="$features"
++else
++ no_build="$no_build $plugins"
++ disable_feature="$features"
++fi
++
++plugins="mod_mysql_vhost"
++if test ! "x$MYSQL_LIBS" = x; then
++ do_build="$do_build $plugins"
++else
++ no_build="$no_build $plugins"
++fi
++
++plugins="mod_cml mod_magnet"
++if test ! "x$LUA_LIBS" = x; then
++ do_build="$do_build $plugins"
++else
++ no_build="$no_build $plugins"
++fi
++
++features="storage-gdbm"
++if test ! "x$GDBM_LIB" = x; then
++ enable_feature="$enable_feature $features"
++else
++ disable_feature="$disable_feature $features"
++fi
++
++features="storage-memcache"
++if test ! "x$MEMCACHE_LIB" = x; then
++ enable_feature="$enable_feature $features"
++else
++ disable_feature="$disable_feature $features"
++fi
++
++features="compress-gzip compress-deflate"
++if test ! "x$Z_LIB" = x; then
++ enable_feature="$enable_feature $features"
++else
++ disable_feature="$disable_feature $features"
++fi
++
++features="compress-bzip2"
++if test ! "x$BZ_LIB" = x; then
++ enable_feature="$enable_feature $features"
++else
++ disable_feature="$disable_feature $features"
++fi
++
++features="auth-ldap"
++if test ! "x$LDAP_LIB" = x; then
++ enable_feature="$enable_feature $features"
++else
++ disable_feature="$disable_feature $features"
++fi
++
++features="network-openssl"
++if test ! "x$SSL_LIB" = x; then
++ enable_feature="$enable_feature $features"
++else
++ disable_feature="$disable_feature $features"
++fi
++
++# no crypt call
++features="auth-crypt"
++if test "$ac_cv_search_crypt" = no; then
++ disable_feature="$disable_feature $features"
++else
++ enable_feature="$enable_feature $features"
++fi
++
++features="network-ipv6"
++if test "$ac_cv_ipv6_support" = yes; then
++ enable_feature="$enable_feature $features"
++else
++ disable_feature="$disable_feature $features"
++fi
++
++features="large-files"
++if test "$enable_lfs" = yes; then
++ enable_feature="$enable_feature $features"
++else
++ disable_feature="$disable_feature $features"
++fi
++
++features="stat-cache-fam"
++if test ! "x$FAM_LIBS" = x; then
++ enable_feature="$enable_feature $features"
++else
++ disable_feature="$disable_feature $features"
++fi
++
++features="webdav-properties"
++if test "x$XML_LIBS" \!= x -a "x$SQLITE_LIBS" \!= x; then
++ enable_feature="$enable_feature $features"
++else
++ disable_feature="$disable_feature $features"
++fi
++
++features="webdav-locks"
++if test "x$UUID_LIBS" \!= x; then
++ enable_feature="$enable_feature $features"
++else
++ disable_feature="$disable_feature $features"
++fi
++
++
++## output
++
++$ECHO
++$ECHO "Plugins:"
++$ECHO
++
++$ECHO "enabled: "
++for p in $do_build; do
++ $ECHO " $p"
++done | sort
++
++$ECHO "disabled: "
++for p in $no_build; do
++ $ECHO " $p"
++done | sort
++
++$ECHO
++$ECHO "Features:"
++$ECHO
++
++$ECHO "enabled: "
++for p in $enable_feature; do
++ $ECHO " $p"
++done | sort
++
++$ECHO "disabled: "
++for p in $disable_feature; do
++ $ECHO " $p"
++done | sort
++
++$ECHO
+Index: doc/lighttpd.1
+===================================================================
+--- doc/lighttpd.1 (.../tags/lighttpd-1.4.22) (revision 2504)
++++ doc/lighttpd.1 (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -1,18 +0,0 @@
+-.TH LIGHTTPD 1 2003-12-21
+-.SH NAME
+-lighttpd - a fast, secure and flexible webserver
+-.SH SYNOPSIS
+-lighttpd -D -f <configfile>
+-.SH DESCRIPTION
+-.SH FILES
+-/etc/lighttpd/lighttpd.conf
+-.SH CONFORMING TO
+-HTTP/1.0
+-HTTP/1.0
+-HTTP-Authentification - Basic, Digest
+-FastCGI
+-CGI/1.1
+-.SH SEE ALSO
+-spawn-fcgi(1)
+-.SH AUTHOR
+-jan@kneschke.de
+Index: doc/spawn-fcgi.1
+===================================================================
+--- doc/spawn-fcgi.1 (.../tags/lighttpd-1.4.22) (revision 2504)
++++ doc/spawn-fcgi.1 (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -1,13 +0,0 @@
+-.TH SPAWNFCGI 1 2003-12-21
+-.SH NAME
+-spawn-fcgi \- spawning FastCGI processes
+-.SH SYNOPSIS
+-spawn-fcgi -f <fastcgi-binary> [-p <port> | -s <socket>] [-C <num-of-php-procs>] [-c <chroot-dir>] [-u <username>] [-g <groupname>]
+-spawn-fcgi -v
+-spawn-fcgi -h
+-.SH DESCRIPTION
+-spawn-fcgi is used to spawn remote FastCGI processes.
+-.SH SEE ALSO
+-lighttpd(1)
+-.SH AUTHOR
+-jan@kneschke.de
+Index: doc/configuration.txt
+===================================================================
+--- doc/configuration.txt (.../tags/lighttpd-1.4.22) (revision 2504)
++++ doc/configuration.txt (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -281,6 +281,12 @@
+ server.use-ipv6
+ bind to the IPv6 socket
+
++server.defer-accept
++ set TCP_DEFER_ACCEPT to the specified value on the socket if the value is > 0
++ and TCP_DEFER_ACCEPT is available on the platform (linux2.4+)
++
++ default: 0
++
+ server.tag
+ set the string returned by the Server: response header
-Index: tests/mod-access.t
+Index: doc/lighttpd.8
===================================================================
---- tests/mod-access.t (.../tags/lighttpd-1.4.15) (revision 1880)
-+++ tests/mod-access.t (.../branches/lighttpd-1.4.x) (revision 1880)
-@@ -8,7 +8,7 @@
+--- doc/lighttpd.8 (.../tags/lighttpd-1.4.22) (revision 0)
++++ doc/lighttpd.8 (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -0,0 +1,70 @@
++.TH LIGHTTPD "8" "2009-03-07" "" ""
++.
++.SH NAME
++lighttpd \- a fast, secure and flexible web server
++.
++.SH SYNOPSIS
++\fBlighttpd\fP [\fB\-ptDvVh\fP] \fB\-f\fP \fIconfigfile\fP [\fB\-m\fP \fImoduledir\fP]
++.
++.SH DESCRIPTION
++\fBlighttpd\fP (pronounced 'lighty') is an advanced HTTP daemon that aims
++to be secure, fast, compliant and very flexible. It has been optimized for
++high performance. Its feature set includes, but is not limited to, FastCGI,
++CGI, basic and digest HTTP authentication, output compression, URL rewriting.
++.PP
++This manual page only lists the command line arguments. For details
++on how to configure \fBlighttpd\fP and its modules see the files in the
++doc-directory.
++.
++.SH OPTIONS
++The following options are supported:
++.TP 8
++\fB\-f\ \fP \fIconfigfile\fP
++Load configuration file \fIconfigfile\fP.
++.TP 8
++\fB\-m\ \fP \fImoduledir\fP
++Use
++\fImoduledir\fP
++as the directory that contains modules, instead of the default.
++.TP 8
++\fB\-p\fP
++Print the parsed configuration file in its internal form and exit.
++.TP 8
++\fB\-t\fP
++Test the configuration file for syntax errors and exit.
++.TP 8
++\fB\-D\fP
++Do not daemonize (go into background). The default is to daemonize.
++.TP 8
++\fB\-v\fP
++Show version and exit.
++.TP 8
++\fB\-V\fP
++Show compile-time features and exit.
++.TP 8
++\fB\-h\fP
++Show a brief help message and exit.
++.
++.SH FILES
++.TP 8
++/etc/lighttpd/lighttpd.conf
++The standard location for the configuration file.
++.TP 8
++/var/run/lighttpd.pid
++The standard location for the PID of the running \fBlighttpd\fP process.
++.
++.SH SEE ALSO
++Online Documentation: http://wiki.lighttpd.net/
++.PP
++spawn-fcgi(1)
++.PP
++\fIHypertext Transfer Protocol -- HTTP/1.1\fP, RFC 2616.
++.PP
++\fIHTTP Authentication: Basic and Digest Access Authentication\fP, RFC 2617.
++.PP
++\fIThe Common Gateway Interface Version 1.1\fP, RFC 3875.
++.PP
++\fIThe FastCGI specification\fP.
++.
++.SH AUTHOR
++Jan Kneschke <jan@kneschke.de>
+Index: doc/evhost.txt
+===================================================================
+--- doc/evhost.txt (.../tags/lighttpd-1.4.22) (revision 2504)
++++ doc/evhost.txt (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -33,6 +33,7 @@
+ %2 => domain name without tld
+ %3 => subdomain 1 name
+ %4 => subdomain 2 name
++ %_ => the complete hostname (without port info)
- use strict;
- use IO::Socket;
--use Test::More tests => 3;
-+use Test::More tests => 4;
- use LightyTest;
+ evhost.path-pattern = "/home/www/servers/%3/pages/"
- my $tf = LightyTest->new();
-@@ -23,5 +23,12 @@
- $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 403 } ];
- ok($tf->handle_http($t) == 0, 'forbid access to ...~');
+Index: doc/dirlisting.txt
+===================================================================
+--- doc/dirlisting.txt (.../tags/lighttpd-1.4.22) (revision 2504)
++++ doc/dirlisting.txt (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -80,3 +80,47 @@
+ Example: ::
-+$t->{REQUEST} = ( <<EOF
-+GET /index.html~/ HTTP/1.0
-+EOF
-+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 403 } ];
-+ok($tf->handle_http($t) == 0, '#1230 - forbid access to ...~ - trailing slash');
+ dir-listing.encoding = "utf-8"
+
- ok($tf->stop_proc == 0, "Stopping lighttpd");
-
-Index: tests/core-request.t
++dir-listing.show-readme
++ shows README.txt after the dirlisting if it exists in the directory
++
++ Default: disabled
++
++dir-listing.hide-readme-file
++ hides README.txt in the dirlisting
++
++ Default: disabled
++
++dir-listing.show-header
++ shows HEADER.txt before the dirlisting if it exists in the directory
++
++ Default: disabled
++
++dir-listing.hide-header-file
++ hides HEADER.txt in the dirlisting
++
++ Default: disabled
++
++dir-listing.set-footer
++
++ Default: empty, uses server.tag instead
++
++dir-listing.encode-readme
++ encodes all control characers, '&', '<', '>' and '\x7f' as &#x**;
++
++ Default: enabled
++
++dir-listing.encode-header
++ encodes all control characers, '&', '<', '>' and '\x7f' as &#x**;
++
++ Default: enabled
++
++dir-listing.auto-layout
++ Disable this if you want your own html header and footer; specify
++ them in HEADER.txt and README.txt
++
++ you have to enable dir-list.show-readme/header for this of course
++
++ .external-css and .set-footer will be ignored if this is disabled
++
++ Default: enabled
+Index: doc/lighttpd.conf
+===================================================================
+--- doc/lighttpd.conf (.../tags/lighttpd-1.4.22) (revision 2504)
++++ doc/lighttpd.conf (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -16,7 +16,6 @@
+ # "mod_redirect",
+ # "mod_alias",
+ "mod_access",
+-# "mod_cml",
+ # "mod_trigger_b4_dl",
+ # "mod_auth",
+ # "mod_status",
+@@ -35,8 +34,8 @@
+ # "mod_rrdtool",
+ "mod_accesslog" )
+
+-## a static document-root, for virtual-hosting take look at the
+-## server.virtual-* options
++## A static document-root. For virtual hosting take a look at the
++## mod_simple_vhost module.
+ server.document-root = "/srv/www/htdocs/"
+
+ ## where to send error-messages to
+@@ -299,11 +298,6 @@
+ # trigger-before-download.deny-url = "http://127.0.0.1/index.html"
+ # trigger-before-download.trigger-timeout = 10
+
+-## for mod_cml
+-## don't forget to add index.cml to server.indexfiles
+-# cml.extension = ".cml"
+-# cml.memcache-hosts = ( "127.0.0.1:11211" )
+-
+ #### variable usage:
+ ## variable name without "." is auto prefixed by "var." and becomes "var.bar"
+ #bar = 1
+Index: doc/extforward.txt
===================================================================
---- tests/core-request.t (.../tags/lighttpd-1.4.15) (revision 1880)
-+++ tests/core-request.t (.../branches/lighttpd-1.4.x) (revision 1880)
-@@ -8,7 +8,7 @@
+--- doc/extforward.txt (.../tags/lighttpd-1.4.22) (revision 2504)
++++ doc/extforward.txt (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -49,11 +49,20 @@
+ Default: empty
- use strict;
- use IO::Socket;
--use Test::More tests => 33;
-+use Test::More tests => 36;
- use LightyTest;
+ Example: ::
+-
++
+ extforward.forwarder = ("10.0.0.232" => "trust")
- my $tf = LightyTest->new();
-@@ -273,6 +273,38 @@
- $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
- ok($tf->handle_http($t) == 0, 'uppercase filenames');
-
-+$t->{REQUEST} = ( <<EOF
-+GET / HTTP/1.0
-+Location: foo
-+Location: foobar
-+ baz
-+EOF
-+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
-+ok($tf->handle_http($t) == 0, '#1232 - duplicate headers with line-wrapping');
-
-+$t->{REQUEST} = ( <<EOF
-+GET / HTTP/1.0
-+Location:
-+Location: foobar
-+ baz
-+EOF
-+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
-+ok($tf->handle_http($t) == 0, '#1232 - duplicate headers with line-wrapping - test 2');
-+
-+$t->{REQUEST} = ( <<EOF
-+GET / HTTP/1.0
-+A:
-+Location: foobar
-+ baz
-+EOF
-+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
-+ok($tf->handle_http($t) == 0, '#1232 - duplicate headers with line-wrapping - test 3');
+- will translate ip addresses coming from 10.0.0.232 to real ip addresses extracted from X-Forwarded-For: HTTP request header.
++ will translate ip addresses coming from 10.0.0.232 to real ip addresses extracted from "X-Forwarded-For" or "Forwarded-For" HTTP request header.
+
++extforward.headers
++ Sets headers to search for finding the originl addresses.
+
++ Example (for use with a Zeus ZXTM loadbalancer): ::
+
++ extforward.headers = ("X-Cluster-Client-Ip")
+
++ Default: empty, results in searching for "X-Forwarded-For" and "Forwarded-For"
+
- ok($tf->stop_proc == 0, "Stopping lighttpd");
+ Note
+ =======
-Index: tests/prepare.sh
+Index: doc/Makefile.am
+===================================================================
+--- doc/Makefile.am (.../tags/lighttpd-1.4.22) (revision 2504)
++++ doc/Makefile.am (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -1,6 +1,5 @@
+-dist_man1_MANS=lighttpd.1 spawn-fcgi.1
++dist_man8_MANS=lighttpd.8
+
+-
+ DOCS=accesslog.txt \
+ authentication.txt \
+ cgi.txt \
+Index: SConstruct
===================================================================
---- tests/prepare.sh (.../tags/lighttpd-1.4.15) (revision 1880)
-+++ tests/prepare.sh (.../branches/lighttpd-1.4.x) (revision 1880)
-@@ -25,6 +25,7 @@
- # copy everything into the right places
- cp $srcdir/docroot/www/*.html \
- $srcdir/docroot/www/*.php \
-+ $srcdir/docroot/www/*.html~ \
- $srcdir/docroot/www/*.pl \
- $srcdir/docroot/www/*.fcgi \
- $srcdir/docroot/www/*.shtml \
-Index: tests/docroot/www/index.html~
-===================================================================
-Index: tests/docroot/www/Makefile.am
-===================================================================
---- tests/docroot/www/Makefile.am (.../tags/lighttpd-1.4.15) (revision 1880)
-+++ tests/docroot/www/Makefile.am (.../branches/lighttpd-1.4.x) (revision 1880)
-@@ -1,5 +1,5 @@
- EXTRA_DIST=cgi.php cgi.pl dummydir index.html index.txt phpinfo.php \
- redirect.php cgi-pathinfo.pl get-env.php get-server-env.php \
- nph-status.pl prefix.fcgi get-header.pl ssi.shtml get-post-len.pl \
-- exec-date.shtml
-+ exec-date.shtml index.html~
- SUBDIRS=go indexfile expire
Index: NEWS
===================================================================
---- NEWS (.../tags/lighttpd-1.4.15) (revision 1880)
-+++ NEWS (.../branches/lighttpd-1.4.x) (revision 1880)
-@@ -3,9 +3,28 @@
+--- NEWS (.../tags/lighttpd-1.4.22) (revision 2504)
++++ NEWS (.../branches/lighttpd-1.4.x) (revision 2504)
+@@ -3,7 +3,45 @@
NEWS
====
-+- 1.4.16 -
-+
-+ * added static-file.etags, etag.use-inode, etag.use-mtime, etag.use-size
-+ to customize the generation of ETags for static files. (#1209)
-+ (patch by <Yusufg@gmail.com>)
-+ * fixed typecast of NULL on execl() (#1235)
-+ (patch by F. Denis)
-+ * fixed circumventing url.access-deny by trailing slash (#1230)
-+ * fixed crash on duplicate headers with trailing WS (#1232)
-+ * fixed accepting more connections then requested (#1216)
-+ * fixed mem-leak in mod_auth (reported by Stefan Esser)
-+ * fixed crash with md5-sess and cnonce not set in mod_auth (reported by Stefan Esser)
-+ * fixed missing check for base64 encoded string in mod_auth and Basic auth
-+ (reported by Stefan Esser)
-+ * fixed possible crash in Auth-Digest header parser on trailing WS in
-+ mod_auth (reported by Stefan Esser)
-+ * fixed check on stale errno values, which broke handling of broken fastcgi
-+ applications. (#1245)
-+
- - 1.4.15 - 2007-04-13
-
-- * fixed broken Set-Cookie headers
-+ * fixed broken Set-Cookie headers
-
- - 1.4.14 - 2007-04-13
-
-@@ -29,7 +48,7 @@
- * fix cpu hog in certain requests [1473] CVE-2007-1869
- * fix for handling hostnames with trailing dot [1406]
- * fixed header-injection via server.tag (#1106)
-- * disabled caching of files without a content-type to solve the
-+ * disabled caching of files without a content-type to solve the
- aggressive caching of FF
- * remove trailing white-spaces from HTTP-requests before parsing (#1098)
- * fixed accesslog.use-syslog in a conditional and the caching of the
-@@ -42,7 +61,7 @@
- * fixed crash on url.redirect and url.rewrite if %0 is used in a global context
- (#800)
- * fixed possible crash in debug-message in mod_extforward
-- * fixed compilation of mod_extforward on glibc < 2.3.4
-+ * fixed compilation of mod_extforward on glibc < 2.3.4
- * fixed include of empty in the configfiles (#1076)
- * send SIGUSR1 to fastcgi children before SIGTERM. libfcgi wants SIGUSR1. (#737)
- * fixed missing AUTH_TYPE entry in the fastcgi environment. (#889)
-@@ -54,16 +73,16 @@
- * added initgroups in spawn-fcgi (#871)
- * added apr1 support htpasswd in mod-auth (#870)
- * added lighty.stat() to mod_magnet
-- * fixed segfault in splitted CRLF CRLF sequences
-+ * fixed segfault in splitted CRLF CRLF sequences
- (introduced in 1.4.12) (#876)
- * fixed compilation of LOCK support in mod-webdav
- * fixed fragments in request-URLs (#869)
- * fixed pkg-config check for lua5.1 on debian
-- * fixed Content-Length = 0 on HEAD requests without
-+ * fixed Content-Length = 0 on HEAD requests without
- a known Content-Length (#119)
- * fixed mkdir() forcing 0700 (#884)
- * fixed writev() on FreeBSD 4.x and older (#875)
-- * removed warning about a 404-error-handler
-+ * removed warning about a 404-error-handler
- returned 404
- * backported and fixed the buildsystem changes for
- webdav locks
+-- 1.4.22 -
++- 1.4.23 -
++ * 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)
++ * Fix workaround for incorrect path info/scriptname if fastcgi prefix is "/" (fixes #729)
++ * Finally removed spawn-fcgi
++ * Allow xattr to overwrite mime type (fixes #1929)
++ * Remove link from errormsg about fastcgi apps (fixes #1942)
++ * Strip trailing dot from "Host:" header
++ * Remove the optional port info from SERVER_NAME (thx Mr_Bond)
++ * Fix mod_proxy RoundRobin (off by one problem if only one backend is up)
++ * Rename configure.in to configure.ac, with small cleanups (fixes #1932)
++ * Add proper SUID bit detection (fixes #416)
++ * Check for regular file in mod_cgi, so we don't try to start directories
++ * Include mmap.h from chunk.h to fix some problems with #define mmap mmap64 (fixes #1923)
++ * Add support for pipe logging for server.errorlog (fixes #296)
++ * Add revision number to package version for svn/git checkouts
++ * Use server.tag for SERVER_SOFTWARE if configured (fixes #357)
++ * Fix trailing zero char in REQUEST_URI after "strip-request-uri" in mod_fastcgi
++ * mod_magnet: Add env["request.remote-ip"] (fixes #1740)
++ * mod_magnet: Add env["request.path-info"]
++ * Change name/version separator back to "/" (affects every place where the version is printed)
++ * Fix bug with FastCGI request id overflow under high load; just use always id 1 as we don't use multiplexing. (thx jgray)
++ * Add some dirlisting enhancements (fixes #1458)
++ * Add option to enable TCP_DEFER_ACCEPT (fixes #1447)
++ * Limit amount of bytes read for one read-event (fixes #1070)
++ * Add evasive.silent option (fixes #1438)
++ * Make mod_extforward headers configurable (fixes #1545)
++ * Add '%_' pattern for complete hostname in mod_evhost (fixes #1737)
++ * Add IPv6 support to mod_proxy (fixes #1537)
++ * mod_ssi printenv: print cgi env, add environment vars to cgi env (fixes #1713)
++ * Fix error message if no auth backend was set
++ * Fix SERVER_NAME port stripping (fixes #1968)
++ * Fix x-sendfile 2gb limiting (fixes #1970)
++ * Fix mod_cgi environment keys mangling (fixes #1969)
++ * Fix workaround for incorrect path info/scriptname if scgi prefix is "/" (fixes #729)
++ * Fix max-age value in mod_expire for 'modification' (fixes #1978)
++
++- 1.4.22 - 2009-03-07
+ * Fix wrong lua type for CACHE_MISS/CACHE_HIT in mod_cml (fixes #533)
+ * Fix default vhost in mod_simple_vhost (fixes #1905)
+ * Handle EINTR in mod_rrdtool (fixes #604)
+Index: CMakeLists.txt
+===================================================================
+
+Property changes on: .
+___________________________________________________________________
+Modified: bzr:revision-info
+ - timestamp: 2009-03-07 14:58:05.338000059 +0100
+committer: Stefan Bühler <stbuehler@web.de>
+properties:
+ branch-nick: lighttpd-1.4.x
+
+ + timestamp: 2009-03-07 22:04:32.213999987 +0100
+committer: Stefan Bühler <stbuehler@web.de>
+properties:
+ branch-nick: lighttpd-1.4.x
+
+Modified: bzr:file-ids
+ -
+ + doc/lighttpd.8 lighttpd.8-20090307205615-mc312p5ocjwthwte-1
+
+Modified: bzr:revision-id:v3-trunk0
+ - 1127 stbuehler@web.de-20080728081644-j4cxnhduw8kbt8um
+1128 stbuehler@web.de-20080728084246-axvxdtjsrratxixs
+1129 stbuehler@web.de-20080729211700-s8v6nq2cu06qesls
+1130 stbuehler@web.de-20080729211726-4yxb6e5dva1cn0lz
+1131 stbuehler@web.de-20080729211750-4ulzigswx17uciyu
+1132 stbuehler@web.de-20080729211850-nliz3kd0m576ztuu
+1133 stbuehler@web.de-20080730163440-dg2y2sbf0u4grmn4
+1134 stbuehler@web.de-20080730173952-kiutzg6geqy7mick
+1135 stbuehler@web.de-20080730193616-9kc2ms7rrhv1lkn7
+1136 stbuehler@web.de-20080730211457-z4a6uth1y29glbqh
+1137 stbuehler@web.de-20080730213517-b6sjcrdwbmipl334
+1138 stbuehler@web.de-20080731102617-2xw8unjfqic7lsew
+1139 stbuehler@web.de-20080731102703-q4tu5a6em9y8xdg0
+1140 stbuehler@web.de-20080731102729-l6vn5b05w9swqbg5
+1141 stbuehler@web.de-20080731102756-oj3d4tnk0l90mj77
+1142 stbuehler@web.de-20080731204442-blw14cj2fkr3l8ly
+1143 stbuehler@web.de-20080731204508-imtfnurf922mg7tj
+1144 stbuehler@web.de-20080801112347-girnwswdkwm8wuip
+1145 stbuehler@web.de-20080801161245-kx1temr529o7xko9
+1146 stbuehler@web.de-20080801175332-oc9e7x8edn1owcc0
+1147 stbuehler@web.de-20080801183454-5i66v0gsdv0cgmia
+1148 stbuehler@web.de-20080801192849-6zklfbb832sx0hvr
+1149 stbuehler@web.de-20080801203119-o16elp8w854s6lol
+1150 stbuehler@web.de-20080802162146-a4v57svc788pwdsv
+1151 stbuehler@web.de-20080802162202-9udlc1wuwt09pyh2
+1152 stbuehler@web.de-20080804135803-yuor9ze06px7qta4
+1153 stbuehler@web.de-20080812194728-fupt781o6q058unh
+1154 stbuehler@web.de-20080818162116-piz0ukqsaecv2li2
+1155 stbuehler@web.de-20080818235700-94t0xc6ml70zojwq
+1156 stbuehler@web.de-20080819163650-1qhwsqszr78cr4xx
+1157 stbuehler@web.de-20080819163757-1qq3t1f1wj69t8xs
+1158 stbuehler@web.de-20080819163914-rklhkurg8apv85l2
+1159 stbuehler@web.de-20080819163953-tlqew751e43phf5b
+1160 stbuehler@web.de-20080819164108-8ogh68sm1uyteawe
+1161 stbuehler@web.de-20080819173911-w5bqpb7cp9jmdqye
+1162 stbuehler@web.de-20080819222242-c0ta5gnli9p3j35a
+1163 stbuehler@web.de-20080820100730-g1bwdh4nqb53ag9u
+1164 stbuehler@web.de-20080820100752-9pggugdyfnnps8qu
+1165 stbuehler@web.de-20080820164258-v2j00motsrsc5esp
+1166 stbuehler@web.de-20080827144628-hi9hf4ch3n1wf9ao
+1167 stbuehler@web.de-20080827144903-tfxu4yehlyu5kegc
+1168 stbuehler@web.de-20080827155155-7mt92orehbxkh2lh
+1169 stbuehler@web.de-20080917142048-zbcwpk39q9ewd516
+1170 stbuehler@web.de-20080917142300-16gzt21x4nbjtj87
+1171 stbuehler@web.de-20080919160134-385anjnd3txxdw3x
+1172 stbuehler@web.de-20080920134142-fvvwaw2ys51dg4rj
+1173 stbuehler@web.de-20080921153311-1f7rn01atdilmxmy
+1174 stbuehler@web.de-20080922101346-wel327kjmykkpvmp
+1175 stbuehler@web.de-20080923190422-uow06l38ndue36o4
+1176 stbuehler@web.de-20080930112012-53jby2m8xslmd1hm
+1177 stbuehler@web.de-20080930134824-j9q72rwuiczzof5k
+1178 stbuehler@web.de-20080930142037-32pb6m3zjcwryw1w
+1179 stbuehler@web.de-20080930142756-ueovgoshyb996bce
+1180 stbuehler@web.de-20080930152935-1zfy67brol3xdbc0
+1181 stbuehler@web.de-20080930193919-13n2q4c6fbgw0dkx
+1182 stbuehler@web.de-20080930211152-4hmgs95wyg2deol7
+1183 stbuehler@web.de-20081001132402-hxnyu6yzyk3mjf4d
+1184 stbuehler@web.de-20081001155102-qf0mmu2kkpgr7xf0
+1185 stbuehler@web.de-20081001160009-n67ss0vzlac2y60k
+1186 stbuehler@web.de-20081001200802-l5og517etnneitk0
+1188 stbuehler@web.de-20081004160711-ygaohrecmutiqlla
+1189 stbuehler@web.de-20081004211932-vq16u26mthbeed7d
+1191 stbuehler@web.de-20081005224446-1bztt6zqrjh8w8fd
+1192 stbuehler@web.de-20081012114652-ihgz590f0gl5gxpw
+1193 stbuehler@web.de-20081012114716-jnzljhexi4z2gh92
+1195 stbuehler@web.de-20081016120614-kz39vxtz1pebho0o
+1196 stbuehler@web.de-20081016121103-trug4hts0o62d1ut
+1197 stbuehler@web.de-20081016121114-65quosenmso8frf8
+1198 stbuehler@web.de-20081016121421-xjjb7fb53pxu6odj
+1199 stbuehler@web.de-20081205222033-6qok7y19pwp3kxm9
+1200 stbuehler@web.de-20081205222811-49izmzxui0y9ncq6
+1201 stbuehler@web.de-20081205233903-708beaujtf26gprx
+1202 stbuehler@web.de-20081207151631-yv9bdf94zw83jxpv
+1203 stbuehler@web.de-20081207151822-mhyg0gkedmttdqvd
+1204 stbuehler@web.de-20081207151835-1m3yta2fjc4pgb8y
+1205 stbuehler@web.de-20081218221139-w8los43bjbhy9urh
+1206 stbuehler@web.de-20081218222305-5wz7000a62iqa81r
+1208 stbuehler@web.de-20090203201352-ivan8lsb3nkv1go5
+1209 stbuehler@web.de-20090203204231-03zjmk7qiol9yxgq
+1210 stbuehler@web.de-20090203210157-bx1e59fqple5oj3v
+1211 stbuehler@web.de-20090203221006-qd6w80m7lmeqgrjh
+1212 stbuehler@web.de-20090203225303-3dwmialad2u720h8
+1213 stbuehler@web.de-20090204102521-jl3vo2ftp5rsbx9y
+1214 stbuehler@web.de-20090204151616-n56of74dydkqdkgh
+1215 stbuehler@web.de-20090204172956-6wzsv0nm5nxcgfym
+1216 stbuehler@web.de-20090205105134-6i5key9439wspueq
+1217 stbuehler@web.de-20090205114017-0voscqjd5bdm9mwv
+1218 stbuehler@web.de-20090205114442-peekxwpevjl3t7j3
+1219 stbuehler@web.de-20090205215425-vicbc6hzb3at7gj9
+1220 stbuehler@web.de-20090205220741-vqz9l1eui3dwnulq
+1221 stbuehler@web.de-20090205222705-8179v6jkv2x38l70
+1222 stbuehler@web.de-20090210194631-6epujtpen9xfxx5j
+1223 stbuehler@web.de-20090216134207-fg99ikt1ds21hx25
+1224 stbuehler@web.de-20090217085833-9g5c7j7zdylvezl5
+1225 stbuehler@web.de-20090217133414-y80hydn9raqgkgto
+1226 stbuehler@web.de-20090217224447-ve7ns45c9otbgz9h
+1227 stbuehler@web.de-20090219130703-117t93t4hr4j0e8d
+1228 stbuehler@web.de-20090219130728-m8nui64vin0w95b2
+1229 stbuehler@web.de-20090219131550-exi19tbqyd8fpa0d
+1230 stbuehler@web.de-20090224133046-toewpee0ybw5tuay
+1231 stbuehler@web.de-20090228205351-yqjhutdqf30jr66o
+1232 stbuehler@web.de-20090228213824-gnwuf6by8705g6zk
+1233 stbuehler@web.de-20090303100525-kamra70ocxpji0l5
+1234 stbuehler@web.de-20090303100929-p4w2995k61yhxws2
+1235 stbuehler@web.de-20090307135056-02q8f6l1e5jehu9y
+1236 stbuehler@web.de-20090307135805-z488kad68sgcjtzz
+
+ + 1127 stbuehler@web.de-20080728081644-j4cxnhduw8kbt8um
+1128 stbuehler@web.de-20080728084246-axvxdtjsrratxixs
+1129 stbuehler@web.de-20080729211700-s8v6nq2cu06qesls
+1130 stbuehler@web.de-20080729211726-4yxb6e5dva1cn0lz
+1131 stbuehler@web.de-20080729211750-4ulzigswx17uciyu
+1132 stbuehler@web.de-20080729211850-nliz3kd0m576ztuu
+1133 stbuehler@web.de-20080730163440-dg2y2sbf0u4grmn4
+1134 stbuehler@web.de-20080730173952-kiutzg6geqy7mick
+1135 stbuehler@web.de-20080730193616-9kc2ms7rrhv1lkn7
+1136 stbuehler@web.de-20080730211457-z4a6uth1y29glbqh
+1137 stbuehler@web.de-20080730213517-b6sjcrdwbmipl334
+1138 stbuehler@web.de-20080731102617-2xw8unjfqic7lsew
+1139 stbuehler@web.de-20080731102703-q4tu5a6em9y8xdg0
+1140 stbuehler@web.de-20080731102729-l6vn5b05w9swqbg5
+1141 stbuehler@web.de-20080731102756-oj3d4tnk0l90mj77
+1142 stbuehler@web.de-20080731204442-blw14cj2fkr3l8ly
+1143 stbuehler@web.de-20080731204508-imtfnurf922mg7tj
+1144 stbuehler@web.de-20080801112347-girnwswdkwm8wuip
+1145 stbuehler@web.de-20080801161245-kx1temr529o7xko9
+1146 stbuehler@web.de-20080801175332-oc9e7x8edn1owcc0
+1147 stbuehler@web.de-20080801183454-5i66v0gsdv0cgmia
+1148 stbuehler@web.de-20080801192849-6zklfbb832sx0hvr
+1149 stbuehler@web.de-20080801203119-o16elp8w854s6lol
+1150 stbuehler@web.de-20080802162146-a4v57svc788pwdsv
+1151 stbuehler@web.de-20080802162202-9udlc1wuwt09pyh2
+1152 stbuehler@web.de-20080804135803-yuor9ze06px7qta4
+1153 stbuehler@web.de-20080812194728-fupt781o6q058unh
+1154 stbuehler@web.de-20080818162116-piz0ukqsaecv2li2
+1155 stbuehler@web.de-20080818235700-94t0xc6ml70zojwq
+1156 stbuehler@web.de-20080819163650-1qhwsqszr78cr4xx
+1157 stbuehler@web.de-20080819163757-1qq3t1f1wj69t8xs
+1158 stbuehler@web.de-20080819163914-rklhkurg8apv85l2
+1159 stbuehler@web.de-20080819163953-tlqew751e43phf5b
+1160 stbuehler@web.de-20080819164108-8ogh68sm1uyteawe
+1161 stbuehler@web.de-20080819173911-w5bqpb7cp9jmdqye
+1162 stbuehler@web.de-20080819222242-c0ta5gnli9p3j35a
+1163 stbuehler@web.de-20080820100730-g1bwdh4nqb53ag9u
+1164 stbuehler@web.de-20080820100752-9pggugdyfnnps8qu
+1165 stbuehler@web.de-20080820164258-v2j00motsrsc5esp
+1166 stbuehler@web.de-20080827144628-hi9hf4ch3n1wf9ao
+1167 stbuehler@web.de-20080827144903-tfxu4yehlyu5kegc
+1168 stbuehler@web.de-20080827155155-7mt92orehbxkh2lh
+1169 stbuehler@web.de-20080917142048-zbcwpk39q9ewd516
+1170 stbuehler@web.de-20080917142300-16gzt21x4nbjtj87
+1171 stbuehler@web.de-20080919160134-385anjnd3txxdw3x
+1172 stbuehler@web.de-20080920134142-fvvwaw2ys51dg4rj
+1173 stbuehler@web.de-20080921153311-1f7rn01atdilmxmy
+1174 stbuehler@web.de-20080922101346-wel327kjmykkpvmp
+1175 stbuehler@web.de-20080923190422-uow06l38ndue36o4
+1176 stbuehler@web.de-20080930112012-53jby2m8xslmd1hm
+1177 stbuehler@web.de-20080930134824-j9q72rwuiczzof5k
+1178 stbuehler@web.de-20080930142037-32pb6m3zjcwryw1w
+1179 stbuehler@web.de-20080930142756-ueovgoshyb996bce
+1180 stbuehler@web.de-20080930152935-1zfy67brol3xdbc0
+1181 stbuehler@web.de-20080930193919-13n2q4c6fbgw0dkx
+1182 stbuehler@web.de-20080930211152-4hmgs95wyg2deol7
+1183 stbuehler@web.de-20081001132402-hxnyu6yzyk3mjf4d
+1184 stbuehler@web.de-20081001155102-qf0mmu2kkpgr7xf0
+1185 stbuehler@web.de-20081001160009-n67ss0vzlac2y60k
+1186 stbuehler@web.de-20081001200802-l5og517etnneitk0
+1188 stbuehler@web.de-20081004160711-ygaohrecmutiqlla
+1189 stbuehler@web.de-20081004211932-vq16u26mthbeed7d
+1191 stbuehler@web.de-20081005224446-1bztt6zqrjh8w8fd
+1192 stbuehler@web.de-20081012114652-ihgz590f0gl5gxpw
+1193 stbuehler@web.de-20081012114716-jnzljhexi4z2gh92
+1195 stbuehler@web.de-20081016120614-kz39vxtz1pebho0o
+1196 stbuehler@web.de-20081016121103-trug4hts0o62d1ut
+1197 stbuehler@web.de-20081016121114-65quosenmso8frf8
+1198 stbuehler@web.de-20081016121421-xjjb7fb53pxu6odj
+1199 stbuehler@web.de-20081205222033-6qok7y19pwp3kxm9
+1200 stbuehler@web.de-20081205222811-49izmzxui0y9ncq6
+1201 stbuehler@web.de-20081205233903-708beaujtf26gprx
+1202 stbuehler@web.de-20081207151631-yv9bdf94zw83jxpv
+1203 stbuehler@web.de-20081207151822-mhyg0gkedmttdqvd
+1204 stbuehler@web.de-20081207151835-1m3yta2fjc4pgb8y
+1205 stbuehler@web.de-20081218221139-w8los43bjbhy9urh
+1206 stbuehler@web.de-20081218222305-5wz7000a62iqa81r
+1208 stbuehler@web.de-20090203201352-ivan8lsb3nkv1go5
+1209 stbuehler@web.de-20090203204231-03zjmk7qiol9yxgq
+1210 stbuehler@web.de-20090203210157-bx1e59fqple5oj3v
+1211 stbuehler@web.de-20090203221006-qd6w80m7lmeqgrjh
+1212 stbuehler@web.de-20090203225303-3dwmialad2u720h8
+1213 stbuehler@web.de-20090204102521-jl3vo2ftp5rsbx9y
+1214 stbuehler@web.de-20090204151616-n56of74dydkqdkgh
+1215 stbuehler@web.de-20090204172956-6wzsv0nm5nxcgfym
+1216 stbuehler@web.de-20090205105134-6i5key9439wspueq
+1217 stbuehler@web.de-20090205114017-0voscqjd5bdm9mwv
+1218 stbuehler@web.de-20090205114442-peekxwpevjl3t7j3
+1219 stbuehler@web.de-20090205215425-vicbc6hzb3at7gj9
+1220 stbuehler@web.de-20090205220741-vqz9l1eui3dwnulq
+1221 stbuehler@web.de-20090205222705-8179v6jkv2x38l70
+1222 stbuehler@web.de-20090210194631-6epujtpen9xfxx5j
+1223 stbuehler@web.de-20090216134207-fg99ikt1ds21hx25
+1224 stbuehler@web.de-20090217085833-9g5c7j7zdylvezl5
+1225 stbuehler@web.de-20090217133414-y80hydn9raqgkgto
+1226 stbuehler@web.de-20090217224447-ve7ns45c9otbgz9h
+1227 stbuehler@web.de-20090219130703-117t93t4hr4j0e8d
+1228 stbuehler@web.de-20090219130728-m8nui64vin0w95b2
+1229 stbuehler@web.de-20090219131550-exi19tbqyd8fpa0d
+1230 stbuehler@web.de-20090224133046-toewpee0ybw5tuay
+1231 stbuehler@web.de-20090228205351-yqjhutdqf30jr66o
+1232 stbuehler@web.de-20090228213824-gnwuf6by8705g6zk
+1233 stbuehler@web.de-20090303100525-kamra70ocxpji0l5
+1234 stbuehler@web.de-20090303100929-p4w2995k61yhxws2
+1235 stbuehler@web.de-20090307135056-02q8f6l1e5jehu9y
+1236 stbuehler@web.de-20090307135805-z488kad68sgcjtzz
+1237 stbuehler@web.de-20090307154555-xybvl7sxrha6vhds
+1238 stbuehler@web.de-20090307204326-10m0681831yvhi3k
+1239 stbuehler@web.de-20090307204846-seq3cmzn6dy9927i
+1240 stbuehler@web.de-20090307205519-ha3s58fcum106yl0
+1241 stbuehler@web.de-20090307210432-jdlv5pp9m519vyv2
+
+