[MAJOR] reworked ->be, ->fe and ->fi in sessions

There was a confusion about the way to find filters and backend
parameters from sessions. The chaining has been changed between
the session and the proxy.

Now, a session knows only two proxies : one frontend (->fe) and
one backend (->be). Each proxy has a link to the proxy providing
filters and to the proxy providing backend parameters (both self
by default).

The captures (cookies and headers) have been attached to the
frontend's filters for now.

The uri_auth and the statistics are attached to the backend's
filters so that the uri can depend on a hostname for instance.
diff --git a/src/backend.c b/src/backend.c
index e01068f..15d85da 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -155,16 +155,16 @@
 		return SRV_STATUS_INTERNAL;
 
 	if (!(s->flags & SN_ASSIGNED)) {
-		if ((s->be->options & PR_O_BALANCE) && !(s->flags & SN_DIRECT)) {
-			if (!s->be->srv_act && !s->be->srv_bck)
+		if ((s->be->beprm->options & PR_O_BALANCE) && !(s->flags & SN_DIRECT)) {
+			if (!s->be->beprm->srv_act && !s->be->beprm->srv_bck)
 				return SRV_STATUS_NOSRV;
 
-			if (s->be->options & PR_O_BALANCE_RR) {
-				s->srv = get_server_rr_with_conns(s->be);
+			if (s->be->beprm->options & PR_O_BALANCE_RR) {
+				s->srv = get_server_rr_with_conns(s->be->beprm);
 				if (!s->srv)
 					return SRV_STATUS_FULL;
 			}
-			else if (s->be->options & PR_O_BALANCE_SH) {
+			else if (s->be->beprm->options & PR_O_BALANCE_SH) {
 				int len;
 		
 				if (s->cli_addr.ss_family == AF_INET)
@@ -174,7 +174,7 @@
 				else /* unknown IP family */
 					return SRV_STATUS_INTERNAL;
 		
-				s->srv = get_server_sh(s->be,
+				s->srv = get_server_sh(s->be->beprm,
 						       (void *)&((struct sockaddr_in *)&s->cli_addr)->sin_addr,
 						       len);
 			}
@@ -206,7 +206,7 @@
 	fprintf(stderr,"assign_server_address : s=%p\n",s);
 #endif
 
-	if (s->flags & SN_DIRECT || s->be->options & PR_O_BALANCE) {
+	if (s->flags & SN_DIRECT || s->be->beprm->options & PR_O_BALANCE) {
 		/* A server is necessarily known for this session */
 		if (!(s->flags & SN_ASSIGNED))
 			return SRV_STATUS_INTERNAL;
@@ -225,9 +225,9 @@
 			s->srv_addr.sin_port = htons(ntohs(s->srv_addr.sin_port) + ntohs(sockname.sin_port));
 		}
 	}
-	else if (*(int *)&s->be->dispatch_addr.sin_addr) {
+	else if (*(int *)&s->be->beprm->dispatch_addr.sin_addr) {
 		/* connect to the defined dispatch addr */
-		s->srv_addr = s->be->dispatch_addr;
+		s->srv_addr = s->be->beprm->dispatch_addr;
 	}
 	else if (s->fe->options & PR_O_TRANSP) {
 		/* in transparent mode, use the original dest addr if no dispatch specified */
@@ -339,17 +339,17 @@
 		qfprintf(stderr, "Cannot get a server socket.\n");
 
 		if (errno == ENFILE)
-			send_log(s->be, LOG_EMERG,
+			send_log(s->be->beprm, LOG_EMERG,
 				 "Proxy %s reached system FD limit at %d. Please check system tunables.\n",
-				 s->be->id, maxfd);
+				 s->be->beprm->id, maxfd);
 		else if (errno == EMFILE)
-			send_log(s->be, LOG_EMERG,
+			send_log(s->be->beprm, LOG_EMERG,
 				 "Proxy %s reached process FD limit at %d. Please check 'ulimit-n' and restart.\n",
-				 s->be->id, maxfd);
+				 s->be->beprm->id, maxfd);
 		else if (errno == ENOBUFS || errno == ENOMEM)
-			send_log(s->be, LOG_EMERG,
+			send_log(s->be->beprm, LOG_EMERG,
 				 "Proxy %s reached system memory limit at %d sockets. Please check system tunables.\n",
-				 s->be->id, maxfd);
+				 s->be->beprm->id, maxfd);
 		/* this is a resource error */
 		return SN_ERR_RESOURCE;
 	}
@@ -370,7 +370,7 @@
 		return SN_ERR_INTERNAL;
 	}
 
-	if (s->be->options & PR_O_TCP_SRV_KA)
+	if (s->be->beprm->options & PR_O_TCP_SRV_KA)
 		setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char *) &one, sizeof(one));
 
 	/* allow specific binding :
@@ -381,11 +381,11 @@
 		setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one));
 		if (bind(fd, (struct sockaddr *)&s->srv->source_addr, sizeof(s->srv->source_addr)) == -1) {
 			Alert("Cannot bind to source address before connect() for server %s/%s. Aborting.\n",
-			      s->be->id, s->srv->id);
+			      s->be->beprm->id, s->srv->id);
 			close(fd);
-			send_log(s->be, LOG_EMERG,
+			send_log(s->be->beprm, LOG_EMERG,
 				 "Cannot bind to source address before connect() for server %s/%s.\n",
-				 s->be->id, s->srv->id);
+				 s->be->beprm->id, s->srv->id);
 			return SN_ERR_RESOURCE;
 		}
 #ifdef CONFIG_HAP_CTTPROXY
@@ -415,33 +415,33 @@
 			if (setsockopt(fd, SOL_IP, IP_TPROXY, &itp1, sizeof(itp1)) == -1 ||
 			    setsockopt(fd, SOL_IP, IP_TPROXY, &itp2, sizeof(itp2)) == -1) {
 				Alert("Cannot bind to tproxy source address before connect() for server %s/%s. Aborting.\n",
-				      s->be->id, s->srv->id);
+				      s->be->beprm->id, s->srv->id);
 				close(fd);
-				send_log(s->be, LOG_EMERG,
+				send_log(s->be->beprm, LOG_EMERG,
 					 "Cannot bind to tproxy source address before connect() for server %s/%s.\n",
-					 s->be->id, s->srv->id);
+					 s->be->beprm->id, s->srv->id);
 				return SN_ERR_RESOURCE;
 			}
 		}
 #endif
 	}
-	else if (s->be->options & PR_O_BIND_SRC) {
+	else if (s->be->beprm->options & PR_O_BIND_SRC) {
 		setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one));
-		if (bind(fd, (struct sockaddr *)&s->be->source_addr, sizeof(s->be->source_addr)) == -1) {
-			Alert("Cannot bind to source address before connect() for proxy %s. Aborting.\n", s->be->id);
+		if (bind(fd, (struct sockaddr *)&s->be->beprm->source_addr, sizeof(s->be->beprm->source_addr)) == -1) {
+			Alert("Cannot bind to source address before connect() for proxy %s. Aborting.\n", s->be->beprm->id);
 			close(fd);
-			send_log(s->be, LOG_EMERG,
+			send_log(s->be->beprm, LOG_EMERG,
 				 "Cannot bind to source address before connect() for server %s/%s.\n",
-				 s->be->id, s->srv->id);
+				 s->be->beprm->id, s->srv->id);
 			return SN_ERR_RESOURCE;
 		}
 #ifdef CONFIG_HAP_CTTPROXY
-		if (s->be->options & PR_O_TPXY_MASK) {
+		if (s->be->beprm->options & PR_O_TPXY_MASK) {
 			struct in_tproxy itp1, itp2;
 			memset(&itp1, 0, sizeof(itp1));
 
 			itp1.op = TPROXY_ASSIGN;
-			switch (s->be->options & PR_O_TPXY_MASK) {
+			switch (s->be->beprm->options & PR_O_TPXY_MASK) {
 			case PR_O_TPXY_ADDR:
 				itp1.v.addr.faddr = s->srv->tproxy_addr.sin_addr;
 				itp1.v.addr.fport = s->srv->tproxy_addr.sin_port;
@@ -462,11 +462,11 @@
 			if (setsockopt(fd, SOL_IP, IP_TPROXY, &itp1, sizeof(itp1)) == -1 ||
 			    setsockopt(fd, SOL_IP, IP_TPROXY, &itp2, sizeof(itp2)) == -1) {
 				Alert("Cannot bind to tproxy source address before connect() for proxy %s. Aborting.\n",
-				      s->be->id);
+				      s->be->beprm->id);
 				close(fd);
-				send_log(s->be, LOG_EMERG,
+				send_log(s->be->beprm, LOG_EMERG,
 					 "Cannot bind to tproxy source address before connect() for server %s/%s.\n",
-					 s->be->id, s->srv->id);
+					 s->be->beprm->id, s->srv->id);
 				return SN_ERR_RESOURCE;
 			}
 		}
@@ -485,9 +485,9 @@
 
 			qfprintf(stderr,"Cannot connect: %s.\n",msg);
 			close(fd);
-			send_log(s->be, LOG_EMERG,
+			send_log(s->be->beprm, LOG_EMERG,
 				 "Connect() failed for server %s/%s: %s.\n",
-				 s->be->id, s->srv->id, msg);
+				 s->be->beprm->id, s->srv->id, msg);
 			return SN_ERR_RESOURCE;
 		} else if (errno == ETIMEDOUT) {
 			//qfprintf(stderr,"Connect(): ETIMEDOUT");
@@ -523,8 +523,8 @@
 			s->srv->cur_sess_max = s->srv->cur_sess;
 	}
 
-	if (s->be->contimeout)
-		tv_delayfrom(&s->req->cex, &now, s->be->contimeout);
+	if (s->be->beprm->contimeout)
+		tv_delayfrom(&s->req->cex, &now, s->be->beprm->contimeout);
 	else
 		tv_eternity(&s->req->cex);
 	return SN_ERR_NONE;  /* connection is OK */
@@ -548,12 +548,12 @@
 				   503, t->fe->errmsg.len503, t->fe->errmsg.msg503);
 		if (t->srv)
 			t->srv->failed_conns++;
-		t->be->failed_conns++;
+		t->be->beprm->failed_conns++;
 
 		/* We used to have a free connection slot. Since we'll never use it,
 		 * we have to inform the server that it may be used by another session.
 		 */
-		if (may_dequeue_tasks(t->srv, t->be))
+		if (may_dequeue_tasks(t->srv, t->be->beprm))
 			task_wakeup(&rq, t->srv->queue_mgt);
 		return 1;
 	}
@@ -590,9 +590,9 @@
 					   500, t->fe->errmsg.len500, t->fe->errmsg.msg500);
 			if (t->srv)
 				t->srv->failed_conns++;
-			t->be->failed_conns++;
+			t->be->beprm->failed_conns++;
 			/* release other sessions waiting for this server */
-			if (may_dequeue_tasks(t->srv, t->be))
+			if (may_dequeue_tasks(t->srv, t->be->beprm))
 				task_wakeup(&rq, t->srv->queue_mgt);
 			return 1;
 		}
