/* ====================================================================
 * "THE FOO LICENSE" (Revision 3.14159265358979323844): 
 *
 * <ask@netcetera.dk> wrote this file. As long as you retain this
 * notice you can do whatever you want with this stuff. If it does
 * anything you didn't want it to do, it is of course your own fault.
 * If we meet some day, and you think this stuff is worth it, you
 * can buy me a beer in return. - Ask Bjoern Hansen.
 *
 * ==================================================================== */

/* proxy_add_forward module
 *
 * This module adds a 'X-Forwarded-For' header to outgoing
 * proxy requests like Squid does.
 *
 * You can then get the client ip back on the "proxied host" by
 * setting r->connection->remote_ip from this header.
 *
 * Ask Bjoern Hansen <ask@netcetera.dk>, October 1998

 * Changes:
 *
 * February 1st 2001: Added X-Host and X-Server-Name forwarding.
 * 
 * January 15 2001: Fixed the copyright to not be ASF's since I never
 *                  got around to put this into mod_perl.
 *
 * April 12 2000: Changed the license to the ASF 1.1 license.
 *
 * April 12 2000: Made it so that we append our IP to an existing
 *                "X-Forwarded-For" line instead of clobbering an 
 *                existing one. - <ahosey@systhug.com>
 *
 * June   8 1999: Added instructions on how to compile it into the
 *                frontend apache
 *
 * April 12 1999: Changed the sample code so it doesn't confuse the
 *                C compiler, ydkhr! Thanks to Mike Whitaker for 
 *                noticing. 
 *
 * March  1 1999: Added sample code on how to use the header with
 *                mod_perl
 * 

To use the module you have to compile it into the frontend part of
your server, I usually copy the module to apache-1.3/src/modules/extra/
and use APACI like:

  ./configure --prefix=/usr/local/apache \
     --activate-module=src/modules/extra/mod_proxy_add_forward.c \
     --enable-module=proxy_add_forward [... more apaci options ...]    

You should also be able to compile and use this module as a
dynamically loaded module (DSO).
 
TMTOWTDI, but I usually make the 'backend' part of the system
something like the following:

in startup.pl:

  sub My::ProxyRemoteAddr ($) {
    my $r = shift;

	# we'll only look at the X-Forwarded-For header if the requests
	# comes from our proxy at localhost
	return OK unless ($r->connection->remote_ip eq "127.0.0.1");

	if (my ($ip) = $r->header_in('X-Forwarded-For') =~ /([^,\s]+)$/) {
	  $r->connection->remote_ip($ip);
	}
	
	return OK;
  }

And in httpd.conf:

  PerlPostReadRequestHandler My::ProxyRemoteAddr
 
 */


#include "httpd.h"
#include "http_config.h"
#include "http_core.h"

module MODULE_VAR_EXPORT proxy_add_forward_module;

static int add_forward_header(request_rec *r)
{
    const char *oldvalue;

    if (r->proxyreq) {
	/* If there is an existing header, append our IP to that. */
	if (oldvalue = ap_table_get(r->headers_in, "X-Forwarded-For")) {
	    ap_table_set(r->headers_in, "X-Forwarded-For",
			 ap_pstrcat(r->pool, oldvalue, ", ", 
				    r->connection->remote_ip, NULL));
	}
	else {
          ap_table_set(r->headers_in, "X-Forwarded-For",
                       r->connection->remote_ip);
	}

        ap_table_set(r->headers_in, "X-Host",
                     ap_table_get(r->headers_in, "Host"));

        ap_table_set(r->headers_in, "X-Server-Hostname",
                     r->server->server_hostname);

	return OK;
    }
    return DECLINED;
}

module MODULE_VAR_EXPORT proxy_add_forward_module = {
    STANDARD_MODULE_STUFF,
    NULL,                       /* initializer */
    NULL,                       /* dir config creater */
    NULL,                       /* dir merger --- default is to override */
    NULL,                       /* server config */
    NULL,                       /* merge server configs */
    NULL,                       /* command table */
    NULL,                       /* handlers */
    NULL,                       /* filename translation */
    NULL,                       /* check_user_id */
    NULL,                       /* check auth */
    NULL,                       /* check access */
    NULL,                       /* type_checker */
    add_forward_header,         /* fixups */
    NULL,                       /* logger */
    NULL,                       /* header parser */
    NULL,                       /* child_init */
    NULL,                       /* child_exit */
    NULL                        /* post read-request */
};


