diff -Nrup squid-2.5.STABLE5/src/cache_cf.c squid-2.5.STABLE5-folke/src/cache_cf.c
--- squid-2.5.STABLE5/src/cache_cf.c	Sat Dec  6 18:19:36 2003
+++ squid-2.5.STABLE5-folke/src/cache_cf.c	Fri Jun  4 17:16:30 2004
@@ -605,6 +605,143 @@ free_acl_access(acl_access ** head)
     aclDestroyAccessList(head);
 }
 
+/*
+ * Decode a ascii representation (asc) of a IP adress, and place
+ * adress and netmask information in addr and mask.
+ * This function should NOT be called if 'asc' is a hostname!
+ */
+static int
+fm_decode_addr(const char *asc, struct in_addr *addr, struct in_addr *mask)
+{
+    u_num32 a;
+    int a1 = 0, a2 = 0, a3 = 0, a4 = 0;
+
+    switch (sscanf(asc, "%d.%d.%d.%d", &a1, &a2, &a3, &a4)) {
+    case 4:			/* a dotted quad */
+	if (!safe_inet_addr(asc, addr)) {
+	    debug(90, 0) ("decode_addr: unsafe IP address: '%s'\n", asc);
+	    fatal("decode_addr: unsafe IP address");
+	}
+	break;
+    case 1:			/* a significant bits value for a mask */
+	if (a1 >= 0 && a1 < 33) {
+	    addr->s_addr = a1 ? htonl(0xfffffffful << (32 - a1)) : 0;
+	    break;
+	}
+    default:
+	debug(90, 0) ("decode_addr: Invalid IP address '%s'\n", asc);
+	return 0;		/* This is not valid address */
+    }
+
+    if (mask != NULL) {		/* mask == NULL if called to decode a netmask */
+
+	/* Guess netmask */
+	a = (u_num32) ntohl(addr->s_addr);
+	if (!(a & 0xFFFFFFFFul))
+	    mask->s_addr = htonl(0x00000000ul);
+	else if (!(a & 0x00FFFFFF))
+	    mask->s_addr = htonl(0xFF000000ul);
+	else if (!(a & 0x0000FFFF))
+	    mask->s_addr = htonl(0xFFFF0000ul);
+	else if (!(a & 0x000000FF))
+	    mask->s_addr = htonl(0xFFFFFF00ul);
+	else
+	    mask->s_addr = htonl(0xFFFFFFFFul);
+    }
+    return 1;
+}
+
+static void
+dump_forwardmap(StoreEntry * entry, const char *name, forwardmap * fme)
+{
+    //TODO folke
+    forwardmap *fm=fme;
+    while (fm){
+	storeAppendPrintf(entry, "%s 0x%s ->%s", name, fm->from_uri, fm->to_uri);
+	fm=fm->next;
+    }
+
+}
+
+static void
+parse_forwardmap(forwardmap ** fme)
+{
+    char *token;
+    char *t = strtok(NULL, "");
+    forwardmap *fm;
+    char *confs[6];
+    int cnt;
+    char *c;
+    int i;
+    for (cnt=0;cnt<6;cnt++) confs[cnt]=NULL;
+    cnt=0;
+    /* forwardmap from_ip/from_mask from_port from_uri to_ip to_port to_uri */
+    /* confs[]    0                 1         2        3     4       5      */
+    while ((token = strwordtok(NULL, &t))){
+	//TODO: check "" parameters (and \" escapes)
+	cnt++;
+	if (cnt>6) fatal("Bad forwardmap entry (needs exactly 6 parameters)");
+	confs[cnt-1]=xstrdup(token);
+	debug(90, 10) ("parse_forwardmap: %s\n", token);
+    }
+    if (cnt!=6) fatal("Bad forwardmap entry (needs exactly 6 parameters");
+
+    fm=(forwardmap*)xmalloc(sizeof(forwardmap));
+    memset(&(fm->from_ip), '\0', sizeof(struct in_addr));
+    memset(&(fm->from_mask), '\0', sizeof(struct in_addr));
+    if ((c=strchr(confs[0],'/'))){
+	c++;
+	c[-1]='\0';
+    } else c=NULL;
+    fm_decode_addr(confs[0], &(fm->from_ip), NULL);
+    if (c){
+	if (!fm_decode_addr(c, &(fm->from_mask), NULL)) fatal("Bad source_ip/source_mask");
+    } else {
+	if (!fm_decode_addr("255.255.255.255", &(fm->from_mask), NULL)) fatal("Bad source_ip/source_mask");
+    }
+    fm->from_ip.s_addr &= fm->from_mask.s_addr;
+    i=atoi(confs[1]);
+    if (i<1 || i>65535) fatal("invalid from_port");
+    fm->from_port=i;
+    while (confs[2] && confs[2][strlen(confs[2])]=='/') confs[2][strlen(confs[2])]='\0'; 
+    if (strlen(confs[2])>1) fm->from_uri=xstrdup(confs[2]);
+    else fm->from_uri=NULL;
+    memset(&(fm->to_ip), '\0', sizeof(struct in_addr));
+    if (!fm_decode_addr(confs[3], &(fm->to_ip), NULL)) fatal("Bad to_ip");
+    i=atoi(confs[4]);
+    if (i<1 || i>65535) fatal("invalid to_port");
+    fm->to_port=i;
+    while (confs[5] && confs[5][strlen(confs[5])]=='/') confs[5][strlen(confs[5])]='\0'; 
+    if (strlen(confs[5])>1) fm->to_uri=xstrdup(confs[5]);
+    else fm->to_uri=NULL;
+    fm->next=NULL;
+    
+    if (!*fme){
+	/* we are the first one */
+	*fme=fm;
+    } else{
+	/* goto last one and set there the next (our new) */
+	forwardmap *f=*fme;	
+	while (f && f->next) f=f->next;
+	f->next=fm;
+    }
+
+}
+
+static void
+free_forwardmap(forwardmap ** fme)
+{
+    forwardmap *fm=*fme;
+    forwardmap *next;
+    while (fm){
+	if (fm->from_uri) xfree(fm->from_uri);
+	if (fm->to_uri) xfree(fm->to_uri);
+	next=fm->next;
+	xfree(fm);
+	fm=next;
+    }
+}
+
 static void
 dump_address(StoreEntry * entry, const char *name, struct in_addr addr)
 {
diff -Nrup squid-2.5.STABLE5/src/cf.data.pre squid-2.5.STABLE5-folke/src/cf.data.pre
--- squid-2.5.STABLE5/src/cf.data.pre	Tue Feb 10 22:01:21 2004
+++ squid-2.5.STABLE5-folke/src/cf.data.pre	Fri Jun  4 17:16:30 2004
@@ -3960,4 +3960,37 @@ DOC_START
 	until all the child processes have been started.
 DOC_END
 
+NAME: forwardmap
+TYPE: forwardmap
+LOC: Config.forwardmapList
+DEFAULT: none
+DOC_START
+	forwardmap maps incoming connections based on
+	  * destination ip
+	  * destination port
+	  * request URI
+	to another ip, port and uri.
+	
+	"../.." in URIs are resolved for security reasons.
+	Also we unescape the URI (but not any query strings).
+
+	Syntax:
+	    forwardmap from_ip[/from_mask] from_port from_uri to_ip to_port to_uri
+	
+	from_ is not source, but map-from!
+	The order is importan!  not the best, but the FIRST match is used!
+
+	    
+	Examples:
+	    forwardmap 62.245.218.10 80 /server1 10.0.20.10 80 /
+	    forwardmap 62.245.218.10 80 /server2 10.0.20.11 80 /
+	    forwardmap 62.245.218.11 80 / 10.0.10.4 80 /
+	    forwardmap 62.245.218.11 81 / 10.0.10.4 81 /
+	  If you have dynamic-ip-adreses: you loose! then you can only use 0.0.0.0/0 as from_ip!
+
+NOCOMMENT_START
+
+NOCOMMENT_END
+DOC_END
+
 EOF
diff -Nrup squid-2.5.STABLE5/src/client_side.c squid-2.5.STABLE5-folke/src/client_side.c
--- squid-2.5.STABLE5/src/client_side.c	Wed Feb 18 19:51:16 2004
+++ squid-2.5.STABLE5-folke/src/client_side.c	Fri Jun  4 17:17:06 2004
@@ -2577,6 +2577,7 @@ parseHttpRequest(ConnStateData * conn, m
 #if LINUX_NETFILTER
     size_t sock_sz = sizeof(conn->me);
 #endif
+    int handled = 0;
 
     /* pre-set these values to make aborting simpler */
     *prefix_p = NULL;
@@ -2693,6 +2694,10 @@ parseHttpRequest(ConnStateData * conn, m
 	*t = '\0';
 #endif
 
+
+
+
+    
     /* handle internal objects */
     if (internalCheck(url)) {
 	/* prepend our name & port */
@@ -2701,7 +2706,172 @@ parseHttpRequest(ConnStateData * conn, m
 	http->flags.accel = 1;
     }
     /* see if we running in Config2.Accel.on, if so got to convert it to URL */
-    else if (Config2.Accel.on && *url == '/') {
+    else if (Config.forwardmapList){
+
+	void path_clean(char *p){
+	    /* kicks all // | /./ | /../ out of path */
+	    char * start = p,  * new = p;
+	    if (!p) return;
+	    while (*p){
+		if (*p=='/'){
+		    if (*(p+1)=='/') p++;
+		    else if (!strncmp(p+1, "../", 3)){
+			if (new>start) new--;
+			while (new>start && *new!='/') new--;
+			p+=3;
+			continue;
+		    }
+		    else if (!strncasecmp(p+1, "./", 2)){
+			p+=2;
+			continue;
+		    }
+		}
+		*new=*p;
+		p++;
+		new++;
+	    }
+	    *new='\0';
+	    p=start;
+	}
+
+	FILE *x;
+	forwardmap *fm;
+	forwardmap *fm2;
+	//=NULL, *fm2=NULL;
+	char *url_unescaped;
+	char *url_params;
+	
+	/* folke start */
+	x=fopen("/tmp/sq", "a+");
+	
+
+	/* make string with (not unescaped ?/# part) */
+	url_params=NULL;
+	url_params=strchr(url,'?');
+	if (url_params==NULL) url_params=strchr(url,'#');
+	if (url_params==NULL) url_params=xstrdup("");
+	/* make filename with no ?/# part */
+	url_unescaped=xstrdup(url);
+	  {
+	    char *c;
+	    if ((c=strchr(url_unescaped,'#'))) *c='\0';
+	    if ((c=strchr(url_unescaped,'?'))) *c='\0';
+	  }
+
+	rfc1738_unescape(url_unescaped);
+	path_clean(url_unescaped);
+#if LINUX_NETFILTER
+	    /* If the call fails the address structure will be unchanged */
+	    getsockopt(conn->fd, SOL_IP, SO_ORIGINAL_DST, &conn->me, &sock_sz);
+#endif
+	fprintf(x,"my_addr: %s / my_port: %i ('%s') ('%s') ('%s')\n",
+		    inet_ntoa(http->conn->me.sin_addr),
+		    ntohs(http->conn->me.sin_port),
+		    url_unescaped, url, url_params
+	       );
+	fm=Config.forwardmapList;
+	while (fm){
+	    fprintf(x,"while(fm)\n");
+	    fprintf(x,"http->conn: %p / http->conn->me: %p\n", http->conn, http->conn->me);
+	    fflush(x);
+	    if (
+			(fm->from_ip.s_addr == (http->conn->me.sin_addr.s_addr & fm->from_mask.s_addr)) &&
+			(fm->from_port == ntohs(http->conn->me.sin_port))){
+		fprintf(x,"Matched fm->from_uri '%s'\n", fm->from_uri);
+		fflush(x);
+		if (fm->from_uri==NULL || !strlen(fm->from_uri)){
+		    char *to_uri_esc, *url_esc;
+		    int len;
+		    fprintf(x,"no from_uri\n");
+		    fprintf(x,"url_unescaped '%s'\n", url_unescaped);
+		    fprintf(x,"url '%s'\n", url);
+		    fflush(x);
+		    if (fm->to_uri) to_uri_esc=xstrdup(rfc1738_escape_unescaped(fm->to_uri));
+		    else to_uri_esc=xstrdup("");
+		    url_esc=xstrdup(rfc1738_escape_unescaped(url_unescaped));
+		    len = strlen(to_uri_esc) + strlen(url_esc) +strlen(url_params) + 2;
+		    fprintf(x,"url_esc: '%s' / to_uri_esc: '%s'\n", url_esc, to_uri_esc);	
+		    fflush(x);
+		    fprintf(x, "xfree(url)\n"); fflush(x);
+		    //xfree(url);
+		    fprintf(x, "xfree(url) done, xmalloc(url)\n"); fflush(x);
+		    url=xmalloc(len);
+		    fprintf(x, "xmalloc(url) done, snprintf\n"); fflush(x);
+		    snprintf(url,len,"%s%s%s%s", to_uri_esc ,
+				((url_esc[0]=='/') ? "" : "/"),
+				url_esc, url_params );
+		    fprintf(x, "snprintf done\n"); fflush(x);
+		    xfree(url_esc);
+		    xfree(to_uri_esc);
+		    fprintf(x,"break\n");
+		    fflush(x);
+		    break;
+		} else {
+		    int i=0;
+		    fprintf(x,"not Matched, try 2\n");
+		    fflush(x);
+		    while (fm->from_uri && url_unescaped && fm->from_uri[i] && url_unescaped[i] && (fm->from_uri[i] == url_unescaped[i])){
+			fprintf(x,"while %c<->%c\n", fm->from_uri[i], url_unescaped[i]);
+			i++;
+		    }
+		    fprintf(x,"while ende '%s'\n", &(fm->from_uri[i]));
+		    if (!fm->from_uri[i]){
+			fprintf(x,"from_uri matched\n");
+			if (!url_unescaped[i] || url_unescaped[i]=='/'){
+			    char *newuri_esc, *to_uri_esc;
+			    int len;
+			    if (url_unescaped[i]) newuri_esc=xstrdup(&url_unescaped[i]);
+			    else newuri_esc=xstrdup("");
+			    fprintf(x, "newuri_esc: '%s'\n",newuri_esc);
+			    if (fm->to_uri) to_uri_esc=xstrdup(rfc1738_escape_unescaped(fm->to_uri));
+			    else to_uri_esc=xstrdup("");
+			    len=strlen(newuri_esc)+ strlen(to_uri_esc) + strlen(url_params) +2;
+			    xfree(url);
+			    url=xmalloc(len);
+			    snprintf(url,len,"%s%s%s%s", to_uri_esc,
+					((newuri_esc[0]=='/') ? "" : "/"),
+					newuri_esc, url_params);
+			    xfree(newuri_esc);
+			    xfree(to_uri_esc);
+			    break;
+			} else {
+			    fprintf(x,"but pathname ends not with '\\0' or '/'\n");
+			}
+		    }  
+		} /* else !from_uri*/
+	    } /* ip/port match */
+
+	    fm = fm->next;
+	} /* while */
+	fprintf(x,"while fm beendet\n");
+	xfree(url_unescaped);
+	if (fm){
+	    /* mapping found! */
+	    char *host;
+	    unsigned short port;
+	    host=xstrdup(inet_ntoa(fm->to_ip));
+	    port = fm->to_port;
+	    fprintf(x,"Mapping %s:%i ->%s:%i ('%s')\n",
+			inet_ntoa(http->conn->me.sin_addr),
+			ntohs(http->conn->me.sin_port),
+			host, port, url
+		   );
+	    url_sz = strlen(url) + 32 + Config.appendDomainLen;
+	    http->uri = xcalloc(url_sz, 1);
+
+	    snprintf(http->uri, url_sz, "http://%s:%d%s",
+			host, port, url);
+	    xfree(host);
+	    handled=1;
+	    http->flags.forwardmap_redirected=1;
+
+	}  /* no mapping found, try Other Stuff */
+	fprintf(x, "beendet\n");
+	fclose(x);
+    }
+    if (handled){
+    } else {
+    if (Config2.Accel.on && *url == '/') {
 	/* prepend the accel prefix */
 	if (opt_accel_uses_host && (t = mime_get_header(req_hdr, "Host"))) {
 	    int vport;
@@ -2847,7 +3017,8 @@ parseHttpRequest(ConnStateData * conn, m
 		vport, url);
 #endif
 	    debug(33, 5) ("VHOST REWRITE: '%s'\n", http->uri);
-	} else {
+	    /* vhostmode ends here */
+	} else { 
 	    url_sz = strlen(Config2.Accel.prefix) + strlen(url) +
 		Config.appendDomainLen + 1;
 	    http->uri = xcalloc(url_sz, 1);
@@ -2861,6 +3032,7 @@ parseHttpRequest(ConnStateData * conn, m
 	strcpy(http->uri, url);
 	http->flags.accel = 0;
     }
+    } /* ! handled */
     if (!stringHasCntl(http->uri))
 	http->log_uri = xstrndup(http->uri, MAX_URL);
     else
@@ -3029,6 +3201,7 @@ clientReadRequest(int fd, void *data)
 		safe_free(prefix);
 		break;
 	    }
+	    /* FOLKE TODO */
 	    if ((request = urlParse(method, http->uri)) == NULL) {
 		debug(33, 5) ("Invalid URL: %s\n", http->uri);
 		err = errorCon(ERR_INVALID_URL, HTTP_BAD_REQUEST);
@@ -3041,6 +3214,8 @@ clientReadRequest(int fd, void *data)
 		safe_free(prefix);
 		break;
 	    } else {
+		request->flags.forwardmap_redirected=http->flags.forwardmap_redirected;
+
 		/* compile headers */
 		/* we should skip request line! */
 		if (!httpRequestParseHeader(request, prefix + req_line_sz))
diff -Nrup squid-2.5.STABLE5/src/http.c squid-2.5.STABLE5-folke/src/http.c
--- squid-2.5.STABLE5/src/http.c	Sat Jan 31 00:09:12 2004
+++ squid-2.5.STABLE5-folke/src/http.c	Fri Jun  4 17:16:30 2004
@@ -816,7 +816,7 @@ httpBuildRequestHeader(request_t * reque
 	     * went through our redirector and the admin configured
 	     * 'redir_rewrites_host' to be off.
 	     */
-	    if (request->flags.redirected && !Config.onoff.redir_rewrites_host)
+	    if (request->flags.forwardmap_redirected || ( request->flags.redirected && !Config.onoff.redir_rewrites_host))
 		httpHeaderAddEntry(hdr_out, httpHeaderEntryClone(e));
 	    else {
 		/* use port# only if not default */
diff -Nrup squid-2.5.STABLE5/src/structs.h squid-2.5.STABLE5-folke/src/structs.h
--- squid-2.5.STABLE5/src/structs.h	Wed Feb  4 18:42:28 2004
+++ squid-2.5.STABLE5-folke/src/structs.h	Fri Jun  4 17:16:30 2004
@@ -244,6 +244,17 @@ struct _snmp_request_t {
 
 #endif
 
+struct _forwardmap {
+    struct in_addr		from_ip;
+    struct in_addr		from_mask;
+    unsigned short		from_port;
+    char			*from_uri;
+    struct in_addr		to_ip;
+    unsigned short		to_port;
+    char			*to_uri;
+    forwardmap			*next;
+};
+
 struct _acl {
     char name[ACL_NAME_SZ];
     squid_acl type;
@@ -617,6 +628,7 @@ struct _SquidConfig {
 	acl_tos *outgoing_tos;
     } accessList;
     acl_deny_info_list *denyInfoList;
+    forwardmap *forwardmapList;
     struct _authConfig {
 	authScheme *schemes;
 	int n_allocated;
@@ -1083,6 +1095,7 @@ struct _clientHttpRequest {
 	unsigned int internal:1;
 	unsigned int done_copying:1;
 	unsigned int purging:1;
+	unsigned int forwardmap_redirected:1;
     } flags;
     struct {
 	http_status status;
@@ -1603,6 +1616,7 @@ struct _request_flags {
     unsigned int proxying:1;
     unsigned int refresh:1;
     unsigned int redirected:1;
+    unsigned int forwardmap_redirected:1;
     unsigned int need_validation:1;
 #if HTTP_VIOLATIONS
     unsigned int nocache_hack:1;	/* for changing/ignoring no-cache requests */
diff -Nrup squid-2.5.STABLE5/src/typedefs.h squid-2.5.STABLE5-folke/src/typedefs.h
--- squid-2.5.STABLE5/src/typedefs.h	Wed Feb  4 18:42:29 2004
+++ squid-2.5.STABLE5-folke/src/typedefs.h	Fri Jun  4 17:16:30 2004
@@ -78,6 +78,7 @@ typedef struct _acl_access acl_access;
 typedef struct _acl_address acl_address;
 typedef struct _acl_tos acl_tos;
 typedef struct _aclCheck_t aclCheck_t;
+typedef struct _forwardmap forwardmap;
 typedef struct _wordlist wordlist;
 typedef struct _intlist intlist;
 typedef struct _intrange intrange;