@@ -600,18 +600,18 @@
 		if (srv_count_retry_down(t, conn_err)) {
 			return 1;
 		}
-	} while (t->srv == NULL || t->conn_retries > 0 || !(t->be->options & PR_O_REDISP));
+	} while (t->srv == NULL || t->conn_retries > 0 || !(t->be->beprm->options & PR_O_REDISP));
 
 	/* We're on our last chance, and the REDISP option was specified.
 	 * We will ignore cookie and force to balance or use the dispatcher.
 	 */
 	/* let's try to offer this slot to anybody */
-	if (may_dequeue_tasks(t->srv, t->be))
+	if (may_dequeue_tasks(t->srv, t->be->beprm))
 		task_wakeup(&rq, t->srv->queue_mgt);
 
 	if (t->srv)
 		t->srv->failed_conns++;
-	t->be->failed_conns++;
+	t->be->beprm->failed_conns++;
 
 	t->flags &= ~(SN_DIRECT | SN_ASSIGNED | SN_ADDR_SET);
 	t->srv = NULL; /* it's left to the dispatcher to choose a server */
@@ -650,14 +650,14 @@
 				   503, t->fe->errmsg.len503, t->fe->errmsg.msg503);
 		if (t->srv)
 			t->srv->failed_conns++;
-		t->be->failed_conns++;
+		t->be->beprm->failed_conns++;
 
 		return 1;
 
 	case SRV_STATUS_QUEUED:
 		/* FIXME-20060503 : we should use the queue timeout instead */
-		if (t->be->contimeout)
-			tv_delayfrom(&t->req->cex, &now, t->be->contimeout);
+		if (t->be->beprm->contimeout)
+			tv_delayfrom(&t->req->cex, &now, t->be->beprm->contimeout);
 		else
 			tv_eternity(&t->req->cex);
 		t->srv_state = SV_STIDLE;
@@ -672,10 +672,10 @@
 				   500, t->fe->errmsg.len500, t->fe->errmsg.msg500);
 		if (t->srv)
 			t->srv->failed_conns++;
-		t->be->failed_conns++;
+		t->be->beprm->failed_conns++;
 
 		/* release other sessions waiting for this server */
-		if (may_dequeue_tasks(t->srv, t->be))
+		if (may_dequeue_tasks(t->srv, t->be->beprm))
 			task_wakeup(&rq, t->srv->queue_mgt);
 		return 1;
 	}
