From: Elan Ruusamäe Date: Wed, 28 Mar 2007 09:17:56 +0000 (+0000) Subject: - updated to 1706 X-Git-Tag: auto/ac/lighttpd-1_4_13-9~2 X-Git-Url: http://git.pld-linux.org/?p=packages%2Flighttpd.git;a=commitdiff_plain;h=cf0fe2e1c62db8273ff3e5b4b3a509b4ef85ec80 - updated to 1706 Changed files: lighttpd-branch.diff -> 1.13 --- diff --git a/lighttpd-branch.diff b/lighttpd-branch.diff index d4c2eb6..4140c35 100644 --- a/lighttpd-branch.diff +++ b/lighttpd-branch.diff @@ -1,7 +1,46 @@ +Index: configure.in +=================================================================== +--- configure.in (.../tags/lighttpd-1.4.13) (revision 1706) ++++ configure.in (.../branches/lighttpd-1.4.x) (revision 1706) +@@ -398,7 +398,7 @@ + + AC_MSG_RESULT($WITH_LUA) + if test "$WITH_LUA" != "no"; then +- if test "$WITH_LUA" == "yes"; then ++ if test "$WITH_LUA" = "yes"; then + WITH_LUA=lua + fi + PKG_CHECK_MODULES(LUA, $WITH_LUA >= 5.1, [ +@@ -538,7 +538,7 @@ + AC_OUTPUT + + +-do_build="mod_cgi mod_fastcgi mod_proxy mod_evhost mod_simple_vhost mod_access mod_alias mod_setenv mod_usertrack mod_auth mod_status mod_accesslog mod_rrdtool mod_secdownload mod_expire mod_compress mod_dirlisting mod_indexfiles mod_userdir mod_webdav mod_staticfile mod_scgi mod_flv_streaming" ++do_build="mod_cgi mod_fastcgi mod_extforward mod_proxy mod_evhost mod_simple_vhost mod_access mod_alias mod_setenv mod_usertrack mod_auth mod_status mod_accesslog mod_rrdtool mod_secdownload mod_expire mod_compress mod_dirlisting mod_indexfiles mod_userdir mod_webdav mod_staticfile mod_scgi mod_flv_streaming" + + plugins="mod_rewrite mod_redirect mod_ssi mod_trigger_b4_dl" + features="regex-conditionals" +Index: src/mod_cgi.c +=================================================================== +--- src/mod_cgi.c (.../tags/lighttpd-1.4.13) (revision 1706) ++++ src/mod_cgi.c (.../branches/lighttpd-1.4.x) (revision 1706) +@@ -842,6 +842,12 @@ + CONST_BUF_LEN(con->authed_user)); + } + ++#ifdef USE_OPENSSL ++ if (srv_sock->is_ssl) { ++ cgi_env_add(&env, CONST_STR_LEN("HTTPS"), CONST_STR_LEN("on")); ++ } ++#endif ++ + /* request.content_length < SSIZE_MAX, see request.c */ + ltostr(buf, con->request.content_length); + cgi_env_add(&env, CONST_STR_LEN("CONTENT_LENGTH"), buf, strlen(buf)); Index: src/base.h =================================================================== ---- src/base.h (.../tags/lighttpd-1.4.13) (revision 1664) -+++ src/base.h (.../branches/lighttpd-1.4.x) (revision 1664) +--- src/base.h (.../tags/lighttpd-1.4.13) (revision 1706) ++++ src/base.h (.../branches/lighttpd-1.4.x) (revision 1706) @@ -481,7 +481,9 @@ enum { STAT_CACHE_ENGINE_UNSET, STAT_CACHE_ENGINE_NONE, @@ -14,9 +53,17 @@ Index: src/base.h } server_config; Index: src/connections.c =================================================================== ---- src/connections.c (.../tags/lighttpd-1.4.13) (revision 1664) -+++ src/connections.c (.../branches/lighttpd-1.4.x) (revision 1664) -@@ -970,7 +970,7 @@ +--- src/connections.c (.../tags/lighttpd-1.4.13) (revision 1706) ++++ src/connections.c (.../branches/lighttpd-1.4.x) (revision 1706) +@@ -500,6 +500,7 @@ + case 201: + case 301: + case 302: ++ case 303: + break; + + case 206: /* write_queue is already prepared */ +@@ -970,7 +971,7 @@ } } else { /* a splited \r \n */ @@ -27,8 +74,8 @@ Index: src/connections.c } Index: src/configfile.c =================================================================== ---- src/configfile.c (.../tags/lighttpd-1.4.13) (revision 1664) -+++ src/configfile.c (.../branches/lighttpd-1.4.x) (revision 1664) +--- src/configfile.c (.../tags/lighttpd-1.4.13) (revision 1706) ++++ src/configfile.c (.../branches/lighttpd-1.4.x) (revision 1706) @@ -218,13 +218,19 @@ srv->srvconf.stat_cache_engine = STAT_CACHE_ENGINE_SIMPLE; } else if (buffer_is_equal_string(stat_cache_string, CONST_STR_LEN("simple"))) { @@ -52,8 +99,8 @@ Index: src/configfile.c Index: src/mod_scgi.c =================================================================== ---- src/mod_scgi.c (.../tags/lighttpd-1.4.13) (revision 1664) -+++ src/mod_scgi.c (.../branches/lighttpd-1.4.x) (revision 1664) +--- src/mod_scgi.c (.../tags/lighttpd-1.4.13) (revision 1706) ++++ src/mod_scgi.c (.../branches/lighttpd-1.4.x) (revision 1706) @@ -2528,7 +2528,7 @@ hctx->reconnects < 5) { scgi_reconnect(srv, hctx); @@ -65,8 +112,8 @@ Index: src/mod_scgi.c "fcgi-fd:", hctx->fd); Index: src/request.c =================================================================== ---- src/request.c (.../tags/lighttpd-1.4.13) (revision 1664) -+++ src/request.c (.../branches/lighttpd-1.4.x) (revision 1664) +--- src/request.c (.../tags/lighttpd-1.4.13) (revision 1706) ++++ src/request.c (.../branches/lighttpd-1.4.x) (revision 1706) @@ -85,6 +85,9 @@ /* Host is empty */ if (host_len == 0) return -1; @@ -79,8 +126,8 @@ Index: src/request.c const char c = host->ptr[i]; Index: src/network_backends.h =================================================================== ---- src/network_backends.h (.../tags/lighttpd-1.4.13) (revision 1664) -+++ src/network_backends.h (.../branches/lighttpd-1.4.x) (revision 1664) +--- src/network_backends.h (.../tags/lighttpd-1.4.13) (revision 1706) ++++ src/network_backends.h (.../branches/lighttpd-1.4.x) (revision 1706) @@ -14,7 +14,7 @@ # include #endif @@ -92,8 +139,8 @@ Index: src/network_backends.h #endif Index: src/mod_proxy.c =================================================================== ---- src/mod_proxy.c (.../tags/lighttpd-1.4.13) (revision 1664) -+++ src/mod_proxy.c (.../branches/lighttpd-1.4.x) (revision 1664) +--- src/mod_proxy.c (.../tags/lighttpd-1.4.13) (revision 1706) ++++ src/mod_proxy.c (.../branches/lighttpd-1.4.x) (revision 1706) @@ -656,6 +656,7 @@ } @@ -102,10 +149,540 @@ Index: src/mod_proxy.c log_error_write(srv, __FILE__, __LINE__, "sds", "unexpected end-of-file (perhaps the proxy process died):", proxy_fd, strerror(errno)); +Index: src/mod_extforward.c +=================================================================== +--- src/mod_extforward.c (.../tags/lighttpd-1.4.13) (revision 0) ++++ src/mod_extforward.c (.../branches/lighttpd-1.4.x) (revision 1706) +@@ -0,0 +1,490 @@ ++#include ++#include ++#include ++#include ++#include ++ ++#include "base.h" ++#include "log.h" ++#include "buffer.h" ++ ++#include "plugin.h" ++ ++#include "inet_ntop_cache.h" ++#ifdef HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++/** ++ * mod_extforward.c for lighttpd, by comman.kang gmail com ++ * extended, modified by Lionel Elie Mamane (LEM), lionel mamane lu ++ * ++ * Config example: ++ * ++ * Trust proxy 10.0.0.232 and 10.0.0.232 ++ * extforward.forwarder = ( "10.0.0.232" => "trust", ++ * "10.0.0.233" => "trust" ) ++ * ++ * Trust all proxies (NOT RECOMMENDED!) ++ * extforward.forwarder = ( "all" => "trust") ++ * ++ * Note that "all" has precedence over specific entries, ++ * so "all except" setups will not work. ++ * ++ * Note: The effect of this module is variable on $HTTP["remotip"] directives and ++ * other module's remote ip dependent actions. ++ * Things done by modules before we change the remoteip or after we reset it will match on the proxy's IP. ++ * Things done in between these two moments will match on the real client's IP. ++ * The moment things are done by a module depends on in which hook it does things and within the same hook ++ * on whether they are before/after us in the module loading order ++ * (order in the server.modules directive in the config file). ++ * ++ * Tested behaviours: ++ * ++ * mod_access: Will match on the real client. ++ * ++ * mod_accesslog: ++ * In order to see the "real" ip address in access log , ++ * you'll have to load mod_extforward after mod_accesslog. ++ * like this: ++ * ++ * server.modules = ( ++ * ..... ++ * mod_accesslog, ++ * mod_extforward ++ * ) ++ * ++ * Known issues: ++ * seems causing segfault with mod_ssl and $HTTP{"socket"} directives ++ * LEM 2006.05.26: Fixed segfault $SERVER["socket"] directive. Untested with SSL. ++ * ++ * ChangeLog: ++ * 2005.12.19 Initial Version ++ * 2005.12.19 fixed conflict with conditional directives ++ * 2006.05.26 LEM: IPv6 support ++ * 2006.05.26 LEM: Fix a segfault with $SERVER["socket"] directive. ++ * 2006.05.26 LEM: Run at uri_raw time, as we don't need to see the URI ++ * In this manner, we run before mod_access and $HTTP["remoteip"] directives work! ++ * 2006.05.26 LEM: Clean config_cond cache of tests whose result we probably change. ++ */ ++ ++ ++/* plugin config for all request/connections */ ++ ++typedef struct { ++ array *forwarder; ++} plugin_config; ++ ++typedef struct { ++ PLUGIN_DATA; ++ ++ plugin_config **config_storage; ++ ++ plugin_config conf; ++} plugin_data; ++ ++ ++/* context , used for restore remote ip */ ++ ++typedef struct { ++ sock_addr saved_remote_addr; ++ buffer *saved_remote_addr_buf; ++} handler_ctx; ++ ++ ++static handler_ctx * handler_ctx_init(sock_addr oldaddr, buffer *oldaddr_buf) { ++ handler_ctx * hctx; ++ hctx = calloc(1, sizeof(*hctx)); ++ hctx->saved_remote_addr = oldaddr; ++ hctx->saved_remote_addr_buf = oldaddr_buf; ++ return hctx; ++} ++ ++static void handler_ctx_free(handler_ctx *hctx) { ++ free(hctx); ++} ++ ++/* init the plugin data */ ++INIT_FUNC(mod_extforward_init) { ++ plugin_data *p; ++ p = calloc(1, sizeof(*p)); ++ return p; ++} ++ ++/* destroy the plugin data */ ++FREE_FUNC(mod_extforward_free) { ++ plugin_data *p = p_d; ++ ++ UNUSED(srv); ++ ++ if (!p) return HANDLER_GO_ON; ++ ++ if (p->config_storage) { ++ size_t i; ++ ++ for (i = 0; i < srv->config_context->used; i++) { ++ plugin_config *s = p->config_storage[i]; ++ ++ if (!s) continue; ++ ++ array_free(s->forwarder); ++ ++ free(s); ++ } ++ free(p->config_storage); ++ } ++ ++ ++ free(p); ++ ++ return HANDLER_GO_ON; ++} ++ ++/* handle plugin config and check values */ ++ ++SETDEFAULTS_FUNC(mod_extforward_set_defaults) { ++ plugin_data *p = p_d; ++ size_t i = 0; ++ ++ config_values_t cv[] = { ++ { "extforward.forwarder", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 0 */ ++ { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } ++ }; ++ ++ if (!p) return HANDLER_ERROR; ++ ++ p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); ++ ++ for (i = 0; i < srv->config_context->used; i++) { ++ plugin_config *s; ++ ++ s = calloc(1, sizeof(plugin_config)); ++ s->forwarder = array_init(); ++ ++ cv[0].destination = s->forwarder; ++ ++ p->config_storage[i] = s; ++ ++ if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) { ++ return HANDLER_ERROR; ++ } ++ } ++ ++ return HANDLER_GO_ON; ++} ++ ++#define PATCH(x) \ ++ p->conf.x = s->x; ++static int mod_extforward_patch_connection(server *srv, connection *con, plugin_data *p) { ++ size_t i, j; ++ plugin_config *s = p->config_storage[0]; ++ ++ PATCH(forwarder); ++ ++ /* LEM: The purpose of this seems to match extforward configuration ++ stanzas that are not in the global context, but in some sub-context. ++ I fear this will break contexts of the form HTTP['remote'] = . ++ (in the form that they do not work with the real remote, but matching on ++ the proxy instead). ++ ++ I'm not sure this this is all thread-safe. Is the p we are passed different ++ for each connection or is it global? ++ ++ mod_fastcgi does the same, so it must be safe. ++ */ ++ /* skip the first, the global context */ ++ for (i = 1; i < srv->config_context->used; i++) { ++ data_config *dc = (data_config *)srv->config_context->data[i]; ++ s = p->config_storage[i]; ++ ++ /* condition didn't match */ ++ if (!config_check_cond(srv, con, dc)) continue; ++ ++ /* merge config */ ++ for (j = 0; j < dc->value->used; j++) { ++ data_unset *du = dc->value->data[j]; ++ ++ if (buffer_is_equal_string(du->key, CONST_STR_LEN("extforward.forwarder"))) { ++ PATCH(forwarder); ++ } ++ } ++ } ++ ++ return 0; ++} ++#undef PATCH ++ ++ ++static void put_string_into_array_len(array *ary, const char *str, int len) ++{ ++ data_string *tempdata; ++ if (len == 0) ++ return; ++ tempdata = data_string_init(); ++ buffer_copy_string_len(tempdata->value,str,len); ++ array_insert_unique(ary,(data_unset *)tempdata); ++} ++/* ++ extract a forward array from the environment ++*/ ++static array *extract_forward_array(buffer *pbuffer) ++{ ++ array *result = array_init(); ++ if (pbuffer->used > 0) { ++ char *base, *curr; ++ /* state variable, 0 means not in string, 1 means in string */ ++ int in_str = 0; ++ for (base = pbuffer->ptr, curr = pbuffer->ptr; *curr; curr++) ++ { ++ if (in_str) { ++ if ( (*curr > '9' || *curr < '0') && *curr != '.' && *curr != ':' ) { ++ /* found an separator , insert value into result array */ ++ put_string_into_array_len(result, base, curr-base); ++ /* change state to not in string */ ++ in_str = 0; ++ } ++ } else { ++ if (*curr >= '0' && *curr <= '9') ++ { ++ /* found leading char of an IP address, move base pointer and change state */ ++ base = curr; ++ in_str = 1; ++ } ++ } ++ } ++ /* if breaking out while in str, we got to the end of string, so add it */ ++ if (in_str) ++ { ++ put_string_into_array_len(result, base, curr-base); ++ } ++ } ++ return result; ++} ++ ++#define IP_TRUSTED 1 ++#define IP_UNTRUSTED 0 ++/* ++ check whether ip is trusted, return 1 for trusted , 0 for untrusted ++*/ ++static int is_proxy_trusted(const char *ipstr, plugin_data *p) ++{ ++ data_string* allds = (data_string *) array_get_element(p->conf.forwarder,"all"); ++ if (allds) { ++ if (strcasecmp(allds->value->ptr,"trust") == 0) ++ return IP_TRUSTED; ++ else ++ return IP_UNTRUSTED; ++ } ++ return (data_string *)array_get_element(p->conf.forwarder,ipstr) ? IP_TRUSTED : IP_UNTRUSTED ; ++} ++ ++struct addrinfo *ipstr_to_sockaddr(const char *host) ++{ ++ struct addrinfo hints, *res0; ++ int result; ++ memset(&hints, 0, sizeof(hints)); ++ hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV; ++ ++ result = getaddrinfo(host, NULL, &hints, &res0); ++ if ( result != 0 ) ++ { ++ fprintf(stderr,"could not resolve hostname %s because %s\n", host,gai_strerror(result)); ++ if (result == EAI_SYSTEM) ++ perror("The system error is "); ++ return NULL; ++ } ++ else ++ if (res0==0) ++ fprintf(stderr, "Problem in resolving hostname %s: succeeded, but no information returned\n", host); ++ ++ return res0; ++} ++ ++ ++static void clean_cond_cache(server *srv, connection *con) ++{ ++ size_t i; ++ ++ for (i = 0; i < srv->config_context->used; i++) { ++ data_config *dc = (data_config *)srv->config_context->data[i]; ++ ++ if (dc->comp == COMP_HTTP_REMOTEIP) ++ { ++ con->cond_cache[i].result = COND_RESULT_UNSET; ++ con->cond_cache[i].patterncount = 0; ++ } ++ } ++} ++ ++URIHANDLER_FUNC(mod_extforward_uri_handler) { ++ plugin_data *p = p_d; ++ data_string *forwarded = NULL; ++#ifdef HAVE_IPV6 ++ char b2[INET6_ADDRSTRLEN + 1]; ++#endif ++ const char *s; ++ UNUSED(srv); ++ mod_extforward_patch_connection(srv, con, p); ++ ++/* log_error_write(srv, __FILE__, __LINE__,"s","mod_extforward_uri_handler called\n"); */ ++ ++ /* if the remote ip itself is not trusted , then do nothing */ ++#ifdef HAVE_IPV6 ++ s = inet_ntop(con->dst_addr.plain.sa_family, ++ con->dst_addr.plain.sa_family == AF_INET6 ? ++ &(con->dst_addr.ipv6.sin6_addr) : ++ &(con->dst_addr.ipv4.sin_addr), ++ b2, ++ (sizeof b2) - 1); ++#else ++ s = inet_ntoa(con->dst_addr.ipv4.sin_addr); ++#endif ++ if (IP_UNTRUSTED == is_proxy_trusted (s, p) ) ++ return HANDLER_GO_ON; ++ ++ /* log_error_write(srv, __FILE__, __LINE__,"s","remote address is trusted proxy, go on\n");*/ ++ if (con->request.headers && ++ ((forwarded = (data_string *) array_get_element(con->request.headers,"X-Forwarded-For")) || ++ (forwarded = (data_string *) array_get_element(con->request.headers, "Forwarded-For")))) ++ { ++ /* log_error_write(srv, __FILE__, __LINE__,"s","found forwarded header\n");*/ ++ /* found forwarded for header */ ++ int i; ++ array *forward_array = extract_forward_array(forwarded->value); ++ char *real_remote_addr = NULL; ++#ifdef HAVE_IPV6 ++ struct addrinfo *addrlist = NULL; ++#endif ++ /* Testing shows that multiple headers and multiple values in one header ++ come in _reverse_ order. So the first one we get is the last one in the request. */ ++ for (i = forward_array->used - 1; i >= 0; i--) ++ { ++ data_string *ds = (data_string *) forward_array->data[i]; ++ if (ds) { ++/* log_error_write(srv, __FILE__, __LINE__,"ss","forward",ds->value->ptr); */ ++ real_remote_addr = ds->value->ptr; ++ break; ++ /* LEM: What the hell is this about? ++ We test whether the forwarded for IP is trusted? ++ This looks like an ugly hack to handle multiple Forwarded-For's ++ and avoid those set to our proxies, or something like that. ++ My testing shows that reverse proxies add a new X-Forwarded-For header, ++ and we should thus take the last one, which is the first one we see. ++ ++ The net result of the old code is that we use the first untrusted IP, ++ or if all are trusted, the last trusted IP. ++ That's crazy. So I've disabled this. ++ */ ++ /* check whether it is trusted */ ++/* if (IP_UNTRUSTED == is_proxy_trusted(ds->value->ptr,p) ) */ ++/* break; */ ++/* log_error_write(srv, __FILE__, __LINE__,"ss",ds->value->ptr," is trusted."); */ ++ ++ } ++ else { ++ /* bug ? bailing out here */ ++ break; ++ } ++ } ++ if (real_remote_addr != NULL) /* parsed */ ++ { ++ sock_addr s; ++ struct addrinfo *addrs_left; ++/* log_error_write(srv, __FILE__, __LINE__,"ss","use forward",real_remote_addr); */ ++#ifdef HAVE_IPV6 ++ addrlist = ipstr_to_sockaddr(real_remote_addr); ++ s.plain.sa_family = AF_UNSPEC; ++ for (addrs_left = addrlist; addrs_left != NULL; ++ addrs_left = addrs_left -> ai_next) ++ { ++ s.plain.sa_family = addrs_left->ai_family; ++ if ( s.plain.sa_family == AF_INET ) ++ { ++ s.ipv4.sin_addr = ((struct sockaddr_in*)addrs_left->ai_addr)->sin_addr; ++ break; ++ } ++ else if ( s.plain.sa_family == AF_INET6 ) ++ { ++ s.ipv6.sin6_addr = ((struct sockaddr_in6*)addrs_left->ai_addr)->sin6_addr; ++ break; ++ } ++ } ++#else ++ s.ipv4.sin_addr.s_addr = inet_addr(real_remote_addr); ++ s.plain.sa_family = (s.ipv4.sin_addr.s_addr == 0xFFFFFFFF) ? AF_UNSPEC : AF_INET; ++#endif ++ if (s.plain.sa_family != AF_UNSPEC) ++ { ++ /* we found the remote address, modify current connection and save the old address */ ++ if (con->plugin_ctx[p->id]) { ++ log_error_write(srv, __FILE__, __LINE__,"patching an already patched connection!"); ++ handler_ctx_free(con->plugin_ctx[p->id]); ++ con->plugin_ctx[p->id] = NULL; ++ } ++ /* save old address */ ++ con->plugin_ctx[p->id] = handler_ctx_init(con->dst_addr, con->dst_addr_buf); ++ /* patch connection address */ ++ con->dst_addr = s; ++ con->dst_addr_buf = buffer_init(); ++ buffer_copy_string(con->dst_addr_buf, real_remote_addr); ++/* log_error_write(srv, __FILE__, __LINE__,"ss","Set dst_addr_buf to ", real_remote_addr); */ ++ /* Now, clean the conf_cond cache, because we may have changed the results of tests */ ++ clean_cond_cache(srv, con); ++ } ++#ifdef HAVE_IPV6 ++ if (addrlist != NULL ) freeaddrinfo(addrlist); ++#endif ++ } ++ array_free(forward_array); ++ } ++ ++ /* not found */ ++ return HANDLER_GO_ON; ++} ++ ++CONNECTION_FUNC(mod_extforward_restore) { ++ plugin_data *p = p_d; ++ UNUSED(srv); ++ ++ /* LEM: This seems completely unuseful, as we are not using ++ p->conf in this function. Furthermore, it brings a ++ segfault if one of the conditional configuration ++ blocks is "SERVER['socket'] == foo", because the ++ socket is not known yet in the srv/con structure. ++ */ ++ /* mod_extforward_patch_connection(srv, con, p); */ ++ ++ /* restore this connection's remote ip */ ++ if (con->plugin_ctx[p->id]) { ++ handler_ctx *hctx = con->plugin_ctx[p->id]; ++ con->dst_addr = hctx->saved_remote_addr; ++ buffer_free(con->dst_addr_buf); ++ con->dst_addr_buf = hctx->saved_remote_addr_buf; ++/* log_error_write(srv, __FILE__, __LINE__,"s","LEM: Reset dst_addr_buf"); */ ++ handler_ctx_free(hctx); ++ con->plugin_ctx[p->id] = NULL; ++ /* Now, clean the conf_cond cache, because we may have changed the results of tests */ ++ clean_cond_cache(srv, con); ++ } ++ return HANDLER_GO_ON; ++} ++ ++ ++/* this function is called at dlopen() time and inits the callbacks */ ++ ++int mod_extforward_plugin_init(plugin *p) { ++ p->version = LIGHTTPD_VERSION_ID; ++ p->name = buffer_init_string("extforward"); ++ ++ p->init = mod_extforward_init; ++ p->handle_uri_raw = mod_extforward_uri_handler; ++ p->handle_request_done = mod_extforward_restore; ++ p->connection_reset = mod_extforward_restore; ++ p->set_defaults = mod_extforward_set_defaults; ++ p->cleanup = mod_extforward_free; ++ ++ p->data = NULL; ++ ++ return 0; ++} ++ + +Property changes on: src/mod_extforward.c +___________________________________________________________________ +Name: svn:eol-style + + native + +Index: src/Makefile.am +=================================================================== +--- src/Makefile.am (.../tags/lighttpd-1.4.13) (revision 1706) ++++ src/Makefile.am (.../branches/lighttpd-1.4.x) (revision 1706) +@@ -199,6 +199,11 @@ + mod_fastcgi_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined + mod_fastcgi_la_LIBADD = $(common_libadd) + ++lib_LTLIBRARIES += mod_extforward.la ++mod_extforward_la_SOURCES = mod_extforward.c ++mod_extforward_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined ++mod_extforward_la_LIBADD = $(common_libadd) ++ + lib_LTLIBRARIES += mod_access.la + mod_access_la_SOURCES = mod_access.c + mod_access_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined +Index: src/network_writev.c +=================================================================== +--- src/network_writev.c (.../tags/lighttpd-1.4.13) (revision 1706) ++++ src/network_writev.c (.../branches/lighttpd-1.4.x) (revision 1706) +@@ -55,7 +55,7 @@ + const size_t max_chunks = MAX_IOVEC; + #elif defined(UIO_MAXIOV) /* Linux x86 (glibc-2.2.5-233) */ + const size_t max_chunks = UIO_MAXIOV; +-#elif (defined(__FreeBSD__) && __FreeBSD_version < 500000) /* FreeBSD 4.x */ ++#elif (defined(__FreeBSD__) && __FreeBSD_version < 500000) || defined(__DragonFly__) /* FreeBSD 4.x */ + const size_t max_chunks = 1024; /* UIO_MAXIOV value from sys/uio.h */ + #else + #error "sysconf() doesnt return _SC_IOV_MAX ..., check the output of 'man writev' for the EINVAL error and send the output to jan@kneschke.de" Index: src/mod_expire.c =================================================================== ---- src/mod_expire.c (.../tags/lighttpd-1.4.13) (revision 1664) -+++ src/mod_expire.c (.../branches/lighttpd-1.4.x) (revision 1664) +--- src/mod_expire.c (.../tags/lighttpd-1.4.13) (revision 1706) ++++ src/mod_expire.c (.../branches/lighttpd-1.4.x) (revision 1706) @@ -85,7 +85,7 @@ /* * parse @@ -155,8 +732,8 @@ Index: src/mod_expire.c } else if (0 == strcmp(ts, "hours")) { Index: src/network_freebsd_sendfile.c =================================================================== ---- src/network_freebsd_sendfile.c (.../tags/lighttpd-1.4.13) (revision 1664) -+++ src/network_freebsd_sendfile.c (.../branches/lighttpd-1.4.x) (revision 1664) +--- src/network_freebsd_sendfile.c (.../tags/lighttpd-1.4.13) (revision 1706) ++++ src/network_freebsd_sendfile.c (.../branches/lighttpd-1.4.x) (revision 1706) @@ -25,7 +25,7 @@ @@ -168,8 +745,8 @@ Index: src/network_freebsd_sendfile.c # endif Index: src/http_auth.c =================================================================== ---- src/http_auth.c (.../tags/lighttpd-1.4.13) (revision 1664) -+++ src/http_auth.c (.../branches/lighttpd-1.4.x) (revision 1664) +--- src/http_auth.c (.../tags/lighttpd-1.4.13) (revision 1706) ++++ src/http_auth.c (.../branches/lighttpd-1.4.x) (revision 1706) @@ -733,8 +733,9 @@ } } @@ -183,8 +760,8 @@ Index: src/http_auth.c buffer_append_string_buffer(p->ldap_filter, username); Index: src/http_auth.h =================================================================== ---- src/http_auth.h (.../tags/lighttpd-1.4.13) (revision 1664) -+++ src/http_auth.h (.../branches/lighttpd-1.4.x) (revision 1664) +--- src/http_auth.h (.../tags/lighttpd-1.4.13) (revision 1706) ++++ src/http_auth.h (.../branches/lighttpd-1.4.x) (revision 1706) @@ -36,6 +36,7 @@ buffer *auth_ldap_filter; buffer *auth_ldap_cafile; @@ -195,8 +772,8 @@ Index: src/http_auth.h Index: src/mod_auth.c =================================================================== ---- src/mod_auth.c (.../tags/lighttpd-1.4.13) (revision 1664) -+++ src/mod_auth.c (.../branches/lighttpd-1.4.x) (revision 1664) +--- src/mod_auth.c (.../tags/lighttpd-1.4.13) (revision 1706) ++++ src/mod_auth.c (.../branches/lighttpd-1.4.x) (revision 1706) @@ -113,6 +113,7 @@ PATCH(auth_ldap_filter); PATCH(auth_ldap_cafile); @@ -242,8 +819,8 @@ Index: src/mod_auth.c ca = ((data_config *)srv->config_context->data[i])->value; Index: src/mod_fastcgi.c =================================================================== ---- src/mod_fastcgi.c (.../tags/lighttpd-1.4.13) (revision 1664) -+++ src/mod_fastcgi.c (.../branches/lighttpd-1.4.x) (revision 1664) +--- src/mod_fastcgi.c (.../tags/lighttpd-1.4.13) (revision 1706) ++++ src/mod_fastcgi.c (.../branches/lighttpd-1.4.x) (revision 1706) @@ -275,6 +275,7 @@ buffer *key; /* like .php */ @@ -264,7 +841,7 @@ Index: src/mod_fastcgi.c * check how much we have to read */ if (ioctl(hctx->fd, FIONREAD, &toread)) { -+ if( errno == EAGAIN ) return 0; ++ if (errno == EAGAIN) return 0; log_error_write(srv, __FILE__, __LINE__, "sd", "unexpected end-of-file (perhaps the fastcgi process died):", fcgi_fd); @@ -280,7 +857,7 @@ Index: src/mod_fastcgi.c /* append to read-buffer */ if (-1 == (r = read(hctx->fd, b->ptr, toread))) { -+ if( errno == EAGAIN ) { ++ if (errno == EAGAIN) { + /* roll back the last chunk allocation, + and continue on next iteration */ + buffer_free(hctx->rb->last->mem); @@ -296,7 +873,7 @@ Index: src/mod_fastcgi.c b->used = r + 1; /* one extra for the fake \0 */ b->ptr[b->used - 1] = '\0'; } else { -+ if( errno == EAGAIN ) return 0; ++ if (errno == EAGAIN) return 0; log_error_write(srv, __FILE__, __LINE__, "ssdsb", "unexpected end-of-file (perhaps the fastcgi process died):", "pid:", proc->pid, @@ -351,8 +928,8 @@ Index: src/mod_fastcgi.c /* Index: src/server.c =================================================================== ---- src/server.c (.../tags/lighttpd-1.4.13) (revision 1664) -+++ src/server.c (.../branches/lighttpd-1.4.x) (revision 1664) +--- src/server.c (.../tags/lighttpd-1.4.13) (revision 1706) ++++ src/server.c (.../branches/lighttpd-1.4.x) (revision 1706) @@ -163,6 +163,7 @@ #undef CLEAN @@ -391,6 +968,141 @@ Index: src/server.c if (0 != unlink(srv->srvconf.pid_file->ptr)) { if (errno != EACCES && errno != EPERM) { log_error_write(srv, __FILE__, __LINE__, "sbds", +Index: doc/extforward.txt +=================================================================== +--- doc/extforward.txt (.../tags/lighttpd-1.4.13) (revision 0) ++++ doc/extforward.txt (.../branches/lighttpd-1.4.x) (revision 1706) +@@ -0,0 +1,96 @@ ++============== ++mod_extforward ++============== ++ ++.. contents:: ++ ++Overview ++======== ++ ++Comman Kang sent me: :: ++ ++ Hello jan. ++ ++ I've made something rough but similar to mod_extract_forwarded for ++ Apache. This module will extract the client's "real" ip from ++ X-Forwarded-For header which is added by squid or other proxies. It might be ++ useful for servers behind reverse proxy servers. ++ ++ However, this module is causing segfault with mod_ssl or ++ $HTTP{''socket"} directive, crashing in config_check_cond while patching ++ connection , I do not understand architecture of the lighttpd well, does it ++ need to call patch_connection in either handle_request_done and ++ connection_reset ? ++ ++Lionel Elie Mamane improved the patch: :: ++ ++ I've taken lighttpd-1.4.10-mod_extforward.c from the wiki and I've ++ extended it. Here is the result. ++ ++ Major changes: ++ ++ - IPv6 support ++ ++ - Fixed at least one segfault with SERVER['socket'] ++ ++ - Arrange things so that a url.access-deny under scope of a ++ HTTP['remoteip'] condition works well :) ++ ++ I've commented the code in some places, mostly where I wasn't sure ++ what was going on, or I didn't see what the original author meant to ++ do. ++ ++Options ++======= ++ ++extforward.forwarder ++ Sets trust level of proxy IP's. ++ ++ Default: empty ++ ++ Example: :: ++ ++ extforward.forwarder = ("10.0.0.232" => "trust") ++ ++ will translate ip addresses coming from 10.0.0.232 to real ip addresses extracted from X-Forwarded-For: HTTP request header. ++ ++Note ++======= ++ ++The effect of this module is variable on $HTTP["remotip"] directives and other module's remote ip dependent actions. ++Things done by modules before we change the remoteip or after we reset it will match on the proxy's IP. ++Things done in between these two moments will match on the real client's IP. ++The moment things are done by a module depends on in which hook it does things and within the same hook ++on whether they are before/after us in the module loading order ++(order in the server.modules directive in the config file). ++ ++Tested behaviours: ++ ++ mod_access: Will match on the real client. ++ ++ mod_accesslog: ++ In order to see the "real" ip address in access log , ++ you'll have to load mod_extforward after mod_accesslog. ++ like this: :: ++ ++ server.modules = ( ++ ..... ++ mod_accesslog, ++ mod_extforward ++ ) ++ ++Samples ++======= ++ ++Trust proxy 10.0.0.232 and 10.0.0.232 :: ++ ++ extforward.forwarder = ( ++ "10.0.0.232" => "trust", ++ "10.0.0.233" => "trust", ++ ) ++ ++Trust all proxies (NOT RECOMMENDED!) :: ++ ++ extforward.forwarder = ( "all" => "trust") ++ ++Note that "all" has precedence over specific entries, so "all except" setups will not work. +Index: doc/Makefile.am +=================================================================== +--- doc/Makefile.am (.../tags/lighttpd-1.4.13) (revision 1706) ++++ doc/Makefile.am (.../branches/lighttpd-1.4.x) (revision 1706) +@@ -6,6 +6,7 @@ + cgi.txt \ + compress.txt \ + configuration.txt \ ++extforward.txt \ + fastcgi-state.txt \ + fastcgi.txt \ + features.txt \ +@@ -43,6 +44,7 @@ + cgi.html \ + compress.html \ + configuration.html \ ++ extforward.html \ + fastcgi-state.html \ + fastcgi.html \ + features.html \ +Index: NEWS +=================================================================== +--- NEWS (.../tags/lighttpd-1.4.13) (revision 1706) ++++ NEWS (.../branches/lighttpd-1.4.x) (revision 1706) +@@ -3,6 +3,9 @@ + NEWS + ==== + ++- 1.4.14 - ??? ++ * added mod_extforward module [1665] ++ + - 1.4.13 - 2006-10-09 + + * added initgroups in spawn-fcgi (#871) Property changes on: . ___________________________________________________________________