+--- 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.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;
+@@ -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.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
+
+ #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;
++
++ 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);
++ }
++ }
++
+ return 0;
+ }
+
+@@ -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"));
+ }
+- buffer_append_string_len(b, CONST_STR_LEN("</pre>"));
+
+ 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_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_