Browse Source

Make mod_extforward headers configurable (fixes #1545)

git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2482 152afb58-edef-0310-8abb-c4023f1b3aa9
svn/tags/lighttpd-1.4.23
Stefan Bühler 13 years ago
parent
commit
4c7c0b815e
  1. 1
      NEWS
  2. 13
      doc/extforward.txt
  3. 97
      src/mod_extforward.c

1
NEWS

@ -30,6 +30,7 @@ NEWS
* Add option to enable TCP_DEFER_ACCEPT (fixes #1447)
* Limit amount of bytes read for one read-event (fixes #1070)
* Add evasive.silent option (fixes #1438)
* Make mod_extforward headers configurable (fixes #1545)
- 1.4.22 - 2009-03-07
* Fix wrong lua type for CACHE_MISS/CACHE_HIT in mod_cml (fixes #533)

13
doc/extforward.txt

@ -49,10 +49,19 @@ extforward.forwarder
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.
will translate ip addresses coming from 10.0.0.232 to real ip addresses extracted from "X-Forwarded-For" or "Forwarded-For" HTTP request header.
extforward.headers
Sets headers to search for finding the originl addresses.
Example (for use with a Zeus ZXTM loadbalancer): ::
extforward.headers = ("X-Cluster-Client-Ip")
Default: empty, results in searching for "X-Forwarded-For" and "Forwarded-For"
Note
=======

97
src/mod_extforward.c

@ -80,6 +80,7 @@
typedef struct {
array *forwarder;
array *headers;
} plugin_config;
typedef struct {
@ -135,6 +136,7 @@ FREE_FUNC(mod_extforward_free) {
if (!s) continue;
array_free(s->forwarder);
array_free(s->headers);
free(s);
}
@ -154,7 +156,8 @@ SETDEFAULTS_FUNC(mod_extforward_set_defaults) {
size_t i = 0;
config_values_t cv[] = {
{ "extforward.forwarder", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
{ "extforward.forwarder", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
{ "extforward.headers", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
{ NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
};
@ -167,8 +170,10 @@ SETDEFAULTS_FUNC(mod_extforward_set_defaults) {
s = calloc(1, sizeof(plugin_config));
s->forwarder = array_init();
s->headers = array_init();
cv[0].destination = s->forwarder;
cv[1].destination = s->headers;
p->config_storage[i] = s;
@ -187,6 +192,7 @@ static int mod_extforward_patch_connection(server *srv, connection *con, plugin_
plugin_config *s = p->config_storage[0];
PATCH(forwarder);
PATCH(headers);
/* skip the first, the global context */
for (i = 1; i < srv->config_context->used; i++) {
@ -202,6 +208,8 @@ static int mod_extforward_patch_connection(server *srv, connection *con, plugin_
if (buffer_is_equal_string(du->key, CONST_STR_LEN("extforward.forwarder"))) {
PATCH(forwarder);
} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("extforward.headers"))) {
PATCH(headers);
}
}
}
@ -294,37 +302,37 @@ static const char *last_not_in_array(array *a, plugin_data *p)
return NULL;
}
static struct addrinfo *ipstr_to_sockaddr(const char *host)
{
struct addrinfo hints, *res0;
int result;
static struct addrinfo *ipstr_to_sockaddr(const char *host) {
struct addrinfo hints, *res0;
int result;
memset(&hints, 0, sizeof(hints));
memset(&hints, 0, sizeof(hints));
#ifndef AI_NUMERICSERV
/**
* quoting $ man getaddrinfo
*
* NOTES
* AI_ADDRCONFIG, AI_ALL, and AI_V4MAPPED are available since glibc 2.3.3.
* AI_NUMERICSERV is available since glibc 2.3.4.
*/
/**
* quoting $ man getaddrinfo
*
* NOTES
* AI_ADDRCONFIG, AI_ALL, and AI_V4MAPPED are available since glibc 2.3.3.
* AI_NUMERICSERV is available since glibc 2.3.4.
*/
#define AI_NUMERICSERV 0
#endif
hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
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;
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;
}
@ -351,16 +359,26 @@ URIHANDLER_FUNC(mod_extforward_uri_handler) {
mod_extforward_patch_connection(srv, con, p);
if (con->conf.log_request_handling) {
log_error_write(srv, __FILE__, __LINE__, "s",
"-- mod_extforward_uri_handler called");
log_error_write(srv, __FILE__, __LINE__, "s",
"-- mod_extforward_uri_handler called");
}
if ((NULL == (forwarded = (data_string *) array_get_element(con->request.headers,"X-Forwarded-For")) &&
NULL == (forwarded = (data_string *) array_get_element(con->request.headers, "Forwarded-For")))) {
if (p->conf.headers->used) {
data_string *ds;
size_t k;
for(k = 0; k < p->conf.headers->used; k++) {
ds = (data_string *) p->conf.headers->data[k];
if (NULL != (forwarded = (data_string*) array_get_element(con->request.headers, ds->value->ptr))) break;
}
} else {
forwarded = (data_string *) array_get_element(con->request.headers,"X-Forwarded-For");
if (NULL == forwarded) forwarded = (data_string *) array_get_element(con->request.headers, "Forwarded-For");
}
if (NULL == forwarded) {
if (con->conf.log_request_handling) {
log_error_write(srv, __FILE__, __LINE__, "s",
"no X-Forwarded-For|Forwarded-For: found, skipping");
log_error_write(srv, __FILE__, __LINE__, "s", "no forward header found, skipping");
}
return HANDLER_GO_ON;
@ -368,11 +386,10 @@ URIHANDLER_FUNC(mod_extforward_uri_handler) {
#ifdef HAVE_IPV6
dst_addr_str = inet_ntop(con->dst_addr.plain.sa_family,
con->dst_addr.plain.sa_family == AF_INET6 ?
(struct sockaddr *)&(con->dst_addr.ipv6.sin6_addr) :
(struct sockaddr *)&(con->dst_addr.ipv4.sin_addr),
b2,
(sizeof b2) - 1);
con->dst_addr.plain.sa_family == AF_INET6 ?
(struct sockaddr *)&(con->dst_addr.ipv6.sin6_addr) :
(struct sockaddr *)&(con->dst_addr.ipv4.sin_addr),
b2, (sizeof b2) - 1);
#else
dst_addr_str = inet_ntoa(con->dst_addr.ipv4.sin_addr);
#endif
@ -439,7 +456,7 @@ URIHANDLER_FUNC(mod_extforward_uri_handler) {
buffer_copy_string(con->dst_addr_buf, real_remote_addr);
if (con->conf.log_request_handling) {
log_error_write(srv, __FILE__, __LINE__, "ss",
log_error_write(srv, __FILE__, __LINE__, "ss",
"patching con->dst_addr_buf for the accesslog:", real_remote_addr);
}
/* Now, clean the conf_cond cache, because we may have changed the results of tests */

Loading…
Cancel
Save