MEDIUM: http: move header captures from http_txn to struct stream

The header captures are now general purpose captures since tcp rules
can use them to capture various contents. That removes a dependency
on http_txn that appeared in some sample fetch functions and in the
order by which captures and http_txn were allocated.

Interestingly the reset of the header captures were done at too many
places as http_init_txn() used to do it while it was done previously
in every call place.
diff --git a/src/frontend.c b/src/frontend.c
index caf0fc2..3a71bc4 100644
--- a/src/frontend.c
+++ b/src/frontend.c
@@ -111,15 +111,15 @@
 		setsockopt(cfd, SOL_SOCKET, SO_RCVBUF, &global.tune.client_rcvbuf, sizeof(global.tune.client_rcvbuf));
 
 	if (unlikely(fe->nb_req_cap > 0)) {
-		if ((s->txn.req.cap = pool_alloc2(fe->req_cap_pool)) == NULL)
+		if ((s->req_cap = pool_alloc2(fe->req_cap_pool)) == NULL)
 			goto out_return;	/* no memory */
-		memset(s->txn.req.cap, 0, fe->nb_req_cap * sizeof(void *));
+		memset(s->req_cap, 0, fe->nb_req_cap * sizeof(void *));
 	}
 
 	if (unlikely(fe->nb_rsp_cap > 0)) {
-		if ((s->txn.rsp.cap = pool_alloc2(fe->rsp_cap_pool)) == NULL)
+		if ((s->res_cap = pool_alloc2(fe->rsp_cap_pool)) == NULL)
 			goto out_free_reqcap;	/* no memory */
-		memset(s->txn.rsp.cap, 0, fe->nb_rsp_cap * sizeof(void *));
+		memset(s->res_cap, 0, fe->nb_rsp_cap * sizeof(void *));
 	}
 
 	if (fe->http_needed) {
@@ -209,9 +209,9 @@
 
 	/* Error unrolling */
  out_free_rspcap:
-	pool_free2(fe->rsp_cap_pool, s->txn.rsp.cap);
+	pool_free2(fe->rsp_cap_pool, s->res_cap);
  out_free_reqcap:
-	pool_free2(fe->req_cap_pool, s->txn.req.cap);
+	pool_free2(fe->req_cap_pool, s->req_cap);
  out_return:
 	return -1;
 }
diff --git a/src/hlua.c b/src/hlua.c
index 650051a..e54c029 100644
--- a/src/hlua.c
+++ b/src/hlua.c
@@ -2165,14 +2165,14 @@
 
 	/* XXX: ? */
 	socket->s->pend_pos = NULL;
+	socket->s->req_cap = NULL;
+	socket->s->res_cap = NULL;
 
 	/* XXX: See later. */
 	socket->s->txn.sessid = NULL;
 	socket->s->txn.srv_cookie = NULL;
 	socket->s->txn.cli_cookie = NULL;
 	socket->s->txn.uri = NULL;
-	socket->s->txn.req.cap = NULL;
-	socket->s->txn.rsp.cap = NULL;
 	socket->s->txn.hdr_idx.v = NULL;
 	socket->s->txn.hdr_idx.size = 0;
 	socket->s->txn.hdr_idx.used = 0;
diff --git a/src/log.c b/src/log.c
index d2f8ad5..949dc29 100644
--- a/src/log.c
+++ b/src/log.c
@@ -1415,16 +1415,16 @@
 
 			case LOG_FMT_HDRREQUEST: // %hr
 				/* request header */