diff --git a/src/checks.c b/src/checks.c
index 8466b75..e190a2e 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -64,7 +64,7 @@
 		xferred = 0;
 		FOREACH_ITEM_SAFE(pc, pc_bck, &s->pendconns, pc_end, struct pendconn *, list) {
 			sess = pc->sess;
-			if ((sess->be->options & PR_O_REDISP)) {
+			if ((sess->be->beprm->options & PR_O_REDISP)) {
 				/* The REDISP option was specified. We will ignore
 				 * cookie and force to balance or use the dispatcher.
 				 */
diff --git a/src/client.c b/src/client.c
index c4b2bf4..e55f20b 100644
--- a/src/client.c
+++ b/src/client.c
@@ -157,7 +157,7 @@
 		t->context = s;
 
 		s->task = t;
-		s->be = s->fe = s->fi = p;
+		s->be = s->fe = p;
 
 		s->cli_state = (p->mode == PR_MODE_HTTP) ?  CL_STHEADERS : CL_STDATA; /* no HTTP headers for non-HTTP proxies */
 		s->srv_state = SV_STIDLE;
@@ -206,31 +206,31 @@
 
 			s->hreq.hdr_idx.size = MAX_HTTP_HDR;
 
-			if (p->nb_req_cap > 0) {
+			if (p->fiprm->nb_req_cap > 0) {
 				if ((s->hreq.cap =
-				     pool_alloc_from(p->req_cap_pool, p->nb_req_cap*sizeof(char *)))
+				     pool_alloc_from(p->fiprm->req_cap_pool, p->fiprm->nb_req_cap*sizeof(char *)))
 				    == NULL) { /* no memory */
 					close(cfd); /* nothing can be done for this fd without memory */
 					pool_free(task, t);
 					pool_free(session, s);
 					return 0;
 				}
-				memset(s->hreq.cap, 0, p->nb_req_cap*sizeof(char *));
+				memset(s->hreq.cap, 0, p->fiprm->nb_req_cap*sizeof(char *));
 			}
 
 
-			if (p->nb_rsp_cap > 0) {
+			if (p->fiprm->nb_rsp_cap > 0) {
 				if ((s->rsp_cap =
-				     pool_alloc_from(p->rsp_cap_pool, p->nb_rsp_cap*sizeof(char *)))
+				     pool_alloc_from(p->fiprm->rsp_cap_pool, p->fiprm->nb_rsp_cap*sizeof(char *)))
 				    == NULL) { /* no memory */
 					if (s->hreq.cap != NULL)
-						pool_free_to(p->req_cap_pool, s->hreq.cap);
+						pool_free_to(p->fiprm->req_cap_pool, s->hreq.cap);
 					close(cfd); /* nothing can be done for this fd without memory */
 					pool_free(task, t);
 					pool_free(session, s);
 					return 0;
 				}
-				memset(s->rsp_cap, 0, p->nb_rsp_cap*sizeof(char *));
+				memset(s->rsp_cap, 0, p->fiprm->nb_rsp_cap*sizeof(char *));
 			}
 
 
@@ -238,9 +238,9 @@
 			     pool_alloc_from(p->hdr_idx_pool, s->hreq.hdr_idx.size*sizeof(*s->hreq.hdr_idx.v)))
 			    == NULL) { /* no memory */
 				if (s->rsp_cap != NULL)
-					pool_free_to(p->rsp_cap_pool, s->rsp_cap);
+					pool_free_to(p->fiprm->rsp_cap_pool, s->rsp_cap);
 				if (s->hreq.cap != NULL)
-					pool_free_to(p->req_cap_pool, s->hreq.cap);
+					pool_free_to(p->fiprm->req_cap_pool, s->hreq.cap);
 				close(cfd); /* nothing can be done for this fd without memory */
 				pool_free(task, t);
 				pool_free(session, s);
@@ -328,9 +328,9 @@
 			if (s->hreq.hdr_idx.v != NULL)
 				pool_free_to(p->hdr_idx_pool, s->hreq.hdr_idx.v);
 			if (s->rsp_cap != NULL)
-				pool_free_to(p->rsp_cap_pool, s->rsp_cap);
+				pool_free_to(p->fiprm->rsp_cap_pool, s->rsp_cap);
 			if (s->hreq.cap != NULL)
-				pool_free_to(p->req_cap_pool, s->hreq.cap);
+				pool_free_to(p->fiprm->req_cap_pool, s->hreq.cap);
 			close(cfd); /* nothing can be done for this fd without memory */
 			pool_free(task, t);
 			pool_free(session, s);
@@ -343,17 +343,17 @@
 			s->req->rlim -= MAXREWRITE;
 
 		s->req->rto = s->fe->clitimeout;
-		s->req->wto = s->be->srvtimeout;
-		s->req->cto = s->be->srvtimeout;
+		s->req->wto = s->be->beprm->srvtimeout;
+		s->req->cto = s->be->beprm->srvtimeout;
 
 		if ((s->rep = pool_alloc(buffer)) == NULL) { /* no memory */
 			pool_free(buffer, s->req);
 			if (s->hreq.hdr_idx.v != NULL)
 				pool_free_to(p->hdr_idx_pool, s->hreq.hdr_idx.v);
 			if (s->rsp_cap != NULL)
-				pool_free_to(p->rsp_cap_pool, s->rsp_cap);
+				pool_free_to(p->fiprm->rsp_cap_pool, s->rsp_cap);
 			if (s->hreq.cap != NULL)
-				pool_free_to(p->req_cap_pool, s->hreq.cap);
+				pool_free_to(p->fiprm->req_cap_pool, s->hreq.cap);
 			close(cfd); /* nothing can be done for this fd without memory */
 			pool_free(task, t);
 			pool_free(session, s);
@@ -362,8 +362,8 @@
 
 		buffer_init(s->rep);
 
-		s->rep->rto = s->be->srvtimeout;
-		s->rep->wto = s->be->clitimeout;
+		s->rep->rto = s->be->beprm->srvtimeout;
+		s->rep->wto = s->fe->clitimeout;
 		s->rep->cto = 0;
 
 		fdtab[cfd].owner = t;
diff --git a/src/log.c b/src/log.c
index cf7412f..0773358 100644
--- a/src/log.c
+++ b/src/log.c
@@ -291,7 +291,7 @@
 	struct proxy *p = s->fe;
 #endif
 	struct proxy *fe = s->fe;
-	struct proxy *be = s->be;
+	struct proxy *be = s->be->beprm;
 	int log;
 	char *uri;
 	char *pxid;
diff --git a/src/proto_http.c b/src/proto_http.c
index bf53813..e87da3e 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -264,7 +264,7 @@
 	if ((global.mode & MODE_DEBUG) && (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))) {
 		int len;
 		len = sprintf(trash, "%08x:%s.closed[%04x:%04x]\n",
-			      s->uniq_id, s->be->id,
+			      s->uniq_id, s->be->beprm->id,
 			      (unsigned short)s->cli_fd, (unsigned short)s->srv_fd);
 		write(1, trash, len);
 	}
@@ -341,7 +341,7 @@
 		 */
 
 		char *sol, *eol; /* Start Of Line, End Of Line */
-		struct proxy *rule_set;
+		struct proxy *cur_proxy;
 
 		eol = sol = req->data + t->hreq.eoh;
 
@@ -434,7 +434,7 @@
 					 * consider that it's necessary after one single space.*/
 					struct cap_hdr *h;
 					int len;
-					for (h = t->fi->req_cap; h; h = h->next) {
+					for (h = t->fe->fiprm->req_cap; h; h = h->next) {
 						if ((h->namelen + 2 <= eol - sol) &&
 						    (sol[h->namelen] == ':') &&
 						    (strncasecmp(sol, h->name, h->namelen) == 0)) {
@@ -891,23 +891,22 @@
 		 * filters and various options. In order to support 3-level
 		 * switching, here's how we should proceed :
 		 *
-		 *  a) run be->filters.
-		 *     if (switch) then switch ->fi and ->be to the new backend.
-		 *  b) run be->filters.
-		 *     If there's another switch, then switch ->be to the new be.
-		 *  c) run be->filters
+		 *  a) run be->fiprm.
+		 *     if (switch) then switch ->be to the new backend.
+		 *  b) run be->fiprm if (be != fe).
 		 *     There cannot be any switch from there, so ->be cannot be
 		 *     changed anymore.
 		 *
-		 *  => filters always apply to ->be, then ->be may change.
+		 * => filters always apply to ->be, then ->be may change.
 		 *
-		 *  The response path will be able to apply either ->be, or
-		 *  ->be then ->fi, or ->be then ->fi then ->fe filters in order
-		 * to match the reverse of the forward sequence.
+		 * The response path will be able to apply either ->be, or
+		 * ->be then ->fe filters in order to match the reverse of
+		 * the forward sequence.
 		 */
 
 		do {
-			rule_set = t->be;
+			struct proxy *rule_set = t->be->fiprm;
+			cur_proxy = t->be;
 
 			/* try headers filters */
 			if (rule_set->req_exp != NULL) {
@@ -947,14 +946,14 @@
 					return 1;
 			}
 
-		} while (rule_set != t->be);  /* we loop only if t->be has changed */
+		} while (cur_proxy != t->be);  /* we loop only if t->be has changed */
 		
 
 		/*
 		 * Right now, we know that we have processed the entire headers
 		 * and that unwanted requests have been filtered out. We can do
 		 * whatever we want with the remaining request. Also, now we
-		 * may have separate values for ->fe, ->fi and ->be.
+		 * may have separate values for ->fe, ->be.
 		 */
 
 
@@ -966,7 +965,7 @@
 		 */
 
 		/* It needs to look into the URI */
