# Revision 2695
-Index: src/base.h
-===================================================================
---- src/base.h (.../tags/lighttpd-1.4.24)
-+++ src/base.h (.../branches/lighttpd-1.4.x)
-@@ -280,6 +280,7 @@
- unsigned short ssl_verifyclient_enforce;
- unsigned short ssl_verifyclient_depth;
- buffer *ssl_verifyclient_username;
-+ unsigned short ssl_verifyclient_export_cert;
-
- unsigned short use_ipv6;
- unsigned short defer_accept;
-Index: src/mod_rewrite.c
-===================================================================
---- src/mod_rewrite.c (.../tags/lighttpd-1.4.24)
-+++ src/mod_rewrite.c (.../branches/lighttpd-1.4.x)
-@@ -9,10 +9,9 @@
- #include <stdlib.h>
- #include <string.h>
-
--typedef struct {
- #ifdef HAVE_PCRE_H
-+typedef struct {
- pcre *key;
--#endif
-
- buffer *value;
-
-@@ -70,7 +69,6 @@
- }
-
- static int rewrite_rule_buffer_append(rewrite_rule_buffer *kvb, buffer *key, buffer *value, int once) {
--#ifdef HAVE_PCRE_H
- size_t i;
- const char *errptr;
- int erroff;
-@@ -109,18 +107,9 @@
- kvb->used++;
-
- return 0;
--#else
-- UNUSED(kvb);
-- UNUSED(value);
-- UNUSED(once);
-- UNUSED(key);
--
-- return -1;
--#endif
- }
-
- static void rewrite_rule_buffer_free(rewrite_rule_buffer *kvb) {
--#ifdef HAVE_PCRE_H
- size_t i;
-
- for (i = 0; i < kvb->size; i++) {
-@@ -130,7 +119,6 @@
- }
-
- if (kvb->ptr) free(kvb->ptr);
--#endif
-
- free(kvb);
- }
-@@ -201,24 +189,29 @@
- ((data_string *)(da->value->data[j]))->key,
- ((data_string *)(da->value->data[j]))->value,
- once)) {
--#ifdef HAVE_PCRE_H
- log_error_write(srv, __FILE__, __LINE__, "sb",
- "pcre-compile failed for", da->value->data[j]->key);
--#else
-- log_error_write(srv, __FILE__, __LINE__, "s",
-- "pcre support is missing, please install libpcre and the headers");
--#endif
- }
- }
- }
-
- return 0;
- }
-+#else
-+static int parse_config_entry(server *srv, array *ca, const char *option) {
-+ static int logged_message = 0;
-+ if (logged_message) return 0;
-+ if (NULL != array_get_element(ca, option)) {
-+ logged_message = 1;
-+ log_error_write(srv, __FILE__, __LINE__, "s",
-+ "pcre support is missing, please install libpcre and the headers");
-+ }
-+ return 0;
-+}
-+#endif
-
- SETDEFAULTS_FUNC(mod_rewrite_set_defaults) {
-- plugin_data *p = p_d;
- size_t i = 0;
--
- config_values_t cv[] = {
- { "url.rewrite-repeat", NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
- { "url.rewrite-once", NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
-@@ -243,33 +236,37 @@
- { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
- };
-
-+#ifdef HAVE_PCRE_H
-+ plugin_data *p = p_d;
-+
- if (!p) return HANDLER_ERROR;
-
- /* 0 */
- p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
-+#else
-+ UNUSED(p_d);
-+#endif
-
- for (i = 0; i < srv->config_context->used; i++) {
-- plugin_config *s;
- array *ca;
-+#ifdef HAVE_PCRE_H
-+ plugin_config *s;
-
- s = calloc(1, sizeof(plugin_config));
- s->rewrite = rewrite_rule_buffer_init();
- s->rewrite_NF = rewrite_rule_buffer_init();
--
-- cv[0].destination = s->rewrite;
-- cv[1].destination = s->rewrite;
-- cv[2].destination = s->rewrite_NF;
-- cv[3].destination = s->rewrite_NF;
-- cv[4].destination = s->rewrite;
-- cv[5].destination = s->rewrite;
--
- p->config_storage[i] = s;
-+#endif
-+
- ca = ((data_config *)srv->config_context->data[i])->value;
-
- if (0 != config_insert_values_global(srv, ca, cv)) {
- return HANDLER_ERROR;
- }
-
-+#ifndef HAVE_PCRE_H
-+# define parse_config_entry(srv, ca, x, option, y) parse_config_entry(srv, ca, option)
-+#endif
- parse_config_entry(srv, ca, s->rewrite, "url.rewrite-once", 1);
- parse_config_entry(srv, ca, s->rewrite, "url.rewrite-final", 1);
- parse_config_entry(srv, ca, s->rewrite_NF, "url.rewrite-if-not-file", 1);
-@@ -280,7 +277,9 @@
-
- return HANDLER_GO_ON;
- }
-+
- #ifdef HAVE_PCRE_H
-+
- #define PATCH(x) \
- p->conf.x = s->x;
- static int mod_rewrite_patch_connection(server *srv, connection *con, plugin_data *p) {
-@@ -330,7 +329,7 @@
-
- return 0;
- }
--#endif
-+
- URIHANDLER_FUNC(mod_rewrite_con_reset) {
- plugin_data *p = p_d;
-
-@@ -345,7 +344,6 @@
- }
-
- static int process_rewrite_rules(server *srv, connection *con, plugin_data *p, rewrite_rule_buffer *kvb) {
--#ifdef HAVE_PCRE_H
- size_t i;
- handler_ctx *hctx;
-
-@@ -444,19 +442,11 @@
- }
- #undef N
- }
--#else
-- UNUSED(srv);
-- UNUSED(con);
-- UNUSED(p);
-- UNUSED(hctx);
-- UNUSED(kvb);
--#endif
-
- return HANDLER_GO_ON;
- }
-
- URIHANDLER_FUNC(mod_rewrite_physical) {
--#ifdef HAVE_PCRE_H
- plugin_data *p = p_d;
- handler_t r;
- stat_cache_entry *sce;
-@@ -480,17 +470,11 @@
- default:
- return r;
- }
--#else
-- UNUSED(srv);
-- UNUSED(con);
-- UNUSED(p_d);
--#endif
-
- return HANDLER_GO_ON;
- }
-
- URIHANDLER_FUNC(mod_rewrite_uri_handler) {
--#ifdef HAVE_PCRE_H
- plugin_data *p = p_d;
-
- mod_rewrite_patch_connection(srv, con, p);
-@@ -498,29 +482,27 @@
- if (!p->conf.rewrite) return HANDLER_GO_ON;
-
- return process_rewrite_rules(srv, con, p, p->conf.rewrite);
--#else
-- UNUSED(srv);
-- UNUSED(con);
-- UNUSED(p_d);
--#endif
-
- return HANDLER_GO_ON;
- }
-+#endif
-
- int mod_rewrite_plugin_init(plugin *p);
- int mod_rewrite_plugin_init(plugin *p) {
- p->version = LIGHTTPD_VERSION_ID;
- p->name = buffer_init_string("rewrite");
-
-+#ifdef HAVE_PCRE_H
- p->init = mod_rewrite_init;
- /* it has to stay _raw as we are matching on uri + querystring
- */
-
- p->handle_uri_raw = mod_rewrite_uri_handler;
- p->handle_physical = mod_rewrite_physical;
-- p->set_defaults = mod_rewrite_set_defaults;
- p->cleanup = mod_rewrite_free;
- p->connection_reset = mod_rewrite_con_reset;
-+#endif
-+ p->set_defaults = mod_rewrite_set_defaults;
-
- p->data = NULL;
-
-Index: src/connections.c
-===================================================================
---- src/connections.c (.../tags/lighttpd-1.4.24)
-+++ src/connections.c (.../branches/lighttpd-1.4.x)
-@@ -807,6 +807,9 @@
- CLEAN(authed_user);
- CLEAN(server_name);
- CLEAN(error_handler);
-+#if defined USE_OPENSSL && ! defined OPENSSL_NO_TLSEXT
-+ CLEAN(tlsext_server_name);
-+#endif
- #undef CLEAN
-
- #define CLEAN(x) \
-@@ -1250,8 +1253,10 @@
-
- if (b > 0) {
- char buf[1024];
-+#if 0
- log_error_write(srv, __FILE__, __LINE__, "sdd",
- "CLOSE-read()", con->fd, b);
-+#endif
-
- /* */
- read(con->fd, buf, sizeof(buf));
-@@ -1621,8 +1626,10 @@
- }
- if (b > 0) {
- char buf[1024];
-+#if 0
- log_error_write(srv, __FILE__, __LINE__, "sdd",
- "CLOSE-read()", con->fd, b);
-+#endif
-
- /* */
- read(con->fd, buf, sizeof(buf));
-Index: src/configfile.c
-===================================================================
---- src/configfile.c (.../tags/lighttpd-1.4.24)
-+++ src/configfile.c (.../branches/lighttpd-1.4.x)
-@@ -99,6 +99,7 @@
- { "ssl.verifyclient.enforce", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 57 */
- { "ssl.verifyclient.depth", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_SERVER }, /* 58 */
- { "ssl.verifyclient.username", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 59 */
-+ { "ssl.verifyclient.exportcert", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 60 */
- { "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 },
-@@ -187,6 +188,7 @@
- s->ssl_verifyclient_enforce = 1;
- s->ssl_verifyclient_username = buffer_init();
- s->ssl_verifyclient_depth = 9;
-+ s->ssl_verifyclient_export_cert = 0;
-
- cv[2].destination = s->errorfile_prefix;
-
-@@ -238,6 +240,7 @@
- cv[57].destination = &(s->ssl_verifyclient_enforce);
- cv[58].destination = &(s->ssl_verifyclient_depth);
- cv[59].destination = s->ssl_verifyclient_username;
-+ cv[60].destination = &(s->ssl_verifyclient_export_cert);
-
- srv->config_storage[i] = s;
-
-@@ -325,6 +328,7 @@
- PATCH(ssl_verifyclient_enforce);
- PATCH(ssl_verifyclient_depth);
- PATCH(ssl_verifyclient_username);
-+ PATCH(ssl_verifyclient_export_cert);
-
- return 0;
- }
-@@ -425,6 +429,8 @@
- PATCH(ssl_verifyclient_depth);
- } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.verifyclient.username"))) {
- PATCH(ssl_verifyclient_username);
-+ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.verifyclient.exportcert"))) {
-+ PATCH(ssl_verifyclient_export_cert);
- }
- }
- }
-Index: src/mod_rrdtool.c
-===================================================================
---- src/mod_rrdtool.c (.../tags/lighttpd-1.4.24)
-+++ src/mod_rrdtool.c (.../branches/lighttpd-1.4.x)
-@@ -237,11 +237,11 @@
- "not a regular file:", s->path_rrd);
- return HANDLER_ERROR;
- }
-- }
-
-- /* still create DB if it's empty file */
-- if (st.st_size > 0) {
-- return HANDLER_GO_ON;
-+ /* still create DB if it's empty file */
-+ if (st.st_size > 0) {
-+ return HANDLER_GO_ON;
-+ }
- }
-
- /* create a new one */
-Index: src/response.c
-===================================================================
---- src/response.c (.../tags/lighttpd-1.4.24)
-+++ src/response.c (.../branches/lighttpd-1.4.x)
-@@ -131,8 +131,77 @@
- return 0;
- }
-
-+#ifdef USE_OPENSSL
-+static void https_add_ssl_entries(connection *con) {
-+ X509 *xs;
-+ X509_NAME *xn;
-+ X509_NAME_ENTRY *xe;
-+ if (
-+ SSL_get_verify_result(con->ssl) != X509_V_OK
-+ || !(xs = SSL_get_peer_certificate(con->ssl))
-+ ) {
-+ return;
-+ }
-
-+ xn = X509_get_subject_name(xs);
-+ for (int i = 0, nentries = X509_NAME_entry_count(xn); i < nentries; ++i) {
-+ int xobjnid;
-+ const char * xobjsn;
-+ data_string *envds;
-
-+ if (!(xe = X509_NAME_get_entry(xn, i))) {
-+ continue;
-+ }
-+ xobjnid = OBJ_obj2nid((ASN1_OBJECT*)X509_NAME_ENTRY_get_object(xe));
-+ xobjsn = OBJ_nid2sn(xobjnid);
-+ if (!xobjsn) {
-+ continue;
-+ }
-+
-+ if (NULL == (envds = (data_string *)array_get_unused_element(con->environment, TYPE_STRING))) {
-+ envds = data_string_init();
-+ }
-+ buffer_copy_string_len(envds->key, CONST_STR_LEN("SSL_CLIENT_S_DN_"));
-+ buffer_append_string(envds->key, xobjsn);
-+ buffer_copy_string_len(
-+ envds->value,
-+ (const char *)xe->value->data, xe->value->length
-+ );
-+ /* pick one of the exported values as "authed user", for example
-+ * ssl.verifyclient.username = "SSL_CLIENT_S_DN_UID" or "SSL_CLIENT_S_DN_emailAddress"
-+ */
-+ if (buffer_is_equal(con->conf.ssl_verifyclient_username, envds->key)) {
-+ buffer_copy_string_buffer(con->authed_user, envds->value);
-+ }
-+ array_insert_unique(con->environment, (data_unset *)envds);
-+ }
-+ if (con->conf.ssl_verifyclient_export_cert) {
-+ BIO *bio;
-+ if (NULL != (bio = BIO_new(BIO_s_mem()))) {
-+ data_string *envds;
-+ int n;
-+
-+ PEM_write_bio_X509(bio, xs);
-+ n = BIO_pending(bio);
-+
-+ if (NULL == (envds = (data_string *)array_get_unused_element(con->environment, TYPE_STRING))) {
-+ envds = data_string_init();
-+ }
-+
-+ buffer_copy_string_len(envds->key, CONST_STR_LEN("SSL_CLIENT_CERT"));
-+ buffer_prepare_copy(envds->value, n+1);
-+ BIO_read(bio, envds->value->ptr, n);
-+ BIO_free(bio);
-+ envds->value->ptr[n] = '\0';
-+ envds->value->used = n+1;
-+ array_insert_unique(con->environment, (data_unset *)envds);
-+ }
-+ }
-+ X509_free(xs);
-+}
-+#endif
-+
-+
- handler_t http_response_prepare(server *srv, connection *con) {
- handler_t r;
-
-@@ -279,6 +348,12 @@
- log_error_write(srv, __FILE__, __LINE__, "sb", "URI-path : ", con->uri.path);
- }
-
-+#ifdef USE_OPENSSL
-+ if (con->conf.is_ssl && con->conf.ssl_verifyclient) {
-+ https_add_ssl_entries(con);
-+ }
-+#endif
-+
- /**
- *
- * call plugins
-Index: src/mod_fastcgi.c
-===================================================================
---- src/mod_fastcgi.c (.../tags/lighttpd-1.4.24)
-+++ src/mod_fastcgi.c (.../branches/lighttpd-1.4.x)
-@@ -2416,8 +2416,8 @@
-
- static int fastcgi_get_packet(server *srv, handler_ctx *hctx, fastcgi_response_packet *packet) {
- chunk * c;
-- size_t offset = 0;
-- size_t toread = 0;
-+ size_t offset;
-+ size_t toread;
- FCGI_Header *header;
-
- if (!hctx->rb->first) return -1;
-@@ -2428,20 +2428,22 @@
- packet->padding = 0;
- packet->request_id = 0;
-
-+ offset = 0; toread = 8;
- /* get at least the FastCGI header */
- for (c = hctx->rb->first; c; c = c->next) {
-- size_t weWant = sizeof(*header) - (packet->b->used - 1);
- size_t weHave = c->mem->used - c->offset - 1;
-
-- if (weHave > weWant) weHave = weWant;
-+ if (weHave > toread) weHave = toread;
-
- if (packet->b->used == 0) {
- buffer_copy_string_len(packet->b, c->mem->ptr + c->offset, weHave);
- } else {
- buffer_append_string_len(packet->b, c->mem->ptr + c->offset, weHave);
- }
-+ toread -= weHave;
-+ offset = weHave; /* skip offset bytes in chunk for "real" data */
-
-- if (packet->b->used >= sizeof(*header) + 1) break;
-+ if (0 == toread) break;
- }
-
- if ((packet->b->used == 0) ||
-@@ -2449,7 +2451,9 @@
- /* no header */
- buffer_free(packet->b);
-
-- log_error_write(srv, __FILE__, __LINE__, "sdsds", "FastCGI: header too small:", packet->b->used, "bytes <", sizeof(FCGI_Header), "bytes");
-+ if (hctx->plugin_data->conf.debug) {
-+ log_error_write(srv, __FILE__, __LINE__, "sdsds", "FastCGI: header too small:", packet->b->used, "bytes <", sizeof(FCGI_Header), "bytes, waiting for more data");
-+ }
- return -1;
- }
-
-@@ -2461,9 +2465,6 @@
- packet->type = header->type;
- packet->padding = header->paddingLength;
-
-- /* the first bytes in packet->b are the header */
-- offset = sizeof(*header);
--
- /* ->b should only be the content */
- buffer_copy_string_len(packet->b, CONST_STR_LEN("")); /* used == 1 */
-
-@@ -2477,7 +2478,7 @@
-
- buffer_append_string_len(packet->b, c->mem->ptr + c->offset + offset, weHave);
-
-- /* we only skipped the first 8 bytes as they are the fcgi header */
-+ /* we only skipped the first bytes as they belonged to the fcgi header */
- offset = 0;
- }
-
-@@ -3080,34 +3081,17 @@
-
- if (ret < 0) {
- switch(errno) {
-+ case EPIPE:
- case ENOTCONN:
-+ case ECONNRESET:
- /* the connection got dropped after accept()
-- *
-- * this is most of the time a PHP which dies
-- * after PHP_FCGI_MAX_REQUESTS
-- *
-+ * we don't care about that - if you accept() it, you have to handle it.
- */
-- if (hctx->wb->bytes_out == 0 &&
-- hctx->reconnects < 5) {
-- usleep(10000); /* take away the load of the webserver
-- * to give the php a chance to restart
-- */
-
-- fcgi_reconnect(srv, hctx);
--
-- return HANDLER_WAIT_FOR_FD;
-- }
--
-- /* not reconnected ... why
-- *
-- * far@#lighttpd report this for FreeBSD
-- *
-- */
--
-- log_error_write(srv, __FILE__, __LINE__, "ssosd",
-- "[REPORT ME] connection was dropped after accept(). reconnect() denied:",
-+ log_error_write(srv, __FILE__, __LINE__, "ssosb",
-+ "connection was dropped after accept() (perhaps the fastcgi process died),",
- "write-offset:", hctx->wb->bytes_out,
-- "reconnect attempts:", hctx->reconnects);
-+ "socket:", hctx->proc->connection_name);
-
- return HANDLER_ERROR;
- default:
-Index: src/mod_magnet.c
-===================================================================
---- src/mod_magnet.c (.../tags/lighttpd-1.4.24)
-+++ src/mod_magnet.c (.../branches/lighttpd-1.4.x)
-@@ -170,6 +170,7 @@
- return lua_gettop(L);
- } else {
- lua_pushvalue(L, lua_upvalueindex(1));
-+ lua_insert(L, 1);
- lua_call(L, lua_gettop(L) - 1, LUA_MULTRET);
- return lua_gettop(L);
- }
-@@ -824,9 +825,36 @@
- return 0;
- }
-
-+static int traceback (lua_State *L) {
-+ if (!lua_isstring(L, 1)) /* 'message' not a string? */
-+ return 1; /* keep it intact */
-+ lua_getfield(L, LUA_GLOBALSINDEX, "debug");
-+ if (!lua_istable(L, -1)) {
-+ lua_pop(L, 1);
-+ return 1;
-+ }
-+ lua_getfield(L, -1, "traceback");
-+ if (!lua_isfunction(L, -1)) {
-+ lua_pop(L, 2);
-+ return 1;
-+ }
-+ lua_pushvalue(L, 1); /* pass error message */
-+ lua_pushinteger(L, 2); /* skip this function and traceback */
-+ lua_call(L, 2, 1); /* call debug.traceback */
-+ return 1;
-+}
-+
-+static int push_traceback(lua_State *L, int narg) {
-+ int base = lua_gettop(L) - narg; /* function index */
-+ lua_pushcfunction(L, traceback);
-+ lua_insert(L, base);
-+ return base;
-+}
-+
- static handler_t magnet_attract(server *srv, connection *con, plugin_data *p, buffer *name) {
- lua_State *L;
- int lua_return_value = -1;
-+ int errfunc;
- /* get the script-context */
-
-
-@@ -955,7 +983,9 @@
-
- lua_setfenv(L, -2); /* on the stack should be a modified env (sp -= 1) */
-
-- if (lua_pcall(L, 0, 1, 0)) {
-+ errfunc = push_traceback(L, 0);
-+ if (lua_pcall(L, 0, 1, errfunc)) {
-+ lua_remove(L, errfunc);
- log_error_write(srv, __FILE__, __LINE__,
- "ss",
- "lua_pcall():",
-@@ -969,6 +999,7 @@
-
- return HANDLER_FINISHED;
- }
-+ lua_remove(L, errfunc);
-
- /* we should have the function-copy and the return value on the stack */
- assert(lua_gettop(L) == 2);
Index: configure.ac
===================================================================
-Index: doc/Makefile.am
-===================================================================
---- doc/Makefile.am (.../tags/lighttpd-1.4.24)
-+++ doc/Makefile.am (.../branches/lighttpd-1.4.x)
-@@ -89,7 +89,7 @@
- rst2html $^ > $@
-
-
--html: $(HTMLDOCS)
-+html-local: $(HTMLDOCS)
-
- #%.ps.gz: %.ps
- # gzip $^
Index: SConstruct
===================================================================
Index: NEWS
===================================================================
---- NEWS (.../tags/lighttpd-1.4.24)
+--- NEWS (.../tags/lighttpd-1.4.25)
+++ NEWS (.../branches/lighttpd-1.4.x)
-@@ -3,7 +3,22 @@
+@@ -3,7 +3,10 @@
NEWS
====
--- 1.4.24 -
+-- 1.4.25 -
+- 1.4.26 -
+ *
+
+- 1.4.25 - 2009-11-21
-+ * mod_magnet: fix pairs() for normal tables and strings (fixes #1307)
-+ * mod_magnet: add traceback for printing lua errors
-+ * mod_rewrite: fix compile error if compiled without pcre
-+ * disable warning "CLOSE-read" (fixes #2091)
-+ * mod_rrdtool: fix creating file if it doesn't exist (#1788)
-+ * reset tlsext_server_name in connection_reset - fixes random hostnames in the $HTTP["host"] conditional
-+ * export some SSL_CLIENT_* vars for client cert validation (fixes #1288, thx presbrey)
-+ * mod_fastcgi: fix mod_fastcgi packet parsing
-+ * mod_fastcgi: Don't reconnect after connect() succeeded (fixes #2096)
-+ * Fix configure.ac to allow autoreconf, also enables make V=0
-+
-+- 1.4.24 - 2009-10-25
- * Add T_CONFIG_INT for bigger integers from the config (needed for #1966)
- * Use unsigned int (and T_CONFIG_INT) for max_request_size
- * Use unsigned int for secdownload.timeout (fixes #1966)
+ * mod_magnet: fix pairs() for normal tables and strings (fixes #1307)
+ * mod_magnet: add traceback for printing lua errors
+ * mod_rewrite: fix compile error if compiled without pcre
Index: CMakeLists.txt
===================================================================