-				if (fe->nb_req_cap && txn->req.cap) {
+				if (fe->nb_req_cap && s->req_cap) {
 					if (tmp->options & LOG_OPT_QUOTE)
 						LOGCHAR('"');
 					LOGCHAR('{');
 					for (hdr = 0; hdr < fe->nb_req_cap; hdr++) {
 						if (hdr)
 							LOGCHAR('|');
-						if (txn->req.cap[hdr] != NULL) {
+						if (s->req_cap[hdr] != NULL) {
 							ret = encode_string(tmplog, dst + maxsize,
-									       '#', hdr_encode_map, txn->req.cap[hdr]);
+									       '#', hdr_encode_map, s->req_cap[hdr]);
 							if (ret == NULL || *ret != '\0')
 								goto out;
 							tmplog = ret;
@@ -1439,15 +1439,15 @@
 
 			case LOG_FMT_HDRREQUESTLIST: // %hrl
 				/* request header list */
-				if (fe->nb_req_cap && txn->req.cap) {
+				if (fe->nb_req_cap && s->req_cap) {
 					for (hdr = 0; hdr < fe->nb_req_cap; hdr++) {
 						if (hdr > 0)
 							LOGCHAR(' ');
 						if (tmp->options & LOG_OPT_QUOTE)
 							LOGCHAR('"');
-						if (txn->req.cap[hdr] != NULL) {
+						if (s->req_cap[hdr] != NULL) {
 							ret = encode_string(tmplog, dst + maxsize,
-									       '#', hdr_encode_map, txn->req.cap[hdr]);
+									       '#', hdr_encode_map, s->req_cap[hdr]);
 							if (ret == NULL || *ret != '\0')
 								goto out;
 							tmplog = ret;
@@ -1463,16 +1463,16 @@
 
 			case LOG_FMT_HDRRESPONS: // %hs
 				/* response header */
-				if (fe->nb_rsp_cap && txn->rsp.cap) {
+				if (fe->nb_rsp_cap && s->res_cap) {
 					if (tmp->options & LOG_OPT_QUOTE)
 						LOGCHAR('"');
 					LOGCHAR('{');
 					for (hdr = 0; hdr < fe->nb_rsp_cap; hdr++) {
 						if (hdr)
 							LOGCHAR('|');
-						if (txn->rsp.cap[hdr] != NULL) {
+						if (s->res_cap[hdr] != NULL) {
 							ret = encode_string(tmplog, dst + maxsize,
-							                    '#', hdr_encode_map, txn->rsp.cap[hdr]);
+							                    '#', hdr_encode_map, s->res_cap[hdr]);
 							if (ret == NULL || *ret != '\0')
 								goto out;
 							tmplog = ret;
@@ -1487,15 +1487,15 @@
 
 			case LOG_FMT_HDRRESPONSLIST: // %hsl
 				/* response header list */
-				if (fe->nb_rsp_cap && txn->rsp.cap) {
+				if (fe->nb_rsp_cap && s->res_cap) {
 					for (hdr = 0; hdr < fe->nb_rsp_cap; hdr++) {
 						if (hdr > 0)
 							LOGCHAR(' ');
 						if (tmp->options & LOG_OPT_QUOTE)
 							LOGCHAR('"');
-						if (txn->rsp.cap[hdr] != NULL) {
+						if (s->res_cap[hdr] != NULL) {
 							ret = encode_string(tmplog, dst + maxsize,
-							                    '#', hdr_encode_map, txn->rsp.cap[hdr]);
+							                    '#', hdr_encode_map, s->res_cap[hdr]);
 							if (ret == NULL || *ret != '\0')
 								goto out;
 							tmplog = ret;
diff --git a/src/peers.c b/src/peers.c
index c27fad0..08ccfa9 100644
--- a/src/peers.c
+++ b/src/peers.c
@@ -1154,6 +1154,8 @@
 	s->sess->fe = p;
 	s->be = s->sess->fe;
 	s->req.buf = s->res.buf = NULL;
+	s->req_cap = NULL;
+	s->res_cap = NULL;
 
 	s->si[0].flags = SI_FL_NONE;
 	s->si[1].flags = SI_FL_ISBACK;
@@ -1225,8 +1227,6 @@
 	txn->srv_cookie = NULL;
 	txn->cli_cookie = NULL;
 	txn->uri = NULL;
-	txn->req.cap = NULL;
-	txn->rsp.cap = NULL;
 	txn->hdr_idx.v = NULL;
 	txn->hdr_idx.size = txn->hdr_idx.used = 0;
 
diff --git a/src/proto_http.c b/src/proto_http.c
index f514928..fac05b7 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -2951,9 +2951,9 @@
 	msg->flags &= ~HTTP_MSGF_XFER_LEN;
 
 	/* 5: we may need to capture headers */
-	if (unlikely((s->logs.logwait & LW_REQHDR) && txn->req.cap))
+	if (unlikely((s->logs.logwait & LW_REQHDR) && s->req_cap))
 		capture_headers(req->buf->p, &txn->hdr_idx,
-				txn->req.cap, sess->fe->req_cap);
+				s->req_cap, sess->fe->req_cap);
 
 	/* 6: determine the transfer-length.
 	 * According to RFC2616 #4.4, amended by the HTTPbis working group,
@@ -6076,9 +6076,9 @@
 	 * 3: we may need to capture headers
 	 */
 	s->logs.logwait &= ~LW_RESP;
-	if (unlikely((s->logs.logwait & LW_RSPHDR) && txn->rsp.cap))
+	if (unlikely((s->logs.logwait & LW_RSPHDR) && s->res_cap))
 		capture_headers(rep->buf->p, &txn->hdr_idx,
-				txn->rsp.cap, sess->fe->rsp_cap);
+				s->res_cap, sess->fe->rsp_cap);
 
 	/* 4: determine the transfer-length.
 	 * According to RFC2616 #4.4, amended by the HTTPbis working group,
@@ -8824,12 +8824,6 @@
 	if (fe->options2 & PR_O2_REQBUG_OK)
 		txn->req.err_pos = -1;            /* let buggy requests pass */
 
-	if (txn->req.cap)
-		memset(txn->req.cap, 0, fe->nb_req_cap * sizeof(void *));
-
-	if (txn->rsp.cap)
-		memset(txn->rsp.cap, 0, fe->nb_rsp_cap * sizeof(void *));
-
 	if (txn->hdr_idx.v)
 		hdr_idx_init(&txn->hdr_idx);
 }
@@ -8859,18 +8853,18 @@
 	txn->srv_cookie = NULL;
 	txn->cli_cookie = NULL;
 
-	if (txn->req.cap) {
+	if (s->req_cap) {
 		struct cap_hdr *h;
 		for (h = fe->req_cap; h; h = h->next)
-			pool_free2(h->pool, txn->req.cap[h->index]);
-		memset(txn->req.cap, 0, fe->nb_req_cap * sizeof(void *));
+			pool_free2(h->pool, s->req_cap[h->index]);
+		memset(s->req_cap, 0, fe->nb_req_cap * sizeof(void *));
 	}
 
-	if (txn->rsp.cap) {
+	if (s->res_cap) {
 		struct cap_hdr *h;
 		for (h = fe->rsp_cap; h; h = h->next)
-			pool_free2(h->pool, txn->rsp.cap[h->index]);
-		memset(txn->rsp.cap, 0, fe->nb_rsp_cap * sizeof(void *));
+			pool_free2(h->pool, s->res_cap[h->index]);
+		memset(s->res_cap, 0, fe->nb_rsp_cap * sizeof(void *));
 	}
 
 }
@@ -10830,7 +10824,6 @@
                  const struct arg *args, struct sample *smp, const char *kw, void *private)
 {
 	struct proxy *fe = strm_sess(l4)->fe;
-	struct http_txn *txn = l7;
 	int idx;
 
 	if (!args || args->type != ARGT_UINT)
@@ -10838,13 +10831,13 @@
 
 	idx = args->data.uint;
 
-	if (idx > (fe->nb_req_cap - 1) || txn->req.cap == NULL || txn->req.cap[idx] == NULL)
+	if (idx > (fe->nb_req_cap - 1) || l4->req_cap == NULL || l4->req_cap[idx] == NULL)
 		return 0;
 
 	smp->type = SMP_T_STR;
 	smp->flags |= SMP_F_CONST;
-	smp->data.str.str = txn->req.cap[idx];
-	smp->data.str.len = strlen(txn->req.cap[idx]);
+	smp->data.str.str = l4->req_cap[idx];
+	smp->data.str.len = strlen(l4->req_cap[idx]);
 
 	return 1;
 }
@@ -10857,7 +10850,6 @@
                  const struct arg *args, struct sample *smp, const char *kw, void *private)
 {
 	struct proxy *fe = strm_sess(l4)->fe;
-	struct http_txn *txn = l7;
 	int idx;
 
 	if (!args || args->type != ARGT_UINT)
@@ -10865,13 +10857,13 @@
 
 	idx = args->data.uint;
 
-	if (idx > (fe->nb_rsp_cap - 1) || txn->rsp.cap == NULL || txn->rsp.cap[idx] == NULL)
+	if (idx > (fe->nb_rsp_cap - 1) || l4->res_cap == NULL || l4->res_cap[idx] == NULL)
 		return 0;
 
 	smp->type = SMP_T_STR;
 	smp->flags |= SMP_F_CONST;
-	smp->data.str.str = txn->rsp.cap[idx];
-	smp->data.str.len = strlen(txn->rsp.cap[idx]);
+	smp->data.str.str = l4->res_cap[idx];
+	smp->data.str.len = strlen(l4->res_cap[idx]);
 
 	return 1;
 }
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
index 6a67785..e77edc4 100644
--- a/src/proto_tcp.c
+++ b/src/proto_tcp.c
@@ -1190,7 +1190,7 @@
 			else if (rule->action == TCP_ACT_CAPTURE) {
 				struct sample *key;
 				struct cap_hdr *h = rule->act_prm.cap.hdr;
-				char **cap = s->txn.req.cap;
+				char **cap = s->req_cap;
 				int len;
 
 				key = sample_fetch_string(s->be, s, &s->txn, SMP_OPT_DIR_REQ | partial, rule->act_prm.cap.expr);
diff --git a/src/stream.c b/src/stream.c
index 70c07a7..d28684e 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -452,6 +452,8 @@
 	s->be  = sess->fe;
 	s->comp_algo = NULL;
 	s->req.buf = s->res.buf = NULL;
+	s->req_cap = NULL;
+	s->res_cap = NULL;
 
 	/* Let's count a stream now */
 	proxy_inc_fe_sess_ctr(l, p);
@@ -538,8 +540,6 @@
 	txn->srv_cookie = NULL;
 	txn->cli_cookie = NULL;
 	txn->uri = NULL;
-	txn->req.cap = NULL;
-	txn->rsp.cap = NULL;
 	txn->hdr_idx.v = NULL;
 	txn->hdr_idx.size = txn->hdr_idx.used = 0;
 	txn->flags = 0;
@@ -651,8 +651,8 @@
 
 	pool_free2(pool2_hdr_idx, txn->hdr_idx.v);
 	if (fe) {
-		pool_free2(fe->rsp_cap_pool, txn->rsp.cap);
-		pool_free2(fe->req_cap_pool, txn->req.cap);
+		pool_free2(fe->rsp_cap_pool, s->res_cap);
+		pool_free2(fe->req_cap_pool, s->req_cap);
 	}
 
 	stream_store_counters(s);