-		if (t->be->appsession_name) {
+		if (t->be->beprm->appsession_name) {
 			get_srv_from_appsession(t,
 						t->hreq.start.str,
 						t->hreq.start.str + t->hreq.start.len);
@@ -986,7 +985,7 @@
 		/*
 		 * 5: add X-Forwarded-For : Should depend on the backend only.
 		 */
-		if (t->be->options & PR_O_FWDFOR) {
+		if (t->be->beprm->options & PR_O_FWDFOR) {
 			if (t->cli_addr.ss_family == AF_INET) {
 				int len;
 				unsigned char *pn;
@@ -1052,7 +1051,7 @@
 
 
 		if (!t->fe->clitimeout ||
-		    (t->srv_state < SV_STDATA && t->be->srvtimeout)) {
+		    (t->srv_state < SV_STDATA && t->be->beprm->srvtimeout)) {
 			/* If the client has no timeout, or if the server is not ready yet,
 			 * and we know for sure that it can expire, then it's cleaner to
 			 * disable the timeout on the client side so that too low values
@@ -1077,7 +1076,7 @@
 			 * if the client closes first.
 			 */
 			tv_delayfrom(&req->cex, &now,
-				     t->be->contimeout ? t->be->contimeout : 0);
+				     t->be->beprm->contimeout ? t->be->beprm->contimeout : 0);
 		}
 
 #if DEBUG_HTTP_PARSER
@@ -1225,7 +1224,7 @@
 			if (! MY_FD_ISSET(t->cli_fd, StaticReadEvent)) {
 				MY_FD_SET(t->cli_fd, StaticReadEvent);
 				if (!t->fe->clitimeout ||
-				    (t->srv_state < SV_STDATA && t->be->srvtimeout))
+				    (t->srv_state < SV_STDATA && t->be->beprm->srvtimeout))
 					/* If the client has no timeout, or if the server not ready yet, and we
 					 * know for sure that it can expire, then it's cleaner to disable the
 					 * timeout on the client side so that too low values cannot make the
@@ -1400,7 +1399,7 @@
 	else { /* CL_STCLOSE: nothing to do */
 		if ((global.mode & MODE_DEBUG) && (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))) {
 			int len;
-			len = sprintf(trash, "%08x:%s.clicls[%04x:%04x]\n", t->uniq_id, t->be->id, (unsigned short)t->cli_fd, (unsigned short)t->srv_fd);
+			len = sprintf(trash, "%08x:%s.clicls[%04x:%04x]\n", t->uniq_id, t->be->beprm->id, (unsigned short)t->cli_fd, (unsigned short)t->srv_fd);
 			write(1, trash, len);
 		}
 		return 0;
@@ -1435,7 +1434,7 @@
 			return 0;	/* stay in idle, waiting for data to reach the client side */
 		else if (c == CL_STCLOSE || c == CL_STSHUTW ||
 			 (c == CL_STSHUTR &&
-			  (t->req->l == 0 || t->be->options & PR_O_ABRT_CLOSE))) { /* give up */
+			  (t->req->l == 0 || t->be->beprm->options & PR_O_ABRT_CLOSE))) { /* give up */
 			tv_eternity(&req->cex);
 			if (t->pend_pos)
 				t->logs.t_queue = tv_diff(&t->logs.tv_accept, &now);
@@ -1511,7 +1510,7 @@
 	else if (s == SV_STCONN) { /* connection in progress */
 		if (c == CL_STCLOSE || c == CL_STSHUTW ||
 		    (c == CL_STSHUTR &&
-		     (t->req->l == 0 || t->be->options & PR_O_ABRT_CLOSE))) { /* give up */
+		     (t->req->l == 0 || t->be->beprm->options & PR_O_ABRT_CLOSE))) { /* give up */
 			tv_eternity(&req->cex);
 			fd_delete(t->srv_fd);
 			if (t->srv)
@@ -1544,17 +1543,17 @@
 			if (srv_count_retry_down(t, conn_err))
 				return 1;
 
-			if (t->srv && t->conn_retries == 0 && t->be->options & PR_O_REDISP) {
+			if (t->srv && t->conn_retries == 0 && t->be->beprm->options & PR_O_REDISP) {
 				/* We're on our last chance, and the REDISP option was specified.
 				 * We will ignore cookie and force to balance or use the dispatcher.
 				 */
 				/* let's try to offer this slot to anybody */
-				if (may_dequeue_tasks(t->srv, t->be))
+				if (may_dequeue_tasks(t->srv, t->be->beprm))
 					task_wakeup(&rq, t->srv->queue_mgt);
 
 				if (t->srv)
 					t->srv->failed_conns++;
-				t->be->failed_conns++;
+				t->be->beprm->failed_conns++;
 
 				t->flags &= ~(SN_DIRECT | SN_ASSIGNED | SN_ADDR_SET);
 				t->srv = NULL; /* it's left to the dispatcher to choose a server */
@@ -1593,8 +1592,8 @@
 				tv_eternity(&req->wex);
 			} else  /* need the right to write */ {
 				MY_FD_SET(t->srv_fd, StaticWriteEvent);
-				if (t->be->srvtimeout) {
-					tv_delayfrom(&req->wex, &now, t->be->srvtimeout);
+				if (t->be->beprm->srvtimeout) {
+					tv_delayfrom(&req->wex, &now, t->be->beprm->srvtimeout);
 					/* FIXME: to prevent the server from expiring read timeouts during writes,
 					 * we refresh it. */
 					rep->rex = req->wex;
@@ -1603,10 +1602,10 @@
 					tv_eternity(&req->wex);
 			}
 
-			if (t->be->mode == PR_MODE_TCP) { /* let's allow immediate data connection in this case */
+			if (t->be->beprm->mode == PR_MODE_TCP) { /* let's allow immediate data connection in this case */
 				MY_FD_SET(t->srv_fd, StaticReadEvent);
-				if (t->be->srvtimeout)
-					tv_delayfrom(&rep->rex, &now, t->be->srvtimeout);
+				if (t->be->beprm->srvtimeout)
+					tv_delayfrom(&rep->rex, &now, t->be->beprm->srvtimeout);
 				else
 					tv_eternity(&rep->rex);
 		
@@ -1653,7 +1652,7 @@
 				if (t->flags & SN_CACHEABLE) {
 					if ((t->flags & SN_CACHE_COOK) &&
 					    (t->flags & SN_SCK_ANY) &&
-					    (t->be->options & PR_O_CHK_CACHE)) {
+					    (t->be->beprm->options & PR_O_CHK_CACHE)) {
 
 						/* we're in presence of a cacheable response containing
 						 * a set-cookie header. We'll block it as requested by
@@ -1675,13 +1674,13 @@
 						if (!(t->flags & SN_FINST_MASK))
 							t->flags |= SN_FINST_H;
 
-						Alert("Blocking cacheable cookie in response from instance %s, server %s.\n", t->be->id, t->srv->id);
-						send_log(t->be, LOG_ALERT, "Blocking cacheable cookie in response from instance %s, server %s.\n", t->be->id, t->srv->id);
+						Alert("Blocking cacheable cookie in response from instance %s, server %s.\n", t->be->beprm->id, t->srv->id);
+						send_log(t->be, LOG_ALERT, "Blocking cacheable cookie in response from instance %s, server %s.\n", t->be->beprm->id, t->srv->id);
 
 						/* We used to have a free connection slot. Since we'll never use it,
 						 * we have to inform the server that it may be used by another session.
 						 */
-						if (may_dequeue_tasks(t->srv, t->be))
+						if (may_dequeue_tasks(t->srv, t->be->beprm))
 							task_wakeup(&rq, t->srv->queue_mgt);
 
 						return 1;
@@ -1708,7 +1707,7 @@
 					/* We used to have a free connection slot. Since we'll never use it,
 					 * we have to inform the server that it may be used by another session.
 					 */
-					if (may_dequeue_tasks(t->srv, t->be))
+					if (may_dequeue_tasks(t->srv, t->be->beprm))
 						task_wakeup(&rq, t->srv->queue_mgt);
 
 					return 1;
@@ -1716,15 +1715,15 @@
 
 				/* we'll have something else to do here : add new headers ... */
 
-				if ((t->srv) && !(t->flags & SN_DIRECT) && (t->be->options & PR_O_COOK_INS) &&
-				    (!(t->be->options & PR_O_COOK_POST) || (t->hreq.meth == HTTP_METH_POST))) {
+				if ((t->srv) && !(t->flags & SN_DIRECT) && (t->be->beprm->options & PR_O_COOK_INS) &&
+				    (!(t->be->beprm->options & PR_O_COOK_POST) || (t->hreq.meth == HTTP_METH_POST))) {
 					/* the server is known, it's not the one the client requested, we have to
 					 * insert a set-cookie here, except if we want to insert only on POST
 					 * requests and this one isn't. Note that servers which don't have cookies
 					 * (eg: some backup servers) will return a full cookie removal request.
 					 */
 					len = sprintf(trash, "Set-Cookie: %s=%s; path=/\r\n",
-						      t->be->cookie_name,
+						      t->be->beprm->cookie_name,
 						      t->srv->cookie ? t->srv->cookie : "; Expires=Thu, 01-Jan-1970 00:00:01 GMT");
 
 					t->flags |= SN_SCK_INSERTED;
@@ -1734,7 +1733,7 @@
 					 * Some caches understand the correct form: 'no-cache="set-cookie"', but
 					 * others don't (eg: apache <= 1.3.26). So we use 'private' instead.
 					 */
-					if (t->be->options & PR_O_COOK_NOC)
+					if (t->be->beprm->options & PR_O_COOK_NOC)
 						//len += sprintf(newhdr + len, "Cache-control: no-cache=\"set-cookie\"\r\n");
 						len += sprintf(trash + len, "Cache-control: private\r\n");
 
@@ -1745,8 +1744,9 @@
 				}
 
 				/* headers to be added */
-				for (line = 0; line < t->fi->nb_rspadd; line++) {
-					len = sprintf(trash, "%s\r\n", t->fi->rsp_add[line]);
+				/* FIXME: we should add headers from BE then from FE */
+				for (line = 0; line < t->be->fiprm->nb_rspadd; line++) {
+					len = sprintf(trash, "%s\r\n", t->be->fiprm->rsp_add[line]);
 					buffer_replace2(rep, rep->h, rep->h, trash, len);
 				}
 
@@ -1762,15 +1762,15 @@
 				 * we close the server's outgoing connection right now.
 				 */
 				if ((req->l == 0) &&
-				    (c == CL_STSHUTR || c == CL_STCLOSE || t->be->options & PR_O_FORCE_CLO)) {
+				    (c == CL_STSHUTR || c == CL_STCLOSE || t->be->beprm->options & PR_O_FORCE_CLO)) {
 					MY_FD_CLR(t->srv_fd, StaticWriteEvent);
 					tv_eternity(&req->wex);
 
 					/* We must ensure that the read part is still alive when switching
 					 * to shutw */
 					MY_FD_SET(t->srv_fd, StaticReadEvent);
-					if (t->be->srvtimeout)
-						tv_delayfrom(&rep->rex, &now, t->be->srvtimeout);
+					if (t->be->beprm->srvtimeout)
+						tv_delayfrom(&rep->rex, &now, t->be->beprm->srvtimeout);
 
 					shutdown(t->srv_fd, SHUT_WR);
 					t->srv_state = SV_STSHUTW;
@@ -1835,7 +1835,7 @@
 					 *    unless the response includes appropriate
 					 *    Cache-Control or Expires header fields."
 					 */
-					if (!(t->hreq.meth == HTTP_METH_POST) && (t->be->options & PR_O_CHK_CACHE))
+					if (!(t->hreq.meth == HTTP_METH_POST) && (t->be->beprm->options & PR_O_CHK_CACHE))
 						t->flags |= SN_CACHEABLE | SN_CACHE_COOK;
 					break;
 				default:
@@ -1845,7 +1845,7 @@
 			else if (t->logs.logwait & LW_RSPHDR) {
 				struct cap_hdr *h;
 				int len;
-				for (h = t->fi->rsp_cap; h; h = h->next) {
+				for (h = t->fe->fiprm->rsp_cap; h; h = h->next) {
 					if ((h->namelen + 2 <= ptr - rep->h) &&
 					    (rep->h[h->namelen] == ':') &&
 					    (strncasecmp(rep->h, h->name, h->namelen) == 0)) {
@@ -1876,14 +1876,14 @@
 			}
 
 			/* try headers regexps */
-			if (!delete_header && t->fi->rsp_exp != NULL
+			if (!delete_header && t->be->fiprm->rsp_exp != NULL
 			    && !(t->flags & SN_SVDENY)) {
 				struct hdr_exp *exp;
 				char term;
 		
 				term = *ptr;
 				*ptr = '\0';
-				exp = t->fi->rsp_exp;
+				exp = t->be->fiprm->rsp_exp;
 				do {
 					if (regexec(exp->preg, rep->h, MAX_MATCH, pmatch, 0) == 0) {
 						switch (exp->action) {
@@ -1947,7 +1947,9 @@
 
 			/* check for server cookies */
 			if (!delete_header /*&& (t->proxy->options & PR_O_COOK_ANY)*/
-			    && (t->be->cookie_name != NULL || t->fi->capture_name != NULL || t->be->appsession_name !=NULL)
+			    && (t->be->beprm->cookie_name != NULL ||
+				t->be->fiprm->capture_name != NULL ||
+				t->be->beprm->appsession_name !=NULL)
 			    && (strncasecmp(rep->h, "Set-Cookie: ", 12) == 0)) {
 				char *p1, *p2, *p3, *p4;
 		
@@ -1985,24 +1987,24 @@
 					 */
 
 					/* first, let's see if we want to capture it */
-					if (t->fi->capture_name != NULL &&
+					if (t->be->fiprm->capture_name != NULL &&
 					    t->logs.srv_cookie == NULL &&
-					    (p4 - p1 >= t->fi->capture_namelen) &&
-					    memcmp(p1, t->fi->capture_name, t->fi->capture_namelen) == 0) {
+					    (p4 - p1 >= t->be->fiprm->capture_namelen) &&
+					    memcmp(p1, t->be->fiprm->capture_name, t->be->fiprm->capture_namelen) == 0) {
 						int log_len = p4 - p1;
 
 						if ((t->logs.srv_cookie = pool_alloc(capture)) == NULL) {
 							Alert("HTTP logging : out of memory.\n");
 						}
 
-						if (log_len > t->fi->capture_len)
-							log_len = t->fi->capture_len;
+						if (log_len > t->be->fiprm->capture_len)
+							log_len = t->be->fiprm->capture_len;
 						memcpy(t->logs.srv_cookie, p1, log_len);
 						t->logs.srv_cookie[log_len] = 0;
 					}
 
-					if ((p2 - p1 == t->be->cookie_len) && (t->be->cookie_name != NULL) &&
-					    (memcmp(p1, t->be->cookie_name, p2 - p1) == 0)) {
+					if ((p2 - p1 == t->be->beprm->cookie_len) && (t->be->beprm->cookie_name != NULL) &&
+					    (memcmp(p1, t->be->beprm->cookie_name, p2 - p1) == 0)) {
 						/* Cool... it's the right one */
 						t->flags |= SN_SCK_SEEN;
 			
@@ -2010,20 +2012,20 @@
 						 * this occurrence because we'll insert another one later.
 						 * We'll delete it too if the "indirect" option is set and we're in
 						 * a direct access. */
-						if (((t->srv) && (t->be->options & PR_O_COOK_INS)) ||
-						    ((t->flags & SN_DIRECT) && (t->be->options & PR_O_COOK_IND))) {
+						if (((t->srv) && (t->be->beprm->options & PR_O_COOK_INS)) ||
+						    ((t->flags & SN_DIRECT) && (t->be->beprm->options & PR_O_COOK_IND))) {
 							/* this header must be deleted */
 							delete_header = 1;
 							t->flags |= SN_SCK_DELETED;
 						}
-						else if ((t->srv) && (t->be->options & PR_O_COOK_RW)) {
+						else if ((t->srv) && (t->be->beprm->options & PR_O_COOK_RW)) {
 							/* replace bytes p3->p4 with the cookie name associated
 							 * with this server since we know it.
 							 */
 							buffer_replace2(rep, p3, p4, t->srv->cookie, t->srv->cklen);
 							t->flags |= SN_SCK_INSERTED | SN_SCK_DELETED;
 						}
-						else if ((t->srv) && (t->be->options & PR_O_COOK_PFX)) {
+						else if ((t->srv) && (t->be->beprm->options & PR_O_COOK_PFX)) {
 							/* insert the cookie name associated with this server
 							 * before existing cookie, and insert a delimitor between them..
 							 */
@@ -2035,8 +2037,8 @@
 					}
 
 					/* first, let's see if the cookie is our appcookie*/
-					if ((t->be->appsession_name != NULL) &&
-					    (memcmp(p1, t->be->appsession_name, p2 - p1) == 0)) {
+					if ((t->be->beprm->appsession_name != NULL) &&
+					    (memcmp(p1, t->be->beprm->appsession_name, p2 - p1) == 0)) {
 
 						/* Cool... it's the right one */
 
@@ -2047,8 +2049,8 @@
 							Alert("Not enought Memory process_srv():asession->sessid:malloc().\n");
 							send_log(t->be, LOG_ALERT, "Not enought Memory process_srv():asession->sessid:malloc().\n");
 						}
-						memcpy(asession_temp->sessid, p3, t->be->appsession_len);
-						asession_temp->sessid[t->be->appsession_len] = 0;
+						memcpy(asession_temp->sessid, p3, t->be->beprm->appsession_len);
+						asession_temp->sessid[t->be->beprm->appsession_len] = 0;
 						asession_temp->serverid = NULL;
 
 						/* only do insert, if lookup fails */
@@ -2060,7 +2062,7 @@
 							}
 							asession_temp->sessid = local_asession.sessid;
 							asession_temp->serverid = local_asession.serverid;
-							chtbl_insert(&(t->be->htbl_proxy), (void *) asession_temp);
+							chtbl_insert(&(t->be->beprm->htbl_proxy), (void *) asession_temp);
 						}/* end if (chtbl_lookup()) */
 						else {
 							/* free wasted memory */
@@ -2078,10 +2080,10 @@
 						if (asession_temp->serverid[0] == '\0')
 							memcpy(asession_temp->serverid,t->srv->id,server_id_len);
 		      
-						tv_delayfrom(&asession_temp->expire, &now, t->be->appsession_timeout);
+						tv_delayfrom(&asession_temp->expire, &now, t->be->beprm->appsession_timeout);
 
 #if defined(DEBUG_HASH)
-						print_table(&(t->be->htbl_proxy));
+						print_table(&(t->be->beprm->htbl_proxy));
 #endif
 						break;
 					}/* end if ((t->proxy->appsession_name != NULL) ... */
@@ -2098,7 +2100,7 @@
 
 			/* check for any set-cookie in case we check for cacheability */
 			if (!delete_header && !(t->flags & SN_SCK_ANY) &&
-			    (t->be->options & PR_O_CHK_CACHE) &&
+			    (t->be->beprm->options & PR_O_CHK_CACHE) &&
 			    (strncasecmp(rep->h, "Set-Cookie: ", 12) == 0)) {
 				t->flags |= SN_SCK_ANY;
 			}
@@ -2118,8 +2120,8 @@
 			 * rep->l == rlim-data
 			 */
 			MY_FD_SET(t->srv_fd, StaticReadEvent);
-			if (t->be->srvtimeout)
-				tv_delayfrom(&rep->rex, &now, t->be->srvtimeout);
+			if (t->be->beprm->srvtimeout)
+				tv_delayfrom(&rep->rex, &now, t->be->beprm->srvtimeout);
 			else
 				tv_eternity(&rep->rex);
 		}
@@ -2145,7 +2147,7 @@
 			/* We used to have a free connection slot. Since we'll never use it,
 			 * we have to inform the server that it may be used by another session.
 			 */
-			if (may_dequeue_tasks(t->srv, t->be))
+			if (may_dequeue_tasks(t->srv, t->be->beprm))
 				task_wakeup(&rq, t->srv->queue_mgt);
 
 			return 1;
@@ -2183,7 +2185,7 @@
 			/* We used to have a free connection slot. Since we'll never use it,
 			 * we have to inform the server that it may be used by another session.
 			 */
-			if (may_dequeue_tasks(t->srv, t->be))
+			if (may_dequeue_tasks(t->srv, t->be->beprm))
 				task_wakeup(&rq, t->srv->queue_mgt);
 
 			return 1;
@@ -2203,8 +2205,8 @@
 			/* We must ensure that the read part is still alive when switching
 			 * to shutw */
 			MY_FD_SET(t->srv_fd, StaticReadEvent);
-			if (t->be->srvtimeout)
-				tv_delayfrom(&rep->rex, &now, t->be->srvtimeout);
+			if (t->be->beprm->srvtimeout)
+				tv_delayfrom(&rep->rex, &now, t->be->beprm->srvtimeout);
 
 			shutdown(t->srv_fd, SHUT_WR);
 			t->srv_state = SV_STSHUTW;
@@ -2222,14 +2224,14 @@
 			/* We must ensure that the read part is still alive when switching
 			 * to shutw */
 			MY_FD_SET(t->srv_fd, StaticReadEvent);
-			if (t->be->srvtimeout)
-				tv_delayfrom(&rep->rex, &now, t->be->srvtimeout);
+			if (t->be->beprm->srvtimeout)
+				tv_delayfrom(&rep->rex, &now, t->be->beprm->srvtimeout);
 
 			/* We must ensure that the read part is still alive when switching
 			 * to shutw */
 			MY_FD_SET(t->srv_fd, StaticReadEvent);
-			if (t->be->srvtimeout)
-				tv_delayfrom(&rep->rex, &now, t->be->srvtimeout);
+			if (t->be->beprm->srvtimeout)
+				tv_delayfrom(&rep->rex, &now, t->be->beprm->srvtimeout);
 
 			t->srv_state = SV_STSHUTW;
 			if (!(t->flags & SN_ERR_MASK))
@@ -2248,8 +2250,8 @@
 		else { /* client buffer not empty */
 			if (! MY_FD_ISSET(t->srv_fd, StaticWriteEvent)) {
 				MY_FD_SET(t->srv_fd, StaticWriteEvent); /* restart writing */
-				if (t->be->srvtimeout) {
-					tv_delayfrom(&req->wex, &now, t->be->srvtimeout);
+				if (t->be->beprm->srvtimeout) {
+					tv_delayfrom(&req->wex, &now, t->be->beprm->srvtimeout);
 					/* FIXME: to prevent the server from expiring read timeouts during writes,
 					 * we refresh it. */
 					rep->rex = req->wex;
@@ -2286,7 +2288,7 @@
 			/* We used to have a free connection slot. Since we'll never use it,
 			 * we have to inform the server that it may be used by another session.
 			 */
-			if (may_dequeue_tasks(t->srv, t->be))
+			if (may_dequeue_tasks(t->srv, t->be->beprm))
 				task_wakeup(&rq, t->srv->queue_mgt);
 
 			return 1;
@@ -2308,8 +2310,8 @@
 			/* We must ensure that the read part is still alive when switching
 			 * to shutw */
 			MY_FD_SET(t->srv_fd, StaticReadEvent);
-			if (t->be->srvtimeout)
-				tv_delayfrom(&rep->rex, &now, t->be->srvtimeout);
+			if (t->be->beprm->srvtimeout)
+				tv_delayfrom(&rep->rex, &now, t->be->beprm->srvtimeout);
 
 			t->srv_state = SV_STSHUTW;
 			return 1;
@@ -2334,8 +2336,8 @@
 			/* We must ensure that the read part is still alive when switching
 			 * to shutw */
 			MY_FD_SET(t->srv_fd, StaticReadEvent);
-			if (t->be->srvtimeout)
-				tv_delayfrom(&rep->rex, &now, t->be->srvtimeout);
+			if (t->be->beprm->srvtimeout)
+				tv_delayfrom(&rep->rex, &now, t->be->beprm->srvtimeout);
 			t->srv_state = SV_STSHUTW;
 			if (!(t->flags & SN_ERR_MASK))
 				t->flags |= SN_ERR_SRVTO;
@@ -2354,8 +2356,8 @@
 		else { /* buffer not empty, there are still data to be transferred */
 			if (! MY_FD_ISSET(t->srv_fd, StaticWriteEvent)) {
 				MY_FD_SET(t->srv_fd, StaticWriteEvent); /* restart writing */
-				if (t->be->srvtimeout) {
-					tv_delayfrom(&req->wex, &now, t->be->srvtimeout);
+				if (t->be->beprm->srvtimeout) {
+					tv_delayfrom(&req->wex, &now, t->be->beprm->srvtimeout);
 					/* FIXME: to prevent the server from expiring read timeouts during writes,
 					 * we refresh it. */
 					rep->rex = req->wex;
@@ -2375,8 +2377,8 @@
 		else {
 			if (! MY_FD_ISSET(t->srv_fd, StaticReadEvent)) {
 				MY_FD_SET(t->srv_fd, StaticReadEvent);
-				if (t->be->srvtimeout)
-					tv_delayfrom(&rep->rex, &now, t->be->srvtimeout);
+				if (t->be->beprm->srvtimeout)
+					tv_delayfrom(&rep->rex, &now, t->be->beprm->srvtimeout);
 				else
 					tv_eternity(&rep->rex);
 			}
@@ -2403,7 +2405,7 @@
 			/* We used to have a free connection slot. Since we'll never use it,
 			 * we have to inform the server that it may be used by another session.
 			 */
-			if (may_dequeue_tasks(t->srv, t->be))
+			if (may_dequeue_tasks(t->srv, t->be->beprm))
 				task_wakeup(&rq, t->srv->queue_mgt);
 
 			return 1;
@@ -2419,7 +2421,7 @@
 			/* We used to have a free connection slot. Since we'll never use it,
 			 * we have to inform the server that it may be used by another session.
 			 */
-			if (may_dequeue_tasks(t->srv, t->be))
+			if (may_dequeue_tasks(t->srv, t->be->beprm))
 				task_wakeup(&rq, t->srv->queue_mgt);
 
 			return 1;
@@ -2439,7 +2441,7 @@
 			/* We used to have a free connection slot. Since we'll never use it,
 			 * we have to inform the server that it may be used by another session.
 			 */
-			if (may_dequeue_tasks(t->srv, t->be))
+			if (may_dequeue_tasks(t->srv, t->be->beprm))
 				task_wakeup(&rq, t->srv->queue_mgt);
 
 			return 1;
@@ -2453,8 +2455,8 @@
 		else { /* buffer not empty */
 			if (! MY_FD_ISSET(t->srv_fd, StaticWriteEvent)) {
 				MY_FD_SET(t->srv_fd, StaticWriteEvent); /* restart writing */
-				if (t->be->srvtimeout) {
-					tv_delayfrom(&req->wex, &now, t->be->srvtimeout);
+				if (t->be->beprm->srvtimeout) {
+					tv_delayfrom(&req->wex, &now, t->be->beprm->srvtimeout);
 					/* FIXME: to prevent the server from expiring read timeouts during writes,
 					 * we refresh it. */
 					rep->rex = req->wex;
@@ -2484,7 +2486,7 @@
 			/* We used to have a free connection slot. Since we'll never use it,
 			 * we have to inform the server that it may be used by another session.
 			 */
-			if (may_dequeue_tasks(t->srv, t->be))
+			if (may_dequeue_tasks(t->srv, t->be->beprm))
 				task_wakeup(&rq, t->srv->queue_mgt);
 
 			return 1;
@@ -2500,7 +2502,7 @@
 			/* We used to have a free connection slot. Since we'll never use it,
 			 * we have to inform the server that it may be used by another session.
 			 */
-			if (may_dequeue_tasks(t->srv, t->be))
+			if (may_dequeue_tasks(t->srv, t->be->beprm))
 				task_wakeup(&rq, t->srv->queue_mgt);
 
 			return 1;
@@ -2520,7 +2522,7 @@
 			/* We used to have a free connection slot. Since we'll never use it,
 			 * we have to inform the server that it may be used by another session.
 			 */
-			if (may_dequeue_tasks(t->srv, t->be))
+			if (may_dequeue_tasks(t->srv, t->be->beprm))
 				task_wakeup(&rq, t->srv->queue_mgt);
 
 			return 1;
@@ -2534,8 +2536,8 @@
 		else {
 			if (! MY_FD_ISSET(t->srv_fd, StaticReadEvent)) {
 				MY_FD_SET(t->srv_fd, StaticReadEvent);
-				if (t->be->srvtimeout)
-					tv_delayfrom(&rep->rex, &now, t->be->srvtimeout);
+				if (t->be->beprm->srvtimeout)
+					tv_delayfrom(&rep->rex, &now, t->be->beprm->srvtimeout);
 				else
 					tv_eternity(&rep->rex);
 			}
@@ -2545,7 +2547,7 @@
 	else { /* SV_STCLOSE : nothing to do */
 		if ((global.mode & MODE_DEBUG) && (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))) {
 			int len;
-			len = sprintf(trash, "%08x:%s.srvcls[%04x:%04x]\n", t->uniq_id, t->be->id, (unsigned short)t->cli_fd, (unsigned short)t->srv_fd);
+			len = sprintf(trash, "%08x:%s.srvcls[%04x:%04x]\n", t->uniq_id, t->be->beprm->id, (unsigned short)t->cli_fd, (unsigned short)t->srv_fd);
 			write(1, trash, len);
 		}
 		return 0;
@@ -2720,13 +2722,13 @@
 				if (px->state == PR_STSTOPPED)
 					goto next_proxy;
 
-				if (s->fi->uri_auth && s->fi->uri_auth->scope) {
+				if (s->be->fiprm->uri_auth && s->be->fiprm->uri_auth->scope) {
 					/* we have a limited scope, we have to check the proxy name */
 					struct stat_scope *scope;
 					int len;
 
 					len = strlen(px->id);
-					scope = s->fi->uri_auth->scope;
+					scope = s->be->fiprm->uri_auth->scope;
 
 					while (scope) {
 						/* match exact proxy name */
@@ -3088,13 +3090,11 @@
 	char *cur_ptr, *cur_end, *cur_next;
 	int cur_idx, old_idx, abort_filt;
 
-	if (t->be->cookie_name == NULL &&
-	    t->be->appsession_name ==NULL &&
-	    t->fi->capture_name != NULL)
+	if (t->be->beprm->cookie_name == NULL &&
+	    t->be->beprm->appsession_name ==NULL &&
+	    t->be->fiprm->capture_name != NULL)
 		return;
 
-
-
 	/* Iterate through the headers.
 	 * we start with the start line.
 	 */
@@ -3193,26 +3193,26 @@
 			}
 			else {
 				/* first, let's see if we want to capture it */
-				if (t->fi->capture_name != NULL &&
+				if (t->fe->fiprm->capture_name != NULL &&
 				    t->logs.cli_cookie == NULL &&
-				    (p4 - p1 >= t->fi->capture_namelen) &&
-				    memcmp(p1, t->fi->capture_name, t->fi->capture_namelen) == 0) {
+				    (p4 - p1 >= t->fe->fiprm->capture_namelen) &&
+				    memcmp(p1, t->fe->fiprm->capture_name, t->fe->fiprm->capture_namelen) == 0) {
 					int log_len = p4 - p1;
 
 					if ((t->logs.cli_cookie = pool_alloc(capture)) == NULL) {
 						Alert("HTTP logging : out of memory.\n");
 					} else {
-						if (log_len > t->fi->capture_len)
-							log_len = t->fi->capture_len;
+						if (log_len > t->fe->fiprm->capture_len)
+							log_len = t->fe->fiprm->capture_len;
 						memcpy(t->logs.cli_cookie, p1, log_len);
 						t->logs.cli_cookie[log_len] = 0;
 					}
 				}
 
-				if ((p2 - p1 == t->be->cookie_len) && (t->be->cookie_name != NULL) &&
-				    (memcmp(p1, t->be->cookie_name, p2 - p1) == 0)) {
+				if ((p2 - p1 == t->be->beprm->cookie_len) && (t->be->beprm->cookie_name != NULL) &&
+				    (memcmp(p1, t->be->beprm->cookie_name, p2 - p1) == 0)) {
 					/* Cool... it's the right one */
-					struct server *srv = t->be->srv;
+					struct server *srv = t->be->beprm->srv;
 					char *delim;
 
 					/* if we're in cookie prefix mode, we'll search the delimitor so that we
@@ -3230,7 +3230,7 @@
 					 * +------------------------> cur_ptr
 					 */
 
-					if (t->be->options & PR_O_COOK_PFX) {
+					if (t->be->beprm->options & PR_O_COOK_PFX) {
 						for (delim = p3; delim < p4; delim++)
 							if (*delim == COOKIE_DELIM)
 								break;
@@ -3251,7 +3251,7 @@
 
 					while (srv) {
 						if ((srv->cklen == delim - p3) && !memcmp(p3, srv->cookie, delim - p3)) {
-							if (srv->state & SRV_RUNNING || t->be->options & PR_O_PERSIST) {
+							if (srv->state & SRV_RUNNING || t->be->beprm->options & PR_O_PERSIST) {
 								/* we found the server and it's usable */
 								t->flags &= ~SN_CK_MASK;
 								t->flags |= SN_CK_VALID | SN_DIRECT | SN_ASSIGNED;
@@ -3279,7 +3279,7 @@
 					 *   application cookie so that it does not get accidentely removed later,
 					 *   if we're in cookie prefix mode
 					 */
-					if ((t->be->options & PR_O_COOK_PFX) && (delim != p4)) {
+					if ((t->be->beprm->options & PR_O_COOK_PFX) && (delim != p4)) {
 						int delta; /* negative */
 
 						delta = buffer_replace2(req, p3, delim + 1, NULL, 0);
@@ -3293,7 +3293,7 @@
 						app_cookies++;	/* protect the header from deletion */
 					}
 					else if (del_cookie == NULL &&
-						 (t->be->options & (PR_O_COOK_INS | PR_O_COOK_IND)) == (PR_O_COOK_INS | PR_O_COOK_IND)) {
+						 (t->be->beprm->options & (PR_O_COOK_INS | PR_O_COOK_IND)) == (PR_O_COOK_INS | PR_O_COOK_IND)) {
 						del_cookie = p1;
 						del_colon = colon;
 					}
@@ -3318,8 +3318,8 @@
 					}
 				}
 
-				if ((t->be->appsession_name != NULL) &&
-				    (memcmp(p1, t->be->appsession_name, p2 - p1) == 0)) {
+				if ((t->be->beprm->appsession_name != NULL) &&
+				    (memcmp(p1, t->be->beprm->appsession_name, p2 - p1) == 0)) {
 					/* first, let's see if the cookie is our appcookie*/
 			    
 					/* Cool... it's the right one */
@@ -3332,12 +3332,12 @@
 						return;
 					}
 
-					memcpy(asession_temp->sessid, p3, t->be->appsession_len);
-					asession_temp->sessid[t->be->appsession_len] = 0;
+					memcpy(asession_temp->sessid, p3, t->be->beprm->appsession_len);
+					asession_temp->sessid[t->be->beprm->appsession_len] = 0;
 					asession_temp->serverid = NULL;
 			    
 					/* only do insert, if lookup fails */
-					if (chtbl_lookup(&(t->be->htbl_proxy), (void *) &asession_temp) != 0) {
+					if (chtbl_lookup(&(t->be->beprm->htbl_proxy), (void *) &asession_temp) != 0) {
 						if ((asession_temp = pool_alloc(appsess)) == NULL) {
 							/* free previously allocated memory */
 							pool_free_to(apools.sessid, local_asession.sessid);
@@ -3348,7 +3348,7 @@
 
 						asession_temp->sessid = local_asession.sessid;
 						asession_temp->serverid = local_asession.serverid;
-						chtbl_insert(&(t->be->htbl_proxy), (void *) asession_temp);
+						chtbl_insert(&(t->be->beprm->htbl_proxy), (void *) asession_temp);
 					} else {
 						/* free previously allocated memory */
 						pool_free_to(apools.sessid, local_asession.sessid);
@@ -3357,10 +3357,10 @@
 					if (asession_temp->serverid == NULL) {
 						Alert("Found Application Session without matching server.\n");
 					} else {
-						struct server *srv = t->be->srv;
+						struct server *srv = t->be->beprm->srv;
 						while (srv) {
 							if (strcmp(srv->id, asession_temp->serverid) == 0) {
-								if (srv->state & SRV_RUNNING || t->be->options & PR_O_PERSIST) {
+								if (srv->state & SRV_RUNNING || t->be->beprm->options & PR_O_PERSIST) {
 									/* we found the server and it's usable */
 									t->flags &= ~SN_CK_MASK;
 									t->flags |= SN_CK_VALID | SN_DIRECT | SN_ASSIGNED;
@@ -3375,7 +3375,7 @@
 						}/* end while(srv) */
 					}/* end else if server == NULL */
 
-					tv_delayfrom(&asession_temp->expire, &now, t->be->appsession_timeout);
+					tv_delayfrom(&asession_temp->expire, &now, t->be->beprm->appsession_timeout);
 				}/* end if ((t->proxy->appsession_name != NULL) ... */
 			}
 
@@ -3427,21 +3427,21 @@
 	appsess local_asession;
 	char *request_line;
 
-	if (t->be->appsession_name == NULL ||
+	if (t->be->beprm->appsession_name == NULL ||
 	    (t->hreq.meth != HTTP_METH_GET && t->hreq.meth != HTTP_METH_POST) ||
 	    (request_line = memchr(begin, ';', end - begin)) == NULL ||
-	    ((1 + t->be->appsession_name_len + 1 + t->be->appsession_len) > (end - request_line)))
+	    ((1 + t->be->beprm->appsession_name_len + 1 + t->be->beprm->appsession_len) > (end - request_line)))
 		return;
 
 	/* skip ';' */
 	request_line++;
 
 	/* look if we have a jsessionid */
-	if (strncasecmp(request_line, t->be->appsession_name, t->be->appsession_name_len) != 0)
+	if (strncasecmp(request_line, t->be->beprm->appsession_name, t->be->beprm->appsession_name_len) != 0)
 		return;
 
 	/* skip jsessionid= */
-	request_line += t->be->appsession_name_len + 1;
+	request_line += t->be->beprm->appsession_name_len + 1;
 	
 	/* First try if we already have an appsession */
 	asession_temp = &local_asession;
@@ -3453,12 +3453,12 @@
 	}
 	
 	/* Copy the sessionid */
-	memcpy(asession_temp->sessid, request_line, t->be->appsession_len);
-	asession_temp->sessid[t->be->appsession_len] = 0;
+	memcpy(asession_temp->sessid, request_line, t->be->beprm->appsession_len);
+	asession_temp->sessid[t->be->beprm->appsession_len] = 0;
 	asession_temp->serverid = NULL;
 	
 	/* only do insert, if lookup fails */
-	if (chtbl_lookup(&(t->be->htbl_proxy), (void *)&asession_temp)) {
+	if (chtbl_lookup(&(t->be->beprm->htbl_proxy), (void *)&asession_temp)) {
 		if ((asession_temp = pool_alloc(appsess)) == NULL) {
 			/* free previously allocated memory */
 			pool_free_to(apools.sessid, local_asession.sessid);
@@ -3468,14 +3468,14 @@
 		}
 		asession_temp->sessid = local_asession.sessid;
 		asession_temp->serverid = local_asession.serverid;
-		chtbl_insert(&(t->be->htbl_proxy), (void *) asession_temp);
+		chtbl_insert(&(t->be->beprm->htbl_proxy), (void *) asession_temp);
 	}
 	else {
 		/* free previously allocated memory */
 		pool_free_to(apools.sessid, local_asession.sessid);
 	}
 	
-	tv_delayfrom(&asession_temp->expire, &now, t->be->appsession_timeout);
+	tv_delayfrom(&asession_temp->expire, &now, t->be->beprm->appsession_timeout);
 	asession_temp->request_count++;
 	
 #if defined(DEBUG_HASH)
@@ -3484,10 +3484,10 @@
 	if (asession_temp->serverid == NULL) {
 		Alert("Found Application Session without matching server.\n");
 	} else {
-		struct server *srv = t->be->srv;
+		struct server *srv = t->be->beprm->srv;
 		while (srv) {
 			if (strcmp(srv->id, asession_temp->serverid) == 0) {
-				if (srv->state & SRV_RUNNING || t->be->options & PR_O_PERSIST) {
+				if (srv->state & SRV_RUNNING || t->be->beprm->options & PR_O_PERSIST) {
 					/* we found the server and it's usable */
 					t->flags &= ~SN_CK_MASK;
 					t->flags |= SN_CK_VALID | SN_DIRECT | SN_ASSIGNED;
@@ -3509,7 +3509,7 @@
  * In a GET request, check if the requested URI matches the stats uri for the
  * current backend, and if an authorization has been passed and is valid.
  *
- * It is assumed that the request is a GET and that the t->be->uri_auth field
+ * It is assumed that the request is a GET and that the t->be->fiprm->uri_auth field
  * is valid. An HTTP/401 response may be sent, or produce_content() can be
  * called to start sending data.
  *
diff --git a/src/queue.c b/src/queue.c
index 1247d25..d672fed 100644
--- a/src/queue.c
+++ b/src/queue.c
@@ -104,13 +104,13 @@
 		if (sess->srv->nbpend > sess->srv->nbpend_max)
 			sess->srv->nbpend_max = sess->srv->nbpend;
 	} else {
-		LIST_ADDQ(&sess->be->pendconns, &p->list);
-		sess->logs.prx_queue_size += sess->be->nbpend;
-		sess->be->nbpend++;
-		if (sess->be->nbpend > sess->be->nbpend_max)
-			sess->be->nbpend_max = sess->be->nbpend;
+		LIST_ADDQ(&sess->be->beprm->pendconns, &p->list);
+		sess->logs.prx_queue_size += sess->be->beprm->nbpend;
+		sess->be->beprm->nbpend++;
+		if (sess->be->beprm->nbpend > sess->be->beprm->nbpend_max)
+			sess->be->beprm->nbpend_max = sess->be->beprm->nbpend;
 	}
-	sess->be->totpend++;
+	sess->be->beprm->totpend++;
 	return p;
 }
 
@@ -126,8 +126,8 @@
 	if (p->srv)
 		p->srv->nbpend--;
 	else
-		p->sess->be->nbpend--;
-	p->sess->be->totpend--;
+		p->sess->be->beprm->nbpend--;
+	p->sess->be->beprm->totpend--;
 	pool_free(pendconn, p);
 }
 
diff --git a/src/session.c b/src/session.c
index 23aca36..7a19136 100644
--- a/src/session.c
+++ b/src/session.c
@@ -41,19 +41,19 @@
 
 	if (s->rsp_cap != NULL) {
 		struct cap_hdr *h;
-		for (h = s->fi->rsp_cap; h; h = h->next) {
+		for (h = s->fe->fiprm->rsp_cap; h; h = h->next) {
 			if (s->rsp_cap[h->index] != NULL)
 				pool_free_to(h->pool, s->rsp_cap[h->index]);
 		}
-		pool_free_to(s->fi->rsp_cap_pool, s->rsp_cap);
+		pool_free_to(s->fe->fiprm->rsp_cap_pool, s->rsp_cap);
 	}
 	if (s->hreq.cap != NULL) {
 		struct cap_hdr *h;
-		for (h = s->fi->req_cap; h; h = h->next) {
+		for (h = s->fe->fiprm->req_cap; h; h = h->next) {
 			if (s->hreq.cap[h->index] != NULL)
 				pool_free_to(h->pool, s->hreq.cap[h->index]);
 		}
-		pool_free_to(s->fi->req_cap_pool, s->hreq.cap);
+		pool_free_to(s->fe->fiprm->req_cap_pool, s->hreq.cap);
 	}
 
 	if (s->logs.uri)