/* ====================================================================
 * Copyright (c) 1995-1997 The Apache Group.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the Apache Group
 *    for use in the Apache HTTP server project (http://www.apache.org/)."
 *
 * 4. The names "Apache Server" and "Apache Group" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission.
 *
 * 5. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the Apache Group
 *    for use in the Apache HTTP server project (http://www.apache.org/)."
 *
 * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Group and was originally based
 * on public domain software written at the National Center for
 * Supercomputing Applications, University of Illinois, Urbana-Champaign.
 * For more information on the Apache Group and the Apache HTTP server
 * project, please see <http://www.apache.org/>.
 *
 */

/* 
 * "Transparent Proxy" Module.
 * (c) 1997 Steve Kann <SteveK@stevek.com>
 * This module is designed to be used in conjunction with Linux'
 * IP TRANSPARENT PROXY firewalling, or any similar system on another
 * operating system.  Transparent Proxying redirects tcp connections 
 * destined for a foreign host to a local port.  A local server can then accept
 * the connection, and act as a proxy.  getsockname will reveal the original
 * destination host.
 * It should be used with a Ipfwadm command like: 
 * ipfwadm -I -S "your-network" -D 0.0.0.0/0 80 -a accept -P tcp -r 8080  
 * Where 8080, in this example is the port you're running apache on.
 *
 */

#include "httpd.h"
#include "http_config.h"
#include "http_core.h"
#include "http_log.h"
#include "http_main.h"
#include "http_protocol.h"
#include "util_script.h"

#include <stdio.h>

/*--------------------------------------------------------------------------*/
/*                                                                          */
/* Data declarations.                                                       */
/*                                                                          */
/* Here are the static cells and structure declarations private to our      */
/* module.                                                                  */
/*                                                                          */
/*--------------------------------------------------------------------------*/

/*
 * Declare ourselves so the configuration routines can find and know us.
 * We'll fill it in at the end of the module.
 */
module tproxy_module;

/*
 * This routine gives our module an opportunity to translate the URI into an
 * actual filename.  If we don't do anything special, the server's default
 * rules (Alias directives and the like) will continue to be followed.
 *
 * The return value is OK, DECLINED, or HTTP_mumble.  If we return OK, no
 * further modules are called for this phase.
 */
static int tproxy_translate_handler(request_rec *r)
{
	struct sockaddr_in local_addr;	
	char * uri;
	char * host;
	char buf[256];

	local_addr = r->connection->local_addr;

	/* XXX - this will cause us to not do this stuff for connections
	 really destined for this server.  It should really also check 
	 to make sure the address isn't a valid local address as well.
	*/
	if(ntohs(local_addr.sin_port) == r->server->port)	
		return DECLINED;

#ifdef DEBUG
	fprintf(stderr, "tproxy: XLAT %s -> ", r->uri);
#endif

	buf[0]=0;				
	host = table_get(r->headers_in, "Host");
	
	if(ntohs(local_addr.sin_port) != 80)
		sprintf(buf,"%d", ntohs(local_addr.sin_port));

	/* construct the proxy URI: 
	 * we use the hostname in the Host: line if we can, so we
	 * use the cache more effectively (or else Round-robin DNS
	 * would defeat the cache somewhat).
	 */
	r->uri = pstrcat(r->pool, "http://", 
		host ? host : inet_ntoa(local_addr.sin_addr),
		buf[0] ? ":" : "", buf, r->uri,
		r->path_info ? r->path_info : "",
		r->args ? "?" : NULL, r->args,
		NULL);

	/* now make sure the request gets handled by the proxy handler */
	r->proxyreq = 1;
	r->handler  = "proxy-server";

#ifdef DEBUG
	fprintf(stderr, "%s\n", r->uri);
#endif
	return DECLINED;	

}

/*                                                                          */
/* All of the routines have been declared now.  Here's the list of          */
/* directives specific to our module, and information about where they      */
/* may appear and how the command parser should pass them to us for         */
/* processing.  Note that care must be taken to ensure that there are NO    */
/* collisions of directive names between modules.                           */
/*                                                                          */
/*--------------------------------------------------------------------------*/
/* 
 * List of directives specific to our module.
 */
command_rec tproxy_cmds[] =
{
    {NULL}
};

handler_rec example_handlers[] =
{
    {NULL}
};

/*--------------------------------------------------------------------------*/
/*                                                                          */
/* Finally, the list of callback routines and data structures that          */
/* provide the hooks into our module from the other parts of the server.    */
/*                                                                          */
/*--------------------------------------------------------------------------*/
/* 
 * Module definition for configuration.  If a particular callback is not
 * needed, replace its routine name below with the word NULL.
 *
 * The number in brackets indicates the order in which the routine is called
 * during request processing.  Note that not all routines are necessarily
 * called (such as if a resource doesn't have access restrictions).
 */
module tproxy_module =
{
    STANDARD_MODULE_STUFF,
    NULL,               /* module initializer */
    NULL,  /* per-directory config creator */
    NULL,   /* dir config merger */
    NULL,       /* server config creator */
    NULL,        /* server config merger */
    NULL,               /* command table */
    NULL,           /* [7] list of handlers */
    tproxy_translate_handler,  /* [2] filename-to-URI translation */
    NULL,      /* [5] check/validate user_id */
    NULL,       /* [6] check user_id is valid *here* */
    NULL,     /* [4] check access by host address */
    NULL,       /* [7] MIME type checker/setter */
    NULL,        /* [8] fixups */
    NULL,             /* [10] logger */
    NULL,      /* [3] header parser */
    NULL,         /* process initializer */
    NULL,         /* process exit/cleanup */
    NULL   /* [1] post read_request handling */
};
