X-Git-Url: http://git.pld-linux.org/?p=packages%2Flighttpd.git;a=blobdiff_plain;f=lighttpd-branch.diff;h=76f06ce17cb591b31c716dc962d936cf96c36b2c;hp=8271adfd0e84f1e05b4306e9baa51959e69c79aa;hb=2aca1085a89e62b4d3e3120492226ed7104039c8;hpb=55b83c7c29d5c68379feebd617eb2ebce77509b0 diff --git a/lighttpd-branch.diff b/lighttpd-branch.diff index 8271adf..76f06ce 100644 --- a/lighttpd-branch.diff +++ b/lighttpd-branch.diff @@ -1,7032 +1,1957 @@ -Index: lighttpd.spec.in +# Revision 2815 +Index: src/http_auth_digest.c =================================================================== ---- lighttpd.spec.in (.../tags/lighttpd-1.4.19) (revision 2303) -+++ lighttpd.spec.in (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -1,83 +0,0 @@ --Summary: A fast webserver with minimal memory-footprint (lighttpd) --Name: lighttpd --Version: @VERSION@ --Release: 1 --Source: http://jan.kneschke.de/projects/lighttpd/download/lighttpd-%version.tar.gz --Packager: Jan Kneschke --License: BSD --Group: Networking/Daemons --URL: http://www.lighttpd.net/ --Requires: pcre >= 3.1 zlib --BuildRequires: libtool zlib-devel --BuildRoot: %{_tmppath}/%{name}-root +--- src/http_auth_digest.c (.../tags/lighttpd-1.4.29) ++++ src/http_auth_digest.c (.../branches/lighttpd-1.4.x) +@@ -1,26 +0,0 @@ +-#include "buffer.h" - --%description --lighttpd is intented to be a frontend for ad-servers which have to deliver --small files concurrently to many connections. +-#include "http_auth_digest.h" - --Available rpmbuild rebuild options: ----with: ssl mysql lua memcache +-#include - --%prep --%setup -q +-#ifndef USE_OPENSSL +-# include "md5.h" - --%build --rm -rf %{buildroot} --%configure \ -- %{?_with_mysql: --with-mysql} \ -- %{?_with_lua: --with-lua} \ -- %{?_with_memcache: --with-memcache} \ -- %{?_with_ssl: --with-openssl} --make +-typedef li_MD5_CTX MD5_CTX; +-#define MD5_Init li_MD5_Init +-#define MD5_Update li_MD5_Update +-#define MD5_Final li_MD5_Final - --%install --%makeinstall +-#endif - --mkdir -p %{buildroot}%{_sysconfdir}/{init.d,sysconfig} --if [ -f /etc/redhat-release -o -f /etc/fedora-release ]; then -- install -m 755 doc/rc.lighttpd.redhat %{buildroot}%{_sysconfdir}/init.d/lighttpd --else -- install -m 755 doc/rc.lighttpd %{buildroot}%{_sysconfdir}/init.d/lighttpd --fi --install -m 644 doc/sysconfig.lighttpd %{buildroot}%{_sysconfdir}/sysconfig/lighttpd +-void CvtHex(IN HASH Bin, OUT HASHHEX Hex) { +- unsigned short i; - --%clean --rm -rf %{buildroot} -- --%post --## read http://www.fedora.us/docs/spec.html next time :) --if [ "$1" = "1" ]; then -- # real install, not upgrade -- /sbin/chkconfig --add lighttpd --fi +- for (i = 0; i < HASHLEN; i++) { +- Hex[i*2] = int2hex((Bin[i] >> 4) & 0xf); +- Hex[i*2+1] = int2hex(Bin[i] & 0xf); +- } +- Hex[HASHHEXLEN] = '\0'; +-} - --%preun --if [ "$1" = "0"]; then -- # real uninstall, not upgrade -- %{_sysconfdir}/init.d/lighttpd stop -- /sbin/chkconfig --del lighttpd --fi +Index: src/http_auth_digest.h +=================================================================== +--- src/http_auth_digest.h (.../tags/lighttpd-1.4.29) ++++ src/http_auth_digest.h (.../branches/lighttpd-1.4.x) +@@ -1,24 +0,0 @@ +-#ifndef _DIGCALC_H_ +-#define _DIGCALC_H_ - --%files --%defattr(-,root,root) --%doc doc/lighttpd.conf doc/lighttpd.user README INSTALL ChangeLog COPYING AUTHORS --%doc doc/*.txt --%config(noreplace) %attr(0755,root,root) %{_sysconfdir}/init.d/lighttpd --%config(noreplace) %attr(0644,root,root) %{_sysconfdir}/sysconfig/lighttpd --%{_mandir}/* --%{_libdir}/* --%{_sbindir}/* --%{_bindir}/* +-#ifdef HAVE_CONFIG_H +-# include "config.h" +-#endif - --%changelog --* Thu Sep 30 2004 12:41 1.3.1 --- upgraded to 1.3.1 +-#define HASHLEN 16 +-typedef unsigned char HASH[HASHLEN]; +-#define HASHHEXLEN 32 +-typedef char HASHHEX[HASHHEXLEN+1]; +-#ifdef USE_OPENSSL +-#define IN const +-#else +-#define IN +-#endif +-#define OUT - --* Tue Jun 29 2004 17:26 1.2.3 --- rpmlint'ed the package --- added URL --- added (noreplace) to start-script --- change group to Networking/Daemon (like apache) +-void CvtHex( +- IN HASH Bin, +- OUT HASHHEX Hex +- ); - --* Sun Feb 23 2003 15:04 --- initial version -Index: configure.in +-#endif +Index: src/network_write.c =================================================================== -Index: src/mod_ssi_exprparser.h -=================================================================== ---- src/mod_ssi_exprparser.h (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/mod_ssi_exprparser.h (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -1,12 +0,0 @@ --#define TK_AND 1 --#define TK_OR 2 --#define TK_EQ 3 --#define TK_NE 4 --#define TK_GT 5 --#define TK_GE 6 --#define TK_LT 7 --#define TK_LE 8 --#define TK_NOT 9 --#define TK_LPARAN 10 --#define TK_RPARAN 11 --#define TK_VALUE 12 -Index: src/configfile-glue.c -=================================================================== ---- src/configfile-glue.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/configfile-glue.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -155,7 +155,7 @@ - /* touched */ - touched = data_string_init(); - -- buffer_copy_string(touched->value, ""); -+ buffer_copy_string_len(touched->value, CONST_STR_LEN("")); - buffer_copy_string_buffer(touched->key, du->key); - - array_insert_unique(srv->config_touched, (data_unset *)touched); -@@ -260,7 +260,7 @@ - if (ck_colon) { - /* condition "host:port" but client send "host" */ - buffer_copy_string_buffer(srv->cond_check_buf, l); -- BUFFER_APPEND_STRING_CONST(srv->cond_check_buf, ":"); -+ buffer_append_string_len(srv->cond_check_buf, CONST_STR_LEN(":")); - buffer_append_long(srv->cond_check_buf, sock_addr_get_port(&(srv_sock->addr))); - l = srv->cond_check_buf; - } else if (!ck_colon) { -@@ -529,7 +529,7 @@ - int config_append_cond_match_buffer(connection *con, data_config *dc, buffer *buf, int n) - { - cond_cache_t *cache = &con->cond_cache[dc->context_ndx]; -- if (n > cache->patterncount) { -+ if (n >= cache->patterncount) { - return 0; - } +--- src/network_write.c (.../tags/lighttpd-1.4.29) ++++ src/network_write.c (.../branches/lighttpd-1.4.x) +@@ -24,17 +24,16 @@ + # include + #endif -Index: src/mod_cgi.c -=================================================================== ---- src/mod_cgi.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/mod_cgi.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -912,7 +912,7 @@ - buffer_reset(p->tmp_buf); - - if (0 != strcasecmp(ds->key->ptr, "CONTENT-TYPE")) { -- buffer_copy_string(p->tmp_buf, "HTTP_"); -+ buffer_copy_string_len(p->tmp_buf, CONST_STR_LEN("HTTP_")); - p->tmp_buf->used--; /* strip \0 after HTTP_ */ - } +-int network_write_chunkqueue_write(server *srv, connection *con, int fd, chunkqueue *cq) { ++int network_write_chunkqueue_write(server *srv, connection *con, int fd, chunkqueue *cq, off_t max_bytes) { + chunk *c; +- size_t chunks_written = 0; -@@ -949,7 +949,7 @@ +- for(c = cq->first; c; c = c->next) { ++ for(c = cq->first; (max_bytes > 0) && (NULL != c); c = c->next) { + int chunk_finished = 0; - for (j = 0; j < ds->key->used - 1; j++) { - p->tmp_buf->ptr[p->tmp_buf->used++] = -- isalpha((unsigned char)ds->key->ptr[j]) ? -+ light_isalnum((unsigned char)ds->key->ptr[j]) ? - toupper((unsigned char)ds->key->ptr[j]) : '_'; - } - p->tmp_buf->ptr[p->tmp_buf->used++] = '\0'; -@@ -987,6 +987,8 @@ - *c = '/'; - } + switch(c->type) { + case MEM_CHUNK: { + char * offset; +- size_t toSend; ++ off_t toSend; + ssize_t r; + + if (c->mem->used == 0) { +@@ -44,6 +43,8 @@ -+ openDevNull(STDERR_FILENO); + offset = c->mem->ptr + c->offset; + toSend = c->mem->used - 1 - c->offset; ++ if (toSend > max_bytes) toSend = max_bytes; + - /* we don't need the client socket */ - for (i = 3; i < 256; i++) { - if (i != srv->errorlog_fd) close(i); -@@ -995,7 +997,7 @@ - /* exec the cgi */ - execve(args[0], args, env.ptr); - -- log_error_write(srv, __FILE__, __LINE__, "sss", "CGI failed:", strerror(errno), args[0]); -+ /* log_error_write(srv, __FILE__, __LINE__, "sss", "CGI failed:", strerror(errno), args[0]); */ - - /* */ - SEGFAULT(); -@@ -1058,8 +1060,9 @@ - switch(errno) { - case ENOSPC: - con->http_status = 507; -- - break; -+ case EINTR: -+ continue; - default: - con->http_status = 403; - break; -@@ -1071,8 +1074,9 @@ - switch(errno) { - case ENOSPC: - con->http_status = 507; -- - break; -+ case EINTR: -+ continue; - default: - con->http_status = 403; - break; -@@ -1087,6 +1091,8 @@ - c->offset += r; - cq->bytes_out += r; - } else { -+ log_error_write(srv, __FILE__, __LINE__, "ss", "write() failed due to: ", strerror(errno)); -+ con->http_status = 500; - break; - } - chunkqueue_remove_finished_chunks(cq); -@@ -1174,6 +1180,8 @@ - plugin_data *p = p_d; - buffer *fn = con->physical.path; + #ifdef __WIN32 + if ((r = send(fd, offset, toSend, 0)) < 0) { + /* no error handling for windows... */ +@@ -72,6 +73,7 @@ + + c->offset += r; + cq->bytes_out += r; ++ max_bytes -= r; + + if (c->offset == (off_t)c->mem->used - 1) { + chunk_finished = 1; +@@ -85,7 +87,7 @@ + #endif + ssize_t r; + off_t offset; +- size_t toSend; ++ off_t toSend; + stat_cache_entry *sce = NULL; + int ifd; -+ if (con->mode != DIRECT) return HANDLER_GO_ON; +@@ -98,6 +100,8 @@ + offset = c->file.start + c->offset; + toSend = c->file.length - c->offset; + ++ if (toSend > max_bytes) toSend = max_bytes; + - if (fn->used == 0) return HANDLER_GO_ON; + if (offset > sce->st.st_size) { + log_error_write(srv, __FILE__, __LINE__, "sb", "file was shrinked:", c->file.name); + +@@ -181,6 +185,7 @@ - mod_cgi_patch_connection(srv, con, p); -@@ -1189,6 +1197,7 @@ + c->offset += r; + cq->bytes_out += r; ++ max_bytes -= r; + + if (c->offset == c->file.length) { + chunk_finished = 1; +@@ -200,11 +205,9 @@ + + break; + } +- +- chunks_written++; + } - if (0 == strncmp(fn->ptr + s_len - ct_len, ds->key->ptr, ct_len)) { - if (cgi_create_env(srv, con, p, ds->value)) { -+ con->mode = DIRECT; - con->http_status = 500; +- return chunks_written; ++ return 0; + } - buffer_reset(con->physical.path); + #if 0 Index: src/mod_secure_download.c =================================================================== ---- src/mod_secure_download.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/mod_secure_download.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -204,6 +204,8 @@ - time_t ts = 0; - size_t i; +--- src/mod_secure_download.c (.../tags/lighttpd-1.4.29) ++++ src/mod_secure_download.c (.../branches/lighttpd-1.4.x) +@@ -8,18 +8,8 @@ + #include + #include -+ if (con->mode != DIRECT) return HANDLER_GO_ON; -+ - if (con->uri.path->used == 0) return HANDLER_GO_ON; +-#ifdef USE_OPENSSL +-# include +-#else +-# include "md5.h" ++#include "md5.h" - mod_secdownload_patch_connection(srv, con, p); -@@ -243,8 +245,8 @@ - } +-typedef li_MD5_CTX MD5_CTX; +-#define MD5_Init li_MD5_Init +-#define MD5_Update li_MD5_Update +-#define MD5_Final li_MD5_Final +- +-#endif +- + #define HASHLEN 16 + typedef unsigned char HASH[HASHLEN]; + #define HASHHEXLEN 32 +@@ -200,7 +190,7 @@ - /* timed-out */ -- if (srv->cur_ts - ts > p->conf.timeout || -- srv->cur_ts - ts < -p->conf.timeout) { -+ if ( (srv->cur_ts > ts && srv->cur_ts - ts > p->conf.timeout) || -+ (srv->cur_ts < ts && ts - srv->cur_ts > p->conf.timeout) ) { - /* "Gone" as the url will never be valid again instead of "408 - Timeout" where the request may be repeated */ - con->http_status = 410; + URIHANDLER_FUNC(mod_secdownload_uri_handler) { + plugin_data *p = p_d; +- MD5_CTX Md5Ctx; ++ li_MD5_CTX Md5Ctx; + HASH HA1; + const char *rel_uri, *ts_str, *md5_str; + time_t ts = 0; +@@ -266,9 +256,9 @@ + buffer_append_string(p->md5, rel_uri); + buffer_append_string_len(p->md5, ts_str, 8); -@@ -268,7 +270,7 @@ +- MD5_Init(&Md5Ctx); +- MD5_Update(&Md5Ctx, (unsigned char *)p->md5->ptr, p->md5->used - 1); +- MD5_Final(HA1, &Md5Ctx); ++ li_MD5_Init(&Md5Ctx); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)p->md5->ptr, p->md5->used - 1); ++ li_MD5_Final(HA1, &Md5Ctx); buffer_copy_string_hex(p->md5, (char *)HA1, 16); -- if (0 != strncmp(md5_str, p->md5->ptr, 32)) { -+ if (0 != strncasecmp(md5_str, p->md5->ptr, 32)) { - con->http_status = 403; - - log_error_write(srv, __FILE__, __LINE__, "sss", -Index: src/array.c +Index: src/base.h =================================================================== ---- src/array.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/array.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -330,30 +330,30 @@ - a = array_init(); - - ds = data_string_init(); -- buffer_copy_string(ds->key, "abc"); -- buffer_copy_string(ds->value, "alfrag"); -+ buffer_copy_string_len(ds->key, CONST_STR_LEN("abc")); -+ buffer_copy_string_len(ds->value, CONST_STR_LEN("alfrag")); +--- src/base.h (.../tags/lighttpd-1.4.29) ++++ src/base.h (.../branches/lighttpd-1.4.x) +@@ -277,6 +277,7 @@ + buffer *ssl_cipher_list; + buffer *ssl_dh_file; + buffer *ssl_ec_curve; ++ unsigned short ssl_honor_cipher_order; /* determine SSL cipher in server-preferred order, not client-order */ + unsigned short ssl_use_sslv2; + unsigned short ssl_use_sslv3; + unsigned short ssl_verifyclient; +@@ -284,6 +285,7 @@ + unsigned short ssl_verifyclient_depth; + buffer *ssl_verifyclient_username; + unsigned short ssl_verifyclient_export_cert; ++ unsigned short ssl_disable_client_renegotiation; + + unsigned short use_ipv6, set_v6only; /* set_v6only is only a temporary option */ + unsigned short defer_accept; +@@ -437,6 +439,7 @@ + # ifndef OPENSSL_NO_TLSEXT + buffer *tlsext_server_name; + # endif ++ unsigned int renegotiations; /* count of SSL_CB_HANDSHAKE_START */ + #endif + /* etag handling */ + etag_flags_t etag_flags; +@@ -647,11 +650,9 @@ - array_insert_unique(a, (data_unset *)ds); + fdevent_handler_t event_handler; - ds = data_string_init(); -- buffer_copy_string(ds->key, "abc"); -- buffer_copy_string(ds->value, "hameplman"); -+ buffer_copy_string_len(ds->key, CONST_STR_LEN("abc")); -+ buffer_copy_string_len(ds->value, CONST_STR_LEN("hameplman")); +- int (* network_backend_write)(struct server *srv, connection *con, int fd, chunkqueue *cq); +- int (* network_backend_read)(struct server *srv, connection *con, int fd, chunkqueue *cq); ++ int (* network_backend_write)(struct server *srv, connection *con, int fd, chunkqueue *cq, off_t max_bytes); + #ifdef USE_OPENSSL +- int (* network_ssl_backend_write)(struct server *srv, connection *con, SSL *ssl, chunkqueue *cq); +- int (* network_ssl_backend_read)(struct server *srv, connection *con, SSL *ssl, chunkqueue *cq); ++ int (* network_ssl_backend_write)(struct server *srv, connection *con, SSL *ssl, chunkqueue *cq, off_t max_bytes); + #endif - array_insert_unique(a, (data_unset *)ds); + uid_t uid; +Index: src/connections.c +=================================================================== +--- src/connections.c (.../tags/lighttpd-1.4.29) ++++ src/connections.c (.../branches/lighttpd-1.4.x) +@@ -223,6 +223,12 @@ - ds = data_string_init(); -- buffer_copy_string(ds->key, "123"); -- buffer_copy_string(ds->value, "alfrag"); -+ buffer_copy_string_len(ds->key, CONST_STR_LEN("123")); -+ buffer_copy_string_len(ds->value, CONST_STR_LEN("alfrag")); + len = SSL_read(con->ssl, b->ptr + read_offset, toread); - array_insert_unique(a, (data_unset *)ds); ++ if (con->renegotiations > 1 && con->conf.ssl_disable_client_renegotiation) { ++ connection_set_state(srv, con, CON_STATE_ERROR); ++ log_error_write(srv, __FILE__, __LINE__, "s", "SSL: renegotiation initiated by client"); ++ return -1; ++ } ++ + if (len > 0) { + if (b->used > 0) b->used--; + b->used += len; +@@ -445,6 +451,7 @@ + default: + switch(con->http_status) { + case 400: /* bad request */ ++ case 401: /* authorization required */ + case 414: /* overload request header */ + case 505: /* unknown protocol */ + case 207: /* this was webdav */ +@@ -617,8 +624,9 @@ + } - dc = data_count_init(); -- buffer_copy_string(dc->key, "def"); -+ buffer_copy_string_len(dc->key, CONST_STR_LEN("def")); + static int connection_handle_write(server *srv, connection *con) { +- switch(network_write_chunkqueue(srv, con, con->write_queue)) { ++ switch(network_write_chunkqueue(srv, con, con->write_queue, MAX_WRITE_LIMIT)) { + case 0: ++ con->write_request_ts = srv->cur_ts; + if (con->file_finished) { + connection_set_state(srv, con, CON_STATE_RESPONSE_END); + joblist_append(srv, con); +@@ -635,6 +643,7 @@ + joblist_append(srv, con); + break; + case 1: ++ con->write_request_ts = srv->cur_ts; + con->is_writable = 0; - array_insert_unique(a, (data_unset *)dc); + /* not finished yet -> WRITE */ +@@ -1251,8 +1260,6 @@ + log_error_write(srv, __FILE__, __LINE__, "ds", + con->fd, + "handle write failed."); +- } else if (con->state == CON_STATE_WRITE) { +- con->write_request_ts = srv->cur_ts; + } + } - dc = data_count_init(); -- buffer_copy_string(dc->key, "def"); -+ buffer_copy_string_len(dc->key, CONST_STR_LEN("def")); +@@ -1352,6 +1359,7 @@ + return NULL; + } - array_insert_unique(a, (data_unset *)dc); ++ con->renegotiations = 0; + #ifndef OPENSSL_NO_TLSEXT + SSL_set_app_data(con->ssl, con); + #endif +@@ -1667,8 +1675,6 @@ + con->fd, + "handle write failed."); + connection_set_state(srv, con, CON_STATE_ERROR); +- } else if (con->state == CON_STATE_WRITE) { +- con->write_request_ts = srv->cur_ts; + } + } -Index: src/base.h +Index: src/mod_staticfile.c =================================================================== ---- src/base.h (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/base.h (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -259,6 +259,7 @@ - unsigned short log_request_handling; - unsigned short log_response_header; - unsigned short log_condition_handling; -+ unsigned short log_ssl_noise; +--- src/mod_staticfile.c (.../tags/lighttpd-1.4.29) ++++ src/mod_staticfile.c (.../branches/lighttpd-1.4.x) +@@ -26,6 +26,7 @@ + typedef struct { + array *exclude_ext; + unsigned short etags_used; ++ unsigned short disable_pathinfo; + } plugin_config; + typedef struct { +@@ -84,6 +85,7 @@ + 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 */ ++ { "static-file.disable-pathinfo", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 2 */ + { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } + }; + +@@ -97,9 +99,11 @@ + s = calloc(1, sizeof(plugin_config)); + s->exclude_ext = array_init(); + s->etags_used = 1; ++ s->disable_pathinfo = 0; + + cv[0].destination = s->exclude_ext; + cv[1].destination = &(s->etags_used); ++ cv[2].destination = &(s->disable_pathinfo); + + p->config_storage[i] = s; + +@@ -119,6 +123,7 @@ + + PATCH(exclude_ext); + PATCH(etags_used); ++ PATCH(disable_pathinfo); + + /* skip the first, the global context */ + for (i = 1; i < srv->config_context->used; i++) { +@@ -136,7 +141,9 @@ + PATCH(exclude_ext); + } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("static-file.etags"))) { + PATCH(etags_used); +- } ++ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("static-file.disable-pathinfo"))) { ++ PATCH(disable_pathinfo); ++ } + } + } - /* server wide */ -Index: src/mod_rewrite.c -=================================================================== ---- src/mod_rewrite.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/mod_rewrite.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -350,7 +350,11 @@ +@@ -350,7 +357,6 @@ + URIHANDLER_FUNC(mod_staticfile_subrequest) { + plugin_data *p = p_d; + size_t k; +- int s_len; + stat_cache_entry *sce = NULL; + buffer *mtime = NULL; + data_string *ds; +@@ -376,7 +382,12 @@ - if (!p->conf.rewrite) return HANDLER_GO_ON; + mod_staticfile_patch_connection(srv, con, p); -- buffer_copy_string_buffer(p->match_buf, con->request.uri); -+ buffer_copy_string_buffer(p->match_buf, con->uri.path); -+ if (con->uri.query->used > 0) { -+ buffer_append_string_len(p->match_buf, CONST_STR_LEN("?")); -+ buffer_append_string_buffer(p->match_buf, con->uri.query); +- s_len = con->uri.path->used - 1; ++ if (p->conf.disable_pathinfo && 0 != con->request.pathinfo->used) { ++ if (con->conf.log_request_handling) { ++ log_error_write(srv, __FILE__, __LINE__, "s", "-- NOT handling file as static file, pathinfo forbidden"); ++ } ++ return HANDLER_GO_ON; + } - for (i = 0; i < p->conf.rewrite->used; i++) { - pcre *match; -@@ -385,8 +389,7 @@ - - start = 0; end = pattern_len; - for (k = 0; k < pattern_len; k++) { -- if ((pattern[k] == '$' || pattern[k] == '%') && -- isdigit((unsigned char)pattern[k + 1])) { -+ if (pattern[k] == '$' || pattern[k] == '%') { - /* got one */ - - size_t num = pattern[k + 1] - '0'; -@@ -395,7 +398,10 @@ - - buffer_append_string_len(con->request.uri, pattern + start, end - start); - -- if (pattern[k] == '$') { -+ if (!isdigit((unsigned char)pattern[k + 1])) { -+ /* enable escape: "%%" => "%", "%a" => "%a", "$$" => "$" */ -+ buffer_append_string_len(con->request.uri, pattern+k, pattern[k] == pattern[k+1] ? 1 : 2); -+ } else if (pattern[k] == '$') { - /* n is always > 0 */ - if (num < (size_t)n) { - buffer_append_string(con->request.uri, list[num]); -Index: src/lempar.c -=================================================================== ---- src/lempar.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/lempar.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -210,7 +210,7 @@ - */ - const char *ParseTokenName(int tokenType){ - #ifndef NDEBUG -- if( tokenType>0 && tokenType<(sizeof(yyTokenName)/sizeof(yyTokenName[0])) ){ -+ if( tokenType>0 && (size_t)tokenType<(sizeof(yyTokenName)/sizeof(yyTokenName[0])) ){ - return yyTokenName[tokenType]; - }else{ - return "Unknown"; -@@ -335,7 +335,7 @@ - return YY_NO_ACTION; - } - i += iLookAhead; -- if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){ -+ if( i<0 || (size_t)i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){ - #ifdef YYFALLBACK - int iFallback; /* Fallback token */ - if( iLookAhead=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){ -+ if( i<0 || (size_t)i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){ - return yy_default[stateno]; - }else{ - return yy_action[i]; -@@ -456,7 +456,7 @@ - yymsp = &yypParser->yystack[yypParser->yyidx]; - #ifndef NDEBUG - if( yyTraceFILE && yyruleno>=0 -- && yyrulenoconf.exclude_ext->used; k++) { +Index: src/network.c =================================================================== ---- src/connections.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/connections.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -199,6 +199,7 @@ - - /* don't resize the buffer if we were in SSL_ERROR_WANT_* */ - -+ ERR_clear_error(); - do { - if (!con->ssl_error_want_reuse_buffer) { - b = buffer_init(); -@@ -275,9 +276,19 @@ - /* fall thourgh */ - default: - while((ssl_err = ERR_get_error())) { -+ switch (ERR_GET_REASON(ssl_err)) { -+ case SSL_R_SSL_HANDSHAKE_FAILURE: -+ case SSL_R_TLSV1_ALERT_UNKNOWN_CA: -+ case SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN: -+ case SSL_R_SSLV3_ALERT_BAD_CERTIFICATE: -+ if (!con->conf.log_ssl_noise) continue; -+ break; -+ default: -+ break; -+ } - /* get all errors from the error-queue */ - log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:", -- r, ERR_error_string(ssl_err, NULL)); -+ r, ERR_error_string(ssl_err, NULL)); +--- src/network.c (.../tags/lighttpd-1.4.29) ++++ src/network.c (.../branches/lighttpd-1.4.x) +@@ -27,6 +27,19 @@ + # include + #endif + ++#ifdef USE_OPENSSL ++static void ssl_info_callback(const SSL *ssl, int where, int ret) { ++ UNUSED(ret); ++ ++ if (0 != (where & SSL_CB_HANDSHAKE_START)) { ++ connection *con = SSL_get_app_data(ssl); ++ ++con->renegotiations; ++ } else if (0 != (where & SSL_CB_HANDSHAKE_DONE)) { ++ ssl->s3->flags |= SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS; ++ } ++} ++#endif ++ + static handler_t network_server_handle_fdevent(server *srv, void *context, int revents) { + server_socket *srv_socket = (server_socket *)context; + connection *con; +@@ -480,9 +493,11 @@ + network_backend_t backend; + + #if OPENSSL_VERSION_NUMBER >= 0x0090800fL ++#ifndef OPENSSL_NO_ECDH + EC_KEY *ecdh; + int nid; + #endif ++#endif + + #ifdef USE_OPENSSL + DH *dh; +@@ -553,6 +568,11 @@ + /* load SSL certificates */ + for (i = 0; i < srv->config_context->used; i++) { + specific_config *s = srv->config_storage[i]; ++#ifndef SSL_OP_NO_COMPRESSION ++# define SSL_OP_NO_COMPRESSION 0 ++#endif ++ long ssloptions = ++ SSL_OP_ALL | SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION | SSL_OP_NO_COMPRESSION; + + if (buffer_is_empty(s->ssl_pemfile)) continue; + +@@ -586,6 +606,9 @@ + return -1; + } + ++ SSL_CTX_set_options(s->ssl_ctx, ssloptions); ++ SSL_CTX_set_info_callback(s->ssl_ctx, ssl_info_callback); ++ + if (!s->ssl_use_sslv2) { + /* disable SSLv2 */ + if (!(SSL_OP_NO_SSLv2 & SSL_CTX_set_options(s->ssl_ctx, SSL_OP_NO_SSLv2))) { +@@ -611,6 +634,10 @@ + ERR_error_string(ERR_get_error(), NULL)); + return -1; } - break; ++ ++ if (s->ssl_honor_cipher_order) { ++ SSL_CTX_set_options(s->ssl_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); ++ } } -@@ -299,6 +310,8 @@ + /* Support for Diffie-Hellman key exchange */ +@@ -847,7 +874,7 @@ return 0; - #else -+ UNUSED(srv); -+ UNUSED(con); - return -1; - #endif } -@@ -427,21 +440,22 @@ + +-int network_write_chunkqueue(server *srv, connection *con, chunkqueue *cq) { ++int network_write_chunkqueue(server *srv, connection *con, chunkqueue *cq, off_t max_bytes) { + int ret = -1; + off_t written = 0; + #ifdef TCP_CORK +@@ -855,16 +882,34 @@ + #endif + server_socket *srv_socket = con->srv_socket; + +- if (con->conf.global_kbytes_per_second && +- *(con->conf.global_bytes_per_second_cnt_ptr) > con->conf.global_kbytes_per_second * 1024) { +- /* we reached the global traffic limit */ ++ if (con->conf.global_kbytes_per_second) { ++ off_t limit = con->conf.global_kbytes_per_second * 1024 - *(con->conf.global_bytes_per_second_cnt_ptr); ++ if (limit <= 0) { ++ /* we reached the global traffic limit */ + +- con->traffic_limit_reached = 1; +- joblist_append(srv, con); ++ con->traffic_limit_reached = 1; ++ joblist_append(srv, con); + +- return 1; ++ return 1; ++ } else { ++ if (max_bytes > limit) max_bytes = limit; ++ } } - switch(con->http_status) { -- case 400: /* class: header + custom body */ -- case 401: -- case 403: -- case 404: -- case 408: -- case 409: -- case 411: -- case 416: -- case 423: -- case 500: -- case 501: -- case 503: -- case 505: -+ case 204: /* class: header only */ -+ case 205: -+ case 304: -+ /* disable chunked encoding again as we have no body */ -+ con->response.transfer_encoding &= ~HTTP_TRANSFER_ENCODING_CHUNKED; -+ con->parsed_response &= ~HTTP_CONTENT_LENGTH; -+ chunkqueue_reset(con->write_queue); ++ if (con->conf.kbytes_per_second) { ++ off_t limit = con->conf.kbytes_per_second * 1024 - con->bytes_written_cur_second; ++ if (limit <= 0) { ++ /* we reached the traffic limit */ + -+ con->file_finished = 1; -+ break; -+ default: /* class: header + body */ - if (con->mode != DIRECT) break; - -+ /* only custom body for 4xx and 5xx */ -+ if (con->http_status < 400 || con->http_status >= 600) break; ++ con->traffic_limit_reached = 1; ++ joblist_append(srv, con); + - con->file_finished = 0; - - buffer_reset(con->physical.path); -@@ -451,7 +465,8 @@ - stat_cache_entry *sce = NULL; ++ return 1; ++ } else { ++ if (max_bytes > limit) max_bytes = limit; ++ } ++ } ++ + written = cq->bytes_out; - buffer_copy_string_buffer(con->physical.path, con->conf.errorfile_prefix); -- buffer_append_string(con->physical.path, get_http_status_body_name(con->http_status)); -+ buffer_append_long(con->physical.path, con->http_status); -+ buffer_append_string_len(con->physical.path, CONST_STR_LEN(".html")); - - if (HANDLER_ERROR != stat_cache_get_entry(srv, con, con->physical.path, &sce)) { - con->file_finished = 1; -@@ -470,57 +485,34 @@ - b = chunkqueue_get_append_buffer(con->write_queue); - - /* build default error-page */ -- buffer_copy_string(b, -+ buffer_copy_string_len(b, CONST_STR_LEN( - "\n" - "\n" - "\n" - " \n" -- " "); -+ " <title>")); - buffer_append_long(b, con->http_status); -- buffer_append_string(b, " - "); -+ buffer_append_string_len(b, CONST_STR_LEN(" - ")); - buffer_append_string(b, get_http_status_name(con->http_status)); - -- buffer_append_string(b, -+ buffer_append_string_len(b, CONST_STR_LEN( - "\n" - " \n" - " \n" -- "

"); -+ "

")); - buffer_append_long(b, con->http_status); -- buffer_append_string(b, " - "); -+ buffer_append_string_len(b, CONST_STR_LEN(" - ")); - buffer_append_string(b, get_http_status_name(con->http_status)); - -- buffer_append_string(b,"

\n" -+ buffer_append_string_len(b, CONST_STR_LEN("\n" - " \n" - "\n" -- ); -+ )); - - response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html")); - } -- /* fall through */ -- case 207: -- case 200: /* class: header + body */ -- case 201: -- case 300: -- case 301: -- case 302: -- case 303: -- case 307: - break; -- -- case 206: /* write_queue is already prepared */ -- break; -- case 204: -- case 205: /* class: header only */ -- case 304: -- default: -- /* disable chunked encoding again as we have no body */ -- con->response.transfer_encoding &= ~HTTP_TRANSFER_ENCODING_CHUNKED; -- con->parsed_response &= ~HTTP_CONTENT_LENGTH; -- chunkqueue_reset(con->write_queue); -- -- con->file_finished = 1; -- break; - } + #ifdef TCP_CORK +@@ -879,10 +924,10 @@ - if (con->file_finished) { -@@ -544,7 +536,7 @@ - data_string *ds; - /* no Content-Body, no Content-Length */ - if (NULL != (ds = (data_string*) array_get_element(con->response.headers, "Content-Length"))) { -- buffer_reset(ds->value); // Headers with empty values are ignored for output -+ buffer_reset(ds->value); /* Headers with empty values are ignored for output */ - } - } else if (qlen > 0 || con->request.http_method != HTTP_METHOD_HEAD) { - /* qlen = 0 is important for Redirects (301, ...) as they MAY have -@@ -846,7 +838,7 @@ + if (srv_socket->is_ssl) { + #ifdef USE_OPENSSL +- ret = srv->network_ssl_backend_write(srv, con, con->ssl, cq); ++ ret = srv->network_ssl_backend_write(srv, con, con->ssl, cq, max_bytes); + #endif + } else { +- ret = srv->network_backend_write(srv, con, con->fd, cq); ++ ret = srv->network_backend_write(srv, con, con->fd, cq, max_bytes); } - /* The cond_cache gets reset in response.c */ --// config_cond_cache_reset(srv, con); -+ /* config_cond_cache_reset(srv, con); */ + if (ret >= 0) { +@@ -903,12 +948,5 @@ - #ifdef USE_OPENSSL - if (con->ssl_error_want_reuse_buffer) { -@@ -1668,21 +1660,51 @@ - } - #ifdef USE_OPENSSL - if (srv_sock->is_ssl) { -- int ret; -+ int ret, ssl_r; -+ unsigned long err; -+ ERR_clear_error(); - switch ((ret = SSL_shutdown(con->ssl))) { - case 1: - /* ok */ - break; - case 0: -- SSL_shutdown(con->ssl); -- break; -+ ERR_clear_error(); -+ if (-1 != (ret = SSL_shutdown(con->ssl))) break; -+ -+ /* fall through */ - default: -- log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:", -- SSL_get_error(con->ssl, ret), -- ERR_error_string(ERR_get_error(), NULL)); -- return -1; -+ -+ switch ((ssl_r = SSL_get_error(con->ssl, ret))) { -+ case SSL_ERROR_WANT_WRITE: -+ case SSL_ERROR_WANT_READ: -+ break; -+ case SSL_ERROR_SYSCALL: -+ /* perhaps we have error waiting in our error-queue */ -+ if (0 != (err = ERR_get_error())) { -+ do { -+ log_error_write(srv, __FILE__, __LINE__, "sdds", "SSL:", -+ ssl_r, ret, -+ ERR_error_string(err, NULL)); -+ } while((err = ERR_get_error())); -+ } else { -+ log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL (error):", -+ ssl_r, ret, errno, -+ strerror(errno)); -+ } -+ -+ break; -+ default: -+ while((err = ERR_get_error())) { -+ log_error_write(srv, __FILE__, __LINE__, "sdds", "SSL:", -+ ssl_r, ret, -+ ERR_error_string(err, NULL)); -+ } -+ -+ break; -+ } - } - } -+ ERR_clear_error(); - #endif + *(con->conf.global_bytes_per_second_cnt_ptr) += written; - switch(con->mode) { -Index: src/mod_staticfile.c +- if (con->conf.kbytes_per_second && +- (con->bytes_written_cur_second > con->conf.kbytes_per_second * 1024)) { +- /* we reached the traffic limit */ +- +- con->traffic_limit_reached = 1; +- joblist_append(srv, con); +- } + return ret; + } +Index: src/network.h =================================================================== ---- src/mod_staticfile.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/mod_staticfile.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -282,22 +282,22 @@ +--- src/network.h (.../tags/lighttpd-1.4.29) ++++ src/network.h (.../branches/lighttpd-1.4.x) +@@ -3,7 +3,7 @@ - b = chunkqueue_get_append_buffer(con->write_queue); + #include "server.h" -- buffer_copy_string(b, "\r\n--"); -+ buffer_copy_string_len(b, CONST_STR_LEN("\r\n--")); - buffer_append_string(b, boundary); +-int network_write_chunkqueue(server *srv, connection *con, chunkqueue *c); ++int network_write_chunkqueue(server *srv, connection *con, chunkqueue *c, off_t max_bytes); - /* write Content-Range */ -- buffer_append_string(b, "\r\nContent-Range: bytes "); -+ buffer_append_string_len(b, CONST_STR_LEN("\r\nContent-Range: bytes ")); - buffer_append_off_t(b, start); -- buffer_append_string(b, "-"); -+ buffer_append_string_len(b, CONST_STR_LEN("-")); - buffer_append_off_t(b, end); -- buffer_append_string(b, "/"); -+ buffer_append_string_len(b, CONST_STR_LEN("/")); - buffer_append_off_t(b, sce->st.st_size); + int network_init(server *srv); + int network_close(server *srv); +Index: src/configfile.c +=================================================================== +--- src/configfile.c (.../tags/lighttpd-1.4.29) ++++ src/configfile.c (.../branches/lighttpd-1.4.x) +@@ -105,6 +105,8 @@ + { "ssl.use-sslv3", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 62 */ + { "ssl.dh-file", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 63 */ + { "ssl.ec-curve", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 64 */ ++ { "ssl.disable-client-renegotiation", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },/* 65 */ ++ { "ssl.honor-cipher-order", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 66 */ -- buffer_append_string(b, "\r\nContent-Type: "); -+ buffer_append_string_len(b, CONST_STR_LEN("\r\nContent-Type: ")); - buffer_append_string_buffer(b, content_type); + { "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 }, +@@ -176,6 +178,7 @@ + s->max_write_idle = 360; + s->use_xattr = 0; + s->is_ssl = 0; ++ s->ssl_honor_cipher_order = 1; + s->ssl_use_sslv2 = 0; + s->ssl_use_sslv3 = 1; + s->use_ipv6 = 0; +@@ -199,6 +202,7 @@ + s->ssl_verifyclient_username = buffer_init(); + s->ssl_verifyclient_depth = 9; + s->ssl_verifyclient_export_cert = 0; ++ s->ssl_disable_client_renegotiation = 1; + + cv[2].destination = s->errorfile_prefix; + +@@ -245,6 +249,8 @@ + cv[62].destination = &(s->ssl_use_sslv3); + cv[63].destination = s->ssl_dh_file; + cv[64].destination = s->ssl_ec_curve; ++ cv[66].destination = &(s->ssl_honor_cipher_order); ++ + cv[49].destination = &(s->etag_use_inode); + cv[50].destination = &(s->etag_use_mtime); + cv[51].destination = &(s->etag_use_size); +@@ -255,6 +261,7 @@ + cv[58].destination = &(s->ssl_verifyclient_depth); + cv[59].destination = s->ssl_verifyclient_username; + cv[60].destination = &(s->ssl_verifyclient_export_cert); ++ cv[65].destination = &(s->ssl_disable_client_renegotiation); - /* write END-OF-HEADER */ -- buffer_append_string(b, "\r\n\r\n"); -+ buffer_append_string_len(b, CONST_STR_LEN("\r\n\r\n")); + srv->config_storage[i] = s; - con->response.content_length += b->used - 1; +@@ -335,6 +342,7 @@ + PATCH(ssl_cipher_list); + PATCH(ssl_dh_file); + PATCH(ssl_ec_curve); ++ PATCH(ssl_honor_cipher_order); + PATCH(ssl_use_sslv2); + PATCH(ssl_use_sslv3); + PATCH(etag_use_inode); +@@ -346,6 +354,7 @@ + PATCH(ssl_verifyclient_depth); + PATCH(ssl_verifyclient_username); + PATCH(ssl_verifyclient_export_cert); ++ PATCH(ssl_disable_client_renegotiation); -@@ -325,7 +325,7 @@ + return 0; + } +@@ -400,6 +409,8 @@ + #endif + } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.ca-file"))) { + PATCH(ssl_ca_file); ++ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.honor-cipher-order"))) { ++ PATCH(ssl_honor_cipher_order); + } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.use-sslv2"))) { + PATCH(ssl_use_sslv2); + } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.use-sslv3"))) { +@@ -454,6 +465,8 @@ + PATCH(ssl_verifyclient_username); + } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.verifyclient.exportcert"))) { + PATCH(ssl_verifyclient_export_cert); ++ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.disable-client-renegotiation"))) { ++ PATCH(ssl_disable_client_renegotiation); + } + } + } +Index: src/mod_scgi.c +=================================================================== +--- src/mod_scgi.c (.../tags/lighttpd-1.4.29) ++++ src/mod_scgi.c (.../branches/lighttpd-1.4.x) +@@ -2296,7 +2296,7 @@ - /* set header-fields */ + /* fall through */ + case FCGI_STATE_WRITE: +- ret = srv->network_backend_write(srv, con, hctx->fd, hctx->wb); ++ ret = srv->network_backend_write(srv, con, hctx->fd, hctx->wb, MAX_WRITE_LIMIT); -- buffer_copy_string(p->range_buf, "multipart/byteranges; boundary="); -+ buffer_copy_string_len(p->range_buf, CONST_STR_LEN("multipart/byteranges; boundary=")); - buffer_append_string(p->range_buf, boundary); + chunkqueue_remove_finished_chunks(hctx->wb); - /* overwrite content-type */ -@@ -333,11 +333,11 @@ - } else { - /* add Content-Range-header */ - -- buffer_copy_string(p->range_buf, "bytes "); -+ buffer_copy_string_len(p->range_buf, CONST_STR_LEN("bytes ")); - buffer_append_off_t(p->range_buf, start); -- buffer_append_string(p->range_buf, "-"); -+ buffer_append_string_len(p->range_buf, CONST_STR_LEN("-")); - buffer_append_off_t(p->range_buf, end); -- buffer_append_string(p->range_buf, "/"); -+ buffer_append_string_len(p->range_buf, CONST_STR_LEN("/")); - buffer_append_off_t(p->range_buf, sce->st.st_size); - - response_header_insert(srv, con, CONST_STR_LEN("Content-Range"), CONST_BUF_LEN(p->range_buf)); -Index: src/network.c +Index: src/request.c +=================================================================== +--- src/request.c (.../tags/lighttpd-1.4.29) ++++ src/request.c (.../branches/lighttpd-1.4.x) +@@ -49,7 +49,7 @@ + if (++colon_cnt > 7) { + return -1; + } +- } else if (!light_isxdigit(*c)) { ++ } else if (!light_isxdigit(*c) && '.' != *c) { + return -1; + } + } +Index: src/network_backends.h =================================================================== ---- src/network.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/network.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -494,7 +494,7 @@ - b = buffer_init(); +--- src/network_backends.h (.../tags/lighttpd-1.4.29) ++++ src/network_backends.h (.../branches/lighttpd-1.4.x) +@@ -47,18 +47,18 @@ + #include "base.h" - buffer_copy_string_buffer(b, srv->srvconf.bindhost); -- buffer_append_string(b, ":"); -+ buffer_append_string_len(b, CONST_STR_LEN(":")); - buffer_append_long(b, srv->srvconf.port); + /* return values: +- * >= 0 : chunks completed ++ * >= 0 : no error + * -1 : error (on our side) + * -2 : remote close + */ - if (0 != network_server_init(srv, b, srv->config_storage[0])) { -Index: src/configfile.c +-int network_write_chunkqueue_write(server *srv, connection *con, int fd, chunkqueue *cq); +-int network_write_chunkqueue_writev(server *srv, connection *con, int fd, chunkqueue *cq); +-int network_write_chunkqueue_linuxsendfile(server *srv, connection *con, int fd, chunkqueue *cq); +-int network_write_chunkqueue_freebsdsendfile(server *srv, connection *con, int fd, chunkqueue *cq); +-int network_write_chunkqueue_solarissendfilev(server *srv, connection *con, int fd, chunkqueue *cq); ++int network_write_chunkqueue_write(server *srv, connection *con, int fd, chunkqueue *cq, off_t max_bytes); ++int network_write_chunkqueue_writev(server *srv, connection *con, int fd, chunkqueue *cq, off_t max_bytes); ++int network_write_chunkqueue_linuxsendfile(server *srv, connection *con, int fd, chunkqueue *cq, off_t max_bytes); ++int network_write_chunkqueue_freebsdsendfile(server *srv, connection *con, int fd, chunkqueue *cq, off_t max_bytes); ++int network_write_chunkqueue_solarissendfilev(server *srv, connection *con, int fd, chunkqueue *cq, off_t max_bytes); + #ifdef USE_OPENSSL +-int network_write_chunkqueue_openssl(server *srv, connection *con, SSL *ssl, chunkqueue *cq); ++int network_write_chunkqueue_openssl(server *srv, connection *con, SSL *ssl, chunkqueue *cq, off_t max_bytes); + #endif + + #endif +Index: src/SConscript =================================================================== ---- src/configfile.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/configfile.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -7,6 +7,7 @@ - #include +--- src/SConscript (.../tags/lighttpd-1.4.29) ++++ src/SConscript (.../branches/lighttpd-1.4.x) +@@ -12,7 +12,8 @@ + data_integer.c md5.c data_fastcgi.c \ + fdevent_select.c fdevent_libev.c \ + fdevent_poll.c fdevent_linux_sysepoll.c \ +- fdevent_solaris_devpoll.c fdevent_freebsd_kqueue.c \ ++ fdevent_solaris_devpoll.c fdevent_solaris_port.c \ ++ fdevent_freebsd_kqueue.c \ + data_config.c bitset.c \ + inet_ntop_cache.c crc32.c \ + connections-glue.c \ +@@ -62,7 +63,7 @@ + 'mod_redirect' : { 'src' : [ 'mod_redirect.c' ], 'lib' : [ env['LIBPCRE'] ] }, + 'mod_rewrite' : { 'src' : [ 'mod_rewrite.c' ], 'lib' : [ env['LIBPCRE'] ] }, + 'mod_auth' : { +- 'src' : [ 'mod_auth.c', 'http_auth_digest.c', 'http_auth.c' ], ++ 'src' : [ 'mod_auth.c', 'http_auth.c' ], + 'lib' : [ env['LIBCRYPT'], env['LIBLDAP'], env['LIBLBER'] ] }, + 'mod_webdav' : { 'src' : [ 'mod_webdav.c' ], 'lib' : [ env['LIBXML2'], env['LIBSQLITE3'], env['LIBUUID'] ] }, + 'mod_mysql_vhost' : { 'src' : [ 'mod_mysql_vhost.c' ], 'lib' : [ env['LIBMYSQL'] ] }, +Index: src/mod_cml_funcs.c +=================================================================== +--- src/mod_cml_funcs.c (.../tags/lighttpd-1.4.29) ++++ src/mod_cml_funcs.c (.../branches/lighttpd-1.4.x) +@@ -17,18 +17,8 @@ + #include #include - #include -+#include - #include - #include "server.h" -@@ -74,24 +75,25 @@ - { "debug.log-request-handling", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 32 */ - { "debug.log-response-header", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 33 */ - { "debug.log-request-header", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 34 */ -+ { "debug.log-ssl-noise", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 35 */ - -- { "server.protocol-http11", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 35 */ -- { "debug.log-request-header-on-error", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 36 */ -- { "debug.log-state-handling", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 37 */ -- { "ssl.ca-file", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 38 */ -+ { "server.protocol-http11", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 36 */ -+ { "debug.log-request-header-on-error", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 37 */ -+ { "debug.log-state-handling", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 38 */ -+ { "ssl.ca-file", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 39 */ - -- { "server.errorlog-use-syslog", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 39 */ -- { "server.range-requests", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 40 */ -- { "server.stat-cache-engine", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 41 */ -- { "server.max-connections", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_SERVER }, /* 42 */ -- { "server.network-backend", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 43 */ -- { "server.upload-dirs", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 44 */ -- { "server.core-files", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 45 */ -- { "ssl.cipher-list", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 46 */ -- { "ssl.use-sslv2", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 47 */ -- { "etag.use-inode", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 48 */ -- { "etag.use-mtime", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 49 */ -- { "etag.use-size", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 50 */ -+ { "server.errorlog-use-syslog", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 40 */ -+ { "server.range-requests", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 41 */ -+ { "server.stat-cache-engine", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 42 */ -+ { "server.max-connections", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_SERVER }, /* 43 */ -+ { "server.network-backend", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 44 */ -+ { "server.upload-dirs", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 45 */ -+ { "server.core-files", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 46 */ -+ { "ssl.cipher-list", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 47 */ -+ { "ssl.use-sslv2", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 48 */ -+ { "etag.use-inode", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 49 */ -+ { "etag.use-mtime", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 50 */ -+ { "etag.use-size", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 51 */ - { "server.host", "use server.bind instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, - { "server.docroot", "use server.document-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, - { "server.virtual-root", "load mod_simple_vhost and use simple-vhost.server-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, -@@ -120,18 +122,18 @@ - - cv[13].destination = &(srv->srvconf.max_worker); - cv[23].destination = &(srv->srvconf.max_fds); -- cv[36].destination = &(srv->srvconf.log_request_header_on_error); -- cv[37].destination = &(srv->srvconf.log_state_handling); -+ cv[37].destination = &(srv->srvconf.log_request_header_on_error); -+ cv[38].destination = &(srv->srvconf.log_state_handling); - -- cv[39].destination = &(srv->srvconf.errorlog_use_syslog); -+ cv[40].destination = &(srv->srvconf.errorlog_use_syslog); - - stat_cache_string = buffer_init(); -- cv[41].destination = stat_cache_string; -- cv[43].destination = srv->srvconf.network_backend; -- cv[44].destination = srv->srvconf.upload_tempdirs; -- cv[45].destination = &(srv->srvconf.enable_cores); -+ cv[42].destination = stat_cache_string; -+ cv[44].destination = srv->srvconf.network_backend; -+ cv[45].destination = srv->srvconf.upload_tempdirs; -+ cv[46].destination = &(srv->srvconf.enable_cores); - -- cv[42].destination = &(srv->srvconf.max_conns); -+ cv[43].destination = &(srv->srvconf.max_conns); - cv[12].destination = &(srv->srvconf.max_request_size); - srv->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); - -@@ -204,16 +206,17 @@ - cv[32].destination = &(s->log_request_handling); - cv[33].destination = &(s->log_response_header); - cv[34].destination = &(s->log_request_header); -+ cv[35].destination = &(s->log_ssl_noise); - -- cv[35].destination = &(s->allow_http11); -- cv[38].destination = s->ssl_ca_file; -- cv[40].destination = &(s->range_requests); -+ cv[36].destination = &(s->allow_http11); -+ cv[39].destination = s->ssl_ca_file; -+ cv[41].destination = &(s->range_requests); - -- cv[46].destination = s->ssl_cipher_list; -- cv[47].destination = &(s->ssl_use_sslv2); -- cv[48].destination = &(s->etag_use_inode); -- cv[49].destination = &(s->etag_use_mtime); -- cv[50].destination = &(s->etag_use_size); -+ cv[47].destination = s->ssl_cipher_list; -+ cv[48].destination = &(s->ssl_use_sslv2); -+ cv[49].destination = &(s->etag_use_inode); -+ cv[50].destination = &(s->etag_use_mtime); -+ cv[51].destination = &(s->etag_use_size); +-#ifdef USE_OPENSSL +-# include +-#else +-# include "md5.h" ++#include "md5.h" - srv->config_storage[i] = s; +-typedef li_MD5_CTX MD5_CTX; +-#define MD5_Init li_MD5_Init +-#define MD5_Update li_MD5_Update +-#define MD5_Final li_MD5_Final +- +-#endif +- + #define HASHLEN 16 + typedef unsigned char HASH[HASHLEN]; + #define HASHHEXLEN 32 +@@ -43,7 +33,7 @@ + #ifdef HAVE_LUA_H + + int f_crypto_md5(lua_State *L) { +- MD5_CTX Md5Ctx; ++ li_MD5_CTX Md5Ctx; + HASH HA1; + buffer b; + char hex[33]; +@@ -63,9 +53,9 @@ + lua_error(L); + } + +- MD5_Init(&Md5Ctx); +- MD5_Update(&Md5Ctx, (unsigned char *)lua_tostring(L, 1), lua_strlen(L, 1)); +- MD5_Final(HA1, &Md5Ctx); ++ li_MD5_Init(&Md5Ctx); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)lua_tostring(L, 1), lua_strlen(L, 1)); ++ li_MD5_Final(HA1, &Md5Ctx); + + buffer_copy_string_hex(&b, (char *)HA1, 16); -@@ -279,6 +282,7 @@ - PATCH(log_request_handling); - PATCH(log_condition_handling); - PATCH(log_file_not_found); -+ PATCH(log_ssl_noise); +Index: src/mod_userdir.c +=================================================================== +--- src/mod_userdir.c (.../tags/lighttpd-1.4.29) ++++ src/mod_userdir.c (.../branches/lighttpd-1.4.x) +@@ -166,7 +166,6 @@ - PATCH(range_requests); - PATCH(force_lowercase_filenames); -@@ -305,9 +309,6 @@ - data_config *dc = (data_config *)srv->config_context->data[i]; - specific_config *s = srv->config_storage[i]; + URIHANDLER_FUNC(mod_userdir_docroot_handler) { + plugin_data *p = p_d; +- int uri_len; + size_t k; + char *rel_url; + #ifdef HAVE_PWD_H +@@ -182,8 +181,6 @@ + */ + if (p->conf.path->used == 0) return HANDLER_GO_ON; -- /* not our stage */ -- if (comp != dc->comp) continue; +- uri_len = con->uri.path->used - 1; - - /* condition didn't match */ - if (!config_check_cond(srv, con, dc)) continue; - -@@ -371,6 +372,8 @@ - PATCH(log_condition_handling); - } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("debug.log-file-not-found"))) { - PATCH(log_file_not_found); -+ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("debug.log-ssl-noise"))) { -+ PATCH(log_ssl_noise); - } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.protocol-http11"))) { - PATCH(allow_http11); - } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.force-lowercase-filenames"))) { -@@ -410,8 +413,8 @@ + /* /~user/foo.html -> /home/user/public_html/foo.html */ - #if 0 - static int tokenizer_open(server *srv, tokenizer_t *t, buffer *basedir, const char *fn) { -- if (buffer_is_empty(basedir) && -- (fn[0] == '/' || fn[0] == '\\') && -+ if (buffer_is_empty(basedir) || -+ (fn[0] == '/' || fn[0] == '\\') || - (fn[0] == '.' && (fn[1] == '/' || fn[1] == '\\'))) { - t->file = buffer_init_string(fn); - } else { -@@ -480,7 +483,7 @@ - if (t->input[t->offset + 1] == '>') { - t->offset += 2; + if (con->uri.path->ptr[0] != '/' || +Index: src/mod_proxy.c +=================================================================== +--- src/mod_proxy.c (.../tags/lighttpd-1.4.29) ++++ src/mod_proxy.c (.../branches/lighttpd-1.4.x) +@@ -825,7 +825,7 @@ -- buffer_copy_string(token, "=>"); -+ buffer_copy_string_len(token, CONST_STR_LEN("=>")); + /* fall through */ + case PROXY_STATE_WRITE:; +- ret = srv->network_backend_write(srv, con, hctx->fd, hctx->wb); ++ ret = srv->network_backend_write(srv, con, hctx->fd, hctx->wb, MAX_WRITE_LIMIT); - tid = TK_ARRAY_ASSIGN; - } else { -@@ -494,13 +497,13 @@ - if (t->input[t->offset + 1] == '=') { - t->offset += 2; + chunkqueue_remove_finished_chunks(hctx->wb); + +Index: src/Makefile.am +=================================================================== +--- src/Makefile.am (.../tags/lighttpd-1.4.29) ++++ src/Makefile.am (.../branches/lighttpd-1.4.x) +@@ -241,7 +241,7 @@ + mod_compress_la_LIBADD = $(Z_LIB) $(BZ_LIB) $(common_libadd) + + lib_LTLIBRARIES += mod_auth.la +-mod_auth_la_SOURCES = mod_auth.c http_auth_digest.c http_auth.c ++mod_auth_la_SOURCES = mod_auth.c http_auth.c + mod_auth_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined + mod_auth_la_LIBADD = $(CRYPT_LIB) $(LDAP_LIB) $(LBER_LIB) $(common_libadd) + +@@ -268,7 +268,7 @@ + + hdr = server.h buffer.h network.h log.h keyvalue.h \ + response.h request.h fastcgi.h chunk.h \ +- settings.h http_chunk.h http_auth_digest.h \ ++ settings.h http_chunk.h \ + md5.h http_auth.h stream.h \ + fdevent.h connections.h base.h stat_cache.h \ + plugin.h mod_auth.h \ +Index: src/network_writev.c +=================================================================== +--- src/network_writev.c (.../tags/lighttpd-1.4.29) ++++ src/network_writev.c (.../branches/lighttpd-1.4.x) +@@ -30,17 +30,16 @@ + #define LOCAL_BUFFERING 1 + #endif -- buffer_copy_string(token, "=="); -+ buffer_copy_string_len(token, CONST_STR_LEN("==")); +-int network_write_chunkqueue_writev(server *srv, connection *con, int fd, chunkqueue *cq) { ++int network_write_chunkqueue_writev(server *srv, connection *con, int fd, chunkqueue *cq, off_t max_bytes) { + chunk *c; +- size_t chunks_written = 0; + +- for(c = cq->first; c; c = c->next) { ++ for(c = cq->first; (max_bytes > 0) && (NULL != c); c = c->next) { + int chunk_finished = 0; + + switch(c->type) { + case MEM_CHUNK: { + char * offset; +- size_t toSend; ++ off_t toSend; + ssize_t r; + + size_t num_chunks, i; +@@ -65,12 +64,10 @@ + #error "sysconf() doesnt return _SC_IOV_MAX ..., check the output of 'man writev' for the EINVAL error and send the output to jan@kneschke.de" + #endif + +- /* we can't send more then SSIZE_MAX bytes in one chunk */ +- + /* build writev list + * + * 1. limit: num_chunks < max_chunks +- * 2. limit: num_bytes < SSIZE_MAX ++ * 2. limit: num_bytes < max_bytes + */ + for (num_chunks = 0, tc = c; tc && tc->type == MEM_CHUNK && num_chunks < max_chunks; num_chunks++, tc = tc->next); - tid = TK_EQ; - } else if (t->input[t->offset + 1] == '~') { - t->offset += 2; +@@ -87,9 +84,9 @@ + chunks[i].iov_base = offset; -- buffer_copy_string(token, "=~"); -+ buffer_copy_string_len(token, CONST_STR_LEN("=~")); + /* protect the return value of writev() */ +- if (toSend > SSIZE_MAX || +- num_bytes + toSend > SSIZE_MAX) { +- chunks[i].iov_len = SSIZE_MAX - num_bytes; ++ if (toSend > max_bytes || ++ (off_t) num_bytes + toSend > max_bytes) { ++ chunks[i].iov_len = max_bytes - num_bytes; - tid = TK_MATCH; - } else { -@@ -533,13 +536,13 @@ - if (t->input[t->offset + 1] == '=') { - t->offset += 2; + num_chunks = i + 1; + break; +@@ -121,6 +118,7 @@ + } -- buffer_copy_string(token, "!="); -+ buffer_copy_string_len(token, CONST_STR_LEN("!=")); + cq->bytes_out += r; ++ max_bytes -= r; - tid = TK_NE; - } else if (t->input[t->offset + 1] == '~') { - t->offset += 2; + /* check which chunks have been written */ -- buffer_copy_string(token, "!~"); -+ buffer_copy_string_len(token, CONST_STR_LEN("!~")); +@@ -132,11 +130,10 @@ - tid = TK_NOMATCH; + if (chunk_finished) { + /* skip the chunks from further touches */ +- chunks_written++; + c = c->next; + } else { + /* chunks_written + c = c->next is done in the for()*/ +- chunk_finished++; ++ chunk_finished = 1; + } } else { -@@ -594,7 +597,7 @@ - } - t->in_key = 1; - tid = TK_EOL; -- buffer_copy_string(token, "(EOL)"); -+ buffer_copy_string_len(token, CONST_STR_LEN("(EOL)")); - } else { - config_skip_newline(t); - t->line_pos = 1; -@@ -605,7 +608,7 @@ - if (t->in_brace > 0) { - tid = TK_COMMA; - -- buffer_copy_string(token, "(COMMA)"); -+ buffer_copy_string_len(token, CONST_STR_LEN("(COMMA)")); + /* partially written */ +@@ -284,6 +281,8 @@ + assert(toSend < 0); } - t->offset++; -@@ -614,7 +617,7 @@ - case '"': - /* search for the terminating " */ - start = t->input + t->offset + 1; -- buffer_copy_string(token, ""); -+ buffer_copy_string_len(token, CONST_STR_LEN("")); ++ if (toSend > max_bytes) toSend = max_bytes; ++ + #ifdef LOCAL_BUFFERING + start = c->mem->ptr; + #else +@@ -309,6 +308,7 @@ - for (i = 1; t->input[t->offset + i]; i++) { - if (t->input[t->offset + i] == '\\' && -@@ -660,7 +663,7 @@ + c->offset += r; + cq->bytes_out += r; ++ max_bytes -= r; - tid = TK_LPARAN; + if (c->offset == c->file.length) { + chunk_finished = 1; +@@ -334,11 +334,9 @@ -- buffer_copy_string(token, "("); -+ buffer_copy_string_len(token, CONST_STR_LEN("(")); break; - case ')': - t->offset++; -@@ -668,7 +671,7 @@ + } +- +- chunks_written++; + } - tid = TK_RPARAN; +- return chunks_written; ++ return 0; + } -- buffer_copy_string(token, ")"); -+ buffer_copy_string_len(token, CONST_STR_LEN(")")); - break; - case '$': - t->offset++; -@@ -677,19 +680,19 @@ - t->in_cond = 1; - t->in_key = 0; + #endif +Index: src/network_freebsd_sendfile.c +=================================================================== +--- src/network_freebsd_sendfile.c (.../tags/lighttpd-1.4.29) ++++ src/network_freebsd_sendfile.c (.../branches/lighttpd-1.4.x) +@@ -31,17 +31,16 @@ + # endif + #endif -- buffer_copy_string(token, "$"); -+ buffer_copy_string_len(token, CONST_STR_LEN("$")); +-int network_write_chunkqueue_freebsdsendfile(server *srv, connection *con, int fd, chunkqueue *cq) { ++int network_write_chunkqueue_freebsdsendfile(server *srv, connection *con, int fd, chunkqueue *cq, off_t max_bytes) { + chunk *c; +- size_t chunks_written = 0; - break; +- for(c = cq->first; c; c = c->next, chunks_written++) { ++ for(c = cq->first; (max_bytes > 0) && (NULL != c); c = c->next) { + int chunk_finished = 0; - case '+': - if (t->input[t->offset + 1] == '=') { - t->offset += 2; -- buffer_copy_string(token, "+="); -+ buffer_copy_string_len(token, CONST_STR_LEN("+=")); - tid = TK_APPEND; - } else { - t->offset++; - tid = TK_PLUS; -- buffer_copy_string(token, "+"); -+ buffer_copy_string_len(token, CONST_STR_LEN("+")); - } - break; + switch(c->type) { + case MEM_CHUNK: { + char * offset; +- size_t toSend; ++ off_t toSend; + ssize_t r; -@@ -698,7 +701,7 @@ + size_t num_chunks, i; +@@ -49,12 +48,10 @@ + chunk *tc; + size_t num_bytes = 0; - tid = TK_LCURLY; +- /* we can't send more then SSIZE_MAX bytes in one chunk */ +- + /* build writev list + * + * 1. limit: num_chunks < UIO_MAXIOV +- * 2. limit: num_bytes < SSIZE_MAX ++ * 2. limit: num_bytes < max_bytes + */ + for(num_chunks = 0, tc = c; tc && tc->type == MEM_CHUNK && num_chunks < UIO_MAXIOV; num_chunks++, tc = tc->next); -- buffer_copy_string(token, "{"); -+ buffer_copy_string_len(token, CONST_STR_LEN("{")); +@@ -69,9 +66,9 @@ + chunks[i].iov_base = offset; - break; + /* protect the return value of writev() */ +- if (toSend > SSIZE_MAX || +- num_bytes + toSend > SSIZE_MAX) { +- chunks[i].iov_len = SSIZE_MAX - num_bytes; ++ if (toSend > max_bytes || ++ (off_t) num_bytes + toSend > max_bytes) { ++ chunks[i].iov_len = max_bytes - num_bytes; -@@ -707,7 +710,7 @@ + num_chunks = i + 1; + break; +@@ -105,6 +102,7 @@ - tid = TK_RCURLY; + /* check which chunks have been written */ + cq->bytes_out += r; ++ max_bytes -= r; -- buffer_copy_string(token, "}"); -+ buffer_copy_string_len(token, CONST_STR_LEN("}")); + for(i = 0, tc = c; i < num_chunks; i++, tc = tc->next) { + if (r >= (ssize_t)chunks[i].iov_len) { +@@ -114,11 +112,10 @@ - break; + if (chunk_finished) { + /* skip the chunks from further touches */ +- chunks_written++; + c = c->next; + } else { + /* chunks_written + c = c->next is done in the for()*/ +- chunk_finished++; ++ chunk_finished = 1; + } + } else { + /* partially written */ +@@ -134,7 +131,7 @@ + } + case FILE_CHUNK: { + off_t offset, r; +- size_t toSend; ++ off_t toSend; + stat_cache_entry *sce = NULL; -@@ -716,7 +719,7 @@ + if (HANDLER_ERROR == stat_cache_get_entry(srv, con, c->file.name, &sce)) { +@@ -144,9 +141,8 @@ + } - tid = TK_LBRACKET; + offset = c->file.start + c->offset; +- /* limit the toSend to 2^31-1 bytes in a chunk */ +- toSend = c->file.length - c->offset > ((1 << 30) - 1) ? +- ((1 << 30) - 1) : c->file.length - c->offset; ++ toSend = c->file.length - c->offset; ++ if (toSend > max_bytes) toSend = max_bytes; -- buffer_copy_string(token, "["); -+ buffer_copy_string_len(token, CONST_STR_LEN("[")); + if (-1 == c->file.fd) { + if (-1 == (c->file.fd = open(c->file.name->ptr, O_RDONLY))) { +@@ -197,6 +193,7 @@ - break; + c->offset += r; + cq->bytes_out += r; ++ max_bytes -= r; -@@ -725,7 +728,7 @@ + if (c->offset == c->file.length) { + chunk_finished = 1; +@@ -218,7 +215,7 @@ + } + } - tid = TK_RBRACKET; +- return chunks_written; ++ return 0; + } -- buffer_copy_string(token, "]"); -+ buffer_copy_string_len(token, CONST_STR_LEN("]")); + #endif +Index: src/network_openssl.c +=================================================================== +--- src/network_openssl.c (.../tags/lighttpd-1.4.29) ++++ src/network_openssl.c (.../branches/lighttpd-1.4.x) +@@ -27,10 +27,9 @@ + # include + # include - break; - case '#': -@@ -884,8 +887,8 @@ - int ret; - buffer *filename; - -- if (buffer_is_empty(context->basedir) && -- (fn[0] == '/' || fn[0] == '\\') && -+ if (buffer_is_empty(context->basedir) || -+ (fn[0] == '/' || fn[0] == '\\') || - (fn[0] == '.' && (fn[1] == '/' || fn[1] == '\\'))) { - filename = buffer_init_string(fn); - } else { -@@ -912,15 +915,39 @@ - return ret; - } +-int network_write_chunkqueue_openssl(server *srv, connection *con, SSL *ssl, chunkqueue *cq) { ++int network_write_chunkqueue_openssl(server *srv, connection *con, SSL *ssl, chunkqueue *cq, off_t max_bytes) { + int ssl_r; + chunk *c; +- size_t chunks_written = 0; -+static char* getCWD() { -+ char *s, *s1; -+ size_t len; -+#ifdef PATH_MAX -+ len = PATH_MAX; -+#else -+ len = 4096; -+#endif -+ -+ s = malloc(len); -+ if (!s) return NULL; -+ while (NULL == getcwd(s, len)) { -+ if (errno != ERANGE || SSIZE_MAX - len < len) return NULL; -+ len *= 2; -+ s1 = realloc(s, len); -+ if (!s1) { -+ free(s); -+ return NULL; -+ } -+ s = s1; -+ } -+ return s; -+} -+ - int config_parse_cmd(server *srv, config_t *context, const char *cmd) { - proc_handler_t proc; - tokenizer_t t; - int ret; - buffer *source; - buffer *out; -- char oldpwd[PATH_MAX]; -+ char *oldpwd; - -- if (NULL == getcwd(oldpwd, sizeof(oldpwd))) { -+ if (NULL == (oldpwd = getCWD())) { - log_error_write(srv, __FILE__, __LINE__, "s", - "cannot get cwd", strerror(errno)); - return -1; -@@ -945,6 +972,7 @@ - buffer_free(source); - buffer_free(out); - chdir(oldpwd); -+ free(oldpwd); - return ret; - } - -@@ -986,7 +1014,7 @@ + /* this is a 64k sendbuffer + * +@@ -59,13 +58,13 @@ + SSL_set_shutdown(ssl, SSL_RECEIVED_SHUTDOWN); } - dc = data_config_init(); -- buffer_copy_string(dc->key, "global"); -+ buffer_copy_string_len(dc->key, CONST_STR_LEN("global")); - - assert(context.all_configs->used == 0); - dc->context_ndx = context.all_configs->used; -@@ -997,14 +1025,14 @@ - srv->config = dc->value; - dpid = data_integer_init(); - dpid->value = getpid(); -- buffer_copy_string(dpid->key, "var.PID"); -+ buffer_copy_string_len(dpid->key, CONST_STR_LEN("var.PID")); - array_insert_unique(srv->config, (data_unset *)dpid); - - dcwd = data_string_init(); - buffer_prepare_copy(dcwd->value, 1024); - if (NULL != getcwd(dcwd->value->ptr, dcwd->value->size - 1)) { - dcwd->value->used = strlen(dcwd->value->ptr) + 1; -- buffer_copy_string(dcwd->key, "var.CWD"); -+ buffer_copy_string_len(dcwd->key, CONST_STR_LEN("var.CWD")); - array_insert_unique(srv->config, (data_unset *)dcwd); - } +- for(c = cq->first; c; c = c->next) { ++ for(c = cq->first; (max_bytes > 0) && (NULL != c); c = c->next) { + int chunk_finished = 0; -@@ -1038,7 +1066,7 @@ - /* prepend default modules */ - if (NULL == array_get_element(modules->value, "mod_indexfile")) { - ds = data_string_init(); -- buffer_copy_string(ds->value, "mod_indexfile"); -+ buffer_copy_string_len(ds->value, CONST_STR_LEN("mod_indexfile")); - array_insert_unique(prepends->value, (data_unset *)ds); - } + switch(c->type) { + case MEM_CHUNK: { + char * offset; +- size_t toSend; ++ off_t toSend; + ssize_t r; -@@ -1051,13 +1079,13 @@ - /* append default modules */ - if (NULL == array_get_element(modules->value, "mod_dirlisting")) { - ds = data_string_init(); -- buffer_copy_string(ds->value, "mod_dirlisting"); -+ buffer_copy_string_len(ds->value, CONST_STR_LEN("mod_dirlisting")); - array_insert_unique(modules->value, (data_unset *)ds); - } + if (c->mem->used == 0 || c->mem->used == 1) { +@@ -75,6 +74,7 @@ - if (NULL == array_get_element(modules->value, "mod_staticfile")) { - ds = data_string_init(); -- buffer_copy_string(ds->value, "mod_staticfile"); -+ buffer_copy_string_len(ds->value, CONST_STR_LEN("mod_staticfile")); - array_insert_unique(modules->value, (data_unset *)ds); - } - } else { -@@ -1067,18 +1095,18 @@ - - /* server.modules is not set */ - ds = data_string_init(); -- buffer_copy_string(ds->value, "mod_indexfile"); -+ buffer_copy_string_len(ds->value, CONST_STR_LEN("mod_indexfile")); - array_insert_unique(modules->value, (data_unset *)ds); - - ds = data_string_init(); -- buffer_copy_string(ds->value, "mod_dirlisting"); -+ buffer_copy_string_len(ds->value, CONST_STR_LEN("mod_dirlisting")); - array_insert_unique(modules->value, (data_unset *)ds); - - ds = data_string_init(); -- buffer_copy_string(ds->value, "mod_staticfile"); -+ buffer_copy_string_len(ds->value, CONST_STR_LEN("mod_staticfile")); - array_insert_unique(modules->value, (data_unset *)ds); - -- buffer_copy_string(modules->key, "server.modules"); -+ buffer_copy_string_len(modules->key, CONST_STR_LEN("server.modules")); - array_insert_unique(srv->config, (data_unset *)modules); - } + offset = c->mem->ptr + c->offset; + toSend = c->mem->used - 1 - c->offset; ++ if (toSend > max_bytes) toSend = max_bytes; -Index: src/mod_trigger_b4_dl.c -=================================================================== ---- src/mod_trigger_b4_dl.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/mod_trigger_b4_dl.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -316,6 +316,8 @@ - # define N 10 - int ovec[N * 3]; + /** + * SSL_write man-page +@@ -87,7 +87,14 @@ + */ -+ if (con->mode != DIRECT) return HANDLER_GO_ON; + ERR_clear_error(); +- if ((r = SSL_write(ssl, offset, toSend)) <= 0) { ++ r = SSL_write(ssl, offset, toSend); + - if (con->uri.path->used == 0) return HANDLER_GO_ON; - - mod_trigger_b4_dl_patch_connection(srv, con, p); -@@ -425,8 +427,8 @@ - /* not found, redirect */ - - response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(p->conf.deny_url)); -- - con->http_status = 307; -+ con->file_finished = 1; - - return HANDLER_FINISHED; - } -@@ -440,6 +442,7 @@ - - response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(p->conf.deny_url)); - con->http_status = 307; -+ con->file_finished = 1; - - if (p->conf.db) { - if (0 != gdbm_delete(p->conf.db, key)) { -@@ -490,6 +493,7 @@ - response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(p->conf.deny_url)); - - con->http_status = 307; -+ con->file_finished = 1; ++ if (con->renegotiations > 1 && con->conf.ssl_disable_client_renegotiation) { ++ log_error_write(srv, __FILE__, __LINE__, "s", "SSL: renegotiation initiated by client"); ++ return -1; ++ } ++ ++ if (r <= 0) { + unsigned long err; - return HANDLER_FINISHED; + switch ((ssl_r = SSL_get_error(ssl, r))) { +@@ -139,6 +146,7 @@ + } else { + c->offset += r; + cq->bytes_out += r; ++ max_bytes -= r; } -Index: src/mod_evhost.c -=================================================================== ---- src/mod_evhost.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/mod_evhost.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -95,7 +95,7 @@ - s->path_pieces = realloc(s->path_pieces,(s->len+1) * sizeof(*s->path_pieces)); - s->path_pieces[s->len] = buffer_init(); - -- buffer_append_memory(s->path_pieces[s->len],pos,ptr-pos); -+ buffer_copy_string_len(s->path_pieces[s->len],pos,ptr-pos); - - s->len += 1; - } -@@ -181,7 +181,7 @@ - } - ds = data_string_init(); -- buffer_copy_string(ds->key,"%0"); -+ buffer_copy_string_len(ds->key,CONST_STR_LEN("%0")); - - /* if we stopped at a dot, skip the dot */ - if (*ptr == '.') ptr++; -@@ -197,7 +197,7 @@ - if (ptr != colon - 1) { - /* is something between the dots */ - ds = data_string_init(); -- buffer_copy_string(ds->key,"%"); -+ buffer_copy_string_len(ds->key,CONST_STR_LEN("%")); - buffer_append_long(ds->key, i++); - buffer_copy_string_len(ds->value,ptr+1,colon-ptr-1); - -@@ -210,7 +210,7 @@ - /* if the . is not the first charactor of the hostname */ - if (colon != ptr) { - ds = data_string_init(); -- buffer_copy_string(ds->key,"%"); -+ buffer_copy_string_len(ds->key,CONST_STR_LEN("%")); - buffer_append_long(ds->key, i++); - buffer_copy_string_len(ds->value,ptr,colon-ptr); - -@@ -286,7 +286,7 @@ - - if (*(ptr+1) == '%') { - /* %% */ -- BUFFER_APPEND_STRING_CONST(p->tmp_buf,"%"); -+ buffer_append_string_len(p->tmp_buf,CONST_STR_LEN("%")); - } else if (NULL != (ds = (data_string *)array_get_element(parsed_host,p->conf.path_pieces[i]->ptr))) { - if (ds->value->used) { - buffer_append_string_buffer(p->tmp_buf,ds->value); -Index: src/chunk.c -=================================================================== ---- src/chunk.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/chunk.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -296,7 +296,7 @@ - - buffer_copy_string_buffer(template, ds->value); - BUFFER_APPEND_SLASH(template); -- BUFFER_APPEND_STRING_CONST(template, "lighttpd-upload-XXXXXX"); -+ buffer_append_string_len(template, CONST_STR_LEN("lighttpd-upload-XXXXXX")); - - if (-1 != (c->file.fd = mkstemp(template->ptr))) { - /* only trigger the unlink if we created the temp-file successfully */ -Index: src/lemon.c -=================================================================== ---- src/lemon.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/lemon.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -12,6 +12,19 @@ - #include - #include + if (c->offset == (off_t)c->mem->used - 1) { +@@ -168,6 +176,7 @@ + do { + off_t offset = c->file.start + c->offset; + off_t toSend = c->file.length - c->offset; ++ if (toSend > max_bytes) toSend = max_bytes; -+#ifdef HAVE_CONFIG_H -+#include "config.h" -+#endif -+ -+#ifdef HAVE_STDINT_H -+# include -+#endif -+#ifdef HAVE_INTTYPES_H -+# include -+#endif -+ -+#define UNUSED(x) ( (void)(x) ) -+ - extern void qsort(); - extern double strtod(); - extern long strtol(); -@@ -983,6 +996,7 @@ - { - struct symbol *spx, *spy; - int errcnt = 0; -+ UNUSED(errsym); - assert( apx->sp==apy->sp ); /* Otherwise there would be no conflict */ - if( apx->type==SHIFT && apy->type==REDUCE ){ - spx = apx->sp; -@@ -1347,6 +1361,7 @@ - struct lemon lem; - char *def_tmpl_name = "lempar.c"; - -+ UNUSED(argc); - OptInit(argv,options,stderr); - if( version ){ - printf("Lemon version 1.0\n"); -@@ -1651,7 +1666,7 @@ - }else if( op[j].type==OPT_FLAG ){ - *((int*)op[j].arg) = v; - }else if( op[j].type==OPT_FFLAG ){ -- (*(void(*)())(op[j].arg))(v); -+ (*(void(*)())(intptr_t)(op[j].arg))(v); - }else{ - if( err ){ - fprintf(err,"%smissing argument on switch.\n",emsg); -@@ -1733,19 +1748,19 @@ - *(double*)(op[j].arg) = dv; - break; - case OPT_FDBL: -- (*(void(*)())(op[j].arg))(dv); -+ (*(void(*)())(intptr_t)(op[j].arg))(dv); - break; - case OPT_INT: - *(int*)(op[j].arg) = lv; - break; - case OPT_FINT: -- (*(void(*)())(op[j].arg))((int)lv); -+ (*(void(*)())(intptr_t)(op[j].arg))((int)lv); - break; - case OPT_STR: - *(char**)(op[j].arg) = sv; - break; - case OPT_FSTR: -- (*(void(*)())(op[j].arg))(sv); -+ (*(void(*)())(intptr_t)(op[j].arg))(sv); - break; - } - } -@@ -2286,10 +2301,10 @@ - ** token is passed to the function "parseonetoken" which builds all - ** the appropriate data structures in the global state vector "gp". - */ -+struct pstate ps; - void Parse(gp) - struct lemon *gp; - { -- struct pstate ps; - FILE *fp; - char *filebuf; - size_t filesize; -Index: src/mod_skeleton.c -=================================================================== ---- src/mod_skeleton.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/mod_skeleton.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -169,6 +169,8 @@ + if (toSend > LOCAL_SEND_BUFSIZE) toSend = LOCAL_SEND_BUFSIZE; - UNUSED(srv); +@@ -190,7 +199,14 @@ + close(ifd); -+ if (con->mode != DIRECT) return HANDLER_GO_ON; + ERR_clear_error(); +- if ((r = SSL_write(ssl, s, toSend)) <= 0) { ++ r = SSL_write(ssl, s, toSend); + - if (con->uri.path->used == 0) return HANDLER_GO_ON; - - mod_skeleton_patch_connection(srv, con, p); -Index: src/mod_scgi.c -=================================================================== ---- src/mod_scgi.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/mod_scgi.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -202,6 +202,15 @@ - * - */ - -+ /* -+ * workaround for program when prefix="/" -+ * -+ * rule to build PATH_INFO is hardcoded for when check_local is disabled -+ * enable this option to use the workaround -+ * -+ */ ++ if (con->renegotiations > 1 && con->conf.ssl_disable_client_renegotiation) { ++ log_error_write(srv, __FILE__, __LINE__, "s", "SSL: renegotiation initiated by client"); ++ return -1; ++ } + -+ unsigned short fix_root_path_name; - ssize_t load; /* replace by host->load */ ++ if (r <= 0) { + unsigned long err; - size_t max_id; /* corresponds most of the time to -@@ -233,6 +242,7 @@ - typedef struct { - buffer *key; /* like .php */ + switch ((ssl_r = SSL_get_error(ssl, r))) { +@@ -243,12 +259,13 @@ + } else { + c->offset += r; + cq->bytes_out += r; ++ max_bytes -= r; + } -+ int note_is_sent; - scgi_extension_host **hosts; + if (c->offset == c->file.length) { + chunk_finished = 1; + } +- } while(!chunk_finished && !write_wait); ++ } while (!chunk_finished && !write_wait && max_bytes > 0); - size_t used; -@@ -583,6 +593,7 @@ + break; + } +@@ -263,11 +280,9 @@ - static int env_add(char_array *env, const char *key, size_t key_len, const char *val, size_t val_len) { - char *dst; -+ size_t i; + break; + } +- +- chunks_written++; + } - if (!key || !val) return -1; +- return chunks_written; ++ return 0; + } + #endif -@@ -592,6 +603,15 @@ - /* add the \0 from the value */ - memcpy(dst + key_len + 1, val, val_len + 1); +Index: src/http_auth.c +=================================================================== +--- src/http_auth.c (.../tags/lighttpd-1.4.29) ++++ src/http_auth.c (.../branches/lighttpd-1.4.x) +@@ -1,7 +1,6 @@ + #include "server.h" + #include "log.h" + #include "http_auth.h" +-#include "http_auth_digest.h" + #include "inet_ntop_cache.h" + #include "stream.h" + +@@ -28,18 +27,23 @@ + #include + #include -+ for (i = 0; i < env->used; i++) { -+ if (0 == strncmp(dst, env->ptr[i], key_len + 1)) { -+ /* don't care about free as we are in a forked child which is going to exec(...) */ -+ /* free(env->ptr[i]); */ -+ env->ptr[i] = dst; -+ return 0; -+ } +-#ifdef USE_OPENSSL +-# include +-#else +-# include "md5.h" ++#include "md5.h" + +-typedef li_MD5_CTX MD5_CTX; +-#define MD5_Init li_MD5_Init +-#define MD5_Update li_MD5_Update +-#define MD5_Final li_MD5_Final ++#define HASHLEN 16 ++#define HASHHEXLEN 32 ++typedef unsigned char HASH[HASHLEN]; ++typedef char HASHHEX[HASHHEXLEN+1]; + +-#endif ++static void CvtHex(const HASH Bin, char Hex[33]) { ++ unsigned short i; + ++ for (i = 0; i < 16; i++) { ++ Hex[i*2] = int2hex((Bin[i] >> 4) & 0xf); ++ Hex[i*2+1] = int2hex(Bin[i] & 0xf); + } ++ Hex[32] = '\0'; ++} + - if (env->size == 0) { - env->size = 16; - env->ptr = malloc(env->size * sizeof(*env->ptr)); -@@ -749,11 +769,20 @@ - env.size = 0; - env.used = 0; - -+ if (scgi_fd != 0) { -+ close(0); -+ dup2(scgi_fd, 0); -+ close(scgi_fd); -+ scgi_fd = 0; -+ } -+ - /* we don't need the client socket */ - for (fd = 3; fd < 256; fd++) { -- if (fd != 2 && fd != scgi_fd) close(fd); -+ close(fd); - } - -+ openDevNull(STDERR_FILENO); -+ - /* build clean environment */ - if (host->bin_env_copy->used) { - for (i = 0; i < host->bin_env_copy->used; i++) { -@@ -794,7 +823,7 @@ - env.ptr[env.used] = NULL; - - b = buffer_init(); -- buffer_copy_string(b, "exec "); -+ buffer_copy_string_len(b, CONST_STR_LEN("exec ")); - buffer_append_string_buffer(b, host->bin_path); - - /* exec the cgi */ -@@ -968,6 +997,7 @@ - - { "bin-environment", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 11 */ - { "bin-copy-environment", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 12 */ -+ { "fix-root-scriptname", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 13 */ - - - { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } -@@ -990,6 +1020,7 @@ - df->max_load_per_proc = 1; - df->idle_timeout = 60; - df->disable_time = 60; -+ df->fix_root_path_name = 0; - - fcv[0].destination = df->host; - fcv[1].destination = df->docroot; -@@ -1006,6 +1037,7 @@ - - fcv[11].destination = df->bin_env; - fcv[12].destination = df->bin_env_copy; -+ fcv[13].destination = &(df->fix_root_path_name); - - - if (0 != config_insert_values_internal(srv, da_host->value, fcv)) { -@@ -1084,7 +1116,7 @@ - proc->port = df->port + pno; - } else { - buffer_copy_string_buffer(proc->socket, df->unixsocket); -- buffer_append_string(proc->socket, "-"); -+ buffer_append_string_len(proc->socket, CONST_STR_LEN("-")); - buffer_append_long(proc->socket, pno); - } - -@@ -1155,11 +1187,6 @@ - p = hctx->plugin_data; - con = hctx->remote_conn; - -- if (con->mode != p->id) { -- WP(); -- return; -- } -- - if (hctx->fd != -1) { - fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd); - fdevent_unregister(srv->ev, hctx->fd); -@@ -1366,7 +1393,7 @@ - buffer_reset(srv->tmp_buf); - - if (0 != strcasecmp(ds->key->ptr, "CONTENT-TYPE")) { -- BUFFER_COPY_STRING_CONST(srv->tmp_buf, "HTTP_"); -+ buffer_copy_string_len(srv->tmp_buf, CONST_STR_LEN("HTTP_")); - srv->tmp_buf->used--; - } - -@@ -1394,7 +1421,7 @@ - buffer_prepare_append(srv->tmp_buf, ds->key->used + 2); - for (j = 0; j < ds->key->used - 1; j++) { - srv->tmp_buf->ptr[srv->tmp_buf->used++] = -- isalpha((unsigned char)ds->key->ptr[j]) ? -+ light_isalnum((unsigned char)ds->key->ptr[j]) ? - toupper((unsigned char)ds->key->ptr[j]) : '_'; - } - srv->tmp_buf->ptr[srv->tmp_buf->used++] = '\0'; -@@ -1673,9 +1700,8 @@ - - status = strtol(s+9, NULL, 10); - -- if (con->http_status >= 100 && -- con->http_status < 1000) { -- /* we expected 3 digits and didn't got them */ -+ if (status >= 100 && status < 1000) { -+ /* we expected 3 digits got them */ - con->parsed_response |= HTTP_STATUS; - con->http_status = status; - } -@@ -2438,15 +2464,11 @@ - p = hctx->plugin_data; - con = hctx->remote_conn; - -- if (con->mode != p->id) return HANDLER_GO_ON; -- - log_error_write(srv, __FILE__, __LINE__, "ssdsd", - "emergency exit: scgi:", - "connection-fd:", con->fd, - "fcgi-fd:", hctx->fd); + /** + * the $apr1$ handling is taken from apache 1.3.x + */ +@@ -95,7 +99,7 @@ + ch = in[0]; + /* run through the whole string, converting as we go */ + for (i = 0; i < in_len; i++) { +- ch = in[i]; ++ ch = (unsigned char) in[i]; -- -- - scgi_connection_cleanup(srv, hctx); + if (ch == '\0') break; - return HANDLER_FINISHED; -@@ -2668,11 +2690,13 @@ - plugin_data *p = p_d; - size_t s_len; - int used = -1; -- int ndx; - size_t k; - buffer *fn; - scgi_extension *extension = NULL; -+ scgi_extension_host *host = NULL; +@@ -435,7 +439,7 @@ -+ if (con->mode != DIRECT) return HANDLER_GO_ON; -+ - /* Possibly, we processed already this request */ - if (con->file_started == 1) return HANDLER_GO_ON; + static void to64(char *s, unsigned long v, int n) + { +- static unsigned char itoa64[] = /* 0 ... 63 => ASCII - 64 */ ++ static const unsigned char itoa64[] = /* 0 ... 63 => ASCII - 64 */ + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + + while (--n >= 0) { +@@ -455,7 +459,7 @@ + const char *sp, *ep; + unsigned char final[APR_MD5_DIGESTSIZE]; + ssize_t sl, pl, i; +- MD5_CTX ctx, ctx1; ++ li_MD5_CTX ctx, ctx1; + unsigned long l; + + /* +@@ -487,33 +491,33 @@ + /* + * 'Time to make the doughnuts..' + */ +- MD5_Init(&ctx); ++ li_MD5_Init(&ctx); + + /* + * The password first, since that is what is most unknown + */ +- MD5_Update(&ctx, pw, strlen(pw)); ++ li_MD5_Update(&ctx, pw, strlen(pw)); + + /* + * Then our magic string + */ +- MD5_Update(&ctx, APR1_ID, strlen(APR1_ID)); ++ li_MD5_Update(&ctx, APR1_ID, strlen(APR1_ID)); + + /* + * Then the raw salt + */ +- MD5_Update(&ctx, sp, sl); ++ li_MD5_Update(&ctx, sp, sl); + + /* + * Then just as many characters of the MD5(pw, salt, pw) + */ +- MD5_Init(&ctx1); +- MD5_Update(&ctx1, pw, strlen(pw)); +- MD5_Update(&ctx1, sp, sl); +- MD5_Update(&ctx1, pw, strlen(pw)); +- MD5_Final(final, &ctx1); ++ li_MD5_Init(&ctx1); ++ li_MD5_Update(&ctx1, pw, strlen(pw)); ++ li_MD5_Update(&ctx1, sp, sl); ++ li_MD5_Update(&ctx1, pw, strlen(pw)); ++ li_MD5_Final(final, &ctx1); + for (pl = strlen(pw); pl > 0; pl -= APR_MD5_DIGESTSIZE) { +- MD5_Update(&ctx, final, ++ li_MD5_Update(&ctx, final, + (pl > APR_MD5_DIGESTSIZE) ? APR_MD5_DIGESTSIZE : pl); + } -@@ -2712,95 +2736,59 @@ - } +@@ -527,10 +531,10 @@ + */ + for (i = strlen(pw); i != 0; i >>= 1) { + if (i & 1) { +- MD5_Update(&ctx, final, 1); ++ li_MD5_Update(&ctx, final, 1); + } + else { +- MD5_Update(&ctx, pw, 1); ++ li_MD5_Update(&ctx, pw, 1); + } + } - /* get best server */ -- for (k = 0, ndx = -1; k < extension->used; k++) { -- scgi_extension_host *host = extension->hosts[k]; -+ for (k = 0; k < extension->used; k++) { -+ scgi_extension_host *h = extension->hosts[k]; - -- /* we should have at least one proc that can do somthing */ -- if (host->active_procs == 0) continue; -+ /* we should have at least one proc that can do something */ -+ if (h->active_procs == 0) { -+ continue; -+ } +@@ -542,7 +546,7 @@ + strncat(passwd, sp, sl); + strcat(passwd, "$"); + +- MD5_Final(final, &ctx); ++ li_MD5_Final(final, &ctx); + + /* + * And now, just to make sure things don't run too fast.. +@@ -550,28 +554,28 @@ + * need 30 seconds to build a 1000 entry dictionary... + */ + for (i = 0; i < 1000; i++) { +- MD5_Init(&ctx1); ++ li_MD5_Init(&ctx1); + if (i & 1) { +- MD5_Update(&ctx1, pw, strlen(pw)); ++ li_MD5_Update(&ctx1, pw, strlen(pw)); + } + else { +- MD5_Update(&ctx1, final, APR_MD5_DIGESTSIZE); ++ li_MD5_Update(&ctx1, final, APR_MD5_DIGESTSIZE); + } + if (i % 3) { +- MD5_Update(&ctx1, sp, sl); ++ li_MD5_Update(&ctx1, sp, sl); + } + + if (i % 7) { +- MD5_Update(&ctx1, pw, strlen(pw)); ++ li_MD5_Update(&ctx1, pw, strlen(pw)); + } + + if (i & 1) { +- MD5_Update(&ctx1, final, APR_MD5_DIGESTSIZE); ++ li_MD5_Update(&ctx1, final, APR_MD5_DIGESTSIZE); + } + else { +- MD5_Update(&ctx1, pw, strlen(pw)); ++ li_MD5_Update(&ctx1, pw, strlen(pw)); + } +- MD5_Final(final,&ctx1); ++ li_MD5_Final(final,&ctx1); + } -- if (used == -1 || host->load < used) { -- used = host->load; -+ if (used == -1 || h->load < used) { -+ used = h->load; + p = passwd + strlen(passwd); +@@ -614,17 +618,17 @@ + * user:realm:md5(user:realm:password) + */ -- ndx = k; -+ host = h; - } - } +- MD5_CTX Md5Ctx; ++ li_MD5_CTX Md5Ctx; + HASH HA1; + char a1[256]; + +- MD5_Init(&Md5Ctx); +- MD5_Update(&Md5Ctx, (unsigned char *)username->ptr, username->used - 1); +- MD5_Update(&Md5Ctx, (unsigned char *)":", 1); +- MD5_Update(&Md5Ctx, (unsigned char *)realm->ptr, realm->used - 1); +- MD5_Update(&Md5Ctx, (unsigned char *)":", 1); +- MD5_Update(&Md5Ctx, (unsigned char *)pw, strlen(pw)); +- MD5_Final(HA1, &Md5Ctx); ++ li_MD5_Init(&Md5Ctx); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)username->ptr, username->used - 1); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)":", 1); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)realm->ptr, realm->used - 1); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)":", 1); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)pw, strlen(pw)); ++ li_MD5_Final(HA1, &Md5Ctx); + + CvtHex(HA1, a1); + +@@ -930,7 +934,7 @@ + int i; + buffer *password, *b, *username_buf, *realm_buf; + +- MD5_CTX Md5Ctx; ++ li_MD5_CTX Md5Ctx; + HASH HA1; + HASH HA2; + HASH RespHash; +@@ -1067,13 +1071,13 @@ + + if (p->conf.auth_backend == AUTH_BACKEND_PLAIN) { + /* generate password from plain-text */ +- MD5_Init(&Md5Ctx); +- MD5_Update(&Md5Ctx, (unsigned char *)username, strlen(username)); +- MD5_Update(&Md5Ctx, (unsigned char *)":", 1); +- MD5_Update(&Md5Ctx, (unsigned char *)realm, strlen(realm)); +- MD5_Update(&Md5Ctx, (unsigned char *)":", 1); +- MD5_Update(&Md5Ctx, (unsigned char *)password->ptr, password->used - 1); +- MD5_Final(HA1, &Md5Ctx); ++ li_MD5_Init(&Md5Ctx); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)username, strlen(username)); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)":", 1); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)realm, strlen(realm)); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)":", 1); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)password->ptr, password->used - 1); ++ li_MD5_Final(HA1, &Md5Ctx); + } else if (p->conf.auth_backend == AUTH_BACKEND_HTDIGEST) { + /* HA1 */ + /* transform the 32-byte-hex-md5 to a 16-byte-md5 */ +@@ -1090,45 +1094,45 @@ + + if (algorithm && + strcasecmp(algorithm, "md5-sess") == 0) { +- MD5_Init(&Md5Ctx); +- MD5_Update(&Md5Ctx, (unsigned char *)HA1, 16); +- MD5_Update(&Md5Ctx, (unsigned char *)":", 1); +- MD5_Update(&Md5Ctx, (unsigned char *)nonce, strlen(nonce)); +- MD5_Update(&Md5Ctx, (unsigned char *)":", 1); +- MD5_Update(&Md5Ctx, (unsigned char *)cnonce, strlen(cnonce)); +- MD5_Final(HA1, &Md5Ctx); ++ li_MD5_Init(&Md5Ctx); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)HA1, 16); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)":", 1); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)nonce, strlen(nonce)); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)":", 1); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)cnonce, strlen(cnonce)); ++ li_MD5_Final(HA1, &Md5Ctx); + } + + CvtHex(HA1, a1); + + /* calculate H(A2) */ +- MD5_Init(&Md5Ctx); +- MD5_Update(&Md5Ctx, (unsigned char *)m, strlen(m)); +- MD5_Update(&Md5Ctx, (unsigned char *)":", 1); +- MD5_Update(&Md5Ctx, (unsigned char *)uri, strlen(uri)); ++ li_MD5_Init(&Md5Ctx); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)m, strlen(m)); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)":", 1); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)uri, strlen(uri)); + if (qop && strcasecmp(qop, "auth-int") == 0) { +- MD5_Update(&Md5Ctx, (unsigned char *)":", 1); +- MD5_Update(&Md5Ctx, (unsigned char *)"", HASHHEXLEN); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)":", 1); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)"", HASHHEXLEN); + } +- MD5_Final(HA2, &Md5Ctx); ++ li_MD5_Final(HA2, &Md5Ctx); + CvtHex(HA2, HA2Hex); + + /* calculate response */ +- MD5_Init(&Md5Ctx); +- MD5_Update(&Md5Ctx, (unsigned char *)a1, HASHHEXLEN); +- MD5_Update(&Md5Ctx, (unsigned char *)":", 1); +- MD5_Update(&Md5Ctx, (unsigned char *)nonce, strlen(nonce)); +- MD5_Update(&Md5Ctx, (unsigned char *)":", 1); ++ li_MD5_Init(&Md5Ctx); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)a1, HASHHEXLEN); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)":", 1); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)nonce, strlen(nonce)); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)":", 1); + if (qop && *qop) { +- MD5_Update(&Md5Ctx, (unsigned char *)nc, strlen(nc)); +- MD5_Update(&Md5Ctx, (unsigned char *)":", 1); +- MD5_Update(&Md5Ctx, (unsigned char *)cnonce, strlen(cnonce)); +- MD5_Update(&Md5Ctx, (unsigned char *)":", 1); +- MD5_Update(&Md5Ctx, (unsigned char *)qop, strlen(qop)); +- MD5_Update(&Md5Ctx, (unsigned char *)":", 1); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)nc, strlen(nc)); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)":", 1); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)cnonce, strlen(cnonce)); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)":", 1); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)qop, strlen(qop)); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)":", 1); + }; +- MD5_Update(&Md5Ctx, (unsigned char *)HA2Hex, HASHHEXLEN); +- MD5_Final(RespHash, &Md5Ctx); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)HA2Hex, HASHHEXLEN); ++ li_MD5_Final(RespHash, &Md5Ctx); + CvtHex(RespHash, a2); + + if (0 != strcmp(a2, respons)) { +@@ -1171,24 +1175,24 @@ + + int http_auth_digest_generate_nonce(server *srv, mod_auth_plugin_data *p, buffer *fn, char out[33]) { + HASH h; +- MD5_CTX Md5Ctx; ++ li_MD5_CTX Md5Ctx; + char hh[32]; + + UNUSED(p); + + /* generate shared-secret */ +- MD5_Init(&Md5Ctx); +- MD5_Update(&Md5Ctx, (unsigned char *)fn->ptr, fn->used - 1); +- MD5_Update(&Md5Ctx, (unsigned char *)"+", 1); ++ li_MD5_Init(&Md5Ctx); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)fn->ptr, fn->used - 1); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)"+", 1); + + /* we assume sizeof(time_t) == 4 here, but if not it ain't a problem at all */ + LI_ltostr(hh, srv->cur_ts); +- MD5_Update(&Md5Ctx, (unsigned char *)hh, strlen(hh)); +- MD5_Update(&Md5Ctx, (unsigned char *)srv->entropy, sizeof(srv->entropy)); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)hh, strlen(hh)); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)srv->entropy, sizeof(srv->entropy)); + LI_ltostr(hh, rand()); +- MD5_Update(&Md5Ctx, (unsigned char *)hh, strlen(hh)); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)hh, strlen(hh)); + +- MD5_Final(h, &Md5Ctx); ++ li_MD5_Final(h, &Md5Ctx); + + CvtHex(h, out); -- /* found a server */ -- if (ndx != -1) { -- scgi_extension_host *host = extension->hosts[ndx]; -+ if (!host) { -+ /* sorry, we don't have a server alive for this ext */ -+ buffer_reset(con->physical.path); -+ con->http_status = 500; - -- /* -- * if check-local is disabled, use the uri.path handler -- * -- */ -+ /* only send the 'no handler' once */ -+ if (!extension->note_is_sent) { -+ extension->note_is_sent = 1; - -- /* init handler-context */ -- if (uri_path_handler) { -- if (host->check_local == 0) { -- handler_ctx *hctx; -- char *pathinfo; -+ log_error_write(srv, __FILE__, __LINE__, "sbsbs", -+ "all handlers for ", con->uri.path, -+ "on", extension->key, -+ "are down."); -+ } +Index: src/mod_usertrack.c +=================================================================== +--- src/mod_usertrack.c (.../tags/lighttpd-1.4.29) ++++ src/mod_usertrack.c (.../branches/lighttpd-1.4.x) +@@ -8,18 +8,8 @@ + #include + #include -- hctx = handler_ctx_init(); -+ return HANDLER_FINISHED; -+ } +-#ifdef USE_OPENSSL +-# include +-#else +-# include "md5.h" ++#include "md5.h" -- hctx->remote_conn = con; -- hctx->plugin_data = p; -- hctx->host = host; -- hctx->proc = NULL; -+ /* a note about no handler is not sent yet */ -+ extension->note_is_sent = 0; - -- hctx->conf.exts = p->conf.exts; -- hctx->conf.debug = p->conf.debug; -+ /* -+ * if check-local is disabled, use the uri.path handler -+ * -+ */ - -- con->plugin_ctx[p->id] = hctx; -+ /* init handler-context */ -+ if (uri_path_handler) { -+ if (host->check_local == 0) { -+ handler_ctx *hctx; -+ char *pathinfo; - -- host->load++; -- -- con->mode = p->id; -- -- if (con->conf.log_request_handling) { -- log_error_write(srv, __FILE__, __LINE__, "s", "handling it in mod_scgi"); -- } +-typedef li_MD5_CTX MD5_CTX; +-#define MD5_Init li_MD5_Init +-#define MD5_Update li_MD5_Update +-#define MD5_Final li_MD5_Final - -- /* the prefix is the SCRIPT_NAME, -- * everthing from start to the next slash -- * this is important for check-local = "disable" -- * -- * if prefix = /admin.fcgi -- * -- * /admin.fcgi/foo/bar -- * -- * SCRIPT_NAME = /admin.fcgi -- * PATH_INFO = /foo/bar -- * -- * if prefix = /fcgi-bin/ -- * -- * /fcgi-bin/foo/bar -- * -- * SCRIPT_NAME = /fcgi-bin/foo -- * PATH_INFO = /bar -- * -- */ +-#endif - -- /* the rewrite is only done for /prefix/? matches */ -- if (extension->key->ptr[0] == '/' && -- con->uri.path->used > extension->key->used && -- NULL != (pathinfo = strchr(con->uri.path->ptr + extension->key->used - 1, '/'))) { -- /* rewrite uri.path and pathinfo */ -- -- buffer_copy_string(con->request.pathinfo, pathinfo); -- -- con->uri.path->used -= con->request.pathinfo->used - 1; -- con->uri.path->ptr[con->uri.path->used - 1] = '\0'; -- } -- } -- return HANDLER_GO_ON; -- } else { -- handler_ctx *hctx; - hctx = handler_ctx_init(); - - hctx->remote_conn = con; - hctx->plugin_data = p; - hctx->host = host; -- hctx->proc = NULL; -+ hctx->proc = NULL; - - hctx->conf.exts = p->conf.exts; - hctx->conf.debug = p->conf.debug; -@@ -2812,22 +2800,69 @@ - con->mode = p->id; - - if (con->conf.log_request_handling) { -- log_error_write(srv, __FILE__, __LINE__, "s", "handling it in mod_fastcgi"); -+ log_error_write(srv, __FILE__, __LINE__, "s", -+ "handling it in mod_fastcgi"); - } + /* plugin config for all request/connections */ -- return HANDLER_GO_ON; -+ /* the prefix is the SCRIPT_NAME, -+ * everything from start to the next slash -+ * this is important for check-local = "disable" -+ * -+ * if prefix = /admin.fcgi -+ * -+ * /admin.fcgi/foo/bar -+ * -+ * SCRIPT_NAME = /admin.fcgi -+ * PATH_INFO = /foo/bar -+ * -+ * if prefix = /fcgi-bin/ -+ * -+ * /fcgi-bin/foo/bar -+ * -+ * SCRIPT_NAME = /fcgi-bin/foo -+ * PATH_INFO = /bar -+ * -+ */ -+ -+ /* the rewrite is only done for /prefix/? matches */ -+ if (extension->key->ptr[0] == '/' && -+ con->uri.path->used > extension->key->used && -+ NULL != (pathinfo = strchr(con->uri.path->ptr + extension->key->used - 1, '/'))) { -+ /* rewrite uri.path and pathinfo */ -+ -+ buffer_copy_string(con->request.pathinfo, pathinfo); -+ -+ con->uri.path->used -= con->request.pathinfo->used - 1; -+ con->uri.path->ptr[con->uri.path->used - 1] = '\0'; -+ } 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 { -- /* no handler found */ -- buffer_reset(con->physical.path); -- con->http_status = 500; -+ handler_ctx *hctx; -+ hctx = handler_ctx_init(); - -- log_error_write(srv, __FILE__, __LINE__, "sb", -- "no fcgi-handler found for:", -- fn); -+ hctx->remote_conn = con; -+ hctx->plugin_data = p; -+ hctx->host = host; -+ hctx->proc = NULL; - -- return HANDLER_FINISHED; -+ hctx->conf.exts = p->conf.exts; -+ hctx->conf.debug = p->conf.debug; -+ -+ con->plugin_ctx[p->id] = hctx; -+ -+ host->load++; -+ -+ con->mode = p->id; -+ -+ if (con->conf.log_request_handling) { -+ log_error_write(srv, __FILE__, __LINE__, "s", "handling it in mod_fastcgi"); -+ } - } -+ - return HANDLER_GO_ON; - } + typedef struct { +@@ -182,7 +172,7 @@ + plugin_data *p = p_d; + data_string *ds; + unsigned char h[16]; +- MD5_CTX Md5Ctx; ++ li_MD5_CTX Md5Ctx; + char hh[32]; -@@ -2949,7 +2984,7 @@ - fp->port = host->port + fp->id; - } else { - buffer_copy_string_buffer(fp->socket, host->unixsocket); -- buffer_append_string(fp->socket, "-"); -+ buffer_append_string_len(fp->socket, CONST_STR_LEN("-")); - buffer_append_long(fp->socket, fp->id); - } + if (con->uri.path->used == 0) return HANDLER_GO_ON; +@@ -228,18 +218,18 @@ + /* taken from mod_auth.c */ -Index: src/mod_mysql_vhost.c -=================================================================== ---- src/mod_mysql_vhost.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/mod_mysql_vhost.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -410,6 +410,7 @@ - - ERR500: if (result) mysql_free_result(result); - con->http_status = 500; /* Internal Error */ -+ con->mode = DIRECT; - return HANDLER_FINISHED; - } + /* generate shared-secret */ +- MD5_Init(&Md5Ctx); +- MD5_Update(&Md5Ctx, (unsigned char *)con->uri.path->ptr, con->uri.path->used - 1); +- MD5_Update(&Md5Ctx, (unsigned char *)"+", 1); ++ li_MD5_Init(&Md5Ctx); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)con->uri.path->ptr, con->uri.path->used - 1); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)"+", 1); + + /* we assume sizeof(time_t) == 4 here, but if not it ain't a problem at all */ + LI_ltostr(hh, srv->cur_ts); +- MD5_Update(&Md5Ctx, (unsigned char *)hh, strlen(hh)); +- MD5_Update(&Md5Ctx, (unsigned char *)srv->entropy, sizeof(srv->entropy)); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)hh, strlen(hh)); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)srv->entropy, sizeof(srv->entropy)); + LI_ltostr(hh, rand()); +- MD5_Update(&Md5Ctx, (unsigned char *)hh, strlen(hh)); ++ li_MD5_Update(&Md5Ctx, (unsigned char *)hh, strlen(hh)); + +- MD5_Final(h, &Md5Ctx); ++ li_MD5_Final(h, &Md5Ctx); -Index: src/mod_flv_streaming.c + buffer_append_string_encoded(ds->value, (char *)h, 16, ENCODING_HEX); + buffer_append_string_len(ds->value, CONST_STR_LEN("; Path=/")); +Index: src/mod_status.c =================================================================== ---- src/mod_flv_streaming.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/mod_flv_streaming.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -193,6 +193,8 @@ - - UNUSED(srv); - -+ if (con->mode != DIRECT) return HANDLER_GO_ON; -+ - if (buffer_is_empty(con->physical.path)) return HANDLER_GO_ON; +--- src/mod_status.c (.../tags/lighttpd-1.4.29) ++++ src/mod_status.c (.../branches/lighttpd-1.4.x) +@@ -487,7 +487,7 @@ - mod_flv_streaming_patch_connection(srv, con, p); -@@ -245,7 +247,7 @@ + buffer_append_string_len(b, CONST_STR_LEN("")); - /* we are safe now, let's build a flv header */ - b = chunkqueue_get_append_buffer(con->write_queue); -- BUFFER_COPY_STRING_CONST(b, "FLV\x1\x1\0\0\0\x9\0\0\0\x9"); -+ buffer_copy_string_len(b, CONST_STR_LEN("FLV\x1\x1\0\0\0\x9\0\0\0\x9")); - - http_chunk_append_file(srv, con, con->physical.path, start, sce->st.st_size - start); - -Index: src/lighttpd-angel.c +- if (con->request.content_length) { ++ if (c->request.content_length) { + buffer_append_long(b, c->request_content_queue->bytes_in); + buffer_append_string_len(b, CONST_STR_LEN("/")); + buffer_append_long(b, c->request.content_length); +Index: src/settings.h =================================================================== ---- src/lighttpd-angel.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/lighttpd-angel.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -28,9 +28,12 @@ - static volatile sig_atomic_t graceful_restart = 0; - static volatile pid_t pid = -1; +--- src/settings.h (.../tags/lighttpd-1.4.29) ++++ src/settings.h (.../branches/lighttpd-1.4.x) +@@ -21,8 +21,11 @@ + * 64kB (no real reason, just a guess) + */ + #define BUFFER_MAX_REUSE_SIZE (4 * 1024) +-#define MAX_READ_LIMIT (4*1024*1024) -+#define UNUSED(x) ( (void)(x) ) -+ - static void sigaction_handler(int sig, siginfo_t *si, void *context) { - int exitcode; - -+ UNUSED(context); - switch (sig) { - case SIGINT: - case SIGTERM: -@@ -60,6 +63,8 @@ - int is_shutdown = 0; - struct sigaction act; - -+ UNUSED(argc); ++/* both should be way smaller than SSIZE_MAX :) */ ++#define MAX_READ_LIMIT (256*1024) ++#define MAX_WRITE_LIMIT (256*1024) + - /** - * we are running as root BEWARE - */ -Index: src/mod_rrdtool.c -=================================================================== ---- src/mod_rrdtool.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/mod_rrdtool.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -148,6 +148,8 @@ - args[i++] = dash; - args[i++] = NULL; - -+ openDevNull(STDERR_FILENO); -+ - /* we don't need the client socket */ - for (i = 3; i < 256; i++) { - close(i); -@@ -156,7 +158,7 @@ - /* exec the cgi */ - execv(args[0], args); - -- log_error_write(srv, __FILE__, __LINE__, "sss", "spawing rrdtool failed: ", strerror(errno), args[0]); -+ /* log_error_write(srv, __FILE__, __LINE__, "sss", "spawing rrdtool failed: ", strerror(errno), args[0]); */ - - /* */ - SEGFAULT(); -@@ -202,24 +204,25 @@ - int r ; - /* create a new one */ - -- BUFFER_COPY_STRING_CONST(p->cmd, "create "); -+ buffer_copy_string_len(p->cmd, CONST_STR_LEN("create ")); - buffer_append_string_buffer(p->cmd, s->path_rrd); -- buffer_append_string(p->cmd, " --step 60 "); -- buffer_append_string(p->cmd, "DS:InOctets:ABSOLUTE:600:U:U "); -- buffer_append_string(p->cmd, "DS:OutOctets:ABSOLUTE:600:U:U "); -- buffer_append_string(p->cmd, "DS:Requests:ABSOLUTE:600:U:U "); -- buffer_append_string(p->cmd, "RRA:AVERAGE:0.5:1:600 "); -- buffer_append_string(p->cmd, "RRA:AVERAGE:0.5:6:700 "); -- buffer_append_string(p->cmd, "RRA:AVERAGE:0.5:24:775 "); -- buffer_append_string(p->cmd, "RRA:AVERAGE:0.5:288:797 "); -- buffer_append_string(p->cmd, "RRA:MAX:0.5:1:600 "); -- buffer_append_string(p->cmd, "RRA:MAX:0.5:6:700 "); -- buffer_append_string(p->cmd, "RRA:MAX:0.5:24:775 "); -- buffer_append_string(p->cmd, "RRA:MAX:0.5:288:797 "); -- buffer_append_string(p->cmd, "RRA:MIN:0.5:1:600 "); -- buffer_append_string(p->cmd, "RRA:MIN:0.5:6:700 "); -- buffer_append_string(p->cmd, "RRA:MIN:0.5:24:775 "); -- buffer_append_string(p->cmd, "RRA:MIN:0.5:288:797\n"); -+ buffer_append_string_len(p->cmd, CONST_STR_LEN( -+ " --step 60 " -+ "DS:InOctets:ABSOLUTE:600:U:U " -+ "DS:OutOctets:ABSOLUTE:600:U:U " -+ "DS:Requests:ABSOLUTE:600:U:U " -+ "RRA:AVERAGE:0.5:1:600 " -+ "RRA:AVERAGE:0.5:6:700 " -+ "RRA:AVERAGE:0.5:24:775 " -+ "RRA:AVERAGE:0.5:288:797 " -+ "RRA:MAX:0.5:1:600 " -+ "RRA:MAX:0.5:6:700 " -+ "RRA:MAX:0.5:24:775 " -+ "RRA:MAX:0.5:288:797 " -+ "RRA:MIN:0.5:1:600 " -+ "RRA:MIN:0.5:6:700 " -+ "RRA:MIN:0.5:24:775 " -+ "RRA:MIN:0.5:288:797\n")); - - if (-1 == (r = write(p->write_fd, p->cmd->ptr, p->cmd->used - 1))) { - log_error_write(srv, __FILE__, __LINE__, "ss", -@@ -372,15 +375,15 @@ - - if (HANDLER_GO_ON != mod_rrdtool_create_rrd(srv, p, s)) return HANDLER_ERROR; - -- BUFFER_COPY_STRING_CONST(p->cmd, "update "); -+ buffer_copy_string_len(p->cmd, CONST_STR_LEN("update ")); - buffer_append_string_buffer(p->cmd, s->path_rrd); -- BUFFER_APPEND_STRING_CONST(p->cmd, " N:"); -+ buffer_append_string_len(p->cmd, CONST_STR_LEN(" N:")); - buffer_append_off_t(p->cmd, s->bytes_read); -- BUFFER_APPEND_STRING_CONST(p->cmd, ":"); -+ buffer_append_string_len(p->cmd, CONST_STR_LEN(":")); - buffer_append_off_t(p->cmd, s->bytes_written); -- BUFFER_APPEND_STRING_CONST(p->cmd, ":"); -+ buffer_append_string_len(p->cmd, CONST_STR_LEN(":")); - buffer_append_long(p->cmd, s->requests); -- BUFFER_APPEND_STRING_CONST(p->cmd, "\n"); -+ buffer_append_string_len(p->cmd, CONST_STR_LEN("\n")); - - if (-1 == (r = write(p->write_fd, p->cmd->ptr, p->cmd->used - 1))) { - p->rrdtool_running = 0; -Index: src/mod_ssi_expr.c + /** + * max size of the HTTP request header + * +Index: src/mod_cml_lua.c =================================================================== ---- src/mod_ssi_expr.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/mod_ssi_expr.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -59,7 +59,7 @@ - t->offset++; - t->line_pos++; +--- src/mod_cml_lua.c (.../tags/lighttpd-1.4.29) ++++ src/mod_cml_lua.c (.../branches/lighttpd-1.4.x) +@@ -11,18 +11,6 @@ + #include + #include -- buffer_copy_string(token, "(=)"); -+ buffer_copy_string_len(token, CONST_STR_LEN("(=)")); +-#ifdef USE_OPENSSL +-# include +-#else +-# include "md5.h" +- +-typedef li_MD5_CTX MD5_CTX; +-#define MD5_Init li_MD5_Init +-#define MD5_Update li_MD5_Update +-#define MD5_Final li_MD5_Final +- +-#endif +- + #define HASHLEN 16 + typedef unsigned char HASH[HASHLEN]; + #define HASHHEXLEN 32 +Index: src/mod_fastcgi.c +=================================================================== +--- src/mod_fastcgi.c (.../tags/lighttpd-1.4.29) ++++ src/mod_fastcgi.c (.../branches/lighttpd-1.4.x) +@@ -3075,7 +3075,7 @@ + fcgi_set_state(srv, hctx, FCGI_STATE_WRITE); + /* fall through */ + case FCGI_STATE_WRITE: +- ret = srv->network_backend_write(srv, con, hctx->fd, hctx->wb); ++ ret = srv->network_backend_write(srv, con, hctx->fd, hctx->wb, MAX_WRITE_LIMIT); - break; - case '>': -@@ -69,14 +69,14 @@ + chunkqueue_remove_finished_chunks(hctx->wb); - tid = TK_GE; +@@ -3132,7 +3132,6 @@ + plugin_data *p = p_d; -- buffer_copy_string(token, "(>=)"); -+ buffer_copy_string_len(token, CONST_STR_LEN("(>=)")); - } else { - t->offset += 1; - t->line_pos += 1; + handler_ctx *hctx = con->plugin_ctx[p->id]; +- fcgi_proc *proc; + fcgi_extension_host *host; - tid = TK_GT; + if (NULL == hctx) return HANDLER_GO_ON; +@@ -3201,7 +3200,6 @@ + /* ok, create the request */ + switch(fcgi_write_request(srv, hctx)) { + case HANDLER_ERROR: +- proc = hctx->proc; + host = hctx->host; -- buffer_copy_string(token, "(>)"); -+ buffer_copy_string_len(token, CONST_STR_LEN("(>)")); - } + if (hctx->state == FCGI_STATE_INIT || +Index: src/network_solaris_sendfilev.c +=================================================================== +--- src/network_solaris_sendfilev.c (.../tags/lighttpd-1.4.29) ++++ src/network_solaris_sendfilev.c (.../branches/lighttpd-1.4.x) +@@ -38,17 +38,16 @@ + */ - break; -@@ -87,14 +87,14 @@ - tid = TK_LE; +-int network_write_chunkqueue_solarissendfilev(server *srv, connection *con, int fd, chunkqueue *cq) { ++int network_write_chunkqueue_solarissendfilev(server *srv, connection *con, int fd, chunkqueue *cq, off_t max_bytes) { + chunk *c; +- size_t chunks_written = 0; -- buffer_copy_string(token, "(<=)"); -+ buffer_copy_string_len(token, CONST_STR_LEN("(<=)")); - } else { - t->offset += 1; - t->line_pos += 1; +- for(c = cq->first; c; c = c->next, chunks_written++) { ++ for(c = cq->first; (max_bytes > 0) && (NULL != c); c = c->next) { + int chunk_finished = 0; - tid = TK_LT; + switch(c->type) { + case MEM_CHUNK: { + char * offset; +- size_t toSend; ++ off_t toSend; + ssize_t r; -- buffer_copy_string(token, "(<)"); -+ buffer_copy_string_len(token, CONST_STR_LEN("(<)")); - } + size_t num_chunks, i; +@@ -77,9 +76,9 @@ + chunks[i].iov_base = offset; - break; -@@ -106,14 +106,14 @@ + /* protect the return value of writev() */ +- if (toSend > SSIZE_MAX || +- num_bytes + toSend > SSIZE_MAX) { +- chunks[i].iov_len = SSIZE_MAX - num_bytes; ++ if (toSend > max_bytes || ++ (off_t) num_bytes + toSend > max_bytes) { ++ chunks[i].iov_len = max_bytes - num_bytes; - tid = TK_NE; + num_chunks = i + 1; + break; +@@ -119,11 +118,10 @@ -- buffer_copy_string(token, "(!=)"); -+ buffer_copy_string_len(token, CONST_STR_LEN("(!=)")); - } else { - t->offset += 1; - t->line_pos += 1; + if (chunk_finished) { + /* skip the chunks from further touches */ +- chunks_written++; + c = c->next; + } else { + /* chunks_written + c = c->next is done in the for()*/ +- chunk_finished++; ++ chunk_finished = 1; + } + } else { + /* partially written */ +@@ -139,8 +137,8 @@ + } + case FILE_CHUNK: { + ssize_t r; +- off_t offset; +- size_t toSend, written; ++ off_t offset, toSend; ++ size_t written; + sendfilevec_t fvec; + stat_cache_entry *sce = NULL; + int ifd; +@@ -153,6 +151,7 @@ - tid = TK_NOT; + offset = c->file.start + c->offset; + toSend = c->file.length - c->offset; ++ if (toSend > max_bytes) toSend = max_bytes; -- buffer_copy_string(token, "(!)"); -+ buffer_copy_string_len(token, CONST_STR_LEN("(!)")); - } + if (offset > sce->st.st_size) { + log_error_write(srv, __FILE__, __LINE__, "sb", "file was shrinked:", c->file.name); +@@ -186,6 +185,7 @@ + close(ifd); + c->offset += written; + cq->bytes_out += written; ++ max_bytes -= written; - break; -@@ -124,7 +124,7 @@ + if (c->offset == c->file.length) { + chunk_finished = 1; +@@ -207,7 +207,7 @@ + } + } - tid = TK_AND; +- return chunks_written; ++ return 0; + } -- buffer_copy_string(token, "(&&)"); -+ buffer_copy_string_len(token, CONST_STR_LEN("(&&)")); - } else { - log_error_write(srv, __FILE__, __LINE__, "sds", - "pos:", t->line_pos, -@@ -140,7 +140,7 @@ + #endif +Index: src/CMakeLists.txt +=================================================================== +Index: src/mod_dirlisting.c +=================================================================== +--- src/mod_dirlisting.c (.../tags/lighttpd-1.4.29) ++++ src/mod_dirlisting.c (.../branches/lighttpd-1.4.x) +@@ -657,7 +657,8 @@ + i = dir->used - 1; + + #ifdef HAVE_PATHCONF +- if (-1 == (name_max = pathconf(dir->ptr, _PC_NAME_MAX))) { ++ if (0 >= (name_max = pathconf(dir->ptr, _PC_NAME_MAX))) { ++ /* some broken fs (fuse) return 0 instead of -1 */ + #ifdef NAME_MAX + name_max = NAME_MAX; + #else +Index: src/network_linux_sendfile.c +=================================================================== +--- src/network_linux_sendfile.c (.../tags/lighttpd-1.4.29) ++++ src/network_linux_sendfile.c (.../branches/lighttpd-1.4.x) +@@ -27,17 +27,16 @@ + /* on linux 2.4.29 + debian/ubuntu we have crashes if this is enabled */ + #undef HAVE_POSIX_FADVISE + +-int network_write_chunkqueue_linuxsendfile(server *srv, connection *con, int fd, chunkqueue *cq) { ++int network_write_chunkqueue_linuxsendfile(server *srv, connection *con, int fd, chunkqueue *cq, off_t max_bytes) { + chunk *c; +- size_t chunks_written = 0; + +- for(c = cq->first; c; c = c->next, chunks_written++) { ++ for(c = cq->first; (max_bytes > 0) && (NULL != c); c = c->next) { + int chunk_finished = 0; + + switch(c->type) { + case MEM_CHUNK: { + char * offset; +- size_t toSend; ++ off_t toSend; + ssize_t r; + + size_t num_chunks, i; +@@ -45,12 +44,10 @@ + chunk *tc; + size_t num_bytes = 0; + +- /* we can't send more then SSIZE_MAX bytes in one chunk */ +- + /* build writev list + * + * 1. limit: num_chunks < UIO_MAXIOV +- * 2. limit: num_bytes < SSIZE_MAX ++ * 2. limit: num_bytes < max_bytes + */ + for (num_chunks = 0, tc = c; + tc && tc->type == MEM_CHUNK && num_chunks < UIO_MAXIOV; +@@ -67,9 +64,9 @@ + chunks[i].iov_base = offset; + + /* protect the return value of writev() */ +- if (toSend > SSIZE_MAX || +- num_bytes + toSend > SSIZE_MAX) { +- chunks[i].iov_len = SSIZE_MAX - num_bytes; ++ if (toSend > max_bytes || ++ (off_t) num_bytes + toSend > max_bytes) { ++ chunks[i].iov_len = max_bytes - num_bytes; + + num_chunks = i + 1; + break; +@@ -100,6 +97,7 @@ - tid = TK_OR; + /* check which chunks have been written */ + cq->bytes_out += r; ++ max_bytes -= r; -- buffer_copy_string(token, "(||)"); -+ buffer_copy_string_len(token, CONST_STR_LEN("(||)")); - } else { - log_error_write(srv, __FILE__, __LINE__, "sds", - "pos:", t->line_pos, -@@ -183,7 +183,7 @@ + for(i = 0, tc = c; i < num_chunks; i++, tc = tc->next) { + if (r >= (ssize_t)chunks[i].iov_len) { +@@ -109,11 +107,10 @@ - tid = TK_LPARAN; + if (chunk_finished) { + /* skip the chunks from further touches */ +- chunks_written++; + c = c->next; + } else { + /* chunks_written + c = c->next is done in the for()*/ +- chunk_finished++; ++ chunk_finished = 1; + } + } else { + /* partially written */ +@@ -130,13 +127,12 @@ + case FILE_CHUNK: { + ssize_t r; + off_t offset; +- size_t toSend; ++ off_t toSend; + stat_cache_entry *sce = NULL; -- buffer_copy_string(token, "("); -+ buffer_copy_string_len(token, CONST_STR_LEN("(")); - break; - case ')': - t->offset++; -@@ -191,7 +191,7 @@ + offset = c->file.start + c->offset; +- /* limit the toSend to 2^31-1 bytes in a chunk */ +- toSend = c->file.length - c->offset > ((1 << 30) - 1) ? +- ((1 << 30) - 1) : c->file.length - c->offset; ++ toSend = c->file.length - c->offset; ++ if (toSend > max_bytes) toSend = max_bytes; - tid = TK_RPARAN; + /* open file if not already opened */ + if (-1 == c->file.fd) { +@@ -215,6 +211,7 @@ -- buffer_copy_string(token, ")"); -+ buffer_copy_string_len(token, CONST_STR_LEN(")")); - break; - case '$': - if (t->input[t->offset + 1] == '{') { -@@ -219,7 +219,7 @@ - } else if (NULL != (ds = (data_string *)array_get_element(p->ssi_vars, token->ptr))) { - buffer_copy_string_buffer(token, ds->value); - } else { -- buffer_copy_string(token, ""); -+ buffer_copy_string_len(token, CONST_STR_LEN("")); - } + c->offset += r; + cq->bytes_out += r; ++ max_bytes -= r; - t->offset += i; -Index: src/stat_cache.c -=================================================================== ---- src/stat_cache.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/stat_cache.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -445,7 +445,9 @@ - /* dir-check */ - if (srv->srvconf.stat_cache_engine == STAT_CACHE_ENGINE_FAM) { - if (0 != buffer_copy_dirname(sc->dir_name, name)) { -- SEGFAULT(); -+ log_error_write(srv, __FILE__, __LINE__, "sb", -+ "no '/' found in filename:", name); -+ return HANDLER_ERROR; + if (c->offset == c->file.length) { + chunk_finished = 1; +@@ -243,7 +240,7 @@ } - - buffer_copy_string_buffer(sc->hash_key, sc->dir_name); -Index: src/response.c -=================================================================== ---- src/response.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/response.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -35,21 +35,25 @@ - b = chunkqueue_get_prepend_buffer(con->write_queue); - - if (con->request.http_version == HTTP_VERSION_1_1) { -- BUFFER_COPY_STRING_CONST(b, "HTTP/1.1 "); -+ buffer_copy_string_len(b, CONST_STR_LEN("HTTP/1.1 ")); - } else { -- BUFFER_COPY_STRING_CONST(b, "HTTP/1.0 "); -+ buffer_copy_string_len(b, CONST_STR_LEN("HTTP/1.0 ")); - } - buffer_append_long(b, con->http_status); -- BUFFER_APPEND_STRING_CONST(b, " "); -+ buffer_append_string_len(b, CONST_STR_LEN(" ")); - buffer_append_string(b, get_http_status_name(con->http_status)); - - if (con->request.http_version != HTTP_VERSION_1_1 || con->keep_alive == 0) { -- BUFFER_APPEND_STRING_CONST(b, "\r\nConnection: "); -- buffer_append_string(b, con->keep_alive ? "keep-alive" : "close"); -+ buffer_append_string_len(b, CONST_STR_LEN("\r\nConnection: ")); -+ if (con->keep_alive) { -+ buffer_append_string_len(b, CONST_STR_LEN("keep-alive")); -+ } else { -+ buffer_append_string_len(b, CONST_STR_LEN("close")); -+ } } - if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) { -- BUFFER_APPEND_STRING_CONST(b, "\r\nTransfer-Encoding: chunked"); -+ buffer_append_string_len(b, CONST_STR_LEN("\r\nTransfer-Encoding: chunked")); - } +- return chunks_written; ++ return 0; + } + #endif +Index: tests/mod-auth.t +=================================================================== +--- tests/mod-auth.t (.../tags/lighttpd-1.4.29) ++++ tests/mod-auth.t (.../branches/lighttpd-1.4.x) +@@ -8,7 +8,7 @@ -@@ -60,14 +64,15 @@ - ds = (data_string *)con->response.headers->data[i]; - - if (ds->value->used && ds->key->used && -- 0 != strncmp(ds->key->ptr, "X-LIGHTTPD-", sizeof("X-LIGHTTPD-") - 1) && -- 0 != strncmp(ds->key->ptr, "X-Sendfile", sizeof("X-Sendfile") - 1)) { -- if (buffer_is_equal_string(ds->key, CONST_STR_LEN("Date"))) have_date = 1; -- if (buffer_is_equal_string(ds->key, CONST_STR_LEN("Server"))) have_server = 1; -+ 0 != strncasecmp(ds->key->ptr, CONST_STR_LEN("X-LIGHTTPD-")) && -+ 0 != strcasecmp(ds->key->ptr, "X-Sendfile")) { -+ if (0 == strcasecmp(ds->key->ptr, "Date")) have_date = 1; -+ if (0 == strcasecmp(ds->key->ptr, "Server")) have_server = 1; -+ if (0 == strcasecmp(ds->key->ptr, "Content-Encoding") && 304 == con->http_status) continue; - -- BUFFER_APPEND_STRING_CONST(b, "\r\n"); -+ buffer_append_string_len(b, CONST_STR_LEN("\r\n")); - buffer_append_string_buffer(b, ds->key); -- BUFFER_APPEND_STRING_CONST(b, ": "); -+ buffer_append_string_len(b, CONST_STR_LEN(": ")); - #if 0 - /** - * the value might contain newlines, encode them with at least one white-space -@@ -81,7 +86,7 @@ - - if (!have_date) { - /* HTTP/1.1 requires a Date: header */ -- BUFFER_APPEND_STRING_CONST(b, "\r\nDate: "); -+ buffer_append_string_len(b, CONST_STR_LEN("\r\nDate: ")); - - /* cache the generated timestamp */ - if (srv->cur_ts != srv->last_generated_date_ts) { -@@ -100,14 +105,14 @@ - - if (!have_server) { - if (buffer_is_empty(con->conf.server_tag)) { -- BUFFER_APPEND_STRING_CONST(b, "\r\nServer: " PACKAGE_NAME "/" PACKAGE_VERSION); -- } else { -- BUFFER_APPEND_STRING_CONST(b, "\r\nServer: "); -+ buffer_append_string_len(b, CONST_STR_LEN("\r\nServer: " PACKAGE_NAME "/" PACKAGE_VERSION)); -+ } else if (con->conf.server_tag->used > 1) { -+ buffer_append_string_len(b, CONST_STR_LEN("\r\nServer: ")); - buffer_append_string_encoded(b, CONST_BUF_LEN(con->conf.server_tag), ENCODING_HTTP_HEADER); - } - } + use strict; + use IO::Socket; +-use Test::More tests => 14; ++use Test::More tests => 15; + use LightyTest; -- BUFFER_APPEND_STRING_CONST(b, "\r\n\r\n"); -+ buffer_append_string_len(b, CONST_STR_LEN("\r\n\r\n")); + my $tf = LightyTest->new(); +@@ -25,6 +25,14 @@ + $t->{REQUEST} = ( <{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 401 } ]; ++ok($tf->handle_http($t) == 0, 'Basic-Auth: Invalid base64 Auth-token'); ++ ++$t->{REQUEST} = ( <bytes_header = b->used - 1; -@@ -152,7 +157,7 @@ - * */ + use strict; + use IO::Socket; +-use Test::More tests => 44; ++use Test::More tests => 46; + use LightyTest; - config_cond_cache_reset(srv, con); -- config_setup_connection(srv, con); // Perhaps this could be removed at other places. -+ config_setup_connection(srv, con); /* Perhaps this could be removed at other places. */ + my $tf = LightyTest->new(); +@@ -413,5 +413,21 @@ + $t->{SLOWREQUEST} = 1; + ok($tf->handle_http($t) == 0, 'GET, slow \\r\\n\\r\\n (#2105)'); - if (con->conf.log_condition_handling) { - log_error_write(srv, __FILE__, __LINE__, "s", "run condition"); -@@ -181,7 +186,11 @@ - * - */ ++print "\nPathinfo for static files\n"; ++$t->{REQUEST} = ( <{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'Content-Type' => 'image/jpeg' } ]; ++ok($tf->handle_http($t) == 0, 'static file accepting pathinfo by default'); ++ ++$t->{REQUEST} = ( <{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 403 } ]; ++ok($tf->handle_http($t) == 0, 'static file with forbidden pathinfo'); ++ + ok($tf->stop_proc == 0, "Stopping lighttpd"); -- buffer_copy_string(con->uri.scheme, con->conf.is_ssl ? "https" : "http"); -+ if (con->conf.is_ssl) { -+ buffer_copy_string_len(con->uri.scheme, CONST_STR_LEN("https")); -+ } else { -+ buffer_copy_string_len(con->uri.scheme, CONST_STR_LEN("http")); -+ } - buffer_copy_string_buffer(con->uri.authority, con->request.http_host); - buffer_to_lower(con->uri.authority); +Index: tests/wrapper.sh +=================================================================== +--- tests/wrapper.sh (.../tags/lighttpd-1.4.29) ++++ tests/wrapper.sh (.../branches/lighttpd-1.4.x) +@@ -6,4 +6,4 @@ + top_builddir=$2 + export SHELL srcdir top_builddir -@@ -224,27 +233,6 @@ - } +-$3 ++exec $3 +Index: tests/lighttpd.conf +=================================================================== +--- tests/lighttpd.conf (.../tags/lighttpd-1.4.29) ++++ tests/lighttpd.conf (.../branches/lighttpd-1.4.x) +@@ -149,6 +149,7 @@ + $HTTP["host"] == "zzz.example.org" { + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" + server.name = "zzz.example.org" ++ static-file.disable-pathinfo = "enable" + } + $HTTP["host"] == "symlink.example.org" { +Index: configure.ac +=================================================================== +Index: doc/config/lighttpd.conf +=================================================================== +--- doc/config/lighttpd.conf (.../tags/lighttpd-1.4.29) ++++ doc/config/lighttpd.conf (.../branches/lighttpd-1.4.x) +@@ -394,6 +394,25 @@ + ## $SERVER["socket"] == "10.0.0.1:443" { + ## ssl.engine = "enable" + ## ssl.pemfile = "/etc/ssl/private/www.example.com.pem" ++## # ++## # Mitigate BEAST attack: ++## # ++## # A stricter base cipher suite. For details see: ++## # http://blog.ivanristic.com/2011/10/mitigating-the-beast-attack-on-tls.html ++## # ++## ssl.ciphers = "ECDHE-RSA-AES256-SHA384:AES256-SHA256:RC4-SHA:RC4:HIGH:!MD5:!aNULL:!EDH:!AESGCM" ++## # ++## # Make the server prefer the order of the server side cipher suite instead of the client suite. ++## # This is necessary to mitigate the BEAST attack (unless you disable all non RC4 algorithms). ++## # This option is enabled by default, but only used if ssl.ciphers is set. ++## # ++## # ssl.honor-cipher-order = "enable" ++## # ++## # Mitigate CVE-2009-3555 by disabling client triggered renegotation ++## # This is enabled by default. ++## # ++## # ssl.disable-client-renegotiation = "enable" ++## # + ## server.name = "www.example.com" + ## + ## server.document-root = "/srv/www/vhosts/example.com/www/" +Index: SConstruct +=================================================================== +Index: NEWS +=================================================================== +--- NEWS (.../tags/lighttpd-1.4.29) ++++ NEWS (.../branches/lighttpd-1.4.x) +@@ -3,7 +3,20 @@ + NEWS + ==== -- /** -- * -- * call plugins -- * -- * - based on the raw URL -- * -- */ -- -- switch(r = plugins_call_handle_uri_raw(srv, con)) { -- case HANDLER_GO_ON: -- break; -- case HANDLER_FINISHED: -- case HANDLER_COMEBACK: -- case HANDLER_WAIT_FOR_EVENT: -- case HANDLER_ERROR: -- return r; -- default: -- log_error_write(srv, __FILE__, __LINE__, "sd", "handle_uri_raw: unknown return value", r); -- break; -- } -- - /* build filename - * - * - decode url-encodings (e.g. %20 -> ' ') -@@ -252,7 +240,6 @@ - */ - - -- - if (con->request.http_method == HTTP_METHOD_OPTIONS && - con->uri.path_raw->ptr[0] == '*' && con->uri.path_raw->ptr[1] == '\0') { - /* OPTIONS * ... */ -@@ -268,10 +255,32 @@ - log_error_write(srv, __FILE__, __LINE__, "sb", "URI-path : ", con->uri.path); - } - -+ - /** - * - * call plugins - * -+ * - based on the raw URL -+ * -+ */ -+ -+ switch(r = plugins_call_handle_uri_raw(srv, con)) { -+ case HANDLER_GO_ON: -+ break; -+ case HANDLER_FINISHED: -+ case HANDLER_COMEBACK: -+ case HANDLER_WAIT_FOR_EVENT: -+ case HANDLER_ERROR: -+ return r; -+ default: -+ log_error_write(srv, __FILE__, __LINE__, "sd", "handle_uri_raw: unknown return value", r); -+ break; -+ } -+ -+ /** -+ * -+ * call plugins -+ * - * - based on the clean URL - * - */ -Index: src/plugin.c -=================================================================== ---- src/plugin.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/plugin.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -131,12 +131,12 @@ - - buffer_copy_string_buffer(srv->tmp_buf, srv->srvconf.modules_dir); - -- buffer_append_string(srv->tmp_buf, "/"); -+ buffer_append_string_len(srv->tmp_buf, CONST_STR_LEN("/")); - buffer_append_string(srv->tmp_buf, modules); - #if defined(__WIN32) || defined(__CYGWIN__) -- buffer_append_string(srv->tmp_buf, ".dll"); -+ buffer_append_string_len(srv->tmp_buf, CONST_STR_LEN(".dll")); - #else -- buffer_append_string(srv->tmp_buf, ".so"); -+ buffer_append_string_len(srv->tmp_buf, CONST_STR_LEN(".so")); - #endif - - p = plugin_init(); -@@ -173,7 +173,7 @@ - #endif - buffer_reset(srv->tmp_buf); - buffer_copy_string(srv->tmp_buf, modules); -- buffer_append_string(srv->tmp_buf, "_plugin_init"); -+ buffer_append_string_len(srv->tmp_buf, CONST_STR_LEN("_plugin_init")); - - #ifdef __WIN32 - init = GetProcAddress(p->lib, srv->tmp_buf->ptr); -@@ -197,7 +197,7 @@ - - #else - #if 1 -- init = (int (*)(plugin *))dlsym(p->lib, srv->tmp_buf->ptr); -+ init = (int (*)(plugin *))(intptr_t)dlsym(p->lib, srv->tmp_buf->ptr); - #else - *(void **)(&init) = dlsym(p->lib, srv->tmp_buf->ptr); - #endif -Index: src/SConscript -=================================================================== ---- src/SConscript (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/SConscript (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -43,6 +43,7 @@ - 'mod_cgi' : { 'src' : [ 'mod_cgi.c' ] }, - 'mod_fastcgi' : { 'src' : [ 'mod_fastcgi.c' ] }, - 'mod_scgi' : { 'src' : [ 'mod_scgi.c' ] }, -+ 'mod_extforward' : { 'src' : [ 'mod_extforward.c' ] }, - 'mod_staticfile' : { 'src' : [ 'mod_staticfile.c' ] }, - 'mod_dirlisting' : { 'src' : [ 'mod_dirlisting.c' ], 'lib' : [ env['LIBPCRE'] ] }, - 'mod_indexfile' : { 'src' : [ 'mod_indexfile.c' ] }, -Index: src/buffer.c -=================================================================== ---- src/buffer.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/buffer.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -55,6 +55,8 @@ - free(b->ptr); - b->ptr = NULL; - b->size = 0; -+ } else if (b->size) { -+ b->ptr[0] = '\0'; - } - - b->used = 0; -@@ -626,6 +628,7 @@ - return 0; - } - -+/* everything except: ! ( ) * - . 0-9 A-Z _ a-z */ - const char encoded_chars_rel_uri_part[] = { - /* - 0 1 2 3 4 5 6 7 8 9 A B C D E F -@@ -633,11 +636,11 @@ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 00 - 0F control chars */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */ - 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, /* 20 - 2F space " # $ % & ' + , / */ -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, /* 30 - 3F : ; = ? @ < > */ -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40 - 4F */ -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 50 - 5F */ -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 60 - 6F */ -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* 70 - 7F DEL */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, /* 30 - 3F : ; < = > ? */ -+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40 - 4F @ */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, /* 50 - 5F [ \ ] ^ */ -+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 60 - 6F ` */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, /* 70 - 7F { | } ~ DEL */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 80 - 8F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 90 - 9F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* A0 - AF */ -@@ -648,18 +651,19 @@ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* F0 - FF */ - }; - -+/* everything except: ! ( ) * - . / 0-9 A-Z _ a-z */ - const char encoded_chars_rel_uri[] = { - /* - 0 1 2 3 4 5 6 7 8 9 A B C D E F - */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 00 - 0F control chars */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */ -- 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, /* 20 - 2F space " # $ % & ' + , / */ -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, /* 30 - 3F : ; = ? @ < > */ -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40 - 4F */ -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 50 - 5F */ -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 60 - 6F */ -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* 70 - 7F DEL */ -+ 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, /* 20 - 2F space " # $ % & ' + , */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, /* 30 - 3F : ; < = > ? */ -+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40 - 4F @ */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, /* 50 - 5F [ \ ] ^ */ -+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 60 - 6F ` */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, /* 70 - 7F { | } ~ DEL */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 80 - 8F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 90 - 9F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* A0 - AF */ -Index: src/mod_userdir.c -=================================================================== ---- src/mod_userdir.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/mod_userdir.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -262,6 +262,9 @@ - return HANDLER_GO_ON; - } - } -+ if (con->conf.force_lowercase_filenames) { -+ buffer_to_lower(p->username); -+ } - - buffer_copy_string_buffer(p->temp_path, p->conf.basepath); - BUFFER_APPEND_SLASH(p->temp_path); -@@ -284,8 +287,24 @@ - } - } - -+ /* the physical rel_path is basically the same as uri.path; -+ * but it is converted to lowercase in case of force_lowercase_filenames and some special handling -+ * for trailing '.', ' ' and '/' on windows -+ * we assume that no docroot/physical handler changed this -+ * (docroot should only set the docroot/server name, phyiscal should only change the phyiscal.path; -+ * the exception mod_secure_download doesn't work with userdir anyway) -+ */ - BUFFER_APPEND_SLASH(p->temp_path); -- buffer_append_string(p->temp_path, rel_url + 1); /* skip the / */ -+ /* if no second '/' is found, we assume that it was stripped from the uri.path for the special handling -+ * on windows. -+ * we do not care about the trailing slash here on windows, as we already ensured it is a directory -+ * -+ * TODO: what to do with trailing dots in usernames on windows? they may result in the same directory -+ * as a username without them. -+ */ -+ if (NULL != (rel_url = strchr(con->physical.rel_path->ptr + 2, '/'))) { -+ buffer_append_string(p->temp_path, rel_url + 1); /* skip the / */ -+ } - buffer_copy_string_buffer(con->physical.path, p->temp_path); - - buffer_reset(p->temp_path); -Index: src/mod_proxy.c -=================================================================== ---- src/mod_proxy.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/mod_proxy.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -432,10 +432,10 @@ - - /* request line */ - buffer_copy_string(b, get_http_method_name(con->request.http_method)); -- BUFFER_APPEND_STRING_CONST(b, " "); -+ buffer_append_string_len(b, CONST_STR_LEN(" ")); - - buffer_append_string_buffer(b, con->request.uri); -- BUFFER_APPEND_STRING_CONST(b, " HTTP/1.0\r\n"); -+ buffer_append_string_len(b, CONST_STR_LEN(" HTTP/1.0\r\n")); - - proxy_append_header(con, "X-Forwarded-For", (char *)inet_ntop_cache_get_ip(srv, &(con->dst_addr))); - /* http_host is NOT is just a pointer to a buffer -@@ -456,13 +456,13 @@ - if (buffer_is_equal_string(ds->key, CONST_STR_LEN("Connection"))) continue; - - buffer_append_string_buffer(b, ds->key); -- BUFFER_APPEND_STRING_CONST(b, ": "); -+ buffer_append_string_len(b, CONST_STR_LEN(": ")); - buffer_append_string_buffer(b, ds->value); -- BUFFER_APPEND_STRING_CONST(b, "\r\n"); -+ buffer_append_string_len(b, CONST_STR_LEN("\r\n")); - } - } - -- BUFFER_APPEND_STRING_CONST(b, "\r\n"); -+ buffer_append_string_len(b, CONST_STR_LEN("\r\n")); - - hctx->wb->bytes_in += b->used - 1; - /* body */ -@@ -1060,6 +1060,8 @@ - data_array *extension = NULL; - size_t path_info_offset; - -+ if (con->mode != DIRECT) return HANDLER_GO_ON; -+ - /* Possibly, we processed already this request */ - if (con->file_started == 1) return HANDLER_GO_ON; - -@@ -1118,7 +1120,13 @@ - log_error_write(srv, __FILE__, __LINE__, "s", "proxy - ext found"); - } - -- switch(p->conf.balance) { -+ if (extension->value->used == 1) { -+ if ( ((data_proxy *)extension->value->data[0])->is_disabled ) { -+ ndx = -1; -+ } else { -+ ndx = 0; -+ } -+ } else if (extension->value->used != 0) switch(p->conf.balance) { - case PROXY_BALANCE_HASH: - /* hash balancing */ - -@@ -1175,7 +1183,9 @@ - } - - break; -- case PROXY_BALANCE_RR: -+ case PROXY_BALANCE_RR: { -+ data_proxy *host; -+ - /* round robin */ - if (p->conf.debug) { - log_error_write(srv, __FILE__, __LINE__, "s", -@@ -1185,31 +1195,32 @@ - /* just to be sure */ - assert(extension->value->used < INT_MAX); - -- for (k = 0, ndx = -1, max_usage = INT_MAX; k < extension->value->used; k++) { -- data_proxy *host = (data_proxy *)extension->value->data[k]; -+ host = (data_proxy *)extension->value->data[0]; - -- if (host->is_disabled) continue; -+ /* Use last_used_ndx from first host in list */ -+ k = ndx = host->last_used_ndx; -+ if (ndx < 0) ndx = 0; - -- /* first usable ndx */ -- if (max_usage == INT_MAX) { -- max_usage = k; -- } -+ /* Search first active host after last_used_ndx */ -+ while ( ndx < (int) extension->value->used -+ && (host = (data_proxy *)extension->value->data[ndx])->is_disabled ) ndx++; - -- /* get next ndx */ -- if ((int)k > host->last_used_ndx) { -- ndx = k; -- host->last_used_ndx = k; -- -- break; -+ if (ndx >= (int) extension->value->used) { -+ /* didn't found a higher id, wrap to the start */ -+ for (ndx = 0; ndx < (int) k; ndx++) { -+ host = (data_proxy *)extension->value->data[ndx]; -+ if (!host->is_disabled) break; - } -- } - -- /* didn't found a higher id, wrap to the start */ -- if (ndx == -1 && max_usage != INT_MAX) { -- ndx = max_usage; -+ /* No active host found */ -+ if (host->is_disabled) ndx = -1; - } - -+ /* Save new index for next round */ -+ ((data_proxy *)extension->value->data[0])->last_used_ndx = ndx; -+ - break; -+ } - default: - break; - } -Index: src/mod_extforward.c -=================================================================== ---- src/mod_extforward.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/mod_extforward.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -281,8 +281,9 @@ - static const char *last_not_in_array(array *a, plugin_data *p) - { - array *forwarder = p->conf.forwarder; -+ int i; - -- for (int i = a->used - 1; i >= 0; i--) { -+ for (i = a->used - 1; i >= 0; i--) { - data_string *ds = (data_string *)a->data[i]; - const char *ip = ds->value->ptr; - -Index: src/Makefile.am -=================================================================== ---- src/Makefile.am (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/Makefile.am (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -3,7 +3,7 @@ - noinst_PROGRAMS=proc_open lemon # simple-fcgi #graphic evalo bench ajp ssl error_test adserver gen-license - sbin_PROGRAMS=lighttpd lighttpd-angel - bin_PROGRAMS=spawn-fcgi --LEMON=$(top_builddir)/src/lemon -+LEMON=$(top_builddir)/src/lemon$(EXEEXT) - - lemon_SOURCES=lemon.c - -@@ -15,21 +15,26 @@ - if CROSS_COMPILING - configparser.c configparser.h: - mod_ssi_exprparser.c mod_ssi_exprparser.h: -+ -+.PHONY: parsers -+parsers: - else --$(srcdir)/configparser.y: lemon --$(srcdir)/mod_ssi_exprparser.y: lemon -- --configparser.c configparser.h: $(srcdir)/configparser.y -+configparser.h: configparser.c -+configparser.c: $(srcdir)/configparser.y $(srcdir)/lempar.c lemon$(EXEEXT) - rm -f configparser.h - $(LEMON) -q $(srcdir)/configparser.y $(srcdir)/lempar.c - --mod_ssi_exprparser.c mod_ssi_exprparser.h: $(srcdir)/mod_ssi_exprparser.y -+mod_ssi_exprparser.h: mod_ssi_exprparser.c -+mod_ssi_exprparser.c: $(srcdir)/mod_ssi_exprparser.y $(srcdir)/lempar.c lemon$(EXEEXT) - rm -f mod_ssi_exprparser.h - $(LEMON) -q $(srcdir)/mod_ssi_exprparser.y $(srcdir)/lempar.c -+ -+.PHONY: parsers -+parsers: configparser.c mod_ssi_exprparser.c - endif - --$(srcdir)/configfile.c: configparser.h --$(srcdir)/mod_ssi_expr.c: mod_ssi_exprparser.h -+BUILT_SOURCES = parsers -+MAINTAINERCLEANFILES = configparser.c configparser.h mod_ssi_exprparser.c mod_ssi_exprparser.h - - common_src=buffer.c log.c \ - keyvalue.c chunk.c \ -Index: src/mod_expire.c -=================================================================== ---- src/mod_expire.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/mod_expire.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -339,7 +339,7 @@ - response_header_overwrite(srv, con, CONST_STR_LEN("Expires"), CONST_BUF_LEN(p->expire_tstmp)); - - /* HTTP/1.1 */ -- buffer_copy_string(p->expire_tstmp, "max-age="); -+ buffer_copy_string_len(p->expire_tstmp, CONST_STR_LEN("max-age=")); - buffer_append_long(p->expire_tstmp, ts); - - response_header_overwrite(srv, con, CONST_STR_LEN("Cache-Control"), CONST_BUF_LEN(p->expire_tstmp)); -Index: src/network_openssl.c -=================================================================== ---- src/network_openssl.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/network_openssl.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -85,6 +85,7 @@ - * - */ - -+ ERR_clear_error(); - if ((r = SSL_write(ssl, offset, toSend)) <= 0) { - unsigned long err; - -@@ -187,6 +188,7 @@ - - close(ifd); - -+ ERR_clear_error(); - if ((r = SSL_write(ssl, s, toSend)) <= 0) { - unsigned long err; - -Index: src/network_freebsd_sendfile.c -=================================================================== ---- src/network_freebsd_sendfile.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/network_freebsd_sendfile.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -166,6 +166,7 @@ - if (-1 == sendfile(c->file.fd, fd, offset, toSend, NULL, &r, 0)) { - switch(errno) { - case EAGAIN: -+ case EINTR: - break; - case ENOTCONN: - return -2; -@@ -175,7 +176,7 @@ - } - } - -- if (r == 0) { -+ if (r == 0 && (errno != EAGAIN && errno != EINTR)) { - int oerrno = errno; - /* We got an event to write but we wrote nothing - * -Index: src/mod_redirect.c -=================================================================== ---- src/mod_redirect.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/mod_redirect.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -215,8 +215,7 @@ - - start = 0; end = pattern_len; - for (k = 0; k < pattern_len; k++) { -- if ((pattern[k] == '$' || pattern[k] == '%') && -- isdigit((unsigned char)pattern[k + 1])) { -+ if (pattern[k] == '$' || pattern[k] == '%') { - /* got one */ - - size_t num = pattern[k + 1] - '0'; -@@ -225,7 +224,10 @@ - - buffer_append_string_len(p->location, pattern + start, end - start); - -- if (pattern[k] == '$') { -+ if (!isdigit((unsigned char)pattern[k + 1])) { -+ /* enable escape: "%%" => "%", "%a" => "%a", "$$" => "$" */ -+ buffer_append_string_len(p->location, pattern+k, pattern[k] == pattern[k+1] ? 1 : 2); -+ } else if (pattern[k] == '$') { - /* n is always > 0 */ - if (num < (size_t)n) { - buffer_append_string(p->location, list[num]); -@@ -251,6 +253,7 @@ - response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(p->location)); - - con->http_status = 301; -+ con->mode = DIRECT; - con->file_finished = 1; - - return HANDLER_FINISHED; -Index: src/http_auth.c -=================================================================== ---- src/http_auth.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/http_auth.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -697,7 +697,7 @@ - } - } else if (p->conf.auth_backend == AUTH_BACKEND_LDAP) { - #ifdef USE_LDAP -- LDAP *ldap; -+ LDAP *ldap = NULL; - LDAPMessage *lm, *first; - char *dn; - int ret; -@@ -742,39 +742,56 @@ - buffer_append_string_buffer(p->ldap_filter, username); - buffer_append_string_buffer(p->ldap_filter, p->conf.ldap_filter_post); - -- - /* 2. */ - if (p->conf.ldap == NULL || - LDAP_SUCCESS != (ret = ldap_search_s(p->conf.ldap, p->conf.auth_ldap_basedn->ptr, LDAP_SCOPE_SUBTREE, p->ldap_filter->ptr, attrs, 0, &lm))) { -- if (auth_ldap_init(srv, &p->conf) != HANDLER_GO_ON) -- return -1; -- if (LDAP_SUCCESS != (ret = ldap_search_s(p->conf.ldap, p->conf.auth_ldap_basedn->ptr, LDAP_SCOPE_SUBTREE, p->ldap_filter->ptr, attrs, 0, &lm))) { -+ /* try again if ldap was only temporary down */ -+ if (p->conf.ldap == NULL || ret != LDAP_SERVER_DOWN || LDAP_SUCCESS != (ret = ldap_search_s(p->conf.ldap, p->conf.auth_ldap_basedn->ptr, LDAP_SCOPE_SUBTREE, p->ldap_filter->ptr, attrs, 0, &lm))) { -+ if (auth_ldap_init(srv, &p->conf) != HANDLER_GO_ON) -+ return -1; - -- log_error_write(srv, __FILE__, __LINE__, "sssb", -- "ldap:", ldap_err2string(ret), "filter:", p->ldap_filter); -- -- return -1; -+ ldap = p->conf.ldap; /* save temporary ldap connection (TODO: redo ldap) */ -+ if (LDAP_SUCCESS != (ret = ldap_search_s(p->conf.ldap, p->conf.auth_ldap_basedn->ptr, LDAP_SCOPE_SUBTREE, p->ldap_filter->ptr, attrs, 0, &lm))) { -+ log_error_write(srv, __FILE__, __LINE__, "sssb", -+ "ldap:", ldap_err2string(ret), "filter:", p->ldap_filter); -+ /* destroy temporary ldap connection (TODO: redo ldap) */ -+ ldap_unbind_s(ldap); -+ return -1; -+ } - } - } - - if (NULL == (first = ldap_first_entry(p->conf.ldap, lm))) { -- log_error_write(srv, __FILE__, __LINE__, "s", "ldap ..."); -+ /* No matching entry is not an error */ -+ /* log_error_write(srv, __FILE__, __LINE__, "s", "ldap ..."); */ - - ldap_msgfree(lm); - -+ /* destroy temporary ldap connection (TODO: redo ldap) */ -+ if (NULL != ldap) { -+ ldap_unbind_s(ldap); -+ } - return -1; - } - - if (NULL == (dn = ldap_get_dn(p->conf.ldap, first))) { -- log_error_write(srv, __FILE__, __LINE__, "s", "ldap ..."); -+ log_error_write(srv, __FILE__, __LINE__, "s", "ldap: ldap_get_dn failed"); - - ldap_msgfree(lm); - -+ /* destroy temporary ldap connection (TODO: redo ldap) */ -+ if (NULL != ldap) { -+ ldap_unbind_s(ldap); -+ } - return -1; - } - - ldap_msgfree(lm); - -+ /* destroy temporary ldap connection (TODO: redo ldap) */ -+ if (NULL != ldap) { -+ ldap_unbind_s(ldap); -+ } - - /* 3. */ - if (NULL == (ldap = ldap_init(p->conf.auth_ldap_hostname->ptr, LDAP_PORT))) { -Index: src/mod_usertrack.c -=================================================================== ---- src/mod_usertrack.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/mod_usertrack.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -103,7 +103,7 @@ - } - - if (buffer_is_empty(s->cookie_name)) { -- buffer_copy_string(s->cookie_name, "TRACKID"); -+ buffer_copy_string_len(s->cookie_name, CONST_STR_LEN("TRACKID")); - } else { - size_t j; - for (j = 0; j < s->cookie_name->used - 1; j++) { -@@ -214,9 +214,9 @@ - if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) { - ds = data_response_init(); - } -- buffer_copy_string(ds->key, "Set-Cookie"); -+ buffer_copy_string_len(ds->key, CONST_STR_LEN("Set-Cookie")); - buffer_copy_string_buffer(ds->value, p->conf.cookie_name); -- buffer_append_string(ds->value, "="); -+ buffer_append_string_len(ds->value, CONST_STR_LEN("=")); - - - /* taken from mod_auth.c */ -@@ -235,16 +235,16 @@ - MD5_Final(h, &Md5Ctx); - - buffer_append_string_encoded(ds->value, (char *)h, 16, ENCODING_HEX); -- buffer_append_string(ds->value, "; Path=/"); -- buffer_append_string(ds->value, "; Version=1"); -+ buffer_append_string_len(ds->value, CONST_STR_LEN("; Path=/")); -+ buffer_append_string_len(ds->value, CONST_STR_LEN("; Version=1")); - - if (!buffer_is_empty(p->conf.cookie_domain)) { -- buffer_append_string(ds->value, "; Domain="); -+ buffer_append_string_len(ds->value, CONST_STR_LEN("; Domain=")); - buffer_append_string_encoded(ds->value, CONST_BUF_LEN(p->conf.cookie_domain), ENCODING_REL_URI); - } - - if (p->conf.cookie_max_age) { -- buffer_append_string(ds->value, "; max-age="); -+ buffer_append_string_len(ds->value, CONST_STR_LEN("; max-age=")); - buffer_append_long(ds->value, p->conf.cookie_max_age); - } - -Index: src/mod_webdav.c -=================================================================== ---- src/mod_webdav.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/mod_webdav.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -485,23 +485,23 @@ - UNUSED(con); - - if (value) { -- buffer_append_string(b,"<"); -+ buffer_append_string_len(b,CONST_STR_LEN("<")); - buffer_append_string(b, prop_name); -- buffer_append_string(b, " xmlns=\""); -+ buffer_append_string_len(b, CONST_STR_LEN(" xmlns=\"")); - buffer_append_string(b, prop_ns); -- buffer_append_string(b, "\">"); -+ buffer_append_string_len(b, CONST_STR_LEN("\">")); - - buffer_append_string(b, value); - -- buffer_append_string(b,""); -+ buffer_append_string_len(b, CONST_STR_LEN(">")); - } else { -- buffer_append_string(b,"<"); -+ buffer_append_string_len(b,CONST_STR_LEN("<")); - buffer_append_string(b, prop_name); -- buffer_append_string(b, " xmlns=\""); -+ buffer_append_string_len(b, CONST_STR_LEN(" xmlns=\"")); - buffer_append_string(b, prop_ns); -- buffer_append_string(b, "\"/>"); -+ buffer_append_string_len(b, CONST_STR_LEN("\"/>")); - } - - return 0; -@@ -511,24 +511,24 @@ - static int webdav_gen_response_status_tag(server *srv, connection *con, physical *dst, int status, buffer *b) { - UNUSED(srv); - -- buffer_append_string(b,"\n"); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); - -- buffer_append_string(b,"\n"); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); - buffer_append_string_buffer(b, dst->rel_path); -- buffer_append_string(b,"\n"); -- buffer_append_string(b,"\n"); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); - - if (con->request.http_version == HTTP_VERSION_1_1) { -- BUFFER_COPY_STRING_CONST(b, "HTTP/1.1 "); -+ buffer_copy_string_len(b, CONST_STR_LEN("HTTP/1.1 ")); - } else { -- BUFFER_COPY_STRING_CONST(b, "HTTP/1.0 "); -+ buffer_copy_string_len(b, CONST_STR_LEN("HTTP/1.0 ")); - } - buffer_append_long(b, status); -- BUFFER_APPEND_STRING_CONST(b, " "); -+ buffer_append_string_len(b, CONST_STR_LEN(" ")); - buffer_append_string(b, get_http_status_name(status)); - -- buffer_append_string(b,"\n"); -- buffer_append_string(b,"\n"); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); - - return 0; - } -@@ -570,6 +570,8 @@ - /* */ - } - } -+#else -+ UNUSED(p); - #endif - } - -@@ -730,6 +732,8 @@ - } - } - } -+#else -+ UNUSED(p); - #endif - return status; - } -@@ -840,12 +844,12 @@ - - if (0 == strcmp(prop_name, "resourcetype")) { - if (S_ISDIR(sce->st.st_mode)) { -- buffer_append_string(b, ""); -+ buffer_append_string_len(b, CONST_STR_LEN("")); - found = 1; - } - } else if (0 == strcmp(prop_name, "getcontenttype")) { - if (S_ISDIR(sce->st.st_mode)) { -- buffer_append_string(b, "httpd/unix-directory"); -+ buffer_append_string_len(b, CONST_STR_LEN("httpd/unix-directory")); - found = 1; - } else if(S_ISREG(sce->st.st_mode)) { - for (k = 0; k < con->conf.mimetypes->used; k++) { -@@ -854,9 +858,9 @@ - if (ds->key->used == 0) continue; - - if (buffer_is_equal_right_len(dst->path, ds->key, ds->key->used - 1)) { -- buffer_append_string(b,""); -+ buffer_append_string_len(b,CONST_STR_LEN("")); - buffer_append_string_buffer(b, ds->value); -- buffer_append_string(b, ""); -+ buffer_append_string_len(b, CONST_STR_LEN("")); - found = 1; - - break; -@@ -864,26 +868,26 @@ - } - } - } else if (0 == strcmp(prop_name, "creationdate")) { -- buffer_append_string(b, ""); -+ buffer_append_string_len(b, CONST_STR_LEN("")); - strftime(ctime_buf, sizeof(ctime_buf), "%Y-%m-%dT%H:%M:%SZ", gmtime(&(sce->st.st_ctime))); - buffer_append_string(b, ctime_buf); -- buffer_append_string(b, ""); -+ buffer_append_string_len(b, CONST_STR_LEN("")); - found = 1; - } else if (0 == strcmp(prop_name, "getlastmodified")) { -- buffer_append_string(b,""); -+ buffer_append_string_len(b,CONST_STR_LEN("")); - strftime(mtime_buf, sizeof(mtime_buf), "%a, %d %b %Y %H:%M:%S GMT", gmtime(&(sce->st.st_mtime))); - buffer_append_string(b, mtime_buf); -- buffer_append_string(b, ""); -+ buffer_append_string_len(b, CONST_STR_LEN("")); - found = 1; - } else if (0 == strcmp(prop_name, "getcontentlength")) { -- buffer_append_string(b,""); -+ buffer_append_string_len(b,CONST_STR_LEN("")); - buffer_append_off_t(b, sce->st.st_size); -- buffer_append_string(b, ""); -+ buffer_append_string_len(b, CONST_STR_LEN("")); - found = 1; - } else if (0 == strcmp(prop_name, "getcontentlanguage")) { -- buffer_append_string(b,""); -- buffer_append_string(b, "en"); -- buffer_append_string(b, ""); -+ buffer_append_string_len(b,CONST_STR_LEN("")); -+ buffer_append_string_len(b, CONST_STR_LEN("en")); -+ buffer_append_string_len(b, CONST_STR_LEN("")); - found = 1; - } - } -@@ -1103,44 +1107,44 @@ - - b = chunkqueue_get_append_buffer(con->write_queue); - -- buffer_copy_string(b, "\n"); -+ buffer_copy_string_len(b, CONST_STR_LEN("\n")); - -- buffer_append_string(b,"\n"); -- buffer_append_string(b,"\n"); -- buffer_append_string(b,"\n"); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); - -- buffer_append_string(b,""); -- buffer_append_string(b,"")); -+ buffer_append_string_len(b,CONST_STR_LEN(""); -- buffer_append_string(b,"\n"); -+ buffer_append_string_len(b, CONST_STR_LEN("/>")); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); - -- buffer_append_string(b,""); -- buffer_append_string(b,"")); -+ buffer_append_string_len(b,CONST_STR_LEN(""); -- buffer_append_string(b,"\n"); -+ buffer_append_string_len(b, CONST_STR_LEN("/>")); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); - -- buffer_append_string(b,""); -+ buffer_append_string_len(b,CONST_STR_LEN("")); - buffer_append_string(b, depth == 0 ? "0" : "infinity"); -- buffer_append_string(b,"\n"); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); - -- buffer_append_string(b,""); -- buffer_append_string(b, "Second-600"); -- buffer_append_string(b,"\n"); -+ buffer_append_string_len(b,CONST_STR_LEN("")); -+ buffer_append_string_len(b, CONST_STR_LEN("Second-600")); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); - -- buffer_append_string(b,""); -- buffer_append_string(b,"\n"); -+ buffer_append_string_len(b,CONST_STR_LEN("")); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); - -- buffer_append_string(b,""); -- buffer_append_string(b, ""); -+ buffer_append_string_len(b,CONST_STR_LEN("")); -+ buffer_append_string_len(b, CONST_STR_LEN("")); - buffer_append_string_buffer(b, locktoken); -- buffer_append_string(b, ""); -- buffer_append_string(b,"\n"); -+ buffer_append_string_len(b, CONST_STR_LEN("")); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); - -- buffer_append_string(b,"\n"); -- buffer_append_string(b,"\n"); -- buffer_append_string(b,"\n"); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); - - return 0; - } -@@ -1154,6 +1158,7 @@ - int has_lock = 1; - - #ifdef USE_LOCKS -+ UNUSED(srv); - data_string *ds; - - /** -@@ -1192,6 +1197,11 @@ - has_lock = 0; - } - } -+#else -+ UNUSED(srv); -+ UNUSED(con); -+ UNUSED(p); -+ UNUSED(uri); - #endif - - return has_lock; -@@ -1334,9 +1344,9 @@ - - b = chunkqueue_get_append_buffer(con->write_queue); - -- buffer_copy_string(b, "\n"); -+ buffer_copy_string_len(b, CONST_STR_LEN("\n")); - -- buffer_append_string(b,"\n"); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); - - /* allprop */ - -@@ -1348,40 +1358,40 @@ - /* Depth: 0 */ - webdav_get_props(srv, con, p, &(con->physical), req_props, prop_200, prop_404); - -- buffer_append_string(b,"\n"); -- buffer_append_string(b,""); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); -+ buffer_append_string_len(b,CONST_STR_LEN("")); - buffer_append_string_buffer(b, con->uri.scheme); -- buffer_append_string(b,"://"); -+ buffer_append_string_len(b,CONST_STR_LEN("://")); - buffer_append_string_buffer(b, con->uri.authority); - buffer_append_string_encoded(b, CONST_BUF_LEN(con->uri.path), ENCODING_REL_URI); -- buffer_append_string(b,"\n"); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); - - if (!buffer_is_empty(prop_200)) { -- buffer_append_string(b,"\n"); -- buffer_append_string(b,"\n"); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); - - buffer_append_string_buffer(b, prop_200); - -- buffer_append_string(b,"\n"); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); - -- buffer_append_string(b,"HTTP/1.1 200 OK\n"); -+ buffer_append_string_len(b,CONST_STR_LEN("HTTP/1.1 200 OK\n")); - -- buffer_append_string(b,"\n"); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); - } - if (!buffer_is_empty(prop_404)) { -- buffer_append_string(b,"\n"); -- buffer_append_string(b,"\n"); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); - - buffer_append_string_buffer(b, prop_404); - -- buffer_append_string(b,"\n"); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); - -- buffer_append_string(b,"HTTP/1.1 404 Not Found\n"); -+ buffer_append_string_len(b,CONST_STR_LEN("HTTP/1.1 404 Not Found\n")); - -- buffer_append_string(b,"\n"); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); - } - -- buffer_append_string(b,"\n"); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); - - break; - case 1: -@@ -1417,40 +1427,40 @@ - - webdav_get_props(srv, con, p, &d, req_props, prop_200, prop_404); - -- buffer_append_string(b,"\n"); -- buffer_append_string(b,""); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); -+ buffer_append_string_len(b,CONST_STR_LEN("")); - buffer_append_string_buffer(b, con->uri.scheme); -- buffer_append_string(b,"://"); -+ buffer_append_string_len(b,CONST_STR_LEN("://")); - buffer_append_string_buffer(b, con->uri.authority); - buffer_append_string_encoded(b, CONST_BUF_LEN(d.rel_path), ENCODING_REL_URI); -- buffer_append_string(b,"\n"); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); - - if (!buffer_is_empty(prop_200)) { -- buffer_append_string(b,"\n"); -- buffer_append_string(b,"\n"); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); - - buffer_append_string_buffer(b, prop_200); - -- buffer_append_string(b,"\n"); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); - -- buffer_append_string(b,"HTTP/1.1 200 OK\n"); -+ buffer_append_string_len(b,CONST_STR_LEN("HTTP/1.1 200 OK\n")); - -- buffer_append_string(b,"\n"); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); - } - if (!buffer_is_empty(prop_404)) { -- buffer_append_string(b,"\n"); -- buffer_append_string(b,"\n"); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); - - buffer_append_string_buffer(b, prop_404); - -- buffer_append_string(b,"\n"); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); - -- buffer_append_string(b,"HTTP/1.1 404 Not Found\n"); -+ buffer_append_string_len(b,CONST_STR_LEN("HTTP/1.1 404 Not Found\n")); - -- buffer_append_string(b,"\n"); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); - } - -- buffer_append_string(b,"\n"); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); - } - closedir(dir); - buffer_free(d.path); -@@ -1473,7 +1483,7 @@ - buffer_free(prop_200); - buffer_free(prop_404); - -- buffer_append_string(b,"\n"); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); - - if (p->conf.log_xml) { - log_error_write(srv, __FILE__, __LINE__, "sb", "XML-response-body:", b); -@@ -1548,13 +1558,13 @@ - - b = chunkqueue_get_append_buffer(con->write_queue); - -- buffer_copy_string(b, "\n"); -+ buffer_copy_string_len(b, CONST_STR_LEN("\n")); - -- buffer_append_string(b,"\n"); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); - - buffer_append_string_buffer(b, multi_status_resp); - -- buffer_append_string(b,"\n"); -+ buffer_append_string_len(b,CONST_STR_LEN("\n")); - - if (p->conf.log_xml) { - log_error_write(srv, __FILE__, __LINE__, "sb", "XML-response-body:", b); -@@ -2286,7 +2296,7 @@ - uuid_generate(id); - uuid_unparse(id, uuid); - -- buffer_copy_string(p->tmp_buf, "opaquelocktoken:"); -+ buffer_copy_string_len(p->tmp_buf, CONST_STR_LEN("opaquelocktoken:")); - buffer_append_string(p->tmp_buf, uuid); - - /* "CREATE TABLE locks (" -Index: src/configparser.y -=================================================================== ---- src/configparser.y (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/configparser.y (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -21,6 +21,10 @@ - dc->parent = ctx->current; - array_insert_unique(dc->parent->childs, (data_unset *)dc); - } -+ if (ctx->configs_stack->used > 0 && ctx->current->context_ndx == 0) { -+ fprintf(stderr, "Cannot use conditionals inside a global { ... } block\n"); -+ exit(-1); -+ } - array_insert_unique(ctx->configs_stack, (data_unset *)ctx->current); - ctx->current = dc; - } -Index: src/mod_status.c -=================================================================== ---- src/mod_status.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/mod_status.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -143,24 +143,24 @@ - - - static int mod_status_row_append(buffer *b, const char *key, const char *value) { -- BUFFER_APPEND_STRING_CONST(b, " \n"); -- BUFFER_APPEND_STRING_CONST(b, " "); -+ buffer_append_string_len(b, CONST_STR_LEN(" \n")); -+ buffer_append_string_len(b, CONST_STR_LEN(" ")); - buffer_append_string(b, key); -- BUFFER_APPEND_STRING_CONST(b, "\n"); -- BUFFER_APPEND_STRING_CONST(b, " "); -+ buffer_append_string_len(b, CONST_STR_LEN("\n")); -+ buffer_append_string_len(b, CONST_STR_LEN(" ")); - buffer_append_string(b, value); -- BUFFER_APPEND_STRING_CONST(b, "\n"); -- BUFFER_APPEND_STRING_CONST(b, " \n"); -+ buffer_append_string_len(b, CONST_STR_LEN("\n")); -+ buffer_append_string_len(b, CONST_STR_LEN(" \n")); - - return 0; - } - - static int mod_status_header_append(buffer *b, const char *key) { -- BUFFER_APPEND_STRING_CONST(b, " \n"); -- BUFFER_APPEND_STRING_CONST(b, " "); -+ buffer_append_string_len(b, CONST_STR_LEN(" \n")); -+ buffer_append_string_len(b, CONST_STR_LEN(" ")); - buffer_append_string(b, key); -- BUFFER_APPEND_STRING_CONST(b, "\n"); -- BUFFER_APPEND_STRING_CONST(b, " \n"); -+ buffer_append_string_len(b, CONST_STR_LEN("\n")); -+ buffer_append_string_len(b, CONST_STR_LEN(" \n")); - - return 0; - } -@@ -169,13 +169,13 @@ - plugin_data *p = p_d; - - if (p->conf.sort) { -- BUFFER_APPEND_STRING_CONST(b, ""); -+ buffer_append_string_len(b, CONST_STR_LEN("")); - buffer_append_string(b, key); -- BUFFER_APPEND_STRING_CONST(b, ":\n"); -+ buffer_append_string_len(b, CONST_STR_LEN(":\n")); - } else { -- BUFFER_APPEND_STRING_CONST(b, ""); -+ buffer_append_string_len(b, CONST_STR_LEN("")); - buffer_append_string(b, key); -- BUFFER_APPEND_STRING_CONST(b, "\n"); -+ buffer_append_string_len(b, CONST_STR_LEN("\n")); - } - - return 0; -@@ -209,15 +209,14 @@ - - b = chunkqueue_get_append_buffer(con->write_queue); - -- BUFFER_COPY_STRING_CONST(b, -+ buffer_copy_string_len(b, CONST_STR_LEN( - "\n" - "\n" - "\n" - " \n" -- " Status\n"); -+ " Status\n" - -- BUFFER_APPEND_STRING_CONST(b, - " \n"); -+ " \n")); - - if (p->conf.sort) { -- BUFFER_APPEND_STRING_CONST(b, -+ buffer_append_string_len(b, CONST_STR_LEN( - "\n"); -+ "\n")); - } - -- BUFFER_APPEND_STRING_CONST(b, -+ buffer_append_string_len(b, CONST_STR_LEN( - " \n" -- " \n"); -+ " \n")); - - - - /* connection listing */ -- BUFFER_APPEND_STRING_CONST(b, "

Server-Status

"); -+ buffer_append_string_len(b, CONST_STR_LEN("

Server-Status

")); - -- BUFFER_APPEND_STRING_CONST(b, ""); -- BUFFER_APPEND_STRING_CONST(b, "
Hostname"); -+ buffer_append_string_len(b, CONST_STR_LEN("")); -+ buffer_append_string_len(b, CONST_STR_LEN("\n"); -- BUFFER_APPEND_STRING_CONST(b, "\n")); -+ buffer_append_string_len(b, CONST_STR_LEN("\n"); -- BUFFER_APPEND_STRING_CONST(b, "\n")); -+ buffer_append_string_len(b, CONST_STR_LEN("\n"); -+ buffer_append_string_len(b, CONST_STR_LEN("\n")); - - -- BUFFER_APPEND_STRING_CONST(b, "\n"); -+ buffer_append_string_len(b, CONST_STR_LEN("\n")); - -- BUFFER_APPEND_STRING_CONST(b, "\n"); -+ buffer_append_string_len(b, CONST_STR_LEN("req\n")); - -- BUFFER_APPEND_STRING_CONST(b, "\n"); -+ buffer_append_string_len(b, CONST_STR_LEN("byte\n")); - - - -- BUFFER_APPEND_STRING_CONST(b, "\n"); -+ buffer_append_string_len(b, CONST_STR_LEN("\n")); - -- BUFFER_APPEND_STRING_CONST(b, "\n"); -+ buffer_append_string_len(b, CONST_STR_LEN("req/s\n")); - -- BUFFER_APPEND_STRING_CONST(b, "\n"); -+ buffer_append_string_len(b, CONST_STR_LEN("byte/s\n")); - - - -- BUFFER_APPEND_STRING_CONST(b, "\n"); -+ buffer_append_string_len(b, CONST_STR_LEN("\n")); - for (j = 0, avg = 0; j < 5; j++) { - avg += p->mod_5s_requests[j]; - } - - avg /= 5; - -- BUFFER_APPEND_STRING_CONST(b, "\n"); -+ buffer_append_string_len(b, CONST_STR_LEN("req/s\n")); - - for (j = 0, avg = 0; j < 5; j++) { - avg += p->mod_5s_traffic_out[j]; -@@ -427,28 +422,29 @@ - - avg /= 5; - -- BUFFER_APPEND_STRING_CONST(b, "\n"); -+ buffer_append_string_len(b, CONST_STR_LEN("byte/s\n")); - -- BUFFER_APPEND_STRING_CONST(b, "
Hostname")); - buffer_append_string_buffer(b, con->uri.authority); -- BUFFER_APPEND_STRING_CONST(b, " ("); -+ buffer_append_string_len(b, CONST_STR_LEN(" (")); - buffer_append_string_buffer(b, con->server_name); -- BUFFER_APPEND_STRING_CONST(b, ")
Uptime"); -+ buffer_append_string_len(b, CONST_STR_LEN(")
Uptime")); - - ts = srv->cur_ts - srv->startup_ts; - -@@ -328,98 +323,98 @@ - - if (days) { - buffer_append_long(b, days); -- BUFFER_APPEND_STRING_CONST(b, " days "); -+ buffer_append_string_len(b, CONST_STR_LEN(" days ")); - } - - if (hours) { - buffer_append_long(b, hours); -- BUFFER_APPEND_STRING_CONST(b, " hours "); -+ buffer_append_string_len(b, CONST_STR_LEN(" hours ")); - } - - if (mins) { - buffer_append_long(b, mins); -- BUFFER_APPEND_STRING_CONST(b, " min "); -+ buffer_append_string_len(b, CONST_STR_LEN(" min ")); - } - - buffer_append_long(b, seconds); -- BUFFER_APPEND_STRING_CONST(b, " s"); -+ buffer_append_string_len(b, CONST_STR_LEN(" s")); - -- BUFFER_APPEND_STRING_CONST(b, "
Started at"); -+ buffer_append_string_len(b, CONST_STR_LEN("
Started at")); - - ts = srv->startup_ts; - - strftime(buf, sizeof(buf) - 1, "%Y-%m-%d %H:%M:%S", localtime(&ts)); - buffer_append_string(b, buf); -- BUFFER_APPEND_STRING_CONST(b, "
absolute (since start)
absolute (since start)
Requests"); -+ buffer_append_string_len(b, CONST_STR_LEN("
Requests")); - avg = p->abs_requests; - - mod_status_get_multiplier(&avg, &multiplier, 1000); - - buffer_append_long(b, avg); -- BUFFER_APPEND_STRING_CONST(b, " "); -+ buffer_append_string_len(b, CONST_STR_LEN(" ")); - if (multiplier) buffer_append_string_len(b, &multiplier, 1); -- BUFFER_APPEND_STRING_CONST(b, "req
Traffic"); -+ buffer_append_string_len(b, CONST_STR_LEN("
Traffic")); - avg = p->abs_traffic_out; - - mod_status_get_multiplier(&avg, &multiplier, 1024); - - sprintf(buf, "%.2f", avg); - buffer_append_string(b, buf); -- BUFFER_APPEND_STRING_CONST(b, " "); -+ buffer_append_string_len(b, CONST_STR_LEN(" ")); - if (multiplier) buffer_append_string_len(b, &multiplier, 1); -- BUFFER_APPEND_STRING_CONST(b, "byte
average (since start)
average (since start)
Requests"); -+ buffer_append_string_len(b, CONST_STR_LEN("
Requests")); - avg = p->abs_requests / (srv->cur_ts - srv->startup_ts); - - mod_status_get_multiplier(&avg, &multiplier, 1000); - - buffer_append_long(b, avg); -- BUFFER_APPEND_STRING_CONST(b, " "); -+ buffer_append_string_len(b, CONST_STR_LEN(" ")); - if (multiplier) buffer_append_string_len(b, &multiplier, 1); -- BUFFER_APPEND_STRING_CONST(b, "req/s
Traffic"); -+ buffer_append_string_len(b, CONST_STR_LEN("
Traffic")); - avg = p->abs_traffic_out / (srv->cur_ts - srv->startup_ts); - - mod_status_get_multiplier(&avg, &multiplier, 1024); - - sprintf(buf, "%.2f", avg); - buffer_append_string(b, buf); -- BUFFER_APPEND_STRING_CONST(b, " "); -+ buffer_append_string_len(b, CONST_STR_LEN(" ")); - if (multiplier) buffer_append_string_len(b, &multiplier, 1); -- BUFFER_APPEND_STRING_CONST(b, "byte/s
average (5s sliding average)
average (5s sliding average)
Requests"); -+ buffer_append_string_len(b, CONST_STR_LEN("
Requests")); - - mod_status_get_multiplier(&avg, &multiplier, 1000); - - buffer_append_long(b, avg); -- BUFFER_APPEND_STRING_CONST(b, " "); -+ buffer_append_string_len(b, CONST_STR_LEN(" ")); - if (multiplier) buffer_append_string_len(b, &multiplier, 1); - -- BUFFER_APPEND_STRING_CONST(b, "req/s
Traffic"); -+ buffer_append_string_len(b, CONST_STR_LEN("
Traffic")); - - mod_status_get_multiplier(&avg, &multiplier, 1024); - - sprintf(buf, "%.2f", avg); - buffer_append_string(b, buf); -- BUFFER_APPEND_STRING_CONST(b, " "); -+ buffer_append_string_len(b, CONST_STR_LEN(" ")); - if (multiplier) buffer_append_string_len(b, &multiplier, 1); -- BUFFER_APPEND_STRING_CONST(b, "byte/s
\n"); -+ buffer_append_string_len(b, CONST_STR_LEN("
\n")); - - -- BUFFER_APPEND_STRING_CONST(b, "
\n
legend\n");
--	BUFFER_APPEND_STRING_CONST(b, ". = connect, C = close, E = hard error\n");
--	BUFFER_APPEND_STRING_CONST(b, "r = read, R = read-POST, W = write, h = handle-request\n");
--	BUFFER_APPEND_STRING_CONST(b, "q = request-start,  Q = request-end\n");
--	BUFFER_APPEND_STRING_CONST(b, "s = response-start, S = response-end\n");
-+	buffer_append_string_len(b, CONST_STR_LEN(
-+		"
\n
legend\n"
-+		". = connect, C = close, E = hard error\n"
-+		"r = read, R = read-POST, W = write, h = handle-request\n"
-+		"q = request-start,  Q = request-end\n"
-+		"s = response-start, S = response-end\n"));
- 
--	BUFFER_APPEND_STRING_CONST(b, "");
-+	buffer_append_string_len(b, CONST_STR_LEN(""));
- 	buffer_append_long(b, srv->conns->used);
--	BUFFER_APPEND_STRING_CONST(b, " connections\n");
-+	buffer_append_string_len(b, CONST_STR_LEN(" connections\n"));
- 
- 	for (j = 0; j < srv->conns->used; j++) {
- 		connection *c = srv->conns->ptr[j];
-@@ -457,14 +453,14 @@
- 		buffer_append_string_len(b, state, 1);
- 
- 		if (((j + 1) % 50) == 0) {
--			BUFFER_APPEND_STRING_CONST(b, "\n");
-+			buffer_append_string_len(b, CONST_STR_LEN("\n"));
- 		}
- 	}
- 
--	BUFFER_APPEND_STRING_CONST(b, "\n

\n

Connections

\n"); -+ buffer_append_string_len(b, CONST_STR_LEN("\n

\n

Connections

\n")); - -- BUFFER_APPEND_STRING_CONST(b, "\n"); -- BUFFER_APPEND_STRING_CONST(b, ""); -+ buffer_append_string_len(b, CONST_STR_LEN("
\n")); -+ buffer_append_string_len(b, CONST_STR_LEN("")); - mod_status_header_append_sort(b, p_d, "Client IP"); - mod_status_header_append_sort(b, p_d, "Read"); - mod_status_header_append_sort(b, p_d, "Written"); -@@ -473,40 +469,40 @@ - mod_status_header_append_sort(b, p_d, "Host"); - mod_status_header_append_sort(b, p_d, "URI"); - mod_status_header_append_sort(b, p_d, "File"); -- BUFFER_APPEND_STRING_CONST(b, "\n"); -+ buffer_append_string_len(b, CONST_STR_LEN("\n")); - - for (j = 0; j < srv->conns->used; j++) { - connection *c = srv->conns->ptr[j]; - -- BUFFER_APPEND_STRING_CONST(b, "\n"); -+ buffer_append_string_len(b, CONST_STR_LEN("\n")); - } - - -- BUFFER_APPEND_STRING_CONST(b, -- "
"); -+ buffer_append_string_len(b, CONST_STR_LEN("
")); - - buffer_append_string(b, inet_ntop_cache_get_ip(srv, &(c->dst_addr))); - -- BUFFER_APPEND_STRING_CONST(b, ""); -+ buffer_append_string_len(b, CONST_STR_LEN("")); - - if (con->request.content_length) { - buffer_append_long(b, c->request_content_queue->bytes_in); -- BUFFER_APPEND_STRING_CONST(b, "/"); -+ buffer_append_string_len(b, CONST_STR_LEN("/")); - buffer_append_long(b, c->request.content_length); - } else { -- BUFFER_APPEND_STRING_CONST(b, "0/0"); -+ buffer_append_string_len(b, CONST_STR_LEN("0/0")); - } - -- BUFFER_APPEND_STRING_CONST(b, ""); -+ buffer_append_string_len(b, CONST_STR_LEN("")); - - buffer_append_off_t(b, chunkqueue_written(c->write_queue)); -- BUFFER_APPEND_STRING_CONST(b, "/"); -+ buffer_append_string_len(b, CONST_STR_LEN("/")); - buffer_append_off_t(b, chunkqueue_length(c->write_queue)); - -- BUFFER_APPEND_STRING_CONST(b, ""); -+ buffer_append_string_len(b, CONST_STR_LEN("")); - - buffer_append_string(b, connection_get_state(c->state)); - -- BUFFER_APPEND_STRING_CONST(b, ""); -+ buffer_append_string_len(b, CONST_STR_LEN("")); - - buffer_append_long(b, srv->cur_ts - c->request_start); - -- BUFFER_APPEND_STRING_CONST(b, ""); -+ buffer_append_string_len(b, CONST_STR_LEN("")); - - if (buffer_is_empty(c->server_name)) { - buffer_append_string_buffer(b, c->uri.authority); -@@ -515,38 +511,38 @@ - buffer_append_string_buffer(b, c->server_name); - } - -- BUFFER_APPEND_STRING_CONST(b, ""); -+ buffer_append_string_len(b, CONST_STR_LEN("")); - - if (!buffer_is_empty(c->uri.path)) { - buffer_append_string_encoded(b, CONST_BUF_LEN(c->uri.path), ENCODING_HTML); - } - - if (!buffer_is_empty(c->uri.query)) { -- BUFFER_APPEND_STRING_CONST(b, "?"); -+ buffer_append_string_len(b, CONST_STR_LEN("?")); - buffer_append_string_encoded(b, CONST_BUF_LEN(c->uri.query), ENCODING_HTML); - } - - if (!buffer_is_empty(c->request.orig_uri)) { -- BUFFER_APPEND_STRING_CONST(b, " ("); -+ buffer_append_string_len(b, CONST_STR_LEN(" (")); - buffer_append_string_encoded(b, CONST_BUF_LEN(c->request.orig_uri), ENCODING_HTML); -- BUFFER_APPEND_STRING_CONST(b, ")"); -+ buffer_append_string_len(b, CONST_STR_LEN(")")); - } -- BUFFER_APPEND_STRING_CONST(b, ""); -+ buffer_append_string_len(b, CONST_STR_LEN("")); - - buffer_append_string_buffer(b, c->physical.path); - -- BUFFER_APPEND_STRING_CONST(b, "
\n"); -+ buffer_append_string_len(b, CONST_STR_LEN( -+ "\n")); - - -- BUFFER_APPEND_STRING_CONST(b, -+ buffer_append_string_len(b, CONST_STR_LEN( - " \n" - "\n" -- ); -+ )); - - response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html")); - -@@ -566,45 +562,45 @@ - b = chunkqueue_get_append_buffer(con->write_queue); - - /* output total number of requests */ -- BUFFER_APPEND_STRING_CONST(b, "Total Accesses: "); -+ buffer_append_string_len(b, CONST_STR_LEN("Total Accesses: ")); - avg = p->abs_requests; - snprintf(buf, sizeof(buf) - 1, "%.0f", avg); - buffer_append_string(b, buf); -- BUFFER_APPEND_STRING_CONST(b, "\n"); -+ buffer_append_string_len(b, CONST_STR_LEN("\n")); - - /* output total traffic out in kbytes */ -- BUFFER_APPEND_STRING_CONST(b, "Total kBytes: "); -+ buffer_append_string_len(b, CONST_STR_LEN("Total kBytes: ")); - avg = p->abs_traffic_out / 1024; - snprintf(buf, sizeof(buf) - 1, "%.0f", avg); - buffer_append_string(b, buf); -- BUFFER_APPEND_STRING_CONST(b, "\n"); -+ buffer_append_string_len(b, CONST_STR_LEN("\n")); - - /* output uptime */ -- BUFFER_APPEND_STRING_CONST(b, "Uptime: "); -+ buffer_append_string_len(b, CONST_STR_LEN("Uptime: ")); - ts = srv->cur_ts - srv->startup_ts; - buffer_append_long(b, ts); -- BUFFER_APPEND_STRING_CONST(b, "\n"); -+ buffer_append_string_len(b, CONST_STR_LEN("\n")); - - /* output busy servers */ -- BUFFER_APPEND_STRING_CONST(b, "BusyServers: "); -+ buffer_append_string_len(b, CONST_STR_LEN("BusyServers: ")); - buffer_append_long(b, srv->conns->used); -- BUFFER_APPEND_STRING_CONST(b, "\n"); -+ buffer_append_string_len(b, CONST_STR_LEN("\n")); - -- BUFFER_APPEND_STRING_CONST(b, "IdleServers: "); -+ buffer_append_string_len(b, CONST_STR_LEN("IdleServers: ")); - buffer_append_long(b, srv->conns->size - srv->conns->used); -- BUFFER_APPEND_STRING_CONST(b, "\n"); -+ buffer_append_string_len(b, CONST_STR_LEN("\n")); - - /* output scoreboard */ -- BUFFER_APPEND_STRING_CONST(b, "Scoreboard: "); -+ buffer_append_string_len(b, CONST_STR_LEN("Scoreboard: ")); - for (k = 0; k < srv->conns->used; k++) { - connection *c = srv->conns->ptr[k]; - const char *state = connection_get_short_state(c->state); - buffer_append_string_len(b, state, 1); - } - for (l = 0; l < srv->conns->size - srv->conns->used; l++) { -- BUFFER_APPEND_STRING_CONST(b, "_"); -+ buffer_append_string_len(b, CONST_STR_LEN("_")); - } -- BUFFER_APPEND_STRING_CONST(b, "\n"); -+ buffer_append_string_len(b, CONST_STR_LEN("\n")); - - /* set text/plain output */ - -@@ -633,9 +629,9 @@ - size_t ndx = st->sorted[i]; - - buffer_append_string_buffer(b, st->data[ndx]->key); -- buffer_append_string(b, ": "); -+ buffer_append_string_len(b, CONST_STR_LEN(": ")); - buffer_append_long(b, ((data_integer *)(st->data[ndx]))->value); -- buffer_append_string(b, "\n"); -+ buffer_append_string_len(b, CONST_STR_LEN("\n")); - } - - response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/plain")); -@@ -696,7 +692,7 @@ - - b = chunkqueue_get_append_buffer(con->write_queue); - -- BUFFER_COPY_STRING_CONST(b, -+ buffer_copy_string_len(b, CONST_STR_LEN( - "\n" - "\n" -@@ -706,7 +702,7 @@ - " \n" - " \n" - "

" PACKAGE_NAME " " PACKAGE_VERSION "

\n" -- " \n"); -+ "
\n")); - - mod_status_header_append(b, "Server-Features"); - #ifdef HAVE_PCRE_H -@@ -733,19 +729,19 @@ - if (i == 0) { - buffer_copy_string_buffer(m, pl->name); - } else { -- BUFFER_APPEND_STRING_CONST(m, "
"); -+ buffer_append_string_len(m, CONST_STR_LEN("
")); - buffer_append_string_buffer(m, pl->name); - } - } - - mod_status_row_append(b, "Loaded Modules", m->ptr); - -- BUFFER_APPEND_STRING_CONST(b, "
\n"); -+ buffer_append_string_len(b, CONST_STR_LEN(" \n")); - -- BUFFER_APPEND_STRING_CONST(b, -+ buffer_append_string_len(b, CONST_STR_LEN( - " \n" - "\n" -- ); -+ )); - - response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html")); - -@@ -796,6 +792,8 @@ - static handler_t mod_status_handler(server *srv, connection *con, void *p_d) { - plugin_data *p = p_d; - -+ if (con->mode != DIRECT) return HANDLER_GO_ON; -+ - mod_status_patch_connection(srv, con, p); - - if (!buffer_is_empty(p->conf.status_url) && -Index: src/md5.c -=================================================================== ---- src/md5.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/md5.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -52,9 +52,9 @@ - #define S43 15 - #define S44 21 - --static void MD5Transform (UINT4 [4], unsigned char [64]); -+static void MD5Transform (UINT4 [4], const unsigned char [64]); - static void Encode (unsigned char *, UINT4 *, unsigned int); --static void Decode (UINT4 *, unsigned char *, unsigned int); -+static void Decode (UINT4 *, const unsigned char *, unsigned int); - - #ifdef HAVE_MEMCPY - #define MD5_memcpy(output, input, len) memcpy((output), (input), (len)) -@@ -126,12 +126,13 @@ - operation, processing another message block, and updating the - context. - */ --void MD5_Update (context, input, inputLen) -+void MD5_Update (context, _input, inputLen) - MD5_CTX *context; /* context */ --unsigned char *input; /* input block */ -+const void *_input; /* input block */ - unsigned int inputLen; /* length of input block */ - { - unsigned int i, ndx, partLen; -+ const unsigned char *input = (const unsigned char*) _input; - - /* Compute number of bytes mod 64 */ - ndx = (unsigned int)((context->count[0] >> 3) & 0x3F); -@@ -200,7 +201,7 @@ - */ - static void MD5Transform (state, block) - UINT4 state[4]; --unsigned char block[64]; -+const unsigned char block[64]; - { - UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; - -@@ -313,7 +314,7 @@ - */ - static void Decode (output, input, len) - UINT4 *output; --unsigned char *input; -+const unsigned char *input; - unsigned int len; - { - unsigned int i, j; -Index: src/mod_compress.c -=================================================================== ---- src/mod_compress.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/mod_compress.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -102,7 +102,7 @@ - return HANDLER_GO_ON; - } - --// 0 on success, -1 for error -+/* 0 on success, -1 for error */ - int mkdir_recursive(char *dir) { - char *p = dir; - -@@ -118,13 +118,13 @@ - } - - *p++ = '/'; -- if (!*p) return 0; // Ignore trailing slash -+ if (!*p) return 0; /* Ignore trailing slash */ - } - - return (mkdir(dir, 0700) != 0) && (errno != EEXIST) ? -1 : 0; - } - --// 0 on success, -1 for error -+/* 0 on success, -1 for error */ - int mkdir_for_file(char *filename) { - char *p = filename; - -@@ -140,7 +140,7 @@ - } - - *p++ = '/'; -- if (!*p) return -1; // Unexpected trailing slash in filename -+ if (!*p) return -1; /* Unexpected trailing slash in filename */ - } - - return 0; -@@ -178,9 +178,9 @@ - } - - if (!buffer_is_empty(s->compress_cache_dir)) { -+ struct stat st; - mkdir_recursive(s->compress_cache_dir->ptr); - -- struct stat st; - if (0 != stat(s->compress_cache_dir->ptr, &st)) { - log_error_write(srv, __FILE__, __LINE__, "sbs", "can't stat compress.cache-dir", - s->compress_cache_dir, strerror(errno)); -@@ -396,13 +396,13 @@ - - switch(type) { - case HTTP_ACCEPT_ENCODING_GZIP: -- buffer_append_string(p->ofn, "-gzip-"); -+ buffer_append_string_len(p->ofn, CONST_STR_LEN("-gzip-")); - break; - case HTTP_ACCEPT_ENCODING_DEFLATE: -- buffer_append_string(p->ofn, "-deflate-"); -+ buffer_append_string_len(p->ofn, CONST_STR_LEN("-deflate-")); - break; - case HTTP_ACCEPT_ENCODING_BZIP2: -- buffer_append_string(p->ofn, "-bzip2-"); -+ buffer_append_string_len(p->ofn, CONST_STR_LEN("-bzip2-")); - break; - default: - log_error_write(srv, __FILE__, __LINE__, "sd", "unknown compression type", type); -Index: src/md5.h -=================================================================== ---- src/md5.h (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/md5.h (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -42,6 +42,6 @@ - } MD5_CTX; - - void MD5_Init (MD5_CTX *); --void MD5_Update (MD5_CTX *, unsigned char *, unsigned int); -+void MD5_Update (MD5_CTX *, const void *, unsigned int); - void MD5_Final (unsigned char [16], MD5_CTX *); - -Index: src/mod_ssi.c -=================================================================== ---- src/mod_ssi.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/mod_ssi.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -177,7 +177,7 @@ - } - - if (0 != strcasecmp(ds->key->ptr, "CONTENT-TYPE")) { -- buffer_copy_string(srv->tmp_buf, "HTTP_"); -+ buffer_copy_string_len(srv->tmp_buf, CONST_STR_LEN("HTTP_")); - srv->tmp_buf->used--; - } - -@@ -419,7 +419,7 @@ - - b = chunkqueue_get_append_buffer(con->write_queue); - if (0 == strftime(buf, sizeof(buf), p->timefmt->ptr, localtime(&t))) { -- buffer_copy_string(b, "(none)"); -+ buffer_copy_string_len(b, CONST_STR_LEN("(none)")); - } else { - buffer_copy_string(b, buf); - } -@@ -430,7 +430,7 @@ - - b = chunkqueue_get_append_buffer(con->write_queue); - if (0 == strftime(buf, sizeof(buf), p->timefmt->ptr, localtime(&t))) { -- buffer_copy_string(b, "(none)"); -+ buffer_copy_string_len(b, CONST_STR_LEN("(none)")); - } else { - buffer_copy_string(b, buf); - } -@@ -441,7 +441,7 @@ - - b = chunkqueue_get_append_buffer(con->write_queue); - if (0 == strftime(buf, sizeof(buf), p->timefmt->ptr, gmtime(&t))) { -- buffer_copy_string(b, "(none)"); -+ buffer_copy_string_len(b, CONST_STR_LEN("(none)")); - } else { - buffer_copy_string(b, buf); - } -@@ -472,7 +472,7 @@ - if (NULL != (ds = (data_string *)array_get_element(p->ssi_cgi_env, var_val))) { - buffer_copy_string_buffer(b, ds->value); - } else { -- buffer_copy_string(b, "(none)"); -+ buffer_copy_string_len(b, CONST_STR_LEN("(none)")); - } - - break; -@@ -519,7 +519,7 @@ - if (file_path) { - /* current doc-root */ - if (NULL == (sl = strrchr(con->physical.path->ptr, '/'))) { -- buffer_copy_string(p->stat_fn, "/"); -+ buffer_copy_string_len(p->stat_fn, CONST_STR_LEN("/")); - } else { - buffer_copy_string_len(p->stat_fn, con->physical.path->ptr, sl - con->physical.path->ptr + 1); - } -@@ -573,7 +573,7 @@ - case SSI_FLASTMOD: - b = chunkqueue_get_append_buffer(con->write_queue); - if (0 == strftime(buf, sizeof(buf), p->timefmt->ptr, localtime(&t))) { -- buffer_copy_string(b, "(none)"); -+ buffer_copy_string_len(b, CONST_STR_LEN("(none)")); - } else { - buffer_copy_string(b, buf); - } -@@ -656,17 +656,17 @@ - if (p->if_is_false) break; - - b = chunkqueue_get_append_buffer(con->write_queue); -- buffer_copy_string(b, "
");
-+		buffer_copy_string_len(b, CONST_STR_LEN("
"));
- 		for (i = 0; i < p->ssi_vars->used; i++) {
- 			data_string *ds = (data_string *)p->ssi_vars->data[p->ssi_vars->sorted[i]];
- 
- 			buffer_append_string_buffer(b, ds->key);
--			buffer_append_string(b, ": ");
-+			buffer_append_string_len(b, CONST_STR_LEN(": "));
- 			buffer_append_string_buffer(b, ds->value);
--			buffer_append_string(b, "
"); -+ buffer_append_string_len(b, CONST_STR_LEN("
")); - - } -- buffer_append_string(b, "
"); -+ buffer_append_string_len(b, CONST_STR_LEN("
")); - - break; - case SSI_EXEC: { -@@ -924,7 +924,7 @@ - - array_reset(p->ssi_vars); - array_reset(p->ssi_cgi_env); -- buffer_copy_string(p->timefmt, "%a, %d %b %Y %H:%M:%S %Z"); -+ buffer_copy_string_len(p->timefmt, CONST_STR_LEN("%a, %d %b %Y %H:%M:%S %Z")); - p->sizefmt = 0; - build_ssi_cgi_vars(srv, con, p); - p->if_is_false = 0; -@@ -1027,6 +1027,7 @@ - - con->file_started = 1; - con->file_finished = 1; -+ con->mode = p->id; - - response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html")); - -@@ -1094,6 +1095,8 @@ - plugin_data *p = p_d; - size_t k; - -+ if (con->mode != DIRECT) return HANDLER_GO_ON; -+ - if (con->physical.path->used == 0) return HANDLER_GO_ON; - - mod_ssi_patch_connection(srv, con, p); -@@ -1109,6 +1112,7 @@ - if (mod_ssi_handle_request(srv, con, p)) { - /* on error */ - con->http_status = 500; -+ con->mode = DIRECT; - } - - return HANDLER_FINISHED; -Index: src/spawn-fcgi.c -=================================================================== ---- src/spawn-fcgi.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/spawn-fcgi.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -37,9 +37,9 @@ - #endif - - #ifdef HAVE_SYS_UN_H --int fcgi_spawn_connection(char *appPath, char **appArgv, char *addr, unsigned short port, const char *unixsocket, int child_count, int pid_fd, int nofork) { -+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; -+ int socket_type, status, rc = 0; - struct timeval tv = { 0, 100 * 1000 }; - - struct sockaddr_un fcgi_addr_un; -@@ -48,9 +48,6 @@ - - socklen_t servlen; - -- pid_t child; -- int val; -- - if (child_count < 2) { - child_count = 5; - } -@@ -74,25 +71,6 @@ - #endif - socket_type = AF_UNIX; - fcgi_addr = (struct sockaddr *) &fcgi_addr_un; -- -- /* check if some backend is listening on the socket -- * as if we delete the socket-file and rebind there will be no "socket already in use" error -- */ -- 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)) { -- fprintf(stderr, "%s.%d: socket is already used, can't spawn\n", -- __FILE__, __LINE__); -- return -1; -- } -- -- /* cleanup previous socket if it exists */ -- unlink(unixsocket); -- close(fcgi_fd); - } else { - fcgi_addr_in.sin_family = AF_INET; - if (addr != NULL) { -@@ -107,133 +85,176 @@ - fcgi_addr = (struct sockaddr *) &fcgi_addr_in; - } - -- /* open 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; -- } -+ if (-1 == connect(fcgi_fd, fcgi_addr, servlen)) { -+ /* server is not up, spawn in */ -+ pid_t child; -+ int val; - -- /* 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 (unixsocket) unlink(unixsocket); - -- if (-1 == listen(fcgi_fd, 1024)) { -- fprintf(stderr, "%s.%d: fd = -1\n", -- __FILE__, __LINE__); -- return -1; -- } -+ close(fcgi_fd); - -- if (!nofork) { -- child = fork(); -- } else { -- child = 0; -- } -+ /* reopen socket */ -+ if (-1 == (fcgi_fd = socket(socket_type, SOCK_STREAM, 0))) { -+ fprintf(stderr, "%s.%d\n", -+ __FILE__, __LINE__); -+ return -1; -+ } - -- switch (child) { -- case 0: { -- char cgi_childs[64]; -+ val = 1; -+ if (setsockopt(fcgi_fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) { -+ fprintf(stderr, "%s.%d\n", -+ __FILE__, __LINE__); -+ return -1; -+ } - -- int i = 0; -- -- /* 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); -+ /* create socket */ -+ if (-1 == bind(fcgi_fd, fcgi_addr, servlen)) { -+ fprintf(stderr, "%s.%d: bind failed: %s\n", -+ __FILE__, __LINE__, -+ strerror(errno)); -+ return -1; - } - -- /* we don't need the client socket */ -- for (i = 3; i < 256; i++) { -- close(i); -+ if (-1 == listen(fcgi_fd, 1024)) { -+ fprintf(stderr, "%s.%d: fd = -1\n", -+ __FILE__, __LINE__); -+ return -1; - } - -- /* create environment */ -+ while (fork_count-- > 0) { - -- putenv(cgi_childs); -+ if (!nofork) { -+ child = fork(); -+ } else { -+ child = 0; -+ } - -- /* fork and replace shell */ -- if (appArgv) { -- execv(appArgv[0], appArgv); -+ switch (child) { -+ case 0: { -+ char cgi_childs[64]; -+ int max_fd = 0; - -- } else { -- char *b = malloc(strlen("exec ") + strlen(appPath) + 1); -- strcpy(b, "exec "); -- strcat(b, appPath); -+ int i = 0; - -- /* exec the cgi */ -- execl("/bin/sh", "sh", "-c", b, (char *)NULL); -- } -+ /* loose control terminal */ -+ setsid(); - -- exit(errno); -+ /* is safe as we limit to 256 childs */ -+ sprintf(cgi_childs, "PHP_FCGI_CHILDREN=%d", child_count); - -- break; -- } -- case -1: -- /* error */ -- break; -- default: -- /* father */ -+ if(fcgi_fd != FCGI_LISTENSOCK_FILENO) { -+ close(FCGI_LISTENSOCK_FILENO); -+ dup2(fcgi_fd, FCGI_LISTENSOCK_FILENO); -+ close(fcgi_fd); -+ } - -- /* wait */ -- select(0, NULL, NULL, NULL, &tv); -+ max_fd = open("/dev/null", O_RDWR); -+ close(STDERR_FILENO); -+ dup2(max_fd, STDERR_FILENO); -+ close(max_fd); - -- switch (waitpid(child, &status, WNOHANG)) { -- case 0: -- fprintf(stderr, "%s.%d: child spawned successfully: PID: %d\n", -- __FILE__, __LINE__, -- child); -+ max_fd = open("/dev/null", O_RDWR); -+ close(STDOUT_FILENO); -+ dup2(max_fd, STDOUT_FILENO); -+ close(max_fd); - -- /* write pid file */ -- if (pid_fd != -1) { -- /* assume a 32bit pid_t */ -- char pidbuf[12]; -+ /* we don't need the client socket */ -+ for (i = 3; i < max_fd; i++) { -+ if (i != FCGI_LISTENSOCK_FILENO) close(i); -+ } - -- snprintf(pidbuf, sizeof(pidbuf) - 1, "%d", child); -+ /* create environment */ - -- write(pid_fd, pidbuf, strlen(pidbuf)); -- close(pid_fd); -- pid_fd = -1; -+ 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 */ - -- break; -- case -1: -- break; -- default: -- if (WIFEXITED(status)) { -- fprintf(stderr, "%s.%d: child exited with: %d, %s\n", -- __FILE__, __LINE__, -- WEXITSTATUS(status), strerror(WEXITSTATUS(status))); -- } else if (WIFSIGNALED(status)) { -- fprintf(stderr, "%s.%d: child signaled: %d\n", -- __FILE__, __LINE__, -- WTERMSIG(status)); -- } else { -- fprintf(stderr, "%s.%d: child died somehow: %d\n", -- __FILE__, __LINE__, -- status); -+ /* 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; - } - } -- -- 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 0; -+ return rc; - } - - -@@ -256,6 +277,7 @@ - " -p bind to tcp-port\n" \ - " -s bind to unix-domain socket\n" \ - " -C (PHP only) numbers of childs to spawn (default 5)\n" \ -+" -F numbers of childs to fork (default 1)\n" \ - " -P name of PID-file for spawed process\n" \ - " -n no fork (for daemontools)\n" \ - " -v show version\n" \ -@@ -276,20 +298,21 @@ - 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; -- const size_t sun_path_len = sizeof(un.sun_path); - - i_am_root = (getuid() == 0); - -- while(-1 != (o = getopt(argc, argv, "c:f:g:hna:p:u:vC:s:P:"))) { -+ 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; -@@ -321,7 +344,7 @@ - return -1; - } - -- if (unixsocket && strlen(unixsocket) > sun_path_len - 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"); -@@ -416,18 +439,15 @@ - "I will not set gid to 0\n"); - return -1; - } -- } - -- /* -- * Change group before chroot, when we have access -- * to /etc/group -- */ -- if (groupname) { -+ /* do the change before we do the chroot() */ - setgid(grp->gr_gid); -- setgroups(0, NULL); -+ setgroups(0, NULL); -+ - if (username) { - initgroups(username, grp->gr_gid); - } -+ - } - - if (changeroot) { -@@ -451,7 +471,7 @@ - } - } - -- return fcgi_spawn_connection(fcgi_app, fcgi_app_argv, addr, port, unixsocket, child_count, pid_fd, nofork); -+ return fcgi_spawn_connection(fcgi_app, fcgi_app_argv, addr, port, unixsocket, fork_count, child_count, pid_fd, nofork); - } - #else - int main() { -Index: src/mod_auth.c -=================================================================== ---- src/mod_auth.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/mod_auth.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -150,13 +150,15 @@ - PATCH(auth_ldap_hostname); - #ifdef USE_LDAP - PATCH(ldap); -- PATCH(ldap_filter_pre); -- PATCH(ldap_filter_post); - #endif - } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.base-dn"))) { - PATCH(auth_ldap_basedn); - } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.filter"))) { - PATCH(auth_ldap_filter); -+#ifdef USE_LDAP -+ PATCH(ldap_filter_pre); -+ PATCH(ldap_filter_post); -+#endif - } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.ca-file"))) { - PATCH(auth_ldap_cafile); - } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.starttls"))) { -@@ -248,6 +250,7 @@ - if (0 == strcmp(method->value->ptr, "digest")) { - if (-1 == (auth_satisfied = http_auth_digest_check(srv, con, p, req, con->uri.path, auth_realm+1))) { - con->http_status = 400; -+ con->mode = DIRECT; - - /* a field was missing */ - -@@ -268,22 +271,23 @@ - realm = (data_string *)array_get_element(req, "realm"); - - con->http_status = 401; -+ con->mode = DIRECT; - - if (0 == strcmp(method->value->ptr, "basic")) { -- buffer_copy_string(p->tmp_buf, "Basic realm=\""); -+ buffer_copy_string_len(p->tmp_buf, CONST_STR_LEN("Basic realm=\"")); - buffer_append_string_buffer(p->tmp_buf, realm->value); -- buffer_append_string(p->tmp_buf, "\""); -+ buffer_append_string_len(p->tmp_buf, CONST_STR_LEN("\"")); - - response_header_insert(srv, con, CONST_STR_LEN("WWW-Authenticate"), CONST_BUF_LEN(p->tmp_buf)); - } else if (0 == strcmp(method->value->ptr, "digest")) { - char hh[33]; - http_auth_digest_generate_nonce(srv, p, srv->tmp_buf, hh); - -- buffer_copy_string(p->tmp_buf, "Digest realm=\""); -+ buffer_copy_string_len(p->tmp_buf, CONST_STR_LEN("Digest realm=\"")); - buffer_append_string_buffer(p->tmp_buf, realm->value); -- buffer_append_string(p->tmp_buf, "\", nonce=\""); -+ buffer_append_string_len(p->tmp_buf, CONST_STR_LEN("\", nonce=\"")); - buffer_append_string(p->tmp_buf, hh); -- buffer_append_string(p->tmp_buf, "\", qop=\"auth\""); -+ buffer_append_string_len(p->tmp_buf, CONST_STR_LEN("\", qop=\"auth\"")); - - response_header_insert(srv, con, CONST_STR_LEN("WWW-Authenticate"), CONST_BUF_LEN(p->tmp_buf)); - } else { -@@ -393,6 +397,23 @@ - } - } - -+#ifdef USE_LDAP -+ if (s->auth_ldap_filter->used) { -+ char *dollar; -+ -+ /* parse filter */ -+ -+ if (NULL == (dollar = strchr(s->auth_ldap_filter->ptr, '$'))) { -+ log_error_write(srv, __FILE__, __LINE__, "s", "ldap: auth.backend.ldap.filter is missing a replace-operator '$'"); -+ -+ return HANDLER_ERROR; -+ } -+ -+ buffer_copy_string_len(s->ldap_filter_pre, s->auth_ldap_filter->ptr, dollar - s->auth_ldap_filter->ptr); -+ buffer_copy_string(s->ldap_filter_post, dollar+1); -+ } -+#endif -+ - /* no auth.require for this section */ - if (NULL == (da = (data_array *)array_get_element(ca, "auth.require"))) continue; - -@@ -479,21 +500,21 @@ - - ds = data_string_init(); - -- buffer_copy_string(ds->key, "method"); -+ buffer_copy_string_len(ds->key, CONST_STR_LEN("method")); - buffer_copy_string(ds->value, method); - - array_insert_unique(a->value, (data_unset *)ds); - - ds = data_string_init(); - -- buffer_copy_string(ds->key, "realm"); -+ buffer_copy_string_len(ds->key, CONST_STR_LEN("realm")); - buffer_copy_string(ds->value, realm); - - array_insert_unique(a->value, (data_unset *)ds); - - ds = data_string_init(); - -- buffer_copy_string(ds->key, "require"); -+ buffer_copy_string_len(ds->key, CONST_STR_LEN("require")); - buffer_copy_string(ds->value, require); - - array_insert_unique(a->value, (data_unset *)ds); -@@ -507,97 +528,83 @@ - handler_t ret = auth_ldap_init(srv, s); - if (ret == HANDLER_ERROR) - return (ret); -- break; -+ break; - } -- default: -- break; -- } -- } -+ default: -+ break; -+ } -+ } - -- return HANDLER_GO_ON; -+ return HANDLER_GO_ON; - } - - handler_t auth_ldap_init(server *srv, mod_auth_plugin_config *s) { - #ifdef USE_LDAP -- int ret; -+ int ret; - #if 0 -- if (s->auth_ldap_basedn->used == 0) { -- log_error_write(srv, __FILE__, __LINE__, "s", "ldap: auth.backend.ldap.base-dn has to be set"); -+ if (s->auth_ldap_basedn->used == 0) { -+ log_error_write(srv, __FILE__, __LINE__, "s", "ldap: auth.backend.ldap.base-dn has to be set"); - -- return HANDLER_ERROR; -- } -+ return HANDLER_ERROR; -+ } - #endif - -- if (s->auth_ldap_filter->used) { -- char *dollar; -+ if (s->auth_ldap_hostname->used) { -+ if (NULL == (s->ldap = ldap_init(s->auth_ldap_hostname->ptr, LDAP_PORT))) { -+ log_error_write(srv, __FILE__, __LINE__, "ss", "ldap ...", strerror(errno)); - -- /* parse filter */ -+ return HANDLER_ERROR; -+ } - -- if (NULL == (dollar = strchr(s->auth_ldap_filter->ptr, '$'))) { -- log_error_write(srv, __FILE__, __LINE__, "s", "ldap: auth.backend.ldap.filter is missing a replace-operator '$'"); -+ ret = LDAP_VERSION3; -+ if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(s->ldap, LDAP_OPT_PROTOCOL_VERSION, &ret))) { -+ log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret)); - -- return HANDLER_ERROR; -- } -+ return HANDLER_ERROR; -+ } - -- buffer_copy_string_len(s->ldap_filter_pre, s->auth_ldap_filter->ptr, dollar - s->auth_ldap_filter->ptr); -- buffer_copy_string(s->ldap_filter_post, dollar+1); -- } -+ if (s->auth_ldap_starttls) { -+ /* if no CA file is given, it is ok, as we will use encryption -+ * if the server requires a CAfile it will tell us */ -+ if (!buffer_is_empty(s->auth_ldap_cafile)) { -+ if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE, -+ s->auth_ldap_cafile->ptr))) { -+ log_error_write(srv, __FILE__, __LINE__, "ss", -+ "Loading CA certificate failed:", ldap_err2string(ret)); - -- if (s->auth_ldap_hostname->used) { -- if (NULL == (s->ldap = ldap_init(s->auth_ldap_hostname->ptr, LDAP_PORT))) { -- log_error_write(srv, __FILE__, __LINE__, "ss", "ldap ...", strerror(errno)); -- - return HANDLER_ERROR; - } -+ } - -- ret = LDAP_VERSION3; -- if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(s->ldap, LDAP_OPT_PROTOCOL_VERSION, &ret))) { -- log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret)); -+ if (LDAP_OPT_SUCCESS != (ret = ldap_start_tls_s(s->ldap, NULL, NULL))) { -+ log_error_write(srv, __FILE__, __LINE__, "ss", "ldap startTLS failed:", ldap_err2string(ret)); - -- return HANDLER_ERROR; -- } -+ return HANDLER_ERROR; -+ } -+ } - -- if (s->auth_ldap_starttls) { -- /* if no CA file is given, it is ok, as we will use encryption -- * if the server requires a CAfile it will tell us */ -- if (!buffer_is_empty(s->auth_ldap_cafile)) { -- if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE, -- s->auth_ldap_cafile->ptr))) { -- log_error_write(srv, __FILE__, __LINE__, "ss", -- "Loading CA certificate failed:", ldap_err2string(ret)); - -- return HANDLER_ERROR; -- } -- } -+ /* 1. */ -+ if (s->auth_ldap_binddn->used) { -+ if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(s->ldap, s->auth_ldap_binddn->ptr, s->auth_ldap_bindpw->ptr))) { -+ log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret)); - -- if (LDAP_OPT_SUCCESS != (ret = ldap_start_tls_s(s->ldap, NULL, NULL))) { -- log_error_write(srv, __FILE__, __LINE__, "ss", "ldap startTLS failed:", ldap_err2string(ret)); -+ return HANDLER_ERROR; -+ } -+ } else { -+ if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(s->ldap, NULL, NULL))) { -+ log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret)); - -- return HANDLER_ERROR; -- } -- } -- -- -- /* 1. */ -- if (s->auth_ldap_binddn->used) { -- if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(s->ldap, s->auth_ldap_binddn->ptr, s->auth_ldap_bindpw->ptr))) { -- log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret)); -- -- return HANDLER_ERROR; -- } -- } else { -- if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(s->ldap, NULL, NULL))) { -- log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret)); -- -- return HANDLER_ERROR; -- } -- } -+ return HANDLER_ERROR; - } -+ } -+ } -+ return HANDLER_GO_ON; - #else -- log_error_write(srv, __FILE__, __LINE__, "s", "no ldap support available"); -- return HANDLER_ERROR; -+ UNUSED(s); -+ log_error_write(srv, __FILE__, __LINE__, "s", "no ldap support available"); -+ return HANDLER_ERROR; - #endif -- return HANDLER_GO_ON; - } - - int mod_auth_plugin_init(plugin *p) { -Index: src/data_string.c -=================================================================== ---- src/data_string.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/data_string.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -37,7 +37,7 @@ - data_string *ds_src = (data_string *)src; - - if (ds_dst->value->used) { -- buffer_append_string(ds_dst->value, ", "); -+ buffer_append_string_len(ds_dst->value, CONST_STR_LEN(", ")); - buffer_append_string_buffer(ds_dst->value, ds_src->value); - } else { - buffer_copy_string_buffer(ds_dst->value, ds_src->value); -@@ -53,9 +53,9 @@ - data_string *ds_src = (data_string *)src; - - if (ds_dst->value->used) { -- buffer_append_string(ds_dst->value, "\r\n"); -+ buffer_append_string_len(ds_dst->value, CONST_STR_LEN("\r\n")); - buffer_append_string_buffer(ds_dst->value, ds_dst->key); -- buffer_append_string(ds_dst->value, ": "); -+ buffer_append_string_len(ds_dst->value, CONST_STR_LEN(": ")); - buffer_append_string_buffer(ds_dst->value, ds_src->value); - } else { - buffer_copy_string_buffer(ds_dst->value, ds_src->value); -Index: src/http-header-glue.c -=================================================================== ---- src/http-header-glue.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/http-header-glue.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -109,9 +109,9 @@ - o = buffer_init(); - - if (con->conf.is_ssl) { -- buffer_copy_string(o, "https://"); -+ buffer_copy_string_len(o, CONST_STR_LEN("https://")); - } else { -- buffer_copy_string(o, "http://"); -+ buffer_copy_string_len(o, CONST_STR_LEN("http://")); - } - if (con->uri.authority->used) { - buffer_append_string_buffer(o, con->uri.authority); -@@ -180,14 +180,14 @@ - - if (!((con->conf.is_ssl == 0 && srv->srvconf.port == 80) || - (con->conf.is_ssl == 1 && srv->srvconf.port == 443))) { -- buffer_append_string(o, ":"); -+ buffer_append_string_len(o, CONST_STR_LEN(":")); - buffer_append_long(o, srv->srvconf.port); - } - } - buffer_append_string_buffer(o, con->uri.path); -- buffer_append_string(o, "/"); -+ buffer_append_string_len(o, CONST_STR_LEN("/")); - if (!buffer_is_empty(con->uri.query)) { -- buffer_append_string(o, "?"); -+ buffer_append_string_len(o, CONST_STR_LEN("?")); - buffer_append_string_buffer(o, con->uri.query); - } - -@@ -272,6 +272,7 @@ - con->request.http_if_modified_since, used_len, sizeof(buf) - 1); - - con->http_status = 412; -+ con->mode = DIRECT; - return HANDLER_FINISHED; - } - -@@ -281,6 +282,7 @@ - - if (NULL == strptime(buf, "%a, %d %b %Y %H:%M:%S GMT", &tm)) { - con->http_status = 412; -+ con->mode = DIRECT; - return HANDLER_FINISHED; - } - t_header = mktime(&tm); -@@ -299,6 +301,7 @@ - } - } else { - con->http_status = 412; -+ con->mode = DIRECT; - return HANDLER_FINISHED; - } - } -Index: src/mod_evasive.c -=================================================================== ---- src/mod_evasive.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/mod_evasive.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -138,24 +138,47 @@ - /* no limit set, nothing to block */ - if (p->conf.max_conns == 0) return HANDLER_GO_ON; - -+ switch (con->dst_addr.plain.sa_family) { -+ case AF_INET: -+#ifdef HAVE_IPV6 -+ case AF_INET6: -+#endif -+ break; -+ default: // Address family not supported -+ return HANDLER_GO_ON; -+ }; -+ - for (j = 0; j < srv->conns->used; j++) { - connection *c = srv->conns->ptr[j]; - - /* check if other connections are already actively serving data for the same IP - * we can only ban connections which are already behind the 'read request' state - * */ -- if (c->dst_addr.ipv4.sin_addr.s_addr == con->dst_addr.ipv4.sin_addr.s_addr && -- c->state > CON_STATE_REQUEST_END) { -- conns_by_ip++; -+ if (c->dst_addr.plain.sa_family != con->dst_addr.plain.sa_family) continue; -+ if (c->state <= CON_STATE_REQUEST_END) continue; - -- if (conns_by_ip > p->conf.max_conns) { -- log_error_write(srv, __FILE__, __LINE__, "ss", -- inet_ntop_cache_get_ip(srv, &(con->dst_addr)), -- "turned away. Too many connections."); -+ switch (con->dst_addr.plain.sa_family) { -+ case AF_INET: -+ if (c->dst_addr.ipv4.sin_addr.s_addr != con->dst_addr.ipv4.sin_addr.s_addr) continue; -+ break; -+#ifdef HAVE_IPV6 -+ case AF_INET6: -+ if (0 != memcmp(c->dst_addr.ipv6.sin6_addr.s6_addr, con->dst_addr.ipv6.sin6_addr.s6_addr, 16)) continue; -+ break; -+#endif -+ default: /* Address family not supported, should never be reached */ -+ continue; -+ }; -+ conns_by_ip++; - -- con->http_status = 403; -- return HANDLER_FINISHED; -- } -+ if (conns_by_ip > p->conf.max_conns) { -+ log_error_write(srv, __FILE__, __LINE__, "ss", -+ inet_ntop_cache_get_ip(srv, &(con->dst_addr)), -+ "turned away. Too many connections."); -+ -+ con->http_status = 403; -+ con->mode = DIRECT; -+ return HANDLER_FINISHED; - } - } - -Index: src/mod_indexfile.c -=================================================================== ---- src/mod_indexfile.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/mod_indexfile.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -140,6 +140,8 @@ - size_t k; - stat_cache_entry *sce = NULL; - -+ if (con->mode != DIRECT) return HANDLER_GO_ON; -+ - if (con->uri.path->used == 0) return HANDLER_GO_ON; - if (con->uri.path->ptr[con->uri.path->used - 2] != '/') return HANDLER_GO_ON; - -Index: src/mod_uploadprogress.c -=================================================================== -Index: src/mod_fastcgi.c -=================================================================== ---- src/mod_fastcgi.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/mod_fastcgi.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -236,6 +236,16 @@ - unsigned short break_scriptfilename_for_php; - - /* -+ * workaround for program when prefix="/" -+ * -+ * rule to build PATH_INFO is hardcoded for when check_local is disabled -+ * enable this option to use the workaround -+ * -+ */ -+ -+ unsigned short fix_root_path_name; -+ -+ /* - * If the backend includes X-LIGHTTPD-send-file in the response - * we use the value as filename and ignore the content. - * -@@ -380,10 +390,10 @@ - static handler_t fcgi_handle_fdevent(void *s, void *ctx, int revents); - - int fastcgi_status_copy_procname(buffer *b, fcgi_extension_host *host, fcgi_proc *proc) { -- buffer_copy_string(b, "fastcgi.backend."); -+ buffer_copy_string_len(b, CONST_STR_LEN("fastcgi.backend.")); - buffer_append_string_buffer(b, host->id); - if (proc) { -- buffer_append_string(b, "."); -+ buffer_append_string_len(b, CONST_STR_LEN(".")); - buffer_append_long(b, proc->id); - } - -@@ -393,7 +403,7 @@ - int fastcgi_status_init(server *srv, buffer *b, fcgi_extension_host *host, fcgi_proc *proc) { - #define CLEAN(x) \ - fastcgi_status_copy_procname(b, host, proc); \ -- buffer_append_string(b, x); \ -+ buffer_append_string_len(b, CONST_STR_LEN(x)); \ - status_counter_set(srv, CONST_BUF_LEN(b), 0); - - CLEAN(".disabled"); -@@ -406,7 +416,7 @@ - - #define CLEAN(x) \ - fastcgi_status_copy_procname(b, host, NULL); \ -- buffer_append_string(b, x); \ -+ buffer_append_string_len(b, CONST_STR_LEN(x)); \ - status_counter_set(srv, CONST_BUF_LEN(b), 0); - - CLEAN(".load"); -@@ -693,6 +703,7 @@ - - static int env_add(char_array *env, const char *key, size_t key_len, const char *val, size_t val_len) { - char *dst; -+ size_t i; - - if (!key || !val) return -1; - -@@ -702,6 +713,15 @@ - /* add the \0 from the value */ - memcpy(dst + key_len + 1, val, val_len + 1); - -+ for (i = 0; i < env->used; i++) { -+ if (0 == strncmp(dst, env->ptr[i], key_len + 1)) { -+ /* don't care about free as we are in a forked child which is going to exec(...) */ -+ /* free(env->ptr[i]); */ -+ env->ptr[i] = dst; -+ return 0; -+ } -+ } -+ - if (env->size == 0) { - env->size = 16; - env->ptr = malloc(env->size * sizeof(*env->ptr)); -@@ -811,7 +831,7 @@ - socket_type = AF_UNIX; - fcgi_addr = (struct sockaddr *) &fcgi_addr_un; - -- buffer_copy_string(proc->connection_name, "unix:"); -+ buffer_copy_string_len(proc->connection_name, CONST_STR_LEN("unix:")); - buffer_append_string_buffer(proc->connection_name, proc->unixsocket); - - #else -@@ -857,13 +877,13 @@ - socket_type = AF_INET; - fcgi_addr = (struct sockaddr *) &fcgi_addr_in; - -- buffer_copy_string(proc->connection_name, "tcp:"); -+ buffer_copy_string_len(proc->connection_name, CONST_STR_LEN("tcp:")); - if (!buffer_is_empty(host->host)) { - buffer_append_string_buffer(proc->connection_name, host->host); - } else { -- buffer_append_string(proc->connection_name, "localhost"); -+ buffer_append_string_len(proc->connection_name, CONST_STR_LEN("localhost")); - } -- buffer_append_string(proc->connection_name, ":"); -+ buffer_append_string_len(proc->connection_name, CONST_STR_LEN(":")); - buffer_append_long(proc->connection_name, proc->port); - } - -@@ -937,6 +957,8 @@ - close(fcgi_fd); - } - -+ openDevNull(STDERR_FILENO); -+ - /* we don't need the client socket */ - for (i = 3; i < 256; i++) { - close(i); -@@ -1000,8 +1022,8 @@ - /* exec the cgi */ - execve(arg.ptr[0], arg.ptr, env.ptr); - -- log_error_write(srv, __FILE__, __LINE__, "sbs", -- "execve failed for:", host->bin_path, strerror(errno)); -+ /* log_error_write(srv, __FILE__, __LINE__, "sbs", -+ "execve failed for:", host->bin_path, strerror(errno)); */ - - exit(errno); - -@@ -1193,6 +1215,7 @@ - { "allow-x-send-file", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 15 */ - { "strip-request-uri", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 16 */ - { "kill-signal", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 17 */ -+ { "fix-root-scriptname", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 18 */ - - { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } - }; -@@ -1220,6 +1243,7 @@ - host->break_scriptfilename_for_php = 0; - host->allow_xsendfile = 0; /* handle X-LIGHTTPD-send-file */ - host->kill_signal = SIGTERM; -+ host->fix_root_path_name = 0; - - fcv[0].destination = host->host; - fcv[1].destination = host->docroot; -@@ -1241,6 +1265,7 @@ - fcv[15].destination = &(host->allow_xsendfile); - fcv[16].destination = host->strip_request_uri; - fcv[17].destination = &(host->kill_signal); -+ fcv[18].destination = &(host->fix_root_path_name); - - if (0 != config_insert_values_internal(srv, da_host->value, fcv)) { - return HANDLER_ERROR; -@@ -1324,7 +1349,7 @@ - proc->port = host->port + pno; - } else { - buffer_copy_string_buffer(proc->unixsocket, host->unixsocket); -- buffer_append_string(proc->unixsocket, "-"); -+ buffer_append_string_len(proc->unixsocket, CONST_STR_LEN("-")); - buffer_append_long(proc->unixsocket, pno); - } - -@@ -1482,7 +1507,7 @@ - status_counter_dec(srv, CONST_STR_LEN("fastcgi.active-requests")); - - fastcgi_status_copy_procname(p->statuskey, hctx->host, hctx->proc); -- buffer_append_string(p->statuskey, ".load"); -+ buffer_append_string_len(p->statuskey, CONST_STR_LEN(".load")); - - status_counter_set(srv, CONST_BUF_LEN(p->statuskey), hctx->proc->load); - -@@ -1683,7 +1708,7 @@ - - if (buffer_is_empty(proc->connection_name)) { - /* on remote spawing we have to set the connection-name now */ -- buffer_copy_string(proc->connection_name, "unix:"); -+ buffer_copy_string_len(proc->connection_name, CONST_STR_LEN("unix:")); - buffer_append_string_buffer(proc->connection_name, proc->unixsocket); - } - #else -@@ -1709,13 +1734,13 @@ - - if (buffer_is_empty(proc->connection_name)) { - /* on remote spawing we have to set the connection-name now */ -- buffer_copy_string(proc->connection_name, "tcp:"); -+ buffer_copy_string_len(proc->connection_name, CONST_STR_LEN("tcp:")); - if (!buffer_is_empty(host->host)) { - buffer_append_string_buffer(proc->connection_name, host->host); - } else { -- buffer_append_string(proc->connection_name, "localhost"); -+ buffer_append_string_len(proc->connection_name, CONST_STR_LEN("localhost")); - } -- buffer_append_string(proc->connection_name, ":"); -+ buffer_append_string_len(proc->connection_name, CONST_STR_LEN(":")); - buffer_append_long(proc->connection_name, proc->port); - } - } -@@ -1771,7 +1796,7 @@ - buffer_reset(srv->tmp_buf); - - if (0 != strcasecmp(ds->key->ptr, "CONTENT-TYPE")) { -- BUFFER_COPY_STRING_CONST(srv->tmp_buf, "HTTP_"); -+ buffer_copy_string_len(srv->tmp_buf, CONST_STR_LEN("HTTP_")); - srv->tmp_buf->used--; - } - -@@ -2026,7 +2051,7 @@ - */ - if ('/' != host->strip_request_uri->ptr[host->strip_request_uri->used - 2]) { - /* fix the user-input to have / as last char */ -- buffer_append_string(host->strip_request_uri, "/"); -+ buffer_append_string_len(host->strip_request_uri, CONST_STR_LEN("/")); - } - - if (con->request.orig_uri->used >= host->strip_request_uri->used && -@@ -2094,12 +2119,12 @@ - hctx->wb->bytes_in += sizeof(header); - - if (p->conf.debug > 10) { -- fprintf(stderr, "%s.%d: tosend: %lld / %lld\n", __FILE__, __LINE__, offset, req_cq->bytes_in); -+ log_error_write(srv, __FILE__, __LINE__, "soso", "tosend:", offset, "/", req_cq->bytes_in); - } - - for (written = 0; written != weWant; ) { - if (p->conf.debug > 10) { -- fprintf(stderr, "%s.%d: chunk: %lld / %lld\n", __FILE__, __LINE__, written, weWant); -+ log_error_write(srv, __FILE__, __LINE__, "soso", "chunk:", written, "/", weWant); - } - - switch (req_c->type) { -@@ -2109,12 +2134,10 @@ - if (weHave > weWant - written) weHave = weWant - written; - - if (p->conf.debug > 10) { -- fprintf(stderr, "%s.%d: sending %lld bytes from (%lld / %lld) %s\n", -- __FILE__, __LINE__, -- weHave, -- req_c->offset, -- req_c->file.length, -- req_c->file.name->ptr); -+ log_error_write(srv, __FILE__, __LINE__, "soSosOsb", -+ "sending", weHave, "bytes from (", -+ req_c->offset, "/", req_c->file.length, ")", -+ req_c->file.name); - } - - assert(weHave != 0); -@@ -2143,7 +2166,7 @@ - chunk *c; - - if (p->conf.debug > 10) { -- fprintf(stderr, "%s.%d: next chunk\n", __FILE__, __LINE__); -+ log_error_write(srv, __FILE__, __LINE__, "s", "next chunk"); - } - c = hctx->wb->last; - -@@ -2173,7 +2196,7 @@ - - hctx->wb->bytes_in += weHave; - -- if (req_c->offset == req_c->mem->used - 1) { -+ if (req_c->offset == (off_t) req_c->mem->used - 1) { - chunkqueue_remove_finished_chunks(req_cq); - - req_c = req_cq->first; -@@ -2368,7 +2391,7 @@ - offset = sizeof(*header); - - /* ->b should only be the content */ -- buffer_copy_string(packet->b, ""); /* used == 1 */ -+ buffer_copy_string_len(packet->b, CONST_STR_LEN("")); /* used == 1 */ - - if (packet->len) { - /* copy the content */ -@@ -2544,7 +2567,10 @@ - stat_cache_entry *sce; - - if (HANDLER_ERROR != stat_cache_get_entry(srv, con, ds->value, &sce)) { -- data_string *dcls = data_string_init(); -+ data_string *dcls; -+ if (NULL == (dcls = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) { -+ dcls = data_response_init(); -+ } - /* found */ - http_chunk_append_file(srv, con, ds->value, 0, sce->st.st_size); - hctx->send_content_body = 0; /* ignore the content */ -@@ -2663,30 +2689,48 @@ - - /* the child should not terminate at all */ - -- switch(waitpid(proc->pid, &status, WNOHANG)) { -- case 0: -- /* child is still alive */ -- break; -- case -1: -- break; -- default: -- if (WIFEXITED(status)) { -+ for ( ;; ) { -+ switch(waitpid(proc->pid, &status, WNOHANG)) { -+ case 0: -+ /* child is still alive */ -+ if (srv->cur_ts <= proc->disabled_until) break; -+ -+ proc->state = PROC_STATE_RUNNING; -+ host->active_procs++; -+ -+ log_error_write(srv, __FILE__, __LINE__, "sbdb", -+ "fcgi-server re-enabled:", -+ host->host, host->port, -+ host->unixsocket); -+ break; -+ case -1: -+ if (errno == EINTR) continue; -+ -+ log_error_write(srv, __FILE__, __LINE__, "sd", -+ "child died somehow, waitpid failed:", -+ errno); -+ proc->state = PROC_STATE_DIED; -+ break; -+ default: -+ if (WIFEXITED(status)) { - #if 0 -- log_error_write(srv, __FILE__, __LINE__, "sdsd", -- "child exited, pid:", proc->pid, -- "status:", WEXITSTATUS(status)); -+ log_error_write(srv, __FILE__, __LINE__, "sdsd", -+ "child exited, pid:", proc->pid, -+ "status:", WEXITSTATUS(status)); - #endif -- } else if (WIFSIGNALED(status)) { -- log_error_write(srv, __FILE__, __LINE__, "sd", -- "child signaled:", -- WTERMSIG(status)); -- } else { -- log_error_write(srv, __FILE__, __LINE__, "sd", -- "child died somehow:", -- status); -+ } else if (WIFSIGNALED(status)) { -+ log_error_write(srv, __FILE__, __LINE__, "sd", -+ "child signaled:", -+ WTERMSIG(status)); -+ } else { -+ log_error_write(srv, __FILE__, __LINE__, "sd", -+ "child died somehow:", -+ status); -+ } -+ -+ proc->state = PROC_STATE_DIED; -+ break; - } -- -- proc->state = PROC_STATE_DIED; - break; - } - -@@ -2797,7 +2841,7 @@ - hctx->proc->state = PROC_STATE_DIED; - - fastcgi_status_copy_procname(p->statuskey, hctx->host, hctx->proc); -- buffer_append_string(p->statuskey, ".died"); -+ buffer_append_string_len(p->statuskey, CONST_STR_LEN(".died")); - - status_counter_inc(srv, CONST_BUF_LEN(p->statuskey)); - -@@ -2889,7 +2933,7 @@ - hctx->proc->state = PROC_STATE_OVERLOADED; - - fastcgi_status_copy_procname(p->statuskey, hctx->host, hctx->proc); -- buffer_append_string(p->statuskey, ".overloaded"); -+ buffer_append_string_len(p->statuskey, CONST_STR_LEN(".overloaded")); - - status_counter_inc(srv, CONST_BUF_LEN(p->statuskey)); - -@@ -2915,7 +2959,7 @@ - "load:", host->load); - - fastcgi_status_copy_procname(p->statuskey, hctx->host, hctx->proc); -- buffer_append_string(p->statuskey, ".died"); -+ buffer_append_string_len(p->statuskey, CONST_STR_LEN(".died")); - - status_counter_inc(srv, CONST_BUF_LEN(p->statuskey)); - -@@ -2941,19 +2985,19 @@ - status_counter_inc(srv, CONST_STR_LEN("fastcgi.active-requests")); - - fastcgi_status_copy_procname(p->statuskey, hctx->host, hctx->proc); -- buffer_append_string(p->statuskey, ".connected"); -+ buffer_append_string_len(p->statuskey, CONST_STR_LEN(".connected")); - - status_counter_inc(srv, CONST_BUF_LEN(p->statuskey)); - - /* the proc-load */ - fastcgi_status_copy_procname(p->statuskey, hctx->host, hctx->proc); -- buffer_append_string(p->statuskey, ".load"); -+ buffer_append_string_len(p->statuskey, CONST_STR_LEN(".load")); - - status_counter_set(srv, CONST_BUF_LEN(p->statuskey), hctx->proc->load); - - /* the host-load */ - fastcgi_status_copy_procname(p->statuskey, hctx->host, NULL); -- buffer_append_string(p->statuskey, ".load"); -+ buffer_append_string_len(p->statuskey, CONST_STR_LEN(".load")); - - status_counter_set(srv, CONST_BUF_LEN(p->statuskey), hctx->host->load); - -@@ -3074,7 +3118,7 @@ - - /* check if the next server has no load. */ - ndx = hctx->ext->last_used_ndx + 1; -- if(ndx >= hctx->ext->used || ndx < 0) ndx = 0; -+ if(ndx >= (int) hctx->ext->used || ndx < 0) ndx = 0; - host = hctx->ext->hosts[ndx]; - if (host->load > 0) { - /* get backend with the least load. */ -@@ -3418,6 +3462,8 @@ - fcgi_extension *extension = NULL; - fcgi_extension_host *host = NULL; - -+ if (con->mode != DIRECT) return HANDLER_GO_ON; -+ - /* Possibly, we processed already this request */ - if (con->file_started == 1) return HANDLER_GO_ON; - -@@ -3480,13 +3526,12 @@ - - ct_len = extension->key->used - 1; - -- if (s_len < ct_len) continue; -- -- /* check extension in the form "/fcgi_pattern" */ -- if (*(extension->key->ptr) == '/') { -- if (strncmp(fn->ptr, extension->key->ptr, ct_len) == 0) -+ /* check _url_ in the form "/fcgi_pattern" */ -+ if (extension->key->ptr[0] == '/') { -+ if ((ct_len <= con->uri.path->used -1) && -+ (strncmp(con->uri.path->ptr, extension->key->ptr, ct_len) == 0)) - break; -- } else if (0 == strncmp(fn->ptr + s_len - ct_len, extension->key->ptr, ct_len)) { -+ } else if ((ct_len <= s_len) && (0 == strncmp(fn->ptr + s_len - ct_len, extension->key->ptr, ct_len))) { - /* check extension in the form ".fcg" */ - break; - } -@@ -3499,16 +3544,15 @@ - - /* check if we have at least one server for this extension up and running */ - for (k = 0; k < extension->used; k++) { -- host = extension->hosts[k]; -+ fcgi_extension_host *h = extension->hosts[k]; - - /* we should have at least one proc that can do something */ -- if (host->active_procs == 0) { -- host = NULL; -- -+ if (h->active_procs == 0) { - continue; - } - - /* we found one host that is alive */ -+ host = h; - break; - } - -@@ -3582,6 +3626,13 @@ - * SCRIPT_NAME = /fcgi-bin/foo - * PATH_INFO = /bar - * -+ * if prefix = /, and fix-root-path-name is enable -+ * -+ * /fcgi-bin/foo/bar -+ * -+ * SCRIPT_NAME = /fcgi-bin/foo -+ * PATH_INFO = /bar -+ * - */ - - /* the rewrite is only done for /prefix/? matches */ -@@ -3594,6 +3645,10 @@ - - 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 { -@@ -3738,7 +3793,7 @@ - proc->port = host->port + proc->id; - } else { - buffer_copy_string_buffer(proc->unixsocket, host->unixsocket); -- buffer_append_string(proc->unixsocket, "-"); -+ buffer_append_string_len(proc->unixsocket, CONST_STR_LEN("-")); - buffer_append_long(proc->unixsocket, proc->id); - } - -Index: src/mod_ssi_exprparser.y -=================================================================== ---- src/mod_ssi_exprparser.y (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/mod_ssi_exprparser.y (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -105,12 +105,13 @@ - } - - value(A) ::= VALUE(B). { -- A = buffer_init_string(B->ptr); -+ A = B; - } - - value(A) ::= value(B) VALUE(C). { - A = B; - buffer_append_string_buffer(A, C); -+ buffer_free(C); - } - - cond(A) ::= EQ. { A = SSI_COND_EQ; } -Index: src/mod_access.c -=================================================================== ---- src/mod_access.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/mod_access.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -159,6 +159,7 @@ - - if (denied) { - con->http_status = 403; -+ con->mode = DIRECT; - - if (con->conf.log_request_handling) { - log_error_write(srv, __FILE__, __LINE__, "sb", -Index: src/mod_accesslog.c -=================================================================== ---- src/mod_accesslog.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/mod_accesslog.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -356,7 +356,7 @@ - if (s->use_syslog) { - # ifdef HAVE_SYSLOG_H - if (s->access_logbuffer->used > 2) { -- syslog(LOG_INFO, "%*s", s->access_logbuffer->used - 2, s->access_logbuffer->ptr); -+ syslog(LOG_INFO, "%*s", (int) s->access_logbuffer->used - 2, s->access_logbuffer->ptr); - } - # endif - } else if (s->log_access_fd != -1) { -@@ -433,7 +433,7 @@ - if (i == 0 && buffer_is_empty(s->format)) { - /* set a default logfile string */ - -- buffer_copy_string(s->format, "%h %V %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\""); -+ buffer_copy_string_len(s->format, CONST_STR_LEN("%h %V %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"")); - } - - /* parse */ -@@ -473,7 +473,7 @@ - continue; - } - -- if (buffer_is_empty(s->access_logfile)) continue; -+ if (s->access_logfile->used < 2) continue; - - if (s->access_logfile->ptr[0] == '|') { - #ifdef HAVE_FORK -@@ -498,6 +498,8 @@ - /* 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); -@@ -559,7 +561,7 @@ - #ifdef HAVE_SYSLOG_H - if (s->access_logbuffer->used > 2) { - /* syslog appends a \n on its own */ -- syslog(LOG_INFO, "%*s", s->access_logbuffer->used - 2, s->access_logbuffer->ptr); -+ syslog(LOG_INFO, "%*s", (int) s->access_logbuffer->used - 2, s->access_logbuffer->ptr); - } - #endif - } else if (s->log_access_fd != -1) { -@@ -570,7 +572,7 @@ - } - - if (s->use_syslog == 0 && -- !buffer_is_empty(s->access_logfile) && -+ s->access_logfile->used > 1 && - s->access_logfile->ptr[0] != '|') { - - close(s->log_access_fd); -@@ -647,9 +649,12 @@ - - mod_accesslog_patch_connection(srv, con, p); - -+ /* No output device, nothing to do */ -+ if (!p->conf.use_syslog && p->conf.log_access_fd == -1) return HANDLER_GO_ON; -+ - b = p->conf.access_logbuffer; - if (b->used == 0) { -- buffer_copy_string(b, ""); -+ buffer_copy_string_len(b, CONST_STR_LEN("")); - } - - for (j = 0; j < p->conf.parsed_format->used; j++) { -@@ -674,23 +679,23 @@ - localtime_r(&(srv->cur_ts), &tm); - strftime(p->conf.ts_accesslog_str->ptr, p->conf.ts_accesslog_str->size - 1, "[%d/%b/%Y:%H:%M:%S ", &tm); - # else -- strftime(p->conf.ts_accesslog_str->ptr, p->conf.ts_accesslog_str->size - 1, "[%d/%b/%Y:%H:%M:%S ", localtime_r(&(srv->cur_ts))); -+ strftime(p->conf.ts_accesslog_str->ptr, p->conf.ts_accesslog_str->size - 1, "[%d/%b/%Y:%H:%M:%S ", localtime(&(srv->cur_ts))); - # endif - p->conf.ts_accesslog_str->used = strlen(p->conf.ts_accesslog_str->ptr) + 1; - -- buffer_append_string(p->conf.ts_accesslog_str, tm.tm_gmtoff >= 0 ? "+" : "-"); -+ buffer_append_string_len(p->conf.ts_accesslog_str, tm.tm_gmtoff >= 0 ? "+" : "-", 1); - - scd = abs(tm.tm_gmtoff); - hrs = scd / 3600; - min = (scd % 3600) / 60; - - /* hours */ -- if (hrs < 10) buffer_append_string(p->conf.ts_accesslog_str, "0"); -+ if (hrs < 10) buffer_append_string_len(p->conf.ts_accesslog_str, CONST_STR_LEN("0")); - buffer_append_long(p->conf.ts_accesslog_str, hrs); - -- if (min < 10) buffer_append_string(p->conf.ts_accesslog_str, "0"); -+ if (min < 10) buffer_append_string_len(p->conf.ts_accesslog_str, CONST_STR_LEN("0")); - buffer_append_long(p->conf.ts_accesslog_str, min); -- BUFFER_APPEND_STRING_CONST(p->conf.ts_accesslog_str, "]"); -+ buffer_append_string_len(p->conf.ts_accesslog_str, CONST_STR_LEN("]")); - #else - #ifdef HAVE_GMTIME_R - gmtime_r(&(srv->cur_ts), &tm); -@@ -717,13 +722,13 @@ - break; - case FORMAT_REMOTE_IDENT: - /* ident */ -- BUFFER_APPEND_STRING_CONST(b, "-"); -+ buffer_append_string_len(b, CONST_STR_LEN("-")); - break; - case FORMAT_REMOTE_USER: - if (con->authed_user->used > 1) { - buffer_append_string_buffer(b, con->authed_user); - } else { -- BUFFER_APPEND_STRING_CONST(b, "-"); -+ buffer_append_string_len(b, CONST_STR_LEN("-")); - } - break; - case FORMAT_REQUEST_LINE: -@@ -740,42 +745,42 @@ - buffer_append_off_t(b, - con->bytes_written - con->bytes_header <= 0 ? 0 : con->bytes_written - con->bytes_header); - } else { -- BUFFER_APPEND_STRING_CONST(b, "-"); -+ buffer_append_string_len(b, CONST_STR_LEN("-")); - } - break; - case FORMAT_HEADER: - if (NULL != (ds = (data_string *)array_get_element(con->request.headers, p->conf.parsed_format->ptr[j]->string->ptr))) { - buffer_append_string_buffer(b, ds->value); - } else { -- BUFFER_APPEND_STRING_CONST(b, "-"); -+ buffer_append_string_len(b, CONST_STR_LEN("-")); - } - break; - case FORMAT_RESPONSE_HEADER: - if (NULL != (ds = (data_string *)array_get_element(con->response.headers, p->conf.parsed_format->ptr[j]->string->ptr))) { - buffer_append_string_buffer(b, ds->value); - } else { -- BUFFER_APPEND_STRING_CONST(b, "-"); -+ buffer_append_string_len(b, CONST_STR_LEN("-")); - } - break; - case FORMAT_FILENAME: - if (con->physical.path->used > 1) { - buffer_append_string_buffer(b, con->physical.path); - } else { -- BUFFER_APPEND_STRING_CONST(b, "-"); -+ buffer_append_string_len(b, CONST_STR_LEN("-")); - } - break; - case FORMAT_BYTES_OUT: - if (con->bytes_written > 0) { - buffer_append_off_t(b, con->bytes_written); - } else { -- BUFFER_APPEND_STRING_CONST(b, "-"); -+ buffer_append_string_len(b, CONST_STR_LEN("-")); - } - break; - case FORMAT_BYTES_IN: - if (con->bytes_read > 0) { - buffer_append_off_t(b, con->bytes_read); - } else { -- BUFFER_APPEND_STRING_CONST(b, "-"); -+ buffer_append_string_len(b, CONST_STR_LEN("-")); - } - break; - case FORMAT_TIME_USED: -@@ -785,28 +790,35 @@ - if (con->server_name->used > 1) { - buffer_append_string_buffer(b, con->server_name); - } else { -- BUFFER_APPEND_STRING_CONST(b, "-"); -+ buffer_append_string_len(b, CONST_STR_LEN("-")); - } - break; - case FORMAT_HTTP_HOST: - if (con->uri.authority->used > 1) { - buffer_append_string_buffer(b, con->uri.authority); - } else { -- BUFFER_APPEND_STRING_CONST(b, "-"); -+ buffer_append_string_len(b, CONST_STR_LEN("-")); - } - break; - case FORMAT_REQUEST_PROTOCOL: -- buffer_append_string(b, -- con->request.http_version == HTTP_VERSION_1_1 ? "HTTP/1.1" : "HTTP/1.0"); -+ buffer_append_string_len(b, -+ con->request.http_version == HTTP_VERSION_1_1 ? "HTTP/1.1" : "HTTP/1.0", 8); - break; - case FORMAT_REQUEST_METHOD: - buffer_append_string(b, get_http_method_name(con->request.http_method)); - break; - case FORMAT_PERCENT: -- buffer_append_string(b, "%"); -+ buffer_append_string_len(b, CONST_STR_LEN("%")); - break; - case FORMAT_SERVER_PORT: -- buffer_append_long(b, srv->srvconf.port); -+ { -+ char *colon = strchr(((server_socket*)(con->srv_socket))->srv_token->ptr, ':'); -+ if (colon) { -+ buffer_append_string(b, colon+1); -+ } else { -+ buffer_append_long(b, srv->srvconf.port); -+ } -+ } - break; - case FORMAT_QUERY_STRING: - buffer_append_string_buffer(b, con->uri.query); -@@ -816,8 +828,8 @@ - break; - case FORMAT_CONNECTION_STATUS: - switch(con->keep_alive) { -- case 0: buffer_append_string(b, "-"); break; -- default: buffer_append_string(b, "+"); break; -+ case 0: buffer_append_string_len(b, CONST_STR_LEN("-")); break; -+ default: buffer_append_string_len(b, CONST_STR_LEN("+")); break; - } - break; - default: -@@ -837,7 +849,7 @@ - } - } - -- BUFFER_APPEND_STRING_CONST(b, "\n"); -+ buffer_append_string_len(b, CONST_STR_LEN("\n")); - - if (p->conf.use_syslog || /* syslog doesn't cache */ - (p->conf.access_logfile->used && p->conf.access_logfile->ptr[0] == '|') || /* pipes don't cache */ -@@ -847,7 +859,7 @@ - #ifdef HAVE_SYSLOG_H - if (b->used > 2) { - /* syslog appends a \n on its own */ -- syslog(LOG_INFO, "%*s", b->used - 2, b->ptr); -+ syslog(LOG_INFO, "%*s", (int) b->used - 2, b->ptr); - } - #endif - } else if (p->conf.log_access_fd != -1) { -Index: src/server.c -=================================================================== ---- src/server.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/server.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -80,7 +80,7 @@ - switch (sig) { - case SIGTERM: - srv_shutdown = 1; -- memcpy(&last_sigterm_info, si, sizeof(*si)); -+ last_sigterm_info = *si; - break; - case SIGINT: - if (graceful_shutdown) { -@@ -88,7 +88,7 @@ - } else { - graceful_shutdown = 1; - } -- memcpy(&last_sigterm_info, si, sizeof(*si)); -+ last_sigterm_info = *si; - - break; - case SIGALRM: -@@ -104,7 +104,7 @@ - */ - if (!forwarded_sig_hup) { - handle_sig_hup = 1; -- memcpy(&last_sighup_info, si, sizeof(*si)); -+ last_sighup_info = *si; - } else { - forwarded_sig_hup = 0; - } -@@ -573,20 +573,9 @@ - } - - /* close stdin and stdout, as they are not needed */ -- /* move stdin to /dev/null */ -- if (-1 != (fd = open("/dev/null", O_RDONLY))) { -- close(STDIN_FILENO); -- dup2(fd, STDIN_FILENO); -- close(fd); -- } -+ openDevNull(STDIN_FILENO); -+ openDevNull(STDOUT_FILENO); - -- /* move stdout to /dev/null */ -- if (-1 != (fd = open("/dev/null", O_WRONLY))) { -- close(STDOUT_FILENO); -- dup2(fd, STDOUT_FILENO); -- close(fd); -- } -- - if (0 != config_set_defaults(srv)) { - log_error_write(srv, __FILE__, __LINE__, "s", - "setting default values failed"); -@@ -887,14 +876,14 @@ - /* write pid file */ - if (pid_fd != -1) { - buffer_copy_long(srv->tmp_buf, getpid()); -- buffer_append_string(srv->tmp_buf, "\n"); -+ buffer_append_string_len(srv->tmp_buf, CONST_STR_LEN("\n")); - write(pid_fd, srv->tmp_buf->ptr, srv->tmp_buf->used - 1); - close(pid_fd); - pid_fd = -1; - } - -- // Close stderr ASAP in the child process to make sure that nothing -- // is being written to that fd which may not be valid anymore. -+ /* Close stderr ASAP in the child process to make sure that nothing -+ * is being written to that fd which may not be valid anymore. */ - if (-1 == log_error_open(srv)) { - log_error_write(srv, __FILE__, __LINE__, "s", "Opening errorlog failed. Going down."); - -Index: src/mod_dirlisting.c -=================================================================== ---- src/mod_dirlisting.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/mod_dirlisting.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -454,21 +454,21 @@ - static void http_list_directory_header(server *srv, connection *con, plugin_data *p, buffer *out) { - UNUSED(srv); - -- BUFFER_APPEND_STRING_CONST(out, -+ buffer_append_string_len(out, CONST_STR_LEN( - "\n" - "\n" - "\n" - "Index of " -- ); -+ )); - buffer_append_string_encoded(out, CONST_BUF_LEN(con->uri.path), ENCODING_MINIMAL_XML); -- BUFFER_APPEND_STRING_CONST(out, "\n"); -+ buffer_append_string_len(out, CONST_STR_LEN("\n")); - - if (p->conf.external_css->used > 1) { -- BUFFER_APPEND_STRING_CONST(out, "conf.external_css); -- BUFFER_APPEND_STRING_CONST(out, "\" />\n"); -+ buffer_append_string_len(out, CONST_STR_LEN("\" />\n")); - } else { -- BUFFER_APPEND_STRING_CONST(out, -+ buffer_append_string_len(out, CONST_STR_LEN( - "\n" -- ); -+ )); - } - -- BUFFER_APPEND_STRING_CONST(out, "\n\n"); -+ buffer_append_string_len(out, CONST_STR_LEN("\n\n")); - - /* HEADER.txt */ - if (p->conf.show_header) { -@@ -514,19 +512,19 @@ - - buffer_copy_string_buffer(p->tmp_buf, con->physical.path); - BUFFER_APPEND_SLASH(p->tmp_buf); -- BUFFER_APPEND_STRING_CONST(p->tmp_buf, "HEADER.txt"); -+ buffer_append_string_len(p->tmp_buf, CONST_STR_LEN("HEADER.txt")); - - if (-1 != stream_open(&s, p->tmp_buf)) { -- BUFFER_APPEND_STRING_CONST(out, "
");
-+			buffer_append_string_len(out, CONST_STR_LEN("
"));
- 			buffer_append_string_encoded(out, s.start, s.size, ENCODING_MINIMAL_XML);
--			BUFFER_APPEND_STRING_CONST(out, "
"); -+ buffer_append_string_len(out, CONST_STR_LEN("
")); - } - stream_close(&s); - } - -- BUFFER_APPEND_STRING_CONST(out, "

Index of "); -+ buffer_append_string_len(out, CONST_STR_LEN("

Index of ")); - buffer_append_string_encoded(out, CONST_BUF_LEN(con->uri.path), ENCODING_MINIMAL_XML); -- BUFFER_APPEND_STRING_CONST(out, -+ buffer_append_string_len(out, CONST_STR_LEN( - "

\n" - "
\n" - "\n" -@@ -545,17 +543,17 @@ - "" - "" - "\n" -- ); -+ )); - } - - static void http_list_directory_footer(server *srv, connection *con, plugin_data *p, buffer *out) { - UNUSED(srv); - -- BUFFER_APPEND_STRING_CONST(out, -+ buffer_append_string_len(out, CONST_STR_LEN( - "\n" - "
-  Directory
\n" - "
\n" -- ); -+ )); - - if (p->conf.show_readme) { - stream s; -@@ -563,33 +561,33 @@ - - buffer_copy_string_buffer(p->tmp_buf, con->physical.path); - BUFFER_APPEND_SLASH(p->tmp_buf); -- BUFFER_APPEND_STRING_CONST(p->tmp_buf, "README.txt"); -+ buffer_append_string_len(p->tmp_buf, CONST_STR_LEN("README.txt")); - - if (-1 != stream_open(&s, p->tmp_buf)) { -- BUFFER_APPEND_STRING_CONST(out, "
");
-+			buffer_append_string_len(out, CONST_STR_LEN("
"));
- 			buffer_append_string_encoded(out, s.start, s.size, ENCODING_MINIMAL_XML);
--			BUFFER_APPEND_STRING_CONST(out, "
"); -+ buffer_append_string_len(out, CONST_STR_LEN("
")); - } - stream_close(&s); - } - -- BUFFER_APPEND_STRING_CONST(out, -+ buffer_append_string_len(out, CONST_STR_LEN( - "
" -- ); -+ )); - - if (p->conf.set_footer->used > 1) { - buffer_append_string_buffer(out, p->conf.set_footer); - } else if (buffer_is_empty(con->conf.server_tag)) { -- BUFFER_APPEND_STRING_CONST(out, PACKAGE_NAME "/" PACKAGE_VERSION); -+ buffer_append_string_len(out, CONST_STR_LEN(PACKAGE_NAME "/" PACKAGE_VERSION)); - } else { - buffer_append_string_buffer(out, con->conf.server_tag); - } - -- BUFFER_APPEND_STRING_CONST(out, -+ buffer_append_string_len(out, CONST_STR_LEN( - "
\n" - "\n" - "\n" -- ); -+ )); - } - - static int http_list_directory(server *srv, connection *con, plugin_data *p, buffer *dir) { -@@ -742,13 +740,13 @@ - if (files.used) http_dirls_sort(files.ent, files.used); - - out = chunkqueue_get_append_buffer(con->write_queue); -- BUFFER_COPY_STRING_CONST(out, "conf.encoding)) { -- BUFFER_APPEND_STRING_CONST(out, "iso-8859-1"); -+ buffer_append_string_len(out, CONST_STR_LEN("iso-8859-1")); - } else { - buffer_append_string_buffer(out, p->conf.encoding); - } -- BUFFER_APPEND_STRING_CONST(out, "\"?>\n"); -+ buffer_append_string_len(out, CONST_STR_LEN("\"?>\n")); - http_list_directory_header(srv, con, p, out); - - /* directories */ -@@ -762,13 +760,13 @@ - strftime(datebuf, sizeof(datebuf), "%Y-%b-%d %H:%M:%S", localtime(&(tmp->mtime))); - #endif - -- BUFFER_APPEND_STRING_CONST(out, "namelen, ENCODING_REL_URI_PART); -- BUFFER_APPEND_STRING_CONST(out, "/\">"); -+ buffer_append_string_len(out, CONST_STR_LEN("/\">")); - buffer_append_string_encoded(out, DIRLIST_ENT_NAME(tmp), tmp->namelen, ENCODING_MINIMAL_XML); -- BUFFER_APPEND_STRING_CONST(out, "/"); -+ buffer_append_string_len(out, CONST_STR_LEN("/")); - buffer_append_string_len(out, datebuf, sizeof(datebuf) - 1); -- BUFFER_APPEND_STRING_CONST(out, "-  Directory\n"); -+ buffer_append_string_len(out, CONST_STR_LEN("-  Directory\n")); - - free(tmp); - } -@@ -818,17 +816,17 @@ - #endif - http_list_directory_sizefmt(sizebuf, tmp->size); - -- BUFFER_APPEND_STRING_CONST(out, "namelen, ENCODING_REL_URI_PART); -- BUFFER_APPEND_STRING_CONST(out, "\">"); -+ buffer_append_string_len(out, CONST_STR_LEN("\">")); - buffer_append_string_encoded(out, DIRLIST_ENT_NAME(tmp), tmp->namelen, ENCODING_MINIMAL_XML); -- BUFFER_APPEND_STRING_CONST(out, ""); -+ buffer_append_string_len(out, CONST_STR_LEN("")); - buffer_append_string_len(out, datebuf, sizeof(datebuf) - 1); -- BUFFER_APPEND_STRING_CONST(out, ""); -+ buffer_append_string_len(out, CONST_STR_LEN("")); - buffer_append_string(out, sizebuf); -- BUFFER_APPEND_STRING_CONST(out, ""); -+ buffer_append_string_len(out, CONST_STR_LEN("")); - buffer_append_string(out, content_type); -- BUFFER_APPEND_STRING_CONST(out, "\n"); -+ buffer_append_string_len(out, CONST_STR_LEN("\n")); - - free(tmp); - } -@@ -841,11 +839,11 @@ - - /* Insert possible charset to Content-Type */ - if (buffer_is_empty(p->conf.encoding)) { -- response_header_insert(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html")); -+ response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html")); - } else { -- buffer_copy_string(p->content_charset, "text/html; charset="); -+ buffer_copy_string_len(p->content_charset, CONST_STR_LEN("text/html; charset=")); - buffer_append_string_buffer(p->content_charset, p->conf.encoding); -- response_header_insert(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(p->content_charset)); -+ response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(p->content_charset)); - } - - con->file_finished = 1; -@@ -861,6 +859,18 @@ - - UNUSED(srv); - -+ /* we only handle GET, POST and HEAD */ -+ switch(con->request.http_method) { -+ case HTTP_METHOD_GET: -+ case HTTP_METHOD_POST: -+ case HTTP_METHOD_HEAD: -+ break; -+ default: -+ return HANDLER_GO_ON; -+ } -+ -+ if (con->mode != DIRECT) return HANDLER_GO_ON; -+ - if (con->physical.path->used == 0) return HANDLER_GO_ON; - if (con->uri.path->used == 0) return HANDLER_GO_ON; - if (con->uri.path->ptr[con->uri.path->used - 2] != '/') return HANDLER_GO_ON; -Index: src/http_chunk.c -=================================================================== ---- src/http_chunk.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/http_chunk.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -27,7 +27,7 @@ - b = srv->tmp_chunk_len; - - if (len == 0) { -- buffer_copy_string(b, "0"); -+ buffer_copy_string_len(b, CONST_STR_LEN("0")); - } else { - for (i = 0; i < 8 && len; i++) { - len >>= 4; -@@ -44,7 +44,7 @@ - b->ptr[b->used++] = '\0'; - } - -- buffer_append_string(b, "\r\n"); -+ buffer_append_string_len(b, CONST_STR_LEN("\r\n")); - chunkqueue_append_buffer(con->write_queue, b); - - return 0; -Index: src/mod_magnet.c -=================================================================== ---- src/mod_magnet.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/mod_magnet.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -414,10 +414,16 @@ - case MAGNET_ENV_URI_AUTHORITY: dest = con->uri.authority; break; - case MAGNET_ENV_URI_QUERY: dest = con->uri.query; break; - -- case MAGNET_ENV_REQUEST_METHOD: break; -+ case MAGNET_ENV_REQUEST_METHOD: -+ buffer_copy_string(srv->tmp_buf, get_http_method_name(con->request.http_method)); -+ dest = srv->tmp_buf; -+ 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_PROTOCOL: break; -+ case MAGNET_ENV_REQUEST_PROTOCOL: -+ buffer_copy_string(srv->tmp_buf, get_http_version_name(con->request.http_version)); -+ dest = srv->tmp_buf; -+ break; - - case MAGNET_ENV_UNSET: break; - } -@@ -647,6 +653,7 @@ - assert(lua_gettop(L) == 0); /* only the function should be on the stack */ - - con->http_status = 500; -+ con->mode = DIRECT; - - return HANDLER_FINISHED; - } -@@ -744,6 +751,7 @@ - assert(lua_gettop(L) == 1); /* only the function should be on the stack */ - - con->http_status = 500; -+ con->mode = DIRECT; - - return HANDLER_FINISHED; - } -@@ -766,9 +774,13 @@ - /* try { ...*/ - if (0 == setjmp(exceptionjmp)) { - magnet_attach_content(srv, con, p, L); -+ if (!chunkqueue_is_empty(con->write_queue)) { -+ con->mode = p->id; -+ } - } else { - /* } catch () { */ - con->http_status = 500; -+ con->mode = DIRECT; - } - - assert(lua_gettop(L) == 1); /* only the function should be on the stack */ -Index: src/log.c -=================================================================== ---- src/log.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/log.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -31,6 +31,29 @@ - # define O_LARGEFILE 0 - #endif - -+/* Close fd and _try_ to get a /dev/null for it instead. -+ * close() alone may trigger some bugs when a -+ * process opens another file and gets fd = STDOUT_FILENO or STDERR_FILENO -+ * and later tries to just print on stdout/stderr -+ * -+ * Returns 0 on success and -1 on failure (fd gets closed in all cases) -+ */ -+int openDevNull(int fd) { -+ int tmpfd; -+ close(fd); -+#if defined(__WIN32) -+ /* Cygwin should work with /dev/null */ -+ tmpfd = open("nul", O_RDWR); -+#else -+ tmpfd = open("/dev/null", O_RDWR); -+#endif -+ if (tmpfd != -1 && tmpfd != fd) { -+ dup2(tmpfd, fd); -+ close(tmpfd); -+ } -+ return (tmpfd != -1) ? 0 : -1; -+} -+ - /** - * open the errorlog - * -@@ -44,7 +67,6 @@ - */ - - int log_error_open(server *srv) { -- int fd; - int close_stderr = 1; - - #ifdef HAVE_SYSLOG_H -@@ -78,15 +100,16 @@ - /* don't close stderr for debugging purposes if run in valgrind */ - if (RUNNING_ON_VALGRIND) close_stderr = 0; - #endif -- if (srv->errorlog_mode == ERRORLOG_STDERR) close_stderr = 0; - -+ if (srv->errorlog_mode == ERRORLOG_STDERR && srv->srvconf.dont_daemonize) { -+ /* We can only log to stderr in dont-daemonize mode; -+ * if we do daemonize and no errorlog file is specified, we log into /dev/null -+ */ -+ close_stderr = 0; -+ } -+ - /* move stderr to /dev/null */ -- if (close_stderr && -- -1 != (fd = open("/dev/null", O_WRONLY))) { -- close(STDERR_FILENO); -- dup2(fd, STDERR_FILENO); -- close(fd); -- } -+ if (close_stderr) openDevNull(STDERR_FILENO); - return 0; - } - -@@ -162,18 +185,18 @@ - } - - buffer_copy_string_buffer(srv->errorlog_buf, srv->ts_debug_str); -- BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, ": ("); -+ buffer_append_string_len(srv->errorlog_buf, CONST_STR_LEN(": (")); - break; - case ERRORLOG_SYSLOG: - /* syslog is generating its own timestamps */ -- BUFFER_COPY_STRING_CONST(srv->errorlog_buf, "("); -+ buffer_copy_string_len(srv->errorlog_buf, CONST_STR_LEN("(")); - break; - } - - buffer_append_string(srv->errorlog_buf, filename); -- BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, "."); -+ buffer_append_string_len(srv->errorlog_buf, CONST_STR_LEN(".")); - buffer_append_long(srv->errorlog_buf, line); -- BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, ") "); -+ buffer_append_string_len(srv->errorlog_buf, CONST_STR_LEN(") ")); - - - for(va_start(ap, fmt); *fmt; fmt++) { -@@ -186,28 +209,28 @@ - case 's': /* string */ - s = va_arg(ap, char *); - buffer_append_string(srv->errorlog_buf, s); -- BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, " "); -+ buffer_append_string_len(srv->errorlog_buf, CONST_STR_LEN(" ")); - break; - case 'b': /* buffer */ - b = va_arg(ap, buffer *); - buffer_append_string_buffer(srv->errorlog_buf, b); -- BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, " "); -+ buffer_append_string_len(srv->errorlog_buf, CONST_STR_LEN(" ")); - break; - case 'd': /* int */ - d = va_arg(ap, int); - buffer_append_long(srv->errorlog_buf, d); -- BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, " "); -+ buffer_append_string_len(srv->errorlog_buf, CONST_STR_LEN(" ")); - break; - case 'o': /* off_t */ - o = va_arg(ap, off_t); - buffer_append_off_t(srv->errorlog_buf, o); -- BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, " "); -+ buffer_append_string_len(srv->errorlog_buf, CONST_STR_LEN(" ")); - break; - case 'x': /* int (hex) */ - d = va_arg(ap, int); -- BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, "0x"); -+ buffer_append_string_len(srv->errorlog_buf, CONST_STR_LEN("0x")); - buffer_append_long_hex(srv->errorlog_buf, d); -- BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, " "); -+ buffer_append_string_len(srv->errorlog_buf, CONST_STR_LEN(" ")); - break; - case 'S': /* string */ - s = va_arg(ap, char *); -@@ -221,6 +244,15 @@ - d = va_arg(ap, int); - buffer_append_long(srv->errorlog_buf, d); - break; -+ case 'O': /* off_t */ -+ o = va_arg(ap, off_t); -+ buffer_append_off_t(srv->errorlog_buf, o); -+ break; -+ case 'X': /* int (hex) */ -+ d = va_arg(ap, int); -+ buffer_append_string_len(srv->errorlog_buf, CONST_STR_LEN("0x")); -+ buffer_append_long_hex(srv->errorlog_buf, d); -+ break; - case '(': - case ')': - case '<': -@@ -235,11 +267,11 @@ - - switch(srv->errorlog_mode) { - case ERRORLOG_FILE: -- BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, "\n"); -+ buffer_append_string_len(srv->errorlog_buf, CONST_STR_LEN("\n")); - write(srv->errorlog_fd, srv->errorlog_buf->ptr, srv->errorlog_buf->used - 1); - break; - case ERRORLOG_STDERR: -- BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, "\n"); -+ buffer_append_string_len(srv->errorlog_buf, CONST_STR_LEN("\n")); - write(STDERR_FILENO, srv->errorlog_buf->ptr, srv->errorlog_buf->used - 1); - break; - case ERRORLOG_SYSLOG: -Index: src/proc_open.c -=================================================================== ---- src/proc_open.c (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/proc_open.c (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -184,7 +184,7 @@ - buffer_append_string(cmdline, shell); - } else { - buffer_append_string(cmdline, windir); -- buffer_append_string(cmdline, "\\system32\\cmd.exe"); -+ buffer_append_string_len(cmdline, CONST_STR_LEN("\\system32\\cmd.exe")); - } - buffer_append_string_len(cmdline, CONST_STR_LEN(" /c ")); - buffer_append_string(cmdline, command); -Index: src/log.h -=================================================================== ---- src/log.h (.../tags/lighttpd-1.4.19) (revision 2303) -+++ src/log.h (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -3,6 +3,11 @@ - - #include "server.h" - -+/* Close fd and _try_ to get a /dev/null for it instead. -+ * Returns 0 on success and -1 on failure (fd gets closed in all cases) -+ */ -+int openDevNull(int fd); -+ - #define WP() log_error_write(srv, __FILE__, __LINE__, ""); - - int log_error_open(server *srv); -Index: tests/env-variables.conf -=================================================================== ---- tests/env-variables.conf (.../tags/lighttpd-1.4.19) (revision 2303) -+++ tests/env-variables.conf (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -1 +0,0 @@ --server.document-root = env.CWD -Index: tests/env-variables.t -=================================================================== ---- tests/env-variables.t (.../tags/lighttpd-1.4.19) (revision 2303) -+++ tests/env-variables.t (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -1,21 +0,0 @@ --#!/usr/bin/perl --BEGIN { -- # add current source dir to the include-path -- # we need this for make distcheck -- (my $srcdir = $0) =~ s,/[^/]+$,/,; -- unshift @INC, $srcdir; --} -- --use strict; --use IO::Socket; --use Test::More tests => 2; --use LightyTest; -- --my $tf = LightyTest->new(); --$tf->{CONFIGFILE} = 'env-variables.conf'; -- --TODO: { -- local $TODO = 'we still crash on undefined environment variables'; -- ok($tf->start_proc == 0, "Starting lighttpd"); -- ok($tf->stop_proc == 0, "Stopping lighttpd"); --}; -Index: tests/bug-12.conf -=================================================================== ---- tests/bug-12.conf (.../tags/lighttpd-1.4.19) (revision 2303) -+++ tests/bug-12.conf (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -1,5 +1,4 @@ - server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" --server.pid-file = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid" - - ## bind to port (default: 80) - server.port = 2048 -Index: tests/fastcgi-10.conf -=================================================================== ---- tests/fastcgi-10.conf (.../tags/lighttpd-1.4.19) (revision 2303) -+++ tests/fastcgi-10.conf (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -1,5 +1,4 @@ - server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" --server.pid-file = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid" - - ## bind to port (default: 80) - server.port = 2048 -Index: tests/bug-06.conf -=================================================================== ---- tests/bug-06.conf (.../tags/lighttpd-1.4.19) (revision 2303) -+++ tests/bug-06.conf (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -1,5 +1,4 @@ - server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" --server.pid-file = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid" - - ## bind to port (default: 80) - server.port = 2048 -Index: tests/mod-extforward.conf -=================================================================== - -Property changes on: tests/symlink.t -___________________________________________________________________ -Added: svn:executable - + * - -Index: tests/request.t -=================================================================== ---- tests/request.t (.../tags/lighttpd-1.4.19) (revision 2303) -+++ tests/request.t (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -101,7 +101,7 @@ - Expect: 100-continue - EOF - ); --$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 417, '-HTTP-Content' => ''} ]; -+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 417 } ]; - ok($tf->handle_http($t) == 0, 'Continue, Expect'); - - ## ranges -Index: tests/var-include.conf -=================================================================== ---- tests/var-include.conf (.../tags/lighttpd-1.4.19) (revision 2303) -+++ tests/var-include.conf (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -3,7 +3,6 @@ - debug.log-condition-handling = "enable" - - server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" --server.pid-file = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid" - - ## bind to port (default: 80) - server.port = 2048 -Index: tests/mod-proxy.t -=================================================================== ---- tests/mod-proxy.t (.../tags/lighttpd-1.4.19) (revision 2303) -+++ tests/mod-proxy.t (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -22,11 +22,9 @@ - - $tf_real->{PORT} = 2048; - $tf_real->{CONFIGFILE} = 'lighttpd.conf'; --$tf_real->{LIGHTTPD_PIDFILE} = $tf_real->{TESTDIR}.'/tmp/lighttpd/lighttpd.pid'; - - $tf_proxy->{PORT} = 2050; - $tf_proxy->{CONFIGFILE} = 'proxy.conf'; --$tf_proxy->{LIGHTTPD_PIDFILE} = $tf_proxy->{TESTDIR}.'/tmp/lighttpd/lighttpd-proxy.pid'; - - ok($tf_real->start_proc == 0, "Starting lighttpd") or die(); - -Index: tests/404-handler.conf -=================================================================== ---- tests/404-handler.conf (.../tags/lighttpd-1.4.19) (revision 2303) -+++ tests/404-handler.conf (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -3,7 +3,6 @@ - debug.log-request-header = "enable" - - server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" --server.pid-file = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid" - - ## bind to port (default: 80) - server.port = 2048 -Index: tests/lowercase.conf -=================================================================== ---- tests/lowercase.conf (.../tags/lighttpd-1.4.19) (revision 2303) -+++ tests/lowercase.conf (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -1,5 +1,4 @@ - server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" --server.pid-file = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid" - - ## bind to port (default: 80) - server.port = 2048 -Index: tests/condition.conf -=================================================================== ---- tests/condition.conf (.../tags/lighttpd-1.4.19) (revision 2303) -+++ tests/condition.conf (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -3,7 +3,6 @@ - debug.log-condition-handling = "enable" - - server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" --server.pid-file = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid" - - ## bind to port (default: 80) - server.port = 2048 -Index: tests/fastcgi-13.conf -=================================================================== ---- tests/fastcgi-13.conf (.../tags/lighttpd-1.4.19) (revision 2303) -+++ tests/fastcgi-13.conf (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -1,5 +1,4 @@ - server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" --server.pid-file = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid" - - debug.log-request-header = "enable" - debug.log-response-header = "enable" -@@ -85,7 +84,7 @@ - "grisu" => ( - "host" => "127.0.0.1", - "port" => 1048, -- "bin-path" => "/usr/bin/php-cgi", -+ "bin-path" => env.PHP, - "bin-copy-environment" => ( "PATH", "SHELL", "USER" ), - ) - ) -Index: tests/mod-fastcgi.t -=================================================================== ---- tests/mod-fastcgi.t (.../tags/lighttpd-1.4.19) (revision 2303) -+++ tests/mod-fastcgi.t (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -7,17 +7,27 @@ - } - - use strict; --use Test::More tests => 47; -+use Test::More tests => 49; - use LightyTest; - - my $tf = LightyTest->new(); - - my $t; -+my $php_child = -1; - -+my $phpbin = (defined $ENV{'PHP'} ? $ENV{'PHP'} : '/usr/bin/php-cgi'); -+$ENV{'PHP'} = $phpbin; -+ - SKIP: { -+ skip "PHP already running on port 1026", 1 if $tf->listening_on(1026); -+ skip "no php binary found", 1 unless -x $phpbin; -+ ok(-1 != ($php_child = $tf->spawnfcgi($phpbin, 1026)), "Spawning php"); -+} -+ -+SKIP: { - skip "no PHP running on port 1026", 29 unless $tf->listening_on(1026); - -- ok($tf->start_proc == 0, "Starting lighttpd") or die(); -+ ok($tf->start_proc == 0, "Starting lighttpd") or goto cleanup; - - $t->{REQUEST} = ( <{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '/get-server-env.php' } ]; -- ok($tf->handle_http($t) == 0, '$_SERVER["PHP_SELF"]'); -+ ok($tf->handle_http($t) == 0, '$_SERVER["SCRIPT_NAME"]'); - - $t->{REQUEST} = ( <{CONFIGFILE} = 'fastcgi-10.conf'; -- ok($tf->start_proc == 0, "Starting lighttpd with $tf->{CONFIGFILE}") or die(); -+ ok($tf->start_proc == 0, "Starting lighttpd with $tf->{CONFIGFILE}") or goto cleanup; - $t->{REQUEST} = ( <stop_proc == 0, "Stopping lighttpd"); - - $tf->{CONFIGFILE} = 'bug-06.conf'; -- ok($tf->start_proc == 0, "Starting lighttpd with $tf->{CONFIGFILE}") or die(); -+ ok($tf->start_proc == 0, "Starting lighttpd with $tf->{CONFIGFILE}") or goto cleanup; - $t->{REQUEST} = ( <stop_proc == 0, "Stopping lighttpd"); - - $tf->{CONFIGFILE} = 'bug-12.conf'; -- ok($tf->start_proc == 0, "Starting lighttpd with bug-12.conf") or die(); -+ ok($tf->start_proc == 0, "Starting lighttpd with bug-12.conf") or goto cleanup; - $t->{REQUEST} = ( <endspawnfcgi($php_child), "Stopping php"); -+ $php_child = -1; -+} -+ -+SKIP: { - skip "no fcgi-auth found", 4 unless -x $tf->{BASEDIR}."/tests/fcgi-auth" || -x $tf->{BASEDIR}."/tests/fcgi-auth.exe"; - - $tf->{CONFIGFILE} = 'fastcgi-auth.conf'; -@@ -223,7 +239,7 @@ - } - - SKIP: { -- skip "no php found", 5 unless -x "/usr/bin/php-cgi"; -+ skip "no php found", 5 unless -x $phpbin; - $tf->{CONFIGFILE} = 'fastcgi-13.conf'; - ok($tf->start_proc == 0, "Starting lighttpd with $tf->{CONFIGFILE}") or die(); - $t->{REQUEST} = ( <stop_proc == 0, "Stopping lighttpd"); - } - -+exit 0; -+ -+cleanup: ; -+ -+$tf->endspawnfcgi($php_child) if $php_child != -1; -+ -+die(); -Index: tests/mod-rewrite.t -=================================================================== ---- tests/mod-rewrite.t (.../tags/lighttpd-1.4.19) (revision 2303) -+++ tests/mod-rewrite.t (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -8,18 +8,26 @@ - - use strict; - use IO::Socket; --use Test::More tests => 5; -+use Test::More tests => 8; - use LightyTest; - - my $tf = LightyTest->new(); - my $t; -+my $php_child = -1; - -+my $phpbin = (defined $ENV{'PHP'} ? $ENV{'PHP'} : '/usr/bin/php-cgi'); - - SKIP: { -- skip "no PHP running on port 1026", 5 unless $tf->listening_on(1026); -+ skip "PHP already running on port 1026", 1 if $tf->listening_on(1026); -+ skip "no php binary found", 1 unless -x $phpbin; -+ ok(-1 != ($php_child = $tf->spawnfcgi($phpbin, 1026)), "Spawning php"); -+} - -- ok($tf->start_proc == 0, "Starting lighttpd") or die(); -+SKIP: { -+ skip "no PHP running on port 1026", 6 unless $tf->listening_on(1026); - -+ ok($tf->start_proc == 0, "Starting lighttpd") or goto cleanup; -+ - $t->{REQUEST} = ( <{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => 'bar&a=b' } ]; - ok($tf->handle_http($t) == 0, 'valid request'); - -+ $t->{REQUEST} = ( <{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => 'a=b' } ]; -+ ok($tf->handle_http($t) == 0, 'valid request with url encoded characters'); -+ - ok($tf->stop_proc == 0, "Stopping lighttpd"); - } -+ -+SKIP: { -+ skip "PHP not started, cannot stop it", 1 unless $php_child != -1; -+ ok(0 == $tf->endspawnfcgi($php_child), "Stopping php"); -+} -+ -+ -+exit 0; -+ -+cleanup: ; -+ -+$tf->endspawnfcgi($php_child) if $php_child != -1; -+ -+die(); -Index: tests/lighttpd.conf -=================================================================== ---- tests/lighttpd.conf (.../tags/lighttpd-1.4.19) (revision 2303) -+++ tests/lighttpd.conf (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -3,7 +3,6 @@ - debug.log-response-header = "enable" - debug.log-condition-handling = "enable" - server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" --server.pid-file = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid" - - ## 64 Mbyte ... nice limit - server.max-request-size = 65000 -Index: tests/fastcgi-responder.conf -=================================================================== ---- tests/fastcgi-responder.conf (.../tags/lighttpd-1.4.19) (revision 2303) -+++ tests/fastcgi-responder.conf (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -1,5 +1,4 @@ - server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" --server.pid-file = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid" - - #debug.log-request-header = "enable" - #debug.log-response-header = "enable" -Index: tests/fastcgi-auth.conf -=================================================================== ---- tests/fastcgi-auth.conf (.../tags/lighttpd-1.4.19) (revision 2303) -+++ tests/fastcgi-auth.conf (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -1,5 +1,4 @@ - server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" --server.pid-file = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid" - - debug.log-request-header = "enable" - debug.log-response-header = "enable" -Index: tests/proxy.conf -=================================================================== ---- tests/proxy.conf (.../tags/lighttpd-1.4.19) (revision 2303) -+++ tests/proxy.conf (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -1,5 +1,4 @@ - server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/" --server.pid-file = env.SRCDIR + "/tmp/lighttpd/lighttpd-proxy.pid" - - ## bind to port (default: 80) - server.port = 2050 -Index: tests/docroot/www/get-env.php -=================================================================== ---- tests/docroot/www/get-env.php (.../tags/lighttpd-1.4.19) (revision 2303) -+++ tests/docroot/www/get-env.php (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -1,3 +1,4 @@ - -Index: tests/docroot/www/Makefile.am -=================================================================== ---- tests/docroot/www/Makefile.am (.../tags/lighttpd-1.4.19) (revision 2303) -+++ tests/docroot/www/Makefile.am (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -1,4 +1,4 @@ --EXTRA_DIST=cgi.php cgi.pl dummydir index.html index.txt phpinfo.php \ -+EXTRA_DIST=cgi.php cgi.pl index.html index.txt phpinfo.php \ - redirect.php cgi-pathinfo.pl get-env.php get-server-env.php \ - nph-status.pl prefix.fcgi get-header.pl ssi.shtml get-post-len.pl \ - exec-date.shtml index.html~ 404.fcgi 404.html 404.pl send404.pl crlfcrash.pl -Index: tests/Makefile.am -=================================================================== ---- tests/Makefile.am (.../tags/lighttpd-1.4.19) (revision 2303) -+++ tests/Makefile.am (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -42,8 +42,6 @@ - mod-redirect.t \ - mod-rewrite.t \ - mod-userdir.t \ -- env-variables.t \ -- env-variables.conf \ - symlink.t \ - request.t \ - mod-ssi.t \ - -Property changes on: tests/core-404-handler.t -___________________________________________________________________ -Added: svn:executable - + * - -Index: tests/LightyTest.pm -=================================================================== ---- tests/LightyTest.pm (.../tags/lighttpd-1.4.19) (revision 2303) -+++ tests/LightyTest.pm (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -6,6 +6,7 @@ - use Test::More; - use Socket; - use Cwd 'abs_path'; -+use POSIX ":sys_wait_h"; - - sub mtime { - my $file = shift; -@@ -30,14 +31,17 @@ - - - if (mtime($self->{BASEDIR}.'/src/lighttpd') > mtime($self->{BASEDIR}.'/build/lighttpd')) { -- $self->{LIGHTTPD_PATH} = $self->{BASEDIR}.'/src/lighttpd'; -- $self->{MODULES_PATH} = $self->{BASEDIR}.'/src/.libs'; -+ $self->{BINDIR} = $self->{BASEDIR}.'/src'; -+ if (mtime($self->{BASEDIR}.'/src/.libs')) { -+ $self->{MODULES_PATH} = $self->{BASEDIR}.'/src/.libs'; -+ } else { -+ $self->{MODULES_PATH} = $self->{BASEDIR}.'/src'; -+ } - } else { -- $self->{LIGHTTPD_PATH} = $self->{BASEDIR}.'/build/lighttpd'; -+ $self->{BINDIR} = $self->{BASEDIR}.'/build'; - $self->{MODULES_PATH} = $self->{BASEDIR}.'/build'; - } -- $self->{LIGHTTPD_PIDFILE} = $self->{TESTDIR}.'/tmp/lighttpd/lighttpd.pid'; -- $self->{PIDOF_PIDFILE} = $self->{TESTDIR}.'/tmp/lighttpd/pidof.pid'; -+ $self->{LIGHTTPD_PATH} = $self->{BINDIR}.'/lighttpd'; - $self->{PORT} = 2048; - - my ($name, $aliases, $addrtype, $net) = gethostbyaddr(inet_aton("127.0.0.1"), AF_INET); -@@ -66,59 +70,73 @@ - sub stop_proc { - my $self = shift; - -- open F, $self->{LIGHTTPD_PIDFILE} or return -1; -- my $pid = ; -- close F; -+ my $pid = $self->{LIGHTTPD_PID}; -+ if (defined $pid && $pid != -1) { -+ kill('TERM', $pid) or return -1; -+ return -1 if ($pid != waitpid($pid, 0)); -+ } else { -+ diag("Process not started, nothing to stop"); -+ return -1; -+ } - -- if (defined $pid) { -- kill('TERM',$pid) or return -1; -+ return 0; -+} -+ -+sub wait_for_port_with_proc { -+ my $self = shift; -+ my $port = shift; -+ my $child = shift; -+ -+ while (0 == $self->listening_on($port)) { - select(undef, undef, undef, 0.1); -+ -+ # the process is gone, we failed -+ if (0 != waitpid($child, WNOHANG)) { -+ return -1; -+ } - } - - return 0; - } - -- - sub start_proc { - my $self = shift; - # kill old proc if necessary -- $self->stop_proc; -+ #$self->stop_proc; - - # pre-process configfile if necessary - # - - $ENV{'SRCDIR'} = $self->{BASEDIR}.'/tests'; -+ $ENV{'PORT'} = $self->{PORT}; - -- unlink($self->{LIGHTTPD_PIDFILE}); -+ my $cmdline = $self->{LIGHTTPD_PATH}." -D -f ".$self->{SRCDIR}."/".$self->{CONFIGFILE}." -m ".$self->{MODULES_PATH}; - if (defined $ENV{"TRACEME"} && $ENV{"TRACEME"} eq 'strace') { -- system("strace -tt -s 512 -o strace ".$self->{LIGHTTPD_PATH}." -D -f ".$self->{SRCDIR}."/".$self->{CONFIGFILE}." -m ".$self->{MODULES_PATH}." &"); -+ $cmdline = "strace -tt -s 512 -o strace ".$cmdline; - } elsif (defined $ENV{"TRACEME"} && $ENV{"TRACEME"} eq 'truss') { -- system("/usr/dtrctkit/bin/dtruss -d -e ".$self->{LIGHTTPD_PATH}." -D -f ".$self->{SRCDIR}."/".$self->{CONFIGFILE}." -m ".$self->{MODULES_PATH}." 2> strace &"); -+ $cmdline = "truss -a -l -w all -v all -o strace ".$cmdline; -+ } elsif (defined $ENV{"TRACEME"} && $ENV{"TRACEME"} eq 'gdb') { -+ $cmdline = "gdb --batch --ex 'run' --ex 'bt' --args ".$cmdline." > gdb.out"; - } elsif (defined $ENV{"TRACEME"} && $ENV{"TRACEME"} eq 'valgrind') { -- system("valgrind --tool=memcheck --show-reachable=yes --leak-check=yes --log-file=valgrind ".$self->{LIGHTTPD_PATH}." -D -f ".$self->{SRCDIR}."/".$self->{CONFIGFILE}." -m ".$self->{MODULES_PATH}." &"); -- } else { -- system($self->{LIGHTTPD_PATH}." -f ".$self->{SRCDIR}."/".$self->{CONFIGFILE}." -m ".$self->{MODULES_PATH}); -+ $cmdline = "valgrind --tool=memcheck --show-reachable=yes --leak-check=yes --log-file=valgrind ".$cmdline; - } -- -- select(undef, undef, undef, 0.1); -- if (not -e $self->{LIGHTTPD_PIDFILE} or 0 == kill 0, `cat $self->{LIGHTTPD_PIDFILE}`) { -- select(undef, undef, undef, 2); -- } -- -- unlink($self->{TESTDIR}."/tmp/cfg.file"); -- -- # no pidfile, we failed -- if (not -e $self->{LIGHTTPD_PIDFILE}) { -- diag(sprintf('Could not find pidfile: %s', $self->{LIGHTTPD_PIDFILE})); -+ # diag("starting lighttpd at :".$self->{PORT}.", cmdline: ".$cmdline ); -+ my $child = fork(); -+ if (not defined $child) { -+ diag("Fork failed"); - return -1; - } -+ if ($child == 0) { -+ exec $cmdline or die($?); -+ } - -- # the process is gone, we failed -- if (0 == kill 0, `cat $self->{LIGHTTPD_PIDFILE}`) { -- diag(sprintf('the process referenced by %s is not up', $self->{LIGHTTPD_PIDFILE})); -+ if (0 != $self->wait_for_port_with_proc($self->{PORT}, $child)) { -+ diag(sprintf('The process %i is not up', $child)); - return -1; - } - -+ $self->{LIGHTTPD_PID} = $child; -+ - 0; - } - -@@ -131,6 +149,7 @@ - - my @request = $t->{REQUEST}; - my @response = $t->{RESPONSE}; -+ my $is_debug = $ENV{"TRACE_HTTP"}; - - my $remote = - IO::Socket::INET->new(Proto => "tcp", -@@ -144,20 +163,27 @@ - - $remote->autoflush(1); - -+ diag("sending request header to ".$host.":".$self->{PORT}) if $is_debug; - foreach(@request) { - # pipeline requests - s/\r//g; - s/\n/$EOL/g; - -- print $remote $_.$BLANK; -+ print $remote $_.$BLANK; -+ diag("<< ".$_) if $is_debug; - } -+ shutdown($remote, 1); # I've stopped writing data -+ diag("... done") if $is_debug; - - my $lines = ""; - -+ diag("receiving response") if $is_debug; - # read everything - while(<$remote>) { - $lines .= $_; -+ diag(">> ".$_) if $is_debug; - } -+ diag("... done") if $is_debug; - - close $remote; - -@@ -187,18 +213,24 @@ - (my $h = $1) =~ tr/[A-Z]/[a-z]/; - - if (defined $resp_hdr{$h}) { -- diag(sprintf("header %s is duplicated: %s and %s\n", -- $h, $resp_hdr{$h}, $2)); -+# diag(sprintf("header '%s' is duplicated: '%s' and '%s'\n", -+# $h, $resp_hdr{$h}, $2)); -+ $resp_hdr{$h} .= ', '.$2; - } else { - $resp_hdr{$h} = $2; - } - } else { -- diag(sprintf("unexpected line '$line'\n")); -+ diag(sprintf("unexpected line '%s'\n", $line)); - return -1; - } - } - } - -+ if (not defined($resp_line)) { -+ diag(sprintf("empty response\n")); -+ return -1; -+ } -+ - $t->{etag} = $resp_hdr{'etag'}; - $t->{date} = $resp_hdr{'date'}; - -@@ -227,7 +259,7 @@ - return -1; - } - } else { -- diag(sprintf("unexpected resp_line '$resp_line'\n")); -+ diag(sprintf("unexpected resp_line '%s'\n", $resp_line)); - return -1; - } - -@@ -237,7 +269,9 @@ - diag(sprintf("body failed: expected '%s', got '%s'\n", $href->{'HTTP-Content'}, $resp_body)); - return -1; - } -- } elsif (defined $href->{'-HTTP-Content'}) { -+ } -+ -+ if (defined $href->{'-HTTP-Content'}) { - if (defined $resp_body && $resp_body ne '') { - diag(sprintf("body failed: expected empty body, got '%s'\n", $resp_body)); - return -1; -@@ -245,7 +279,6 @@ - } - - foreach (keys %{ $href }) { -- ## filter special keys - next if $_ eq 'HTTP-Protocol'; - next if $_ eq 'HTTP-Status'; - next if $_ eq 'HTTP-Content'; -@@ -257,7 +290,6 @@ - my $key_inverted = 0; - - if (substr($k, 0, 1) eq '+') { -- ## the key has to exist, but the value is ignored - $k = substr($k, 1); - $verify_value = 0; - } elsif (substr($k, 0, 1) eq '-') { -@@ -265,11 +297,11 @@ - $k = substr($k, 1); - $key_inverted = 1; - $verify_value = 0; ## skip the value check -- } -+ } - - if ($key_inverted) { - if (defined $resp_hdr{$k}) { -- diag(sprintf("required header '%s' is missing\n", $k)); -+ diag(sprintf("header '%s' MUST not be set\n", $k)); - return -1; - } - } else { -@@ -297,12 +329,38 @@ - - # we should have sucked up everything - if (defined $lines) { -- diag(sprintf("unexpected lines '$lines'\n")); -+ diag(sprintf("unexpected lines '%s'\n", $lines)); - return -1; - } - - return 0; - } -- -+ -+sub spawnfcgi { -+ my ($self, $binary, $port) = @_; -+ my $child = fork(); -+ if (not defined $child) { -+ diag("Couldn't fork\n"); -+ return -1; -+ } -+ if ($child == 0) { -+ my $cmd = $self->{BINDIR}.'/spawn-fcgi -n -p '.$port.' -f "'.$binary.'"'; -+ exec $cmd or die($?); -+ } else { -+ if (0 != $self->wait_for_port_with_proc($port, $child)) { -+ diag(sprintf('The process %i is not up (port %i, %s)', $child, $port, $binary)); -+ return -1; -+ } -+ return $child; -+ } -+} -+ -+sub endspawnfcgi { -+ my ($self, $pid) = @_; -+ return -1 if (-1 == $pid); -+ kill(2, $pid); -+ waitpid($pid, 0); -+ return 0; -+} -+ - 1; -- -Index: tests/run-tests.pl -=================================================================== ---- tests/run-tests.pl (.../tags/lighttpd-1.4.19) (revision 2303) -+++ tests/run-tests.pl (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -3,17 +3,18 @@ - use strict; - - use Test::Harness qw(&runtests $verbose); --$verbose = (defined $ENV{'VERBOSE'} ? $ENV{'VERBOSE'} : 0);; -+$verbose = (defined $ENV{'VERBOSE'} ? $ENV{'VERBOSE'} : 0); -+my $tests = (defined $ENV{'TESTS'} ? $ENV{'TESTS'} : ''); - - my $srcdir = (defined $ENV{'srcdir'} ? $ENV{'srcdir'} : '.'); - - opendir DIR, $srcdir; - my (@fs, $f); - while ($f = readdir(DIR)) { -- if ($f =~ /\.t$/) { -+ if ($f =~ /^(.*)\.t$/) { -+ next if ($tests ne '' and $tests !~ /(^|\s+)$1(\s+|$)/); - push @fs, $srcdir.'/'.$f; - } - } - closedir DIR; - runtests @fs; -- -Index: doc/userdir.txt -=================================================================== ---- doc/userdir.txt (.../tags/lighttpd-1.4.19) (revision 2303) -+++ doc/userdir.txt (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -46,10 +46,10 @@ - Options - ======= - --userdir.path -+userdir.path (required option) - usually it should be set to "public_html" to take ~/public_html/ as the document root - -- Default: empty (document root is the home directory) -+ Default: unset (mod_userdir disabled; set it to "" if you want the home directory to be the document root as it was the default before 1.4.19) - Example: :: - - userdir.path = "public_html" -Index: doc/configuration.txt -=================================================================== ---- doc/configuration.txt (.../tags/lighttpd-1.4.19) (revision 2303) -+++ doc/configuration.txt (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -513,3 +513,6 @@ - - debug.log-request-handling - default: disabled -+ -+debug.log-ssl-noise -+ default: disabled -Index: SConstruct -=================================================================== ---- SConstruct (.../tags/lighttpd-1.4.19) (revision 2303) -+++ SConstruct (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -5,7 +5,7 @@ - from stat import * - - package = 'lighttpd' --version = '1.4.19' -+version = '1.4.20' - - def checkCHeaders(autoconf, hdrs): - p = re.compile('[^A-Z0-9]') -Index: Makefile.am -=================================================================== ---- Makefile.am (.../tags/lighttpd-1.4.19) (revision 2303) -+++ Makefile.am (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -1,3 +1,5 @@ - SUBDIRS=src doc tests cygwin openwrt - --EXTRA_DIST=lighttpd.spec autogen.sh SConstruct -+EXTRA_DIST=autogen.sh SConstruct -+ -+distcleancheck_listfiles = find -type f -exec sh -c 'test -f $(srcdir)/{} || echo {}' ';' -Index: NEWS -=================================================================== ---- NEWS (.../tags/lighttpd-1.4.19) (revision 2303) -+++ NEWS (.../branches/lighttpd-1.4.x) (revision 2303) -@@ -3,8 +3,67 @@ - NEWS - ==== - --- 1.4.19 - -+- 1.4.20 - - -+ * Fix mod_compress to compile with old gcc version (#1592) -+ * Fix mod_extforward to compile with old gcc version (#1591) -+ * Update documentation for #1587 -+ * Fix #285 again: read error after SSL_shutdown (thx marton.illes@balabit.com) and clear the error queue before some other calls (CVE-2008-1531) -+ * Fix mod_magnet: enable "request.method" and "request.protocol" in lighty.env (#1308) -+ * Fix segfault for appending matched parts if there was no regex matching (just give empty strings) (#1601) -+ * Use data_response_init in mod_fastcgi x-sendfile handling for response.headers, fix a small "memleak" (#1628) -+ * Don't send empty Server headers (#1620) -+ * Fix conditional interpretation of core options -+ * Enable escaping of % and $ in redirect/rewrite; only two cases changed their behaviour: "%%" => "%", "$$" => "$" -+ * Fix accesslog port (should be port from the connection, not the "server.port") (#1618) -+ * Fix mod_fastcgi prefix matching: match the prefix always against url, not the absolute filepath (regardless of check-local) -+ * Overwrite Content-Type header in mod_dirlisting instead of inserting (#1614), patch by Henrik Holst -+ * Handle EINTR in mod_cgi during write() (#1640) -+ * Allow all http status codes by default; disable body only for 204,205 and 304; generate error pages for 4xx and 5xx (#1639) -+ * Fix mod_magnet to set con->mode = p->id if it generates content, so returning 4xx/5xx doesn't append an error page -+ * Remove lighttpd.spec* from source, fixing all problems with it ;-) -+ * Do not rely on PATH_MAX (POSIX does not require it) (#580) -+ * Disable logging to access.log if filename is an empty string -+ * Implement a clean way to open /dev/null and use it to close stdin/out/err in the needed places (#624) -+ * merge spawn-fcgi changes from trunk (from @2191) -+ * let spawn-fcgi propagate exit code from spawned fcgi application -+ * close connection after redirect in trigger_b4_dl (thx icy) -+ * close connection in mod_magnet if returned status code -+ * fix bug with IPv6 in mod_evasive (#1579) -+ * fix scgi HTTP/1.* status parsing (#1638), found by met@uberstats.com -+ * [tests] fixed system, use foreground daemons and waitpid -+ * [tests] removed pidfile from test system -+ * [tests] fixed tests needing php running (if not running on port 1026, search php in env[PHP] or /usr/bin/php-cgi) -+ * fixed typo in mod_accesslog (#1699) -+ * replaced buffer_{append,copy}_string with the _len variant where possible (#1732) (thx crypt) -+ * case insensitive match for secdownload md5 token (#1710) -+ * Handle only HEAD, GET and POST in mod_dirlisting (same as in staticfile) (#1687) -+ * fixed mod_secdownload problem with unsigned time_t (#1688) -+ * handle EAGAIN and EINTR for freebsd sendfile (#1675) -+ * Use filedescriptor 0 for mod_scgi spawn socket, redirect STDERR to /dev/null (#1716) -+ * fixed round-robin balancing in mod_proxy (#1715) -+ * fixed EINTR handling for waitpid in mod_fastcgi -+ * mod_{fast,s}cgi: overwrite environment variables (#1722) -+ * inserted many con->mode checks; they should prevent two modules to handle the same request if they shouldn't (#631) -+ * fixed url encoding to encode more characters (#266) -+ * allow digits in [s]cgi env vars (#1712) -+ * fixed dropping last character of evhost pattern (#161) -+ * print helpful error message on conditionals in global block (#1550) -+ * decode url before matching in mod_rewrite (#1720) -+ * fixed conditional patching of ldap filter (#1564) -+ * Match headers case insensitive in response (removing of X-{Sendfile,LIGHTTPD-*}, catching Date/Server) -+ * fixed bug with case-insensitive filenames in mod_userdir (#1589), spotted by "anders1" -+ * fixed format string bugs in mod_accesslog for SYSLOG -+ * replaced fprintf with log_error_write in fastcgi debug -+ * fixed mem leak in ssi expression parser (#1753), thx Take5k -+ * hide some ssl errors per default, enable them with debug.log-ssl-noise (#397) -+ * do not send content-encoding for 304 (#1754), thx yzlai -+ * fix segfault for stat_cache(fam) calls with relative path (without '/', can be triggered by x-sendfile) (#1750) -+ * fix splitting of auth-ldap filter -+ * workaround ldap connection leak if a ldap connection failed (restarting ldap) -+ -+- 1.4.19 - 2008-03-10 -+ - * added support for If-Range: (#1346) - * added support for matching $HTTP["scheme"] in configs - * fixed initgroups() called after chroot (#1384) -Index: .cvsignore +-- 1.4.29 - ++- 1.4.30 - ++ * Always use our 'own' md5 implementation, fixes linking issues on MacOS (fixes #2331) ++ * Limit amount of bytes we send in one go; fixes stalling in one connection and timeouts on slow systems. ++ * [ssl] fix build errors when Elliptic-Curve Diffie-Hellman is disabled ++ * Add static-file.disable-pathinfo option to prevent handling of urls like .../secret.php/image.jpg as static file ++ * Don't overwrite 401 (auth required) with 501 (unknown method) (fixes #2341) ++ * Fix mod_status bug: always showed "0/0" in the "Read" column for uploads (fixes #2351) ++ * [mod_auth] Fix signedness error in http_auth (fixes #2370, CVE-2011-4362) ++ * [ssl] count renegotiations to prevent client renegotiations ++ * [ssl] add option to honor server cipher order (fixes #2364, BEAST attack) ++ * [core] accept dots in ipv6 addresses in host header (fixes #2359) ++ * [ssl] fix ssl connection aborts if files are larger than the MAX_WRITE_LIMIT (256kb) ++ ++- 1.4.29 - 2011-07-03 + * Fix mod_proxy waiting for response even if content-length is 0 (fixes #2259) + * Silence annoying "connection closed: poll() -> ERR" error.log message (fixes #2257) + * mod_cgi: make read buffer as big as incoming data block +Index: CMakeLists.txt =================================================================== - -Property changes on: . -___________________________________________________________________ -Modified: svk:merge - - 152afb58-edef-0310-8abb-c4023f1b3aa9:/branches/lighttpd-1.3.x:499 -152afb58-edef-0310-8abb-c4023f1b3aa9:/branches/lighttpd-1.4.11-ssl-fixes:1346 -152afb58-edef-0310-8abb-c4023f1b3aa9:/branches/lighttpd-merge-1.4.x:1041 -152afb58-edef-0310-8abb-c4023f1b3aa9:/tags/lighttpd-1.4.11:1042 -152afb58-edef-0310-8abb-c4023f1b3aa9:/tags/release-1.3.13:105 -152afb58-edef-0310-8abb-c4023f1b3aa9:/trunk:104 -a98e19e4-a712-0410-8832-6551a15ffc53:/local/branches/lighttpd-1.4.x:1557 -ebd0e9cf-3e47-4385-9dd4-f0e25e97baa2:/local/lighttpd/branches/lighttpd-1.4.x:2164 - + 152afb58-edef-0310-8abb-c4023f1b3aa9:/branches/lighttpd-1.3.x:499 -152afb58-edef-0310-8abb-c4023f1b3aa9:/branches/lighttpd-1.4.11-ssl-fixes:1346 -152afb58-edef-0310-8abb-c4023f1b3aa9:/branches/lighttpd-merge-1.4.x:1041 -152afb58-edef-0310-8abb-c4023f1b3aa9:/tags/lighttpd-1.4.11:1042 -152afb58-edef-0310-8abb-c4023f1b3aa9:/tags/release-1.3.13:105 -152afb58-edef-0310-8abb-c4023f1b3aa9:/trunk:104 -a98e19e4-a712-0410-8832-6551a15ffc53:/local/branches/lighttpd-1.4.x:1557 -ebd0e9cf-3e47-4385-9dd4-f0e25e97baa2:/local/lighttpd/branches/lighttpd-1.4.x:2250 -Added: bzr:revision-info - + timestamp: 2008-09-17 16:23:00.644000053 +0200 -committer: Stefan Bühler -properties: - branch-nick: lighttpd-1.4.x - -Added: bzr:file-ids - + -Added: bzr:revision-id:v3-trunk0 - + 1127 stbuehler@web.de-20080728081644-j4cxnhduw8kbt8um -1128 stbuehler@web.de-20080728084246-axvxdtjsrratxixs -1129 stbuehler@web.de-20080729211700-s8v6nq2cu06qesls -1130 stbuehler@web.de-20080729211726-4yxb6e5dva1cn0lz -1131 stbuehler@web.de-20080729211750-4ulzigswx17uciyu -1132 stbuehler@web.de-20080729211850-nliz3kd0m576ztuu -1133 stbuehler@web.de-20080730163440-dg2y2sbf0u4grmn4 -1134 stbuehler@web.de-20080730173952-kiutzg6geqy7mick -1135 stbuehler@web.de-20080730193616-9kc2ms7rrhv1lkn7 -1136 stbuehler@web.de-20080730211457-z4a6uth1y29glbqh -1137 stbuehler@web.de-20080730213517-b6sjcrdwbmipl334 -1138 stbuehler@web.de-20080731102617-2xw8unjfqic7lsew -1139 stbuehler@web.de-20080731102703-q4tu5a6em9y8xdg0 -1140 stbuehler@web.de-20080731102729-l6vn5b05w9swqbg5 -1141 stbuehler@web.de-20080731102756-oj3d4tnk0l90mj77 -1142 stbuehler@web.de-20080731204442-blw14cj2fkr3l8ly -1143 stbuehler@web.de-20080731204508-imtfnurf922mg7tj -1144 stbuehler@web.de-20080801112347-girnwswdkwm8wuip -1145 stbuehler@web.de-20080801161245-kx1temr529o7xko9 -1146 stbuehler@web.de-20080801175332-oc9e7x8edn1owcc0 -1147 stbuehler@web.de-20080801183454-5i66v0gsdv0cgmia -1148 stbuehler@web.de-20080801192849-6zklfbb832sx0hvr -1149 stbuehler@web.de-20080801203119-o16elp8w854s6lol -1150 stbuehler@web.de-20080802162146-a4v57svc788pwdsv -1151 stbuehler@web.de-20080802162202-9udlc1wuwt09pyh2 -1152 stbuehler@web.de-20080804135803-yuor9ze06px7qta4 -1153 stbuehler@web.de-20080812194728-fupt781o6q058unh -1154 stbuehler@web.de-20080818162116-piz0ukqsaecv2li2 -1155 stbuehler@web.de-20080818235700-94t0xc6ml70zojwq -1156 stbuehler@web.de-20080819163650-1qhwsqszr78cr4xx -1157 stbuehler@web.de-20080819163757-1qq3t1f1wj69t8xs -1158 stbuehler@web.de-20080819163914-rklhkurg8apv85l2 -1159 stbuehler@web.de-20080819163953-tlqew751e43phf5b -1160 stbuehler@web.de-20080819164108-8ogh68sm1uyteawe -1161 stbuehler@web.de-20080819173911-w5bqpb7cp9jmdqye -1162 stbuehler@web.de-20080819222242-c0ta5gnli9p3j35a -1163 stbuehler@web.de-20080820100730-g1bwdh4nqb53ag9u -1164 stbuehler@web.de-20080820100752-9pggugdyfnnps8qu -1165 stbuehler@web.de-20080820164258-v2j00motsrsc5esp -1166 stbuehler@web.de-20080827144628-hi9hf4ch3n1wf9ao -1167 stbuehler@web.de-20080827144903-tfxu4yehlyu5kegc -1168 stbuehler@web.de-20080827155155-7mt92orehbxkh2lh -1169 stbuehler@web.de-20080917142048-zbcwpk39q9ewd516 -1170 stbuehler@web.de-20080917142300-16gzt21x4nbjtj87 - -